preciousmouse / Pipe solution

// ==UserScript==
// @namespace       https://openuserjs.org/users/preciousmouse
// @name            Pipe solution
// @description     auto solve Pipe problem
// @author          preciousmouse
// @copyright       2020, preciousmouse (https://openuserjs.org/users/preciousmouse)
// @license         MIT
// @version         1.4
// @updateURL       https://openuserjs.org/meta/preciousmouse/Pipe_solution.user.js
// @downloadURL     https://openuserjs.org/install/preciousmouse/Pipe_solution.user.js
// @supportURL      https://github.com/puzzle-resolution/Pipe
// @require         https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.18.2/babel.js
// @require         https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.16.0/polyfill.js
// @require         http://requirejs.org/docs/release/2.1.5/comments/require.js
// @include         https://cn.puzzle-pipes.com/
// @include         https://cn.puzzle-pipes.com/?*
// @grant none
// ==/UserScript==

// ==OpenUserJS==
// @author preciousmouse
// ==/OpenUserJS==


"use strict";

function submitAnswer() {
    var t;
    null === (t = document.querySelector("#btnReady")) || void 0 === t || t.click();
}

try {
    window.useRobot = !0;
} catch (t) {}

class Pipe {
    constructor(t, i) {
        this.initState = t => ({
            blockState: t.map((t => t.map((t => ({
                sharp: this.getBlockType(t),
                status: {},
                locked: !1
            })))))
        }), this.getBlockType = t => {
            const i = !!(1 & t), o = !!(2 & t), s = !!(4 & t), e = !!(8 & t), n = [ o, s, e, i ].filter((t => t)).length;
            if (n < 1 || n > 3) throw new Error(`BlockType assert: ${t}`);
            return {
                1: "Sharp1",
                2: o && e || s && i ? "Sharp2" : "Sharp3",
                3: "Sharp4"
            }[n];
        }, this.clonePosition = t => Object.assign({}, t), this.checkPositionEqual = (t, i) => t.x === i.x && t.y === i.y, 
        this.topPosition = t => this.clonePosition({
            x: 0 == t.x ? this.graph.length - 1 : t.x - 1,
            y: t.y
        }), this.bottomPosition = t => this.clonePosition({
            x: t.x == this.graph.length - 1 ? 0 : t.x + 1,
            y: t.y
        }), this.leftPosition = t => this.clonePosition({
            x: t.x,
            y: 0 == t.y ? this.graph[0].length - 1 : t.y - 1
        }), this.rightPosition = t => this.clonePosition({
            x: t.x,
            y: t.y == this.graph[0].length - 1 ? 0 : t.y + 1
        }), this.oppositeDirection = t => {
            const i = [ "up", "left", "down", "right" ];
            return i[(i.indexOf(t) + 2) % 4];
        }, this.directionPositionReducer = t => {
            switch (t) {
              case "up":
                return this.topPosition;

              case "down":
                return this.bottomPosition;

              case "left":
                return this.leftPosition;

              case "right":
                return this.rightPosition;

              default:
                throw new Error("direction param illegal assert");
            }
        }, this.cloneState = function(t) {
            return t.map((t => t.map((t => JSON.parse(JSON.stringify(t))))));
        }, this.checkBoundary = t => !(t.x < 0 || t.x >= this.graph.length || t.y < 0 || t.y >= this.graph[0].length), 
        this.lockPointDirectionStatus = (t, i, o, s, e) => {
            const n = this.directionPositionReducer(t)(s), r = this.oppositeDirection(t), h = i.blockState[s.x][s.y].status[t], a = i.blockState[n.x][n.y].status[r];
            return (void 0 === h || void 0 === a || h === a) && (!(void 0 !== h && h !== e || void 0 !== a && a !== e) && (void 0 === h && (i.blockState[s.x][s.y].status[t] = e, 
            this.appendToUpdateQueue(i, o, [ this.clonePosition(s) ])), void 0 === a && (i.blockState[n.x][n.y].status[r] = e, 
            this.appendToUpdateQueue(i, o, [ this.clonePosition(n) ])), !0));
        }, this.lockPointUpStatus = this.lockPointDirectionStatus.bind(null, "up"), this.lockPointDownStatus = this.lockPointDirectionStatus.bind(null, "down"), 
        this.lockPointLeftStatus = this.lockPointDirectionStatus.bind(null, "left"), this.lockPointRightStatus = this.lockPointDirectionStatus.bind(null, "right"), 
        this.applyNeighborLink = (t, i, o, s, e) => {
            if (this.checkPositionEqual(this.topPosition(i), o)) return this.lockPointUpStatus(s, e, i, t);
            if (this.checkPositionEqual(this.bottomPosition(i), o)) return this.lockPointDownStatus(s, e, i, t);
            if (this.checkPositionEqual(this.leftPosition(i), o)) return this.lockPointLeftStatus(s, e, i, t);
            if (this.checkPositionEqual(this.rightPosition(i), o)) return this.lockPointRightStatus(s, e, i, t);
            throw new Error("Nodes are not adjacent assert");
        }, this.checkNeighborLink = this.applyNeighborLink.bind(null, !0), this.disableNeighborLink = this.applyNeighborLink.bind(null, !1), 
        this.isSolvedPosition = (t, i) => t.blockState[i.x][i.y].locked, this.getDirectionLink = (t, i, o) => {
            const s = t.blockState, e = s[i.x][i.y].status;
            if (s[o.x][o.y].status, this.checkPositionEqual(this.topPosition(i), o)) return e.up;
            if (this.checkPositionEqual(this.bottomPosition(i), o)) return e.down;
            if (this.checkPositionEqual(this.leftPosition(i), o)) return e.left;
            if (this.checkPositionEqual(this.rightPosition(i), o)) return e.right;
            throw new Error("Nodes are not adjacent assert");
        }, this.checkDirectionLink = (t, i, o) => {
            const check = (t, i) => void 0 === t || void 0 === i || t === i, s = t.blockState, e = s[i.x][i.y].status, n = s[o.x][o.y].status;
            if (this.checkPositionEqual(this.topPosition(i), o)) return check(e.up, n.down);
            if (this.checkPositionEqual(this.bottomPosition(i), o)) return check(e.down, n.up);
            if (this.checkPositionEqual(this.leftPosition(i), o)) return check(e.left, n.right);
            if (this.checkPositionEqual(this.rightPosition(i), o)) return check(e.right, n.left);
            throw new Error("Nodes are not adjacent assert");
        }, this.asynDirectionLink = (t, i, o) => {
            const {status: {up: s, down: e, left: n, right: r}} = t.blockState[o.x][o.y], h = this.topPosition(o), a = t.blockState[h.x][h.y], l = this.bottomPosition(o), c = t.blockState[l.x][l.y], u = this.leftPosition(o), f = t.blockState[u.x][u.y], p = this.rightPosition(o), d = t.blockState[p.x][p.y];
            if (void 0 !== a.status.down) if (void 0 === s) {
                if (!this.lockPointUpStatus(t, i, o, a.status.down)) return !1;
            } else if (s !== a.status.down) return !1;
            if (void 0 !== c.status.up) if (void 0 === e) {
                if (!this.lockPointDownStatus(t, i, o, c.status.up)) return !1;
            } else if (e !== c.status.up) return !1;
            if (void 0 !== f.status.right) if (void 0 === n) {
                if (!this.lockPointLeftStatus(t, i, o, f.status.right)) return !1;
            } else if (n !== f.status.right) return !1;
            if (void 0 !== d.status.left) if (void 0 === r) {
                if (!this.lockPointRightStatus(t, i, o, d.status.left)) return !1;
            } else if (r !== d.status.left) return !1;
            return !0;
        }, this.updatePoint = (t, i, o) => {
            if (this.isSolvedPosition(t, o)) return !0;
            const {blockState: s} = t, {x: e, y: n} = o, r = s[e][n], {sharp: h, status: {up: a, down: l, left: c, right: u}} = r, f = {
                Sharp1: 1,
                Sharp2: 2,
                Sharp3: 2,
                Sharp4: 3
            }[h], p = [ a, c, l, u ].filter((t => !0 === t)).length, d = [ a, c, l, u ].filter((t => !1 === t)).length;
            if (p > f || d > 4 - f) return !1;
            if (p === f) {
                if ("Sharp2" === h && (void 0 !== a && void 0 !== l && a !== l || void 0 !== c && void 0 !== u && c !== u)) return !1;
                if ("Sharp3" === h && (a && l || c && u)) return !1;
                if (void 0 === a && !this.lockPointUpStatus(t, i, o, !1)) return !1;
                if (void 0 === l && !this.lockPointDownStatus(t, i, o, !1)) return !1;
                if (void 0 === c && !this.lockPointLeftStatus(t, i, o, !1)) return !1;
                if (void 0 === u && !this.lockPointRightStatus(t, i, o, !1)) return !1;
                s[e][n].locked = !0;
            } else if (d === 4 - f) {
                if ("Sharp2" === h && (!1 === a != (!1 === l) || !1 === c != (!1 === u))) return !1;
                if ("Sharp3" === h && (!1 === a && !1 === l || !1 === c && !1 === u)) return !1;
                if (void 0 === a && !this.lockPointUpStatus(t, i, o, !0)) return !1;
                if (void 0 === l && !this.lockPointDownStatus(t, i, o, !0)) return !1;
                if (void 0 === c && !this.lockPointLeftStatus(t, i, o, !0)) return !1;
                if (void 0 === u && !this.lockPointRightStatus(t, i, o, !0)) return !1;
                s[e][n].locked = !0;
            } else {
                const r = [ "up", "left", "down", "right" ];
                if ("Sharp1" === h) ; else if ("Sharp2" === h) {
                    if (1 == p) {
                        const h = [ a, c, l, u ].findIndex((t => !0 === t));
                        if (!this.lockPointDirectionStatus(r[(h + 2) % 4], t, i, o, !0)) return !1;
                        if (!this.lockPointDirectionStatus(r[(h + 1) % 4], t, i, o, !1)) return !1;
                        if (!this.lockPointDirectionStatus(r[(h + 3) % 4], t, i, o, !1)) return !1;
                        s[e][n].locked = !0;
                    } else if (1 == d) {
                        const h = [ a, c, l, u ].findIndex((t => !1 === t));
                        if (!this.lockPointDirectionStatus(r[(h + 2) % 4], t, i, o, !1)) return !1;
                        if (!this.lockPointDirectionStatus(r[(h + 1) % 4], t, i, o, !0)) return !1;
                        if (!this.lockPointDirectionStatus(r[(h + 3) % 4], t, i, o, !0)) return !1;
                        s[e][n].locked = !0;
                    }
                } else if ("Sharp3" === h) {
                    if (1 == d) {
                        const s = [ a, c, l, u ].findIndex((t => !1 === t));
                        if (!this.lockPointDirectionStatus(r[(s + 2) % 4], t, i, o, !0)) return !1;
                    }
                    if (1 == p) {
                        const s = [ a, c, l, u ].findIndex((t => !0 === t));
                        if (!this.lockPointDirectionStatus(r[(s + 2) % 4], t, i, o, !1)) return !1;
                    }
                }
            }
            return !0;
        }, this.updateAroudState = (t, i) => {
            for (let o of this.graph.keys()) this.lockPointLeftStatus(t, i, {
                x: o,
                y: 0
            }, !1), this.lockPointRightStatus(t, i, {
                x: o,
                y: this.graph[0].length - 1
            }, !1);
            for (let o of this.graph[0].keys()) this.lockPointUpStatus(t, i, {
                x: 0,
                y: o
            }, !1), this.lockPointDownStatus(t, i, {
                x: this.graph.length - 1,
                y: o
            }, !1);
            return !0;
        }, this.updateCutInCases = (t, i) => {
            const {blockState: o} = t;
            for (let s of this.graph.keys()) for (let e of this.graph[0].keys()) if ("Sharp1" === o[s][e].sharp) this.aroundTRBL({
                x: s,
                y: e
            }, (t => "Sharp1" === o[t.x][t.y].sharp)).map((o => {
                if (o && !this.disableNeighborLink({
                    x: s,
                    y: e
                }, o, t, i)) return !1;
            })); else if ("Sharp2" === o[s][e].sharp) {
                const testIsDirectToSharp1 = t => {
                    const i = this.directionPositionReducer(t), n = {
                        x: s,
                        y: e
                    };
                    let r = this.clonePosition(n);
                    for (;;) {
                        if (r = i(r), this.checkPositionEqual(n, r)) return !0;
                        const t = o[r.x][r.y].sharp;
                        if ("Sharp1" === t) return !0;
                        if ("Sharp2" !== t) return !1;
                    }
                };
                if (testIsDirectToSharp1("up") && testIsDirectToSharp1("down")) {
                    if (!this.lockPointUpStatus(t, i, {
                        x: s,
                        y: e
                    }, !1)) return !1;
                } else if (testIsDirectToSharp1("left") && testIsDirectToSharp1("right") && !this.lockPointLeftStatus(t, i, {
                    x: s,
                    y: e
                }, !1)) return !1;
            }
            return !0;
        }, this.updateCases = t => {
            const i = t.blockState;
            for (let o of this.graph.keys()) for (let s of this.graph[0].keys()) if (!i[o][s].locked) {
                const e = {
                    x: o,
                    y: s
                }, n = this.generateSet(t, this.clonePosition(e)), r = this.aroundTRBL(e).filter((t => t && !i[t.x][t.y].locked));
                for (let i of r) if (n.exportPoints.has(`${i.x}_${i.y}`)) {
                    let o = new Set;
                    if (!this.disableNeighborLink(e, i, t, o)) return !1;
                    if (o.size > 0) return !!this.clearUpdateQueue(t, o) && 1;
                }
                if (1 == n.exportPoints.size) {
                    const [i, o] = [ ...n.exportPoints.values() ][0].split("_");
                    let s = {
                        x: +i,
                        y: +o
                    };
                    if (this.checkPositionEqual(e, s)) for (let i of r) {
                        if (void 0 !== this.getDirectionLink(t, e, i)) continue;
                        const o = this.generateSet(t, this.clonePosition(i)), s = `${this.floorEntry.x}_${this.floorEntry.y}`;
                        if (1 === n.exportPoints.size && 1 === o.exportPoints.size && !n.lockedPoints.has(s) && !o.lockedPoints.has(s)) {
                            const positionRest = (t, i) => {
                                const o = t.blockState[i.x][i.y], s = {
                                    Sharp1: 1,
                                    Sharp2: 2,
                                    Sharp3: 2,
                                    Sharp4: 3
                                }, e = this.topPosition(i), n = this.bottomPosition(i), r = this.leftPosition(i), h = this.rightPosition(i);
                                let a = 0;
                                return o.status.up && t.blockState[e.x][e.y].locked && a++, o.status.down && t.blockState[n.x][n.y].locked && a++, 
                                o.status.left && t.blockState[r.x][r.y].locked && a++, o.status.right && t.blockState[h.x][h.y].locked && a++, 
                                s[o.sharp] - a;
                            };
                            if (1 === positionRest(t, e) && 1 === positionRest(t, i)) {
                                let o = new Set;
                                if (!this.disableNeighborLink(e, i, t, o)) return !1;
                                if (o.size > 0) return !!this.clearUpdateQueue(t, o) && 1;
                            }
                        }
                    }
                }
            }
            return 2;
        }, this.findNext = t => {
            for (let i of this.graph.keys()) for (let o of this.graph[0].keys()) if (!t.blockState[i][o].locked) return {
                x: i,
                y: o
            };
            return !1;
        }, this.getCases = (t, i) => {
            const {x: o, y: s} = i, e = t.blockState[o][s];
            if (e.locked) return [];
            const {sharp: n, status: {up: r, down: h, left: a, right: l}} = e, c = [ r, a, h, l ].filter((t => !0 === t)).length, u = [ r, a, h, l ].filter((t => !1 === t)).length;
            if ("Sharp1" === n) {
                if (c >= 1) return [];
                let t = [];
                return void 0 === r && t.push({
                    position: this.clonePosition(i),
                    directions: [ "up" ]
                }), void 0 === h && t.push({
                    position: this.clonePosition(i),
                    directions: [ "down" ]
                }), void 0 === a && t.push({
                    position: this.clonePosition(i),
                    directions: [ "left" ]
                }), void 0 === l && t.push({
                    position: this.clonePosition(i),
                    directions: [ "right" ]
                }), t;
            }
            if ("Sharp2" === n) {
                if (c >= 1 || u >= 1) return [];
                let t = [];
                return t.push({
                    position: this.clonePosition(i),
                    directions: [ "up", "down" ]
                }), t.push({
                    position: this.clonePosition(i),
                    directions: [ "left", "right" ]
                }), t;
            }
            if ("Sharp3" === n) {
                if (c >= 2 || u >= 2) return [];
                let t = [];
                return void 0 === r || void 0 === h ? void 0 === a && void 0 === l ? (t.push({
                    position: this.clonePosition(i),
                    directions: [ "up", "left" ]
                }), t.push({
                    position: this.clonePosition(i),
                    directions: [ "down", "left" ]
                }), t.push({
                    position: this.clonePosition(i),
                    directions: [ "up", "right" ]
                }), t.push({
                    position: this.clonePosition(i),
                    directions: [ "down", "right" ]
                })) : (void 0 === r && t.push({
                    position: this.clonePosition(i),
                    directions: [ "up" ]
                }), void 0 === h && t.push({
                    position: this.clonePosition(i),
                    directions: [ "down" ]
                })) : (void 0 === a && t.push({
                    position: this.clonePosition(i),
                    directions: [ "left" ]
                }), void 0 === l && t.push({
                    position: this.clonePosition(i),
                    directions: [ "right" ]
                })), t;
            }
            if ("Sharp4" === n) {
                if (c >= 3 || u >= 1) return [];
                let t = [];
                return void 0 === r && t.push({
                    position: this.clonePosition(i),
                    directions: [ "up" ]
                }), void 0 === h && t.push({
                    position: this.clonePosition(i),
                    directions: [ "down" ]
                }), void 0 === a && t.push({
                    position: this.clonePosition(i),
                    directions: [ "left" ]
                }), void 0 === l && t.push({
                    position: this.clonePosition(i),
                    directions: [ "right" ]
                }), t;
            }
            return [];
        }, this.applyCase = (t, i) => {
            const {position: o, directions: s} = i;
            let e = new Set;
            for (let i of s) if (!this.lockPointDirectionStatus(i, t, e, o, !0)) return !1;
            return !!this.clearUpdateQueue(t, e);
        }, this.recu = t => {
            for (;;) {
                const i = this.updateCases(t);
                if (!1 === i) return !1;
                if (2 === i) {
                    if (this.verificate(t)) return t;
                    break;
                }
                0;
            }
            const i = this.findNext(t);
            if (!i) return !!this.verificate(t) && t;
            {
                const o = this.getCases(t, i);
                for (let i of o) {
                    const o = {
                        blockState: this.cloneState(t.blockState),
                        currentRecuIndex: t.currentRecuIndex + 1
                    };
                    if (this.applyCase(o, i)) {
                        const t = this.recu(o);
                        if (t) return t;
                    }
                }
            }
            return !1;
        }, this.solve = () => {
            const {blockState: t} = this.initState(this.graph);
            let i = {
                blockState: t,
                currentRecuIndex: 0
            }, o = new Set;
            return this.isCrossMap || this.updateAroudState(i, o), this.updateCutInCases(i, o), 
            this.clearUpdateQueue(i, o), this.verificate(i) || (i = this.recu({
                blockState: this.cloneState(t),
                currentRecuIndex: 0
            })), this.answer = i ? this.generaterAnawer(i.blockState) : "failed";
        }, this.generaterAnawer = t => {
            const calcStatusNumber = t => {
                const {up: i, down: o, left: s, right: e} = t;
                let n = 0;
                return e && (n |= 1), i && (n |= 2), s && (n |= 4), o && (n |= 8), n;
            }, getBlockAnawerStatus = (t, i) => {
                const next = t => 8 * +!!(4 & t) + 4 * +!!(2 & t) + 2 * +!!(1 & t) + 1 * +!!(8 & t);
                let o = 0, s = t;
                for (;s != i; ) if (s = next(s), o++, o > 3) throw new Error(`next cnt limit excceded: ${t},${i},${o}>3`);
                return o % 4;
            };
            let i = "";
            for (let o of this.graph.keys()) for (let s of this.graph[0].keys()) {
                const e = getBlockAnawerStatus(this.graph[o][s], calcStatusNumber(t[o][s].status));
                i += "Sharp2" == this.getBlockType(this.graph[o][s]) ? {
                    0: 0,
                    1: 1,
                    2: 0,
                    3: 1
                }[e] : e;
            }
            return i += ":", i += Array(this.graph.length * this.graph[0].length).fill(1).join(""), 
            i;
        }, this.generateSet = (t, i) => {
            const o = t.blockState;
            let s = new Set, e = new Set;
            const formatPoint = t => `${t.x}_${t.y}`, formatEdge = (t, i) => {
                const [o, s] = t.x < i.x ? [ t, i ] : t.x > i.x ? [ i, t ] : t.y < i.y ? [ t, i ] : [ i, t ];
                return `${formatPoint(o)},${formatPoint(s)}`;
            };
            let n = [ i ];
            do {
                const i = n.shift(), r = formatPoint(i);
                if (!s.has(r)) {
                    s.add(r);
                    const addPoint = t => {
                        n.push(t);
                        const o = formatEdge(i, t);
                        e.has(o) || e.add(o);
                    }, {status: {up: h, down: a, left: l, right: c}} = o[i.x][i.y];
                    h && this.isSolvedPosition(t, this.topPosition(i)) && addPoint(this.topPosition(i)), 
                    a && this.isSolvedPosition(t, this.bottomPosition(i)) && addPoint(this.bottomPosition(i)), 
                    l && this.isSolvedPosition(t, this.leftPosition(i)) && addPoint(this.leftPosition(i)), 
                    c && this.isSolvedPosition(t, this.rightPosition(i)) && addPoint(this.rightPosition(i));
                }
            } while (n.length > 0);
            let r = !1;
            if (e.size >= s.size) r = !0; else {
                r = (() => {
                    let t = {}, i = [];
                    for (let i of s.values()) t[i] = i;
                    for (let t of e.values()) {
                        const [o, s] = t.split(",");
                        i.push({
                            p: o,
                            q: s
                        });
                    }
                    const find = i => {
                        let o = i;
                        for (;i != t[i]; ) i = t[i];
                        for (;o != t[o]; ) {
                            let s = o;
                            o = t[o], t[s] = i;
                        }
                        return i;
                    }, union = (i, o) => {
                        const s = find(i);
                        find(o), t[i] = t[o] = s;
                    };
                    for (let o of i) {
                        const {p: i, q: s} = o;
                        if (t[i] == t[s]) return !0;
                        union(i, s);
                    }
                    return !1;
                })();
            }
            let h = new Set, a = new Set;
            for (let t of s.values()) {
                const [i, s] = t.split("_");
                o[+i][+s].locked ? a.add(t) : h.add(t);
            }
            for (let t of a) {
                const [i, s] = t.split("_"), e = +i, n = +s, {status: {up: r, down: a, left: l, right: c}} = o[e][n], u = this.topPosition({
                    x: e,
                    y: n
                }), f = this.bottomPosition({
                    x: e,
                    y: n
                }), p = this.leftPosition({
                    x: e,
                    y: n
                }), d = this.rightPosition({
                    x: e,
                    y: n
                });
                r && !o[u.x][u.y].locked && h.add(formatPoint(u)), a && !o[f.x][f.y].locked && h.add(formatPoint(f)), 
                l && !o[p.x][p.y].locked && h.add(formatPoint(p)), c && !o[d.x][d.y].locked && h.add(formatPoint(d));
            }
            return {
                lockedPoints: a,
                edges: e,
                hasLoop: r,
                exportPoints: h
            };
        }, this.graph = t, this.isCrossMap = i, this.floorEntry = {
            x: Math.floor(t.length / 2),
            y: Math.floor(t[0].length / 2)
        };
    }
    appendToUpdateQueue(t, i, o) {
        for (let {x: s, y: e} of o) {
            const o = `${s},${e}`;
            i.has(o) || (this.isSolvedPosition(t, this.clonePosition({
                x: s,
                y: e
            })) || i.add(o));
        }
        return !0;
    }
    clearUpdateQueue(t, i) {
        try {
            for (;i.size > 0; ) {
                const o = [ ...i.keys() ][0];
                i.delete(o);
                const [s, e] = o.split(",").map((t => +t));
                if (!this.updatePoint(t, i, this.clonePosition({
                    x: s,
                    y: e
                }))) return !1;
            }
        } catch (t) {
            return !1;
        }
        return !0;
    }
    aroundTRBL(t, i = (() => !0)) {
        let o = [ void 0, void 0, void 0, void 0 ];
        const s = this.topPosition(t);
        i(this.clonePosition(s)) && (o[0] = s);
        const e = this.rightPosition(t);
        i(this.clonePosition(e)) && (o[1] = e);
        const n = this.bottomPosition(t);
        i(this.clonePosition(n)) && (o[2] = n);
        const r = this.leftPosition(t);
        return i(this.clonePosition(r)) && (o[3] = r), o;
    }
    verificate(t) {
        const i = this.generateSet(t, {
            x: 0,
            y: 0
        });
        if (i.lockedPoints.size !== this.graph.length * this.graph[0].length) return !1;
        if (i.hasLoop) return !1;
        for (let i of this.graph.keys()) for (let o of this.graph[0].keys()) {
            const {blockState: s} = t, e = s[i][o].status, n = this.rightPosition({
                x: i,
                y: o
            }), r = s[n.x][n.y].status, h = this.bottomPosition({
                x: i,
                y: o
            }), a = s[h.x][h.y].status;
            if (e.right !== r.left || e.down !== a.up) return !1;
        }
        return !0;
    }
}

