{"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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"}