{"version":3,"file":"polygon-clipping.umd.min.js","sources":["../src/bbox.js","../src/flp.js","../src/rounder.js","../node_modules/robust-predicates/esm/util.js","../node_modules/robust-predicates/esm/orient2d.js","../src/vector.js","../src/sweep-event.js","../src/segment.js","../src/geom-in.js","../src/geom-out.js","../src/sweep-line.js","../src/operation.js","../src/index.js"],"sourcesContent":["/**\n * A bounding box has the format:\n *\n * { ll: { x: xmin, y: ymin }, ur: { x: xmax, y: ymax } }\n *\n */\n\nexport const isInBbox = (bbox, point) => {\n return (\n bbox.ll.x <= point.x &&\n point.x <= bbox.ur.x &&\n bbox.ll.y <= point.y &&\n point.y <= bbox.ur.y\n )\n}\n\n/* Returns either null, or a bbox (aka an ordered pair of points)\n * If there is only one point of overlap, a bbox with identical points\n * will be returned */\nexport const getBboxOverlap = (b1, b2) => {\n // check if the bboxes overlap at all\n if (\n b2.ur.x < b1.ll.x ||\n b1.ur.x < b2.ll.x ||\n b2.ur.y < b1.ll.y ||\n b1.ur.y < b2.ll.y\n )\n return null\n\n // find the middle two X values\n const lowerX = b1.ll.x < b2.ll.x ? b2.ll.x : b1.ll.x\n const upperX = b1.ur.x < b2.ur.x ? b1.ur.x : b2.ur.x\n\n // find the middle two Y values\n const lowerY = b1.ll.y < b2.ll.y ? b2.ll.y : b1.ll.y\n const upperY = b1.ur.y < b2.ur.y ? b1.ur.y : b2.ur.y\n\n // put those middle values together to get the overlap\n return { ll: { x: lowerX, y: lowerY }, ur: { x: upperX, y: upperY } }\n}\n","/* Javascript doesn't do integer math. Everything is\n * floating point with percision Number.EPSILON.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON\n */\n\nlet epsilon = Number.EPSILON\n\n// IE Polyfill\nif (epsilon === undefined) epsilon = Math.pow(2, -52)\n\nconst EPSILON_SQ = epsilon * epsilon\n\n/* FLP comparator */\nexport const cmp = (a, b) => {\n // check if they're both 0\n if (-epsilon < a && a < epsilon) {\n if (-epsilon < b && b < epsilon) {\n return 0\n }\n }\n\n // check if they're flp equal\n const ab = a - b\n if (ab * ab < EPSILON_SQ * a * b) {\n return 0\n }\n\n // normal comparison\n return a < b ? -1 : 1\n}\n","import { cmp } from \"./flp\"\nimport SplayTree from \"splaytree\"\n\n/**\n * This class rounds incoming values sufficiently so that\n * floating points problems are, for the most part, avoided.\n *\n * Incoming points are have their x & y values tested against\n * all previously seen x & y values. If either is 'too close'\n * to a previously seen value, it's value is 'snapped' to the\n * previously seen value.\n *\n * All points should be rounded by this class before being\n * stored in any data structures in the rest of this algorithm.\n */\n\nclass PtRounder {\n constructor() {\n this.reset()\n }\n\n reset() {\n this.xRounder = new CoordRounder()\n this.yRounder = new CoordRounder()\n }\n\n round(x, y) {\n return {\n x: this.xRounder.round(x),\n y: this.yRounder.round(y),\n }\n }\n}\n\nclass CoordRounder {\n constructor() {\n this.tree = new SplayTree()\n // preseed with 0 so we don't end up with values < Number.EPSILON\n this.round(0)\n }\n\n // Note: this can rounds input values backwards or forwards.\n // You might ask, why not restrict this to just rounding\n // forwards? Wouldn't that allow left endpoints to always\n // remain left endpoints during splitting (never change to\n // right). No - it wouldn't, because we snap intersections\n // to endpoints (to establish independence from the segment\n // angle for t-intersections).\n round(coord) {\n const node = this.tree.add(coord)\n\n const prevNode = this.tree.prev(node)\n if (prevNode !== null && cmp(node.key, prevNode.key) === 0) {\n this.tree.remove(coord)\n return prevNode.key\n }\n\n const nextNode = this.tree.next(node)\n if (nextNode !== null && cmp(node.key, nextNode.key) === 0) {\n this.tree.remove(coord)\n return nextNode.key\n }\n\n return coord\n }\n}\n\n// singleton available by import\nconst rounder = new PtRounder()\n\nexport default rounder\n","export const epsilon = 1.1102230246251565e-16;\nexport const splitter = 134217729;\nexport const resulterrbound = (3 + 8 * epsilon) * epsilon;\n\n// fast_expansion_sum_zeroelim routine from oritinal code\nexport function sum(elen, e, flen, f, h) {\n let Q, Qnew, hh, bvirt;\n let enow = e[0];\n let fnow = f[0];\n let eindex = 0;\n let findex = 0;\n if ((fnow > enow) === (fnow > -enow)) {\n Q = enow;\n enow = e[++eindex];\n } else {\n Q = fnow;\n fnow = f[++findex];\n }\n let hindex = 0;\n if (eindex < elen && findex < flen) {\n if ((fnow > enow) === (fnow > -enow)) {\n Qnew = enow + Q;\n hh = Q - (Qnew - enow);\n enow = e[++eindex];\n } else {\n Qnew = fnow + Q;\n hh = Q - (Qnew - fnow);\n fnow = f[++findex];\n }\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n while (eindex < elen && findex < flen) {\n if ((fnow > enow) === (fnow > -enow)) {\n Qnew = Q + enow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (enow - bvirt);\n enow = e[++eindex];\n } else {\n Qnew = Q + fnow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (fnow - bvirt);\n fnow = f[++findex];\n }\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n }\n while (eindex < elen) {\n Qnew = Q + enow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (enow - bvirt);\n enow = e[++eindex];\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n while (findex < flen) {\n Qnew = Q + fnow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (fnow - bvirt);\n fnow = f[++findex];\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n if (Q !== 0 || hindex === 0) {\n h[hindex++] = Q;\n }\n return hindex;\n}\n\nexport function sum_three(alen, a, blen, b, clen, c, tmp, out) {\n return sum(sum(alen, a, blen, b, tmp), tmp, clen, c, out);\n}\n\n// scale_expansion_zeroelim routine from oritinal code\nexport function scale(elen, e, b, h) {\n let Q, sum, hh, product1, product0;\n let bvirt, c, ahi, alo, bhi, blo;\n\n c = splitter * b;\n bhi = c - (c - b);\n blo = b - bhi;\n let enow = e[0];\n Q = enow * b;\n c = splitter * enow;\n ahi = c - (c - enow);\n alo = enow - ahi;\n hh = alo * blo - (Q - ahi * bhi - alo * bhi - ahi * blo);\n let hindex = 0;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n for (let i = 1; i < elen; i++) {\n enow = e[i];\n product1 = enow * b;\n c = splitter * enow;\n ahi = c - (c - enow);\n alo = enow - ahi;\n product0 = alo * blo - (product1 - ahi * bhi - alo * bhi - ahi * blo);\n sum = Q + product0;\n bvirt = sum - Q;\n hh = Q - (sum - bvirt) + (product0 - bvirt);\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n Q = product1 + sum;\n hh = sum - (Q - product1);\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n if (Q !== 0 || hindex === 0) {\n h[hindex++] = Q;\n }\n return hindex;\n}\n\nexport function negate(elen, e) {\n for (let i = 0; i < elen; i++) e[i] = -e[i];\n return elen;\n}\n\nexport function estimate(elen, e) {\n let Q = e[0];\n for (let i = 1; i < elen; i++) Q += e[i];\n return Q;\n}\n\nexport function vec(n) {\n return new Float64Array(n);\n}\n","import {epsilon, splitter, resulterrbound, estimate, vec, sum} from './util.js';\n\nconst ccwerrboundA = (3 + 16 * epsilon) * epsilon;\nconst ccwerrboundB = (2 + 12 * epsilon) * epsilon;\nconst ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;\n\nconst B = vec(4);\nconst C1 = vec(8);\nconst C2 = vec(12);\nconst D = vec(16);\nconst u = vec(4);\n\nfunction orient2dadapt(ax, ay, bx, by, cx, cy, detsum) {\n let acxtail, acytail, bcxtail, bcytail;\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3;\n\n const acx = ax - cx;\n const bcx = bx - cx;\n const acy = ay - cy;\n const bcy = by - cy;\n\n s1 = acx * bcy;\n c = splitter * acx;\n ahi = c - (c - acx);\n alo = acx - ahi;\n c = splitter * bcy;\n bhi = c - (c - bcy);\n blo = bcy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acy * bcx;\n c = splitter * acy;\n ahi = c - (c - acy);\n alo = acy - ahi;\n c = splitter * bcx;\n bhi = c - (c - bcx);\n blo = bcx - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n B[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n B[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n B[2] = _j - (u3 - bvirt) + (_i - bvirt);\n B[3] = u3;\n\n let det = estimate(4, B);\n let errbound = ccwerrboundB * detsum;\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n bvirt = ax - acx;\n acxtail = ax - (acx + bvirt) + (bvirt - cx);\n bvirt = bx - bcx;\n bcxtail = bx - (bcx + bvirt) + (bvirt - cx);\n bvirt = ay - acy;\n acytail = ay - (acy + bvirt) + (bvirt - cy);\n bvirt = by - bcy;\n bcytail = by - (bcy + bvirt) + (bvirt - cy);\n\n if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {\n return det;\n }\n\n errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);\n det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);\n if (det >= errbound || -det >= errbound) return det;\n\n s1 = acxtail * bcy;\n c = splitter * acxtail;\n ahi = c - (c - acxtail);\n alo = acxtail - ahi;\n c = splitter * bcy;\n bhi = c - (c - bcy);\n blo = bcy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acytail * bcx;\n c = splitter * acytail;\n ahi = c - (c - acytail);\n alo = acytail - ahi;\n c = splitter * bcx;\n bhi = c - (c - bcx);\n blo = bcx - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n u[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n u[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n const C1len = sum(4, B, 4, u, C1);\n\n s1 = acx * bcytail;\n c = splitter * acx;\n ahi = c - (c - acx);\n alo = acx - ahi;\n c = splitter * bcytail;\n bhi = c - (c - bcytail);\n blo = bcytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acy * bcxtail;\n c = splitter * acy;\n ahi = c - (c - acy);\n alo = acy - ahi;\n c = splitter * bcxtail;\n bhi = c - (c - bcxtail);\n blo = bcxtail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n u[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n u[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n const C2len = sum(C1len, C1, 4, u, C2);\n\n s1 = acxtail * bcytail;\n c = splitter * acxtail;\n ahi = c - (c - acxtail);\n alo = acxtail - ahi;\n c = splitter * bcytail;\n bhi = c - (c - bcytail);\n blo = bcytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acytail * bcxtail;\n c = splitter * acytail;\n ahi = c - (c - acytail);\n alo = acytail - ahi;\n c = splitter * bcxtail;\n bhi = c - (c - bcxtail);\n blo = bcxtail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n u[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n u[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n const Dlen = sum(C2len, C2, 4, u, D);\n\n return D[Dlen - 1];\n}\n\nexport function orient2d(ax, ay, bx, by, cx, cy) {\n const detleft = (ay - cy) * (bx - cx);\n const detright = (ax - cx) * (by - cy);\n const det = detleft - detright;\n\n const detsum = Math.abs(detleft + detright);\n if (Math.abs(det) >= ccwerrboundA * detsum) return det;\n\n return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum);\n}\n\nexport function orient2dfast(ax, ay, bx, by, cx, cy) {\n return (ay - cy) * (bx - cx) - (ax - cx) * (by - cy);\n}\n","import { orient2d } from \"robust-predicates\"\n\n/* Cross Product of two vectors with first point at origin */\nexport const crossProduct = (a, b) => a.x * b.y - a.y * b.x\n\n/* Dot Product of two vectors with first point at origin */\nexport const dotProduct = (a, b) => a.x * b.x + a.y * b.y\n\n/* Comparator for two vectors with same starting point */\nexport const compareVectorAngles = (basePt, endPt1, endPt2) => {\n const res = orient2d(\n basePt.x,\n basePt.y,\n endPt1.x,\n endPt1.y,\n endPt2.x,\n endPt2.y,\n )\n if (res > 0) return -1\n if (res < 0) return 1\n return 0\n}\n\nexport const length = (v) => Math.sqrt(dotProduct(v, v))\n\n/* Get the sine of the angle from pShared -> pAngle to pShaed -> pBase */\nexport const sineOfAngle = (pShared, pBase, pAngle) => {\n const vBase = { x: pBase.x - pShared.x, y: pBase.y - pShared.y }\n const vAngle = { x: pAngle.x - pShared.x, y: pAngle.y - pShared.y }\n return crossProduct(vAngle, vBase) / length(vAngle) / length(vBase)\n}\n\n/* Get the cosine of the angle from pShared -> pAngle to pShaed -> pBase */\nexport const cosineOfAngle = (pShared, pBase, pAngle) => {\n const vBase = { x: pBase.x - pShared.x, y: pBase.y - pShared.y }\n const vAngle = { x: pAngle.x - pShared.x, y: pAngle.y - pShared.y }\n return dotProduct(vAngle, vBase) / length(vAngle) / length(vBase)\n}\n\n/* Get the closest point on an line (defined by two points)\n * to another point. */\nexport const closestPoint = (ptA1, ptA2, ptB) => {\n if (ptA1.x === ptA2.x) return { x: ptA1.x, y: ptB.y } // vertical vector\n if (ptA1.y === ptA2.y) return { x: ptB.x, y: ptA1.y } // horizontal vector\n\n // determinne which point is further away\n // we use the further point as our base in the calculation, so that the\n // vectors are more parallel, providing more accurate dot product\n const v1 = { x: ptB.x - ptA1.x, y: ptB.y - ptA1.y }\n const v2 = { x: ptB.x - ptA2.x, y: ptB.y - ptA2.y }\n let vFar, vA, farPt\n if (dotProduct(v1, v1) > dotProduct(v2, v2)) {\n vFar = v1\n vA = { x: ptA2.x - ptA1.x, y: ptA2.y - ptA1.y }\n farPt = ptA1\n } else {\n vFar = v2\n vA = { x: ptA1.x - ptA2.x, y: ptA1.y - ptA2.y }\n farPt = ptA2\n }\n\n // manually test if the current point can be considered to be on the line\n // If the X coordinate was on the line, would the Y coordinate be as well?\n const xDist = (ptB.x - farPt.x) / vA.x\n if (ptB.y === farPt.y + xDist * vA.y) return ptB\n\n // If the Y coordinate was on the line, would the X coordinate be as well?\n const yDist = (ptB.y - farPt.y) / vA.y\n if (ptB.x === farPt.x + yDist * vA.x) return ptB\n\n // current point isn't exactly on line, so return closest point\n const dist = dotProduct(vA, vFar) / dotProduct(vA, vA)\n return { x: farPt.x + dist * vA.x, y: farPt.y + dist * vA.y }\n}\n\n/* Get the x coordinate where the given line (defined by a point and vector)\n * crosses the horizontal line with the given y coordiante.\n * In the case of parrallel lines (including overlapping ones) returns null. */\nexport const horizontalIntersection = (pt, v, y) => {\n if (v.y === 0) return null\n return { x: pt.x + (v.x / v.y) * (y - pt.y), y: y }\n}\n\n/* Get the y coordinate where the given line (defined by a point and vector)\n * crosses the vertical line with the given x coordiante.\n * In the case of parrallel lines (including overlapping ones) returns null. */\nexport const verticalIntersection = (pt, v, x) => {\n if (v.x === 0) return null\n return { x: x, y: pt.y + (v.y / v.x) * (x - pt.x) }\n}\n\n/* Get the intersection of two lines, each defined by a base point and a vector.\n * In the case of parrallel lines (including overlapping ones) returns null. */\nexport const intersection = (pt1, v1, pt2, v2) => {\n // take some shortcuts for vertical and horizontal lines\n // this also ensures we don't calculate an intersection and then discover\n // it's actually outside the bounding box of the line\n if (v1.x === 0) return verticalIntersection(pt2, v2, pt1.x)\n if (v2.x === 0) return verticalIntersection(pt1, v1, pt2.x)\n if (v1.y === 0) return horizontalIntersection(pt2, v2, pt1.y)\n if (v2.y === 0) return horizontalIntersection(pt1, v1, pt2.y)\n\n // General case for non-overlapping segments.\n // This algorithm is based on Schneider and Eberly.\n // http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf - pg 244\n\n const kross = crossProduct(v1, v2)\n if (kross == 0) return null\n\n const ve = { x: pt2.x - pt1.x, y: pt2.y - pt1.y }\n const d1 = crossProduct(ve, v1) / kross\n const d2 = crossProduct(ve, v2) / kross\n\n // take the average of the two calculations to minimize rounding error\n const x1 = pt1.x + d2 * v1.x,\n x2 = pt2.x + d1 * v2.x\n const y1 = pt1.y + d2 * v1.y,\n y2 = pt2.y + d1 * v2.y\n const x = (x1 + x2) / 2\n const y = (y1 + y2) / 2\n return { x: x, y: y }\n}\n\n/* Given a vector, return one that is perpendicular */\nexport const perpendicular = (v) => {\n return { x: -v.y, y: v.x }\n}\n","import Segment from \"./segment\"\nimport { cosineOfAngle, sineOfAngle } from \"./vector\"\n\nexport default class SweepEvent {\n // for ordering sweep events in the sweep event queue\n static compare(a, b) {\n // favor event with a point that the sweep line hits first\n const ptCmp = SweepEvent.comparePoints(a.point, b.point)\n if (ptCmp !== 0) return ptCmp\n\n // the points are the same, so link them if needed\n if (a.point !== b.point) a.link(b)\n\n // favor right events over left\n if (a.isLeft !== b.isLeft) return a.isLeft ? 1 : -1\n\n // we have two matching left or right endpoints\n // ordering of this case is the same as for their segments\n return Segment.compare(a.segment, b.segment)\n }\n\n // for ordering points in sweep line order\n static comparePoints(aPt, bPt) {\n if (aPt.x < bPt.x) return -1\n if (aPt.x > bPt.x) return 1\n\n if (aPt.y < bPt.y) return -1\n if (aPt.y > bPt.y) return 1\n\n return 0\n }\n\n // Warning: 'point' input will be modified and re-used (for performance)\n constructor(point, isLeft) {\n if (point.events === undefined) point.events = [this]\n else point.events.push(this)\n this.point = point\n this.isLeft = isLeft\n // this.segment, this.otherSE set by factory\n }\n\n link(other) {\n if (other.point === this.point) {\n throw new Error(\"Tried to link already linked events\")\n }\n const otherEvents = other.point.events\n for (let i = 0, iMax = otherEvents.length; i < iMax; i++) {\n const evt = otherEvents[i]\n this.point.events.push(evt)\n evt.point = this.point\n }\n this.checkForConsuming()\n }\n\n /* Do a pass over our linked events and check to see if any pair\n * of segments match, and should be consumed. */\n checkForConsuming() {\n // FIXME: The loops in this method run O(n^2) => no good.\n // Maintain little ordered sweep event trees?\n // Can we maintaining an ordering that avoids the need\n // for the re-sorting with getLeftmostComparator in geom-out?\n\n // Compare each pair of events to see if other events also match\n const numEvents = this.point.events.length\n for (let i = 0; i < numEvents; i++) {\n const evt1 = this.point.events[i]\n if (evt1.segment.consumedBy !== undefined) continue\n for (let j = i + 1; j < numEvents; j++) {\n const evt2 = this.point.events[j]\n if (evt2.consumedBy !== undefined) continue\n if (evt1.otherSE.point.events !== evt2.otherSE.point.events) continue\n evt1.segment.consume(evt2.segment)\n }\n }\n }\n\n getAvailableLinkedEvents() {\n // point.events is always of length 2 or greater\n const events = []\n for (let i = 0, iMax = this.point.events.length; i < iMax; i++) {\n const evt = this.point.events[i]\n if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult()) {\n events.push(evt)\n }\n }\n return events\n }\n\n /**\n * Returns a comparator function for sorting linked events that will\n * favor the event that will give us the smallest left-side angle.\n * All ring construction starts as low as possible heading to the right,\n * so by always turning left as sharp as possible we'll get polygons\n * without uncessary loops & holes.\n *\n * The comparator function has a compute cache such that it avoids\n * re-computing already-computed values.\n */\n getLeftmostComparator(baseEvent) {\n const cache = new Map()\n\n const fillCache = (linkedEvent) => {\n const nextEvent = linkedEvent.otherSE\n cache.set(linkedEvent, {\n sine: sineOfAngle(this.point, baseEvent.point, nextEvent.point),\n cosine: cosineOfAngle(this.point, baseEvent.point, nextEvent.point),\n })\n }\n\n return (a, b) => {\n if (!cache.has(a)) fillCache(a)\n if (!cache.has(b)) fillCache(b)\n\n const { sine: asine, cosine: acosine } = cache.get(a)\n const { sine: bsine, cosine: bcosine } = cache.get(b)\n\n // both on or above x-axis\n if (asine >= 0 && bsine >= 0) {\n if (acosine < bcosine) return 1\n if (acosine > bcosine) return -1\n return 0\n }\n\n // both below x-axis\n if (asine < 0 && bsine < 0) {\n if (acosine < bcosine) return -1\n if (acosine > bcosine) return 1\n return 0\n }\n\n // one above x-axis, one below\n if (bsine < asine) return -1\n if (bsine > asine) return 1\n return 0\n }\n }\n}\n","import operation from \"./operation\"\nimport SweepEvent from \"./sweep-event\"\nimport { isInBbox, getBboxOverlap } from \"./bbox\"\nimport { intersection } from \"./vector\"\nimport rounder from \"./rounder\"\n\n// Give segments unique ID's to get consistent sorting of\n// segments and sweep events when all else is identical\nlet segmentId = 0\n\nexport default class Segment {\n /* This compare() function is for ordering segments in the sweep\n * line tree, and does so according to the following criteria:\n *\n * Consider the vertical line that lies an infinestimal step to the\n * right of the right-more of the two left endpoints of the input\n * segments. Imagine slowly moving a point up from negative infinity\n * in the increasing y direction. Which of the two segments will that\n * point intersect first? That segment comes 'before' the other one.\n *\n * If neither segment would be intersected by such a line, (if one\n * or more of the segments are vertical) then the line to be considered\n * is directly on the right-more of the two left inputs.\n */\n static compare(a, b) {\n const alx = a.leftSE.point.x\n const blx = b.leftSE.point.x\n const arx = a.rightSE.point.x\n const brx = b.rightSE.point.x\n\n // check if they're even in the same vertical plane\n if (brx < alx) return 1\n if (arx < blx) return -1\n\n const aly = a.leftSE.point.y\n const bly = b.leftSE.point.y\n const ary = a.rightSE.point.y\n const bry = b.rightSE.point.y\n\n // is left endpoint of segment B the right-more?\n if (alx < blx) {\n // are the two segments in the same horizontal plane?\n if (bly < aly && bly < ary) return 1\n if (bly > aly && bly > ary) return -1\n\n // is the B left endpoint colinear to segment A?\n const aCmpBLeft = a.comparePoint(b.leftSE.point)\n if (aCmpBLeft < 0) return 1\n if (aCmpBLeft > 0) return -1\n\n // is the A right endpoint colinear to segment B ?\n const bCmpARight = b.comparePoint(a.rightSE.point)\n if (bCmpARight !== 0) return bCmpARight\n\n // colinear segments, consider the one with left-more\n // left endpoint to be first (arbitrary?)\n return -1\n }\n\n // is left endpoint of segment A the right-more?\n if (alx > blx) {\n if (aly < bly && aly < bry) return -1\n if (aly > bly && aly > bry) return 1\n\n // is the A left endpoint colinear to segment B?\n const bCmpALeft = b.comparePoint(a.leftSE.point)\n if (bCmpALeft !== 0) return bCmpALeft\n\n // is the B right endpoint colinear to segment A?\n const aCmpBRight = a.comparePoint(b.rightSE.point)\n if (aCmpBRight < 0) return 1\n if (aCmpBRight > 0) return -1\n\n // colinear segments, consider the one with left-more\n // left endpoint to be first (arbitrary?)\n return 1\n }\n\n // if we get here, the two left endpoints are in the same\n // vertical plane, ie alx === blx\n\n // consider the lower left-endpoint to come first\n if (aly < bly) return -1\n if (aly > bly) return 1\n\n // left endpoints are identical\n // check for colinearity by using the left-more right endpoint\n\n // is the A right endpoint more left-more?\n if (arx < brx) {\n const bCmpARight = b.comparePoint(a.rightSE.point)\n if (bCmpARight !== 0) return bCmpARight\n }\n\n // is the B right endpoint more left-more?\n if (arx > brx) {\n const aCmpBRight = a.comparePoint(b.rightSE.point)\n if (aCmpBRight < 0) return 1\n if (aCmpBRight > 0) return -1\n }\n\n if (arx !== brx) {\n // are these two [almost] vertical segments with opposite orientation?\n // if so, the one with the lower right endpoint comes first\n const ay = ary - aly\n const ax = arx - alx\n const by = bry - bly\n const bx = brx - blx\n if (ay > ax && by < bx) return 1\n if (ay < ax && by > bx) return -1\n }\n\n // we have colinear segments with matching orientation\n // consider the one with more left-more right endpoint to be first\n if (arx > brx) return 1\n if (arx < brx) return -1\n\n // if we get here, two two right endpoints are in the same\n // vertical plane, ie arx === brx\n\n // consider the lower right-endpoint to come first\n if (ary < bry) return -1\n if (ary > bry) return 1\n\n // right endpoints identical as well, so the segments are idential\n // fall back on creation order as consistent tie-breaker\n if (a.id < b.id) return -1\n if (a.id > b.id) return 1\n\n // identical segment, ie a === b\n return 0\n }\n\n /* Warning: a reference to ringWindings input will be stored,\n * and possibly will be later modified */\n constructor(leftSE, rightSE, rings, windings) {\n this.id = ++segmentId\n this.leftSE = leftSE\n leftSE.segment = this\n leftSE.otherSE = rightSE\n this.rightSE = rightSE\n rightSE.segment = this\n rightSE.otherSE = leftSE\n this.rings = rings\n this.windings = windings\n // left unset for performance, set later in algorithm\n // this.ringOut, this.consumedBy, this.prev\n }\n\n static fromRing(pt1, pt2, ring) {\n let leftPt, rightPt, winding\n\n // ordering the two points according to sweep line ordering\n const cmpPts = SweepEvent.comparePoints(pt1, pt2)\n if (cmpPts < 0) {\n leftPt = pt1\n rightPt = pt2\n winding = 1\n } else if (cmpPts > 0) {\n leftPt = pt2\n rightPt = pt1\n winding = -1\n } else\n throw new Error(\n `Tried to create degenerate segment at [${pt1.x}, ${pt1.y}]`,\n )\n\n const leftSE = new SweepEvent(leftPt, true)\n const rightSE = new SweepEvent(rightPt, false)\n return new Segment(leftSE, rightSE, [ring], [winding])\n }\n\n /* When a segment is split, the rightSE is replaced with a new sweep event */\n replaceRightSE(newRightSE) {\n this.rightSE = newRightSE\n this.rightSE.segment = this\n this.rightSE.otherSE = this.leftSE\n this.leftSE.otherSE = this.rightSE\n }\n\n bbox() {\n const y1 = this.leftSE.point.y\n const y2 = this.rightSE.point.y\n return {\n ll: { x: this.leftSE.point.x, y: y1 < y2 ? y1 : y2 },\n ur: { x: this.rightSE.point.x, y: y1 > y2 ? y1 : y2 },\n }\n }\n\n /* A vector from the left point to the right */\n vector() {\n return {\n x: this.rightSE.point.x - this.leftSE.point.x,\n y: this.rightSE.point.y - this.leftSE.point.y,\n }\n }\n\n isAnEndpoint(pt) {\n return (\n (pt.x === this.leftSE.point.x && pt.y === this.leftSE.point.y) ||\n (pt.x === this.rightSE.point.x && pt.y === this.rightSE.point.y)\n )\n }\n\n /* Compare this segment with a point.\n *\n * A point P is considered to be colinear to a segment if there\n * exists a distance D such that if we travel along the segment\n * from one * endpoint towards the other a distance D, we find\n * ourselves at point P.\n *\n * Return value indicates:\n *\n * 1: point lies above the segment (to the left of vertical)\n * 0: point is colinear to segment\n * -1: point lies below the segment (to the right of vertical)\n */\n comparePoint(point) {\n if (this.isAnEndpoint(point)) return 0\n\n const lPt = this.leftSE.point\n const rPt = this.rightSE.point\n const v = this.vector()\n\n // Exactly vertical segments.\n if (lPt.x === rPt.x) {\n if (point.x === lPt.x) return 0\n return point.x < lPt.x ? 1 : -1\n }\n\n // Nearly vertical segments with an intersection.\n // Check to see where a point on the line with matching Y coordinate is.\n const yDist = (point.y - lPt.y) / v.y\n const xFromYDist = lPt.x + yDist * v.x\n if (point.x === xFromYDist) return 0\n\n // General case.\n // Check to see where a point on the line with matching X coordinate is.\n const xDist = (point.x - lPt.x) / v.x\n const yFromXDist = lPt.y + xDist * v.y\n if (point.y === yFromXDist) return 0\n return point.y < yFromXDist ? -1 : 1\n }\n\n /**\n * Given another segment, returns the first non-trivial intersection\n * between the two segments (in terms of sweep line ordering), if it exists.\n *\n * A 'non-trivial' intersection is one that will cause one or both of the\n * segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection:\n *\n * * endpoint of segA with endpoint of segB --> trivial\n * * endpoint of segA with point along segB --> non-trivial\n * * endpoint of segB with point along segA --> non-trivial\n * * point along segA with point along segB --> non-trivial\n *\n * If no non-trivial intersection exists, return null\n * Else, return null.\n */\n getIntersection(other) {\n // If bboxes don't overlap, there can't be any intersections\n const tBbox = this.bbox()\n const oBbox = other.bbox()\n const bboxOverlap = getBboxOverlap(tBbox, oBbox)\n if (bboxOverlap === null) return null\n\n // We first check to see if the endpoints can be considered intersections.\n // This will 'snap' intersections to endpoints if possible, and will\n // handle cases of colinearity.\n\n const tlp = this.leftSE.point\n const trp = this.rightSE.point\n const olp = other.leftSE.point\n const orp = other.rightSE.point\n\n // does each endpoint touch the other segment?\n // note that we restrict the 'touching' definition to only allow segments\n // to touch endpoints that lie forward from where we are in the sweep line pass\n const touchesOtherLSE = isInBbox(tBbox, olp) && this.comparePoint(olp) === 0\n const touchesThisLSE = isInBbox(oBbox, tlp) && other.comparePoint(tlp) === 0\n const touchesOtherRSE = isInBbox(tBbox, orp) && this.comparePoint(orp) === 0\n const touchesThisRSE = isInBbox(oBbox, trp) && other.comparePoint(trp) === 0\n\n // do left endpoints match?\n if (touchesThisLSE && touchesOtherLSE) {\n // these two cases are for colinear segments with matching left\n // endpoints, and one segment being longer than the other\n if (touchesThisRSE && !touchesOtherRSE) return trp\n if (!touchesThisRSE && touchesOtherRSE) return orp\n // either the two segments match exactly (two trival intersections)\n // or just on their left endpoint (one trivial intersection\n return null\n }\n\n // does this left endpoint matches (other doesn't)\n if (touchesThisLSE) {\n // check for segments that just intersect on opposing endpoints\n if (touchesOtherRSE) {\n if (tlp.x === orp.x && tlp.y === orp.y) return null\n }\n // t-intersection on left endpoint\n return tlp\n }\n\n // does other left endpoint matches (this doesn't)\n if (touchesOtherLSE) {\n // check for segments that just intersect on opposing endpoints\n if (touchesThisRSE) {\n if (trp.x === olp.x && trp.y === olp.y) return null\n }\n // t-intersection on left endpoint\n return olp\n }\n\n // trivial intersection on right endpoints\n if (touchesThisRSE && touchesOtherRSE) return null\n\n // t-intersections on just one right endpoint\n if (touchesThisRSE) return trp\n if (touchesOtherRSE) return orp\n\n // None of our endpoints intersect. Look for a general intersection between\n // infinite lines laid over the segments\n const pt = intersection(tlp, this.vector(), olp, other.vector())\n\n // are the segments parrallel? Note that if they were colinear with overlap,\n // they would have an endpoint intersection and that case was already handled above\n if (pt === null) return null\n\n // is the intersection found between the lines not on the segments?\n if (!isInBbox(bboxOverlap, pt)) return null\n\n // round the the computed point if needed\n return rounder.round(pt.x, pt.y)\n }\n\n /**\n * Split the given segment into multiple segments on the given points.\n * * Each existing segment will retain its leftSE and a new rightSE will be\n * generated for it.\n * * A new segment will be generated which will adopt the original segment's\n * rightSE, and a new leftSE will be generated for it.\n * * If there are more than two points given to split on, new segments\n * in the middle will be generated with new leftSE and rightSE's.\n * * An array of the newly generated SweepEvents will be returned.\n *\n * Warning: input array of points is modified\n */\n split(point) {\n const newEvents = []\n const alreadyLinked = point.events !== undefined\n\n const newLeftSE = new SweepEvent(point, true)\n const newRightSE = new SweepEvent(point, false)\n const oldRightSE = this.rightSE\n this.replaceRightSE(newRightSE)\n newEvents.push(newRightSE)\n newEvents.push(newLeftSE)\n const newSeg = new Segment(\n newLeftSE,\n oldRightSE,\n this.rings.slice(),\n this.windings.slice(),\n )\n\n // when splitting a nearly vertical downward-facing segment,\n // sometimes one of the resulting new segments is vertical, in which\n // case its left and right events may need to be swapped\n if (\n SweepEvent.comparePoints(newSeg.leftSE.point, newSeg.rightSE.point) > 0\n ) {\n newSeg.swapEvents()\n }\n if (SweepEvent.comparePoints(this.leftSE.point, this.rightSE.point) > 0) {\n this.swapEvents()\n }\n\n // in the point we just used to create new sweep events with was already\n // linked to other events, we need to check if either of the affected\n // segments should be consumed\n if (alreadyLinked) {\n newLeftSE.checkForConsuming()\n newRightSE.checkForConsuming()\n }\n\n return newEvents\n }\n\n /* Swap which event is left and right */\n swapEvents() {\n const tmpEvt = this.rightSE\n this.rightSE = this.leftSE\n this.leftSE = tmpEvt\n this.leftSE.isLeft = true\n this.rightSE.isLeft = false\n for (let i = 0, iMax = this.windings.length; i < iMax; i++) {\n this.windings[i] *= -1\n }\n }\n\n /* Consume another segment. We take their rings under our wing\n * and mark them as consumed. Use for perfectly overlapping segments */\n consume(other) {\n let consumer = this\n let consumee = other\n while (consumer.consumedBy) consumer = consumer.consumedBy\n while (consumee.consumedBy) consumee = consumee.consumedBy\n\n const cmp = Segment.compare(consumer, consumee)\n if (cmp === 0) return // already consumed\n // the winner of the consumption is the earlier segment\n // according to sweep line ordering\n if (cmp > 0) {\n const tmp = consumer\n consumer = consumee\n consumee = tmp\n }\n\n // make sure a segment doesn't consume it's prev\n if (consumer.prev === consumee) {\n const tmp = consumer\n consumer = consumee\n consumee = tmp\n }\n\n for (let i = 0, iMax = consumee.rings.length; i < iMax; i++) {\n const ring = consumee.rings[i]\n const winding = consumee.windings[i]\n const index = consumer.rings.indexOf(ring)\n if (index === -1) {\n consumer.rings.push(ring)\n consumer.windings.push(winding)\n } else consumer.windings[index] += winding\n }\n consumee.rings = null\n consumee.windings = null\n consumee.consumedBy = consumer\n\n // mark sweep events consumed as to maintain ordering in sweep event queue\n consumee.leftSE.consumedBy = consumer.leftSE\n consumee.rightSE.consumedBy = consumer.rightSE\n }\n\n /* The first segment previous segment chain that is in the result */\n prevInResult() {\n if (this._prevInResult !== undefined) return this._prevInResult\n if (!this.prev) this._prevInResult = null\n else if (this.prev.isInResult()) this._prevInResult = this.prev\n else this._prevInResult = this.prev.prevInResult()\n return this._prevInResult\n }\n\n beforeState() {\n if (this._beforeState !== undefined) return this._beforeState\n if (!this.prev)\n this._beforeState = {\n rings: [],\n windings: [],\n multiPolys: [],\n }\n else {\n const seg = this.prev.consumedBy || this.prev\n this._beforeState = seg.afterState()\n }\n return this._beforeState\n }\n\n afterState() {\n if (this._afterState !== undefined) return this._afterState\n\n const beforeState = this.beforeState()\n this._afterState = {\n rings: beforeState.rings.slice(0),\n windings: beforeState.windings.slice(0),\n multiPolys: [],\n }\n const ringsAfter = this._afterState.rings\n const windingsAfter = this._afterState.windings\n const mpsAfter = this._afterState.multiPolys\n\n // calculate ringsAfter, windingsAfter\n for (let i = 0, iMax = this.rings.length; i < iMax; i++) {\n const ring = this.rings[i]\n const winding = this.windings[i]\n const index = ringsAfter.indexOf(ring)\n if (index === -1) {\n ringsAfter.push(ring)\n windingsAfter.push(winding)\n } else windingsAfter[index] += winding\n }\n\n // calcualte polysAfter\n const polysAfter = []\n const polysExclude = []\n for (let i = 0, iMax = ringsAfter.length; i < iMax; i++) {\n if (windingsAfter[i] === 0) continue // non-zero rule\n const ring = ringsAfter[i]\n const poly = ring.poly\n if (polysExclude.indexOf(poly) !== -1) continue\n if (ring.isExterior) polysAfter.push(poly)\n else {\n if (polysExclude.indexOf(poly) === -1) polysExclude.push(poly)\n const index = polysAfter.indexOf(ring.poly)\n if (index !== -1) polysAfter.splice(index, 1)\n }\n }\n\n // calculate multiPolysAfter\n for (let i = 0, iMax = polysAfter.length; i < iMax; i++) {\n const mp = polysAfter[i].multiPoly\n if (mpsAfter.indexOf(mp) === -1) mpsAfter.push(mp)\n }\n\n return this._afterState\n }\n\n /* Is this segment part of the final result? */\n isInResult() {\n // if we've been consumed, we're not in the result\n if (this.consumedBy) return false\n\n if (this._isInResult !== undefined) return this._isInResult\n\n const mpsBefore = this.beforeState().multiPolys\n const mpsAfter = this.afterState().multiPolys\n\n switch (operation.type) {\n case \"union\": {\n // UNION - included iff:\n // * On one side of us there is 0 poly interiors AND\n // * On the other side there is 1 or more.\n const noBefores = mpsBefore.length === 0\n const noAfters = mpsAfter.length === 0\n this._isInResult = noBefores !== noAfters\n break\n }\n\n case \"intersection\": {\n // INTERSECTION - included iff:\n // * on one side of us all multipolys are rep. with poly interiors AND\n // * on the other side of us, not all multipolys are repsented\n // with poly interiors\n let least\n let most\n if (mpsBefore.length < mpsAfter.length) {\n least = mpsBefore.length\n most = mpsAfter.length\n } else {\n least = mpsAfter.length\n most = mpsBefore.length\n }\n this._isInResult = most === operation.numMultiPolys && least < most\n break\n }\n\n case \"xor\": {\n // XOR - included iff:\n // * the difference between the number of multipolys represented\n // with poly interiors on our two sides is an odd number\n const diff = Math.abs(mpsBefore.length - mpsAfter.length)\n this._isInResult = diff % 2 === 1\n break\n }\n\n case \"difference\": {\n // DIFFERENCE included iff:\n // * on exactly one side, we have just the subject\n const isJustSubject = (mps) => mps.length === 1 && mps[0].isSubject\n this._isInResult = isJustSubject(mpsBefore) !== isJustSubject(mpsAfter)\n break\n }\n\n default:\n throw new Error(`Unrecognized operation type found ${operation.type}`)\n }\n\n return this._isInResult\n }\n}\n","import rounder from \"./rounder\"\nimport Segment from \"./segment\"\n\nexport class RingIn {\n constructor(geomRing, poly, isExterior) {\n if (!Array.isArray(geomRing) || geomRing.length === 0) {\n throw new Error(\"Input geometry is not a valid Polygon or MultiPolygon\")\n }\n\n this.poly = poly\n this.isExterior = isExterior\n this.segments = []\n\n if (\n typeof geomRing[0][0] !== \"number\" ||\n typeof geomRing[0][1] !== \"number\"\n ) {\n throw new Error(\"Input geometry is not a valid Polygon or MultiPolygon\")\n }\n\n const firstPoint = rounder.round(geomRing[0][0], geomRing[0][1])\n this.bbox = {\n ll: { x: firstPoint.x, y: firstPoint.y },\n ur: { x: firstPoint.x, y: firstPoint.y },\n }\n\n let prevPoint = firstPoint\n for (let i = 1, iMax = geomRing.length; i < iMax; i++) {\n if (\n typeof geomRing[i][0] !== \"number\" ||\n typeof geomRing[i][1] !== \"number\"\n ) {\n throw new Error(\"Input geometry is not a valid Polygon or MultiPolygon\")\n }\n let point = rounder.round(geomRing[i][0], geomRing[i][1])\n // skip repeated points\n if (point.x === prevPoint.x && point.y === prevPoint.y) continue\n this.segments.push(Segment.fromRing(prevPoint, point, this))\n if (point.x < this.bbox.ll.x) this.bbox.ll.x = point.x\n if (point.y < this.bbox.ll.y) this.bbox.ll.y = point.y\n if (point.x > this.bbox.ur.x) this.bbox.ur.x = point.x\n if (point.y > this.bbox.ur.y) this.bbox.ur.y = point.y\n prevPoint = point\n }\n // add segment from last to first if last is not the same as first\n if (firstPoint.x !== prevPoint.x || firstPoint.y !== prevPoint.y) {\n this.segments.push(Segment.fromRing(prevPoint, firstPoint, this))\n }\n }\n\n getSweepEvents() {\n const sweepEvents = []\n for (let i = 0, iMax = this.segments.length; i < iMax; i++) {\n const segment = this.segments[i]\n sweepEvents.push(segment.leftSE)\n sweepEvents.push(segment.rightSE)\n }\n return sweepEvents\n }\n}\n\nexport class PolyIn {\n constructor(geomPoly, multiPoly) {\n if (!Array.isArray(geomPoly)) {\n throw new Error(\"Input geometry is not a valid Polygon or MultiPolygon\")\n }\n this.exteriorRing = new RingIn(geomPoly[0], this, true)\n // copy by value\n this.bbox = {\n ll: { x: this.exteriorRing.bbox.ll.x, y: this.exteriorRing.bbox.ll.y },\n ur: { x: this.exteriorRing.bbox.ur.x, y: this.exteriorRing.bbox.ur.y },\n }\n this.interiorRings = []\n for (let i = 1, iMax = geomPoly.length; i < iMax; i++) {\n const ring = new RingIn(geomPoly[i], this, false)\n if (ring.bbox.ll.x < this.bbox.ll.x) this.bbox.ll.x = ring.bbox.ll.x\n if (ring.bbox.ll.y < this.bbox.ll.y) this.bbox.ll.y = ring.bbox.ll.y\n if (ring.bbox.ur.x > this.bbox.ur.x) this.bbox.ur.x = ring.bbox.ur.x\n if (ring.bbox.ur.y > this.bbox.ur.y) this.bbox.ur.y = ring.bbox.ur.y\n this.interiorRings.push(ring)\n }\n this.multiPoly = multiPoly\n }\n\n getSweepEvents() {\n const sweepEvents = this.exteriorRing.getSweepEvents()\n for (let i = 0, iMax = this.interiorRings.length; i < iMax; i++) {\n const ringSweepEvents = this.interiorRings[i].getSweepEvents()\n for (let j = 0, jMax = ringSweepEvents.length; j < jMax; j++) {\n sweepEvents.push(ringSweepEvents[j])\n }\n }\n return sweepEvents\n }\n}\n\nexport class MultiPolyIn {\n constructor(geom, isSubject) {\n if (!Array.isArray(geom)) {\n throw new Error(\"Input geometry is not a valid Polygon or MultiPolygon\")\n }\n\n try {\n // if the input looks like a polygon, convert it to a multipolygon\n if (typeof geom[0][0][0] === \"number\") geom = [geom]\n } catch (ex) {\n // The input is either malformed or has empty arrays.\n // In either case, it will be handled later on.\n }\n\n this.polys = []\n this.bbox = {\n ll: { x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY },\n ur: { x: Number.NEGATIVE_INFINITY, y: Number.NEGATIVE_INFINITY },\n }\n for (let i = 0, iMax = geom.length; i < iMax; i++) {\n const poly = new PolyIn(geom[i], this)\n if (poly.bbox.ll.x < this.bbox.ll.x) this.bbox.ll.x = poly.bbox.ll.x\n if (poly.bbox.ll.y < this.bbox.ll.y) this.bbox.ll.y = poly.bbox.ll.y\n if (poly.bbox.ur.x > this.bbox.ur.x) this.bbox.ur.x = poly.bbox.ur.x\n if (poly.bbox.ur.y > this.bbox.ur.y) this.bbox.ur.y = poly.bbox.ur.y\n this.polys.push(poly)\n }\n this.isSubject = isSubject\n }\n\n getSweepEvents() {\n const sweepEvents = []\n for (let i = 0, iMax = this.polys.length; i < iMax; i++) {\n const polySweepEvents = this.polys[i].getSweepEvents()\n for (let j = 0, jMax = polySweepEvents.length; j < jMax; j++) {\n sweepEvents.push(polySweepEvents[j])\n }\n }\n return sweepEvents\n }\n}\n","import { compareVectorAngles } from \"./vector\"\nimport SweepEvent from \"./sweep-event\"\n\nexport class RingOut {\n /* Given the segments from the sweep line pass, compute & return a series\n * of closed rings from all the segments marked to be part of the result */\n static factory(allSegments) {\n const ringsOut = []\n\n for (let i = 0, iMax = allSegments.length; i < iMax; i++) {\n const segment = allSegments[i]\n if (!segment.isInResult() || segment.ringOut) continue\n\n let prevEvent = null\n let event = segment.leftSE\n let nextEvent = segment.rightSE\n const events = [event]\n\n const startingPoint = event.point\n const intersectionLEs = []\n\n /* Walk the chain of linked events to form a closed ring */\n while (true) {\n prevEvent = event\n event = nextEvent\n events.push(event)\n\n /* Is the ring complete? */\n if (event.point === startingPoint) break\n\n while (true) {\n const availableLEs = event.getAvailableLinkedEvents()\n\n /* Did we hit a dead end? This shouldn't happen.\n * Indicates some earlier part of the algorithm malfunctioned. */\n if (availableLEs.length === 0) {\n const firstPt = events[0].point\n const lastPt = events[events.length - 1].point\n throw new Error(\n `Unable to complete output ring starting at [${firstPt.x},` +\n ` ${firstPt.y}]. Last matching segment found ends at` +\n ` [${lastPt.x}, ${lastPt.y}].`,\n )\n }\n\n /* Only one way to go, so cotinue on the path */\n if (availableLEs.length === 1) {\n nextEvent = availableLEs[0].otherSE\n break\n }\n\n /* We must have an intersection. Check for a completed loop */\n let indexLE = null\n for (let j = 0, jMax = intersectionLEs.length; j < jMax; j++) {\n if (intersectionLEs[j].point === event.point) {\n indexLE = j\n break\n }\n }\n /* Found a completed loop. Cut that off and make a ring */\n if (indexLE !== null) {\n const intersectionLE = intersectionLEs.splice(indexLE)[0]\n const ringEvents = events.splice(intersectionLE.index)\n ringEvents.unshift(ringEvents[0].otherSE)\n ringsOut.push(new RingOut(ringEvents.reverse()))\n continue\n }\n /* register the intersection */\n intersectionLEs.push({\n index: events.length,\n point: event.point,\n })\n /* Choose the left-most option to continue the walk */\n const comparator = event.getLeftmostComparator(prevEvent)\n nextEvent = availableLEs.sort(comparator)[0].otherSE\n break\n }\n }\n\n ringsOut.push(new RingOut(events))\n }\n return ringsOut\n }\n\n constructor(events) {\n this.events = events\n for (let i = 0, iMax = events.length; i < iMax; i++) {\n events[i].segment.ringOut = this\n }\n this.poly = null\n }\n\n getGeom() {\n // Remove superfluous points (ie extra points along a straight line),\n let prevPt = this.events[0].point\n const points = [prevPt]\n for (let i = 1, iMax = this.events.length - 1; i < iMax; i++) {\n const pt = this.events[i].point\n const nextPt = this.events[i + 1].point\n if (compareVectorAngles(pt, prevPt, nextPt) === 0) continue\n points.push(pt)\n prevPt = pt\n }\n\n // ring was all (within rounding error of angle calc) colinear points\n if (points.length === 1) return null\n\n // check if the starting point is necessary\n const pt = points[0]\n const nextPt = points[1]\n if (compareVectorAngles(pt, prevPt, nextPt) === 0) points.shift()\n\n points.push(points[0])\n const step = this.isExteriorRing() ? 1 : -1\n const iStart = this.isExteriorRing() ? 0 : points.length - 1\n const iEnd = this.isExteriorRing() ? points.length : -1\n const orderedPoints = []\n for (let i = iStart; i != iEnd; i += step)\n orderedPoints.push([points[i].x, points[i].y])\n return orderedPoints\n }\n\n isExteriorRing() {\n if (this._isExteriorRing === undefined) {\n const enclosing = this.enclosingRing()\n this._isExteriorRing = enclosing ? !enclosing.isExteriorRing() : true\n }\n return this._isExteriorRing\n }\n\n enclosingRing() {\n if (this._enclosingRing === undefined) {\n this._enclosingRing = this._calcEnclosingRing()\n }\n return this._enclosingRing\n }\n\n /* Returns the ring that encloses this one, if any */\n _calcEnclosingRing() {\n // start with the ealier sweep line event so that the prevSeg\n // chain doesn't lead us inside of a loop of ours\n let leftMostEvt = this.events[0]\n for (let i = 1, iMax = this.events.length; i < iMax; i++) {\n const evt = this.events[i]\n if (SweepEvent.compare(leftMostEvt, evt) > 0) leftMostEvt = evt\n }\n\n let prevSeg = leftMostEvt.segment.prevInResult()\n let prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null\n\n while (true) {\n // no segment found, thus no ring can enclose us\n if (!prevSeg) return null\n\n // no segments below prev segment found, thus the ring of the prev\n // segment must loop back around and enclose us\n if (!prevPrevSeg) return prevSeg.ringOut\n\n // if the two segments are of different rings, the ring of the prev\n // segment must either loop around us or the ring of the prev prev\n // seg, which would make us and the ring of the prev peers\n if (prevPrevSeg.ringOut !== prevSeg.ringOut) {\n if (prevPrevSeg.ringOut.enclosingRing() !== prevSeg.ringOut) {\n return prevSeg.ringOut\n } else return prevSeg.ringOut.enclosingRing()\n }\n\n // two segments are from the same ring, so this was a penisula\n // of that ring. iterate downward, keep searching\n prevSeg = prevPrevSeg.prevInResult()\n prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null\n }\n }\n}\n\nexport class PolyOut {\n constructor(exteriorRing) {\n this.exteriorRing = exteriorRing\n exteriorRing.poly = this\n this.interiorRings = []\n }\n\n addInterior(ring) {\n this.interiorRings.push(ring)\n ring.poly = this\n }\n\n getGeom() {\n const geom = [this.exteriorRing.getGeom()]\n // exterior ring was all (within rounding error of angle calc) colinear points\n if (geom[0] === null) return null\n for (let i = 0, iMax = this.interiorRings.length; i < iMax; i++) {\n const ringGeom = this.interiorRings[i].getGeom()\n // interior ring was all (within rounding error of angle calc) colinear points\n if (ringGeom === null) continue\n geom.push(ringGeom)\n }\n return geom\n }\n}\n\nexport class MultiPolyOut {\n constructor(rings) {\n this.rings = rings\n this.polys = this._composePolys(rings)\n }\n\n getGeom() {\n const geom = []\n for (let i = 0, iMax = this.polys.length; i < iMax; i++) {\n const polyGeom = this.polys[i].getGeom()\n // exterior ring was all (within rounding error of angle calc) colinear points\n if (polyGeom === null) continue\n geom.push(polyGeom)\n }\n return geom\n }\n\n _composePolys(rings) {\n const polys = []\n for (let i = 0, iMax = rings.length; i < iMax; i++) {\n const ring = rings[i]\n if (ring.poly) continue\n if (ring.isExteriorRing()) polys.push(new PolyOut(ring))\n else {\n const enclosingRing = ring.enclosingRing()\n if (!enclosingRing.poly) polys.push(new PolyOut(enclosingRing))\n enclosingRing.poly.addInterior(ring)\n }\n }\n return polys\n }\n}\n","import SplayTree from \"splaytree\"\nimport Segment from \"./segment\"\nimport SweepEvent from \"./sweep-event\"\n\n/**\n * NOTE: We must be careful not to change any segments while\n * they are in the SplayTree. AFAIK, there's no way to tell\n * the tree to rebalance itself - thus before splitting\n * a segment that's in the tree, we remove it from the tree,\n * do the split, then re-insert it. (Even though splitting a\n * segment *shouldn't* change its correct position in the\n * sweep line tree, the reality is because of rounding errors,\n * it sometimes does.)\n */\n\nexport default class SweepLine {\n constructor(queue, comparator = Segment.compare) {\n this.queue = queue\n this.tree = new SplayTree(comparator)\n this.segments = []\n }\n\n process(event) {\n const segment = event.segment\n const newEvents = []\n\n // if we've already been consumed by another segment,\n // clean up our body parts and get out\n if (event.consumedBy) {\n if (event.isLeft) this.queue.remove(event.otherSE)\n else this.tree.remove(segment)\n return newEvents\n }\n\n const node = event.isLeft ? this.tree.add(segment) : this.tree.find(segment)\n\n if (!node)\n throw new Error(\n `Unable to find segment #${segment.id} ` +\n `[${segment.leftSE.point.x}, ${segment.leftSE.point.y}] -> ` +\n `[${segment.rightSE.point.x}, ${segment.rightSE.point.y}] ` +\n \"in SweepLine tree.\",\n )\n\n let prevNode = node\n let nextNode = node\n let prevSeg = undefined\n let nextSeg = undefined\n\n // skip consumed segments still in tree\n while (prevSeg === undefined) {\n prevNode = this.tree.prev(prevNode)\n if (prevNode === null) prevSeg = null\n else if (prevNode.key.consumedBy === undefined) prevSeg = prevNode.key\n }\n\n // skip consumed segments still in tree\n while (nextSeg === undefined) {\n nextNode = this.tree.next(nextNode)\n if (nextNode === null) nextSeg = null\n else if (nextNode.key.consumedBy === undefined) nextSeg = nextNode.key\n }\n\n if (event.isLeft) {\n // Check for intersections against the previous segment in the sweep line\n let prevMySplitter = null\n if (prevSeg) {\n const prevInter = prevSeg.getIntersection(segment)\n if (prevInter !== null) {\n if (!segment.isAnEndpoint(prevInter)) prevMySplitter = prevInter\n if (!prevSeg.isAnEndpoint(prevInter)) {\n const newEventsFromSplit = this._splitSafely(prevSeg, prevInter)\n for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {\n newEvents.push(newEventsFromSplit[i])\n }\n }\n }\n }\n\n // Check for intersections against the next segment in the sweep line\n let nextMySplitter = null\n if (nextSeg) {\n const nextInter = nextSeg.getIntersection(segment)\n if (nextInter !== null) {\n if (!segment.isAnEndpoint(nextInter)) nextMySplitter = nextInter\n if (!nextSeg.isAnEndpoint(nextInter)) {\n const newEventsFromSplit = this._splitSafely(nextSeg, nextInter)\n for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {\n newEvents.push(newEventsFromSplit[i])\n }\n }\n }\n }\n\n // For simplicity, even if we find more than one intersection we only\n // spilt on the 'earliest' (sweep-line style) of the intersections.\n // The other intersection will be handled in a future process().\n if (prevMySplitter !== null || nextMySplitter !== null) {\n let mySplitter = null\n if (prevMySplitter === null) mySplitter = nextMySplitter\n else if (nextMySplitter === null) mySplitter = prevMySplitter\n else {\n const cmpSplitters = SweepEvent.comparePoints(\n prevMySplitter,\n nextMySplitter,\n )\n mySplitter = cmpSplitters <= 0 ? prevMySplitter : nextMySplitter\n }\n\n // Rounding errors can cause changes in ordering,\n // so remove afected segments and right sweep events before splitting\n this.queue.remove(segment.rightSE)\n newEvents.push(segment.rightSE)\n\n const newEventsFromSplit = segment.split(mySplitter)\n for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {\n newEvents.push(newEventsFromSplit[i])\n }\n }\n\n if (newEvents.length > 0) {\n // We found some intersections, so re-do the current event to\n // make sure sweep line ordering is totally consistent for later\n // use with the segment 'prev' pointers\n this.tree.remove(segment)\n newEvents.push(event)\n } else {\n // done with left event\n this.segments.push(segment)\n segment.prev = prevSeg\n }\n } else {\n // event.isRight\n\n // since we're about to be removed from the sweep line, check for\n // intersections between our previous and next segments\n if (prevSeg && nextSeg) {\n const inter = prevSeg.getIntersection(nextSeg)\n if (inter !== null) {\n if (!prevSeg.isAnEndpoint(inter)) {\n const newEventsFromSplit = this._splitSafely(prevSeg, inter)\n for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {\n newEvents.push(newEventsFromSplit[i])\n }\n }\n if (!nextSeg.isAnEndpoint(inter)) {\n const newEventsFromSplit = this._splitSafely(nextSeg, inter)\n for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {\n newEvents.push(newEventsFromSplit[i])\n }\n }\n }\n }\n\n this.tree.remove(segment)\n }\n\n return newEvents\n }\n\n /* Safely split a segment that is currently in the datastructures\n * IE - a segment other than the one that is currently being processed. */\n _splitSafely(seg, pt) {\n // Rounding errors can cause changes in ordering,\n // so remove afected segments and right sweep events before splitting\n // removeNode() doesn't work, so have re-find the seg\n // https://github.com/w8r/splay-tree/pull/5\n this.tree.remove(seg)\n const rightSE = seg.rightSE\n this.queue.remove(rightSE)\n const newEvents = seg.split(pt)\n newEvents.push(rightSE)\n // splitting can trigger consumption\n if (seg.consumedBy === undefined) this.tree.add(seg)\n return newEvents\n }\n}\n","import SplayTree from \"splaytree\"\nimport { getBboxOverlap } from \"./bbox\"\nimport * as geomIn from \"./geom-in\"\nimport * as geomOut from \"./geom-out\"\nimport rounder from \"./rounder\"\nimport SweepEvent from \"./sweep-event\"\nimport SweepLine from \"./sweep-line\"\n\n// Limits on iterative processes to prevent infinite loops - usually caused by floating-point math round-off errors.\nconst POLYGON_CLIPPING_MAX_QUEUE_SIZE =\n (typeof process !== \"undefined\" &&\n process.env.POLYGON_CLIPPING_MAX_QUEUE_SIZE) ||\n 1000000\nconst POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS =\n (typeof process !== \"undefined\" &&\n process.env.POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS) ||\n 1000000\n\nexport class Operation {\n run(type, geom, moreGeoms) {\n operation.type = type\n rounder.reset()\n\n /* Convert inputs to MultiPoly objects */\n const multipolys = [new geomIn.MultiPolyIn(geom, true)]\n for (let i = 0, iMax = moreGeoms.length; i < iMax; i++) {\n multipolys.push(new geomIn.MultiPolyIn(moreGeoms[i], false))\n }\n operation.numMultiPolys = multipolys.length\n\n /* BBox optimization for difference operation\n * If the bbox of a multipolygon that's part of the clipping doesn't\n * intersect the bbox of the subject at all, we can just drop that\n * multiploygon. */\n if (operation.type === \"difference\") {\n // in place removal\n const subject = multipolys[0]\n let i = 1\n while (i < multipolys.length) {\n if (getBboxOverlap(multipolys[i].bbox, subject.bbox) !== null) i++\n else multipolys.splice(i, 1)\n }\n }\n\n /* BBox optimization for intersection operation\n * If we can find any pair of multipolygons whose bbox does not overlap,\n * then the result will be empty. */\n if (operation.type === \"intersection\") {\n // TODO: this is O(n^2) in number of polygons. By sorting the bboxes,\n // it could be optimized to O(n * ln(n))\n for (let i = 0, iMax = multipolys.length; i < iMax; i++) {\n const mpA = multipolys[i]\n for (let j = i + 1, jMax = multipolys.length; j < jMax; j++) {\n if (getBboxOverlap(mpA.bbox, multipolys[j].bbox) === null) return []\n }\n }\n }\n\n /* Put segment endpoints in a priority queue */\n const queue = new SplayTree(SweepEvent.compare)\n for (let i = 0, iMax = multipolys.length; i < iMax; i++) {\n const sweepEvents = multipolys[i].getSweepEvents()\n for (let j = 0, jMax = sweepEvents.length; j < jMax; j++) {\n queue.insert(sweepEvents[j])\n\n if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {\n // prevents an infinite loop, an otherwise common manifestation of bugs\n throw new Error(\n \"Infinite loop when putting segment endpoints in a priority queue \" +\n \"(queue size too big).\",\n )\n }\n }\n }\n\n /* Pass the sweep line over those endpoints */\n const sweepLine = new SweepLine(queue)\n let prevQueueSize = queue.size\n let node = queue.pop()\n while (node) {\n const evt = node.key\n if (queue.size === prevQueueSize) {\n // prevents an infinite loop, an otherwise common manifestation of bugs\n const seg = evt.segment\n throw new Error(\n `Unable to pop() ${evt.isLeft ? \"left\" : \"right\"} SweepEvent ` +\n `[${evt.point.x}, ${evt.point.y}] from segment #${seg.id} ` +\n `[${seg.leftSE.point.x}, ${seg.leftSE.point.y}] -> ` +\n `[${seg.rightSE.point.x}, ${seg.rightSE.point.y}] from queue.`,\n )\n }\n\n if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {\n // prevents an infinite loop, an otherwise common manifestation of bugs\n throw new Error(\n \"Infinite loop when passing sweep line over endpoints \" +\n \"(queue size too big).\",\n )\n }\n\n if (sweepLine.segments.length > POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS) {\n // prevents an infinite loop, an otherwise common manifestation of bugs\n throw new Error(\n \"Infinite loop when passing sweep line over endpoints \" +\n \"(too many sweep line segments).\",\n )\n }\n\n const newEvents = sweepLine.process(evt)\n for (let i = 0, iMax = newEvents.length; i < iMax; i++) {\n const evt = newEvents[i]\n if (evt.consumedBy === undefined) queue.insert(evt)\n }\n prevQueueSize = queue.size\n node = queue.pop()\n }\n\n // free some memory we don't need anymore\n rounder.reset()\n\n /* Collect and compile segments we're keeping into a multipolygon */\n const ringsOut = geomOut.RingOut.factory(sweepLine.segments)\n const result = new geomOut.MultiPolyOut(ringsOut)\n return result.getGeom()\n }\n}\n\n// singleton available by import\nconst operation = new Operation()\n\nexport default operation\n","import operation from \"./operation\"\n\nconst union = (geom, ...moreGeoms) => operation.run(\"union\", geom, moreGeoms)\n\nconst intersection = (geom, ...moreGeoms) =>\n operation.run(\"intersection\", geom, moreGeoms)\n\nconst xor = (geom, ...moreGeoms) => operation.run(\"xor\", geom, moreGeoms)\n\nconst difference = (subjectGeom, ...clippingGeoms) =>\n operation.run(\"difference\", subjectGeom, clippingGeoms)\n\nexport default {\n union: union,\n intersection: intersection,\n xor: xor,\n difference: difference,\n}\n"],"names":["isInBbox","bbox","point","ll","x","ur","y","getBboxOverlap","b1","b2","lowerX","upperX","epsilon","Number","EPSILON","undefined","Math","pow","EPSILON_SQ","cmp","a","b","ab","CoordRounder","constructor","this","tree","SplayTree","round","coord","node","add","prevNode","prev","key","remove","nextNode","next","rounder","reset","xRounder","yRounder","splitter","resulterrbound","sum","elen","e","flen","f","h","Q","Qnew","hh","bvirt","enow","fnow","eindex","findex","hindex","vec","n","Float64Array","ccwerrboundB","ccwerrboundC","B","C1","C2","D","u","orient2d","ax","ay","bx","by","cx","cy","detleft","detright","det","detsum","abs","acxtail","acytail","bcxtail","bcytail","c","ahi","alo","bhi","blo","_i","_j","_0","s1","s0","t1","t0","u3","acx","bcx","acy","bcy","i","estimate","errbound","C1len","C2len","Dlen","orient2dadapt","crossProduct","dotProduct","compareVectorAngles","basePt","endPt1","endPt2","res","length","v","sqrt","sineOfAngle","pShared","pBase","pAngle","vBase","vAngle","cosineOfAngle","horizontalIntersection","pt","verticalIntersection","SweepEvent","compare","ptCmp","comparePoints","link","isLeft","Segment","segment","aPt","bPt","events","push","other","Error","otherEvents","iMax","evt","checkForConsuming","numEvents","evt1","consumedBy","j","evt2","otherSE","consume","getAvailableLinkedEvents","ringOut","isInResult","getLeftmostComparator","baseEvent","cache","Map","fillCache","linkedEvent","nextEvent","set","sine","cosine","has","asine","acosine","get","bsine","bcosine","segmentId","alx","leftSE","blx","arx","rightSE","brx","aly","bly","ary","bry","aCmpBLeft","comparePoint","bCmpARight","bCmpALeft","aCmpBRight","id","rings","windings","fromRing","pt1","pt2","ring","leftPt","rightPt","winding","cmpPts","replaceRightSE","newRightSE","y1","y2","vector","isAnEndpoint","lPt","rPt","yDist","xFromYDist","xDist","yFromXDist","getIntersection","tBbox","oBbox","bboxOverlap","tlp","trp","olp","orp","touchesOtherLSE","touchesThisLSE","touchesOtherRSE","touchesThisRSE","intersection","v1","v2","kross","ve","d1","d2","split","newEvents","alreadyLinked","newLeftSE","oldRightSE","newSeg","slice","swapEvents","tmpEvt","consumer","consumee","tmp","index","indexOf","prevInResult","_prevInResult","beforeState","_beforeState","seg","afterState","multiPolys","_afterState","ringsAfter","windingsAfter","mpsAfter","polysAfter","polysExclude","poly","isExterior","splice","mp","multiPoly","_isInResult","mpsBefore","operation","type","noBefores","noAfters","least","most","numMultiPolys","diff","isJustSubject","mps","isSubject","RingIn","geomRing","Array","isArray","segments","firstPoint","prevPoint","getSweepEvents","sweepEvents","PolyIn","geomPoly","exteriorRing","interiorRings","ringSweepEvents","jMax","MultiPolyIn","geom","ex","polys","POSITIVE_INFINITY","NEGATIVE_INFINITY","polySweepEvents","RingOut","factory","allSegments","ringsOut","prevEvent","event","startingPoint","intersectionLEs","availableLEs","firstPt","lastPt","indexLE","intersectionLE","ringEvents","unshift","reverse","comparator","sort","getGeom","prevPt","points","nextPt","shift","step","isExteriorRing","iStart","iEnd","orderedPoints","_isExteriorRing","enclosing","enclosingRing","_enclosingRing","_calcEnclosingRing","leftMostEvt","prevSeg","prevPrevSeg","PolyOut","addInterior","ringGeom","MultiPolyOut","_composePolys","polyGeom","SweepLine","queue","arguments","process","find","nextSeg","prevMySplitter","prevInter","newEventsFromSplit","_splitSafely","nextMySplitter","nextInter","mySplitter","inter","POLYGON_CLIPPING_MAX_QUEUE_SIZE","env","POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS","run","moreGeoms","multipolys","geomIn","subject","mpA","insert","size","sweepLine","prevQueueSize","pop","geomOut","union","_len","_key","_len2","_key2","xor","_len3","_key3","difference","subjectGeom","_len4","clippingGeoms","_key4"],"mappings":"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"}