(() => {
    const t = `\n\n        ${Pipe.toString()} \n        onmessage=${(t => {
        const {tasks: i, isCrossMap: o} = JSON.parse(t.data), s = new Pipe(i, o).solve();
        postMessage(s);
    }).toString()}\n    `, i = [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ].includes(Game.plSize), o = task, s = Game.task;
    console.info("task", o, s);
    const e = new Date;
    !function registerWorkerWithBlob(t) {
        const {scriptStr: i, postMessageStr: o, onMessage: s} = t, e = new Blob([ i ], {
            type: "text/javascript"
        }), n = URL.createObjectURL(e), r = new Worker(n);
        r.onmessage = s, r.postMessage(o);
    }({
        scriptStr: t,
        postMessageStr: JSON.stringify({
            tasks: s,
            isCrossMap: i
        }),
        onMessage: t => {
            const i = new Date, o = t.data;
            console.info("answer", o), console.info("耗时", i.valueOf() - e.valueOf(), "ms"), 
            function replaceAnswer(t) {
                document && $ && ($("#puzzleForm").attr("onsubmit", `console.log('customer onsubmit');\n        Game.saveState();\n        Game.tickTimer();\n        this.jstimerPersonal.value = Game.getTimer();\n        this.ansH.value = '${t}';`), 
                $("#btnReady").off("click"), window.useRobot && $("#robot").attr("value", "1"));
            }(o), window.submit = submitAnswer, window.useRobot && submitAnswer();
        }
    });
})()