diff --git a/dist/leaflet-tracksymbol2.es.js b/dist/leaflet-tracksymbol2.es.js index 0aad679..c220466 100644 --- a/dist/leaflet-tracksymbol2.es.js +++ b/dist/leaflet-tracksymbol2.es.js @@ -86,7 +86,7 @@ Object.defineProperty(i, "DP_TOL", { Ve(r); } }); -class v { +class w { /** * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter * @returns {ReferenceError} @@ -126,7 +126,7 @@ class v { return new Error("Operation is not supported"); } } -i.Errors = v; +i.Errors = w; class he { constructor(t, e) { this.first = t, this.last = e || this.first; @@ -210,7 +210,7 @@ class he { let e = t, n = t; do { if (e != t && e === n) - throw v.INFINITE_LOOP; + throw w.INFINITE_LOOP; e = e.next, n = n.next.next; } while (e != t); } @@ -292,20 +292,20 @@ function Nn(r) { a + h < s && r.int_points1_sorted[a + h].face === t ? u = a + h : u = e; let f = vt(r.int_points1_sorted, u, t); n = null; - for (let m = u; m < u + f; m++) { - let S = r.int_points1_sorted[m]; - if (S.face === t && r.int_points2[S.id].face === r.int_points2[o.id].face) { - n = S; + for (let x = u; x < u + f; x++) { + let E = r.int_points1_sorted[x]; + if (E.face === t && r.int_points2[E.id].face === r.int_points2[o.id].face) { + n = E; break; } } if (n === null) continue; - let g = o.edge_after, x = n.edge_before; - if (!(g.bv === z && x.bv === z) || g !== x) + let g = o.edge_after, p = n.edge_before; + if (!(g.bv === z && p.bv === z) || g !== p) continue; - let I = r.int_points2[o.id], w = r.int_points2[n.id], E = I.edge_after, T = w.edge_before; - E.bv === z && T.bv === z && E === T || (I = r.int_points2[n.id], w = r.int_points2[o.id], E = I.edge_after, T = w.edge_before), E.bv === z && T.bv === z && E === T && g.setOverlap(E); + let S = r.int_points2[o.id], T = r.int_points2[n.id], v = S.edge_after, I = T.edge_before; + v.bv === z && I.bv === z && v === I || (S = r.int_points2[n.id], T = r.int_points2[o.id], v = S.edge_after, I = T.edge_before), v.bv === z && I.bv === z && v === I && g.setOverlap(v); } } function vt(r, t, e) { @@ -413,53 +413,53 @@ function Ie(r, t) { function Fn(r, t, e, n, s, l) { let o, a, h, u = n.length, f = !1; for (let g = 0; g < u; g++) { - let x = n[g]; - x.face !== o && (a = g, o = x.face); - let I = g, w = vt(n, g, o), E; - I + w < u && n[I + w].face === o ? E = I + w : E = a; - let T = vt(n, E, o); + let p = n[g]; + p.face !== o && (a = g, o = p.face); + let S = g, T = vt(n, g, o), v; + S + T < u && n[S + T].face === o ? v = S + T : v = a; + let I = vt(n, v, o); h = null; - for (let _ = E; _ < E + T; _++) { + for (let _ = v; _ < v + I; _++) { let L = n[_]; - if (L.face === o && s[L.id].face === s[x.id].face) { + if (L.face === o && s[L.id].face === s[p.id].face) { h = L; break; } } if (h === null) continue; - let m = x.edge_after, S = h.edge_before; - if (m.bv === b && S.bv != b) { - m.bv = S.bv; + let x = p.edge_after, E = h.edge_before; + if (x.bv === b && E.bv != b) { + x.bv = E.bv; continue; } - if (m.bv != b && S.bv === b) { - S.bv = m.bv; + if (x.bv != b && E.bv === b) { + E.bv = x.bv; continue; } - if (m.bv === b && S.bv === b && m != S || m.bv === Q && S.bv === W || m.bv === W && S.bv === Q) { - let _ = m.next; - for (; _ != S; ) + if (x.bv === b && E.bv === b && x != E || x.bv === Q && E.bv === W || x.bv === W && E.bv === Q) { + let _ = x.next; + for (; _ != E; ) _.bvStart = void 0, _.bvEnd = void 0, _.bv = void 0, _.setInclusion(t), _ = _.next; } - if (m.bv === b && S.bv === b && m != S) { - let _ = m.next, L; - for (; _ != S; ) { + if (x.bv === b && E.bv === b && x != E) { + let _ = x.next, L; + for (; _ != E; ) { if (_.bv != b) { if (L === void 0) L = _.bv; else if (_.bv != L) - throw v.UNRESOLVED_BOUNDARY_CONFLICT; + throw w.UNRESOLVED_BOUNDARY_CONFLICT; } _ = _.next; } - L != null && (m.bv = L, S.bv = L); + L != null && (x.bv = L, E.bv = L); continue; } - if (m.bv === Q && S.bv === W || m.bv === W && S.bv === Q) { - let _ = m; - for (; _ != S; ) { - if (_.bvStart === m.bv && _.bvEnd === S.bv) { + if (x.bv === Q && E.bv === W || x.bv === W && E.bv === Q) { + let _ = x; + for (; _ != E; ) { + if (_.bvStart === x.bv && _.bvEnd === E.bv) { let [L, Xt] = _.shape.distanceTo(t); if (L < 10 * i.DP_TOL) { Et(_, Xt.ps, e); @@ -491,7 +491,7 @@ function Fn(r, t, e, n, s, l) { } if (f) break; - throw v.UNRESOLVED_BOUNDARY_CONFLICT; + throw w.UNRESOLVED_BOUNDARY_CONFLICT; } } return f; @@ -505,13 +505,13 @@ function oe(r, t, e, n) { continue; let u = h, f = vt(e, h, s), g; u + f < e.length && e[u + f].face === o.face ? g = u + f : g = l, a = e[g]; - let x = g, I = vt(e, x, s), w = o.edge_after, E = a.edge_before; - if (w.bv === Q && E.bv === Q && t === Wt || w.bv === W && E.bv === W && t === Ut || (w.bv === W || E.bv === W) && t === lt && !n || (w.bv === Q || E.bv === Q) && t === lt && n || w.bv === b && E.bv === b && w.overlap & Rn && n || w.bv === b && E.bv === b && w.overlap & Un) { - r.removeChain(s, w, E); - for (let T = u; T < u + f; T++) - e[T].edge_after = void 0; - for (let T = x; T < x + I; T++) - e[T].edge_before = void 0; + let p = g, S = vt(e, p, s), T = o.edge_after, v = a.edge_before; + if (T.bv === Q && v.bv === Q && t === Wt || T.bv === W && v.bv === W && t === Ut || (T.bv === W || v.bv === W) && t === lt && !n || (T.bv === Q || v.bv === Q) && t === lt && n || T.bv === b && v.bv === b && T.overlap & Rn && n || T.bv === b && v.bv === b && T.overlap & Un) { + r.removeChain(s, T, v); + for (let I = u; I < u + f; I++) + e[I].edge_after = void 0; + for (let I = p; I < p + S; I++) + e[I].edge_before = void 0; } h += f - 1; } @@ -548,7 +548,7 @@ function ae(r, t, e) { try { he.testInfiniteLoop(s); } catch { - throw v.CANNOT_COMPLETE_BOOLEAN_OPERATION; + throw w.CANNOT_COMPLETE_BOOLEAN_OPERATION; } let o = r.addFace(s, l); for (let a of t) @@ -742,8 +742,8 @@ class St { function It(r, t) { let e = [], [n, s, l] = r.standard, [o, a, h] = t.standard, u = n * a - s * o, f = l * a - s * h, g = n * h - l * o; if (!i.Utils.EQ_0(u)) { - let x, I; - s === 0 ? (x = l / n, I = g / u) : a === 0 ? (x = h / o, I = g / u) : n === 0 ? (x = f / u, I = l / s) : o === 0 ? (x = f / u, I = h / a) : (x = f / u, I = g / u), e.push(new i.Point(x, I)); + let p, S; + s === 0 ? (p = l / n, S = g / u) : a === 0 ? (p = h / o, S = g / u) : n === 0 ? (p = f / u, S = l / s) : o === 0 ? (p = f / u, S = h / a) : (p = f / u, S = g / u), e.push(new i.Point(p, S)); } return e; } @@ -1195,49 +1195,50 @@ function Pt(r, t) { if (r.box.not_intersect(l)) return i.OUTSIDE; let o = r.edges.search(l); - if (o.length == 0) + if (o.length === 0) return i.OUTSIDE; - for (let u of o) - if (u.shape.contains(t)) + for (let f of o) + if (f.shape.contains(t)) return i.BOUNDARY; - let a = []; - for (let u of o) - for (let f of n.intersect(u.shape)) { - if (f.equalTo(t)) + let a = [...r.faces], h = []; + for (let f of o) + for (let g of n.intersect(f.shape)) { + if (g.equalTo(t)) return i.BOUNDARY; - a.push({ - pt: f, - edge: u + h.push({ + pt: g, + edge: f, + face_index: a.indexOf(f.face) }); } - a.sort((u, f) => qe(u.pt.x, f.pt.x) ? -1 : $e(u.pt.x, f.pt.x) ? 1 : 0); - let h = 0; - for (let u = 0; u < a.length; u++) { - let f = a[u]; - if (f.pt.equalTo(f.edge.shape.start)) { - if (u > 0 && f.pt.equalTo(a[u - 1].pt) && f.edge.prev === a[u - 1].edge) + h.sort((f, g) => qe(f.pt.x, g.pt.x) ? -1 : $e(f.pt.x, g.pt.x) ? 1 : f.face_index < g.face_index ? -1 : f.face_index > g.face_index ? 1 : f.edge.arc_length < g.edge.arc_length ? -1 : f.edge.arc_length > g.edge.arc_length ? 1 : 0); + let u = 0; + for (let f = 0; f < h.length; f++) { + let g = h[f]; + if (g.pt.equalTo(g.edge.shape.start)) { + if (f > 0 && g.pt.equalTo(h[f - 1].pt) && g.face_index === h[f - 1].face_index && g.edge.prev === h[f - 1].edge) continue; - let g = f.edge.prev; - for (; ee(g.length); ) - g = g.prev; - let x = g.shape.tangentInEnd(), I = f.pt.translate(x), w = f.edge.shape.tangentInStart(), E = f.pt.translate(w), T = I.leftTo(s), m = E.leftTo(s); - (T && !m || !T && m) && h++; - } else if (f.pt.equalTo(f.edge.shape.end)) { - if (u > 0 && f.pt.equalTo(a[u - 1].pt) && f.edge.next === a[u - 1].edge) + let p = g.edge.prev; + for (; ee(p.length); ) + p = p.prev; + let S = p.shape.tangentInEnd(), T = g.pt.translate(S), v = g.edge.shape.tangentInStart(), I = g.pt.translate(v), x = T.leftTo(s), E = I.leftTo(s); + (x && !E || !x && E) && u++; + } else if (g.pt.equalTo(g.edge.shape.end)) { + if (f > 0 && g.pt.equalTo(h[f - 1].pt) && g.face_index === h[f - 1].face_index && g.edge.next === h[f - 1].edge) continue; - let g = f.edge.next; - for (; ee(g.length); ) - g = g.next; - let x = g.shape.tangentInStart(), I = f.pt.translate(x), w = f.edge.shape.tangentInEnd(), E = f.pt.translate(w), T = I.leftTo(s), m = E.leftTo(s); - (T && !m || !T && m) && h++; - } else if (f.edge.shape instanceof i.Segment) - h++; + let p = g.edge.next; + for (; ee(p.length); ) + p = p.next; + let S = p.shape.tangentInStart(), T = g.pt.translate(S), v = g.edge.shape.tangentInEnd(), I = g.pt.translate(v), x = T.leftTo(s), E = I.leftTo(s); + (x && !E || !x && E) && u++; + } else if (g.edge.shape instanceof i.Segment) + u++; else { - let g = f.edge.shape.box; - ot(f.pt.y, g.ymin) || ot(f.pt.y, g.ymax) || h++; + let p = g.edge.shape.box; + ot(g.pt.y, p.ymin) || ot(g.pt.y, p.ymax) || u++; } } - return e = h % 2 == 1 ? qt : Fe, e; + return e = u % 2 === 1 ? qt : Fe, e; } function si(r, t) { return bt(r, t).equal(); @@ -1423,7 +1424,7 @@ let Lt = class dt { else if (t.length === 2 && typeof t[0] == "number" && typeof t[1] == "number") e = t[0], n = t[1]; else - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; return this.multiply(new dt(1, 0, 0, 1, e, n)); } /** @@ -1552,13 +1553,13 @@ const _i = class fe { static comparable_less_than(t, e) { return t < e; } -}, A = 0, p = 1; +}, A = 0, m = 1; class ht { - constructor(t = void 0, e = void 0, n = null, s = null, l = null, o = p) { + constructor(t = void 0, e = void 0, n = null, s = null, l = null, o = m) { this.left = n, this.right = s, this.parent = l, this.color = o, this.item = { key: t, value: e }, t && t instanceof Array && t.length == 2 && !Number.isNaN(t[0]) && !Number.isNaN(t[1]) && (this.item.key = new _i(Math.min(t[0], t[1]), Math.max(t[0], t[1]))), this.max = this.item.key ? this.item.key.max : void 0; } isNil() { - return this.item.key === void 0 && this.item.value === void 0 && this.left === null && this.right === null && this.color === p; + return this.item.key === void 0 && this.item.value === void 0 && this.left === null && this.right === null && this.color === m; } _value_less_than(t) { return this.item.value && t.item.value && this.item.value.less_than ? this.item.value.less_than(t.item.value) : this.item.value < t.item.value; @@ -1746,19 +1747,19 @@ class Rt { insert_fixup(t) { let e, n; for (e = t; e != this.root && e.parent.color == A; ) - e.parent == e.parent.parent.left ? (n = e.parent.parent.right, n.color == A ? (e.parent.color = p, n.color = p, e.parent.parent.color = A, e = e.parent.parent) : (e == e.parent.right && (e = e.parent, this.rotate_left(e)), e.parent.color = p, e.parent.parent.color = A, this.rotate_right(e.parent.parent))) : (n = e.parent.parent.left, n.color == A ? (e.parent.color = p, n.color = p, e.parent.parent.color = A, e = e.parent.parent) : (e == e.parent.left && (e = e.parent, this.rotate_right(e)), e.parent.color = p, e.parent.parent.color = A, this.rotate_left(e.parent.parent))); - this.root.color = p; + e.parent == e.parent.parent.left ? (n = e.parent.parent.right, n.color == A ? (e.parent.color = m, n.color = m, e.parent.parent.color = A, e = e.parent.parent) : (e == e.parent.right && (e = e.parent, this.rotate_left(e)), e.parent.color = m, e.parent.parent.color = A, this.rotate_right(e.parent.parent))) : (n = e.parent.parent.left, n.color == A ? (e.parent.color = m, n.color = m, e.parent.parent.color = A, e = e.parent.parent) : (e == e.parent.left && (e = e.parent, this.rotate_right(e)), e.parent.color = m, e.parent.parent.color = A, this.rotate_left(e.parent.parent))); + this.root.color = m; } tree_delete(t) { let e, n; t.left == this.nil_node || t.right == this.nil_node ? e = t : e = this.tree_successor(t), e.left != this.nil_node ? n = e.left : n = e.right, n.parent = e.parent, e == this.root ? this.root = n : (e == e.parent.left ? e.parent.left = n : e.parent.right = n, e.parent.update_max()), this.recalc_max(n), e != t && (t.copy_data(e), t.update_max(), this.recalc_max(t)), /*fix_node != this.nil_node && */ - e.color == p && this.delete_fixup(n); + e.color == m && this.delete_fixup(n); } delete_fixup(t) { let e = t, n; - for (; e != this.root && e.parent != null && e.color == p; ) - e == e.parent.left ? (n = e.parent.right, n.color == A && (n.color = p, e.parent.color = A, this.rotate_left(e.parent), n = e.parent.right), n.left.color == p && n.right.color == p ? (n.color = A, e = e.parent) : (n.right.color == p && (n.color = A, n.left.color = p, this.rotate_right(n), n = e.parent.right), n.color = e.parent.color, e.parent.color = p, n.right.color = p, this.rotate_left(e.parent), e = this.root)) : (n = e.parent.left, n.color == A && (n.color = p, e.parent.color = A, this.rotate_right(e.parent), n = e.parent.left), n.left.color == p && n.right.color == p ? (n.color = A, e = e.parent) : (n.left.color == p && (n.color = A, n.right.color = p, this.rotate_left(n), n = e.parent.left), n.color = e.parent.color, e.parent.color = p, n.left.color = p, this.rotate_right(e.parent), e = this.root)); - e.color = p; + for (; e != this.root && e.parent != null && e.color == m; ) + e == e.parent.left ? (n = e.parent.right, n.color == A && (n.color = m, e.parent.color = A, this.rotate_left(e.parent), n = e.parent.right), n.left.color == m && n.right.color == m ? (n.color = A, e = e.parent) : (n.right.color == m && (n.color = A, n.left.color = m, this.rotate_right(n), n = e.parent.right), n.color = e.parent.color, e.parent.color = m, n.right.color = m, this.rotate_left(e.parent), e = this.root)) : (n = e.parent.left, n.color == A && (n.color = m, e.parent.color = A, this.rotate_right(e.parent), n = e.parent.left), n.left.color == m && n.right.color == m ? (n.color = A, e = e.parent) : (n.left.color == m && (n.color = A, n.right.color = m, this.rotate_left(n), n = e.parent.left), n.color = e.parent.color, e.parent.color = m, n.left.color = m, this.rotate_right(e.parent), e = this.root)); + e.color = m; } tree_search(t, e) { if (!(t == null || t == this.nil_node)) @@ -1818,13 +1819,13 @@ class Rt { testRedBlackProperty() { let t = !0; return this.tree_walk(this.root, function(e) { - e.color == A && (e.left.color == p && e.right.color == p || (t = !1)); + e.color == A && (e.left.color == m && e.right.color == m || (t = !1)); }), t; } /* Throw error if not every path from root to bottom has same black height */ testBlackHeightProperty(t) { let e = 0, n = 0, s = 0; - if (t.color == p && e++, t.left != this.nil_node ? n = this.testBlackHeightProperty(t.left) : n = 1, t.right != this.nil_node ? s = this.testBlackHeightProperty(t.right) : s = 1, n != s) + if (t.color == m && e++, t.left != this.nil_node ? n = this.testBlackHeightProperty(t.left) : n = 1, t.right != this.nil_node ? s = this.testBlackHeightProperty(t.right) : s = 1, n != s) throw new Error("Red-black height property violated"); return e += n, e; } @@ -1898,13 +1899,13 @@ class pi extends Set { i.PlanarSet = pi; class rt { get name() { - throw v.CANNOT_INVOKE_ABSTRACT_METHOD; + throw w.CANNOT_INVOKE_ABSTRACT_METHOD; } get box() { - throw v.CANNOT_INVOKE_ABSTRACT_METHOD; + throw w.CANNOT_INVOKE_ABSTRACT_METHOD; } clone() { - throw v.CANNOT_INVOKE_ABSTRACT_METHOD; + throw w.CANNOT_INVOKE_ABSTRACT_METHOD; } /** * Returns new shape translated by given vector. @@ -1938,7 +1939,7 @@ class rt { return this.transform(new Lt().scale(t, e)); } transform(...t) { - throw v.CANNOT_INVOKE_ABSTRACT_METHOD; + throw w.CANNOT_INVOKE_ABSTRACT_METHOD; } /** * This method returns an object that defines how data will be @@ -1949,7 +1950,7 @@ class rt { return Object.assign({}, this, { name: this.name }); } svg(t = {}) { - throw v.CANNOT_INVOKE_ABSTRACT_METHOD; + throw w.CANNOT_INVOKE_ABSTRACT_METHOD; } } let mi = class fn extends rt { @@ -1976,7 +1977,7 @@ let mi = class fn extends rt { this.x = t[0], this.y = t[1]; return; } - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; } } /** @@ -2151,7 +2152,7 @@ let Ei = class extends rt { return; } } - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; } } /** @@ -2219,7 +2220,7 @@ let Ei = class extends rt { normalize() { if (!i.Utils.EQ_0(this.length)) return new i.Vector(this.x / this.length, this.y / this.length); - throw v.ZERO_DIVISION; + throw w.ZERO_DIVISION; } /** * Returns new vector rotated by given angle, @@ -2232,7 +2233,7 @@ let Ei = class extends rt { rotate(t, e = new i.Point()) { if (e.x === 0 && e.y === 0) return this.transform(new Lt().rotate(t)); - throw v.OPERATION_IS_NOT_SUPPORTED; + throw w.OPERATION_IS_NOT_SUPPORTED; } /** * Return new vector transformed by affine transformation matrix m @@ -2336,7 +2337,7 @@ class zt extends rt { this.ps = new i.Point(t[0], t[1]), this.pe = new i.Point(t[2], t[3]); return; } - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; } } /** @@ -2597,18 +2598,18 @@ let { vector: At } = i, wi = class hn extends rt { } if (e instanceof i.Point && n instanceof i.Vector) { if (i.Utils.EQ_0(n.x) && i.Utils.EQ_0(n.y)) - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; this.pt = e.clone(), this.norm = n.clone(), this.norm = this.norm.normalize(), this.norm.dot(At(this.pt.x, this.pt.y)) >= 0 && this.norm.invert(); return; } if (e instanceof i.Vector && n instanceof i.Point) { if (i.Utils.EQ_0(e.x) && i.Utils.EQ_0(e.y)) - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; this.pt = n.clone(), this.norm = e.clone(), this.norm = this.norm.normalize(), this.norm.dot(At(this.pt.x, this.pt.y)) >= 0 && this.norm.invert(); return; } } - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; } } /** @@ -2821,7 +2822,7 @@ let { vector: At } = i, wi = class hn extends rt { } static points2norm(t, e) { if (t.equalTo(e)) - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; return new i.Vector(t, e).normalize().rotate90CCW(); } }; @@ -2904,7 +2905,7 @@ let Si = class extends rt { */ scale(t, e) { if (t !== e || !(this.pc.x === 0 && this.pc.y === 0)) - throw v.OPERATION_IS_NOT_SUPPORTED; + throw w.OPERATION_IS_NOT_SUPPORTED; return new i.Circle(this.pc, this.r * t); } /** @@ -3458,7 +3459,7 @@ class Ot extends rt { * @param {Point} [center=(0,0)] center */ rotate(t, e = new i.Point()) { - throw v.OPERATION_IS_NOT_SUPPORTED; + throw w.OPERATION_IS_NOT_SUPPORTED; } /** * Return new box transformed using affine transformation matrix @@ -3956,7 +3957,7 @@ class xe extends rt { this.norm = t[1].clone(); return; } - throw v.ILLEGAL_PARAMETERS; + throw w.ILLEGAL_PARAMETERS; } } /** @@ -4675,9 +4676,9 @@ class d { return [0, new i.Segment(n[0], n[0])]; let s = new i.Line(t.ps, t.pe), l = new i.Circle(e.pc, e.r), [o, a] = d.point2line(l.center, s); if (i.Utils.GE(o, l.r) && a.end.on(t)) { - let [g, x] = d.point2circle(a.end, l); - if (x.end.on(e)) - return [g, x]; + let [g, p] = d.point2circle(a.end, l); + if (p.end.on(e)) + return [g, p]; } let h = []; h.push(d.point2arc(t.start, e)), h.push(d.point2arc(t.end, e)); @@ -4833,7 +4834,7 @@ class d { if (e.length === 0) return n; let a = e.map((f) => f.left.isNil() ? void 0 : f.left).filter((f) => f !== void 0), h = e.map((f) => f.right.isNil() ? void 0 : f.right).filter((f) => f !== void 0), u = [...a, ...h].filter((f) => { - let [g, x] = d.box2box_minmax(t.box, f.max); + let [g, p] = d.box2box_minmax(t.box, f.max); return i.Utils.LE(g, n); }); return n = d.minmax_tree_process_level(t, u, n, s), n; diff --git a/dist/leaflet-tracksymbol2.es.js.map b/dist/leaflet-tracksymbol2.es.js.map index 265b03e..4ce4a87 100644 --- a/dist/leaflet-tracksymbol2.es.js.map +++ b/dist/leaflet-tracksymbol2.es.js.map @@ -1 +1 @@ -{"version":3,"file":"leaflet-tracksymbol2.es.js","sources":["../node_modules/.pnpm/@flatten-js+core@1.5.1/node_modules/@flatten-js/core/dist/main.mjs","../src/trackSymbol.ts","../src/ais/aisTrackSymbol.ts","../src/index.ts"],"sourcesContent":["/**\n * Global constant CCW defines counterclockwise direction of arc\n * @type {boolean}\n */\nconst CCW = true;\n\n/**\n * Global constant CW defines clockwise direction of arc\n * @type {boolean}\n */\nconst CW = false;\n\n/**\n * Defines orientation for face of the polygon: clockwise, counterclockwise\n * or not orientable in the case of self-intersection\n * @type {{CW: number, CCW: number, NOT_ORIENTABLE: number}}\n */\nconst ORIENTATION = {CCW:-1, CW:1, NOT_ORIENTABLE: 0};\n\nconst PIx2 = 2 * Math.PI;\n\nconst INSIDE$2 = 1;\nconst OUTSIDE$1 = 0;\nconst BOUNDARY$1 = 2;\nconst CONTAINS = 3;\nconst INTERLACE = 4;\n\nconst OVERLAP_SAME$1 = 1;\nconst OVERLAP_OPPOSITE$1 = 2;\n\nconst NOT_VERTEX$1 = 0;\nconst START_VERTEX$1 = 1;\nconst END_VERTEX$1 = 2;\n\nvar Constants = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOUNDARY: BOUNDARY$1,\n CCW: CCW,\n CONTAINS: CONTAINS,\n CW: CW,\n END_VERTEX: END_VERTEX$1,\n INSIDE: INSIDE$2,\n INTERLACE: INTERLACE,\n NOT_VERTEX: NOT_VERTEX$1,\n ORIENTATION: ORIENTATION,\n OUTSIDE: OUTSIDE$1,\n OVERLAP_OPPOSITE: OVERLAP_OPPOSITE$1,\n OVERLAP_SAME: OVERLAP_SAME$1,\n PIx2: PIx2,\n START_VERTEX: START_VERTEX$1\n});\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n/**\n * Floating point comparison tolerance.\n * Default value is 0.000001 (10e-6)\n * @type {number}\n */\nlet DP_TOL = 0.000001;\n\n/**\n * Set new floating point comparison tolerance\n * @param {number} tolerance\n */\nfunction setTolerance(tolerance) {DP_TOL = tolerance;}\n\n/**\n * Get floating point comparison tolerance\n * @returns {number}\n */\nfunction getTolerance() {return DP_TOL;}\n\nconst DECIMALS = 3;\n\n/**\n * Returns *true* if value comparable to zero\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ_0(x) {\n return (x < DP_TOL && x > -DP_TOL);\n}\n\n/**\n * Returns *true* if two values are equal up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ(x, y) {\n return (x - y < DP_TOL && x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction GT(x, y) {\n return (x - y > DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @returns {boolean}\n */\nfunction GE(x, y) {\n return (x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument less than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LT(x, y) {\n return (x - y < -DP_TOL)\n}\n\n/**\n * Returns *true* if first argument less than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LE(x, y) {\n return (x - y < DP_TOL);\n}\n\nvar Utils$1 = /*#__PURE__*/Object.freeze({\n __proto__: null,\n DECIMALS: DECIMALS,\n EQ: EQ,\n EQ_0: EQ_0,\n GE: GE,\n GT: GT,\n LE: LE,\n LT: LT,\n getTolerance: getTolerance,\n setTolerance: setTolerance\n});\n\nlet Flatten = {\n Utils: Utils$1,\n Errors: undefined,\n Matrix: undefined,\n Planar_set: undefined,\n Point: undefined,\n Vector: undefined,\n Line: undefined,\n Circle: undefined,\n Segment: undefined,\n Arc: undefined,\n Box: undefined,\n Edge: undefined,\n Face: undefined,\n Ray: undefined,\n Ray_shooting: undefined,\n Multiline: undefined,\n Polygon: undefined,\n Distance: undefined,\n Inversion: undefined\n};\n\nfor (let c in Constants) {Flatten[c] = Constants[c];}\n\nObject.defineProperty(Flatten, 'DP_TOL', {\n get:function(){return getTolerance()}, \n set:function(value){setTolerance(value);}\n});\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class of system errors\n */\nclass Errors {\n /**\n * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter\n * @returns {ReferenceError}\n */\n static get ILLEGAL_PARAMETERS() {\n return new ReferenceError('Illegal Parameters');\n }\n\n /**\n * Throw error ZERO_DIVISION to catch situation of zero division\n * @returns {Error}\n */\n static get ZERO_DIVISION() {\n return new Error('Zero division');\n }\n\n /**\n * Error to throw from BooleanOperations module in case when fixBoundaryConflicts not capable to fix it\n * @returns {Error}\n */\n static get UNRESOLVED_BOUNDARY_CONFLICT() {\n return new Error('Unresolved boundary conflict in boolean operation');\n }\n\n /**\n * Error to throw from LinkedList:testInfiniteLoop static method\n * in case when circular loop detected in linked list\n * @returns {Error}\n */\n static get INFINITE_LOOP() {\n return new Error('Infinite loop');\n }\n\n static get CANNOT_COMPLETE_BOOLEAN_OPERATION() {\n return new Error('Cannot complete boolean operation')\n }\n\n static get CANNOT_INVOKE_ABSTRACT_METHOD() {\n return new Error('Abstract method cannot be invoked');\n }\n\n static get OPERATION_IS_NOT_SUPPORTED() {\n return new Error('Operation is not supported')\n }\n}\n\nFlatten.Errors = Errors;\n\n/**\n * Class implements bidirectional non-circular linked list.
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass LinkedList {\n constructor(first, last) {\n this.first = first;\n this.last = last || this.first;\n }\n\n [Symbol.iterator]() {\n let value = undefined;\n return {\n next: () => {\n value = value ? value.next : this.first;\n return {value: value, done: value === undefined};\n }\n };\n };\n\n /**\n * Return number of elements in the list\n * @returns {number}\n */\n get size() {\n let counter = 0;\n for (let edge of this) {\n counter++;\n }\n return counter;\n }\n\n /**\n * Return array of elements from start to end,\n * If start or end not defined, take first as start, last as end\n * @returns {Array}\n */\n toArray(start=undefined, end=undefined) {\n let elements = [];\n let from = start || this.first;\n let to = end || this.last;\n let element = from;\n if (element === undefined) return elements;\n do {\n elements.push(element);\n element = element.next;\n } while (element !== to.next);\n return elements;\n }\n\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n append(element) {\n if (this.isEmpty()) {\n this.first = element;\n } else {\n element.prev = this.last;\n this.last.next = element;\n }\n\n // update edge to be last\n this.last = element;\n\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement\n * @param {LinkedListElement} elementBefore\n * @returns {LinkedList}\n */\n insert(newElement, elementBefore) {\n if (this.isEmpty()) {\n this.first = newElement;\n this.last = newElement;\n }\n else if (elementBefore === null || elementBefore === undefined) {\n newElement.next = this.first;\n this.first.prev = newElement;\n this.first = newElement;\n }\n else {\n /* set links to new element */\n let elementAfter = elementBefore.next;\n elementBefore.next = newElement;\n if (elementAfter) elementAfter.prev = newElement;\n\n /* set links from new element */\n newElement.prev = elementBefore;\n newElement.next = elementAfter;\n\n /* extend list if new element added after the last element */\n if (this.last === elementBefore)\n this.last = newElement;\n }\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n remove(element) {\n // special case if last edge removed\n if (element === this.first && element === this.last) {\n this.first = undefined;\n this.last = undefined;\n } else {\n // update linked list\n if (element.prev) element.prev.next = element.next;\n if (element.next) element.next.prev = element.prev;\n // update first if need\n if (element === this.first) {\n this.first = element.next;\n }\n // update last if need\n if (element === this.last) {\n this.last = element.prev;\n }\n }\n return this;\n }\n\n /**\n * Return true if list is empty\n * @returns {boolean}\n */\n isEmpty() {\n return this.first === undefined;\n }\n\n /**\n * Throw an error if circular loop detected in the linked list\n * @param {LinkedListElement} first element to start iteration\n * @throws {Errors.INFINITE_LOOP}\n */\n static testInfiniteLoop(first) {\n let edge = first;\n let controlEdge = first;\n do {\n if (edge != first && edge === controlEdge) {\n throw Errors.INFINITE_LOOP; // new Error(\"Infinite loop\")\n }\n edge = edge.next;\n controlEdge = controlEdge.next.next;\n } while (edge != first)\n }\n}\n\n/*\n Smart intersections describe intersection points that refers to the edges they intersect\n This function are supposed for internal usage by morphing and relation methods between\n */\n\nfunction addToIntPoints(edge, pt, int_points)\n{\n let id = int_points.length;\n let shapes = edge.shape.split(pt);\n\n // if (shapes.length < 2) return;\n if (shapes.length === 0) return; // Point does not belong to edge ?\n\n let len = 0;\n if (shapes[0] === null) { // point incident to edge start vertex\n len = 0;\n }\n else if (shapes[1] === null) { // point incident to edge end vertex\n len = edge.shape.length;\n }\n else { // Edge was split into to edges\n len = shapes[0].length;\n }\n\n let is_vertex = NOT_VERTEX$1;\n if (EQ(len, 0)) {\n is_vertex |= START_VERTEX$1;\n }\n if (EQ(len, edge.shape.length)) {\n is_vertex |= END_VERTEX$1;\n }\n // Fix intersection point which is end point of the last edge\n let arc_length;\n if (len === Infinity) {\n arc_length = shapes[0].coord(pt);\n }\n else {\n arc_length = (is_vertex & END_VERTEX$1) && edge.next && edge.next.arc_length === 0 ?\n 0 :\n edge.arc_length + len;\n }\n\n int_points.push({\n id: id,\n pt: pt,\n arc_length: arc_length,\n edge_before: edge,\n edge_after: undefined,\n face: edge.face,\n is_vertex: is_vertex\n });\n}\n\nfunction sortIntersections(intersections)\n{\n // if (intersections.int_points1.length === 0) return;\n\n // augment intersections with new sorted arrays\n // intersections.int_points1_sorted = intersections.int_points1.slice().sort(compareFn);\n // intersections.int_points2_sorted = intersections.int_points2.slice().sort(compareFn);\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n}\n\nfunction getSortedArray(int_points)\n{\n let faceMap = new Map;\n let id = 0;\n // Create integer id's for faces\n for (let ip of int_points) {\n if (!faceMap.has(ip.face)) {\n faceMap.set(ip.face, id);\n id++;\n }\n }\n // Augment intersection points with face id's\n for (let ip of int_points) {\n ip.faceId = faceMap.get(ip.face);\n }\n // Clone and sort\n let int_points_sorted = int_points.slice().sort(compareFn);\n return int_points_sorted;\n}\n\nfunction compareFn(ip1, ip2)\n{\n // compare face id's\n if (ip1.faceId < ip2.faceId) {\n return -1;\n }\n if (ip1.faceId > ip2.faceId) {\n return 1;\n }\n // same face - compare arc_length\n if (ip1.arc_length < ip2.arc_length) {\n return -1;\n }\n if (ip1.arc_length > ip2.arc_length) {\n return 1;\n }\n return 0;\n}\n\n// export function getSortedArrayOnLine(line, int_points) {\n// return int_points.slice().sort( (int_point1, int_point2) => {\n// if (line.coord(int_point1.pt) < line.coord(int_point2.pt)) {\n// return -1;\n// }\n// if (line.coord(int_point1.pt) > line.coord(int_point2.pt)) {\n// return 1;\n// }\n// return 0;\n// })\n// }\n\nfunction filterDuplicatedIntersections(intersections)\n{\n if (intersections.int_points1.length < 2) return;\n\n let do_squeeze = false;\n\n let int_point_ref1;\n let int_point_ref2;\n let int_point_cur1;\n let int_point_cur2;\n for (let i = 0; i < intersections.int_points1_sorted.length; i++) {\n\n if (intersections.int_points1_sorted[i].id === -1)\n continue;\n\n int_point_ref1 = intersections.int_points1_sorted[i];\n int_point_ref2 = intersections.int_points2[int_point_ref1.id];\n\n for (let j=i+1; j < intersections.int_points1_sorted.length; j++) {\n int_point_cur1 = intersections.int_points1_sorted[j];\n if (!EQ(int_point_cur1.arc_length, int_point_ref1.arc_length)) {\n break;\n }\n if (int_point_cur1.id === -1)\n continue;\n int_point_cur2 = intersections.int_points2[int_point_cur1.id];\n if (int_point_cur2.id === -1)\n continue;\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n }\n\n int_point_ref2 = intersections.int_points2_sorted[0];\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n for (let i = 1; i < intersections.int_points2_sorted.length; i++) {\n let int_point_cur2 = intersections.int_points2_sorted[i];\n\n if (int_point_cur2.id === -1) continue;\n /* already deleted */\n\n if (int_point_ref2.id === -1 || /* can't be reference if already deleted */\n !(EQ(int_point_cur2.arc_length, int_point_ref2.arc_length))) {\n int_point_ref2 = int_point_cur2;\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n continue;\n }\n\n let int_point_cur1 = intersections.int_points1[int_point_cur2.id];\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n\n if (do_squeeze) {\n intersections.int_points1 = intersections.int_points1.filter((int_point) => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter((int_point) => int_point.id >= 0);\n\n // update id's\n intersections.int_points1.forEach((int_point, index) => int_point.id = index);\n intersections.int_points2.forEach((int_point, index) => int_point.id = index);\n }\n}\n\nfunction initializeInclusionFlags(int_points)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_before.bvStart = undefined;\n int_point.edge_before.bvEnd = undefined;\n int_point.edge_before.bv = undefined;\n int_point.edge_before.overlap = undefined;\n }\n\n if (int_point.edge_after) {\n int_point.edge_after.bvStart = undefined;\n int_point.edge_after.bvEnd = undefined;\n int_point.edge_after.bv = undefined;\n int_point.edge_after.overlap = undefined;\n }\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.bvEnd = BOUNDARY$1;\n if (int_point.edge_after) int_point.edge_after.bvStart = BOUNDARY$1;\n }\n}\n\nfunction calculateInclusionFlags(int_points, polygon)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.setInclusion(polygon);\n if (int_point.edge_after) int_point.edge_after.setInclusion(polygon);\n }\n}\n\nfunction setOverlappingFlags(intersections)\n{\n let cur_face = undefined;\n let first_int_point_in_face_id = undefined;\n let next_int_point1 = undefined;\n let num_int_points = intersections.int_points1.length;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = intersections.int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(intersections.int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n intersections.int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(intersections.int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = intersections.int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n intersections.int_points2[next_int_point1_tmp.id].face === intersections.int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n if (!(edge_from1.bv === BOUNDARY$1 && edge_to1.bv === BOUNDARY$1)) // not a boundary chain - skip\n continue;\n\n if (edge_from1 !== edge_to1) // one edge chain TODO: support complex case\n continue;\n\n /* Find boundary chain in polygon2 between same intersection points */\n let cur_int_point2 = intersections.int_points2[cur_int_point1.id];\n let next_int_point2 = intersections.int_points2[next_int_point1.id];\n\n let edge_from2 = cur_int_point2.edge_after;\n let edge_to2 = next_int_point2.edge_before;\n\n /* if [edge_from2..edge_to2] is not a boundary chain, invert it */\n /* check also that chain consist of one or two edges */\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2)) {\n cur_int_point2 = intersections.int_points2[next_int_point1.id];\n next_int_point2 = intersections.int_points2[cur_int_point1.id];\n\n edge_from2 = cur_int_point2.edge_after;\n edge_to2 = next_int_point2.edge_before;\n }\n\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2))\n continue; // not an overlapping chain - skip TODO: fix boundary conflict\n\n // Set overlapping flag - one-to-one case\n edge_from1.setOverlap(edge_from2);\n }\n}\n\nfunction intPointsPoolCount(int_points, cur_int_point_num, cur_face)\n{\n let int_point_current;\n let int_point_next;\n\n let int_points_pool_num = 1;\n\n if (int_points.length === 1) return 1;\n\n int_point_current = int_points[cur_int_point_num];\n\n for (let i = cur_int_point_num + 1; i < int_points.length; i++) {\n if (int_point_current.face !== cur_face) { /* next face started */\n break;\n }\n\n int_point_next = int_points[i];\n\n if (!(int_point_next.pt.equalTo(int_point_current.pt) &&\n int_point_next.edge_before === int_point_current.edge_before &&\n int_point_next.edge_after === int_point_current.edge_after)) {\n break; /* next point is different - break and exit */\n }\n\n int_points_pool_num++; /* duplicated intersection point - increase counter */\n }\n return int_points_pool_num;\n}\n\nfunction splitByIntersections(polygon, int_points)\n{\n if (!int_points) return;\n for (let int_point of int_points) {\n let edge = int_point.edge_before;\n\n // recalculate vertex flag: it may be changed after previous split\n int_point.is_vertex = NOT_VERTEX$1;\n if (edge.shape.start && edge.shape.start.equalTo(int_point.pt)) {\n int_point.is_vertex |= START_VERTEX$1;\n }\n if (edge.shape.end && edge.shape.end.equalTo(int_point.pt)) {\n int_point.is_vertex |= END_VERTEX$1;\n }\n\n if (int_point.is_vertex & START_VERTEX$1) { // nothing to split\n if (edge.prev) {\n int_point.edge_before = edge.prev; // polygon\n int_point.is_vertex = END_VERTEX$1;\n }\n else { // multiline start vertex\n int_point.edge_after = int_point.edge_before;\n int_point.edge_before = edge.prev;\n }\n continue;\n }\n if (int_point.is_vertex & END_VERTEX$1) { // nothing to split\n continue;\n }\n\n let newEdge = polygon.addVertex(int_point.pt, edge);\n int_point.edge_before = newEdge;\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_after = int_point.edge_before.next;\n }\n }\n}\n\nfunction insertBetweenIntPoints(int_point1, int_point2, new_edges) {\n const edge_before = int_point1.edge_before;\n const edge_after = int_point2.edge_after;\n const len = new_edges.length;\n edge_before.next = new_edges[0];\n new_edges[0].prev = edge_before;\n\n new_edges[len-1].next = edge_after;\n edge_after.prev = new_edges[len-1];\n}\n\nvar smart_intersections = /*#__PURE__*/Object.freeze({\n __proto__: null,\n addToIntPoints: addToIntPoints,\n calculateInclusionFlags: calculateInclusionFlags,\n filterDuplicatedIntersections: filterDuplicatedIntersections,\n getSortedArray: getSortedArray,\n initializeInclusionFlags: initializeInclusionFlags,\n insertBetweenIntPoints: insertBetweenIntPoints,\n intPointsPoolCount: intPointsPoolCount,\n setOverlappingFlags: setOverlappingFlags,\n sortIntersections: sortIntersections,\n splitByIntersections: splitByIntersections\n});\n\n/**\n * Created by Alex Bol on 12/02/2018.\n */\n/**\n * @module BooleanOperations\n */\n\nconst {INSIDE: INSIDE$1, OUTSIDE, BOUNDARY, OVERLAP_SAME, OVERLAP_OPPOSITE} = Constants;\nconst {NOT_VERTEX, START_VERTEX, END_VERTEX} = Constants;\n\nconst BOOLEAN_UNION = 1;\nconst BOOLEAN_INTERSECT = 2;\nconst BOOLEAN_SUBTRACT = 3;\n\n\n/**\n * Unify two polygons polygons and returns new polygon.
\n * Point belongs to the resulted polygon if it belongs to the first OR to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction unify(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_UNION, true);\n return res_poly;\n}\n\n/**\n * Subtract second polygon from the first and returns new polygon\n * Point belongs to the resulted polygon if it belongs to the first polygon AND NOT to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction subtract(polygon1, polygon2) {\n let polygon2_tmp = polygon2.clone();\n let polygon2_reversed = polygon2_tmp.reverse();\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2_reversed, BOOLEAN_SUBTRACT, true);\n return res_poly;\n}\n\n/**\n * Intersect two polygons and returns new polygon\n * Point belongs to the resulted polygon is it belongs to the first AND to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction intersect$1(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, true);\n return res_poly;\n}\n\n/**\n * Returns boundary of intersection between two polygons as two arrays of shapes (Segments/Arcs)
\n * The first array are shapes from the first polygon, the second array are shapes from the second\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[][]}\n */\nfunction innerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n let clip_shapes2 = [];\n for (let face of wrk_poly.faces) {\n clip_shapes2 = [...clip_shapes2, ...[...face.edges].map(edge => edge.shape)];\n }\n return [clip_shapes1, clip_shapes2];\n}\n\n/**\n * Returns boundary of subtraction of the second polygon from first polygon as array of shapes\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[]}\n */\nfunction outerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_SUBTRACT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n\n return clip_shapes1;\n}\n\n/**\n * Returns intersection points between boundaries of two polygons as two array of points
\n * Points in the first array belong to first polygon, points from the second - to the second.\n * Points in each array are ordered according to the direction of the correspondent polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Point[][]}\n */\nfunction calculateIntersections(polygon1, polygon2) {\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n let ip_sorted1 = intersections.int_points1_sorted.map( int_point => int_point.pt);\n let ip_sorted2 = intersections.int_points2_sorted.map( int_point => int_point.pt);\n return [ip_sorted1, ip_sorted2];\n}\n\nfunction filterNotRelevantEdges(res_poly, wrk_poly, intersections, op) {\n // keep not intersected faces for further remove and merge\n let notIntersectedFacesRes = getNotIntersectedFaces(res_poly, intersections.int_points1);\n let notIntersectedFacesWrk = getNotIntersectedFaces(wrk_poly, intersections.int_points2);\n\n // calculate inclusion flag for not intersected faces\n calcInclusionForNotIntersectedFaces(notIntersectedFacesRes, wrk_poly);\n calcInclusionForNotIntersectedFaces(notIntersectedFacesWrk, res_poly);\n\n // initialize inclusion flags for edges incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n initializeInclusionFlags(intersections.int_points2);\n\n // calculate inclusion flags only for edges incident to intersections\n calculateInclusionFlags(intersections.int_points1, wrk_poly);\n calculateInclusionFlags(intersections.int_points2, res_poly);\n\n // fix boundary conflicts\n while (fixBoundaryConflicts(res_poly, wrk_poly, intersections.int_points1, intersections.int_points1_sorted, intersections.int_points2, intersections));\n // while (fixBoundaryConflicts(wrk_poly, res_poly, intersections.int_points2, intersections.int_points2_sorted, intersections.int_points1, intersections));\n\n // Set overlapping flags for boundary chains: SAME or OPPOSITE\n setOverlappingFlags(intersections);\n\n // remove not relevant chains between intersection points\n removeNotRelevantChains(res_poly, op, intersections.int_points1_sorted, true);\n removeNotRelevantChains(wrk_poly, op, intersections.int_points2_sorted, false);\n\n // remove not relevant not intersected faces from res_polygon and wrk_polygon\n // if op == UNION, remove faces that are included in wrk_polygon without intersection\n // if op == INTERSECT, remove faces that are not included into wrk_polygon\n removeNotRelevantNotIntersectedFaces(res_poly, notIntersectedFacesRes, op, true);\n removeNotRelevantNotIntersectedFaces(wrk_poly, notIntersectedFacesWrk, op, false);\n}\n\nfunction swapLinksAndRestore(res_poly, wrk_poly, intersections, op) {\n\n // add edges of wrk_poly into the edge container of res_poly\n copyWrkToRes(res_poly, wrk_poly, op, intersections.int_points2);\n\n // swap links from res_poly to wrk_poly and vice versa\n swapLinks(res_poly, wrk_poly, intersections);\n\n // remove old faces\n removeOldFaces(res_poly, intersections.int_points1);\n removeOldFaces(wrk_poly, intersections.int_points2);\n\n // restore faces\n restoreFaces(res_poly, intersections.int_points1, intersections.int_points2);\n restoreFaces(res_poly, intersections.int_points2, intersections.int_points1);\n\n // merge relevant not intersected faces from wrk_polygon to res_polygon\n // mergeRelevantNotIntersectedFaces(res_poly, wrk_poly);\n}\n\n\nfunction booleanOpBinary(polygon1, polygon2, op, restore)\n{\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n // calculate inclusion and remove not relevant edges\n filterNotRelevantEdges(res_poly, wrk_poly, intersections, op);\n\n if (restore) {\n swapLinksAndRestore(res_poly, wrk_poly, intersections, op);\n }\n\n return [res_poly, wrk_poly];\n}\n\nfunction getIntersections(polygon1, polygon2)\n{\n let intersections = {\n int_points1: [],\n int_points2: []\n };\n\n // calculate intersections\n for (let edge1 of polygon1.edges) {\n\n // request edges of polygon2 in the box of edge1\n let resp = polygon2.edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n return intersections;\n}\n\nfunction getNotIntersectedFaces(poly, int_points)\n{\n let notIntersected = [];\n for (let face of poly.faces) {\n if (!int_points.find((ip) => ip.face === face)) {\n notIntersected.push(face);\n }\n }\n return notIntersected;\n}\n\nfunction calcInclusionForNotIntersectedFaces(notIntersectedFaces, poly2)\n{\n for (let face of notIntersectedFaces) {\n face.first.bv = face.first.bvStart = face.first.bvEnd = undefined;\n face.first.setInclusion(poly2);\n }\n}\n\nfunction fixBoundaryConflicts(poly1, poly2, int_points1, int_points1_sorted, int_points2, intersections )\n{\n let cur_face;\n let first_int_point_in_face_id;\n let next_int_point1;\n let num_int_points = int_points1_sorted.length;\n let iterate_more = false;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n int_points2[next_int_point1_tmp.id].face === int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n // Case #1. One of the ends is not boundary - probably tiny edge wrongly marked as boundary\n if (edge_from1.bv === BOUNDARY && edge_to1.bv != BOUNDARY) {\n edge_from1.bv = edge_to1.bv;\n continue;\n }\n\n if (edge_from1.bv != BOUNDARY && edge_to1.bv === BOUNDARY) {\n edge_to1.bv = edge_from1.bv;\n continue;\n }\n\n // Set up all boundary values for middle edges. Need for cases 2 and 3\n if ( (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) ||\n (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) ) {\n let edge_tmp = edge_from1.next;\n while (edge_tmp != edge_to1) {\n edge_tmp.bvStart = undefined;\n edge_tmp.bvEnd = undefined;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n edge_tmp = edge_tmp.next;\n }\n }\n\n // Case #2. Both of the ends boundary. Check all the edges in the middle\n // If some edges in the middle are not boundary then update bv of 'from' and 'to' edges\n if (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) {\n let edge_tmp = edge_from1.next;\n let new_bv;\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bv != BOUNDARY) {\n if (new_bv === undefined) { // first not boundary edge between from and to\n new_bv = edge_tmp.bv;\n }\n else { // another not boundary edge between from and to\n if (edge_tmp.bv != new_bv) { // and it has different bv - can't resolve conflict\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n if (new_bv != undefined) {\n edge_from1.bv = new_bv;\n edge_to1.bv = new_bv;\n }\n continue; // all middle edges are boundary, proceed with this\n }\n\n // Case 3. One of the ends is inner, another is outer\n if (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) {\n let edge_tmp = edge_from1;\n // Find missing intersection point\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bvStart === edge_from1.bv && edge_tmp.bvEnd === edge_to1.bv) {\n let [dist, segment] = edge_tmp.shape.distanceTo(poly2);\n if (dist < 10*Flatten.DP_TOL) { // it should be very close\n // let pt = edge_tmp.end;\n // add to the list of intersections of poly1\n addToIntPoints(edge_tmp, segment.ps, int_points1);\n\n // split edge_tmp in poly1 if need\n let int_point1 = int_points1[int_points1.length-1];\n if (int_point1.is_vertex & START_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp;\n int_point1.edge_before = edge_tmp.prev;\n edge_tmp.bvStart = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else if (int_point1.is_vertex & END_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp.next;\n edge_tmp.bvEnd = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else { // split edge here\n let newEdge1 = poly2.addVertex(int_point1.pt, edge_tmp);\n int_point1.edge_before = newEdge1;\n int_point1.edge_after = newEdge1.next;\n\n newEdge1.setInclusion(poly2);\n\n newEdge1.next.bvStart = BOUNDARY;\n newEdge1.next.bvEnd = undefined;\n newEdge1.next.bv = undefined;\n newEdge1.next.setInclusion(poly2);\n }\n\n // add to the list of intersections of poly2\n let edge2 = poly2.findEdgeByPoint(segment.pe);\n addToIntPoints(edge2, segment.pe, int_points2);\n // split edge2 in poly2 if need\n let int_point2 = int_points2[int_points2.length-1];\n if (int_point2.is_vertex & START_VERTEX) { // nothing to split\n int_point2.edge_after = edge2;\n int_point2.edge_before = edge2.prev;\n }\n else if (int_point2.is_vertex & END_VERTEX) { // nothing to split\n int_point2.edge_after = edge2.next;\n }\n else { // split edge here\n // first locate int_points that may refer to edge2 as edge.after\n // let int_point2_edge_before = int_points2.find( int_point => int_point.edge_before === edge2)\n let int_point2_edge_after = int_points2.find( int_point => int_point.edge_after === edge2 );\n\n let newEdge2 = poly2.addVertex(int_point2.pt, edge2);\n int_point2.edge_before = newEdge2;\n int_point2.edge_after = newEdge2.next;\n\n if (int_point2_edge_after)\n int_point2_edge_after.edge_after = newEdge2;\n\n newEdge2.bvStart = undefined;\n newEdge2.bvEnd = BOUNDARY;\n newEdge2.bv = undefined;\n newEdge2.setInclusion(poly1);\n\n newEdge2.next.bvStart = BOUNDARY;\n newEdge2.next.bvEnd = undefined;\n newEdge2.next.bv = undefined;\n newEdge2.next.setInclusion(poly1);\n }\n\n sortIntersections(intersections);\n\n iterate_more = true;\n break;\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n // we changed intersections inside loop, have to exit and repair again\n if (iterate_more)\n break;\n\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n\n return iterate_more;\n}\n\nfunction removeNotRelevantChains(polygon, op, int_points, is_res_polygon)\n{\n if (!int_points) return;\n let cur_face = undefined;\n let first_int_point_in_face_num = undefined;\n let int_point_current;\n let int_point_next;\n\n for (let i = 0; i < int_points.length; i++) {\n int_point_current = int_points[i];\n\n if (int_point_current.face !== cur_face) { // next face started\n first_int_point_in_face_num = i;\n cur_face = int_point_current.face;\n }\n\n if (cur_face.isEmpty()) // ??\n continue;\n\n // Get next int point from the same face that current\n\n // Count how many duplicated points with same in \"points from\" pool ?\n let int_points_from_pull_start = i;\n let int_points_from_pull_num = intPointsPoolCount(int_points, i, cur_face);\n let next_int_point_num;\n if (int_points_from_pull_start + int_points_from_pull_num < int_points.length &&\n int_points[int_points_from_pull_start + int_points_from_pull_num].face === int_point_current.face) {\n next_int_point_num = int_points_from_pull_start + int_points_from_pull_num;\n } else { // get first point from the same face\n next_int_point_num = first_int_point_in_face_num;\n }\n int_point_next = int_points[next_int_point_num];\n\n /* Count how many duplicated points with same in \"points to\" pull ? */\n let int_points_to_pull_start = next_int_point_num;\n let int_points_to_pull_num = intPointsPoolCount(int_points, int_points_to_pull_start, cur_face);\n\n\n let edge_from = int_point_current.edge_after;\n let edge_to = int_point_next.edge_before;\n\n if ((edge_from.bv === INSIDE$1 && edge_to.bv === INSIDE$1 && op === BOOLEAN_UNION) ||\n (edge_from.bv === OUTSIDE && edge_to.bv === OUTSIDE && op === BOOLEAN_INTERSECT) ||\n ((edge_from.bv === OUTSIDE || edge_to.bv === OUTSIDE) && op === BOOLEAN_SUBTRACT && !is_res_polygon) ||\n ((edge_from.bv === INSIDE$1 || edge_to.bv === INSIDE$1) && op === BOOLEAN_SUBTRACT && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_SAME) && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_OPPOSITE))) {\n\n polygon.removeChain(cur_face, edge_from, edge_to);\n\n /* update all points in \"points from\" pull */\n for (let k = int_points_from_pull_start; k < int_points_from_pull_start + int_points_from_pull_num; k++) {\n int_points[k].edge_after = undefined;\n }\n\n /* update all points in \"points to\" pull */\n for (let k = int_points_to_pull_start; k < int_points_to_pull_start + int_points_to_pull_num; k++) {\n int_points[k].edge_before = undefined;\n }\n }\n\n /* skip to the last point in \"points from\" group */\n i += int_points_from_pull_num - 1;\n }\n}\nfunction copyWrkToRes(res_polygon, wrk_polygon, op, int_points)\n{\n for (let face of wrk_polygon.faces) {\n for (let edge of face) {\n res_polygon.edges.add(edge);\n }\n // If union - add face from wrk_polygon that is not intersected with res_polygon\n if ( /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/\n int_points.find((ip) => (ip.face === face)) === undefined) {\n res_polygon.addFace(face.first, face.last);\n }\n }\n}\n\nfunction swapLinks(res_polygon, wrk_polygon, intersections)\n{\n if (intersections.int_points1.length === 0) return;\n\n for (let i = 0; i < intersections.int_points1.length; i++) {\n let int_point1 = intersections.int_points1[i];\n let int_point2 = intersections.int_points2[i];\n\n // Simple case - find continuation on the other polygon\n\n // Process edge from res_polygon\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // swap need\n if (int_point2.edge_before === undefined && int_point2.edge_after !== undefined) { // simple case\n // Connect edges\n int_point1.edge_before.next = int_point2.edge_after;\n int_point2.edge_after.prev = int_point1.edge_before;\n\n // Fill in missed links in intersection points\n int_point1.edge_after = int_point2.edge_after;\n int_point2.edge_before = int_point1.edge_before;\n }\n }\n // Process edge from wrk_polygon\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // swap need\n if (int_point1.edge_before === undefined && int_point1.edge_after !== undefined) { // simple case\n // Connect edges\n int_point2.edge_before.next = int_point1.edge_after;\n int_point1.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point1.edge_after;\n int_point1.edge_before = int_point2.edge_before;\n }\n }\n\n // Continuation not found - complex case\n // Continuation will be found on the same polygon.\n // It happens when intersection point is actually touching point\n // Polygon1\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points1_sorted) {\n if (int_point === int_point1) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point1.pt)) {\n // Connect edges\n int_point1.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point1.edge_before;\n\n // Complete missed links\n int_point1.edge_after = int_point.edge_after;\n int_point.edge_before = int_point1.edge_before;\n }\n }\n }\n }\n // Polygon2\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points2_sorted) {\n if (int_point === int_point2) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point2.pt)) {\n // Connect edges\n int_point2.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point.edge_after;\n int_point.edge_before = int_point2.edge_before;\n }\n }\n }\n }\n }\n // Sanity check that no dead ends left\n}\n\nfunction removeOldFaces(polygon, int_points)\n{\n for (let int_point of int_points) {\n polygon.faces.delete(int_point.face);\n int_point.face = undefined;\n if (int_point.edge_before)\n int_point.edge_before.face = undefined;\n if (int_point.edge_after)\n int_point.edge_after.face = undefined;\n }\n}\n\nfunction restoreFaces(polygon, int_points, other_int_points)\n{\n // For each intersection point - create new face\n for (let int_point of int_points) {\n if (int_point.edge_before === undefined || int_point.edge_after === undefined) // completely deleted\n continue;\n if (int_point.face) // already restored\n continue;\n\n if (int_point.edge_after.face || int_point.edge_before.face) // Face already created. Possible case in duplicated intersection points\n continue;\n\n let first = int_point.edge_after; // face start\n let last = int_point.edge_before; // face end;\n\n try {\n LinkedList.testInfiniteLoop(first); // check and throw error if infinite loop found\n }\n catch (error) {\n throw Errors.CANNOT_COMPLETE_BOOLEAN_OPERATION\n }\n\n let face = polygon.addFace(first, last);\n\n // Mark intersection points from the newly create face\n // to avoid multiple creation of the same face.\n // Face was assigned to each edge of new face in addFace function\n for (let int_point_tmp of int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n // Mark other intersection points as well\n for (let int_point_tmp of other_int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n }\n}\n\nfunction removeNotRelevantNotIntersectedFaces(polygon, notIntersectedFaces, op, is_res_polygon)\n{\n for (let face of notIntersectedFaces) {\n let rel = face.first.bv;\n if (op === BOOLEAN_UNION && rel === INSIDE$1 ||\n op === BOOLEAN_SUBTRACT && rel === INSIDE$1 && is_res_polygon ||\n op === BOOLEAN_SUBTRACT && rel === OUTSIDE && !is_res_polygon ||\n op === BOOLEAN_INTERSECT && rel === OUTSIDE) {\n\n polygon.deleteFace(face);\n }\n }\n}\n\nvar BooleanOperations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOOLEAN_INTERSECT: BOOLEAN_INTERSECT,\n BOOLEAN_SUBTRACT: BOOLEAN_SUBTRACT,\n BOOLEAN_UNION: BOOLEAN_UNION,\n calculateIntersections: calculateIntersections,\n innerClip: innerClip,\n intersect: intersect$1,\n outerClip: outerClip,\n removeNotRelevantChains: removeNotRelevantChains,\n removeOldFaces: removeOldFaces,\n restoreFaces: restoreFaces,\n subtract: subtract,\n unify: unify\n});\n\n/*\n Dimensionally extended 9-intersected model\n See https://en.wikipedia.org/wiki/DE-9IM for more details\n */\n// const DISJOINT = RegExp('FF.FF....');\nconst EQUAL = RegExp('T.F..FFF.|T.F...F..');\nconst INTERSECT = RegExp('T........|.T.......|...T.....|....T....');\nconst TOUCH = RegExp('FT.......|F..T.....|F...T....');\nconst INSIDE = RegExp('T.F..F...');\nconst COVERED = RegExp('T.F..F...|.TF..F...|..FT.F...|..F.TF...');\n\nclass DE9IM {\n /**\n * Create new instance of DE9IM matrix\n */\n constructor() {\n /**\n * Array representing 3x3 intersection matrix\n * @type {Shape[]}\n */\n this.m = new Array(9).fill(undefined);\n }\n\n /**\n * Get Interior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get I2I() {\n return this.m[0];\n }\n\n /**\n * Set Interior To Interior intersection\n * @param geom\n */\n set I2I(geom) {\n this.m[0] = geom;\n }\n\n /**\n * Get Interior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get I2B() {\n return this.m[1];\n }\n\n /**\n * Set Interior to Boundary intersection\n * @param geomc\n */\n set I2B(geom) {\n this.m[1] = geom;\n }\n\n /**\n * Get Interior To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get I2E() {\n return this.m[2];\n }\n\n /**\n * Set Interior to Exterior intersection\n * @param geom\n */\n set I2E(geom) {\n this.m[2] = geom;\n }\n\n /**\n * Get Boundary To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get B2I() {\n return this.m[3];\n }\n\n /**\n * Set Boundary to Interior intersection\n * @param geom\n */\n set B2I(geom) {\n this.m[3] = geom;\n }\n\n /**\n * Get Boundary To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get B2B() {\n return this.m[4];\n }\n\n /**\n * Set Boundary to Boundary intersection\n * @param geom\n */\n set B2B(geom) {\n this.m[4] = geom;\n }\n\n /**\n * Get Boundary To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get B2E() {\n return this.m[5];\n }\n\n /**\n * Set Boundary to Exterior intersection\n * @param geom\n */\n set B2E(geom) {\n this.m[5] = geom;\n }\n\n /**\n * Get Exterior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get E2I() {\n return this.m[6];\n }\n\n /**\n * Set Exterior to Interior intersection\n * @param geom\n */\n set E2I(geom) {\n this.m[6] = geom;\n }\n\n /**\n * Get Exterior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get E2B() {\n return this.m[7];\n }\n\n /**\n * Set Exterior to Boundary intersection\n * @param geom\n */\n set E2B(geom) {\n this.m[7] = geom;\n }\n\n /**\n * Get Exterior to Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get E2E() {\n return this.m[8];\n }\n\n /**\n * Set Exterior to Exterior intersection\n * @param geom\n */\n set E2E(geom) {\n this.m[8] = geom;\n }\n\n /**\n * Return de9im matrix as string where
\n * - intersection is 'T'
\n * - not intersected is 'F'
\n * - not relevant is '*'
\n * For example, string 'FF**FF****' means 'DISJOINT'\n * @returns {string}\n */\n toString() {\n return this.m.map( e => {\n if (e instanceof Array && e.length > 0) {\n return 'T'\n }\n else if (e instanceof Array && e.length === 0) {\n return 'F'\n }\n else {\n return '*'\n }\n }).join(\"\")\n }\n\n equal() {\n return EQUAL.test(this.toString());\n }\n\n intersect() {\n return INTERSECT.test(this.toString());\n }\n\n touch() {\n return TOUCH.test(this.toString());\n }\n\n inside() {\n return INSIDE.test(this.toString());\n }\n\n covered() {\n return COVERED.test(this.toString());\n }\n}\n\n/**\n * Intersection\n *\n * */\n\n\nfunction intersectLine2Line(line1, line2) {\n let ip = [];\n\n let [A1, B1, C1] = line1.standard;\n let [A2, B2, C2] = line2.standard;\n\n /* Cramer's rule */\n let det = A1 * B2 - B1 * A2;\n let detX = C1 * B2 - B1 * C2;\n let detY = A1 * C2 - C1 * A2;\n\n if (!Flatten.Utils.EQ_0(det)) {\n let x, y;\n\n if (B1 === 0) { // vertical line x = C1/A1, where A1 == +1 or -1\n x = C1/A1;\n y = detY / det;\n }\n else if (B2 === 0) { // vertical line x = C2/A2, where A2 = +1 or -1\n x = C2/A2;\n y = detY / det;\n }\n else if (A1 === 0) { // horizontal line y = C1/B1, where B1 = +1 or -1\n x = detX / det;\n y = C1/B1;\n }\n else if (A2 === 0) { // horizontal line y = C2/B2, where B2 = +1 or -1\n x = detX / det;\n y = C2/B2;\n }\n else {\n x = detX / det;\n y = detY / det;\n }\n\n ip.push(new Flatten.Point(x, y));\n }\n\n return ip;\n}\n\nfunction intersectLine2Circle(line, circle) {\n let ip = [];\n let prj = circle.pc.projectionOn(line); // projection of circle center on a line\n let dist = circle.pc.distanceTo(prj)[0]; // distance from circle center to projection\n\n if (Flatten.Utils.EQ(dist, circle.r)) { // line tangent to circle - return single intersection point\n ip.push(prj);\n } else if (Flatten.Utils.LT(dist, circle.r)) { // return two intersection points\n let delta = Math.sqrt(circle.r * circle.r - dist * dist);\n let v_trans, pt;\n\n v_trans = line.norm.rotate90CCW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n\n v_trans = line.norm.rotate90CW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n }\n return ip;\n}\n\nfunction intersectLine2Box(line, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Line(seg, line);\n for (let pt of ips_tmp) {\n if (!ptInIntPoints(pt, ips)) {\n ips.push(pt);\n }\n }\n }\n return ips;\n}\n\nfunction intersectLine2Arc(line, arc) {\n let ip = [];\n\n if (intersectLine2Box(line, arc.box).length === 0) {\n return ip;\n }\n\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectLine2Circle(line, circle);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectSegment2Line(seg, line) {\n let ip = [];\n\n // Boundary cases\n if (seg.ps.on(line)) {\n ip.push(seg.ps);\n }\n // If both ends lay on line, return two intersection points\n if (seg.pe.on(line) && !seg.isZeroLength()) {\n ip.push(seg.pe);\n }\n\n if (ip.length > 0) {\n return ip; // done, intersection found\n }\n\n // If zero-length segment and nothing found, return no intersections\n if (seg.isZeroLength()) {\n return ip;\n }\n\n // Not a boundary case, check if both points are on the same side and\n // hence there is no intersection\n if (seg.ps.leftTo(line) && seg.pe.leftTo(line) ||\n !seg.ps.leftTo(line) && !seg.pe.leftTo(line)) {\n return ip;\n }\n\n // Calculate intersection between lines\n let line1 = new Flatten.Line(seg.ps, seg.pe);\n return intersectLine2Line(line1, line);\n}\n\nfunction intersectSegment2Segment(seg1, seg2) {\n let ip = [];\n\n // quick reject\n if (seg1.box.not_intersect(seg2.box)) {\n return ip;\n }\n\n // Special case of seg1 zero length\n if (seg1.isZeroLength()) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n return ip;\n }\n\n // Special case of seg2 zero length\n if (seg2.isZeroLength()) {\n if (seg2.ps.on(seg1)) {\n ip.push(seg2.ps);\n }\n return ip;\n }\n\n // Neither seg1 nor seg2 is zero length\n let line1 = new Flatten.Line(seg1.ps, seg1.pe);\n let line2 = new Flatten.Line(seg2.ps, seg2.pe);\n\n // Check overlapping between segments in case of incidence\n // If segments touching, add one point. If overlapping, add two points\n if (line1.incidentTo(line2)) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n if (seg1.pe.on(seg2)) {\n ip.push(seg1.pe);\n }\n if (seg2.ps.on(seg1) && !seg2.ps.equalTo(seg1.ps) && !seg2.ps.equalTo(seg1.pe)) {\n ip.push(seg2.ps);\n }\n if (seg2.pe.on(seg1) && !seg2.pe.equalTo(seg1.ps) && !seg2.pe.equalTo(seg1.pe)) {\n ip.push(seg2.pe);\n }\n } else { /* not incident - parallel or intersect */\n // Calculate intersection between lines\n let new_ip = intersectLine2Line(line1, line2);\n if (new_ip.length > 0) {\n if (isPointInSegmentBox(new_ip[0], seg1) && isPointInSegmentBox(new_ip[0], seg2)) {\n ip.push(new_ip[0]);\n }\n }\n }\n return ip;\n}\n\nfunction isPointInSegmentBox(point, segment) {\n const box = segment.box;\n return Flatten.Utils.LE(point.x, box.xmax) && Flatten.Utils.GE(point.x, box.xmin) &&\n Flatten.Utils.LE(point.y, box.ymax) && Flatten.Utils.GE(point.y, box.ymin)\n}\n\nfunction intersectSegment2Circle(segment, circle) {\n let ips = [];\n\n if (segment.box.not_intersect(circle.box)) {\n return ips;\n }\n\n // Special case of zero length segment\n if (segment.isZeroLength()) {\n let [dist, _] = segment.ps.distanceTo(circle.pc);\n if (Flatten.Utils.EQ(dist, circle.r)) {\n ips.push(segment.ps);\n }\n return ips;\n }\n\n // Non zero-length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n\n let ips_tmp = intersectLine2Circle(line, circle);\n\n for (let ip of ips_tmp) {\n if (ip.on(segment)) {\n ips.push(ip);\n }\n }\n\n return ips;\n}\n\nfunction intersectSegment2Arc(segment, arc) {\n let ip = [];\n\n if (segment.box.not_intersect(arc.box)) {\n return ip;\n }\n\n // Special case of zero-length segment\n if (segment.isZeroLength()) {\n if (segment.ps.on(arc)) {\n ip.push(segment.ps);\n }\n return ip;\n }\n\n // Non-zero length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n let ip_tmp = intersectLine2Circle(line, circle);\n\n for (let pt of ip_tmp) {\n if (pt.on(segment) && pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n\n}\n\nfunction intersectSegment2Box(segment, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Segment(seg, segment);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectCircle2Circle(circle1, circle2) {\n let ip = [];\n\n if (circle1.box.not_intersect(circle2.box)) {\n return ip;\n }\n\n let vec = new Flatten.Vector(circle1.pc, circle2.pc);\n\n let r1 = circle1.r;\n let r2 = circle2.r;\n\n // Degenerated circle\n if (Flatten.Utils.EQ_0(r1) || Flatten.Utils.EQ_0(r2))\n return ip;\n\n // In case of equal circles return one leftmost point\n if (Flatten.Utils.EQ_0(vec.x) && Flatten.Utils.EQ_0(vec.y) && Flatten.Utils.EQ(r1, r2)) {\n ip.push(circle1.pc.translate(-r1, 0));\n return ip;\n }\n\n let dist = circle1.pc.distanceTo(circle2.pc)[0];\n\n if (Flatten.Utils.GT(dist, r1 + r2)) // circles too far, no intersections\n return ip;\n\n if (Flatten.Utils.LT(dist, Math.abs(r1 - r2))) // one circle is contained within another, no intersections\n return ip;\n\n // Normalize vector.\n vec.x /= dist;\n vec.y /= dist;\n\n let pt;\n\n // Case of touching from outside or from inside - single intersection point\n // TODO: check this specifically not sure if correct\n if (Flatten.Utils.EQ(dist, r1 + r2) || Flatten.Utils.EQ(dist, Math.abs(r1 - r2))) {\n pt = circle1.pc.translate(r1 * vec.x, r1 * vec.y);\n ip.push(pt);\n return ip;\n }\n\n // Case of two intersection points\n\n // Distance from first center to center of common chord:\n // a = (r1^2 - r2^2 + d^2) / 2d\n // Separate for better accuracy\n let a = (r1 * r1) / (2 * dist) - (r2 * r2) / (2 * dist) + dist / 2;\n\n let mid_pt = circle1.pc.translate(a * vec.x, a * vec.y);\n let h = Math.sqrt(r1 * r1 - a * a);\n // let norm;\n\n // norm = vec.rotate90CCW().multiply(h);\n pt = mid_pt.translate(vec.rotate90CCW().multiply(h));\n ip.push(pt);\n\n // norm = vec.rotate90CW();\n pt = mid_pt.translate(vec.rotate90CW().multiply(h));\n ip.push(pt);\n\n return ip;\n}\n\nfunction intersectCircle2Box(circle, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Circle(seg, circle);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectArc2Arc(arc1, arc2) {\n let ip = [];\n\n if (arc1.box.not_intersect(arc2.box)) {\n return ip;\n }\n\n // Special case: overlapping arcs\n // May return up to 4 intersection points\n if (arc1.pc.equalTo(arc2.pc) && Flatten.Utils.EQ(arc1.r, arc2.r)) {\n let pt;\n\n pt = arc1.start;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc1.end;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc2.start;\n if (pt.on(arc1)) ip.push(pt);\n\n pt = arc2.end;\n if (pt.on(arc1)) ip.push(pt);\n\n return ip;\n }\n\n // Common case\n let circle1 = new Flatten.Circle(arc1.pc, arc1.r);\n let circle2 = new Flatten.Circle(arc2.pc, arc2.r);\n let ip_tmp = circle1.intersect(circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc1) && pt.on(arc2)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Circle(arc, circle) {\n let ip = [];\n\n if (arc.box.not_intersect(circle.box)) {\n return ip;\n }\n\n // Case when arc center incident to circle center\n // Return arc's end points as 2 intersection points\n if (circle.pc.equalTo(arc.pc) && Flatten.Utils.EQ(circle.r, arc.r)) {\n ip.push(arc.start);\n ip.push(arc.end);\n return ip;\n }\n\n // Common case\n let circle1 = circle;\n let circle2 = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectCircle2Circle(circle1, circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Box(arc, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Arc(seg, arc);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectEdge2Segment(edge, segment) {\n return edge.isSegment ? intersectSegment2Segment(edge.shape, segment) : intersectSegment2Arc(segment, edge.shape);\n}\n\nfunction intersectEdge2Arc(edge, arc) {\n return edge.isSegment ? intersectSegment2Arc(edge.shape, arc) : intersectArc2Arc(edge.shape, arc);\n}\n\nfunction intersectEdge2Line(edge, line) {\n return edge.isSegment ? intersectSegment2Line(edge.shape, line) : intersectLine2Arc(line, edge.shape);\n}\n\nfunction intersectEdge2Ray(edge, ray) {\n return edge.isSegment ? intersectRay2Segment(ray, edge.shape) : intersectRay2Arc(ray, edge.shape);\n}\n\nfunction intersectEdge2Circle(edge, circle) {\n return edge.isSegment ? intersectSegment2Circle(edge.shape, circle) : intersectArc2Circle(edge.shape, circle);\n}\n\nfunction intersectSegment2Polygon(segment, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Segment(edge, segment)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectArc2Polygon(arc, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Arc(edge, arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectLine2Polygon(line, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Line(edge, line)) {\n if (!ptInIntPoints(pt, ip)) {\n ip.push(pt);\n }\n }\n }\n\n return line.sortPoints(ip);\n}\n\nfunction intersectCircle2Polygon(circle, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Circle(edge, circle)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectEdge2Edge(edge1, edge2) {\n if (edge1.isSegment) {\n return intersectEdge2Segment(edge2, edge1.shape)\n }\n else if (edge1.isArc) {\n return intersectEdge2Arc(edge2, edge1.shape)\n }\n else if (edge1.isLine) {\n return intersectEdge2Line(edge2, edge1.shape)\n }\n else if (edge1.isRay) {\n return intersectEdge2Ray(edge2, edge1.shape)\n }\n return []\n}\n\nfunction intersectEdge2Polygon(edge, polygon) {\n let ip = [];\n\n if (polygon.isEmpty() || edge.shape.box.not_intersect(polygon.box)) {\n return ip;\n }\n\n let resp_edges = polygon.edges.search(edge.shape.box);\n\n for (let resp_edge of resp_edges) {\n ip = [...ip, ...intersectEdge2Edge(edge, resp_edge)];\n }\n\n return ip;\n}\n\nfunction intersectPolygon2Polygon(polygon1, polygon2) {\n let ip = [];\n\n if (polygon1.isEmpty() || polygon2.isEmpty()) {\n return ip;\n }\n\n if (polygon1.box.not_intersect(polygon2.box)) {\n return ip;\n }\n\n for (let edge1 of polygon1.edges) {\n ip = [...ip, ...intersectEdge2Polygon(edge1, polygon2)];\n }\n\n return ip;\n}\n\nfunction intersectShape2Polygon(shape, polygon) {\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, polygon);\n }\n else {\n return [];\n }\n}\n\nfunction ptInIntPoints(new_pt, ip) {\n return ip.some( pt => pt.equalTo(new_pt) )\n}\n\nfunction createLineFromRay(ray) {\n return new Flatten.Line(ray.start, ray.norm)\n}\nfunction intersectRay2Segment(ray, segment) {\n return intersectSegment2Line(segment, createLineFromRay(ray))\n .filter(pt => ray.contains(pt));\n}\n\nfunction intersectRay2Arc(ray, arc) {\n return intersectLine2Arc(createLineFromRay(ray), arc)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Circle(ray, circle) {\n return intersectLine2Circle(createLineFromRay(ray), circle)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Box(ray, box) {\n return intersectLine2Box(createLineFromRay(ray), box)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Line(ray, line) {\n return intersectLine2Line(createLineFromRay(ray), line)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Ray(ray1, ray2) {\n return intersectLine2Line(createLineFromRay(ray1), createLineFromRay(ray2))\n .filter(pt => ray1.contains(pt))\n .filter(pt => ray2.contains(pt))\n}\n\nfunction intersectRay2Polygon(ray, polygon) {\n return intersectLine2Polygon(createLineFromRay(ray), polygon)\n .filter(pt => ray.contains(pt))\n}\n\nconst defaultAttributes = {\n stroke: \"black\"\n};\n\nclass SVGAttributes {\n constructor(args = defaultAttributes) {\n for(const property in args) {\n this[property] = args[property];\n }\n this.stroke = args.stroke ?? defaultAttributes.stroke;\n }\n\n toAttributesString() {\n return Object.keys(this)\n .reduce( (acc, key) =>\n acc + (this[key] !== undefined ? this.toAttrString(key, this[key]) : \"\")\n , ``)\n }\n\n toAttrString(key, value) {\n const SVGKey = key === \"className\" ? \"class\" : this.convertCamelToKebabCase(key);\n return value === null ? `${SVGKey} ` : `${SVGKey}=\"${value.toString()}\" `\n }\n\n convertCamelToKebabCase(str) {\n return str\n .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)\n .join('-')\n .toLowerCase();\n }\n}\n\nfunction convertToString(attrs) {\n return new SVGAttributes(attrs).toAttributesString()\n}\n\n/**\n * Class Multiline represent connected path of [edges]{@link Flatten.Edge}, where each edge may be\n * [segment]{@link Flatten.Segment}, [arc]{@link Flatten.Arc}, [line]{@link Flatten.Line} or [ray]{@link Flatten.Ray}\n */\nclass Multiline extends LinkedList {\n constructor(...args) {\n super();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n let shapes = args[0];\n if (shapes.length === 0)\n return;\n\n // TODO: more strict validation:\n // there may be only one line\n // only first and last may be rays\n shapes.every((shape) => {\n return shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc ||\n shape instanceof Flatten.Ray ||\n shape instanceof Flatten.Line\n });\n\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n }\n\n this.setArcLength();\n }\n }\n }\n\n /**\n * (Getter) Return array of edges\n * @returns {Edge[]}\n */\n get edges() {\n return [...this];\n }\n\n /**\n * (Getter) Return bounding box of the multiline\n * @returns {Box}\n */\n get box() {\n return this.edges.reduce( (acc,edge) => acc.merge(edge.box), new Flatten.Box() );\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Point[]}\n */\n get vertices() {\n let v = this.edges.map(edge => edge.start);\n v.push(this.last.end);\n return v;\n }\n\n /**\n * Return new cloned instance of Multiline\n * @returns {Multiline}\n */\n clone() {\n return new Multiline(this.toShapes());\n }\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Split edge and add new vertex, return new edge inserted\n * @param {Point} pt - point on edge that will be added as new vertex\n * @param {Edge} edge - edge to split\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n this.insert(newEdge, edgeBefore); // edge.face ?\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n return newEdge;\n }\n\n getChain(edgeFrom, edgeTo) {\n let edges = [];\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n edges.push(edge);\n }\n return edges\n }\n\n /**\n * Split edges of multiline with intersection points and return mutated multiline\n * @param {Point[]} ip - array of points to be added as new vertices\n * @returns {Multiline}\n */\n split(ip) {\n for (let pt of ip) {\n let edge = this.findEdgeByPoint(pt);\n this.addVertex(pt, edge);\n }\n return this;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new multiline translated by vector vec\n * @param {Vector} vec\n * @returns {Multiline}\n */\n translate(vec) {\n return new Multiline(this.edges.map( edge => edge.shape.translate(vec)));\n }\n\n /**\n * Return new multiline rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Multiline} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n return new Multiline(this.edges.map( edge => edge.shape.rotate(angle, center) ));\n }\n\n /**\n * Return new multiline transformed using affine transformation matrix\n * Method does not support unbounded shapes\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Multiline} - new multiline\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Multiline(this.edges.map( edge => edge.shape.transform(matrix)));\n }\n\n /**\n * Transform multiline into array of shapes\n * @returns {Shape[]}\n */\n toShapes() {\n return this.edges.map(edge => edge.shape.clone())\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Return string to draw multiline in svg\n * @param attrs - an object with attributes for svg path element\n * TODO: support semi-infinite Ray and infinite Line\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Multiline = Multiline;\n\n/**\n * Shortcut function to create multiline\n * @param args\n */\nconst multiline = (...args) => new Flatten.Multiline(...args);\nFlatten.multiline = multiline;\n\n/**\n * @module RayShoot\n */\n/**\n * Implements ray shooting algorithm. Returns relation between point and polygon: inside, outside or boundary\n * @param {Polygon} polygon - polygon to test\n * @param {Point} point - point to test\n * @returns {INSIDE|OUTSIDE|BOUNDARY}\n */\nfunction ray_shoot(polygon, point) {\n let contains = undefined;\n\n // 1. Quick reject\n // if (polygon.box.not_intersect(point.box)) {\n // return Flatten.OUTSIDE;\n // }\n\n let ray = new Flatten.Ray(point);\n let line = new Flatten.Line(ray.pt, ray.norm);\n\n // 2. Locate relevant edges of the polygon\n const searchBox = new Flatten.Box(\n ray.box.xmin-Flatten.DP_TOL, ray.box.ymin-Flatten.DP_TOL,\n ray.box.xmax, ray.box.ymax+Flatten.DP_TOL\n );\n\n if (polygon.box.not_intersect(searchBox)) {\n return Flatten.OUTSIDE;\n }\n\n let resp_edges = polygon.edges.search(searchBox);\n\n if (resp_edges.length == 0) {\n return Flatten.OUTSIDE;\n }\n\n // 2.5 Check if boundary\n for (let edge of resp_edges) {\n if (edge.shape.contains(point)) {\n return Flatten.BOUNDARY;\n }\n }\n\n // 3. Calculate intersections\n let intersections = [];\n for (let edge of resp_edges) {\n for (let ip of ray.intersect(edge.shape)) {\n\n // If intersection is equal to query point then point lays on boundary\n if (ip.equalTo(point)) {\n return Flatten.BOUNDARY;\n }\n\n intersections.push({\n pt: ip,\n edge: edge\n });\n }\n }\n\n // 4. Sort intersection in x-ascending order\n intersections.sort((i1, i2) => {\n if (LT(i1.pt.x, i2.pt.x)) {\n return -1;\n }\n if (GT(i1.pt.x, i2.pt.x)) {\n return 1;\n }\n return 0;\n });\n\n // 5. Count real intersections, exclude touching\n let counter = 0;\n\n for (let i = 0; i < intersections.length; i++) {\n let intersection = intersections[i];\n if (intersection.pt.equalTo(intersection.edge.shape.start)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.edge.prev === intersections[i - 1].edge) {\n continue;\n }\n let prev_edge = intersection.edge.prev;\n while (EQ_0(prev_edge.length)) {\n prev_edge = prev_edge.prev;\n }\n let prev_tangent = prev_edge.shape.tangentInEnd();\n let prev_point = intersection.pt.translate(prev_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInStart();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let prev_on_the_left = prev_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((prev_on_the_left && !cur_on_the_left) || (!prev_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else if (intersection.pt.equalTo(intersection.edge.shape.end)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.edge.next === intersections[i - 1].edge) {\n continue;\n }\n let next_edge = intersection.edge.next;\n while (EQ_0(next_edge.length)) {\n next_edge = next_edge.next;\n }\n let next_tangent = next_edge.shape.tangentInStart();\n let next_point = intersection.pt.translate(next_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInEnd();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let next_on_the_left = next_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((next_on_the_left && !cur_on_the_left) || (!next_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else { /* intersection point is not a coincident with a vertex */\n if (intersection.edge.shape instanceof Flatten.Segment) {\n counter++;\n } else {\n /* Check if ray does not touch the curve in the extremal (top or bottom) point */\n let box = intersection.edge.shape.box;\n if (!(EQ(intersection.pt.y, box.ymin) ||\n EQ(intersection.pt.y, box.ymax))) {\n counter++;\n }\n }\n }\n }\n\n // 6. Odd or even?\n contains = counter % 2 == 1 ? INSIDE$2 : OUTSIDE$1;\n\n return contains;\n}\n\n/*\n Calculate relationship between two shapes and return result in the form of\n Dimensionally Extended nine-Intersection Matrix (https://en.wikipedia.org/wiki/DE-9IM)\n */\n\n\n/**\n * Returns true if shapes are topologically equal: their interiors intersect and\n * no part of the interior or boundary of one geometry intersects the exterior of the other\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction equal(shape1, shape2) {\n return relate(shape1, shape2).equal();\n}\n\n/**\n * Returns true if shapes have at least one point in common, same as \"not disjoint\"\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction intersect(shape1, shape2) {\n return relate(shape1, shape2).intersect();\n}\n\n/**\n * Returns true if shapes have at least one point in common, but their interiors do not intersect\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction touch(shape1, shape2) {\n return relate(shape1, shape2).touch();\n}\n\n/**\n * Returns true if shapes have no points in common neither in interior nor in boundary\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction disjoint(shape1, shape2) {\n return !intersect(shape1, shape2);\n}\n\n/**\n * Returns true shape1 lies in the interior of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction inside(shape1, shape2) {\n return relate(shape1, shape2).inside();\n}\n\n/**\n * Returns true if every point in shape1 lies in the interior or on the boundary of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction covered(shape1, shape2) {\n return relate(shape1, shape2).covered();\n}\n\n/**\n * Returns true shape1's interior contains shape2
\n * Same as inside(shape2, shape1)\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction contain(shape1, shape2) {\n return inside(shape2, shape1);\n}\n\n/**\n * Returns true shape1's cover shape2, same as shape2 covered by shape1\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction cover(shape1, shape2) {\n return covered(shape2, shape1);\n}\n\n/**\n * Returns relation between two shapes as intersection 3x3 matrix, where each\n * element contains relevant intersection as array of shapes.\n * If there is no intersection, element contains empty array\n * If intersection is irrelevant it left undefined. (For example, intersection\n * between two exteriors is usually irrelevant)\n * @param shape1\n * @param shape2\n * @returns {DE9IM}\n */\nfunction relate(shape1, shape2) {\n if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Line) {\n return relateLine2Line(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Circle) {\n return relateLine2Circle(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Box) {\n return relateLine2Box(shape1, shape2);\n }\n else if ( shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Polygon) {\n return relateLine2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) && shape2 instanceof Flatten.Polygon) {\n return relateShape2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box) ) {\n return relateShape2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n else if (shape1 instanceof Flatten.Polygon && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(shape1, shape2);\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), new Flatten.Polygon(shape2));\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), shape2);\n }\n else if (shape1 instanceof Flatten.Polygon && (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n}\n\nfunction relateLine2Line(line1, line2) {\n let denim = new DE9IM();\n let ip = intersectLine2Line(line1, line2);\n if (ip.length === 0) { // parallel or equal ?\n if (line1.contains(line2.pt) && line2.contains(line1.pt)) {\n denim.I2I = [line1]; // equal 'T.F...F..' - no boundary\n denim.I2E = [];\n denim.E2I = [];\n }\n else { // parallel - disjoint 'FFTFF*T**'\n denim.I2I = [];\n denim.I2E = [line1];\n denim.E2I = [line2];\n }\n }\n else { // intersect 'T********'\n denim.I2I = ip;\n denim.I2E = line1.split(ip);\n denim.E2I = line2.split(ip);\n }\n return denim;\n}\n\nfunction relateLine2Circle(line,circle) {\n let denim = new DE9IM();\n let ip = intersectLine2Circle(line, circle);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n denim.E2I = [circle];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [circle];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n denim.I2I = [splitShapes[1]];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon([circle.toArc()]).cutWithLine(line);\n }\n\n return denim;\n}\n\nfunction relateLine2Box(line, box) {\n let denim = new DE9IM();\n let ip = intersectLine2Box(line, box);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n\n denim.E2I = [box];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [box];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n /* Are two intersection points on the same segment of the box boundary ? */\n if (box.toSegments().some( segment => segment.contains(ip[0]) && segment.contains(ip[1]) )) {\n denim.I2I = []; // case of touching\n denim.I2B = [splitShapes[1]];\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = [box];\n }\n else { // case of intersection\n denim.I2I = [splitShapes[1]]; // [segment(ip[0], ip[1])];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon(box.toSegments()).cutWithLine(line);\n }\n }\n return denim;\n}\n\nfunction relateLine2Polygon(line, polygon) {\n let denim = new DE9IM();\n let ip = intersectLine2Polygon(line, polygon);\n let multiline = new Multiline([line]);\n let ip_sorted = ip.length > 0 ? ip.slice() : line.sortPoints(ip);\n\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n denim.E2I = polygon.cutWithLine(line);\n\n return denim;\n}\n\nfunction relateShape2Polygon(shape, polygon) {\n let denim = new DE9IM();\n let ip = intersectShape2Polygon(shape, polygon);\n let ip_sorted = ip.length > 0 ? ip.slice() : shape.sortPoints(ip);\n\n let multiline = new Multiline([shape]);\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n\n denim.B2I = [];\n denim.B2B = [];\n denim.B2E = [];\n for (let pt of [shape.start, shape.end]) {\n switch (ray_shoot(polygon, pt)) {\n case Flatten.INSIDE:\n denim.B2I.push(pt);\n break;\n case Flatten.BOUNDARY:\n denim.B2B.push(pt);\n break;\n case Flatten.OUTSIDE:\n denim.B2E.push(pt);\n break;\n }\n }\n\n // denim.E2I TODO: calculate, not clear what is expected result\n\n return denim;\n}\n\nfunction relatePolygon2Polygon(polygon1, polygon2) {\n let denim = new DE9IM();\n\n let [ip_sorted1, ip_sorted2] = calculateIntersections(polygon1, polygon2);\n let boolean_intersection = intersect$1(polygon1, polygon2);\n let boolean_difference1 = subtract(polygon1, polygon2);\n let boolean_difference2 = subtract(polygon2, polygon1);\n let [inner_clip_shapes1, inner_clip_shapes2] = innerClip(polygon1, polygon2);\n let outer_clip_shapes1 = outerClip(polygon1, polygon2);\n let outer_clip_shapes2 = outerClip(polygon2, polygon1);\n\n denim.I2I = boolean_intersection.isEmpty() ? [] : [boolean_intersection];\n denim.I2B = inner_clip_shapes2;\n denim.I2E = boolean_difference1.isEmpty() ? [] : [boolean_difference1];\n\n denim.B2I = inner_clip_shapes1;\n denim.B2B = ip_sorted1;\n denim.B2E = outer_clip_shapes1;\n\n denim.E2I = boolean_difference2.isEmpty() ? [] : [boolean_difference2];\n denim.E2B = outer_clip_shapes2;\n // denim.E2E not relevant meanwhile\n\n return denim;\n}\n\nvar Relations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n contain: contain,\n cover: cover,\n covered: covered,\n disjoint: disjoint,\n equal: equal,\n inside: inside,\n intersect: intersect,\n relate: relate,\n touch: touch\n});\n\n/**\n * Class representing an affine transformation 3x3 matrix:\n *
\n *      [ a  c  tx\n * A =    b  d  ty\n *        0  0  1  ]\n * \n     * If parameters omitted, construct identity matrix a = 1, d = 1\n     * @param {number} a - position(0,0)   sx*cos(alpha)\n     * @param {number} b - position (0,1)  sx*sin(alpha)\n     * @param {number} c - position (1,0)  -sy*sin(alpha)\n     * @param {number} d - position (1,1)  sy*cos(alpha)\n     * @param {number} tx - position (2,0) translation by x\n     * @param {number} ty - position (2,1) translation by y\n     */\n    constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) {\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.tx = tx;\n        this.ty = ty;\n    }\n\n    /**\n     * Return new cloned instance of matrix\n     * @return {Matrix}\n     **/\n    clone() {\n        return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);\n    };\n\n    /**\n     * Transform vector [x,y] using transformation matrix. 
\n * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object
\n * The result is also an abstract vector [x',y'] = A * [x,y]:\n * \n * [x' [ ax + by + tx\n * y' = cx + dy + ty\n * 1] 1 ]\n * \n * @param {number[]} vector - array[2] of numbers\n * @returns {number[]} transformation result - array[2] of numbers\n */\n transform(vector) {\n return [\n vector[0] * this.a + vector[1] * this.c + this.tx,\n vector[0] * this.b + vector[1] * this.d + this.ty\n ]\n };\n\n /**\n * Returns result of multiplication of this matrix by other matrix\n * @param {Matrix} other_matrix - matrix to multiply by\n * @returns {Matrix}\n */\n multiply(other_matrix) {\n return new Matrix(\n this.a * other_matrix.a + this.c * other_matrix.b,\n this.b * other_matrix.a + this.d * other_matrix.b,\n this.a * other_matrix.c + this.c * other_matrix.d,\n this.b * other_matrix.c + this.d * other_matrix.d,\n this.a * other_matrix.tx + this.c * other_matrix.ty + this.tx,\n this.b * other_matrix.tx + this.d * other_matrix.ty + this.ty\n )\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix(1,0,0,1,tx,ty)\n * @param {Vector} vector - Translation by vector or\n * @param {number} tx - translation by x-axis\n * @param {number} ty - translation by y-axis\n * @returns {Matrix}\n */\n translate(...args) {\n let tx, ty;\n if (args.length == 1 && !isNaN(args[0].x) && !isNaN(args[0].y)) {\n tx = args[0].x;\n ty = args[0].y;\n } else if (args.length === 2 && typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n tx = args[0];\n ty = args[1];\n } else {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n return this.multiply(new Matrix(1, 0, 0, 1, tx, ty))\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix that defines rotation by given angle (in radians) around\n * center of rotation (centerX,centerY) in counterclockwise direction\n * @param {number} angle - angle in radians\n * @param {number} centerX - center of rotation\n * @param {number} centerY - center of rotation\n * @returns {Matrix}\n */\n rotate(angle, centerX = 0.0, centerY = 0.0) {\n let cos = Math.cos(angle);\n let sin = Math.sin(angle);\n return this\n .translate(centerX, centerY)\n .multiply(new Matrix(cos, sin, -sin, cos, 0, 0))\n .translate(-centerX, -centerY);\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix (sx,0,0,sy,0,0) that defines scaling\n * @param {number} sx\n * @param {number} sy\n * @returns {Matrix}\n */\n scale(sx, sy) {\n return this.multiply(new Matrix(sx, 0, 0, sy, 0, 0));\n };\n\n /**\n * Returns true if two matrix are equal parameter by parameter\n * @param {Matrix} matrix - other matrix\n * @returns {boolean} true if equal, false otherwise\n */\n equalTo(matrix) {\n if (!Flatten.Utils.EQ(this.tx, matrix.tx)) return false;\n if (!Flatten.Utils.EQ(this.ty, matrix.ty)) return false;\n if (!Flatten.Utils.EQ(this.a, matrix.a)) return false;\n if (!Flatten.Utils.EQ(this.b, matrix.b)) return false;\n if (!Flatten.Utils.EQ(this.c, matrix.c)) return false;\n if (!Flatten.Utils.EQ(this.d, matrix.d)) return false;\n return true;\n };\n}\nFlatten.Matrix = Matrix;\n/**\n * Function to create matrix equivalent to \"new\" constructor\n * @param args\n */\nconst matrix = (...args) => new Flatten.Matrix(...args);\nFlatten.matrix = matrix;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n/**\n * Interval is a pair of numbers or a pair of any comparable objects on which may be defined predicates\n * *equal*, *less* and method *max(p1, p1)* that returns maximum in a pair.\n * When interval is an object rather than pair of numbers, this object should have properties *low*, *high*, *max*\n * and implement methods *less_than(), equal_to(), intersect(), not_intersect(), clone(), output()*.\n * Two static methods *comparable_max(), comparable_less_than()* define how to compare values in pair.
\n * This interface is described in typescript definition file *index.d.ts*\n *\n * Axis aligned rectangle is an example of such interval.\n * We may look at rectangle as an interval between its low left and top right corners.\n * See **Box** class in [flatten-js](https://github.com/alexbol99/flatten-js) library as the example\n * of Interval interface implementation\n * @type {Interval}\n */\nconst Interval = class Interval {\n /**\n * Accept two comparable values and creates new instance of interval\n * Predicate Interval.comparable_less(low, high) supposed to return true on these values\n * @param low\n * @param high\n */\n constructor(low, high) {\n this.low = low;\n this.high = high;\n }\n\n /**\n * Clone interval\n * @returns {Interval}\n */\n clone() {\n return new Interval(this.low, this.high);\n }\n\n /**\n * Propery max returns clone of this interval\n * @returns {Interval}\n */\n get max() {\n return this.clone(); // this.high;\n }\n\n /**\n * Predicate returns true is this interval less than other interval\n * @param other_interval\n * @returns {boolean}\n */\n less_than(other_interval) {\n return this.low < other_interval.low ||\n this.low == other_interval.low && this.high < other_interval.high;\n }\n\n /**\n * Predicate returns true is this interval equals to other interval\n * @param other_interval\n * @returns {boolean}\n */\n equal_to(other_interval) {\n return this.low == other_interval.low && this.high == other_interval.high;\n }\n\n /**\n * Predicate returns true if this interval intersects other interval\n * @param other_interval\n * @returns {boolean}\n */\n intersect(other_interval) {\n return !this.not_intersect(other_interval);\n }\n\n /**\n * Predicate returns true if this interval does not intersect other interval\n * @param other_interval\n * @returns {boolean}\n */\n not_intersect(other_interval) {\n return (this.high < other_interval.low || other_interval.high < this.low);\n }\n\n /**\n * Returns new interval merged with other interval\n * @param {Interval} interval - Other interval to merge with\n * @returns {Interval}\n */\n merge(other_interval) {\n return new Interval(\n this.low === undefined ? other_interval.low : Math.min(this.low, other_interval.low),\n this.high === undefined ? other_interval.high : Math.max(this.high, other_interval.high)\n );\n }\n\n /**\n * Returns how key should return\n */\n output() {\n return [this.low, this.high];\n }\n\n /**\n * Function returns maximum between two comparable values\n * @param interval1\n * @param interval2\n * @returns {Interval}\n */\n static comparable_max(interval1, interval2) {\n return interval1.merge(interval2);\n }\n\n /**\n * Predicate returns true if first value less than second value\n * @param val1\n * @param val2\n * @returns {boolean}\n */\n static comparable_less_than(val1, val2 ) {\n return val1 < val2;\n }\n};\n\n/**\n * Created by Alex Bol on 3/28/2017.\n */\n\n\n// module.exports = {\n// RB_TREE_COLOR_RED: 0,\n// RB_TREE_COLOR_BLACK: 1\n// };\n\nconst RB_TREE_COLOR_RED = 0;\nconst RB_TREE_COLOR_BLACK = 1;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n\nclass Node {\n constructor(key = undefined, value = undefined,\n left = null, right = null, parent = null, color = RB_TREE_COLOR_BLACK) {\n this.left = left; // reference to left child node\n this.right = right; // reference to right child node\n this.parent = parent; // reference to parent node\n this.color = color;\n\n this.item = {key: key, value: value}; // key is supposed to be instance of Interval\n\n /* If not, this should by an array of two numbers */\n if (key && key instanceof Array && key.length == 2) {\n if (!Number.isNaN(key[0]) && !Number.isNaN(key[1])) {\n this.item.key = new Interval(Math.min(key[0], key[1]), Math.max(key[0], key[1]));\n }\n }\n\n this.max = this.item.key ? this.item.key.max : undefined;\n }\n\n isNil() {\n return (this.item.key === undefined && this.item.value === undefined &&\n this.left === null && this.right === null && this.color === RB_TREE_COLOR_BLACK);\n }\n\n _value_less_than(other_node) {\n return this.item.value && other_node.item.value && this.item.value.less_than ?\n this.item.value.less_than(other_node.item.value) :\n this.item.value < other_node.item.value;\n }\n\n less_than(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.less_than(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.less_than(other_node.item.key) ||\n this.item.key.equal_to((other_node.item.key)) && this._value_less_than(other_node)\n }\n }\n\n _value_equal(other_node) {\n return this.item.value && other_node.item.value && this.item.value.equal_to ?\n this.item.value.equal_to(other_node.item.value) :\n this.item.value == other_node.item.value;\n }\n equal_to(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.equal_to(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.equal_to(other_node.item.key) && this._value_equal(other_node);\n }\n }\n\n intersect(other_node) {\n return this.item.key.intersect(other_node.item.key);\n }\n\n copy_data(other_node) {\n this.item.key = other_node.item.key;\n this.item.value = other_node.item.value;\n }\n\n update_max() {\n // use key (Interval) max property instead of key.high\n this.max = this.item.key ? this.item.key.max : undefined;\n if (this.right && this.right.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.right.max);\n }\n if (this.left && this.left.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.left.max);\n }\n }\n\n // Other_node does not intersect any node of left subtree, if this.left.max < other_node.item.key.low\n not_intersect_left_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let high = this.left.max.high !== undefined ? this.left.max.high : this.left.max;\n return comparable_less_than(high, search_node.item.key.low);\n }\n\n // Other_node does not intersect right subtree if other_node.item.key.high < this.right.key.low\n not_intersect_right_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let low = this.right.max.low !== undefined ? this.right.max.low : this.right.item.key.low;\n return comparable_less_than(search_node.item.key.high, low);\n }\n}\n\n/**\n * Created by Alex Bol on 3/31/2017.\n */\n\n// const nil_node = new Node();\n\n/**\n * Implementation of interval binary search tree
\n * Interval tree stores items which are couples of {key:interval, value: value}
\n * Interval is an object with high and low properties or simply pair [low,high] of numeric values
\n * @type {IntervalTree}\n */\nclass IntervalTree {\n /**\n * Construct new empty instance of IntervalTree\n */\n constructor() {\n this.root = null;\n this.nil_node = new Node();\n }\n\n /**\n * Returns number of items stored in the interval tree\n * @returns {number}\n */\n get size() {\n let count = 0;\n this.tree_walk(this.root, () => count++);\n return count;\n }\n\n /**\n * Returns array of sorted keys in the ascending order\n * @returns {Array}\n */\n get keys() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(\n node.item.key.output ? node.item.key.output() : node.item.key\n ));\n return res;\n }\n\n /**\n * Return array of values in the ascending keys order\n * @returns {Array}\n */\n get values() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(node.item.value));\n return res;\n }\n\n /**\n * Returns array of items ( pairs) in the ascended keys order\n * @returns {Array}\n */\n get items() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push({\n key: node.item.key.output ? node.item.key.output() : node.item.key,\n value: node.item.value\n }));\n return res;\n }\n\n /**\n * Returns true if tree is empty\n * @returns {boolean}\n */\n isEmpty() {\n return (this.root == null || this.root == this.nil_node);\n }\n\n /**\n * Clear tree\n */\n clear() {\n this.root = null;\n }\n\n /**\n * Insert new item into interval tree\n * @param {Interval} key - interval object or array of two numbers [low, high]\n * @param {any} value - value representing any object (optional)\n * @returns {Node} returns reference to inserted node as an object {key:interval, value: value}\n */\n insert(key, value = key) {\n if (key === undefined) return;\n let insert_node = new Node(key, value, this.nil_node, this.nil_node, null, RB_TREE_COLOR_RED);\n this.tree_insert(insert_node);\n this.recalc_max(insert_node);\n return insert_node;\n }\n\n /**\n * Returns true if item {key,value} exist in the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object to be checked\n * @returns {boolean} true if item {key, value} exist in the tree, false otherwise\n */\n exist(key, value = key) {\n let search_node = new Node(key, value);\n return this.tree_search(this.root, search_node) ? true : false;\n }\n\n /**\n * Remove entry {key, value} from the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object\n * @returns {boolean} true if item {key, value} deleted, false if not found\n */\n remove(key, value = key) {\n let search_node = new Node(key, value);\n let delete_node = this.tree_search(this.root, search_node);\n if (delete_node) {\n this.tree_delete(delete_node);\n }\n return delete_node;\n }\n\n /**\n * Returns array of entry values which keys intersect with given interval
\n * If no values stored in the tree, returns array of keys which intersect given interval\n * @param {Interval} interval - search interval, or tuple [low, high]\n * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output\n * @returns {Array}\n */\n search(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {\n let search_node = new Node(interval);\n let resp_nodes = [];\n this.tree_search_interval(this.root, search_node, resp_nodes);\n return resp_nodes.map(node => outputMapperFn(node.item.value, node.item.key))\n }\n\n /**\n * Returns true if intersection between given and any interval stored in the tree found\n * @param {Interval} interval - search interval or tuple [low, high]\n * @returns {boolean}\n */\n intersect_any(interval) {\n let search_node = new Node(interval);\n let found = this.tree_find_any_interval(this.root, search_node);\n return found;\n }\n\n /**\n * Tree visitor. For each node implement a callback function.
\n * Method calls a callback function with two parameters (key, value)\n * @param visitor(key,value) - function to be called for each tree item\n */\n forEach(visitor) {\n this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));\n }\n\n /** Value Mapper. Walk through every node and map node value to another value\n * @param callback(value,key) - function to be called for each tree item\n */\n map(callback) {\n const tree = new IntervalTree();\n this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));\n return tree;\n }\n\n recalc_max(node) {\n let node_current = node;\n while (node_current.parent != null) {\n node_current.parent.update_max();\n node_current = node_current.parent;\n }\n }\n\n tree_insert(insert_node) {\n let current_node = this.root;\n let parent_node = null;\n\n if (this.root == null || this.root == this.nil_node) {\n this.root = insert_node;\n }\n else {\n while (current_node != this.nil_node) {\n parent_node = current_node;\n if (insert_node.less_than(current_node)) {\n current_node = current_node.left;\n }\n else {\n current_node = current_node.right;\n }\n }\n\n insert_node.parent = parent_node;\n\n if (insert_node.less_than(parent_node)) {\n parent_node.left = insert_node;\n }\n else {\n parent_node.right = insert_node;\n }\n }\n\n this.insert_fixup(insert_node);\n }\n\n// After insertion insert_node may have red-colored parent, and this is a single possible violation\n// Go upwords to the root and re-color until violation will be resolved\n insert_fixup(insert_node) {\n let current_node;\n let uncle_node;\n\n current_node = insert_node;\n while (current_node != this.root && current_node.parent.color == RB_TREE_COLOR_RED) {\n if (current_node.parent == current_node.parent.parent.left) { // parent is left child of grandfather\n uncle_node = current_node.parent.parent.right; // right brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 1. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else { // Case 2 & 3. Uncle is black\n if (current_node == current_node.parent.right) { // Case 2. Current if right child\n // This case is transformed into Case 3.\n current_node = current_node.parent;\n this.rotate_left(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 3. Current is left child.\n // Re-color father and grandfather, rotate grandfather right\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_right(current_node.parent.parent);\n }\n }\n else { // parent is right child of grandfather\n uncle_node = current_node.parent.parent.left; // left brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 4. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else {\n if (current_node == current_node.parent.left) { // Case 5. Current is left child\n // Transform into case 6\n current_node = current_node.parent;\n this.rotate_right(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 6. Current is right child.\n // Re-color father and grandfather, rotate grandfather left\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_left(current_node.parent.parent);\n }\n }\n }\n\n this.root.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_delete(delete_node) {\n let cut_node; // node to be cut - either delete_node or successor_node (\"y\" from 14.4)\n let fix_node; // node to fix rb tree property (\"x\" from 14.4)\n\n if (delete_node.left == this.nil_node || delete_node.right == this.nil_node) { // delete_node has less then 2 children\n cut_node = delete_node;\n }\n else { // delete_node has 2 children\n cut_node = this.tree_successor(delete_node);\n }\n\n // fix_node if single child of cut_node\n if (cut_node.left != this.nil_node) {\n fix_node = cut_node.left;\n }\n else {\n fix_node = cut_node.right;\n }\n\n // remove cut_node from parent\n /*if (fix_node != this.nil_node) {*/\n fix_node.parent = cut_node.parent;\n /*}*/\n\n if (cut_node == this.root) {\n this.root = fix_node;\n }\n else {\n if (cut_node == cut_node.parent.left) {\n cut_node.parent.left = fix_node;\n }\n else {\n cut_node.parent.right = fix_node;\n }\n cut_node.parent.update_max(); // update max property of the parent\n }\n\n this.recalc_max(fix_node); // update max property upward from fix_node to root\n\n // COPY DATA !!!\n // Delete_node becomes cut_node, it means that we cannot hold reference\n // to node in outer structure and we will have to delete by key, additional search need\n if (cut_node != delete_node) {\n delete_node.copy_data(cut_node);\n delete_node.update_max(); // update max property of the cut node at the new place\n this.recalc_max(delete_node); // update max property upward from delete_node to root\n }\n\n if (/*fix_node != this.nil_node && */cut_node.color == RB_TREE_COLOR_BLACK) {\n this.delete_fixup(fix_node);\n }\n }\n\n delete_fixup(fix_node) {\n let current_node = fix_node;\n let brother_node;\n\n while (current_node != this.root && current_node.parent != null && current_node.color == RB_TREE_COLOR_BLACK) {\n if (current_node == current_node.parent.left) { // fix node is left child\n brother_node = current_node.parent.right;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_left(current_node.parent);\n brother_node = current_node.parent.right; // update brother\n }\n // Derive to cases 2..4: brother is black\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2: both nephews black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 3: left nephew red, right nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.left.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_right(brother_node);\n brother_node = current_node.parent.right; // update brother\n // Derive to case 4: left nephew black, right nephew red\n }\n // case 4: left nephew black, right nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.right.color = RB_TREE_COLOR_BLACK;\n this.rotate_left(current_node.parent);\n current_node = this.root; // exit from loop\n }\n }\n else { // fix node is right child\n brother_node = current_node.parent.left;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_right(current_node.parent);\n brother_node = current_node.parent.left; // update brother\n }\n // Go to cases 2..4\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.left.color == RB_TREE_COLOR_BLACK) { // case 3: right nephew red, left nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.right.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_left(brother_node);\n brother_node = current_node.parent.left; // update brother\n // Derive to case 4: right nephew black, left nephew red\n }\n // case 4: right nephew black, left nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.left.color = RB_TREE_COLOR_BLACK;\n this.rotate_right(current_node.parent);\n current_node = this.root; // force exit from loop\n }\n }\n }\n\n current_node.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_search(node, search_node) {\n if (node == null || node == this.nil_node)\n return undefined;\n\n if (search_node.equal_to(node)) {\n return node;\n }\n if (search_node.less_than(node)) {\n return this.tree_search(node.left, search_node);\n }\n else {\n return this.tree_search(node.right, search_node);\n }\n }\n\n // Original search_interval method; container res support push() insertion\n // Search all intervals intersecting given one\n tree_search_interval(node, search_node, res) {\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n this.tree_search_interval(node.left, search_node, res);\n }\n // if (low <= node->high && node->low <= high) {\n if (node.intersect(search_node)) {\n res.push(node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n this.tree_search_interval(node.right, search_node, res);\n }\n }\n }\n\n tree_find_any_interval(node, search_node) {\n let found = false;\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n found = this.tree_find_any_interval(node.left, search_node);\n }\n // if (low <= node->high && node->low <= high) {\n if (!found) {\n found = node.intersect(search_node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (!found && node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n found = this.tree_find_any_interval(node.right, search_node);\n }\n }\n return found;\n }\n\n local_minimum(node) {\n let node_min = node;\n while (node_min.left != null && node_min.left != this.nil_node) {\n node_min = node_min.left;\n }\n return node_min;\n }\n\n // not in use\n local_maximum(node) {\n let node_max = node;\n while (node_max.right != null && node_max.right != this.nil_node) {\n node_max = node_max.right;\n }\n return node_max;\n }\n\n tree_successor(node) {\n let node_successor;\n let current_node;\n let parent_node;\n\n if (node.right != this.nil_node) {\n node_successor = this.local_minimum(node.right);\n }\n else {\n current_node = node;\n parent_node = node.parent;\n while (parent_node != null && parent_node.right == current_node) {\n current_node = parent_node;\n parent_node = parent_node.parent;\n }\n node_successor = parent_node;\n }\n return node_successor;\n }\n\n // | right-rotate(T,y) |\n // y ---------------. x\n // / \\ / \\\n // x c left-rotate(T,x) a y\n // / \\ <--------------- / \\\n // a b b c\n\n rotate_left(x) {\n let y = x.right;\n\n x.right = y.left; // b goes to x.right\n\n if (y.left != this.nil_node) {\n y.left.parent = x; // x becomes parent of b\n }\n y.parent = x.parent; // move parent\n\n if (x == this.root) {\n this.root = y; // y becomes root\n }\n else { // y becomes child of x.parent\n if (x == x.parent.left) {\n x.parent.left = y;\n }\n else {\n x.parent.right = y;\n }\n }\n y.left = x; // x becomes left child of y\n x.parent = y; // and y becomes parent of x\n\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n\n y = x.parent;\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n }\n\n rotate_right(y) {\n let x = y.left;\n\n y.left = x.right; // b goes to y.left\n\n if (x.right != this.nil_node) {\n x.right.parent = y; // y becomes parent of b\n }\n x.parent = y.parent; // move parent\n\n if (y == this.root) { // x becomes root\n this.root = x;\n }\n else { // y becomes child of x.parent\n if (y == y.parent.left) {\n y.parent.left = x;\n }\n else {\n y.parent.right = x;\n }\n }\n x.right = y; // y becomes right child of x\n y.parent = x; // and x becomes parent of y\n\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n\n x = y.parent;\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n }\n\n tree_walk(node, action) {\n if (node != null && node != this.nil_node) {\n this.tree_walk(node.left, action);\n // arr.push(node.toArray());\n action(node);\n this.tree_walk(node.right, action);\n }\n }\n\n /* Return true if all red nodes have exactly two black child nodes */\n testRedBlackProperty() {\n let res = true;\n this.tree_walk(this.root, function (node) {\n if (node.color == RB_TREE_COLOR_RED) {\n if (!(node.left.color == RB_TREE_COLOR_BLACK && node.right.color == RB_TREE_COLOR_BLACK)) {\n res = false;\n }\n }\n });\n return res;\n }\n\n /* Throw error if not every path from root to bottom has same black height */\n testBlackHeightProperty(node) {\n let height = 0;\n let heightLeft = 0;\n let heightRight = 0;\n if (node.color == RB_TREE_COLOR_BLACK) {\n height++;\n }\n if (node.left != this.nil_node) {\n heightLeft = this.testBlackHeightProperty(node.left);\n }\n else {\n heightLeft = 1;\n }\n if (node.right != this.nil_node) {\n heightRight = this.testBlackHeightProperty(node.right);\n }\n else {\n heightRight = 1;\n }\n if (heightLeft != heightRight) {\n throw new Error('Red-black height property violated');\n }\n height += heightLeft;\n return height;\n };\n}\n\n/**\n * Created by Alex Bol on 3/12/2017.\n */\n\n\n/**\n * Class representing a planar set - a generic container with ability to keep and retrieve shapes and\n * perform spatial queries. Planar set is an extension of Set container, so it supports\n * Set properties and methods\n */\nclass PlanarSet extends Set {\n /**\n * Create new instance of PlanarSet\n * @param shapes - array or set of geometric objects to store in planar set\n * Each object should have a box property\n */\n constructor(shapes) {\n super(shapes);\n this.index = new IntervalTree();\n this.forEach(shape => this.index.insert(shape));\n }\n\n /**\n * Add new shape to planar set and to its spatial index.
\n * If shape already exist, it will not be added again.\n * This happens with no error, it is possible to use size property to check if\n * a shape was actually added.
\n * Method returns planar set object updated and may be chained\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property\n * Another option to transfer as an object {key: Box, value: AnyShape}\n * @returns {PlanarSet}\n */\n add(entry) {\n let size = this.size;\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n super.add(shape);\n // size not changed - item not added, probably trying to add same item twice\n if (this.size > size) {\n this.index.insert(box, shape);\n }\n return this; // in accordance to Set.add interface\n }\n\n /**\n * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted\n * @returns {boolean}\n */\n delete(entry) {\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n let deleted = super.delete(shape);\n if (deleted) {\n this.index.remove(box, shape);\n }\n return deleted;\n }\n\n /**\n * Clear planar set\n */\n clear() {\n super.clear();\n this.index = new IntervalTree();\n }\n\n /**\n * 2d range search in planar set.
\n * Returns array of all shapes in planar set which bounding box is intersected with query box\n * @param {Box} box - query box\n * @returns {AnyShape[]}\n */\n search(box) {\n let resp = this.index.search(box);\n return resp;\n }\n\n /**\n * Point location test. Returns array of shapes which contains given point\n * @param {Point} point - query point\n * @returns {AnyShape[]}\n */\n hit(point) {\n let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);\n let resp = this.index.search(box);\n return resp.filter((shape) => point.on(shape));\n }\n\n /**\n * Returns svg string to draw all shapes in planar set\n * @returns {String}\n */\n svg() {\n let svgcontent = [...this].reduce((acc, shape) => acc + shape.svg(), \"\");\n return svgcontent;\n }\n}\n\nFlatten.PlanarSet = PlanarSet;\n\n/**\n * Base class representing shape\n * Implement common methods of affine transformations\n */\nclass Shape {\n get name() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n get box() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n clone() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * Returns new shape translated by given vector.\n * Translation vector may be also defined by a pair of numbers.\n * @param {Vector | (number, number) } args - Translation vector\n * or tuple of numbers\n * @returns {Shape}\n */\n translate(...args) {\n return this.transform(new Matrix().translate(...args))\n }\n\n /**\n * Returns new shape rotated by given angle around given center point.\n * If center point is omitted, rotates around zero point (0,0).\n * Positive value of angle defines rotation in counterclockwise direction,\n * negative angle defines rotation in clockwise direction\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n * @returns {Shape}\n */\n rotate(angle, center = new Flatten.Point()) {\n return this.transform(new Matrix().rotate(angle, center.x, center.y));\n }\n\n /**\n * Return new shape with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Shape}\n */\n scale(sx, sy) {\n return this.transform(new Matrix().scale(sx, sy));\n }\n\n transform(...args) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return Object.assign({}, this, {name: this.name});\n }\n\n svg(attrs = {}) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n}\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\n/**\n *\n * Class representing a point\n * @type {Point}\n */\nlet Point$1 = class Point extends Shape {\n /**\n * Point may be constructed by two numbers, or by array of two numbers\n * @param {number} x - x-coordinate (float number)\n * @param {number} y - y-coordinate (float number)\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate (float number)\n * @type {number}\n */\n this.y = 0;\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"point\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n if (typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n this.x = args[0];\n this.y = args[1];\n return;\n }\n }\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Returns bounding box of a point\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(this.x, this.y, this.x, this.y);\n }\n\n /**\n * Return new cloned instance of point\n * @returns {Point}\n */\n clone() {\n return new Flatten.Point(this.x, this.y);\n }\n\n get vertices() {\n return [this.clone()];\n }\n\n /**\n * Returns true if points are equal up to [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n equalTo(pt) {\n return Flatten.Utils.EQ(this.x, pt.x) && Flatten.Utils.EQ(this.y, pt.y);\n }\n\n /**\n * Defines predicate \"less than\" between points. Returns true if the point is less than query points, false otherwise
\n * By definition point1 < point2 if {point1.y < point2.y || point1.y == point2.y && point1.x < point2.x
\n * Numeric values compared with [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n lessThan(pt) {\n if (Flatten.Utils.LT(this.y, pt.y))\n return true;\n if (Flatten.Utils.EQ(this.y, pt.y) && Flatten.Utils.LT(this.x, pt.x))\n return true;\n return false;\n }\n\n /**\n * Return new point transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Point}\n */\n transform(m) {\n return new Flatten.Point(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns projection point on given line\n * @param {Line} line Line this point be projected on\n * @returns {Point}\n */\n projectionOn(line) {\n if (this.equalTo(line.pt)) // this point equal to line anchor point\n return this.clone();\n\n let vec = new Flatten.Vector(this, line.pt);\n if (Flatten.Utils.EQ_0(vec.cross(line.norm))) // vector to point from anchor point collinear to normal vector\n return line.pt.clone();\n\n let dist = vec.dot(line.norm); // signed distance\n let proj_vec = line.norm.multiply(dist);\n return this.translate(proj_vec);\n }\n\n /**\n * Returns true if point belongs to the \"left\" semi-plane, which means, point belongs to the same semi plane where line normal vector points to\n * Return false if point belongs to the \"right\" semi-plane or to the line itself\n * @param {Line} line Query line\n * @returns {boolean}\n */\n leftTo(line) {\n let vec = new Flatten.Vector(line.pt, this);\n let onLeftSemiPlane = Flatten.Utils.GT(vec.dot(line.norm), 0);\n return onLeftSemiPlane;\n }\n\n /**\n * Calculate distance and shortest segment from point to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from point to shape\n * @returns {Segment} shortest segment between point and shape (started at point, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Point) {\n let dx = shape.x - this.x;\n let dy = shape.y - this.y;\n return [Math.sqrt(dx * dx + dy * dy), new Flatten.Segment(this, shape)];\n }\n\n if (shape instanceof Flatten.Line) {\n return Flatten.Distance.point2line(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return Flatten.Distance.point2circle(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Distance.point2segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return Flatten.Distance.point2arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return Flatten.Distance.point2polygon(this, shape);\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n return Flatten.Distance.shape2planarSet(this, shape);\n }\n }\n\n /**\n * Returns true if point is on a shape, false otherwise\n * @param {Shape} shape\n * @returns {boolean}\n */\n on(shape) {\n if (shape instanceof Flatten.Point) {\n return this.equalTo(shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Line) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return shape.contains(this)\n }\n\n if (shape instanceof Flatten.Circle) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return shape.contains(this);\n }\n }\n\n get name() {\n return \"point\"\n }\n\n /**\n * Return string to draw point in svg as circle with radius \"r\"
\n * Accept any valid attributes of svg elements as svg object\n * Defaults attribues are:
\n * {\n * r:\"3\",\n * stroke:\"black\",\n * strokeWidth:\"1\",\n * fill:\"red\"\n * }\n * @param {Object} attrs - Any valid attributes of svg circle element, like \"r\", \"stroke\", \"strokeWidth\", \"fill\"\n * @returns {String}\n */\n svg(attrs = {}) {\n const r = attrs.r ?? 3; // default radius - 3\n return `\\n`;\n }\n};\n\nFlatten.Point = Point$1;\n/**\n * Function to create point equivalent to \"new\" constructor\n * @param args\n */\nconst point = (...args) => new Flatten.Point(...args);\nFlatten.point = point;\n\n// export {Point};\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class representing a vector\n * @type {Vector}\n */\nlet Vector$1 = class Vector extends Shape {\n /**\n * Vector may be constructed by two points, or by two float numbers,\n * or by array of two numbers\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate of a vector (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate of a vector (float number)\n * @type {number}\n */\n this.y = 0;\n\n /* return zero vector */\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"vector\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (typeof (a1) == \"number\" && typeof (a2) == \"number\") {\n this.x = a1;\n this.y = a2;\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.x = a2.x - a1.x;\n this.y = a2.y - a1.y;\n return;\n }\n\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Method clone returns new instance of Vector\n * @returns {Vector}\n */\n clone() {\n return new Flatten.Vector(this.x, this.y);\n }\n\n /**\n * Slope of the vector in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let angle = Math.atan2(this.y, this.x);\n if (angle < 0) angle = 2 * Math.PI + angle;\n return angle;\n }\n\n /**\n * Length of vector\n * @returns {number}\n */\n get length() {\n return Math.sqrt(this.dot(this));\n }\n\n /**\n * Returns true if vectors are equal up to [DP_TOL]{@link http://localhost:63342/flatten-js/docs/global.html#DP_TOL}\n * tolerance\n * @param {Vector} v\n * @returns {boolean}\n */\n equalTo(v) {\n return Flatten.Utils.EQ(this.x, v.x) && Flatten.Utils.EQ(this.y, v.y);\n }\n\n /**\n * Returns new vector multiplied by scalar\n * @param {number} scalar\n * @returns {Vector}\n */\n multiply(scalar) {\n return (new Flatten.Vector(scalar * this.x, scalar * this.y));\n }\n\n /**\n * Returns scalar product (dot product) of two vectors
\n * dot_product = (this * v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n dot(v) {\n return (this.x * v.x + this.y * v.y);\n }\n\n /**\n * Returns vector product (cross product) of two vectors
\n * cross_product = (this x v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n cross(v) {\n return (this.x * v.y - this.y * v.x);\n }\n\n /**\n * Returns unit vector.
\n * Throw error if given vector has zero length\n * @returns {Vector}\n */\n normalize() {\n if (!Flatten.Utils.EQ_0(this.length)) {\n return (new Flatten.Vector(this.x / this.length, this.y / this.length));\n }\n throw Errors.ZERO_DIVISION;\n }\n\n /**\n * Returns new vector rotated by given angle,\n * positive angle defines rotation in counterclockwise direction,\n * negative - in clockwise direction\n * Vector only can be rotated around (0,0) point!\n * @param {number} angle - Angle in radians\n * @returns {Vector}\n */\n rotate(angle, center = new Flatten.Point()) {\n if (center.x === 0 && center.y === 0) {\n return this.transform(new Matrix().rotate(angle));\n }\n throw(Errors.OPERATION_IS_NOT_SUPPORTED);\n }\n\n /**\n * Return new vector transformed by affine transformation matrix m\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Vector}\n */\n transform(m) {\n return new Flatten.Vector(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns vector rotated 90 degrees counterclockwise\n * @returns {Vector}\n */\n rotate90CCW() {\n return new Flatten.Vector(-this.y, this.x);\n };\n\n /**\n * Returns vector rotated 90 degrees clockwise\n * @returns {Vector}\n */\n rotate90CW() {\n return new Flatten.Vector(this.y, -this.x);\n };\n\n /**\n * Return inverted vector\n * @returns {Vector}\n */\n invert() {\n return new Flatten.Vector(-this.x, -this.y);\n }\n\n /**\n * Return result of addition of other vector to this vector as a new vector\n * @param {Vector} v Other vector\n * @returns {Vector}\n */\n add(v) {\n return new Flatten.Vector(this.x + v.x, this.y + v.y);\n }\n\n /**\n * Return result of subtraction of other vector from current vector as a new vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n subtract(v) {\n return new Flatten.Vector(this.x - v.x, this.y - v.y);\n }\n\n /**\n * Return angle between this vector and other vector.
\n * Angle is measured from 0 to 2*PI in the counterclockwise direction\n * from current vector to another.\n * @param {Vector} v Another vector\n * @returns {number}\n */\n angleTo(v) {\n let norm1 = this.normalize();\n let norm2 = v.normalize();\n let angle = Math.atan2(norm1.cross(norm2), norm1.dot(norm2));\n if (angle < 0) angle += 2 * Math.PI;\n return angle;\n }\n\n /**\n * Return vector projection of the current vector on another vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n projectionOn(v) {\n let n = v.normalize();\n let d = this.dot(n);\n return n.multiply(d);\n }\n\n get name() {\n return \"vector\"\n }\n};\n\nFlatten.Vector = Vector$1;\n\n/**\n * Function to create vector equivalent to \"new\" constructor\n * @param args\n */\nconst vector$1 = (...args) => new Flatten.Vector(...args);\nFlatten.vector = vector$1;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a segment\n * @type {Segment}\n */\nclass Segment extends Shape {\n /**\n *\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * Start point\n * @type {Point}\n */\n this.ps = new Flatten.Point();\n /**\n * End Point\n * @type {Point}\n */\n this.pe = new Flatten.Point();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 4) {\n let coords = args[0];\n this.ps = new Flatten.Point(coords[0], coords[1]);\n this.pe = new Flatten.Point(coords[2], coords[3]);\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"segment\") {\n let {ps, pe} = args[0];\n this.ps = new Flatten.Point(ps.x, ps.y);\n this.pe = new Flatten.Point(pe.x, pe.y);\n return;\n }\n\n // second point omitted issue #84\n if (args.length === 1 && args[0] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n return;\n }\n\n if (args.length === 2 && args[0] instanceof Flatten.Point && args[1] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n this.pe = args[1].clone();\n return;\n }\n\n if (args.length === 4) {\n this.ps = new Flatten.Point(args[0], args[1]);\n this.pe = new Flatten.Point(args[2], args[3]);\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of segment\n * @returns {Segment}\n */\n clone() {\n return new Flatten.Segment(this.start, this.end);\n }\n\n /**\n * Start point\n * @returns {Point}\n */\n get start() {\n return this.ps;\n }\n\n /**\n * End point\n * @returns {Point}\n */\n get end() {\n return this.pe;\n }\n\n\n /**\n * Returns array of start and end point\n * @returns [Point,Point]\n */\n get vertices() {\n return [this.ps.clone(), this.pe.clone()];\n }\n\n /**\n * Length of a segment\n * @returns {number}\n */\n get length() {\n return this.start.distanceTo(this.end)[0];\n }\n\n /**\n * Slope of the line - angle to axe x in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.slope;\n }\n\n /**\n * Bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Math.min(this.start.x, this.end.x),\n Math.min(this.start.y, this.end.y),\n Math.max(this.start.x, this.end.x),\n Math.max(this.start.y, this.end.y)\n )\n }\n\n /**\n * Returns true if equals to query segment, false otherwise\n * @param {Seg} seg - query segment\n * @returns {boolean}\n */\n equalTo(seg) {\n return this.ps.equalTo(seg.ps) && this.pe.equalTo(seg.pe);\n }\n\n /**\n * Returns true if segment contains point\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n return Flatten.Utils.EQ_0(this.distanceToPoint(pt));\n }\n\n /**\n * Returns array of intersection points between segment and other shape\n * @param {Shape} shape - Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectSegment2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Segment(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectSegment2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectSegment2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectSegment2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectSegment2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from segment to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from segment to shape\n * @returns {Segment} shortest segment between segment and shape (started at segment, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2segment(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.segment2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.segment2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2segment(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Returns unit vector in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.normalize();\n }\n\n /**\n * Return unit vector in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.end, this.start);\n return vec.normalize();\n }\n\n /**\n * Returns new segment with swapped start and end points\n * @returns {Segment}\n */\n reverse() {\n return new Segment(this.end, this.start);\n }\n\n /**\n * When point belongs to segment, return array of two segments split by given point,\n * if point is inside segment. Returns clone of this segment if query point is incident\n * to start or end point of the segment. Returns empty array if point does not belong to segment\n * @param {Point} pt Query point\n * @returns {Segment[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n return [\n new Flatten.Segment(this.start, pt),\n new Flatten.Segment(pt, this.end)\n ]\n }\n\n /**\n * Return middle point of the segment\n * @returns {Point}\n */\n middle() {\n return new Flatten.Point((this.start.x + this.end.x) / 2, (this.start.y + this.end.y) / 2);\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the segment\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length == 0) return this.start;\n if (length == this.length) return this.end;\n let factor = length / this.length;\n return new Flatten.Point(\n (this.end.x - this.start.x) * factor + this.start.x,\n (this.end.y - this.start.y) * factor + this.start.y\n );\n }\n\n distanceToPoint(pt) {\n let [dist, ...rest] = Flatten.Distance.point2segment(pt, this);\n return dist;\n };\n\n definiteIntegral(ymin = 0.0) {\n let dx = this.end.x - this.start.x;\n let dy1 = this.start.y - ymin;\n let dy2 = this.end.y - ymin;\n return (dx * (dy1 + dy2) / 2);\n }\n\n /**\n * Return new segment transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Segment} - transformed segment\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Segment(this.ps.transform(matrix), this.pe.transform(matrix))\n }\n\n /**\n * Returns true if segment start is equal to segment end up to DP_TOL\n * @returns {boolean}\n */\n isZeroLength() {\n return this.ps.equalTo(this.pe)\n }\n\n /**\n * Sort given array of points from segment start to end, assuming all points lay on the segment\n * @param {Point[]} - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let line = new Flatten.Line(this.start, this.end);\n return line.sortPoints(pts);\n }\n\n get name() {\n return \"segment\"\n }\n\n /**\n * Return string to draw segment in svg\n * @param {Object} attrs - an object with attributes for svg path element,\n * like \"stroke\", \"strokeWidth\"
\n * Defaults are stroke:\"black\", strokeWidth:\"1\"\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n}\n\nFlatten.Segment = Segment;\n/**\n * Shortcut method to create new segment\n */\nconst segment = (...args) => new Flatten.Segment(...args);\nFlatten.segment = segment;\n\n/**\n * Created by Alex Bol on 2/20/2017.\n */\n\nlet {vector} = Flatten;\n\n/**\n * Class representing a line\n * @type {Line}\n */\nlet Line$1 = class Line extends Shape {\n /**\n * Line may be constructed by point and normal vector or by two points that a line passes through\n * @param {Point} pt - point that a line passes through\n * @param {Vector|Point} norm - normal vector to a line or second point a line passes through\n */\n constructor(...args) {\n super();\n /**\n * Point a line passes through\n * @type {Point}\n */\n this.pt = new Flatten.Point();\n /**\n * Normal vector to a line
\n * Vector is normalized (length == 1)
\n * Direction of the vector is chosen to satisfy inequality norm * p >= 0\n * @type {Vector}\n */\n this.norm = new Flatten.Vector(0, 1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"line\") {\n let {pt, norm} = args[0];\n this.pt = new Flatten.Point(pt);\n this.norm = new Flatten.Vector(norm);\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.pt = a1;\n this.norm = Line.points2norm(a1, a2);\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Vector) {\n if (Flatten.Utils.EQ_0(a2.x) && Flatten.Utils.EQ_0(a2.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a1.clone();\n this.norm = a2.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Vector && a2 instanceof Flatten.Point) {\n if (Flatten.Utils.EQ_0(a1.x) && Flatten.Utils.EQ_0(a1.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a2.clone();\n this.norm = a1.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of line\n * @returns {Line}\n */\n clone() {\n return new Flatten.Line(this.pt, this.norm);\n }\n\n /* The following methods need for implementation of Edge interface\n /**\n * Line has no start point\n * @returns {undefined}\n */\n get start() {return undefined;}\n\n /**\n * Line has no end point\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns infinite box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Middle point is undefined\n * @returns {undefined}\n */\n get middle() {return undefined}\n\n /**\n * Slope of the line - angle in radians between line and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Get coefficients [A,B,C] of a standard line equation in the form Ax + By = C\n * @code [A, B, C] = line.standard\n * @returns {number[]} - array of coefficients\n */\n get standard() {\n let A = this.norm.x;\n let B = this.norm.y;\n let C = this.norm.dot(vector(this.pt.x, this.pt.y));\n\n return [A, B, C];\n }\n\n /**\n * Return true if parallel or incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n parallelTo(other_line) {\n return Flatten.Utils.EQ_0(this.norm.cross(other_line.norm));\n }\n\n /**\n * Returns true if incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n incidentTo(other_line) {\n return this.parallelTo(other_line) && this.pt.on(other_line);\n }\n\n /**\n * Returns true if point belongs to line\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Line contains point if vector to point is orthogonal to the line normal vector */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec));\n }\n\n /**\n * Return coordinate of the point that lies on the line in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the line and does not check it\n * @param {Point} pt - point on a line\n * @returns {number}\n */\n coord(pt) {\n return vector(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Returns array of intersection points\n * @param {Shape} shape - shape to intersect with\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectLine2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectLine2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectLine2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectLine2Polygon(this, shape);\n }\n\n }\n\n /**\n * Calculate distance and shortest segment from line to shape and returns array [distance, shortest_segment]\n * @param {Shape} shape Shape of the one of the types Point, Circle, Segment, Arc, Polygon\n * @returns {[number, Segment]}\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n }\n\n /**\n * Split line with a point or array of points and return array of shapes\n * Assumed (but not checked) that all points lay on the line\n * @param {Point | Point[]} pt\n * @returns {MultilineShapes}\n */\n split(pt) {\n if (pt instanceof Flatten.Point) {\n return [new Flatten.Ray(pt, this.norm), new Flatten.Ray(pt, this.norm)]\n }\n else {\n let multiline = new Flatten.Multiline([this]);\n let sorted_points = this.sortPoints(pt);\n multiline.split(sorted_points);\n return multiline.toShapes();\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Line(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new line transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Line}\n */\n transform(m) {\n return new Flatten.Line(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n /**\n * Sort given array of points that lay on a line with respect to coordinate on a line\n * The method assumes that points lay on the line and does not check this\n * @param {Point[]} pts - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n return pts.slice().sort( (pt1, pt2) => {\n if (this.coord(pt1) < this.coord(pt2)) {\n return -1;\n }\n if (this.coord(pt1) > this.coord(pt2)) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"line\"\n }\n\n /**\n * Return string to draw svg segment representing line inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg circle element\n */\n svg(box, attrs = {}) {\n let ip = intersectLine2Box(this, box);\n if (ip.length === 0)\n return \"\";\n let ps = ip[0];\n let pe = ip.length === 2 ? ip[1] : ip.find(pt => !pt.equalTo(ps));\n if (pe === undefined) pe = ps;\n let segment = new Flatten.Segment(ps, pe);\n return segment.svg(attrs);\n }\n\n static points2norm(pt1, pt2) {\n if (pt1.equalTo(pt2)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n let vec = new Flatten.Vector(pt1, pt2);\n let unit = vec.normalize();\n return unit.rotate90CCW();\n }\n};\n\nFlatten.Line = Line$1;\n/**\n * Function to create line equivalent to \"new\" constructor\n * @param args\n */\nconst line = (...args) => new Flatten.Line(...args);\nFlatten.line = line;\n\n/**\n * Created by Alex Bol on 3/6/2017.\n */\n\n\n/**\n * Class representing a circle\n * @type {Circle}\n */\nlet Circle$1 = class Circle extends Shape {\n /**\n * Class private property\n * @type {string}\n */\n\n /**\n *\n * @param {Point} pc - circle center point\n * @param {number} r - circle radius\n */\n constructor(...args) {\n super();\n /**\n * Circle center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Circle radius\n * @type {number}\n */\n this.r = 1;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"circle\") {\n let {pc, r} = args[0];\n this.pc = new Flatten.Point(pc);\n this.r = r;\n } else {\n let [pc, r] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n }\n // throw Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of circle\n * @returns {Circle}\n */\n clone() {\n return new Flatten.Circle(this.pc.clone(), this.r);\n }\n\n /**\n * Circle center\n * @returns {Point}\n */\n get center() {\n return this.pc;\n }\n\n /**\n * Circle bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n this.pc.x - this.r,\n this.pc.y - this.r,\n this.pc.x + this.r,\n this.pc.y + this.r\n );\n }\n\n /**\n * Return true if circle contains shape: no point of shape lies outside of the circle\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return Flatten.Utils.LE(shape.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Arc) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.r, this.r) &&\n Flatten.Utils.LE(shape.center.distanceTo(this.center)[0], this.r);\n }\n\n /* TODO: box, polygon */\n }\n\n /**\n * Transform circle to closed arc\n * @param {boolean} counterclockwise\n * @returns {Arc}\n */\n toArc(counterclockwise = true) {\n return new Flatten.Arc(this.center, this.r, Math.PI, -Math.PI, counterclockwise);\n }\n\n /**\n * Method scale is supported only for uniform scaling of the circle with (0,0) center\n * @param {number} sx\n * @param {number} sy\n * @returns {Circle}\n */\n scale(sx, sy) {\n if (sx !== sy)\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n if (!(this.pc.x === 0.0 && this.pc.y === 0.0))\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n return new Flatten.Circle(this.pc, this.r*sx)\n }\n\n /**\n * Return new circle transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Circle}\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Flatten.Circle(this.pc.transform(matrix), this.r)\n }\n\n /**\n * Returns array of intersection points between circle and other shape\n * @param {Shape} shape Shape of the one of supported types\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Circle(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Circle(shape, this);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectCircle2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Circle(shape, this);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectCircle2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from circle to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from circle to shape\n * @returns {Segment} shortest segment between circle and shape (started at circle, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2circle(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n get name() {\n return \"circle\"\n }\n\n /**\n * Return string to draw circle in svg\n * @param {Object} attrs - an object with attributes of svg circle element\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n\n};\n\nFlatten.Circle = Circle$1;\n/**\n * Shortcut to create new circle\n * @param args\n */\nconst circle = (...args) => new Flatten.Circle(...args);\nFlatten.circle = circle;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a circular arc\n * @type {Arc}\n */\nclass Arc extends Shape {\n /**\n *\n * @param {Point} pc - arc center\n * @param {number} r - arc radius\n * @param {number} startAngle - start angle in radians from 0 to 2*PI\n * @param {number} endAngle - end angle in radians from 0 to 2*PI\n * @param {boolean} counterClockwise - arc direction, true - clockwise, false - counterclockwise\n */\n constructor(...args) {\n super();\n /**\n * Arc center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Arc radius\n * @type {number}\n */\n this.r = 1;\n /**\n * Arc start angle in radians\n * @type {number}\n */\n this.startAngle = 0;\n /**\n * Arc end angle in radians\n * @type {number}\n */\n this.endAngle = 2 * Math.PI;\n /**\n * Arc orientation\n * @type {boolean}\n */\n this.counterClockwise = Flatten.CCW;\n\n if (args.length === 0)\n return;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"arc\") {\n let {pc, r, startAngle, endAngle, counterClockwise} = args[0];\n this.pc = new Flatten.Point(pc.x, pc.y);\n this.r = r;\n this.startAngle = startAngle;\n this.endAngle = endAngle;\n this.counterClockwise = counterClockwise;\n } else {\n let [pc, r, startAngle, endAngle, counterClockwise] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n if (startAngle !== undefined) this.startAngle = startAngle;\n if (endAngle !== undefined) this.endAngle = endAngle;\n if (counterClockwise !== undefined) this.counterClockwise = counterClockwise;\n }\n\n // throw Flatten.Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of arc\n * @returns {Arc}\n */\n clone() {\n return new Flatten.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n\n /**\n * Get sweep angle in radians. Sweep angle is non-negative number from 0 to 2*PI\n * @returns {number}\n */\n get sweep() {\n if (Flatten.Utils.EQ(this.startAngle, this.endAngle))\n return 0.0;\n if (Flatten.Utils.EQ(Math.abs(this.startAngle - this.endAngle), Flatten.PIx2)) {\n return Flatten.PIx2;\n }\n let sweep;\n if (this.counterClockwise) {\n sweep = Flatten.Utils.GT(this.endAngle, this.startAngle) ?\n this.endAngle - this.startAngle : this.endAngle - this.startAngle + Flatten.PIx2;\n } else {\n sweep = Flatten.Utils.GT(this.startAngle, this.endAngle) ?\n this.startAngle - this.endAngle : this.startAngle - this.endAngle + Flatten.PIx2;\n }\n\n if (Flatten.Utils.GT(sweep, Flatten.PIx2)) {\n sweep -= Flatten.PIx2;\n }\n if (Flatten.Utils.LT(sweep, 0)) {\n sweep += Flatten.PIx2;\n }\n return sweep;\n }\n\n /**\n * Get start point of arc\n * @returns {Point}\n */\n get start() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.startAngle, this.pc);\n }\n\n /**\n * Get end point of arc\n * @returns {Point}\n */\n get end() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.endAngle, this.pc);\n }\n\n /**\n * Get center of arc\n * @returns {Point}\n */\n get center() {\n return this.pc.clone();\n }\n\n get vertices() {\n return [this.start.clone(), this.end.clone()];\n }\n\n /**\n * Get arc length\n * @returns {number}\n */\n get length() {\n return Math.abs(this.sweep * this.r);\n }\n\n /**\n * Get bounding box of the arc\n * @returns {Box}\n */\n get box() {\n let func_arcs = this.breakToFunctional();\n let box = func_arcs.reduce((acc, arc) => acc.merge(arc.start.box), new Flatten.Box());\n box = box.merge(this.end.box);\n return box;\n }\n\n /**\n * Returns true if arc contains point, false otherwise\n * @param {Point} pt - point to test\n * @returns {boolean}\n */\n contains(pt) {\n // first check if point on circle (pc,r)\n if (!Flatten.Utils.EQ(this.pc.distanceTo(pt)[0], this.r))\n return false;\n\n // point on circle\n\n if (pt.equalTo(this.start))\n return true;\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n let test_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise);\n return Flatten.Utils.LE(test_arc.length, this.length);\n }\n\n /**\n * When given point belongs to arc, return array of two arcs split by this point. If points is incident\n * to start or end point of the arc, return clone of the arc. If point does not belong to the arcs, return\n * empty array.\n * @param {Point} pt Query point\n * @returns {Arc[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n\n return [\n new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise),\n new Flatten.Arc(this.pc, this.r, angle, this.endAngle, this.counterClockwise)\n ]\n }\n\n /**\n * Return middle point of the arc\n * @returns {Point}\n */\n middle() {\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep / 2 : this.startAngle - this.sweep / 2;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the arc\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length === 0) return this.start;\n if (length === this.length) return this.end;\n let factor = length / this.length;\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep * factor : this.startAngle - this.sweep * factor;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Returns chord height (\"sagitta\") of the arc\n * @returns {number}\n */\n chordHeight() {\n return (1.0 - Math.cos(Math.abs(this.sweep / 2.0))) * this.r;\n }\n\n /**\n * Returns array of intersection points between arc and other shape\n * @param {Shape} shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Arc(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Arc(shape, this);\n }\n if (shape instanceof Flatten.Circle) {\n return intersectArc2Circle(this, shape);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Arc(shape, this);\n }\n if (shape instanceof Flatten.Box) {\n return intersectArc2Box(this, shape);\n }\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Arc(this, shape);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectArc2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from arc to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from arc to shape\n * @returns {Segment} shortest segment between arc and shape (started at arc, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.arc2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.arc2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.arc2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Breaks arc in extreme point 0, pi/2, pi, 3*pi/2 and returns array of sub-arcs\n * @returns {Arc[]}\n */\n breakToFunctional() {\n let func_arcs_array = [];\n let angles = [0, Math.PI / 2, 2 * Math.PI / 2, 3 * Math.PI / 2];\n let pts = [\n this.pc.translate(this.r, 0),\n this.pc.translate(0, this.r),\n this.pc.translate(-this.r, 0),\n this.pc.translate(0, -this.r)\n ];\n\n // If arc contains extreme point,\n // create test arc started at start point and ended at this extreme point\n let test_arcs = [];\n for (let i = 0; i < 4; i++) {\n if (pts[i].on(this)) {\n test_arcs.push(new Flatten.Arc(this.pc, this.r, this.startAngle, angles[i], this.counterClockwise));\n }\n }\n\n if (test_arcs.length === 0) { // arc does contain any extreme point\n func_arcs_array.push(this.clone());\n } else { // arc passes extreme point\n // sort these arcs by length\n test_arcs.sort((arc1, arc2) => arc1.length - arc2.length);\n\n for (let i = 0; i < test_arcs.length; i++) {\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, test_arcs[i].endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, test_arcs[i].endAngle, this.counterClockwise);\n }\n if (!Flatten.Utils.EQ_0(new_arc.length)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n\n // add last sub arc\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, this.endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n // It could be 2*PI when occasionally start = 0 and end = 2*PI but this is not valid for breakToFunctional\n if (!Flatten.Utils.EQ_0(new_arc.length) && !Flatten.Utils.EQ(new_arc.sweep, 2*Math.PI)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n return func_arcs_array;\n }\n\n /**\n * Return tangent unit vector in the start point in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.pc, this.start);\n let angle = this.counterClockwise ? Math.PI / 2. : -Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Return tangent unit vector in the end point in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.pc, this.end);\n let angle = this.counterClockwise ? -Math.PI / 2. : Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Returns new arc with swapped start and end angles and reversed direction\n * @returns {Arc}\n */\n reverse() {\n return new Flatten.Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise);\n }\n\n /**\n * Return new arc transformed using affine transformation matrix
\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Arc}\n */\n transform(matrix = new Flatten.Matrix()) {\n let newStart = this.start.transform(matrix);\n let newEnd = this.end.transform(matrix);\n let newCenter = this.pc.transform(matrix);\n let newDirection = this.counterClockwise;\n if (matrix.a * matrix.d < 0) {\n newDirection = !newDirection;\n }\n return Flatten.Arc.arcSE(newCenter, newStart, newEnd, newDirection);\n }\n\n static arcSE(center, start, end, counterClockwise) {\n let {vector} = Flatten;\n let startAngle = vector(center, start).slope;\n let endAngle = vector(center, end).slope;\n if (Flatten.Utils.EQ(startAngle, endAngle)) {\n endAngle += 2 * Math.PI;\n counterClockwise = true;\n }\n let r = vector(center, start).length;\n\n return new Flatten.Arc(center, r, startAngle, endAngle, counterClockwise);\n }\n\n definiteIntegral(ymin = 0) {\n let f_arcs = this.breakToFunctional();\n let area = f_arcs.reduce((acc, arc) => acc + arc.circularSegmentDefiniteIntegral(ymin), 0.0);\n return area;\n }\n\n circularSegmentDefiniteIntegral(ymin) {\n let line = new Flatten.Line(this.start, this.end);\n let onLeftSide = this.pc.leftTo(line);\n let segment = new Flatten.Segment(this.start, this.end);\n let areaTrapez = segment.definiteIntegral(ymin);\n let areaCircularSegment = this.circularSegmentArea();\n let area = onLeftSide ? areaTrapez - areaCircularSegment : areaTrapez + areaCircularSegment;\n return area;\n }\n\n circularSegmentArea() {\n return (0.5 * this.r * this.r * (this.sweep - Math.sin(this.sweep)))\n }\n\n /**\n * Sort given array of points from arc start to end, assuming all points lay on the arc\n * @param {Point[]} pts array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let {vector} = Flatten;\n return pts.slice().sort( (pt1, pt2) => {\n let slope1 = vector(this.pc, pt1).slope;\n let slope2 = vector(this.pc, pt2).slope;\n if (slope1 < slope2) {\n return -1;\n }\n if (slope1 > slope2) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"arc\"\n }\n\n /**\n * Return string to draw arc in svg\n * @param {Object} attrs - an object with attributes of svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let largeArcFlag = this.sweep <= Math.PI ? \"0\" : \"1\";\n let sweepFlag = this.counterClockwise ? \"1\" : \"0\";\n\n if (Flatten.Utils.EQ(this.sweep, 2 * Math.PI)) {\n let circle = new Flatten.Circle(this.pc, this.r);\n return circle.svg(attrs);\n } else {\n return `\\n`\n }\n }\n\n}\n\nFlatten.Arc = Arc;\n/**\n * Function to create arc equivalent to \"new\" constructor\n * @param args\n */\nconst arc = (...args) => new Flatten.Arc(...args);\nFlatten.arc = arc;\n\n/**\n * Created by Alex Bol on 3/7/2017.\n */\n\n/**\n * Class Box represents bounding box of the shape.\n * It may also represent axis-aligned rectangle\n * @type {Box}\n */\nclass Box extends Shape {\n /**\n *\n * @param {number} xmin - minimal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n constructor(xmin = undefined, ymin = undefined, xmax = undefined, ymax = undefined) {\n super();\n /**\n * Minimal x coordinate\n * @type {number}\n */\n this.xmin = xmin;\n /**\n * Minimal y coordinate\n * @type {number}\n */\n this.ymin = ymin;\n /**\n * Maximal x coordinate\n * @type {number}\n */\n this.xmax = xmax;\n /**\n * Maximal y coordinate\n * @type {number}\n */\n this.ymax = ymax;\n }\n\n /**\n * Return new cloned instance of box\n * @returns {Box}\n */\n clone() {\n return new Box(this.xmin, this.ymin, this.xmax, this.ymax);\n }\n\n /**\n * Property low need for interval tree interface\n * @returns {Point}\n */\n get low() {\n return new Flatten.Point(this.xmin, this.ymin);\n }\n\n /**\n * Property high need for interval tree interface\n * @returns {Point}\n */\n get high() {\n return new Flatten.Point(this.xmax, this.ymax);\n }\n\n /**\n * Property max returns the box itself !\n * @returns {Box}\n */\n get max() {\n return this.clone();\n }\n \n /**\n * Return center of the box\n * @returns {Point}\n */\n get center() {\n return new Flatten.Point((this.xmin + this.xmax) / 2, (this.ymin + this.ymax) / 2);\n }\n\n /**\n * Return the width of the box\n * @returns {number}\n */\n get width() {\n return Math.abs(this.xmax - this.xmin);\n }\n\n /**\n * Return the height of the box\n * @returns {number}\n */\n get height() {\n return Math.abs(this.ymax - this.ymin);\n }\n \n /**\n * Return property box like all other shapes\n * @returns {Box}\n */\n get box() {\n return this.clone();\n }\n\n /**\n * Returns true if not intersected with other box\n * @param {Box} other_box - other box to test\n * @returns {boolean}\n */\n not_intersect(other_box) {\n return (\n this.xmax < other_box.xmin ||\n this.xmin > other_box.xmax ||\n this.ymax < other_box.ymin ||\n this.ymin > other_box.ymax\n );\n }\n\n /**\n * Returns true if intersected with other box\n * @param {Box} other_box - Query box\n * @returns {boolean}\n */\n intersect(other_box) {\n return !this.not_intersect(other_box);\n }\n\n /**\n * Returns new box merged with other box\n * @param {Box} other_box - Other box to merge with\n * @returns {Box}\n */\n merge(other_box) {\n return new Box(\n this.xmin === undefined ? other_box.xmin : Math.min(this.xmin, other_box.xmin),\n this.ymin === undefined ? other_box.ymin : Math.min(this.ymin, other_box.ymin),\n this.xmax === undefined ? other_box.xmax : Math.max(this.xmax, other_box.xmax),\n this.ymax === undefined ? other_box.ymax : Math.max(this.ymax, other_box.ymax)\n );\n }\n\n /**\n * Defines predicate \"less than\" between two boxes. Need for interval index\n * @param {Box} other_box - other box\n * @returns {boolean} - true if this box less than other box, false otherwise\n */\n less_than(other_box) {\n if (this.low.lessThan(other_box.low))\n return true;\n if (this.low.equalTo(other_box.low) && this.high.lessThan(other_box.high))\n return true;\n return false;\n }\n\n /**\n * Returns true if this box is equal to other box, false otherwise\n * @param {Box} other_box - query box\n * @returns {boolean}\n */\n equal_to(other_box) {\n return (this.low.equalTo(other_box.low) && this.high.equalTo(other_box.high));\n }\n\n output() {\n return this.clone();\n }\n\n static comparable_max(box1, box2) {\n // return pt1.lessThan(pt2) ? pt2.clone() : pt1.clone();\n return box1.merge(box2);\n }\n\n static comparable_less_than(pt1, pt2) {\n return pt1.lessThan(pt2);\n }\n\n /**\n * Set new values to the box object\n * @param {number} xmin - mininal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n set(xmin, ymin, xmax, ymax) {\n this.xmin = xmin;\n this.ymin = ymin;\n this.xmax = xmax;\n this.ymax = ymax;\n }\n\n /**\n * Transform box into array of points from low left corner in counterclockwise\n * @returns {Point[]}\n */\n toPoints() {\n return [\n new Flatten.Point(this.xmin, this.ymin),\n new Flatten.Point(this.xmax, this.ymin),\n new Flatten.Point(this.xmax, this.ymax),\n new Flatten.Point(this.xmin, this.ymax)\n ];\n }\n\n /**\n * Transform box into array of segments from low left corner in counterclockwise\n * @returns {Segment[]}\n */\n toSegments() {\n let pts = this.toPoints();\n return [\n new Flatten.Segment(pts[0], pts[1]),\n new Flatten.Segment(pts[1], pts[2]),\n new Flatten.Segment(pts[2], pts[3]),\n new Flatten.Segment(pts[3], pts[0])\n ];\n }\n\n /**\n * Box rotation is not supported\n * Attempt to rotate box throws error\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n */\n rotate(angle, center = new Flatten.Point()) {\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n }\n\n /**\n * Return new box transformed using affine transformation matrix\n * New box is a bounding box of transformed corner points\n * @param {Matrix} m - affine transformation matrix\n * @returns {Box}\n */\n transform(m = new Flatten.Matrix()) {\n const transformed_points = this.toPoints().map(pt => pt.transform(m));\n return transformed_points.reduce(\n (new_box, pt) => new_box.merge(pt.box), new Box())\n }\n\n /**\n * Return true if box contains shape: no point of shape lies outside the box\n * @param {AnyShape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.vertices.every(vertex => this.contains(vertex))\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.toSegments().every(segment => this.contains(segment))\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.contains(shape.box)\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.vertices.every(vertex => this.contains(vertex)) &&\n shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)\n }\n\n if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {\n return false\n }\n\n if (shape instanceof Flatten.Multiline) {\n return shape.toShapes().every(shape => this.contains(shape))\n }\n\n if (shape instanceof Flatten.Polygon) {\n return this.contains(shape.box)\n }\n }\n\n get name() {\n return \"box\"\n }\n\n /**\n * Return string to draw box in svg\n * @param {Object} attrs - an object with attributes of svg rectangle element\n * @returns {string}\n */\n svg(attrs = {}) {\n const width = this.xmax - this.xmin;\n const height = this.ymax - this.ymin;\n return `\\n`;\n };\n}\n\nFlatten.Box = Box;\n/**\n * Shortcut to create new box\n * @param args\n * @returns {Box}\n */\nconst box = (...args) => new Flatten.Box(...args);\nFlatten.box = box;\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing an edge of polygon. Edge shape may be Segment or Arc.\n * Each edge contains references to the next and previous edges in the face of the polygon.\n *\n * @type {Edge}\n */\nclass Edge {\n /**\n * Construct new instance of edge\n * @param {Shape} shape Shape of type Segment or Arc\n */\n constructor(shape) {\n /**\n * Shape of the edge: Segment or Arc\n * @type {Segment|Arc}\n */\n this.shape = shape;\n /**\n * Pointer to the next edge in the face\n * @type {Edge}\n */\n this.next = undefined;\n /**\n * Pointer to the previous edge in the face\n * @type {Edge}\n */\n this.prev = undefined;\n /**\n * Pointer to the face containing this edge\n * @type {Face}\n */\n this.face = undefined;\n /**\n * \"Arc distance\" from the face start\n * @type {number}\n */\n this.arc_length = 0;\n /**\n * Start inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvStart = undefined;\n /**\n * End inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvEnd = undefined;\n /**\n * Edge inclusion flag (Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY)\n * @type {*}\n */\n this.bv = undefined;\n /**\n * Overlap flag for boundary edge (Flatten.OVERLAP_SAME/Flatten.OVERLAP_OPPOSITE)\n * @type {*}\n */\n this.overlap = undefined;\n }\n\n /**\n * Get edge start point\n */\n get start() {\n return this.shape.start;\n }\n\n /**\n * Get edge end point\n */\n get end() {\n return this.shape.end;\n }\n\n /**\n * Get edge length\n */\n get length() {\n return this.shape.length;\n }\n\n /**\n * Get bounding box of the edge\n * @returns {Box}\n */\n get box() {\n return this.shape.box;\n }\n\n get isSegment() {\n return this.shape instanceof Flatten.Segment;\n }\n\n get isArc() {\n return this.shape instanceof Flatten.Arc;\n }\n\n get isLine() {\n return this.shape instanceof Flatten.Line;\n }\n\n get isRay() {\n return this.shape instanceof Flatten.Ray\n }\n\n /**\n * Get middle point of the edge\n * @returns {Point}\n */\n middle() {\n return this.shape.middle();\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the edge\n * @returns {Point}\n */\n pointAtLength(length) {\n return this.shape.pointAtLength(length);\n }\n\n /**\n * Returns true if point belongs to the edge, false otherwise\n * @param {Point} pt - test point\n */\n contains(pt) {\n return this.shape.contains(pt);\n }\n\n /**\n * Set inclusion flag of the edge with respect to another polygon\n * Inclusion flag is one of Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY\n * @param polygon\n */\n setInclusion(polygon) {\n if (this.bv !== undefined) return this.bv;\n\n if (this.shape instanceof Flatten.Line || this.shape instanceof Flatten.Ray) {\n this.bv = Flatten.OUTSIDE;\n return this.bv;\n }\n\n if (this.bvStart === undefined) {\n this.bvStart = ray_shoot(polygon, this.start);\n }\n if (this.bvEnd === undefined) {\n this.bvEnd = ray_shoot(polygon, this.end);\n }\n /* At least one end outside - the whole edge outside */\n if (this.bvStart === Flatten.OUTSIDE || this.bvEnd == Flatten.OUTSIDE) {\n this.bv = Flatten.OUTSIDE;\n }\n /* At least one end inside - the whole edge inside */\n else if (this.bvStart === Flatten.INSIDE || this.bvEnd == Flatten.INSIDE) {\n this.bv = Flatten.INSIDE;\n }\n /* Both are boundary - check the middle point */\n else {\n let bvMiddle = ray_shoot(polygon, this.middle());\n // let boundary = this.middle().distanceTo(polygon)[0] < 10*Flatten.DP_TOL;\n // let bvMiddle = boundary ? Flatten.BOUNDARY : ray_shoot(polygon, this.middle());\n this.bv = bvMiddle;\n }\n return this.bv;\n }\n\n /**\n * Set overlapping between two coincident boundary edges\n * Overlapping flag is one of Flatten.OVERLAP_SAME or Flatten.OVERLAP_OPPOSITE\n * @param edge\n */\n setOverlap(edge) {\n let flag = undefined;\n let shape1 = this.shape;\n let shape2 = edge.shape;\n\n if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end)) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start)) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Arc) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && /*shape1.counterClockwise === shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && /*shape1.counterClockwise !== shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Arc ||\n shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n }\n\n /* Do not update overlap flag if already set on previous chain */\n if (this.overlap === undefined) this.overlap = flag;\n if (edge.overlap === undefined) edge.overlap = flag;\n }\n\n svg() {\n if (this.shape instanceof Flatten.Segment) {\n return ` L${this.shape.end.x},${this.shape.end.y}`;\n } else if (this.shape instanceof Flatten.Arc) {\n let arc = this.shape;\n let largeArcFlag;\n let sweepFlag = arc.counterClockwise ? \"1\" : \"0\";\n\n // Draw full circe arc as special case: split it into two half-circles\n if (Flatten.Utils.EQ(arc.sweep, 2 * Math.PI)) {\n let sign = arc.counterClockwise ? 1 : -1;\n let halfArc1 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle, arc.startAngle + sign * Math.PI, arc.counterClockwise);\n let halfArc2 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle + sign * Math.PI, arc.endAngle, arc.counterClockwise);\n\n largeArcFlag = \"0\";\n\n return ` A${halfArc1.r},${halfArc1.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc1.end.x},${halfArc1.end.y}\n A${halfArc2.r},${halfArc2.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc2.end.x},${halfArc2.end.y}`\n } else {\n largeArcFlag = arc.sweep <= Math.PI ? \"0\" : \"1\";\n\n return ` A${arc.r},${arc.r} 0 ${largeArcFlag},${sweepFlag} ${arc.end.x},${arc.end.y}`;\n }\n }\n }\n\n toJSON() {\n return this.shape.toJSON();\n }\n}\nFlatten.Edge = Edge;\n\n/**\n * Class implements circular bidirectional linked list
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass CircularLinkedList extends LinkedList {\n constructor(first, last) {\n super(first, last);\n this.setCircularLinks();\n }\n\n setCircularLinks() {\n if (this.isEmpty()) return;\n this.last.next = this.first;\n this.first.prev = this.last;\n }\n\n [Symbol.iterator]() {\n let element = undefined;\n return {\n next: () => {\n let value = element ? element : this.first;\n let done = this.first ? (element ? element === this.first : false) : true;\n element = value ? value.next : undefined;\n return {value: value, done: done};\n }\n };\n };\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element - new element to be appended\n * @returns {CircularLinkedList}\n */\n append(element) {\n super.append(element);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement - new element to be inserted\n * @param {LinkedListElement} elementBefore - element in the list to insert after it\n * @returns {CircularLinkedList}\n */\n insert(newElement, elementBefore) {\n super.insert(newElement, elementBefore);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element - element to be removed from the list\n * @returns {CircularLinkedList}\n */\n remove(element) {\n super.remove(element);\n // this.setCircularLinks();\n return this;\n }\n}\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing a face (closed loop) in a [polygon]{@link Flatten.Polygon} object.\n * Face is a circular bidirectional linked list of [edges]{@link Flatten.Edge}.\n * Face object cannot be instantiated with a constructor.\n * Instead, use [polygon.addFace()]{@link Flatten.Polygon#addFace} method.\n *
\n * Note, that face only set entry point to the linked list of edges but does not contain edges by itself.\n * Container of edges is a property of the polygon object.
\n *\n * @example\n * // Face implements \"next\" iterator which enables to iterate edges in for loop:\n * for (let edge of face) {\n * console.log(edge.shape.length) // do something\n * }\n *\n * // Instead, it is possible to iterate edges as linked list, starting from face.first:\n * let edge = face.first;\n * do {\n * console.log(edge.shape.length); // do something\n * edge = edge.next;\n * } while (edge != face.first)\n */\nclass Face extends CircularLinkedList {\n constructor(polygon, ...args) {\n super(); // construct empty list of edges\n /**\n * Reference to the first edge in face\n */\n // this.first;\n /**\n * Reference to the last edge in face\n */\n // this.last;\n\n this._box = undefined; // new Box();\n this._orientation = undefined;\n\n if (args.length === 0) {\n return;\n }\n\n /* If passed an array it supposed to be:\n 1) array of shapes that performs close loop or\n 2) array of points that performs set of vertices\n */\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n // let argsArray = args[0];\n let shapes = args[0]; // argsArray[0];\n if (shapes.length === 0)\n return;\n\n /* array of Flatten.Points */\n if (shapes.every((shape) => {return shape instanceof Flatten.Point})) {\n let segments = Face.points2segments(shapes);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of points as pairs of numbers */\n else if (shapes.every((shape) => {return shape instanceof Array && shape.length === 2})) {\n let points = shapes.map((shape) => new Flatten.Point(shape[0],shape[1]));\n let segments = Face.points2segments(points);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of segments ot arcs */\n else if (shapes.every((shape) => {\n return (shape instanceof Flatten.Segment || shape instanceof Flatten.Arc)\n })) {\n this.shapes2face(polygon.edges, shapes);\n }\n // this is from JSON.parse object\n else if (shapes.every((shape) => {\n return (shape.name === \"segment\" || shape.name === \"arc\")\n })) {\n let flattenShapes = [];\n for (let shape of shapes) {\n let flattenShape;\n if (shape.name === \"segment\") {\n flattenShape = new Flatten.Segment(shape);\n } else {\n flattenShape = new Flatten.Arc(shape);\n }\n flattenShapes.push(flattenShape);\n }\n this.shapes2face(polygon.edges, flattenShapes);\n }\n }\n /* Create new face and copy edges into polygon.edges set */\n else if (args[0] instanceof Face) {\n let face = args[0];\n this.first = face.first;\n this.last = face.last;\n for (let edge of face) {\n polygon.edges.add(edge);\n }\n }\n /* Instantiate face from a circle in CCW orientation */\n else if (args[0] instanceof Flatten.Circle) {\n this.shapes2face(polygon.edges, [args[0].toArc(CCW)]);\n }\n /* Instantiate face from a box in CCW orientation */\n else if (args[0] instanceof Flatten.Box) {\n let box = args[0];\n this.shapes2face(polygon.edges, [\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymin), new Flatten.Point(box.xmax, box.ymin)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymin), new Flatten.Point(box.xmax, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymax), new Flatten.Point(box.xmin, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymax), new Flatten.Point(box.xmin, box.ymin))\n ]);\n }\n }\n /* If passed two edges, consider them as start and end of the face loop */\n /* THIS METHOD WILL BE USED BY BOOLEAN OPERATIONS */\n /* Assume that edges already copied to polygon.edges set in the clip algorithm !!! */\n if (args.length === 2 && args[0] instanceof Flatten.Edge && args[1] instanceof Flatten.Edge) {\n this.first = args[0]; // first edge in face or undefined\n this.last = args[1]; // last edge in face or undefined\n this.last.next = this.first;\n this.first.prev = this.last;\n\n // set arc length\n this.setArcLength();\n\n // this.box = this.getBox();\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n }\n\n /**\n * Return array of edges from first to last\n * @returns {Array}\n */\n get edges() {\n return this.toArray();\n }\n\n /**\n * Return array of shapes which comprise face\n * @returns {Array}\n */\n get shapes() {\n return this.edges.map(edge => edge.shape.clone());\n }\n\n /**\n * Return bounding box of the face\n * @returns {Box}\n */\n get box() {\n if (this._box === undefined) {\n let box = new Flatten.Box();\n for (let edge of this) {\n box = box.merge(edge.box);\n }\n this._box = box;\n }\n return this._box;\n }\n\n /**\n * Get all edges length\n * @returns {number}\n */\n get perimeter() {\n return this.last.arc_length + this.last.length\n }\n\n /**\n * Get point on face boundary at given length\n * @param {number} length - The length along the face boundary\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.perimeter || length < 0) return null;\n let point = null;\n for (let edge of this) {\n if (length >= edge.arc_length &&\n (edge === this.last || length < edge.next.arc_length)) {\n point = edge.pointAtLength(length - edge.arc_length);\n break;\n }\n }\n return point;\n }\n\n static points2segments(points) {\n let segments = [];\n for (let i = 0; i < points.length; i++) {\n // skip zero length segment\n if (points[i].equalTo(points[(i + 1) % points.length]))\n continue;\n segments.push(new Flatten.Segment(points[i], points[(i + 1) % points.length]));\n }\n return segments;\n }\n\n shapes2face(edges, shapes) {\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n // this.box = this.box.merge(shape.box);\n edges.add(edge);\n }\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n\n /**\n * Append edge after the last edge of the face (and before the first edge).
\n * @param {Edge} edge - Edge to be appended to the linked list\n * @returns {Face}\n */\n append(edge) {\n super.append(edge);\n // set arc length\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n // edges.add(edge); // Add new edges into edges container\n return this;\n }\n\n /**\n * Insert edge newEdge into the linked list after the edge edgeBefore
\n * @param {Edge} newEdge - Edge to be inserted into linked list\n * @param {Edge} edgeBefore - Edge to insert newEdge after it\n * @returns {Face}\n */\n insert(newEdge, edgeBefore) {\n super.insert(newEdge, edgeBefore);\n // set arc length\n this.setOneEdgeArcLength(newEdge);\n newEdge.face = this;\n return this;\n }\n\n /**\n * Remove the given edge from the linked list of the face
\n * @param {Edge} edge - Edge to be removed\n * @returns {Face}\n */\n remove(edge) {\n super.remove(edge);\n // Recalculate arc length\n this.setArcLength();\n return this;\n }\n\n /**\n * Merge current edge with the next edge. Given edge will be extended,\n * next edge after it will be removed. The distortion of the polygon\n * is on the responsibility of the user of this method\n * @param {Edge} edge - edge to be extended\n * @returns {Face}\n */\n merge_with_next_edge(edge) {\n edge.shape.end.x = edge.next.shape.end.x;\n edge.shape.end.y = edge.next.shape.end.y;\n this.remove(edge.next);\n return this;\n }\n\n /**\n * Reverse orientation of the face: first edge become last and vice a verse,\n * all edges starts and ends swapped, direction of arcs inverted. If face was oriented\n * clockwise, it becomes counterclockwise and vice versa\n */\n reverse() {\n // collect edges in revert order with reverted shapes\n let edges = [];\n let edge_tmp = this.last;\n do {\n // reverse shape\n edge_tmp.shape = edge_tmp.shape.reverse();\n edges.push(edge_tmp);\n edge_tmp = edge_tmp.prev;\n } while (edge_tmp !== this.last);\n\n // restore linked list\n this.first = undefined;\n this.last = undefined;\n for (let edge of edges) {\n if (this.first === undefined) {\n edge.prev = edge;\n edge.next = edge;\n this.first = edge;\n this.last = edge;\n } else {\n // append to end\n edge.prev = this.last;\n this.last.next = edge;\n\n // update edge to be last\n this.last = edge;\n\n // restore circular links\n this.last.next = this.first;\n this.first.prev = this.last;\n\n }\n // set arc length\n this.setOneEdgeArcLength(edge);\n }\n\n // Recalculate orientation, if set\n if (this._orientation !== undefined) {\n this._orientation = undefined;\n this._orientation = this.orientation();\n }\n }\n\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Returns the absolute value of the area of the face\n * @returns {number}\n */\n area() {\n return Math.abs(this.signedArea());\n }\n\n /**\n * Returns signed area of the simple face.\n * Face is simple if it has no self intersections that change its orientation.\n * Then the area will be positive if the orientation of the face is clockwise,\n * and negative if orientation is counterclockwise.\n * It may be zero if polygon is degenerated.\n * @returns {number}\n */\n signedArea() {\n let sArea = 0;\n let ymin = this.box.ymin;\n for (let edge of this) {\n sArea += edge.shape.definiteIntegral(ymin);\n }\n return sArea;\n }\n\n /**\n * Return face orientation: one of Flatten.ORIENTATION.CCW, Flatten.ORIENTATION.CW, Flatten.ORIENTATION.NOT_ORIENTABLE
\n * According to Green theorem the area of a closed curve may be calculated as double integral,\n * and the sign of the integral will be defined by the direction of the curve.\n * When the integral (\"signed area\") will be negative, direction is counterclockwise,\n * when positive - clockwise and when it is zero, polygon is not orientable.\n * See {@link https://mathinsight.org/greens_theorem_find_area}\n * @returns {number}\n */\n orientation() {\n if (this._orientation === undefined) {\n let area = this.signedArea();\n if (Flatten.Utils.EQ_0(area)) {\n this._orientation = ORIENTATION.NOT_ORIENTABLE;\n } else if (Flatten.Utils.LT(area, 0)) {\n this._orientation = ORIENTATION.CCW;\n } else {\n this._orientation = ORIENTATION.CW;\n }\n }\n return this._orientation;\n }\n\n /**\n * Returns true if face of the polygon is simple (no self-intersection points found)\n * NOTE: this method is incomplete because it does not exclude touching points.\n * Self intersection test should check if polygon change orientation in the test point.\n * @param {PlanarSet} edges - reference to polygon edges to provide search index\n * @returns {boolean}\n */\n isSimple(edges) {\n let ip = Face.getSelfIntersections(this, edges, true);\n return ip.length === 0;\n }\n\n static getSelfIntersections(face, edges, exitOnFirst = false) {\n let int_points = [];\n\n // calculate intersections\n for (let edge1 of face) {\n\n // request edges of polygon in the box of edge1\n let resp = edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // Skip itself\n if (edge1 === edge2)\n continue;\n\n // Skip is edge2 belongs to another face\n if (edge2.face !== face)\n continue;\n\n // Skip next and previous edge if both are segment (if one of them arc - calc intersection)\n if (edge1.shape instanceof Flatten.Segment && edge2.shape instanceof Flatten.Segment &&\n (edge1.next === edge2 || edge1.prev === edge2))\n continue;\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n\n // skip start-end connections\n if (pt.equalTo(edge1.start) && pt.equalTo(edge2.end) && edge2 === edge1.prev)\n continue;\n if (pt.equalTo(edge1.end) && pt.equalTo(edge2.start) && edge2 === edge1.next)\n continue;\n\n int_points.push(pt);\n\n if (exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n\n }\n return int_points;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt - test point\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (pt.equalTo(edge.shape.start)) continue\n if (pt.equalTo(edge.shape.end) || edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new polygon created from one face\n * @returns {Polygon}\n */\n toPolygon() {\n return new Flatten.Polygon(this.shapes);\n }\n\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Returns string to be assigned to \"d\" attribute inside defined \"path\"\n * @returns {string}\n */\n svg() {\n let svgStr = `\\nM${this.first.start.x},${this.first.start.y}`;\n for (let edge of this) {\n svgStr += edge.svg();\n }\n svgStr += ` z`;\n return svgStr;\n }\n\n}\n\nFlatten.Face = Face;\n\n/**\n * Class representing a ray (a half-infinite line).\n * @type {Ray}\n */\nclass Ray extends Shape {\n /**\n * Ray may be constructed by setting an origin point and a normal vector, so that any point x\n * on a ray fit an equation:
\n * (x - origin) * vector = 0
\n * Ray defined by constructor is a right semi-infinite line with respect to the normal vector
\n * If normal vector is omitted ray is considered horizontal (normal vector is (0,1)).
\n * Don't be confused: direction of the normal vector is orthogonal to the ray
\n * @param {Point} pt - start point\n * @param {Vector} norm - normal vector\n */\n constructor(...args) {\n super();\n this.pt = new Flatten.Point();\n this.norm = new Flatten.Vector(0,1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length >= 1 && args[0] instanceof Flatten.Point) {\n this.pt = args[0].clone();\n }\n\n if (args.length === 1) {\n return;\n }\n\n if (args.length === 2 && args[1] instanceof Flatten.Vector) {\n this.norm = args[1].clone();\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of ray\n * @returns {Ray}\n */\n clone() {\n return new Ray(this.pt, this.norm);\n }\n\n /**\n * Slope of the ray - angle in radians between ray and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Returns half-infinite bounding box of the ray\n * @returns {Box} - bounding box\n */\n get box() {\n let slope = this.slope;\n return new Flatten.Box(\n slope > Math.PI/2 && slope < 3*Math.PI/2 ? Number.NEGATIVE_INFINITY : this.pt.x,\n slope >= 0 && slope <= Math.PI ? this.pt.y : Number.NEGATIVE_INFINITY,\n slope >= Math.PI/2 && slope <= 3*Math.PI/2 ? this.pt.x : Number.POSITIVE_INFINITY,\n slope >= Math.PI && slope <= 2*Math.PI || slope === 0 ? this.pt.y : Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Return ray start point\n * @returns {Point} - ray start point\n */\n get start() {\n return this.pt;\n }\n\n /**\n * Ray has no end point?\n * @returns {undefined}\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns true if point belongs to ray\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Ray contains point if vector to point is orthogonal to the ray normal vector\n and cross product from vector to point is positive */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec)) && Flatten.Utils.GE(vec.cross(this.norm),0);\n }\n\n /**\n * Return coordinate of the point that lies on the ray in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line containing this ray and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the ray\n * @param {Point} pt - point on a ray\n * @returns {number}\n */\n coord(pt) {\n return vector$1(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Split ray with point and return array of segment and new ray\n * @param {Point} pt\n * @returns [Segment,Ray]\n */\n split(pt) {\n if (!this.contains(pt))\n return [];\n\n if (this.pt.equalTo(pt)) {\n return [this]\n }\n\n return [\n new Flatten.Segment(this.pt, pt),\n new Flatten.Ray(pt, this.norm)\n ]\n }\n\n /**\n * Returns array of intersection points between ray and another shape\n * @param {Shape} shape - Shape to intersect with ray\n * @returns {Point[]} array of intersection points\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectRay2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectRay2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectRay2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Ray(this, shape)\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectRay2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectRay2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectRay2Polygon(this, shape);\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Ray(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new ray transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Ray}\n */\n transform(m) {\n return new Flatten.Ray(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n get name() {\n return \"ray\"\n }\n\n /**\n * Return string to draw svg segment representing ray inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg segment element\n */\n svg(box, attrs = {}) {\n let line = new Flatten.Line(this.pt, this.norm);\n let ip = intersectLine2Box(line, box);\n ip = ip.filter( pt => this.contains(pt) );\n if (ip.length === 0 || ip.length === 2)\n return \"\";\n let segment = new Flatten.Segment(this.pt, ip[0]);\n return segment.svg(attrs);\n }\n\n}\n\nFlatten.Ray = Ray;\n\nconst ray = (...args) => new Flatten.Ray(...args);\nFlatten.ray = ray;\n\n/**\n * Created by Alex Bol on 3/15/2017.\n */\n\n\n/**\n * Class representing a polygon.
\n * Polygon in FlattenJS is a multipolygon comprised from a set of [faces]{@link Flatten.Face}.
\n * Face, in turn, is a closed loop of [edges]{@link Flatten.Edge}, where edge may be segment or circular arc
\n * @type {Polygon}\n */\nclass Polygon {\n /**\n * Constructor creates new instance of polygon. With no arguments new polygon is empty.
\n * Constructor accepts as argument array that define loop of shapes\n * or array of arrays in case of multi polygon
\n * Loop may be defined in different ways:
\n * - array of shapes of type Segment or Arc
\n * - array of points (Flatten.Point)
\n * - array of numeric pairs which represent points
\n * - box or circle object
\n * Alternatively, it is possible to use polygon.addFace method\n * @param {args} - array of shapes or array of arrays\n */\n constructor() {\n /**\n * Container of faces (closed loops), may be empty\n * @type {PlanarSet}\n */\n this.faces = new Flatten.PlanarSet();\n /**\n * Container of edges\n * @type {PlanarSet}\n */\n this.edges = new Flatten.PlanarSet();\n\n /* It may be array of something that may represent one loop (face) or\n array of arrays that represent multiple loops\n */\n let args = [...arguments];\n if (args.length === 1 &&\n ((args[0] instanceof Array && args[0].length > 0) ||\n args[0] instanceof Flatten.Circle || args[0] instanceof Flatten.Box)) {\n let argsArray = args[0];\n if (args[0] instanceof Array && args[0].every((loop) => {\n return loop instanceof Array\n })) {\n if (argsArray.every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon as array of pairs of numbers\n } else {\n for (let loop of argsArray) { // multi-loop polygon\n /* Check extra level of nesting for GeoJSON-style multi polygons */\n if (loop instanceof Array && loop[0] instanceof Array &&\n loop[0].every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n for (let loop1 of loop) {\n this.faces.add(new Flatten.Face(this, loop1));\n }\n } else {\n this.faces.add(new Flatten.Face(this, loop));\n }\n }\n }\n } else {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon\n }\n }\n }\n\n /**\n * (Getter) Returns bounding box of the polygon\n * @returns {Box}\n */\n get box() {\n return [...this.faces].reduce((acc, face) => acc.merge(face.box), new Flatten.Box());\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Array}\n */\n get vertices() {\n return [...this.edges].map(edge => edge.start);\n }\n\n /**\n * Create new cloned instance of the polygon\n * @returns {Polygon}\n */\n clone() {\n let polygon = new Polygon();\n for (let face of this.faces) {\n polygon.addFace(face.shapes);\n }\n return polygon;\n }\n\n /**\n * Return true is polygon has no edges\n * @returns {boolean}\n */\n isEmpty() {\n return this.edges.size === 0;\n }\n\n /**\n * Return true if polygon is valid for boolean operations\n * Polygon is valid if
\n * 1. All faces are simple polygons (there are no self-intersected polygons)
\n * 2. All faces are orientable and there is no island inside island or hole inside hole - TODO
\n * 3. There is no intersections between faces (excluding touching) - TODO
\n * @returns {boolean}\n */\n isValid() {\n let valid = true;\n // 1. Polygon is invalid if at least one face is not simple\n for (let face of this.faces) {\n if (!face.isSimple(this.edges)) {\n valid = false;\n break;\n }\n }\n // 2. TODO: check if no island inside island and no hole inside hole\n // 3. TODO: check the there is no intersection between faces\n return valid;\n }\n\n /**\n * Returns area of the polygon. Area of an island will be added, area of a hole will be subtracted\n * @returns {number}\n */\n area() {\n let signedArea = [...this.faces].reduce((acc, face) => acc + face.signedArea(), 0);\n return Math.abs(signedArea);\n }\n\n /**\n * Add new face to polygon. Returns added face\n * @param {Point[]|Segment[]|Arc[]|Circle|Box} args - new face may be create with one of the following ways:
\n * 1) array of points that describe closed path (edges are segments)
\n * 2) array of shapes (segments and arcs) which describe closed path
\n * 3) circle - will be added as counterclockwise arc
\n * 4) box - will be added as counterclockwise rectangle
\n * You can chain method face.reverse() is you need to change direction of the creates face\n * @returns {Face}\n */\n addFace(...args) {\n let face = new Flatten.Face(this, ...args);\n this.faces.add(face);\n return face;\n }\n\n /**\n * Delete existing face from polygon\n * @param {Face} face Face to be deleted\n * @returns {boolean}\n */\n deleteFace(face) {\n for (let edge of face) {\n this.edges.delete(edge);\n }\n return this.faces.delete(face);\n }\n\n /**\n * Clear all faces and create new faces from edges\n */\n recreateFaces() {\n // Remove all faces\n this.faces.clear();\n for (let edge of this.edges) {\n edge.face = null;\n }\n\n // Restore faces\n let first;\n let unassignedEdgeFound = true;\n while (unassignedEdgeFound) {\n unassignedEdgeFound = false;\n for (let edge of this.edges) {\n if (edge.face === null) {\n first = edge;\n unassignedEdgeFound = true;\n break;\n }\n }\n\n if (unassignedEdgeFound) {\n let last = first;\n do {\n last = last.next;\n } while (last.next !== first)\n\n this.addFace(first, last);\n }\n }\n }\n\n /**\n * Delete chain of edges from the face.\n * @param {Face} face Face to remove chain\n * @param {Edge} edgeFrom Start of the chain of edges to be removed\n * @param {Edge} edgeTo End of the chain of edges to be removed\n */\n removeChain(face, edgeFrom, edgeTo) {\n // Special case: all edges removed\n if (edgeTo.next === edgeFrom) {\n this.deleteFace(face);\n return;\n }\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n face.remove(edge);\n this.edges.delete(edge); // delete from PlanarSet of edges and update index\n if (face.isEmpty()) {\n this.deleteFace(face); // delete from PlanarSet of faces and update index\n break;\n }\n }\n }\n\n /**\n * Add point as a new vertex and split edge. Point supposed to belong to an edge.\n * When edge is split, new edge created from the start of the edge to the new vertex\n * and inserted before current edge.\n * Current edge is trimmed and updated.\n * Method returns new edge added. If no edge added, it returns edge before vertex\n * @param {Point} pt Point to be added as a new vertex\n * @param {Edge} edge Edge to be split with new vertex and then trimmed from start\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n edge.face.insert(newEdge, edgeBefore);\n\n // Remove old edge from edges container and 2d index\n this.edges.delete(edge);\n\n // Insert new edge to the edges container and 2d index\n this.edges.add(newEdge);\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n // Add updated edge to the edges container and 2d index\n this.edges.add(edge);\n\n return newEdge;\n }\n\n /**\n * Merge given edge with next edge and remove vertex between them\n * @param {Edge} edge\n */\n removeEndVertex(edge) {\n const edge_next = edge.next;\n if (edge_next === edge) return\n edge.face.merge_with_next_edge(edge);\n this.edges.delete(edge_next);\n }\n\n /**\n * Cut polygon with multiline and return a new polygon\n * @param {Multiline} multiline\n * @returns {Polygon}\n */\n cut(multiline) {\n let newPoly = this.clone();\n\n // smart intersections\n let intersections = {\n int_points1: [],\n int_points2: [],\n int_points1_sorted: [],\n int_points2_sorted: []\n };\n\n // intersect each edge of multiline with each edge of the polygon\n // and create smart intersections\n for (let edge1 of multiline.edges) {\n for (let edge2 of newPoly.edges) {\n let ip = intersectEdge2Edge(edge1, edge2);\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n\n // No intersections - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort smart intersections\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // split by intersection points\n splitByIntersections(multiline, intersections.int_points1_sorted);\n splitByIntersections(newPoly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // initialize inclusion flags for edges of multiline incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n\n // calculate inclusion flag for edges of multiline incident to intersections\n calculateInclusionFlags(intersections.int_points1, newPoly);\n\n // filter intersections between two edges that got same inclusion flag\n for (let int_point1 of intersections.int_points1_sorted) {\n if (int_point1.edge_before && int_point1.edge_after &&\n int_point1.edge_before.bv === int_point1.edge_after.bv) {\n intersections.int_points2[int_point1.id] = -1; // to be filtered out\n int_point1.id = -1; // to be filtered out\n }\n }\n intersections.int_points1 = intersections.int_points1.filter( int_point => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter( int_point => int_point.id >= 0);\n\n // No intersections left after filtering - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort intersection points 3d time after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // Add new inner edges between intersection points\n let int_point1_prev;\n let int_point1_curr;\n for (let i = 1; i < intersections.int_points1_sorted.length; i++) {\n int_point1_curr = intersections.int_points1_sorted[i];\n int_point1_prev = intersections.int_points1_sorted[i-1];\n if (int_point1_curr.edge_before && int_point1_curr.edge_before.bv === INSIDE$2) {\n let edgeFrom = int_point1_prev.edge_after;\n let edgeTo = int_point1_curr.edge_before;\n let newEdges = multiline.getChain(edgeFrom, edgeTo);\n insertBetweenIntPoints(intersections.int_points2[int_point1_prev.id], intersections.int_points2[int_point1_curr.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n\n newEdges = newEdges.reverse().map(edge => new Flatten.Edge(edge.shape.reverse()));\n for (let k=0; k < newEdges.length-1; k++) {\n newEdges[k].next = newEdges[k+1];\n newEdges[k+1].prev = newEdges[k];\n }\n insertBetweenIntPoints(intersections.int_points2[int_point1_curr.id], intersections.int_points2[int_point1_prev.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n }\n\n }\n\n // Recreate faces\n newPoly.recreateFaces();\n\n return newPoly\n }\n\n /**\n * A special case of cut() function\n * The return is a polygon cut with line\n * @param {Line} line - cutting line\n * @returns {Polygon} newPoly - resulted polygon\n */\n cutWithLine(line) {\n let multiline = new Multiline([line]);\n return this.cut(multiline);\n }\n\n /**\n * Returns the first found edge of polygon that contains given point\n * If point is a vertex, return the edge where the point is an end vertex, not a start one\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edge;\n for (let face of this.faces) {\n edge = face.findEdgeByPoint(pt);\n if (edge !== undefined)\n break;\n }\n return edge;\n }\n\n /**\n * Split polygon into array of polygons, where each polygon is an outer face with all\n * containing inner faces\n * @returns {Flatten.Polygon[]}\n */\n splitToIslands() {\n if (this.isEmpty()) return []; // return empty array if polygon is empty\n let polygons = this.toArray(); // split into array of one-loop polygons\n /* Sort polygons by area in descending order */\n polygons.sort((polygon1, polygon2) => polygon2.area() - polygon1.area());\n /* define orientation of the island by orientation of the first polygon in array */\n let orientation = [...polygons[0].faces][0].orientation();\n /* Create output array from polygons with same orientation as a first polygon (array of islands) */\n let newPolygons = polygons.filter(polygon => [...polygon.faces][0].orientation() === orientation);\n for (let polygon of polygons) {\n let face = [...polygon.faces][0];\n if (face.orientation() === orientation) continue; // skip same orientation\n /* Proceed with opposite orientation */\n /* Look if any of island polygons contains tested polygon as a hole */\n for (let islandPolygon of newPolygons) {\n if (face.shapes.every(shape => islandPolygon.contains(shape))) {\n islandPolygon.addFace(face.shapes); // add polygon as a hole in islandPolygon\n break;\n }\n }\n }\n // TODO: assert if not all polygons added into output\n return newPolygons;\n }\n\n /**\n * Reverse orientation of all faces to opposite\n * @returns {Polygon}\n */\n reverse() {\n for (let face of this.faces) {\n face.reverse();\n }\n return this;\n }\n\n /**\n * Returns true if polygon contains shape: no point of shape lay outside of the polygon,\n * false otherwise\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n let rel = ray_shoot(this, shape);\n return rel === INSIDE$2 || rel === BOUNDARY$1;\n } else {\n return cover(this, shape);\n }\n }\n\n /**\n * Return distance and shortest segment between polygon and other shape as array [distance, shortest_segment]\n * @param {Shape} shape Shape of one of the types Point, Circle, Line, Segment, Arc or Polygon\n * @returns {Number | Segment}\n */\n distanceTo(shape) {\n // let {Distance} = Flatten;\n\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle ||\n shape instanceof Flatten.Line ||\n shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /* this method is bit faster */\n if (shape instanceof Flatten.Polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n let dist, shortest_segment;\n\n for (let edge of this.edges) {\n // let [dist, shortest_segment] = Distance.shape2polygon(edge.shape, shape);\n let min_stop = min_dist_and_segment[0];\n [dist, shortest_segment] = Flatten.Distance.shape2planarSet(edge.shape, shape.edges, min_stop);\n if (Flatten.Utils.LT(dist, min_stop)) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n }\n\n /**\n * Return array of intersection points between polygon and other shape\n * @param shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectPolygon2Polygon(shape, this);\n }\n }\n\n /**\n * Returns new polygon translated by vector vec\n * @param {Vector} vec\n * @returns {Polygon}\n */\n translate(vec) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.translate(vec)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Polygon} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.rotate(angle, center)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Polygon}\n */\n scale(sx, sy) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.scale(sx, sy)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Polygon} - new polygon\n */\n transform(matrix = new Flatten.Matrix()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.transform(matrix)));\n }\n return newPolygon;\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return [...this.faces].map(face => face.toJSON());\n }\n\n /**\n * Transform all faces into array of polygons\n * @returns {Flatten.Polygon[]}\n */\n toArray() {\n return [...this.faces].map(face => face.toPolygon());\n }\n\n /**\n * Return string to draw polygon in svg\n * @param attrs - an object with attributes for svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Polygon = Polygon;\n\n/**\n * Shortcut method to create new polygon\n */\nconst polygon = (...args) => new Flatten.Polygon(...args);\nFlatten.polygon = polygon;\n\nconst {Circle, Line, Point, Vector, Utils} = Flatten;\n/**\n * Class Inversion represent operator of inversion in circle\n * Inversion is a transformation of the Euclidean plane that maps generalized circles\n * (where line is considered as a circle with infinite radius) into generalized circles\n * See also https://en.wikipedia.org/wiki/Inversive_geometry and\n * http://mathworld.wolfram.com/Inversion.html
\n * @type {Inversion}\n */\nclass Inversion {\n /**\n * Inversion constructor\n * @param {Circle} inversion_circle inversion circle\n */\n constructor(inversion_circle) {\n this.circle = inversion_circle;\n }\n\n\n get inversion_circle() {\n return this.circle;\n }\n\n static inversePoint(inversion_circle, point) {\n const v = new Vector(inversion_circle.pc, point);\n const k2 = inversion_circle.r * inversion_circle.r;\n const len2 = v.dot(v);\n const reflected_point = Utils.EQ_0(len2) ?\n new Point(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) :\n inversion_circle.pc.translate(v.multiply(k2 / len2));\n return reflected_point;\n }\n\n static inverseCircle(inversion_circle, circle) {\n const dist = inversion_circle.pc.distanceTo(circle.pc)[0];\n if (Utils.EQ(dist, circle.r)) { // Circle passing through inversion center mapped into line\n let d = (inversion_circle.r * inversion_circle.r) / (2 * circle.r);\n let v = new Vector(inversion_circle.pc, circle.pc);\n v = v.normalize();\n let pt = inversion_circle.pc.translate(v.multiply(d));\n\n return new Line(pt, v);\n } else { // Circle not passing through inversion center - map into another circle */\n /* Taken from http://mathworld.wolfram.com */\n let v = new Vector(inversion_circle.pc, circle.pc);\n let s = inversion_circle.r * inversion_circle.r / (v.dot(v) - circle.r * circle.r);\n let pc = inversion_circle.pc.translate(v.multiply(s));\n let r = Math.abs(s) * circle.r;\n\n return new Circle(pc, r);\n }\n }\n\n static inverseLine(inversion_circle, line) {\n const [dist, shortest_segment] = inversion_circle.pc.distanceTo(line);\n if (Utils.EQ_0(dist)) { // Line passing through inversion center, is mapping to itself\n return line.clone();\n } else { // Line not passing through inversion center is mapping into circle\n let r = inversion_circle.r * inversion_circle.r / (2 * dist);\n let v = new Vector(inversion_circle.pc, shortest_segment.end);\n v = v.multiply(r / dist);\n return new Circle(inversion_circle.pc.translate(v), r);\n }\n }\n\n inverse(shape) {\n if (shape instanceof Point) {\n return Inversion.inversePoint(this.circle, shape);\n }\n else if (shape instanceof Circle) {\n return Inversion.inverseCircle(this.circle, shape);\n }\n else if (shape instanceof Line) {\n return Inversion.inverseLine(this.circle, shape);\n }\n }\n}\nFlatten.Inversion = Inversion;\n\n/**\n * Shortcut to create inversion operator\n * @param circle\n * @returns {Inversion}\n */\nconst inversion = (circle) => new Flatten.Inversion(circle);\nFlatten.inversion = inversion;\n\nclass Distance {\n /**\n * Calculate distance and shortest segment between points\n * @param pt1\n * @param pt2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2point(pt1, pt2) {\n return pt1.distanceTo(pt2);\n }\n\n /**\n * Calculate distance and shortest segment between point and line\n * @param pt\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2line(pt, line) {\n let closest_point = pt.projectionOn(line);\n let vec = new Flatten.Vector(pt, closest_point);\n return [vec.length, new Flatten.Segment(pt, closest_point)];\n }\n\n /**\n * Calculate distance and shortest segment between point and circle\n * @param pt\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2circle(pt, circle) {\n let [dist2center, shortest_dist] = pt.distanceTo(circle.center);\n if (Flatten.Utils.EQ_0(dist2center)) {\n return [circle.r, new Flatten.Segment(pt, circle.toArc().start)];\n } else {\n let dist = Math.abs(dist2center - circle.r);\n let v = new Flatten.Vector(circle.pc, pt).normalize().multiply(circle.r);\n let closest_point = circle.pc.translate(v);\n return [dist, new Flatten.Segment(pt, closest_point)];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and segment\n * @param pt\n * @param segment\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2segment(pt, segment) {\n /* Degenerated case of zero-length segment */\n if (segment.start.equalTo(segment.end)) {\n return Distance.point2point(pt, segment.start);\n }\n\n let v_seg = new Flatten.Vector(segment.start, segment.end);\n let v_ps2pt = new Flatten.Vector(segment.start, pt);\n let v_pe2pt = new Flatten.Vector(segment.end, pt);\n let start_sp = v_seg.dot(v_ps2pt);\n /* dot product v_seg * v_ps2pt */\n let end_sp = -v_seg.dot(v_pe2pt);\n /* minus dot product v_seg * v_pe2pt */\n\n let dist;\n let closest_point;\n if (Flatten.Utils.GE(start_sp, 0) && Flatten.Utils.GE(end_sp, 0)) { /* point inside segment scope */\n let v_unit = segment.tangentInStart(); // new Flatten.Vector(v_seg.x / this.length, v_seg.y / this.length);\n /* unit vector ||v_unit|| = 1 */\n dist = Math.abs(v_unit.cross(v_ps2pt));\n /* dist = abs(v_unit x v_ps2pt) */\n closest_point = segment.start.translate(v_unit.multiply(v_unit.dot(v_ps2pt)));\n return [dist, new Flatten.Segment(pt, closest_point)];\n } else if (start_sp < 0) { /* point is out of scope closer to ps */\n return pt.distanceTo(segment.start);\n } else { /* point is out of scope closer to pe */\n return pt.distanceTo(segment.end);\n }\n };\n\n /**\n * Calculate distance and shortest segment between point and arc\n * @param pt\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2arc(pt, arc) {\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let dist_and_segment = [];\n let dist, shortest_segment;\n [dist, shortest_segment] = Distance.point2circle(pt, circle);\n if (shortest_segment.end.on(arc)) {\n dist_and_segment.push(Distance.point2circle(pt, circle));\n }\n dist_and_segment.push(Distance.point2point(pt, arc.start));\n dist_and_segment.push(Distance.point2point(pt, arc.end));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and line\n * @param seg\n * @param line\n * @returns {Number | Segment}\n */\n static segment2line(seg, line) {\n let ip = seg.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(seg.start, line));\n dist_and_segment.push(Distance.point2line(seg.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n\n }\n\n /**\n * Calculate distance and shortest segment between two segments\n * @param seg1\n * @param seg2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2segment(seg1, seg2) {\n let ip = intersectSegment2Segment(seg1, seg2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n\n // Seg1 and seg2 not intersected\n let dist_and_segment = [];\n let dist_tmp, shortest_segment_tmp;\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.start, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.end, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n dist_and_segment.push(Distance.point2segment(seg1.start, seg2));\n dist_and_segment.push(Distance.point2segment(seg1.end, seg2));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and circle\n * @param seg\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2circle(seg, circle) {\n /* Case 1 Segment and circle intersected. Return the first point and zero distance */\n let ip = seg.intersect(circle);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and circle\n\n /* Case 2. Distance to projection of center point to line bigger than radius\n * And projection point belong to segment\n * Then measure again distance from projection to circle and return it */\n let line = new Flatten.Line(seg.ps, seg.pe);\n let [dist, shortest_segment] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist, circle.r) && shortest_segment.end.on(seg)) {\n return Distance.point2circle(shortest_segment.end, circle);\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n else {\n let [dist_from_start, shortest_segment_from_start] = Distance.point2circle(seg.start, circle);\n let [dist_from_end, shortest_segment_from_end] = Distance.point2circle(seg.end, circle);\n return Flatten.Utils.LT(dist_from_start, dist_from_end) ?\n [dist_from_start, shortest_segment_from_start] :\n [dist_from_end, shortest_segment_from_end];\n }\n }\n\n /**\n * Calculate distance and shortest segment between segment and arc\n * @param seg\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2arc(seg, arc) {\n /* Case 1 Segment and arc intersected. Return the first point and zero distance */\n let ip = seg.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and arc\n let line = new Flatten.Line(seg.ps, seg.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r) && shortest_segment_from_center.end.on(seg)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2arc(seg.start, arc));\n dist_and_segment.push(Distance.point2arc(seg.end, arc));\n\n let dist_tmp, segment_tmp;\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.start, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.end, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle1\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2circle(circle1, circle2) {\n let ip = circle1.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // Case 1. Concentric circles. Convert to arcs and take distance between two arc starts\n if (circle1.center.equalTo(circle2.center)) {\n let arc1 = circle1.toArc();\n let arc2 = circle2.toArc();\n return Distance.point2point(arc1.start, arc2.start);\n } else {\n // Case 2. Not concentric circles\n let line = new Flatten.Line(circle1.center, circle2.center);\n let ip1 = line.intersect(circle1);\n let ip2 = line.intersect(circle2);\n\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[1]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[1]));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2line(circle, line) {\n let ip = circle.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n let [dist, shortest_segment] = Distance.point2circle(shortest_segment_from_center.end, circle);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /**\n * Calculate distance and shortest segment between arc and line\n * @param arc\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2line(arc, line) {\n /* Case 1 Line and arc intersected. Return the first point and zero distance */\n let ip = line.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle = new Flatten.Circle(arc.center, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n } else {\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(arc.start, line));\n dist_and_segment.push(Distance.point2line(arc.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between arc and circle\n * @param arc\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2circle(arc, circle2) {\n let ip = arc.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc.center, arc.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2circle(arc.start, circle2));\n dist_and_segment.push(Distance.point2circle(arc.end, circle2));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two arcs\n * @param arc1\n * @param arc2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2arc(arc1, arc2) {\n let ip = arc1.intersect(arc2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc1.center, arc1.r);\n let circle2 = new Flatten.Circle(arc2.center, arc2.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc1) && shortest_segment.end.on(arc2)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n let dist_tmp, segment_tmp;\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.start, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.end, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.start, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.end, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and polygon\n * @param point\n * @param polygon\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2polygon(point, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = (edge.shape instanceof Flatten.Segment) ?\n Distance.point2segment(point, edge.shape) : Distance.point2arc(point, edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n static shape2polygon(shape, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = shape.distanceTo(edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Calculate distance and shortest segment between two polygons\n * @param polygon1\n * @param polygon2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static polygon2polygon(polygon1, polygon2) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge1 of polygon1.edges) {\n for (let edge2 of polygon2.edges) {\n let [dist, shortest_segment] = edge1.shape.distanceTo(edge2.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Returns [mindist, maxdist] array of squared minimal and maximal distance between boxes\n * Minimal distance by x is\n * (box2.xmin - box1.xmax), if box1 is left to box2\n * (box1.xmin - box2.xmax), if box2 is left to box1\n * 0, if box1 and box2 are intersected by x\n * Minimal distance by y is defined in the same way\n *\n * Maximal distance is estimated as a sum of squared dimensions of the merged box\n *\n * @param box1\n * @param box2\n * @returns {Number | Number} - minimal and maximal distance\n */\n static box2box_minmax(box1, box2) {\n let mindist_x = Math.max(Math.max(box1.xmin - box2.xmax, 0), Math.max(box2.xmin - box1.xmax, 0));\n let mindist_y = Math.max(Math.max(box1.ymin - box2.ymax, 0), Math.max(box2.ymin - box1.ymax, 0));\n let mindist = mindist_x * mindist_x + mindist_y * mindist_y;\n\n let box = box1.merge(box2);\n let dx = box.xmax - box.xmin;\n let dy = box.ymax - box.ymin;\n let maxdist = dx * dx + dy * dy;\n\n return [mindist, maxdist];\n }\n\n static minmax_tree_process_level(shape, level, min_stop, tree) {\n // Calculate minmax distance to each shape in current level\n // Insert result into the interval tree for further processing\n // update min_stop with maxdist, it will be the new stop distance\n let mindist, maxdist;\n for (let node of level) {\n\n // [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n // if (Flatten.Utils.GT(mindist, min_stop))\n // continue;\n\n // Estimate min-max dist to the shape stored in the node.item, using node.item.key which is shape's box\n [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.item.key);\n if (node.item.value instanceof Flatten.Edge) {\n tree.insert([mindist, maxdist], node.item.value.shape);\n } else {\n tree.insert([mindist, maxdist], node.item.value);\n }\n if (Flatten.Utils.LT(maxdist, min_stop)) {\n min_stop = maxdist; // this will be the new distance estimation\n }\n }\n\n if (level.length === 0)\n return min_stop;\n\n // Calculate new level from left and right children of the current\n let new_level_left = level.map(node => node.left.isNil() ? undefined : node.left).filter(node => node !== undefined);\n let new_level_right = level.map(node => node.right.isNil() ? undefined : node.right).filter(node => node !== undefined);\n // Merge left and right subtrees and leave only relevant subtrees\n let new_level = [...new_level_left, ...new_level_right].filter(node => {\n // Node subtree quick reject, node.max is a subtree box\n let [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n return (Flatten.Utils.LE(mindist, min_stop));\n });\n\n min_stop = Distance.minmax_tree_process_level(shape, new_level, min_stop, tree);\n return min_stop;\n }\n\n /**\n * Calculates sorted tree of [mindist, maxdist] intervals between query shape\n * and shapes of the planar set.\n * @param shape\n * @param set\n */\n static minmax_tree(shape, set, min_stop) {\n let tree = new IntervalTree();\n let level = [set.index.root];\n let squared_min_stop = min_stop < Number.POSITIVE_INFINITY ? min_stop * min_stop : Number.POSITIVE_INFINITY;\n squared_min_stop = Distance.minmax_tree_process_level(shape, level, squared_min_stop, tree);\n return tree;\n }\n\n static minmax_tree_calc_distance(shape, node, min_dist_and_segment) {\n let min_dist_and_segment_new, stop;\n if (node != null && !node.isNil()) {\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.left, min_dist_and_segment);\n\n if (stop) {\n return [min_dist_and_segment_new, stop];\n }\n\n if (Flatten.Utils.LT(min_dist_and_segment_new[0], Math.sqrt(node.item.key.low))) {\n return [min_dist_and_segment_new, true]; // stop condition\n }\n\n let [dist, shortest_segment] = Distance.distance(shape, node.item.value);\n // console.log(dist)\n if (Flatten.Utils.LT(dist, min_dist_and_segment_new[0])) {\n min_dist_and_segment_new = [dist, shortest_segment];\n }\n\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.right, min_dist_and_segment_new);\n\n return [min_dist_and_segment_new, stop];\n }\n\n return [min_dist_and_segment, false];\n }\n\n /**\n * Calculates distance between shape and Planar Set of shapes\n * @param shape\n * @param {PlanarSet} set\n * @param {Number} min_stop\n * @returns {*}\n */\n static shape2planarSet(shape, set, min_stop = Number.POSITIVE_INFINITY) {\n let min_dist_and_segment = [min_stop, new Flatten.Segment()];\n let stop = false;\n if (set instanceof Flatten.PlanarSet) {\n let tree = Distance.minmax_tree(shape, set, min_stop);\n [min_dist_and_segment, stop] = Distance.minmax_tree_calc_distance(shape, tree.root, min_dist_and_segment);\n }\n return min_dist_and_segment;\n }\n\n static sort(dist_and_segment) {\n dist_and_segment.sort((d1, d2) => {\n if (Flatten.Utils.LT(d1[0], d2[0])) {\n return -1;\n }\n if (Flatten.Utils.GT(d1[0], d2[0])) {\n return 1;\n }\n return 0;\n });\n }\n\n static distance(shape1, shape2) {\n return shape1.distanceTo(shape2);\n }\n}\n\nFlatten.Distance = Distance;\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\nFlatten.BooleanOperations = BooleanOperations;\nFlatten.Relations = Relations;\n\nexport { Arc, BOUNDARY$1 as BOUNDARY, BooleanOperations, Box, CCW, CW, Circle$1 as Circle, Distance, Edge, Errors, Face, INSIDE$2 as INSIDE, Inversion, Line$1 as Line, Matrix, Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$1 as Point, Polygon, Ray, Relations, Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, line, matrix, multiline, point, polygon, ray, ray_shoot, segment, vector$1 as vector };\n","import type {LatLngExpression} from 'leaflet';\nimport L, {Bounds, LatLng, LatLngBounds, Path, Point, Util} from 'leaflet';\nimport Flatten from '@flatten-js/core';\nimport Matrix = Flatten.Matrix;\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport type {ShapeOptions, TrackSymbolOptions} from './options';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_LEADER_TIME = 60;\n\n/**\n * Track symbol.\n */\nexport class TrackSymbol\n extends Path {\n\n /** Default 'withHeading' shape points. */\n public static DEFAULT_HEADING_SHAPE_POINTS: Points = [[0.75, 0], [-0.25, 0.3], [-0.25, -0.3]];\n\n /** Default 'withoutHeading' shape points. */\n public static DEFAULT_NOHEADING_SHAPE_POINTS: Points = [[0.3, 0], [0, 0.3], [-0.3, 0], [0, -0.3]];\n\n /** Default shape set. */\n private static DEFAULT_SHAPE_SET: ShapeSet = {\n withHeading: {\n points: TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n withoutHeading: {\n points: TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n };\n\n /** Location. */\n private _latLng: LatLng;\n /** Heading (radians, from north, clockwise. */\n private _heading?: number;\n /** Course (radians, from north, clockwise. */\n private _course?: number;\n /** Speed (m/s). */\n private _speed?: number;\n /** Shape options. */\n private _shapeOptions: ShapeOptions;\n\n /** Current shape points. */\n private _currentShapePoints: Point[] | undefined;\n /** Current leader points. */\n private _currentLeaderPoints: Point[] | undefined;\n /** Current bounds. */\n private _currentBounds: Bounds | undefined;\n /** Current lat/lng bounds. */\n private _currentLatLngBounds: LatLngBounds | undefined;\n\n /**\n * TrackSymbol constructor.\n *\n * @param latLng - Initial location.\n * @param options - Options.\n */\n constructor(latLng: LatLngExpression, options?: TrackSymbolOptions) {\n super();\n\n Util.setOptions(this, options);\n if (latLng == undefined) {\n throw Error(\"latLng required\");\n }\n options = options || {};\n this._latLng = L.latLng(latLng);\n this._heading = options.heading;\n this._course = options.course;\n this._speed = options.speed;\n this._shapeOptions = options.shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n this._setShapeOptions(options.shapeOptions);\n }\n\n // ---- Leaflet\n\n /**\n * Project to layer.\n *\n * [Leaflet internal]\n */\n protected _project() {\n this._currentShapePoints = this._getProjectedShapePoints();\n this._currentLeaderPoints = this._getLeaderShapePoints();\n\n const bounds = new Bounds();\n for (let i = 0; i < this._currentShapePoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n if (this._currentLeaderPoints !== undefined) {\n for (let i = 0; i < this._currentLeaderPoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n }\n this._currentBounds = bounds;\n this._currentLatLngBounds = new LatLngBounds(\n this._map.layerPointToLatLng(bounds.getBottomLeft()),\n this._map.layerPointToLatLng(bounds.getTopRight())\n );\n }\n\n /**\n * Update element.\n *\n * [Leaflet internal]\n */\n protected _update() {\n if (!this._map) {\n return;\n }\n const el = this.getElement();\n if (el === undefined) {\n return;\n }\n const paths: string[] = [];\n if (this._currentShapePoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentShapePoints, true));\n }\n if (this._currentLeaderPoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentLeaderPoints, false));\n }\n const viewPath = paths.join(' ');\n el.setAttribute('d', viewPath);\n }\n\n // ----\n\n /**\n * Set shape options.\n *\n * @param shapeOptions - Shape options.\n */\n private _setShapeOptions(shapeOptions: ShapeOptions | undefined) {\n this._shapeOptions = shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n if (this._shapeOptions.leaderTime === undefined) {\n this._shapeOptions.leaderTime = DEFAULT_LEADER_TIME;\n }\n if (this._shapeOptions.defaultShapeSet === undefined) {\n this._shapeOptions.defaultShapeSet = TrackSymbol.DEFAULT_SHAPE_SET;\n }\n if (this._shapeOptions.shapeSetEntries !== undefined) {\n this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel);\n }\n }\n\n // ---\n\n /**\n * Sets the location.\n *\n * @param latLng - Location.\n * @returns this\n */\n public setLatLng(latLng: LatLngExpression): this {\n const oldLatLng = this._latLng;\n this._latLng = L.latLng(latLng);\n this.fire('move', {\n oldLatLng: oldLatLng,\n latlng: this._latLng,\n });\n return this.redraw();\n }\n\n /**\n * Sets the heading.\n *\n * @param heading - Heading (unit: radians, from north, clockwise).\n * @returns this\n */\n public setHeading(heading: number | undefined): this {\n this._heading = heading;\n return this.redraw();\n }\n\n /**\n * Sets the course over ground.\n *\n * @param course - Course over ground (unit: radians, from north, clockwise).\n * @returns this\n */\n public setCourse(course: number | undefined): this {\n this._course = course;\n return this.redraw();\n }\n\n /**\n * Sets the speed.\n *\n * @param speed - Speed (unit: m/s).\n * @returns this\n */\n public setSpeed(speed: number | undefined): this {\n this._speed = speed;\n return this.redraw();\n }\n\n /**\n * Sets the shape options.\n *\n * @param shapeOptions - Shape options.\n * @returns this\n */\n public setShapeOptions(shapeOptions: ShapeOptions): this {\n this._setShapeOptions(shapeOptions);\n return this.redraw();\n }\n\n /**\n * Returns the bounding box.\n *\n * @returns The bounding box.\n */\n public getBounds(): LatLngBounds | undefined {\n return this._currentLatLngBounds;\n }\n\n /**\n * Returns the location.\n *\n * @returns The location.\n */\n public getLatLng(): LatLng {\n return this._latLng;\n }\n\n /**\n * Returns the speed.\n *\n * @returns The speed (m/s).\n */\n public getSpeed(): number | undefined {\n return this._speed;\n }\n\n /**\n * Returns the heading.\n *\n * @returns The heading (radians, from north, clockwise).\n */\n public getHeading(): number | undefined {\n return this._heading;\n }\n\n /**\n * Returns the course.\n *\n * @returns The course (radians, from north, clockwise).\n */\n public getCourse(): number | undefined {\n return this._course;\n }\n\n /**\n * Creates a shape.\n *\n * @param points - Points.\n * @param size - Size (units: pixels).\n * @returns The new shape.\n */\n public static createShape(points: Points, size: number): Shape {\n return {\n points: points,\n length: size,\n breadth: size,\n units: \"pixels\",\n };\n }\n\n /**\n * Creates a shape set.\n *\n * @param size - Size (units: pixels).\n * @returns The new shape set.\n */\n public static createShapeSet(size: number): ShapeSet {\n return {\n withHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS, size),\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n /**\n * Get latitude size of y-distance.\n *\n * @param value - Y distance (m).\n * @returns dLat\n */\n private _getLatSizeOf(value: number): number {\n return (value / 40075017) * 360;\n }\n\n /**\n * Get longitude size of x-distance.\n *\n * @param value - X distance (m).\n * @returns dLng\n */\n private _getLngSizeOf(value: number): number {\n return ((value / 40075017) * 360) / Math.cos((Math.PI / 180) * this._latLng.lat);\n }\n\n /**\n * Get view angle from model.\n *\n * @param modelAngle - Model angle (radians).\n * @returns View angle from model (radians).\n */\n private _getViewAngleFromModel(modelAngle: number): number {\n return modelAngle - Math.PI / 2.0;\n }\n\n /**\n * Get leader shape points.\n *\n * @returns Points.\n */\n private _getLeaderShapePoints(): Point[] | undefined {\n if ((this._course === undefined) || (this._speed === undefined)\n || (this._shapeOptions === undefined) || (this._shapeOptions.leaderTime === undefined)) {\n return undefined;\n }\n const angle = this._getViewAngleFromModel(this._course);\n const leaderLength = this._speed * this._shapeOptions.leaderTime;\n const leaderEndLatLng = this._calcRelativeLatLng(this._latLng, leaderLength, angle);\n return this._latLngsToLayerPoints(this._latLng, leaderEndLatLng);\n }\n\n /**\n * Calculate relative lat/lng.\n *\n * @param latLng - LatLng.\n * @param distance - Distance (meters).\n * @param angle - Angle (radians).\n * @returns Calculated LatLng.\n */\n private _calcRelativeLatLng(latLng: LatLng, distance: number, angle: number): LatLng {\n return new LatLng(\n latLng.lat - this._getLatSizeOf(distance * Math.sin(angle)),\n latLng.lng + this._getLngSizeOf(distance * Math.cos(angle))\n );\n }\n\n /**\n * Convert LatLngs to map layer points.\n *\n * @param latLngs - LatLngs.\n * @returns Points.\n */\n private _latLngsToLayerPoints(...latLngs: LatLng[]): Point[] {\n return latLngs.map(latLng => this._map.latLngToLayerPoint(latLng));\n }\n\n /**\n * Gets the shape set.\n *\n * @returns The shape set.\n */\n private _getShapeSet(): ShapeSet {\n if ((this._shapeOptions.shapeSetEntries === undefined)\n || (this._shapeOptions.shapeSetEntries.length == 0)) {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n const zoomLevel = this._map.getZoom();\n const shapeSetEntriesFiltered = this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel)\n .filter(shapeSetEntry => zoomLevel >= shapeSetEntry.minZoomLevel);\n if (shapeSetEntriesFiltered.length > 0) {\n return shapeSetEntriesFiltered[0].shapeSet;\n } else {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n }\n\n /**\n * Gets the shape.\n *\n * @returns The shape.\n */\n private _getShape(): Shape {\n const shapeSet = this._getShapeSet();\n return (this._heading !== undefined) ? shapeSet.withHeading : shapeSet.withoutHeading;\n }\n\n /**\n * Get transformed shape points.\n *\n * @returns Transformed points and units.\n */\n private _getTransformedShapePoints(): [Points, Units] {\n const shape = this._getShape();\n let m = new Matrix();\n if (this._heading !== undefined) {\n const headingAngle = this._getViewAngleFromModel(this._heading);\n m = m.rotate(headingAngle);\n }\n if (shape.center !== undefined) {\n m = m.translate(-shape.center[0], -shape.center[1]);\n }\n m = m.scale(shape.length, shape.breadth);\n const points = shape.points.map(point => m.transform(point));\n return [points, shape.units];\n }\n\n /**\n * Get projected shape points.\n *\n * @returns Points projected to map layer.\n */\n private _getProjectedShapePoints(): Point[] {\n const [points, units] = this._getTransformedShapePoints();\n switch (units) {\n case \"pixels\": {\n const p = this._map.latLngToLayerPoint(this._latLng);\n const m = new Matrix().translate(p.x, p.y);\n return points.map(point => {\n const p1 = m.transform(point);\n return new Point(p1[0], p1[1]);\n });\n }\n case \"meters\": {\n return points.map(point => this._map.latLngToLayerPoint(\n new LatLng(\n this._latLng.lat - this._getLatSizeOf(point[1]),\n this._latLng.lng + this._getLngSizeOf(point[0])\n )\n ));\n }\n default:\n throw `unsupported units: ${units}`;\n }\n }\n\n /**\n * Converts points to an SVG path string.\n *\n * @param points - Points.\n * @param close - Close path.\n * @returns SVG path string.\n */\n private static _toSVGPath(points: Point[], close: boolean): string {\n let result = '';\n for (let i = 0; i < points.length; i++) {\n const point = points[i];\n if (result === '') {\n result = `M ${point.x} ${point.y} `;\n } else {\n result += `L ${point.x} ${point.y} `;\n }\n }\n if (close) {\n result += 'Z';\n }\n return result;\n }\n}\n","import {TrackSymbol} from '../trackSymbol';\nimport type {ShapeOptions} from '../options';\nimport type {Points, ShapeSet} from '../types';\nimport type {AISTrackSymbolOptions} from './options';\nimport type {Dimension, ETA, PositionReport, ShipStaticData} from './types';\nimport {DomUtil, Util} from 'leaflet';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_MIN_ZOOM_LEVEL = 14;\nconst DEFAULT_LEADER_TIME = 60;\nconst KNOTS_PER_METER_PER_SECOND = 1.944;\nconst MAX_SOG_EXCLUSIVE = 102.3;\nconst MAX_COG_EXCLUSIVE = 360;\nconst MAX_HEADING_EXCLUSIVE = 360;\n\ninterface ShipType {\n name: string;\n color: string;\n fillColor: string;\n}\n\nconst RESERVED_COLOR = \"#000000\";\nconst RESERVED_FILL_COLOR = \"#d3d3d3\";\nconst WIG_COLOR = \"#000000\";\nconst WIG_FILL_COLOR = \"#d3d3d3\";\nconst TYPE_3X_COLOR = \"#8b008b\";\nconst TYPE_3X_FILL_COLOR = \"#ff00ff\";\nconst HSC_COLOR = \"#00008b\";\nconst HSC_FILL_COLOR = \"#ffff00\";\nconst TYPE_5X_COLOR = \"#008b8b\";\nconst TYPE_5X_FILL_COLOR = \"#00ffff\";\nconst PASSENGER_COLOR = \"#00008b\";\nconst PASSENGER_FILL_COLOR = \"#0000ff\";\nconst CARGO_COLOR = \"#006400\";\nconst CARGO_FILL_COLOR = \"#90ee90\";\nconst TANKER_COLOR = \"#8b0000\";\nconst TANKER_FILL_COLOR = \"#ff0000\";\nconst OTHER_COLOR = \"#008b8b\";\nconst OTHER_FILL_COLOR = \"#00ffff\";\n\nconst TYPES: { [key: number]: ShipType } = {\n 0: newShipType('Not available', WIG_COLOR, WIG_FILL_COLOR),\n 20: newShipType('Wing in ground (WIG), all ships of this type', WIG_COLOR, WIG_FILL_COLOR),\n 21: newShipType('Wing in ground (WIG), Hazardous category A', WIG_COLOR, WIG_FILL_COLOR),\n 22: newShipType('Wing in ground (WIG), Hazardous category B', WIG_COLOR, WIG_FILL_COLOR),\n 23: newShipType('Wing in ground (WIG), Hazardous category C', WIG_COLOR, WIG_FILL_COLOR),\n 24: newShipType('Wing in ground (WIG), Hazardous category D', WIG_COLOR, WIG_FILL_COLOR),\n 25: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 26: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 27: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 28: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 29: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 30: newShipType('Fishing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 31: newShipType('Towing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 32: newShipType('Towing: length exceeds 200m or breadth exceeds 25m', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 33: newShipType('Dredging or underwater ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 34: newShipType('Diving ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 35: newShipType('Military ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 36: newShipType('Sailing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 37: newShipType('Pleasure Craft', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 40: newShipType('High speed craft (HSC), all ships of this type', HSC_COLOR, HSC_FILL_COLOR),\n 41: newShipType('High speed craft (HSC), Hazardous category A', HSC_COLOR, HSC_FILL_COLOR),\n 42: newShipType('High speed craft (HSC), Hazardous category B', HSC_COLOR, HSC_FILL_COLOR),\n 43: newShipType('High speed craft (HSC), Hazardous category C', HSC_COLOR, HSC_FILL_COLOR),\n 44: newShipType('High speed craft (HSC), Hazardous category D', HSC_COLOR, HSC_FILL_COLOR),\n 45: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 46: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 47: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 48: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 49: newShipType('High speed craft (HSC), No additional information', HSC_COLOR, HSC_FILL_COLOR),\n 50: newShipType('Pilot Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 51: newShipType('Search and Rescue vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 52: newShipType('Tug', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 53: newShipType('Port Tender', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 54: newShipType('Anti-pollution equipment', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 55: newShipType('Law Enforcement', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 56: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 57: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 58: newShipType('Medical Transport', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 59: newShipType('Noncombatant ship according to RR Resolution No. 18', '', ''),\n 60: newShipType('Passenger, all ships of this type', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 61: newShipType('Passenger, Hazardous category A', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 62: newShipType('Passenger, Hazardous category B', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 63: newShipType('Passenger, Hazardous category C', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 64: newShipType('Passenger, Hazardous category D', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 65: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 66: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 67: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 68: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 69: newShipType('Passenger, No additional information', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 70: newShipType('Cargo, all ships of this type', CARGO_COLOR, CARGO_FILL_COLOR),\n 71: newShipType('Cargo, Hazardous category A', CARGO_COLOR, CARGO_FILL_COLOR),\n 72: newShipType('Cargo, Hazardous category B', CARGO_COLOR, CARGO_FILL_COLOR),\n 73: newShipType('Cargo, Hazardous category C', CARGO_COLOR, CARGO_FILL_COLOR),\n 74: newShipType('Cargo, Hazardous category D', CARGO_COLOR, CARGO_FILL_COLOR),\n 75: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 76: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 77: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 78: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 79: newShipType('Cargo, No additional information', CARGO_COLOR, CARGO_FILL_COLOR),\n 80: newShipType('Tanker, all ships of this type', TANKER_COLOR, TANKER_FILL_COLOR),\n 81: newShipType('Tanker, Hazardous category A', TANKER_COLOR, TANKER_FILL_COLOR),\n 82: newShipType('Tanker, Hazardous category B', TANKER_COLOR, TANKER_FILL_COLOR),\n 83: newShipType('Tanker, Hazardous category C', TANKER_COLOR, TANKER_FILL_COLOR),\n 84: newShipType('Tanker, Hazardous category D', TANKER_COLOR, TANKER_FILL_COLOR),\n 85: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 86: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 87: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 88: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 89: newShipType('Tanker, No additional information', TANKER_COLOR, TANKER_FILL_COLOR),\n 90: newShipType('Other Type, all ships of this type', OTHER_COLOR, OTHER_FILL_COLOR),\n 91: newShipType('Other Type, Hazardous category A', OTHER_COLOR, OTHER_FILL_COLOR),\n 92: newShipType('Other Type, Hazardous category B', OTHER_COLOR, OTHER_FILL_COLOR),\n 93: newShipType('Other Type, Hazardous category C', OTHER_COLOR, OTHER_FILL_COLOR),\n 94: newShipType('Other Type, Hazardous category D', OTHER_COLOR, OTHER_FILL_COLOR),\n 95: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 96: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 97: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 98: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 99: newShipType('Other Type, no additional information', OTHER_COLOR, OTHER_FILL_COLOR),\n};\nconst RESERVED_TYPE = newShipType('Reserved', RESERVED_COLOR, RESERVED_FILL_COLOR);\nconst UNKNOWN_TYPE = newShipType('Unknown', RESERVED_COLOR, RESERVED_FILL_COLOR);\n\nexport class AISTrackSymbol\n extends TrackSymbol {\n\n /** Default silhouette shape points. */\n public static DEFAULT_SILHOUETTE_SHAPE_POINTS: Points = [[1, 0.5], [0.75, 1], [0, 1], [0, 0], [0.75, 0]];\n\n private readonly _leaderTime: number;\n private readonly _minZoomLevel: number;\n private readonly _size: number;\n private _positionReport: PositionReport;\n private _shipStaticData?: ShipStaticData;\n\n /**\n * AISTrackSymbol constructor.\n *\n * @param positionReport - Position report.\n * @param options - Options.\n */\n constructor(positionReport: PositionReport, options?: AISTrackSymbolOptions) {\n super([positionReport.latitude, positionReport.longitude], options);\n\n Util.setOptions(this, options);\n options = options || {};\n this._leaderTime = options.leaderTime || DEFAULT_LEADER_TIME;\n this._minZoomLevel = options.minZoomLevel || DEFAULT_MIN_ZOOM_LEVEL;\n this._size = options.size || DEFAULT_SIZE;\n this._positionReport = positionReport;\n this.setPositionReport(positionReport);\n this.setShipStaticData(options.shipStaticData);\n }\n\n /**\n * Get ETA from Date.\n *\n * @param date - Date.\n * @returns ETA\n */\n public static etaFromDate(date: Date | null | undefined): ETA | undefined {\n if ((date === null) || (date === undefined)) {\n return undefined;\n }\n return {\n month: date.getMonth() + 1,\n day: date.getDate(),\n hour: date.getHours(),\n minute: date.getMinutes(),\n }\n }\n\n /**\n * Sets the position report.\n *\n * @param positionReport - Position report.\n * @returns this\n */\n public setPositionReport(positionReport: PositionReport): this {\n this._positionReport = positionReport;\n this.setLatLng([positionReport.latitude, positionReport.longitude]);\n if ((positionReport.trueHeading !== null) && (positionReport.trueHeading !== undefined) && (positionReport.trueHeading < MAX_HEADING_EXCLUSIVE)) {\n this.setHeading(toRadians(positionReport.trueHeading));\n } else {\n this.setHeading(undefined);\n }\n if ((positionReport.cog !== null) && (positionReport.cog !== undefined) && (positionReport.cog < MAX_COG_EXCLUSIVE)) {\n this.setCourse(toRadians(positionReport.cog));\n } else {\n this.setCourse(undefined);\n }\n if ((positionReport.sog !== null) && (positionReport.sog !== undefined) && (positionReport.sog < MAX_SOG_EXCLUSIVE)) {\n this.setSpeed(positionReport.sog / KNOTS_PER_METER_PER_SECOND);\n } else {\n this.setSpeed(undefined);\n }\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.redraw();\n }\n\n /**\n * Sets the ship static data.\n *\n * @param shipStaticData - Ship static data.\n * @returns this\n */\n public setShipStaticData(shipStaticData?: ShipStaticData): this {\n this._shipStaticData = shipStaticData;\n const shipType = getShipType((shipStaticData !== null) && (shipStaticData !== undefined) ? shipStaticData.type : undefined);\n this.setStyle({\n color: shipType.color,\n fill: true,\n fillOpacity: 1.0,\n fillColor: shipType.fillColor,\n });\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.setShapeOptions(AISTrackSymbol._getShapeOptions(this._leaderTime, this._minZoomLevel, this._size,\n shipStaticData));\n }\n\n private static _getShapeOptions(leaderTime: number, minZoomLevel: number, size: number,\n shipStaticData?: ShipStaticData): ShapeOptions {\n const shapeOptions: ShapeOptions = {\n leaderTime: leaderTime,\n defaultShapeSet: TrackSymbol.createShapeSet(size),\n };\n const shapeSet = AISTrackSymbol._getShapeSet(size, shipStaticData);\n if (shapeSet !== null) {\n shapeOptions.shapeSetEntries = [{\n shapeSet: shapeSet,\n minZoomLevel: minZoomLevel,\n }];\n }\n return shapeOptions;\n }\n\n private static _getShapeSet(size: number, shipStaticData?: ShipStaticData): ShapeSet | null {\n if ((shipStaticData === null) || (shipStaticData === undefined)\n || (shipStaticData.dimension === null) || (shipStaticData.dimension === undefined)\n || !isDimensionValid(shipStaticData.dimension)) {\n return null;\n }\n return {\n withHeading: {\n points: AISTrackSymbol.DEFAULT_SILHOUETTE_SHAPE_POINTS,\n center: [shipStaticData.dimension.B, shipStaticData.dimension.D],\n length: shipStaticData.dimension.A + shipStaticData.dimension.B,\n breadth: shipStaticData.dimension.C + shipStaticData.dimension.D,\n units: \"meters\",\n },\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n private _getPopupContent(positionReport?: PositionReport, shipStaticData?: ShipStaticData): HTMLElement {\n let content = \"\";\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"User ID\", shipStaticData.userId);\n content += createTableRow(\"IMO Number\", shipStaticData.imoNumber);\n content += createTableRow(\"Call sign\", shipStaticData.callSign);\n content += createTableRow(\"Name\", shipStaticData.name);\n }\n if ((positionReport !== null) && (positionReport !== undefined)) {\n content += createTableRow(\"Location\", `${toFixed(positionReport.latitude, 5)}, ${toFixed(positionReport.longitude, 5)}`);\n content += createTableRow(\"SOG\",\n toFixed(positionReport.sog, 2, v => v < MAX_SOG_EXCLUSIVE), \"knots\");\n content += createTableRow(\"COG\",\n toFixed(positionReport.cog, 1), \"°\");\n content += createTableRow(\"Heading\",\n toFixed(positionReport.trueHeading, 1), \"°\");\n content += createTableRow(\"Navigation status\",\n toNavigationStatusString(positionReport.navigationalStatus));\n }\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"Type\", toTypeString(shipStaticData.type));\n if ((shipStaticData.dimension !== null) && (shipStaticData.dimension !== undefined)\n && isDimensionValid(shipStaticData.dimension)) {\n content += createTableRow(\"Ship length\",\n shipStaticData.dimension.A + shipStaticData.dimension.B, \"m\");\n content += createTableRow(\"Ship width\",\n shipStaticData.dimension.C + shipStaticData.dimension.D, \"m\");\n }\n content += createTableRow(\"Fix type\", toFixTypeString(shipStaticData.fixType));\n content += createTableRow(\"ETA\", toETAString(shipStaticData.eta));\n content += createTableRow(\"Maximum static draught\",\n toFixed(shipStaticData.maximumStaticDraught, 1), \"m\");\n content += createTableRow(\"Destination\", shipStaticData.destination);\n content += createTableRow(\"DTE\", shipStaticData.dte);\n }\n content += \"
\";\n const popupContent = DomUtil.create(\"div\");\n popupContent.innerHTML = content;\n return popupContent;\n }\n}\n\nfunction toFixed(v: number | null | undefined, fractionDigits?: number, isValid?: (v: number) => boolean): string | undefined {\n if ((v === null) || (v === undefined)) {\n return undefined;\n }\n if (isValid && !isValid(v)) {\n return undefined;\n }\n return v.toFixed(fractionDigits);\n}\n\nfunction toTypeString(type: number | null | undefined): string | undefined {\n if ((type === null) || (type === undefined)) {\n return undefined;\n }\n const shipType = getShipType(type);\n return shipType.name;\n}\n\nfunction toFixTypeString(fixType: number | null | undefined): string | undefined {\n if ((fixType === null) || (fixType === undefined)) {\n return undefined;\n }\n switch (fixType) {\n case 0:\n return undefined;\n case 1:\n return 'GPS';\n case 2:\n return 'GLONASS';\n case 3:\n return 'combined GPS/GLONASS';\n case 4:\n return 'Loran-C';\n case 5:\n return 'Chayka';\n case 6:\n return 'integrated navigation system';\n case 7:\n return 'surveyed';\n case 8:\n return 'Galileo';\n case 9:\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n return `not used (${fixType})`;\n case 15:\n return \"internal GNSS\";\n default:\n return `unknown (${fixType})`;\n }\n}\n\nfunction toNavigationStatusString(navigationStatus: number | null | undefined): string | undefined {\n if ((navigationStatus === null) || (navigationStatus === undefined)) {\n return undefined;\n }\n switch (navigationStatus) {\n case 0:\n return 'Under way using engine';\n case 1:\n return 'At anchor';\n case 2:\n return 'Not under command';\n case 3:\n return 'Restricted manoeuverability';\n case 4:\n return 'Constrained by her draught';\n case 5:\n return 'Moored';\n case 6:\n return 'Aground';\n case 7:\n return 'Engaged in Fishing';\n case 8:\n return 'Under way sailing';\n case 9:\n return 'Reserved for future amendment of Navigational Status for HSC';\n case 10:\n return 'Reserved for future amendment of Navigational Status for WIG';\n case 11:\n return 'Reserved for future use';\n case 12:\n return 'Reserved for future use';\n case 13:\n return 'Reserved for future use';\n case 14:\n return 'AIS-SART is active';\n case 15:\n return 'Not defined (default)';\n default:\n return `unknown (${navigationStatus})`;\n }\n}\n\nfunction toETAString(eta: ETA | null | undefined): string | undefined {\n if ((eta === null) || (eta === undefined)) {\n return undefined;\n }\n const parts: string[] = [];\n if (!isNullOrUndefined(eta.month) && !isNullOrUndefined(eta.day)) {\n parts.push(`${eta.month.toString().padStart(2, '0')}/${eta.day.toString().padStart(2, '0')}`);\n }\n if (!isNullOrUndefined(eta.hour) && !isNullOrUndefined(eta.minute)) {\n parts.push(`${eta.hour.toString().padStart(2, '0')}:${eta.minute.toString().padStart(2, '0')}`);\n }\n if (parts.length === 0) {\n return undefined;\n }\n return `${parts.join(' ')} UTC`;\n}\n\nfunction toRadians(degs: number | null | undefined): number | undefined {\n if ((degs === null) || (degs === undefined)) {\n return undefined;\n }\n return degs * Math.PI / 180;\n}\n\nfunction isNullOrUndefined(v: any): boolean {\n return (v === null) || (v === undefined);\n}\n\nfunction isDimensionValid(dimension: Dimension | null | undefined): boolean {\n return (dimension !== null) && (dimension !== undefined)\n && (dimension.A > 0) && (dimension.B > 0) && (dimension.C > 0) && (dimension.D > 0);\n}\n\nfunction createTableRow(name: string, value: any, unit?: string): string {\n if ((value === null) || (value === undefined)) {\n return '';\n }\n const sValue = String(value);\n return `${name}${sValue} ${isNullOrUndefined(unit) ? \"\" : unit}`;\n}\n\nfunction newShipType(name: string, color: string, fillColor: string): ShipType {\n return {\n name: name,\n color: color,\n fillColor: fillColor,\n };\n}\n\nfunction getShipType(type: number | null | undefined): ShipType {\n if ((type === null) || (type === undefined)) {\n return TYPES[0];\n }\n if ((type < 0) || (type > 99)) {\n return UNKNOWN_TYPE;\n }\n const shipType = TYPES[type];\n if (!isNullOrUndefined(shipType)) {\n return shipType;\n }\n return RESERVED_TYPE;\n}\n","//@ts-strict-ignore\nimport L from 'leaflet';\nimport type {LatLngExpression} from 'leaflet';\nimport {TrackSymbol} from './trackSymbol';\nimport type {ShapeSetEntry, ShapeOptions, TrackSymbolOptions} from './options';\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport {AISTrackSymbol} from './ais/aisTrackSymbol';\nimport type {AISTrackSymbolOptions} from './ais/options';\nimport type {AISMessage, Dimension, ETA, PositionReport, ShipStaticData} from './ais/types';\n\nexport {\n Points,\n Shape,\n ShapeOptions,\n ShapeSet,\n ShapeSetEntry,\n TrackSymbol,\n TrackSymbolOptions,\n Units,\n};\n\nexport {\n AISMessage,\n AISTrackSymbol,\n AISTrackSymbolOptions,\n Dimension,\n ETA,\n PositionReport,\n ShipStaticData,\n};\n\nL['trackSymbol'] = function(latLng: LatLngExpression, options?: TrackSymbolOptions): TrackSymbol {\n return new TrackSymbol(latLng, options);\n}\nL['TrackSymbol'] = TrackSymbol;\n\nL['aisTrackSymbol'] = function(positionReport: PositionReport, options?: AISTrackSymbolOptions): AISTrackSymbol {\n return new AISTrackSymbol(positionReport, options);\n}\nL['AISTrackSymbol'] = AISTrackSymbol;\n\nexport default TrackSymbol;\n"],"names":["CCW","CW","ORIENTATION","PIx2","INSIDE$2","OUTSIDE$1","BOUNDARY$1","CONTAINS","INTERLACE","OVERLAP_SAME$1","OVERLAP_OPPOSITE$1","NOT_VERTEX$1","START_VERTEX$1","END_VERTEX$1","Constants","DP_TOL","setTolerance","tolerance","getTolerance","DECIMALS","EQ_0","x","EQ","y","GT","GE","LT","LE","Utils$1","Flatten","c","value","Errors","LinkedList","first","last","counter","edge","start","end","elements","from","to","element","newElement","elementBefore","elementAfter","controlEdge","addToIntPoints","pt","int_points","id","shapes","len","is_vertex","arc_length","sortIntersections","intersections","getSortedArray","faceMap","ip","compareFn","ip1","ip2","filterDuplicatedIntersections","do_squeeze","int_point_ref1","int_point_ref2","int_point_cur1","int_point_cur2","i","j","int_point","index","initializeInclusionFlags","calculateInclusionFlags","polygon","setOverlappingFlags","cur_face","first_int_point_in_face_id","next_int_point1","num_int_points","cur_int_point1","int_points_cur_pool_start","int_points_cur_pool_num","intPointsPoolCount","next_int_point_id","int_points_next_pool_num","next_int_point1_tmp","edge_from1","edge_to1","cur_int_point2","next_int_point2","edge_from2","edge_to2","cur_int_point_num","int_point_current","int_point_next","int_points_pool_num","splitByIntersections","newEdge","insertBetweenIntPoints","int_point1","int_point2","new_edges","edge_before","edge_after","INSIDE$1","OUTSIDE","BOUNDARY","OVERLAP_SAME","OVERLAP_OPPOSITE","NOT_VERTEX","START_VERTEX","END_VERTEX","BOOLEAN_UNION","BOOLEAN_INTERSECT","BOOLEAN_SUBTRACT","unify","polygon1","polygon2","res_poly","wrk_poly","booleanOpBinary","subtract","polygon2_reversed","intersect$1","innerClip","clip_shapes1","face","clip_shapes2","outerClip","calculateIntersections","getIntersections","ip_sorted1","ip_sorted2","filterNotRelevantEdges","op","notIntersectedFacesRes","getNotIntersectedFaces","notIntersectedFacesWrk","calcInclusionForNotIntersectedFaces","fixBoundaryConflicts","removeNotRelevantChains","removeNotRelevantNotIntersectedFaces","swapLinksAndRestore","copyWrkToRes","swapLinks","removeOldFaces","restoreFaces","restore","edge1","resp","edge2","poly","notIntersected","notIntersectedFaces","poly2","poly1","int_points1","int_points1_sorted","int_points2","iterate_more","edge_tmp","new_bv","dist","segment","newEdge1","int_point2_edge_after","newEdge2","is_res_polygon","first_int_point_in_face_num","int_points_from_pull_start","int_points_from_pull_num","next_int_point_num","int_points_to_pull_start","int_points_to_pull_num","edge_from","edge_to","k","res_polygon","wrk_polygon","other_int_points","int_point_tmp","rel","BooleanOperations","EQUAL","INTERSECT","TOUCH","INSIDE","COVERED","DE9IM","geom","e","intersectLine2Line","line1","line2","A1","B1","C1","A2","B2","C2","det","detX","detY","intersectLine2Circle","line","circle","prj","delta","v_trans","intersectLine2Box","box","ips","seg","ips_tmp","intersectSegment2Line","ptInIntPoints","intersectLine2Arc","arc","ip_tmp","intersectSegment2Segment","seg1","seg2","new_ip","isPointInSegmentBox","point","intersectSegment2Circle","_","intersectSegment2Arc","intersectSegment2Box","intersectCircle2Circle","circle1","circle2","vec","r1","r2","a","mid_pt","h","intersectCircle2Box","intersectArc2Arc","arc1","arc2","intersectArc2Circle","intersectArc2Box","intersectEdge2Segment","intersectEdge2Arc","intersectEdge2Line","intersectEdge2Ray","ray","intersectRay2Segment","intersectRay2Arc","intersectEdge2Circle","intersectSegment2Polygon","intersectArc2Polygon","intersectLine2Polygon","intersectCircle2Polygon","intersectEdge2Edge","intersectEdge2Polygon","resp_edges","resp_edge","intersectPolygon2Polygon","intersectShape2Polygon","shape","new_pt","createLineFromRay","intersectRay2Circle","intersectRay2Box","intersectRay2Line","intersectRay2Ray","ray1","ray2","intersectRay2Polygon","defaultAttributes","SVGAttributes","args","property","acc","key","SVGKey","str","convertToString","attrs","Multiline","v","edgeBefore","edgeFrom","edgeTo","edges","edgeFound","angle","center","matrix","svgStr","multiline","ray_shoot","contains","searchBox","i1","i2","intersection","prev_edge","prev_tangent","prev_point","cur_tangent","cur_point","prev_on_the_left","cur_on_the_left","next_edge","next_tangent","next_point","next_on_the_left","equal","shape1","shape2","relate","intersect","touch","disjoint","inside","covered","contain","cover","relateLine2Line","relateLine2Circle","relateLine2Box","relateLine2Polygon","relateShape2Polygon","relatePolygon2Polygon","denim","ip_sorted","splitShapes","boolean_intersection","boolean_difference1","boolean_difference2","inner_clip_shapes1","inner_clip_shapes2","outer_clip_shapes1","outer_clip_shapes2","Relations","Matrix$1","Matrix","b","d","tx","ty","vector","other_matrix","centerX","centerY","cos","sin","sx","sy","Interval","low","high","other_interval","interval1","interval2","val1","val2","RB_TREE_COLOR_RED","RB_TREE_COLOR_BLACK","Node","left","right","parent","color","other_node","comparable_max","search_node","comparable_less_than","IntervalTree","count","res","node","insert_node","delete_node","interval","outputMapperFn","resp_nodes","visitor","callback","tree","node_current","current_node","parent_node","uncle_node","cut_node","fix_node","brother_node","found","node_min","node_max","node_successor","action","height","heightLeft","heightRight","PlanarSet","entry","size","deleted","Shape","Point$1","Point","arr","m","proj_vec","dx","dy","r","Vector$1","a1","a2","scalar","norm1","norm2","n","vector$1","Segment","coords","ps","pe","shortest_segment","length","factor","rest","ymin","dy1","dy2","pts","Line$1","Line","norm","A","B","C","other_line","distance","sorted_points","pt1","pt2","Circle$1","pc","counterclockwise","Arc","startAngle","endAngle","counterClockwise","sweep","test_arc","func_arcs_array","angles","test_arcs","prev_arc","new_arc","newStart","newEnd","newCenter","newDirection","onLeftSide","areaTrapez","areaCircularSegment","slope1","slope2","largeArcFlag","sweepFlag","Box","xmin","xmax","ymax","other_box","box1","box2","new_box","vertex","width","Edge","bvMiddle","flag","sign","halfArc1","halfArc2","CircularLinkedList","done","Face","segments","points","flattenShapes","flattenShape","sArea","area","exitOnFirst","Ray","slope","Polygon","argsArray","loop","el","loop1","valid","signedArea","unassignedEdgeFound","edge_next","newPoly","int_point1_prev","int_point1_curr","newEdges","polygons","orientation","newPolygons","islandPolygon","min_dist_and_segment","min_stop","newPolygon","Circle","Vector","Utils","Inversion","inversion_circle","k2","len2","s","inversion","Distance","closest_point","dist2center","shortest_dist","v_seg","v_ps2pt","v_pe2pt","start_sp","end_sp","v_unit","dist_and_segment","dist_tmp","shortest_segment_tmp","dist_from_start","shortest_segment_from_start","dist_from_end","shortest_segment_from_end","dist_from_center","shortest_segment_from_center","dist_from_projection","shortest_segment_from_projection","segment_tmp","mindist_x","mindist_y","mindist","maxdist","level","new_level_left","new_level_right","new_level","set","squared_min_stop","min_dist_and_segment_new","stop","d1","d2","DEFAULT_SIZE","DEFAULT_LEADER_TIME","_TrackSymbol","Path","latLng","options","Util","L","bounds","Bounds","LatLngBounds","paths","viewPath","shapeOptions","oldLatLng","heading","course","speed","modelAngle","leaderLength","leaderEndLatLng","LatLng","latLngs","zoomLevel","shapeSetEntriesFiltered","shapeSetEntry","shapeSet","headingAngle","units","p","p1","close","result","TrackSymbol","DEFAULT_MIN_ZOOM_LEVEL","KNOTS_PER_METER_PER_SECOND","MAX_SOG_EXCLUSIVE","MAX_COG_EXCLUSIVE","MAX_HEADING_EXCLUSIVE","RESERVED_COLOR","RESERVED_FILL_COLOR","WIG_COLOR","WIG_FILL_COLOR","TYPE_3X_COLOR","TYPE_3X_FILL_COLOR","HSC_COLOR","HSC_FILL_COLOR","TYPE_5X_COLOR","TYPE_5X_FILL_COLOR","PASSENGER_COLOR","PASSENGER_FILL_COLOR","CARGO_COLOR","CARGO_FILL_COLOR","TANKER_COLOR","TANKER_FILL_COLOR","OTHER_COLOR","OTHER_FILL_COLOR","TYPES","newShipType","RESERVED_TYPE","UNKNOWN_TYPE","_AISTrackSymbol","positionReport","date","toRadians","shipStaticData","shipType","getShipType","leaderTime","minZoomLevel","isDimensionValid","content","createTableRow","toFixed","toNavigationStatusString","toTypeString","toFixTypeString","toETAString","popupContent","DomUtil","AISTrackSymbol","fractionDigits","isValid","type","fixType","navigationStatus","eta","parts","isNullOrUndefined","degs","dimension","name","unit","sValue","fillColor"],"mappings":"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","x_google_ignoreList":[0]} \ No newline at end of file +{"version":3,"file":"leaflet-tracksymbol2.es.js","sources":["../node_modules/.pnpm/@flatten-js+core@1.5.2/node_modules/@flatten-js/core/dist/main.mjs","../src/trackSymbol.ts","../src/ais/aisTrackSymbol.ts","../src/index.ts"],"sourcesContent":["/**\n * Global constant CCW defines counterclockwise direction of arc\n * @type {boolean}\n */\nconst CCW = true;\n\n/**\n * Global constant CW defines clockwise direction of arc\n * @type {boolean}\n */\nconst CW = false;\n\n/**\n * Defines orientation for face of the polygon: clockwise, counterclockwise\n * or not orientable in the case of self-intersection\n * @type {{CW: number, CCW: number, NOT_ORIENTABLE: number}}\n */\nconst ORIENTATION = {CCW:-1, CW:1, NOT_ORIENTABLE: 0};\n\nconst PIx2 = 2 * Math.PI;\n\nconst INSIDE$2 = 1;\nconst OUTSIDE$1 = 0;\nconst BOUNDARY$1 = 2;\nconst CONTAINS = 3;\nconst INTERLACE = 4;\n\nconst OVERLAP_SAME$1 = 1;\nconst OVERLAP_OPPOSITE$1 = 2;\n\nconst NOT_VERTEX$1 = 0;\nconst START_VERTEX$1 = 1;\nconst END_VERTEX$1 = 2;\n\nvar Constants = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOUNDARY: BOUNDARY$1,\n CCW: CCW,\n CONTAINS: CONTAINS,\n CW: CW,\n END_VERTEX: END_VERTEX$1,\n INSIDE: INSIDE$2,\n INTERLACE: INTERLACE,\n NOT_VERTEX: NOT_VERTEX$1,\n ORIENTATION: ORIENTATION,\n OUTSIDE: OUTSIDE$1,\n OVERLAP_OPPOSITE: OVERLAP_OPPOSITE$1,\n OVERLAP_SAME: OVERLAP_SAME$1,\n PIx2: PIx2,\n START_VERTEX: START_VERTEX$1\n});\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n/**\n * Floating point comparison tolerance.\n * Default value is 0.000001 (10e-6)\n * @type {number}\n */\nlet DP_TOL = 0.000001;\n\n/**\n * Set new floating point comparison tolerance\n * @param {number} tolerance\n */\nfunction setTolerance(tolerance) {DP_TOL = tolerance;}\n\n/**\n * Get floating point comparison tolerance\n * @returns {number}\n */\nfunction getTolerance() {return DP_TOL;}\n\nconst DECIMALS = 3;\n\n/**\n * Returns *true* if value comparable to zero\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ_0(x) {\n return (x < DP_TOL && x > -DP_TOL);\n}\n\n/**\n * Returns *true* if two values are equal up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ(x, y) {\n return (x - y < DP_TOL && x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction GT(x, y) {\n return (x - y > DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @returns {boolean}\n */\nfunction GE(x, y) {\n return (x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument less than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LT(x, y) {\n return (x - y < -DP_TOL)\n}\n\n/**\n * Returns *true* if first argument less than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LE(x, y) {\n return (x - y < DP_TOL);\n}\n\nvar Utils$1 = /*#__PURE__*/Object.freeze({\n __proto__: null,\n DECIMALS: DECIMALS,\n EQ: EQ,\n EQ_0: EQ_0,\n GE: GE,\n GT: GT,\n LE: LE,\n LT: LT,\n getTolerance: getTolerance,\n setTolerance: setTolerance\n});\n\nlet Flatten = {\n Utils: Utils$1,\n Errors: undefined,\n Matrix: undefined,\n Planar_set: undefined,\n Point: undefined,\n Vector: undefined,\n Line: undefined,\n Circle: undefined,\n Segment: undefined,\n Arc: undefined,\n Box: undefined,\n Edge: undefined,\n Face: undefined,\n Ray: undefined,\n Ray_shooting: undefined,\n Multiline: undefined,\n Polygon: undefined,\n Distance: undefined,\n Inversion: undefined\n};\n\nfor (let c in Constants) {Flatten[c] = Constants[c];}\n\nObject.defineProperty(Flatten, 'DP_TOL', {\n get:function(){return getTolerance()}, \n set:function(value){setTolerance(value);}\n});\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class of system errors\n */\nclass Errors {\n /**\n * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter\n * @returns {ReferenceError}\n */\n static get ILLEGAL_PARAMETERS() {\n return new ReferenceError('Illegal Parameters');\n }\n\n /**\n * Throw error ZERO_DIVISION to catch situation of zero division\n * @returns {Error}\n */\n static get ZERO_DIVISION() {\n return new Error('Zero division');\n }\n\n /**\n * Error to throw from BooleanOperations module in case when fixBoundaryConflicts not capable to fix it\n * @returns {Error}\n */\n static get UNRESOLVED_BOUNDARY_CONFLICT() {\n return new Error('Unresolved boundary conflict in boolean operation');\n }\n\n /**\n * Error to throw from LinkedList:testInfiniteLoop static method\n * in case when circular loop detected in linked list\n * @returns {Error}\n */\n static get INFINITE_LOOP() {\n return new Error('Infinite loop');\n }\n\n static get CANNOT_COMPLETE_BOOLEAN_OPERATION() {\n return new Error('Cannot complete boolean operation')\n }\n\n static get CANNOT_INVOKE_ABSTRACT_METHOD() {\n return new Error('Abstract method cannot be invoked');\n }\n\n static get OPERATION_IS_NOT_SUPPORTED() {\n return new Error('Operation is not supported')\n }\n}\n\nFlatten.Errors = Errors;\n\n/**\n * Class implements bidirectional non-circular linked list.
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass LinkedList {\n constructor(first, last) {\n this.first = first;\n this.last = last || this.first;\n }\n\n [Symbol.iterator]() {\n let value = undefined;\n return {\n next: () => {\n value = value ? value.next : this.first;\n return {value: value, done: value === undefined};\n }\n };\n };\n\n /**\n * Return number of elements in the list\n * @returns {number}\n */\n get size() {\n let counter = 0;\n for (let edge of this) {\n counter++;\n }\n return counter;\n }\n\n /**\n * Return array of elements from start to end,\n * If start or end not defined, take first as start, last as end\n * @returns {Array}\n */\n toArray(start=undefined, end=undefined) {\n let elements = [];\n let from = start || this.first;\n let to = end || this.last;\n let element = from;\n if (element === undefined) return elements;\n do {\n elements.push(element);\n element = element.next;\n } while (element !== to.next);\n return elements;\n }\n\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n append(element) {\n if (this.isEmpty()) {\n this.first = element;\n } else {\n element.prev = this.last;\n this.last.next = element;\n }\n\n // update edge to be last\n this.last = element;\n\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement\n * @param {LinkedListElement} elementBefore\n * @returns {LinkedList}\n */\n insert(newElement, elementBefore) {\n if (this.isEmpty()) {\n this.first = newElement;\n this.last = newElement;\n }\n else if (elementBefore === null || elementBefore === undefined) {\n newElement.next = this.first;\n this.first.prev = newElement;\n this.first = newElement;\n }\n else {\n /* set links to new element */\n let elementAfter = elementBefore.next;\n elementBefore.next = newElement;\n if (elementAfter) elementAfter.prev = newElement;\n\n /* set links from new element */\n newElement.prev = elementBefore;\n newElement.next = elementAfter;\n\n /* extend list if new element added after the last element */\n if (this.last === elementBefore)\n this.last = newElement;\n }\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n remove(element) {\n // special case if last edge removed\n if (element === this.first && element === this.last) {\n this.first = undefined;\n this.last = undefined;\n } else {\n // update linked list\n if (element.prev) element.prev.next = element.next;\n if (element.next) element.next.prev = element.prev;\n // update first if need\n if (element === this.first) {\n this.first = element.next;\n }\n // update last if need\n if (element === this.last) {\n this.last = element.prev;\n }\n }\n return this;\n }\n\n /**\n * Return true if list is empty\n * @returns {boolean}\n */\n isEmpty() {\n return this.first === undefined;\n }\n\n /**\n * Throw an error if circular loop detected in the linked list\n * @param {LinkedListElement} first element to start iteration\n * @throws {Errors.INFINITE_LOOP}\n */\n static testInfiniteLoop(first) {\n let edge = first;\n let controlEdge = first;\n do {\n if (edge != first && edge === controlEdge) {\n throw Errors.INFINITE_LOOP; // new Error(\"Infinite loop\")\n }\n edge = edge.next;\n controlEdge = controlEdge.next.next;\n } while (edge != first)\n }\n}\n\n/*\n Smart intersections describe intersection points that refers to the edges they intersect\n This function are supposed for internal usage by morphing and relation methods between\n */\n\nfunction addToIntPoints(edge, pt, int_points)\n{\n let id = int_points.length;\n let shapes = edge.shape.split(pt);\n\n // if (shapes.length < 2) return;\n if (shapes.length === 0) return; // Point does not belong to edge ?\n\n let len = 0;\n if (shapes[0] === null) { // point incident to edge start vertex\n len = 0;\n }\n else if (shapes[1] === null) { // point incident to edge end vertex\n len = edge.shape.length;\n }\n else { // Edge was split into to edges\n len = shapes[0].length;\n }\n\n let is_vertex = NOT_VERTEX$1;\n if (EQ(len, 0)) {\n is_vertex |= START_VERTEX$1;\n }\n if (EQ(len, edge.shape.length)) {\n is_vertex |= END_VERTEX$1;\n }\n // Fix intersection point which is end point of the last edge\n let arc_length;\n if (len === Infinity) {\n arc_length = shapes[0].coord(pt);\n }\n else {\n arc_length = (is_vertex & END_VERTEX$1) && edge.next && edge.next.arc_length === 0 ?\n 0 :\n edge.arc_length + len;\n }\n\n int_points.push({\n id: id,\n pt: pt,\n arc_length: arc_length,\n edge_before: edge,\n edge_after: undefined,\n face: edge.face,\n is_vertex: is_vertex\n });\n}\n\nfunction sortIntersections(intersections)\n{\n // if (intersections.int_points1.length === 0) return;\n\n // augment intersections with new sorted arrays\n // intersections.int_points1_sorted = intersections.int_points1.slice().sort(compareFn);\n // intersections.int_points2_sorted = intersections.int_points2.slice().sort(compareFn);\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n}\n\nfunction getSortedArray(int_points)\n{\n let faceMap = new Map;\n let id = 0;\n // Create integer id's for faces\n for (let ip of int_points) {\n if (!faceMap.has(ip.face)) {\n faceMap.set(ip.face, id);\n id++;\n }\n }\n // Augment intersection points with face id's\n for (let ip of int_points) {\n ip.faceId = faceMap.get(ip.face);\n }\n // Clone and sort\n let int_points_sorted = int_points.slice().sort(compareFn);\n return int_points_sorted;\n}\n\nfunction compareFn(ip1, ip2)\n{\n // compare face id's\n if (ip1.faceId < ip2.faceId) {\n return -1;\n }\n if (ip1.faceId > ip2.faceId) {\n return 1;\n }\n // same face - compare arc_length\n if (ip1.arc_length < ip2.arc_length) {\n return -1;\n }\n if (ip1.arc_length > ip2.arc_length) {\n return 1;\n }\n return 0;\n}\n\n// export function getSortedArrayOnLine(line, int_points) {\n// return int_points.slice().sort( (int_point1, int_point2) => {\n// if (line.coord(int_point1.pt) < line.coord(int_point2.pt)) {\n// return -1;\n// }\n// if (line.coord(int_point1.pt) > line.coord(int_point2.pt)) {\n// return 1;\n// }\n// return 0;\n// })\n// }\n\nfunction filterDuplicatedIntersections(intersections)\n{\n if (intersections.int_points1.length < 2) return;\n\n let do_squeeze = false;\n\n let int_point_ref1;\n let int_point_ref2;\n let int_point_cur1;\n let int_point_cur2;\n for (let i = 0; i < intersections.int_points1_sorted.length; i++) {\n\n if (intersections.int_points1_sorted[i].id === -1)\n continue;\n\n int_point_ref1 = intersections.int_points1_sorted[i];\n int_point_ref2 = intersections.int_points2[int_point_ref1.id];\n\n for (let j=i+1; j < intersections.int_points1_sorted.length; j++) {\n int_point_cur1 = intersections.int_points1_sorted[j];\n if (!EQ(int_point_cur1.arc_length, int_point_ref1.arc_length)) {\n break;\n }\n if (int_point_cur1.id === -1)\n continue;\n int_point_cur2 = intersections.int_points2[int_point_cur1.id];\n if (int_point_cur2.id === -1)\n continue;\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n }\n\n int_point_ref2 = intersections.int_points2_sorted[0];\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n for (let i = 1; i < intersections.int_points2_sorted.length; i++) {\n let int_point_cur2 = intersections.int_points2_sorted[i];\n\n if (int_point_cur2.id === -1) continue;\n /* already deleted */\n\n if (int_point_ref2.id === -1 || /* can't be reference if already deleted */\n !(EQ(int_point_cur2.arc_length, int_point_ref2.arc_length))) {\n int_point_ref2 = int_point_cur2;\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n continue;\n }\n\n let int_point_cur1 = intersections.int_points1[int_point_cur2.id];\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n\n if (do_squeeze) {\n intersections.int_points1 = intersections.int_points1.filter((int_point) => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter((int_point) => int_point.id >= 0);\n\n // update id's\n intersections.int_points1.forEach((int_point, index) => int_point.id = index);\n intersections.int_points2.forEach((int_point, index) => int_point.id = index);\n }\n}\n\nfunction initializeInclusionFlags(int_points)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_before.bvStart = undefined;\n int_point.edge_before.bvEnd = undefined;\n int_point.edge_before.bv = undefined;\n int_point.edge_before.overlap = undefined;\n }\n\n if (int_point.edge_after) {\n int_point.edge_after.bvStart = undefined;\n int_point.edge_after.bvEnd = undefined;\n int_point.edge_after.bv = undefined;\n int_point.edge_after.overlap = undefined;\n }\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.bvEnd = BOUNDARY$1;\n if (int_point.edge_after) int_point.edge_after.bvStart = BOUNDARY$1;\n }\n}\n\nfunction calculateInclusionFlags(int_points, polygon)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.setInclusion(polygon);\n if (int_point.edge_after) int_point.edge_after.setInclusion(polygon);\n }\n}\n\nfunction setOverlappingFlags(intersections)\n{\n let cur_face = undefined;\n let first_int_point_in_face_id = undefined;\n let next_int_point1 = undefined;\n let num_int_points = intersections.int_points1.length;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = intersections.int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(intersections.int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n intersections.int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(intersections.int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = intersections.int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n intersections.int_points2[next_int_point1_tmp.id].face === intersections.int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n if (!(edge_from1.bv === BOUNDARY$1 && edge_to1.bv === BOUNDARY$1)) // not a boundary chain - skip\n continue;\n\n if (edge_from1 !== edge_to1) // one edge chain TODO: support complex case\n continue;\n\n /* Find boundary chain in polygon2 between same intersection points */\n let cur_int_point2 = intersections.int_points2[cur_int_point1.id];\n let next_int_point2 = intersections.int_points2[next_int_point1.id];\n\n let edge_from2 = cur_int_point2.edge_after;\n let edge_to2 = next_int_point2.edge_before;\n\n /* if [edge_from2..edge_to2] is not a boundary chain, invert it */\n /* check also that chain consist of one or two edges */\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2)) {\n cur_int_point2 = intersections.int_points2[next_int_point1.id];\n next_int_point2 = intersections.int_points2[cur_int_point1.id];\n\n edge_from2 = cur_int_point2.edge_after;\n edge_to2 = next_int_point2.edge_before;\n }\n\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2))\n continue; // not an overlapping chain - skip TODO: fix boundary conflict\n\n // Set overlapping flag - one-to-one case\n edge_from1.setOverlap(edge_from2);\n }\n}\n\nfunction intPointsPoolCount(int_points, cur_int_point_num, cur_face)\n{\n let int_point_current;\n let int_point_next;\n\n let int_points_pool_num = 1;\n\n if (int_points.length === 1) return 1;\n\n int_point_current = int_points[cur_int_point_num];\n\n for (let i = cur_int_point_num + 1; i < int_points.length; i++) {\n if (int_point_current.face !== cur_face) { /* next face started */\n break;\n }\n\n int_point_next = int_points[i];\n\n if (!(int_point_next.pt.equalTo(int_point_current.pt) &&\n int_point_next.edge_before === int_point_current.edge_before &&\n int_point_next.edge_after === int_point_current.edge_after)) {\n break; /* next point is different - break and exit */\n }\n\n int_points_pool_num++; /* duplicated intersection point - increase counter */\n }\n return int_points_pool_num;\n}\n\nfunction splitByIntersections(polygon, int_points)\n{\n if (!int_points) return;\n for (let int_point of int_points) {\n let edge = int_point.edge_before;\n\n // recalculate vertex flag: it may be changed after previous split\n int_point.is_vertex = NOT_VERTEX$1;\n if (edge.shape.start && edge.shape.start.equalTo(int_point.pt)) {\n int_point.is_vertex |= START_VERTEX$1;\n }\n if (edge.shape.end && edge.shape.end.equalTo(int_point.pt)) {\n int_point.is_vertex |= END_VERTEX$1;\n }\n\n if (int_point.is_vertex & START_VERTEX$1) { // nothing to split\n if (edge.prev) {\n int_point.edge_before = edge.prev; // polygon\n int_point.is_vertex = END_VERTEX$1;\n }\n else { // multiline start vertex\n int_point.edge_after = int_point.edge_before;\n int_point.edge_before = edge.prev;\n }\n continue;\n }\n if (int_point.is_vertex & END_VERTEX$1) { // nothing to split\n continue;\n }\n\n let newEdge = polygon.addVertex(int_point.pt, edge);\n int_point.edge_before = newEdge;\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_after = int_point.edge_before.next;\n }\n }\n}\n\nfunction insertBetweenIntPoints(int_point1, int_point2, new_edges) {\n const edge_before = int_point1.edge_before;\n const edge_after = int_point2.edge_after;\n const len = new_edges.length;\n edge_before.next = new_edges[0];\n new_edges[0].prev = edge_before;\n\n new_edges[len-1].next = edge_after;\n edge_after.prev = new_edges[len-1];\n}\n\nvar smart_intersections = /*#__PURE__*/Object.freeze({\n __proto__: null,\n addToIntPoints: addToIntPoints,\n calculateInclusionFlags: calculateInclusionFlags,\n filterDuplicatedIntersections: filterDuplicatedIntersections,\n getSortedArray: getSortedArray,\n initializeInclusionFlags: initializeInclusionFlags,\n insertBetweenIntPoints: insertBetweenIntPoints,\n intPointsPoolCount: intPointsPoolCount,\n setOverlappingFlags: setOverlappingFlags,\n sortIntersections: sortIntersections,\n splitByIntersections: splitByIntersections\n});\n\n/**\n * Created by Alex Bol on 12/02/2018.\n */\n/**\n * @module BooleanOperations\n */\n\nconst {INSIDE: INSIDE$1, OUTSIDE, BOUNDARY, OVERLAP_SAME, OVERLAP_OPPOSITE} = Constants;\nconst {NOT_VERTEX, START_VERTEX, END_VERTEX} = Constants;\n\nconst BOOLEAN_UNION = 1;\nconst BOOLEAN_INTERSECT = 2;\nconst BOOLEAN_SUBTRACT = 3;\n\n\n/**\n * Unify two polygons polygons and returns new polygon.
\n * Point belongs to the resulted polygon if it belongs to the first OR to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction unify(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_UNION, true);\n return res_poly;\n}\n\n/**\n * Subtract second polygon from the first and returns new polygon\n * Point belongs to the resulted polygon if it belongs to the first polygon AND NOT to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction subtract(polygon1, polygon2) {\n let polygon2_tmp = polygon2.clone();\n let polygon2_reversed = polygon2_tmp.reverse();\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2_reversed, BOOLEAN_SUBTRACT, true);\n return res_poly;\n}\n\n/**\n * Intersect two polygons and returns new polygon\n * Point belongs to the resulted polygon is it belongs to the first AND to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction intersect$1(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, true);\n return res_poly;\n}\n\n/**\n * Returns boundary of intersection between two polygons as two arrays of shapes (Segments/Arcs)
\n * The first array are shapes from the first polygon, the second array are shapes from the second\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[][]}\n */\nfunction innerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n let clip_shapes2 = [];\n for (let face of wrk_poly.faces) {\n clip_shapes2 = [...clip_shapes2, ...[...face.edges].map(edge => edge.shape)];\n }\n return [clip_shapes1, clip_shapes2];\n}\n\n/**\n * Returns boundary of subtraction of the second polygon from first polygon as array of shapes\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[]}\n */\nfunction outerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_SUBTRACT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n\n return clip_shapes1;\n}\n\n/**\n * Returns intersection points between boundaries of two polygons as two array of points
\n * Points in the first array belong to first polygon, points from the second - to the second.\n * Points in each array are ordered according to the direction of the correspondent polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Point[][]}\n */\nfunction calculateIntersections(polygon1, polygon2) {\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n let ip_sorted1 = intersections.int_points1_sorted.map( int_point => int_point.pt);\n let ip_sorted2 = intersections.int_points2_sorted.map( int_point => int_point.pt);\n return [ip_sorted1, ip_sorted2];\n}\n\nfunction filterNotRelevantEdges(res_poly, wrk_poly, intersections, op) {\n // keep not intersected faces for further remove and merge\n let notIntersectedFacesRes = getNotIntersectedFaces(res_poly, intersections.int_points1);\n let notIntersectedFacesWrk = getNotIntersectedFaces(wrk_poly, intersections.int_points2);\n\n // calculate inclusion flag for not intersected faces\n calcInclusionForNotIntersectedFaces(notIntersectedFacesRes, wrk_poly);\n calcInclusionForNotIntersectedFaces(notIntersectedFacesWrk, res_poly);\n\n // initialize inclusion flags for edges incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n initializeInclusionFlags(intersections.int_points2);\n\n // calculate inclusion flags only for edges incident to intersections\n calculateInclusionFlags(intersections.int_points1, wrk_poly);\n calculateInclusionFlags(intersections.int_points2, res_poly);\n\n // fix boundary conflicts\n while (fixBoundaryConflicts(res_poly, wrk_poly, intersections.int_points1, intersections.int_points1_sorted, intersections.int_points2, intersections));\n // while (fixBoundaryConflicts(wrk_poly, res_poly, intersections.int_points2, intersections.int_points2_sorted, intersections.int_points1, intersections));\n\n // Set overlapping flags for boundary chains: SAME or OPPOSITE\n setOverlappingFlags(intersections);\n\n // remove not relevant chains between intersection points\n removeNotRelevantChains(res_poly, op, intersections.int_points1_sorted, true);\n removeNotRelevantChains(wrk_poly, op, intersections.int_points2_sorted, false);\n\n // remove not relevant not intersected faces from res_polygon and wrk_polygon\n // if op == UNION, remove faces that are included in wrk_polygon without intersection\n // if op == INTERSECT, remove faces that are not included into wrk_polygon\n removeNotRelevantNotIntersectedFaces(res_poly, notIntersectedFacesRes, op, true);\n removeNotRelevantNotIntersectedFaces(wrk_poly, notIntersectedFacesWrk, op, false);\n}\n\nfunction swapLinksAndRestore(res_poly, wrk_poly, intersections, op) {\n\n // add edges of wrk_poly into the edge container of res_poly\n copyWrkToRes(res_poly, wrk_poly, op, intersections.int_points2);\n\n // swap links from res_poly to wrk_poly and vice versa\n swapLinks(res_poly, wrk_poly, intersections);\n\n // remove old faces\n removeOldFaces(res_poly, intersections.int_points1);\n removeOldFaces(wrk_poly, intersections.int_points2);\n\n // restore faces\n restoreFaces(res_poly, intersections.int_points1, intersections.int_points2);\n restoreFaces(res_poly, intersections.int_points2, intersections.int_points1);\n\n // merge relevant not intersected faces from wrk_polygon to res_polygon\n // mergeRelevantNotIntersectedFaces(res_poly, wrk_poly);\n}\n\n\nfunction booleanOpBinary(polygon1, polygon2, op, restore)\n{\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n // calculate inclusion and remove not relevant edges\n filterNotRelevantEdges(res_poly, wrk_poly, intersections, op);\n\n if (restore) {\n swapLinksAndRestore(res_poly, wrk_poly, intersections, op);\n }\n\n return [res_poly, wrk_poly];\n}\n\nfunction getIntersections(polygon1, polygon2)\n{\n let intersections = {\n int_points1: [],\n int_points2: []\n };\n\n // calculate intersections\n for (let edge1 of polygon1.edges) {\n\n // request edges of polygon2 in the box of edge1\n let resp = polygon2.edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n return intersections;\n}\n\nfunction getNotIntersectedFaces(poly, int_points)\n{\n let notIntersected = [];\n for (let face of poly.faces) {\n if (!int_points.find((ip) => ip.face === face)) {\n notIntersected.push(face);\n }\n }\n return notIntersected;\n}\n\nfunction calcInclusionForNotIntersectedFaces(notIntersectedFaces, poly2)\n{\n for (let face of notIntersectedFaces) {\n face.first.bv = face.first.bvStart = face.first.bvEnd = undefined;\n face.first.setInclusion(poly2);\n }\n}\n\nfunction fixBoundaryConflicts(poly1, poly2, int_points1, int_points1_sorted, int_points2, intersections )\n{\n let cur_face;\n let first_int_point_in_face_id;\n let next_int_point1;\n let num_int_points = int_points1_sorted.length;\n let iterate_more = false;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n int_points2[next_int_point1_tmp.id].face === int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n // Case #1. One of the ends is not boundary - probably tiny edge wrongly marked as boundary\n if (edge_from1.bv === BOUNDARY && edge_to1.bv != BOUNDARY) {\n edge_from1.bv = edge_to1.bv;\n continue;\n }\n\n if (edge_from1.bv != BOUNDARY && edge_to1.bv === BOUNDARY) {\n edge_to1.bv = edge_from1.bv;\n continue;\n }\n\n // Set up all boundary values for middle edges. Need for cases 2 and 3\n if ( (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) ||\n (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) ) {\n let edge_tmp = edge_from1.next;\n while (edge_tmp != edge_to1) {\n edge_tmp.bvStart = undefined;\n edge_tmp.bvEnd = undefined;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n edge_tmp = edge_tmp.next;\n }\n }\n\n // Case #2. Both of the ends boundary. Check all the edges in the middle\n // If some edges in the middle are not boundary then update bv of 'from' and 'to' edges\n if (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) {\n let edge_tmp = edge_from1.next;\n let new_bv;\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bv != BOUNDARY) {\n if (new_bv === undefined) { // first not boundary edge between from and to\n new_bv = edge_tmp.bv;\n }\n else { // another not boundary edge between from and to\n if (edge_tmp.bv != new_bv) { // and it has different bv - can't resolve conflict\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n if (new_bv != undefined) {\n edge_from1.bv = new_bv;\n edge_to1.bv = new_bv;\n }\n continue; // all middle edges are boundary, proceed with this\n }\n\n // Case 3. One of the ends is inner, another is outer\n if (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) {\n let edge_tmp = edge_from1;\n // Find missing intersection point\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bvStart === edge_from1.bv && edge_tmp.bvEnd === edge_to1.bv) {\n let [dist, segment] = edge_tmp.shape.distanceTo(poly2);\n if (dist < 10*Flatten.DP_TOL) { // it should be very close\n // let pt = edge_tmp.end;\n // add to the list of intersections of poly1\n addToIntPoints(edge_tmp, segment.ps, int_points1);\n\n // split edge_tmp in poly1 if need\n let int_point1 = int_points1[int_points1.length-1];\n if (int_point1.is_vertex & START_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp;\n int_point1.edge_before = edge_tmp.prev;\n edge_tmp.bvStart = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else if (int_point1.is_vertex & END_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp.next;\n edge_tmp.bvEnd = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else { // split edge here\n let newEdge1 = poly2.addVertex(int_point1.pt, edge_tmp);\n int_point1.edge_before = newEdge1;\n int_point1.edge_after = newEdge1.next;\n\n newEdge1.setInclusion(poly2);\n\n newEdge1.next.bvStart = BOUNDARY;\n newEdge1.next.bvEnd = undefined;\n newEdge1.next.bv = undefined;\n newEdge1.next.setInclusion(poly2);\n }\n\n // add to the list of intersections of poly2\n let edge2 = poly2.findEdgeByPoint(segment.pe);\n addToIntPoints(edge2, segment.pe, int_points2);\n // split edge2 in poly2 if need\n let int_point2 = int_points2[int_points2.length-1];\n if (int_point2.is_vertex & START_VERTEX) { // nothing to split\n int_point2.edge_after = edge2;\n int_point2.edge_before = edge2.prev;\n }\n else if (int_point2.is_vertex & END_VERTEX) { // nothing to split\n int_point2.edge_after = edge2.next;\n }\n else { // split edge here\n // first locate int_points that may refer to edge2 as edge.after\n // let int_point2_edge_before = int_points2.find( int_point => int_point.edge_before === edge2)\n let int_point2_edge_after = int_points2.find( int_point => int_point.edge_after === edge2 );\n\n let newEdge2 = poly2.addVertex(int_point2.pt, edge2);\n int_point2.edge_before = newEdge2;\n int_point2.edge_after = newEdge2.next;\n\n if (int_point2_edge_after)\n int_point2_edge_after.edge_after = newEdge2;\n\n newEdge2.bvStart = undefined;\n newEdge2.bvEnd = BOUNDARY;\n newEdge2.bv = undefined;\n newEdge2.setInclusion(poly1);\n\n newEdge2.next.bvStart = BOUNDARY;\n newEdge2.next.bvEnd = undefined;\n newEdge2.next.bv = undefined;\n newEdge2.next.setInclusion(poly1);\n }\n\n sortIntersections(intersections);\n\n iterate_more = true;\n break;\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n // we changed intersections inside loop, have to exit and repair again\n if (iterate_more)\n break;\n\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n\n return iterate_more;\n}\n\nfunction removeNotRelevantChains(polygon, op, int_points, is_res_polygon)\n{\n if (!int_points) return;\n let cur_face = undefined;\n let first_int_point_in_face_num = undefined;\n let int_point_current;\n let int_point_next;\n\n for (let i = 0; i < int_points.length; i++) {\n int_point_current = int_points[i];\n\n if (int_point_current.face !== cur_face) { // next face started\n first_int_point_in_face_num = i;\n cur_face = int_point_current.face;\n }\n\n if (cur_face.isEmpty()) // ??\n continue;\n\n // Get next int point from the same face that current\n\n // Count how many duplicated points with same in \"points from\" pool ?\n let int_points_from_pull_start = i;\n let int_points_from_pull_num = intPointsPoolCount(int_points, i, cur_face);\n let next_int_point_num;\n if (int_points_from_pull_start + int_points_from_pull_num < int_points.length &&\n int_points[int_points_from_pull_start + int_points_from_pull_num].face === int_point_current.face) {\n next_int_point_num = int_points_from_pull_start + int_points_from_pull_num;\n } else { // get first point from the same face\n next_int_point_num = first_int_point_in_face_num;\n }\n int_point_next = int_points[next_int_point_num];\n\n /* Count how many duplicated points with same in \"points to\" pull ? */\n let int_points_to_pull_start = next_int_point_num;\n let int_points_to_pull_num = intPointsPoolCount(int_points, int_points_to_pull_start, cur_face);\n\n\n let edge_from = int_point_current.edge_after;\n let edge_to = int_point_next.edge_before;\n\n if ((edge_from.bv === INSIDE$1 && edge_to.bv === INSIDE$1 && op === BOOLEAN_UNION) ||\n (edge_from.bv === OUTSIDE && edge_to.bv === OUTSIDE && op === BOOLEAN_INTERSECT) ||\n ((edge_from.bv === OUTSIDE || edge_to.bv === OUTSIDE) && op === BOOLEAN_SUBTRACT && !is_res_polygon) ||\n ((edge_from.bv === INSIDE$1 || edge_to.bv === INSIDE$1) && op === BOOLEAN_SUBTRACT && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_SAME) && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_OPPOSITE))) {\n\n polygon.removeChain(cur_face, edge_from, edge_to);\n\n /* update all points in \"points from\" pull */\n for (let k = int_points_from_pull_start; k < int_points_from_pull_start + int_points_from_pull_num; k++) {\n int_points[k].edge_after = undefined;\n }\n\n /* update all points in \"points to\" pull */\n for (let k = int_points_to_pull_start; k < int_points_to_pull_start + int_points_to_pull_num; k++) {\n int_points[k].edge_before = undefined;\n }\n }\n\n /* skip to the last point in \"points from\" group */\n i += int_points_from_pull_num - 1;\n }\n}\nfunction copyWrkToRes(res_polygon, wrk_polygon, op, int_points)\n{\n for (let face of wrk_polygon.faces) {\n for (let edge of face) {\n res_polygon.edges.add(edge);\n }\n // If union - add face from wrk_polygon that is not intersected with res_polygon\n if ( /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/\n int_points.find((ip) => (ip.face === face)) === undefined) {\n res_polygon.addFace(face.first, face.last);\n }\n }\n}\n\nfunction swapLinks(res_polygon, wrk_polygon, intersections)\n{\n if (intersections.int_points1.length === 0) return;\n\n for (let i = 0; i < intersections.int_points1.length; i++) {\n let int_point1 = intersections.int_points1[i];\n let int_point2 = intersections.int_points2[i];\n\n // Simple case - find continuation on the other polygon\n\n // Process edge from res_polygon\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // swap need\n if (int_point2.edge_before === undefined && int_point2.edge_after !== undefined) { // simple case\n // Connect edges\n int_point1.edge_before.next = int_point2.edge_after;\n int_point2.edge_after.prev = int_point1.edge_before;\n\n // Fill in missed links in intersection points\n int_point1.edge_after = int_point2.edge_after;\n int_point2.edge_before = int_point1.edge_before;\n }\n }\n // Process edge from wrk_polygon\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // swap need\n if (int_point1.edge_before === undefined && int_point1.edge_after !== undefined) { // simple case\n // Connect edges\n int_point2.edge_before.next = int_point1.edge_after;\n int_point1.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point1.edge_after;\n int_point1.edge_before = int_point2.edge_before;\n }\n }\n\n // Continuation not found - complex case\n // Continuation will be found on the same polygon.\n // It happens when intersection point is actually touching point\n // Polygon1\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points1_sorted) {\n if (int_point === int_point1) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point1.pt)) {\n // Connect edges\n int_point1.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point1.edge_before;\n\n // Complete missed links\n int_point1.edge_after = int_point.edge_after;\n int_point.edge_before = int_point1.edge_before;\n }\n }\n }\n }\n // Polygon2\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points2_sorted) {\n if (int_point === int_point2) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point2.pt)) {\n // Connect edges\n int_point2.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point.edge_after;\n int_point.edge_before = int_point2.edge_before;\n }\n }\n }\n }\n }\n // Sanity check that no dead ends left\n}\n\nfunction removeOldFaces(polygon, int_points)\n{\n for (let int_point of int_points) {\n polygon.faces.delete(int_point.face);\n int_point.face = undefined;\n if (int_point.edge_before)\n int_point.edge_before.face = undefined;\n if (int_point.edge_after)\n int_point.edge_after.face = undefined;\n }\n}\n\nfunction restoreFaces(polygon, int_points, other_int_points)\n{\n // For each intersection point - create new face\n for (let int_point of int_points) {\n if (int_point.edge_before === undefined || int_point.edge_after === undefined) // completely deleted\n continue;\n if (int_point.face) // already restored\n continue;\n\n if (int_point.edge_after.face || int_point.edge_before.face) // Face already created. Possible case in duplicated intersection points\n continue;\n\n let first = int_point.edge_after; // face start\n let last = int_point.edge_before; // face end;\n\n try {\n LinkedList.testInfiniteLoop(first); // check and throw error if infinite loop found\n }\n catch (error) {\n throw Errors.CANNOT_COMPLETE_BOOLEAN_OPERATION\n }\n\n let face = polygon.addFace(first, last);\n\n // Mark intersection points from the newly create face\n // to avoid multiple creation of the same face.\n // Face was assigned to each edge of new face in addFace function\n for (let int_point_tmp of int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n // Mark other intersection points as well\n for (let int_point_tmp of other_int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n }\n}\n\nfunction removeNotRelevantNotIntersectedFaces(polygon, notIntersectedFaces, op, is_res_polygon)\n{\n for (let face of notIntersectedFaces) {\n let rel = face.first.bv;\n if (op === BOOLEAN_UNION && rel === INSIDE$1 ||\n op === BOOLEAN_SUBTRACT && rel === INSIDE$1 && is_res_polygon ||\n op === BOOLEAN_SUBTRACT && rel === OUTSIDE && !is_res_polygon ||\n op === BOOLEAN_INTERSECT && rel === OUTSIDE) {\n\n polygon.deleteFace(face);\n }\n }\n}\n\nvar BooleanOperations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOOLEAN_INTERSECT: BOOLEAN_INTERSECT,\n BOOLEAN_SUBTRACT: BOOLEAN_SUBTRACT,\n BOOLEAN_UNION: BOOLEAN_UNION,\n calculateIntersections: calculateIntersections,\n innerClip: innerClip,\n intersect: intersect$1,\n outerClip: outerClip,\n removeNotRelevantChains: removeNotRelevantChains,\n removeOldFaces: removeOldFaces,\n restoreFaces: restoreFaces,\n subtract: subtract,\n unify: unify\n});\n\n/*\n Dimensionally extended 9-intersected model\n See https://en.wikipedia.org/wiki/DE-9IM for more details\n */\n// const DISJOINT = RegExp('FF.FF....');\nconst EQUAL = RegExp('T.F..FFF.|T.F...F..');\nconst INTERSECT = RegExp('T........|.T.......|...T.....|....T....');\nconst TOUCH = RegExp('FT.......|F..T.....|F...T....');\nconst INSIDE = RegExp('T.F..F...');\nconst COVERED = RegExp('T.F..F...|.TF..F...|..FT.F...|..F.TF...');\n\nclass DE9IM {\n /**\n * Create new instance of DE9IM matrix\n */\n constructor() {\n /**\n * Array representing 3x3 intersection matrix\n * @type {Shape[]}\n */\n this.m = new Array(9).fill(undefined);\n }\n\n /**\n * Get Interior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get I2I() {\n return this.m[0];\n }\n\n /**\n * Set Interior To Interior intersection\n * @param geom\n */\n set I2I(geom) {\n this.m[0] = geom;\n }\n\n /**\n * Get Interior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get I2B() {\n return this.m[1];\n }\n\n /**\n * Set Interior to Boundary intersection\n * @param geomc\n */\n set I2B(geom) {\n this.m[1] = geom;\n }\n\n /**\n * Get Interior To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get I2E() {\n return this.m[2];\n }\n\n /**\n * Set Interior to Exterior intersection\n * @param geom\n */\n set I2E(geom) {\n this.m[2] = geom;\n }\n\n /**\n * Get Boundary To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get B2I() {\n return this.m[3];\n }\n\n /**\n * Set Boundary to Interior intersection\n * @param geom\n */\n set B2I(geom) {\n this.m[3] = geom;\n }\n\n /**\n * Get Boundary To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get B2B() {\n return this.m[4];\n }\n\n /**\n * Set Boundary to Boundary intersection\n * @param geom\n */\n set B2B(geom) {\n this.m[4] = geom;\n }\n\n /**\n * Get Boundary To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get B2E() {\n return this.m[5];\n }\n\n /**\n * Set Boundary to Exterior intersection\n * @param geom\n */\n set B2E(geom) {\n this.m[5] = geom;\n }\n\n /**\n * Get Exterior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get E2I() {\n return this.m[6];\n }\n\n /**\n * Set Exterior to Interior intersection\n * @param geom\n */\n set E2I(geom) {\n this.m[6] = geom;\n }\n\n /**\n * Get Exterior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get E2B() {\n return this.m[7];\n }\n\n /**\n * Set Exterior to Boundary intersection\n * @param geom\n */\n set E2B(geom) {\n this.m[7] = geom;\n }\n\n /**\n * Get Exterior to Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get E2E() {\n return this.m[8];\n }\n\n /**\n * Set Exterior to Exterior intersection\n * @param geom\n */\n set E2E(geom) {\n this.m[8] = geom;\n }\n\n /**\n * Return de9im matrix as string where
\n * - intersection is 'T'
\n * - not intersected is 'F'
\n * - not relevant is '*'
\n * For example, string 'FF**FF****' means 'DISJOINT'\n * @returns {string}\n */\n toString() {\n return this.m.map( e => {\n if (e instanceof Array && e.length > 0) {\n return 'T'\n }\n else if (e instanceof Array && e.length === 0) {\n return 'F'\n }\n else {\n return '*'\n }\n }).join(\"\")\n }\n\n equal() {\n return EQUAL.test(this.toString());\n }\n\n intersect() {\n return INTERSECT.test(this.toString());\n }\n\n touch() {\n return TOUCH.test(this.toString());\n }\n\n inside() {\n return INSIDE.test(this.toString());\n }\n\n covered() {\n return COVERED.test(this.toString());\n }\n}\n\n/**\n * Intersection\n *\n * */\n\n\nfunction intersectLine2Line(line1, line2) {\n let ip = [];\n\n let [A1, B1, C1] = line1.standard;\n let [A2, B2, C2] = line2.standard;\n\n /* Cramer's rule */\n let det = A1 * B2 - B1 * A2;\n let detX = C1 * B2 - B1 * C2;\n let detY = A1 * C2 - C1 * A2;\n\n if (!Flatten.Utils.EQ_0(det)) {\n let x, y;\n\n if (B1 === 0) { // vertical line x = C1/A1, where A1 == +1 or -1\n x = C1/A1;\n y = detY / det;\n }\n else if (B2 === 0) { // vertical line x = C2/A2, where A2 = +1 or -1\n x = C2/A2;\n y = detY / det;\n }\n else if (A1 === 0) { // horizontal line y = C1/B1, where B1 = +1 or -1\n x = detX / det;\n y = C1/B1;\n }\n else if (A2 === 0) { // horizontal line y = C2/B2, where B2 = +1 or -1\n x = detX / det;\n y = C2/B2;\n }\n else {\n x = detX / det;\n y = detY / det;\n }\n\n ip.push(new Flatten.Point(x, y));\n }\n\n return ip;\n}\n\nfunction intersectLine2Circle(line, circle) {\n let ip = [];\n let prj = circle.pc.projectionOn(line); // projection of circle center on a line\n let dist = circle.pc.distanceTo(prj)[0]; // distance from circle center to projection\n\n if (Flatten.Utils.EQ(dist, circle.r)) { // line tangent to circle - return single intersection point\n ip.push(prj);\n } else if (Flatten.Utils.LT(dist, circle.r)) { // return two intersection points\n let delta = Math.sqrt(circle.r * circle.r - dist * dist);\n let v_trans, pt;\n\n v_trans = line.norm.rotate90CCW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n\n v_trans = line.norm.rotate90CW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n }\n return ip;\n}\n\nfunction intersectLine2Box(line, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Line(seg, line);\n for (let pt of ips_tmp) {\n if (!ptInIntPoints(pt, ips)) {\n ips.push(pt);\n }\n }\n }\n return ips;\n}\n\nfunction intersectLine2Arc(line, arc) {\n let ip = [];\n\n if (intersectLine2Box(line, arc.box).length === 0) {\n return ip;\n }\n\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectLine2Circle(line, circle);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectSegment2Line(seg, line) {\n let ip = [];\n\n // Boundary cases\n if (seg.ps.on(line)) {\n ip.push(seg.ps);\n }\n // If both ends lay on line, return two intersection points\n if (seg.pe.on(line) && !seg.isZeroLength()) {\n ip.push(seg.pe);\n }\n\n if (ip.length > 0) {\n return ip; // done, intersection found\n }\n\n // If zero-length segment and nothing found, return no intersections\n if (seg.isZeroLength()) {\n return ip;\n }\n\n // Not a boundary case, check if both points are on the same side and\n // hence there is no intersection\n if (seg.ps.leftTo(line) && seg.pe.leftTo(line) ||\n !seg.ps.leftTo(line) && !seg.pe.leftTo(line)) {\n return ip;\n }\n\n // Calculate intersection between lines\n let line1 = new Flatten.Line(seg.ps, seg.pe);\n return intersectLine2Line(line1, line);\n}\n\nfunction intersectSegment2Segment(seg1, seg2) {\n let ip = [];\n\n // quick reject\n if (seg1.box.not_intersect(seg2.box)) {\n return ip;\n }\n\n // Special case of seg1 zero length\n if (seg1.isZeroLength()) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n return ip;\n }\n\n // Special case of seg2 zero length\n if (seg2.isZeroLength()) {\n if (seg2.ps.on(seg1)) {\n ip.push(seg2.ps);\n }\n return ip;\n }\n\n // Neither seg1 nor seg2 is zero length\n let line1 = new Flatten.Line(seg1.ps, seg1.pe);\n let line2 = new Flatten.Line(seg2.ps, seg2.pe);\n\n // Check overlapping between segments in case of incidence\n // If segments touching, add one point. If overlapping, add two points\n if (line1.incidentTo(line2)) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n if (seg1.pe.on(seg2)) {\n ip.push(seg1.pe);\n }\n if (seg2.ps.on(seg1) && !seg2.ps.equalTo(seg1.ps) && !seg2.ps.equalTo(seg1.pe)) {\n ip.push(seg2.ps);\n }\n if (seg2.pe.on(seg1) && !seg2.pe.equalTo(seg1.ps) && !seg2.pe.equalTo(seg1.pe)) {\n ip.push(seg2.pe);\n }\n } else { /* not incident - parallel or intersect */\n // Calculate intersection between lines\n let new_ip = intersectLine2Line(line1, line2);\n if (new_ip.length > 0) {\n if (isPointInSegmentBox(new_ip[0], seg1) && isPointInSegmentBox(new_ip[0], seg2)) {\n ip.push(new_ip[0]);\n }\n }\n }\n return ip;\n}\n\nfunction isPointInSegmentBox(point, segment) {\n const box = segment.box;\n return Flatten.Utils.LE(point.x, box.xmax) && Flatten.Utils.GE(point.x, box.xmin) &&\n Flatten.Utils.LE(point.y, box.ymax) && Flatten.Utils.GE(point.y, box.ymin)\n}\n\nfunction intersectSegment2Circle(segment, circle) {\n let ips = [];\n\n if (segment.box.not_intersect(circle.box)) {\n return ips;\n }\n\n // Special case of zero length segment\n if (segment.isZeroLength()) {\n let [dist, _] = segment.ps.distanceTo(circle.pc);\n if (Flatten.Utils.EQ(dist, circle.r)) {\n ips.push(segment.ps);\n }\n return ips;\n }\n\n // Non zero-length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n\n let ips_tmp = intersectLine2Circle(line, circle);\n\n for (let ip of ips_tmp) {\n if (ip.on(segment)) {\n ips.push(ip);\n }\n }\n\n return ips;\n}\n\nfunction intersectSegment2Arc(segment, arc) {\n let ip = [];\n\n if (segment.box.not_intersect(arc.box)) {\n return ip;\n }\n\n // Special case of zero-length segment\n if (segment.isZeroLength()) {\n if (segment.ps.on(arc)) {\n ip.push(segment.ps);\n }\n return ip;\n }\n\n // Non-zero length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n let ip_tmp = intersectLine2Circle(line, circle);\n\n for (let pt of ip_tmp) {\n if (pt.on(segment) && pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n\n}\n\nfunction intersectSegment2Box(segment, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Segment(seg, segment);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectCircle2Circle(circle1, circle2) {\n let ip = [];\n\n if (circle1.box.not_intersect(circle2.box)) {\n return ip;\n }\n\n let vec = new Flatten.Vector(circle1.pc, circle2.pc);\n\n let r1 = circle1.r;\n let r2 = circle2.r;\n\n // Degenerated circle\n if (Flatten.Utils.EQ_0(r1) || Flatten.Utils.EQ_0(r2))\n return ip;\n\n // In case of equal circles return one leftmost point\n if (Flatten.Utils.EQ_0(vec.x) && Flatten.Utils.EQ_0(vec.y) && Flatten.Utils.EQ(r1, r2)) {\n ip.push(circle1.pc.translate(-r1, 0));\n return ip;\n }\n\n let dist = circle1.pc.distanceTo(circle2.pc)[0];\n\n if (Flatten.Utils.GT(dist, r1 + r2)) // circles too far, no intersections\n return ip;\n\n if (Flatten.Utils.LT(dist, Math.abs(r1 - r2))) // one circle is contained within another, no intersections\n return ip;\n\n // Normalize vector.\n vec.x /= dist;\n vec.y /= dist;\n\n let pt;\n\n // Case of touching from outside or from inside - single intersection point\n // TODO: check this specifically not sure if correct\n if (Flatten.Utils.EQ(dist, r1 + r2) || Flatten.Utils.EQ(dist, Math.abs(r1 - r2))) {\n pt = circle1.pc.translate(r1 * vec.x, r1 * vec.y);\n ip.push(pt);\n return ip;\n }\n\n // Case of two intersection points\n\n // Distance from first center to center of common chord:\n // a = (r1^2 - r2^2 + d^2) / 2d\n // Separate for better accuracy\n let a = (r1 * r1) / (2 * dist) - (r2 * r2) / (2 * dist) + dist / 2;\n\n let mid_pt = circle1.pc.translate(a * vec.x, a * vec.y);\n let h = Math.sqrt(r1 * r1 - a * a);\n // let norm;\n\n // norm = vec.rotate90CCW().multiply(h);\n pt = mid_pt.translate(vec.rotate90CCW().multiply(h));\n ip.push(pt);\n\n // norm = vec.rotate90CW();\n pt = mid_pt.translate(vec.rotate90CW().multiply(h));\n ip.push(pt);\n\n return ip;\n}\n\nfunction intersectCircle2Box(circle, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Circle(seg, circle);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectArc2Arc(arc1, arc2) {\n let ip = [];\n\n if (arc1.box.not_intersect(arc2.box)) {\n return ip;\n }\n\n // Special case: overlapping arcs\n // May return up to 4 intersection points\n if (arc1.pc.equalTo(arc2.pc) && Flatten.Utils.EQ(arc1.r, arc2.r)) {\n let pt;\n\n pt = arc1.start;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc1.end;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc2.start;\n if (pt.on(arc1)) ip.push(pt);\n\n pt = arc2.end;\n if (pt.on(arc1)) ip.push(pt);\n\n return ip;\n }\n\n // Common case\n let circle1 = new Flatten.Circle(arc1.pc, arc1.r);\n let circle2 = new Flatten.Circle(arc2.pc, arc2.r);\n let ip_tmp = circle1.intersect(circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc1) && pt.on(arc2)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Circle(arc, circle) {\n let ip = [];\n\n if (arc.box.not_intersect(circle.box)) {\n return ip;\n }\n\n // Case when arc center incident to circle center\n // Return arc's end points as 2 intersection points\n if (circle.pc.equalTo(arc.pc) && Flatten.Utils.EQ(circle.r, arc.r)) {\n ip.push(arc.start);\n ip.push(arc.end);\n return ip;\n }\n\n // Common case\n let circle1 = circle;\n let circle2 = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectCircle2Circle(circle1, circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Box(arc, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Arc(seg, arc);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectEdge2Segment(edge, segment) {\n return edge.isSegment ? intersectSegment2Segment(edge.shape, segment) : intersectSegment2Arc(segment, edge.shape);\n}\n\nfunction intersectEdge2Arc(edge, arc) {\n return edge.isSegment ? intersectSegment2Arc(edge.shape, arc) : intersectArc2Arc(edge.shape, arc);\n}\n\nfunction intersectEdge2Line(edge, line) {\n return edge.isSegment ? intersectSegment2Line(edge.shape, line) : intersectLine2Arc(line, edge.shape);\n}\n\nfunction intersectEdge2Ray(edge, ray) {\n return edge.isSegment ? intersectRay2Segment(ray, edge.shape) : intersectRay2Arc(ray, edge.shape);\n}\n\nfunction intersectEdge2Circle(edge, circle) {\n return edge.isSegment ? intersectSegment2Circle(edge.shape, circle) : intersectArc2Circle(edge.shape, circle);\n}\n\nfunction intersectSegment2Polygon(segment, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Segment(edge, segment)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectArc2Polygon(arc, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Arc(edge, arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectLine2Polygon(line, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Line(edge, line)) {\n if (!ptInIntPoints(pt, ip)) {\n ip.push(pt);\n }\n }\n }\n\n return line.sortPoints(ip);\n}\n\nfunction intersectCircle2Polygon(circle, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Circle(edge, circle)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectEdge2Edge(edge1, edge2) {\n if (edge1.isSegment) {\n return intersectEdge2Segment(edge2, edge1.shape)\n }\n else if (edge1.isArc) {\n return intersectEdge2Arc(edge2, edge1.shape)\n }\n else if (edge1.isLine) {\n return intersectEdge2Line(edge2, edge1.shape)\n }\n else if (edge1.isRay) {\n return intersectEdge2Ray(edge2, edge1.shape)\n }\n return []\n}\n\nfunction intersectEdge2Polygon(edge, polygon) {\n let ip = [];\n\n if (polygon.isEmpty() || edge.shape.box.not_intersect(polygon.box)) {\n return ip;\n }\n\n let resp_edges = polygon.edges.search(edge.shape.box);\n\n for (let resp_edge of resp_edges) {\n ip = [...ip, ...intersectEdge2Edge(edge, resp_edge)];\n }\n\n return ip;\n}\n\nfunction intersectPolygon2Polygon(polygon1, polygon2) {\n let ip = [];\n\n if (polygon1.isEmpty() || polygon2.isEmpty()) {\n return ip;\n }\n\n if (polygon1.box.not_intersect(polygon2.box)) {\n return ip;\n }\n\n for (let edge1 of polygon1.edges) {\n ip = [...ip, ...intersectEdge2Polygon(edge1, polygon2)];\n }\n\n return ip;\n}\n\nfunction intersectShape2Polygon(shape, polygon) {\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, polygon);\n }\n else {\n return [];\n }\n}\n\nfunction ptInIntPoints(new_pt, ip) {\n return ip.some( pt => pt.equalTo(new_pt) )\n}\n\nfunction createLineFromRay(ray) {\n return new Flatten.Line(ray.start, ray.norm)\n}\nfunction intersectRay2Segment(ray, segment) {\n return intersectSegment2Line(segment, createLineFromRay(ray))\n .filter(pt => ray.contains(pt));\n}\n\nfunction intersectRay2Arc(ray, arc) {\n return intersectLine2Arc(createLineFromRay(ray), arc)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Circle(ray, circle) {\n return intersectLine2Circle(createLineFromRay(ray), circle)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Box(ray, box) {\n return intersectLine2Box(createLineFromRay(ray), box)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Line(ray, line) {\n return intersectLine2Line(createLineFromRay(ray), line)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Ray(ray1, ray2) {\n return intersectLine2Line(createLineFromRay(ray1), createLineFromRay(ray2))\n .filter(pt => ray1.contains(pt))\n .filter(pt => ray2.contains(pt))\n}\n\nfunction intersectRay2Polygon(ray, polygon) {\n return intersectLine2Polygon(createLineFromRay(ray), polygon)\n .filter(pt => ray.contains(pt))\n}\n\nconst defaultAttributes = {\n stroke: \"black\"\n};\n\nclass SVGAttributes {\n constructor(args = defaultAttributes) {\n for(const property in args) {\n this[property] = args[property];\n }\n this.stroke = args.stroke ?? defaultAttributes.stroke;\n }\n\n toAttributesString() {\n return Object.keys(this)\n .reduce( (acc, key) =>\n acc + (this[key] !== undefined ? this.toAttrString(key, this[key]) : \"\")\n , ``)\n }\n\n toAttrString(key, value) {\n const SVGKey = key === \"className\" ? \"class\" : this.convertCamelToKebabCase(key);\n return value === null ? `${SVGKey} ` : `${SVGKey}=\"${value.toString()}\" `\n }\n\n convertCamelToKebabCase(str) {\n return str\n .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)\n .join('-')\n .toLowerCase();\n }\n}\n\nfunction convertToString(attrs) {\n return new SVGAttributes(attrs).toAttributesString()\n}\n\n/**\n * Class Multiline represent connected path of [edges]{@link Flatten.Edge}, where each edge may be\n * [segment]{@link Flatten.Segment}, [arc]{@link Flatten.Arc}, [line]{@link Flatten.Line} or [ray]{@link Flatten.Ray}\n */\nclass Multiline extends LinkedList {\n constructor(...args) {\n super();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n let shapes = args[0];\n if (shapes.length === 0)\n return;\n\n // TODO: more strict validation:\n // there may be only one line\n // only first and last may be rays\n shapes.every((shape) => {\n return shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc ||\n shape instanceof Flatten.Ray ||\n shape instanceof Flatten.Line\n });\n\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n }\n\n this.setArcLength();\n }\n }\n }\n\n /**\n * (Getter) Return array of edges\n * @returns {Edge[]}\n */\n get edges() {\n return [...this];\n }\n\n /**\n * (Getter) Return bounding box of the multiline\n * @returns {Box}\n */\n get box() {\n return this.edges.reduce( (acc,edge) => acc.merge(edge.box), new Flatten.Box() );\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Point[]}\n */\n get vertices() {\n let v = this.edges.map(edge => edge.start);\n v.push(this.last.end);\n return v;\n }\n\n /**\n * Return new cloned instance of Multiline\n * @returns {Multiline}\n */\n clone() {\n return new Multiline(this.toShapes());\n }\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Split edge and add new vertex, return new edge inserted\n * @param {Point} pt - point on edge that will be added as new vertex\n * @param {Edge} edge - edge to split\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n this.insert(newEdge, edgeBefore); // edge.face ?\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n return newEdge;\n }\n\n getChain(edgeFrom, edgeTo) {\n let edges = [];\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n edges.push(edge);\n }\n return edges\n }\n\n /**\n * Split edges of multiline with intersection points and return mutated multiline\n * @param {Point[]} ip - array of points to be added as new vertices\n * @returns {Multiline}\n */\n split(ip) {\n for (let pt of ip) {\n let edge = this.findEdgeByPoint(pt);\n this.addVertex(pt, edge);\n }\n return this;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new multiline translated by vector vec\n * @param {Vector} vec\n * @returns {Multiline}\n */\n translate(vec) {\n return new Multiline(this.edges.map( edge => edge.shape.translate(vec)));\n }\n\n /**\n * Return new multiline rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Multiline} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n return new Multiline(this.edges.map( edge => edge.shape.rotate(angle, center) ));\n }\n\n /**\n * Return new multiline transformed using affine transformation matrix\n * Method does not support unbounded shapes\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Multiline} - new multiline\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Multiline(this.edges.map( edge => edge.shape.transform(matrix)));\n }\n\n /**\n * Transform multiline into array of shapes\n * @returns {Shape[]}\n */\n toShapes() {\n return this.edges.map(edge => edge.shape.clone())\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Return string to draw multiline in svg\n * @param attrs - an object with attributes for svg path element\n * TODO: support semi-infinite Ray and infinite Line\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Multiline = Multiline;\n\n/**\n * Shortcut function to create multiline\n * @param args\n */\nconst multiline = (...args) => new Flatten.Multiline(...args);\nFlatten.multiline = multiline;\n\n/**\n * @module RayShoot\n */\n/**\n * Implements ray shooting algorithm. Returns relation between point and polygon: inside, outside or boundary\n * @param {Polygon} polygon - polygon to test\n * @param {Point} point - point to test\n * @returns {INSIDE|OUTSIDE|BOUNDARY}\n */\nfunction ray_shoot(polygon, point) {\n let contains = undefined;\n\n // 1. Quick reject\n // if (polygon.box.not_intersect(point.box)) {\n // return Flatten.OUTSIDE;\n // }\n\n let ray = new Flatten.Ray(point);\n let line = new Flatten.Line(ray.pt, ray.norm);\n\n // 2. Locate relevant edges of the polygon\n const searchBox = new Flatten.Box(\n ray.box.xmin-Flatten.DP_TOL, ray.box.ymin-Flatten.DP_TOL,\n ray.box.xmax, ray.box.ymax+Flatten.DP_TOL\n );\n\n if (polygon.box.not_intersect(searchBox)) {\n return Flatten.OUTSIDE;\n }\n\n let resp_edges = polygon.edges.search(searchBox);\n\n if (resp_edges.length === 0) {\n return Flatten.OUTSIDE;\n }\n\n // 2.5 Check if boundary\n for (let edge of resp_edges) {\n if (edge.shape.contains(point)) {\n return Flatten.BOUNDARY;\n }\n }\n\n let faces = [...polygon.faces];\n\n // 3. Calculate intersections\n let intersections = [];\n for (let edge of resp_edges) {\n for (let ip of ray.intersect(edge.shape)) {\n\n // If intersection is equal to query point then point lays on boundary\n if (ip.equalTo(point)) {\n return Flatten.BOUNDARY;\n }\n\n intersections.push({\n pt: ip,\n edge: edge,\n face_index: faces.indexOf(edge.face)\n });\n }\n }\n\n // 4. Sort intersection in x-ascending order\n intersections.sort((i1, i2) => {\n if (LT(i1.pt.x, i2.pt.x)) {\n return -1;\n }\n if (GT(i1.pt.x, i2.pt.x)) {\n return 1;\n }\n if (i1.face_index < i2.face_index) {\n return -1\n }\n if (i1.face_index > i2.face_index) {\n return 1\n }\n if (i1.edge.arc_length < i2.edge.arc_length) {\n return -1\n }\n if (i1.edge.arc_length > i2.edge.arc_length) {\n return 1\n }\n return 0;\n });\n\n // 5. Count real intersections, exclude touching\n let counter = 0;\n\n for (let i = 0; i < intersections.length; i++) {\n let intersection = intersections[i];\n\n if (intersection.pt.equalTo(intersection.edge.shape.start)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.face_index === intersections[i - 1].face_index &&\n intersection.edge.prev === intersections[i - 1].edge) {\n continue;\n }\n\n let prev_edge = intersection.edge.prev;\n while (EQ_0(prev_edge.length)) {\n prev_edge = prev_edge.prev;\n }\n let prev_tangent = prev_edge.shape.tangentInEnd();\n let prev_point = intersection.pt.translate(prev_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInStart();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let prev_on_the_left = prev_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((prev_on_the_left && !cur_on_the_left) || (!prev_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else if (intersection.pt.equalTo(intersection.edge.shape.end)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.face_index === intersections[i-1].face_index &&\n intersection.edge.next === intersections[i - 1].edge) {\n continue;\n }\n\n let next_edge = intersection.edge.next;\n while (EQ_0(next_edge.length)) {\n next_edge = next_edge.next;\n }\n let next_tangent = next_edge.shape.tangentInStart();\n let next_point = intersection.pt.translate(next_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInEnd();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let next_on_the_left = next_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((next_on_the_left && !cur_on_the_left) || (!next_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else { /* intersection point is not a vertex */\n if (intersection.edge.shape instanceof Flatten.Segment) {\n counter++;\n } else {\n /* Check if ray does not touch the curve in the extremal (top or bottom) point */\n let box = intersection.edge.shape.box;\n if (!(EQ(intersection.pt.y, box.ymin) ||\n EQ(intersection.pt.y, box.ymax))) {\n counter++;\n }\n }\n }\n }\n\n // 6. Odd or even?\n contains = counter % 2 === 1 ? INSIDE$2 : OUTSIDE$1;\n return contains;\n}\n\n/*\n Calculate relationship between two shapes and return result in the form of\n Dimensionally Extended nine-Intersection Matrix (https://en.wikipedia.org/wiki/DE-9IM)\n */\n\n\n/**\n * Returns true if shapes are topologically equal: their interiors intersect and\n * no part of the interior or boundary of one geometry intersects the exterior of the other\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction equal(shape1, shape2) {\n return relate(shape1, shape2).equal();\n}\n\n/**\n * Returns true if shapes have at least one point in common, same as \"not disjoint\"\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction intersect(shape1, shape2) {\n return relate(shape1, shape2).intersect();\n}\n\n/**\n * Returns true if shapes have at least one point in common, but their interiors do not intersect\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction touch(shape1, shape2) {\n return relate(shape1, shape2).touch();\n}\n\n/**\n * Returns true if shapes have no points in common neither in interior nor in boundary\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction disjoint(shape1, shape2) {\n return !intersect(shape1, shape2);\n}\n\n/**\n * Returns true shape1 lies in the interior of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction inside(shape1, shape2) {\n return relate(shape1, shape2).inside();\n}\n\n/**\n * Returns true if every point in shape1 lies in the interior or on the boundary of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction covered(shape1, shape2) {\n return relate(shape1, shape2).covered();\n}\n\n/**\n * Returns true shape1's interior contains shape2
\n * Same as inside(shape2, shape1)\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction contain(shape1, shape2) {\n return inside(shape2, shape1);\n}\n\n/**\n * Returns true shape1's cover shape2, same as shape2 covered by shape1\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction cover(shape1, shape2) {\n return covered(shape2, shape1);\n}\n\n/**\n * Returns relation between two shapes as intersection 3x3 matrix, where each\n * element contains relevant intersection as array of shapes.\n * If there is no intersection, element contains empty array\n * If intersection is irrelevant it left undefined. (For example, intersection\n * between two exteriors is usually irrelevant)\n * @param shape1\n * @param shape2\n * @returns {DE9IM}\n */\nfunction relate(shape1, shape2) {\n if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Line) {\n return relateLine2Line(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Circle) {\n return relateLine2Circle(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Box) {\n return relateLine2Box(shape1, shape2);\n }\n else if ( shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Polygon) {\n return relateLine2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) && shape2 instanceof Flatten.Polygon) {\n return relateShape2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box) ) {\n return relateShape2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n else if (shape1 instanceof Flatten.Polygon && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(shape1, shape2);\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), new Flatten.Polygon(shape2));\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), shape2);\n }\n else if (shape1 instanceof Flatten.Polygon && (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n}\n\nfunction relateLine2Line(line1, line2) {\n let denim = new DE9IM();\n let ip = intersectLine2Line(line1, line2);\n if (ip.length === 0) { // parallel or equal ?\n if (line1.contains(line2.pt) && line2.contains(line1.pt)) {\n denim.I2I = [line1]; // equal 'T.F...F..' - no boundary\n denim.I2E = [];\n denim.E2I = [];\n }\n else { // parallel - disjoint 'FFTFF*T**'\n denim.I2I = [];\n denim.I2E = [line1];\n denim.E2I = [line2];\n }\n }\n else { // intersect 'T********'\n denim.I2I = ip;\n denim.I2E = line1.split(ip);\n denim.E2I = line2.split(ip);\n }\n return denim;\n}\n\nfunction relateLine2Circle(line,circle) {\n let denim = new DE9IM();\n let ip = intersectLine2Circle(line, circle);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n denim.E2I = [circle];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [circle];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n denim.I2I = [splitShapes[1]];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon([circle.toArc()]).cutWithLine(line);\n }\n\n return denim;\n}\n\nfunction relateLine2Box(line, box) {\n let denim = new DE9IM();\n let ip = intersectLine2Box(line, box);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n\n denim.E2I = [box];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [box];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n /* Are two intersection points on the same segment of the box boundary ? */\n if (box.toSegments().some( segment => segment.contains(ip[0]) && segment.contains(ip[1]) )) {\n denim.I2I = []; // case of touching\n denim.I2B = [splitShapes[1]];\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = [box];\n }\n else { // case of intersection\n denim.I2I = [splitShapes[1]]; // [segment(ip[0], ip[1])];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon(box.toSegments()).cutWithLine(line);\n }\n }\n return denim;\n}\n\nfunction relateLine2Polygon(line, polygon) {\n let denim = new DE9IM();\n let ip = intersectLine2Polygon(line, polygon);\n let multiline = new Multiline([line]);\n let ip_sorted = ip.length > 0 ? ip.slice() : line.sortPoints(ip);\n\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n denim.E2I = polygon.cutWithLine(line);\n\n return denim;\n}\n\nfunction relateShape2Polygon(shape, polygon) {\n let denim = new DE9IM();\n let ip = intersectShape2Polygon(shape, polygon);\n let ip_sorted = ip.length > 0 ? ip.slice() : shape.sortPoints(ip);\n\n let multiline = new Multiline([shape]);\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n\n denim.B2I = [];\n denim.B2B = [];\n denim.B2E = [];\n for (let pt of [shape.start, shape.end]) {\n switch (ray_shoot(polygon, pt)) {\n case Flatten.INSIDE:\n denim.B2I.push(pt);\n break;\n case Flatten.BOUNDARY:\n denim.B2B.push(pt);\n break;\n case Flatten.OUTSIDE:\n denim.B2E.push(pt);\n break;\n }\n }\n\n // denim.E2I TODO: calculate, not clear what is expected result\n\n return denim;\n}\n\nfunction relatePolygon2Polygon(polygon1, polygon2) {\n let denim = new DE9IM();\n\n let [ip_sorted1, ip_sorted2] = calculateIntersections(polygon1, polygon2);\n let boolean_intersection = intersect$1(polygon1, polygon2);\n let boolean_difference1 = subtract(polygon1, polygon2);\n let boolean_difference2 = subtract(polygon2, polygon1);\n let [inner_clip_shapes1, inner_clip_shapes2] = innerClip(polygon1, polygon2);\n let outer_clip_shapes1 = outerClip(polygon1, polygon2);\n let outer_clip_shapes2 = outerClip(polygon2, polygon1);\n\n denim.I2I = boolean_intersection.isEmpty() ? [] : [boolean_intersection];\n denim.I2B = inner_clip_shapes2;\n denim.I2E = boolean_difference1.isEmpty() ? [] : [boolean_difference1];\n\n denim.B2I = inner_clip_shapes1;\n denim.B2B = ip_sorted1;\n denim.B2E = outer_clip_shapes1;\n\n denim.E2I = boolean_difference2.isEmpty() ? [] : [boolean_difference2];\n denim.E2B = outer_clip_shapes2;\n // denim.E2E not relevant meanwhile\n\n return denim;\n}\n\nvar Relations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n contain: contain,\n cover: cover,\n covered: covered,\n disjoint: disjoint,\n equal: equal,\n inside: inside,\n intersect: intersect,\n relate: relate,\n touch: touch\n});\n\n/**\n * Class representing an affine transformation 3x3 matrix:\n *
\n *      [ a  c  tx\n * A =    b  d  ty\n *        0  0  1  ]\n * \n     * If parameters omitted, construct identity matrix a = 1, d = 1\n     * @param {number} a - position(0,0)   sx*cos(alpha)\n     * @param {number} b - position (0,1)  sx*sin(alpha)\n     * @param {number} c - position (1,0)  -sy*sin(alpha)\n     * @param {number} d - position (1,1)  sy*cos(alpha)\n     * @param {number} tx - position (2,0) translation by x\n     * @param {number} ty - position (2,1) translation by y\n     */\n    constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) {\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.tx = tx;\n        this.ty = ty;\n    }\n\n    /**\n     * Return new cloned instance of matrix\n     * @return {Matrix}\n     **/\n    clone() {\n        return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);\n    };\n\n    /**\n     * Transform vector [x,y] using transformation matrix. 
\n * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object
\n * The result is also an abstract vector [x',y'] = A * [x,y]:\n * \n * [x' [ ax + by + tx\n * y' = cx + dy + ty\n * 1] 1 ]\n * \n * @param {number[]} vector - array[2] of numbers\n * @returns {number[]} transformation result - array[2] of numbers\n */\n transform(vector) {\n return [\n vector[0] * this.a + vector[1] * this.c + this.tx,\n vector[0] * this.b + vector[1] * this.d + this.ty\n ]\n };\n\n /**\n * Returns result of multiplication of this matrix by other matrix\n * @param {Matrix} other_matrix - matrix to multiply by\n * @returns {Matrix}\n */\n multiply(other_matrix) {\n return new Matrix(\n this.a * other_matrix.a + this.c * other_matrix.b,\n this.b * other_matrix.a + this.d * other_matrix.b,\n this.a * other_matrix.c + this.c * other_matrix.d,\n this.b * other_matrix.c + this.d * other_matrix.d,\n this.a * other_matrix.tx + this.c * other_matrix.ty + this.tx,\n this.b * other_matrix.tx + this.d * other_matrix.ty + this.ty\n )\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix(1,0,0,1,tx,ty)\n * @param {Vector} vector - Translation by vector or\n * @param {number} tx - translation by x-axis\n * @param {number} ty - translation by y-axis\n * @returns {Matrix}\n */\n translate(...args) {\n let tx, ty;\n if (args.length == 1 && !isNaN(args[0].x) && !isNaN(args[0].y)) {\n tx = args[0].x;\n ty = args[0].y;\n } else if (args.length === 2 && typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n tx = args[0];\n ty = args[1];\n } else {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n return this.multiply(new Matrix(1, 0, 0, 1, tx, ty))\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix that defines rotation by given angle (in radians) around\n * center of rotation (centerX,centerY) in counterclockwise direction\n * @param {number} angle - angle in radians\n * @param {number} centerX - center of rotation\n * @param {number} centerY - center of rotation\n * @returns {Matrix}\n */\n rotate(angle, centerX = 0.0, centerY = 0.0) {\n let cos = Math.cos(angle);\n let sin = Math.sin(angle);\n return this\n .translate(centerX, centerY)\n .multiply(new Matrix(cos, sin, -sin, cos, 0, 0))\n .translate(-centerX, -centerY);\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix (sx,0,0,sy,0,0) that defines scaling\n * @param {number} sx\n * @param {number} sy\n * @returns {Matrix}\n */\n scale(sx, sy) {\n return this.multiply(new Matrix(sx, 0, 0, sy, 0, 0));\n };\n\n /**\n * Returns true if two matrix are equal parameter by parameter\n * @param {Matrix} matrix - other matrix\n * @returns {boolean} true if equal, false otherwise\n */\n equalTo(matrix) {\n if (!Flatten.Utils.EQ(this.tx, matrix.tx)) return false;\n if (!Flatten.Utils.EQ(this.ty, matrix.ty)) return false;\n if (!Flatten.Utils.EQ(this.a, matrix.a)) return false;\n if (!Flatten.Utils.EQ(this.b, matrix.b)) return false;\n if (!Flatten.Utils.EQ(this.c, matrix.c)) return false;\n if (!Flatten.Utils.EQ(this.d, matrix.d)) return false;\n return true;\n };\n}\nFlatten.Matrix = Matrix;\n/**\n * Function to create matrix equivalent to \"new\" constructor\n * @param args\n */\nconst matrix = (...args) => new Flatten.Matrix(...args);\nFlatten.matrix = matrix;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n/**\n * Interval is a pair of numbers or a pair of any comparable objects on which may be defined predicates\n * *equal*, *less* and method *max(p1, p1)* that returns maximum in a pair.\n * When interval is an object rather than pair of numbers, this object should have properties *low*, *high*, *max*\n * and implement methods *less_than(), equal_to(), intersect(), not_intersect(), clone(), output()*.\n * Two static methods *comparable_max(), comparable_less_than()* define how to compare values in pair.
\n * This interface is described in typescript definition file *index.d.ts*\n *\n * Axis aligned rectangle is an example of such interval.\n * We may look at rectangle as an interval between its low left and top right corners.\n * See **Box** class in [flatten-js](https://github.com/alexbol99/flatten-js) library as the example\n * of Interval interface implementation\n * @type {Interval}\n */\nconst Interval = class Interval {\n /**\n * Accept two comparable values and creates new instance of interval\n * Predicate Interval.comparable_less(low, high) supposed to return true on these values\n * @param low\n * @param high\n */\n constructor(low, high) {\n this.low = low;\n this.high = high;\n }\n\n /**\n * Clone interval\n * @returns {Interval}\n */\n clone() {\n return new Interval(this.low, this.high);\n }\n\n /**\n * Propery max returns clone of this interval\n * @returns {Interval}\n */\n get max() {\n return this.clone(); // this.high;\n }\n\n /**\n * Predicate returns true is this interval less than other interval\n * @param other_interval\n * @returns {boolean}\n */\n less_than(other_interval) {\n return this.low < other_interval.low ||\n this.low == other_interval.low && this.high < other_interval.high;\n }\n\n /**\n * Predicate returns true is this interval equals to other interval\n * @param other_interval\n * @returns {boolean}\n */\n equal_to(other_interval) {\n return this.low == other_interval.low && this.high == other_interval.high;\n }\n\n /**\n * Predicate returns true if this interval intersects other interval\n * @param other_interval\n * @returns {boolean}\n */\n intersect(other_interval) {\n return !this.not_intersect(other_interval);\n }\n\n /**\n * Predicate returns true if this interval does not intersect other interval\n * @param other_interval\n * @returns {boolean}\n */\n not_intersect(other_interval) {\n return (this.high < other_interval.low || other_interval.high < this.low);\n }\n\n /**\n * Returns new interval merged with other interval\n * @param {Interval} interval - Other interval to merge with\n * @returns {Interval}\n */\n merge(other_interval) {\n return new Interval(\n this.low === undefined ? other_interval.low : Math.min(this.low, other_interval.low),\n this.high === undefined ? other_interval.high : Math.max(this.high, other_interval.high)\n );\n }\n\n /**\n * Returns how key should return\n */\n output() {\n return [this.low, this.high];\n }\n\n /**\n * Function returns maximum between two comparable values\n * @param interval1\n * @param interval2\n * @returns {Interval}\n */\n static comparable_max(interval1, interval2) {\n return interval1.merge(interval2);\n }\n\n /**\n * Predicate returns true if first value less than second value\n * @param val1\n * @param val2\n * @returns {boolean}\n */\n static comparable_less_than(val1, val2 ) {\n return val1 < val2;\n }\n};\n\n/**\n * Created by Alex Bol on 3/28/2017.\n */\n\n\n// module.exports = {\n// RB_TREE_COLOR_RED: 0,\n// RB_TREE_COLOR_BLACK: 1\n// };\n\nconst RB_TREE_COLOR_RED = 0;\nconst RB_TREE_COLOR_BLACK = 1;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n\nclass Node {\n constructor(key = undefined, value = undefined,\n left = null, right = null, parent = null, color = RB_TREE_COLOR_BLACK) {\n this.left = left; // reference to left child node\n this.right = right; // reference to right child node\n this.parent = parent; // reference to parent node\n this.color = color;\n\n this.item = {key: key, value: value}; // key is supposed to be instance of Interval\n\n /* If not, this should by an array of two numbers */\n if (key && key instanceof Array && key.length == 2) {\n if (!Number.isNaN(key[0]) && !Number.isNaN(key[1])) {\n this.item.key = new Interval(Math.min(key[0], key[1]), Math.max(key[0], key[1]));\n }\n }\n\n this.max = this.item.key ? this.item.key.max : undefined;\n }\n\n isNil() {\n return (this.item.key === undefined && this.item.value === undefined &&\n this.left === null && this.right === null && this.color === RB_TREE_COLOR_BLACK);\n }\n\n _value_less_than(other_node) {\n return this.item.value && other_node.item.value && this.item.value.less_than ?\n this.item.value.less_than(other_node.item.value) :\n this.item.value < other_node.item.value;\n }\n\n less_than(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.less_than(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.less_than(other_node.item.key) ||\n this.item.key.equal_to((other_node.item.key)) && this._value_less_than(other_node)\n }\n }\n\n _value_equal(other_node) {\n return this.item.value && other_node.item.value && this.item.value.equal_to ?\n this.item.value.equal_to(other_node.item.value) :\n this.item.value == other_node.item.value;\n }\n equal_to(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.equal_to(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.equal_to(other_node.item.key) && this._value_equal(other_node);\n }\n }\n\n intersect(other_node) {\n return this.item.key.intersect(other_node.item.key);\n }\n\n copy_data(other_node) {\n this.item.key = other_node.item.key;\n this.item.value = other_node.item.value;\n }\n\n update_max() {\n // use key (Interval) max property instead of key.high\n this.max = this.item.key ? this.item.key.max : undefined;\n if (this.right && this.right.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.right.max);\n }\n if (this.left && this.left.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.left.max);\n }\n }\n\n // Other_node does not intersect any node of left subtree, if this.left.max < other_node.item.key.low\n not_intersect_left_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let high = this.left.max.high !== undefined ? this.left.max.high : this.left.max;\n return comparable_less_than(high, search_node.item.key.low);\n }\n\n // Other_node does not intersect right subtree if other_node.item.key.high < this.right.key.low\n not_intersect_right_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let low = this.right.max.low !== undefined ? this.right.max.low : this.right.item.key.low;\n return comparable_less_than(search_node.item.key.high, low);\n }\n}\n\n/**\n * Created by Alex Bol on 3/31/2017.\n */\n\n// const nil_node = new Node();\n\n/**\n * Implementation of interval binary search tree
\n * Interval tree stores items which are couples of {key:interval, value: value}
\n * Interval is an object with high and low properties or simply pair [low,high] of numeric values
\n * @type {IntervalTree}\n */\nclass IntervalTree {\n /**\n * Construct new empty instance of IntervalTree\n */\n constructor() {\n this.root = null;\n this.nil_node = new Node();\n }\n\n /**\n * Returns number of items stored in the interval tree\n * @returns {number}\n */\n get size() {\n let count = 0;\n this.tree_walk(this.root, () => count++);\n return count;\n }\n\n /**\n * Returns array of sorted keys in the ascending order\n * @returns {Array}\n */\n get keys() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(\n node.item.key.output ? node.item.key.output() : node.item.key\n ));\n return res;\n }\n\n /**\n * Return array of values in the ascending keys order\n * @returns {Array}\n */\n get values() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(node.item.value));\n return res;\n }\n\n /**\n * Returns array of items ( pairs) in the ascended keys order\n * @returns {Array}\n */\n get items() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push({\n key: node.item.key.output ? node.item.key.output() : node.item.key,\n value: node.item.value\n }));\n return res;\n }\n\n /**\n * Returns true if tree is empty\n * @returns {boolean}\n */\n isEmpty() {\n return (this.root == null || this.root == this.nil_node);\n }\n\n /**\n * Clear tree\n */\n clear() {\n this.root = null;\n }\n\n /**\n * Insert new item into interval tree\n * @param {Interval} key - interval object or array of two numbers [low, high]\n * @param {any} value - value representing any object (optional)\n * @returns {Node} returns reference to inserted node as an object {key:interval, value: value}\n */\n insert(key, value = key) {\n if (key === undefined) return;\n let insert_node = new Node(key, value, this.nil_node, this.nil_node, null, RB_TREE_COLOR_RED);\n this.tree_insert(insert_node);\n this.recalc_max(insert_node);\n return insert_node;\n }\n\n /**\n * Returns true if item {key,value} exist in the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object to be checked\n * @returns {boolean} true if item {key, value} exist in the tree, false otherwise\n */\n exist(key, value = key) {\n let search_node = new Node(key, value);\n return this.tree_search(this.root, search_node) ? true : false;\n }\n\n /**\n * Remove entry {key, value} from the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object\n * @returns {boolean} true if item {key, value} deleted, false if not found\n */\n remove(key, value = key) {\n let search_node = new Node(key, value);\n let delete_node = this.tree_search(this.root, search_node);\n if (delete_node) {\n this.tree_delete(delete_node);\n }\n return delete_node;\n }\n\n /**\n * Returns array of entry values which keys intersect with given interval
\n * If no values stored in the tree, returns array of keys which intersect given interval\n * @param {Interval} interval - search interval, or tuple [low, high]\n * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output\n * @returns {Array}\n */\n search(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {\n let search_node = new Node(interval);\n let resp_nodes = [];\n this.tree_search_interval(this.root, search_node, resp_nodes);\n return resp_nodes.map(node => outputMapperFn(node.item.value, node.item.key))\n }\n\n /**\n * Returns true if intersection between given and any interval stored in the tree found\n * @param {Interval} interval - search interval or tuple [low, high]\n * @returns {boolean}\n */\n intersect_any(interval) {\n let search_node = new Node(interval);\n let found = this.tree_find_any_interval(this.root, search_node);\n return found;\n }\n\n /**\n * Tree visitor. For each node implement a callback function.
\n * Method calls a callback function with two parameters (key, value)\n * @param visitor(key,value) - function to be called for each tree item\n */\n forEach(visitor) {\n this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));\n }\n\n /** Value Mapper. Walk through every node and map node value to another value\n * @param callback(value,key) - function to be called for each tree item\n */\n map(callback) {\n const tree = new IntervalTree();\n this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));\n return tree;\n }\n\n recalc_max(node) {\n let node_current = node;\n while (node_current.parent != null) {\n node_current.parent.update_max();\n node_current = node_current.parent;\n }\n }\n\n tree_insert(insert_node) {\n let current_node = this.root;\n let parent_node = null;\n\n if (this.root == null || this.root == this.nil_node) {\n this.root = insert_node;\n }\n else {\n while (current_node != this.nil_node) {\n parent_node = current_node;\n if (insert_node.less_than(current_node)) {\n current_node = current_node.left;\n }\n else {\n current_node = current_node.right;\n }\n }\n\n insert_node.parent = parent_node;\n\n if (insert_node.less_than(parent_node)) {\n parent_node.left = insert_node;\n }\n else {\n parent_node.right = insert_node;\n }\n }\n\n this.insert_fixup(insert_node);\n }\n\n// After insertion insert_node may have red-colored parent, and this is a single possible violation\n// Go upwords to the root and re-color until violation will be resolved\n insert_fixup(insert_node) {\n let current_node;\n let uncle_node;\n\n current_node = insert_node;\n while (current_node != this.root && current_node.parent.color == RB_TREE_COLOR_RED) {\n if (current_node.parent == current_node.parent.parent.left) { // parent is left child of grandfather\n uncle_node = current_node.parent.parent.right; // right brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 1. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else { // Case 2 & 3. Uncle is black\n if (current_node == current_node.parent.right) { // Case 2. Current if right child\n // This case is transformed into Case 3.\n current_node = current_node.parent;\n this.rotate_left(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 3. Current is left child.\n // Re-color father and grandfather, rotate grandfather right\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_right(current_node.parent.parent);\n }\n }\n else { // parent is right child of grandfather\n uncle_node = current_node.parent.parent.left; // left brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 4. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else {\n if (current_node == current_node.parent.left) { // Case 5. Current is left child\n // Transform into case 6\n current_node = current_node.parent;\n this.rotate_right(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 6. Current is right child.\n // Re-color father and grandfather, rotate grandfather left\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_left(current_node.parent.parent);\n }\n }\n }\n\n this.root.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_delete(delete_node) {\n let cut_node; // node to be cut - either delete_node or successor_node (\"y\" from 14.4)\n let fix_node; // node to fix rb tree property (\"x\" from 14.4)\n\n if (delete_node.left == this.nil_node || delete_node.right == this.nil_node) { // delete_node has less then 2 children\n cut_node = delete_node;\n }\n else { // delete_node has 2 children\n cut_node = this.tree_successor(delete_node);\n }\n\n // fix_node if single child of cut_node\n if (cut_node.left != this.nil_node) {\n fix_node = cut_node.left;\n }\n else {\n fix_node = cut_node.right;\n }\n\n // remove cut_node from parent\n /*if (fix_node != this.nil_node) {*/\n fix_node.parent = cut_node.parent;\n /*}*/\n\n if (cut_node == this.root) {\n this.root = fix_node;\n }\n else {\n if (cut_node == cut_node.parent.left) {\n cut_node.parent.left = fix_node;\n }\n else {\n cut_node.parent.right = fix_node;\n }\n cut_node.parent.update_max(); // update max property of the parent\n }\n\n this.recalc_max(fix_node); // update max property upward from fix_node to root\n\n // COPY DATA !!!\n // Delete_node becomes cut_node, it means that we cannot hold reference\n // to node in outer structure and we will have to delete by key, additional search need\n if (cut_node != delete_node) {\n delete_node.copy_data(cut_node);\n delete_node.update_max(); // update max property of the cut node at the new place\n this.recalc_max(delete_node); // update max property upward from delete_node to root\n }\n\n if (/*fix_node != this.nil_node && */cut_node.color == RB_TREE_COLOR_BLACK) {\n this.delete_fixup(fix_node);\n }\n }\n\n delete_fixup(fix_node) {\n let current_node = fix_node;\n let brother_node;\n\n while (current_node != this.root && current_node.parent != null && current_node.color == RB_TREE_COLOR_BLACK) {\n if (current_node == current_node.parent.left) { // fix node is left child\n brother_node = current_node.parent.right;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_left(current_node.parent);\n brother_node = current_node.parent.right; // update brother\n }\n // Derive to cases 2..4: brother is black\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2: both nephews black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 3: left nephew red, right nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.left.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_right(brother_node);\n brother_node = current_node.parent.right; // update brother\n // Derive to case 4: left nephew black, right nephew red\n }\n // case 4: left nephew black, right nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.right.color = RB_TREE_COLOR_BLACK;\n this.rotate_left(current_node.parent);\n current_node = this.root; // exit from loop\n }\n }\n else { // fix node is right child\n brother_node = current_node.parent.left;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_right(current_node.parent);\n brother_node = current_node.parent.left; // update brother\n }\n // Go to cases 2..4\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.left.color == RB_TREE_COLOR_BLACK) { // case 3: right nephew red, left nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.right.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_left(brother_node);\n brother_node = current_node.parent.left; // update brother\n // Derive to case 4: right nephew black, left nephew red\n }\n // case 4: right nephew black, left nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.left.color = RB_TREE_COLOR_BLACK;\n this.rotate_right(current_node.parent);\n current_node = this.root; // force exit from loop\n }\n }\n }\n\n current_node.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_search(node, search_node) {\n if (node == null || node == this.nil_node)\n return undefined;\n\n if (search_node.equal_to(node)) {\n return node;\n }\n if (search_node.less_than(node)) {\n return this.tree_search(node.left, search_node);\n }\n else {\n return this.tree_search(node.right, search_node);\n }\n }\n\n // Original search_interval method; container res support push() insertion\n // Search all intervals intersecting given one\n tree_search_interval(node, search_node, res) {\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n this.tree_search_interval(node.left, search_node, res);\n }\n // if (low <= node->high && node->low <= high) {\n if (node.intersect(search_node)) {\n res.push(node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n this.tree_search_interval(node.right, search_node, res);\n }\n }\n }\n\n tree_find_any_interval(node, search_node) {\n let found = false;\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n found = this.tree_find_any_interval(node.left, search_node);\n }\n // if (low <= node->high && node->low <= high) {\n if (!found) {\n found = node.intersect(search_node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (!found && node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n found = this.tree_find_any_interval(node.right, search_node);\n }\n }\n return found;\n }\n\n local_minimum(node) {\n let node_min = node;\n while (node_min.left != null && node_min.left != this.nil_node) {\n node_min = node_min.left;\n }\n return node_min;\n }\n\n // not in use\n local_maximum(node) {\n let node_max = node;\n while (node_max.right != null && node_max.right != this.nil_node) {\n node_max = node_max.right;\n }\n return node_max;\n }\n\n tree_successor(node) {\n let node_successor;\n let current_node;\n let parent_node;\n\n if (node.right != this.nil_node) {\n node_successor = this.local_minimum(node.right);\n }\n else {\n current_node = node;\n parent_node = node.parent;\n while (parent_node != null && parent_node.right == current_node) {\n current_node = parent_node;\n parent_node = parent_node.parent;\n }\n node_successor = parent_node;\n }\n return node_successor;\n }\n\n // | right-rotate(T,y) |\n // y ---------------. x\n // / \\ / \\\n // x c left-rotate(T,x) a y\n // / \\ <--------------- / \\\n // a b b c\n\n rotate_left(x) {\n let y = x.right;\n\n x.right = y.left; // b goes to x.right\n\n if (y.left != this.nil_node) {\n y.left.parent = x; // x becomes parent of b\n }\n y.parent = x.parent; // move parent\n\n if (x == this.root) {\n this.root = y; // y becomes root\n }\n else { // y becomes child of x.parent\n if (x == x.parent.left) {\n x.parent.left = y;\n }\n else {\n x.parent.right = y;\n }\n }\n y.left = x; // x becomes left child of y\n x.parent = y; // and y becomes parent of x\n\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n\n y = x.parent;\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n }\n\n rotate_right(y) {\n let x = y.left;\n\n y.left = x.right; // b goes to y.left\n\n if (x.right != this.nil_node) {\n x.right.parent = y; // y becomes parent of b\n }\n x.parent = y.parent; // move parent\n\n if (y == this.root) { // x becomes root\n this.root = x;\n }\n else { // y becomes child of x.parent\n if (y == y.parent.left) {\n y.parent.left = x;\n }\n else {\n y.parent.right = x;\n }\n }\n x.right = y; // y becomes right child of x\n y.parent = x; // and x becomes parent of y\n\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n\n x = y.parent;\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n }\n\n tree_walk(node, action) {\n if (node != null && node != this.nil_node) {\n this.tree_walk(node.left, action);\n // arr.push(node.toArray());\n action(node);\n this.tree_walk(node.right, action);\n }\n }\n\n /* Return true if all red nodes have exactly two black child nodes */\n testRedBlackProperty() {\n let res = true;\n this.tree_walk(this.root, function (node) {\n if (node.color == RB_TREE_COLOR_RED) {\n if (!(node.left.color == RB_TREE_COLOR_BLACK && node.right.color == RB_TREE_COLOR_BLACK)) {\n res = false;\n }\n }\n });\n return res;\n }\n\n /* Throw error if not every path from root to bottom has same black height */\n testBlackHeightProperty(node) {\n let height = 0;\n let heightLeft = 0;\n let heightRight = 0;\n if (node.color == RB_TREE_COLOR_BLACK) {\n height++;\n }\n if (node.left != this.nil_node) {\n heightLeft = this.testBlackHeightProperty(node.left);\n }\n else {\n heightLeft = 1;\n }\n if (node.right != this.nil_node) {\n heightRight = this.testBlackHeightProperty(node.right);\n }\n else {\n heightRight = 1;\n }\n if (heightLeft != heightRight) {\n throw new Error('Red-black height property violated');\n }\n height += heightLeft;\n return height;\n };\n}\n\n/**\n * Created by Alex Bol on 3/12/2017.\n */\n\n\n/**\n * Class representing a planar set - a generic container with ability to keep and retrieve shapes and\n * perform spatial queries. Planar set is an extension of Set container, so it supports\n * Set properties and methods\n */\nclass PlanarSet extends Set {\n /**\n * Create new instance of PlanarSet\n * @param shapes - array or set of geometric objects to store in planar set\n * Each object should have a box property\n */\n constructor(shapes) {\n super(shapes);\n this.index = new IntervalTree();\n this.forEach(shape => this.index.insert(shape));\n }\n\n /**\n * Add new shape to planar set and to its spatial index.
\n * If shape already exist, it will not be added again.\n * This happens with no error, it is possible to use size property to check if\n * a shape was actually added.
\n * Method returns planar set object updated and may be chained\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property\n * Another option to transfer as an object {key: Box, value: AnyShape}\n * @returns {PlanarSet}\n */\n add(entry) {\n let size = this.size;\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n super.add(shape);\n // size not changed - item not added, probably trying to add same item twice\n if (this.size > size) {\n this.index.insert(box, shape);\n }\n return this; // in accordance to Set.add interface\n }\n\n /**\n * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted\n * @returns {boolean}\n */\n delete(entry) {\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n let deleted = super.delete(shape);\n if (deleted) {\n this.index.remove(box, shape);\n }\n return deleted;\n }\n\n /**\n * Clear planar set\n */\n clear() {\n super.clear();\n this.index = new IntervalTree();\n }\n\n /**\n * 2d range search in planar set.
\n * Returns array of all shapes in planar set which bounding box is intersected with query box\n * @param {Box} box - query box\n * @returns {AnyShape[]}\n */\n search(box) {\n let resp = this.index.search(box);\n return resp;\n }\n\n /**\n * Point location test. Returns array of shapes which contains given point\n * @param {Point} point - query point\n * @returns {AnyShape[]}\n */\n hit(point) {\n let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);\n let resp = this.index.search(box);\n return resp.filter((shape) => point.on(shape));\n }\n\n /**\n * Returns svg string to draw all shapes in planar set\n * @returns {String}\n */\n svg() {\n let svgcontent = [...this].reduce((acc, shape) => acc + shape.svg(), \"\");\n return svgcontent;\n }\n}\n\nFlatten.PlanarSet = PlanarSet;\n\n/**\n * Base class representing shape\n * Implement common methods of affine transformations\n */\nclass Shape {\n get name() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n get box() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n clone() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * Returns new shape translated by given vector.\n * Translation vector may be also defined by a pair of numbers.\n * @param {Vector | (number, number) } args - Translation vector\n * or tuple of numbers\n * @returns {Shape}\n */\n translate(...args) {\n return this.transform(new Matrix().translate(...args))\n }\n\n /**\n * Returns new shape rotated by given angle around given center point.\n * If center point is omitted, rotates around zero point (0,0).\n * Positive value of angle defines rotation in counterclockwise direction,\n * negative angle defines rotation in clockwise direction\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n * @returns {Shape}\n */\n rotate(angle, center = new Flatten.Point()) {\n return this.transform(new Matrix().rotate(angle, center.x, center.y));\n }\n\n /**\n * Return new shape with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Shape}\n */\n scale(sx, sy) {\n return this.transform(new Matrix().scale(sx, sy));\n }\n\n transform(...args) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return Object.assign({}, this, {name: this.name});\n }\n\n svg(attrs = {}) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n}\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\n/**\n *\n * Class representing a point\n * @type {Point}\n */\nlet Point$1 = class Point extends Shape {\n /**\n * Point may be constructed by two numbers, or by array of two numbers\n * @param {number} x - x-coordinate (float number)\n * @param {number} y - y-coordinate (float number)\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate (float number)\n * @type {number}\n */\n this.y = 0;\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"point\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n if (typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n this.x = args[0];\n this.y = args[1];\n return;\n }\n }\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Returns bounding box of a point\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(this.x, this.y, this.x, this.y);\n }\n\n /**\n * Return new cloned instance of point\n * @returns {Point}\n */\n clone() {\n return new Flatten.Point(this.x, this.y);\n }\n\n get vertices() {\n return [this.clone()];\n }\n\n /**\n * Returns true if points are equal up to [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n equalTo(pt) {\n return Flatten.Utils.EQ(this.x, pt.x) && Flatten.Utils.EQ(this.y, pt.y);\n }\n\n /**\n * Defines predicate \"less than\" between points. Returns true if the point is less than query points, false otherwise
\n * By definition point1 < point2 if {point1.y < point2.y || point1.y == point2.y && point1.x < point2.x
\n * Numeric values compared with [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n lessThan(pt) {\n if (Flatten.Utils.LT(this.y, pt.y))\n return true;\n if (Flatten.Utils.EQ(this.y, pt.y) && Flatten.Utils.LT(this.x, pt.x))\n return true;\n return false;\n }\n\n /**\n * Return new point transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Point}\n */\n transform(m) {\n return new Flatten.Point(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns projection point on given line\n * @param {Line} line Line this point be projected on\n * @returns {Point}\n */\n projectionOn(line) {\n if (this.equalTo(line.pt)) // this point equal to line anchor point\n return this.clone();\n\n let vec = new Flatten.Vector(this, line.pt);\n if (Flatten.Utils.EQ_0(vec.cross(line.norm))) // vector to point from anchor point collinear to normal vector\n return line.pt.clone();\n\n let dist = vec.dot(line.norm); // signed distance\n let proj_vec = line.norm.multiply(dist);\n return this.translate(proj_vec);\n }\n\n /**\n * Returns true if point belongs to the \"left\" semi-plane, which means, point belongs to the same semi plane where line normal vector points to\n * Return false if point belongs to the \"right\" semi-plane or to the line itself\n * @param {Line} line Query line\n * @returns {boolean}\n */\n leftTo(line) {\n let vec = new Flatten.Vector(line.pt, this);\n let onLeftSemiPlane = Flatten.Utils.GT(vec.dot(line.norm), 0);\n return onLeftSemiPlane;\n }\n\n /**\n * Calculate distance and shortest segment from point to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from point to shape\n * @returns {Segment} shortest segment between point and shape (started at point, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Point) {\n let dx = shape.x - this.x;\n let dy = shape.y - this.y;\n return [Math.sqrt(dx * dx + dy * dy), new Flatten.Segment(this, shape)];\n }\n\n if (shape instanceof Flatten.Line) {\n return Flatten.Distance.point2line(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return Flatten.Distance.point2circle(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Distance.point2segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return Flatten.Distance.point2arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return Flatten.Distance.point2polygon(this, shape);\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n return Flatten.Distance.shape2planarSet(this, shape);\n }\n }\n\n /**\n * Returns true if point is on a shape, false otherwise\n * @param {Shape} shape\n * @returns {boolean}\n */\n on(shape) {\n if (shape instanceof Flatten.Point) {\n return this.equalTo(shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Line) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return shape.contains(this)\n }\n\n if (shape instanceof Flatten.Circle) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return shape.contains(this);\n }\n }\n\n get name() {\n return \"point\"\n }\n\n /**\n * Return string to draw point in svg as circle with radius \"r\"
\n * Accept any valid attributes of svg elements as svg object\n * Defaults attribues are:
\n * {\n * r:\"3\",\n * stroke:\"black\",\n * strokeWidth:\"1\",\n * fill:\"red\"\n * }\n * @param {Object} attrs - Any valid attributes of svg circle element, like \"r\", \"stroke\", \"strokeWidth\", \"fill\"\n * @returns {String}\n */\n svg(attrs = {}) {\n const r = attrs.r ?? 3; // default radius - 3\n return `\\n`;\n }\n};\n\nFlatten.Point = Point$1;\n/**\n * Function to create point equivalent to \"new\" constructor\n * @param args\n */\nconst point = (...args) => new Flatten.Point(...args);\nFlatten.point = point;\n\n// export {Point};\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class representing a vector\n * @type {Vector}\n */\nlet Vector$1 = class Vector extends Shape {\n /**\n * Vector may be constructed by two points, or by two float numbers,\n * or by array of two numbers\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate of a vector (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate of a vector (float number)\n * @type {number}\n */\n this.y = 0;\n\n /* return zero vector */\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"vector\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (typeof (a1) == \"number\" && typeof (a2) == \"number\") {\n this.x = a1;\n this.y = a2;\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.x = a2.x - a1.x;\n this.y = a2.y - a1.y;\n return;\n }\n\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Method clone returns new instance of Vector\n * @returns {Vector}\n */\n clone() {\n return new Flatten.Vector(this.x, this.y);\n }\n\n /**\n * Slope of the vector in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let angle = Math.atan2(this.y, this.x);\n if (angle < 0) angle = 2 * Math.PI + angle;\n return angle;\n }\n\n /**\n * Length of vector\n * @returns {number}\n */\n get length() {\n return Math.sqrt(this.dot(this));\n }\n\n /**\n * Returns true if vectors are equal up to [DP_TOL]{@link http://localhost:63342/flatten-js/docs/global.html#DP_TOL}\n * tolerance\n * @param {Vector} v\n * @returns {boolean}\n */\n equalTo(v) {\n return Flatten.Utils.EQ(this.x, v.x) && Flatten.Utils.EQ(this.y, v.y);\n }\n\n /**\n * Returns new vector multiplied by scalar\n * @param {number} scalar\n * @returns {Vector}\n */\n multiply(scalar) {\n return (new Flatten.Vector(scalar * this.x, scalar * this.y));\n }\n\n /**\n * Returns scalar product (dot product) of two vectors
\n * dot_product = (this * v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n dot(v) {\n return (this.x * v.x + this.y * v.y);\n }\n\n /**\n * Returns vector product (cross product) of two vectors
\n * cross_product = (this x v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n cross(v) {\n return (this.x * v.y - this.y * v.x);\n }\n\n /**\n * Returns unit vector.
\n * Throw error if given vector has zero length\n * @returns {Vector}\n */\n normalize() {\n if (!Flatten.Utils.EQ_0(this.length)) {\n return (new Flatten.Vector(this.x / this.length, this.y / this.length));\n }\n throw Errors.ZERO_DIVISION;\n }\n\n /**\n * Returns new vector rotated by given angle,\n * positive angle defines rotation in counterclockwise direction,\n * negative - in clockwise direction\n * Vector only can be rotated around (0,0) point!\n * @param {number} angle - Angle in radians\n * @returns {Vector}\n */\n rotate(angle, center = new Flatten.Point()) {\n if (center.x === 0 && center.y === 0) {\n return this.transform(new Matrix().rotate(angle));\n }\n throw(Errors.OPERATION_IS_NOT_SUPPORTED);\n }\n\n /**\n * Return new vector transformed by affine transformation matrix m\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Vector}\n */\n transform(m) {\n return new Flatten.Vector(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns vector rotated 90 degrees counterclockwise\n * @returns {Vector}\n */\n rotate90CCW() {\n return new Flatten.Vector(-this.y, this.x);\n };\n\n /**\n * Returns vector rotated 90 degrees clockwise\n * @returns {Vector}\n */\n rotate90CW() {\n return new Flatten.Vector(this.y, -this.x);\n };\n\n /**\n * Return inverted vector\n * @returns {Vector}\n */\n invert() {\n return new Flatten.Vector(-this.x, -this.y);\n }\n\n /**\n * Return result of addition of other vector to this vector as a new vector\n * @param {Vector} v Other vector\n * @returns {Vector}\n */\n add(v) {\n return new Flatten.Vector(this.x + v.x, this.y + v.y);\n }\n\n /**\n * Return result of subtraction of other vector from current vector as a new vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n subtract(v) {\n return new Flatten.Vector(this.x - v.x, this.y - v.y);\n }\n\n /**\n * Return angle between this vector and other vector.
\n * Angle is measured from 0 to 2*PI in the counterclockwise direction\n * from current vector to another.\n * @param {Vector} v Another vector\n * @returns {number}\n */\n angleTo(v) {\n let norm1 = this.normalize();\n let norm2 = v.normalize();\n let angle = Math.atan2(norm1.cross(norm2), norm1.dot(norm2));\n if (angle < 0) angle += 2 * Math.PI;\n return angle;\n }\n\n /**\n * Return vector projection of the current vector on another vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n projectionOn(v) {\n let n = v.normalize();\n let d = this.dot(n);\n return n.multiply(d);\n }\n\n get name() {\n return \"vector\"\n }\n};\n\nFlatten.Vector = Vector$1;\n\n/**\n * Function to create vector equivalent to \"new\" constructor\n * @param args\n */\nconst vector$1 = (...args) => new Flatten.Vector(...args);\nFlatten.vector = vector$1;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a segment\n * @type {Segment}\n */\nclass Segment extends Shape {\n /**\n *\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * Start point\n * @type {Point}\n */\n this.ps = new Flatten.Point();\n /**\n * End Point\n * @type {Point}\n */\n this.pe = new Flatten.Point();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 4) {\n let coords = args[0];\n this.ps = new Flatten.Point(coords[0], coords[1]);\n this.pe = new Flatten.Point(coords[2], coords[3]);\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"segment\") {\n let {ps, pe} = args[0];\n this.ps = new Flatten.Point(ps.x, ps.y);\n this.pe = new Flatten.Point(pe.x, pe.y);\n return;\n }\n\n // second point omitted issue #84\n if (args.length === 1 && args[0] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n return;\n }\n\n if (args.length === 2 && args[0] instanceof Flatten.Point && args[1] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n this.pe = args[1].clone();\n return;\n }\n\n if (args.length === 4) {\n this.ps = new Flatten.Point(args[0], args[1]);\n this.pe = new Flatten.Point(args[2], args[3]);\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of segment\n * @returns {Segment}\n */\n clone() {\n return new Flatten.Segment(this.start, this.end);\n }\n\n /**\n * Start point\n * @returns {Point}\n */\n get start() {\n return this.ps;\n }\n\n /**\n * End point\n * @returns {Point}\n */\n get end() {\n return this.pe;\n }\n\n\n /**\n * Returns array of start and end point\n * @returns [Point,Point]\n */\n get vertices() {\n return [this.ps.clone(), this.pe.clone()];\n }\n\n /**\n * Length of a segment\n * @returns {number}\n */\n get length() {\n return this.start.distanceTo(this.end)[0];\n }\n\n /**\n * Slope of the line - angle to axe x in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.slope;\n }\n\n /**\n * Bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Math.min(this.start.x, this.end.x),\n Math.min(this.start.y, this.end.y),\n Math.max(this.start.x, this.end.x),\n Math.max(this.start.y, this.end.y)\n )\n }\n\n /**\n * Returns true if equals to query segment, false otherwise\n * @param {Seg} seg - query segment\n * @returns {boolean}\n */\n equalTo(seg) {\n return this.ps.equalTo(seg.ps) && this.pe.equalTo(seg.pe);\n }\n\n /**\n * Returns true if segment contains point\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n return Flatten.Utils.EQ_0(this.distanceToPoint(pt));\n }\n\n /**\n * Returns array of intersection points between segment and other shape\n * @param {Shape} shape - Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectSegment2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Segment(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectSegment2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectSegment2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectSegment2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectSegment2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from segment to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from segment to shape\n * @returns {Segment} shortest segment between segment and shape (started at segment, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2segment(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.segment2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.segment2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2segment(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Returns unit vector in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.normalize();\n }\n\n /**\n * Return unit vector in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.end, this.start);\n return vec.normalize();\n }\n\n /**\n * Returns new segment with swapped start and end points\n * @returns {Segment}\n */\n reverse() {\n return new Segment(this.end, this.start);\n }\n\n /**\n * When point belongs to segment, return array of two segments split by given point,\n * if point is inside segment. Returns clone of this segment if query point is incident\n * to start or end point of the segment. Returns empty array if point does not belong to segment\n * @param {Point} pt Query point\n * @returns {Segment[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n return [\n new Flatten.Segment(this.start, pt),\n new Flatten.Segment(pt, this.end)\n ]\n }\n\n /**\n * Return middle point of the segment\n * @returns {Point}\n */\n middle() {\n return new Flatten.Point((this.start.x + this.end.x) / 2, (this.start.y + this.end.y) / 2);\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the segment\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length == 0) return this.start;\n if (length == this.length) return this.end;\n let factor = length / this.length;\n return new Flatten.Point(\n (this.end.x - this.start.x) * factor + this.start.x,\n (this.end.y - this.start.y) * factor + this.start.y\n );\n }\n\n distanceToPoint(pt) {\n let [dist, ...rest] = Flatten.Distance.point2segment(pt, this);\n return dist;\n };\n\n definiteIntegral(ymin = 0.0) {\n let dx = this.end.x - this.start.x;\n let dy1 = this.start.y - ymin;\n let dy2 = this.end.y - ymin;\n return (dx * (dy1 + dy2) / 2);\n }\n\n /**\n * Return new segment transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Segment} - transformed segment\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Segment(this.ps.transform(matrix), this.pe.transform(matrix))\n }\n\n /**\n * Returns true if segment start is equal to segment end up to DP_TOL\n * @returns {boolean}\n */\n isZeroLength() {\n return this.ps.equalTo(this.pe)\n }\n\n /**\n * Sort given array of points from segment start to end, assuming all points lay on the segment\n * @param {Point[]} - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let line = new Flatten.Line(this.start, this.end);\n return line.sortPoints(pts);\n }\n\n get name() {\n return \"segment\"\n }\n\n /**\n * Return string to draw segment in svg\n * @param {Object} attrs - an object with attributes for svg path element,\n * like \"stroke\", \"strokeWidth\"
\n * Defaults are stroke:\"black\", strokeWidth:\"1\"\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n}\n\nFlatten.Segment = Segment;\n/**\n * Shortcut method to create new segment\n */\nconst segment = (...args) => new Flatten.Segment(...args);\nFlatten.segment = segment;\n\n/**\n * Created by Alex Bol on 2/20/2017.\n */\n\nlet {vector} = Flatten;\n\n/**\n * Class representing a line\n * @type {Line}\n */\nlet Line$1 = class Line extends Shape {\n /**\n * Line may be constructed by point and normal vector or by two points that a line passes through\n * @param {Point} pt - point that a line passes through\n * @param {Vector|Point} norm - normal vector to a line or second point a line passes through\n */\n constructor(...args) {\n super();\n /**\n * Point a line passes through\n * @type {Point}\n */\n this.pt = new Flatten.Point();\n /**\n * Normal vector to a line
\n * Vector is normalized (length == 1)
\n * Direction of the vector is chosen to satisfy inequality norm * p >= 0\n * @type {Vector}\n */\n this.norm = new Flatten.Vector(0, 1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"line\") {\n let {pt, norm} = args[0];\n this.pt = new Flatten.Point(pt);\n this.norm = new Flatten.Vector(norm);\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.pt = a1;\n this.norm = Line.points2norm(a1, a2);\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Vector) {\n if (Flatten.Utils.EQ_0(a2.x) && Flatten.Utils.EQ_0(a2.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a1.clone();\n this.norm = a2.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Vector && a2 instanceof Flatten.Point) {\n if (Flatten.Utils.EQ_0(a1.x) && Flatten.Utils.EQ_0(a1.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a2.clone();\n this.norm = a1.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of line\n * @returns {Line}\n */\n clone() {\n return new Flatten.Line(this.pt, this.norm);\n }\n\n /* The following methods need for implementation of Edge interface\n /**\n * Line has no start point\n * @returns {undefined}\n */\n get start() {return undefined;}\n\n /**\n * Line has no end point\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns infinite box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Middle point is undefined\n * @returns {undefined}\n */\n get middle() {return undefined}\n\n /**\n * Slope of the line - angle in radians between line and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Get coefficients [A,B,C] of a standard line equation in the form Ax + By = C\n * @code [A, B, C] = line.standard\n * @returns {number[]} - array of coefficients\n */\n get standard() {\n let A = this.norm.x;\n let B = this.norm.y;\n let C = this.norm.dot(vector(this.pt.x, this.pt.y));\n\n return [A, B, C];\n }\n\n /**\n * Return true if parallel or incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n parallelTo(other_line) {\n return Flatten.Utils.EQ_0(this.norm.cross(other_line.norm));\n }\n\n /**\n * Returns true if incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n incidentTo(other_line) {\n return this.parallelTo(other_line) && this.pt.on(other_line);\n }\n\n /**\n * Returns true if point belongs to line\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Line contains point if vector to point is orthogonal to the line normal vector */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec));\n }\n\n /**\n * Return coordinate of the point that lies on the line in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the line and does not check it\n * @param {Point} pt - point on a line\n * @returns {number}\n */\n coord(pt) {\n return vector(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Returns array of intersection points\n * @param {Shape} shape - shape to intersect with\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectLine2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectLine2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectLine2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectLine2Polygon(this, shape);\n }\n\n }\n\n /**\n * Calculate distance and shortest segment from line to shape and returns array [distance, shortest_segment]\n * @param {Shape} shape Shape of the one of the types Point, Circle, Segment, Arc, Polygon\n * @returns {[number, Segment]}\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n }\n\n /**\n * Split line with a point or array of points and return array of shapes\n * Assumed (but not checked) that all points lay on the line\n * @param {Point | Point[]} pt\n * @returns {MultilineShapes}\n */\n split(pt) {\n if (pt instanceof Flatten.Point) {\n return [new Flatten.Ray(pt, this.norm), new Flatten.Ray(pt, this.norm)]\n }\n else {\n let multiline = new Flatten.Multiline([this]);\n let sorted_points = this.sortPoints(pt);\n multiline.split(sorted_points);\n return multiline.toShapes();\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Line(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new line transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Line}\n */\n transform(m) {\n return new Flatten.Line(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n /**\n * Sort given array of points that lay on a line with respect to coordinate on a line\n * The method assumes that points lay on the line and does not check this\n * @param {Point[]} pts - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n return pts.slice().sort( (pt1, pt2) => {\n if (this.coord(pt1) < this.coord(pt2)) {\n return -1;\n }\n if (this.coord(pt1) > this.coord(pt2)) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"line\"\n }\n\n /**\n * Return string to draw svg segment representing line inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg circle element\n */\n svg(box, attrs = {}) {\n let ip = intersectLine2Box(this, box);\n if (ip.length === 0)\n return \"\";\n let ps = ip[0];\n let pe = ip.length === 2 ? ip[1] : ip.find(pt => !pt.equalTo(ps));\n if (pe === undefined) pe = ps;\n let segment = new Flatten.Segment(ps, pe);\n return segment.svg(attrs);\n }\n\n static points2norm(pt1, pt2) {\n if (pt1.equalTo(pt2)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n let vec = new Flatten.Vector(pt1, pt2);\n let unit = vec.normalize();\n return unit.rotate90CCW();\n }\n};\n\nFlatten.Line = Line$1;\n/**\n * Function to create line equivalent to \"new\" constructor\n * @param args\n */\nconst line = (...args) => new Flatten.Line(...args);\nFlatten.line = line;\n\n/**\n * Created by Alex Bol on 3/6/2017.\n */\n\n\n/**\n * Class representing a circle\n * @type {Circle}\n */\nlet Circle$1 = class Circle extends Shape {\n /**\n * Class private property\n * @type {string}\n */\n\n /**\n *\n * @param {Point} pc - circle center point\n * @param {number} r - circle radius\n */\n constructor(...args) {\n super();\n /**\n * Circle center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Circle radius\n * @type {number}\n */\n this.r = 1;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"circle\") {\n let {pc, r} = args[0];\n this.pc = new Flatten.Point(pc);\n this.r = r;\n } else {\n let [pc, r] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n }\n // throw Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of circle\n * @returns {Circle}\n */\n clone() {\n return new Flatten.Circle(this.pc.clone(), this.r);\n }\n\n /**\n * Circle center\n * @returns {Point}\n */\n get center() {\n return this.pc;\n }\n\n /**\n * Circle bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n this.pc.x - this.r,\n this.pc.y - this.r,\n this.pc.x + this.r,\n this.pc.y + this.r\n );\n }\n\n /**\n * Return true if circle contains shape: no point of shape lies outside of the circle\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return Flatten.Utils.LE(shape.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Arc) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.r, this.r) &&\n Flatten.Utils.LE(shape.center.distanceTo(this.center)[0], this.r);\n }\n\n /* TODO: box, polygon */\n }\n\n /**\n * Transform circle to closed arc\n * @param {boolean} counterclockwise\n * @returns {Arc}\n */\n toArc(counterclockwise = true) {\n return new Flatten.Arc(this.center, this.r, Math.PI, -Math.PI, counterclockwise);\n }\n\n /**\n * Method scale is supported only for uniform scaling of the circle with (0,0) center\n * @param {number} sx\n * @param {number} sy\n * @returns {Circle}\n */\n scale(sx, sy) {\n if (sx !== sy)\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n if (!(this.pc.x === 0.0 && this.pc.y === 0.0))\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n return new Flatten.Circle(this.pc, this.r*sx)\n }\n\n /**\n * Return new circle transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Circle}\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Flatten.Circle(this.pc.transform(matrix), this.r)\n }\n\n /**\n * Returns array of intersection points between circle and other shape\n * @param {Shape} shape Shape of the one of supported types\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Circle(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Circle(shape, this);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectCircle2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Circle(shape, this);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectCircle2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from circle to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from circle to shape\n * @returns {Segment} shortest segment between circle and shape (started at circle, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2circle(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n get name() {\n return \"circle\"\n }\n\n /**\n * Return string to draw circle in svg\n * @param {Object} attrs - an object with attributes of svg circle element\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n\n};\n\nFlatten.Circle = Circle$1;\n/**\n * Shortcut to create new circle\n * @param args\n */\nconst circle = (...args) => new Flatten.Circle(...args);\nFlatten.circle = circle;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a circular arc\n * @type {Arc}\n */\nclass Arc extends Shape {\n /**\n *\n * @param {Point} pc - arc center\n * @param {number} r - arc radius\n * @param {number} startAngle - start angle in radians from 0 to 2*PI\n * @param {number} endAngle - end angle in radians from 0 to 2*PI\n * @param {boolean} counterClockwise - arc direction, true - clockwise, false - counterclockwise\n */\n constructor(...args) {\n super();\n /**\n * Arc center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Arc radius\n * @type {number}\n */\n this.r = 1;\n /**\n * Arc start angle in radians\n * @type {number}\n */\n this.startAngle = 0;\n /**\n * Arc end angle in radians\n * @type {number}\n */\n this.endAngle = 2 * Math.PI;\n /**\n * Arc orientation\n * @type {boolean}\n */\n this.counterClockwise = Flatten.CCW;\n\n if (args.length === 0)\n return;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"arc\") {\n let {pc, r, startAngle, endAngle, counterClockwise} = args[0];\n this.pc = new Flatten.Point(pc.x, pc.y);\n this.r = r;\n this.startAngle = startAngle;\n this.endAngle = endAngle;\n this.counterClockwise = counterClockwise;\n } else {\n let [pc, r, startAngle, endAngle, counterClockwise] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n if (startAngle !== undefined) this.startAngle = startAngle;\n if (endAngle !== undefined) this.endAngle = endAngle;\n if (counterClockwise !== undefined) this.counterClockwise = counterClockwise;\n }\n\n // throw Flatten.Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of arc\n * @returns {Arc}\n */\n clone() {\n return new Flatten.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n\n /**\n * Get sweep angle in radians. Sweep angle is non-negative number from 0 to 2*PI\n * @returns {number}\n */\n get sweep() {\n if (Flatten.Utils.EQ(this.startAngle, this.endAngle))\n return 0.0;\n if (Flatten.Utils.EQ(Math.abs(this.startAngle - this.endAngle), Flatten.PIx2)) {\n return Flatten.PIx2;\n }\n let sweep;\n if (this.counterClockwise) {\n sweep = Flatten.Utils.GT(this.endAngle, this.startAngle) ?\n this.endAngle - this.startAngle : this.endAngle - this.startAngle + Flatten.PIx2;\n } else {\n sweep = Flatten.Utils.GT(this.startAngle, this.endAngle) ?\n this.startAngle - this.endAngle : this.startAngle - this.endAngle + Flatten.PIx2;\n }\n\n if (Flatten.Utils.GT(sweep, Flatten.PIx2)) {\n sweep -= Flatten.PIx2;\n }\n if (Flatten.Utils.LT(sweep, 0)) {\n sweep += Flatten.PIx2;\n }\n return sweep;\n }\n\n /**\n * Get start point of arc\n * @returns {Point}\n */\n get start() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.startAngle, this.pc);\n }\n\n /**\n * Get end point of arc\n * @returns {Point}\n */\n get end() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.endAngle, this.pc);\n }\n\n /**\n * Get center of arc\n * @returns {Point}\n */\n get center() {\n return this.pc.clone();\n }\n\n get vertices() {\n return [this.start.clone(), this.end.clone()];\n }\n\n /**\n * Get arc length\n * @returns {number}\n */\n get length() {\n return Math.abs(this.sweep * this.r);\n }\n\n /**\n * Get bounding box of the arc\n * @returns {Box}\n */\n get box() {\n let func_arcs = this.breakToFunctional();\n let box = func_arcs.reduce((acc, arc) => acc.merge(arc.start.box), new Flatten.Box());\n box = box.merge(this.end.box);\n return box;\n }\n\n /**\n * Returns true if arc contains point, false otherwise\n * @param {Point} pt - point to test\n * @returns {boolean}\n */\n contains(pt) {\n // first check if point on circle (pc,r)\n if (!Flatten.Utils.EQ(this.pc.distanceTo(pt)[0], this.r))\n return false;\n\n // point on circle\n\n if (pt.equalTo(this.start))\n return true;\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n let test_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise);\n return Flatten.Utils.LE(test_arc.length, this.length);\n }\n\n /**\n * When given point belongs to arc, return array of two arcs split by this point. If points is incident\n * to start or end point of the arc, return clone of the arc. If point does not belong to the arcs, return\n * empty array.\n * @param {Point} pt Query point\n * @returns {Arc[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n\n return [\n new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise),\n new Flatten.Arc(this.pc, this.r, angle, this.endAngle, this.counterClockwise)\n ]\n }\n\n /**\n * Return middle point of the arc\n * @returns {Point}\n */\n middle() {\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep / 2 : this.startAngle - this.sweep / 2;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the arc\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length === 0) return this.start;\n if (length === this.length) return this.end;\n let factor = length / this.length;\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep * factor : this.startAngle - this.sweep * factor;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Returns chord height (\"sagitta\") of the arc\n * @returns {number}\n */\n chordHeight() {\n return (1.0 - Math.cos(Math.abs(this.sweep / 2.0))) * this.r;\n }\n\n /**\n * Returns array of intersection points between arc and other shape\n * @param {Shape} shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Arc(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Arc(shape, this);\n }\n if (shape instanceof Flatten.Circle) {\n return intersectArc2Circle(this, shape);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Arc(shape, this);\n }\n if (shape instanceof Flatten.Box) {\n return intersectArc2Box(this, shape);\n }\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Arc(this, shape);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectArc2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from arc to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from arc to shape\n * @returns {Segment} shortest segment between arc and shape (started at arc, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.arc2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.arc2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.arc2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Breaks arc in extreme point 0, pi/2, pi, 3*pi/2 and returns array of sub-arcs\n * @returns {Arc[]}\n */\n breakToFunctional() {\n let func_arcs_array = [];\n let angles = [0, Math.PI / 2, 2 * Math.PI / 2, 3 * Math.PI / 2];\n let pts = [\n this.pc.translate(this.r, 0),\n this.pc.translate(0, this.r),\n this.pc.translate(-this.r, 0),\n this.pc.translate(0, -this.r)\n ];\n\n // If arc contains extreme point,\n // create test arc started at start point and ended at this extreme point\n let test_arcs = [];\n for (let i = 0; i < 4; i++) {\n if (pts[i].on(this)) {\n test_arcs.push(new Flatten.Arc(this.pc, this.r, this.startAngle, angles[i], this.counterClockwise));\n }\n }\n\n if (test_arcs.length === 0) { // arc does contain any extreme point\n func_arcs_array.push(this.clone());\n } else { // arc passes extreme point\n // sort these arcs by length\n test_arcs.sort((arc1, arc2) => arc1.length - arc2.length);\n\n for (let i = 0; i < test_arcs.length; i++) {\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, test_arcs[i].endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, test_arcs[i].endAngle, this.counterClockwise);\n }\n if (!Flatten.Utils.EQ_0(new_arc.length)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n\n // add last sub arc\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, this.endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n // It could be 2*PI when occasionally start = 0 and end = 2*PI but this is not valid for breakToFunctional\n if (!Flatten.Utils.EQ_0(new_arc.length) && !Flatten.Utils.EQ(new_arc.sweep, 2*Math.PI)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n return func_arcs_array;\n }\n\n /**\n * Return tangent unit vector in the start point in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.pc, this.start);\n let angle = this.counterClockwise ? Math.PI / 2. : -Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Return tangent unit vector in the end point in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.pc, this.end);\n let angle = this.counterClockwise ? -Math.PI / 2. : Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Returns new arc with swapped start and end angles and reversed direction\n * @returns {Arc}\n */\n reverse() {\n return new Flatten.Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise);\n }\n\n /**\n * Return new arc transformed using affine transformation matrix
\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Arc}\n */\n transform(matrix = new Flatten.Matrix()) {\n let newStart = this.start.transform(matrix);\n let newEnd = this.end.transform(matrix);\n let newCenter = this.pc.transform(matrix);\n let newDirection = this.counterClockwise;\n if (matrix.a * matrix.d < 0) {\n newDirection = !newDirection;\n }\n return Flatten.Arc.arcSE(newCenter, newStart, newEnd, newDirection);\n }\n\n static arcSE(center, start, end, counterClockwise) {\n let {vector} = Flatten;\n let startAngle = vector(center, start).slope;\n let endAngle = vector(center, end).slope;\n if (Flatten.Utils.EQ(startAngle, endAngle)) {\n endAngle += 2 * Math.PI;\n counterClockwise = true;\n }\n let r = vector(center, start).length;\n\n return new Flatten.Arc(center, r, startAngle, endAngle, counterClockwise);\n }\n\n definiteIntegral(ymin = 0) {\n let f_arcs = this.breakToFunctional();\n let area = f_arcs.reduce((acc, arc) => acc + arc.circularSegmentDefiniteIntegral(ymin), 0.0);\n return area;\n }\n\n circularSegmentDefiniteIntegral(ymin) {\n let line = new Flatten.Line(this.start, this.end);\n let onLeftSide = this.pc.leftTo(line);\n let segment = new Flatten.Segment(this.start, this.end);\n let areaTrapez = segment.definiteIntegral(ymin);\n let areaCircularSegment = this.circularSegmentArea();\n let area = onLeftSide ? areaTrapez - areaCircularSegment : areaTrapez + areaCircularSegment;\n return area;\n }\n\n circularSegmentArea() {\n return (0.5 * this.r * this.r * (this.sweep - Math.sin(this.sweep)))\n }\n\n /**\n * Sort given array of points from arc start to end, assuming all points lay on the arc\n * @param {Point[]} pts array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let {vector} = Flatten;\n return pts.slice().sort( (pt1, pt2) => {\n let slope1 = vector(this.pc, pt1).slope;\n let slope2 = vector(this.pc, pt2).slope;\n if (slope1 < slope2) {\n return -1;\n }\n if (slope1 > slope2) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"arc\"\n }\n\n /**\n * Return string to draw arc in svg\n * @param {Object} attrs - an object with attributes of svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let largeArcFlag = this.sweep <= Math.PI ? \"0\" : \"1\";\n let sweepFlag = this.counterClockwise ? \"1\" : \"0\";\n\n if (Flatten.Utils.EQ(this.sweep, 2 * Math.PI)) {\n let circle = new Flatten.Circle(this.pc, this.r);\n return circle.svg(attrs);\n } else {\n return `\\n`\n }\n }\n\n}\n\nFlatten.Arc = Arc;\n/**\n * Function to create arc equivalent to \"new\" constructor\n * @param args\n */\nconst arc = (...args) => new Flatten.Arc(...args);\nFlatten.arc = arc;\n\n/**\n * Created by Alex Bol on 3/7/2017.\n */\n\n/**\n * Class Box represents bounding box of the shape.\n * It may also represent axis-aligned rectangle\n * @type {Box}\n */\nclass Box extends Shape {\n /**\n *\n * @param {number} xmin - minimal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n constructor(xmin = undefined, ymin = undefined, xmax = undefined, ymax = undefined) {\n super();\n /**\n * Minimal x coordinate\n * @type {number}\n */\n this.xmin = xmin;\n /**\n * Minimal y coordinate\n * @type {number}\n */\n this.ymin = ymin;\n /**\n * Maximal x coordinate\n * @type {number}\n */\n this.xmax = xmax;\n /**\n * Maximal y coordinate\n * @type {number}\n */\n this.ymax = ymax;\n }\n\n /**\n * Return new cloned instance of box\n * @returns {Box}\n */\n clone() {\n return new Box(this.xmin, this.ymin, this.xmax, this.ymax);\n }\n\n /**\n * Property low need for interval tree interface\n * @returns {Point}\n */\n get low() {\n return new Flatten.Point(this.xmin, this.ymin);\n }\n\n /**\n * Property high need for interval tree interface\n * @returns {Point}\n */\n get high() {\n return new Flatten.Point(this.xmax, this.ymax);\n }\n\n /**\n * Property max returns the box itself !\n * @returns {Box}\n */\n get max() {\n return this.clone();\n }\n \n /**\n * Return center of the box\n * @returns {Point}\n */\n get center() {\n return new Flatten.Point((this.xmin + this.xmax) / 2, (this.ymin + this.ymax) / 2);\n }\n\n /**\n * Return the width of the box\n * @returns {number}\n */\n get width() {\n return Math.abs(this.xmax - this.xmin);\n }\n\n /**\n * Return the height of the box\n * @returns {number}\n */\n get height() {\n return Math.abs(this.ymax - this.ymin);\n }\n \n /**\n * Return property box like all other shapes\n * @returns {Box}\n */\n get box() {\n return this.clone();\n }\n\n /**\n * Returns true if not intersected with other box\n * @param {Box} other_box - other box to test\n * @returns {boolean}\n */\n not_intersect(other_box) {\n return (\n this.xmax < other_box.xmin ||\n this.xmin > other_box.xmax ||\n this.ymax < other_box.ymin ||\n this.ymin > other_box.ymax\n );\n }\n\n /**\n * Returns true if intersected with other box\n * @param {Box} other_box - Query box\n * @returns {boolean}\n */\n intersect(other_box) {\n return !this.not_intersect(other_box);\n }\n\n /**\n * Returns new box merged with other box\n * @param {Box} other_box - Other box to merge with\n * @returns {Box}\n */\n merge(other_box) {\n return new Box(\n this.xmin === undefined ? other_box.xmin : Math.min(this.xmin, other_box.xmin),\n this.ymin === undefined ? other_box.ymin : Math.min(this.ymin, other_box.ymin),\n this.xmax === undefined ? other_box.xmax : Math.max(this.xmax, other_box.xmax),\n this.ymax === undefined ? other_box.ymax : Math.max(this.ymax, other_box.ymax)\n );\n }\n\n /**\n * Defines predicate \"less than\" between two boxes. Need for interval index\n * @param {Box} other_box - other box\n * @returns {boolean} - true if this box less than other box, false otherwise\n */\n less_than(other_box) {\n if (this.low.lessThan(other_box.low))\n return true;\n if (this.low.equalTo(other_box.low) && this.high.lessThan(other_box.high))\n return true;\n return false;\n }\n\n /**\n * Returns true if this box is equal to other box, false otherwise\n * @param {Box} other_box - query box\n * @returns {boolean}\n */\n equal_to(other_box) {\n return (this.low.equalTo(other_box.low) && this.high.equalTo(other_box.high));\n }\n\n output() {\n return this.clone();\n }\n\n static comparable_max(box1, box2) {\n // return pt1.lessThan(pt2) ? pt2.clone() : pt1.clone();\n return box1.merge(box2);\n }\n\n static comparable_less_than(pt1, pt2) {\n return pt1.lessThan(pt2);\n }\n\n /**\n * Set new values to the box object\n * @param {number} xmin - mininal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n set(xmin, ymin, xmax, ymax) {\n this.xmin = xmin;\n this.ymin = ymin;\n this.xmax = xmax;\n this.ymax = ymax;\n }\n\n /**\n * Transform box into array of points from low left corner in counterclockwise\n * @returns {Point[]}\n */\n toPoints() {\n return [\n new Flatten.Point(this.xmin, this.ymin),\n new Flatten.Point(this.xmax, this.ymin),\n new Flatten.Point(this.xmax, this.ymax),\n new Flatten.Point(this.xmin, this.ymax)\n ];\n }\n\n /**\n * Transform box into array of segments from low left corner in counterclockwise\n * @returns {Segment[]}\n */\n toSegments() {\n let pts = this.toPoints();\n return [\n new Flatten.Segment(pts[0], pts[1]),\n new Flatten.Segment(pts[1], pts[2]),\n new Flatten.Segment(pts[2], pts[3]),\n new Flatten.Segment(pts[3], pts[0])\n ];\n }\n\n /**\n * Box rotation is not supported\n * Attempt to rotate box throws error\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n */\n rotate(angle, center = new Flatten.Point()) {\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n }\n\n /**\n * Return new box transformed using affine transformation matrix\n * New box is a bounding box of transformed corner points\n * @param {Matrix} m - affine transformation matrix\n * @returns {Box}\n */\n transform(m = new Flatten.Matrix()) {\n const transformed_points = this.toPoints().map(pt => pt.transform(m));\n return transformed_points.reduce(\n (new_box, pt) => new_box.merge(pt.box), new Box())\n }\n\n /**\n * Return true if box contains shape: no point of shape lies outside the box\n * @param {AnyShape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.vertices.every(vertex => this.contains(vertex))\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.toSegments().every(segment => this.contains(segment))\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.contains(shape.box)\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.vertices.every(vertex => this.contains(vertex)) &&\n shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)\n }\n\n if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {\n return false\n }\n\n if (shape instanceof Flatten.Multiline) {\n return shape.toShapes().every(shape => this.contains(shape))\n }\n\n if (shape instanceof Flatten.Polygon) {\n return this.contains(shape.box)\n }\n }\n\n get name() {\n return \"box\"\n }\n\n /**\n * Return string to draw box in svg\n * @param {Object} attrs - an object with attributes of svg rectangle element\n * @returns {string}\n */\n svg(attrs = {}) {\n const width = this.xmax - this.xmin;\n const height = this.ymax - this.ymin;\n return `\\n`;\n };\n}\n\nFlatten.Box = Box;\n/**\n * Shortcut to create new box\n * @param args\n * @returns {Box}\n */\nconst box = (...args) => new Flatten.Box(...args);\nFlatten.box = box;\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing an edge of polygon. Edge shape may be Segment or Arc.\n * Each edge contains references to the next and previous edges in the face of the polygon.\n *\n * @type {Edge}\n */\nclass Edge {\n /**\n * Construct new instance of edge\n * @param {Shape} shape Shape of type Segment or Arc\n */\n constructor(shape) {\n /**\n * Shape of the edge: Segment or Arc\n * @type {Segment|Arc}\n */\n this.shape = shape;\n /**\n * Pointer to the next edge in the face\n * @type {Edge}\n */\n this.next = undefined;\n /**\n * Pointer to the previous edge in the face\n * @type {Edge}\n */\n this.prev = undefined;\n /**\n * Pointer to the face containing this edge\n * @type {Face}\n */\n this.face = undefined;\n /**\n * \"Arc distance\" from the face start\n * @type {number}\n */\n this.arc_length = 0;\n /**\n * Start inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvStart = undefined;\n /**\n * End inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvEnd = undefined;\n /**\n * Edge inclusion flag (Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY)\n * @type {*}\n */\n this.bv = undefined;\n /**\n * Overlap flag for boundary edge (Flatten.OVERLAP_SAME/Flatten.OVERLAP_OPPOSITE)\n * @type {*}\n */\n this.overlap = undefined;\n }\n\n /**\n * Get edge start point\n */\n get start() {\n return this.shape.start;\n }\n\n /**\n * Get edge end point\n */\n get end() {\n return this.shape.end;\n }\n\n /**\n * Get edge length\n */\n get length() {\n return this.shape.length;\n }\n\n /**\n * Get bounding box of the edge\n * @returns {Box}\n */\n get box() {\n return this.shape.box;\n }\n\n get isSegment() {\n return this.shape instanceof Flatten.Segment;\n }\n\n get isArc() {\n return this.shape instanceof Flatten.Arc;\n }\n\n get isLine() {\n return this.shape instanceof Flatten.Line;\n }\n\n get isRay() {\n return this.shape instanceof Flatten.Ray\n }\n\n /**\n * Get middle point of the edge\n * @returns {Point}\n */\n middle() {\n return this.shape.middle();\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the edge\n * @returns {Point}\n */\n pointAtLength(length) {\n return this.shape.pointAtLength(length);\n }\n\n /**\n * Returns true if point belongs to the edge, false otherwise\n * @param {Point} pt - test point\n */\n contains(pt) {\n return this.shape.contains(pt);\n }\n\n /**\n * Set inclusion flag of the edge with respect to another polygon\n * Inclusion flag is one of Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY\n * @param polygon\n */\n setInclusion(polygon) {\n if (this.bv !== undefined) return this.bv;\n\n if (this.shape instanceof Flatten.Line || this.shape instanceof Flatten.Ray) {\n this.bv = Flatten.OUTSIDE;\n return this.bv;\n }\n\n if (this.bvStart === undefined) {\n this.bvStart = ray_shoot(polygon, this.start);\n }\n if (this.bvEnd === undefined) {\n this.bvEnd = ray_shoot(polygon, this.end);\n }\n /* At least one end outside - the whole edge outside */\n if (this.bvStart === Flatten.OUTSIDE || this.bvEnd == Flatten.OUTSIDE) {\n this.bv = Flatten.OUTSIDE;\n }\n /* At least one end inside - the whole edge inside */\n else if (this.bvStart === Flatten.INSIDE || this.bvEnd == Flatten.INSIDE) {\n this.bv = Flatten.INSIDE;\n }\n /* Both are boundary - check the middle point */\n else {\n let bvMiddle = ray_shoot(polygon, this.middle());\n // let boundary = this.middle().distanceTo(polygon)[0] < 10*Flatten.DP_TOL;\n // let bvMiddle = boundary ? Flatten.BOUNDARY : ray_shoot(polygon, this.middle());\n this.bv = bvMiddle;\n }\n return this.bv;\n }\n\n /**\n * Set overlapping between two coincident boundary edges\n * Overlapping flag is one of Flatten.OVERLAP_SAME or Flatten.OVERLAP_OPPOSITE\n * @param edge\n */\n setOverlap(edge) {\n let flag = undefined;\n let shape1 = this.shape;\n let shape2 = edge.shape;\n\n if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end)) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start)) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Arc) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && /*shape1.counterClockwise === shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && /*shape1.counterClockwise !== shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Arc ||\n shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n }\n\n /* Do not update overlap flag if already set on previous chain */\n if (this.overlap === undefined) this.overlap = flag;\n if (edge.overlap === undefined) edge.overlap = flag;\n }\n\n svg() {\n if (this.shape instanceof Flatten.Segment) {\n return ` L${this.shape.end.x},${this.shape.end.y}`;\n } else if (this.shape instanceof Flatten.Arc) {\n let arc = this.shape;\n let largeArcFlag;\n let sweepFlag = arc.counterClockwise ? \"1\" : \"0\";\n\n // Draw full circe arc as special case: split it into two half-circles\n if (Flatten.Utils.EQ(arc.sweep, 2 * Math.PI)) {\n let sign = arc.counterClockwise ? 1 : -1;\n let halfArc1 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle, arc.startAngle + sign * Math.PI, arc.counterClockwise);\n let halfArc2 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle + sign * Math.PI, arc.endAngle, arc.counterClockwise);\n\n largeArcFlag = \"0\";\n\n return ` A${halfArc1.r},${halfArc1.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc1.end.x},${halfArc1.end.y}\n A${halfArc2.r},${halfArc2.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc2.end.x},${halfArc2.end.y}`\n } else {\n largeArcFlag = arc.sweep <= Math.PI ? \"0\" : \"1\";\n\n return ` A${arc.r},${arc.r} 0 ${largeArcFlag},${sweepFlag} ${arc.end.x},${arc.end.y}`;\n }\n }\n }\n\n toJSON() {\n return this.shape.toJSON();\n }\n}\nFlatten.Edge = Edge;\n\n/**\n * Class implements circular bidirectional linked list
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass CircularLinkedList extends LinkedList {\n constructor(first, last) {\n super(first, last);\n this.setCircularLinks();\n }\n\n setCircularLinks() {\n if (this.isEmpty()) return;\n this.last.next = this.first;\n this.first.prev = this.last;\n }\n\n [Symbol.iterator]() {\n let element = undefined;\n return {\n next: () => {\n let value = element ? element : this.first;\n let done = this.first ? (element ? element === this.first : false) : true;\n element = value ? value.next : undefined;\n return {value: value, done: done};\n }\n };\n };\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element - new element to be appended\n * @returns {CircularLinkedList}\n */\n append(element) {\n super.append(element);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement - new element to be inserted\n * @param {LinkedListElement} elementBefore - element in the list to insert after it\n * @returns {CircularLinkedList}\n */\n insert(newElement, elementBefore) {\n super.insert(newElement, elementBefore);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element - element to be removed from the list\n * @returns {CircularLinkedList}\n */\n remove(element) {\n super.remove(element);\n // this.setCircularLinks();\n return this;\n }\n}\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing a face (closed loop) in a [polygon]{@link Flatten.Polygon} object.\n * Face is a circular bidirectional linked list of [edges]{@link Flatten.Edge}.\n * Face object cannot be instantiated with a constructor.\n * Instead, use [polygon.addFace()]{@link Flatten.Polygon#addFace} method.\n *
\n * Note, that face only set entry point to the linked list of edges but does not contain edges by itself.\n * Container of edges is a property of the polygon object.
\n *\n * @example\n * // Face implements \"next\" iterator which enables to iterate edges in for loop:\n * for (let edge of face) {\n * console.log(edge.shape.length) // do something\n * }\n *\n * // Instead, it is possible to iterate edges as linked list, starting from face.first:\n * let edge = face.first;\n * do {\n * console.log(edge.shape.length); // do something\n * edge = edge.next;\n * } while (edge != face.first)\n */\nclass Face extends CircularLinkedList {\n constructor(polygon, ...args) {\n super(); // construct empty list of edges\n /**\n * Reference to the first edge in face\n */\n // this.first;\n /**\n * Reference to the last edge in face\n */\n // this.last;\n\n this._box = undefined; // new Box();\n this._orientation = undefined;\n\n if (args.length === 0) {\n return;\n }\n\n /* If passed an array it supposed to be:\n 1) array of shapes that performs close loop or\n 2) array of points that performs set of vertices\n */\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n // let argsArray = args[0];\n let shapes = args[0]; // argsArray[0];\n if (shapes.length === 0)\n return;\n\n /* array of Flatten.Points */\n if (shapes.every((shape) => {return shape instanceof Flatten.Point})) {\n let segments = Face.points2segments(shapes);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of points as pairs of numbers */\n else if (shapes.every((shape) => {return shape instanceof Array && shape.length === 2})) {\n let points = shapes.map((shape) => new Flatten.Point(shape[0],shape[1]));\n let segments = Face.points2segments(points);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of segments ot arcs */\n else if (shapes.every((shape) => {\n return (shape instanceof Flatten.Segment || shape instanceof Flatten.Arc)\n })) {\n this.shapes2face(polygon.edges, shapes);\n }\n // this is from JSON.parse object\n else if (shapes.every((shape) => {\n return (shape.name === \"segment\" || shape.name === \"arc\")\n })) {\n let flattenShapes = [];\n for (let shape of shapes) {\n let flattenShape;\n if (shape.name === \"segment\") {\n flattenShape = new Flatten.Segment(shape);\n } else {\n flattenShape = new Flatten.Arc(shape);\n }\n flattenShapes.push(flattenShape);\n }\n this.shapes2face(polygon.edges, flattenShapes);\n }\n }\n /* Create new face and copy edges into polygon.edges set */\n else if (args[0] instanceof Face) {\n let face = args[0];\n this.first = face.first;\n this.last = face.last;\n for (let edge of face) {\n polygon.edges.add(edge);\n }\n }\n /* Instantiate face from a circle in CCW orientation */\n else if (args[0] instanceof Flatten.Circle) {\n this.shapes2face(polygon.edges, [args[0].toArc(CCW)]);\n }\n /* Instantiate face from a box in CCW orientation */\n else if (args[0] instanceof Flatten.Box) {\n let box = args[0];\n this.shapes2face(polygon.edges, [\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymin), new Flatten.Point(box.xmax, box.ymin)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymin), new Flatten.Point(box.xmax, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymax), new Flatten.Point(box.xmin, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymax), new Flatten.Point(box.xmin, box.ymin))\n ]);\n }\n }\n /* If passed two edges, consider them as start and end of the face loop */\n /* THIS METHOD WILL BE USED BY BOOLEAN OPERATIONS */\n /* Assume that edges already copied to polygon.edges set in the clip algorithm !!! */\n if (args.length === 2 && args[0] instanceof Flatten.Edge && args[1] instanceof Flatten.Edge) {\n this.first = args[0]; // first edge in face or undefined\n this.last = args[1]; // last edge in face or undefined\n this.last.next = this.first;\n this.first.prev = this.last;\n\n // set arc length\n this.setArcLength();\n\n // this.box = this.getBox();\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n }\n\n /**\n * Return array of edges from first to last\n * @returns {Array}\n */\n get edges() {\n return this.toArray();\n }\n\n /**\n * Return array of shapes which comprise face\n * @returns {Array}\n */\n get shapes() {\n return this.edges.map(edge => edge.shape.clone());\n }\n\n /**\n * Return bounding box of the face\n * @returns {Box}\n */\n get box() {\n if (this._box === undefined) {\n let box = new Flatten.Box();\n for (let edge of this) {\n box = box.merge(edge.box);\n }\n this._box = box;\n }\n return this._box;\n }\n\n /**\n * Get all edges length\n * @returns {number}\n */\n get perimeter() {\n return this.last.arc_length + this.last.length\n }\n\n /**\n * Get point on face boundary at given length\n * @param {number} length - The length along the face boundary\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.perimeter || length < 0) return null;\n let point = null;\n for (let edge of this) {\n if (length >= edge.arc_length &&\n (edge === this.last || length < edge.next.arc_length)) {\n point = edge.pointAtLength(length - edge.arc_length);\n break;\n }\n }\n return point;\n }\n\n static points2segments(points) {\n let segments = [];\n for (let i = 0; i < points.length; i++) {\n // skip zero length segment\n if (points[i].equalTo(points[(i + 1) % points.length]))\n continue;\n segments.push(new Flatten.Segment(points[i], points[(i + 1) % points.length]));\n }\n return segments;\n }\n\n shapes2face(edges, shapes) {\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n // this.box = this.box.merge(shape.box);\n edges.add(edge);\n }\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n\n /**\n * Append edge after the last edge of the face (and before the first edge).
\n * @param {Edge} edge - Edge to be appended to the linked list\n * @returns {Face}\n */\n append(edge) {\n super.append(edge);\n // set arc length\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n // edges.add(edge); // Add new edges into edges container\n return this;\n }\n\n /**\n * Insert edge newEdge into the linked list after the edge edgeBefore
\n * @param {Edge} newEdge - Edge to be inserted into linked list\n * @param {Edge} edgeBefore - Edge to insert newEdge after it\n * @returns {Face}\n */\n insert(newEdge, edgeBefore) {\n super.insert(newEdge, edgeBefore);\n // set arc length\n this.setOneEdgeArcLength(newEdge);\n newEdge.face = this;\n return this;\n }\n\n /**\n * Remove the given edge from the linked list of the face
\n * @param {Edge} edge - Edge to be removed\n * @returns {Face}\n */\n remove(edge) {\n super.remove(edge);\n // Recalculate arc length\n this.setArcLength();\n return this;\n }\n\n /**\n * Merge current edge with the next edge. Given edge will be extended,\n * next edge after it will be removed. The distortion of the polygon\n * is on the responsibility of the user of this method\n * @param {Edge} edge - edge to be extended\n * @returns {Face}\n */\n merge_with_next_edge(edge) {\n edge.shape.end.x = edge.next.shape.end.x;\n edge.shape.end.y = edge.next.shape.end.y;\n this.remove(edge.next);\n return this;\n }\n\n /**\n * Reverse orientation of the face: first edge become last and vice a verse,\n * all edges starts and ends swapped, direction of arcs inverted. If face was oriented\n * clockwise, it becomes counterclockwise and vice versa\n */\n reverse() {\n // collect edges in revert order with reverted shapes\n let edges = [];\n let edge_tmp = this.last;\n do {\n // reverse shape\n edge_tmp.shape = edge_tmp.shape.reverse();\n edges.push(edge_tmp);\n edge_tmp = edge_tmp.prev;\n } while (edge_tmp !== this.last);\n\n // restore linked list\n this.first = undefined;\n this.last = undefined;\n for (let edge of edges) {\n if (this.first === undefined) {\n edge.prev = edge;\n edge.next = edge;\n this.first = edge;\n this.last = edge;\n } else {\n // append to end\n edge.prev = this.last;\n this.last.next = edge;\n\n // update edge to be last\n this.last = edge;\n\n // restore circular links\n this.last.next = this.first;\n this.first.prev = this.last;\n\n }\n // set arc length\n this.setOneEdgeArcLength(edge);\n }\n\n // Recalculate orientation, if set\n if (this._orientation !== undefined) {\n this._orientation = undefined;\n this._orientation = this.orientation();\n }\n }\n\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Returns the absolute value of the area of the face\n * @returns {number}\n */\n area() {\n return Math.abs(this.signedArea());\n }\n\n /**\n * Returns signed area of the simple face.\n * Face is simple if it has no self intersections that change its orientation.\n * Then the area will be positive if the orientation of the face is clockwise,\n * and negative if orientation is counterclockwise.\n * It may be zero if polygon is degenerated.\n * @returns {number}\n */\n signedArea() {\n let sArea = 0;\n let ymin = this.box.ymin;\n for (let edge of this) {\n sArea += edge.shape.definiteIntegral(ymin);\n }\n return sArea;\n }\n\n /**\n * Return face orientation: one of Flatten.ORIENTATION.CCW, Flatten.ORIENTATION.CW, Flatten.ORIENTATION.NOT_ORIENTABLE
\n * According to Green theorem the area of a closed curve may be calculated as double integral,\n * and the sign of the integral will be defined by the direction of the curve.\n * When the integral (\"signed area\") will be negative, direction is counterclockwise,\n * when positive - clockwise and when it is zero, polygon is not orientable.\n * See {@link https://mathinsight.org/greens_theorem_find_area}\n * @returns {number}\n */\n orientation() {\n if (this._orientation === undefined) {\n let area = this.signedArea();\n if (Flatten.Utils.EQ_0(area)) {\n this._orientation = ORIENTATION.NOT_ORIENTABLE;\n } else if (Flatten.Utils.LT(area, 0)) {\n this._orientation = ORIENTATION.CCW;\n } else {\n this._orientation = ORIENTATION.CW;\n }\n }\n return this._orientation;\n }\n\n /**\n * Returns true if face of the polygon is simple (no self-intersection points found)\n * NOTE: this method is incomplete because it does not exclude touching points.\n * Self intersection test should check if polygon change orientation in the test point.\n * @param {PlanarSet} edges - reference to polygon edges to provide search index\n * @returns {boolean}\n */\n isSimple(edges) {\n let ip = Face.getSelfIntersections(this, edges, true);\n return ip.length === 0;\n }\n\n static getSelfIntersections(face, edges, exitOnFirst = false) {\n let int_points = [];\n\n // calculate intersections\n for (let edge1 of face) {\n\n // request edges of polygon in the box of edge1\n let resp = edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // Skip itself\n if (edge1 === edge2)\n continue;\n\n // Skip is edge2 belongs to another face\n if (edge2.face !== face)\n continue;\n\n // Skip next and previous edge if both are segment (if one of them arc - calc intersection)\n if (edge1.shape instanceof Flatten.Segment && edge2.shape instanceof Flatten.Segment &&\n (edge1.next === edge2 || edge1.prev === edge2))\n continue;\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n\n // skip start-end connections\n if (pt.equalTo(edge1.start) && pt.equalTo(edge2.end) && edge2 === edge1.prev)\n continue;\n if (pt.equalTo(edge1.end) && pt.equalTo(edge2.start) && edge2 === edge1.next)\n continue;\n\n int_points.push(pt);\n\n if (exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n\n }\n return int_points;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt - test point\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (pt.equalTo(edge.shape.start)) continue\n if (pt.equalTo(edge.shape.end) || edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new polygon created from one face\n * @returns {Polygon}\n */\n toPolygon() {\n return new Flatten.Polygon(this.shapes);\n }\n\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Returns string to be assigned to \"d\" attribute inside defined \"path\"\n * @returns {string}\n */\n svg() {\n let svgStr = `\\nM${this.first.start.x},${this.first.start.y}`;\n for (let edge of this) {\n svgStr += edge.svg();\n }\n svgStr += ` z`;\n return svgStr;\n }\n\n}\n\nFlatten.Face = Face;\n\n/**\n * Class representing a ray (a half-infinite line).\n * @type {Ray}\n */\nclass Ray extends Shape {\n /**\n * Ray may be constructed by setting an origin point and a normal vector, so that any point x\n * on a ray fit an equation:
\n * (x - origin) * vector = 0
\n * Ray defined by constructor is a right semi-infinite line with respect to the normal vector
\n * If normal vector is omitted ray is considered horizontal (normal vector is (0,1)).
\n * Don't be confused: direction of the normal vector is orthogonal to the ray
\n * @param {Point} pt - start point\n * @param {Vector} norm - normal vector\n */\n constructor(...args) {\n super();\n this.pt = new Flatten.Point();\n this.norm = new Flatten.Vector(0,1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length >= 1 && args[0] instanceof Flatten.Point) {\n this.pt = args[0].clone();\n }\n\n if (args.length === 1) {\n return;\n }\n\n if (args.length === 2 && args[1] instanceof Flatten.Vector) {\n this.norm = args[1].clone();\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of ray\n * @returns {Ray}\n */\n clone() {\n return new Ray(this.pt, this.norm);\n }\n\n /**\n * Slope of the ray - angle in radians between ray and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Returns half-infinite bounding box of the ray\n * @returns {Box} - bounding box\n */\n get box() {\n let slope = this.slope;\n return new Flatten.Box(\n slope > Math.PI/2 && slope < 3*Math.PI/2 ? Number.NEGATIVE_INFINITY : this.pt.x,\n slope >= 0 && slope <= Math.PI ? this.pt.y : Number.NEGATIVE_INFINITY,\n slope >= Math.PI/2 && slope <= 3*Math.PI/2 ? this.pt.x : Number.POSITIVE_INFINITY,\n slope >= Math.PI && slope <= 2*Math.PI || slope === 0 ? this.pt.y : Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Return ray start point\n * @returns {Point} - ray start point\n */\n get start() {\n return this.pt;\n }\n\n /**\n * Ray has no end point?\n * @returns {undefined}\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns true if point belongs to ray\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Ray contains point if vector to point is orthogonal to the ray normal vector\n and cross product from vector to point is positive */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec)) && Flatten.Utils.GE(vec.cross(this.norm),0);\n }\n\n /**\n * Return coordinate of the point that lies on the ray in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line containing this ray and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the ray\n * @param {Point} pt - point on a ray\n * @returns {number}\n */\n coord(pt) {\n return vector$1(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Split ray with point and return array of segment and new ray\n * @param {Point} pt\n * @returns [Segment,Ray]\n */\n split(pt) {\n if (!this.contains(pt))\n return [];\n\n if (this.pt.equalTo(pt)) {\n return [this]\n }\n\n return [\n new Flatten.Segment(this.pt, pt),\n new Flatten.Ray(pt, this.norm)\n ]\n }\n\n /**\n * Returns array of intersection points between ray and another shape\n * @param {Shape} shape - Shape to intersect with ray\n * @returns {Point[]} array of intersection points\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectRay2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectRay2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectRay2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Ray(this, shape)\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectRay2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectRay2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectRay2Polygon(this, shape);\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Ray(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new ray transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Ray}\n */\n transform(m) {\n return new Flatten.Ray(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n get name() {\n return \"ray\"\n }\n\n /**\n * Return string to draw svg segment representing ray inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg segment element\n */\n svg(box, attrs = {}) {\n let line = new Flatten.Line(this.pt, this.norm);\n let ip = intersectLine2Box(line, box);\n ip = ip.filter( pt => this.contains(pt) );\n if (ip.length === 0 || ip.length === 2)\n return \"\";\n let segment = new Flatten.Segment(this.pt, ip[0]);\n return segment.svg(attrs);\n }\n\n}\n\nFlatten.Ray = Ray;\n\nconst ray = (...args) => new Flatten.Ray(...args);\nFlatten.ray = ray;\n\n/**\n * Created by Alex Bol on 3/15/2017.\n */\n\n\n/**\n * Class representing a polygon.
\n * Polygon in FlattenJS is a multipolygon comprised from a set of [faces]{@link Flatten.Face}.
\n * Face, in turn, is a closed loop of [edges]{@link Flatten.Edge}, where edge may be segment or circular arc
\n * @type {Polygon}\n */\nclass Polygon {\n /**\n * Constructor creates new instance of polygon. With no arguments new polygon is empty.
\n * Constructor accepts as argument array that define loop of shapes\n * or array of arrays in case of multi polygon
\n * Loop may be defined in different ways:
\n * - array of shapes of type Segment or Arc
\n * - array of points (Flatten.Point)
\n * - array of numeric pairs which represent points
\n * - box or circle object
\n * Alternatively, it is possible to use polygon.addFace method\n * @param {args} - array of shapes or array of arrays\n */\n constructor() {\n /**\n * Container of faces (closed loops), may be empty\n * @type {PlanarSet}\n */\n this.faces = new Flatten.PlanarSet();\n /**\n * Container of edges\n * @type {PlanarSet}\n */\n this.edges = new Flatten.PlanarSet();\n\n /* It may be array of something that may represent one loop (face) or\n array of arrays that represent multiple loops\n */\n let args = [...arguments];\n if (args.length === 1 &&\n ((args[0] instanceof Array && args[0].length > 0) ||\n args[0] instanceof Flatten.Circle || args[0] instanceof Flatten.Box)) {\n let argsArray = args[0];\n if (args[0] instanceof Array && args[0].every((loop) => {\n return loop instanceof Array\n })) {\n if (argsArray.every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon as array of pairs of numbers\n } else {\n for (let loop of argsArray) { // multi-loop polygon\n /* Check extra level of nesting for GeoJSON-style multi polygons */\n if (loop instanceof Array && loop[0] instanceof Array &&\n loop[0].every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n for (let loop1 of loop) {\n this.faces.add(new Flatten.Face(this, loop1));\n }\n } else {\n this.faces.add(new Flatten.Face(this, loop));\n }\n }\n }\n } else {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon\n }\n }\n }\n\n /**\n * (Getter) Returns bounding box of the polygon\n * @returns {Box}\n */\n get box() {\n return [...this.faces].reduce((acc, face) => acc.merge(face.box), new Flatten.Box());\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Array}\n */\n get vertices() {\n return [...this.edges].map(edge => edge.start);\n }\n\n /**\n * Create new cloned instance of the polygon\n * @returns {Polygon}\n */\n clone() {\n let polygon = new Polygon();\n for (let face of this.faces) {\n polygon.addFace(face.shapes);\n }\n return polygon;\n }\n\n /**\n * Return true is polygon has no edges\n * @returns {boolean}\n */\n isEmpty() {\n return this.edges.size === 0;\n }\n\n /**\n * Return true if polygon is valid for boolean operations\n * Polygon is valid if
\n * 1. All faces are simple polygons (there are no self-intersected polygons)
\n * 2. All faces are orientable and there is no island inside island or hole inside hole - TODO
\n * 3. There is no intersections between faces (excluding touching) - TODO
\n * @returns {boolean}\n */\n isValid() {\n let valid = true;\n // 1. Polygon is invalid if at least one face is not simple\n for (let face of this.faces) {\n if (!face.isSimple(this.edges)) {\n valid = false;\n break;\n }\n }\n // 2. TODO: check if no island inside island and no hole inside hole\n // 3. TODO: check the there is no intersection between faces\n return valid;\n }\n\n /**\n * Returns area of the polygon. Area of an island will be added, area of a hole will be subtracted\n * @returns {number}\n */\n area() {\n let signedArea = [...this.faces].reduce((acc, face) => acc + face.signedArea(), 0);\n return Math.abs(signedArea);\n }\n\n /**\n * Add new face to polygon. Returns added face\n * @param {Point[]|Segment[]|Arc[]|Circle|Box} args - new face may be create with one of the following ways:
\n * 1) array of points that describe closed path (edges are segments)
\n * 2) array of shapes (segments and arcs) which describe closed path
\n * 3) circle - will be added as counterclockwise arc
\n * 4) box - will be added as counterclockwise rectangle
\n * You can chain method face.reverse() is you need to change direction of the creates face\n * @returns {Face}\n */\n addFace(...args) {\n let face = new Flatten.Face(this, ...args);\n this.faces.add(face);\n return face;\n }\n\n /**\n * Delete existing face from polygon\n * @param {Face} face Face to be deleted\n * @returns {boolean}\n */\n deleteFace(face) {\n for (let edge of face) {\n this.edges.delete(edge);\n }\n return this.faces.delete(face);\n }\n\n /**\n * Clear all faces and create new faces from edges\n */\n recreateFaces() {\n // Remove all faces\n this.faces.clear();\n for (let edge of this.edges) {\n edge.face = null;\n }\n\n // Restore faces\n let first;\n let unassignedEdgeFound = true;\n while (unassignedEdgeFound) {\n unassignedEdgeFound = false;\n for (let edge of this.edges) {\n if (edge.face === null) {\n first = edge;\n unassignedEdgeFound = true;\n break;\n }\n }\n\n if (unassignedEdgeFound) {\n let last = first;\n do {\n last = last.next;\n } while (last.next !== first)\n\n this.addFace(first, last);\n }\n }\n }\n\n /**\n * Delete chain of edges from the face.\n * @param {Face} face Face to remove chain\n * @param {Edge} edgeFrom Start of the chain of edges to be removed\n * @param {Edge} edgeTo End of the chain of edges to be removed\n */\n removeChain(face, edgeFrom, edgeTo) {\n // Special case: all edges removed\n if (edgeTo.next === edgeFrom) {\n this.deleteFace(face);\n return;\n }\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n face.remove(edge);\n this.edges.delete(edge); // delete from PlanarSet of edges and update index\n if (face.isEmpty()) {\n this.deleteFace(face); // delete from PlanarSet of faces and update index\n break;\n }\n }\n }\n\n /**\n * Add point as a new vertex and split edge. Point supposed to belong to an edge.\n * When edge is split, new edge created from the start of the edge to the new vertex\n * and inserted before current edge.\n * Current edge is trimmed and updated.\n * Method returns new edge added. If no edge added, it returns edge before vertex\n * @param {Point} pt Point to be added as a new vertex\n * @param {Edge} edge Edge to be split with new vertex and then trimmed from start\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n edge.face.insert(newEdge, edgeBefore);\n\n // Remove old edge from edges container and 2d index\n this.edges.delete(edge);\n\n // Insert new edge to the edges container and 2d index\n this.edges.add(newEdge);\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n // Add updated edge to the edges container and 2d index\n this.edges.add(edge);\n\n return newEdge;\n }\n\n /**\n * Merge given edge with next edge and remove vertex between them\n * @param {Edge} edge\n */\n removeEndVertex(edge) {\n const edge_next = edge.next;\n if (edge_next === edge) return\n edge.face.merge_with_next_edge(edge);\n this.edges.delete(edge_next);\n }\n\n /**\n * Cut polygon with multiline and return a new polygon\n * @param {Multiline} multiline\n * @returns {Polygon}\n */\n cut(multiline) {\n let newPoly = this.clone();\n\n // smart intersections\n let intersections = {\n int_points1: [],\n int_points2: [],\n int_points1_sorted: [],\n int_points2_sorted: []\n };\n\n // intersect each edge of multiline with each edge of the polygon\n // and create smart intersections\n for (let edge1 of multiline.edges) {\n for (let edge2 of newPoly.edges) {\n let ip = intersectEdge2Edge(edge1, edge2);\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n\n // No intersections - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort smart intersections\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // split by intersection points\n splitByIntersections(multiline, intersections.int_points1_sorted);\n splitByIntersections(newPoly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // initialize inclusion flags for edges of multiline incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n\n // calculate inclusion flag for edges of multiline incident to intersections\n calculateInclusionFlags(intersections.int_points1, newPoly);\n\n // filter intersections between two edges that got same inclusion flag\n for (let int_point1 of intersections.int_points1_sorted) {\n if (int_point1.edge_before && int_point1.edge_after &&\n int_point1.edge_before.bv === int_point1.edge_after.bv) {\n intersections.int_points2[int_point1.id] = -1; // to be filtered out\n int_point1.id = -1; // to be filtered out\n }\n }\n intersections.int_points1 = intersections.int_points1.filter( int_point => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter( int_point => int_point.id >= 0);\n\n // No intersections left after filtering - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort intersection points 3d time after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // Add new inner edges between intersection points\n let int_point1_prev;\n let int_point1_curr;\n for (let i = 1; i < intersections.int_points1_sorted.length; i++) {\n int_point1_curr = intersections.int_points1_sorted[i];\n int_point1_prev = intersections.int_points1_sorted[i-1];\n if (int_point1_curr.edge_before && int_point1_curr.edge_before.bv === INSIDE$2) {\n let edgeFrom = int_point1_prev.edge_after;\n let edgeTo = int_point1_curr.edge_before;\n let newEdges = multiline.getChain(edgeFrom, edgeTo);\n insertBetweenIntPoints(intersections.int_points2[int_point1_prev.id], intersections.int_points2[int_point1_curr.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n\n newEdges = newEdges.reverse().map(edge => new Flatten.Edge(edge.shape.reverse()));\n for (let k=0; k < newEdges.length-1; k++) {\n newEdges[k].next = newEdges[k+1];\n newEdges[k+1].prev = newEdges[k];\n }\n insertBetweenIntPoints(intersections.int_points2[int_point1_curr.id], intersections.int_points2[int_point1_prev.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n }\n\n }\n\n // Recreate faces\n newPoly.recreateFaces();\n\n return newPoly\n }\n\n /**\n * A special case of cut() function\n * The return is a polygon cut with line\n * @param {Line} line - cutting line\n * @returns {Polygon} newPoly - resulted polygon\n */\n cutWithLine(line) {\n let multiline = new Multiline([line]);\n return this.cut(multiline);\n }\n\n /**\n * Returns the first found edge of polygon that contains given point\n * If point is a vertex, return the edge where the point is an end vertex, not a start one\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edge;\n for (let face of this.faces) {\n edge = face.findEdgeByPoint(pt);\n if (edge !== undefined)\n break;\n }\n return edge;\n }\n\n /**\n * Split polygon into array of polygons, where each polygon is an outer face with all\n * containing inner faces\n * @returns {Flatten.Polygon[]}\n */\n splitToIslands() {\n if (this.isEmpty()) return []; // return empty array if polygon is empty\n let polygons = this.toArray(); // split into array of one-loop polygons\n /* Sort polygons by area in descending order */\n polygons.sort((polygon1, polygon2) => polygon2.area() - polygon1.area());\n /* define orientation of the island by orientation of the first polygon in array */\n let orientation = [...polygons[0].faces][0].orientation();\n /* Create output array from polygons with same orientation as a first polygon (array of islands) */\n let newPolygons = polygons.filter(polygon => [...polygon.faces][0].orientation() === orientation);\n for (let polygon of polygons) {\n let face = [...polygon.faces][0];\n if (face.orientation() === orientation) continue; // skip same orientation\n /* Proceed with opposite orientation */\n /* Look if any of island polygons contains tested polygon as a hole */\n for (let islandPolygon of newPolygons) {\n if (face.shapes.every(shape => islandPolygon.contains(shape))) {\n islandPolygon.addFace(face.shapes); // add polygon as a hole in islandPolygon\n break;\n }\n }\n }\n // TODO: assert if not all polygons added into output\n return newPolygons;\n }\n\n /**\n * Reverse orientation of all faces to opposite\n * @returns {Polygon}\n */\n reverse() {\n for (let face of this.faces) {\n face.reverse();\n }\n return this;\n }\n\n /**\n * Returns true if polygon contains shape: no point of shape lay outside of the polygon,\n * false otherwise\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n let rel = ray_shoot(this, shape);\n return rel === INSIDE$2 || rel === BOUNDARY$1;\n } else {\n return cover(this, shape);\n }\n }\n\n /**\n * Return distance and shortest segment between polygon and other shape as array [distance, shortest_segment]\n * @param {Shape} shape Shape of one of the types Point, Circle, Line, Segment, Arc or Polygon\n * @returns {Number | Segment}\n */\n distanceTo(shape) {\n // let {Distance} = Flatten;\n\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle ||\n shape instanceof Flatten.Line ||\n shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /* this method is bit faster */\n if (shape instanceof Flatten.Polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n let dist, shortest_segment;\n\n for (let edge of this.edges) {\n // let [dist, shortest_segment] = Distance.shape2polygon(edge.shape, shape);\n let min_stop = min_dist_and_segment[0];\n [dist, shortest_segment] = Flatten.Distance.shape2planarSet(edge.shape, shape.edges, min_stop);\n if (Flatten.Utils.LT(dist, min_stop)) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n }\n\n /**\n * Return array of intersection points between polygon and other shape\n * @param shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectPolygon2Polygon(shape, this);\n }\n }\n\n /**\n * Returns new polygon translated by vector vec\n * @param {Vector} vec\n * @returns {Polygon}\n */\n translate(vec) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.translate(vec)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Polygon} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.rotate(angle, center)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Polygon}\n */\n scale(sx, sy) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.scale(sx, sy)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Polygon} - new polygon\n */\n transform(matrix = new Flatten.Matrix()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.transform(matrix)));\n }\n return newPolygon;\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return [...this.faces].map(face => face.toJSON());\n }\n\n /**\n * Transform all faces into array of polygons\n * @returns {Flatten.Polygon[]}\n */\n toArray() {\n return [...this.faces].map(face => face.toPolygon());\n }\n\n /**\n * Return string to draw polygon in svg\n * @param attrs - an object with attributes for svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Polygon = Polygon;\n\n/**\n * Shortcut method to create new polygon\n */\nconst polygon = (...args) => new Flatten.Polygon(...args);\nFlatten.polygon = polygon;\n\nconst {Circle, Line, Point, Vector, Utils} = Flatten;\n/**\n * Class Inversion represent operator of inversion in circle\n * Inversion is a transformation of the Euclidean plane that maps generalized circles\n * (where line is considered as a circle with infinite radius) into generalized circles\n * See also https://en.wikipedia.org/wiki/Inversive_geometry and\n * http://mathworld.wolfram.com/Inversion.html
\n * @type {Inversion}\n */\nclass Inversion {\n /**\n * Inversion constructor\n * @param {Circle} inversion_circle inversion circle\n */\n constructor(inversion_circle) {\n this.circle = inversion_circle;\n }\n\n\n get inversion_circle() {\n return this.circle;\n }\n\n static inversePoint(inversion_circle, point) {\n const v = new Vector(inversion_circle.pc, point);\n const k2 = inversion_circle.r * inversion_circle.r;\n const len2 = v.dot(v);\n const reflected_point = Utils.EQ_0(len2) ?\n new Point(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) :\n inversion_circle.pc.translate(v.multiply(k2 / len2));\n return reflected_point;\n }\n\n static inverseCircle(inversion_circle, circle) {\n const dist = inversion_circle.pc.distanceTo(circle.pc)[0];\n if (Utils.EQ(dist, circle.r)) { // Circle passing through inversion center mapped into line\n let d = (inversion_circle.r * inversion_circle.r) / (2 * circle.r);\n let v = new Vector(inversion_circle.pc, circle.pc);\n v = v.normalize();\n let pt = inversion_circle.pc.translate(v.multiply(d));\n\n return new Line(pt, v);\n } else { // Circle not passing through inversion center - map into another circle */\n /* Taken from http://mathworld.wolfram.com */\n let v = new Vector(inversion_circle.pc, circle.pc);\n let s = inversion_circle.r * inversion_circle.r / (v.dot(v) - circle.r * circle.r);\n let pc = inversion_circle.pc.translate(v.multiply(s));\n let r = Math.abs(s) * circle.r;\n\n return new Circle(pc, r);\n }\n }\n\n static inverseLine(inversion_circle, line) {\n const [dist, shortest_segment] = inversion_circle.pc.distanceTo(line);\n if (Utils.EQ_0(dist)) { // Line passing through inversion center, is mapping to itself\n return line.clone();\n } else { // Line not passing through inversion center is mapping into circle\n let r = inversion_circle.r * inversion_circle.r / (2 * dist);\n let v = new Vector(inversion_circle.pc, shortest_segment.end);\n v = v.multiply(r / dist);\n return new Circle(inversion_circle.pc.translate(v), r);\n }\n }\n\n inverse(shape) {\n if (shape instanceof Point) {\n return Inversion.inversePoint(this.circle, shape);\n }\n else if (shape instanceof Circle) {\n return Inversion.inverseCircle(this.circle, shape);\n }\n else if (shape instanceof Line) {\n return Inversion.inverseLine(this.circle, shape);\n }\n }\n}\nFlatten.Inversion = Inversion;\n\n/**\n * Shortcut to create inversion operator\n * @param circle\n * @returns {Inversion}\n */\nconst inversion = (circle) => new Flatten.Inversion(circle);\nFlatten.inversion = inversion;\n\nclass Distance {\n /**\n * Calculate distance and shortest segment between points\n * @param pt1\n * @param pt2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2point(pt1, pt2) {\n return pt1.distanceTo(pt2);\n }\n\n /**\n * Calculate distance and shortest segment between point and line\n * @param pt\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2line(pt, line) {\n let closest_point = pt.projectionOn(line);\n let vec = new Flatten.Vector(pt, closest_point);\n return [vec.length, new Flatten.Segment(pt, closest_point)];\n }\n\n /**\n * Calculate distance and shortest segment between point and circle\n * @param pt\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2circle(pt, circle) {\n let [dist2center, shortest_dist] = pt.distanceTo(circle.center);\n if (Flatten.Utils.EQ_0(dist2center)) {\n return [circle.r, new Flatten.Segment(pt, circle.toArc().start)];\n } else {\n let dist = Math.abs(dist2center - circle.r);\n let v = new Flatten.Vector(circle.pc, pt).normalize().multiply(circle.r);\n let closest_point = circle.pc.translate(v);\n return [dist, new Flatten.Segment(pt, closest_point)];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and segment\n * @param pt\n * @param segment\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2segment(pt, segment) {\n /* Degenerated case of zero-length segment */\n if (segment.start.equalTo(segment.end)) {\n return Distance.point2point(pt, segment.start);\n }\n\n let v_seg = new Flatten.Vector(segment.start, segment.end);\n let v_ps2pt = new Flatten.Vector(segment.start, pt);\n let v_pe2pt = new Flatten.Vector(segment.end, pt);\n let start_sp = v_seg.dot(v_ps2pt);\n /* dot product v_seg * v_ps2pt */\n let end_sp = -v_seg.dot(v_pe2pt);\n /* minus dot product v_seg * v_pe2pt */\n\n let dist;\n let closest_point;\n if (Flatten.Utils.GE(start_sp, 0) && Flatten.Utils.GE(end_sp, 0)) { /* point inside segment scope */\n let v_unit = segment.tangentInStart(); // new Flatten.Vector(v_seg.x / this.length, v_seg.y / this.length);\n /* unit vector ||v_unit|| = 1 */\n dist = Math.abs(v_unit.cross(v_ps2pt));\n /* dist = abs(v_unit x v_ps2pt) */\n closest_point = segment.start.translate(v_unit.multiply(v_unit.dot(v_ps2pt)));\n return [dist, new Flatten.Segment(pt, closest_point)];\n } else if (start_sp < 0) { /* point is out of scope closer to ps */\n return pt.distanceTo(segment.start);\n } else { /* point is out of scope closer to pe */\n return pt.distanceTo(segment.end);\n }\n };\n\n /**\n * Calculate distance and shortest segment between point and arc\n * @param pt\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2arc(pt, arc) {\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let dist_and_segment = [];\n let dist, shortest_segment;\n [dist, shortest_segment] = Distance.point2circle(pt, circle);\n if (shortest_segment.end.on(arc)) {\n dist_and_segment.push(Distance.point2circle(pt, circle));\n }\n dist_and_segment.push(Distance.point2point(pt, arc.start));\n dist_and_segment.push(Distance.point2point(pt, arc.end));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and line\n * @param seg\n * @param line\n * @returns {Number | Segment}\n */\n static segment2line(seg, line) {\n let ip = seg.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(seg.start, line));\n dist_and_segment.push(Distance.point2line(seg.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n\n }\n\n /**\n * Calculate distance and shortest segment between two segments\n * @param seg1\n * @param seg2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2segment(seg1, seg2) {\n let ip = intersectSegment2Segment(seg1, seg2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n\n // Seg1 and seg2 not intersected\n let dist_and_segment = [];\n let dist_tmp, shortest_segment_tmp;\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.start, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.end, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n dist_and_segment.push(Distance.point2segment(seg1.start, seg2));\n dist_and_segment.push(Distance.point2segment(seg1.end, seg2));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and circle\n * @param seg\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2circle(seg, circle) {\n /* Case 1 Segment and circle intersected. Return the first point and zero distance */\n let ip = seg.intersect(circle);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and circle\n\n /* Case 2. Distance to projection of center point to line bigger than radius\n * And projection point belong to segment\n * Then measure again distance from projection to circle and return it */\n let line = new Flatten.Line(seg.ps, seg.pe);\n let [dist, shortest_segment] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist, circle.r) && shortest_segment.end.on(seg)) {\n return Distance.point2circle(shortest_segment.end, circle);\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n else {\n let [dist_from_start, shortest_segment_from_start] = Distance.point2circle(seg.start, circle);\n let [dist_from_end, shortest_segment_from_end] = Distance.point2circle(seg.end, circle);\n return Flatten.Utils.LT(dist_from_start, dist_from_end) ?\n [dist_from_start, shortest_segment_from_start] :\n [dist_from_end, shortest_segment_from_end];\n }\n }\n\n /**\n * Calculate distance and shortest segment between segment and arc\n * @param seg\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2arc(seg, arc) {\n /* Case 1 Segment and arc intersected. Return the first point and zero distance */\n let ip = seg.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and arc\n let line = new Flatten.Line(seg.ps, seg.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r) && shortest_segment_from_center.end.on(seg)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2arc(seg.start, arc));\n dist_and_segment.push(Distance.point2arc(seg.end, arc));\n\n let dist_tmp, segment_tmp;\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.start, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.end, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle1\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2circle(circle1, circle2) {\n let ip = circle1.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // Case 1. Concentric circles. Convert to arcs and take distance between two arc starts\n if (circle1.center.equalTo(circle2.center)) {\n let arc1 = circle1.toArc();\n let arc2 = circle2.toArc();\n return Distance.point2point(arc1.start, arc2.start);\n } else {\n // Case 2. Not concentric circles\n let line = new Flatten.Line(circle1.center, circle2.center);\n let ip1 = line.intersect(circle1);\n let ip2 = line.intersect(circle2);\n\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[1]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[1]));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2line(circle, line) {\n let ip = circle.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n let [dist, shortest_segment] = Distance.point2circle(shortest_segment_from_center.end, circle);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /**\n * Calculate distance and shortest segment between arc and line\n * @param arc\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2line(arc, line) {\n /* Case 1 Line and arc intersected. Return the first point and zero distance */\n let ip = line.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle = new Flatten.Circle(arc.center, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n } else {\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(arc.start, line));\n dist_and_segment.push(Distance.point2line(arc.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between arc and circle\n * @param arc\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2circle(arc, circle2) {\n let ip = arc.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc.center, arc.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2circle(arc.start, circle2));\n dist_and_segment.push(Distance.point2circle(arc.end, circle2));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two arcs\n * @param arc1\n * @param arc2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2arc(arc1, arc2) {\n let ip = arc1.intersect(arc2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc1.center, arc1.r);\n let circle2 = new Flatten.Circle(arc2.center, arc2.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc1) && shortest_segment.end.on(arc2)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n let dist_tmp, segment_tmp;\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.start, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.end, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.start, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.end, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and polygon\n * @param point\n * @param polygon\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2polygon(point, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = (edge.shape instanceof Flatten.Segment) ?\n Distance.point2segment(point, edge.shape) : Distance.point2arc(point, edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n static shape2polygon(shape, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = shape.distanceTo(edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Calculate distance and shortest segment between two polygons\n * @param polygon1\n * @param polygon2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static polygon2polygon(polygon1, polygon2) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge1 of polygon1.edges) {\n for (let edge2 of polygon2.edges) {\n let [dist, shortest_segment] = edge1.shape.distanceTo(edge2.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Returns [mindist, maxdist] array of squared minimal and maximal distance between boxes\n * Minimal distance by x is\n * (box2.xmin - box1.xmax), if box1 is left to box2\n * (box1.xmin - box2.xmax), if box2 is left to box1\n * 0, if box1 and box2 are intersected by x\n * Minimal distance by y is defined in the same way\n *\n * Maximal distance is estimated as a sum of squared dimensions of the merged box\n *\n * @param box1\n * @param box2\n * @returns {Number | Number} - minimal and maximal distance\n */\n static box2box_minmax(box1, box2) {\n let mindist_x = Math.max(Math.max(box1.xmin - box2.xmax, 0), Math.max(box2.xmin - box1.xmax, 0));\n let mindist_y = Math.max(Math.max(box1.ymin - box2.ymax, 0), Math.max(box2.ymin - box1.ymax, 0));\n let mindist = mindist_x * mindist_x + mindist_y * mindist_y;\n\n let box = box1.merge(box2);\n let dx = box.xmax - box.xmin;\n let dy = box.ymax - box.ymin;\n let maxdist = dx * dx + dy * dy;\n\n return [mindist, maxdist];\n }\n\n static minmax_tree_process_level(shape, level, min_stop, tree) {\n // Calculate minmax distance to each shape in current level\n // Insert result into the interval tree for further processing\n // update min_stop with maxdist, it will be the new stop distance\n let mindist, maxdist;\n for (let node of level) {\n\n // [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n // if (Flatten.Utils.GT(mindist, min_stop))\n // continue;\n\n // Estimate min-max dist to the shape stored in the node.item, using node.item.key which is shape's box\n [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.item.key);\n if (node.item.value instanceof Flatten.Edge) {\n tree.insert([mindist, maxdist], node.item.value.shape);\n } else {\n tree.insert([mindist, maxdist], node.item.value);\n }\n if (Flatten.Utils.LT(maxdist, min_stop)) {\n min_stop = maxdist; // this will be the new distance estimation\n }\n }\n\n if (level.length === 0)\n return min_stop;\n\n // Calculate new level from left and right children of the current\n let new_level_left = level.map(node => node.left.isNil() ? undefined : node.left).filter(node => node !== undefined);\n let new_level_right = level.map(node => node.right.isNil() ? undefined : node.right).filter(node => node !== undefined);\n // Merge left and right subtrees and leave only relevant subtrees\n let new_level = [...new_level_left, ...new_level_right].filter(node => {\n // Node subtree quick reject, node.max is a subtree box\n let [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n return (Flatten.Utils.LE(mindist, min_stop));\n });\n\n min_stop = Distance.minmax_tree_process_level(shape, new_level, min_stop, tree);\n return min_stop;\n }\n\n /**\n * Calculates sorted tree of [mindist, maxdist] intervals between query shape\n * and shapes of the planar set.\n * @param shape\n * @param set\n */\n static minmax_tree(shape, set, min_stop) {\n let tree = new IntervalTree();\n let level = [set.index.root];\n let squared_min_stop = min_stop < Number.POSITIVE_INFINITY ? min_stop * min_stop : Number.POSITIVE_INFINITY;\n squared_min_stop = Distance.minmax_tree_process_level(shape, level, squared_min_stop, tree);\n return tree;\n }\n\n static minmax_tree_calc_distance(shape, node, min_dist_and_segment) {\n let min_dist_and_segment_new, stop;\n if (node != null && !node.isNil()) {\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.left, min_dist_and_segment);\n\n if (stop) {\n return [min_dist_and_segment_new, stop];\n }\n\n if (Flatten.Utils.LT(min_dist_and_segment_new[0], Math.sqrt(node.item.key.low))) {\n return [min_dist_and_segment_new, true]; // stop condition\n }\n\n let [dist, shortest_segment] = Distance.distance(shape, node.item.value);\n // console.log(dist)\n if (Flatten.Utils.LT(dist, min_dist_and_segment_new[0])) {\n min_dist_and_segment_new = [dist, shortest_segment];\n }\n\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.right, min_dist_and_segment_new);\n\n return [min_dist_and_segment_new, stop];\n }\n\n return [min_dist_and_segment, false];\n }\n\n /**\n * Calculates distance between shape and Planar Set of shapes\n * @param shape\n * @param {PlanarSet} set\n * @param {Number} min_stop\n * @returns {*}\n */\n static shape2planarSet(shape, set, min_stop = Number.POSITIVE_INFINITY) {\n let min_dist_and_segment = [min_stop, new Flatten.Segment()];\n let stop = false;\n if (set instanceof Flatten.PlanarSet) {\n let tree = Distance.minmax_tree(shape, set, min_stop);\n [min_dist_and_segment, stop] = Distance.minmax_tree_calc_distance(shape, tree.root, min_dist_and_segment);\n }\n return min_dist_and_segment;\n }\n\n static sort(dist_and_segment) {\n dist_and_segment.sort((d1, d2) => {\n if (Flatten.Utils.LT(d1[0], d2[0])) {\n return -1;\n }\n if (Flatten.Utils.GT(d1[0], d2[0])) {\n return 1;\n }\n return 0;\n });\n }\n\n static distance(shape1, shape2) {\n return shape1.distanceTo(shape2);\n }\n}\n\nFlatten.Distance = Distance;\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\nFlatten.BooleanOperations = BooleanOperations;\nFlatten.Relations = Relations;\n\nexport { Arc, BOUNDARY$1 as BOUNDARY, BooleanOperations, Box, CCW, CW, Circle$1 as Circle, Distance, Edge, Errors, Face, INSIDE$2 as INSIDE, Inversion, Line$1 as Line, Matrix, Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$1 as Point, Polygon, Ray, Relations, Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, line, matrix, multiline, point, polygon, ray, ray_shoot, segment, vector$1 as vector };\n","import type {LatLngExpression} from 'leaflet';\nimport L, {Bounds, LatLng, LatLngBounds, Path, Point, Util} from 'leaflet';\nimport Flatten from '@flatten-js/core';\nimport Matrix = Flatten.Matrix;\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport type {ShapeOptions, TrackSymbolOptions} from './options';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_LEADER_TIME = 60;\n\n/**\n * Track symbol.\n */\nexport class TrackSymbol\n extends Path {\n\n /** Default 'withHeading' shape points. */\n public static DEFAULT_HEADING_SHAPE_POINTS: Points = [[0.75, 0], [-0.25, 0.3], [-0.25, -0.3]];\n\n /** Default 'withoutHeading' shape points. */\n public static DEFAULT_NOHEADING_SHAPE_POINTS: Points = [[0.3, 0], [0, 0.3], [-0.3, 0], [0, -0.3]];\n\n /** Default shape set. */\n private static DEFAULT_SHAPE_SET: ShapeSet = {\n withHeading: {\n points: TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n withoutHeading: {\n points: TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n };\n\n /** Location. */\n private _latLng: LatLng;\n /** Heading (radians, from north, clockwise. */\n private _heading?: number;\n /** Course (radians, from north, clockwise. */\n private _course?: number;\n /** Speed (m/s). */\n private _speed?: number;\n /** Shape options. */\n private _shapeOptions: ShapeOptions;\n\n /** Current shape points. */\n private _currentShapePoints: Point[] | undefined;\n /** Current leader points. */\n private _currentLeaderPoints: Point[] | undefined;\n /** Current bounds. */\n private _currentBounds: Bounds | undefined;\n /** Current lat/lng bounds. */\n private _currentLatLngBounds: LatLngBounds | undefined;\n\n /**\n * TrackSymbol constructor.\n *\n * @param latLng - Initial location.\n * @param options - Options.\n */\n constructor(latLng: LatLngExpression, options?: TrackSymbolOptions) {\n super();\n\n Util.setOptions(this, options);\n if (latLng == undefined) {\n throw Error(\"latLng required\");\n }\n options = options || {};\n this._latLng = L.latLng(latLng);\n this._heading = options.heading;\n this._course = options.course;\n this._speed = options.speed;\n this._shapeOptions = options.shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n this._setShapeOptions(options.shapeOptions);\n }\n\n // ---- Leaflet\n\n /**\n * Project to layer.\n *\n * [Leaflet internal]\n */\n protected _project() {\n this._currentShapePoints = this._getProjectedShapePoints();\n this._currentLeaderPoints = this._getLeaderShapePoints();\n\n const bounds = new Bounds();\n for (let i = 0; i < this._currentShapePoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n if (this._currentLeaderPoints !== undefined) {\n for (let i = 0; i < this._currentLeaderPoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n }\n this._currentBounds = bounds;\n this._currentLatLngBounds = new LatLngBounds(\n this._map.layerPointToLatLng(bounds.getBottomLeft()),\n this._map.layerPointToLatLng(bounds.getTopRight())\n );\n }\n\n /**\n * Update element.\n *\n * [Leaflet internal]\n */\n protected _update() {\n if (!this._map) {\n return;\n }\n const el = this.getElement();\n if (el === undefined) {\n return;\n }\n const paths: string[] = [];\n if (this._currentShapePoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentShapePoints, true));\n }\n if (this._currentLeaderPoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentLeaderPoints, false));\n }\n const viewPath = paths.join(' ');\n el.setAttribute('d', viewPath);\n }\n\n // ----\n\n /**\n * Set shape options.\n *\n * @param shapeOptions - Shape options.\n */\n private _setShapeOptions(shapeOptions: ShapeOptions | undefined) {\n this._shapeOptions = shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n if (this._shapeOptions.leaderTime === undefined) {\n this._shapeOptions.leaderTime = DEFAULT_LEADER_TIME;\n }\n if (this._shapeOptions.defaultShapeSet === undefined) {\n this._shapeOptions.defaultShapeSet = TrackSymbol.DEFAULT_SHAPE_SET;\n }\n if (this._shapeOptions.shapeSetEntries !== undefined) {\n this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel);\n }\n }\n\n // ---\n\n /**\n * Sets the location.\n *\n * @param latLng - Location.\n * @returns this\n */\n public setLatLng(latLng: LatLngExpression): this {\n const oldLatLng = this._latLng;\n this._latLng = L.latLng(latLng);\n this.fire('move', {\n oldLatLng: oldLatLng,\n latlng: this._latLng,\n });\n return this.redraw();\n }\n\n /**\n * Sets the heading.\n *\n * @param heading - Heading (unit: radians, from north, clockwise).\n * @returns this\n */\n public setHeading(heading: number | undefined): this {\n this._heading = heading;\n return this.redraw();\n }\n\n /**\n * Sets the course over ground.\n *\n * @param course - Course over ground (unit: radians, from north, clockwise).\n * @returns this\n */\n public setCourse(course: number | undefined): this {\n this._course = course;\n return this.redraw();\n }\n\n /**\n * Sets the speed.\n *\n * @param speed - Speed (unit: m/s).\n * @returns this\n */\n public setSpeed(speed: number | undefined): this {\n this._speed = speed;\n return this.redraw();\n }\n\n /**\n * Sets the shape options.\n *\n * @param shapeOptions - Shape options.\n * @returns this\n */\n public setShapeOptions(shapeOptions: ShapeOptions): this {\n this._setShapeOptions(shapeOptions);\n return this.redraw();\n }\n\n /**\n * Returns the bounding box.\n *\n * @returns The bounding box.\n */\n public getBounds(): LatLngBounds | undefined {\n return this._currentLatLngBounds;\n }\n\n /**\n * Returns the location.\n *\n * @returns The location.\n */\n public getLatLng(): LatLng {\n return this._latLng;\n }\n\n /**\n * Returns the speed.\n *\n * @returns The speed (m/s).\n */\n public getSpeed(): number | undefined {\n return this._speed;\n }\n\n /**\n * Returns the heading.\n *\n * @returns The heading (radians, from north, clockwise).\n */\n public getHeading(): number | undefined {\n return this._heading;\n }\n\n /**\n * Returns the course.\n *\n * @returns The course (radians, from north, clockwise).\n */\n public getCourse(): number | undefined {\n return this._course;\n }\n\n /**\n * Creates a shape.\n *\n * @param points - Points.\n * @param size - Size (units: pixels).\n * @returns The new shape.\n */\n public static createShape(points: Points, size: number): Shape {\n return {\n points: points,\n length: size,\n breadth: size,\n units: \"pixels\",\n };\n }\n\n /**\n * Creates a shape set.\n *\n * @param size - Size (units: pixels).\n * @returns The new shape set.\n */\n public static createShapeSet(size: number): ShapeSet {\n return {\n withHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS, size),\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n /**\n * Get latitude size of y-distance.\n *\n * @param value - Y distance (m).\n * @returns dLat\n */\n private _getLatSizeOf(value: number): number {\n return (value / 40075017) * 360;\n }\n\n /**\n * Get longitude size of x-distance.\n *\n * @param value - X distance (m).\n * @returns dLng\n */\n private _getLngSizeOf(value: number): number {\n return ((value / 40075017) * 360) / Math.cos((Math.PI / 180) * this._latLng.lat);\n }\n\n /**\n * Get view angle from model.\n *\n * @param modelAngle - Model angle (radians).\n * @returns View angle from model (radians).\n */\n private _getViewAngleFromModel(modelAngle: number): number {\n return modelAngle - Math.PI / 2.0;\n }\n\n /**\n * Get leader shape points.\n *\n * @returns Points.\n */\n private _getLeaderShapePoints(): Point[] | undefined {\n if ((this._course === undefined) || (this._speed === undefined)\n || (this._shapeOptions === undefined) || (this._shapeOptions.leaderTime === undefined)) {\n return undefined;\n }\n const angle = this._getViewAngleFromModel(this._course);\n const leaderLength = this._speed * this._shapeOptions.leaderTime;\n const leaderEndLatLng = this._calcRelativeLatLng(this._latLng, leaderLength, angle);\n return this._latLngsToLayerPoints(this._latLng, leaderEndLatLng);\n }\n\n /**\n * Calculate relative lat/lng.\n *\n * @param latLng - LatLng.\n * @param distance - Distance (meters).\n * @param angle - Angle (radians).\n * @returns Calculated LatLng.\n */\n private _calcRelativeLatLng(latLng: LatLng, distance: number, angle: number): LatLng {\n return new LatLng(\n latLng.lat - this._getLatSizeOf(distance * Math.sin(angle)),\n latLng.lng + this._getLngSizeOf(distance * Math.cos(angle))\n );\n }\n\n /**\n * Convert LatLngs to map layer points.\n *\n * @param latLngs - LatLngs.\n * @returns Points.\n */\n private _latLngsToLayerPoints(...latLngs: LatLng[]): Point[] {\n return latLngs.map(latLng => this._map.latLngToLayerPoint(latLng));\n }\n\n /**\n * Gets the shape set.\n *\n * @returns The shape set.\n */\n private _getShapeSet(): ShapeSet {\n if ((this._shapeOptions.shapeSetEntries === undefined)\n || (this._shapeOptions.shapeSetEntries.length == 0)) {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n const zoomLevel = this._map.getZoom();\n const shapeSetEntriesFiltered = this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel)\n .filter(shapeSetEntry => zoomLevel >= shapeSetEntry.minZoomLevel);\n if (shapeSetEntriesFiltered.length > 0) {\n return shapeSetEntriesFiltered[0].shapeSet;\n } else {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n }\n\n /**\n * Gets the shape.\n *\n * @returns The shape.\n */\n private _getShape(): Shape {\n const shapeSet = this._getShapeSet();\n return (this._heading !== undefined) ? shapeSet.withHeading : shapeSet.withoutHeading;\n }\n\n /**\n * Get transformed shape points.\n *\n * @returns Transformed points and units.\n */\n private _getTransformedShapePoints(): [Points, Units] {\n const shape = this._getShape();\n let m = new Matrix();\n if (this._heading !== undefined) {\n const headingAngle = this._getViewAngleFromModel(this._heading);\n m = m.rotate(headingAngle);\n }\n if (shape.center !== undefined) {\n m = m.translate(-shape.center[0], -shape.center[1]);\n }\n m = m.scale(shape.length, shape.breadth);\n const points = shape.points.map(point => m.transform(point));\n return [points, shape.units];\n }\n\n /**\n * Get projected shape points.\n *\n * @returns Points projected to map layer.\n */\n private _getProjectedShapePoints(): Point[] {\n const [points, units] = this._getTransformedShapePoints();\n switch (units) {\n case \"pixels\": {\n const p = this._map.latLngToLayerPoint(this._latLng);\n const m = new Matrix().translate(p.x, p.y);\n return points.map(point => {\n const p1 = m.transform(point);\n return new Point(p1[0], p1[1]);\n });\n }\n case \"meters\": {\n return points.map(point => this._map.latLngToLayerPoint(\n new LatLng(\n this._latLng.lat - this._getLatSizeOf(point[1]),\n this._latLng.lng + this._getLngSizeOf(point[0])\n )\n ));\n }\n default:\n throw `unsupported units: ${units}`;\n }\n }\n\n /**\n * Converts points to an SVG path string.\n *\n * @param points - Points.\n * @param close - Close path.\n * @returns SVG path string.\n */\n private static _toSVGPath(points: Point[], close: boolean): string {\n let result = '';\n for (let i = 0; i < points.length; i++) {\n const point = points[i];\n if (result === '') {\n result = `M ${point.x} ${point.y} `;\n } else {\n result += `L ${point.x} ${point.y} `;\n }\n }\n if (close) {\n result += 'Z';\n }\n return result;\n }\n}\n","import {TrackSymbol} from '../trackSymbol';\nimport type {ShapeOptions} from '../options';\nimport type {Points, ShapeSet} from '../types';\nimport type {AISTrackSymbolOptions} from './options';\nimport type {Dimension, ETA, PositionReport, ShipStaticData} from './types';\nimport {DomUtil, Util} from 'leaflet';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_MIN_ZOOM_LEVEL = 14;\nconst DEFAULT_LEADER_TIME = 60;\nconst KNOTS_PER_METER_PER_SECOND = 1.944;\nconst MAX_SOG_EXCLUSIVE = 102.3;\nconst MAX_COG_EXCLUSIVE = 360;\nconst MAX_HEADING_EXCLUSIVE = 360;\n\ninterface ShipType {\n name: string;\n color: string;\n fillColor: string;\n}\n\nconst RESERVED_COLOR = \"#000000\";\nconst RESERVED_FILL_COLOR = \"#d3d3d3\";\nconst WIG_COLOR = \"#000000\";\nconst WIG_FILL_COLOR = \"#d3d3d3\";\nconst TYPE_3X_COLOR = \"#8b008b\";\nconst TYPE_3X_FILL_COLOR = \"#ff00ff\";\nconst HSC_COLOR = \"#00008b\";\nconst HSC_FILL_COLOR = \"#ffff00\";\nconst TYPE_5X_COLOR = \"#008b8b\";\nconst TYPE_5X_FILL_COLOR = \"#00ffff\";\nconst PASSENGER_COLOR = \"#00008b\";\nconst PASSENGER_FILL_COLOR = \"#0000ff\";\nconst CARGO_COLOR = \"#006400\";\nconst CARGO_FILL_COLOR = \"#90ee90\";\nconst TANKER_COLOR = \"#8b0000\";\nconst TANKER_FILL_COLOR = \"#ff0000\";\nconst OTHER_COLOR = \"#008b8b\";\nconst OTHER_FILL_COLOR = \"#00ffff\";\n\nconst TYPES: { [key: number]: ShipType } = {\n 0: newShipType('Not available', WIG_COLOR, WIG_FILL_COLOR),\n 20: newShipType('Wing in ground (WIG), all ships of this type', WIG_COLOR, WIG_FILL_COLOR),\n 21: newShipType('Wing in ground (WIG), Hazardous category A', WIG_COLOR, WIG_FILL_COLOR),\n 22: newShipType('Wing in ground (WIG), Hazardous category B', WIG_COLOR, WIG_FILL_COLOR),\n 23: newShipType('Wing in ground (WIG), Hazardous category C', WIG_COLOR, WIG_FILL_COLOR),\n 24: newShipType('Wing in ground (WIG), Hazardous category D', WIG_COLOR, WIG_FILL_COLOR),\n 25: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 26: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 27: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 28: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 29: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 30: newShipType('Fishing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 31: newShipType('Towing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 32: newShipType('Towing: length exceeds 200m or breadth exceeds 25m', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 33: newShipType('Dredging or underwater ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 34: newShipType('Diving ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 35: newShipType('Military ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 36: newShipType('Sailing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 37: newShipType('Pleasure Craft', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 40: newShipType('High speed craft (HSC), all ships of this type', HSC_COLOR, HSC_FILL_COLOR),\n 41: newShipType('High speed craft (HSC), Hazardous category A', HSC_COLOR, HSC_FILL_COLOR),\n 42: newShipType('High speed craft (HSC), Hazardous category B', HSC_COLOR, HSC_FILL_COLOR),\n 43: newShipType('High speed craft (HSC), Hazardous category C', HSC_COLOR, HSC_FILL_COLOR),\n 44: newShipType('High speed craft (HSC), Hazardous category D', HSC_COLOR, HSC_FILL_COLOR),\n 45: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 46: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 47: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 48: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 49: newShipType('High speed craft (HSC), No additional information', HSC_COLOR, HSC_FILL_COLOR),\n 50: newShipType('Pilot Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 51: newShipType('Search and Rescue vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 52: newShipType('Tug', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 53: newShipType('Port Tender', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 54: newShipType('Anti-pollution equipment', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 55: newShipType('Law Enforcement', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 56: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 57: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 58: newShipType('Medical Transport', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 59: newShipType('Noncombatant ship according to RR Resolution No. 18', '', ''),\n 60: newShipType('Passenger, all ships of this type', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 61: newShipType('Passenger, Hazardous category A', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 62: newShipType('Passenger, Hazardous category B', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 63: newShipType('Passenger, Hazardous category C', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 64: newShipType('Passenger, Hazardous category D', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 65: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 66: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 67: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 68: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 69: newShipType('Passenger, No additional information', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 70: newShipType('Cargo, all ships of this type', CARGO_COLOR, CARGO_FILL_COLOR),\n 71: newShipType('Cargo, Hazardous category A', CARGO_COLOR, CARGO_FILL_COLOR),\n 72: newShipType('Cargo, Hazardous category B', CARGO_COLOR, CARGO_FILL_COLOR),\n 73: newShipType('Cargo, Hazardous category C', CARGO_COLOR, CARGO_FILL_COLOR),\n 74: newShipType('Cargo, Hazardous category D', CARGO_COLOR, CARGO_FILL_COLOR),\n 75: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 76: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 77: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 78: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 79: newShipType('Cargo, No additional information', CARGO_COLOR, CARGO_FILL_COLOR),\n 80: newShipType('Tanker, all ships of this type', TANKER_COLOR, TANKER_FILL_COLOR),\n 81: newShipType('Tanker, Hazardous category A', TANKER_COLOR, TANKER_FILL_COLOR),\n 82: newShipType('Tanker, Hazardous category B', TANKER_COLOR, TANKER_FILL_COLOR),\n 83: newShipType('Tanker, Hazardous category C', TANKER_COLOR, TANKER_FILL_COLOR),\n 84: newShipType('Tanker, Hazardous category D', TANKER_COLOR, TANKER_FILL_COLOR),\n 85: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 86: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 87: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 88: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 89: newShipType('Tanker, No additional information', TANKER_COLOR, TANKER_FILL_COLOR),\n 90: newShipType('Other Type, all ships of this type', OTHER_COLOR, OTHER_FILL_COLOR),\n 91: newShipType('Other Type, Hazardous category A', OTHER_COLOR, OTHER_FILL_COLOR),\n 92: newShipType('Other Type, Hazardous category B', OTHER_COLOR, OTHER_FILL_COLOR),\n 93: newShipType('Other Type, Hazardous category C', OTHER_COLOR, OTHER_FILL_COLOR),\n 94: newShipType('Other Type, Hazardous category D', OTHER_COLOR, OTHER_FILL_COLOR),\n 95: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 96: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 97: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 98: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 99: newShipType('Other Type, no additional information', OTHER_COLOR, OTHER_FILL_COLOR),\n};\nconst RESERVED_TYPE = newShipType('Reserved', RESERVED_COLOR, RESERVED_FILL_COLOR);\nconst UNKNOWN_TYPE = newShipType('Unknown', RESERVED_COLOR, RESERVED_FILL_COLOR);\n\nexport class AISTrackSymbol\n extends TrackSymbol {\n\n /** Default silhouette shape points. */\n public static DEFAULT_SILHOUETTE_SHAPE_POINTS: Points = [[1, 0.5], [0.75, 1], [0, 1], [0, 0], [0.75, 0]];\n\n private readonly _leaderTime: number;\n private readonly _minZoomLevel: number;\n private readonly _size: number;\n private _positionReport: PositionReport;\n private _shipStaticData?: ShipStaticData;\n\n /**\n * AISTrackSymbol constructor.\n *\n * @param positionReport - Position report.\n * @param options - Options.\n */\n constructor(positionReport: PositionReport, options?: AISTrackSymbolOptions) {\n super([positionReport.latitude, positionReport.longitude], options);\n\n Util.setOptions(this, options);\n options = options || {};\n this._leaderTime = options.leaderTime || DEFAULT_LEADER_TIME;\n this._minZoomLevel = options.minZoomLevel || DEFAULT_MIN_ZOOM_LEVEL;\n this._size = options.size || DEFAULT_SIZE;\n this._positionReport = positionReport;\n this.setPositionReport(positionReport);\n this.setShipStaticData(options.shipStaticData);\n }\n\n /**\n * Get ETA from Date.\n *\n * @param date - Date.\n * @returns ETA\n */\n public static etaFromDate(date: Date | null | undefined): ETA | undefined {\n if ((date === null) || (date === undefined)) {\n return undefined;\n }\n return {\n month: date.getMonth() + 1,\n day: date.getDate(),\n hour: date.getHours(),\n minute: date.getMinutes(),\n }\n }\n\n /**\n * Sets the position report.\n *\n * @param positionReport - Position report.\n * @returns this\n */\n public setPositionReport(positionReport: PositionReport): this {\n this._positionReport = positionReport;\n this.setLatLng([positionReport.latitude, positionReport.longitude]);\n if ((positionReport.trueHeading !== null) && (positionReport.trueHeading !== undefined) && (positionReport.trueHeading < MAX_HEADING_EXCLUSIVE)) {\n this.setHeading(toRadians(positionReport.trueHeading));\n } else {\n this.setHeading(undefined);\n }\n if ((positionReport.cog !== null) && (positionReport.cog !== undefined) && (positionReport.cog < MAX_COG_EXCLUSIVE)) {\n this.setCourse(toRadians(positionReport.cog));\n } else {\n this.setCourse(undefined);\n }\n if ((positionReport.sog !== null) && (positionReport.sog !== undefined) && (positionReport.sog < MAX_SOG_EXCLUSIVE)) {\n this.setSpeed(positionReport.sog / KNOTS_PER_METER_PER_SECOND);\n } else {\n this.setSpeed(undefined);\n }\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.redraw();\n }\n\n /**\n * Sets the ship static data.\n *\n * @param shipStaticData - Ship static data.\n * @returns this\n */\n public setShipStaticData(shipStaticData?: ShipStaticData): this {\n this._shipStaticData = shipStaticData;\n const shipType = getShipType((shipStaticData !== null) && (shipStaticData !== undefined) ? shipStaticData.type : undefined);\n this.setStyle({\n color: shipType.color,\n fill: true,\n fillOpacity: 1.0,\n fillColor: shipType.fillColor,\n });\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.setShapeOptions(AISTrackSymbol._getShapeOptions(this._leaderTime, this._minZoomLevel, this._size,\n shipStaticData));\n }\n\n private static _getShapeOptions(leaderTime: number, minZoomLevel: number, size: number,\n shipStaticData?: ShipStaticData): ShapeOptions {\n const shapeOptions: ShapeOptions = {\n leaderTime: leaderTime,\n defaultShapeSet: TrackSymbol.createShapeSet(size),\n };\n const shapeSet = AISTrackSymbol._getShapeSet(size, shipStaticData);\n if (shapeSet !== null) {\n shapeOptions.shapeSetEntries = [{\n shapeSet: shapeSet,\n minZoomLevel: minZoomLevel,\n }];\n }\n return shapeOptions;\n }\n\n private static _getShapeSet(size: number, shipStaticData?: ShipStaticData): ShapeSet | null {\n if ((shipStaticData === null) || (shipStaticData === undefined)\n || (shipStaticData.dimension === null) || (shipStaticData.dimension === undefined)\n || !isDimensionValid(shipStaticData.dimension)) {\n return null;\n }\n return {\n withHeading: {\n points: AISTrackSymbol.DEFAULT_SILHOUETTE_SHAPE_POINTS,\n center: [shipStaticData.dimension.B, shipStaticData.dimension.D],\n length: shipStaticData.dimension.A + shipStaticData.dimension.B,\n breadth: shipStaticData.dimension.C + shipStaticData.dimension.D,\n units: \"meters\",\n },\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n private _getPopupContent(positionReport?: PositionReport, shipStaticData?: ShipStaticData): HTMLElement {\n let content = \"\";\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"User ID\", shipStaticData.userId);\n content += createTableRow(\"IMO Number\", shipStaticData.imoNumber);\n content += createTableRow(\"Call sign\", shipStaticData.callSign);\n content += createTableRow(\"Name\", shipStaticData.name);\n }\n if ((positionReport !== null) && (positionReport !== undefined)) {\n content += createTableRow(\"Location\", `${toFixed(positionReport.latitude, 5)}, ${toFixed(positionReport.longitude, 5)}`);\n content += createTableRow(\"SOG\",\n toFixed(positionReport.sog, 2, v => v < MAX_SOG_EXCLUSIVE), \"knots\");\n content += createTableRow(\"COG\",\n toFixed(positionReport.cog, 1), \"°\");\n content += createTableRow(\"Heading\",\n toFixed(positionReport.trueHeading, 1), \"°\");\n content += createTableRow(\"Navigation status\",\n toNavigationStatusString(positionReport.navigationalStatus));\n }\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"Type\", toTypeString(shipStaticData.type));\n if ((shipStaticData.dimension !== null) && (shipStaticData.dimension !== undefined)\n && isDimensionValid(shipStaticData.dimension)) {\n content += createTableRow(\"Ship length\",\n shipStaticData.dimension.A + shipStaticData.dimension.B, \"m\");\n content += createTableRow(\"Ship width\",\n shipStaticData.dimension.C + shipStaticData.dimension.D, \"m\");\n }\n content += createTableRow(\"Fix type\", toFixTypeString(shipStaticData.fixType));\n content += createTableRow(\"ETA\", toETAString(shipStaticData.eta));\n content += createTableRow(\"Maximum static draught\",\n toFixed(shipStaticData.maximumStaticDraught, 1), \"m\");\n content += createTableRow(\"Destination\", shipStaticData.destination);\n content += createTableRow(\"DTE\", shipStaticData.dte);\n }\n content += \"
\";\n const popupContent = DomUtil.create(\"div\");\n popupContent.innerHTML = content;\n return popupContent;\n }\n}\n\nfunction toFixed(v: number | null | undefined, fractionDigits?: number, isValid?: (v: number) => boolean): string | undefined {\n if ((v === null) || (v === undefined)) {\n return undefined;\n }\n if (isValid && !isValid(v)) {\n return undefined;\n }\n return v.toFixed(fractionDigits);\n}\n\nfunction toTypeString(type: number | null | undefined): string | undefined {\n if ((type === null) || (type === undefined)) {\n return undefined;\n }\n const shipType = getShipType(type);\n return shipType.name;\n}\n\nfunction toFixTypeString(fixType: number | null | undefined): string | undefined {\n if ((fixType === null) || (fixType === undefined)) {\n return undefined;\n }\n switch (fixType) {\n case 0:\n return undefined;\n case 1:\n return 'GPS';\n case 2:\n return 'GLONASS';\n case 3:\n return 'combined GPS/GLONASS';\n case 4:\n return 'Loran-C';\n case 5:\n return 'Chayka';\n case 6:\n return 'integrated navigation system';\n case 7:\n return 'surveyed';\n case 8:\n return 'Galileo';\n case 9:\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n return `not used (${fixType})`;\n case 15:\n return \"internal GNSS\";\n default:\n return `unknown (${fixType})`;\n }\n}\n\nfunction toNavigationStatusString(navigationStatus: number | null | undefined): string | undefined {\n if ((navigationStatus === null) || (navigationStatus === undefined)) {\n return undefined;\n }\n switch (navigationStatus) {\n case 0:\n return 'Under way using engine';\n case 1:\n return 'At anchor';\n case 2:\n return 'Not under command';\n case 3:\n return 'Restricted manoeuverability';\n case 4:\n return 'Constrained by her draught';\n case 5:\n return 'Moored';\n case 6:\n return 'Aground';\n case 7:\n return 'Engaged in Fishing';\n case 8:\n return 'Under way sailing';\n case 9:\n return 'Reserved for future amendment of Navigational Status for HSC';\n case 10:\n return 'Reserved for future amendment of Navigational Status for WIG';\n case 11:\n return 'Reserved for future use';\n case 12:\n return 'Reserved for future use';\n case 13:\n return 'Reserved for future use';\n case 14:\n return 'AIS-SART is active';\n case 15:\n return 'Not defined (default)';\n default:\n return `unknown (${navigationStatus})`;\n }\n}\n\nfunction toETAString(eta: ETA | null | undefined): string | undefined {\n if ((eta === null) || (eta === undefined)) {\n return undefined;\n }\n const parts: string[] = [];\n if (!isNullOrUndefined(eta.month) && !isNullOrUndefined(eta.day)) {\n parts.push(`${eta.month.toString().padStart(2, '0')}/${eta.day.toString().padStart(2, '0')}`);\n }\n if (!isNullOrUndefined(eta.hour) && !isNullOrUndefined(eta.minute)) {\n parts.push(`${eta.hour.toString().padStart(2, '0')}:${eta.minute.toString().padStart(2, '0')}`);\n }\n if (parts.length === 0) {\n return undefined;\n }\n return `${parts.join(' ')} UTC`;\n}\n\nfunction toRadians(degs: number | null | undefined): number | undefined {\n if ((degs === null) || (degs === undefined)) {\n return undefined;\n }\n return degs * Math.PI / 180;\n}\n\nfunction isNullOrUndefined(v: any): boolean {\n return (v === null) || (v === undefined);\n}\n\nfunction isDimensionValid(dimension: Dimension | null | undefined): boolean {\n return (dimension !== null) && (dimension !== undefined)\n && (dimension.A > 0) && (dimension.B > 0) && (dimension.C > 0) && (dimension.D > 0);\n}\n\nfunction createTableRow(name: string, value: any, unit?: string): string {\n if ((value === null) || (value === undefined)) {\n return '';\n }\n const sValue = String(value);\n return `${name}${sValue} ${isNullOrUndefined(unit) ? \"\" : unit}`;\n}\n\nfunction newShipType(name: string, color: string, fillColor: string): ShipType {\n return {\n name: name,\n color: color,\n fillColor: fillColor,\n };\n}\n\nfunction getShipType(type: number | null | undefined): ShipType {\n if ((type === null) || (type === undefined)) {\n return TYPES[0];\n }\n if ((type < 0) || (type > 99)) {\n return UNKNOWN_TYPE;\n }\n const shipType = TYPES[type];\n if (!isNullOrUndefined(shipType)) {\n return shipType;\n }\n return RESERVED_TYPE;\n}\n","//@ts-strict-ignore\nimport L from 'leaflet';\nimport type {LatLngExpression} from 'leaflet';\nimport {TrackSymbol} from './trackSymbol';\nimport type {ShapeSetEntry, ShapeOptions, TrackSymbolOptions} from './options';\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport {AISTrackSymbol} from './ais/aisTrackSymbol';\nimport type {AISTrackSymbolOptions} from './ais/options';\nimport type {AISMessage, Dimension, ETA, PositionReport, ShipStaticData} from './ais/types';\n\nexport {\n Points,\n Shape,\n ShapeOptions,\n ShapeSet,\n ShapeSetEntry,\n TrackSymbol,\n TrackSymbolOptions,\n Units,\n};\n\nexport {\n AISMessage,\n AISTrackSymbol,\n AISTrackSymbolOptions,\n Dimension,\n ETA,\n PositionReport,\n ShipStaticData,\n};\n\nL['trackSymbol'] = function(latLng: LatLngExpression, options?: TrackSymbolOptions): TrackSymbol {\n return new TrackSymbol(latLng, options);\n}\nL['TrackSymbol'] = TrackSymbol;\n\nL['aisTrackSymbol'] = function(positionReport: PositionReport, options?: AISTrackSymbolOptions): AISTrackSymbol {\n return new AISTrackSymbol(positionReport, options);\n}\nL['AISTrackSymbol'] = AISTrackSymbol;\n\nexport default TrackSymbol;\n"],"names":["CCW","CW","ORIENTATION","PIx2","INSIDE$2","OUTSIDE$1","BOUNDARY$1","CONTAINS","INTERLACE","OVERLAP_SAME$1","OVERLAP_OPPOSITE$1","NOT_VERTEX$1","START_VERTEX$1","END_VERTEX$1","Constants","DP_TOL","setTolerance","tolerance","getTolerance","DECIMALS","EQ_0","x","EQ","y","GT","GE","LT","LE","Utils$1","Flatten","c","value","Errors","LinkedList","first","last","counter","edge","start","end","elements","from","to","element","newElement","elementBefore","elementAfter","controlEdge","addToIntPoints","pt","int_points","id","shapes","len","is_vertex","arc_length","sortIntersections","intersections","getSortedArray","faceMap","ip","compareFn","ip1","ip2","filterDuplicatedIntersections","do_squeeze","int_point_ref1","int_point_ref2","int_point_cur1","int_point_cur2","i","j","int_point","index","initializeInclusionFlags","calculateInclusionFlags","polygon","setOverlappingFlags","cur_face","first_int_point_in_face_id","next_int_point1","num_int_points","cur_int_point1","int_points_cur_pool_start","int_points_cur_pool_num","intPointsPoolCount","next_int_point_id","int_points_next_pool_num","next_int_point1_tmp","edge_from1","edge_to1","cur_int_point2","next_int_point2","edge_from2","edge_to2","cur_int_point_num","int_point_current","int_point_next","int_points_pool_num","splitByIntersections","newEdge","insertBetweenIntPoints","int_point1","int_point2","new_edges","edge_before","edge_after","INSIDE$1","OUTSIDE","BOUNDARY","OVERLAP_SAME","OVERLAP_OPPOSITE","NOT_VERTEX","START_VERTEX","END_VERTEX","BOOLEAN_UNION","BOOLEAN_INTERSECT","BOOLEAN_SUBTRACT","unify","polygon1","polygon2","res_poly","wrk_poly","booleanOpBinary","subtract","polygon2_reversed","intersect$1","innerClip","clip_shapes1","face","clip_shapes2","outerClip","calculateIntersections","getIntersections","ip_sorted1","ip_sorted2","filterNotRelevantEdges","op","notIntersectedFacesRes","getNotIntersectedFaces","notIntersectedFacesWrk","calcInclusionForNotIntersectedFaces","fixBoundaryConflicts","removeNotRelevantChains","removeNotRelevantNotIntersectedFaces","swapLinksAndRestore","copyWrkToRes","swapLinks","removeOldFaces","restoreFaces","restore","edge1","resp","edge2","poly","notIntersected","notIntersectedFaces","poly2","poly1","int_points1","int_points1_sorted","int_points2","iterate_more","edge_tmp","new_bv","dist","segment","newEdge1","int_point2_edge_after","newEdge2","is_res_polygon","first_int_point_in_face_num","int_points_from_pull_start","int_points_from_pull_num","next_int_point_num","int_points_to_pull_start","int_points_to_pull_num","edge_from","edge_to","k","res_polygon","wrk_polygon","other_int_points","int_point_tmp","rel","BooleanOperations","EQUAL","INTERSECT","TOUCH","INSIDE","COVERED","DE9IM","geom","e","intersectLine2Line","line1","line2","A1","B1","C1","A2","B2","C2","det","detX","detY","intersectLine2Circle","line","circle","prj","delta","v_trans","intersectLine2Box","box","ips","seg","ips_tmp","intersectSegment2Line","ptInIntPoints","intersectLine2Arc","arc","ip_tmp","intersectSegment2Segment","seg1","seg2","new_ip","isPointInSegmentBox","point","intersectSegment2Circle","_","intersectSegment2Arc","intersectSegment2Box","intersectCircle2Circle","circle1","circle2","vec","r1","r2","a","mid_pt","h","intersectCircle2Box","intersectArc2Arc","arc1","arc2","intersectArc2Circle","intersectArc2Box","intersectEdge2Segment","intersectEdge2Arc","intersectEdge2Line","intersectEdge2Ray","ray","intersectRay2Segment","intersectRay2Arc","intersectEdge2Circle","intersectSegment2Polygon","intersectArc2Polygon","intersectLine2Polygon","intersectCircle2Polygon","intersectEdge2Edge","intersectEdge2Polygon","resp_edges","resp_edge","intersectPolygon2Polygon","intersectShape2Polygon","shape","new_pt","createLineFromRay","intersectRay2Circle","intersectRay2Box","intersectRay2Line","intersectRay2Ray","ray1","ray2","intersectRay2Polygon","defaultAttributes","SVGAttributes","args","property","acc","key","SVGKey","str","convertToString","attrs","Multiline","v","edgeBefore","edgeFrom","edgeTo","edges","edgeFound","angle","center","matrix","svgStr","multiline","ray_shoot","contains","searchBox","faces","i1","i2","intersection","prev_edge","prev_tangent","prev_point","cur_tangent","cur_point","prev_on_the_left","cur_on_the_left","next_edge","next_tangent","next_point","next_on_the_left","equal","shape1","shape2","relate","intersect","touch","disjoint","inside","covered","contain","cover","relateLine2Line","relateLine2Circle","relateLine2Box","relateLine2Polygon","relateShape2Polygon","relatePolygon2Polygon","denim","ip_sorted","splitShapes","boolean_intersection","boolean_difference1","boolean_difference2","inner_clip_shapes1","inner_clip_shapes2","outer_clip_shapes1","outer_clip_shapes2","Relations","Matrix$1","Matrix","b","d","tx","ty","vector","other_matrix","centerX","centerY","cos","sin","sx","sy","Interval","low","high","other_interval","interval1","interval2","val1","val2","RB_TREE_COLOR_RED","RB_TREE_COLOR_BLACK","Node","left","right","parent","color","other_node","comparable_max","search_node","comparable_less_than","IntervalTree","count","res","node","insert_node","delete_node","interval","outputMapperFn","resp_nodes","visitor","callback","tree","node_current","current_node","parent_node","uncle_node","cut_node","fix_node","brother_node","found","node_min","node_max","node_successor","action","height","heightLeft","heightRight","PlanarSet","entry","size","deleted","Shape","Point$1","Point","arr","m","proj_vec","dx","dy","r","Vector$1","a1","a2","scalar","norm1","norm2","n","vector$1","Segment","coords","ps","pe","shortest_segment","length","factor","rest","ymin","dy1","dy2","pts","Line$1","Line","norm","A","B","C","other_line","distance","sorted_points","pt1","pt2","Circle$1","pc","counterclockwise","Arc","startAngle","endAngle","counterClockwise","sweep","test_arc","func_arcs_array","angles","test_arcs","prev_arc","new_arc","newStart","newEnd","newCenter","newDirection","onLeftSide","areaTrapez","areaCircularSegment","slope1","slope2","largeArcFlag","sweepFlag","Box","xmin","xmax","ymax","other_box","box1","box2","new_box","vertex","width","Edge","bvMiddle","flag","sign","halfArc1","halfArc2","CircularLinkedList","done","Face","segments","points","flattenShapes","flattenShape","sArea","area","exitOnFirst","Ray","slope","Polygon","argsArray","loop","el","loop1","valid","signedArea","unassignedEdgeFound","edge_next","newPoly","int_point1_prev","int_point1_curr","newEdges","polygons","orientation","newPolygons","islandPolygon","min_dist_and_segment","min_stop","newPolygon","Circle","Vector","Utils","Inversion","inversion_circle","k2","len2","s","inversion","Distance","closest_point","dist2center","shortest_dist","v_seg","v_ps2pt","v_pe2pt","start_sp","end_sp","v_unit","dist_and_segment","dist_tmp","shortest_segment_tmp","dist_from_start","shortest_segment_from_start","dist_from_end","shortest_segment_from_end","dist_from_center","shortest_segment_from_center","dist_from_projection","shortest_segment_from_projection","segment_tmp","mindist_x","mindist_y","mindist","maxdist","level","new_level_left","new_level_right","new_level","set","squared_min_stop","min_dist_and_segment_new","stop","d1","d2","DEFAULT_SIZE","DEFAULT_LEADER_TIME","_TrackSymbol","Path","latLng","options","Util","L","bounds","Bounds","LatLngBounds","paths","viewPath","shapeOptions","oldLatLng","heading","course","speed","modelAngle","leaderLength","leaderEndLatLng","LatLng","latLngs","zoomLevel","shapeSetEntriesFiltered","shapeSetEntry","shapeSet","headingAngle","units","p","p1","close","result","TrackSymbol","DEFAULT_MIN_ZOOM_LEVEL","KNOTS_PER_METER_PER_SECOND","MAX_SOG_EXCLUSIVE","MAX_COG_EXCLUSIVE","MAX_HEADING_EXCLUSIVE","RESERVED_COLOR","RESERVED_FILL_COLOR","WIG_COLOR","WIG_FILL_COLOR","TYPE_3X_COLOR","TYPE_3X_FILL_COLOR","HSC_COLOR","HSC_FILL_COLOR","TYPE_5X_COLOR","TYPE_5X_FILL_COLOR","PASSENGER_COLOR","PASSENGER_FILL_COLOR","CARGO_COLOR","CARGO_FILL_COLOR","TANKER_COLOR","TANKER_FILL_COLOR","OTHER_COLOR","OTHER_FILL_COLOR","TYPES","newShipType","RESERVED_TYPE","UNKNOWN_TYPE","_AISTrackSymbol","positionReport","date","toRadians","shipStaticData","shipType","getShipType","leaderTime","minZoomLevel","isDimensionValid","content","createTableRow","toFixed","toNavigationStatusString","toTypeString","toFixTypeString","toETAString","popupContent","DomUtil","AISTrackSymbol","fractionDigits","isValid","type","fixType","navigationStatus","eta","parts","isNullOrUndefined","degs","dimension","name","unit","sValue","fillColor"],"mappings":"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","x_google_ignoreList":[0]} \ No newline at end of file diff --git a/dist/leaflet-tracksymbol2.umd.js b/dist/leaflet-tracksymbol2.umd.js index 4c5c4f1..2ca708a 100644 --- a/dist/leaflet-tracksymbol2.umd.js +++ b/dist/leaflet-tracksymbol2.umd.js @@ -1,19 +1,19 @@ -(function(X,I){typeof exports=="object"&&typeof module<"u"?I(exports,require("leaflet")):typeof define=="function"&&define.amd?define(["exports","leaflet"],I):(X=typeof globalThis<"u"?globalThis:X||self,I(X["leaflet-tracksymbol2"]={},X.L))})(this,function(X,I){"use strict";const Ht={CCW:-1,CW:1,NOT_ORIENTABLE:0},dn=2*Math.PI,$t=1,ve=0,M=2,gn=3,_n=4,pn=1,mn=2,Kt=0,qt=1,ct=2;var Gt=Object.freeze({__proto__:null,BOUNDARY:M,CCW:!0,CONTAINS:gn,CW:!1,END_VERTEX:ct,INSIDE:$t,INTERLACE:_n,NOT_VERTEX:Kt,ORIENTATION:Ht,OUTSIDE:ve,OVERLAP_OPPOSITE:mn,OVERLAP_SAME:pn,PIx2:dn,START_VERTEX:qt});let k=1e-6;function we(r){k=r}function Te(){return k}const xn=3;function Jt(r){return r-k}function lt(r,t){return r-t-k}function Se(r,t){return r-t>k}function En(r,t){return r-t>-k}function ye(r,t){return r-t<-k}function vn(r,t){return r-t(t=t?t.next:this.first,{value:t,done:t===void 0})}}get size(){let t=0;for(let e of this)t++;return t}toArray(t=void 0,e=void 0){let n=[],s=t||this.first,l=e||this.last,o=s;if(o===void 0)return n;do n.push(o),o=o.next;while(o!==l.next);return n}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,e){if(this.isEmpty())this.first=t,this.last=t;else if(e==null)t.next=this.first,this.first.prev=t,this.first=t;else{let n=e.next;e.next=t,n&&(n.prev=t),t.prev=e,t.next=n,this.last===e&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return this.first===void 0}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t&&e===n)throw E.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}}function dt(r,t,e){let n=e.length,s=r.shape.split(t);if(s.length===0)return;let l=0;s[0]===null?l=0:s[1]===null?l=r.shape.length:l=s[0].length;let o=Kt;lt(l,0)&&(o|=qt),lt(l,r.shape.length)&&(o|=ct);let a;l===1/0?a=s[0].coord(t):a=o&ct&&r.next&&r.next.arc_length===0?0:r.arc_length+l,e.push({id:n,pt:t,arc_length:a,edge_before:r,edge_after:void 0,face:r.face,is_vertex:o})}function Pt(r){r.int_points1_sorted=tt(r.int_points1),r.int_points2_sorted=tt(r.int_points2)}function tt(r){let t=new Map,e=0;for(let s of r)t.has(s.face)||(t.set(s.face,e),e++);for(let s of r)s.faceId=t.get(s.face);return r.slice().sort(Tn)}function Tn(r,t){return r.faceIdt.faceId?1:r.arc_lengtht.arc_length?1:0}function ee(r){if(r.int_points1.length<2)return;let t=!1,e,n,s,l;for(let o=0;oo.id>=0),r.int_points2=r.int_points2.filter(o=>o.id>=0),r.int_points1.forEach((o,a)=>o.id=a),r.int_points2.forEach((o,a)=>o.id=a))}function ne(r){for(let t of r)t.edge_before&&(t.edge_before.bvStart=void 0,t.edge_before.bvEnd=void 0,t.edge_before.bv=void 0,t.edge_before.overlap=void 0),t.edge_after&&(t.edge_after.bvStart=void 0,t.edge_after.bvEnd=void 0,t.edge_after.bv=void 0,t.edge_after.overlap=void 0);for(let t of r)t.edge_before&&(t.edge_before.bvEnd=M),t.edge_after&&(t.edge_after.bvStart=M)}function ie(r,t){for(let e of r)e.edge_before&&e.edge_before.setInclusion(t),e.edge_after&&e.edge_after.setInclusion(t)}function Sn(r){let t,e,n,s=r.int_points1.length;for(let l=0;la.shape)];let l=[];for(let o of n.faces)l=[...l,...[...o.edges].map(a=>a.shape)];return[s,l]}function se(r,t){let[e,n]=Ot(r,t,at,!1),s=[];for(let l of e.faces)s=[...s,...[...l.edges].map(o=>o.shape)];return s}function Oe(r,t){let e=r.clone(),n=t.clone(),s=Ce(e,n);Pt(s),_t(e,s.int_points1_sorted),_t(n,s.int_points2_sorted),ee(s),Pt(s);let l=s.int_points1_sorted.map(a=>a.pt),o=s.int_points2_sorted.map(a=>a.pt);return[l,o]}function An(r,t,e,n){let s=Ne(r,e.int_points1),l=Ne(t,e.int_points2);for(Re(s,t),Re(l,r),ne(e.int_points1),ne(e.int_points2),ie(e.int_points1,t),ie(e.int_points2,r);Ln(r,t,e.int_points1,e.int_points1_sorted,e.int_points2,e););Sn(e),oe(r,n,e.int_points1_sorted,!0),oe(t,n,e.int_points2_sorted,!1),Ue(r,s,n,!0),Ue(t,l,n,!1)}function Pn(r,t,e,n){On(r,t,n,e.int_points2),Cn(r,t,e),le(r,e.int_points1),le(t,e.int_points2),ae(r,e.int_points1,e.int_points2),ae(r,e.int_points2,e.int_points1)}function Ot(r,t,e,n){let s=r.clone(),l=t.clone(),o=Ce(s,l);return Pt(o),_t(s,o.int_points1_sorted),_t(l,o.int_points2_sorted),ee(o),Pt(o),An(s,l,o,e),n&&Pn(s,l,o,e),[s,l]}function Ce(r,t){let e={int_points1:[],int_points2:[]};for(let n of r.edges){let s=t.edges.search(n.box);for(let l of s){let o=n.shape.intersect(l.shape);for(let a of o)dt(n,a,e.int_points1),dt(l,a,e.int_points2)}}return e}function Ne(r,t){let e=[];for(let n of r.faces)t.find(s=>s.face===n)||e.push(n);return e}function Re(r,t){for(let e of r)e.first.bv=e.first.bvStart=e.first.bvEnd=void 0,e.first.setInclusion(t)}function Ln(r,t,e,n,s,l){let o,a,h,u=n.length,f=!1;for(let g=0;gki.edge_after===bt),U=t.addVertex(ot.pt,bt);ot.edge_before=U,ot.edge_after=U.next,Z&&(Z.edge_after=U),U.bvStart=void 0,U.bvEnd=b,U.bv=void 0,U.setInclusion(r),U.next.bvStart=b,U.next.bvEnd=void 0,U.next.bv=void 0,U.next.setInclusion(r)}Pt(l),f=!0;break}}_=_.next}if(f)break;throw E.UNRESOLVED_BOUNDARY_CONFLICT}}return f}function oe(r,t,e,n){if(!e)return;let s,l,o,a;for(let h=0;hl.face===s)===void 0&&r.addFace(s.first,s.last)}}function Cn(r,t,e){if(e.int_points1.length!==0)for(let n=0;nt instanceof Array&&t.length>0?"T":t instanceof Array&&t.length===0?"F":"*").join("")}equal(){return Rn.test(this.toString())}intersect(){return Un.test(this.toString())}touch(){return Mn.test(this.toString())}inside(){return kn.test(this.toString())}covered(){return Bn.test(this.toString())}}function mt(r,t){let e=[],[n,s,l]=r.standard,[o,a,h]=t.standard,u=n*a-s*o,f=l*a-s*h,g=n*h-l*o;if(!i.Utils.EQ_0(u)){let x,y;s===0?(x=l/n,y=g/u):a===0?(x=h/o,y=g/u):n===0?(x=f/u,y=l/s):o===0?(x=f/u,y=h/a):(x=f/u,y=g/u),e.push(new i.Point(x,y))}return e}function ft(r,t){let e=[],n=t.pc.projectionOn(r),s=t.pc.distanceTo(n)[0];if(i.Utils.EQ(s,t.r))e.push(n);else if(i.Utils.LT(s,t.r)){let l=Math.sqrt(t.r*t.r-s*s),o,a;o=r.norm.rotate90CCW().multiply(l),a=n.translate(o),e.push(a),o=r.norm.rotate90CW().multiply(l),a=n.translate(o),e.push(a)}return e}function xt(r,t){let e=[];for(let n of t.toSegments()){let s=Ct(n,r);for(let l of s)Ge(l,e)||e.push(l)}return e}function zt(r,t){let e=[];if(xt(r,t.box).length===0)return e;let n=new i.Circle(t.pc,t.r),s=ft(r,n);for(let l of s)l.on(t)&&e.push(l);return e}function Ct(r,t){let e=[];if(r.ps.on(t)&&e.push(r.ps),r.pe.on(t)&&!r.isZeroLength()&&e.push(r.pe),e.length>0||r.isZeroLength()||r.ps.leftTo(t)&&r.pe.leftTo(t)||!r.ps.leftTo(t)&&!r.pe.leftTo(t))return e;let n=new i.Line(r.ps,r.pe);return mt(n,t)}function Qt(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.isZeroLength())return r.ps.on(t)&&e.push(r.ps),e;if(t.isZeroLength())return t.ps.on(r)&&e.push(t.ps),e;let n=new i.Line(r.ps,r.pe),s=new i.Line(t.ps,t.pe);if(n.incidentTo(s))r.ps.on(t)&&e.push(r.ps),r.pe.on(t)&&e.push(r.pe),t.ps.on(r)&&!t.ps.equalTo(r.ps)&&!t.ps.equalTo(r.pe)&&e.push(t.ps),t.pe.on(r)&&!t.pe.equalTo(r.ps)&&!t.pe.equalTo(r.pe)&&e.push(t.pe);else{let l=mt(n,s);l.length>0&&Me(l[0],r)&&Me(l[0],t)&&e.push(l[0])}return e}function Me(r,t){const e=t.box;return i.Utils.LE(r.x,e.xmax)&&i.Utils.GE(r.x,e.xmin)&&i.Utils.LE(r.y,e.ymax)&&i.Utils.GE(r.y,e.ymin)}function Wt(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.isZeroLength()){let[l,o]=r.ps.distanceTo(t.pc);return i.Utils.EQ(l,t.r)&&e.push(r.ps),e}let n=new i.Line(r.ps,r.pe),s=ft(n,t);for(let l of s)l.on(r)&&e.push(l);return e}function Et(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.isZeroLength())return r.ps.on(t)&&e.push(r.ps),e;let n=new i.Line(r.ps,r.pe),s=new i.Circle(t.pc,t.r),l=ft(n,s);for(let o of l)o.on(r)&&o.on(t)&&e.push(o);return e}function Fn(r,t){let e=[];for(let n of t.toSegments()){let s=Qt(n,r);for(let l of s)e.push(l)}return e}function ke(r,t){let e=[];if(r.box.not_intersect(t.box))return e;let n=new i.Vector(r.pc,t.pc),s=r.r,l=t.r;if(i.Utils.EQ_0(s)||i.Utils.EQ_0(l))return e;if(i.Utils.EQ_0(n.x)&&i.Utils.EQ_0(n.y)&&i.Utils.EQ(s,l))return e.push(r.pc.translate(-s,0)),e;let o=r.pc.distanceTo(t.pc)[0];if(i.Utils.GT(o,s+l)||i.Utils.LT(o,Math.abs(s-l)))return e;n.x/=o,n.y/=o;let a;if(i.Utils.EQ(o,s+l)||i.Utils.EQ(o,Math.abs(s-l)))return a=r.pc.translate(s*n.x,s*n.y),e.push(a),e;let h=s*s/(2*o)-l*l/(2*o)+o/2,u=r.pc.translate(h*n.x,h*n.y),f=Math.sqrt(s*s-h*h);return a=u.translate(n.rotate90CCW().multiply(f)),e.push(a),a=u.translate(n.rotate90CW().multiply(f)),e.push(a),e}function Vn(r,t){let e=[];for(let n of t.toSegments()){let s=Wt(n,r);for(let l of s)e.push(l)}return e}function Be(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.pc.equalTo(t.pc)&&i.Utils.EQ(r.r,t.r)){let o;return o=r.start,o.on(t)&&e.push(o),o=r.end,o.on(t)&&e.push(o),o=t.start,o.on(r)&&e.push(o),o=t.end,o.on(r)&&e.push(o),e}let n=new i.Circle(r.pc,r.r),s=new i.Circle(t.pc,t.r),l=n.intersect(s);for(let o of l)o.on(r)&&o.on(t)&&e.push(o);return e}function fe(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(t.pc.equalTo(r.pc)&&i.Utils.EQ(t.r,r.r))return e.push(r.start),e.push(r.end),e;let n=t,s=new i.Circle(r.pc,r.r),l=ke(n,s);for(let o of l)o.on(r)&&e.push(o);return e}function Hn(r,t){let e=[];for(let n of t.toSegments()){let s=Et(n,r);for(let l of s)e.push(l)}return e}function Fe(r,t){return r.isSegment?Qt(r.shape,t):Et(t,r.shape)}function Ve(r,t){return r.isSegment?Et(r.shape,t):Be(r.shape,t)}function He(r,t){return r.isSegment?Ct(r.shape,t):zt(t,r.shape)}function $n(r,t){return r.isSegment?ce(t,r.shape):de(t,r.shape)}function qn(r,t){return r.isSegment?Wt(r.shape,t):fe(r.shape,t)}function ue(r,t){let e=[];for(let n of t.edges)for(let s of Fe(n,r))e.push(s);return e}function he(r,t){let e=[];for(let n of t.edges)for(let s of Ve(n,r))e.push(s);return e}function Nt(r,t){let e=[];if(t.isEmpty())return e;for(let n of t.edges)for(let s of He(n,r))Ge(s,e)||e.push(s);return r.sortPoints(e)}function $e(r,t){let e=[];if(t.isEmpty())return e;for(let n of t.edges)for(let s of qn(n,r))e.push(s);return e}function qe(r,t){return r.isSegment?Fe(t,r.shape):r.isArc?Ve(t,r.shape):r.isLine?He(t,r.shape):r.isRay?$n(t,r.shape):[]}function Gn(r,t){let e=[];if(t.isEmpty()||r.shape.box.not_intersect(t.box))return e;let n=t.edges.search(r.shape.box);for(let s of n)e=[...e,...qe(r,s)];return e}function Dn(r,t){let e=[];if(r.isEmpty()||t.isEmpty()||r.box.not_intersect(t.box))return e;for(let n of r.edges)e=[...e,...Gn(n,t)];return e}function zn(r,t){return r instanceof i.Line?Nt(r,t):r instanceof i.Segment?ue(r,t):r instanceof i.Arc?he(r,t):[]}function Ge(r,t){return t.some(e=>e.equalTo(r))}function et(r){return new i.Line(r.start,r.norm)}function ce(r,t){return Ct(t,et(r)).filter(e=>r.contains(e))}function de(r,t){return zt(et(r),t).filter(e=>r.contains(e))}function De(r,t){return ft(et(r),t).filter(e=>r.contains(e))}function Qn(r,t){return xt(et(r),t).filter(e=>r.contains(e))}function ze(r,t){return mt(et(r),t).filter(e=>r.contains(e))}function Wn(r,t){return mt(et(r),et(t)).filter(e=>r.contains(e)).filter(e=>t.contains(e))}function Qe(r,t){return Nt(et(r),t).filter(e=>r.contains(e))}const We={stroke:"black"};class jn{constructor(t=We){for(const e in t)this[e]=t[e];this.stroke=t.stroke??We.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=>t+(this[e]!==void 0?this.toAttrString(e,this[e]):""),"")}toAttrString(t,e){const n=t==="className"?"class":this.convertCamelToKebabCase(t);return e===null?`${n} `:`${n}="${e.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}}function ut(r){return new jn(r).toAttributesString()}class C extends te{constructor(...t){if(super(),t.length!==0&&t.length===1&&t[0]instanceof Array){let e=t[0];if(e.length===0)return;e.every(n=>n instanceof i.Segment||n instanceof i.Arc||n instanceof i.Ray||n instanceof i.Line);for(let n of e){let s=new i.Edge(n);this.append(s)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new i.Box)}get vertices(){let t=this.edges.map(e=>e.start);return t.push(this.last.end),t}clone(){return new C(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}addVertex(t,e){let n=e.shape.split(t);if(n[0]===null)return e.prev;if(n[1]===null)return e;let s=new i.Edge(n[0]),l=e.prev;return this.insert(s,l),e.shape=n[1],s}getChain(t,e){let n=[];for(let s=t;s!==e.next;s=s.next)n.push(s);return n}split(t){for(let e of t){let n=this.findEdgeByPoint(e);this.addVertex(e,n)}return this}findEdgeByPoint(t){let e;for(let n of this)if(n.shape.contains(t)){e=n;break}return e}translate(t){return new C(this.edges.map(e=>e.shape.translate(t)))}rotate(t=0,e=new i.Point){return new C(this.edges.map(n=>n.shape.rotate(t,e)))}transform(t=new i.Matrix){return new C(this.edges.map(e=>e.shape.transform(t)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svg(t={}){let e=` +(function(X,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("leaflet")):typeof define=="function"&&define.amd?define(["exports","leaflet"],y):(X=typeof globalThis<"u"?globalThis:X||self,y(X["leaflet-tracksymbol2"]={},X.L))})(this,function(X,y){"use strict";const Ht={CCW:-1,CW:1,NOT_ORIENTABLE:0},dn=2*Math.PI,$t=1,ve=0,M=2,gn=3,_n=4,pn=1,mn=2,Kt=0,qt=1,ct=2;var Gt=Object.freeze({__proto__:null,BOUNDARY:M,CCW:!0,CONTAINS:gn,CW:!1,END_VERTEX:ct,INSIDE:$t,INTERLACE:_n,NOT_VERTEX:Kt,ORIENTATION:Ht,OUTSIDE:ve,OVERLAP_OPPOSITE:mn,OVERLAP_SAME:pn,PIx2:dn,START_VERTEX:qt});let k=1e-6;function we(r){k=r}function Te(){return k}const xn=3;function Jt(r){return r-k}function lt(r,t){return r-t-k}function Se(r,t){return r-t>k}function En(r,t){return r-t>-k}function ye(r,t){return r-t<-k}function vn(r,t){return r-t(t=t?t.next:this.first,{value:t,done:t===void 0})}}get size(){let t=0;for(let e of this)t++;return t}toArray(t=void 0,e=void 0){let n=[],s=t||this.first,l=e||this.last,o=s;if(o===void 0)return n;do n.push(o),o=o.next;while(o!==l.next);return n}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,e){if(this.isEmpty())this.first=t,this.last=t;else if(e==null)t.next=this.first,this.first.prev=t,this.first=t;else{let n=e.next;e.next=t,n&&(n.prev=t),t.prev=e,t.next=n,this.last===e&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return this.first===void 0}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t&&e===n)throw v.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}}function dt(r,t,e){let n=e.length,s=r.shape.split(t);if(s.length===0)return;let l=0;s[0]===null?l=0:s[1]===null?l=r.shape.length:l=s[0].length;let o=Kt;lt(l,0)&&(o|=qt),lt(l,r.shape.length)&&(o|=ct);let a;l===1/0?a=s[0].coord(t):a=o&ct&&r.next&&r.next.arc_length===0?0:r.arc_length+l,e.push({id:n,pt:t,arc_length:a,edge_before:r,edge_after:void 0,face:r.face,is_vertex:o})}function Pt(r){r.int_points1_sorted=tt(r.int_points1),r.int_points2_sorted=tt(r.int_points2)}function tt(r){let t=new Map,e=0;for(let s of r)t.has(s.face)||(t.set(s.face,e),e++);for(let s of r)s.faceId=t.get(s.face);return r.slice().sort(Tn)}function Tn(r,t){return r.faceIdt.faceId?1:r.arc_lengtht.arc_length?1:0}function ee(r){if(r.int_points1.length<2)return;let t=!1,e,n,s,l;for(let o=0;oo.id>=0),r.int_points2=r.int_points2.filter(o=>o.id>=0),r.int_points1.forEach((o,a)=>o.id=a),r.int_points2.forEach((o,a)=>o.id=a))}function ne(r){for(let t of r)t.edge_before&&(t.edge_before.bvStart=void 0,t.edge_before.bvEnd=void 0,t.edge_before.bv=void 0,t.edge_before.overlap=void 0),t.edge_after&&(t.edge_after.bvStart=void 0,t.edge_after.bvEnd=void 0,t.edge_after.bv=void 0,t.edge_after.overlap=void 0);for(let t of r)t.edge_before&&(t.edge_before.bvEnd=M),t.edge_after&&(t.edge_after.bvStart=M)}function ie(r,t){for(let e of r)e.edge_before&&e.edge_before.setInclusion(t),e.edge_after&&e.edge_after.setInclusion(t)}function Sn(r){let t,e,n,s=r.int_points1.length;for(let l=0;la.shape)];let l=[];for(let o of n.faces)l=[...l,...[...o.edges].map(a=>a.shape)];return[s,l]}function se(r,t){let[e,n]=Ot(r,t,at,!1),s=[];for(let l of e.faces)s=[...s,...[...l.edges].map(o=>o.shape)];return s}function Oe(r,t){let e=r.clone(),n=t.clone(),s=Ce(e,n);Pt(s),_t(e,s.int_points1_sorted),_t(n,s.int_points2_sorted),ee(s),Pt(s);let l=s.int_points1_sorted.map(a=>a.pt),o=s.int_points2_sorted.map(a=>a.pt);return[l,o]}function An(r,t,e,n){let s=Ne(r,e.int_points1),l=Ne(t,e.int_points2);for(Re(s,t),Re(l,r),ne(e.int_points1),ne(e.int_points2),ie(e.int_points1,t),ie(e.int_points2,r);Ln(r,t,e.int_points1,e.int_points1_sorted,e.int_points2,e););Sn(e),oe(r,n,e.int_points1_sorted,!0),oe(t,n,e.int_points2_sorted,!1),Ue(r,s,n,!0),Ue(t,l,n,!1)}function Pn(r,t,e,n){On(r,t,n,e.int_points2),Cn(r,t,e),le(r,e.int_points1),le(t,e.int_points2),ae(r,e.int_points1,e.int_points2),ae(r,e.int_points2,e.int_points1)}function Ot(r,t,e,n){let s=r.clone(),l=t.clone(),o=Ce(s,l);return Pt(o),_t(s,o.int_points1_sorted),_t(l,o.int_points2_sorted),ee(o),Pt(o),An(s,l,o,e),n&&Pn(s,l,o,e),[s,l]}function Ce(r,t){let e={int_points1:[],int_points2:[]};for(let n of r.edges){let s=t.edges.search(n.box);for(let l of s){let o=n.shape.intersect(l.shape);for(let a of o)dt(n,a,e.int_points1),dt(l,a,e.int_points2)}}return e}function Ne(r,t){let e=[];for(let n of r.faces)t.find(s=>s.face===n)||e.push(n);return e}function Re(r,t){for(let e of r)e.first.bv=e.first.bvStart=e.first.bvEnd=void 0,e.first.setInclusion(t)}function Ln(r,t,e,n,s,l){let o,a,h,u=n.length,f=!1;for(let g=0;gki.edge_after===bt),U=t.addVertex(ot.pt,bt);ot.edge_before=U,ot.edge_after=U.next,Z&&(Z.edge_after=U),U.bvStart=void 0,U.bvEnd=b,U.bv=void 0,U.setInclusion(r),U.next.bvStart=b,U.next.bvEnd=void 0,U.next.bv=void 0,U.next.setInclusion(r)}Pt(l),f=!0;break}}_=_.next}if(f)break;throw v.UNRESOLVED_BOUNDARY_CONFLICT}}return f}function oe(r,t,e,n){if(!e)return;let s,l,o,a;for(let h=0;hl.face===s)===void 0&&r.addFace(s.first,s.last)}}function Cn(r,t,e){if(e.int_points1.length!==0)for(let n=0;nt instanceof Array&&t.length>0?"T":t instanceof Array&&t.length===0?"F":"*").join("")}equal(){return Rn.test(this.toString())}intersect(){return Un.test(this.toString())}touch(){return Mn.test(this.toString())}inside(){return kn.test(this.toString())}covered(){return Bn.test(this.toString())}}function mt(r,t){let e=[],[n,s,l]=r.standard,[o,a,h]=t.standard,u=n*a-s*o,f=l*a-s*h,g=n*h-l*o;if(!i.Utils.EQ_0(u)){let p,S;s===0?(p=l/n,S=g/u):a===0?(p=h/o,S=g/u):n===0?(p=f/u,S=l/s):o===0?(p=f/u,S=h/a):(p=f/u,S=g/u),e.push(new i.Point(p,S))}return e}function ft(r,t){let e=[],n=t.pc.projectionOn(r),s=t.pc.distanceTo(n)[0];if(i.Utils.EQ(s,t.r))e.push(n);else if(i.Utils.LT(s,t.r)){let l=Math.sqrt(t.r*t.r-s*s),o,a;o=r.norm.rotate90CCW().multiply(l),a=n.translate(o),e.push(a),o=r.norm.rotate90CW().multiply(l),a=n.translate(o),e.push(a)}return e}function xt(r,t){let e=[];for(let n of t.toSegments()){let s=Ct(n,r);for(let l of s)Ge(l,e)||e.push(l)}return e}function zt(r,t){let e=[];if(xt(r,t.box).length===0)return e;let n=new i.Circle(t.pc,t.r),s=ft(r,n);for(let l of s)l.on(t)&&e.push(l);return e}function Ct(r,t){let e=[];if(r.ps.on(t)&&e.push(r.ps),r.pe.on(t)&&!r.isZeroLength()&&e.push(r.pe),e.length>0||r.isZeroLength()||r.ps.leftTo(t)&&r.pe.leftTo(t)||!r.ps.leftTo(t)&&!r.pe.leftTo(t))return e;let n=new i.Line(r.ps,r.pe);return mt(n,t)}function Qt(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.isZeroLength())return r.ps.on(t)&&e.push(r.ps),e;if(t.isZeroLength())return t.ps.on(r)&&e.push(t.ps),e;let n=new i.Line(r.ps,r.pe),s=new i.Line(t.ps,t.pe);if(n.incidentTo(s))r.ps.on(t)&&e.push(r.ps),r.pe.on(t)&&e.push(r.pe),t.ps.on(r)&&!t.ps.equalTo(r.ps)&&!t.ps.equalTo(r.pe)&&e.push(t.ps),t.pe.on(r)&&!t.pe.equalTo(r.ps)&&!t.pe.equalTo(r.pe)&&e.push(t.pe);else{let l=mt(n,s);l.length>0&&Me(l[0],r)&&Me(l[0],t)&&e.push(l[0])}return e}function Me(r,t){const e=t.box;return i.Utils.LE(r.x,e.xmax)&&i.Utils.GE(r.x,e.xmin)&&i.Utils.LE(r.y,e.ymax)&&i.Utils.GE(r.y,e.ymin)}function Wt(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.isZeroLength()){let[l,o]=r.ps.distanceTo(t.pc);return i.Utils.EQ(l,t.r)&&e.push(r.ps),e}let n=new i.Line(r.ps,r.pe),s=ft(n,t);for(let l of s)l.on(r)&&e.push(l);return e}function Et(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.isZeroLength())return r.ps.on(t)&&e.push(r.ps),e;let n=new i.Line(r.ps,r.pe),s=new i.Circle(t.pc,t.r),l=ft(n,s);for(let o of l)o.on(r)&&o.on(t)&&e.push(o);return e}function Fn(r,t){let e=[];for(let n of t.toSegments()){let s=Qt(n,r);for(let l of s)e.push(l)}return e}function ke(r,t){let e=[];if(r.box.not_intersect(t.box))return e;let n=new i.Vector(r.pc,t.pc),s=r.r,l=t.r;if(i.Utils.EQ_0(s)||i.Utils.EQ_0(l))return e;if(i.Utils.EQ_0(n.x)&&i.Utils.EQ_0(n.y)&&i.Utils.EQ(s,l))return e.push(r.pc.translate(-s,0)),e;let o=r.pc.distanceTo(t.pc)[0];if(i.Utils.GT(o,s+l)||i.Utils.LT(o,Math.abs(s-l)))return e;n.x/=o,n.y/=o;let a;if(i.Utils.EQ(o,s+l)||i.Utils.EQ(o,Math.abs(s-l)))return a=r.pc.translate(s*n.x,s*n.y),e.push(a),e;let h=s*s/(2*o)-l*l/(2*o)+o/2,u=r.pc.translate(h*n.x,h*n.y),f=Math.sqrt(s*s-h*h);return a=u.translate(n.rotate90CCW().multiply(f)),e.push(a),a=u.translate(n.rotate90CW().multiply(f)),e.push(a),e}function Vn(r,t){let e=[];for(let n of t.toSegments()){let s=Wt(n,r);for(let l of s)e.push(l)}return e}function Be(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(r.pc.equalTo(t.pc)&&i.Utils.EQ(r.r,t.r)){let o;return o=r.start,o.on(t)&&e.push(o),o=r.end,o.on(t)&&e.push(o),o=t.start,o.on(r)&&e.push(o),o=t.end,o.on(r)&&e.push(o),e}let n=new i.Circle(r.pc,r.r),s=new i.Circle(t.pc,t.r),l=n.intersect(s);for(let o of l)o.on(r)&&o.on(t)&&e.push(o);return e}function fe(r,t){let e=[];if(r.box.not_intersect(t.box))return e;if(t.pc.equalTo(r.pc)&&i.Utils.EQ(t.r,r.r))return e.push(r.start),e.push(r.end),e;let n=t,s=new i.Circle(r.pc,r.r),l=ke(n,s);for(let o of l)o.on(r)&&e.push(o);return e}function Hn(r,t){let e=[];for(let n of t.toSegments()){let s=Et(n,r);for(let l of s)e.push(l)}return e}function Fe(r,t){return r.isSegment?Qt(r.shape,t):Et(t,r.shape)}function Ve(r,t){return r.isSegment?Et(r.shape,t):Be(r.shape,t)}function He(r,t){return r.isSegment?Ct(r.shape,t):zt(t,r.shape)}function $n(r,t){return r.isSegment?ce(t,r.shape):de(t,r.shape)}function qn(r,t){return r.isSegment?Wt(r.shape,t):fe(r.shape,t)}function ue(r,t){let e=[];for(let n of t.edges)for(let s of Fe(n,r))e.push(s);return e}function he(r,t){let e=[];for(let n of t.edges)for(let s of Ve(n,r))e.push(s);return e}function Nt(r,t){let e=[];if(t.isEmpty())return e;for(let n of t.edges)for(let s of He(n,r))Ge(s,e)||e.push(s);return r.sortPoints(e)}function $e(r,t){let e=[];if(t.isEmpty())return e;for(let n of t.edges)for(let s of qn(n,r))e.push(s);return e}function qe(r,t){return r.isSegment?Fe(t,r.shape):r.isArc?Ve(t,r.shape):r.isLine?He(t,r.shape):r.isRay?$n(t,r.shape):[]}function Gn(r,t){let e=[];if(t.isEmpty()||r.shape.box.not_intersect(t.box))return e;let n=t.edges.search(r.shape.box);for(let s of n)e=[...e,...qe(r,s)];return e}function Dn(r,t){let e=[];if(r.isEmpty()||t.isEmpty()||r.box.not_intersect(t.box))return e;for(let n of r.edges)e=[...e,...Gn(n,t)];return e}function zn(r,t){return r instanceof i.Line?Nt(r,t):r instanceof i.Segment?ue(r,t):r instanceof i.Arc?he(r,t):[]}function Ge(r,t){return t.some(e=>e.equalTo(r))}function et(r){return new i.Line(r.start,r.norm)}function ce(r,t){return Ct(t,et(r)).filter(e=>r.contains(e))}function de(r,t){return zt(et(r),t).filter(e=>r.contains(e))}function De(r,t){return ft(et(r),t).filter(e=>r.contains(e))}function Qn(r,t){return xt(et(r),t).filter(e=>r.contains(e))}function ze(r,t){return mt(et(r),t).filter(e=>r.contains(e))}function Wn(r,t){return mt(et(r),et(t)).filter(e=>r.contains(e)).filter(e=>t.contains(e))}function Qe(r,t){return Nt(et(r),t).filter(e=>r.contains(e))}const We={stroke:"black"};class jn{constructor(t=We){for(const e in t)this[e]=t[e];this.stroke=t.stroke??We.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=>t+(this[e]!==void 0?this.toAttrString(e,this[e]):""),"")}toAttrString(t,e){const n=t==="className"?"class":this.convertCamelToKebabCase(t);return e===null?`${n} `:`${n}="${e.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}}function ut(r){return new jn(r).toAttributesString()}class C extends te{constructor(...t){if(super(),t.length!==0&&t.length===1&&t[0]instanceof Array){let e=t[0];if(e.length===0)return;e.every(n=>n instanceof i.Segment||n instanceof i.Arc||n instanceof i.Ray||n instanceof i.Line);for(let n of e){let s=new i.Edge(n);this.append(s)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new i.Box)}get vertices(){let t=this.edges.map(e=>e.start);return t.push(this.last.end),t}clone(){return new C(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}addVertex(t,e){let n=e.shape.split(t);if(n[0]===null)return e.prev;if(n[1]===null)return e;let s=new i.Edge(n[0]),l=e.prev;return this.insert(s,l),e.shape=n[1],s}getChain(t,e){let n=[];for(let s=t;s!==e.next;s=s.next)n.push(s);return n}split(t){for(let e of t){let n=this.findEdgeByPoint(e);this.addVertex(e,n)}return this}findEdgeByPoint(t){let e;for(let n of this)if(n.shape.contains(t)){e=n;break}return e}translate(t){return new C(this.edges.map(e=>e.shape.translate(t)))}rotate(t=0,e=new i.Point){return new C(this.edges.map(n=>n.shape.rotate(t,e)))}transform(t=new i.Matrix){return new C(this.edges.map(e=>e.shape.transform(t)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svg(t={}){let e=` -`,e}}i.Multiline=C;const Yn=(...r)=>new i.Multiline(...r);i.multiline=Yn;function Rt(r,t){let e,n=new i.Ray(t),s=new i.Line(n.pt,n.norm);const l=new i.Box(n.box.xmin-i.DP_TOL,n.box.ymin-i.DP_TOL,n.box.xmax,n.box.ymax+i.DP_TOL);if(r.box.not_intersect(l))return i.OUTSIDE;let o=r.edges.search(l);if(o.length==0)return i.OUTSIDE;for(let u of o)if(u.shape.contains(t))return i.BOUNDARY;let a=[];for(let u of o)for(let f of n.intersect(u.shape)){if(f.equalTo(t))return i.BOUNDARY;a.push({pt:f,edge:u})}a.sort((u,f)=>ye(u.pt.x,f.pt.x)?-1:Se(u.pt.x,f.pt.x)?1:0);let h=0;for(let u=0;u0&&f.pt.equalTo(a[u-1].pt)&&f.edge.prev===a[u-1].edge)continue;let g=f.edge.prev;for(;Jt(g.length);)g=g.prev;let x=g.shape.tangentInEnd(),y=f.pt.translate(x),w=f.edge.shape.tangentInStart(),v=f.pt.translate(w),T=y.leftTo(s),m=v.leftTo(s);(T&&!m||!T&&m)&&h++}else if(f.pt.equalTo(f.edge.shape.end)){if(u>0&&f.pt.equalTo(a[u-1].pt)&&f.edge.next===a[u-1].edge)continue;let g=f.edge.next;for(;Jt(g.length);)g=g.next;let x=g.shape.tangentInStart(),y=f.pt.translate(x),w=f.edge.shape.tangentInEnd(),v=f.pt.translate(w),T=y.leftTo(s),m=v.leftTo(s);(T&&!m||!T&&m)&&h++}else if(f.edge.shape instanceof i.Segment)h++;else{let g=f.edge.shape.box;lt(f.pt.y,g.ymin)||lt(f.pt.y,g.ymax)||h++}}return e=h%2==1?$t:ve,e}function Zn(r,t){return vt(r,t).equal()}function je(r,t){return vt(r,t).intersect()}function Xn(r,t){return vt(r,t).touch()}function Kn(r,t){return!je(r,t)}function Ye(r,t){return vt(r,t).inside()}function Ze(r,t){return vt(r,t).covered()}function Jn(r,t){return Ye(t,r)}function Xe(r,t){return Ze(t,r)}function vt(r,t){if(r instanceof i.Line&&t instanceof i.Line)return ti(r,t);if(r instanceof i.Line&&t instanceof i.Circle)return ei(r,t);if(r instanceof i.Line&&t instanceof i.Box)return ni(r,t);if(r instanceof i.Line&&t instanceof i.Polygon)return ii(r,t);if((r instanceof i.Segment||r instanceof i.Arc)&&t instanceof i.Polygon)return Ke(r,t);if((r instanceof i.Segment||r instanceof i.Arc)&&(t instanceof i.Circle||t instanceof i.Box))return Ke(r,new i.Polygon(t));if(r instanceof i.Polygon&&t instanceof i.Polygon)return jt(r,t);if((r instanceof i.Circle||r instanceof i.Box)&&(t instanceof i.Circle||t instanceof i.Box))return jt(new i.Polygon(r),new i.Polygon(t));if((r instanceof i.Circle||r instanceof i.Box)&&t instanceof i.Polygon)return jt(new i.Polygon(r),t);if(r instanceof i.Polygon&&(t instanceof i.Circle||t instanceof i.Box))return jt(r,new i.Polygon(t))}function ti(r,t){let e=new pt,n=mt(r,t);return n.length===0?r.contains(t.pt)&&t.contains(r.pt)?(e.I2I=[r],e.I2E=[],e.E2I=[]):(e.I2I=[],e.I2E=[r],e.E2I=[t]):(e.I2I=n,e.I2E=r.split(n),e.E2I=t.split(n)),e}function ei(r,t){let e=new pt,n=ft(r,t);if(n.length===0)e.I2I=[],e.I2B=[],e.I2E=[r],e.E2I=[t];else if(n.length===1)e.I2I=[],e.I2B=n,e.I2E=r.split(n),e.E2I=[t];else{let s=new C([r]),l=r.sortPoints(n);s.split(l);let o=s.toShapes();e.I2I=[o[1]],e.I2B=l,e.I2E=[o[0],o[2]],e.E2I=new i.Polygon([t.toArc()]).cutWithLine(r)}return e}function ni(r,t){let e=new pt,n=xt(r,t);if(n.length===0)e.I2I=[],e.I2B=[],e.I2E=[r],e.E2I=[t];else if(n.length===1)e.I2I=[],e.I2B=n,e.I2E=r.split(n),e.E2I=[t];else{let s=new C([r]),l=r.sortPoints(n);s.split(l);let o=s.toShapes();t.toSegments().some(a=>a.contains(n[0])&&a.contains(n[1]))?(e.I2I=[],e.I2B=[o[1]],e.I2E=[o[0],o[2]],e.E2I=[t]):(e.I2I=[o[1]],e.I2B=l,e.I2E=[o[0],o[2]],e.E2I=new i.Polygon(t.toSegments()).cutWithLine(r))}return e}function ii(r,t){let e=new pt,n=Nt(r,t),s=new C([r]),l=n.length>0?n.slice():r.sortPoints(n);return s.split(l),[...s].forEach(o=>o.setInclusion(t)),e.I2I=[...s].filter(o=>o.bv===i.INSIDE).map(o=>o.shape),e.I2B=[...s].slice(1).map(o=>o.bv===i.BOUNDARY?o.shape:o.shape.start),e.I2E=[...s].filter(o=>o.bv===i.OUTSIDE).map(o=>o.shape),e.E2I=t.cutWithLine(r),e}function Ke(r,t){let e=new pt,n=zn(r,t),s=n.length>0?n.slice():r.sortPoints(n),l=new C([r]);l.split(s),[...l].forEach(o=>o.setInclusion(t)),e.I2I=[...l].filter(o=>o.bv===i.INSIDE).map(o=>o.shape),e.I2B=[...l].slice(1).map(o=>o.bv===i.BOUNDARY?o.shape:o.shape.start),e.I2E=[...l].filter(o=>o.bv===i.OUTSIDE).map(o=>o.shape),e.B2I=[],e.B2B=[],e.B2E=[];for(let o of[r.start,r.end])switch(Rt(t,o)){case i.INSIDE:e.B2I.push(o);break;case i.BOUNDARY:e.B2B.push(o);break;case i.OUTSIDE:e.B2E.push(o);break}return e}function jt(r,t){let e=new pt,[n,s]=Oe(r,t),l=Pe(r,t),o=re(r,t),a=re(t,r),[h,u]=Le(r,t),f=se(r,t),g=se(t,r);return e.I2I=l.isEmpty()?[]:[l],e.I2B=u,e.I2E=o.isEmpty()?[]:[o],e.B2I=h,e.B2B=n,e.B2E=f,e.E2I=a.isEmpty()?[]:[a],e.E2B=g,e}var ri=Object.freeze({__proto__:null,contain:Jn,cover:Xe,covered:Ze,disjoint:Kn,equal:Zn,inside:Ye,intersect:je,relate:vt,touch:Xn});let Ut=class At{constructor(t=1,e=0,n=0,s=1,l=0,o=0){this.a=t,this.b=e,this.c=n,this.d=s,this.tx=l,this.ty=o}clone(){return new At(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(t){return new At(this.a*t.a+this.c*t.b,this.b*t.a+this.d*t.b,this.a*t.c+this.c*t.d,this.b*t.c+this.d*t.d,this.a*t.tx+this.c*t.ty+this.tx,this.b*t.tx+this.d*t.ty+this.ty)}translate(...t){let e,n;if(t.length==1&&!isNaN(t[0].x)&&!isNaN(t[0].y))e=t[0].x,n=t[0].y;else if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number")e=t[0],n=t[1];else throw E.ILLEGAL_PARAMETERS;return this.multiply(new At(1,0,0,1,e,n))}rotate(t,e=0,n=0){let s=Math.cos(t),l=Math.sin(t);return this.translate(e,n).multiply(new At(s,l,-l,s,0,0)).translate(-e,-n)}scale(t,e){return this.multiply(new At(t,0,0,e,0,0))}equalTo(t){return!(!i.Utils.EQ(this.tx,t.tx)||!i.Utils.EQ(this.ty,t.ty)||!i.Utils.EQ(this.a,t.a)||!i.Utils.EQ(this.b,t.b)||!i.Utils.EQ(this.c,t.c)||!i.Utils.EQ(this.d,t.d))}};i.Matrix=Ut;const si=(...r)=>new i.Matrix(...r);i.matrix=si;const oi=class Ee{constructor(t,e){this.low=t,this.high=e}clone(){return new Ee(this.low,this.high)}get max(){return this.clone()}less_than(t){return this.lowt++),t}get keys(){let t=[];return this.tree_walk(this.root,e=>t.push(e.item.key.output?e.item.key.output():e.item.key)),t}get values(){let t=[];return this.tree_walk(this.root,e=>t.push(e.item.value)),t}get items(){let t=[];return this.tree_walk(this.root,e=>t.push({key:e.item.key.output?e.item.key.output():e.item.key,value:e.item.value})),t}isEmpty(){return this.root==null||this.root==this.nil_node}clear(){this.root=null}insert(t,e=t){if(t===void 0)return;let n=new wt(t,e,this.nil_node,this.nil_node,null,P);return this.tree_insert(n),this.recalc_max(n),n}exist(t,e=t){let n=new wt(t,e);return!!this.tree_search(this.root,n)}remove(t,e=t){let n=new wt(t,e),s=this.tree_search(this.root,n);return s&&this.tree_delete(s),s}search(t,e=(n,s)=>n===s?s.output():n){let n=new wt(t),s=[];return this.tree_search_interval(this.root,n,s),s.map(l=>e(l.item.value,l.item.key))}intersect_any(t){let e=new wt(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=>t(e.item.key,e.item.value))}map(t){const e=new Mt;return this.tree_walk(this.root,n=>e.insert(n.item.key,t(n.item.value,n.item.key))),e}recalc_max(t){let e=t;for(;e.parent!=null;)e.parent.update_max(),e=e.parent}tree_insert(t){let e=this.root,n=null;if(this.root==null||this.root==this.nil_node)this.root=t;else{for(;e!=this.nil_node;)n=e,t.less_than(e)?e=e.left:e=e.right;t.parent=n,t.less_than(n)?n.left=t:n.right=t}this.insert_fixup(t)}insert_fixup(t){let e,n;for(e=t;e!=this.root&&e.parent.color==P;)e.parent==e.parent.parent.left?(n=e.parent.parent.right,n.color==P?(e.parent.color=p,n.color=p,e.parent.parent.color=P,e=e.parent.parent):(e==e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=p,e.parent.parent.color=P,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,n.color==P?(e.parent.color=p,n.color=p,e.parent.parent.color=P,e=e.parent.parent):(e==e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=p,e.parent.parent.color=P,this.rotate_left(e.parent.parent)));this.root.color=p}tree_delete(t){let e,n;t.left==this.nil_node||t.right==this.nil_node?e=t:e=this.tree_successor(t),e.left!=this.nil_node?n=e.left:n=e.right,n.parent=e.parent,e==this.root?this.root=n:(e==e.parent.left?e.parent.left=n:e.parent.right=n,e.parent.update_max()),this.recalc_max(n),e!=t&&(t.copy_data(e),t.update_max(),this.recalc_max(t)),e.color==p&&this.delete_fixup(n)}delete_fixup(t){let e=t,n;for(;e!=this.root&&e.parent!=null&&e.color==p;)e==e.parent.left?(n=e.parent.right,n.color==P&&(n.color=p,e.parent.color=P,this.rotate_left(e.parent),n=e.parent.right),n.left.color==p&&n.right.color==p?(n.color=P,e=e.parent):(n.right.color==p&&(n.color=P,n.left.color=p,this.rotate_right(n),n=e.parent.right),n.color=e.parent.color,e.parent.color=p,n.right.color=p,this.rotate_left(e.parent),e=this.root)):(n=e.parent.left,n.color==P&&(n.color=p,e.parent.color=P,this.rotate_right(e.parent),n=e.parent.left),n.left.color==p&&n.right.color==p?(n.color=P,e=e.parent):(n.left.color==p&&(n.color=P,n.right.color=p,this.rotate_left(n),n=e.parent.left),n.color=e.parent.color,e.parent.color=p,n.left.color=p,this.rotate_right(e.parent),e=this.root));e.color=p}tree_search(t,e){if(!(t==null||t==this.nil_node))return e.equal_to(t)?t:e.less_than(t)?this.tree_search(t.left,e):this.tree_search(t.right,e)}tree_search_interval(t,e,n){t!=null&&t!=this.nil_node&&(t.left!=this.nil_node&&!t.not_intersect_left_subtree(e)&&this.tree_search_interval(t.left,e,n),t.intersect(e)&&n.push(t),t.right!=this.nil_node&&!t.not_intersect_right_subtree(e)&&this.tree_search_interval(t.right,e,n))}tree_find_any_interval(t,e){let n=!1;return t!=null&&t!=this.nil_node&&(t.left!=this.nil_node&&!t.not_intersect_left_subtree(e)&&(n=this.tree_find_any_interval(t.left,e)),n||(n=t.intersect(e)),!n&&t.right!=this.nil_node&&!t.not_intersect_right_subtree(e)&&(n=this.tree_find_any_interval(t.right,e))),n}local_minimum(t){let e=t;for(;e.left!=null&&e.left!=this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;e.right!=null&&e.right!=this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,s;if(t.right!=this.nil_node)e=this.local_minimum(t.right);else{for(n=t,s=t.parent;s!=null&&s.right==n;)n=s,s=s.parent;e=s}return e}rotate_left(t){let e=t.right;t.right=e.left,e.left!=this.nil_node&&(e.left.parent=t),e.parent=t.parent,t==this.root?this.root=e:t==t.parent.left?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e,t!=null&&t!=this.nil_node&&t.update_max(),e=t.parent,e!=null&&e!=this.nil_node&&e.update_max()}rotate_right(t){let e=t.left;t.left=e.right,e.right!=this.nil_node&&(e.right.parent=t),e.parent=t.parent,t==this.root?this.root=e:t==t.parent.left?t.parent.left=e:t.parent.right=e,e.right=t,t.parent=e,t!=null&&t!=this.nil_node&&t.update_max(),e=t.parent,e!=null&&e!=this.nil_node&&e.update_max()}tree_walk(t,e){t!=null&&t!=this.nil_node&&(this.tree_walk(t.left,e),e(t),this.tree_walk(t.right,e))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(e){e.color==P&&(e.left.color==p&&e.right.color==p||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,s=0;if(t.color==p&&e++,t.left!=this.nil_node?n=this.testBlackHeightProperty(t.left):n=1,t.right!=this.nil_node?s=this.testBlackHeightProperty(t.right):s=1,n!=s)throw new Error("Red-black height property violated");return e+=n,e}}class li extends Set{constructor(t){super(t),this.index=new Mt,this.forEach(e=>this.index.insert(e))}add(t){let e=this.size;const{key:n,value:s}=t,l=n||t.box,o=s||t;return super.add(o),this.size>e&&this.index.insert(l,o),this}delete(t){const{key:e,value:n}=t,s=e||t.box,l=n||t;let o=super.delete(l);return o&&this.index.remove(s,l),o}clear(){super.clear(),this.index=new Mt}search(t){return this.index.search(t)}hit(t){let e=new i.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(s=>t.on(s))}svg(){return[...this].reduce((e,n)=>e+n.svg(),"")}}i.PlanarSet=li;class nt{get name(){throw E.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw E.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw E.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform(new Ut().translate(...t))}rotate(t,e=new i.Point){return this.transform(new Ut().rotate(t,e.x,e.y))}scale(t,e){return this.transform(new Ut().scale(t,e))}transform(...t){throw E.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw E.CANNOT_INVOKE_ABSTRACT_METHOD}}let ai=class hn extends nt{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let e=t[0];if(typeof e[0]=="number"&&typeof e[1]=="number"){this.x=e[0],this.y=e[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="point"){let{x:e,y:n}=t[0];this.x=e,this.y=n;return}if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number"){this.x=t[0],this.y=t[1];return}throw E.ILLEGAL_PARAMETERS}}get box(){return new i.Box(this.x,this.y,this.x,this.y)}clone(){return new i.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return i.Utils.EQ(this.x,t.x)&&i.Utils.EQ(this.y,t.y)}lessThan(t){return!!(i.Utils.LT(this.y,t.y)||i.Utils.EQ(this.y,t.y)&&i.Utils.LT(this.x,t.x))}transform(t){return new i.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new i.Vector(this,t.pt);if(i.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),s=t.norm.multiply(n);return this.translate(s)}leftTo(t){let e=new i.Vector(t.pt,this);return i.Utils.GT(e.dot(t.norm),0)}distanceTo(t){if(t instanceof hn){let e=t.x-this.x,n=t.y-this.y;return[Math.sqrt(e*e+n*n),new i.Segment(this,t)]}if(t instanceof i.Line)return i.Distance.point2line(this,t);if(t instanceof i.Circle)return i.Distance.point2circle(this,t);if(t instanceof i.Segment)return i.Distance.point2segment(this,t);if(t instanceof i.Arc)return i.Distance.point2arc(this,t);if(t instanceof i.Polygon)return i.Distance.point2polygon(this,t);if(t instanceof i.PlanarSet)return i.Distance.shape2planarSet(this,t)}on(t){if(t instanceof i.Point)return this.equalTo(t);if(t instanceof i.Box)return t.contains(this);if(t instanceof i.Line)return t.contains(this);if(t instanceof i.Ray)return t.contains(this);if(t instanceof i.Circle)return t.contains(this);if(t instanceof i.Segment)return t.contains(this);if(t instanceof i.Arc)return t.contains(this);if(t instanceof i.Polygon)return t.contains(this)}get name(){return"point"}svg(t={}){const e=t.r??3;return` +
`,e}}i.Multiline=C;const Yn=(...r)=>new i.Multiline(...r);i.multiline=Yn;function Rt(r,t){let e,n=new i.Ray(t),s=new i.Line(n.pt,n.norm);const l=new i.Box(n.box.xmin-i.DP_TOL,n.box.ymin-i.DP_TOL,n.box.xmax,n.box.ymax+i.DP_TOL);if(r.box.not_intersect(l))return i.OUTSIDE;let o=r.edges.search(l);if(o.length===0)return i.OUTSIDE;for(let f of o)if(f.shape.contains(t))return i.BOUNDARY;let a=[...r.faces],h=[];for(let f of o)for(let g of n.intersect(f.shape)){if(g.equalTo(t))return i.BOUNDARY;h.push({pt:g,edge:f,face_index:a.indexOf(f.face)})}h.sort((f,g)=>ye(f.pt.x,g.pt.x)?-1:Se(f.pt.x,g.pt.x)?1:f.face_indexg.face_index?1:f.edge.arc_lengthg.edge.arc_length?1:0);let u=0;for(let f=0;f0&&g.pt.equalTo(h[f-1].pt)&&g.face_index===h[f-1].face_index&&g.edge.prev===h[f-1].edge)continue;let p=g.edge.prev;for(;Jt(p.length);)p=p.prev;let S=p.shape.tangentInEnd(),T=g.pt.translate(S),w=g.edge.shape.tangentInStart(),I=g.pt.translate(w),x=T.leftTo(s),E=I.leftTo(s);(x&&!E||!x&&E)&&u++}else if(g.pt.equalTo(g.edge.shape.end)){if(f>0&&g.pt.equalTo(h[f-1].pt)&&g.face_index===h[f-1].face_index&&g.edge.next===h[f-1].edge)continue;let p=g.edge.next;for(;Jt(p.length);)p=p.next;let S=p.shape.tangentInStart(),T=g.pt.translate(S),w=g.edge.shape.tangentInEnd(),I=g.pt.translate(w),x=T.leftTo(s),E=I.leftTo(s);(x&&!E||!x&&E)&&u++}else if(g.edge.shape instanceof i.Segment)u++;else{let p=g.edge.shape.box;lt(g.pt.y,p.ymin)||lt(g.pt.y,p.ymax)||u++}}return e=u%2===1?$t:ve,e}function Zn(r,t){return vt(r,t).equal()}function je(r,t){return vt(r,t).intersect()}function Xn(r,t){return vt(r,t).touch()}function Kn(r,t){return!je(r,t)}function Ye(r,t){return vt(r,t).inside()}function Ze(r,t){return vt(r,t).covered()}function Jn(r,t){return Ye(t,r)}function Xe(r,t){return Ze(t,r)}function vt(r,t){if(r instanceof i.Line&&t instanceof i.Line)return ti(r,t);if(r instanceof i.Line&&t instanceof i.Circle)return ei(r,t);if(r instanceof i.Line&&t instanceof i.Box)return ni(r,t);if(r instanceof i.Line&&t instanceof i.Polygon)return ii(r,t);if((r instanceof i.Segment||r instanceof i.Arc)&&t instanceof i.Polygon)return Ke(r,t);if((r instanceof i.Segment||r instanceof i.Arc)&&(t instanceof i.Circle||t instanceof i.Box))return Ke(r,new i.Polygon(t));if(r instanceof i.Polygon&&t instanceof i.Polygon)return jt(r,t);if((r instanceof i.Circle||r instanceof i.Box)&&(t instanceof i.Circle||t instanceof i.Box))return jt(new i.Polygon(r),new i.Polygon(t));if((r instanceof i.Circle||r instanceof i.Box)&&t instanceof i.Polygon)return jt(new i.Polygon(r),t);if(r instanceof i.Polygon&&(t instanceof i.Circle||t instanceof i.Box))return jt(r,new i.Polygon(t))}function ti(r,t){let e=new pt,n=mt(r,t);return n.length===0?r.contains(t.pt)&&t.contains(r.pt)?(e.I2I=[r],e.I2E=[],e.E2I=[]):(e.I2I=[],e.I2E=[r],e.E2I=[t]):(e.I2I=n,e.I2E=r.split(n),e.E2I=t.split(n)),e}function ei(r,t){let e=new pt,n=ft(r,t);if(n.length===0)e.I2I=[],e.I2B=[],e.I2E=[r],e.E2I=[t];else if(n.length===1)e.I2I=[],e.I2B=n,e.I2E=r.split(n),e.E2I=[t];else{let s=new C([r]),l=r.sortPoints(n);s.split(l);let o=s.toShapes();e.I2I=[o[1]],e.I2B=l,e.I2E=[o[0],o[2]],e.E2I=new i.Polygon([t.toArc()]).cutWithLine(r)}return e}function ni(r,t){let e=new pt,n=xt(r,t);if(n.length===0)e.I2I=[],e.I2B=[],e.I2E=[r],e.E2I=[t];else if(n.length===1)e.I2I=[],e.I2B=n,e.I2E=r.split(n),e.E2I=[t];else{let s=new C([r]),l=r.sortPoints(n);s.split(l);let o=s.toShapes();t.toSegments().some(a=>a.contains(n[0])&&a.contains(n[1]))?(e.I2I=[],e.I2B=[o[1]],e.I2E=[o[0],o[2]],e.E2I=[t]):(e.I2I=[o[1]],e.I2B=l,e.I2E=[o[0],o[2]],e.E2I=new i.Polygon(t.toSegments()).cutWithLine(r))}return e}function ii(r,t){let e=new pt,n=Nt(r,t),s=new C([r]),l=n.length>0?n.slice():r.sortPoints(n);return s.split(l),[...s].forEach(o=>o.setInclusion(t)),e.I2I=[...s].filter(o=>o.bv===i.INSIDE).map(o=>o.shape),e.I2B=[...s].slice(1).map(o=>o.bv===i.BOUNDARY?o.shape:o.shape.start),e.I2E=[...s].filter(o=>o.bv===i.OUTSIDE).map(o=>o.shape),e.E2I=t.cutWithLine(r),e}function Ke(r,t){let e=new pt,n=zn(r,t),s=n.length>0?n.slice():r.sortPoints(n),l=new C([r]);l.split(s),[...l].forEach(o=>o.setInclusion(t)),e.I2I=[...l].filter(o=>o.bv===i.INSIDE).map(o=>o.shape),e.I2B=[...l].slice(1).map(o=>o.bv===i.BOUNDARY?o.shape:o.shape.start),e.I2E=[...l].filter(o=>o.bv===i.OUTSIDE).map(o=>o.shape),e.B2I=[],e.B2B=[],e.B2E=[];for(let o of[r.start,r.end])switch(Rt(t,o)){case i.INSIDE:e.B2I.push(o);break;case i.BOUNDARY:e.B2B.push(o);break;case i.OUTSIDE:e.B2E.push(o);break}return e}function jt(r,t){let e=new pt,[n,s]=Oe(r,t),l=Pe(r,t),o=re(r,t),a=re(t,r),[h,u]=Le(r,t),f=se(r,t),g=se(t,r);return e.I2I=l.isEmpty()?[]:[l],e.I2B=u,e.I2E=o.isEmpty()?[]:[o],e.B2I=h,e.B2B=n,e.B2E=f,e.E2I=a.isEmpty()?[]:[a],e.E2B=g,e}var ri=Object.freeze({__proto__:null,contain:Jn,cover:Xe,covered:Ze,disjoint:Kn,equal:Zn,inside:Ye,intersect:je,relate:vt,touch:Xn});let Ut=class At{constructor(t=1,e=0,n=0,s=1,l=0,o=0){this.a=t,this.b=e,this.c=n,this.d=s,this.tx=l,this.ty=o}clone(){return new At(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(t){return new At(this.a*t.a+this.c*t.b,this.b*t.a+this.d*t.b,this.a*t.c+this.c*t.d,this.b*t.c+this.d*t.d,this.a*t.tx+this.c*t.ty+this.tx,this.b*t.tx+this.d*t.ty+this.ty)}translate(...t){let e,n;if(t.length==1&&!isNaN(t[0].x)&&!isNaN(t[0].y))e=t[0].x,n=t[0].y;else if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number")e=t[0],n=t[1];else throw v.ILLEGAL_PARAMETERS;return this.multiply(new At(1,0,0,1,e,n))}rotate(t,e=0,n=0){let s=Math.cos(t),l=Math.sin(t);return this.translate(e,n).multiply(new At(s,l,-l,s,0,0)).translate(-e,-n)}scale(t,e){return this.multiply(new At(t,0,0,e,0,0))}equalTo(t){return!(!i.Utils.EQ(this.tx,t.tx)||!i.Utils.EQ(this.ty,t.ty)||!i.Utils.EQ(this.a,t.a)||!i.Utils.EQ(this.b,t.b)||!i.Utils.EQ(this.c,t.c)||!i.Utils.EQ(this.d,t.d))}};i.Matrix=Ut;const si=(...r)=>new i.Matrix(...r);i.matrix=si;const oi=class Ee{constructor(t,e){this.low=t,this.high=e}clone(){return new Ee(this.low,this.high)}get max(){return this.clone()}less_than(t){return this.lowt++),t}get keys(){let t=[];return this.tree_walk(this.root,e=>t.push(e.item.key.output?e.item.key.output():e.item.key)),t}get values(){let t=[];return this.tree_walk(this.root,e=>t.push(e.item.value)),t}get items(){let t=[];return this.tree_walk(this.root,e=>t.push({key:e.item.key.output?e.item.key.output():e.item.key,value:e.item.value})),t}isEmpty(){return this.root==null||this.root==this.nil_node}clear(){this.root=null}insert(t,e=t){if(t===void 0)return;let n=new wt(t,e,this.nil_node,this.nil_node,null,P);return this.tree_insert(n),this.recalc_max(n),n}exist(t,e=t){let n=new wt(t,e);return!!this.tree_search(this.root,n)}remove(t,e=t){let n=new wt(t,e),s=this.tree_search(this.root,n);return s&&this.tree_delete(s),s}search(t,e=(n,s)=>n===s?s.output():n){let n=new wt(t),s=[];return this.tree_search_interval(this.root,n,s),s.map(l=>e(l.item.value,l.item.key))}intersect_any(t){let e=new wt(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=>t(e.item.key,e.item.value))}map(t){const e=new Mt;return this.tree_walk(this.root,n=>e.insert(n.item.key,t(n.item.value,n.item.key))),e}recalc_max(t){let e=t;for(;e.parent!=null;)e.parent.update_max(),e=e.parent}tree_insert(t){let e=this.root,n=null;if(this.root==null||this.root==this.nil_node)this.root=t;else{for(;e!=this.nil_node;)n=e,t.less_than(e)?e=e.left:e=e.right;t.parent=n,t.less_than(n)?n.left=t:n.right=t}this.insert_fixup(t)}insert_fixup(t){let e,n;for(e=t;e!=this.root&&e.parent.color==P;)e.parent==e.parent.parent.left?(n=e.parent.parent.right,n.color==P?(e.parent.color=m,n.color=m,e.parent.parent.color=P,e=e.parent.parent):(e==e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=m,e.parent.parent.color=P,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,n.color==P?(e.parent.color=m,n.color=m,e.parent.parent.color=P,e=e.parent.parent):(e==e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=m,e.parent.parent.color=P,this.rotate_left(e.parent.parent)));this.root.color=m}tree_delete(t){let e,n;t.left==this.nil_node||t.right==this.nil_node?e=t:e=this.tree_successor(t),e.left!=this.nil_node?n=e.left:n=e.right,n.parent=e.parent,e==this.root?this.root=n:(e==e.parent.left?e.parent.left=n:e.parent.right=n,e.parent.update_max()),this.recalc_max(n),e!=t&&(t.copy_data(e),t.update_max(),this.recalc_max(t)),e.color==m&&this.delete_fixup(n)}delete_fixup(t){let e=t,n;for(;e!=this.root&&e.parent!=null&&e.color==m;)e==e.parent.left?(n=e.parent.right,n.color==P&&(n.color=m,e.parent.color=P,this.rotate_left(e.parent),n=e.parent.right),n.left.color==m&&n.right.color==m?(n.color=P,e=e.parent):(n.right.color==m&&(n.color=P,n.left.color=m,this.rotate_right(n),n=e.parent.right),n.color=e.parent.color,e.parent.color=m,n.right.color=m,this.rotate_left(e.parent),e=this.root)):(n=e.parent.left,n.color==P&&(n.color=m,e.parent.color=P,this.rotate_right(e.parent),n=e.parent.left),n.left.color==m&&n.right.color==m?(n.color=P,e=e.parent):(n.left.color==m&&(n.color=P,n.right.color=m,this.rotate_left(n),n=e.parent.left),n.color=e.parent.color,e.parent.color=m,n.left.color=m,this.rotate_right(e.parent),e=this.root));e.color=m}tree_search(t,e){if(!(t==null||t==this.nil_node))return e.equal_to(t)?t:e.less_than(t)?this.tree_search(t.left,e):this.tree_search(t.right,e)}tree_search_interval(t,e,n){t!=null&&t!=this.nil_node&&(t.left!=this.nil_node&&!t.not_intersect_left_subtree(e)&&this.tree_search_interval(t.left,e,n),t.intersect(e)&&n.push(t),t.right!=this.nil_node&&!t.not_intersect_right_subtree(e)&&this.tree_search_interval(t.right,e,n))}tree_find_any_interval(t,e){let n=!1;return t!=null&&t!=this.nil_node&&(t.left!=this.nil_node&&!t.not_intersect_left_subtree(e)&&(n=this.tree_find_any_interval(t.left,e)),n||(n=t.intersect(e)),!n&&t.right!=this.nil_node&&!t.not_intersect_right_subtree(e)&&(n=this.tree_find_any_interval(t.right,e))),n}local_minimum(t){let e=t;for(;e.left!=null&&e.left!=this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;e.right!=null&&e.right!=this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,s;if(t.right!=this.nil_node)e=this.local_minimum(t.right);else{for(n=t,s=t.parent;s!=null&&s.right==n;)n=s,s=s.parent;e=s}return e}rotate_left(t){let e=t.right;t.right=e.left,e.left!=this.nil_node&&(e.left.parent=t),e.parent=t.parent,t==this.root?this.root=e:t==t.parent.left?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e,t!=null&&t!=this.nil_node&&t.update_max(),e=t.parent,e!=null&&e!=this.nil_node&&e.update_max()}rotate_right(t){let e=t.left;t.left=e.right,e.right!=this.nil_node&&(e.right.parent=t),e.parent=t.parent,t==this.root?this.root=e:t==t.parent.left?t.parent.left=e:t.parent.right=e,e.right=t,t.parent=e,t!=null&&t!=this.nil_node&&t.update_max(),e=t.parent,e!=null&&e!=this.nil_node&&e.update_max()}tree_walk(t,e){t!=null&&t!=this.nil_node&&(this.tree_walk(t.left,e),e(t),this.tree_walk(t.right,e))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(e){e.color==P&&(e.left.color==m&&e.right.color==m||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,s=0;if(t.color==m&&e++,t.left!=this.nil_node?n=this.testBlackHeightProperty(t.left):n=1,t.right!=this.nil_node?s=this.testBlackHeightProperty(t.right):s=1,n!=s)throw new Error("Red-black height property violated");return e+=n,e}}class li extends Set{constructor(t){super(t),this.index=new Mt,this.forEach(e=>this.index.insert(e))}add(t){let e=this.size;const{key:n,value:s}=t,l=n||t.box,o=s||t;return super.add(o),this.size>e&&this.index.insert(l,o),this}delete(t){const{key:e,value:n}=t,s=e||t.box,l=n||t;let o=super.delete(l);return o&&this.index.remove(s,l),o}clear(){super.clear(),this.index=new Mt}search(t){return this.index.search(t)}hit(t){let e=new i.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(s=>t.on(s))}svg(){return[...this].reduce((e,n)=>e+n.svg(),"")}}i.PlanarSet=li;class nt{get name(){throw v.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw v.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw v.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform(new Ut().translate(...t))}rotate(t,e=new i.Point){return this.transform(new Ut().rotate(t,e.x,e.y))}scale(t,e){return this.transform(new Ut().scale(t,e))}transform(...t){throw v.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw v.CANNOT_INVOKE_ABSTRACT_METHOD}}let ai=class hn extends nt{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let e=t[0];if(typeof e[0]=="number"&&typeof e[1]=="number"){this.x=e[0],this.y=e[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="point"){let{x:e,y:n}=t[0];this.x=e,this.y=n;return}if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number"){this.x=t[0],this.y=t[1];return}throw v.ILLEGAL_PARAMETERS}}get box(){return new i.Box(this.x,this.y,this.x,this.y)}clone(){return new i.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return i.Utils.EQ(this.x,t.x)&&i.Utils.EQ(this.y,t.y)}lessThan(t){return!!(i.Utils.LT(this.y,t.y)||i.Utils.EQ(this.y,t.y)&&i.Utils.LT(this.x,t.x))}transform(t){return new i.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new i.Vector(this,t.pt);if(i.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),s=t.norm.multiply(n);return this.translate(s)}leftTo(t){let e=new i.Vector(t.pt,this);return i.Utils.GT(e.dot(t.norm),0)}distanceTo(t){if(t instanceof hn){let e=t.x-this.x,n=t.y-this.y;return[Math.sqrt(e*e+n*n),new i.Segment(this,t)]}if(t instanceof i.Line)return i.Distance.point2line(this,t);if(t instanceof i.Circle)return i.Distance.point2circle(this,t);if(t instanceof i.Segment)return i.Distance.point2segment(this,t);if(t instanceof i.Arc)return i.Distance.point2arc(this,t);if(t instanceof i.Polygon)return i.Distance.point2polygon(this,t);if(t instanceof i.PlanarSet)return i.Distance.shape2planarSet(this,t)}on(t){if(t instanceof i.Point)return this.equalTo(t);if(t instanceof i.Box)return t.contains(this);if(t instanceof i.Line)return t.contains(this);if(t instanceof i.Ray)return t.contains(this);if(t instanceof i.Circle)return t.contains(this);if(t instanceof i.Segment)return t.contains(this);if(t instanceof i.Arc)return t.contains(this);if(t instanceof i.Polygon)return t.contains(this)}get name(){return"point"}svg(t={}){const e=t.r??3;return` `}};i.Point=ai;const fi=(...r)=>new i.Point(...r);i.point=fi;let ui=class extends nt{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let e=t[0];if(typeof e[0]=="number"&&typeof e[1]=="number"){this.x=e[0],this.y=e[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="vector"){let{x:e,y:n}=t[0];this.x=e,this.y=n;return}if(t.length===2){let e=t[0],n=t[1];if(typeof e=="number"&&typeof n=="number"){this.x=e,this.y=n;return}if(e instanceof i.Point&&n instanceof i.Point){this.x=n.x-e.x,this.y=n.y-e.y;return}}throw E.ILLEGAL_PARAMETERS}}clone(){return new i.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}equalTo(t){return i.Utils.EQ(this.x,t.x)&&i.Utils.EQ(this.y,t.y)}multiply(t){return new i.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(!i.Utils.EQ_0(this.length))return new i.Vector(this.x/this.length,this.y/this.length);throw E.ZERO_DIVISION}rotate(t,e=new i.Point){if(e.x===0&&e.y===0)return this.transform(new Ut().rotate(t));throw E.OPERATION_IS_NOT_SUPPORTED}transform(t){return new i.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new i.Vector(-this.y,this.x)}rotate90CW(){return new i.Vector(this.y,-this.x)}invert(){return new i.Vector(-this.x,-this.y)}add(t){return new i.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new i.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),s=Math.atan2(e.cross(n),e.dot(n));return s<0&&(s+=2*Math.PI),s}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};i.Vector=ui;const Je=(...r)=>new i.Vector(...r);i.vector=Je;class Yt extends nt{constructor(...t){if(super(),this.ps=new i.Point,this.pe=new i.Point,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===4){let e=t[0];this.ps=new i.Point(e[0],e[1]),this.pe=new i.Point(e[2],e[3]);return}if(t.length===1&&t[0]instanceof Object&&t[0].name==="segment"){let{ps:e,pe:n}=t[0];this.ps=new i.Point(e.x,e.y),this.pe=new i.Point(n.x,n.y);return}if(t.length===1&&t[0]instanceof i.Point){this.ps=t[0].clone();return}if(t.length===2&&t[0]instanceof i.Point&&t[1]instanceof i.Point){this.ps=t[0].clone(),this.pe=t[1].clone();return}if(t.length===4){this.ps=new i.Point(t[0],t[1]),this.pe=new i.Point(t[2],t[3]);return}throw E.ILLEGAL_PARAMETERS}}clone(){return new i.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new i.Vector(this.start,this.end).slope}get box(){return new i.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return i.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return Ct(this,t);if(t instanceof i.Ray)return ce(t,this);if(t instanceof i.Segment)return Qt(this,t);if(t instanceof i.Circle)return Wt(this,t);if(t instanceof i.Box)return Fn(this,t);if(t instanceof i.Arc)return Et(this,t);if(t instanceof i.Polygon)return ue(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.segment2circle(this,t);return[e,n]}if(t instanceof i.Line){let[e,n]=i.Distance.segment2line(this,t);return[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2segment(this,t);return[e,n]}if(t instanceof i.Arc){let[e,n]=i.Distance.segment2arc(this,t);return[e,n]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof i.PlanarSet){let[e,n]=i.Distance.shape2planarSet(this,t);return[e,n]}}tangentInStart(){return new i.Vector(this.start,this.end).normalize()}tangentInEnd(){return new i.Vector(this.end,this.start).normalize()}reverse(){return new Yt(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new i.Segment(this.start,t),new i.Segment(t,this.end)]}middle(){return new i.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(t==0)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new i.Point((this.end.x-this.start.x)*e+this.start.x,(this.end.y-this.start.y)*e+this.start.y)}distanceToPoint(t){let[e,...n]=i.Distance.point2segment(t,this);return e}definiteIntegral(t=0){let e=this.end.x-this.start.x,n=this.start.y-t,s=this.end.y-t;return e*(n+s)/2}transform(t=new i.Matrix){return new Yt(this.ps.transform(t),this.pe.transform(t))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new i.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return` -`}}i.Segment=Yt;const hi=(...r)=>new i.Segment(...r);i.segment=hi;let{vector:kt}=i,ci=class cn extends nt{constructor(...t){if(super(),this.pt=new i.Point,this.norm=new i.Vector(0,1),t.length!==0){if(t.length===1&&t[0]instanceof Object&&t[0].name==="line"){let{pt:e,norm:n}=t[0];this.pt=new i.Point(e),this.norm=new i.Vector(n);return}if(t.length===2){let e=t[0],n=t[1];if(e instanceof i.Point&&n instanceof i.Point){this.pt=e,this.norm=cn.points2norm(e,n),this.norm.dot(kt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}if(e instanceof i.Point&&n instanceof i.Vector){if(i.Utils.EQ_0(n.x)&&i.Utils.EQ_0(n.y))throw E.ILLEGAL_PARAMETERS;this.pt=e.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),this.norm.dot(kt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}if(e instanceof i.Vector&&n instanceof i.Point){if(i.Utils.EQ_0(e.x)&&i.Utils.EQ_0(e.y))throw E.ILLEGAL_PARAMETERS;this.pt=n.clone(),this.norm=e.clone(),this.norm=this.norm.normalize(),this.norm.dot(kt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}}throw E.ILLEGAL_PARAMETERS}}clone(){return new i.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new i.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new i.Vector(this.norm.y,-this.norm.x).slope}get standard(){let t=this.norm.x,e=this.norm.y,n=this.norm.dot(kt(this.pt.x,this.pt.y));return[t,e,n]}parallelTo(t){return i.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new i.Vector(this.pt,t);return i.Utils.EQ_0(this.norm.dot(e))}coord(t){return kt(t.x,t.y).cross(this.norm)}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return mt(this,t);if(t instanceof i.Ray)return ze(t,this);if(t instanceof i.Circle)return ft(this,t);if(t instanceof i.Box)return xt(this,t);if(t instanceof i.Segment)return Ct(t,this);if(t instanceof i.Arc)return zt(this,t);if(t instanceof i.Polygon)return Nt(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof i.Arc){let[e,n]=i.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof i.Point)return[new i.Ray(t,this.norm),new i.Ray(t,this.norm)];{let e=new i.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new i.Point){return new i.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new i.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((e,n)=>this.coord(e)this.coord(n)?1:0)}get name(){return"line"}svg(t,e={}){let n=xt(this,t);if(n.length===0)return"";let s=n[0],l=n.length===2?n[1]:n.find(a=>!a.equalTo(s));return l===void 0&&(l=s),new i.Segment(s,l).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw E.ILLEGAL_PARAMETERS;return new i.Vector(t,e).normalize().rotate90CCW()}};i.Line=ci;const di=(...r)=>new i.Line(...r);i.line=di;let gi=class extends nt{constructor(...t){if(super(),this.pc=new i.Point,this.r=1,t.length===1&&t[0]instanceof Object&&t[0].name==="circle"){let{pc:e,r:n}=t[0];this.pc=new i.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof i.Point&&(this.pc=e.clone()),n!==void 0&&(this.r=n)}}clone(){return new i.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new i.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){if(t instanceof i.Point)return i.Utils.LE(t.distanceTo(this.center)[0],this.r);if(t instanceof i.Segment)return i.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&i.Utils.LE(t.end.distanceTo(this.center)[0],this.r);if(t instanceof i.Arc)return this.intersect(t).length===0&&i.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&i.Utils.LE(t.end.distanceTo(this.center)[0],this.r);if(t instanceof i.Circle)return this.intersect(t).length===0&&i.Utils.LE(t.r,this.r)&&i.Utils.LE(t.center.distanceTo(this.center)[0],this.r)}toArc(t=!0){return new i.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e||!(this.pc.x===0&&this.pc.y===0))throw E.OPERATION_IS_NOT_SUPPORTED;return new i.Circle(this.pc,this.r*t)}transform(t=new i.Matrix){return new i.Circle(this.pc.transform(t),this.r)}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return ft(t,this);if(t instanceof i.Ray)return De(t,this);if(t instanceof i.Segment)return Wt(t,this);if(t instanceof i.Circle)return ke(t,this);if(t instanceof i.Box)return Vn(this,t);if(t instanceof i.Arc)return fe(t,this);if(t instanceof i.Polygon)return $e(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.circle2circle(this,t);return[e,n]}if(t instanceof i.Line){let[e,n]=i.Distance.circle2line(this,t);return[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Arc){let[e,n]=i.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof i.PlanarSet){let[e,n]=i.Distance.shape2planarSet(this,t);return[e,n]}}get name(){return"circle"}svg(t={}){return` + ${ut({fill:"red",...t})} />`}};i.Point=ai;const fi=(...r)=>new i.Point(...r);i.point=fi;let ui=class extends nt{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let e=t[0];if(typeof e[0]=="number"&&typeof e[1]=="number"){this.x=e[0],this.y=e[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="vector"){let{x:e,y:n}=t[0];this.x=e,this.y=n;return}if(t.length===2){let e=t[0],n=t[1];if(typeof e=="number"&&typeof n=="number"){this.x=e,this.y=n;return}if(e instanceof i.Point&&n instanceof i.Point){this.x=n.x-e.x,this.y=n.y-e.y;return}}throw v.ILLEGAL_PARAMETERS}}clone(){return new i.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}equalTo(t){return i.Utils.EQ(this.x,t.x)&&i.Utils.EQ(this.y,t.y)}multiply(t){return new i.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(!i.Utils.EQ_0(this.length))return new i.Vector(this.x/this.length,this.y/this.length);throw v.ZERO_DIVISION}rotate(t,e=new i.Point){if(e.x===0&&e.y===0)return this.transform(new Ut().rotate(t));throw v.OPERATION_IS_NOT_SUPPORTED}transform(t){return new i.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new i.Vector(-this.y,this.x)}rotate90CW(){return new i.Vector(this.y,-this.x)}invert(){return new i.Vector(-this.x,-this.y)}add(t){return new i.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new i.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),s=Math.atan2(e.cross(n),e.dot(n));return s<0&&(s+=2*Math.PI),s}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};i.Vector=ui;const Je=(...r)=>new i.Vector(...r);i.vector=Je;class Yt extends nt{constructor(...t){if(super(),this.ps=new i.Point,this.pe=new i.Point,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===4){let e=t[0];this.ps=new i.Point(e[0],e[1]),this.pe=new i.Point(e[2],e[3]);return}if(t.length===1&&t[0]instanceof Object&&t[0].name==="segment"){let{ps:e,pe:n}=t[0];this.ps=new i.Point(e.x,e.y),this.pe=new i.Point(n.x,n.y);return}if(t.length===1&&t[0]instanceof i.Point){this.ps=t[0].clone();return}if(t.length===2&&t[0]instanceof i.Point&&t[1]instanceof i.Point){this.ps=t[0].clone(),this.pe=t[1].clone();return}if(t.length===4){this.ps=new i.Point(t[0],t[1]),this.pe=new i.Point(t[2],t[3]);return}throw v.ILLEGAL_PARAMETERS}}clone(){return new i.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new i.Vector(this.start,this.end).slope}get box(){return new i.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return i.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return Ct(this,t);if(t instanceof i.Ray)return ce(t,this);if(t instanceof i.Segment)return Qt(this,t);if(t instanceof i.Circle)return Wt(this,t);if(t instanceof i.Box)return Fn(this,t);if(t instanceof i.Arc)return Et(this,t);if(t instanceof i.Polygon)return ue(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.segment2circle(this,t);return[e,n]}if(t instanceof i.Line){let[e,n]=i.Distance.segment2line(this,t);return[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2segment(this,t);return[e,n]}if(t instanceof i.Arc){let[e,n]=i.Distance.segment2arc(this,t);return[e,n]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof i.PlanarSet){let[e,n]=i.Distance.shape2planarSet(this,t);return[e,n]}}tangentInStart(){return new i.Vector(this.start,this.end).normalize()}tangentInEnd(){return new i.Vector(this.end,this.start).normalize()}reverse(){return new Yt(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new i.Segment(this.start,t),new i.Segment(t,this.end)]}middle(){return new i.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(t==0)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new i.Point((this.end.x-this.start.x)*e+this.start.x,(this.end.y-this.start.y)*e+this.start.y)}distanceToPoint(t){let[e,...n]=i.Distance.point2segment(t,this);return e}definiteIntegral(t=0){let e=this.end.x-this.start.x,n=this.start.y-t,s=this.end.y-t;return e*(n+s)/2}transform(t=new i.Matrix){return new Yt(this.ps.transform(t),this.pe.transform(t))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new i.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return` +`}}i.Segment=Yt;const hi=(...r)=>new i.Segment(...r);i.segment=hi;let{vector:kt}=i,ci=class cn extends nt{constructor(...t){if(super(),this.pt=new i.Point,this.norm=new i.Vector(0,1),t.length!==0){if(t.length===1&&t[0]instanceof Object&&t[0].name==="line"){let{pt:e,norm:n}=t[0];this.pt=new i.Point(e),this.norm=new i.Vector(n);return}if(t.length===2){let e=t[0],n=t[1];if(e instanceof i.Point&&n instanceof i.Point){this.pt=e,this.norm=cn.points2norm(e,n),this.norm.dot(kt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}if(e instanceof i.Point&&n instanceof i.Vector){if(i.Utils.EQ_0(n.x)&&i.Utils.EQ_0(n.y))throw v.ILLEGAL_PARAMETERS;this.pt=e.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),this.norm.dot(kt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}if(e instanceof i.Vector&&n instanceof i.Point){if(i.Utils.EQ_0(e.x)&&i.Utils.EQ_0(e.y))throw v.ILLEGAL_PARAMETERS;this.pt=n.clone(),this.norm=e.clone(),this.norm=this.norm.normalize(),this.norm.dot(kt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}}throw v.ILLEGAL_PARAMETERS}}clone(){return new i.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new i.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new i.Vector(this.norm.y,-this.norm.x).slope}get standard(){let t=this.norm.x,e=this.norm.y,n=this.norm.dot(kt(this.pt.x,this.pt.y));return[t,e,n]}parallelTo(t){return i.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new i.Vector(this.pt,t);return i.Utils.EQ_0(this.norm.dot(e))}coord(t){return kt(t.x,t.y).cross(this.norm)}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return mt(this,t);if(t instanceof i.Ray)return ze(t,this);if(t instanceof i.Circle)return ft(this,t);if(t instanceof i.Box)return xt(this,t);if(t instanceof i.Segment)return Ct(t,this);if(t instanceof i.Arc)return zt(this,t);if(t instanceof i.Polygon)return Nt(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof i.Arc){let[e,n]=i.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof i.Point)return[new i.Ray(t,this.norm),new i.Ray(t,this.norm)];{let e=new i.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new i.Point){return new i.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new i.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((e,n)=>this.coord(e)this.coord(n)?1:0)}get name(){return"line"}svg(t,e={}){let n=xt(this,t);if(n.length===0)return"";let s=n[0],l=n.length===2?n[1]:n.find(a=>!a.equalTo(s));return l===void 0&&(l=s),new i.Segment(s,l).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw v.ILLEGAL_PARAMETERS;return new i.Vector(t,e).normalize().rotate90CCW()}};i.Line=ci;const di=(...r)=>new i.Line(...r);i.line=di;let gi=class extends nt{constructor(...t){if(super(),this.pc=new i.Point,this.r=1,t.length===1&&t[0]instanceof Object&&t[0].name==="circle"){let{pc:e,r:n}=t[0];this.pc=new i.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof i.Point&&(this.pc=e.clone()),n!==void 0&&(this.r=n)}}clone(){return new i.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new i.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){if(t instanceof i.Point)return i.Utils.LE(t.distanceTo(this.center)[0],this.r);if(t instanceof i.Segment)return i.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&i.Utils.LE(t.end.distanceTo(this.center)[0],this.r);if(t instanceof i.Arc)return this.intersect(t).length===0&&i.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&i.Utils.LE(t.end.distanceTo(this.center)[0],this.r);if(t instanceof i.Circle)return this.intersect(t).length===0&&i.Utils.LE(t.r,this.r)&&i.Utils.LE(t.center.distanceTo(this.center)[0],this.r)}toArc(t=!0){return new i.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e||!(this.pc.x===0&&this.pc.y===0))throw v.OPERATION_IS_NOT_SUPPORTED;return new i.Circle(this.pc,this.r*t)}transform(t=new i.Matrix){return new i.Circle(this.pc.transform(t),this.r)}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return ft(t,this);if(t instanceof i.Ray)return De(t,this);if(t instanceof i.Segment)return Wt(t,this);if(t instanceof i.Circle)return ke(t,this);if(t instanceof i.Box)return Vn(this,t);if(t instanceof i.Arc)return fe(t,this);if(t instanceof i.Polygon)return $e(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.circle2circle(this,t);return[e,n]}if(t instanceof i.Line){let[e,n]=i.Distance.circle2line(this,t);return[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Arc){let[e,n]=i.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof i.PlanarSet){let[e,n]=i.Distance.shape2planarSet(this,t);return[e,n]}}get name(){return"circle"}svg(t={}){return` `}};i.Circle=gi;const _i=(...r)=>new i.Circle(...r);i.circle=_i;class pi extends nt{constructor(...t){if(super(),this.pc=new i.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=i.CCW,t.length!==0)if(t.length===1&&t[0]instanceof Object&&t[0].name==="arc"){let{pc:e,r:n,startAngle:s,endAngle:l,counterClockwise:o}=t[0];this.pc=new i.Point(e.x,e.y),this.r=n,this.startAngle=s,this.endAngle=l,this.counterClockwise=o}else{let[e,n,s,l,o]=[...t];e&&e instanceof i.Point&&(this.pc=e.clone()),n!==void 0&&(this.r=n),s!==void 0&&(this.startAngle=s),l!==void 0&&(this.endAngle=l),o!==void 0&&(this.counterClockwise=o)}}clone(){return new i.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){if(i.Utils.EQ(this.startAngle,this.endAngle))return 0;if(i.Utils.EQ(Math.abs(this.startAngle-this.endAngle),i.PIx2))return i.PIx2;let t;return this.counterClockwise?t=i.Utils.GT(this.endAngle,this.startAngle)?this.endAngle-this.startAngle:this.endAngle-this.startAngle+i.PIx2:t=i.Utils.GT(this.startAngle,this.endAngle)?this.startAngle-this.endAngle:this.startAngle-this.endAngle+i.PIx2,i.Utils.GT(t,i.PIx2)&&(t-=i.PIx2),i.Utils.LT(t,0)&&(t+=i.PIx2),t}get start(){return new i.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new i.Point(this.pc.x+this.r,this.pc.y).rotate(this.endAngle,this.pc)}get center(){return this.pc.clone()}get vertices(){return[this.start.clone(),this.end.clone()]}get length(){return Math.abs(this.sweep*this.r)}get box(){let e=this.breakToFunctional().reduce((n,s)=>n.merge(s.start.box),new i.Box);return e=e.merge(this.end.box),e}contains(t){if(!i.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new i.Vector(this.pc,t).slope,n=new i.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return i.Utils.LE(n.length,this.length)}split(t){if(this.start.equalTo(t))return[null,this.clone()];if(this.end.equalTo(t))return[this.clone(),null];let e=new i.Vector(this.pc,t).slope;return[new i.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new i.Arc(this.pc,this.r,e,this.endAngle,this.counterClockwise)]}middle(){let t=this.counterClockwise?this.startAngle+this.sweep/2:this.startAngle-this.sweep/2;return new i.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t>this.length||t<0)return null;if(t===0)return this.start;if(t===this.length)return this.end;let e=t/this.length,n=this.counterClockwise?this.startAngle+this.sweep*e:this.startAngle-this.sweep*e;return new i.Arc(this.pc,this.r,this.startAngle,n,this.counterClockwise).end}chordHeight(){return(1-Math.cos(Math.abs(this.sweep/2)))*this.r}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return zt(t,this);if(t instanceof i.Ray)return de(t,this);if(t instanceof i.Circle)return fe(this,t);if(t instanceof i.Segment)return Et(t,this);if(t instanceof i.Box)return Hn(this,t);if(t instanceof i.Arc)return Be(this,t);if(t instanceof i.Polygon)return he(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle){let[e,n]=i.Distance.arc2circle(this,t);return[e,n]}if(t instanceof i.Line){let[e,n]=i.Distance.arc2line(this,t);return[e,n]}if(t instanceof i.Segment){let[e,n]=i.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Arc){let[e,n]=i.Distance.arc2arc(this,t);return[e,n]}if(t instanceof i.Polygon){let[e,n]=i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof i.PlanarSet){let[e,n]=i.Distance.shape2planarSet(this,t);return[e,n]}}breakToFunctional(){let t=[],e=[0,Math.PI/2,2*Math.PI/2,3*Math.PI/2],n=[this.pc.translate(this.r,0),this.pc.translate(0,this.r),this.pc.translate(-this.r,0),this.pc.translate(0,-this.r)],s=[];for(let l=0;l<4;l++)n[l].on(this)&&s.push(new i.Arc(this.pc,this.r,this.startAngle,e[l],this.counterClockwise));if(s.length===0)t.push(this.clone());else{s.sort((a,h)=>a.length-h.length);for(let a=0;a0?t[t.length-1]:void 0,u;h?u=new i.Arc(this.pc,this.r,h.endAngle,s[a].endAngle,this.counterClockwise):u=new i.Arc(this.pc,this.r,this.startAngle,s[a].endAngle,this.counterClockwise),i.Utils.EQ_0(u.length)||t.push(u.clone())}let l=t.length>0?t[t.length-1]:void 0,o;l?o=new i.Arc(this.pc,this.r,l.endAngle,this.endAngle,this.counterClockwise):o=new i.Arc(this.pc,this.r,this.startAngle,this.endAngle,this.counterClockwise),!i.Utils.EQ_0(o.length)&&!i.Utils.EQ(o.sweep,2*Math.PI)&&t.push(o.clone())}return t}tangentInStart(){let t=new i.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new i.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new i.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new i.Matrix){let e=this.start.transform(t),n=this.end.transform(t),s=this.pc.transform(t),l=this.counterClockwise;return t.a*t.d<0&&(l=!l),i.Arc.arcSE(s,e,n,l)}static arcSE(t,e,n,s){let{vector:l}=i,o=l(t,e).slope,a=l(t,n).slope;i.Utils.EQ(o,a)&&(a+=2*Math.PI,s=!0);let h=l(t,e).length;return new i.Arc(t,h,o,a,s)}definiteIntegral(t=0){return this.breakToFunctional().reduce((s,l)=>s+l.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new i.Line(this.start,this.end),n=this.pc.leftTo(e),l=new i.Segment(this.start,this.end).definiteIntegral(t),o=this.circularSegmentArea();return n?l-o:l+o}circularSegmentArea(){return .5*this.r*this.r*(this.sweep-Math.sin(this.sweep))}sortPoints(t){let{vector:e}=i;return t.slice().sort((n,s)=>{let l=e(this.pc,n).slope,o=e(this.pc,s).slope;return lo?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";return i.Utils.EQ(this.sweep,2*Math.PI)?new i.Circle(this.pc,this.r).svg(t):` `}}i.Arc=pi;const mi=(...r)=>new i.Arc(...r);i.arc=mi;class Bt extends nt{constructor(t=void 0,e=void 0,n=void 0,s=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}clone(){return new Bt(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new i.Point(this.xmin,this.ymin)}get high(){return new i.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new i.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmaxt.xmax||this.ymaxt.ymax}intersect(t){return!this.not_intersect(t)}merge(t){return new Bt(this.xmin===void 0?t.xmin:Math.min(this.xmin,t.xmin),this.ymin===void 0?t.ymin:Math.min(this.ymin,t.ymin),this.xmax===void 0?t.xmax:Math.max(this.xmax,t.xmax),this.ymax===void 0?t.ymax:Math.max(this.ymax,t.ymax))}less_than(t){return!!(this.low.lessThan(t.low)||this.low.equalTo(t.low)&&this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}static comparable_max(t,e){return t.merge(e)}static comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,s){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}toPoints(){return[new i.Point(this.xmin,this.ymin),new i.Point(this.xmax,this.ymin),new i.Point(this.xmax,this.ymax),new i.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new i.Segment(t[0],t[1]),new i.Segment(t[1],t[2]),new i.Segment(t[2],t[3]),new i.Segment(t[3],t[0])]}rotate(t,e=new i.Point){throw E.OPERATION_IS_NOT_SUPPORTED}transform(t=new i.Matrix){return this.toPoints().map(n=>n.transform(t)).reduce((n,s)=>n.merge(s.box),new Bt)}contains(t){if(t instanceof i.Point)return t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax;if(t instanceof i.Segment)return t.vertices.every(e=>this.contains(e));if(t instanceof i.Box)return t.toSegments().every(e=>this.contains(e));if(t instanceof i.Circle)return this.contains(t.box);if(t instanceof i.Arc)return t.vertices.every(e=>this.contains(e))&&t.toSegments().every(e=>Et(e,t).length===0);if(t instanceof i.Line||t instanceof i.Ray)return!1;if(t instanceof i.Multiline)return t.toShapes().every(e=>this.contains(e));if(t instanceof i.Polygon)return this.contains(t.box)}get name(){return"box"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return` + ${ut({fill:"none",...t})} />`}}i.Arc=pi;const mi=(...r)=>new i.Arc(...r);i.arc=mi;class Bt extends nt{constructor(t=void 0,e=void 0,n=void 0,s=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}clone(){return new Bt(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new i.Point(this.xmin,this.ymin)}get high(){return new i.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new i.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmaxt.xmax||this.ymaxt.ymax}intersect(t){return!this.not_intersect(t)}merge(t){return new Bt(this.xmin===void 0?t.xmin:Math.min(this.xmin,t.xmin),this.ymin===void 0?t.ymin:Math.min(this.ymin,t.ymin),this.xmax===void 0?t.xmax:Math.max(this.xmax,t.xmax),this.ymax===void 0?t.ymax:Math.max(this.ymax,t.ymax))}less_than(t){return!!(this.low.lessThan(t.low)||this.low.equalTo(t.low)&&this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}static comparable_max(t,e){return t.merge(e)}static comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,s){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}toPoints(){return[new i.Point(this.xmin,this.ymin),new i.Point(this.xmax,this.ymin),new i.Point(this.xmax,this.ymax),new i.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new i.Segment(t[0],t[1]),new i.Segment(t[1],t[2]),new i.Segment(t[2],t[3]),new i.Segment(t[3],t[0])]}rotate(t,e=new i.Point){throw v.OPERATION_IS_NOT_SUPPORTED}transform(t=new i.Matrix){return this.toPoints().map(n=>n.transform(t)).reduce((n,s)=>n.merge(s.box),new Bt)}contains(t){if(t instanceof i.Point)return t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax;if(t instanceof i.Segment)return t.vertices.every(e=>this.contains(e));if(t instanceof i.Box)return t.toSegments().every(e=>this.contains(e));if(t instanceof i.Circle)return this.contains(t.box);if(t instanceof i.Arc)return t.vertices.every(e=>this.contains(e))&&t.toSegments().every(e=>Et(e,t).length===0);if(t instanceof i.Line||t instanceof i.Ray)return!1;if(t instanceof i.Multiline)return t.toShapes().every(e=>this.contains(e));if(t instanceof i.Polygon)return this.contains(t.box)}get name(){return"box"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return` `}}i.Box=Bt;const xi=(...r)=>new i.Box(...r);i.box=xi;class Ei{constructor(t){this.shape=t,this.next=void 0,this.prev=void 0,this.face=void 0,this.arc_length=0,this.bvStart=void 0,this.bvEnd=void 0,this.bv=void 0,this.overlap=void 0}get start(){return this.shape.start}get end(){return this.shape.end}get length(){return this.shape.length}get box(){return this.shape.box}get isSegment(){return this.shape instanceof i.Segment}get isArc(){return this.shape instanceof i.Arc}get isLine(){return this.shape instanceof i.Line}get isRay(){return this.shape instanceof i.Ray}middle(){return this.shape.middle()}pointAtLength(t){return this.shape.pointAtLength(t)}contains(t){return this.shape.contains(t)}setInclusion(t){if(this.bv!==void 0)return this.bv;if(this.shape instanceof i.Line||this.shape instanceof i.Ray)return this.bv=i.OUTSIDE,this.bv;if(this.bvStart===void 0&&(this.bvStart=Rt(t,this.start)),this.bvEnd===void 0&&(this.bvEnd=Rt(t,this.end)),this.bvStart===i.OUTSIDE||this.bvEnd==i.OUTSIDE)this.bv=i.OUTSIDE;else if(this.bvStart===i.INSIDE||this.bvEnd==i.INSIDE)this.bv=i.INSIDE;else{let e=Rt(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,s=t.shape;n instanceof i.Segment&&s instanceof i.Segment?n.start.equalTo(s.start)&&n.end.equalTo(s.end)?e=i.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&(e=i.OVERLAP_OPPOSITE):(n instanceof i.Arc&&s instanceof i.Arc||n instanceof i.Segment&&s instanceof i.Arc||n instanceof i.Arc&&s instanceof i.Segment)&&(n.start.equalTo(s.start)&&n.end.equalTo(s.end)&&n.middle().equalTo(s.middle())?e=i.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&n.middle().equalTo(s.middle())&&(e=i.OVERLAP_OPPOSITE)),this.overlap===void 0&&(this.overlap=e),t.overlap===void 0&&(t.overlap=e)}svg(){if(this.shape instanceof i.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof i.Arc){let t=this.shape,e,n=t.counterClockwise?"1":"0";if(i.Utils.EQ(t.sweep,2*Math.PI)){let s=t.counterClockwise?1:-1,l=new i.Arc(t.pc,t.r,t.startAngle,t.startAngle+s*Math.PI,t.counterClockwise),o=new i.Arc(t.pc,t.r,t.startAngle+s*Math.PI,t.endAngle,t.counterClockwise);return e="0",` A${l.r},${l.r} 0 ${e},${n} ${l.end.x},${l.end.y} A${o.r},${o.r} 0 ${e},${n} ${o.end.x},${o.end.y}`}else return e=t.sweep<=Math.PI?"0":"1",` A${t.r},${t.r} 0 ${e},${n} ${t.end.x},${t.end.y}`}}toJSON(){return this.shape.toJSON()}}i.Edge=Ei;class vi extends te{constructor(t,e){super(t,e),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let e=t||this.first,n=this.first?t?t===this.first:!1:!0;return t=e?e.next:void 0,{value:e,done:n}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,e){return super.insert(t,e),this.setCircularLinks(),this}remove(t){return super.remove(t),this}}class Tt extends vi{constructor(t,...e){if(super(),this._box=void 0,this._orientation=void 0,e.length!==0){if(e.length===1){if(e[0]instanceof Array){let n=e[0];if(n.length===0)return;if(n.every(s=>s instanceof i.Point)){let s=Tt.points2segments(n);this.shapes2face(t.edges,s)}else if(n.every(s=>s instanceof Array&&s.length===2)){let s=n.map(o=>new i.Point(o[0],o[1])),l=Tt.points2segments(s);this.shapes2face(t.edges,l)}else if(n.every(s=>s instanceof i.Segment||s instanceof i.Arc))this.shapes2face(t.edges,n);else if(n.every(s=>s.name==="segment"||s.name==="arc")){let s=[];for(let l of n){let o;l.name==="segment"?o=new i.Segment(l):o=new i.Arc(l),s.push(o)}this.shapes2face(t.edges,s)}}else if(e[0]instanceof Tt){let n=e[0];this.first=n.first,this.last=n.last;for(let s of n)t.edges.add(s)}else if(e[0]instanceof i.Circle)this.shapes2face(t.edges,[e[0].toArc(!0)]);else if(e[0]instanceof i.Box){let n=e[0];this.shapes2face(t.edges,[new i.Segment(new i.Point(n.xmin,n.ymin),new i.Point(n.xmax,n.ymin)),new i.Segment(new i.Point(n.xmax,n.ymin),new i.Point(n.xmax,n.ymax)),new i.Segment(new i.Point(n.xmax,n.ymax),new i.Point(n.xmin,n.ymax)),new i.Segment(new i.Point(n.xmin,n.ymax),new i.Point(n.xmin,n.ymin))])}}e.length===2&&e[0]instanceof i.Edge&&e[1]instanceof i.Edge&&(this.first=e[0],this.last=e[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(this._box===void 0){let t=new i.Box;for(let e of this)t=t.merge(e.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t0&&n)break}if(s.length>0&&n)break}return s}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)&&(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new i.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=` -M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t+=" z",t}}i.Face=Tt;class ge extends nt{constructor(...t){if(super(),this.pt=new i.Point,this.norm=new i.Vector(0,1),t.length!==0&&(t.length>=1&&t[0]instanceof i.Point&&(this.pt=t[0].clone()),t.length!==1)){if(t.length===2&&t[1]instanceof i.Vector){this.norm=t[1].clone();return}throw E.ILLEGAL_PARAMETERS}}clone(){return new ge(this.pt,this.norm)}get slope(){return new i.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new i.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||t===0?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let e=new i.Vector(this.pt,t);return i.Utils.EQ_0(this.norm.dot(e))&&i.Utils.GE(e.cross(this.norm),0)}coord(t){return Je(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new i.Segment(this.pt,t),new i.Ray(t,this.norm)]:[]}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Segment)return ce(this,t);if(t instanceof i.Arc)return de(this,t);if(t instanceof i.Line)return ze(this,t);if(t instanceof i.Ray)return Wn(this,t);if(t instanceof i.Circle)return De(this,t);if(t instanceof i.Box)return Qn(this,t);if(t instanceof i.Polygon)return Qe(this,t)}rotate(t,e=new i.Point){return new i.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new i.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=new i.Line(this.pt,this.norm),s=xt(n,t);return s=s.filter(o=>this.contains(o)),s.length===0||s.length===2?"":new i.Segment(this.pt,s[0]).svg(e)}}i.Ray=ge;const wi=(...r)=>new i.Ray(...r);i.ray=wi;class ht{constructor(){this.faces=new i.PlanarSet,this.edges=new i.PlanarSet;let t=[...arguments];if(t.length===1&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof i.Circle||t[0]instanceof i.Box)){let e=t[0];if(t[0]instanceof Array&&t[0].every(n=>n instanceof Array))if(e.every(n=>n instanceof Array&&n.length===2&&typeof n[0]=="number"&&typeof n[1]=="number"))this.faces.add(new i.Face(this,e));else for(let n of e)if(n instanceof Array&&n[0]instanceof Array&&n[0].every(s=>s instanceof Array&&s.length===2&&typeof s[0]=="number"&&typeof s[1]=="number"))for(let s of n)this.faces.add(new i.Face(this,s));else this.faces.add(new i.Face(this,n));else this.faces.add(new i.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new i.Box)}get vertices(){return[...this.edges].map(t=>t.start)}clone(){let t=new ht;for(let e of this.faces)t.addFace(e.shapes);return t}isEmpty(){return this.edges.size===0}isValid(){let t=!0;for(let e of this.faces)if(!e.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((e,n)=>e+n.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new i.Face(this,...t);return this.faces.add(e),e}deleteFace(t){for(let e of t)this.edges.delete(e);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let n of this.edges)n.face=null;let t,e=!0;for(;e;){e=!1;for(let n of this.edges)if(n.face===null){t=n,e=!0;break}if(e){let n=t;do n=n.next;while(n.next!==t);this.addFace(t,n)}}}removeChain(t,e,n){if(n.next===e){this.deleteFace(t);return}for(let s=e;s!==n.next;s=s.next)if(t.remove(s),this.edges.delete(s),t.isEmpty()){this.deleteFace(t);break}}addVertex(t,e){let n=e.shape.split(t);if(n[0]===null)return e.prev;if(n[1]===null)return e;let s=new i.Edge(n[0]),l=e.prev;return e.face.insert(s,l),this.edges.delete(e),this.edges.add(s),e.shape=n[1],this.edges.add(e),s}removeEndVertex(t){const e=t.next;e!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){let e=this.clone(),n={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let o of t.edges)for(let a of e.edges){let h=qe(o,a);for(let u of h)dt(o,u,n.int_points1),dt(a,u,n.int_points2)}if(n.int_points1.length===0)return e;n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2),_t(t,n.int_points1_sorted),_t(e,n.int_points2_sorted),ee(n),n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2),ne(n.int_points1),ie(n.int_points1,e);for(let o of n.int_points1_sorted)o.edge_before&&o.edge_after&&o.edge_before.bv===o.edge_after.bv&&(n.int_points2[o.id]=-1,o.id=-1);if(n.int_points1=n.int_points1.filter(o=>o.id>=0),n.int_points2=n.int_points2.filter(o=>o.id>=0),n.int_points1.length===0)return e;n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2);let s,l;for(let o=1;oe.edges.add(f)),u=u.reverse().map(f=>new i.Edge(f.shape.reverse()));for(let f=0;fe.edges.add(f))}return e.recreateFaces(),e}cutWithLine(t){let e=new C([t]);return this.cut(e)}findEdgeByPoint(t){let e;for(let n of this.faces)if(e=n.findEdgeByPoint(t),e!==void 0)break;return e}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((s,l)=>l.area()-s.area());let e=[...t[0].faces][0].orientation(),n=t.filter(s=>[...s.faces][0].orientation()===e);for(let s of t){let l=[...s.faces][0];if(l.orientation()!==e){for(let o of n)if(l.shapes.every(a=>o.contains(a))){o.addFace(l.shapes);break}}}return n}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof i.Point){let e=Rt(this,t);return e===$t||e===M}else return Xe(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle||t instanceof i.Line||t instanceof i.Segment||t instanceof i.Arc){let[e,n]=i.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Polygon){let e=[Number.POSITIVE_INFINITY,new i.Segment],n,s;for(let l of this.edges){let o=e[0];[n,s]=i.Distance.shape2planarSet(l.shape,t.edges,o),i.Utils.LT(n,o)&&(e=[n,s])}return e}}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return Nt(t,this);if(t instanceof i.Ray)return Qe(t,this);if(t instanceof i.Circle)return $e(t,this);if(t instanceof i.Segment)return ue(t,this);if(t instanceof i.Arc)return he(t,this);if(t instanceof i.Polygon)return Dn(t,this)}translate(t){let e=new ht;for(let n of this.faces)e.addFace(n.shapes.map(s=>s.translate(t)));return e}rotate(t=0,e=new i.Point){let n=new ht;for(let s of this.faces)n.addFace(s.shapes.map(l=>l.rotate(t,e)));return n}scale(t,e){let n=new ht;for(let s of this.faces)n.addFace(s.shapes.map(l=>l.scale(t,e)));return n}transform(t=new i.Matrix){let e=new ht;for(let n of this.faces)e.addFace(n.shapes.map(s=>s.transform(t)));return e}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}svg(t={}){let e=` +M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t+=" z",t}}i.Face=Tt;class ge extends nt{constructor(...t){if(super(),this.pt=new i.Point,this.norm=new i.Vector(0,1),t.length!==0&&(t.length>=1&&t[0]instanceof i.Point&&(this.pt=t[0].clone()),t.length!==1)){if(t.length===2&&t[1]instanceof i.Vector){this.norm=t[1].clone();return}throw v.ILLEGAL_PARAMETERS}}clone(){return new ge(this.pt,this.norm)}get slope(){return new i.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new i.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||t===0?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let e=new i.Vector(this.pt,t);return i.Utils.EQ_0(this.norm.dot(e))&&i.Utils.GE(e.cross(this.norm),0)}coord(t){return Je(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new i.Segment(this.pt,t),new i.Ray(t,this.norm)]:[]}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Segment)return ce(this,t);if(t instanceof i.Arc)return de(this,t);if(t instanceof i.Line)return ze(this,t);if(t instanceof i.Ray)return Wn(this,t);if(t instanceof i.Circle)return De(this,t);if(t instanceof i.Box)return Qn(this,t);if(t instanceof i.Polygon)return Qe(this,t)}rotate(t,e=new i.Point){return new i.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new i.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=new i.Line(this.pt,this.norm),s=xt(n,t);return s=s.filter(o=>this.contains(o)),s.length===0||s.length===2?"":new i.Segment(this.pt,s[0]).svg(e)}}i.Ray=ge;const wi=(...r)=>new i.Ray(...r);i.ray=wi;class ht{constructor(){this.faces=new i.PlanarSet,this.edges=new i.PlanarSet;let t=[...arguments];if(t.length===1&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof i.Circle||t[0]instanceof i.Box)){let e=t[0];if(t[0]instanceof Array&&t[0].every(n=>n instanceof Array))if(e.every(n=>n instanceof Array&&n.length===2&&typeof n[0]=="number"&&typeof n[1]=="number"))this.faces.add(new i.Face(this,e));else for(let n of e)if(n instanceof Array&&n[0]instanceof Array&&n[0].every(s=>s instanceof Array&&s.length===2&&typeof s[0]=="number"&&typeof s[1]=="number"))for(let s of n)this.faces.add(new i.Face(this,s));else this.faces.add(new i.Face(this,n));else this.faces.add(new i.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new i.Box)}get vertices(){return[...this.edges].map(t=>t.start)}clone(){let t=new ht;for(let e of this.faces)t.addFace(e.shapes);return t}isEmpty(){return this.edges.size===0}isValid(){let t=!0;for(let e of this.faces)if(!e.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((e,n)=>e+n.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new i.Face(this,...t);return this.faces.add(e),e}deleteFace(t){for(let e of t)this.edges.delete(e);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let n of this.edges)n.face=null;let t,e=!0;for(;e;){e=!1;for(let n of this.edges)if(n.face===null){t=n,e=!0;break}if(e){let n=t;do n=n.next;while(n.next!==t);this.addFace(t,n)}}}removeChain(t,e,n){if(n.next===e){this.deleteFace(t);return}for(let s=e;s!==n.next;s=s.next)if(t.remove(s),this.edges.delete(s),t.isEmpty()){this.deleteFace(t);break}}addVertex(t,e){let n=e.shape.split(t);if(n[0]===null)return e.prev;if(n[1]===null)return e;let s=new i.Edge(n[0]),l=e.prev;return e.face.insert(s,l),this.edges.delete(e),this.edges.add(s),e.shape=n[1],this.edges.add(e),s}removeEndVertex(t){const e=t.next;e!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){let e=this.clone(),n={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let o of t.edges)for(let a of e.edges){let h=qe(o,a);for(let u of h)dt(o,u,n.int_points1),dt(a,u,n.int_points2)}if(n.int_points1.length===0)return e;n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2),_t(t,n.int_points1_sorted),_t(e,n.int_points2_sorted),ee(n),n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2),ne(n.int_points1),ie(n.int_points1,e);for(let o of n.int_points1_sorted)o.edge_before&&o.edge_after&&o.edge_before.bv===o.edge_after.bv&&(n.int_points2[o.id]=-1,o.id=-1);if(n.int_points1=n.int_points1.filter(o=>o.id>=0),n.int_points2=n.int_points2.filter(o=>o.id>=0),n.int_points1.length===0)return e;n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2);let s,l;for(let o=1;oe.edges.add(f)),u=u.reverse().map(f=>new i.Edge(f.shape.reverse()));for(let f=0;fe.edges.add(f))}return e.recreateFaces(),e}cutWithLine(t){let e=new C([t]);return this.cut(e)}findEdgeByPoint(t){let e;for(let n of this.faces)if(e=n.findEdgeByPoint(t),e!==void 0)break;return e}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((s,l)=>l.area()-s.area());let e=[...t[0].faces][0].orientation(),n=t.filter(s=>[...s.faces][0].orientation()===e);for(let s of t){let l=[...s.faces][0];if(l.orientation()!==e){for(let o of n)if(l.shapes.every(a=>o.contains(a))){o.addFace(l.shapes);break}}}return n}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof i.Point){let e=Rt(this,t);return e===$t||e===M}else return Xe(this,t)}distanceTo(t){if(t instanceof i.Point){let[e,n]=i.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Circle||t instanceof i.Line||t instanceof i.Segment||t instanceof i.Arc){let[e,n]=i.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof i.Polygon){let e=[Number.POSITIVE_INFINITY,new i.Segment],n,s;for(let l of this.edges){let o=e[0];[n,s]=i.Distance.shape2planarSet(l.shape,t.edges,o),i.Utils.LT(n,o)&&(e=[n,s])}return e}}intersect(t){if(t instanceof i.Point)return this.contains(t)?[t]:[];if(t instanceof i.Line)return Nt(t,this);if(t instanceof i.Ray)return Qe(t,this);if(t instanceof i.Circle)return $e(t,this);if(t instanceof i.Segment)return ue(t,this);if(t instanceof i.Arc)return he(t,this);if(t instanceof i.Polygon)return Dn(t,this)}translate(t){let e=new ht;for(let n of this.faces)e.addFace(n.shapes.map(s=>s.translate(t)));return e}rotate(t=0,e=new i.Point){let n=new ht;for(let s of this.faces)n.addFace(s.shapes.map(l=>l.rotate(t,e)));return n}scale(t,e){let n=new ht;for(let s of this.faces)n.addFace(s.shapes.map(l=>l.scale(t,e)));return n}transform(t=new i.Matrix){let e=new ht;for(let n of this.faces)e.addFace(n.shapes.map(s=>s.transform(t)));return e}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}svg(t={}){let e=` -`,e}}i.Polygon=ht;const Ti=(...r)=>new i.Polygon(...r);i.polygon=Ti;const{Circle:_e,Line:tn,Point:en,Vector:Zt,Utils:pe}=i;class Ft{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new Zt(t.pc,e),s=t.r*t.r,l=n.dot(n);return pe.EQ_0(l)?new en(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(s/l))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(pe.EQ(n,e.r)){let s=t.r*t.r/(2*e.r),l=new Zt(t.pc,e.pc);l=l.normalize();let o=t.pc.translate(l.multiply(s));return new tn(o,l)}else{let s=new Zt(t.pc,e.pc),l=t.r*t.r/(s.dot(s)-e.r*e.r),o=t.pc.translate(s.multiply(l)),a=Math.abs(l)*e.r;return new _e(o,a)}}static inverseLine(t,e){const[n,s]=t.pc.distanceTo(e);if(pe.EQ_0(n))return e.clone();{let l=t.r*t.r/(2*n),o=new Zt(t.pc,s.end);return o=o.multiply(l/n),new _e(t.pc.translate(o),l)}}inverse(t){if(t instanceof en)return Ft.inversePoint(this.circle,t);if(t instanceof _e)return Ft.inverseCircle(this.circle,t);if(t instanceof tn)return Ft.inverseLine(this.circle,t)}}i.Inversion=Ft;const Si=r=>new i.Inversion(r);i.inversion=Si;class d{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new i.Vector(t,n).length,new i.Segment(t,n)]}static point2circle(t,e){let[n,s]=t.distanceTo(e.center);if(i.Utils.EQ_0(n))return[e.r,new i.Segment(t,e.toArc().start)];{let l=Math.abs(n-e.r),o=new i.Vector(e.pc,t).normalize().multiply(e.r),a=e.pc.translate(o);return[l,new i.Segment(t,a)]}}static point2segment(t,e){if(e.start.equalTo(e.end))return d.point2point(t,e.start);let n=new i.Vector(e.start,e.end),s=new i.Vector(e.start,t),l=new i.Vector(e.end,t),o=n.dot(s),a=-n.dot(l),h,u;if(i.Utils.GE(o,0)&&i.Utils.GE(a,0)){let f=e.tangentInStart();return h=Math.abs(f.cross(s)),u=e.start.translate(f.multiply(f.dot(s))),[h,new i.Segment(t,u)]}else return o<0?t.distanceTo(e.start):t.distanceTo(e.end)}static point2arc(t,e){let n=new i.Circle(e.pc,e.r),s=[],l,o;return[l,o]=d.point2circle(t,n),o.end.on(e)&&s.push(d.point2circle(t,n)),s.push(d.point2point(t,e.start)),s.push(d.point2point(t,e.end)),d.sort(s),s[0]}static segment2line(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=[];return s.push(d.point2line(t.start,e)),s.push(d.point2line(t.end,e)),d.sort(s),s[0]}static segment2segment(t,e){let n=Qt(t,e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=[],l,o;return[l,o]=d.point2segment(e.start,t),s.push([l,o.reverse()]),[l,o]=d.point2segment(e.end,t),s.push([l,o.reverse()]),s.push(d.point2segment(t.start,e)),s.push(d.point2segment(t.end,e)),d.sort(s),s[0]}static segment2circle(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Line(t.ps,t.pe),[l,o]=d.point2line(e.center,s);if(i.Utils.GE(l,e.r)&&o.end.on(t))return d.point2circle(o.end,e);{let[a,h]=d.point2circle(t.start,e),[u,f]=d.point2circle(t.end,e);return i.Utils.LT(a,u)?[a,h]:[u,f]}}static segment2arc(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Line(t.ps,t.pe),l=new i.Circle(e.pc,e.r),[o,a]=d.point2line(l.center,s);if(i.Utils.GE(o,l.r)&&a.end.on(t)){let[g,x]=d.point2circle(a.end,l);if(x.end.on(e))return[g,x]}let h=[];h.push(d.point2arc(t.start,e)),h.push(d.point2arc(t.end,e));let u,f;return[u,f]=d.point2segment(e.start,t),h.push([u,f.reverse()]),[u,f]=d.point2segment(e.end,t),h.push([u,f.reverse()]),d.sort(h),h[0]}static circle2circle(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];if(t.center.equalTo(e.center)){let s=t.toArc(),l=e.toArc();return d.point2point(s.start,l.start)}else{let s=new i.Line(t.center,e.center),l=s.intersect(t),o=s.intersect(e),a=[];return a.push(d.point2point(l[0],o[0])),a.push(d.point2point(l[0],o[1])),a.push(d.point2point(l[1],o[0])),a.push(d.point2point(l[1],o[1])),d.sort(a),a[0]}}static circle2line(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let[s,l]=d.point2line(t.center,e),[o,a]=d.point2circle(l.end,t);return a=a.reverse(),[o,a]}static arc2line(t,e){let n=e.intersect(t);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Circle(t.center,t.r),[l,o]=d.point2line(s.center,e);if(i.Utils.GE(l,s.r)){let[a,h]=d.point2circle(o.end,s);if(h.end.on(t))return[a,h]}else{let a=[];return a.push(d.point2line(t.start,e)),a.push(d.point2line(t.end,e)),d.sort(a),a[0]}}static arc2circle(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Circle(t.center,t.r),[l,o]=d.circle2circle(s,e);if(o.start.on(t))return[l,o];{let a=[];return a.push(d.point2circle(t.start,e)),a.push(d.point2circle(t.end,e)),d.sort(a),a[0]}}static arc2arc(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Circle(t.center,t.r),l=new i.Circle(e.center,e.r),[o,a]=d.circle2circle(s,l);if(a.start.on(t)&&a.end.on(e))return[o,a];{let h=[],u,f;return[u,f]=d.point2arc(t.start,e),f.end.on(e)&&h.push([u,f]),[u,f]=d.point2arc(t.end,e),f.end.on(e)&&h.push([u,f]),[u,f]=d.point2arc(e.start,t),f.end.on(t)&&h.push([u,f.reverse()]),[u,f]=d.point2arc(e.end,t),f.end.on(t)&&h.push([u,f.reverse()]),[u,f]=d.point2point(t.start,e.start),h.push([u,f]),[u,f]=d.point2point(t.start,e.end),h.push([u,f]),[u,f]=d.point2point(t.end,e.start),h.push([u,f]),[u,f]=d.point2point(t.end,e.end),h.push([u,f]),d.sort(h),h[0]}}static point2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of e.edges){let[l,o]=s.shape instanceof i.Segment?d.point2segment(t,s.shape):d.point2arc(t,s.shape);i.Utils.LT(l,n[0])&&(n=[l,o])}return n}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of e.edges){let[l,o]=t.distanceTo(s.shape);i.Utils.LT(l,n[0])&&(n=[l,o])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of t.edges)for(let l of e.edges){let[o,a]=s.shape.distanceTo(l.shape);i.Utils.LT(o,n[0])&&(n=[o,a])}return n}static box2box_minmax(t,e){let n=Math.max(Math.max(t.xmin-e.xmax,0),Math.max(e.xmin-t.xmax,0)),s=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),l=n*n+s*s,o=t.merge(e),a=o.xmax-o.xmin,h=o.ymax-o.ymin,u=a*a+h*h;return[l,u]}static minmax_tree_process_level(t,e,n,s){let l,o;for(let f of e)[l,o]=d.box2box_minmax(t.box,f.item.key),f.item.value instanceof i.Edge?s.insert([l,o],f.item.value.shape):s.insert([l,o],f.item.value),i.Utils.LT(o,n)&&(n=o);if(e.length===0)return n;let a=e.map(f=>f.left.isNil()?void 0:f.left).filter(f=>f!==void 0),h=e.map(f=>f.right.isNil()?void 0:f.right).filter(f=>f!==void 0),u=[...a,...h].filter(f=>{let[g,x]=d.box2box_minmax(t.box,f.max);return i.Utils.LE(g,n)});return n=d.minmax_tree_process_level(t,u,n,s),n}static minmax_tree(t,e,n){let s=new Mt,l=[e.index.root],o=ni.Utils.LT(e[0],n[0])?-1:i.Utils.GT(e[0],n[0])?1:0)}static distance(t,e){return t.distanceTo(e)}}i.Distance=d,i.BooleanOperations=Nn,i.Relations=ri;const nn=i.Matrix,Xt=24,me=60,A=class A extends I.Path{constructor(t,e){if(super(),I.Util.setOptions(this,e),t==null)throw Error("latLng required");e=e||{},this._latLng=I.latLng(t),this._heading=e.heading,this._course=e.course,this._speed=e.speed,this._shapeOptions=e.shapeOptions||{leaderTime:me,defaultShapeSet:A.DEFAULT_SHAPE_SET},this._setShapeOptions(e.shapeOptions)}_project(){this._currentShapePoints=this._getProjectedShapePoints(),this._currentLeaderPoints=this._getLeaderShapePoints();const t=new I.Bounds;for(let e=0;en.minZoomLevel-e.minZoomLevel)}setLatLng(t){const e=this._latLng;return this._latLng=I.latLng(t),this.fire("move",{oldLatLng:e,latlng:this._latLng}),this.redraw()}setHeading(t){return this._heading=t,this.redraw()}setCourse(t){return this._course=t,this.redraw()}setSpeed(t){return this._speed=t,this.redraw()}setShapeOptions(t){return this._setShapeOptions(t),this.redraw()}getBounds(){return this._currentLatLngBounds}getLatLng(){return this._latLng}getSpeed(){return this._speed}getHeading(){return this._heading}getCourse(){return this._course}static createShape(t,e){return{points:t,length:e,breadth:e,units:"pixels"}}static createShapeSet(t){return{withHeading:A.createShape(A.DEFAULT_HEADING_SHAPE_POINTS,t),withoutHeading:A.createShape(A.DEFAULT_NOHEADING_SHAPE_POINTS,t)}}_getLatSizeOf(t){return t/40075017*360}_getLngSizeOf(t){return t/40075017*360/Math.cos(Math.PI/180*this._latLng.lat)}_getViewAngleFromModel(t){return t-Math.PI/2}_getLeaderShapePoints(){if(this._course===void 0||this._speed===void 0||this._shapeOptions===void 0||this._shapeOptions.leaderTime===void 0)return;const t=this._getViewAngleFromModel(this._course),e=this._speed*this._shapeOptions.leaderTime,n=this._calcRelativeLatLng(this._latLng,e,t);return this._latLngsToLayerPoints(this._latLng,n)}_calcRelativeLatLng(t,e,n){return new I.LatLng(t.lat-this._getLatSizeOf(e*Math.sin(n)),t.lng+this._getLngSizeOf(e*Math.cos(n)))}_latLngsToLayerPoints(...t){return t.map(e=>this._map.latLngToLayerPoint(e))}_getShapeSet(){if(this._shapeOptions.shapeSetEntries===void 0||this._shapeOptions.shapeSetEntries.length==0)return this._shapeOptions.defaultShapeSet?this._shapeOptions.defaultShapeSet:A.DEFAULT_SHAPE_SET;const t=this._map.getZoom(),e=this._shapeOptions.shapeSetEntries.sort((n,s)=>s.minZoomLevel-n.minZoomLevel).filter(n=>t>=n.minZoomLevel);return e.length>0?e[0].shapeSet:this._shapeOptions.defaultShapeSet?this._shapeOptions.defaultShapeSet:A.DEFAULT_SHAPE_SET}_getShape(){const t=this._getShapeSet();return this._heading!==void 0?t.withHeading:t.withoutHeading}_getTransformedShapePoints(){const t=this._getShape();let e=new nn;if(this._heading!==void 0){const s=this._getViewAngleFromModel(this._heading);e=e.rotate(s)}return t.center!==void 0&&(e=e.translate(-t.center[0],-t.center[1])),e=e.scale(t.length,t.breadth),[t.points.map(s=>e.transform(s)),t.units]}_getProjectedShapePoints(){const[t,e]=this._getTransformedShapePoints();switch(e){case"pixels":{const n=this._map.latLngToLayerPoint(this._latLng),s=new nn().translate(n.x,n.y);return t.map(l=>{const o=s.transform(l);return new I.Point(o[0],o[1])})}case"meters":return t.map(n=>this._map.latLngToLayerPoint(new I.LatLng(this._latLng.lat-this._getLatSizeOf(n[1]),this._latLng.lng+this._getLngSizeOf(n[0]))));default:throw`unsupported units: ${e}`}}static _toSVGPath(t,e){let n="";for(let s=0;sl";const s=I.DomUtil.create("div");return s.innerHTML=n,s}};It.DEFAULT_SILHOUETTE_SHAPE_POINTS=[[1,.5],[.75,1],[0,1],[0,0],[.75,0]];let Vt=It;function St(r,t,e){if(r!=null&&!(e&&!e(r)))return r.toFixed(t)}function Ni(r){return r==null?void 0:un(r).name}function Ri(r){if(r!=null)switch(r){case 0:return;case 1:return"GPS";case 2:return"GLONASS";case 3:return"combined GPS/GLONASS";case 4:return"Loran-C";case 5:return"Chayka";case 6:return"integrated navigation system";case 7:return"surveyed";case 8:return"Galileo";case 9:case 10:case 11:case 12:case 13:case 14:return`not used (${r})`;case 15:return"internal GNSS";default:return`unknown (${r})`}}function Ui(r){if(r!=null)switch(r){case 0:return"Under way using engine";case 1:return"At anchor";case 2:return"Not under command";case 3:return"Restricted manoeuverability";case 4:return"Constrained by her draught";case 5:return"Moored";case 6:return"Aground";case 7:return"Engaged in Fishing";case 8:return"Under way sailing";case 9:return"Reserved for future amendment of Navigational Status for HSC";case 10:return"Reserved for future amendment of Navigational Status for WIG";case 11:return"Reserved for future use";case 12:return"Reserved for future use";case 13:return"Reserved for future use";case 14:return"AIS-SART is active";case 15:return"Not defined (default)";default:return`unknown (${r})`}}function Mi(r){if(r==null)return;const t=[];if(!yt(r.month)&&!yt(r.day)&&t.push(`${r.month.toString().padStart(2,"0")}/${r.day.toString().padStart(2,"0")}`),!yt(r.hour)&&!yt(r.minute)&&t.push(`${r.hour.toString().padStart(2,"0")}:${r.minute.toString().padStart(2,"0")}`),t.length!==0)return`${t.join(" ")} UTC`}function an(r){if(r!=null)return r*Math.PI/180}function yt(r){return r==null}function fn(r){return r!=null&&r.A>0&&r.B>0&&r.C>0&&r.D>0}function L(r,t,e){if(t==null)return"";const n=String(t);return`${r}${n} ${yt(e)?"":e}`}function c(r,t,e){return{name:r,color:t,fillColor:e}}function un(r){if(r==null)return ln[0];if(r<0||r>99)return Ci;const t=ln[r];return yt(t)?Oi:t}I.trackSymbol=function(r,t){return new V(r,t)},I.TrackSymbol=V,I.aisTrackSymbol=function(r,t){return new Vt(r,t)},I.AISTrackSymbol=Vt,X.AISTrackSymbol=Vt,X.TrackSymbol=V,X.default=V,Object.defineProperties(X,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); +`,e}}i.Polygon=ht;const Ti=(...r)=>new i.Polygon(...r);i.polygon=Ti;const{Circle:_e,Line:tn,Point:en,Vector:Zt,Utils:pe}=i;class Ft{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new Zt(t.pc,e),s=t.r*t.r,l=n.dot(n);return pe.EQ_0(l)?new en(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(s/l))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(pe.EQ(n,e.r)){let s=t.r*t.r/(2*e.r),l=new Zt(t.pc,e.pc);l=l.normalize();let o=t.pc.translate(l.multiply(s));return new tn(o,l)}else{let s=new Zt(t.pc,e.pc),l=t.r*t.r/(s.dot(s)-e.r*e.r),o=t.pc.translate(s.multiply(l)),a=Math.abs(l)*e.r;return new _e(o,a)}}static inverseLine(t,e){const[n,s]=t.pc.distanceTo(e);if(pe.EQ_0(n))return e.clone();{let l=t.r*t.r/(2*n),o=new Zt(t.pc,s.end);return o=o.multiply(l/n),new _e(t.pc.translate(o),l)}}inverse(t){if(t instanceof en)return Ft.inversePoint(this.circle,t);if(t instanceof _e)return Ft.inverseCircle(this.circle,t);if(t instanceof tn)return Ft.inverseLine(this.circle,t)}}i.Inversion=Ft;const Si=r=>new i.Inversion(r);i.inversion=Si;class d{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new i.Vector(t,n).length,new i.Segment(t,n)]}static point2circle(t,e){let[n,s]=t.distanceTo(e.center);if(i.Utils.EQ_0(n))return[e.r,new i.Segment(t,e.toArc().start)];{let l=Math.abs(n-e.r),o=new i.Vector(e.pc,t).normalize().multiply(e.r),a=e.pc.translate(o);return[l,new i.Segment(t,a)]}}static point2segment(t,e){if(e.start.equalTo(e.end))return d.point2point(t,e.start);let n=new i.Vector(e.start,e.end),s=new i.Vector(e.start,t),l=new i.Vector(e.end,t),o=n.dot(s),a=-n.dot(l),h,u;if(i.Utils.GE(o,0)&&i.Utils.GE(a,0)){let f=e.tangentInStart();return h=Math.abs(f.cross(s)),u=e.start.translate(f.multiply(f.dot(s))),[h,new i.Segment(t,u)]}else return o<0?t.distanceTo(e.start):t.distanceTo(e.end)}static point2arc(t,e){let n=new i.Circle(e.pc,e.r),s=[],l,o;return[l,o]=d.point2circle(t,n),o.end.on(e)&&s.push(d.point2circle(t,n)),s.push(d.point2point(t,e.start)),s.push(d.point2point(t,e.end)),d.sort(s),s[0]}static segment2line(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=[];return s.push(d.point2line(t.start,e)),s.push(d.point2line(t.end,e)),d.sort(s),s[0]}static segment2segment(t,e){let n=Qt(t,e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=[],l,o;return[l,o]=d.point2segment(e.start,t),s.push([l,o.reverse()]),[l,o]=d.point2segment(e.end,t),s.push([l,o.reverse()]),s.push(d.point2segment(t.start,e)),s.push(d.point2segment(t.end,e)),d.sort(s),s[0]}static segment2circle(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Line(t.ps,t.pe),[l,o]=d.point2line(e.center,s);if(i.Utils.GE(l,e.r)&&o.end.on(t))return d.point2circle(o.end,e);{let[a,h]=d.point2circle(t.start,e),[u,f]=d.point2circle(t.end,e);return i.Utils.LT(a,u)?[a,h]:[u,f]}}static segment2arc(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Line(t.ps,t.pe),l=new i.Circle(e.pc,e.r),[o,a]=d.point2line(l.center,s);if(i.Utils.GE(o,l.r)&&a.end.on(t)){let[g,p]=d.point2circle(a.end,l);if(p.end.on(e))return[g,p]}let h=[];h.push(d.point2arc(t.start,e)),h.push(d.point2arc(t.end,e));let u,f;return[u,f]=d.point2segment(e.start,t),h.push([u,f.reverse()]),[u,f]=d.point2segment(e.end,t),h.push([u,f.reverse()]),d.sort(h),h[0]}static circle2circle(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];if(t.center.equalTo(e.center)){let s=t.toArc(),l=e.toArc();return d.point2point(s.start,l.start)}else{let s=new i.Line(t.center,e.center),l=s.intersect(t),o=s.intersect(e),a=[];return a.push(d.point2point(l[0],o[0])),a.push(d.point2point(l[0],o[1])),a.push(d.point2point(l[1],o[0])),a.push(d.point2point(l[1],o[1])),d.sort(a),a[0]}}static circle2line(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let[s,l]=d.point2line(t.center,e),[o,a]=d.point2circle(l.end,t);return a=a.reverse(),[o,a]}static arc2line(t,e){let n=e.intersect(t);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Circle(t.center,t.r),[l,o]=d.point2line(s.center,e);if(i.Utils.GE(l,s.r)){let[a,h]=d.point2circle(o.end,s);if(h.end.on(t))return[a,h]}else{let a=[];return a.push(d.point2line(t.start,e)),a.push(d.point2line(t.end,e)),d.sort(a),a[0]}}static arc2circle(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Circle(t.center,t.r),[l,o]=d.circle2circle(s,e);if(o.start.on(t))return[l,o];{let a=[];return a.push(d.point2circle(t.start,e)),a.push(d.point2circle(t.end,e)),d.sort(a),a[0]}}static arc2arc(t,e){let n=t.intersect(e);if(n.length>0)return[0,new i.Segment(n[0],n[0])];let s=new i.Circle(t.center,t.r),l=new i.Circle(e.center,e.r),[o,a]=d.circle2circle(s,l);if(a.start.on(t)&&a.end.on(e))return[o,a];{let h=[],u,f;return[u,f]=d.point2arc(t.start,e),f.end.on(e)&&h.push([u,f]),[u,f]=d.point2arc(t.end,e),f.end.on(e)&&h.push([u,f]),[u,f]=d.point2arc(e.start,t),f.end.on(t)&&h.push([u,f.reverse()]),[u,f]=d.point2arc(e.end,t),f.end.on(t)&&h.push([u,f.reverse()]),[u,f]=d.point2point(t.start,e.start),h.push([u,f]),[u,f]=d.point2point(t.start,e.end),h.push([u,f]),[u,f]=d.point2point(t.end,e.start),h.push([u,f]),[u,f]=d.point2point(t.end,e.end),h.push([u,f]),d.sort(h),h[0]}}static point2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of e.edges){let[l,o]=s.shape instanceof i.Segment?d.point2segment(t,s.shape):d.point2arc(t,s.shape);i.Utils.LT(l,n[0])&&(n=[l,o])}return n}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of e.edges){let[l,o]=t.distanceTo(s.shape);i.Utils.LT(l,n[0])&&(n=[l,o])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of t.edges)for(let l of e.edges){let[o,a]=s.shape.distanceTo(l.shape);i.Utils.LT(o,n[0])&&(n=[o,a])}return n}static box2box_minmax(t,e){let n=Math.max(Math.max(t.xmin-e.xmax,0),Math.max(e.xmin-t.xmax,0)),s=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),l=n*n+s*s,o=t.merge(e),a=o.xmax-o.xmin,h=o.ymax-o.ymin,u=a*a+h*h;return[l,u]}static minmax_tree_process_level(t,e,n,s){let l,o;for(let f of e)[l,o]=d.box2box_minmax(t.box,f.item.key),f.item.value instanceof i.Edge?s.insert([l,o],f.item.value.shape):s.insert([l,o],f.item.value),i.Utils.LT(o,n)&&(n=o);if(e.length===0)return n;let a=e.map(f=>f.left.isNil()?void 0:f.left).filter(f=>f!==void 0),h=e.map(f=>f.right.isNil()?void 0:f.right).filter(f=>f!==void 0),u=[...a,...h].filter(f=>{let[g,p]=d.box2box_minmax(t.box,f.max);return i.Utils.LE(g,n)});return n=d.minmax_tree_process_level(t,u,n,s),n}static minmax_tree(t,e,n){let s=new Mt,l=[e.index.root],o=ni.Utils.LT(e[0],n[0])?-1:i.Utils.GT(e[0],n[0])?1:0)}static distance(t,e){return t.distanceTo(e)}}i.Distance=d,i.BooleanOperations=Nn,i.Relations=ri;const nn=i.Matrix,Xt=24,me=60,A=class A extends y.Path{constructor(t,e){if(super(),y.Util.setOptions(this,e),t==null)throw Error("latLng required");e=e||{},this._latLng=y.latLng(t),this._heading=e.heading,this._course=e.course,this._speed=e.speed,this._shapeOptions=e.shapeOptions||{leaderTime:me,defaultShapeSet:A.DEFAULT_SHAPE_SET},this._setShapeOptions(e.shapeOptions)}_project(){this._currentShapePoints=this._getProjectedShapePoints(),this._currentLeaderPoints=this._getLeaderShapePoints();const t=new y.Bounds;for(let e=0;en.minZoomLevel-e.minZoomLevel)}setLatLng(t){const e=this._latLng;return this._latLng=y.latLng(t),this.fire("move",{oldLatLng:e,latlng:this._latLng}),this.redraw()}setHeading(t){return this._heading=t,this.redraw()}setCourse(t){return this._course=t,this.redraw()}setSpeed(t){return this._speed=t,this.redraw()}setShapeOptions(t){return this._setShapeOptions(t),this.redraw()}getBounds(){return this._currentLatLngBounds}getLatLng(){return this._latLng}getSpeed(){return this._speed}getHeading(){return this._heading}getCourse(){return this._course}static createShape(t,e){return{points:t,length:e,breadth:e,units:"pixels"}}static createShapeSet(t){return{withHeading:A.createShape(A.DEFAULT_HEADING_SHAPE_POINTS,t),withoutHeading:A.createShape(A.DEFAULT_NOHEADING_SHAPE_POINTS,t)}}_getLatSizeOf(t){return t/40075017*360}_getLngSizeOf(t){return t/40075017*360/Math.cos(Math.PI/180*this._latLng.lat)}_getViewAngleFromModel(t){return t-Math.PI/2}_getLeaderShapePoints(){if(this._course===void 0||this._speed===void 0||this._shapeOptions===void 0||this._shapeOptions.leaderTime===void 0)return;const t=this._getViewAngleFromModel(this._course),e=this._speed*this._shapeOptions.leaderTime,n=this._calcRelativeLatLng(this._latLng,e,t);return this._latLngsToLayerPoints(this._latLng,n)}_calcRelativeLatLng(t,e,n){return new y.LatLng(t.lat-this._getLatSizeOf(e*Math.sin(n)),t.lng+this._getLngSizeOf(e*Math.cos(n)))}_latLngsToLayerPoints(...t){return t.map(e=>this._map.latLngToLayerPoint(e))}_getShapeSet(){if(this._shapeOptions.shapeSetEntries===void 0||this._shapeOptions.shapeSetEntries.length==0)return this._shapeOptions.defaultShapeSet?this._shapeOptions.defaultShapeSet:A.DEFAULT_SHAPE_SET;const t=this._map.getZoom(),e=this._shapeOptions.shapeSetEntries.sort((n,s)=>s.minZoomLevel-n.minZoomLevel).filter(n=>t>=n.minZoomLevel);return e.length>0?e[0].shapeSet:this._shapeOptions.defaultShapeSet?this._shapeOptions.defaultShapeSet:A.DEFAULT_SHAPE_SET}_getShape(){const t=this._getShapeSet();return this._heading!==void 0?t.withHeading:t.withoutHeading}_getTransformedShapePoints(){const t=this._getShape();let e=new nn;if(this._heading!==void 0){const s=this._getViewAngleFromModel(this._heading);e=e.rotate(s)}return t.center!==void 0&&(e=e.translate(-t.center[0],-t.center[1])),e=e.scale(t.length,t.breadth),[t.points.map(s=>e.transform(s)),t.units]}_getProjectedShapePoints(){const[t,e]=this._getTransformedShapePoints();switch(e){case"pixels":{const n=this._map.latLngToLayerPoint(this._latLng),s=new nn().translate(n.x,n.y);return t.map(l=>{const o=s.transform(l);return new y.Point(o[0],o[1])})}case"meters":return t.map(n=>this._map.latLngToLayerPoint(new y.LatLng(this._latLng.lat-this._getLatSizeOf(n[1]),this._latLng.lng+this._getLngSizeOf(n[0]))));default:throw`unsupported units: ${e}`}}static _toSVGPath(t,e){let n="";for(let s=0;sl";const s=y.DomUtil.create("div");return s.innerHTML=n,s}};It.DEFAULT_SILHOUETTE_SHAPE_POINTS=[[1,.5],[.75,1],[0,1],[0,0],[.75,0]];let Vt=It;function St(r,t,e){if(r!=null&&!(e&&!e(r)))return r.toFixed(t)}function Ni(r){return r==null?void 0:un(r).name}function Ri(r){if(r!=null)switch(r){case 0:return;case 1:return"GPS";case 2:return"GLONASS";case 3:return"combined GPS/GLONASS";case 4:return"Loran-C";case 5:return"Chayka";case 6:return"integrated navigation system";case 7:return"surveyed";case 8:return"Galileo";case 9:case 10:case 11:case 12:case 13:case 14:return`not used (${r})`;case 15:return"internal GNSS";default:return`unknown (${r})`}}function Ui(r){if(r!=null)switch(r){case 0:return"Under way using engine";case 1:return"At anchor";case 2:return"Not under command";case 3:return"Restricted manoeuverability";case 4:return"Constrained by her draught";case 5:return"Moored";case 6:return"Aground";case 7:return"Engaged in Fishing";case 8:return"Under way sailing";case 9:return"Reserved for future amendment of Navigational Status for HSC";case 10:return"Reserved for future amendment of Navigational Status for WIG";case 11:return"Reserved for future use";case 12:return"Reserved for future use";case 13:return"Reserved for future use";case 14:return"AIS-SART is active";case 15:return"Not defined (default)";default:return`unknown (${r})`}}function Mi(r){if(r==null)return;const t=[];if(!yt(r.month)&&!yt(r.day)&&t.push(`${r.month.toString().padStart(2,"0")}/${r.day.toString().padStart(2,"0")}`),!yt(r.hour)&&!yt(r.minute)&&t.push(`${r.hour.toString().padStart(2,"0")}:${r.minute.toString().padStart(2,"0")}`),t.length!==0)return`${t.join(" ")} UTC`}function an(r){if(r!=null)return r*Math.PI/180}function yt(r){return r==null}function fn(r){return r!=null&&r.A>0&&r.B>0&&r.C>0&&r.D>0}function L(r,t,e){if(t==null)return"";const n=String(t);return`${r}${n} ${yt(e)?"":e}`}function c(r,t,e){return{name:r,color:t,fillColor:e}}function un(r){if(r==null)return ln[0];if(r<0||r>99)return Ci;const t=ln[r];return yt(t)?Oi:t}y.trackSymbol=function(r,t){return new V(r,t)},y.TrackSymbol=V,y.aisTrackSymbol=function(r,t){return new Vt(r,t)},y.AISTrackSymbol=Vt,X.AISTrackSymbol=Vt,X.TrackSymbol=V,X.default=V,Object.defineProperties(X,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); //# sourceMappingURL=leaflet-tracksymbol2.umd.js.map diff --git a/dist/leaflet-tracksymbol2.umd.js.map b/dist/leaflet-tracksymbol2.umd.js.map index 418252a..4534ead 100644 --- a/dist/leaflet-tracksymbol2.umd.js.map +++ b/dist/leaflet-tracksymbol2.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"leaflet-tracksymbol2.umd.js","sources":["../node_modules/.pnpm/@flatten-js+core@1.5.1/node_modules/@flatten-js/core/dist/main.mjs","../src/trackSymbol.ts","../src/ais/aisTrackSymbol.ts","../src/index.ts"],"sourcesContent":["/**\n * Global constant CCW defines counterclockwise direction of arc\n * @type {boolean}\n */\nconst CCW = true;\n\n/**\n * Global constant CW defines clockwise direction of arc\n * @type {boolean}\n */\nconst CW = false;\n\n/**\n * Defines orientation for face of the polygon: clockwise, counterclockwise\n * or not orientable in the case of self-intersection\n * @type {{CW: number, CCW: number, NOT_ORIENTABLE: number}}\n */\nconst ORIENTATION = {CCW:-1, CW:1, NOT_ORIENTABLE: 0};\n\nconst PIx2 = 2 * Math.PI;\n\nconst INSIDE$2 = 1;\nconst OUTSIDE$1 = 0;\nconst BOUNDARY$1 = 2;\nconst CONTAINS = 3;\nconst INTERLACE = 4;\n\nconst OVERLAP_SAME$1 = 1;\nconst OVERLAP_OPPOSITE$1 = 2;\n\nconst NOT_VERTEX$1 = 0;\nconst START_VERTEX$1 = 1;\nconst END_VERTEX$1 = 2;\n\nvar Constants = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOUNDARY: BOUNDARY$1,\n CCW: CCW,\n CONTAINS: CONTAINS,\n CW: CW,\n END_VERTEX: END_VERTEX$1,\n INSIDE: INSIDE$2,\n INTERLACE: INTERLACE,\n NOT_VERTEX: NOT_VERTEX$1,\n ORIENTATION: ORIENTATION,\n OUTSIDE: OUTSIDE$1,\n OVERLAP_OPPOSITE: OVERLAP_OPPOSITE$1,\n OVERLAP_SAME: OVERLAP_SAME$1,\n PIx2: PIx2,\n START_VERTEX: START_VERTEX$1\n});\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n/**\n * Floating point comparison tolerance.\n * Default value is 0.000001 (10e-6)\n * @type {number}\n */\nlet DP_TOL = 0.000001;\n\n/**\n * Set new floating point comparison tolerance\n * @param {number} tolerance\n */\nfunction setTolerance(tolerance) {DP_TOL = tolerance;}\n\n/**\n * Get floating point comparison tolerance\n * @returns {number}\n */\nfunction getTolerance() {return DP_TOL;}\n\nconst DECIMALS = 3;\n\n/**\n * Returns *true* if value comparable to zero\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ_0(x) {\n return (x < DP_TOL && x > -DP_TOL);\n}\n\n/**\n * Returns *true* if two values are equal up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ(x, y) {\n return (x - y < DP_TOL && x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction GT(x, y) {\n return (x - y > DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @returns {boolean}\n */\nfunction GE(x, y) {\n return (x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument less than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LT(x, y) {\n return (x - y < -DP_TOL)\n}\n\n/**\n * Returns *true* if first argument less than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LE(x, y) {\n return (x - y < DP_TOL);\n}\n\nvar Utils$1 = /*#__PURE__*/Object.freeze({\n __proto__: null,\n DECIMALS: DECIMALS,\n EQ: EQ,\n EQ_0: EQ_0,\n GE: GE,\n GT: GT,\n LE: LE,\n LT: LT,\n getTolerance: getTolerance,\n setTolerance: setTolerance\n});\n\nlet Flatten = {\n Utils: Utils$1,\n Errors: undefined,\n Matrix: undefined,\n Planar_set: undefined,\n Point: undefined,\n Vector: undefined,\n Line: undefined,\n Circle: undefined,\n Segment: undefined,\n Arc: undefined,\n Box: undefined,\n Edge: undefined,\n Face: undefined,\n Ray: undefined,\n Ray_shooting: undefined,\n Multiline: undefined,\n Polygon: undefined,\n Distance: undefined,\n Inversion: undefined\n};\n\nfor (let c in Constants) {Flatten[c] = Constants[c];}\n\nObject.defineProperty(Flatten, 'DP_TOL', {\n get:function(){return getTolerance()}, \n set:function(value){setTolerance(value);}\n});\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class of system errors\n */\nclass Errors {\n /**\n * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter\n * @returns {ReferenceError}\n */\n static get ILLEGAL_PARAMETERS() {\n return new ReferenceError('Illegal Parameters');\n }\n\n /**\n * Throw error ZERO_DIVISION to catch situation of zero division\n * @returns {Error}\n */\n static get ZERO_DIVISION() {\n return new Error('Zero division');\n }\n\n /**\n * Error to throw from BooleanOperations module in case when fixBoundaryConflicts not capable to fix it\n * @returns {Error}\n */\n static get UNRESOLVED_BOUNDARY_CONFLICT() {\n return new Error('Unresolved boundary conflict in boolean operation');\n }\n\n /**\n * Error to throw from LinkedList:testInfiniteLoop static method\n * in case when circular loop detected in linked list\n * @returns {Error}\n */\n static get INFINITE_LOOP() {\n return new Error('Infinite loop');\n }\n\n static get CANNOT_COMPLETE_BOOLEAN_OPERATION() {\n return new Error('Cannot complete boolean operation')\n }\n\n static get CANNOT_INVOKE_ABSTRACT_METHOD() {\n return new Error('Abstract method cannot be invoked');\n }\n\n static get OPERATION_IS_NOT_SUPPORTED() {\n return new Error('Operation is not supported')\n }\n}\n\nFlatten.Errors = Errors;\n\n/**\n * Class implements bidirectional non-circular linked list.
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass LinkedList {\n constructor(first, last) {\n this.first = first;\n this.last = last || this.first;\n }\n\n [Symbol.iterator]() {\n let value = undefined;\n return {\n next: () => {\n value = value ? value.next : this.first;\n return {value: value, done: value === undefined};\n }\n };\n };\n\n /**\n * Return number of elements in the list\n * @returns {number}\n */\n get size() {\n let counter = 0;\n for (let edge of this) {\n counter++;\n }\n return counter;\n }\n\n /**\n * Return array of elements from start to end,\n * If start or end not defined, take first as start, last as end\n * @returns {Array}\n */\n toArray(start=undefined, end=undefined) {\n let elements = [];\n let from = start || this.first;\n let to = end || this.last;\n let element = from;\n if (element === undefined) return elements;\n do {\n elements.push(element);\n element = element.next;\n } while (element !== to.next);\n return elements;\n }\n\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n append(element) {\n if (this.isEmpty()) {\n this.first = element;\n } else {\n element.prev = this.last;\n this.last.next = element;\n }\n\n // update edge to be last\n this.last = element;\n\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement\n * @param {LinkedListElement} elementBefore\n * @returns {LinkedList}\n */\n insert(newElement, elementBefore) {\n if (this.isEmpty()) {\n this.first = newElement;\n this.last = newElement;\n }\n else if (elementBefore === null || elementBefore === undefined) {\n newElement.next = this.first;\n this.first.prev = newElement;\n this.first = newElement;\n }\n else {\n /* set links to new element */\n let elementAfter = elementBefore.next;\n elementBefore.next = newElement;\n if (elementAfter) elementAfter.prev = newElement;\n\n /* set links from new element */\n newElement.prev = elementBefore;\n newElement.next = elementAfter;\n\n /* extend list if new element added after the last element */\n if (this.last === elementBefore)\n this.last = newElement;\n }\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n remove(element) {\n // special case if last edge removed\n if (element === this.first && element === this.last) {\n this.first = undefined;\n this.last = undefined;\n } else {\n // update linked list\n if (element.prev) element.prev.next = element.next;\n if (element.next) element.next.prev = element.prev;\n // update first if need\n if (element === this.first) {\n this.first = element.next;\n }\n // update last if need\n if (element === this.last) {\n this.last = element.prev;\n }\n }\n return this;\n }\n\n /**\n * Return true if list is empty\n * @returns {boolean}\n */\n isEmpty() {\n return this.first === undefined;\n }\n\n /**\n * Throw an error if circular loop detected in the linked list\n * @param {LinkedListElement} first element to start iteration\n * @throws {Errors.INFINITE_LOOP}\n */\n static testInfiniteLoop(first) {\n let edge = first;\n let controlEdge = first;\n do {\n if (edge != first && edge === controlEdge) {\n throw Errors.INFINITE_LOOP; // new Error(\"Infinite loop\")\n }\n edge = edge.next;\n controlEdge = controlEdge.next.next;\n } while (edge != first)\n }\n}\n\n/*\n Smart intersections describe intersection points that refers to the edges they intersect\n This function are supposed for internal usage by morphing and relation methods between\n */\n\nfunction addToIntPoints(edge, pt, int_points)\n{\n let id = int_points.length;\n let shapes = edge.shape.split(pt);\n\n // if (shapes.length < 2) return;\n if (shapes.length === 0) return; // Point does not belong to edge ?\n\n let len = 0;\n if (shapes[0] === null) { // point incident to edge start vertex\n len = 0;\n }\n else if (shapes[1] === null) { // point incident to edge end vertex\n len = edge.shape.length;\n }\n else { // Edge was split into to edges\n len = shapes[0].length;\n }\n\n let is_vertex = NOT_VERTEX$1;\n if (EQ(len, 0)) {\n is_vertex |= START_VERTEX$1;\n }\n if (EQ(len, edge.shape.length)) {\n is_vertex |= END_VERTEX$1;\n }\n // Fix intersection point which is end point of the last edge\n let arc_length;\n if (len === Infinity) {\n arc_length = shapes[0].coord(pt);\n }\n else {\n arc_length = (is_vertex & END_VERTEX$1) && edge.next && edge.next.arc_length === 0 ?\n 0 :\n edge.arc_length + len;\n }\n\n int_points.push({\n id: id,\n pt: pt,\n arc_length: arc_length,\n edge_before: edge,\n edge_after: undefined,\n face: edge.face,\n is_vertex: is_vertex\n });\n}\n\nfunction sortIntersections(intersections)\n{\n // if (intersections.int_points1.length === 0) return;\n\n // augment intersections with new sorted arrays\n // intersections.int_points1_sorted = intersections.int_points1.slice().sort(compareFn);\n // intersections.int_points2_sorted = intersections.int_points2.slice().sort(compareFn);\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n}\n\nfunction getSortedArray(int_points)\n{\n let faceMap = new Map;\n let id = 0;\n // Create integer id's for faces\n for (let ip of int_points) {\n if (!faceMap.has(ip.face)) {\n faceMap.set(ip.face, id);\n id++;\n }\n }\n // Augment intersection points with face id's\n for (let ip of int_points) {\n ip.faceId = faceMap.get(ip.face);\n }\n // Clone and sort\n let int_points_sorted = int_points.slice().sort(compareFn);\n return int_points_sorted;\n}\n\nfunction compareFn(ip1, ip2)\n{\n // compare face id's\n if (ip1.faceId < ip2.faceId) {\n return -1;\n }\n if (ip1.faceId > ip2.faceId) {\n return 1;\n }\n // same face - compare arc_length\n if (ip1.arc_length < ip2.arc_length) {\n return -1;\n }\n if (ip1.arc_length > ip2.arc_length) {\n return 1;\n }\n return 0;\n}\n\n// export function getSortedArrayOnLine(line, int_points) {\n// return int_points.slice().sort( (int_point1, int_point2) => {\n// if (line.coord(int_point1.pt) < line.coord(int_point2.pt)) {\n// return -1;\n// }\n// if (line.coord(int_point1.pt) > line.coord(int_point2.pt)) {\n// return 1;\n// }\n// return 0;\n// })\n// }\n\nfunction filterDuplicatedIntersections(intersections)\n{\n if (intersections.int_points1.length < 2) return;\n\n let do_squeeze = false;\n\n let int_point_ref1;\n let int_point_ref2;\n let int_point_cur1;\n let int_point_cur2;\n for (let i = 0; i < intersections.int_points1_sorted.length; i++) {\n\n if (intersections.int_points1_sorted[i].id === -1)\n continue;\n\n int_point_ref1 = intersections.int_points1_sorted[i];\n int_point_ref2 = intersections.int_points2[int_point_ref1.id];\n\n for (let j=i+1; j < intersections.int_points1_sorted.length; j++) {\n int_point_cur1 = intersections.int_points1_sorted[j];\n if (!EQ(int_point_cur1.arc_length, int_point_ref1.arc_length)) {\n break;\n }\n if (int_point_cur1.id === -1)\n continue;\n int_point_cur2 = intersections.int_points2[int_point_cur1.id];\n if (int_point_cur2.id === -1)\n continue;\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n }\n\n int_point_ref2 = intersections.int_points2_sorted[0];\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n for (let i = 1; i < intersections.int_points2_sorted.length; i++) {\n let int_point_cur2 = intersections.int_points2_sorted[i];\n\n if (int_point_cur2.id === -1) continue;\n /* already deleted */\n\n if (int_point_ref2.id === -1 || /* can't be reference if already deleted */\n !(EQ(int_point_cur2.arc_length, int_point_ref2.arc_length))) {\n int_point_ref2 = int_point_cur2;\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n continue;\n }\n\n let int_point_cur1 = intersections.int_points1[int_point_cur2.id];\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n\n if (do_squeeze) {\n intersections.int_points1 = intersections.int_points1.filter((int_point) => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter((int_point) => int_point.id >= 0);\n\n // update id's\n intersections.int_points1.forEach((int_point, index) => int_point.id = index);\n intersections.int_points2.forEach((int_point, index) => int_point.id = index);\n }\n}\n\nfunction initializeInclusionFlags(int_points)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_before.bvStart = undefined;\n int_point.edge_before.bvEnd = undefined;\n int_point.edge_before.bv = undefined;\n int_point.edge_before.overlap = undefined;\n }\n\n if (int_point.edge_after) {\n int_point.edge_after.bvStart = undefined;\n int_point.edge_after.bvEnd = undefined;\n int_point.edge_after.bv = undefined;\n int_point.edge_after.overlap = undefined;\n }\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.bvEnd = BOUNDARY$1;\n if (int_point.edge_after) int_point.edge_after.bvStart = BOUNDARY$1;\n }\n}\n\nfunction calculateInclusionFlags(int_points, polygon)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.setInclusion(polygon);\n if (int_point.edge_after) int_point.edge_after.setInclusion(polygon);\n }\n}\n\nfunction setOverlappingFlags(intersections)\n{\n let cur_face = undefined;\n let first_int_point_in_face_id = undefined;\n let next_int_point1 = undefined;\n let num_int_points = intersections.int_points1.length;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = intersections.int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(intersections.int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n intersections.int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(intersections.int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = intersections.int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n intersections.int_points2[next_int_point1_tmp.id].face === intersections.int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n if (!(edge_from1.bv === BOUNDARY$1 && edge_to1.bv === BOUNDARY$1)) // not a boundary chain - skip\n continue;\n\n if (edge_from1 !== edge_to1) // one edge chain TODO: support complex case\n continue;\n\n /* Find boundary chain in polygon2 between same intersection points */\n let cur_int_point2 = intersections.int_points2[cur_int_point1.id];\n let next_int_point2 = intersections.int_points2[next_int_point1.id];\n\n let edge_from2 = cur_int_point2.edge_after;\n let edge_to2 = next_int_point2.edge_before;\n\n /* if [edge_from2..edge_to2] is not a boundary chain, invert it */\n /* check also that chain consist of one or two edges */\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2)) {\n cur_int_point2 = intersections.int_points2[next_int_point1.id];\n next_int_point2 = intersections.int_points2[cur_int_point1.id];\n\n edge_from2 = cur_int_point2.edge_after;\n edge_to2 = next_int_point2.edge_before;\n }\n\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2))\n continue; // not an overlapping chain - skip TODO: fix boundary conflict\n\n // Set overlapping flag - one-to-one case\n edge_from1.setOverlap(edge_from2);\n }\n}\n\nfunction intPointsPoolCount(int_points, cur_int_point_num, cur_face)\n{\n let int_point_current;\n let int_point_next;\n\n let int_points_pool_num = 1;\n\n if (int_points.length === 1) return 1;\n\n int_point_current = int_points[cur_int_point_num];\n\n for (let i = cur_int_point_num + 1; i < int_points.length; i++) {\n if (int_point_current.face !== cur_face) { /* next face started */\n break;\n }\n\n int_point_next = int_points[i];\n\n if (!(int_point_next.pt.equalTo(int_point_current.pt) &&\n int_point_next.edge_before === int_point_current.edge_before &&\n int_point_next.edge_after === int_point_current.edge_after)) {\n break; /* next point is different - break and exit */\n }\n\n int_points_pool_num++; /* duplicated intersection point - increase counter */\n }\n return int_points_pool_num;\n}\n\nfunction splitByIntersections(polygon, int_points)\n{\n if (!int_points) return;\n for (let int_point of int_points) {\n let edge = int_point.edge_before;\n\n // recalculate vertex flag: it may be changed after previous split\n int_point.is_vertex = NOT_VERTEX$1;\n if (edge.shape.start && edge.shape.start.equalTo(int_point.pt)) {\n int_point.is_vertex |= START_VERTEX$1;\n }\n if (edge.shape.end && edge.shape.end.equalTo(int_point.pt)) {\n int_point.is_vertex |= END_VERTEX$1;\n }\n\n if (int_point.is_vertex & START_VERTEX$1) { // nothing to split\n if (edge.prev) {\n int_point.edge_before = edge.prev; // polygon\n int_point.is_vertex = END_VERTEX$1;\n }\n else { // multiline start vertex\n int_point.edge_after = int_point.edge_before;\n int_point.edge_before = edge.prev;\n }\n continue;\n }\n if (int_point.is_vertex & END_VERTEX$1) { // nothing to split\n continue;\n }\n\n let newEdge = polygon.addVertex(int_point.pt, edge);\n int_point.edge_before = newEdge;\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_after = int_point.edge_before.next;\n }\n }\n}\n\nfunction insertBetweenIntPoints(int_point1, int_point2, new_edges) {\n const edge_before = int_point1.edge_before;\n const edge_after = int_point2.edge_after;\n const len = new_edges.length;\n edge_before.next = new_edges[0];\n new_edges[0].prev = edge_before;\n\n new_edges[len-1].next = edge_after;\n edge_after.prev = new_edges[len-1];\n}\n\nvar smart_intersections = /*#__PURE__*/Object.freeze({\n __proto__: null,\n addToIntPoints: addToIntPoints,\n calculateInclusionFlags: calculateInclusionFlags,\n filterDuplicatedIntersections: filterDuplicatedIntersections,\n getSortedArray: getSortedArray,\n initializeInclusionFlags: initializeInclusionFlags,\n insertBetweenIntPoints: insertBetweenIntPoints,\n intPointsPoolCount: intPointsPoolCount,\n setOverlappingFlags: setOverlappingFlags,\n sortIntersections: sortIntersections,\n splitByIntersections: splitByIntersections\n});\n\n/**\n * Created by Alex Bol on 12/02/2018.\n */\n/**\n * @module BooleanOperations\n */\n\nconst {INSIDE: INSIDE$1, OUTSIDE, BOUNDARY, OVERLAP_SAME, OVERLAP_OPPOSITE} = Constants;\nconst {NOT_VERTEX, START_VERTEX, END_VERTEX} = Constants;\n\nconst BOOLEAN_UNION = 1;\nconst BOOLEAN_INTERSECT = 2;\nconst BOOLEAN_SUBTRACT = 3;\n\n\n/**\n * Unify two polygons polygons and returns new polygon.
\n * Point belongs to the resulted polygon if it belongs to the first OR to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction unify(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_UNION, true);\n return res_poly;\n}\n\n/**\n * Subtract second polygon from the first and returns new polygon\n * Point belongs to the resulted polygon if it belongs to the first polygon AND NOT to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction subtract(polygon1, polygon2) {\n let polygon2_tmp = polygon2.clone();\n let polygon2_reversed = polygon2_tmp.reverse();\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2_reversed, BOOLEAN_SUBTRACT, true);\n return res_poly;\n}\n\n/**\n * Intersect two polygons and returns new polygon\n * Point belongs to the resulted polygon is it belongs to the first AND to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction intersect$1(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, true);\n return res_poly;\n}\n\n/**\n * Returns boundary of intersection between two polygons as two arrays of shapes (Segments/Arcs)
\n * The first array are shapes from the first polygon, the second array are shapes from the second\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[][]}\n */\nfunction innerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n let clip_shapes2 = [];\n for (let face of wrk_poly.faces) {\n clip_shapes2 = [...clip_shapes2, ...[...face.edges].map(edge => edge.shape)];\n }\n return [clip_shapes1, clip_shapes2];\n}\n\n/**\n * Returns boundary of subtraction of the second polygon from first polygon as array of shapes\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[]}\n */\nfunction outerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_SUBTRACT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n\n return clip_shapes1;\n}\n\n/**\n * Returns intersection points between boundaries of two polygons as two array of points
\n * Points in the first array belong to first polygon, points from the second - to the second.\n * Points in each array are ordered according to the direction of the correspondent polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Point[][]}\n */\nfunction calculateIntersections(polygon1, polygon2) {\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n let ip_sorted1 = intersections.int_points1_sorted.map( int_point => int_point.pt);\n let ip_sorted2 = intersections.int_points2_sorted.map( int_point => int_point.pt);\n return [ip_sorted1, ip_sorted2];\n}\n\nfunction filterNotRelevantEdges(res_poly, wrk_poly, intersections, op) {\n // keep not intersected faces for further remove and merge\n let notIntersectedFacesRes = getNotIntersectedFaces(res_poly, intersections.int_points1);\n let notIntersectedFacesWrk = getNotIntersectedFaces(wrk_poly, intersections.int_points2);\n\n // calculate inclusion flag for not intersected faces\n calcInclusionForNotIntersectedFaces(notIntersectedFacesRes, wrk_poly);\n calcInclusionForNotIntersectedFaces(notIntersectedFacesWrk, res_poly);\n\n // initialize inclusion flags for edges incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n initializeInclusionFlags(intersections.int_points2);\n\n // calculate inclusion flags only for edges incident to intersections\n calculateInclusionFlags(intersections.int_points1, wrk_poly);\n calculateInclusionFlags(intersections.int_points2, res_poly);\n\n // fix boundary conflicts\n while (fixBoundaryConflicts(res_poly, wrk_poly, intersections.int_points1, intersections.int_points1_sorted, intersections.int_points2, intersections));\n // while (fixBoundaryConflicts(wrk_poly, res_poly, intersections.int_points2, intersections.int_points2_sorted, intersections.int_points1, intersections));\n\n // Set overlapping flags for boundary chains: SAME or OPPOSITE\n setOverlappingFlags(intersections);\n\n // remove not relevant chains between intersection points\n removeNotRelevantChains(res_poly, op, intersections.int_points1_sorted, true);\n removeNotRelevantChains(wrk_poly, op, intersections.int_points2_sorted, false);\n\n // remove not relevant not intersected faces from res_polygon and wrk_polygon\n // if op == UNION, remove faces that are included in wrk_polygon without intersection\n // if op == INTERSECT, remove faces that are not included into wrk_polygon\n removeNotRelevantNotIntersectedFaces(res_poly, notIntersectedFacesRes, op, true);\n removeNotRelevantNotIntersectedFaces(wrk_poly, notIntersectedFacesWrk, op, false);\n}\n\nfunction swapLinksAndRestore(res_poly, wrk_poly, intersections, op) {\n\n // add edges of wrk_poly into the edge container of res_poly\n copyWrkToRes(res_poly, wrk_poly, op, intersections.int_points2);\n\n // swap links from res_poly to wrk_poly and vice versa\n swapLinks(res_poly, wrk_poly, intersections);\n\n // remove old faces\n removeOldFaces(res_poly, intersections.int_points1);\n removeOldFaces(wrk_poly, intersections.int_points2);\n\n // restore faces\n restoreFaces(res_poly, intersections.int_points1, intersections.int_points2);\n restoreFaces(res_poly, intersections.int_points2, intersections.int_points1);\n\n // merge relevant not intersected faces from wrk_polygon to res_polygon\n // mergeRelevantNotIntersectedFaces(res_poly, wrk_poly);\n}\n\n\nfunction booleanOpBinary(polygon1, polygon2, op, restore)\n{\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n // calculate inclusion and remove not relevant edges\n filterNotRelevantEdges(res_poly, wrk_poly, intersections, op);\n\n if (restore) {\n swapLinksAndRestore(res_poly, wrk_poly, intersections, op);\n }\n\n return [res_poly, wrk_poly];\n}\n\nfunction getIntersections(polygon1, polygon2)\n{\n let intersections = {\n int_points1: [],\n int_points2: []\n };\n\n // calculate intersections\n for (let edge1 of polygon1.edges) {\n\n // request edges of polygon2 in the box of edge1\n let resp = polygon2.edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n return intersections;\n}\n\nfunction getNotIntersectedFaces(poly, int_points)\n{\n let notIntersected = [];\n for (let face of poly.faces) {\n if (!int_points.find((ip) => ip.face === face)) {\n notIntersected.push(face);\n }\n }\n return notIntersected;\n}\n\nfunction calcInclusionForNotIntersectedFaces(notIntersectedFaces, poly2)\n{\n for (let face of notIntersectedFaces) {\n face.first.bv = face.first.bvStart = face.first.bvEnd = undefined;\n face.first.setInclusion(poly2);\n }\n}\n\nfunction fixBoundaryConflicts(poly1, poly2, int_points1, int_points1_sorted, int_points2, intersections )\n{\n let cur_face;\n let first_int_point_in_face_id;\n let next_int_point1;\n let num_int_points = int_points1_sorted.length;\n let iterate_more = false;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n int_points2[next_int_point1_tmp.id].face === int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n // Case #1. One of the ends is not boundary - probably tiny edge wrongly marked as boundary\n if (edge_from1.bv === BOUNDARY && edge_to1.bv != BOUNDARY) {\n edge_from1.bv = edge_to1.bv;\n continue;\n }\n\n if (edge_from1.bv != BOUNDARY && edge_to1.bv === BOUNDARY) {\n edge_to1.bv = edge_from1.bv;\n continue;\n }\n\n // Set up all boundary values for middle edges. Need for cases 2 and 3\n if ( (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) ||\n (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) ) {\n let edge_tmp = edge_from1.next;\n while (edge_tmp != edge_to1) {\n edge_tmp.bvStart = undefined;\n edge_tmp.bvEnd = undefined;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n edge_tmp = edge_tmp.next;\n }\n }\n\n // Case #2. Both of the ends boundary. Check all the edges in the middle\n // If some edges in the middle are not boundary then update bv of 'from' and 'to' edges\n if (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) {\n let edge_tmp = edge_from1.next;\n let new_bv;\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bv != BOUNDARY) {\n if (new_bv === undefined) { // first not boundary edge between from and to\n new_bv = edge_tmp.bv;\n }\n else { // another not boundary edge between from and to\n if (edge_tmp.bv != new_bv) { // and it has different bv - can't resolve conflict\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n if (new_bv != undefined) {\n edge_from1.bv = new_bv;\n edge_to1.bv = new_bv;\n }\n continue; // all middle edges are boundary, proceed with this\n }\n\n // Case 3. One of the ends is inner, another is outer\n if (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) {\n let edge_tmp = edge_from1;\n // Find missing intersection point\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bvStart === edge_from1.bv && edge_tmp.bvEnd === edge_to1.bv) {\n let [dist, segment] = edge_tmp.shape.distanceTo(poly2);\n if (dist < 10*Flatten.DP_TOL) { // it should be very close\n // let pt = edge_tmp.end;\n // add to the list of intersections of poly1\n addToIntPoints(edge_tmp, segment.ps, int_points1);\n\n // split edge_tmp in poly1 if need\n let int_point1 = int_points1[int_points1.length-1];\n if (int_point1.is_vertex & START_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp;\n int_point1.edge_before = edge_tmp.prev;\n edge_tmp.bvStart = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else if (int_point1.is_vertex & END_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp.next;\n edge_tmp.bvEnd = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else { // split edge here\n let newEdge1 = poly2.addVertex(int_point1.pt, edge_tmp);\n int_point1.edge_before = newEdge1;\n int_point1.edge_after = newEdge1.next;\n\n newEdge1.setInclusion(poly2);\n\n newEdge1.next.bvStart = BOUNDARY;\n newEdge1.next.bvEnd = undefined;\n newEdge1.next.bv = undefined;\n newEdge1.next.setInclusion(poly2);\n }\n\n // add to the list of intersections of poly2\n let edge2 = poly2.findEdgeByPoint(segment.pe);\n addToIntPoints(edge2, segment.pe, int_points2);\n // split edge2 in poly2 if need\n let int_point2 = int_points2[int_points2.length-1];\n if (int_point2.is_vertex & START_VERTEX) { // nothing to split\n int_point2.edge_after = edge2;\n int_point2.edge_before = edge2.prev;\n }\n else if (int_point2.is_vertex & END_VERTEX) { // nothing to split\n int_point2.edge_after = edge2.next;\n }\n else { // split edge here\n // first locate int_points that may refer to edge2 as edge.after\n // let int_point2_edge_before = int_points2.find( int_point => int_point.edge_before === edge2)\n let int_point2_edge_after = int_points2.find( int_point => int_point.edge_after === edge2 );\n\n let newEdge2 = poly2.addVertex(int_point2.pt, edge2);\n int_point2.edge_before = newEdge2;\n int_point2.edge_after = newEdge2.next;\n\n if (int_point2_edge_after)\n int_point2_edge_after.edge_after = newEdge2;\n\n newEdge2.bvStart = undefined;\n newEdge2.bvEnd = BOUNDARY;\n newEdge2.bv = undefined;\n newEdge2.setInclusion(poly1);\n\n newEdge2.next.bvStart = BOUNDARY;\n newEdge2.next.bvEnd = undefined;\n newEdge2.next.bv = undefined;\n newEdge2.next.setInclusion(poly1);\n }\n\n sortIntersections(intersections);\n\n iterate_more = true;\n break;\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n // we changed intersections inside loop, have to exit and repair again\n if (iterate_more)\n break;\n\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n\n return iterate_more;\n}\n\nfunction removeNotRelevantChains(polygon, op, int_points, is_res_polygon)\n{\n if (!int_points) return;\n let cur_face = undefined;\n let first_int_point_in_face_num = undefined;\n let int_point_current;\n let int_point_next;\n\n for (let i = 0; i < int_points.length; i++) {\n int_point_current = int_points[i];\n\n if (int_point_current.face !== cur_face) { // next face started\n first_int_point_in_face_num = i;\n cur_face = int_point_current.face;\n }\n\n if (cur_face.isEmpty()) // ??\n continue;\n\n // Get next int point from the same face that current\n\n // Count how many duplicated points with same in \"points from\" pool ?\n let int_points_from_pull_start = i;\n let int_points_from_pull_num = intPointsPoolCount(int_points, i, cur_face);\n let next_int_point_num;\n if (int_points_from_pull_start + int_points_from_pull_num < int_points.length &&\n int_points[int_points_from_pull_start + int_points_from_pull_num].face === int_point_current.face) {\n next_int_point_num = int_points_from_pull_start + int_points_from_pull_num;\n } else { // get first point from the same face\n next_int_point_num = first_int_point_in_face_num;\n }\n int_point_next = int_points[next_int_point_num];\n\n /* Count how many duplicated points with same in \"points to\" pull ? */\n let int_points_to_pull_start = next_int_point_num;\n let int_points_to_pull_num = intPointsPoolCount(int_points, int_points_to_pull_start, cur_face);\n\n\n let edge_from = int_point_current.edge_after;\n let edge_to = int_point_next.edge_before;\n\n if ((edge_from.bv === INSIDE$1 && edge_to.bv === INSIDE$1 && op === BOOLEAN_UNION) ||\n (edge_from.bv === OUTSIDE && edge_to.bv === OUTSIDE && op === BOOLEAN_INTERSECT) ||\n ((edge_from.bv === OUTSIDE || edge_to.bv === OUTSIDE) && op === BOOLEAN_SUBTRACT && !is_res_polygon) ||\n ((edge_from.bv === INSIDE$1 || edge_to.bv === INSIDE$1) && op === BOOLEAN_SUBTRACT && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_SAME) && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_OPPOSITE))) {\n\n polygon.removeChain(cur_face, edge_from, edge_to);\n\n /* update all points in \"points from\" pull */\n for (let k = int_points_from_pull_start; k < int_points_from_pull_start + int_points_from_pull_num; k++) {\n int_points[k].edge_after = undefined;\n }\n\n /* update all points in \"points to\" pull */\n for (let k = int_points_to_pull_start; k < int_points_to_pull_start + int_points_to_pull_num; k++) {\n int_points[k].edge_before = undefined;\n }\n }\n\n /* skip to the last point in \"points from\" group */\n i += int_points_from_pull_num - 1;\n }\n}\nfunction copyWrkToRes(res_polygon, wrk_polygon, op, int_points)\n{\n for (let face of wrk_polygon.faces) {\n for (let edge of face) {\n res_polygon.edges.add(edge);\n }\n // If union - add face from wrk_polygon that is not intersected with res_polygon\n if ( /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/\n int_points.find((ip) => (ip.face === face)) === undefined) {\n res_polygon.addFace(face.first, face.last);\n }\n }\n}\n\nfunction swapLinks(res_polygon, wrk_polygon, intersections)\n{\n if (intersections.int_points1.length === 0) return;\n\n for (let i = 0; i < intersections.int_points1.length; i++) {\n let int_point1 = intersections.int_points1[i];\n let int_point2 = intersections.int_points2[i];\n\n // Simple case - find continuation on the other polygon\n\n // Process edge from res_polygon\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // swap need\n if (int_point2.edge_before === undefined && int_point2.edge_after !== undefined) { // simple case\n // Connect edges\n int_point1.edge_before.next = int_point2.edge_after;\n int_point2.edge_after.prev = int_point1.edge_before;\n\n // Fill in missed links in intersection points\n int_point1.edge_after = int_point2.edge_after;\n int_point2.edge_before = int_point1.edge_before;\n }\n }\n // Process edge from wrk_polygon\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // swap need\n if (int_point1.edge_before === undefined && int_point1.edge_after !== undefined) { // simple case\n // Connect edges\n int_point2.edge_before.next = int_point1.edge_after;\n int_point1.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point1.edge_after;\n int_point1.edge_before = int_point2.edge_before;\n }\n }\n\n // Continuation not found - complex case\n // Continuation will be found on the same polygon.\n // It happens when intersection point is actually touching point\n // Polygon1\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points1_sorted) {\n if (int_point === int_point1) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point1.pt)) {\n // Connect edges\n int_point1.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point1.edge_before;\n\n // Complete missed links\n int_point1.edge_after = int_point.edge_after;\n int_point.edge_before = int_point1.edge_before;\n }\n }\n }\n }\n // Polygon2\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points2_sorted) {\n if (int_point === int_point2) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point2.pt)) {\n // Connect edges\n int_point2.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point.edge_after;\n int_point.edge_before = int_point2.edge_before;\n }\n }\n }\n }\n }\n // Sanity check that no dead ends left\n}\n\nfunction removeOldFaces(polygon, int_points)\n{\n for (let int_point of int_points) {\n polygon.faces.delete(int_point.face);\n int_point.face = undefined;\n if (int_point.edge_before)\n int_point.edge_before.face = undefined;\n if (int_point.edge_after)\n int_point.edge_after.face = undefined;\n }\n}\n\nfunction restoreFaces(polygon, int_points, other_int_points)\n{\n // For each intersection point - create new face\n for (let int_point of int_points) {\n if (int_point.edge_before === undefined || int_point.edge_after === undefined) // completely deleted\n continue;\n if (int_point.face) // already restored\n continue;\n\n if (int_point.edge_after.face || int_point.edge_before.face) // Face already created. Possible case in duplicated intersection points\n continue;\n\n let first = int_point.edge_after; // face start\n let last = int_point.edge_before; // face end;\n\n try {\n LinkedList.testInfiniteLoop(first); // check and throw error if infinite loop found\n }\n catch (error) {\n throw Errors.CANNOT_COMPLETE_BOOLEAN_OPERATION\n }\n\n let face = polygon.addFace(first, last);\n\n // Mark intersection points from the newly create face\n // to avoid multiple creation of the same face.\n // Face was assigned to each edge of new face in addFace function\n for (let int_point_tmp of int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n // Mark other intersection points as well\n for (let int_point_tmp of other_int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n }\n}\n\nfunction removeNotRelevantNotIntersectedFaces(polygon, notIntersectedFaces, op, is_res_polygon)\n{\n for (let face of notIntersectedFaces) {\n let rel = face.first.bv;\n if (op === BOOLEAN_UNION && rel === INSIDE$1 ||\n op === BOOLEAN_SUBTRACT && rel === INSIDE$1 && is_res_polygon ||\n op === BOOLEAN_SUBTRACT && rel === OUTSIDE && !is_res_polygon ||\n op === BOOLEAN_INTERSECT && rel === OUTSIDE) {\n\n polygon.deleteFace(face);\n }\n }\n}\n\nvar BooleanOperations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOOLEAN_INTERSECT: BOOLEAN_INTERSECT,\n BOOLEAN_SUBTRACT: BOOLEAN_SUBTRACT,\n BOOLEAN_UNION: BOOLEAN_UNION,\n calculateIntersections: calculateIntersections,\n innerClip: innerClip,\n intersect: intersect$1,\n outerClip: outerClip,\n removeNotRelevantChains: removeNotRelevantChains,\n removeOldFaces: removeOldFaces,\n restoreFaces: restoreFaces,\n subtract: subtract,\n unify: unify\n});\n\n/*\n Dimensionally extended 9-intersected model\n See https://en.wikipedia.org/wiki/DE-9IM for more details\n */\n// const DISJOINT = RegExp('FF.FF....');\nconst EQUAL = RegExp('T.F..FFF.|T.F...F..');\nconst INTERSECT = RegExp('T........|.T.......|...T.....|....T....');\nconst TOUCH = RegExp('FT.......|F..T.....|F...T....');\nconst INSIDE = RegExp('T.F..F...');\nconst COVERED = RegExp('T.F..F...|.TF..F...|..FT.F...|..F.TF...');\n\nclass DE9IM {\n /**\n * Create new instance of DE9IM matrix\n */\n constructor() {\n /**\n * Array representing 3x3 intersection matrix\n * @type {Shape[]}\n */\n this.m = new Array(9).fill(undefined);\n }\n\n /**\n * Get Interior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get I2I() {\n return this.m[0];\n }\n\n /**\n * Set Interior To Interior intersection\n * @param geom\n */\n set I2I(geom) {\n this.m[0] = geom;\n }\n\n /**\n * Get Interior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get I2B() {\n return this.m[1];\n }\n\n /**\n * Set Interior to Boundary intersection\n * @param geomc\n */\n set I2B(geom) {\n this.m[1] = geom;\n }\n\n /**\n * Get Interior To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get I2E() {\n return this.m[2];\n }\n\n /**\n * Set Interior to Exterior intersection\n * @param geom\n */\n set I2E(geom) {\n this.m[2] = geom;\n }\n\n /**\n * Get Boundary To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get B2I() {\n return this.m[3];\n }\n\n /**\n * Set Boundary to Interior intersection\n * @param geom\n */\n set B2I(geom) {\n this.m[3] = geom;\n }\n\n /**\n * Get Boundary To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get B2B() {\n return this.m[4];\n }\n\n /**\n * Set Boundary to Boundary intersection\n * @param geom\n */\n set B2B(geom) {\n this.m[4] = geom;\n }\n\n /**\n * Get Boundary To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get B2E() {\n return this.m[5];\n }\n\n /**\n * Set Boundary to Exterior intersection\n * @param geom\n */\n set B2E(geom) {\n this.m[5] = geom;\n }\n\n /**\n * Get Exterior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get E2I() {\n return this.m[6];\n }\n\n /**\n * Set Exterior to Interior intersection\n * @param geom\n */\n set E2I(geom) {\n this.m[6] = geom;\n }\n\n /**\n * Get Exterior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get E2B() {\n return this.m[7];\n }\n\n /**\n * Set Exterior to Boundary intersection\n * @param geom\n */\n set E2B(geom) {\n this.m[7] = geom;\n }\n\n /**\n * Get Exterior to Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get E2E() {\n return this.m[8];\n }\n\n /**\n * Set Exterior to Exterior intersection\n * @param geom\n */\n set E2E(geom) {\n this.m[8] = geom;\n }\n\n /**\n * Return de9im matrix as string where
\n * - intersection is 'T'
\n * - not intersected is 'F'
\n * - not relevant is '*'
\n * For example, string 'FF**FF****' means 'DISJOINT'\n * @returns {string}\n */\n toString() {\n return this.m.map( e => {\n if (e instanceof Array && e.length > 0) {\n return 'T'\n }\n else if (e instanceof Array && e.length === 0) {\n return 'F'\n }\n else {\n return '*'\n }\n }).join(\"\")\n }\n\n equal() {\n return EQUAL.test(this.toString());\n }\n\n intersect() {\n return INTERSECT.test(this.toString());\n }\n\n touch() {\n return TOUCH.test(this.toString());\n }\n\n inside() {\n return INSIDE.test(this.toString());\n }\n\n covered() {\n return COVERED.test(this.toString());\n }\n}\n\n/**\n * Intersection\n *\n * */\n\n\nfunction intersectLine2Line(line1, line2) {\n let ip = [];\n\n let [A1, B1, C1] = line1.standard;\n let [A2, B2, C2] = line2.standard;\n\n /* Cramer's rule */\n let det = A1 * B2 - B1 * A2;\n let detX = C1 * B2 - B1 * C2;\n let detY = A1 * C2 - C1 * A2;\n\n if (!Flatten.Utils.EQ_0(det)) {\n let x, y;\n\n if (B1 === 0) { // vertical line x = C1/A1, where A1 == +1 or -1\n x = C1/A1;\n y = detY / det;\n }\n else if (B2 === 0) { // vertical line x = C2/A2, where A2 = +1 or -1\n x = C2/A2;\n y = detY / det;\n }\n else if (A1 === 0) { // horizontal line y = C1/B1, where B1 = +1 or -1\n x = detX / det;\n y = C1/B1;\n }\n else if (A2 === 0) { // horizontal line y = C2/B2, where B2 = +1 or -1\n x = detX / det;\n y = C2/B2;\n }\n else {\n x = detX / det;\n y = detY / det;\n }\n\n ip.push(new Flatten.Point(x, y));\n }\n\n return ip;\n}\n\nfunction intersectLine2Circle(line, circle) {\n let ip = [];\n let prj = circle.pc.projectionOn(line); // projection of circle center on a line\n let dist = circle.pc.distanceTo(prj)[0]; // distance from circle center to projection\n\n if (Flatten.Utils.EQ(dist, circle.r)) { // line tangent to circle - return single intersection point\n ip.push(prj);\n } else if (Flatten.Utils.LT(dist, circle.r)) { // return two intersection points\n let delta = Math.sqrt(circle.r * circle.r - dist * dist);\n let v_trans, pt;\n\n v_trans = line.norm.rotate90CCW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n\n v_trans = line.norm.rotate90CW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n }\n return ip;\n}\n\nfunction intersectLine2Box(line, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Line(seg, line);\n for (let pt of ips_tmp) {\n if (!ptInIntPoints(pt, ips)) {\n ips.push(pt);\n }\n }\n }\n return ips;\n}\n\nfunction intersectLine2Arc(line, arc) {\n let ip = [];\n\n if (intersectLine2Box(line, arc.box).length === 0) {\n return ip;\n }\n\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectLine2Circle(line, circle);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectSegment2Line(seg, line) {\n let ip = [];\n\n // Boundary cases\n if (seg.ps.on(line)) {\n ip.push(seg.ps);\n }\n // If both ends lay on line, return two intersection points\n if (seg.pe.on(line) && !seg.isZeroLength()) {\n ip.push(seg.pe);\n }\n\n if (ip.length > 0) {\n return ip; // done, intersection found\n }\n\n // If zero-length segment and nothing found, return no intersections\n if (seg.isZeroLength()) {\n return ip;\n }\n\n // Not a boundary case, check if both points are on the same side and\n // hence there is no intersection\n if (seg.ps.leftTo(line) && seg.pe.leftTo(line) ||\n !seg.ps.leftTo(line) && !seg.pe.leftTo(line)) {\n return ip;\n }\n\n // Calculate intersection between lines\n let line1 = new Flatten.Line(seg.ps, seg.pe);\n return intersectLine2Line(line1, line);\n}\n\nfunction intersectSegment2Segment(seg1, seg2) {\n let ip = [];\n\n // quick reject\n if (seg1.box.not_intersect(seg2.box)) {\n return ip;\n }\n\n // Special case of seg1 zero length\n if (seg1.isZeroLength()) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n return ip;\n }\n\n // Special case of seg2 zero length\n if (seg2.isZeroLength()) {\n if (seg2.ps.on(seg1)) {\n ip.push(seg2.ps);\n }\n return ip;\n }\n\n // Neither seg1 nor seg2 is zero length\n let line1 = new Flatten.Line(seg1.ps, seg1.pe);\n let line2 = new Flatten.Line(seg2.ps, seg2.pe);\n\n // Check overlapping between segments in case of incidence\n // If segments touching, add one point. If overlapping, add two points\n if (line1.incidentTo(line2)) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n if (seg1.pe.on(seg2)) {\n ip.push(seg1.pe);\n }\n if (seg2.ps.on(seg1) && !seg2.ps.equalTo(seg1.ps) && !seg2.ps.equalTo(seg1.pe)) {\n ip.push(seg2.ps);\n }\n if (seg2.pe.on(seg1) && !seg2.pe.equalTo(seg1.ps) && !seg2.pe.equalTo(seg1.pe)) {\n ip.push(seg2.pe);\n }\n } else { /* not incident - parallel or intersect */\n // Calculate intersection between lines\n let new_ip = intersectLine2Line(line1, line2);\n if (new_ip.length > 0) {\n if (isPointInSegmentBox(new_ip[0], seg1) && isPointInSegmentBox(new_ip[0], seg2)) {\n ip.push(new_ip[0]);\n }\n }\n }\n return ip;\n}\n\nfunction isPointInSegmentBox(point, segment) {\n const box = segment.box;\n return Flatten.Utils.LE(point.x, box.xmax) && Flatten.Utils.GE(point.x, box.xmin) &&\n Flatten.Utils.LE(point.y, box.ymax) && Flatten.Utils.GE(point.y, box.ymin)\n}\n\nfunction intersectSegment2Circle(segment, circle) {\n let ips = [];\n\n if (segment.box.not_intersect(circle.box)) {\n return ips;\n }\n\n // Special case of zero length segment\n if (segment.isZeroLength()) {\n let [dist, _] = segment.ps.distanceTo(circle.pc);\n if (Flatten.Utils.EQ(dist, circle.r)) {\n ips.push(segment.ps);\n }\n return ips;\n }\n\n // Non zero-length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n\n let ips_tmp = intersectLine2Circle(line, circle);\n\n for (let ip of ips_tmp) {\n if (ip.on(segment)) {\n ips.push(ip);\n }\n }\n\n return ips;\n}\n\nfunction intersectSegment2Arc(segment, arc) {\n let ip = [];\n\n if (segment.box.not_intersect(arc.box)) {\n return ip;\n }\n\n // Special case of zero-length segment\n if (segment.isZeroLength()) {\n if (segment.ps.on(arc)) {\n ip.push(segment.ps);\n }\n return ip;\n }\n\n // Non-zero length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n let ip_tmp = intersectLine2Circle(line, circle);\n\n for (let pt of ip_tmp) {\n if (pt.on(segment) && pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n\n}\n\nfunction intersectSegment2Box(segment, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Segment(seg, segment);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectCircle2Circle(circle1, circle2) {\n let ip = [];\n\n if (circle1.box.not_intersect(circle2.box)) {\n return ip;\n }\n\n let vec = new Flatten.Vector(circle1.pc, circle2.pc);\n\n let r1 = circle1.r;\n let r2 = circle2.r;\n\n // Degenerated circle\n if (Flatten.Utils.EQ_0(r1) || Flatten.Utils.EQ_0(r2))\n return ip;\n\n // In case of equal circles return one leftmost point\n if (Flatten.Utils.EQ_0(vec.x) && Flatten.Utils.EQ_0(vec.y) && Flatten.Utils.EQ(r1, r2)) {\n ip.push(circle1.pc.translate(-r1, 0));\n return ip;\n }\n\n let dist = circle1.pc.distanceTo(circle2.pc)[0];\n\n if (Flatten.Utils.GT(dist, r1 + r2)) // circles too far, no intersections\n return ip;\n\n if (Flatten.Utils.LT(dist, Math.abs(r1 - r2))) // one circle is contained within another, no intersections\n return ip;\n\n // Normalize vector.\n vec.x /= dist;\n vec.y /= dist;\n\n let pt;\n\n // Case of touching from outside or from inside - single intersection point\n // TODO: check this specifically not sure if correct\n if (Flatten.Utils.EQ(dist, r1 + r2) || Flatten.Utils.EQ(dist, Math.abs(r1 - r2))) {\n pt = circle1.pc.translate(r1 * vec.x, r1 * vec.y);\n ip.push(pt);\n return ip;\n }\n\n // Case of two intersection points\n\n // Distance from first center to center of common chord:\n // a = (r1^2 - r2^2 + d^2) / 2d\n // Separate for better accuracy\n let a = (r1 * r1) / (2 * dist) - (r2 * r2) / (2 * dist) + dist / 2;\n\n let mid_pt = circle1.pc.translate(a * vec.x, a * vec.y);\n let h = Math.sqrt(r1 * r1 - a * a);\n // let norm;\n\n // norm = vec.rotate90CCW().multiply(h);\n pt = mid_pt.translate(vec.rotate90CCW().multiply(h));\n ip.push(pt);\n\n // norm = vec.rotate90CW();\n pt = mid_pt.translate(vec.rotate90CW().multiply(h));\n ip.push(pt);\n\n return ip;\n}\n\nfunction intersectCircle2Box(circle, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Circle(seg, circle);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectArc2Arc(arc1, arc2) {\n let ip = [];\n\n if (arc1.box.not_intersect(arc2.box)) {\n return ip;\n }\n\n // Special case: overlapping arcs\n // May return up to 4 intersection points\n if (arc1.pc.equalTo(arc2.pc) && Flatten.Utils.EQ(arc1.r, arc2.r)) {\n let pt;\n\n pt = arc1.start;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc1.end;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc2.start;\n if (pt.on(arc1)) ip.push(pt);\n\n pt = arc2.end;\n if (pt.on(arc1)) ip.push(pt);\n\n return ip;\n }\n\n // Common case\n let circle1 = new Flatten.Circle(arc1.pc, arc1.r);\n let circle2 = new Flatten.Circle(arc2.pc, arc2.r);\n let ip_tmp = circle1.intersect(circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc1) && pt.on(arc2)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Circle(arc, circle) {\n let ip = [];\n\n if (arc.box.not_intersect(circle.box)) {\n return ip;\n }\n\n // Case when arc center incident to circle center\n // Return arc's end points as 2 intersection points\n if (circle.pc.equalTo(arc.pc) && Flatten.Utils.EQ(circle.r, arc.r)) {\n ip.push(arc.start);\n ip.push(arc.end);\n return ip;\n }\n\n // Common case\n let circle1 = circle;\n let circle2 = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectCircle2Circle(circle1, circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Box(arc, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Arc(seg, arc);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectEdge2Segment(edge, segment) {\n return edge.isSegment ? intersectSegment2Segment(edge.shape, segment) : intersectSegment2Arc(segment, edge.shape);\n}\n\nfunction intersectEdge2Arc(edge, arc) {\n return edge.isSegment ? intersectSegment2Arc(edge.shape, arc) : intersectArc2Arc(edge.shape, arc);\n}\n\nfunction intersectEdge2Line(edge, line) {\n return edge.isSegment ? intersectSegment2Line(edge.shape, line) : intersectLine2Arc(line, edge.shape);\n}\n\nfunction intersectEdge2Ray(edge, ray) {\n return edge.isSegment ? intersectRay2Segment(ray, edge.shape) : intersectRay2Arc(ray, edge.shape);\n}\n\nfunction intersectEdge2Circle(edge, circle) {\n return edge.isSegment ? intersectSegment2Circle(edge.shape, circle) : intersectArc2Circle(edge.shape, circle);\n}\n\nfunction intersectSegment2Polygon(segment, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Segment(edge, segment)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectArc2Polygon(arc, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Arc(edge, arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectLine2Polygon(line, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Line(edge, line)) {\n if (!ptInIntPoints(pt, ip)) {\n ip.push(pt);\n }\n }\n }\n\n return line.sortPoints(ip);\n}\n\nfunction intersectCircle2Polygon(circle, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Circle(edge, circle)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectEdge2Edge(edge1, edge2) {\n if (edge1.isSegment) {\n return intersectEdge2Segment(edge2, edge1.shape)\n }\n else if (edge1.isArc) {\n return intersectEdge2Arc(edge2, edge1.shape)\n }\n else if (edge1.isLine) {\n return intersectEdge2Line(edge2, edge1.shape)\n }\n else if (edge1.isRay) {\n return intersectEdge2Ray(edge2, edge1.shape)\n }\n return []\n}\n\nfunction intersectEdge2Polygon(edge, polygon) {\n let ip = [];\n\n if (polygon.isEmpty() || edge.shape.box.not_intersect(polygon.box)) {\n return ip;\n }\n\n let resp_edges = polygon.edges.search(edge.shape.box);\n\n for (let resp_edge of resp_edges) {\n ip = [...ip, ...intersectEdge2Edge(edge, resp_edge)];\n }\n\n return ip;\n}\n\nfunction intersectPolygon2Polygon(polygon1, polygon2) {\n let ip = [];\n\n if (polygon1.isEmpty() || polygon2.isEmpty()) {\n return ip;\n }\n\n if (polygon1.box.not_intersect(polygon2.box)) {\n return ip;\n }\n\n for (let edge1 of polygon1.edges) {\n ip = [...ip, ...intersectEdge2Polygon(edge1, polygon2)];\n }\n\n return ip;\n}\n\nfunction intersectShape2Polygon(shape, polygon) {\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, polygon);\n }\n else {\n return [];\n }\n}\n\nfunction ptInIntPoints(new_pt, ip) {\n return ip.some( pt => pt.equalTo(new_pt) )\n}\n\nfunction createLineFromRay(ray) {\n return new Flatten.Line(ray.start, ray.norm)\n}\nfunction intersectRay2Segment(ray, segment) {\n return intersectSegment2Line(segment, createLineFromRay(ray))\n .filter(pt => ray.contains(pt));\n}\n\nfunction intersectRay2Arc(ray, arc) {\n return intersectLine2Arc(createLineFromRay(ray), arc)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Circle(ray, circle) {\n return intersectLine2Circle(createLineFromRay(ray), circle)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Box(ray, box) {\n return intersectLine2Box(createLineFromRay(ray), box)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Line(ray, line) {\n return intersectLine2Line(createLineFromRay(ray), line)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Ray(ray1, ray2) {\n return intersectLine2Line(createLineFromRay(ray1), createLineFromRay(ray2))\n .filter(pt => ray1.contains(pt))\n .filter(pt => ray2.contains(pt))\n}\n\nfunction intersectRay2Polygon(ray, polygon) {\n return intersectLine2Polygon(createLineFromRay(ray), polygon)\n .filter(pt => ray.contains(pt))\n}\n\nconst defaultAttributes = {\n stroke: \"black\"\n};\n\nclass SVGAttributes {\n constructor(args = defaultAttributes) {\n for(const property in args) {\n this[property] = args[property];\n }\n this.stroke = args.stroke ?? defaultAttributes.stroke;\n }\n\n toAttributesString() {\n return Object.keys(this)\n .reduce( (acc, key) =>\n acc + (this[key] !== undefined ? this.toAttrString(key, this[key]) : \"\")\n , ``)\n }\n\n toAttrString(key, value) {\n const SVGKey = key === \"className\" ? \"class\" : this.convertCamelToKebabCase(key);\n return value === null ? `${SVGKey} ` : `${SVGKey}=\"${value.toString()}\" `\n }\n\n convertCamelToKebabCase(str) {\n return str\n .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)\n .join('-')\n .toLowerCase();\n }\n}\n\nfunction convertToString(attrs) {\n return new SVGAttributes(attrs).toAttributesString()\n}\n\n/**\n * Class Multiline represent connected path of [edges]{@link Flatten.Edge}, where each edge may be\n * [segment]{@link Flatten.Segment}, [arc]{@link Flatten.Arc}, [line]{@link Flatten.Line} or [ray]{@link Flatten.Ray}\n */\nclass Multiline extends LinkedList {\n constructor(...args) {\n super();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n let shapes = args[0];\n if (shapes.length === 0)\n return;\n\n // TODO: more strict validation:\n // there may be only one line\n // only first and last may be rays\n shapes.every((shape) => {\n return shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc ||\n shape instanceof Flatten.Ray ||\n shape instanceof Flatten.Line\n });\n\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n }\n\n this.setArcLength();\n }\n }\n }\n\n /**\n * (Getter) Return array of edges\n * @returns {Edge[]}\n */\n get edges() {\n return [...this];\n }\n\n /**\n * (Getter) Return bounding box of the multiline\n * @returns {Box}\n */\n get box() {\n return this.edges.reduce( (acc,edge) => acc.merge(edge.box), new Flatten.Box() );\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Point[]}\n */\n get vertices() {\n let v = this.edges.map(edge => edge.start);\n v.push(this.last.end);\n return v;\n }\n\n /**\n * Return new cloned instance of Multiline\n * @returns {Multiline}\n */\n clone() {\n return new Multiline(this.toShapes());\n }\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Split edge and add new vertex, return new edge inserted\n * @param {Point} pt - point on edge that will be added as new vertex\n * @param {Edge} edge - edge to split\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n this.insert(newEdge, edgeBefore); // edge.face ?\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n return newEdge;\n }\n\n getChain(edgeFrom, edgeTo) {\n let edges = [];\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n edges.push(edge);\n }\n return edges\n }\n\n /**\n * Split edges of multiline with intersection points and return mutated multiline\n * @param {Point[]} ip - array of points to be added as new vertices\n * @returns {Multiline}\n */\n split(ip) {\n for (let pt of ip) {\n let edge = this.findEdgeByPoint(pt);\n this.addVertex(pt, edge);\n }\n return this;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new multiline translated by vector vec\n * @param {Vector} vec\n * @returns {Multiline}\n */\n translate(vec) {\n return new Multiline(this.edges.map( edge => edge.shape.translate(vec)));\n }\n\n /**\n * Return new multiline rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Multiline} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n return new Multiline(this.edges.map( edge => edge.shape.rotate(angle, center) ));\n }\n\n /**\n * Return new multiline transformed using affine transformation matrix\n * Method does not support unbounded shapes\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Multiline} - new multiline\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Multiline(this.edges.map( edge => edge.shape.transform(matrix)));\n }\n\n /**\n * Transform multiline into array of shapes\n * @returns {Shape[]}\n */\n toShapes() {\n return this.edges.map(edge => edge.shape.clone())\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Return string to draw multiline in svg\n * @param attrs - an object with attributes for svg path element\n * TODO: support semi-infinite Ray and infinite Line\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Multiline = Multiline;\n\n/**\n * Shortcut function to create multiline\n * @param args\n */\nconst multiline = (...args) => new Flatten.Multiline(...args);\nFlatten.multiline = multiline;\n\n/**\n * @module RayShoot\n */\n/**\n * Implements ray shooting algorithm. Returns relation between point and polygon: inside, outside or boundary\n * @param {Polygon} polygon - polygon to test\n * @param {Point} point - point to test\n * @returns {INSIDE|OUTSIDE|BOUNDARY}\n */\nfunction ray_shoot(polygon, point) {\n let contains = undefined;\n\n // 1. Quick reject\n // if (polygon.box.not_intersect(point.box)) {\n // return Flatten.OUTSIDE;\n // }\n\n let ray = new Flatten.Ray(point);\n let line = new Flatten.Line(ray.pt, ray.norm);\n\n // 2. Locate relevant edges of the polygon\n const searchBox = new Flatten.Box(\n ray.box.xmin-Flatten.DP_TOL, ray.box.ymin-Flatten.DP_TOL,\n ray.box.xmax, ray.box.ymax+Flatten.DP_TOL\n );\n\n if (polygon.box.not_intersect(searchBox)) {\n return Flatten.OUTSIDE;\n }\n\n let resp_edges = polygon.edges.search(searchBox);\n\n if (resp_edges.length == 0) {\n return Flatten.OUTSIDE;\n }\n\n // 2.5 Check if boundary\n for (let edge of resp_edges) {\n if (edge.shape.contains(point)) {\n return Flatten.BOUNDARY;\n }\n }\n\n // 3. Calculate intersections\n let intersections = [];\n for (let edge of resp_edges) {\n for (let ip of ray.intersect(edge.shape)) {\n\n // If intersection is equal to query point then point lays on boundary\n if (ip.equalTo(point)) {\n return Flatten.BOUNDARY;\n }\n\n intersections.push({\n pt: ip,\n edge: edge\n });\n }\n }\n\n // 4. Sort intersection in x-ascending order\n intersections.sort((i1, i2) => {\n if (LT(i1.pt.x, i2.pt.x)) {\n return -1;\n }\n if (GT(i1.pt.x, i2.pt.x)) {\n return 1;\n }\n return 0;\n });\n\n // 5. Count real intersections, exclude touching\n let counter = 0;\n\n for (let i = 0; i < intersections.length; i++) {\n let intersection = intersections[i];\n if (intersection.pt.equalTo(intersection.edge.shape.start)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.edge.prev === intersections[i - 1].edge) {\n continue;\n }\n let prev_edge = intersection.edge.prev;\n while (EQ_0(prev_edge.length)) {\n prev_edge = prev_edge.prev;\n }\n let prev_tangent = prev_edge.shape.tangentInEnd();\n let prev_point = intersection.pt.translate(prev_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInStart();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let prev_on_the_left = prev_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((prev_on_the_left && !cur_on_the_left) || (!prev_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else if (intersection.pt.equalTo(intersection.edge.shape.end)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.edge.next === intersections[i - 1].edge) {\n continue;\n }\n let next_edge = intersection.edge.next;\n while (EQ_0(next_edge.length)) {\n next_edge = next_edge.next;\n }\n let next_tangent = next_edge.shape.tangentInStart();\n let next_point = intersection.pt.translate(next_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInEnd();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let next_on_the_left = next_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((next_on_the_left && !cur_on_the_left) || (!next_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else { /* intersection point is not a coincident with a vertex */\n if (intersection.edge.shape instanceof Flatten.Segment) {\n counter++;\n } else {\n /* Check if ray does not touch the curve in the extremal (top or bottom) point */\n let box = intersection.edge.shape.box;\n if (!(EQ(intersection.pt.y, box.ymin) ||\n EQ(intersection.pt.y, box.ymax))) {\n counter++;\n }\n }\n }\n }\n\n // 6. Odd or even?\n contains = counter % 2 == 1 ? INSIDE$2 : OUTSIDE$1;\n\n return contains;\n}\n\n/*\n Calculate relationship between two shapes and return result in the form of\n Dimensionally Extended nine-Intersection Matrix (https://en.wikipedia.org/wiki/DE-9IM)\n */\n\n\n/**\n * Returns true if shapes are topologically equal: their interiors intersect and\n * no part of the interior or boundary of one geometry intersects the exterior of the other\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction equal(shape1, shape2) {\n return relate(shape1, shape2).equal();\n}\n\n/**\n * Returns true if shapes have at least one point in common, same as \"not disjoint\"\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction intersect(shape1, shape2) {\n return relate(shape1, shape2).intersect();\n}\n\n/**\n * Returns true if shapes have at least one point in common, but their interiors do not intersect\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction touch(shape1, shape2) {\n return relate(shape1, shape2).touch();\n}\n\n/**\n * Returns true if shapes have no points in common neither in interior nor in boundary\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction disjoint(shape1, shape2) {\n return !intersect(shape1, shape2);\n}\n\n/**\n * Returns true shape1 lies in the interior of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction inside(shape1, shape2) {\n return relate(shape1, shape2).inside();\n}\n\n/**\n * Returns true if every point in shape1 lies in the interior or on the boundary of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction covered(shape1, shape2) {\n return relate(shape1, shape2).covered();\n}\n\n/**\n * Returns true shape1's interior contains shape2
\n * Same as inside(shape2, shape1)\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction contain(shape1, shape2) {\n return inside(shape2, shape1);\n}\n\n/**\n * Returns true shape1's cover shape2, same as shape2 covered by shape1\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction cover(shape1, shape2) {\n return covered(shape2, shape1);\n}\n\n/**\n * Returns relation between two shapes as intersection 3x3 matrix, where each\n * element contains relevant intersection as array of shapes.\n * If there is no intersection, element contains empty array\n * If intersection is irrelevant it left undefined. (For example, intersection\n * between two exteriors is usually irrelevant)\n * @param shape1\n * @param shape2\n * @returns {DE9IM}\n */\nfunction relate(shape1, shape2) {\n if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Line) {\n return relateLine2Line(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Circle) {\n return relateLine2Circle(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Box) {\n return relateLine2Box(shape1, shape2);\n }\n else if ( shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Polygon) {\n return relateLine2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) && shape2 instanceof Flatten.Polygon) {\n return relateShape2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box) ) {\n return relateShape2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n else if (shape1 instanceof Flatten.Polygon && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(shape1, shape2);\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), new Flatten.Polygon(shape2));\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), shape2);\n }\n else if (shape1 instanceof Flatten.Polygon && (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n}\n\nfunction relateLine2Line(line1, line2) {\n let denim = new DE9IM();\n let ip = intersectLine2Line(line1, line2);\n if (ip.length === 0) { // parallel or equal ?\n if (line1.contains(line2.pt) && line2.contains(line1.pt)) {\n denim.I2I = [line1]; // equal 'T.F...F..' - no boundary\n denim.I2E = [];\n denim.E2I = [];\n }\n else { // parallel - disjoint 'FFTFF*T**'\n denim.I2I = [];\n denim.I2E = [line1];\n denim.E2I = [line2];\n }\n }\n else { // intersect 'T********'\n denim.I2I = ip;\n denim.I2E = line1.split(ip);\n denim.E2I = line2.split(ip);\n }\n return denim;\n}\n\nfunction relateLine2Circle(line,circle) {\n let denim = new DE9IM();\n let ip = intersectLine2Circle(line, circle);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n denim.E2I = [circle];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [circle];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n denim.I2I = [splitShapes[1]];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon([circle.toArc()]).cutWithLine(line);\n }\n\n return denim;\n}\n\nfunction relateLine2Box(line, box) {\n let denim = new DE9IM();\n let ip = intersectLine2Box(line, box);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n\n denim.E2I = [box];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [box];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n /* Are two intersection points on the same segment of the box boundary ? */\n if (box.toSegments().some( segment => segment.contains(ip[0]) && segment.contains(ip[1]) )) {\n denim.I2I = []; // case of touching\n denim.I2B = [splitShapes[1]];\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = [box];\n }\n else { // case of intersection\n denim.I2I = [splitShapes[1]]; // [segment(ip[0], ip[1])];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon(box.toSegments()).cutWithLine(line);\n }\n }\n return denim;\n}\n\nfunction relateLine2Polygon(line, polygon) {\n let denim = new DE9IM();\n let ip = intersectLine2Polygon(line, polygon);\n let multiline = new Multiline([line]);\n let ip_sorted = ip.length > 0 ? ip.slice() : line.sortPoints(ip);\n\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n denim.E2I = polygon.cutWithLine(line);\n\n return denim;\n}\n\nfunction relateShape2Polygon(shape, polygon) {\n let denim = new DE9IM();\n let ip = intersectShape2Polygon(shape, polygon);\n let ip_sorted = ip.length > 0 ? ip.slice() : shape.sortPoints(ip);\n\n let multiline = new Multiline([shape]);\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n\n denim.B2I = [];\n denim.B2B = [];\n denim.B2E = [];\n for (let pt of [shape.start, shape.end]) {\n switch (ray_shoot(polygon, pt)) {\n case Flatten.INSIDE:\n denim.B2I.push(pt);\n break;\n case Flatten.BOUNDARY:\n denim.B2B.push(pt);\n break;\n case Flatten.OUTSIDE:\n denim.B2E.push(pt);\n break;\n }\n }\n\n // denim.E2I TODO: calculate, not clear what is expected result\n\n return denim;\n}\n\nfunction relatePolygon2Polygon(polygon1, polygon2) {\n let denim = new DE9IM();\n\n let [ip_sorted1, ip_sorted2] = calculateIntersections(polygon1, polygon2);\n let boolean_intersection = intersect$1(polygon1, polygon2);\n let boolean_difference1 = subtract(polygon1, polygon2);\n let boolean_difference2 = subtract(polygon2, polygon1);\n let [inner_clip_shapes1, inner_clip_shapes2] = innerClip(polygon1, polygon2);\n let outer_clip_shapes1 = outerClip(polygon1, polygon2);\n let outer_clip_shapes2 = outerClip(polygon2, polygon1);\n\n denim.I2I = boolean_intersection.isEmpty() ? [] : [boolean_intersection];\n denim.I2B = inner_clip_shapes2;\n denim.I2E = boolean_difference1.isEmpty() ? [] : [boolean_difference1];\n\n denim.B2I = inner_clip_shapes1;\n denim.B2B = ip_sorted1;\n denim.B2E = outer_clip_shapes1;\n\n denim.E2I = boolean_difference2.isEmpty() ? [] : [boolean_difference2];\n denim.E2B = outer_clip_shapes2;\n // denim.E2E not relevant meanwhile\n\n return denim;\n}\n\nvar Relations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n contain: contain,\n cover: cover,\n covered: covered,\n disjoint: disjoint,\n equal: equal,\n inside: inside,\n intersect: intersect,\n relate: relate,\n touch: touch\n});\n\n/**\n * Class representing an affine transformation 3x3 matrix:\n *
\n *      [ a  c  tx\n * A =    b  d  ty\n *        0  0  1  ]\n * \n     * If parameters omitted, construct identity matrix a = 1, d = 1\n     * @param {number} a - position(0,0)   sx*cos(alpha)\n     * @param {number} b - position (0,1)  sx*sin(alpha)\n     * @param {number} c - position (1,0)  -sy*sin(alpha)\n     * @param {number} d - position (1,1)  sy*cos(alpha)\n     * @param {number} tx - position (2,0) translation by x\n     * @param {number} ty - position (2,1) translation by y\n     */\n    constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) {\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.tx = tx;\n        this.ty = ty;\n    }\n\n    /**\n     * Return new cloned instance of matrix\n     * @return {Matrix}\n     **/\n    clone() {\n        return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);\n    };\n\n    /**\n     * Transform vector [x,y] using transformation matrix. 
\n * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object
\n * The result is also an abstract vector [x',y'] = A * [x,y]:\n * \n * [x' [ ax + by + tx\n * y' = cx + dy + ty\n * 1] 1 ]\n * \n * @param {number[]} vector - array[2] of numbers\n * @returns {number[]} transformation result - array[2] of numbers\n */\n transform(vector) {\n return [\n vector[0] * this.a + vector[1] * this.c + this.tx,\n vector[0] * this.b + vector[1] * this.d + this.ty\n ]\n };\n\n /**\n * Returns result of multiplication of this matrix by other matrix\n * @param {Matrix} other_matrix - matrix to multiply by\n * @returns {Matrix}\n */\n multiply(other_matrix) {\n return new Matrix(\n this.a * other_matrix.a + this.c * other_matrix.b,\n this.b * other_matrix.a + this.d * other_matrix.b,\n this.a * other_matrix.c + this.c * other_matrix.d,\n this.b * other_matrix.c + this.d * other_matrix.d,\n this.a * other_matrix.tx + this.c * other_matrix.ty + this.tx,\n this.b * other_matrix.tx + this.d * other_matrix.ty + this.ty\n )\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix(1,0,0,1,tx,ty)\n * @param {Vector} vector - Translation by vector or\n * @param {number} tx - translation by x-axis\n * @param {number} ty - translation by y-axis\n * @returns {Matrix}\n */\n translate(...args) {\n let tx, ty;\n if (args.length == 1 && !isNaN(args[0].x) && !isNaN(args[0].y)) {\n tx = args[0].x;\n ty = args[0].y;\n } else if (args.length === 2 && typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n tx = args[0];\n ty = args[1];\n } else {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n return this.multiply(new Matrix(1, 0, 0, 1, tx, ty))\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix that defines rotation by given angle (in radians) around\n * center of rotation (centerX,centerY) in counterclockwise direction\n * @param {number} angle - angle in radians\n * @param {number} centerX - center of rotation\n * @param {number} centerY - center of rotation\n * @returns {Matrix}\n */\n rotate(angle, centerX = 0.0, centerY = 0.0) {\n let cos = Math.cos(angle);\n let sin = Math.sin(angle);\n return this\n .translate(centerX, centerY)\n .multiply(new Matrix(cos, sin, -sin, cos, 0, 0))\n .translate(-centerX, -centerY);\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix (sx,0,0,sy,0,0) that defines scaling\n * @param {number} sx\n * @param {number} sy\n * @returns {Matrix}\n */\n scale(sx, sy) {\n return this.multiply(new Matrix(sx, 0, 0, sy, 0, 0));\n };\n\n /**\n * Returns true if two matrix are equal parameter by parameter\n * @param {Matrix} matrix - other matrix\n * @returns {boolean} true if equal, false otherwise\n */\n equalTo(matrix) {\n if (!Flatten.Utils.EQ(this.tx, matrix.tx)) return false;\n if (!Flatten.Utils.EQ(this.ty, matrix.ty)) return false;\n if (!Flatten.Utils.EQ(this.a, matrix.a)) return false;\n if (!Flatten.Utils.EQ(this.b, matrix.b)) return false;\n if (!Flatten.Utils.EQ(this.c, matrix.c)) return false;\n if (!Flatten.Utils.EQ(this.d, matrix.d)) return false;\n return true;\n };\n}\nFlatten.Matrix = Matrix;\n/**\n * Function to create matrix equivalent to \"new\" constructor\n * @param args\n */\nconst matrix = (...args) => new Flatten.Matrix(...args);\nFlatten.matrix = matrix;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n/**\n * Interval is a pair of numbers or a pair of any comparable objects on which may be defined predicates\n * *equal*, *less* and method *max(p1, p1)* that returns maximum in a pair.\n * When interval is an object rather than pair of numbers, this object should have properties *low*, *high*, *max*\n * and implement methods *less_than(), equal_to(), intersect(), not_intersect(), clone(), output()*.\n * Two static methods *comparable_max(), comparable_less_than()* define how to compare values in pair.
\n * This interface is described in typescript definition file *index.d.ts*\n *\n * Axis aligned rectangle is an example of such interval.\n * We may look at rectangle as an interval between its low left and top right corners.\n * See **Box** class in [flatten-js](https://github.com/alexbol99/flatten-js) library as the example\n * of Interval interface implementation\n * @type {Interval}\n */\nconst Interval = class Interval {\n /**\n * Accept two comparable values and creates new instance of interval\n * Predicate Interval.comparable_less(low, high) supposed to return true on these values\n * @param low\n * @param high\n */\n constructor(low, high) {\n this.low = low;\n this.high = high;\n }\n\n /**\n * Clone interval\n * @returns {Interval}\n */\n clone() {\n return new Interval(this.low, this.high);\n }\n\n /**\n * Propery max returns clone of this interval\n * @returns {Interval}\n */\n get max() {\n return this.clone(); // this.high;\n }\n\n /**\n * Predicate returns true is this interval less than other interval\n * @param other_interval\n * @returns {boolean}\n */\n less_than(other_interval) {\n return this.low < other_interval.low ||\n this.low == other_interval.low && this.high < other_interval.high;\n }\n\n /**\n * Predicate returns true is this interval equals to other interval\n * @param other_interval\n * @returns {boolean}\n */\n equal_to(other_interval) {\n return this.low == other_interval.low && this.high == other_interval.high;\n }\n\n /**\n * Predicate returns true if this interval intersects other interval\n * @param other_interval\n * @returns {boolean}\n */\n intersect(other_interval) {\n return !this.not_intersect(other_interval);\n }\n\n /**\n * Predicate returns true if this interval does not intersect other interval\n * @param other_interval\n * @returns {boolean}\n */\n not_intersect(other_interval) {\n return (this.high < other_interval.low || other_interval.high < this.low);\n }\n\n /**\n * Returns new interval merged with other interval\n * @param {Interval} interval - Other interval to merge with\n * @returns {Interval}\n */\n merge(other_interval) {\n return new Interval(\n this.low === undefined ? other_interval.low : Math.min(this.low, other_interval.low),\n this.high === undefined ? other_interval.high : Math.max(this.high, other_interval.high)\n );\n }\n\n /**\n * Returns how key should return\n */\n output() {\n return [this.low, this.high];\n }\n\n /**\n * Function returns maximum between two comparable values\n * @param interval1\n * @param interval2\n * @returns {Interval}\n */\n static comparable_max(interval1, interval2) {\n return interval1.merge(interval2);\n }\n\n /**\n * Predicate returns true if first value less than second value\n * @param val1\n * @param val2\n * @returns {boolean}\n */\n static comparable_less_than(val1, val2 ) {\n return val1 < val2;\n }\n};\n\n/**\n * Created by Alex Bol on 3/28/2017.\n */\n\n\n// module.exports = {\n// RB_TREE_COLOR_RED: 0,\n// RB_TREE_COLOR_BLACK: 1\n// };\n\nconst RB_TREE_COLOR_RED = 0;\nconst RB_TREE_COLOR_BLACK = 1;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n\nclass Node {\n constructor(key = undefined, value = undefined,\n left = null, right = null, parent = null, color = RB_TREE_COLOR_BLACK) {\n this.left = left; // reference to left child node\n this.right = right; // reference to right child node\n this.parent = parent; // reference to parent node\n this.color = color;\n\n this.item = {key: key, value: value}; // key is supposed to be instance of Interval\n\n /* If not, this should by an array of two numbers */\n if (key && key instanceof Array && key.length == 2) {\n if (!Number.isNaN(key[0]) && !Number.isNaN(key[1])) {\n this.item.key = new Interval(Math.min(key[0], key[1]), Math.max(key[0], key[1]));\n }\n }\n\n this.max = this.item.key ? this.item.key.max : undefined;\n }\n\n isNil() {\n return (this.item.key === undefined && this.item.value === undefined &&\n this.left === null && this.right === null && this.color === RB_TREE_COLOR_BLACK);\n }\n\n _value_less_than(other_node) {\n return this.item.value && other_node.item.value && this.item.value.less_than ?\n this.item.value.less_than(other_node.item.value) :\n this.item.value < other_node.item.value;\n }\n\n less_than(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.less_than(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.less_than(other_node.item.key) ||\n this.item.key.equal_to((other_node.item.key)) && this._value_less_than(other_node)\n }\n }\n\n _value_equal(other_node) {\n return this.item.value && other_node.item.value && this.item.value.equal_to ?\n this.item.value.equal_to(other_node.item.value) :\n this.item.value == other_node.item.value;\n }\n equal_to(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.equal_to(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.equal_to(other_node.item.key) && this._value_equal(other_node);\n }\n }\n\n intersect(other_node) {\n return this.item.key.intersect(other_node.item.key);\n }\n\n copy_data(other_node) {\n this.item.key = other_node.item.key;\n this.item.value = other_node.item.value;\n }\n\n update_max() {\n // use key (Interval) max property instead of key.high\n this.max = this.item.key ? this.item.key.max : undefined;\n if (this.right && this.right.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.right.max);\n }\n if (this.left && this.left.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.left.max);\n }\n }\n\n // Other_node does not intersect any node of left subtree, if this.left.max < other_node.item.key.low\n not_intersect_left_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let high = this.left.max.high !== undefined ? this.left.max.high : this.left.max;\n return comparable_less_than(high, search_node.item.key.low);\n }\n\n // Other_node does not intersect right subtree if other_node.item.key.high < this.right.key.low\n not_intersect_right_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let low = this.right.max.low !== undefined ? this.right.max.low : this.right.item.key.low;\n return comparable_less_than(search_node.item.key.high, low);\n }\n}\n\n/**\n * Created by Alex Bol on 3/31/2017.\n */\n\n// const nil_node = new Node();\n\n/**\n * Implementation of interval binary search tree
\n * Interval tree stores items which are couples of {key:interval, value: value}
\n * Interval is an object with high and low properties or simply pair [low,high] of numeric values
\n * @type {IntervalTree}\n */\nclass IntervalTree {\n /**\n * Construct new empty instance of IntervalTree\n */\n constructor() {\n this.root = null;\n this.nil_node = new Node();\n }\n\n /**\n * Returns number of items stored in the interval tree\n * @returns {number}\n */\n get size() {\n let count = 0;\n this.tree_walk(this.root, () => count++);\n return count;\n }\n\n /**\n * Returns array of sorted keys in the ascending order\n * @returns {Array}\n */\n get keys() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(\n node.item.key.output ? node.item.key.output() : node.item.key\n ));\n return res;\n }\n\n /**\n * Return array of values in the ascending keys order\n * @returns {Array}\n */\n get values() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(node.item.value));\n return res;\n }\n\n /**\n * Returns array of items ( pairs) in the ascended keys order\n * @returns {Array}\n */\n get items() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push({\n key: node.item.key.output ? node.item.key.output() : node.item.key,\n value: node.item.value\n }));\n return res;\n }\n\n /**\n * Returns true if tree is empty\n * @returns {boolean}\n */\n isEmpty() {\n return (this.root == null || this.root == this.nil_node);\n }\n\n /**\n * Clear tree\n */\n clear() {\n this.root = null;\n }\n\n /**\n * Insert new item into interval tree\n * @param {Interval} key - interval object or array of two numbers [low, high]\n * @param {any} value - value representing any object (optional)\n * @returns {Node} returns reference to inserted node as an object {key:interval, value: value}\n */\n insert(key, value = key) {\n if (key === undefined) return;\n let insert_node = new Node(key, value, this.nil_node, this.nil_node, null, RB_TREE_COLOR_RED);\n this.tree_insert(insert_node);\n this.recalc_max(insert_node);\n return insert_node;\n }\n\n /**\n * Returns true if item {key,value} exist in the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object to be checked\n * @returns {boolean} true if item {key, value} exist in the tree, false otherwise\n */\n exist(key, value = key) {\n let search_node = new Node(key, value);\n return this.tree_search(this.root, search_node) ? true : false;\n }\n\n /**\n * Remove entry {key, value} from the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object\n * @returns {boolean} true if item {key, value} deleted, false if not found\n */\n remove(key, value = key) {\n let search_node = new Node(key, value);\n let delete_node = this.tree_search(this.root, search_node);\n if (delete_node) {\n this.tree_delete(delete_node);\n }\n return delete_node;\n }\n\n /**\n * Returns array of entry values which keys intersect with given interval
\n * If no values stored in the tree, returns array of keys which intersect given interval\n * @param {Interval} interval - search interval, or tuple [low, high]\n * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output\n * @returns {Array}\n */\n search(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {\n let search_node = new Node(interval);\n let resp_nodes = [];\n this.tree_search_interval(this.root, search_node, resp_nodes);\n return resp_nodes.map(node => outputMapperFn(node.item.value, node.item.key))\n }\n\n /**\n * Returns true if intersection between given and any interval stored in the tree found\n * @param {Interval} interval - search interval or tuple [low, high]\n * @returns {boolean}\n */\n intersect_any(interval) {\n let search_node = new Node(interval);\n let found = this.tree_find_any_interval(this.root, search_node);\n return found;\n }\n\n /**\n * Tree visitor. For each node implement a callback function.
\n * Method calls a callback function with two parameters (key, value)\n * @param visitor(key,value) - function to be called for each tree item\n */\n forEach(visitor) {\n this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));\n }\n\n /** Value Mapper. Walk through every node and map node value to another value\n * @param callback(value,key) - function to be called for each tree item\n */\n map(callback) {\n const tree = new IntervalTree();\n this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));\n return tree;\n }\n\n recalc_max(node) {\n let node_current = node;\n while (node_current.parent != null) {\n node_current.parent.update_max();\n node_current = node_current.parent;\n }\n }\n\n tree_insert(insert_node) {\n let current_node = this.root;\n let parent_node = null;\n\n if (this.root == null || this.root == this.nil_node) {\n this.root = insert_node;\n }\n else {\n while (current_node != this.nil_node) {\n parent_node = current_node;\n if (insert_node.less_than(current_node)) {\n current_node = current_node.left;\n }\n else {\n current_node = current_node.right;\n }\n }\n\n insert_node.parent = parent_node;\n\n if (insert_node.less_than(parent_node)) {\n parent_node.left = insert_node;\n }\n else {\n parent_node.right = insert_node;\n }\n }\n\n this.insert_fixup(insert_node);\n }\n\n// After insertion insert_node may have red-colored parent, and this is a single possible violation\n// Go upwords to the root and re-color until violation will be resolved\n insert_fixup(insert_node) {\n let current_node;\n let uncle_node;\n\n current_node = insert_node;\n while (current_node != this.root && current_node.parent.color == RB_TREE_COLOR_RED) {\n if (current_node.parent == current_node.parent.parent.left) { // parent is left child of grandfather\n uncle_node = current_node.parent.parent.right; // right brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 1. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else { // Case 2 & 3. Uncle is black\n if (current_node == current_node.parent.right) { // Case 2. Current if right child\n // This case is transformed into Case 3.\n current_node = current_node.parent;\n this.rotate_left(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 3. Current is left child.\n // Re-color father and grandfather, rotate grandfather right\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_right(current_node.parent.parent);\n }\n }\n else { // parent is right child of grandfather\n uncle_node = current_node.parent.parent.left; // left brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 4. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else {\n if (current_node == current_node.parent.left) { // Case 5. Current is left child\n // Transform into case 6\n current_node = current_node.parent;\n this.rotate_right(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 6. Current is right child.\n // Re-color father and grandfather, rotate grandfather left\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_left(current_node.parent.parent);\n }\n }\n }\n\n this.root.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_delete(delete_node) {\n let cut_node; // node to be cut - either delete_node or successor_node (\"y\" from 14.4)\n let fix_node; // node to fix rb tree property (\"x\" from 14.4)\n\n if (delete_node.left == this.nil_node || delete_node.right == this.nil_node) { // delete_node has less then 2 children\n cut_node = delete_node;\n }\n else { // delete_node has 2 children\n cut_node = this.tree_successor(delete_node);\n }\n\n // fix_node if single child of cut_node\n if (cut_node.left != this.nil_node) {\n fix_node = cut_node.left;\n }\n else {\n fix_node = cut_node.right;\n }\n\n // remove cut_node from parent\n /*if (fix_node != this.nil_node) {*/\n fix_node.parent = cut_node.parent;\n /*}*/\n\n if (cut_node == this.root) {\n this.root = fix_node;\n }\n else {\n if (cut_node == cut_node.parent.left) {\n cut_node.parent.left = fix_node;\n }\n else {\n cut_node.parent.right = fix_node;\n }\n cut_node.parent.update_max(); // update max property of the parent\n }\n\n this.recalc_max(fix_node); // update max property upward from fix_node to root\n\n // COPY DATA !!!\n // Delete_node becomes cut_node, it means that we cannot hold reference\n // to node in outer structure and we will have to delete by key, additional search need\n if (cut_node != delete_node) {\n delete_node.copy_data(cut_node);\n delete_node.update_max(); // update max property of the cut node at the new place\n this.recalc_max(delete_node); // update max property upward from delete_node to root\n }\n\n if (/*fix_node != this.nil_node && */cut_node.color == RB_TREE_COLOR_BLACK) {\n this.delete_fixup(fix_node);\n }\n }\n\n delete_fixup(fix_node) {\n let current_node = fix_node;\n let brother_node;\n\n while (current_node != this.root && current_node.parent != null && current_node.color == RB_TREE_COLOR_BLACK) {\n if (current_node == current_node.parent.left) { // fix node is left child\n brother_node = current_node.parent.right;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_left(current_node.parent);\n brother_node = current_node.parent.right; // update brother\n }\n // Derive to cases 2..4: brother is black\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2: both nephews black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 3: left nephew red, right nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.left.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_right(brother_node);\n brother_node = current_node.parent.right; // update brother\n // Derive to case 4: left nephew black, right nephew red\n }\n // case 4: left nephew black, right nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.right.color = RB_TREE_COLOR_BLACK;\n this.rotate_left(current_node.parent);\n current_node = this.root; // exit from loop\n }\n }\n else { // fix node is right child\n brother_node = current_node.parent.left;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_right(current_node.parent);\n brother_node = current_node.parent.left; // update brother\n }\n // Go to cases 2..4\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.left.color == RB_TREE_COLOR_BLACK) { // case 3: right nephew red, left nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.right.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_left(brother_node);\n brother_node = current_node.parent.left; // update brother\n // Derive to case 4: right nephew black, left nephew red\n }\n // case 4: right nephew black, left nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.left.color = RB_TREE_COLOR_BLACK;\n this.rotate_right(current_node.parent);\n current_node = this.root; // force exit from loop\n }\n }\n }\n\n current_node.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_search(node, search_node) {\n if (node == null || node == this.nil_node)\n return undefined;\n\n if (search_node.equal_to(node)) {\n return node;\n }\n if (search_node.less_than(node)) {\n return this.tree_search(node.left, search_node);\n }\n else {\n return this.tree_search(node.right, search_node);\n }\n }\n\n // Original search_interval method; container res support push() insertion\n // Search all intervals intersecting given one\n tree_search_interval(node, search_node, res) {\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n this.tree_search_interval(node.left, search_node, res);\n }\n // if (low <= node->high && node->low <= high) {\n if (node.intersect(search_node)) {\n res.push(node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n this.tree_search_interval(node.right, search_node, res);\n }\n }\n }\n\n tree_find_any_interval(node, search_node) {\n let found = false;\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n found = this.tree_find_any_interval(node.left, search_node);\n }\n // if (low <= node->high && node->low <= high) {\n if (!found) {\n found = node.intersect(search_node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (!found && node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n found = this.tree_find_any_interval(node.right, search_node);\n }\n }\n return found;\n }\n\n local_minimum(node) {\n let node_min = node;\n while (node_min.left != null && node_min.left != this.nil_node) {\n node_min = node_min.left;\n }\n return node_min;\n }\n\n // not in use\n local_maximum(node) {\n let node_max = node;\n while (node_max.right != null && node_max.right != this.nil_node) {\n node_max = node_max.right;\n }\n return node_max;\n }\n\n tree_successor(node) {\n let node_successor;\n let current_node;\n let parent_node;\n\n if (node.right != this.nil_node) {\n node_successor = this.local_minimum(node.right);\n }\n else {\n current_node = node;\n parent_node = node.parent;\n while (parent_node != null && parent_node.right == current_node) {\n current_node = parent_node;\n parent_node = parent_node.parent;\n }\n node_successor = parent_node;\n }\n return node_successor;\n }\n\n // | right-rotate(T,y) |\n // y ---------------. x\n // / \\ / \\\n // x c left-rotate(T,x) a y\n // / \\ <--------------- / \\\n // a b b c\n\n rotate_left(x) {\n let y = x.right;\n\n x.right = y.left; // b goes to x.right\n\n if (y.left != this.nil_node) {\n y.left.parent = x; // x becomes parent of b\n }\n y.parent = x.parent; // move parent\n\n if (x == this.root) {\n this.root = y; // y becomes root\n }\n else { // y becomes child of x.parent\n if (x == x.parent.left) {\n x.parent.left = y;\n }\n else {\n x.parent.right = y;\n }\n }\n y.left = x; // x becomes left child of y\n x.parent = y; // and y becomes parent of x\n\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n\n y = x.parent;\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n }\n\n rotate_right(y) {\n let x = y.left;\n\n y.left = x.right; // b goes to y.left\n\n if (x.right != this.nil_node) {\n x.right.parent = y; // y becomes parent of b\n }\n x.parent = y.parent; // move parent\n\n if (y == this.root) { // x becomes root\n this.root = x;\n }\n else { // y becomes child of x.parent\n if (y == y.parent.left) {\n y.parent.left = x;\n }\n else {\n y.parent.right = x;\n }\n }\n x.right = y; // y becomes right child of x\n y.parent = x; // and x becomes parent of y\n\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n\n x = y.parent;\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n }\n\n tree_walk(node, action) {\n if (node != null && node != this.nil_node) {\n this.tree_walk(node.left, action);\n // arr.push(node.toArray());\n action(node);\n this.tree_walk(node.right, action);\n }\n }\n\n /* Return true if all red nodes have exactly two black child nodes */\n testRedBlackProperty() {\n let res = true;\n this.tree_walk(this.root, function (node) {\n if (node.color == RB_TREE_COLOR_RED) {\n if (!(node.left.color == RB_TREE_COLOR_BLACK && node.right.color == RB_TREE_COLOR_BLACK)) {\n res = false;\n }\n }\n });\n return res;\n }\n\n /* Throw error if not every path from root to bottom has same black height */\n testBlackHeightProperty(node) {\n let height = 0;\n let heightLeft = 0;\n let heightRight = 0;\n if (node.color == RB_TREE_COLOR_BLACK) {\n height++;\n }\n if (node.left != this.nil_node) {\n heightLeft = this.testBlackHeightProperty(node.left);\n }\n else {\n heightLeft = 1;\n }\n if (node.right != this.nil_node) {\n heightRight = this.testBlackHeightProperty(node.right);\n }\n else {\n heightRight = 1;\n }\n if (heightLeft != heightRight) {\n throw new Error('Red-black height property violated');\n }\n height += heightLeft;\n return height;\n };\n}\n\n/**\n * Created by Alex Bol on 3/12/2017.\n */\n\n\n/**\n * Class representing a planar set - a generic container with ability to keep and retrieve shapes and\n * perform spatial queries. Planar set is an extension of Set container, so it supports\n * Set properties and methods\n */\nclass PlanarSet extends Set {\n /**\n * Create new instance of PlanarSet\n * @param shapes - array or set of geometric objects to store in planar set\n * Each object should have a box property\n */\n constructor(shapes) {\n super(shapes);\n this.index = new IntervalTree();\n this.forEach(shape => this.index.insert(shape));\n }\n\n /**\n * Add new shape to planar set and to its spatial index.
\n * If shape already exist, it will not be added again.\n * This happens with no error, it is possible to use size property to check if\n * a shape was actually added.
\n * Method returns planar set object updated and may be chained\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property\n * Another option to transfer as an object {key: Box, value: AnyShape}\n * @returns {PlanarSet}\n */\n add(entry) {\n let size = this.size;\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n super.add(shape);\n // size not changed - item not added, probably trying to add same item twice\n if (this.size > size) {\n this.index.insert(box, shape);\n }\n return this; // in accordance to Set.add interface\n }\n\n /**\n * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted\n * @returns {boolean}\n */\n delete(entry) {\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n let deleted = super.delete(shape);\n if (deleted) {\n this.index.remove(box, shape);\n }\n return deleted;\n }\n\n /**\n * Clear planar set\n */\n clear() {\n super.clear();\n this.index = new IntervalTree();\n }\n\n /**\n * 2d range search in planar set.
\n * Returns array of all shapes in planar set which bounding box is intersected with query box\n * @param {Box} box - query box\n * @returns {AnyShape[]}\n */\n search(box) {\n let resp = this.index.search(box);\n return resp;\n }\n\n /**\n * Point location test. Returns array of shapes which contains given point\n * @param {Point} point - query point\n * @returns {AnyShape[]}\n */\n hit(point) {\n let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);\n let resp = this.index.search(box);\n return resp.filter((shape) => point.on(shape));\n }\n\n /**\n * Returns svg string to draw all shapes in planar set\n * @returns {String}\n */\n svg() {\n let svgcontent = [...this].reduce((acc, shape) => acc + shape.svg(), \"\");\n return svgcontent;\n }\n}\n\nFlatten.PlanarSet = PlanarSet;\n\n/**\n * Base class representing shape\n * Implement common methods of affine transformations\n */\nclass Shape {\n get name() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n get box() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n clone() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * Returns new shape translated by given vector.\n * Translation vector may be also defined by a pair of numbers.\n * @param {Vector | (number, number) } args - Translation vector\n * or tuple of numbers\n * @returns {Shape}\n */\n translate(...args) {\n return this.transform(new Matrix().translate(...args))\n }\n\n /**\n * Returns new shape rotated by given angle around given center point.\n * If center point is omitted, rotates around zero point (0,0).\n * Positive value of angle defines rotation in counterclockwise direction,\n * negative angle defines rotation in clockwise direction\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n * @returns {Shape}\n */\n rotate(angle, center = new Flatten.Point()) {\n return this.transform(new Matrix().rotate(angle, center.x, center.y));\n }\n\n /**\n * Return new shape with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Shape}\n */\n scale(sx, sy) {\n return this.transform(new Matrix().scale(sx, sy));\n }\n\n transform(...args) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return Object.assign({}, this, {name: this.name});\n }\n\n svg(attrs = {}) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n}\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\n/**\n *\n * Class representing a point\n * @type {Point}\n */\nlet Point$1 = class Point extends Shape {\n /**\n * Point may be constructed by two numbers, or by array of two numbers\n * @param {number} x - x-coordinate (float number)\n * @param {number} y - y-coordinate (float number)\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate (float number)\n * @type {number}\n */\n this.y = 0;\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"point\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n if (typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n this.x = args[0];\n this.y = args[1];\n return;\n }\n }\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Returns bounding box of a point\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(this.x, this.y, this.x, this.y);\n }\n\n /**\n * Return new cloned instance of point\n * @returns {Point}\n */\n clone() {\n return new Flatten.Point(this.x, this.y);\n }\n\n get vertices() {\n return [this.clone()];\n }\n\n /**\n * Returns true if points are equal up to [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n equalTo(pt) {\n return Flatten.Utils.EQ(this.x, pt.x) && Flatten.Utils.EQ(this.y, pt.y);\n }\n\n /**\n * Defines predicate \"less than\" between points. Returns true if the point is less than query points, false otherwise
\n * By definition point1 < point2 if {point1.y < point2.y || point1.y == point2.y && point1.x < point2.x
\n * Numeric values compared with [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n lessThan(pt) {\n if (Flatten.Utils.LT(this.y, pt.y))\n return true;\n if (Flatten.Utils.EQ(this.y, pt.y) && Flatten.Utils.LT(this.x, pt.x))\n return true;\n return false;\n }\n\n /**\n * Return new point transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Point}\n */\n transform(m) {\n return new Flatten.Point(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns projection point on given line\n * @param {Line} line Line this point be projected on\n * @returns {Point}\n */\n projectionOn(line) {\n if (this.equalTo(line.pt)) // this point equal to line anchor point\n return this.clone();\n\n let vec = new Flatten.Vector(this, line.pt);\n if (Flatten.Utils.EQ_0(vec.cross(line.norm))) // vector to point from anchor point collinear to normal vector\n return line.pt.clone();\n\n let dist = vec.dot(line.norm); // signed distance\n let proj_vec = line.norm.multiply(dist);\n return this.translate(proj_vec);\n }\n\n /**\n * Returns true if point belongs to the \"left\" semi-plane, which means, point belongs to the same semi plane where line normal vector points to\n * Return false if point belongs to the \"right\" semi-plane or to the line itself\n * @param {Line} line Query line\n * @returns {boolean}\n */\n leftTo(line) {\n let vec = new Flatten.Vector(line.pt, this);\n let onLeftSemiPlane = Flatten.Utils.GT(vec.dot(line.norm), 0);\n return onLeftSemiPlane;\n }\n\n /**\n * Calculate distance and shortest segment from point to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from point to shape\n * @returns {Segment} shortest segment between point and shape (started at point, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Point) {\n let dx = shape.x - this.x;\n let dy = shape.y - this.y;\n return [Math.sqrt(dx * dx + dy * dy), new Flatten.Segment(this, shape)];\n }\n\n if (shape instanceof Flatten.Line) {\n return Flatten.Distance.point2line(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return Flatten.Distance.point2circle(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Distance.point2segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return Flatten.Distance.point2arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return Flatten.Distance.point2polygon(this, shape);\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n return Flatten.Distance.shape2planarSet(this, shape);\n }\n }\n\n /**\n * Returns true if point is on a shape, false otherwise\n * @param {Shape} shape\n * @returns {boolean}\n */\n on(shape) {\n if (shape instanceof Flatten.Point) {\n return this.equalTo(shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Line) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return shape.contains(this)\n }\n\n if (shape instanceof Flatten.Circle) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return shape.contains(this);\n }\n }\n\n get name() {\n return \"point\"\n }\n\n /**\n * Return string to draw point in svg as circle with radius \"r\"
\n * Accept any valid attributes of svg elements as svg object\n * Defaults attribues are:
\n * {\n * r:\"3\",\n * stroke:\"black\",\n * strokeWidth:\"1\",\n * fill:\"red\"\n * }\n * @param {Object} attrs - Any valid attributes of svg circle element, like \"r\", \"stroke\", \"strokeWidth\", \"fill\"\n * @returns {String}\n */\n svg(attrs = {}) {\n const r = attrs.r ?? 3; // default radius - 3\n return `\\n`;\n }\n};\n\nFlatten.Point = Point$1;\n/**\n * Function to create point equivalent to \"new\" constructor\n * @param args\n */\nconst point = (...args) => new Flatten.Point(...args);\nFlatten.point = point;\n\n// export {Point};\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class representing a vector\n * @type {Vector}\n */\nlet Vector$1 = class Vector extends Shape {\n /**\n * Vector may be constructed by two points, or by two float numbers,\n * or by array of two numbers\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate of a vector (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate of a vector (float number)\n * @type {number}\n */\n this.y = 0;\n\n /* return zero vector */\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"vector\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (typeof (a1) == \"number\" && typeof (a2) == \"number\") {\n this.x = a1;\n this.y = a2;\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.x = a2.x - a1.x;\n this.y = a2.y - a1.y;\n return;\n }\n\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Method clone returns new instance of Vector\n * @returns {Vector}\n */\n clone() {\n return new Flatten.Vector(this.x, this.y);\n }\n\n /**\n * Slope of the vector in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let angle = Math.atan2(this.y, this.x);\n if (angle < 0) angle = 2 * Math.PI + angle;\n return angle;\n }\n\n /**\n * Length of vector\n * @returns {number}\n */\n get length() {\n return Math.sqrt(this.dot(this));\n }\n\n /**\n * Returns true if vectors are equal up to [DP_TOL]{@link http://localhost:63342/flatten-js/docs/global.html#DP_TOL}\n * tolerance\n * @param {Vector} v\n * @returns {boolean}\n */\n equalTo(v) {\n return Flatten.Utils.EQ(this.x, v.x) && Flatten.Utils.EQ(this.y, v.y);\n }\n\n /**\n * Returns new vector multiplied by scalar\n * @param {number} scalar\n * @returns {Vector}\n */\n multiply(scalar) {\n return (new Flatten.Vector(scalar * this.x, scalar * this.y));\n }\n\n /**\n * Returns scalar product (dot product) of two vectors
\n * dot_product = (this * v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n dot(v) {\n return (this.x * v.x + this.y * v.y);\n }\n\n /**\n * Returns vector product (cross product) of two vectors
\n * cross_product = (this x v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n cross(v) {\n return (this.x * v.y - this.y * v.x);\n }\n\n /**\n * Returns unit vector.
\n * Throw error if given vector has zero length\n * @returns {Vector}\n */\n normalize() {\n if (!Flatten.Utils.EQ_0(this.length)) {\n return (new Flatten.Vector(this.x / this.length, this.y / this.length));\n }\n throw Errors.ZERO_DIVISION;\n }\n\n /**\n * Returns new vector rotated by given angle,\n * positive angle defines rotation in counterclockwise direction,\n * negative - in clockwise direction\n * Vector only can be rotated around (0,0) point!\n * @param {number} angle - Angle in radians\n * @returns {Vector}\n */\n rotate(angle, center = new Flatten.Point()) {\n if (center.x === 0 && center.y === 0) {\n return this.transform(new Matrix().rotate(angle));\n }\n throw(Errors.OPERATION_IS_NOT_SUPPORTED);\n }\n\n /**\n * Return new vector transformed by affine transformation matrix m\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Vector}\n */\n transform(m) {\n return new Flatten.Vector(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns vector rotated 90 degrees counterclockwise\n * @returns {Vector}\n */\n rotate90CCW() {\n return new Flatten.Vector(-this.y, this.x);\n };\n\n /**\n * Returns vector rotated 90 degrees clockwise\n * @returns {Vector}\n */\n rotate90CW() {\n return new Flatten.Vector(this.y, -this.x);\n };\n\n /**\n * Return inverted vector\n * @returns {Vector}\n */\n invert() {\n return new Flatten.Vector(-this.x, -this.y);\n }\n\n /**\n * Return result of addition of other vector to this vector as a new vector\n * @param {Vector} v Other vector\n * @returns {Vector}\n */\n add(v) {\n return new Flatten.Vector(this.x + v.x, this.y + v.y);\n }\n\n /**\n * Return result of subtraction of other vector from current vector as a new vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n subtract(v) {\n return new Flatten.Vector(this.x - v.x, this.y - v.y);\n }\n\n /**\n * Return angle between this vector and other vector.
\n * Angle is measured from 0 to 2*PI in the counterclockwise direction\n * from current vector to another.\n * @param {Vector} v Another vector\n * @returns {number}\n */\n angleTo(v) {\n let norm1 = this.normalize();\n let norm2 = v.normalize();\n let angle = Math.atan2(norm1.cross(norm2), norm1.dot(norm2));\n if (angle < 0) angle += 2 * Math.PI;\n return angle;\n }\n\n /**\n * Return vector projection of the current vector on another vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n projectionOn(v) {\n let n = v.normalize();\n let d = this.dot(n);\n return n.multiply(d);\n }\n\n get name() {\n return \"vector\"\n }\n};\n\nFlatten.Vector = Vector$1;\n\n/**\n * Function to create vector equivalent to \"new\" constructor\n * @param args\n */\nconst vector$1 = (...args) => new Flatten.Vector(...args);\nFlatten.vector = vector$1;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a segment\n * @type {Segment}\n */\nclass Segment extends Shape {\n /**\n *\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * Start point\n * @type {Point}\n */\n this.ps = new Flatten.Point();\n /**\n * End Point\n * @type {Point}\n */\n this.pe = new Flatten.Point();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 4) {\n let coords = args[0];\n this.ps = new Flatten.Point(coords[0], coords[1]);\n this.pe = new Flatten.Point(coords[2], coords[3]);\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"segment\") {\n let {ps, pe} = args[0];\n this.ps = new Flatten.Point(ps.x, ps.y);\n this.pe = new Flatten.Point(pe.x, pe.y);\n return;\n }\n\n // second point omitted issue #84\n if (args.length === 1 && args[0] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n return;\n }\n\n if (args.length === 2 && args[0] instanceof Flatten.Point && args[1] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n this.pe = args[1].clone();\n return;\n }\n\n if (args.length === 4) {\n this.ps = new Flatten.Point(args[0], args[1]);\n this.pe = new Flatten.Point(args[2], args[3]);\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of segment\n * @returns {Segment}\n */\n clone() {\n return new Flatten.Segment(this.start, this.end);\n }\n\n /**\n * Start point\n * @returns {Point}\n */\n get start() {\n return this.ps;\n }\n\n /**\n * End point\n * @returns {Point}\n */\n get end() {\n return this.pe;\n }\n\n\n /**\n * Returns array of start and end point\n * @returns [Point,Point]\n */\n get vertices() {\n return [this.ps.clone(), this.pe.clone()];\n }\n\n /**\n * Length of a segment\n * @returns {number}\n */\n get length() {\n return this.start.distanceTo(this.end)[0];\n }\n\n /**\n * Slope of the line - angle to axe x in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.slope;\n }\n\n /**\n * Bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Math.min(this.start.x, this.end.x),\n Math.min(this.start.y, this.end.y),\n Math.max(this.start.x, this.end.x),\n Math.max(this.start.y, this.end.y)\n )\n }\n\n /**\n * Returns true if equals to query segment, false otherwise\n * @param {Seg} seg - query segment\n * @returns {boolean}\n */\n equalTo(seg) {\n return this.ps.equalTo(seg.ps) && this.pe.equalTo(seg.pe);\n }\n\n /**\n * Returns true if segment contains point\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n return Flatten.Utils.EQ_0(this.distanceToPoint(pt));\n }\n\n /**\n * Returns array of intersection points between segment and other shape\n * @param {Shape} shape - Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectSegment2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Segment(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectSegment2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectSegment2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectSegment2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectSegment2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from segment to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from segment to shape\n * @returns {Segment} shortest segment between segment and shape (started at segment, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2segment(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.segment2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.segment2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2segment(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Returns unit vector in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.normalize();\n }\n\n /**\n * Return unit vector in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.end, this.start);\n return vec.normalize();\n }\n\n /**\n * Returns new segment with swapped start and end points\n * @returns {Segment}\n */\n reverse() {\n return new Segment(this.end, this.start);\n }\n\n /**\n * When point belongs to segment, return array of two segments split by given point,\n * if point is inside segment. Returns clone of this segment if query point is incident\n * to start or end point of the segment. Returns empty array if point does not belong to segment\n * @param {Point} pt Query point\n * @returns {Segment[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n return [\n new Flatten.Segment(this.start, pt),\n new Flatten.Segment(pt, this.end)\n ]\n }\n\n /**\n * Return middle point of the segment\n * @returns {Point}\n */\n middle() {\n return new Flatten.Point((this.start.x + this.end.x) / 2, (this.start.y + this.end.y) / 2);\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the segment\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length == 0) return this.start;\n if (length == this.length) return this.end;\n let factor = length / this.length;\n return new Flatten.Point(\n (this.end.x - this.start.x) * factor + this.start.x,\n (this.end.y - this.start.y) * factor + this.start.y\n );\n }\n\n distanceToPoint(pt) {\n let [dist, ...rest] = Flatten.Distance.point2segment(pt, this);\n return dist;\n };\n\n definiteIntegral(ymin = 0.0) {\n let dx = this.end.x - this.start.x;\n let dy1 = this.start.y - ymin;\n let dy2 = this.end.y - ymin;\n return (dx * (dy1 + dy2) / 2);\n }\n\n /**\n * Return new segment transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Segment} - transformed segment\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Segment(this.ps.transform(matrix), this.pe.transform(matrix))\n }\n\n /**\n * Returns true if segment start is equal to segment end up to DP_TOL\n * @returns {boolean}\n */\n isZeroLength() {\n return this.ps.equalTo(this.pe)\n }\n\n /**\n * Sort given array of points from segment start to end, assuming all points lay on the segment\n * @param {Point[]} - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let line = new Flatten.Line(this.start, this.end);\n return line.sortPoints(pts);\n }\n\n get name() {\n return \"segment\"\n }\n\n /**\n * Return string to draw segment in svg\n * @param {Object} attrs - an object with attributes for svg path element,\n * like \"stroke\", \"strokeWidth\"
\n * Defaults are stroke:\"black\", strokeWidth:\"1\"\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n}\n\nFlatten.Segment = Segment;\n/**\n * Shortcut method to create new segment\n */\nconst segment = (...args) => new Flatten.Segment(...args);\nFlatten.segment = segment;\n\n/**\n * Created by Alex Bol on 2/20/2017.\n */\n\nlet {vector} = Flatten;\n\n/**\n * Class representing a line\n * @type {Line}\n */\nlet Line$1 = class Line extends Shape {\n /**\n * Line may be constructed by point and normal vector or by two points that a line passes through\n * @param {Point} pt - point that a line passes through\n * @param {Vector|Point} norm - normal vector to a line or second point a line passes through\n */\n constructor(...args) {\n super();\n /**\n * Point a line passes through\n * @type {Point}\n */\n this.pt = new Flatten.Point();\n /**\n * Normal vector to a line
\n * Vector is normalized (length == 1)
\n * Direction of the vector is chosen to satisfy inequality norm * p >= 0\n * @type {Vector}\n */\n this.norm = new Flatten.Vector(0, 1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"line\") {\n let {pt, norm} = args[0];\n this.pt = new Flatten.Point(pt);\n this.norm = new Flatten.Vector(norm);\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.pt = a1;\n this.norm = Line.points2norm(a1, a2);\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Vector) {\n if (Flatten.Utils.EQ_0(a2.x) && Flatten.Utils.EQ_0(a2.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a1.clone();\n this.norm = a2.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Vector && a2 instanceof Flatten.Point) {\n if (Flatten.Utils.EQ_0(a1.x) && Flatten.Utils.EQ_0(a1.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a2.clone();\n this.norm = a1.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of line\n * @returns {Line}\n */\n clone() {\n return new Flatten.Line(this.pt, this.norm);\n }\n\n /* The following methods need for implementation of Edge interface\n /**\n * Line has no start point\n * @returns {undefined}\n */\n get start() {return undefined;}\n\n /**\n * Line has no end point\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns infinite box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Middle point is undefined\n * @returns {undefined}\n */\n get middle() {return undefined}\n\n /**\n * Slope of the line - angle in radians between line and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Get coefficients [A,B,C] of a standard line equation in the form Ax + By = C\n * @code [A, B, C] = line.standard\n * @returns {number[]} - array of coefficients\n */\n get standard() {\n let A = this.norm.x;\n let B = this.norm.y;\n let C = this.norm.dot(vector(this.pt.x, this.pt.y));\n\n return [A, B, C];\n }\n\n /**\n * Return true if parallel or incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n parallelTo(other_line) {\n return Flatten.Utils.EQ_0(this.norm.cross(other_line.norm));\n }\n\n /**\n * Returns true if incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n incidentTo(other_line) {\n return this.parallelTo(other_line) && this.pt.on(other_line);\n }\n\n /**\n * Returns true if point belongs to line\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Line contains point if vector to point is orthogonal to the line normal vector */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec));\n }\n\n /**\n * Return coordinate of the point that lies on the line in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the line and does not check it\n * @param {Point} pt - point on a line\n * @returns {number}\n */\n coord(pt) {\n return vector(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Returns array of intersection points\n * @param {Shape} shape - shape to intersect with\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectLine2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectLine2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectLine2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectLine2Polygon(this, shape);\n }\n\n }\n\n /**\n * Calculate distance and shortest segment from line to shape and returns array [distance, shortest_segment]\n * @param {Shape} shape Shape of the one of the types Point, Circle, Segment, Arc, Polygon\n * @returns {[number, Segment]}\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n }\n\n /**\n * Split line with a point or array of points and return array of shapes\n * Assumed (but not checked) that all points lay on the line\n * @param {Point | Point[]} pt\n * @returns {MultilineShapes}\n */\n split(pt) {\n if (pt instanceof Flatten.Point) {\n return [new Flatten.Ray(pt, this.norm), new Flatten.Ray(pt, this.norm)]\n }\n else {\n let multiline = new Flatten.Multiline([this]);\n let sorted_points = this.sortPoints(pt);\n multiline.split(sorted_points);\n return multiline.toShapes();\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Line(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new line transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Line}\n */\n transform(m) {\n return new Flatten.Line(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n /**\n * Sort given array of points that lay on a line with respect to coordinate on a line\n * The method assumes that points lay on the line and does not check this\n * @param {Point[]} pts - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n return pts.slice().sort( (pt1, pt2) => {\n if (this.coord(pt1) < this.coord(pt2)) {\n return -1;\n }\n if (this.coord(pt1) > this.coord(pt2)) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"line\"\n }\n\n /**\n * Return string to draw svg segment representing line inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg circle element\n */\n svg(box, attrs = {}) {\n let ip = intersectLine2Box(this, box);\n if (ip.length === 0)\n return \"\";\n let ps = ip[0];\n let pe = ip.length === 2 ? ip[1] : ip.find(pt => !pt.equalTo(ps));\n if (pe === undefined) pe = ps;\n let segment = new Flatten.Segment(ps, pe);\n return segment.svg(attrs);\n }\n\n static points2norm(pt1, pt2) {\n if (pt1.equalTo(pt2)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n let vec = new Flatten.Vector(pt1, pt2);\n let unit = vec.normalize();\n return unit.rotate90CCW();\n }\n};\n\nFlatten.Line = Line$1;\n/**\n * Function to create line equivalent to \"new\" constructor\n * @param args\n */\nconst line = (...args) => new Flatten.Line(...args);\nFlatten.line = line;\n\n/**\n * Created by Alex Bol on 3/6/2017.\n */\n\n\n/**\n * Class representing a circle\n * @type {Circle}\n */\nlet Circle$1 = class Circle extends Shape {\n /**\n * Class private property\n * @type {string}\n */\n\n /**\n *\n * @param {Point} pc - circle center point\n * @param {number} r - circle radius\n */\n constructor(...args) {\n super();\n /**\n * Circle center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Circle radius\n * @type {number}\n */\n this.r = 1;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"circle\") {\n let {pc, r} = args[0];\n this.pc = new Flatten.Point(pc);\n this.r = r;\n } else {\n let [pc, r] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n }\n // throw Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of circle\n * @returns {Circle}\n */\n clone() {\n return new Flatten.Circle(this.pc.clone(), this.r);\n }\n\n /**\n * Circle center\n * @returns {Point}\n */\n get center() {\n return this.pc;\n }\n\n /**\n * Circle bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n this.pc.x - this.r,\n this.pc.y - this.r,\n this.pc.x + this.r,\n this.pc.y + this.r\n );\n }\n\n /**\n * Return true if circle contains shape: no point of shape lies outside of the circle\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return Flatten.Utils.LE(shape.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Arc) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.r, this.r) &&\n Flatten.Utils.LE(shape.center.distanceTo(this.center)[0], this.r);\n }\n\n /* TODO: box, polygon */\n }\n\n /**\n * Transform circle to closed arc\n * @param {boolean} counterclockwise\n * @returns {Arc}\n */\n toArc(counterclockwise = true) {\n return new Flatten.Arc(this.center, this.r, Math.PI, -Math.PI, counterclockwise);\n }\n\n /**\n * Method scale is supported only for uniform scaling of the circle with (0,0) center\n * @param {number} sx\n * @param {number} sy\n * @returns {Circle}\n */\n scale(sx, sy) {\n if (sx !== sy)\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n if (!(this.pc.x === 0.0 && this.pc.y === 0.0))\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n return new Flatten.Circle(this.pc, this.r*sx)\n }\n\n /**\n * Return new circle transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Circle}\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Flatten.Circle(this.pc.transform(matrix), this.r)\n }\n\n /**\n * Returns array of intersection points between circle and other shape\n * @param {Shape} shape Shape of the one of supported types\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Circle(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Circle(shape, this);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectCircle2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Circle(shape, this);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectCircle2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from circle to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from circle to shape\n * @returns {Segment} shortest segment between circle and shape (started at circle, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2circle(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n get name() {\n return \"circle\"\n }\n\n /**\n * Return string to draw circle in svg\n * @param {Object} attrs - an object with attributes of svg circle element\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n\n};\n\nFlatten.Circle = Circle$1;\n/**\n * Shortcut to create new circle\n * @param args\n */\nconst circle = (...args) => new Flatten.Circle(...args);\nFlatten.circle = circle;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a circular arc\n * @type {Arc}\n */\nclass Arc extends Shape {\n /**\n *\n * @param {Point} pc - arc center\n * @param {number} r - arc radius\n * @param {number} startAngle - start angle in radians from 0 to 2*PI\n * @param {number} endAngle - end angle in radians from 0 to 2*PI\n * @param {boolean} counterClockwise - arc direction, true - clockwise, false - counterclockwise\n */\n constructor(...args) {\n super();\n /**\n * Arc center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Arc radius\n * @type {number}\n */\n this.r = 1;\n /**\n * Arc start angle in radians\n * @type {number}\n */\n this.startAngle = 0;\n /**\n * Arc end angle in radians\n * @type {number}\n */\n this.endAngle = 2 * Math.PI;\n /**\n * Arc orientation\n * @type {boolean}\n */\n this.counterClockwise = Flatten.CCW;\n\n if (args.length === 0)\n return;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"arc\") {\n let {pc, r, startAngle, endAngle, counterClockwise} = args[0];\n this.pc = new Flatten.Point(pc.x, pc.y);\n this.r = r;\n this.startAngle = startAngle;\n this.endAngle = endAngle;\n this.counterClockwise = counterClockwise;\n } else {\n let [pc, r, startAngle, endAngle, counterClockwise] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n if (startAngle !== undefined) this.startAngle = startAngle;\n if (endAngle !== undefined) this.endAngle = endAngle;\n if (counterClockwise !== undefined) this.counterClockwise = counterClockwise;\n }\n\n // throw Flatten.Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of arc\n * @returns {Arc}\n */\n clone() {\n return new Flatten.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n\n /**\n * Get sweep angle in radians. Sweep angle is non-negative number from 0 to 2*PI\n * @returns {number}\n */\n get sweep() {\n if (Flatten.Utils.EQ(this.startAngle, this.endAngle))\n return 0.0;\n if (Flatten.Utils.EQ(Math.abs(this.startAngle - this.endAngle), Flatten.PIx2)) {\n return Flatten.PIx2;\n }\n let sweep;\n if (this.counterClockwise) {\n sweep = Flatten.Utils.GT(this.endAngle, this.startAngle) ?\n this.endAngle - this.startAngle : this.endAngle - this.startAngle + Flatten.PIx2;\n } else {\n sweep = Flatten.Utils.GT(this.startAngle, this.endAngle) ?\n this.startAngle - this.endAngle : this.startAngle - this.endAngle + Flatten.PIx2;\n }\n\n if (Flatten.Utils.GT(sweep, Flatten.PIx2)) {\n sweep -= Flatten.PIx2;\n }\n if (Flatten.Utils.LT(sweep, 0)) {\n sweep += Flatten.PIx2;\n }\n return sweep;\n }\n\n /**\n * Get start point of arc\n * @returns {Point}\n */\n get start() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.startAngle, this.pc);\n }\n\n /**\n * Get end point of arc\n * @returns {Point}\n */\n get end() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.endAngle, this.pc);\n }\n\n /**\n * Get center of arc\n * @returns {Point}\n */\n get center() {\n return this.pc.clone();\n }\n\n get vertices() {\n return [this.start.clone(), this.end.clone()];\n }\n\n /**\n * Get arc length\n * @returns {number}\n */\n get length() {\n return Math.abs(this.sweep * this.r);\n }\n\n /**\n * Get bounding box of the arc\n * @returns {Box}\n */\n get box() {\n let func_arcs = this.breakToFunctional();\n let box = func_arcs.reduce((acc, arc) => acc.merge(arc.start.box), new Flatten.Box());\n box = box.merge(this.end.box);\n return box;\n }\n\n /**\n * Returns true if arc contains point, false otherwise\n * @param {Point} pt - point to test\n * @returns {boolean}\n */\n contains(pt) {\n // first check if point on circle (pc,r)\n if (!Flatten.Utils.EQ(this.pc.distanceTo(pt)[0], this.r))\n return false;\n\n // point on circle\n\n if (pt.equalTo(this.start))\n return true;\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n let test_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise);\n return Flatten.Utils.LE(test_arc.length, this.length);\n }\n\n /**\n * When given point belongs to arc, return array of two arcs split by this point. If points is incident\n * to start or end point of the arc, return clone of the arc. If point does not belong to the arcs, return\n * empty array.\n * @param {Point} pt Query point\n * @returns {Arc[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n\n return [\n new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise),\n new Flatten.Arc(this.pc, this.r, angle, this.endAngle, this.counterClockwise)\n ]\n }\n\n /**\n * Return middle point of the arc\n * @returns {Point}\n */\n middle() {\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep / 2 : this.startAngle - this.sweep / 2;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the arc\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length === 0) return this.start;\n if (length === this.length) return this.end;\n let factor = length / this.length;\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep * factor : this.startAngle - this.sweep * factor;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Returns chord height (\"sagitta\") of the arc\n * @returns {number}\n */\n chordHeight() {\n return (1.0 - Math.cos(Math.abs(this.sweep / 2.0))) * this.r;\n }\n\n /**\n * Returns array of intersection points between arc and other shape\n * @param {Shape} shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Arc(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Arc(shape, this);\n }\n if (shape instanceof Flatten.Circle) {\n return intersectArc2Circle(this, shape);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Arc(shape, this);\n }\n if (shape instanceof Flatten.Box) {\n return intersectArc2Box(this, shape);\n }\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Arc(this, shape);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectArc2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from arc to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from arc to shape\n * @returns {Segment} shortest segment between arc and shape (started at arc, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.arc2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.arc2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.arc2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Breaks arc in extreme point 0, pi/2, pi, 3*pi/2 and returns array of sub-arcs\n * @returns {Arc[]}\n */\n breakToFunctional() {\n let func_arcs_array = [];\n let angles = [0, Math.PI / 2, 2 * Math.PI / 2, 3 * Math.PI / 2];\n let pts = [\n this.pc.translate(this.r, 0),\n this.pc.translate(0, this.r),\n this.pc.translate(-this.r, 0),\n this.pc.translate(0, -this.r)\n ];\n\n // If arc contains extreme point,\n // create test arc started at start point and ended at this extreme point\n let test_arcs = [];\n for (let i = 0; i < 4; i++) {\n if (pts[i].on(this)) {\n test_arcs.push(new Flatten.Arc(this.pc, this.r, this.startAngle, angles[i], this.counterClockwise));\n }\n }\n\n if (test_arcs.length === 0) { // arc does contain any extreme point\n func_arcs_array.push(this.clone());\n } else { // arc passes extreme point\n // sort these arcs by length\n test_arcs.sort((arc1, arc2) => arc1.length - arc2.length);\n\n for (let i = 0; i < test_arcs.length; i++) {\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, test_arcs[i].endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, test_arcs[i].endAngle, this.counterClockwise);\n }\n if (!Flatten.Utils.EQ_0(new_arc.length)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n\n // add last sub arc\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, this.endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n // It could be 2*PI when occasionally start = 0 and end = 2*PI but this is not valid for breakToFunctional\n if (!Flatten.Utils.EQ_0(new_arc.length) && !Flatten.Utils.EQ(new_arc.sweep, 2*Math.PI)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n return func_arcs_array;\n }\n\n /**\n * Return tangent unit vector in the start point in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.pc, this.start);\n let angle = this.counterClockwise ? Math.PI / 2. : -Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Return tangent unit vector in the end point in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.pc, this.end);\n let angle = this.counterClockwise ? -Math.PI / 2. : Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Returns new arc with swapped start and end angles and reversed direction\n * @returns {Arc}\n */\n reverse() {\n return new Flatten.Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise);\n }\n\n /**\n * Return new arc transformed using affine transformation matrix
\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Arc}\n */\n transform(matrix = new Flatten.Matrix()) {\n let newStart = this.start.transform(matrix);\n let newEnd = this.end.transform(matrix);\n let newCenter = this.pc.transform(matrix);\n let newDirection = this.counterClockwise;\n if (matrix.a * matrix.d < 0) {\n newDirection = !newDirection;\n }\n return Flatten.Arc.arcSE(newCenter, newStart, newEnd, newDirection);\n }\n\n static arcSE(center, start, end, counterClockwise) {\n let {vector} = Flatten;\n let startAngle = vector(center, start).slope;\n let endAngle = vector(center, end).slope;\n if (Flatten.Utils.EQ(startAngle, endAngle)) {\n endAngle += 2 * Math.PI;\n counterClockwise = true;\n }\n let r = vector(center, start).length;\n\n return new Flatten.Arc(center, r, startAngle, endAngle, counterClockwise);\n }\n\n definiteIntegral(ymin = 0) {\n let f_arcs = this.breakToFunctional();\n let area = f_arcs.reduce((acc, arc) => acc + arc.circularSegmentDefiniteIntegral(ymin), 0.0);\n return area;\n }\n\n circularSegmentDefiniteIntegral(ymin) {\n let line = new Flatten.Line(this.start, this.end);\n let onLeftSide = this.pc.leftTo(line);\n let segment = new Flatten.Segment(this.start, this.end);\n let areaTrapez = segment.definiteIntegral(ymin);\n let areaCircularSegment = this.circularSegmentArea();\n let area = onLeftSide ? areaTrapez - areaCircularSegment : areaTrapez + areaCircularSegment;\n return area;\n }\n\n circularSegmentArea() {\n return (0.5 * this.r * this.r * (this.sweep - Math.sin(this.sweep)))\n }\n\n /**\n * Sort given array of points from arc start to end, assuming all points lay on the arc\n * @param {Point[]} pts array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let {vector} = Flatten;\n return pts.slice().sort( (pt1, pt2) => {\n let slope1 = vector(this.pc, pt1).slope;\n let slope2 = vector(this.pc, pt2).slope;\n if (slope1 < slope2) {\n return -1;\n }\n if (slope1 > slope2) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"arc\"\n }\n\n /**\n * Return string to draw arc in svg\n * @param {Object} attrs - an object with attributes of svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let largeArcFlag = this.sweep <= Math.PI ? \"0\" : \"1\";\n let sweepFlag = this.counterClockwise ? \"1\" : \"0\";\n\n if (Flatten.Utils.EQ(this.sweep, 2 * Math.PI)) {\n let circle = new Flatten.Circle(this.pc, this.r);\n return circle.svg(attrs);\n } else {\n return `\\n`\n }\n }\n\n}\n\nFlatten.Arc = Arc;\n/**\n * Function to create arc equivalent to \"new\" constructor\n * @param args\n */\nconst arc = (...args) => new Flatten.Arc(...args);\nFlatten.arc = arc;\n\n/**\n * Created by Alex Bol on 3/7/2017.\n */\n\n/**\n * Class Box represents bounding box of the shape.\n * It may also represent axis-aligned rectangle\n * @type {Box}\n */\nclass Box extends Shape {\n /**\n *\n * @param {number} xmin - minimal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n constructor(xmin = undefined, ymin = undefined, xmax = undefined, ymax = undefined) {\n super();\n /**\n * Minimal x coordinate\n * @type {number}\n */\n this.xmin = xmin;\n /**\n * Minimal y coordinate\n * @type {number}\n */\n this.ymin = ymin;\n /**\n * Maximal x coordinate\n * @type {number}\n */\n this.xmax = xmax;\n /**\n * Maximal y coordinate\n * @type {number}\n */\n this.ymax = ymax;\n }\n\n /**\n * Return new cloned instance of box\n * @returns {Box}\n */\n clone() {\n return new Box(this.xmin, this.ymin, this.xmax, this.ymax);\n }\n\n /**\n * Property low need for interval tree interface\n * @returns {Point}\n */\n get low() {\n return new Flatten.Point(this.xmin, this.ymin);\n }\n\n /**\n * Property high need for interval tree interface\n * @returns {Point}\n */\n get high() {\n return new Flatten.Point(this.xmax, this.ymax);\n }\n\n /**\n * Property max returns the box itself !\n * @returns {Box}\n */\n get max() {\n return this.clone();\n }\n \n /**\n * Return center of the box\n * @returns {Point}\n */\n get center() {\n return new Flatten.Point((this.xmin + this.xmax) / 2, (this.ymin + this.ymax) / 2);\n }\n\n /**\n * Return the width of the box\n * @returns {number}\n */\n get width() {\n return Math.abs(this.xmax - this.xmin);\n }\n\n /**\n * Return the height of the box\n * @returns {number}\n */\n get height() {\n return Math.abs(this.ymax - this.ymin);\n }\n \n /**\n * Return property box like all other shapes\n * @returns {Box}\n */\n get box() {\n return this.clone();\n }\n\n /**\n * Returns true if not intersected with other box\n * @param {Box} other_box - other box to test\n * @returns {boolean}\n */\n not_intersect(other_box) {\n return (\n this.xmax < other_box.xmin ||\n this.xmin > other_box.xmax ||\n this.ymax < other_box.ymin ||\n this.ymin > other_box.ymax\n );\n }\n\n /**\n * Returns true if intersected with other box\n * @param {Box} other_box - Query box\n * @returns {boolean}\n */\n intersect(other_box) {\n return !this.not_intersect(other_box);\n }\n\n /**\n * Returns new box merged with other box\n * @param {Box} other_box - Other box to merge with\n * @returns {Box}\n */\n merge(other_box) {\n return new Box(\n this.xmin === undefined ? other_box.xmin : Math.min(this.xmin, other_box.xmin),\n this.ymin === undefined ? other_box.ymin : Math.min(this.ymin, other_box.ymin),\n this.xmax === undefined ? other_box.xmax : Math.max(this.xmax, other_box.xmax),\n this.ymax === undefined ? other_box.ymax : Math.max(this.ymax, other_box.ymax)\n );\n }\n\n /**\n * Defines predicate \"less than\" between two boxes. Need for interval index\n * @param {Box} other_box - other box\n * @returns {boolean} - true if this box less than other box, false otherwise\n */\n less_than(other_box) {\n if (this.low.lessThan(other_box.low))\n return true;\n if (this.low.equalTo(other_box.low) && this.high.lessThan(other_box.high))\n return true;\n return false;\n }\n\n /**\n * Returns true if this box is equal to other box, false otherwise\n * @param {Box} other_box - query box\n * @returns {boolean}\n */\n equal_to(other_box) {\n return (this.low.equalTo(other_box.low) && this.high.equalTo(other_box.high));\n }\n\n output() {\n return this.clone();\n }\n\n static comparable_max(box1, box2) {\n // return pt1.lessThan(pt2) ? pt2.clone() : pt1.clone();\n return box1.merge(box2);\n }\n\n static comparable_less_than(pt1, pt2) {\n return pt1.lessThan(pt2);\n }\n\n /**\n * Set new values to the box object\n * @param {number} xmin - mininal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n set(xmin, ymin, xmax, ymax) {\n this.xmin = xmin;\n this.ymin = ymin;\n this.xmax = xmax;\n this.ymax = ymax;\n }\n\n /**\n * Transform box into array of points from low left corner in counterclockwise\n * @returns {Point[]}\n */\n toPoints() {\n return [\n new Flatten.Point(this.xmin, this.ymin),\n new Flatten.Point(this.xmax, this.ymin),\n new Flatten.Point(this.xmax, this.ymax),\n new Flatten.Point(this.xmin, this.ymax)\n ];\n }\n\n /**\n * Transform box into array of segments from low left corner in counterclockwise\n * @returns {Segment[]}\n */\n toSegments() {\n let pts = this.toPoints();\n return [\n new Flatten.Segment(pts[0], pts[1]),\n new Flatten.Segment(pts[1], pts[2]),\n new Flatten.Segment(pts[2], pts[3]),\n new Flatten.Segment(pts[3], pts[0])\n ];\n }\n\n /**\n * Box rotation is not supported\n * Attempt to rotate box throws error\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n */\n rotate(angle, center = new Flatten.Point()) {\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n }\n\n /**\n * Return new box transformed using affine transformation matrix\n * New box is a bounding box of transformed corner points\n * @param {Matrix} m - affine transformation matrix\n * @returns {Box}\n */\n transform(m = new Flatten.Matrix()) {\n const transformed_points = this.toPoints().map(pt => pt.transform(m));\n return transformed_points.reduce(\n (new_box, pt) => new_box.merge(pt.box), new Box())\n }\n\n /**\n * Return true if box contains shape: no point of shape lies outside the box\n * @param {AnyShape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.vertices.every(vertex => this.contains(vertex))\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.toSegments().every(segment => this.contains(segment))\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.contains(shape.box)\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.vertices.every(vertex => this.contains(vertex)) &&\n shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)\n }\n\n if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {\n return false\n }\n\n if (shape instanceof Flatten.Multiline) {\n return shape.toShapes().every(shape => this.contains(shape))\n }\n\n if (shape instanceof Flatten.Polygon) {\n return this.contains(shape.box)\n }\n }\n\n get name() {\n return \"box\"\n }\n\n /**\n * Return string to draw box in svg\n * @param {Object} attrs - an object with attributes of svg rectangle element\n * @returns {string}\n */\n svg(attrs = {}) {\n const width = this.xmax - this.xmin;\n const height = this.ymax - this.ymin;\n return `\\n`;\n };\n}\n\nFlatten.Box = Box;\n/**\n * Shortcut to create new box\n * @param args\n * @returns {Box}\n */\nconst box = (...args) => new Flatten.Box(...args);\nFlatten.box = box;\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing an edge of polygon. Edge shape may be Segment or Arc.\n * Each edge contains references to the next and previous edges in the face of the polygon.\n *\n * @type {Edge}\n */\nclass Edge {\n /**\n * Construct new instance of edge\n * @param {Shape} shape Shape of type Segment or Arc\n */\n constructor(shape) {\n /**\n * Shape of the edge: Segment or Arc\n * @type {Segment|Arc}\n */\n this.shape = shape;\n /**\n * Pointer to the next edge in the face\n * @type {Edge}\n */\n this.next = undefined;\n /**\n * Pointer to the previous edge in the face\n * @type {Edge}\n */\n this.prev = undefined;\n /**\n * Pointer to the face containing this edge\n * @type {Face}\n */\n this.face = undefined;\n /**\n * \"Arc distance\" from the face start\n * @type {number}\n */\n this.arc_length = 0;\n /**\n * Start inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvStart = undefined;\n /**\n * End inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvEnd = undefined;\n /**\n * Edge inclusion flag (Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY)\n * @type {*}\n */\n this.bv = undefined;\n /**\n * Overlap flag for boundary edge (Flatten.OVERLAP_SAME/Flatten.OVERLAP_OPPOSITE)\n * @type {*}\n */\n this.overlap = undefined;\n }\n\n /**\n * Get edge start point\n */\n get start() {\n return this.shape.start;\n }\n\n /**\n * Get edge end point\n */\n get end() {\n return this.shape.end;\n }\n\n /**\n * Get edge length\n */\n get length() {\n return this.shape.length;\n }\n\n /**\n * Get bounding box of the edge\n * @returns {Box}\n */\n get box() {\n return this.shape.box;\n }\n\n get isSegment() {\n return this.shape instanceof Flatten.Segment;\n }\n\n get isArc() {\n return this.shape instanceof Flatten.Arc;\n }\n\n get isLine() {\n return this.shape instanceof Flatten.Line;\n }\n\n get isRay() {\n return this.shape instanceof Flatten.Ray\n }\n\n /**\n * Get middle point of the edge\n * @returns {Point}\n */\n middle() {\n return this.shape.middle();\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the edge\n * @returns {Point}\n */\n pointAtLength(length) {\n return this.shape.pointAtLength(length);\n }\n\n /**\n * Returns true if point belongs to the edge, false otherwise\n * @param {Point} pt - test point\n */\n contains(pt) {\n return this.shape.contains(pt);\n }\n\n /**\n * Set inclusion flag of the edge with respect to another polygon\n * Inclusion flag is one of Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY\n * @param polygon\n */\n setInclusion(polygon) {\n if (this.bv !== undefined) return this.bv;\n\n if (this.shape instanceof Flatten.Line || this.shape instanceof Flatten.Ray) {\n this.bv = Flatten.OUTSIDE;\n return this.bv;\n }\n\n if (this.bvStart === undefined) {\n this.bvStart = ray_shoot(polygon, this.start);\n }\n if (this.bvEnd === undefined) {\n this.bvEnd = ray_shoot(polygon, this.end);\n }\n /* At least one end outside - the whole edge outside */\n if (this.bvStart === Flatten.OUTSIDE || this.bvEnd == Flatten.OUTSIDE) {\n this.bv = Flatten.OUTSIDE;\n }\n /* At least one end inside - the whole edge inside */\n else if (this.bvStart === Flatten.INSIDE || this.bvEnd == Flatten.INSIDE) {\n this.bv = Flatten.INSIDE;\n }\n /* Both are boundary - check the middle point */\n else {\n let bvMiddle = ray_shoot(polygon, this.middle());\n // let boundary = this.middle().distanceTo(polygon)[0] < 10*Flatten.DP_TOL;\n // let bvMiddle = boundary ? Flatten.BOUNDARY : ray_shoot(polygon, this.middle());\n this.bv = bvMiddle;\n }\n return this.bv;\n }\n\n /**\n * Set overlapping between two coincident boundary edges\n * Overlapping flag is one of Flatten.OVERLAP_SAME or Flatten.OVERLAP_OPPOSITE\n * @param edge\n */\n setOverlap(edge) {\n let flag = undefined;\n let shape1 = this.shape;\n let shape2 = edge.shape;\n\n if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end)) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start)) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Arc) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && /*shape1.counterClockwise === shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && /*shape1.counterClockwise !== shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Arc ||\n shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n }\n\n /* Do not update overlap flag if already set on previous chain */\n if (this.overlap === undefined) this.overlap = flag;\n if (edge.overlap === undefined) edge.overlap = flag;\n }\n\n svg() {\n if (this.shape instanceof Flatten.Segment) {\n return ` L${this.shape.end.x},${this.shape.end.y}`;\n } else if (this.shape instanceof Flatten.Arc) {\n let arc = this.shape;\n let largeArcFlag;\n let sweepFlag = arc.counterClockwise ? \"1\" : \"0\";\n\n // Draw full circe arc as special case: split it into two half-circles\n if (Flatten.Utils.EQ(arc.sweep, 2 * Math.PI)) {\n let sign = arc.counterClockwise ? 1 : -1;\n let halfArc1 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle, arc.startAngle + sign * Math.PI, arc.counterClockwise);\n let halfArc2 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle + sign * Math.PI, arc.endAngle, arc.counterClockwise);\n\n largeArcFlag = \"0\";\n\n return ` A${halfArc1.r},${halfArc1.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc1.end.x},${halfArc1.end.y}\n A${halfArc2.r},${halfArc2.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc2.end.x},${halfArc2.end.y}`\n } else {\n largeArcFlag = arc.sweep <= Math.PI ? \"0\" : \"1\";\n\n return ` A${arc.r},${arc.r} 0 ${largeArcFlag},${sweepFlag} ${arc.end.x},${arc.end.y}`;\n }\n }\n }\n\n toJSON() {\n return this.shape.toJSON();\n }\n}\nFlatten.Edge = Edge;\n\n/**\n * Class implements circular bidirectional linked list
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass CircularLinkedList extends LinkedList {\n constructor(first, last) {\n super(first, last);\n this.setCircularLinks();\n }\n\n setCircularLinks() {\n if (this.isEmpty()) return;\n this.last.next = this.first;\n this.first.prev = this.last;\n }\n\n [Symbol.iterator]() {\n let element = undefined;\n return {\n next: () => {\n let value = element ? element : this.first;\n let done = this.first ? (element ? element === this.first : false) : true;\n element = value ? value.next : undefined;\n return {value: value, done: done};\n }\n };\n };\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element - new element to be appended\n * @returns {CircularLinkedList}\n */\n append(element) {\n super.append(element);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement - new element to be inserted\n * @param {LinkedListElement} elementBefore - element in the list to insert after it\n * @returns {CircularLinkedList}\n */\n insert(newElement, elementBefore) {\n super.insert(newElement, elementBefore);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element - element to be removed from the list\n * @returns {CircularLinkedList}\n */\n remove(element) {\n super.remove(element);\n // this.setCircularLinks();\n return this;\n }\n}\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing a face (closed loop) in a [polygon]{@link Flatten.Polygon} object.\n * Face is a circular bidirectional linked list of [edges]{@link Flatten.Edge}.\n * Face object cannot be instantiated with a constructor.\n * Instead, use [polygon.addFace()]{@link Flatten.Polygon#addFace} method.\n *
\n * Note, that face only set entry point to the linked list of edges but does not contain edges by itself.\n * Container of edges is a property of the polygon object.
\n *\n * @example\n * // Face implements \"next\" iterator which enables to iterate edges in for loop:\n * for (let edge of face) {\n * console.log(edge.shape.length) // do something\n * }\n *\n * // Instead, it is possible to iterate edges as linked list, starting from face.first:\n * let edge = face.first;\n * do {\n * console.log(edge.shape.length); // do something\n * edge = edge.next;\n * } while (edge != face.first)\n */\nclass Face extends CircularLinkedList {\n constructor(polygon, ...args) {\n super(); // construct empty list of edges\n /**\n * Reference to the first edge in face\n */\n // this.first;\n /**\n * Reference to the last edge in face\n */\n // this.last;\n\n this._box = undefined; // new Box();\n this._orientation = undefined;\n\n if (args.length === 0) {\n return;\n }\n\n /* If passed an array it supposed to be:\n 1) array of shapes that performs close loop or\n 2) array of points that performs set of vertices\n */\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n // let argsArray = args[0];\n let shapes = args[0]; // argsArray[0];\n if (shapes.length === 0)\n return;\n\n /* array of Flatten.Points */\n if (shapes.every((shape) => {return shape instanceof Flatten.Point})) {\n let segments = Face.points2segments(shapes);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of points as pairs of numbers */\n else if (shapes.every((shape) => {return shape instanceof Array && shape.length === 2})) {\n let points = shapes.map((shape) => new Flatten.Point(shape[0],shape[1]));\n let segments = Face.points2segments(points);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of segments ot arcs */\n else if (shapes.every((shape) => {\n return (shape instanceof Flatten.Segment || shape instanceof Flatten.Arc)\n })) {\n this.shapes2face(polygon.edges, shapes);\n }\n // this is from JSON.parse object\n else if (shapes.every((shape) => {\n return (shape.name === \"segment\" || shape.name === \"arc\")\n })) {\n let flattenShapes = [];\n for (let shape of shapes) {\n let flattenShape;\n if (shape.name === \"segment\") {\n flattenShape = new Flatten.Segment(shape);\n } else {\n flattenShape = new Flatten.Arc(shape);\n }\n flattenShapes.push(flattenShape);\n }\n this.shapes2face(polygon.edges, flattenShapes);\n }\n }\n /* Create new face and copy edges into polygon.edges set */\n else if (args[0] instanceof Face) {\n let face = args[0];\n this.first = face.first;\n this.last = face.last;\n for (let edge of face) {\n polygon.edges.add(edge);\n }\n }\n /* Instantiate face from a circle in CCW orientation */\n else if (args[0] instanceof Flatten.Circle) {\n this.shapes2face(polygon.edges, [args[0].toArc(CCW)]);\n }\n /* Instantiate face from a box in CCW orientation */\n else if (args[0] instanceof Flatten.Box) {\n let box = args[0];\n this.shapes2face(polygon.edges, [\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymin), new Flatten.Point(box.xmax, box.ymin)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymin), new Flatten.Point(box.xmax, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymax), new Flatten.Point(box.xmin, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymax), new Flatten.Point(box.xmin, box.ymin))\n ]);\n }\n }\n /* If passed two edges, consider them as start and end of the face loop */\n /* THIS METHOD WILL BE USED BY BOOLEAN OPERATIONS */\n /* Assume that edges already copied to polygon.edges set in the clip algorithm !!! */\n if (args.length === 2 && args[0] instanceof Flatten.Edge && args[1] instanceof Flatten.Edge) {\n this.first = args[0]; // first edge in face or undefined\n this.last = args[1]; // last edge in face or undefined\n this.last.next = this.first;\n this.first.prev = this.last;\n\n // set arc length\n this.setArcLength();\n\n // this.box = this.getBox();\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n }\n\n /**\n * Return array of edges from first to last\n * @returns {Array}\n */\n get edges() {\n return this.toArray();\n }\n\n /**\n * Return array of shapes which comprise face\n * @returns {Array}\n */\n get shapes() {\n return this.edges.map(edge => edge.shape.clone());\n }\n\n /**\n * Return bounding box of the face\n * @returns {Box}\n */\n get box() {\n if (this._box === undefined) {\n let box = new Flatten.Box();\n for (let edge of this) {\n box = box.merge(edge.box);\n }\n this._box = box;\n }\n return this._box;\n }\n\n /**\n * Get all edges length\n * @returns {number}\n */\n get perimeter() {\n return this.last.arc_length + this.last.length\n }\n\n /**\n * Get point on face boundary at given length\n * @param {number} length - The length along the face boundary\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.perimeter || length < 0) return null;\n let point = null;\n for (let edge of this) {\n if (length >= edge.arc_length &&\n (edge === this.last || length < edge.next.arc_length)) {\n point = edge.pointAtLength(length - edge.arc_length);\n break;\n }\n }\n return point;\n }\n\n static points2segments(points) {\n let segments = [];\n for (let i = 0; i < points.length; i++) {\n // skip zero length segment\n if (points[i].equalTo(points[(i + 1) % points.length]))\n continue;\n segments.push(new Flatten.Segment(points[i], points[(i + 1) % points.length]));\n }\n return segments;\n }\n\n shapes2face(edges, shapes) {\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n // this.box = this.box.merge(shape.box);\n edges.add(edge);\n }\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n\n /**\n * Append edge after the last edge of the face (and before the first edge).
\n * @param {Edge} edge - Edge to be appended to the linked list\n * @returns {Face}\n */\n append(edge) {\n super.append(edge);\n // set arc length\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n // edges.add(edge); // Add new edges into edges container\n return this;\n }\n\n /**\n * Insert edge newEdge into the linked list after the edge edgeBefore
\n * @param {Edge} newEdge - Edge to be inserted into linked list\n * @param {Edge} edgeBefore - Edge to insert newEdge after it\n * @returns {Face}\n */\n insert(newEdge, edgeBefore) {\n super.insert(newEdge, edgeBefore);\n // set arc length\n this.setOneEdgeArcLength(newEdge);\n newEdge.face = this;\n return this;\n }\n\n /**\n * Remove the given edge from the linked list of the face
\n * @param {Edge} edge - Edge to be removed\n * @returns {Face}\n */\n remove(edge) {\n super.remove(edge);\n // Recalculate arc length\n this.setArcLength();\n return this;\n }\n\n /**\n * Merge current edge with the next edge. Given edge will be extended,\n * next edge after it will be removed. The distortion of the polygon\n * is on the responsibility of the user of this method\n * @param {Edge} edge - edge to be extended\n * @returns {Face}\n */\n merge_with_next_edge(edge) {\n edge.shape.end.x = edge.next.shape.end.x;\n edge.shape.end.y = edge.next.shape.end.y;\n this.remove(edge.next);\n return this;\n }\n\n /**\n * Reverse orientation of the face: first edge become last and vice a verse,\n * all edges starts and ends swapped, direction of arcs inverted. If face was oriented\n * clockwise, it becomes counterclockwise and vice versa\n */\n reverse() {\n // collect edges in revert order with reverted shapes\n let edges = [];\n let edge_tmp = this.last;\n do {\n // reverse shape\n edge_tmp.shape = edge_tmp.shape.reverse();\n edges.push(edge_tmp);\n edge_tmp = edge_tmp.prev;\n } while (edge_tmp !== this.last);\n\n // restore linked list\n this.first = undefined;\n this.last = undefined;\n for (let edge of edges) {\n if (this.first === undefined) {\n edge.prev = edge;\n edge.next = edge;\n this.first = edge;\n this.last = edge;\n } else {\n // append to end\n edge.prev = this.last;\n this.last.next = edge;\n\n // update edge to be last\n this.last = edge;\n\n // restore circular links\n this.last.next = this.first;\n this.first.prev = this.last;\n\n }\n // set arc length\n this.setOneEdgeArcLength(edge);\n }\n\n // Recalculate orientation, if set\n if (this._orientation !== undefined) {\n this._orientation = undefined;\n this._orientation = this.orientation();\n }\n }\n\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Returns the absolute value of the area of the face\n * @returns {number}\n */\n area() {\n return Math.abs(this.signedArea());\n }\n\n /**\n * Returns signed area of the simple face.\n * Face is simple if it has no self intersections that change its orientation.\n * Then the area will be positive if the orientation of the face is clockwise,\n * and negative if orientation is counterclockwise.\n * It may be zero if polygon is degenerated.\n * @returns {number}\n */\n signedArea() {\n let sArea = 0;\n let ymin = this.box.ymin;\n for (let edge of this) {\n sArea += edge.shape.definiteIntegral(ymin);\n }\n return sArea;\n }\n\n /**\n * Return face orientation: one of Flatten.ORIENTATION.CCW, Flatten.ORIENTATION.CW, Flatten.ORIENTATION.NOT_ORIENTABLE
\n * According to Green theorem the area of a closed curve may be calculated as double integral,\n * and the sign of the integral will be defined by the direction of the curve.\n * When the integral (\"signed area\") will be negative, direction is counterclockwise,\n * when positive - clockwise and when it is zero, polygon is not orientable.\n * See {@link https://mathinsight.org/greens_theorem_find_area}\n * @returns {number}\n */\n orientation() {\n if (this._orientation === undefined) {\n let area = this.signedArea();\n if (Flatten.Utils.EQ_0(area)) {\n this._orientation = ORIENTATION.NOT_ORIENTABLE;\n } else if (Flatten.Utils.LT(area, 0)) {\n this._orientation = ORIENTATION.CCW;\n } else {\n this._orientation = ORIENTATION.CW;\n }\n }\n return this._orientation;\n }\n\n /**\n * Returns true if face of the polygon is simple (no self-intersection points found)\n * NOTE: this method is incomplete because it does not exclude touching points.\n * Self intersection test should check if polygon change orientation in the test point.\n * @param {PlanarSet} edges - reference to polygon edges to provide search index\n * @returns {boolean}\n */\n isSimple(edges) {\n let ip = Face.getSelfIntersections(this, edges, true);\n return ip.length === 0;\n }\n\n static getSelfIntersections(face, edges, exitOnFirst = false) {\n let int_points = [];\n\n // calculate intersections\n for (let edge1 of face) {\n\n // request edges of polygon in the box of edge1\n let resp = edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // Skip itself\n if (edge1 === edge2)\n continue;\n\n // Skip is edge2 belongs to another face\n if (edge2.face !== face)\n continue;\n\n // Skip next and previous edge if both are segment (if one of them arc - calc intersection)\n if (edge1.shape instanceof Flatten.Segment && edge2.shape instanceof Flatten.Segment &&\n (edge1.next === edge2 || edge1.prev === edge2))\n continue;\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n\n // skip start-end connections\n if (pt.equalTo(edge1.start) && pt.equalTo(edge2.end) && edge2 === edge1.prev)\n continue;\n if (pt.equalTo(edge1.end) && pt.equalTo(edge2.start) && edge2 === edge1.next)\n continue;\n\n int_points.push(pt);\n\n if (exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n\n }\n return int_points;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt - test point\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (pt.equalTo(edge.shape.start)) continue\n if (pt.equalTo(edge.shape.end) || edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new polygon created from one face\n * @returns {Polygon}\n */\n toPolygon() {\n return new Flatten.Polygon(this.shapes);\n }\n\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Returns string to be assigned to \"d\" attribute inside defined \"path\"\n * @returns {string}\n */\n svg() {\n let svgStr = `\\nM${this.first.start.x},${this.first.start.y}`;\n for (let edge of this) {\n svgStr += edge.svg();\n }\n svgStr += ` z`;\n return svgStr;\n }\n\n}\n\nFlatten.Face = Face;\n\n/**\n * Class representing a ray (a half-infinite line).\n * @type {Ray}\n */\nclass Ray extends Shape {\n /**\n * Ray may be constructed by setting an origin point and a normal vector, so that any point x\n * on a ray fit an equation:
\n * (x - origin) * vector = 0
\n * Ray defined by constructor is a right semi-infinite line with respect to the normal vector
\n * If normal vector is omitted ray is considered horizontal (normal vector is (0,1)).
\n * Don't be confused: direction of the normal vector is orthogonal to the ray
\n * @param {Point} pt - start point\n * @param {Vector} norm - normal vector\n */\n constructor(...args) {\n super();\n this.pt = new Flatten.Point();\n this.norm = new Flatten.Vector(0,1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length >= 1 && args[0] instanceof Flatten.Point) {\n this.pt = args[0].clone();\n }\n\n if (args.length === 1) {\n return;\n }\n\n if (args.length === 2 && args[1] instanceof Flatten.Vector) {\n this.norm = args[1].clone();\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of ray\n * @returns {Ray}\n */\n clone() {\n return new Ray(this.pt, this.norm);\n }\n\n /**\n * Slope of the ray - angle in radians between ray and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Returns half-infinite bounding box of the ray\n * @returns {Box} - bounding box\n */\n get box() {\n let slope = this.slope;\n return new Flatten.Box(\n slope > Math.PI/2 && slope < 3*Math.PI/2 ? Number.NEGATIVE_INFINITY : this.pt.x,\n slope >= 0 && slope <= Math.PI ? this.pt.y : Number.NEGATIVE_INFINITY,\n slope >= Math.PI/2 && slope <= 3*Math.PI/2 ? this.pt.x : Number.POSITIVE_INFINITY,\n slope >= Math.PI && slope <= 2*Math.PI || slope === 0 ? this.pt.y : Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Return ray start point\n * @returns {Point} - ray start point\n */\n get start() {\n return this.pt;\n }\n\n /**\n * Ray has no end point?\n * @returns {undefined}\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns true if point belongs to ray\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Ray contains point if vector to point is orthogonal to the ray normal vector\n and cross product from vector to point is positive */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec)) && Flatten.Utils.GE(vec.cross(this.norm),0);\n }\n\n /**\n * Return coordinate of the point that lies on the ray in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line containing this ray and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the ray\n * @param {Point} pt - point on a ray\n * @returns {number}\n */\n coord(pt) {\n return vector$1(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Split ray with point and return array of segment and new ray\n * @param {Point} pt\n * @returns [Segment,Ray]\n */\n split(pt) {\n if (!this.contains(pt))\n return [];\n\n if (this.pt.equalTo(pt)) {\n return [this]\n }\n\n return [\n new Flatten.Segment(this.pt, pt),\n new Flatten.Ray(pt, this.norm)\n ]\n }\n\n /**\n * Returns array of intersection points between ray and another shape\n * @param {Shape} shape - Shape to intersect with ray\n * @returns {Point[]} array of intersection points\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectRay2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectRay2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectRay2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Ray(this, shape)\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectRay2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectRay2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectRay2Polygon(this, shape);\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Ray(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new ray transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Ray}\n */\n transform(m) {\n return new Flatten.Ray(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n get name() {\n return \"ray\"\n }\n\n /**\n * Return string to draw svg segment representing ray inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg segment element\n */\n svg(box, attrs = {}) {\n let line = new Flatten.Line(this.pt, this.norm);\n let ip = intersectLine2Box(line, box);\n ip = ip.filter( pt => this.contains(pt) );\n if (ip.length === 0 || ip.length === 2)\n return \"\";\n let segment = new Flatten.Segment(this.pt, ip[0]);\n return segment.svg(attrs);\n }\n\n}\n\nFlatten.Ray = Ray;\n\nconst ray = (...args) => new Flatten.Ray(...args);\nFlatten.ray = ray;\n\n/**\n * Created by Alex Bol on 3/15/2017.\n */\n\n\n/**\n * Class representing a polygon.
\n * Polygon in FlattenJS is a multipolygon comprised from a set of [faces]{@link Flatten.Face}.
\n * Face, in turn, is a closed loop of [edges]{@link Flatten.Edge}, where edge may be segment or circular arc
\n * @type {Polygon}\n */\nclass Polygon {\n /**\n * Constructor creates new instance of polygon. With no arguments new polygon is empty.
\n * Constructor accepts as argument array that define loop of shapes\n * or array of arrays in case of multi polygon
\n * Loop may be defined in different ways:
\n * - array of shapes of type Segment or Arc
\n * - array of points (Flatten.Point)
\n * - array of numeric pairs which represent points
\n * - box or circle object
\n * Alternatively, it is possible to use polygon.addFace method\n * @param {args} - array of shapes or array of arrays\n */\n constructor() {\n /**\n * Container of faces (closed loops), may be empty\n * @type {PlanarSet}\n */\n this.faces = new Flatten.PlanarSet();\n /**\n * Container of edges\n * @type {PlanarSet}\n */\n this.edges = new Flatten.PlanarSet();\n\n /* It may be array of something that may represent one loop (face) or\n array of arrays that represent multiple loops\n */\n let args = [...arguments];\n if (args.length === 1 &&\n ((args[0] instanceof Array && args[0].length > 0) ||\n args[0] instanceof Flatten.Circle || args[0] instanceof Flatten.Box)) {\n let argsArray = args[0];\n if (args[0] instanceof Array && args[0].every((loop) => {\n return loop instanceof Array\n })) {\n if (argsArray.every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon as array of pairs of numbers\n } else {\n for (let loop of argsArray) { // multi-loop polygon\n /* Check extra level of nesting for GeoJSON-style multi polygons */\n if (loop instanceof Array && loop[0] instanceof Array &&\n loop[0].every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n for (let loop1 of loop) {\n this.faces.add(new Flatten.Face(this, loop1));\n }\n } else {\n this.faces.add(new Flatten.Face(this, loop));\n }\n }\n }\n } else {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon\n }\n }\n }\n\n /**\n * (Getter) Returns bounding box of the polygon\n * @returns {Box}\n */\n get box() {\n return [...this.faces].reduce((acc, face) => acc.merge(face.box), new Flatten.Box());\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Array}\n */\n get vertices() {\n return [...this.edges].map(edge => edge.start);\n }\n\n /**\n * Create new cloned instance of the polygon\n * @returns {Polygon}\n */\n clone() {\n let polygon = new Polygon();\n for (let face of this.faces) {\n polygon.addFace(face.shapes);\n }\n return polygon;\n }\n\n /**\n * Return true is polygon has no edges\n * @returns {boolean}\n */\n isEmpty() {\n return this.edges.size === 0;\n }\n\n /**\n * Return true if polygon is valid for boolean operations\n * Polygon is valid if
\n * 1. All faces are simple polygons (there are no self-intersected polygons)
\n * 2. All faces are orientable and there is no island inside island or hole inside hole - TODO
\n * 3. There is no intersections between faces (excluding touching) - TODO
\n * @returns {boolean}\n */\n isValid() {\n let valid = true;\n // 1. Polygon is invalid if at least one face is not simple\n for (let face of this.faces) {\n if (!face.isSimple(this.edges)) {\n valid = false;\n break;\n }\n }\n // 2. TODO: check if no island inside island and no hole inside hole\n // 3. TODO: check the there is no intersection between faces\n return valid;\n }\n\n /**\n * Returns area of the polygon. Area of an island will be added, area of a hole will be subtracted\n * @returns {number}\n */\n area() {\n let signedArea = [...this.faces].reduce((acc, face) => acc + face.signedArea(), 0);\n return Math.abs(signedArea);\n }\n\n /**\n * Add new face to polygon. Returns added face\n * @param {Point[]|Segment[]|Arc[]|Circle|Box} args - new face may be create with one of the following ways:
\n * 1) array of points that describe closed path (edges are segments)
\n * 2) array of shapes (segments and arcs) which describe closed path
\n * 3) circle - will be added as counterclockwise arc
\n * 4) box - will be added as counterclockwise rectangle
\n * You can chain method face.reverse() is you need to change direction of the creates face\n * @returns {Face}\n */\n addFace(...args) {\n let face = new Flatten.Face(this, ...args);\n this.faces.add(face);\n return face;\n }\n\n /**\n * Delete existing face from polygon\n * @param {Face} face Face to be deleted\n * @returns {boolean}\n */\n deleteFace(face) {\n for (let edge of face) {\n this.edges.delete(edge);\n }\n return this.faces.delete(face);\n }\n\n /**\n * Clear all faces and create new faces from edges\n */\n recreateFaces() {\n // Remove all faces\n this.faces.clear();\n for (let edge of this.edges) {\n edge.face = null;\n }\n\n // Restore faces\n let first;\n let unassignedEdgeFound = true;\n while (unassignedEdgeFound) {\n unassignedEdgeFound = false;\n for (let edge of this.edges) {\n if (edge.face === null) {\n first = edge;\n unassignedEdgeFound = true;\n break;\n }\n }\n\n if (unassignedEdgeFound) {\n let last = first;\n do {\n last = last.next;\n } while (last.next !== first)\n\n this.addFace(first, last);\n }\n }\n }\n\n /**\n * Delete chain of edges from the face.\n * @param {Face} face Face to remove chain\n * @param {Edge} edgeFrom Start of the chain of edges to be removed\n * @param {Edge} edgeTo End of the chain of edges to be removed\n */\n removeChain(face, edgeFrom, edgeTo) {\n // Special case: all edges removed\n if (edgeTo.next === edgeFrom) {\n this.deleteFace(face);\n return;\n }\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n face.remove(edge);\n this.edges.delete(edge); // delete from PlanarSet of edges and update index\n if (face.isEmpty()) {\n this.deleteFace(face); // delete from PlanarSet of faces and update index\n break;\n }\n }\n }\n\n /**\n * Add point as a new vertex and split edge. Point supposed to belong to an edge.\n * When edge is split, new edge created from the start of the edge to the new vertex\n * and inserted before current edge.\n * Current edge is trimmed and updated.\n * Method returns new edge added. If no edge added, it returns edge before vertex\n * @param {Point} pt Point to be added as a new vertex\n * @param {Edge} edge Edge to be split with new vertex and then trimmed from start\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n edge.face.insert(newEdge, edgeBefore);\n\n // Remove old edge from edges container and 2d index\n this.edges.delete(edge);\n\n // Insert new edge to the edges container and 2d index\n this.edges.add(newEdge);\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n // Add updated edge to the edges container and 2d index\n this.edges.add(edge);\n\n return newEdge;\n }\n\n /**\n * Merge given edge with next edge and remove vertex between them\n * @param {Edge} edge\n */\n removeEndVertex(edge) {\n const edge_next = edge.next;\n if (edge_next === edge) return\n edge.face.merge_with_next_edge(edge);\n this.edges.delete(edge_next);\n }\n\n /**\n * Cut polygon with multiline and return a new polygon\n * @param {Multiline} multiline\n * @returns {Polygon}\n */\n cut(multiline) {\n let newPoly = this.clone();\n\n // smart intersections\n let intersections = {\n int_points1: [],\n int_points2: [],\n int_points1_sorted: [],\n int_points2_sorted: []\n };\n\n // intersect each edge of multiline with each edge of the polygon\n // and create smart intersections\n for (let edge1 of multiline.edges) {\n for (let edge2 of newPoly.edges) {\n let ip = intersectEdge2Edge(edge1, edge2);\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n\n // No intersections - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort smart intersections\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // split by intersection points\n splitByIntersections(multiline, intersections.int_points1_sorted);\n splitByIntersections(newPoly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // initialize inclusion flags for edges of multiline incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n\n // calculate inclusion flag for edges of multiline incident to intersections\n calculateInclusionFlags(intersections.int_points1, newPoly);\n\n // filter intersections between two edges that got same inclusion flag\n for (let int_point1 of intersections.int_points1_sorted) {\n if (int_point1.edge_before && int_point1.edge_after &&\n int_point1.edge_before.bv === int_point1.edge_after.bv) {\n intersections.int_points2[int_point1.id] = -1; // to be filtered out\n int_point1.id = -1; // to be filtered out\n }\n }\n intersections.int_points1 = intersections.int_points1.filter( int_point => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter( int_point => int_point.id >= 0);\n\n // No intersections left after filtering - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort intersection points 3d time after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // Add new inner edges between intersection points\n let int_point1_prev;\n let int_point1_curr;\n for (let i = 1; i < intersections.int_points1_sorted.length; i++) {\n int_point1_curr = intersections.int_points1_sorted[i];\n int_point1_prev = intersections.int_points1_sorted[i-1];\n if (int_point1_curr.edge_before && int_point1_curr.edge_before.bv === INSIDE$2) {\n let edgeFrom = int_point1_prev.edge_after;\n let edgeTo = int_point1_curr.edge_before;\n let newEdges = multiline.getChain(edgeFrom, edgeTo);\n insertBetweenIntPoints(intersections.int_points2[int_point1_prev.id], intersections.int_points2[int_point1_curr.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n\n newEdges = newEdges.reverse().map(edge => new Flatten.Edge(edge.shape.reverse()));\n for (let k=0; k < newEdges.length-1; k++) {\n newEdges[k].next = newEdges[k+1];\n newEdges[k+1].prev = newEdges[k];\n }\n insertBetweenIntPoints(intersections.int_points2[int_point1_curr.id], intersections.int_points2[int_point1_prev.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n }\n\n }\n\n // Recreate faces\n newPoly.recreateFaces();\n\n return newPoly\n }\n\n /**\n * A special case of cut() function\n * The return is a polygon cut with line\n * @param {Line} line - cutting line\n * @returns {Polygon} newPoly - resulted polygon\n */\n cutWithLine(line) {\n let multiline = new Multiline([line]);\n return this.cut(multiline);\n }\n\n /**\n * Returns the first found edge of polygon that contains given point\n * If point is a vertex, return the edge where the point is an end vertex, not a start one\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edge;\n for (let face of this.faces) {\n edge = face.findEdgeByPoint(pt);\n if (edge !== undefined)\n break;\n }\n return edge;\n }\n\n /**\n * Split polygon into array of polygons, where each polygon is an outer face with all\n * containing inner faces\n * @returns {Flatten.Polygon[]}\n */\n splitToIslands() {\n if (this.isEmpty()) return []; // return empty array if polygon is empty\n let polygons = this.toArray(); // split into array of one-loop polygons\n /* Sort polygons by area in descending order */\n polygons.sort((polygon1, polygon2) => polygon2.area() - polygon1.area());\n /* define orientation of the island by orientation of the first polygon in array */\n let orientation = [...polygons[0].faces][0].orientation();\n /* Create output array from polygons with same orientation as a first polygon (array of islands) */\n let newPolygons = polygons.filter(polygon => [...polygon.faces][0].orientation() === orientation);\n for (let polygon of polygons) {\n let face = [...polygon.faces][0];\n if (face.orientation() === orientation) continue; // skip same orientation\n /* Proceed with opposite orientation */\n /* Look if any of island polygons contains tested polygon as a hole */\n for (let islandPolygon of newPolygons) {\n if (face.shapes.every(shape => islandPolygon.contains(shape))) {\n islandPolygon.addFace(face.shapes); // add polygon as a hole in islandPolygon\n break;\n }\n }\n }\n // TODO: assert if not all polygons added into output\n return newPolygons;\n }\n\n /**\n * Reverse orientation of all faces to opposite\n * @returns {Polygon}\n */\n reverse() {\n for (let face of this.faces) {\n face.reverse();\n }\n return this;\n }\n\n /**\n * Returns true if polygon contains shape: no point of shape lay outside of the polygon,\n * false otherwise\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n let rel = ray_shoot(this, shape);\n return rel === INSIDE$2 || rel === BOUNDARY$1;\n } else {\n return cover(this, shape);\n }\n }\n\n /**\n * Return distance and shortest segment between polygon and other shape as array [distance, shortest_segment]\n * @param {Shape} shape Shape of one of the types Point, Circle, Line, Segment, Arc or Polygon\n * @returns {Number | Segment}\n */\n distanceTo(shape) {\n // let {Distance} = Flatten;\n\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle ||\n shape instanceof Flatten.Line ||\n shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /* this method is bit faster */\n if (shape instanceof Flatten.Polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n let dist, shortest_segment;\n\n for (let edge of this.edges) {\n // let [dist, shortest_segment] = Distance.shape2polygon(edge.shape, shape);\n let min_stop = min_dist_and_segment[0];\n [dist, shortest_segment] = Flatten.Distance.shape2planarSet(edge.shape, shape.edges, min_stop);\n if (Flatten.Utils.LT(dist, min_stop)) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n }\n\n /**\n * Return array of intersection points between polygon and other shape\n * @param shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectPolygon2Polygon(shape, this);\n }\n }\n\n /**\n * Returns new polygon translated by vector vec\n * @param {Vector} vec\n * @returns {Polygon}\n */\n translate(vec) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.translate(vec)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Polygon} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.rotate(angle, center)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Polygon}\n */\n scale(sx, sy) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.scale(sx, sy)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Polygon} - new polygon\n */\n transform(matrix = new Flatten.Matrix()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.transform(matrix)));\n }\n return newPolygon;\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return [...this.faces].map(face => face.toJSON());\n }\n\n /**\n * Transform all faces into array of polygons\n * @returns {Flatten.Polygon[]}\n */\n toArray() {\n return [...this.faces].map(face => face.toPolygon());\n }\n\n /**\n * Return string to draw polygon in svg\n * @param attrs - an object with attributes for svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Polygon = Polygon;\n\n/**\n * Shortcut method to create new polygon\n */\nconst polygon = (...args) => new Flatten.Polygon(...args);\nFlatten.polygon = polygon;\n\nconst {Circle, Line, Point, Vector, Utils} = Flatten;\n/**\n * Class Inversion represent operator of inversion in circle\n * Inversion is a transformation of the Euclidean plane that maps generalized circles\n * (where line is considered as a circle with infinite radius) into generalized circles\n * See also https://en.wikipedia.org/wiki/Inversive_geometry and\n * http://mathworld.wolfram.com/Inversion.html
\n * @type {Inversion}\n */\nclass Inversion {\n /**\n * Inversion constructor\n * @param {Circle} inversion_circle inversion circle\n */\n constructor(inversion_circle) {\n this.circle = inversion_circle;\n }\n\n\n get inversion_circle() {\n return this.circle;\n }\n\n static inversePoint(inversion_circle, point) {\n const v = new Vector(inversion_circle.pc, point);\n const k2 = inversion_circle.r * inversion_circle.r;\n const len2 = v.dot(v);\n const reflected_point = Utils.EQ_0(len2) ?\n new Point(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) :\n inversion_circle.pc.translate(v.multiply(k2 / len2));\n return reflected_point;\n }\n\n static inverseCircle(inversion_circle, circle) {\n const dist = inversion_circle.pc.distanceTo(circle.pc)[0];\n if (Utils.EQ(dist, circle.r)) { // Circle passing through inversion center mapped into line\n let d = (inversion_circle.r * inversion_circle.r) / (2 * circle.r);\n let v = new Vector(inversion_circle.pc, circle.pc);\n v = v.normalize();\n let pt = inversion_circle.pc.translate(v.multiply(d));\n\n return new Line(pt, v);\n } else { // Circle not passing through inversion center - map into another circle */\n /* Taken from http://mathworld.wolfram.com */\n let v = new Vector(inversion_circle.pc, circle.pc);\n let s = inversion_circle.r * inversion_circle.r / (v.dot(v) - circle.r * circle.r);\n let pc = inversion_circle.pc.translate(v.multiply(s));\n let r = Math.abs(s) * circle.r;\n\n return new Circle(pc, r);\n }\n }\n\n static inverseLine(inversion_circle, line) {\n const [dist, shortest_segment] = inversion_circle.pc.distanceTo(line);\n if (Utils.EQ_0(dist)) { // Line passing through inversion center, is mapping to itself\n return line.clone();\n } else { // Line not passing through inversion center is mapping into circle\n let r = inversion_circle.r * inversion_circle.r / (2 * dist);\n let v = new Vector(inversion_circle.pc, shortest_segment.end);\n v = v.multiply(r / dist);\n return new Circle(inversion_circle.pc.translate(v), r);\n }\n }\n\n inverse(shape) {\n if (shape instanceof Point) {\n return Inversion.inversePoint(this.circle, shape);\n }\n else if (shape instanceof Circle) {\n return Inversion.inverseCircle(this.circle, shape);\n }\n else if (shape instanceof Line) {\n return Inversion.inverseLine(this.circle, shape);\n }\n }\n}\nFlatten.Inversion = Inversion;\n\n/**\n * Shortcut to create inversion operator\n * @param circle\n * @returns {Inversion}\n */\nconst inversion = (circle) => new Flatten.Inversion(circle);\nFlatten.inversion = inversion;\n\nclass Distance {\n /**\n * Calculate distance and shortest segment between points\n * @param pt1\n * @param pt2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2point(pt1, pt2) {\n return pt1.distanceTo(pt2);\n }\n\n /**\n * Calculate distance and shortest segment between point and line\n * @param pt\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2line(pt, line) {\n let closest_point = pt.projectionOn(line);\n let vec = new Flatten.Vector(pt, closest_point);\n return [vec.length, new Flatten.Segment(pt, closest_point)];\n }\n\n /**\n * Calculate distance and shortest segment between point and circle\n * @param pt\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2circle(pt, circle) {\n let [dist2center, shortest_dist] = pt.distanceTo(circle.center);\n if (Flatten.Utils.EQ_0(dist2center)) {\n return [circle.r, new Flatten.Segment(pt, circle.toArc().start)];\n } else {\n let dist = Math.abs(dist2center - circle.r);\n let v = new Flatten.Vector(circle.pc, pt).normalize().multiply(circle.r);\n let closest_point = circle.pc.translate(v);\n return [dist, new Flatten.Segment(pt, closest_point)];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and segment\n * @param pt\n * @param segment\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2segment(pt, segment) {\n /* Degenerated case of zero-length segment */\n if (segment.start.equalTo(segment.end)) {\n return Distance.point2point(pt, segment.start);\n }\n\n let v_seg = new Flatten.Vector(segment.start, segment.end);\n let v_ps2pt = new Flatten.Vector(segment.start, pt);\n let v_pe2pt = new Flatten.Vector(segment.end, pt);\n let start_sp = v_seg.dot(v_ps2pt);\n /* dot product v_seg * v_ps2pt */\n let end_sp = -v_seg.dot(v_pe2pt);\n /* minus dot product v_seg * v_pe2pt */\n\n let dist;\n let closest_point;\n if (Flatten.Utils.GE(start_sp, 0) && Flatten.Utils.GE(end_sp, 0)) { /* point inside segment scope */\n let v_unit = segment.tangentInStart(); // new Flatten.Vector(v_seg.x / this.length, v_seg.y / this.length);\n /* unit vector ||v_unit|| = 1 */\n dist = Math.abs(v_unit.cross(v_ps2pt));\n /* dist = abs(v_unit x v_ps2pt) */\n closest_point = segment.start.translate(v_unit.multiply(v_unit.dot(v_ps2pt)));\n return [dist, new Flatten.Segment(pt, closest_point)];\n } else if (start_sp < 0) { /* point is out of scope closer to ps */\n return pt.distanceTo(segment.start);\n } else { /* point is out of scope closer to pe */\n return pt.distanceTo(segment.end);\n }\n };\n\n /**\n * Calculate distance and shortest segment between point and arc\n * @param pt\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2arc(pt, arc) {\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let dist_and_segment = [];\n let dist, shortest_segment;\n [dist, shortest_segment] = Distance.point2circle(pt, circle);\n if (shortest_segment.end.on(arc)) {\n dist_and_segment.push(Distance.point2circle(pt, circle));\n }\n dist_and_segment.push(Distance.point2point(pt, arc.start));\n dist_and_segment.push(Distance.point2point(pt, arc.end));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and line\n * @param seg\n * @param line\n * @returns {Number | Segment}\n */\n static segment2line(seg, line) {\n let ip = seg.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(seg.start, line));\n dist_and_segment.push(Distance.point2line(seg.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n\n }\n\n /**\n * Calculate distance and shortest segment between two segments\n * @param seg1\n * @param seg2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2segment(seg1, seg2) {\n let ip = intersectSegment2Segment(seg1, seg2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n\n // Seg1 and seg2 not intersected\n let dist_and_segment = [];\n let dist_tmp, shortest_segment_tmp;\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.start, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.end, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n dist_and_segment.push(Distance.point2segment(seg1.start, seg2));\n dist_and_segment.push(Distance.point2segment(seg1.end, seg2));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and circle\n * @param seg\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2circle(seg, circle) {\n /* Case 1 Segment and circle intersected. Return the first point and zero distance */\n let ip = seg.intersect(circle);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and circle\n\n /* Case 2. Distance to projection of center point to line bigger than radius\n * And projection point belong to segment\n * Then measure again distance from projection to circle and return it */\n let line = new Flatten.Line(seg.ps, seg.pe);\n let [dist, shortest_segment] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist, circle.r) && shortest_segment.end.on(seg)) {\n return Distance.point2circle(shortest_segment.end, circle);\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n else {\n let [dist_from_start, shortest_segment_from_start] = Distance.point2circle(seg.start, circle);\n let [dist_from_end, shortest_segment_from_end] = Distance.point2circle(seg.end, circle);\n return Flatten.Utils.LT(dist_from_start, dist_from_end) ?\n [dist_from_start, shortest_segment_from_start] :\n [dist_from_end, shortest_segment_from_end];\n }\n }\n\n /**\n * Calculate distance and shortest segment between segment and arc\n * @param seg\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2arc(seg, arc) {\n /* Case 1 Segment and arc intersected. Return the first point and zero distance */\n let ip = seg.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and arc\n let line = new Flatten.Line(seg.ps, seg.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r) && shortest_segment_from_center.end.on(seg)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2arc(seg.start, arc));\n dist_and_segment.push(Distance.point2arc(seg.end, arc));\n\n let dist_tmp, segment_tmp;\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.start, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.end, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle1\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2circle(circle1, circle2) {\n let ip = circle1.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // Case 1. Concentric circles. Convert to arcs and take distance between two arc starts\n if (circle1.center.equalTo(circle2.center)) {\n let arc1 = circle1.toArc();\n let arc2 = circle2.toArc();\n return Distance.point2point(arc1.start, arc2.start);\n } else {\n // Case 2. Not concentric circles\n let line = new Flatten.Line(circle1.center, circle2.center);\n let ip1 = line.intersect(circle1);\n let ip2 = line.intersect(circle2);\n\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[1]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[1]));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2line(circle, line) {\n let ip = circle.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n let [dist, shortest_segment] = Distance.point2circle(shortest_segment_from_center.end, circle);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /**\n * Calculate distance and shortest segment between arc and line\n * @param arc\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2line(arc, line) {\n /* Case 1 Line and arc intersected. Return the first point and zero distance */\n let ip = line.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle = new Flatten.Circle(arc.center, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n } else {\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(arc.start, line));\n dist_and_segment.push(Distance.point2line(arc.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between arc and circle\n * @param arc\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2circle(arc, circle2) {\n let ip = arc.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc.center, arc.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2circle(arc.start, circle2));\n dist_and_segment.push(Distance.point2circle(arc.end, circle2));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two arcs\n * @param arc1\n * @param arc2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2arc(arc1, arc2) {\n let ip = arc1.intersect(arc2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc1.center, arc1.r);\n let circle2 = new Flatten.Circle(arc2.center, arc2.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc1) && shortest_segment.end.on(arc2)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n let dist_tmp, segment_tmp;\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.start, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.end, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.start, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.end, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and polygon\n * @param point\n * @param polygon\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2polygon(point, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = (edge.shape instanceof Flatten.Segment) ?\n Distance.point2segment(point, edge.shape) : Distance.point2arc(point, edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n static shape2polygon(shape, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = shape.distanceTo(edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Calculate distance and shortest segment between two polygons\n * @param polygon1\n * @param polygon2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static polygon2polygon(polygon1, polygon2) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge1 of polygon1.edges) {\n for (let edge2 of polygon2.edges) {\n let [dist, shortest_segment] = edge1.shape.distanceTo(edge2.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Returns [mindist, maxdist] array of squared minimal and maximal distance between boxes\n * Minimal distance by x is\n * (box2.xmin - box1.xmax), if box1 is left to box2\n * (box1.xmin - box2.xmax), if box2 is left to box1\n * 0, if box1 and box2 are intersected by x\n * Minimal distance by y is defined in the same way\n *\n * Maximal distance is estimated as a sum of squared dimensions of the merged box\n *\n * @param box1\n * @param box2\n * @returns {Number | Number} - minimal and maximal distance\n */\n static box2box_minmax(box1, box2) {\n let mindist_x = Math.max(Math.max(box1.xmin - box2.xmax, 0), Math.max(box2.xmin - box1.xmax, 0));\n let mindist_y = Math.max(Math.max(box1.ymin - box2.ymax, 0), Math.max(box2.ymin - box1.ymax, 0));\n let mindist = mindist_x * mindist_x + mindist_y * mindist_y;\n\n let box = box1.merge(box2);\n let dx = box.xmax - box.xmin;\n let dy = box.ymax - box.ymin;\n let maxdist = dx * dx + dy * dy;\n\n return [mindist, maxdist];\n }\n\n static minmax_tree_process_level(shape, level, min_stop, tree) {\n // Calculate minmax distance to each shape in current level\n // Insert result into the interval tree for further processing\n // update min_stop with maxdist, it will be the new stop distance\n let mindist, maxdist;\n for (let node of level) {\n\n // [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n // if (Flatten.Utils.GT(mindist, min_stop))\n // continue;\n\n // Estimate min-max dist to the shape stored in the node.item, using node.item.key which is shape's box\n [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.item.key);\n if (node.item.value instanceof Flatten.Edge) {\n tree.insert([mindist, maxdist], node.item.value.shape);\n } else {\n tree.insert([mindist, maxdist], node.item.value);\n }\n if (Flatten.Utils.LT(maxdist, min_stop)) {\n min_stop = maxdist; // this will be the new distance estimation\n }\n }\n\n if (level.length === 0)\n return min_stop;\n\n // Calculate new level from left and right children of the current\n let new_level_left = level.map(node => node.left.isNil() ? undefined : node.left).filter(node => node !== undefined);\n let new_level_right = level.map(node => node.right.isNil() ? undefined : node.right).filter(node => node !== undefined);\n // Merge left and right subtrees and leave only relevant subtrees\n let new_level = [...new_level_left, ...new_level_right].filter(node => {\n // Node subtree quick reject, node.max is a subtree box\n let [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n return (Flatten.Utils.LE(mindist, min_stop));\n });\n\n min_stop = Distance.minmax_tree_process_level(shape, new_level, min_stop, tree);\n return min_stop;\n }\n\n /**\n * Calculates sorted tree of [mindist, maxdist] intervals between query shape\n * and shapes of the planar set.\n * @param shape\n * @param set\n */\n static minmax_tree(shape, set, min_stop) {\n let tree = new IntervalTree();\n let level = [set.index.root];\n let squared_min_stop = min_stop < Number.POSITIVE_INFINITY ? min_stop * min_stop : Number.POSITIVE_INFINITY;\n squared_min_stop = Distance.minmax_tree_process_level(shape, level, squared_min_stop, tree);\n return tree;\n }\n\n static minmax_tree_calc_distance(shape, node, min_dist_and_segment) {\n let min_dist_and_segment_new, stop;\n if (node != null && !node.isNil()) {\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.left, min_dist_and_segment);\n\n if (stop) {\n return [min_dist_and_segment_new, stop];\n }\n\n if (Flatten.Utils.LT(min_dist_and_segment_new[0], Math.sqrt(node.item.key.low))) {\n return [min_dist_and_segment_new, true]; // stop condition\n }\n\n let [dist, shortest_segment] = Distance.distance(shape, node.item.value);\n // console.log(dist)\n if (Flatten.Utils.LT(dist, min_dist_and_segment_new[0])) {\n min_dist_and_segment_new = [dist, shortest_segment];\n }\n\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.right, min_dist_and_segment_new);\n\n return [min_dist_and_segment_new, stop];\n }\n\n return [min_dist_and_segment, false];\n }\n\n /**\n * Calculates distance between shape and Planar Set of shapes\n * @param shape\n * @param {PlanarSet} set\n * @param {Number} min_stop\n * @returns {*}\n */\n static shape2planarSet(shape, set, min_stop = Number.POSITIVE_INFINITY) {\n let min_dist_and_segment = [min_stop, new Flatten.Segment()];\n let stop = false;\n if (set instanceof Flatten.PlanarSet) {\n let tree = Distance.minmax_tree(shape, set, min_stop);\n [min_dist_and_segment, stop] = Distance.minmax_tree_calc_distance(shape, tree.root, min_dist_and_segment);\n }\n return min_dist_and_segment;\n }\n\n static sort(dist_and_segment) {\n dist_and_segment.sort((d1, d2) => {\n if (Flatten.Utils.LT(d1[0], d2[0])) {\n return -1;\n }\n if (Flatten.Utils.GT(d1[0], d2[0])) {\n return 1;\n }\n return 0;\n });\n }\n\n static distance(shape1, shape2) {\n return shape1.distanceTo(shape2);\n }\n}\n\nFlatten.Distance = Distance;\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\nFlatten.BooleanOperations = BooleanOperations;\nFlatten.Relations = Relations;\n\nexport { Arc, BOUNDARY$1 as BOUNDARY, BooleanOperations, Box, CCW, CW, Circle$1 as Circle, Distance, Edge, Errors, Face, INSIDE$2 as INSIDE, Inversion, Line$1 as Line, Matrix, Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$1 as Point, Polygon, Ray, Relations, Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, line, matrix, multiline, point, polygon, ray, ray_shoot, segment, vector$1 as vector };\n","import type {LatLngExpression} from 'leaflet';\nimport L, {Bounds, LatLng, LatLngBounds, Path, Point, Util} from 'leaflet';\nimport Flatten from '@flatten-js/core';\nimport Matrix = Flatten.Matrix;\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport type {ShapeOptions, TrackSymbolOptions} from './options';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_LEADER_TIME = 60;\n\n/**\n * Track symbol.\n */\nexport class TrackSymbol\n extends Path {\n\n /** Default 'withHeading' shape points. */\n public static DEFAULT_HEADING_SHAPE_POINTS: Points = [[0.75, 0], [-0.25, 0.3], [-0.25, -0.3]];\n\n /** Default 'withoutHeading' shape points. */\n public static DEFAULT_NOHEADING_SHAPE_POINTS: Points = [[0.3, 0], [0, 0.3], [-0.3, 0], [0, -0.3]];\n\n /** Default shape set. */\n private static DEFAULT_SHAPE_SET: ShapeSet = {\n withHeading: {\n points: TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n withoutHeading: {\n points: TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n };\n\n /** Location. */\n private _latLng: LatLng;\n /** Heading (radians, from north, clockwise. */\n private _heading?: number;\n /** Course (radians, from north, clockwise. */\n private _course?: number;\n /** Speed (m/s). */\n private _speed?: number;\n /** Shape options. */\n private _shapeOptions: ShapeOptions;\n\n /** Current shape points. */\n private _currentShapePoints: Point[] | undefined;\n /** Current leader points. */\n private _currentLeaderPoints: Point[] | undefined;\n /** Current bounds. */\n private _currentBounds: Bounds | undefined;\n /** Current lat/lng bounds. */\n private _currentLatLngBounds: LatLngBounds | undefined;\n\n /**\n * TrackSymbol constructor.\n *\n * @param latLng - Initial location.\n * @param options - Options.\n */\n constructor(latLng: LatLngExpression, options?: TrackSymbolOptions) {\n super();\n\n Util.setOptions(this, options);\n if (latLng == undefined) {\n throw Error(\"latLng required\");\n }\n options = options || {};\n this._latLng = L.latLng(latLng);\n this._heading = options.heading;\n this._course = options.course;\n this._speed = options.speed;\n this._shapeOptions = options.shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n this._setShapeOptions(options.shapeOptions);\n }\n\n // ---- Leaflet\n\n /**\n * Project to layer.\n *\n * [Leaflet internal]\n */\n protected _project() {\n this._currentShapePoints = this._getProjectedShapePoints();\n this._currentLeaderPoints = this._getLeaderShapePoints();\n\n const bounds = new Bounds();\n for (let i = 0; i < this._currentShapePoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n if (this._currentLeaderPoints !== undefined) {\n for (let i = 0; i < this._currentLeaderPoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n }\n this._currentBounds = bounds;\n this._currentLatLngBounds = new LatLngBounds(\n this._map.layerPointToLatLng(bounds.getBottomLeft()),\n this._map.layerPointToLatLng(bounds.getTopRight())\n );\n }\n\n /**\n * Update element.\n *\n * [Leaflet internal]\n */\n protected _update() {\n if (!this._map) {\n return;\n }\n const el = this.getElement();\n if (el === undefined) {\n return;\n }\n const paths: string[] = [];\n if (this._currentShapePoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentShapePoints, true));\n }\n if (this._currentLeaderPoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentLeaderPoints, false));\n }\n const viewPath = paths.join(' ');\n el.setAttribute('d', viewPath);\n }\n\n // ----\n\n /**\n * Set shape options.\n *\n * @param shapeOptions - Shape options.\n */\n private _setShapeOptions(shapeOptions: ShapeOptions | undefined) {\n this._shapeOptions = shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n if (this._shapeOptions.leaderTime === undefined) {\n this._shapeOptions.leaderTime = DEFAULT_LEADER_TIME;\n }\n if (this._shapeOptions.defaultShapeSet === undefined) {\n this._shapeOptions.defaultShapeSet = TrackSymbol.DEFAULT_SHAPE_SET;\n }\n if (this._shapeOptions.shapeSetEntries !== undefined) {\n this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel);\n }\n }\n\n // ---\n\n /**\n * Sets the location.\n *\n * @param latLng - Location.\n * @returns this\n */\n public setLatLng(latLng: LatLngExpression): this {\n const oldLatLng = this._latLng;\n this._latLng = L.latLng(latLng);\n this.fire('move', {\n oldLatLng: oldLatLng,\n latlng: this._latLng,\n });\n return this.redraw();\n }\n\n /**\n * Sets the heading.\n *\n * @param heading - Heading (unit: radians, from north, clockwise).\n * @returns this\n */\n public setHeading(heading: number | undefined): this {\n this._heading = heading;\n return this.redraw();\n }\n\n /**\n * Sets the course over ground.\n *\n * @param course - Course over ground (unit: radians, from north, clockwise).\n * @returns this\n */\n public setCourse(course: number | undefined): this {\n this._course = course;\n return this.redraw();\n }\n\n /**\n * Sets the speed.\n *\n * @param speed - Speed (unit: m/s).\n * @returns this\n */\n public setSpeed(speed: number | undefined): this {\n this._speed = speed;\n return this.redraw();\n }\n\n /**\n * Sets the shape options.\n *\n * @param shapeOptions - Shape options.\n * @returns this\n */\n public setShapeOptions(shapeOptions: ShapeOptions): this {\n this._setShapeOptions(shapeOptions);\n return this.redraw();\n }\n\n /**\n * Returns the bounding box.\n *\n * @returns The bounding box.\n */\n public getBounds(): LatLngBounds | undefined {\n return this._currentLatLngBounds;\n }\n\n /**\n * Returns the location.\n *\n * @returns The location.\n */\n public getLatLng(): LatLng {\n return this._latLng;\n }\n\n /**\n * Returns the speed.\n *\n * @returns The speed (m/s).\n */\n public getSpeed(): number | undefined {\n return this._speed;\n }\n\n /**\n * Returns the heading.\n *\n * @returns The heading (radians, from north, clockwise).\n */\n public getHeading(): number | undefined {\n return this._heading;\n }\n\n /**\n * Returns the course.\n *\n * @returns The course (radians, from north, clockwise).\n */\n public getCourse(): number | undefined {\n return this._course;\n }\n\n /**\n * Creates a shape.\n *\n * @param points - Points.\n * @param size - Size (units: pixels).\n * @returns The new shape.\n */\n public static createShape(points: Points, size: number): Shape {\n return {\n points: points,\n length: size,\n breadth: size,\n units: \"pixels\",\n };\n }\n\n /**\n * Creates a shape set.\n *\n * @param size - Size (units: pixels).\n * @returns The new shape set.\n */\n public static createShapeSet(size: number): ShapeSet {\n return {\n withHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS, size),\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n /**\n * Get latitude size of y-distance.\n *\n * @param value - Y distance (m).\n * @returns dLat\n */\n private _getLatSizeOf(value: number): number {\n return (value / 40075017) * 360;\n }\n\n /**\n * Get longitude size of x-distance.\n *\n * @param value - X distance (m).\n * @returns dLng\n */\n private _getLngSizeOf(value: number): number {\n return ((value / 40075017) * 360) / Math.cos((Math.PI / 180) * this._latLng.lat);\n }\n\n /**\n * Get view angle from model.\n *\n * @param modelAngle - Model angle (radians).\n * @returns View angle from model (radians).\n */\n private _getViewAngleFromModel(modelAngle: number): number {\n return modelAngle - Math.PI / 2.0;\n }\n\n /**\n * Get leader shape points.\n *\n * @returns Points.\n */\n private _getLeaderShapePoints(): Point[] | undefined {\n if ((this._course === undefined) || (this._speed === undefined)\n || (this._shapeOptions === undefined) || (this._shapeOptions.leaderTime === undefined)) {\n return undefined;\n }\n const angle = this._getViewAngleFromModel(this._course);\n const leaderLength = this._speed * this._shapeOptions.leaderTime;\n const leaderEndLatLng = this._calcRelativeLatLng(this._latLng, leaderLength, angle);\n return this._latLngsToLayerPoints(this._latLng, leaderEndLatLng);\n }\n\n /**\n * Calculate relative lat/lng.\n *\n * @param latLng - LatLng.\n * @param distance - Distance (meters).\n * @param angle - Angle (radians).\n * @returns Calculated LatLng.\n */\n private _calcRelativeLatLng(latLng: LatLng, distance: number, angle: number): LatLng {\n return new LatLng(\n latLng.lat - this._getLatSizeOf(distance * Math.sin(angle)),\n latLng.lng + this._getLngSizeOf(distance * Math.cos(angle))\n );\n }\n\n /**\n * Convert LatLngs to map layer points.\n *\n * @param latLngs - LatLngs.\n * @returns Points.\n */\n private _latLngsToLayerPoints(...latLngs: LatLng[]): Point[] {\n return latLngs.map(latLng => this._map.latLngToLayerPoint(latLng));\n }\n\n /**\n * Gets the shape set.\n *\n * @returns The shape set.\n */\n private _getShapeSet(): ShapeSet {\n if ((this._shapeOptions.shapeSetEntries === undefined)\n || (this._shapeOptions.shapeSetEntries.length == 0)) {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n const zoomLevel = this._map.getZoom();\n const shapeSetEntriesFiltered = this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel)\n .filter(shapeSetEntry => zoomLevel >= shapeSetEntry.minZoomLevel);\n if (shapeSetEntriesFiltered.length > 0) {\n return shapeSetEntriesFiltered[0].shapeSet;\n } else {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n }\n\n /**\n * Gets the shape.\n *\n * @returns The shape.\n */\n private _getShape(): Shape {\n const shapeSet = this._getShapeSet();\n return (this._heading !== undefined) ? shapeSet.withHeading : shapeSet.withoutHeading;\n }\n\n /**\n * Get transformed shape points.\n *\n * @returns Transformed points and units.\n */\n private _getTransformedShapePoints(): [Points, Units] {\n const shape = this._getShape();\n let m = new Matrix();\n if (this._heading !== undefined) {\n const headingAngle = this._getViewAngleFromModel(this._heading);\n m = m.rotate(headingAngle);\n }\n if (shape.center !== undefined) {\n m = m.translate(-shape.center[0], -shape.center[1]);\n }\n m = m.scale(shape.length, shape.breadth);\n const points = shape.points.map(point => m.transform(point));\n return [points, shape.units];\n }\n\n /**\n * Get projected shape points.\n *\n * @returns Points projected to map layer.\n */\n private _getProjectedShapePoints(): Point[] {\n const [points, units] = this._getTransformedShapePoints();\n switch (units) {\n case \"pixels\": {\n const p = this._map.latLngToLayerPoint(this._latLng);\n const m = new Matrix().translate(p.x, p.y);\n return points.map(point => {\n const p1 = m.transform(point);\n return new Point(p1[0], p1[1]);\n });\n }\n case \"meters\": {\n return points.map(point => this._map.latLngToLayerPoint(\n new LatLng(\n this._latLng.lat - this._getLatSizeOf(point[1]),\n this._latLng.lng + this._getLngSizeOf(point[0])\n )\n ));\n }\n default:\n throw `unsupported units: ${units}`;\n }\n }\n\n /**\n * Converts points to an SVG path string.\n *\n * @param points - Points.\n * @param close - Close path.\n * @returns SVG path string.\n */\n private static _toSVGPath(points: Point[], close: boolean): string {\n let result = '';\n for (let i = 0; i < points.length; i++) {\n const point = points[i];\n if (result === '') {\n result = `M ${point.x} ${point.y} `;\n } else {\n result += `L ${point.x} ${point.y} `;\n }\n }\n if (close) {\n result += 'Z';\n }\n return result;\n }\n}\n","import {TrackSymbol} from '../trackSymbol';\nimport type {ShapeOptions} from '../options';\nimport type {Points, ShapeSet} from '../types';\nimport type {AISTrackSymbolOptions} from './options';\nimport type {Dimension, ETA, PositionReport, ShipStaticData} from './types';\nimport {DomUtil, Util} from 'leaflet';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_MIN_ZOOM_LEVEL = 14;\nconst DEFAULT_LEADER_TIME = 60;\nconst KNOTS_PER_METER_PER_SECOND = 1.944;\nconst MAX_SOG_EXCLUSIVE = 102.3;\nconst MAX_COG_EXCLUSIVE = 360;\nconst MAX_HEADING_EXCLUSIVE = 360;\n\ninterface ShipType {\n name: string;\n color: string;\n fillColor: string;\n}\n\nconst RESERVED_COLOR = \"#000000\";\nconst RESERVED_FILL_COLOR = \"#d3d3d3\";\nconst WIG_COLOR = \"#000000\";\nconst WIG_FILL_COLOR = \"#d3d3d3\";\nconst TYPE_3X_COLOR = \"#8b008b\";\nconst TYPE_3X_FILL_COLOR = \"#ff00ff\";\nconst HSC_COLOR = \"#00008b\";\nconst HSC_FILL_COLOR = \"#ffff00\";\nconst TYPE_5X_COLOR = \"#008b8b\";\nconst TYPE_5X_FILL_COLOR = \"#00ffff\";\nconst PASSENGER_COLOR = \"#00008b\";\nconst PASSENGER_FILL_COLOR = \"#0000ff\";\nconst CARGO_COLOR = \"#006400\";\nconst CARGO_FILL_COLOR = \"#90ee90\";\nconst TANKER_COLOR = \"#8b0000\";\nconst TANKER_FILL_COLOR = \"#ff0000\";\nconst OTHER_COLOR = \"#008b8b\";\nconst OTHER_FILL_COLOR = \"#00ffff\";\n\nconst TYPES: { [key: number]: ShipType } = {\n 0: newShipType('Not available', WIG_COLOR, WIG_FILL_COLOR),\n 20: newShipType('Wing in ground (WIG), all ships of this type', WIG_COLOR, WIG_FILL_COLOR),\n 21: newShipType('Wing in ground (WIG), Hazardous category A', WIG_COLOR, WIG_FILL_COLOR),\n 22: newShipType('Wing in ground (WIG), Hazardous category B', WIG_COLOR, WIG_FILL_COLOR),\n 23: newShipType('Wing in ground (WIG), Hazardous category C', WIG_COLOR, WIG_FILL_COLOR),\n 24: newShipType('Wing in ground (WIG), Hazardous category D', WIG_COLOR, WIG_FILL_COLOR),\n 25: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 26: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 27: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 28: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 29: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 30: newShipType('Fishing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 31: newShipType('Towing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 32: newShipType('Towing: length exceeds 200m or breadth exceeds 25m', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 33: newShipType('Dredging or underwater ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 34: newShipType('Diving ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 35: newShipType('Military ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 36: newShipType('Sailing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 37: newShipType('Pleasure Craft', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 40: newShipType('High speed craft (HSC), all ships of this type', HSC_COLOR, HSC_FILL_COLOR),\n 41: newShipType('High speed craft (HSC), Hazardous category A', HSC_COLOR, HSC_FILL_COLOR),\n 42: newShipType('High speed craft (HSC), Hazardous category B', HSC_COLOR, HSC_FILL_COLOR),\n 43: newShipType('High speed craft (HSC), Hazardous category C', HSC_COLOR, HSC_FILL_COLOR),\n 44: newShipType('High speed craft (HSC), Hazardous category D', HSC_COLOR, HSC_FILL_COLOR),\n 45: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 46: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 47: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 48: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 49: newShipType('High speed craft (HSC), No additional information', HSC_COLOR, HSC_FILL_COLOR),\n 50: newShipType('Pilot Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 51: newShipType('Search and Rescue vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 52: newShipType('Tug', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 53: newShipType('Port Tender', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 54: newShipType('Anti-pollution equipment', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 55: newShipType('Law Enforcement', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 56: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 57: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 58: newShipType('Medical Transport', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 59: newShipType('Noncombatant ship according to RR Resolution No. 18', '', ''),\n 60: newShipType('Passenger, all ships of this type', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 61: newShipType('Passenger, Hazardous category A', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 62: newShipType('Passenger, Hazardous category B', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 63: newShipType('Passenger, Hazardous category C', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 64: newShipType('Passenger, Hazardous category D', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 65: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 66: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 67: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 68: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 69: newShipType('Passenger, No additional information', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 70: newShipType('Cargo, all ships of this type', CARGO_COLOR, CARGO_FILL_COLOR),\n 71: newShipType('Cargo, Hazardous category A', CARGO_COLOR, CARGO_FILL_COLOR),\n 72: newShipType('Cargo, Hazardous category B', CARGO_COLOR, CARGO_FILL_COLOR),\n 73: newShipType('Cargo, Hazardous category C', CARGO_COLOR, CARGO_FILL_COLOR),\n 74: newShipType('Cargo, Hazardous category D', CARGO_COLOR, CARGO_FILL_COLOR),\n 75: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 76: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 77: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 78: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 79: newShipType('Cargo, No additional information', CARGO_COLOR, CARGO_FILL_COLOR),\n 80: newShipType('Tanker, all ships of this type', TANKER_COLOR, TANKER_FILL_COLOR),\n 81: newShipType('Tanker, Hazardous category A', TANKER_COLOR, TANKER_FILL_COLOR),\n 82: newShipType('Tanker, Hazardous category B', TANKER_COLOR, TANKER_FILL_COLOR),\n 83: newShipType('Tanker, Hazardous category C', TANKER_COLOR, TANKER_FILL_COLOR),\n 84: newShipType('Tanker, Hazardous category D', TANKER_COLOR, TANKER_FILL_COLOR),\n 85: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 86: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 87: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 88: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 89: newShipType('Tanker, No additional information', TANKER_COLOR, TANKER_FILL_COLOR),\n 90: newShipType('Other Type, all ships of this type', OTHER_COLOR, OTHER_FILL_COLOR),\n 91: newShipType('Other Type, Hazardous category A', OTHER_COLOR, OTHER_FILL_COLOR),\n 92: newShipType('Other Type, Hazardous category B', OTHER_COLOR, OTHER_FILL_COLOR),\n 93: newShipType('Other Type, Hazardous category C', OTHER_COLOR, OTHER_FILL_COLOR),\n 94: newShipType('Other Type, Hazardous category D', OTHER_COLOR, OTHER_FILL_COLOR),\n 95: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 96: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 97: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 98: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 99: newShipType('Other Type, no additional information', OTHER_COLOR, OTHER_FILL_COLOR),\n};\nconst RESERVED_TYPE = newShipType('Reserved', RESERVED_COLOR, RESERVED_FILL_COLOR);\nconst UNKNOWN_TYPE = newShipType('Unknown', RESERVED_COLOR, RESERVED_FILL_COLOR);\n\nexport class AISTrackSymbol\n extends TrackSymbol {\n\n /** Default silhouette shape points. */\n public static DEFAULT_SILHOUETTE_SHAPE_POINTS: Points = [[1, 0.5], [0.75, 1], [0, 1], [0, 0], [0.75, 0]];\n\n private readonly _leaderTime: number;\n private readonly _minZoomLevel: number;\n private readonly _size: number;\n private _positionReport: PositionReport;\n private _shipStaticData?: ShipStaticData;\n\n /**\n * AISTrackSymbol constructor.\n *\n * @param positionReport - Position report.\n * @param options - Options.\n */\n constructor(positionReport: PositionReport, options?: AISTrackSymbolOptions) {\n super([positionReport.latitude, positionReport.longitude], options);\n\n Util.setOptions(this, options);\n options = options || {};\n this._leaderTime = options.leaderTime || DEFAULT_LEADER_TIME;\n this._minZoomLevel = options.minZoomLevel || DEFAULT_MIN_ZOOM_LEVEL;\n this._size = options.size || DEFAULT_SIZE;\n this._positionReport = positionReport;\n this.setPositionReport(positionReport);\n this.setShipStaticData(options.shipStaticData);\n }\n\n /**\n * Get ETA from Date.\n *\n * @param date - Date.\n * @returns ETA\n */\n public static etaFromDate(date: Date | null | undefined): ETA | undefined {\n if ((date === null) || (date === undefined)) {\n return undefined;\n }\n return {\n month: date.getMonth() + 1,\n day: date.getDate(),\n hour: date.getHours(),\n minute: date.getMinutes(),\n }\n }\n\n /**\n * Sets the position report.\n *\n * @param positionReport - Position report.\n * @returns this\n */\n public setPositionReport(positionReport: PositionReport): this {\n this._positionReport = positionReport;\n this.setLatLng([positionReport.latitude, positionReport.longitude]);\n if ((positionReport.trueHeading !== null) && (positionReport.trueHeading !== undefined) && (positionReport.trueHeading < MAX_HEADING_EXCLUSIVE)) {\n this.setHeading(toRadians(positionReport.trueHeading));\n } else {\n this.setHeading(undefined);\n }\n if ((positionReport.cog !== null) && (positionReport.cog !== undefined) && (positionReport.cog < MAX_COG_EXCLUSIVE)) {\n this.setCourse(toRadians(positionReport.cog));\n } else {\n this.setCourse(undefined);\n }\n if ((positionReport.sog !== null) && (positionReport.sog !== undefined) && (positionReport.sog < MAX_SOG_EXCLUSIVE)) {\n this.setSpeed(positionReport.sog / KNOTS_PER_METER_PER_SECOND);\n } else {\n this.setSpeed(undefined);\n }\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.redraw();\n }\n\n /**\n * Sets the ship static data.\n *\n * @param shipStaticData - Ship static data.\n * @returns this\n */\n public setShipStaticData(shipStaticData?: ShipStaticData): this {\n this._shipStaticData = shipStaticData;\n const shipType = getShipType((shipStaticData !== null) && (shipStaticData !== undefined) ? shipStaticData.type : undefined);\n this.setStyle({\n color: shipType.color,\n fill: true,\n fillOpacity: 1.0,\n fillColor: shipType.fillColor,\n });\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.setShapeOptions(AISTrackSymbol._getShapeOptions(this._leaderTime, this._minZoomLevel, this._size,\n shipStaticData));\n }\n\n private static _getShapeOptions(leaderTime: number, minZoomLevel: number, size: number,\n shipStaticData?: ShipStaticData): ShapeOptions {\n const shapeOptions: ShapeOptions = {\n leaderTime: leaderTime,\n defaultShapeSet: TrackSymbol.createShapeSet(size),\n };\n const shapeSet = AISTrackSymbol._getShapeSet(size, shipStaticData);\n if (shapeSet !== null) {\n shapeOptions.shapeSetEntries = [{\n shapeSet: shapeSet,\n minZoomLevel: minZoomLevel,\n }];\n }\n return shapeOptions;\n }\n\n private static _getShapeSet(size: number, shipStaticData?: ShipStaticData): ShapeSet | null {\n if ((shipStaticData === null) || (shipStaticData === undefined)\n || (shipStaticData.dimension === null) || (shipStaticData.dimension === undefined)\n || !isDimensionValid(shipStaticData.dimension)) {\n return null;\n }\n return {\n withHeading: {\n points: AISTrackSymbol.DEFAULT_SILHOUETTE_SHAPE_POINTS,\n center: [shipStaticData.dimension.B, shipStaticData.dimension.D],\n length: shipStaticData.dimension.A + shipStaticData.dimension.B,\n breadth: shipStaticData.dimension.C + shipStaticData.dimension.D,\n units: \"meters\",\n },\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n private _getPopupContent(positionReport?: PositionReport, shipStaticData?: ShipStaticData): HTMLElement {\n let content = \"\";\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"User ID\", shipStaticData.userId);\n content += createTableRow(\"IMO Number\", shipStaticData.imoNumber);\n content += createTableRow(\"Call sign\", shipStaticData.callSign);\n content += createTableRow(\"Name\", shipStaticData.name);\n }\n if ((positionReport !== null) && (positionReport !== undefined)) {\n content += createTableRow(\"Location\", `${toFixed(positionReport.latitude, 5)}, ${toFixed(positionReport.longitude, 5)}`);\n content += createTableRow(\"SOG\",\n toFixed(positionReport.sog, 2, v => v < MAX_SOG_EXCLUSIVE), \"knots\");\n content += createTableRow(\"COG\",\n toFixed(positionReport.cog, 1), \"°\");\n content += createTableRow(\"Heading\",\n toFixed(positionReport.trueHeading, 1), \"°\");\n content += createTableRow(\"Navigation status\",\n toNavigationStatusString(positionReport.navigationalStatus));\n }\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"Type\", toTypeString(shipStaticData.type));\n if ((shipStaticData.dimension !== null) && (shipStaticData.dimension !== undefined)\n && isDimensionValid(shipStaticData.dimension)) {\n content += createTableRow(\"Ship length\",\n shipStaticData.dimension.A + shipStaticData.dimension.B, \"m\");\n content += createTableRow(\"Ship width\",\n shipStaticData.dimension.C + shipStaticData.dimension.D, \"m\");\n }\n content += createTableRow(\"Fix type\", toFixTypeString(shipStaticData.fixType));\n content += createTableRow(\"ETA\", toETAString(shipStaticData.eta));\n content += createTableRow(\"Maximum static draught\",\n toFixed(shipStaticData.maximumStaticDraught, 1), \"m\");\n content += createTableRow(\"Destination\", shipStaticData.destination);\n content += createTableRow(\"DTE\", shipStaticData.dte);\n }\n content += \"
\";\n const popupContent = DomUtil.create(\"div\");\n popupContent.innerHTML = content;\n return popupContent;\n }\n}\n\nfunction toFixed(v: number | null | undefined, fractionDigits?: number, isValid?: (v: number) => boolean): string | undefined {\n if ((v === null) || (v === undefined)) {\n return undefined;\n }\n if (isValid && !isValid(v)) {\n return undefined;\n }\n return v.toFixed(fractionDigits);\n}\n\nfunction toTypeString(type: number | null | undefined): string | undefined {\n if ((type === null) || (type === undefined)) {\n return undefined;\n }\n const shipType = getShipType(type);\n return shipType.name;\n}\n\nfunction toFixTypeString(fixType: number | null | undefined): string | undefined {\n if ((fixType === null) || (fixType === undefined)) {\n return undefined;\n }\n switch (fixType) {\n case 0:\n return undefined;\n case 1:\n return 'GPS';\n case 2:\n return 'GLONASS';\n case 3:\n return 'combined GPS/GLONASS';\n case 4:\n return 'Loran-C';\n case 5:\n return 'Chayka';\n case 6:\n return 'integrated navigation system';\n case 7:\n return 'surveyed';\n case 8:\n return 'Galileo';\n case 9:\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n return `not used (${fixType})`;\n case 15:\n return \"internal GNSS\";\n default:\n return `unknown (${fixType})`;\n }\n}\n\nfunction toNavigationStatusString(navigationStatus: number | null | undefined): string | undefined {\n if ((navigationStatus === null) || (navigationStatus === undefined)) {\n return undefined;\n }\n switch (navigationStatus) {\n case 0:\n return 'Under way using engine';\n case 1:\n return 'At anchor';\n case 2:\n return 'Not under command';\n case 3:\n return 'Restricted manoeuverability';\n case 4:\n return 'Constrained by her draught';\n case 5:\n return 'Moored';\n case 6:\n return 'Aground';\n case 7:\n return 'Engaged in Fishing';\n case 8:\n return 'Under way sailing';\n case 9:\n return 'Reserved for future amendment of Navigational Status for HSC';\n case 10:\n return 'Reserved for future amendment of Navigational Status for WIG';\n case 11:\n return 'Reserved for future use';\n case 12:\n return 'Reserved for future use';\n case 13:\n return 'Reserved for future use';\n case 14:\n return 'AIS-SART is active';\n case 15:\n return 'Not defined (default)';\n default:\n return `unknown (${navigationStatus})`;\n }\n}\n\nfunction toETAString(eta: ETA | null | undefined): string | undefined {\n if ((eta === null) || (eta === undefined)) {\n return undefined;\n }\n const parts: string[] = [];\n if (!isNullOrUndefined(eta.month) && !isNullOrUndefined(eta.day)) {\n parts.push(`${eta.month.toString().padStart(2, '0')}/${eta.day.toString().padStart(2, '0')}`);\n }\n if (!isNullOrUndefined(eta.hour) && !isNullOrUndefined(eta.minute)) {\n parts.push(`${eta.hour.toString().padStart(2, '0')}:${eta.minute.toString().padStart(2, '0')}`);\n }\n if (parts.length === 0) {\n return undefined;\n }\n return `${parts.join(' ')} UTC`;\n}\n\nfunction toRadians(degs: number | null | undefined): number | undefined {\n if ((degs === null) || (degs === undefined)) {\n return undefined;\n }\n return degs * Math.PI / 180;\n}\n\nfunction isNullOrUndefined(v: any): boolean {\n return (v === null) || (v === undefined);\n}\n\nfunction isDimensionValid(dimension: Dimension | null | undefined): boolean {\n return (dimension !== null) && (dimension !== undefined)\n && (dimension.A > 0) && (dimension.B > 0) && (dimension.C > 0) && (dimension.D > 0);\n}\n\nfunction createTableRow(name: string, value: any, unit?: string): string {\n if ((value === null) || (value === undefined)) {\n return '';\n }\n const sValue = String(value);\n return `${name}${sValue} ${isNullOrUndefined(unit) ? \"\" : unit}`;\n}\n\nfunction newShipType(name: string, color: string, fillColor: string): ShipType {\n return {\n name: name,\n color: color,\n fillColor: fillColor,\n };\n}\n\nfunction getShipType(type: number | null | undefined): ShipType {\n if ((type === null) || (type === undefined)) {\n return TYPES[0];\n }\n if ((type < 0) || (type > 99)) {\n return UNKNOWN_TYPE;\n }\n const shipType = TYPES[type];\n if (!isNullOrUndefined(shipType)) {\n return shipType;\n }\n return RESERVED_TYPE;\n}\n","//@ts-strict-ignore\nimport L from 'leaflet';\nimport type {LatLngExpression} from 'leaflet';\nimport {TrackSymbol} from './trackSymbol';\nimport type {ShapeSetEntry, ShapeOptions, TrackSymbolOptions} from './options';\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport {AISTrackSymbol} from './ais/aisTrackSymbol';\nimport type {AISTrackSymbolOptions} from './ais/options';\nimport type {AISMessage, Dimension, ETA, PositionReport, ShipStaticData} from './ais/types';\n\nexport {\n Points,\n Shape,\n ShapeOptions,\n ShapeSet,\n ShapeSetEntry,\n TrackSymbol,\n TrackSymbolOptions,\n Units,\n};\n\nexport {\n AISMessage,\n AISTrackSymbol,\n AISTrackSymbolOptions,\n Dimension,\n ETA,\n PositionReport,\n ShipStaticData,\n};\n\nL['trackSymbol'] = function(latLng: LatLngExpression, options?: TrackSymbolOptions): TrackSymbol {\n return new TrackSymbol(latLng, options);\n}\nL['TrackSymbol'] = TrackSymbol;\n\nL['aisTrackSymbol'] = function(positionReport: PositionReport, options?: AISTrackSymbolOptions): AISTrackSymbol {\n return new AISTrackSymbol(positionReport, options);\n}\nL['AISTrackSymbol'] = AISTrackSymbol;\n\nexport default TrackSymbol;\n"],"names":["ORIENTATION","PIx2","INSIDE$2","OUTSIDE$1","BOUNDARY$1","CONTAINS","INTERLACE","OVERLAP_SAME$1","OVERLAP_OPPOSITE$1","NOT_VERTEX$1","START_VERTEX$1","END_VERTEX$1","Constants","DP_TOL","setTolerance","tolerance","getTolerance","DECIMALS","EQ_0","x","EQ","y","GT","GE","LT","LE","Utils$1","Flatten","c","value","Errors","LinkedList","first","last","counter","edge","start","end","elements","from","to","element","newElement","elementBefore","elementAfter","controlEdge","addToIntPoints","pt","int_points","id","shapes","len","is_vertex","arc_length","sortIntersections","intersections","getSortedArray","faceMap","ip","compareFn","ip1","ip2","filterDuplicatedIntersections","do_squeeze","int_point_ref1","int_point_ref2","int_point_cur1","int_point_cur2","i","j","int_point","index","initializeInclusionFlags","calculateInclusionFlags","polygon","setOverlappingFlags","cur_face","first_int_point_in_face_id","next_int_point1","num_int_points","cur_int_point1","int_points_cur_pool_start","int_points_cur_pool_num","intPointsPoolCount","next_int_point_id","int_points_next_pool_num","next_int_point1_tmp","edge_from1","edge_to1","cur_int_point2","next_int_point2","edge_from2","edge_to2","cur_int_point_num","int_point_current","int_point_next","int_points_pool_num","splitByIntersections","newEdge","insertBetweenIntPoints","int_point1","int_point2","new_edges","edge_before","edge_after","INSIDE$1","OUTSIDE","BOUNDARY","OVERLAP_SAME","OVERLAP_OPPOSITE","NOT_VERTEX","START_VERTEX","END_VERTEX","BOOLEAN_UNION","BOOLEAN_INTERSECT","BOOLEAN_SUBTRACT","unify","polygon1","polygon2","res_poly","wrk_poly","booleanOpBinary","subtract","polygon2_reversed","intersect$1","innerClip","clip_shapes1","face","clip_shapes2","outerClip","calculateIntersections","getIntersections","ip_sorted1","ip_sorted2","filterNotRelevantEdges","op","notIntersectedFacesRes","getNotIntersectedFaces","notIntersectedFacesWrk","calcInclusionForNotIntersectedFaces","fixBoundaryConflicts","removeNotRelevantChains","removeNotRelevantNotIntersectedFaces","swapLinksAndRestore","copyWrkToRes","swapLinks","removeOldFaces","restoreFaces","restore","edge1","resp","edge2","poly","notIntersected","notIntersectedFaces","poly2","poly1","int_points1","int_points1_sorted","int_points2","iterate_more","edge_tmp","new_bv","dist","segment","newEdge1","int_point2_edge_after","newEdge2","is_res_polygon","first_int_point_in_face_num","int_points_from_pull_start","int_points_from_pull_num","next_int_point_num","int_points_to_pull_start","int_points_to_pull_num","edge_from","edge_to","k","res_polygon","wrk_polygon","other_int_points","int_point_tmp","rel","BooleanOperations","EQUAL","INTERSECT","TOUCH","INSIDE","COVERED","DE9IM","geom","e","intersectLine2Line","line1","line2","A1","B1","C1","A2","B2","C2","det","detX","detY","intersectLine2Circle","line","circle","prj","delta","v_trans","intersectLine2Box","box","ips","seg","ips_tmp","intersectSegment2Line","ptInIntPoints","intersectLine2Arc","arc","ip_tmp","intersectSegment2Segment","seg1","seg2","new_ip","isPointInSegmentBox","point","intersectSegment2Circle","_","intersectSegment2Arc","intersectSegment2Box","intersectCircle2Circle","circle1","circle2","vec","r1","r2","a","mid_pt","h","intersectCircle2Box","intersectArc2Arc","arc1","arc2","intersectArc2Circle","intersectArc2Box","intersectEdge2Segment","intersectEdge2Arc","intersectEdge2Line","intersectEdge2Ray","ray","intersectRay2Segment","intersectRay2Arc","intersectEdge2Circle","intersectSegment2Polygon","intersectArc2Polygon","intersectLine2Polygon","intersectCircle2Polygon","intersectEdge2Edge","intersectEdge2Polygon","resp_edges","resp_edge","intersectPolygon2Polygon","intersectShape2Polygon","shape","new_pt","createLineFromRay","intersectRay2Circle","intersectRay2Box","intersectRay2Line","intersectRay2Ray","ray1","ray2","intersectRay2Polygon","defaultAttributes","SVGAttributes","args","property","acc","key","SVGKey","str","convertToString","attrs","Multiline","v","edgeBefore","edgeFrom","edgeTo","edges","edgeFound","angle","center","matrix","svgStr","multiline","ray_shoot","contains","searchBox","i1","i2","intersection","prev_edge","prev_tangent","prev_point","cur_tangent","cur_point","prev_on_the_left","cur_on_the_left","next_edge","next_tangent","next_point","next_on_the_left","equal","shape1","shape2","relate","intersect","touch","disjoint","inside","covered","contain","cover","relateLine2Line","relateLine2Circle","relateLine2Box","relateLine2Polygon","relateShape2Polygon","relatePolygon2Polygon","denim","ip_sorted","splitShapes","boolean_intersection","boolean_difference1","boolean_difference2","inner_clip_shapes1","inner_clip_shapes2","outer_clip_shapes1","outer_clip_shapes2","Relations","Matrix$1","Matrix","b","d","tx","ty","vector","other_matrix","centerX","centerY","cos","sin","sx","sy","Interval","low","high","other_interval","interval1","interval2","val1","val2","RB_TREE_COLOR_RED","RB_TREE_COLOR_BLACK","Node","left","right","parent","color","other_node","comparable_max","search_node","comparable_less_than","IntervalTree","count","res","node","insert_node","delete_node","interval","outputMapperFn","resp_nodes","visitor","callback","tree","node_current","current_node","parent_node","uncle_node","cut_node","fix_node","brother_node","found","node_min","node_max","node_successor","action","height","heightLeft","heightRight","PlanarSet","entry","size","deleted","Shape","Point$1","Point","arr","m","proj_vec","dx","dy","r","Vector$1","a1","a2","scalar","norm1","norm2","n","vector$1","Segment","coords","ps","pe","shortest_segment","length","factor","rest","ymin","dy1","dy2","pts","Line$1","Line","norm","A","B","C","other_line","distance","sorted_points","pt1","pt2","Circle$1","pc","counterclockwise","Arc","startAngle","endAngle","counterClockwise","sweep","test_arc","func_arcs_array","angles","test_arcs","prev_arc","new_arc","newStart","newEnd","newCenter","newDirection","onLeftSide","areaTrapez","areaCircularSegment","slope1","slope2","largeArcFlag","sweepFlag","Box","xmin","xmax","ymax","other_box","box1","box2","new_box","vertex","width","Edge","bvMiddle","flag","sign","halfArc1","halfArc2","CircularLinkedList","done","Face","segments","points","flattenShapes","flattenShape","sArea","area","exitOnFirst","Ray","slope","Polygon","argsArray","loop","el","loop1","valid","signedArea","unassignedEdgeFound","edge_next","newPoly","int_point1_prev","int_point1_curr","newEdges","polygons","orientation","newPolygons","islandPolygon","min_dist_and_segment","min_stop","newPolygon","Circle","Vector","Utils","Inversion","inversion_circle","k2","len2","s","inversion","Distance","closest_point","dist2center","shortest_dist","v_seg","v_ps2pt","v_pe2pt","start_sp","end_sp","v_unit","dist_and_segment","dist_tmp","shortest_segment_tmp","dist_from_start","shortest_segment_from_start","dist_from_end","shortest_segment_from_end","dist_from_center","shortest_segment_from_center","dist_from_projection","shortest_segment_from_projection","segment_tmp","mindist_x","mindist_y","mindist","maxdist","level","new_level_left","new_level_right","new_level","set","squared_min_stop","min_dist_and_segment_new","stop","d1","d2","DEFAULT_SIZE","DEFAULT_LEADER_TIME","_TrackSymbol","Path","latLng","options","Util","L","bounds","Bounds","LatLngBounds","paths","viewPath","shapeOptions","oldLatLng","heading","course","speed","modelAngle","leaderLength","leaderEndLatLng","LatLng","latLngs","zoomLevel","shapeSetEntriesFiltered","shapeSetEntry","shapeSet","headingAngle","units","p","p1","close","result","TrackSymbol","DEFAULT_MIN_ZOOM_LEVEL","KNOTS_PER_METER_PER_SECOND","MAX_SOG_EXCLUSIVE","MAX_COG_EXCLUSIVE","MAX_HEADING_EXCLUSIVE","RESERVED_COLOR","RESERVED_FILL_COLOR","WIG_COLOR","WIG_FILL_COLOR","TYPE_3X_COLOR","TYPE_3X_FILL_COLOR","HSC_COLOR","HSC_FILL_COLOR","TYPE_5X_COLOR","TYPE_5X_FILL_COLOR","PASSENGER_COLOR","PASSENGER_FILL_COLOR","CARGO_COLOR","CARGO_FILL_COLOR","TANKER_COLOR","TANKER_FILL_COLOR","OTHER_COLOR","OTHER_FILL_COLOR","TYPES","newShipType","RESERVED_TYPE","UNKNOWN_TYPE","_AISTrackSymbol","positionReport","date","toRadians","shipStaticData","shipType","getShipType","leaderTime","minZoomLevel","isDimensionValid","content","createTableRow","toFixed","toNavigationStatusString","toTypeString","toFixTypeString","toETAString","popupContent","DomUtil","AISTrackSymbol","fractionDigits","isValid","type","fixType","navigationStatus","eta","parts","isNullOrUndefined","degs","dimension","name","unit","sValue","fillColor"],"mappings":"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","x_google_ignoreList":[0]} \ No newline at end of file +{"version":3,"file":"leaflet-tracksymbol2.umd.js","sources":["../node_modules/.pnpm/@flatten-js+core@1.5.2/node_modules/@flatten-js/core/dist/main.mjs","../src/trackSymbol.ts","../src/ais/aisTrackSymbol.ts","../src/index.ts"],"sourcesContent":["/**\n * Global constant CCW defines counterclockwise direction of arc\n * @type {boolean}\n */\nconst CCW = true;\n\n/**\n * Global constant CW defines clockwise direction of arc\n * @type {boolean}\n */\nconst CW = false;\n\n/**\n * Defines orientation for face of the polygon: clockwise, counterclockwise\n * or not orientable in the case of self-intersection\n * @type {{CW: number, CCW: number, NOT_ORIENTABLE: number}}\n */\nconst ORIENTATION = {CCW:-1, CW:1, NOT_ORIENTABLE: 0};\n\nconst PIx2 = 2 * Math.PI;\n\nconst INSIDE$2 = 1;\nconst OUTSIDE$1 = 0;\nconst BOUNDARY$1 = 2;\nconst CONTAINS = 3;\nconst INTERLACE = 4;\n\nconst OVERLAP_SAME$1 = 1;\nconst OVERLAP_OPPOSITE$1 = 2;\n\nconst NOT_VERTEX$1 = 0;\nconst START_VERTEX$1 = 1;\nconst END_VERTEX$1 = 2;\n\nvar Constants = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOUNDARY: BOUNDARY$1,\n CCW: CCW,\n CONTAINS: CONTAINS,\n CW: CW,\n END_VERTEX: END_VERTEX$1,\n INSIDE: INSIDE$2,\n INTERLACE: INTERLACE,\n NOT_VERTEX: NOT_VERTEX$1,\n ORIENTATION: ORIENTATION,\n OUTSIDE: OUTSIDE$1,\n OVERLAP_OPPOSITE: OVERLAP_OPPOSITE$1,\n OVERLAP_SAME: OVERLAP_SAME$1,\n PIx2: PIx2,\n START_VERTEX: START_VERTEX$1\n});\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n/**\n * Floating point comparison tolerance.\n * Default value is 0.000001 (10e-6)\n * @type {number}\n */\nlet DP_TOL = 0.000001;\n\n/**\n * Set new floating point comparison tolerance\n * @param {number} tolerance\n */\nfunction setTolerance(tolerance) {DP_TOL = tolerance;}\n\n/**\n * Get floating point comparison tolerance\n * @returns {number}\n */\nfunction getTolerance() {return DP_TOL;}\n\nconst DECIMALS = 3;\n\n/**\n * Returns *true* if value comparable to zero\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ_0(x) {\n return (x < DP_TOL && x > -DP_TOL);\n}\n\n/**\n * Returns *true* if two values are equal up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction EQ(x, y) {\n return (x - y < DP_TOL && x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction GT(x, y) {\n return (x - y > DP_TOL);\n}\n\n/**\n * Returns *true* if first argument greater than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @returns {boolean}\n */\nfunction GE(x, y) {\n return (x - y > -DP_TOL);\n}\n\n/**\n * Returns *true* if first argument less than second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LT(x, y) {\n return (x - y < -DP_TOL)\n}\n\n/**\n * Returns *true* if first argument less than or equal to second argument up to DP_TOL\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction LE(x, y) {\n return (x - y < DP_TOL);\n}\n\nvar Utils$1 = /*#__PURE__*/Object.freeze({\n __proto__: null,\n DECIMALS: DECIMALS,\n EQ: EQ,\n EQ_0: EQ_0,\n GE: GE,\n GT: GT,\n LE: LE,\n LT: LT,\n getTolerance: getTolerance,\n setTolerance: setTolerance\n});\n\nlet Flatten = {\n Utils: Utils$1,\n Errors: undefined,\n Matrix: undefined,\n Planar_set: undefined,\n Point: undefined,\n Vector: undefined,\n Line: undefined,\n Circle: undefined,\n Segment: undefined,\n Arc: undefined,\n Box: undefined,\n Edge: undefined,\n Face: undefined,\n Ray: undefined,\n Ray_shooting: undefined,\n Multiline: undefined,\n Polygon: undefined,\n Distance: undefined,\n Inversion: undefined\n};\n\nfor (let c in Constants) {Flatten[c] = Constants[c];}\n\nObject.defineProperty(Flatten, 'DP_TOL', {\n get:function(){return getTolerance()}, \n set:function(value){setTolerance(value);}\n});\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class of system errors\n */\nclass Errors {\n /**\n * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter\n * @returns {ReferenceError}\n */\n static get ILLEGAL_PARAMETERS() {\n return new ReferenceError('Illegal Parameters');\n }\n\n /**\n * Throw error ZERO_DIVISION to catch situation of zero division\n * @returns {Error}\n */\n static get ZERO_DIVISION() {\n return new Error('Zero division');\n }\n\n /**\n * Error to throw from BooleanOperations module in case when fixBoundaryConflicts not capable to fix it\n * @returns {Error}\n */\n static get UNRESOLVED_BOUNDARY_CONFLICT() {\n return new Error('Unresolved boundary conflict in boolean operation');\n }\n\n /**\n * Error to throw from LinkedList:testInfiniteLoop static method\n * in case when circular loop detected in linked list\n * @returns {Error}\n */\n static get INFINITE_LOOP() {\n return new Error('Infinite loop');\n }\n\n static get CANNOT_COMPLETE_BOOLEAN_OPERATION() {\n return new Error('Cannot complete boolean operation')\n }\n\n static get CANNOT_INVOKE_ABSTRACT_METHOD() {\n return new Error('Abstract method cannot be invoked');\n }\n\n static get OPERATION_IS_NOT_SUPPORTED() {\n return new Error('Operation is not supported')\n }\n}\n\nFlatten.Errors = Errors;\n\n/**\n * Class implements bidirectional non-circular linked list.
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass LinkedList {\n constructor(first, last) {\n this.first = first;\n this.last = last || this.first;\n }\n\n [Symbol.iterator]() {\n let value = undefined;\n return {\n next: () => {\n value = value ? value.next : this.first;\n return {value: value, done: value === undefined};\n }\n };\n };\n\n /**\n * Return number of elements in the list\n * @returns {number}\n */\n get size() {\n let counter = 0;\n for (let edge of this) {\n counter++;\n }\n return counter;\n }\n\n /**\n * Return array of elements from start to end,\n * If start or end not defined, take first as start, last as end\n * @returns {Array}\n */\n toArray(start=undefined, end=undefined) {\n let elements = [];\n let from = start || this.first;\n let to = end || this.last;\n let element = from;\n if (element === undefined) return elements;\n do {\n elements.push(element);\n element = element.next;\n } while (element !== to.next);\n return elements;\n }\n\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n append(element) {\n if (this.isEmpty()) {\n this.first = element;\n } else {\n element.prev = this.last;\n this.last.next = element;\n }\n\n // update edge to be last\n this.last = element;\n\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement\n * @param {LinkedListElement} elementBefore\n * @returns {LinkedList}\n */\n insert(newElement, elementBefore) {\n if (this.isEmpty()) {\n this.first = newElement;\n this.last = newElement;\n }\n else if (elementBefore === null || elementBefore === undefined) {\n newElement.next = this.first;\n this.first.prev = newElement;\n this.first = newElement;\n }\n else {\n /* set links to new element */\n let elementAfter = elementBefore.next;\n elementBefore.next = newElement;\n if (elementAfter) elementAfter.prev = newElement;\n\n /* set links from new element */\n newElement.prev = elementBefore;\n newElement.next = elementAfter;\n\n /* extend list if new element added after the last element */\n if (this.last === elementBefore)\n this.last = newElement;\n }\n // nullify non-circular links\n this.last.next = undefined;\n this.first.prev = undefined;\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element\n * @returns {LinkedList}\n */\n remove(element) {\n // special case if last edge removed\n if (element === this.first && element === this.last) {\n this.first = undefined;\n this.last = undefined;\n } else {\n // update linked list\n if (element.prev) element.prev.next = element.next;\n if (element.next) element.next.prev = element.prev;\n // update first if need\n if (element === this.first) {\n this.first = element.next;\n }\n // update last if need\n if (element === this.last) {\n this.last = element.prev;\n }\n }\n return this;\n }\n\n /**\n * Return true if list is empty\n * @returns {boolean}\n */\n isEmpty() {\n return this.first === undefined;\n }\n\n /**\n * Throw an error if circular loop detected in the linked list\n * @param {LinkedListElement} first element to start iteration\n * @throws {Errors.INFINITE_LOOP}\n */\n static testInfiniteLoop(first) {\n let edge = first;\n let controlEdge = first;\n do {\n if (edge != first && edge === controlEdge) {\n throw Errors.INFINITE_LOOP; // new Error(\"Infinite loop\")\n }\n edge = edge.next;\n controlEdge = controlEdge.next.next;\n } while (edge != first)\n }\n}\n\n/*\n Smart intersections describe intersection points that refers to the edges they intersect\n This function are supposed for internal usage by morphing and relation methods between\n */\n\nfunction addToIntPoints(edge, pt, int_points)\n{\n let id = int_points.length;\n let shapes = edge.shape.split(pt);\n\n // if (shapes.length < 2) return;\n if (shapes.length === 0) return; // Point does not belong to edge ?\n\n let len = 0;\n if (shapes[0] === null) { // point incident to edge start vertex\n len = 0;\n }\n else if (shapes[1] === null) { // point incident to edge end vertex\n len = edge.shape.length;\n }\n else { // Edge was split into to edges\n len = shapes[0].length;\n }\n\n let is_vertex = NOT_VERTEX$1;\n if (EQ(len, 0)) {\n is_vertex |= START_VERTEX$1;\n }\n if (EQ(len, edge.shape.length)) {\n is_vertex |= END_VERTEX$1;\n }\n // Fix intersection point which is end point of the last edge\n let arc_length;\n if (len === Infinity) {\n arc_length = shapes[0].coord(pt);\n }\n else {\n arc_length = (is_vertex & END_VERTEX$1) && edge.next && edge.next.arc_length === 0 ?\n 0 :\n edge.arc_length + len;\n }\n\n int_points.push({\n id: id,\n pt: pt,\n arc_length: arc_length,\n edge_before: edge,\n edge_after: undefined,\n face: edge.face,\n is_vertex: is_vertex\n });\n}\n\nfunction sortIntersections(intersections)\n{\n // if (intersections.int_points1.length === 0) return;\n\n // augment intersections with new sorted arrays\n // intersections.int_points1_sorted = intersections.int_points1.slice().sort(compareFn);\n // intersections.int_points2_sorted = intersections.int_points2.slice().sort(compareFn);\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n}\n\nfunction getSortedArray(int_points)\n{\n let faceMap = new Map;\n let id = 0;\n // Create integer id's for faces\n for (let ip of int_points) {\n if (!faceMap.has(ip.face)) {\n faceMap.set(ip.face, id);\n id++;\n }\n }\n // Augment intersection points with face id's\n for (let ip of int_points) {\n ip.faceId = faceMap.get(ip.face);\n }\n // Clone and sort\n let int_points_sorted = int_points.slice().sort(compareFn);\n return int_points_sorted;\n}\n\nfunction compareFn(ip1, ip2)\n{\n // compare face id's\n if (ip1.faceId < ip2.faceId) {\n return -1;\n }\n if (ip1.faceId > ip2.faceId) {\n return 1;\n }\n // same face - compare arc_length\n if (ip1.arc_length < ip2.arc_length) {\n return -1;\n }\n if (ip1.arc_length > ip2.arc_length) {\n return 1;\n }\n return 0;\n}\n\n// export function getSortedArrayOnLine(line, int_points) {\n// return int_points.slice().sort( (int_point1, int_point2) => {\n// if (line.coord(int_point1.pt) < line.coord(int_point2.pt)) {\n// return -1;\n// }\n// if (line.coord(int_point1.pt) > line.coord(int_point2.pt)) {\n// return 1;\n// }\n// return 0;\n// })\n// }\n\nfunction filterDuplicatedIntersections(intersections)\n{\n if (intersections.int_points1.length < 2) return;\n\n let do_squeeze = false;\n\n let int_point_ref1;\n let int_point_ref2;\n let int_point_cur1;\n let int_point_cur2;\n for (let i = 0; i < intersections.int_points1_sorted.length; i++) {\n\n if (intersections.int_points1_sorted[i].id === -1)\n continue;\n\n int_point_ref1 = intersections.int_points1_sorted[i];\n int_point_ref2 = intersections.int_points2[int_point_ref1.id];\n\n for (let j=i+1; j < intersections.int_points1_sorted.length; j++) {\n int_point_cur1 = intersections.int_points1_sorted[j];\n if (!EQ(int_point_cur1.arc_length, int_point_ref1.arc_length)) {\n break;\n }\n if (int_point_cur1.id === -1)\n continue;\n int_point_cur2 = intersections.int_points2[int_point_cur1.id];\n if (int_point_cur2.id === -1)\n continue;\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n }\n\n int_point_ref2 = intersections.int_points2_sorted[0];\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n for (let i = 1; i < intersections.int_points2_sorted.length; i++) {\n let int_point_cur2 = intersections.int_points2_sorted[i];\n\n if (int_point_cur2.id === -1) continue;\n /* already deleted */\n\n if (int_point_ref2.id === -1 || /* can't be reference if already deleted */\n !(EQ(int_point_cur2.arc_length, int_point_ref2.arc_length))) {\n int_point_ref2 = int_point_cur2;\n int_point_ref1 = intersections.int_points1[int_point_ref2.id];\n continue;\n }\n\n let int_point_cur1 = intersections.int_points1[int_point_cur2.id];\n if (int_point_cur1.edge_before === int_point_ref1.edge_before &&\n int_point_cur1.edge_after === int_point_ref1.edge_after &&\n int_point_cur2.edge_before === int_point_ref2.edge_before &&\n int_point_cur2.edge_after === int_point_ref2.edge_after) {\n int_point_cur1.id = -1;\n /* to be deleted */\n int_point_cur2.id = -1;\n /* to be deleted */\n do_squeeze = true;\n }\n }\n\n if (do_squeeze) {\n intersections.int_points1 = intersections.int_points1.filter((int_point) => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter((int_point) => int_point.id >= 0);\n\n // update id's\n intersections.int_points1.forEach((int_point, index) => int_point.id = index);\n intersections.int_points2.forEach((int_point, index) => int_point.id = index);\n }\n}\n\nfunction initializeInclusionFlags(int_points)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_before.bvStart = undefined;\n int_point.edge_before.bvEnd = undefined;\n int_point.edge_before.bv = undefined;\n int_point.edge_before.overlap = undefined;\n }\n\n if (int_point.edge_after) {\n int_point.edge_after.bvStart = undefined;\n int_point.edge_after.bvEnd = undefined;\n int_point.edge_after.bv = undefined;\n int_point.edge_after.overlap = undefined;\n }\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.bvEnd = BOUNDARY$1;\n if (int_point.edge_after) int_point.edge_after.bvStart = BOUNDARY$1;\n }\n}\n\nfunction calculateInclusionFlags(int_points, polygon)\n{\n for (let int_point of int_points) {\n if (int_point.edge_before) int_point.edge_before.setInclusion(polygon);\n if (int_point.edge_after) int_point.edge_after.setInclusion(polygon);\n }\n}\n\nfunction setOverlappingFlags(intersections)\n{\n let cur_face = undefined;\n let first_int_point_in_face_id = undefined;\n let next_int_point1 = undefined;\n let num_int_points = intersections.int_points1.length;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = intersections.int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(intersections.int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n intersections.int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(intersections.int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = intersections.int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n intersections.int_points2[next_int_point1_tmp.id].face === intersections.int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n if (!(edge_from1.bv === BOUNDARY$1 && edge_to1.bv === BOUNDARY$1)) // not a boundary chain - skip\n continue;\n\n if (edge_from1 !== edge_to1) // one edge chain TODO: support complex case\n continue;\n\n /* Find boundary chain in polygon2 between same intersection points */\n let cur_int_point2 = intersections.int_points2[cur_int_point1.id];\n let next_int_point2 = intersections.int_points2[next_int_point1.id];\n\n let edge_from2 = cur_int_point2.edge_after;\n let edge_to2 = next_int_point2.edge_before;\n\n /* if [edge_from2..edge_to2] is not a boundary chain, invert it */\n /* check also that chain consist of one or two edges */\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2)) {\n cur_int_point2 = intersections.int_points2[next_int_point1.id];\n next_int_point2 = intersections.int_points2[cur_int_point1.id];\n\n edge_from2 = cur_int_point2.edge_after;\n edge_to2 = next_int_point2.edge_before;\n }\n\n if (!(edge_from2.bv === BOUNDARY$1 && edge_to2.bv === BOUNDARY$1 && edge_from2 === edge_to2))\n continue; // not an overlapping chain - skip TODO: fix boundary conflict\n\n // Set overlapping flag - one-to-one case\n edge_from1.setOverlap(edge_from2);\n }\n}\n\nfunction intPointsPoolCount(int_points, cur_int_point_num, cur_face)\n{\n let int_point_current;\n let int_point_next;\n\n let int_points_pool_num = 1;\n\n if (int_points.length === 1) return 1;\n\n int_point_current = int_points[cur_int_point_num];\n\n for (let i = cur_int_point_num + 1; i < int_points.length; i++) {\n if (int_point_current.face !== cur_face) { /* next face started */\n break;\n }\n\n int_point_next = int_points[i];\n\n if (!(int_point_next.pt.equalTo(int_point_current.pt) &&\n int_point_next.edge_before === int_point_current.edge_before &&\n int_point_next.edge_after === int_point_current.edge_after)) {\n break; /* next point is different - break and exit */\n }\n\n int_points_pool_num++; /* duplicated intersection point - increase counter */\n }\n return int_points_pool_num;\n}\n\nfunction splitByIntersections(polygon, int_points)\n{\n if (!int_points) return;\n for (let int_point of int_points) {\n let edge = int_point.edge_before;\n\n // recalculate vertex flag: it may be changed after previous split\n int_point.is_vertex = NOT_VERTEX$1;\n if (edge.shape.start && edge.shape.start.equalTo(int_point.pt)) {\n int_point.is_vertex |= START_VERTEX$1;\n }\n if (edge.shape.end && edge.shape.end.equalTo(int_point.pt)) {\n int_point.is_vertex |= END_VERTEX$1;\n }\n\n if (int_point.is_vertex & START_VERTEX$1) { // nothing to split\n if (edge.prev) {\n int_point.edge_before = edge.prev; // polygon\n int_point.is_vertex = END_VERTEX$1;\n }\n else { // multiline start vertex\n int_point.edge_after = int_point.edge_before;\n int_point.edge_before = edge.prev;\n }\n continue;\n }\n if (int_point.is_vertex & END_VERTEX$1) { // nothing to split\n continue;\n }\n\n let newEdge = polygon.addVertex(int_point.pt, edge);\n int_point.edge_before = newEdge;\n }\n\n for (let int_point of int_points) {\n if (int_point.edge_before) {\n int_point.edge_after = int_point.edge_before.next;\n }\n }\n}\n\nfunction insertBetweenIntPoints(int_point1, int_point2, new_edges) {\n const edge_before = int_point1.edge_before;\n const edge_after = int_point2.edge_after;\n const len = new_edges.length;\n edge_before.next = new_edges[0];\n new_edges[0].prev = edge_before;\n\n new_edges[len-1].next = edge_after;\n edge_after.prev = new_edges[len-1];\n}\n\nvar smart_intersections = /*#__PURE__*/Object.freeze({\n __proto__: null,\n addToIntPoints: addToIntPoints,\n calculateInclusionFlags: calculateInclusionFlags,\n filterDuplicatedIntersections: filterDuplicatedIntersections,\n getSortedArray: getSortedArray,\n initializeInclusionFlags: initializeInclusionFlags,\n insertBetweenIntPoints: insertBetweenIntPoints,\n intPointsPoolCount: intPointsPoolCount,\n setOverlappingFlags: setOverlappingFlags,\n sortIntersections: sortIntersections,\n splitByIntersections: splitByIntersections\n});\n\n/**\n * Created by Alex Bol on 12/02/2018.\n */\n/**\n * @module BooleanOperations\n */\n\nconst {INSIDE: INSIDE$1, OUTSIDE, BOUNDARY, OVERLAP_SAME, OVERLAP_OPPOSITE} = Constants;\nconst {NOT_VERTEX, START_VERTEX, END_VERTEX} = Constants;\n\nconst BOOLEAN_UNION = 1;\nconst BOOLEAN_INTERSECT = 2;\nconst BOOLEAN_SUBTRACT = 3;\n\n\n/**\n * Unify two polygons polygons and returns new polygon.
\n * Point belongs to the resulted polygon if it belongs to the first OR to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction unify(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_UNION, true);\n return res_poly;\n}\n\n/**\n * Subtract second polygon from the first and returns new polygon\n * Point belongs to the resulted polygon if it belongs to the first polygon AND NOT to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction subtract(polygon1, polygon2) {\n let polygon2_tmp = polygon2.clone();\n let polygon2_reversed = polygon2_tmp.reverse();\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2_reversed, BOOLEAN_SUBTRACT, true);\n return res_poly;\n}\n\n/**\n * Intersect two polygons and returns new polygon\n * Point belongs to the resulted polygon is it belongs to the first AND to the second polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Polygon}\n */\nfunction intersect$1(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, true);\n return res_poly;\n}\n\n/**\n * Returns boundary of intersection between two polygons as two arrays of shapes (Segments/Arcs)
\n * The first array are shapes from the first polygon, the second array are shapes from the second\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[][]}\n */\nfunction innerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_INTERSECT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n let clip_shapes2 = [];\n for (let face of wrk_poly.faces) {\n clip_shapes2 = [...clip_shapes2, ...[...face.edges].map(edge => edge.shape)];\n }\n return [clip_shapes1, clip_shapes2];\n}\n\n/**\n * Returns boundary of subtraction of the second polygon from first polygon as array of shapes\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Shape[]}\n */\nfunction outerClip(polygon1, polygon2) {\n let [res_poly, wrk_poly] = booleanOpBinary(polygon1, polygon2, BOOLEAN_SUBTRACT, false);\n\n let clip_shapes1 = [];\n for (let face of res_poly.faces) {\n clip_shapes1 = [...clip_shapes1, ...[...face.edges].map(edge => edge.shape)];\n }\n\n return clip_shapes1;\n}\n\n/**\n * Returns intersection points between boundaries of two polygons as two array of points
\n * Points in the first array belong to first polygon, points from the second - to the second.\n * Points in each array are ordered according to the direction of the correspondent polygon\n * @param {Polygon} polygon1 - first operand\n * @param {Polygon} polygon2 - second operand\n * @returns {Point[][]}\n */\nfunction calculateIntersections(polygon1, polygon2) {\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n let ip_sorted1 = intersections.int_points1_sorted.map( int_point => int_point.pt);\n let ip_sorted2 = intersections.int_points2_sorted.map( int_point => int_point.pt);\n return [ip_sorted1, ip_sorted2];\n}\n\nfunction filterNotRelevantEdges(res_poly, wrk_poly, intersections, op) {\n // keep not intersected faces for further remove and merge\n let notIntersectedFacesRes = getNotIntersectedFaces(res_poly, intersections.int_points1);\n let notIntersectedFacesWrk = getNotIntersectedFaces(wrk_poly, intersections.int_points2);\n\n // calculate inclusion flag for not intersected faces\n calcInclusionForNotIntersectedFaces(notIntersectedFacesRes, wrk_poly);\n calcInclusionForNotIntersectedFaces(notIntersectedFacesWrk, res_poly);\n\n // initialize inclusion flags for edges incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n initializeInclusionFlags(intersections.int_points2);\n\n // calculate inclusion flags only for edges incident to intersections\n calculateInclusionFlags(intersections.int_points1, wrk_poly);\n calculateInclusionFlags(intersections.int_points2, res_poly);\n\n // fix boundary conflicts\n while (fixBoundaryConflicts(res_poly, wrk_poly, intersections.int_points1, intersections.int_points1_sorted, intersections.int_points2, intersections));\n // while (fixBoundaryConflicts(wrk_poly, res_poly, intersections.int_points2, intersections.int_points2_sorted, intersections.int_points1, intersections));\n\n // Set overlapping flags for boundary chains: SAME or OPPOSITE\n setOverlappingFlags(intersections);\n\n // remove not relevant chains between intersection points\n removeNotRelevantChains(res_poly, op, intersections.int_points1_sorted, true);\n removeNotRelevantChains(wrk_poly, op, intersections.int_points2_sorted, false);\n\n // remove not relevant not intersected faces from res_polygon and wrk_polygon\n // if op == UNION, remove faces that are included in wrk_polygon without intersection\n // if op == INTERSECT, remove faces that are not included into wrk_polygon\n removeNotRelevantNotIntersectedFaces(res_poly, notIntersectedFacesRes, op, true);\n removeNotRelevantNotIntersectedFaces(wrk_poly, notIntersectedFacesWrk, op, false);\n}\n\nfunction swapLinksAndRestore(res_poly, wrk_poly, intersections, op) {\n\n // add edges of wrk_poly into the edge container of res_poly\n copyWrkToRes(res_poly, wrk_poly, op, intersections.int_points2);\n\n // swap links from res_poly to wrk_poly and vice versa\n swapLinks(res_poly, wrk_poly, intersections);\n\n // remove old faces\n removeOldFaces(res_poly, intersections.int_points1);\n removeOldFaces(wrk_poly, intersections.int_points2);\n\n // restore faces\n restoreFaces(res_poly, intersections.int_points1, intersections.int_points2);\n restoreFaces(res_poly, intersections.int_points2, intersections.int_points1);\n\n // merge relevant not intersected faces from wrk_polygon to res_polygon\n // mergeRelevantNotIntersectedFaces(res_poly, wrk_poly);\n}\n\n\nfunction booleanOpBinary(polygon1, polygon2, op, restore)\n{\n let res_poly = polygon1.clone();\n let wrk_poly = polygon2.clone();\n\n // get intersection points\n let intersections = getIntersections(res_poly, wrk_poly);\n\n // sort intersection points\n sortIntersections(intersections);\n\n // split by intersection points\n splitByIntersections(res_poly, intersections.int_points1_sorted);\n splitByIntersections(wrk_poly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n sortIntersections(intersections);\n\n // calculate inclusion and remove not relevant edges\n filterNotRelevantEdges(res_poly, wrk_poly, intersections, op);\n\n if (restore) {\n swapLinksAndRestore(res_poly, wrk_poly, intersections, op);\n }\n\n return [res_poly, wrk_poly];\n}\n\nfunction getIntersections(polygon1, polygon2)\n{\n let intersections = {\n int_points1: [],\n int_points2: []\n };\n\n // calculate intersections\n for (let edge1 of polygon1.edges) {\n\n // request edges of polygon2 in the box of edge1\n let resp = polygon2.edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n return intersections;\n}\n\nfunction getNotIntersectedFaces(poly, int_points)\n{\n let notIntersected = [];\n for (let face of poly.faces) {\n if (!int_points.find((ip) => ip.face === face)) {\n notIntersected.push(face);\n }\n }\n return notIntersected;\n}\n\nfunction calcInclusionForNotIntersectedFaces(notIntersectedFaces, poly2)\n{\n for (let face of notIntersectedFaces) {\n face.first.bv = face.first.bvStart = face.first.bvEnd = undefined;\n face.first.setInclusion(poly2);\n }\n}\n\nfunction fixBoundaryConflicts(poly1, poly2, int_points1, int_points1_sorted, int_points2, intersections )\n{\n let cur_face;\n let first_int_point_in_face_id;\n let next_int_point1;\n let num_int_points = int_points1_sorted.length;\n let iterate_more = false;\n\n for (let i = 0; i < num_int_points; i++) {\n let cur_int_point1 = int_points1_sorted[i];\n\n // Find boundary chain in the polygon1\n if (cur_int_point1.face !== cur_face) { // next chain started\n first_int_point_in_face_id = i; // cur_int_point1;\n cur_face = cur_int_point1.face;\n }\n\n // Skip duplicated points with same in \"cur_int_point1\" pool\n let int_points_cur_pool_start = i;\n let int_points_cur_pool_num = intPointsPoolCount(int_points1_sorted, i, cur_face);\n let next_int_point_id;\n if (int_points_cur_pool_start + int_points_cur_pool_num < num_int_points &&\n int_points1_sorted[int_points_cur_pool_start + int_points_cur_pool_num].face === cur_face) {\n next_int_point_id = int_points_cur_pool_start + int_points_cur_pool_num;\n } else { // get first point from the same face\n next_int_point_id = first_int_point_in_face_id;\n }\n\n // From all points with same ,x,y. in 'next_int_point1' pool choose one that\n // has same face both in res_poly and in wrk_poly\n let int_points_next_pool_num = intPointsPoolCount(int_points1_sorted, next_int_point_id, cur_face);\n next_int_point1 = null;\n for (let j=next_int_point_id; j < next_int_point_id + int_points_next_pool_num; j++) {\n let next_int_point1_tmp = int_points1_sorted[j];\n if (next_int_point1_tmp.face === cur_face &&\n int_points2[next_int_point1_tmp.id].face === int_points2[cur_int_point1.id].face) {\n next_int_point1 = next_int_point1_tmp;\n break;\n }\n }\n if (next_int_point1 === null)\n continue;\n\n let edge_from1 = cur_int_point1.edge_after;\n let edge_to1 = next_int_point1.edge_before;\n\n // Case #1. One of the ends is not boundary - probably tiny edge wrongly marked as boundary\n if (edge_from1.bv === BOUNDARY && edge_to1.bv != BOUNDARY) {\n edge_from1.bv = edge_to1.bv;\n continue;\n }\n\n if (edge_from1.bv != BOUNDARY && edge_to1.bv === BOUNDARY) {\n edge_to1.bv = edge_from1.bv;\n continue;\n }\n\n // Set up all boundary values for middle edges. Need for cases 2 and 3\n if ( (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) ||\n (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) ) {\n let edge_tmp = edge_from1.next;\n while (edge_tmp != edge_to1) {\n edge_tmp.bvStart = undefined;\n edge_tmp.bvEnd = undefined;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n edge_tmp = edge_tmp.next;\n }\n }\n\n // Case #2. Both of the ends boundary. Check all the edges in the middle\n // If some edges in the middle are not boundary then update bv of 'from' and 'to' edges\n if (edge_from1.bv === BOUNDARY && edge_to1.bv === BOUNDARY && edge_from1 != edge_to1) {\n let edge_tmp = edge_from1.next;\n let new_bv;\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bv != BOUNDARY) {\n if (new_bv === undefined) { // first not boundary edge between from and to\n new_bv = edge_tmp.bv;\n }\n else { // another not boundary edge between from and to\n if (edge_tmp.bv != new_bv) { // and it has different bv - can't resolve conflict\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n if (new_bv != undefined) {\n edge_from1.bv = new_bv;\n edge_to1.bv = new_bv;\n }\n continue; // all middle edges are boundary, proceed with this\n }\n\n // Case 3. One of the ends is inner, another is outer\n if (edge_from1.bv === INSIDE$1 && edge_to1.bv === OUTSIDE || edge_from1.bv === OUTSIDE && edge_to1.bv === INSIDE$1 ) {\n let edge_tmp = edge_from1;\n // Find missing intersection point\n while (edge_tmp != edge_to1) {\n if (edge_tmp.bvStart === edge_from1.bv && edge_tmp.bvEnd === edge_to1.bv) {\n let [dist, segment] = edge_tmp.shape.distanceTo(poly2);\n if (dist < 10*Flatten.DP_TOL) { // it should be very close\n // let pt = edge_tmp.end;\n // add to the list of intersections of poly1\n addToIntPoints(edge_tmp, segment.ps, int_points1);\n\n // split edge_tmp in poly1 if need\n let int_point1 = int_points1[int_points1.length-1];\n if (int_point1.is_vertex & START_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp;\n int_point1.edge_before = edge_tmp.prev;\n edge_tmp.bvStart = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else if (int_point1.is_vertex & END_VERTEX) { // nothing to split\n int_point1.edge_after = edge_tmp.next;\n edge_tmp.bvEnd = BOUNDARY;\n edge_tmp.bv = undefined;\n edge_tmp.setInclusion(poly2);\n }\n else { // split edge here\n let newEdge1 = poly2.addVertex(int_point1.pt, edge_tmp);\n int_point1.edge_before = newEdge1;\n int_point1.edge_after = newEdge1.next;\n\n newEdge1.setInclusion(poly2);\n\n newEdge1.next.bvStart = BOUNDARY;\n newEdge1.next.bvEnd = undefined;\n newEdge1.next.bv = undefined;\n newEdge1.next.setInclusion(poly2);\n }\n\n // add to the list of intersections of poly2\n let edge2 = poly2.findEdgeByPoint(segment.pe);\n addToIntPoints(edge2, segment.pe, int_points2);\n // split edge2 in poly2 if need\n let int_point2 = int_points2[int_points2.length-1];\n if (int_point2.is_vertex & START_VERTEX) { // nothing to split\n int_point2.edge_after = edge2;\n int_point2.edge_before = edge2.prev;\n }\n else if (int_point2.is_vertex & END_VERTEX) { // nothing to split\n int_point2.edge_after = edge2.next;\n }\n else { // split edge here\n // first locate int_points that may refer to edge2 as edge.after\n // let int_point2_edge_before = int_points2.find( int_point => int_point.edge_before === edge2)\n let int_point2_edge_after = int_points2.find( int_point => int_point.edge_after === edge2 );\n\n let newEdge2 = poly2.addVertex(int_point2.pt, edge2);\n int_point2.edge_before = newEdge2;\n int_point2.edge_after = newEdge2.next;\n\n if (int_point2_edge_after)\n int_point2_edge_after.edge_after = newEdge2;\n\n newEdge2.bvStart = undefined;\n newEdge2.bvEnd = BOUNDARY;\n newEdge2.bv = undefined;\n newEdge2.setInclusion(poly1);\n\n newEdge2.next.bvStart = BOUNDARY;\n newEdge2.next.bvEnd = undefined;\n newEdge2.next.bv = undefined;\n newEdge2.next.setInclusion(poly1);\n }\n\n sortIntersections(intersections);\n\n iterate_more = true;\n break;\n }\n }\n edge_tmp = edge_tmp.next;\n }\n\n // we changed intersections inside loop, have to exit and repair again\n if (iterate_more)\n break;\n\n throw Errors.UNRESOLVED_BOUNDARY_CONFLICT;\n }\n }\n\n return iterate_more;\n}\n\nfunction removeNotRelevantChains(polygon, op, int_points, is_res_polygon)\n{\n if (!int_points) return;\n let cur_face = undefined;\n let first_int_point_in_face_num = undefined;\n let int_point_current;\n let int_point_next;\n\n for (let i = 0; i < int_points.length; i++) {\n int_point_current = int_points[i];\n\n if (int_point_current.face !== cur_face) { // next face started\n first_int_point_in_face_num = i;\n cur_face = int_point_current.face;\n }\n\n if (cur_face.isEmpty()) // ??\n continue;\n\n // Get next int point from the same face that current\n\n // Count how many duplicated points with same in \"points from\" pool ?\n let int_points_from_pull_start = i;\n let int_points_from_pull_num = intPointsPoolCount(int_points, i, cur_face);\n let next_int_point_num;\n if (int_points_from_pull_start + int_points_from_pull_num < int_points.length &&\n int_points[int_points_from_pull_start + int_points_from_pull_num].face === int_point_current.face) {\n next_int_point_num = int_points_from_pull_start + int_points_from_pull_num;\n } else { // get first point from the same face\n next_int_point_num = first_int_point_in_face_num;\n }\n int_point_next = int_points[next_int_point_num];\n\n /* Count how many duplicated points with same in \"points to\" pull ? */\n let int_points_to_pull_start = next_int_point_num;\n let int_points_to_pull_num = intPointsPoolCount(int_points, int_points_to_pull_start, cur_face);\n\n\n let edge_from = int_point_current.edge_after;\n let edge_to = int_point_next.edge_before;\n\n if ((edge_from.bv === INSIDE$1 && edge_to.bv === INSIDE$1 && op === BOOLEAN_UNION) ||\n (edge_from.bv === OUTSIDE && edge_to.bv === OUTSIDE && op === BOOLEAN_INTERSECT) ||\n ((edge_from.bv === OUTSIDE || edge_to.bv === OUTSIDE) && op === BOOLEAN_SUBTRACT && !is_res_polygon) ||\n ((edge_from.bv === INSIDE$1 || edge_to.bv === INSIDE$1) && op === BOOLEAN_SUBTRACT && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_SAME) && is_res_polygon) ||\n (edge_from.bv === BOUNDARY && edge_to.bv === BOUNDARY && (edge_from.overlap & OVERLAP_OPPOSITE))) {\n\n polygon.removeChain(cur_face, edge_from, edge_to);\n\n /* update all points in \"points from\" pull */\n for (let k = int_points_from_pull_start; k < int_points_from_pull_start + int_points_from_pull_num; k++) {\n int_points[k].edge_after = undefined;\n }\n\n /* update all points in \"points to\" pull */\n for (let k = int_points_to_pull_start; k < int_points_to_pull_start + int_points_to_pull_num; k++) {\n int_points[k].edge_before = undefined;\n }\n }\n\n /* skip to the last point in \"points from\" group */\n i += int_points_from_pull_num - 1;\n }\n}\nfunction copyWrkToRes(res_polygon, wrk_polygon, op, int_points)\n{\n for (let face of wrk_polygon.faces) {\n for (let edge of face) {\n res_polygon.edges.add(edge);\n }\n // If union - add face from wrk_polygon that is not intersected with res_polygon\n if ( /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/\n int_points.find((ip) => (ip.face === face)) === undefined) {\n res_polygon.addFace(face.first, face.last);\n }\n }\n}\n\nfunction swapLinks(res_polygon, wrk_polygon, intersections)\n{\n if (intersections.int_points1.length === 0) return;\n\n for (let i = 0; i < intersections.int_points1.length; i++) {\n let int_point1 = intersections.int_points1[i];\n let int_point2 = intersections.int_points2[i];\n\n // Simple case - find continuation on the other polygon\n\n // Process edge from res_polygon\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // swap need\n if (int_point2.edge_before === undefined && int_point2.edge_after !== undefined) { // simple case\n // Connect edges\n int_point1.edge_before.next = int_point2.edge_after;\n int_point2.edge_after.prev = int_point1.edge_before;\n\n // Fill in missed links in intersection points\n int_point1.edge_after = int_point2.edge_after;\n int_point2.edge_before = int_point1.edge_before;\n }\n }\n // Process edge from wrk_polygon\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // swap need\n if (int_point1.edge_before === undefined && int_point1.edge_after !== undefined) { // simple case\n // Connect edges\n int_point2.edge_before.next = int_point1.edge_after;\n int_point1.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point1.edge_after;\n int_point1.edge_before = int_point2.edge_before;\n }\n }\n\n // Continuation not found - complex case\n // Continuation will be found on the same polygon.\n // It happens when intersection point is actually touching point\n // Polygon1\n if (int_point1.edge_before !== undefined && int_point1.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points1_sorted) {\n if (int_point === int_point1) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point1.pt)) {\n // Connect edges\n int_point1.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point1.edge_before;\n\n // Complete missed links\n int_point1.edge_after = int_point.edge_after;\n int_point.edge_before = int_point1.edge_before;\n }\n }\n }\n }\n // Polygon2\n if (int_point2.edge_before !== undefined && int_point2.edge_after === undefined) { // still swap need\n for (let int_point of intersections.int_points2_sorted) {\n if (int_point === int_point2) continue; // skip same\n if (int_point.edge_before === undefined && int_point.edge_after !== undefined) {\n if (int_point.pt.equalTo(int_point2.pt)) {\n // Connect edges\n int_point2.edge_before.next = int_point.edge_after;\n int_point.edge_after.prev = int_point2.edge_before;\n\n // Complete missed links\n int_point2.edge_after = int_point.edge_after;\n int_point.edge_before = int_point2.edge_before;\n }\n }\n }\n }\n }\n // Sanity check that no dead ends left\n}\n\nfunction removeOldFaces(polygon, int_points)\n{\n for (let int_point of int_points) {\n polygon.faces.delete(int_point.face);\n int_point.face = undefined;\n if (int_point.edge_before)\n int_point.edge_before.face = undefined;\n if (int_point.edge_after)\n int_point.edge_after.face = undefined;\n }\n}\n\nfunction restoreFaces(polygon, int_points, other_int_points)\n{\n // For each intersection point - create new face\n for (let int_point of int_points) {\n if (int_point.edge_before === undefined || int_point.edge_after === undefined) // completely deleted\n continue;\n if (int_point.face) // already restored\n continue;\n\n if (int_point.edge_after.face || int_point.edge_before.face) // Face already created. Possible case in duplicated intersection points\n continue;\n\n let first = int_point.edge_after; // face start\n let last = int_point.edge_before; // face end;\n\n try {\n LinkedList.testInfiniteLoop(first); // check and throw error if infinite loop found\n }\n catch (error) {\n throw Errors.CANNOT_COMPLETE_BOOLEAN_OPERATION\n }\n\n let face = polygon.addFace(first, last);\n\n // Mark intersection points from the newly create face\n // to avoid multiple creation of the same face.\n // Face was assigned to each edge of new face in addFace function\n for (let int_point_tmp of int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n // Mark other intersection points as well\n for (let int_point_tmp of other_int_points) {\n if (int_point_tmp.edge_before && int_point_tmp.edge_after &&\n int_point_tmp.edge_before.face === face && int_point_tmp.edge_after.face === face) {\n int_point_tmp.face = face;\n }\n }\n }\n}\n\nfunction removeNotRelevantNotIntersectedFaces(polygon, notIntersectedFaces, op, is_res_polygon)\n{\n for (let face of notIntersectedFaces) {\n let rel = face.first.bv;\n if (op === BOOLEAN_UNION && rel === INSIDE$1 ||\n op === BOOLEAN_SUBTRACT && rel === INSIDE$1 && is_res_polygon ||\n op === BOOLEAN_SUBTRACT && rel === OUTSIDE && !is_res_polygon ||\n op === BOOLEAN_INTERSECT && rel === OUTSIDE) {\n\n polygon.deleteFace(face);\n }\n }\n}\n\nvar BooleanOperations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n BOOLEAN_INTERSECT: BOOLEAN_INTERSECT,\n BOOLEAN_SUBTRACT: BOOLEAN_SUBTRACT,\n BOOLEAN_UNION: BOOLEAN_UNION,\n calculateIntersections: calculateIntersections,\n innerClip: innerClip,\n intersect: intersect$1,\n outerClip: outerClip,\n removeNotRelevantChains: removeNotRelevantChains,\n removeOldFaces: removeOldFaces,\n restoreFaces: restoreFaces,\n subtract: subtract,\n unify: unify\n});\n\n/*\n Dimensionally extended 9-intersected model\n See https://en.wikipedia.org/wiki/DE-9IM for more details\n */\n// const DISJOINT = RegExp('FF.FF....');\nconst EQUAL = RegExp('T.F..FFF.|T.F...F..');\nconst INTERSECT = RegExp('T........|.T.......|...T.....|....T....');\nconst TOUCH = RegExp('FT.......|F..T.....|F...T....');\nconst INSIDE = RegExp('T.F..F...');\nconst COVERED = RegExp('T.F..F...|.TF..F...|..FT.F...|..F.TF...');\n\nclass DE9IM {\n /**\n * Create new instance of DE9IM matrix\n */\n constructor() {\n /**\n * Array representing 3x3 intersection matrix\n * @type {Shape[]}\n */\n this.m = new Array(9).fill(undefined);\n }\n\n /**\n * Get Interior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get I2I() {\n return this.m[0];\n }\n\n /**\n * Set Interior To Interior intersection\n * @param geom\n */\n set I2I(geom) {\n this.m[0] = geom;\n }\n\n /**\n * Get Interior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get I2B() {\n return this.m[1];\n }\n\n /**\n * Set Interior to Boundary intersection\n * @param geomc\n */\n set I2B(geom) {\n this.m[1] = geom;\n }\n\n /**\n * Get Interior To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get I2E() {\n return this.m[2];\n }\n\n /**\n * Set Interior to Exterior intersection\n * @param geom\n */\n set I2E(geom) {\n this.m[2] = geom;\n }\n\n /**\n * Get Boundary To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get B2I() {\n return this.m[3];\n }\n\n /**\n * Set Boundary to Interior intersection\n * @param geom\n */\n set B2I(geom) {\n this.m[3] = geom;\n }\n\n /**\n * Get Boundary To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get B2B() {\n return this.m[4];\n }\n\n /**\n * Set Boundary to Boundary intersection\n * @param geom\n */\n set B2B(geom) {\n this.m[4] = geom;\n }\n\n /**\n * Get Boundary To Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get B2E() {\n return this.m[5];\n }\n\n /**\n * Set Boundary to Exterior intersection\n * @param geom\n */\n set B2E(geom) {\n this.m[5] = geom;\n }\n\n /**\n * Get Exterior To Interior intersection\n * @returns {Shape[] | undefined}\n */\n get E2I() {\n return this.m[6];\n }\n\n /**\n * Set Exterior to Interior intersection\n * @param geom\n */\n set E2I(geom) {\n this.m[6] = geom;\n }\n\n /**\n * Get Exterior To Boundary intersection\n * @returns {Shape[] | undefined}\n */\n get E2B() {\n return this.m[7];\n }\n\n /**\n * Set Exterior to Boundary intersection\n * @param geom\n */\n set E2B(geom) {\n this.m[7] = geom;\n }\n\n /**\n * Get Exterior to Exterior intersection\n * @returns {Shape[] | undefined}\n */\n get E2E() {\n return this.m[8];\n }\n\n /**\n * Set Exterior to Exterior intersection\n * @param geom\n */\n set E2E(geom) {\n this.m[8] = geom;\n }\n\n /**\n * Return de9im matrix as string where
\n * - intersection is 'T'
\n * - not intersected is 'F'
\n * - not relevant is '*'
\n * For example, string 'FF**FF****' means 'DISJOINT'\n * @returns {string}\n */\n toString() {\n return this.m.map( e => {\n if (e instanceof Array && e.length > 0) {\n return 'T'\n }\n else if (e instanceof Array && e.length === 0) {\n return 'F'\n }\n else {\n return '*'\n }\n }).join(\"\")\n }\n\n equal() {\n return EQUAL.test(this.toString());\n }\n\n intersect() {\n return INTERSECT.test(this.toString());\n }\n\n touch() {\n return TOUCH.test(this.toString());\n }\n\n inside() {\n return INSIDE.test(this.toString());\n }\n\n covered() {\n return COVERED.test(this.toString());\n }\n}\n\n/**\n * Intersection\n *\n * */\n\n\nfunction intersectLine2Line(line1, line2) {\n let ip = [];\n\n let [A1, B1, C1] = line1.standard;\n let [A2, B2, C2] = line2.standard;\n\n /* Cramer's rule */\n let det = A1 * B2 - B1 * A2;\n let detX = C1 * B2 - B1 * C2;\n let detY = A1 * C2 - C1 * A2;\n\n if (!Flatten.Utils.EQ_0(det)) {\n let x, y;\n\n if (B1 === 0) { // vertical line x = C1/A1, where A1 == +1 or -1\n x = C1/A1;\n y = detY / det;\n }\n else if (B2 === 0) { // vertical line x = C2/A2, where A2 = +1 or -1\n x = C2/A2;\n y = detY / det;\n }\n else if (A1 === 0) { // horizontal line y = C1/B1, where B1 = +1 or -1\n x = detX / det;\n y = C1/B1;\n }\n else if (A2 === 0) { // horizontal line y = C2/B2, where B2 = +1 or -1\n x = detX / det;\n y = C2/B2;\n }\n else {\n x = detX / det;\n y = detY / det;\n }\n\n ip.push(new Flatten.Point(x, y));\n }\n\n return ip;\n}\n\nfunction intersectLine2Circle(line, circle) {\n let ip = [];\n let prj = circle.pc.projectionOn(line); // projection of circle center on a line\n let dist = circle.pc.distanceTo(prj)[0]; // distance from circle center to projection\n\n if (Flatten.Utils.EQ(dist, circle.r)) { // line tangent to circle - return single intersection point\n ip.push(prj);\n } else if (Flatten.Utils.LT(dist, circle.r)) { // return two intersection points\n let delta = Math.sqrt(circle.r * circle.r - dist * dist);\n let v_trans, pt;\n\n v_trans = line.norm.rotate90CCW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n\n v_trans = line.norm.rotate90CW().multiply(delta);\n pt = prj.translate(v_trans);\n ip.push(pt);\n }\n return ip;\n}\n\nfunction intersectLine2Box(line, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Line(seg, line);\n for (let pt of ips_tmp) {\n if (!ptInIntPoints(pt, ips)) {\n ips.push(pt);\n }\n }\n }\n return ips;\n}\n\nfunction intersectLine2Arc(line, arc) {\n let ip = [];\n\n if (intersectLine2Box(line, arc.box).length === 0) {\n return ip;\n }\n\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectLine2Circle(line, circle);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectSegment2Line(seg, line) {\n let ip = [];\n\n // Boundary cases\n if (seg.ps.on(line)) {\n ip.push(seg.ps);\n }\n // If both ends lay on line, return two intersection points\n if (seg.pe.on(line) && !seg.isZeroLength()) {\n ip.push(seg.pe);\n }\n\n if (ip.length > 0) {\n return ip; // done, intersection found\n }\n\n // If zero-length segment and nothing found, return no intersections\n if (seg.isZeroLength()) {\n return ip;\n }\n\n // Not a boundary case, check if both points are on the same side and\n // hence there is no intersection\n if (seg.ps.leftTo(line) && seg.pe.leftTo(line) ||\n !seg.ps.leftTo(line) && !seg.pe.leftTo(line)) {\n return ip;\n }\n\n // Calculate intersection between lines\n let line1 = new Flatten.Line(seg.ps, seg.pe);\n return intersectLine2Line(line1, line);\n}\n\nfunction intersectSegment2Segment(seg1, seg2) {\n let ip = [];\n\n // quick reject\n if (seg1.box.not_intersect(seg2.box)) {\n return ip;\n }\n\n // Special case of seg1 zero length\n if (seg1.isZeroLength()) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n return ip;\n }\n\n // Special case of seg2 zero length\n if (seg2.isZeroLength()) {\n if (seg2.ps.on(seg1)) {\n ip.push(seg2.ps);\n }\n return ip;\n }\n\n // Neither seg1 nor seg2 is zero length\n let line1 = new Flatten.Line(seg1.ps, seg1.pe);\n let line2 = new Flatten.Line(seg2.ps, seg2.pe);\n\n // Check overlapping between segments in case of incidence\n // If segments touching, add one point. If overlapping, add two points\n if (line1.incidentTo(line2)) {\n if (seg1.ps.on(seg2)) {\n ip.push(seg1.ps);\n }\n if (seg1.pe.on(seg2)) {\n ip.push(seg1.pe);\n }\n if (seg2.ps.on(seg1) && !seg2.ps.equalTo(seg1.ps) && !seg2.ps.equalTo(seg1.pe)) {\n ip.push(seg2.ps);\n }\n if (seg2.pe.on(seg1) && !seg2.pe.equalTo(seg1.ps) && !seg2.pe.equalTo(seg1.pe)) {\n ip.push(seg2.pe);\n }\n } else { /* not incident - parallel or intersect */\n // Calculate intersection between lines\n let new_ip = intersectLine2Line(line1, line2);\n if (new_ip.length > 0) {\n if (isPointInSegmentBox(new_ip[0], seg1) && isPointInSegmentBox(new_ip[0], seg2)) {\n ip.push(new_ip[0]);\n }\n }\n }\n return ip;\n}\n\nfunction isPointInSegmentBox(point, segment) {\n const box = segment.box;\n return Flatten.Utils.LE(point.x, box.xmax) && Flatten.Utils.GE(point.x, box.xmin) &&\n Flatten.Utils.LE(point.y, box.ymax) && Flatten.Utils.GE(point.y, box.ymin)\n}\n\nfunction intersectSegment2Circle(segment, circle) {\n let ips = [];\n\n if (segment.box.not_intersect(circle.box)) {\n return ips;\n }\n\n // Special case of zero length segment\n if (segment.isZeroLength()) {\n let [dist, _] = segment.ps.distanceTo(circle.pc);\n if (Flatten.Utils.EQ(dist, circle.r)) {\n ips.push(segment.ps);\n }\n return ips;\n }\n\n // Non zero-length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n\n let ips_tmp = intersectLine2Circle(line, circle);\n\n for (let ip of ips_tmp) {\n if (ip.on(segment)) {\n ips.push(ip);\n }\n }\n\n return ips;\n}\n\nfunction intersectSegment2Arc(segment, arc) {\n let ip = [];\n\n if (segment.box.not_intersect(arc.box)) {\n return ip;\n }\n\n // Special case of zero-length segment\n if (segment.isZeroLength()) {\n if (segment.ps.on(arc)) {\n ip.push(segment.ps);\n }\n return ip;\n }\n\n // Non-zero length segment\n let line = new Flatten.Line(segment.ps, segment.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n let ip_tmp = intersectLine2Circle(line, circle);\n\n for (let pt of ip_tmp) {\n if (pt.on(segment) && pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n\n}\n\nfunction intersectSegment2Box(segment, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Segment(seg, segment);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectCircle2Circle(circle1, circle2) {\n let ip = [];\n\n if (circle1.box.not_intersect(circle2.box)) {\n return ip;\n }\n\n let vec = new Flatten.Vector(circle1.pc, circle2.pc);\n\n let r1 = circle1.r;\n let r2 = circle2.r;\n\n // Degenerated circle\n if (Flatten.Utils.EQ_0(r1) || Flatten.Utils.EQ_0(r2))\n return ip;\n\n // In case of equal circles return one leftmost point\n if (Flatten.Utils.EQ_0(vec.x) && Flatten.Utils.EQ_0(vec.y) && Flatten.Utils.EQ(r1, r2)) {\n ip.push(circle1.pc.translate(-r1, 0));\n return ip;\n }\n\n let dist = circle1.pc.distanceTo(circle2.pc)[0];\n\n if (Flatten.Utils.GT(dist, r1 + r2)) // circles too far, no intersections\n return ip;\n\n if (Flatten.Utils.LT(dist, Math.abs(r1 - r2))) // one circle is contained within another, no intersections\n return ip;\n\n // Normalize vector.\n vec.x /= dist;\n vec.y /= dist;\n\n let pt;\n\n // Case of touching from outside or from inside - single intersection point\n // TODO: check this specifically not sure if correct\n if (Flatten.Utils.EQ(dist, r1 + r2) || Flatten.Utils.EQ(dist, Math.abs(r1 - r2))) {\n pt = circle1.pc.translate(r1 * vec.x, r1 * vec.y);\n ip.push(pt);\n return ip;\n }\n\n // Case of two intersection points\n\n // Distance from first center to center of common chord:\n // a = (r1^2 - r2^2 + d^2) / 2d\n // Separate for better accuracy\n let a = (r1 * r1) / (2 * dist) - (r2 * r2) / (2 * dist) + dist / 2;\n\n let mid_pt = circle1.pc.translate(a * vec.x, a * vec.y);\n let h = Math.sqrt(r1 * r1 - a * a);\n // let norm;\n\n // norm = vec.rotate90CCW().multiply(h);\n pt = mid_pt.translate(vec.rotate90CCW().multiply(h));\n ip.push(pt);\n\n // norm = vec.rotate90CW();\n pt = mid_pt.translate(vec.rotate90CW().multiply(h));\n ip.push(pt);\n\n return ip;\n}\n\nfunction intersectCircle2Box(circle, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Circle(seg, circle);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectArc2Arc(arc1, arc2) {\n let ip = [];\n\n if (arc1.box.not_intersect(arc2.box)) {\n return ip;\n }\n\n // Special case: overlapping arcs\n // May return up to 4 intersection points\n if (arc1.pc.equalTo(arc2.pc) && Flatten.Utils.EQ(arc1.r, arc2.r)) {\n let pt;\n\n pt = arc1.start;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc1.end;\n if (pt.on(arc2))\n ip.push(pt);\n\n pt = arc2.start;\n if (pt.on(arc1)) ip.push(pt);\n\n pt = arc2.end;\n if (pt.on(arc1)) ip.push(pt);\n\n return ip;\n }\n\n // Common case\n let circle1 = new Flatten.Circle(arc1.pc, arc1.r);\n let circle2 = new Flatten.Circle(arc2.pc, arc2.r);\n let ip_tmp = circle1.intersect(circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc1) && pt.on(arc2)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Circle(arc, circle) {\n let ip = [];\n\n if (arc.box.not_intersect(circle.box)) {\n return ip;\n }\n\n // Case when arc center incident to circle center\n // Return arc's end points as 2 intersection points\n if (circle.pc.equalTo(arc.pc) && Flatten.Utils.EQ(circle.r, arc.r)) {\n ip.push(arc.start);\n ip.push(arc.end);\n return ip;\n }\n\n // Common case\n let circle1 = circle;\n let circle2 = new Flatten.Circle(arc.pc, arc.r);\n let ip_tmp = intersectCircle2Circle(circle1, circle2);\n for (let pt of ip_tmp) {\n if (pt.on(arc)) {\n ip.push(pt);\n }\n }\n return ip;\n}\n\nfunction intersectArc2Box(arc, box) {\n let ips = [];\n for (let seg of box.toSegments()) {\n let ips_tmp = intersectSegment2Arc(seg, arc);\n for (let ip of ips_tmp) {\n ips.push(ip);\n }\n }\n return ips;\n}\n\nfunction intersectEdge2Segment(edge, segment) {\n return edge.isSegment ? intersectSegment2Segment(edge.shape, segment) : intersectSegment2Arc(segment, edge.shape);\n}\n\nfunction intersectEdge2Arc(edge, arc) {\n return edge.isSegment ? intersectSegment2Arc(edge.shape, arc) : intersectArc2Arc(edge.shape, arc);\n}\n\nfunction intersectEdge2Line(edge, line) {\n return edge.isSegment ? intersectSegment2Line(edge.shape, line) : intersectLine2Arc(line, edge.shape);\n}\n\nfunction intersectEdge2Ray(edge, ray) {\n return edge.isSegment ? intersectRay2Segment(ray, edge.shape) : intersectRay2Arc(ray, edge.shape);\n}\n\nfunction intersectEdge2Circle(edge, circle) {\n return edge.isSegment ? intersectSegment2Circle(edge.shape, circle) : intersectArc2Circle(edge.shape, circle);\n}\n\nfunction intersectSegment2Polygon(segment, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Segment(edge, segment)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectArc2Polygon(arc, polygon) {\n let ip = [];\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Arc(edge, arc)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectLine2Polygon(line, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Line(edge, line)) {\n if (!ptInIntPoints(pt, ip)) {\n ip.push(pt);\n }\n }\n }\n\n return line.sortPoints(ip);\n}\n\nfunction intersectCircle2Polygon(circle, polygon) {\n let ip = [];\n\n if (polygon.isEmpty()) {\n return ip;\n }\n\n for (let edge of polygon.edges) {\n for (let pt of intersectEdge2Circle(edge, circle)) {\n ip.push(pt);\n }\n }\n\n return ip;\n}\n\nfunction intersectEdge2Edge(edge1, edge2) {\n if (edge1.isSegment) {\n return intersectEdge2Segment(edge2, edge1.shape)\n }\n else if (edge1.isArc) {\n return intersectEdge2Arc(edge2, edge1.shape)\n }\n else if (edge1.isLine) {\n return intersectEdge2Line(edge2, edge1.shape)\n }\n else if (edge1.isRay) {\n return intersectEdge2Ray(edge2, edge1.shape)\n }\n return []\n}\n\nfunction intersectEdge2Polygon(edge, polygon) {\n let ip = [];\n\n if (polygon.isEmpty() || edge.shape.box.not_intersect(polygon.box)) {\n return ip;\n }\n\n let resp_edges = polygon.edges.search(edge.shape.box);\n\n for (let resp_edge of resp_edges) {\n ip = [...ip, ...intersectEdge2Edge(edge, resp_edge)];\n }\n\n return ip;\n}\n\nfunction intersectPolygon2Polygon(polygon1, polygon2) {\n let ip = [];\n\n if (polygon1.isEmpty() || polygon2.isEmpty()) {\n return ip;\n }\n\n if (polygon1.box.not_intersect(polygon2.box)) {\n return ip;\n }\n\n for (let edge1 of polygon1.edges) {\n ip = [...ip, ...intersectEdge2Polygon(edge1, polygon2)];\n }\n\n return ip;\n}\n\nfunction intersectShape2Polygon(shape, polygon) {\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, polygon);\n }\n else if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, polygon);\n }\n else {\n return [];\n }\n}\n\nfunction ptInIntPoints(new_pt, ip) {\n return ip.some( pt => pt.equalTo(new_pt) )\n}\n\nfunction createLineFromRay(ray) {\n return new Flatten.Line(ray.start, ray.norm)\n}\nfunction intersectRay2Segment(ray, segment) {\n return intersectSegment2Line(segment, createLineFromRay(ray))\n .filter(pt => ray.contains(pt));\n}\n\nfunction intersectRay2Arc(ray, arc) {\n return intersectLine2Arc(createLineFromRay(ray), arc)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Circle(ray, circle) {\n return intersectLine2Circle(createLineFromRay(ray), circle)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Box(ray, box) {\n return intersectLine2Box(createLineFromRay(ray), box)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Line(ray, line) {\n return intersectLine2Line(createLineFromRay(ray), line)\n .filter(pt => ray.contains(pt))\n}\n\nfunction intersectRay2Ray(ray1, ray2) {\n return intersectLine2Line(createLineFromRay(ray1), createLineFromRay(ray2))\n .filter(pt => ray1.contains(pt))\n .filter(pt => ray2.contains(pt))\n}\n\nfunction intersectRay2Polygon(ray, polygon) {\n return intersectLine2Polygon(createLineFromRay(ray), polygon)\n .filter(pt => ray.contains(pt))\n}\n\nconst defaultAttributes = {\n stroke: \"black\"\n};\n\nclass SVGAttributes {\n constructor(args = defaultAttributes) {\n for(const property in args) {\n this[property] = args[property];\n }\n this.stroke = args.stroke ?? defaultAttributes.stroke;\n }\n\n toAttributesString() {\n return Object.keys(this)\n .reduce( (acc, key) =>\n acc + (this[key] !== undefined ? this.toAttrString(key, this[key]) : \"\")\n , ``)\n }\n\n toAttrString(key, value) {\n const SVGKey = key === \"className\" ? \"class\" : this.convertCamelToKebabCase(key);\n return value === null ? `${SVGKey} ` : `${SVGKey}=\"${value.toString()}\" `\n }\n\n convertCamelToKebabCase(str) {\n return str\n .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)\n .join('-')\n .toLowerCase();\n }\n}\n\nfunction convertToString(attrs) {\n return new SVGAttributes(attrs).toAttributesString()\n}\n\n/**\n * Class Multiline represent connected path of [edges]{@link Flatten.Edge}, where each edge may be\n * [segment]{@link Flatten.Segment}, [arc]{@link Flatten.Arc}, [line]{@link Flatten.Line} or [ray]{@link Flatten.Ray}\n */\nclass Multiline extends LinkedList {\n constructor(...args) {\n super();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n let shapes = args[0];\n if (shapes.length === 0)\n return;\n\n // TODO: more strict validation:\n // there may be only one line\n // only first and last may be rays\n shapes.every((shape) => {\n return shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc ||\n shape instanceof Flatten.Ray ||\n shape instanceof Flatten.Line\n });\n\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n }\n\n this.setArcLength();\n }\n }\n }\n\n /**\n * (Getter) Return array of edges\n * @returns {Edge[]}\n */\n get edges() {\n return [...this];\n }\n\n /**\n * (Getter) Return bounding box of the multiline\n * @returns {Box}\n */\n get box() {\n return this.edges.reduce( (acc,edge) => acc.merge(edge.box), new Flatten.Box() );\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Point[]}\n */\n get vertices() {\n let v = this.edges.map(edge => edge.start);\n v.push(this.last.end);\n return v;\n }\n\n /**\n * Return new cloned instance of Multiline\n * @returns {Multiline}\n */\n clone() {\n return new Multiline(this.toShapes());\n }\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Split edge and add new vertex, return new edge inserted\n * @param {Point} pt - point on edge that will be added as new vertex\n * @param {Edge} edge - edge to split\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n this.insert(newEdge, edgeBefore); // edge.face ?\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n return newEdge;\n }\n\n getChain(edgeFrom, edgeTo) {\n let edges = [];\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n edges.push(edge);\n }\n return edges\n }\n\n /**\n * Split edges of multiline with intersection points and return mutated multiline\n * @param {Point[]} ip - array of points to be added as new vertices\n * @returns {Multiline}\n */\n split(ip) {\n for (let pt of ip) {\n let edge = this.findEdgeByPoint(pt);\n this.addVertex(pt, edge);\n }\n return this;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new multiline translated by vector vec\n * @param {Vector} vec\n * @returns {Multiline}\n */\n translate(vec) {\n return new Multiline(this.edges.map( edge => edge.shape.translate(vec)));\n }\n\n /**\n * Return new multiline rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Multiline} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n return new Multiline(this.edges.map( edge => edge.shape.rotate(angle, center) ));\n }\n\n /**\n * Return new multiline transformed using affine transformation matrix\n * Method does not support unbounded shapes\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Multiline} - new multiline\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Multiline(this.edges.map( edge => edge.shape.transform(matrix)));\n }\n\n /**\n * Transform multiline into array of shapes\n * @returns {Shape[]}\n */\n toShapes() {\n return this.edges.map(edge => edge.shape.clone())\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Return string to draw multiline in svg\n * @param attrs - an object with attributes for svg path element\n * TODO: support semi-infinite Ray and infinite Line\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Multiline = Multiline;\n\n/**\n * Shortcut function to create multiline\n * @param args\n */\nconst multiline = (...args) => new Flatten.Multiline(...args);\nFlatten.multiline = multiline;\n\n/**\n * @module RayShoot\n */\n/**\n * Implements ray shooting algorithm. Returns relation between point and polygon: inside, outside or boundary\n * @param {Polygon} polygon - polygon to test\n * @param {Point} point - point to test\n * @returns {INSIDE|OUTSIDE|BOUNDARY}\n */\nfunction ray_shoot(polygon, point) {\n let contains = undefined;\n\n // 1. Quick reject\n // if (polygon.box.not_intersect(point.box)) {\n // return Flatten.OUTSIDE;\n // }\n\n let ray = new Flatten.Ray(point);\n let line = new Flatten.Line(ray.pt, ray.norm);\n\n // 2. Locate relevant edges of the polygon\n const searchBox = new Flatten.Box(\n ray.box.xmin-Flatten.DP_TOL, ray.box.ymin-Flatten.DP_TOL,\n ray.box.xmax, ray.box.ymax+Flatten.DP_TOL\n );\n\n if (polygon.box.not_intersect(searchBox)) {\n return Flatten.OUTSIDE;\n }\n\n let resp_edges = polygon.edges.search(searchBox);\n\n if (resp_edges.length === 0) {\n return Flatten.OUTSIDE;\n }\n\n // 2.5 Check if boundary\n for (let edge of resp_edges) {\n if (edge.shape.contains(point)) {\n return Flatten.BOUNDARY;\n }\n }\n\n let faces = [...polygon.faces];\n\n // 3. Calculate intersections\n let intersections = [];\n for (let edge of resp_edges) {\n for (let ip of ray.intersect(edge.shape)) {\n\n // If intersection is equal to query point then point lays on boundary\n if (ip.equalTo(point)) {\n return Flatten.BOUNDARY;\n }\n\n intersections.push({\n pt: ip,\n edge: edge,\n face_index: faces.indexOf(edge.face)\n });\n }\n }\n\n // 4. Sort intersection in x-ascending order\n intersections.sort((i1, i2) => {\n if (LT(i1.pt.x, i2.pt.x)) {\n return -1;\n }\n if (GT(i1.pt.x, i2.pt.x)) {\n return 1;\n }\n if (i1.face_index < i2.face_index) {\n return -1\n }\n if (i1.face_index > i2.face_index) {\n return 1\n }\n if (i1.edge.arc_length < i2.edge.arc_length) {\n return -1\n }\n if (i1.edge.arc_length > i2.edge.arc_length) {\n return 1\n }\n return 0;\n });\n\n // 5. Count real intersections, exclude touching\n let counter = 0;\n\n for (let i = 0; i < intersections.length; i++) {\n let intersection = intersections[i];\n\n if (intersection.pt.equalTo(intersection.edge.shape.start)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.face_index === intersections[i - 1].face_index &&\n intersection.edge.prev === intersections[i - 1].edge) {\n continue;\n }\n\n let prev_edge = intersection.edge.prev;\n while (EQ_0(prev_edge.length)) {\n prev_edge = prev_edge.prev;\n }\n let prev_tangent = prev_edge.shape.tangentInEnd();\n let prev_point = intersection.pt.translate(prev_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInStart();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let prev_on_the_left = prev_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((prev_on_the_left && !cur_on_the_left) || (!prev_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else if (intersection.pt.equalTo(intersection.edge.shape.end)) {\n /* skip same point between same edges if already counted */\n if (i > 0 && intersection.pt.equalTo(intersections[i - 1].pt) &&\n intersection.face_index === intersections[i-1].face_index &&\n intersection.edge.next === intersections[i - 1].edge) {\n continue;\n }\n\n let next_edge = intersection.edge.next;\n while (EQ_0(next_edge.length)) {\n next_edge = next_edge.next;\n }\n let next_tangent = next_edge.shape.tangentInStart();\n let next_point = intersection.pt.translate(next_tangent);\n\n let cur_tangent = intersection.edge.shape.tangentInEnd();\n let cur_point = intersection.pt.translate(cur_tangent);\n\n let next_on_the_left = next_point.leftTo(line);\n let cur_on_the_left = cur_point.leftTo(line);\n\n if ((next_on_the_left && !cur_on_the_left) || (!next_on_the_left && cur_on_the_left)) {\n counter++;\n }\n } else { /* intersection point is not a vertex */\n if (intersection.edge.shape instanceof Flatten.Segment) {\n counter++;\n } else {\n /* Check if ray does not touch the curve in the extremal (top or bottom) point */\n let box = intersection.edge.shape.box;\n if (!(EQ(intersection.pt.y, box.ymin) ||\n EQ(intersection.pt.y, box.ymax))) {\n counter++;\n }\n }\n }\n }\n\n // 6. Odd or even?\n contains = counter % 2 === 1 ? INSIDE$2 : OUTSIDE$1;\n return contains;\n}\n\n/*\n Calculate relationship between two shapes and return result in the form of\n Dimensionally Extended nine-Intersection Matrix (https://en.wikipedia.org/wiki/DE-9IM)\n */\n\n\n/**\n * Returns true if shapes are topologically equal: their interiors intersect and\n * no part of the interior or boundary of one geometry intersects the exterior of the other\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction equal(shape1, shape2) {\n return relate(shape1, shape2).equal();\n}\n\n/**\n * Returns true if shapes have at least one point in common, same as \"not disjoint\"\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction intersect(shape1, shape2) {\n return relate(shape1, shape2).intersect();\n}\n\n/**\n * Returns true if shapes have at least one point in common, but their interiors do not intersect\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction touch(shape1, shape2) {\n return relate(shape1, shape2).touch();\n}\n\n/**\n * Returns true if shapes have no points in common neither in interior nor in boundary\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction disjoint(shape1, shape2) {\n return !intersect(shape1, shape2);\n}\n\n/**\n * Returns true shape1 lies in the interior of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction inside(shape1, shape2) {\n return relate(shape1, shape2).inside();\n}\n\n/**\n * Returns true if every point in shape1 lies in the interior or on the boundary of shape2\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction covered(shape1, shape2) {\n return relate(shape1, shape2).covered();\n}\n\n/**\n * Returns true shape1's interior contains shape2
\n * Same as inside(shape2, shape1)\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction contain(shape1, shape2) {\n return inside(shape2, shape1);\n}\n\n/**\n * Returns true shape1's cover shape2, same as shape2 covered by shape1\n * @param shape1\n * @param shape2\n * @returns {boolean}\n */\nfunction cover(shape1, shape2) {\n return covered(shape2, shape1);\n}\n\n/**\n * Returns relation between two shapes as intersection 3x3 matrix, where each\n * element contains relevant intersection as array of shapes.\n * If there is no intersection, element contains empty array\n * If intersection is irrelevant it left undefined. (For example, intersection\n * between two exteriors is usually irrelevant)\n * @param shape1\n * @param shape2\n * @returns {DE9IM}\n */\nfunction relate(shape1, shape2) {\n if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Line) {\n return relateLine2Line(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Circle) {\n return relateLine2Circle(shape1, shape2);\n }\n else if (shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Box) {\n return relateLine2Box(shape1, shape2);\n }\n else if ( shape1 instanceof Flatten.Line && shape2 instanceof Flatten.Polygon) {\n return relateLine2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) && shape2 instanceof Flatten.Polygon) {\n return relateShape2Polygon(shape1, shape2);\n }\n else if ( (shape1 instanceof Flatten.Segment || shape1 instanceof Flatten.Arc) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box) ) {\n return relateShape2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n else if (shape1 instanceof Flatten.Polygon && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(shape1, shape2);\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) &&\n (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), new Flatten.Polygon(shape2));\n }\n else if ((shape1 instanceof Flatten.Circle || shape1 instanceof Flatten.Box) && shape2 instanceof Flatten.Polygon) {\n return relatePolygon2Polygon(new Flatten.Polygon(shape1), shape2);\n }\n else if (shape1 instanceof Flatten.Polygon && (shape2 instanceof Flatten.Circle || shape2 instanceof Flatten.Box)) {\n return relatePolygon2Polygon(shape1, new Flatten.Polygon(shape2));\n }\n}\n\nfunction relateLine2Line(line1, line2) {\n let denim = new DE9IM();\n let ip = intersectLine2Line(line1, line2);\n if (ip.length === 0) { // parallel or equal ?\n if (line1.contains(line2.pt) && line2.contains(line1.pt)) {\n denim.I2I = [line1]; // equal 'T.F...F..' - no boundary\n denim.I2E = [];\n denim.E2I = [];\n }\n else { // parallel - disjoint 'FFTFF*T**'\n denim.I2I = [];\n denim.I2E = [line1];\n denim.E2I = [line2];\n }\n }\n else { // intersect 'T********'\n denim.I2I = ip;\n denim.I2E = line1.split(ip);\n denim.E2I = line2.split(ip);\n }\n return denim;\n}\n\nfunction relateLine2Circle(line,circle) {\n let denim = new DE9IM();\n let ip = intersectLine2Circle(line, circle);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n denim.E2I = [circle];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [circle];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n denim.I2I = [splitShapes[1]];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon([circle.toArc()]).cutWithLine(line);\n }\n\n return denim;\n}\n\nfunction relateLine2Box(line, box) {\n let denim = new DE9IM();\n let ip = intersectLine2Box(line, box);\n if (ip.length === 0) {\n denim.I2I = [];\n denim.I2B = [];\n denim.I2E = [line];\n\n denim.E2I = [box];\n }\n else if (ip.length === 1) {\n denim.I2I = [];\n denim.I2B = ip;\n denim.I2E = line.split(ip);\n\n denim.E2I = [box];\n }\n else { // ip.length == 2\n let multiline = new Multiline([line]);\n let ip_sorted = line.sortPoints(ip);\n multiline.split(ip_sorted);\n let splitShapes = multiline.toShapes();\n\n /* Are two intersection points on the same segment of the box boundary ? */\n if (box.toSegments().some( segment => segment.contains(ip[0]) && segment.contains(ip[1]) )) {\n denim.I2I = []; // case of touching\n denim.I2B = [splitShapes[1]];\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = [box];\n }\n else { // case of intersection\n denim.I2I = [splitShapes[1]]; // [segment(ip[0], ip[1])];\n denim.I2B = ip_sorted;\n denim.I2E = [splitShapes[0], splitShapes[2]];\n\n denim.E2I = new Flatten.Polygon(box.toSegments()).cutWithLine(line);\n }\n }\n return denim;\n}\n\nfunction relateLine2Polygon(line, polygon) {\n let denim = new DE9IM();\n let ip = intersectLine2Polygon(line, polygon);\n let multiline = new Multiline([line]);\n let ip_sorted = ip.length > 0 ? ip.slice() : line.sortPoints(ip);\n\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n denim.E2I = polygon.cutWithLine(line);\n\n return denim;\n}\n\nfunction relateShape2Polygon(shape, polygon) {\n let denim = new DE9IM();\n let ip = intersectShape2Polygon(shape, polygon);\n let ip_sorted = ip.length > 0 ? ip.slice() : shape.sortPoints(ip);\n\n let multiline = new Multiline([shape]);\n multiline.split(ip_sorted);\n\n [...multiline].forEach(edge => edge.setInclusion(polygon));\n\n denim.I2I = [...multiline].filter(edge => edge.bv === Flatten.INSIDE).map(edge => edge.shape);\n denim.I2B = [...multiline].slice(1).map( (edge) => edge.bv === Flatten.BOUNDARY ? edge.shape : edge.shape.start );\n denim.I2E = [...multiline].filter(edge => edge.bv === Flatten.OUTSIDE).map(edge => edge.shape);\n\n\n denim.B2I = [];\n denim.B2B = [];\n denim.B2E = [];\n for (let pt of [shape.start, shape.end]) {\n switch (ray_shoot(polygon, pt)) {\n case Flatten.INSIDE:\n denim.B2I.push(pt);\n break;\n case Flatten.BOUNDARY:\n denim.B2B.push(pt);\n break;\n case Flatten.OUTSIDE:\n denim.B2E.push(pt);\n break;\n }\n }\n\n // denim.E2I TODO: calculate, not clear what is expected result\n\n return denim;\n}\n\nfunction relatePolygon2Polygon(polygon1, polygon2) {\n let denim = new DE9IM();\n\n let [ip_sorted1, ip_sorted2] = calculateIntersections(polygon1, polygon2);\n let boolean_intersection = intersect$1(polygon1, polygon2);\n let boolean_difference1 = subtract(polygon1, polygon2);\n let boolean_difference2 = subtract(polygon2, polygon1);\n let [inner_clip_shapes1, inner_clip_shapes2] = innerClip(polygon1, polygon2);\n let outer_clip_shapes1 = outerClip(polygon1, polygon2);\n let outer_clip_shapes2 = outerClip(polygon2, polygon1);\n\n denim.I2I = boolean_intersection.isEmpty() ? [] : [boolean_intersection];\n denim.I2B = inner_clip_shapes2;\n denim.I2E = boolean_difference1.isEmpty() ? [] : [boolean_difference1];\n\n denim.B2I = inner_clip_shapes1;\n denim.B2B = ip_sorted1;\n denim.B2E = outer_clip_shapes1;\n\n denim.E2I = boolean_difference2.isEmpty() ? [] : [boolean_difference2];\n denim.E2B = outer_clip_shapes2;\n // denim.E2E not relevant meanwhile\n\n return denim;\n}\n\nvar Relations = /*#__PURE__*/Object.freeze({\n __proto__: null,\n contain: contain,\n cover: cover,\n covered: covered,\n disjoint: disjoint,\n equal: equal,\n inside: inside,\n intersect: intersect,\n relate: relate,\n touch: touch\n});\n\n/**\n * Class representing an affine transformation 3x3 matrix:\n *
\n *      [ a  c  tx\n * A =    b  d  ty\n *        0  0  1  ]\n * \n     * If parameters omitted, construct identity matrix a = 1, d = 1\n     * @param {number} a - position(0,0)   sx*cos(alpha)\n     * @param {number} b - position (0,1)  sx*sin(alpha)\n     * @param {number} c - position (1,0)  -sy*sin(alpha)\n     * @param {number} d - position (1,1)  sy*cos(alpha)\n     * @param {number} tx - position (2,0) translation by x\n     * @param {number} ty - position (2,1) translation by y\n     */\n    constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) {\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.tx = tx;\n        this.ty = ty;\n    }\n\n    /**\n     * Return new cloned instance of matrix\n     * @return {Matrix}\n     **/\n    clone() {\n        return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);\n    };\n\n    /**\n     * Transform vector [x,y] using transformation matrix. 
\n * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object
\n * The result is also an abstract vector [x',y'] = A * [x,y]:\n * \n * [x' [ ax + by + tx\n * y' = cx + dy + ty\n * 1] 1 ]\n * \n * @param {number[]} vector - array[2] of numbers\n * @returns {number[]} transformation result - array[2] of numbers\n */\n transform(vector) {\n return [\n vector[0] * this.a + vector[1] * this.c + this.tx,\n vector[0] * this.b + vector[1] * this.d + this.ty\n ]\n };\n\n /**\n * Returns result of multiplication of this matrix by other matrix\n * @param {Matrix} other_matrix - matrix to multiply by\n * @returns {Matrix}\n */\n multiply(other_matrix) {\n return new Matrix(\n this.a * other_matrix.a + this.c * other_matrix.b,\n this.b * other_matrix.a + this.d * other_matrix.b,\n this.a * other_matrix.c + this.c * other_matrix.d,\n this.b * other_matrix.c + this.d * other_matrix.d,\n this.a * other_matrix.tx + this.c * other_matrix.ty + this.tx,\n this.b * other_matrix.tx + this.d * other_matrix.ty + this.ty\n )\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix(1,0,0,1,tx,ty)\n * @param {Vector} vector - Translation by vector or\n * @param {number} tx - translation by x-axis\n * @param {number} ty - translation by y-axis\n * @returns {Matrix}\n */\n translate(...args) {\n let tx, ty;\n if (args.length == 1 && !isNaN(args[0].x) && !isNaN(args[0].y)) {\n tx = args[0].x;\n ty = args[0].y;\n } else if (args.length === 2 && typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n tx = args[0];\n ty = args[1];\n } else {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n return this.multiply(new Matrix(1, 0, 0, 1, tx, ty))\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix that defines rotation by given angle (in radians) around\n * center of rotation (centerX,centerY) in counterclockwise direction\n * @param {number} angle - angle in radians\n * @param {number} centerX - center of rotation\n * @param {number} centerY - center of rotation\n * @returns {Matrix}\n */\n rotate(angle, centerX = 0.0, centerY = 0.0) {\n let cos = Math.cos(angle);\n let sin = Math.sin(angle);\n return this\n .translate(centerX, centerY)\n .multiply(new Matrix(cos, sin, -sin, cos, 0, 0))\n .translate(-centerX, -centerY);\n };\n\n /**\n * Return new matrix as a result of multiplication of the current matrix\n * by the matrix (sx,0,0,sy,0,0) that defines scaling\n * @param {number} sx\n * @param {number} sy\n * @returns {Matrix}\n */\n scale(sx, sy) {\n return this.multiply(new Matrix(sx, 0, 0, sy, 0, 0));\n };\n\n /**\n * Returns true if two matrix are equal parameter by parameter\n * @param {Matrix} matrix - other matrix\n * @returns {boolean} true if equal, false otherwise\n */\n equalTo(matrix) {\n if (!Flatten.Utils.EQ(this.tx, matrix.tx)) return false;\n if (!Flatten.Utils.EQ(this.ty, matrix.ty)) return false;\n if (!Flatten.Utils.EQ(this.a, matrix.a)) return false;\n if (!Flatten.Utils.EQ(this.b, matrix.b)) return false;\n if (!Flatten.Utils.EQ(this.c, matrix.c)) return false;\n if (!Flatten.Utils.EQ(this.d, matrix.d)) return false;\n return true;\n };\n}\nFlatten.Matrix = Matrix;\n/**\n * Function to create matrix equivalent to \"new\" constructor\n * @param args\n */\nconst matrix = (...args) => new Flatten.Matrix(...args);\nFlatten.matrix = matrix;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n/**\n * Interval is a pair of numbers or a pair of any comparable objects on which may be defined predicates\n * *equal*, *less* and method *max(p1, p1)* that returns maximum in a pair.\n * When interval is an object rather than pair of numbers, this object should have properties *low*, *high*, *max*\n * and implement methods *less_than(), equal_to(), intersect(), not_intersect(), clone(), output()*.\n * Two static methods *comparable_max(), comparable_less_than()* define how to compare values in pair.
\n * This interface is described in typescript definition file *index.d.ts*\n *\n * Axis aligned rectangle is an example of such interval.\n * We may look at rectangle as an interval between its low left and top right corners.\n * See **Box** class in [flatten-js](https://github.com/alexbol99/flatten-js) library as the example\n * of Interval interface implementation\n * @type {Interval}\n */\nconst Interval = class Interval {\n /**\n * Accept two comparable values and creates new instance of interval\n * Predicate Interval.comparable_less(low, high) supposed to return true on these values\n * @param low\n * @param high\n */\n constructor(low, high) {\n this.low = low;\n this.high = high;\n }\n\n /**\n * Clone interval\n * @returns {Interval}\n */\n clone() {\n return new Interval(this.low, this.high);\n }\n\n /**\n * Propery max returns clone of this interval\n * @returns {Interval}\n */\n get max() {\n return this.clone(); // this.high;\n }\n\n /**\n * Predicate returns true is this interval less than other interval\n * @param other_interval\n * @returns {boolean}\n */\n less_than(other_interval) {\n return this.low < other_interval.low ||\n this.low == other_interval.low && this.high < other_interval.high;\n }\n\n /**\n * Predicate returns true is this interval equals to other interval\n * @param other_interval\n * @returns {boolean}\n */\n equal_to(other_interval) {\n return this.low == other_interval.low && this.high == other_interval.high;\n }\n\n /**\n * Predicate returns true if this interval intersects other interval\n * @param other_interval\n * @returns {boolean}\n */\n intersect(other_interval) {\n return !this.not_intersect(other_interval);\n }\n\n /**\n * Predicate returns true if this interval does not intersect other interval\n * @param other_interval\n * @returns {boolean}\n */\n not_intersect(other_interval) {\n return (this.high < other_interval.low || other_interval.high < this.low);\n }\n\n /**\n * Returns new interval merged with other interval\n * @param {Interval} interval - Other interval to merge with\n * @returns {Interval}\n */\n merge(other_interval) {\n return new Interval(\n this.low === undefined ? other_interval.low : Math.min(this.low, other_interval.low),\n this.high === undefined ? other_interval.high : Math.max(this.high, other_interval.high)\n );\n }\n\n /**\n * Returns how key should return\n */\n output() {\n return [this.low, this.high];\n }\n\n /**\n * Function returns maximum between two comparable values\n * @param interval1\n * @param interval2\n * @returns {Interval}\n */\n static comparable_max(interval1, interval2) {\n return interval1.merge(interval2);\n }\n\n /**\n * Predicate returns true if first value less than second value\n * @param val1\n * @param val2\n * @returns {boolean}\n */\n static comparable_less_than(val1, val2 ) {\n return val1 < val2;\n }\n};\n\n/**\n * Created by Alex Bol on 3/28/2017.\n */\n\n\n// module.exports = {\n// RB_TREE_COLOR_RED: 0,\n// RB_TREE_COLOR_BLACK: 1\n// };\n\nconst RB_TREE_COLOR_RED = 0;\nconst RB_TREE_COLOR_BLACK = 1;\n\n/**\n * Created by Alex Bol on 4/1/2017.\n */\n\n\nclass Node {\n constructor(key = undefined, value = undefined,\n left = null, right = null, parent = null, color = RB_TREE_COLOR_BLACK) {\n this.left = left; // reference to left child node\n this.right = right; // reference to right child node\n this.parent = parent; // reference to parent node\n this.color = color;\n\n this.item = {key: key, value: value}; // key is supposed to be instance of Interval\n\n /* If not, this should by an array of two numbers */\n if (key && key instanceof Array && key.length == 2) {\n if (!Number.isNaN(key[0]) && !Number.isNaN(key[1])) {\n this.item.key = new Interval(Math.min(key[0], key[1]), Math.max(key[0], key[1]));\n }\n }\n\n this.max = this.item.key ? this.item.key.max : undefined;\n }\n\n isNil() {\n return (this.item.key === undefined && this.item.value === undefined &&\n this.left === null && this.right === null && this.color === RB_TREE_COLOR_BLACK);\n }\n\n _value_less_than(other_node) {\n return this.item.value && other_node.item.value && this.item.value.less_than ?\n this.item.value.less_than(other_node.item.value) :\n this.item.value < other_node.item.value;\n }\n\n less_than(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.less_than(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.less_than(other_node.item.key) ||\n this.item.key.equal_to((other_node.item.key)) && this._value_less_than(other_node)\n }\n }\n\n _value_equal(other_node) {\n return this.item.value && other_node.item.value && this.item.value.equal_to ?\n this.item.value.equal_to(other_node.item.value) :\n this.item.value == other_node.item.value;\n }\n equal_to(other_node) {\n // if tree stores only keys\n if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) {\n return this.item.key.equal_to(other_node.item.key);\n }\n else { // if tree stores keys and values\n return this.item.key.equal_to(other_node.item.key) && this._value_equal(other_node);\n }\n }\n\n intersect(other_node) {\n return this.item.key.intersect(other_node.item.key);\n }\n\n copy_data(other_node) {\n this.item.key = other_node.item.key;\n this.item.value = other_node.item.value;\n }\n\n update_max() {\n // use key (Interval) max property instead of key.high\n this.max = this.item.key ? this.item.key.max : undefined;\n if (this.right && this.right.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.right.max);\n }\n if (this.left && this.left.max) {\n const comparable_max = this.item.key.constructor.comparable_max; // static method\n this.max = comparable_max(this.max, this.left.max);\n }\n }\n\n // Other_node does not intersect any node of left subtree, if this.left.max < other_node.item.key.low\n not_intersect_left_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let high = this.left.max.high !== undefined ? this.left.max.high : this.left.max;\n return comparable_less_than(high, search_node.item.key.low);\n }\n\n // Other_node does not intersect right subtree if other_node.item.key.high < this.right.key.low\n not_intersect_right_subtree(search_node) {\n const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method\n let low = this.right.max.low !== undefined ? this.right.max.low : this.right.item.key.low;\n return comparable_less_than(search_node.item.key.high, low);\n }\n}\n\n/**\n * Created by Alex Bol on 3/31/2017.\n */\n\n// const nil_node = new Node();\n\n/**\n * Implementation of interval binary search tree
\n * Interval tree stores items which are couples of {key:interval, value: value}
\n * Interval is an object with high and low properties or simply pair [low,high] of numeric values
\n * @type {IntervalTree}\n */\nclass IntervalTree {\n /**\n * Construct new empty instance of IntervalTree\n */\n constructor() {\n this.root = null;\n this.nil_node = new Node();\n }\n\n /**\n * Returns number of items stored in the interval tree\n * @returns {number}\n */\n get size() {\n let count = 0;\n this.tree_walk(this.root, () => count++);\n return count;\n }\n\n /**\n * Returns array of sorted keys in the ascending order\n * @returns {Array}\n */\n get keys() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(\n node.item.key.output ? node.item.key.output() : node.item.key\n ));\n return res;\n }\n\n /**\n * Return array of values in the ascending keys order\n * @returns {Array}\n */\n get values() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push(node.item.value));\n return res;\n }\n\n /**\n * Returns array of items ( pairs) in the ascended keys order\n * @returns {Array}\n */\n get items() {\n let res = [];\n this.tree_walk(this.root, (node) => res.push({\n key: node.item.key.output ? node.item.key.output() : node.item.key,\n value: node.item.value\n }));\n return res;\n }\n\n /**\n * Returns true if tree is empty\n * @returns {boolean}\n */\n isEmpty() {\n return (this.root == null || this.root == this.nil_node);\n }\n\n /**\n * Clear tree\n */\n clear() {\n this.root = null;\n }\n\n /**\n * Insert new item into interval tree\n * @param {Interval} key - interval object or array of two numbers [low, high]\n * @param {any} value - value representing any object (optional)\n * @returns {Node} returns reference to inserted node as an object {key:interval, value: value}\n */\n insert(key, value = key) {\n if (key === undefined) return;\n let insert_node = new Node(key, value, this.nil_node, this.nil_node, null, RB_TREE_COLOR_RED);\n this.tree_insert(insert_node);\n this.recalc_max(insert_node);\n return insert_node;\n }\n\n /**\n * Returns true if item {key,value} exist in the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object to be checked\n * @returns {boolean} true if item {key, value} exist in the tree, false otherwise\n */\n exist(key, value = key) {\n let search_node = new Node(key, value);\n return this.tree_search(this.root, search_node) ? true : false;\n }\n\n /**\n * Remove entry {key, value} from the tree\n * @param {Interval} key - interval correspondent to keys stored in the tree\n * @param {any} value - value object\n * @returns {boolean} true if item {key, value} deleted, false if not found\n */\n remove(key, value = key) {\n let search_node = new Node(key, value);\n let delete_node = this.tree_search(this.root, search_node);\n if (delete_node) {\n this.tree_delete(delete_node);\n }\n return delete_node;\n }\n\n /**\n * Returns array of entry values which keys intersect with given interval
\n * If no values stored in the tree, returns array of keys which intersect given interval\n * @param {Interval} interval - search interval, or tuple [low, high]\n * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output\n * @returns {Array}\n */\n search(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {\n let search_node = new Node(interval);\n let resp_nodes = [];\n this.tree_search_interval(this.root, search_node, resp_nodes);\n return resp_nodes.map(node => outputMapperFn(node.item.value, node.item.key))\n }\n\n /**\n * Returns true if intersection between given and any interval stored in the tree found\n * @param {Interval} interval - search interval or tuple [low, high]\n * @returns {boolean}\n */\n intersect_any(interval) {\n let search_node = new Node(interval);\n let found = this.tree_find_any_interval(this.root, search_node);\n return found;\n }\n\n /**\n * Tree visitor. For each node implement a callback function.
\n * Method calls a callback function with two parameters (key, value)\n * @param visitor(key,value) - function to be called for each tree item\n */\n forEach(visitor) {\n this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));\n }\n\n /** Value Mapper. Walk through every node and map node value to another value\n * @param callback(value,key) - function to be called for each tree item\n */\n map(callback) {\n const tree = new IntervalTree();\n this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));\n return tree;\n }\n\n recalc_max(node) {\n let node_current = node;\n while (node_current.parent != null) {\n node_current.parent.update_max();\n node_current = node_current.parent;\n }\n }\n\n tree_insert(insert_node) {\n let current_node = this.root;\n let parent_node = null;\n\n if (this.root == null || this.root == this.nil_node) {\n this.root = insert_node;\n }\n else {\n while (current_node != this.nil_node) {\n parent_node = current_node;\n if (insert_node.less_than(current_node)) {\n current_node = current_node.left;\n }\n else {\n current_node = current_node.right;\n }\n }\n\n insert_node.parent = parent_node;\n\n if (insert_node.less_than(parent_node)) {\n parent_node.left = insert_node;\n }\n else {\n parent_node.right = insert_node;\n }\n }\n\n this.insert_fixup(insert_node);\n }\n\n// After insertion insert_node may have red-colored parent, and this is a single possible violation\n// Go upwords to the root and re-color until violation will be resolved\n insert_fixup(insert_node) {\n let current_node;\n let uncle_node;\n\n current_node = insert_node;\n while (current_node != this.root && current_node.parent.color == RB_TREE_COLOR_RED) {\n if (current_node.parent == current_node.parent.parent.left) { // parent is left child of grandfather\n uncle_node = current_node.parent.parent.right; // right brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 1. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else { // Case 2 & 3. Uncle is black\n if (current_node == current_node.parent.right) { // Case 2. Current if right child\n // This case is transformed into Case 3.\n current_node = current_node.parent;\n this.rotate_left(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 3. Current is left child.\n // Re-color father and grandfather, rotate grandfather right\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_right(current_node.parent.parent);\n }\n }\n else { // parent is right child of grandfather\n uncle_node = current_node.parent.parent.left; // left brother of parent\n if (uncle_node.color == RB_TREE_COLOR_RED) { // Case 4. Uncle is red\n // re-color father and uncle into black\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n uncle_node.color = RB_TREE_COLOR_BLACK;\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n current_node = current_node.parent.parent;\n }\n else {\n if (current_node == current_node.parent.left) { // Case 5. Current is left child\n // Transform into case 6\n current_node = current_node.parent;\n this.rotate_right(current_node);\n }\n current_node.parent.color = RB_TREE_COLOR_BLACK; // Case 6. Current is right child.\n // Re-color father and grandfather, rotate grandfather left\n current_node.parent.parent.color = RB_TREE_COLOR_RED;\n this.rotate_left(current_node.parent.parent);\n }\n }\n }\n\n this.root.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_delete(delete_node) {\n let cut_node; // node to be cut - either delete_node or successor_node (\"y\" from 14.4)\n let fix_node; // node to fix rb tree property (\"x\" from 14.4)\n\n if (delete_node.left == this.nil_node || delete_node.right == this.nil_node) { // delete_node has less then 2 children\n cut_node = delete_node;\n }\n else { // delete_node has 2 children\n cut_node = this.tree_successor(delete_node);\n }\n\n // fix_node if single child of cut_node\n if (cut_node.left != this.nil_node) {\n fix_node = cut_node.left;\n }\n else {\n fix_node = cut_node.right;\n }\n\n // remove cut_node from parent\n /*if (fix_node != this.nil_node) {*/\n fix_node.parent = cut_node.parent;\n /*}*/\n\n if (cut_node == this.root) {\n this.root = fix_node;\n }\n else {\n if (cut_node == cut_node.parent.left) {\n cut_node.parent.left = fix_node;\n }\n else {\n cut_node.parent.right = fix_node;\n }\n cut_node.parent.update_max(); // update max property of the parent\n }\n\n this.recalc_max(fix_node); // update max property upward from fix_node to root\n\n // COPY DATA !!!\n // Delete_node becomes cut_node, it means that we cannot hold reference\n // to node in outer structure and we will have to delete by key, additional search need\n if (cut_node != delete_node) {\n delete_node.copy_data(cut_node);\n delete_node.update_max(); // update max property of the cut node at the new place\n this.recalc_max(delete_node); // update max property upward from delete_node to root\n }\n\n if (/*fix_node != this.nil_node && */cut_node.color == RB_TREE_COLOR_BLACK) {\n this.delete_fixup(fix_node);\n }\n }\n\n delete_fixup(fix_node) {\n let current_node = fix_node;\n let brother_node;\n\n while (current_node != this.root && current_node.parent != null && current_node.color == RB_TREE_COLOR_BLACK) {\n if (current_node == current_node.parent.left) { // fix node is left child\n brother_node = current_node.parent.right;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_left(current_node.parent);\n brother_node = current_node.parent.right; // update brother\n }\n // Derive to cases 2..4: brother is black\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2: both nephews black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 3: left nephew red, right nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.left.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_right(brother_node);\n brother_node = current_node.parent.right; // update brother\n // Derive to case 4: left nephew black, right nephew red\n }\n // case 4: left nephew black, right nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.right.color = RB_TREE_COLOR_BLACK;\n this.rotate_left(current_node.parent);\n current_node = this.root; // exit from loop\n }\n }\n else { // fix node is right child\n brother_node = current_node.parent.left;\n if (brother_node.color == RB_TREE_COLOR_RED) { // Case 1. Brother is red\n brother_node.color = RB_TREE_COLOR_BLACK; // re-color brother\n current_node.parent.color = RB_TREE_COLOR_RED; // re-color father\n this.rotate_right(current_node.parent);\n brother_node = current_node.parent.left; // update brother\n }\n // Go to cases 2..4\n if (brother_node.left.color == RB_TREE_COLOR_BLACK &&\n brother_node.right.color == RB_TREE_COLOR_BLACK) { // case 2\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n current_node = current_node.parent; // continue iteration\n }\n else {\n if (brother_node.left.color == RB_TREE_COLOR_BLACK) { // case 3: right nephew red, left nephew black\n brother_node.color = RB_TREE_COLOR_RED; // re-color brother\n brother_node.right.color = RB_TREE_COLOR_BLACK; // re-color nephew\n this.rotate_left(brother_node);\n brother_node = current_node.parent.left; // update brother\n // Derive to case 4: right nephew black, left nephew red\n }\n // case 4: right nephew black, left nephew red\n brother_node.color = current_node.parent.color;\n current_node.parent.color = RB_TREE_COLOR_BLACK;\n brother_node.left.color = RB_TREE_COLOR_BLACK;\n this.rotate_right(current_node.parent);\n current_node = this.root; // force exit from loop\n }\n }\n }\n\n current_node.color = RB_TREE_COLOR_BLACK;\n }\n\n tree_search(node, search_node) {\n if (node == null || node == this.nil_node)\n return undefined;\n\n if (search_node.equal_to(node)) {\n return node;\n }\n if (search_node.less_than(node)) {\n return this.tree_search(node.left, search_node);\n }\n else {\n return this.tree_search(node.right, search_node);\n }\n }\n\n // Original search_interval method; container res support push() insertion\n // Search all intervals intersecting given one\n tree_search_interval(node, search_node, res) {\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n this.tree_search_interval(node.left, search_node, res);\n }\n // if (low <= node->high && node->low <= high) {\n if (node.intersect(search_node)) {\n res.push(node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n this.tree_search_interval(node.right, search_node, res);\n }\n }\n }\n\n tree_find_any_interval(node, search_node) {\n let found = false;\n if (node != null && node != this.nil_node) {\n // if (node->left != this.nil_node && node->left->max >= low) {\n if (node.left != this.nil_node && !node.not_intersect_left_subtree(search_node)) {\n found = this.tree_find_any_interval(node.left, search_node);\n }\n // if (low <= node->high && node->low <= high) {\n if (!found) {\n found = node.intersect(search_node);\n }\n // if (node->right != this.nil_node && node->low <= high) {\n if (!found && node.right != this.nil_node && !node.not_intersect_right_subtree(search_node)) {\n found = this.tree_find_any_interval(node.right, search_node);\n }\n }\n return found;\n }\n\n local_minimum(node) {\n let node_min = node;\n while (node_min.left != null && node_min.left != this.nil_node) {\n node_min = node_min.left;\n }\n return node_min;\n }\n\n // not in use\n local_maximum(node) {\n let node_max = node;\n while (node_max.right != null && node_max.right != this.nil_node) {\n node_max = node_max.right;\n }\n return node_max;\n }\n\n tree_successor(node) {\n let node_successor;\n let current_node;\n let parent_node;\n\n if (node.right != this.nil_node) {\n node_successor = this.local_minimum(node.right);\n }\n else {\n current_node = node;\n parent_node = node.parent;\n while (parent_node != null && parent_node.right == current_node) {\n current_node = parent_node;\n parent_node = parent_node.parent;\n }\n node_successor = parent_node;\n }\n return node_successor;\n }\n\n // | right-rotate(T,y) |\n // y ---------------. x\n // / \\ / \\\n // x c left-rotate(T,x) a y\n // / \\ <--------------- / \\\n // a b b c\n\n rotate_left(x) {\n let y = x.right;\n\n x.right = y.left; // b goes to x.right\n\n if (y.left != this.nil_node) {\n y.left.parent = x; // x becomes parent of b\n }\n y.parent = x.parent; // move parent\n\n if (x == this.root) {\n this.root = y; // y becomes root\n }\n else { // y becomes child of x.parent\n if (x == x.parent.left) {\n x.parent.left = y;\n }\n else {\n x.parent.right = y;\n }\n }\n y.left = x; // x becomes left child of y\n x.parent = y; // and y becomes parent of x\n\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n\n y = x.parent;\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n }\n\n rotate_right(y) {\n let x = y.left;\n\n y.left = x.right; // b goes to y.left\n\n if (x.right != this.nil_node) {\n x.right.parent = y; // y becomes parent of b\n }\n x.parent = y.parent; // move parent\n\n if (y == this.root) { // x becomes root\n this.root = x;\n }\n else { // y becomes child of x.parent\n if (y == y.parent.left) {\n y.parent.left = x;\n }\n else {\n y.parent.right = x;\n }\n }\n x.right = y; // y becomes right child of x\n y.parent = x; // and x becomes parent of y\n\n if (y != null && y != this.nil_node) {\n y.update_max();\n }\n\n x = y.parent;\n if (x != null && x != this.nil_node) {\n x.update_max();\n }\n }\n\n tree_walk(node, action) {\n if (node != null && node != this.nil_node) {\n this.tree_walk(node.left, action);\n // arr.push(node.toArray());\n action(node);\n this.tree_walk(node.right, action);\n }\n }\n\n /* Return true if all red nodes have exactly two black child nodes */\n testRedBlackProperty() {\n let res = true;\n this.tree_walk(this.root, function (node) {\n if (node.color == RB_TREE_COLOR_RED) {\n if (!(node.left.color == RB_TREE_COLOR_BLACK && node.right.color == RB_TREE_COLOR_BLACK)) {\n res = false;\n }\n }\n });\n return res;\n }\n\n /* Throw error if not every path from root to bottom has same black height */\n testBlackHeightProperty(node) {\n let height = 0;\n let heightLeft = 0;\n let heightRight = 0;\n if (node.color == RB_TREE_COLOR_BLACK) {\n height++;\n }\n if (node.left != this.nil_node) {\n heightLeft = this.testBlackHeightProperty(node.left);\n }\n else {\n heightLeft = 1;\n }\n if (node.right != this.nil_node) {\n heightRight = this.testBlackHeightProperty(node.right);\n }\n else {\n heightRight = 1;\n }\n if (heightLeft != heightRight) {\n throw new Error('Red-black height property violated');\n }\n height += heightLeft;\n return height;\n };\n}\n\n/**\n * Created by Alex Bol on 3/12/2017.\n */\n\n\n/**\n * Class representing a planar set - a generic container with ability to keep and retrieve shapes and\n * perform spatial queries. Planar set is an extension of Set container, so it supports\n * Set properties and methods\n */\nclass PlanarSet extends Set {\n /**\n * Create new instance of PlanarSet\n * @param shapes - array or set of geometric objects to store in planar set\n * Each object should have a box property\n */\n constructor(shapes) {\n super(shapes);\n this.index = new IntervalTree();\n this.forEach(shape => this.index.insert(shape));\n }\n\n /**\n * Add new shape to planar set and to its spatial index.
\n * If shape already exist, it will not be added again.\n * This happens with no error, it is possible to use size property to check if\n * a shape was actually added.
\n * Method returns planar set object updated and may be chained\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property\n * Another option to transfer as an object {key: Box, value: AnyShape}\n * @returns {PlanarSet}\n */\n add(entry) {\n let size = this.size;\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n super.add(shape);\n // size not changed - item not added, probably trying to add same item twice\n if (this.size > size) {\n this.index.insert(box, shape);\n }\n return this; // in accordance to Set.add interface\n }\n\n /**\n * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise\n * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted\n * @returns {boolean}\n */\n delete(entry) {\n const {key, value} = entry;\n const box = key || entry.box;\n const shape = value || entry;\n let deleted = super.delete(shape);\n if (deleted) {\n this.index.remove(box, shape);\n }\n return deleted;\n }\n\n /**\n * Clear planar set\n */\n clear() {\n super.clear();\n this.index = new IntervalTree();\n }\n\n /**\n * 2d range search in planar set.
\n * Returns array of all shapes in planar set which bounding box is intersected with query box\n * @param {Box} box - query box\n * @returns {AnyShape[]}\n */\n search(box) {\n let resp = this.index.search(box);\n return resp;\n }\n\n /**\n * Point location test. Returns array of shapes which contains given point\n * @param {Point} point - query point\n * @returns {AnyShape[]}\n */\n hit(point) {\n let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);\n let resp = this.index.search(box);\n return resp.filter((shape) => point.on(shape));\n }\n\n /**\n * Returns svg string to draw all shapes in planar set\n * @returns {String}\n */\n svg() {\n let svgcontent = [...this].reduce((acc, shape) => acc + shape.svg(), \"\");\n return svgcontent;\n }\n}\n\nFlatten.PlanarSet = PlanarSet;\n\n/**\n * Base class representing shape\n * Implement common methods of affine transformations\n */\nclass Shape {\n get name() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n get box() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n clone() {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * Returns new shape translated by given vector.\n * Translation vector may be also defined by a pair of numbers.\n * @param {Vector | (number, number) } args - Translation vector\n * or tuple of numbers\n * @returns {Shape}\n */\n translate(...args) {\n return this.transform(new Matrix().translate(...args))\n }\n\n /**\n * Returns new shape rotated by given angle around given center point.\n * If center point is omitted, rotates around zero point (0,0).\n * Positive value of angle defines rotation in counterclockwise direction,\n * negative angle defines rotation in clockwise direction\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n * @returns {Shape}\n */\n rotate(angle, center = new Flatten.Point()) {\n return this.transform(new Matrix().rotate(angle, center.x, center.y));\n }\n\n /**\n * Return new shape with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Shape}\n */\n scale(sx, sy) {\n return this.transform(new Matrix().scale(sx, sy));\n }\n\n transform(...args) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return Object.assign({}, this, {name: this.name});\n }\n\n svg(attrs = {}) {\n throw(Errors.CANNOT_INVOKE_ABSTRACT_METHOD);\n }\n}\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\n/**\n *\n * Class representing a point\n * @type {Point}\n */\nlet Point$1 = class Point extends Shape {\n /**\n * Point may be constructed by two numbers, or by array of two numbers\n * @param {number} x - x-coordinate (float number)\n * @param {number} y - y-coordinate (float number)\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate (float number)\n * @type {number}\n */\n this.y = 0;\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"point\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n if (typeof (args[0]) == \"number\" && typeof (args[1]) == \"number\") {\n this.x = args[0];\n this.y = args[1];\n return;\n }\n }\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Returns bounding box of a point\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(this.x, this.y, this.x, this.y);\n }\n\n /**\n * Return new cloned instance of point\n * @returns {Point}\n */\n clone() {\n return new Flatten.Point(this.x, this.y);\n }\n\n get vertices() {\n return [this.clone()];\n }\n\n /**\n * Returns true if points are equal up to [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n equalTo(pt) {\n return Flatten.Utils.EQ(this.x, pt.x) && Flatten.Utils.EQ(this.y, pt.y);\n }\n\n /**\n * Defines predicate \"less than\" between points. Returns true if the point is less than query points, false otherwise
\n * By definition point1 < point2 if {point1.y < point2.y || point1.y == point2.y && point1.x < point2.x
\n * Numeric values compared with [Flatten.Utils.DP_TOL]{@link DP_TOL} tolerance\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n lessThan(pt) {\n if (Flatten.Utils.LT(this.y, pt.y))\n return true;\n if (Flatten.Utils.EQ(this.y, pt.y) && Flatten.Utils.LT(this.x, pt.x))\n return true;\n return false;\n }\n\n /**\n * Return new point transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Point}\n */\n transform(m) {\n return new Flatten.Point(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns projection point on given line\n * @param {Line} line Line this point be projected on\n * @returns {Point}\n */\n projectionOn(line) {\n if (this.equalTo(line.pt)) // this point equal to line anchor point\n return this.clone();\n\n let vec = new Flatten.Vector(this, line.pt);\n if (Flatten.Utils.EQ_0(vec.cross(line.norm))) // vector to point from anchor point collinear to normal vector\n return line.pt.clone();\n\n let dist = vec.dot(line.norm); // signed distance\n let proj_vec = line.norm.multiply(dist);\n return this.translate(proj_vec);\n }\n\n /**\n * Returns true if point belongs to the \"left\" semi-plane, which means, point belongs to the same semi plane where line normal vector points to\n * Return false if point belongs to the \"right\" semi-plane or to the line itself\n * @param {Line} line Query line\n * @returns {boolean}\n */\n leftTo(line) {\n let vec = new Flatten.Vector(line.pt, this);\n let onLeftSemiPlane = Flatten.Utils.GT(vec.dot(line.norm), 0);\n return onLeftSemiPlane;\n }\n\n /**\n * Calculate distance and shortest segment from point to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from point to shape\n * @returns {Segment} shortest segment between point and shape (started at point, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Point) {\n let dx = shape.x - this.x;\n let dy = shape.y - this.y;\n return [Math.sqrt(dx * dx + dy * dy), new Flatten.Segment(this, shape)];\n }\n\n if (shape instanceof Flatten.Line) {\n return Flatten.Distance.point2line(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return Flatten.Distance.point2circle(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Distance.point2segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return Flatten.Distance.point2arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return Flatten.Distance.point2polygon(this, shape);\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n return Flatten.Distance.shape2planarSet(this, shape);\n }\n }\n\n /**\n * Returns true if point is on a shape, false otherwise\n * @param {Shape} shape\n * @returns {boolean}\n */\n on(shape) {\n if (shape instanceof Flatten.Point) {\n return this.equalTo(shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Line) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return shape.contains(this)\n }\n\n if (shape instanceof Flatten.Circle) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.contains(this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return shape.contains(this);\n }\n }\n\n get name() {\n return \"point\"\n }\n\n /**\n * Return string to draw point in svg as circle with radius \"r\"
\n * Accept any valid attributes of svg elements as svg object\n * Defaults attribues are:
\n * {\n * r:\"3\",\n * stroke:\"black\",\n * strokeWidth:\"1\",\n * fill:\"red\"\n * }\n * @param {Object} attrs - Any valid attributes of svg circle element, like \"r\", \"stroke\", \"strokeWidth\", \"fill\"\n * @returns {String}\n */\n svg(attrs = {}) {\n const r = attrs.r ?? 3; // default radius - 3\n return `\\n`;\n }\n};\n\nFlatten.Point = Point$1;\n/**\n * Function to create point equivalent to \"new\" constructor\n * @param args\n */\nconst point = (...args) => new Flatten.Point(...args);\nFlatten.point = point;\n\n// export {Point};\n\n/**\n * Created by Alex Bol on 2/19/2017.\n */\n\n\n/**\n * Class representing a vector\n * @type {Vector}\n */\nlet Vector$1 = class Vector extends Shape {\n /**\n * Vector may be constructed by two points, or by two float numbers,\n * or by array of two numbers\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * x-coordinate of a vector (float number)\n * @type {number}\n */\n this.x = 0;\n /**\n * y-coordinate of a vector (float number)\n * @type {number}\n */\n this.y = 0;\n\n /* return zero vector */\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 2) {\n let arr = args[0];\n if (typeof (arr[0]) == \"number\" && typeof (arr[1]) == \"number\") {\n this.x = arr[0];\n this.y = arr[1];\n return;\n }\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"vector\") {\n let {x, y} = args[0];\n this.x = x;\n this.y = y;\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (typeof (a1) == \"number\" && typeof (a2) == \"number\") {\n this.x = a1;\n this.y = a2;\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.x = a2.x - a1.x;\n this.y = a2.y - a1.y;\n return;\n }\n\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Method clone returns new instance of Vector\n * @returns {Vector}\n */\n clone() {\n return new Flatten.Vector(this.x, this.y);\n }\n\n /**\n * Slope of the vector in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let angle = Math.atan2(this.y, this.x);\n if (angle < 0) angle = 2 * Math.PI + angle;\n return angle;\n }\n\n /**\n * Length of vector\n * @returns {number}\n */\n get length() {\n return Math.sqrt(this.dot(this));\n }\n\n /**\n * Returns true if vectors are equal up to [DP_TOL]{@link http://localhost:63342/flatten-js/docs/global.html#DP_TOL}\n * tolerance\n * @param {Vector} v\n * @returns {boolean}\n */\n equalTo(v) {\n return Flatten.Utils.EQ(this.x, v.x) && Flatten.Utils.EQ(this.y, v.y);\n }\n\n /**\n * Returns new vector multiplied by scalar\n * @param {number} scalar\n * @returns {Vector}\n */\n multiply(scalar) {\n return (new Flatten.Vector(scalar * this.x, scalar * this.y));\n }\n\n /**\n * Returns scalar product (dot product) of two vectors
\n * dot_product = (this * v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n dot(v) {\n return (this.x * v.x + this.y * v.y);\n }\n\n /**\n * Returns vector product (cross product) of two vectors
\n * cross_product = (this x v)\n * @param {Vector} v Other vector\n * @returns {number}\n */\n cross(v) {\n return (this.x * v.y - this.y * v.x);\n }\n\n /**\n * Returns unit vector.
\n * Throw error if given vector has zero length\n * @returns {Vector}\n */\n normalize() {\n if (!Flatten.Utils.EQ_0(this.length)) {\n return (new Flatten.Vector(this.x / this.length, this.y / this.length));\n }\n throw Errors.ZERO_DIVISION;\n }\n\n /**\n * Returns new vector rotated by given angle,\n * positive angle defines rotation in counterclockwise direction,\n * negative - in clockwise direction\n * Vector only can be rotated around (0,0) point!\n * @param {number} angle - Angle in radians\n * @returns {Vector}\n */\n rotate(angle, center = new Flatten.Point()) {\n if (center.x === 0 && center.y === 0) {\n return this.transform(new Matrix().rotate(angle));\n }\n throw(Errors.OPERATION_IS_NOT_SUPPORTED);\n }\n\n /**\n * Return new vector transformed by affine transformation matrix m\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Vector}\n */\n transform(m) {\n return new Flatten.Vector(m.transform([this.x, this.y]))\n }\n\n /**\n * Returns vector rotated 90 degrees counterclockwise\n * @returns {Vector}\n */\n rotate90CCW() {\n return new Flatten.Vector(-this.y, this.x);\n };\n\n /**\n * Returns vector rotated 90 degrees clockwise\n * @returns {Vector}\n */\n rotate90CW() {\n return new Flatten.Vector(this.y, -this.x);\n };\n\n /**\n * Return inverted vector\n * @returns {Vector}\n */\n invert() {\n return new Flatten.Vector(-this.x, -this.y);\n }\n\n /**\n * Return result of addition of other vector to this vector as a new vector\n * @param {Vector} v Other vector\n * @returns {Vector}\n */\n add(v) {\n return new Flatten.Vector(this.x + v.x, this.y + v.y);\n }\n\n /**\n * Return result of subtraction of other vector from current vector as a new vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n subtract(v) {\n return new Flatten.Vector(this.x - v.x, this.y - v.y);\n }\n\n /**\n * Return angle between this vector and other vector.
\n * Angle is measured from 0 to 2*PI in the counterclockwise direction\n * from current vector to another.\n * @param {Vector} v Another vector\n * @returns {number}\n */\n angleTo(v) {\n let norm1 = this.normalize();\n let norm2 = v.normalize();\n let angle = Math.atan2(norm1.cross(norm2), norm1.dot(norm2));\n if (angle < 0) angle += 2 * Math.PI;\n return angle;\n }\n\n /**\n * Return vector projection of the current vector on another vector\n * @param {Vector} v Another vector\n * @returns {Vector}\n */\n projectionOn(v) {\n let n = v.normalize();\n let d = this.dot(n);\n return n.multiply(d);\n }\n\n get name() {\n return \"vector\"\n }\n};\n\nFlatten.Vector = Vector$1;\n\n/**\n * Function to create vector equivalent to \"new\" constructor\n * @param args\n */\nconst vector$1 = (...args) => new Flatten.Vector(...args);\nFlatten.vector = vector$1;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a segment\n * @type {Segment}\n */\nclass Segment extends Shape {\n /**\n *\n * @param {Point} ps - start point\n * @param {Point} pe - end point\n */\n constructor(...args) {\n super();\n /**\n * Start point\n * @type {Point}\n */\n this.ps = new Flatten.Point();\n /**\n * End Point\n * @type {Point}\n */\n this.pe = new Flatten.Point();\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length === 4) {\n let coords = args[0];\n this.ps = new Flatten.Point(coords[0], coords[1]);\n this.pe = new Flatten.Point(coords[2], coords[3]);\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"segment\") {\n let {ps, pe} = args[0];\n this.ps = new Flatten.Point(ps.x, ps.y);\n this.pe = new Flatten.Point(pe.x, pe.y);\n return;\n }\n\n // second point omitted issue #84\n if (args.length === 1 && args[0] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n return;\n }\n\n if (args.length === 2 && args[0] instanceof Flatten.Point && args[1] instanceof Flatten.Point) {\n this.ps = args[0].clone();\n this.pe = args[1].clone();\n return;\n }\n\n if (args.length === 4) {\n this.ps = new Flatten.Point(args[0], args[1]);\n this.pe = new Flatten.Point(args[2], args[3]);\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of segment\n * @returns {Segment}\n */\n clone() {\n return new Flatten.Segment(this.start, this.end);\n }\n\n /**\n * Start point\n * @returns {Point}\n */\n get start() {\n return this.ps;\n }\n\n /**\n * End point\n * @returns {Point}\n */\n get end() {\n return this.pe;\n }\n\n\n /**\n * Returns array of start and end point\n * @returns [Point,Point]\n */\n get vertices() {\n return [this.ps.clone(), this.pe.clone()];\n }\n\n /**\n * Length of a segment\n * @returns {number}\n */\n get length() {\n return this.start.distanceTo(this.end)[0];\n }\n\n /**\n * Slope of the line - angle to axe x in radians from 0 to 2PI\n * @returns {number}\n */\n get slope() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.slope;\n }\n\n /**\n * Bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Math.min(this.start.x, this.end.x),\n Math.min(this.start.y, this.end.y),\n Math.max(this.start.x, this.end.x),\n Math.max(this.start.y, this.end.y)\n )\n }\n\n /**\n * Returns true if equals to query segment, false otherwise\n * @param {Seg} seg - query segment\n * @returns {boolean}\n */\n equalTo(seg) {\n return this.ps.equalTo(seg.ps) && this.pe.equalTo(seg.pe);\n }\n\n /**\n * Returns true if segment contains point\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n return Flatten.Utils.EQ_0(this.distanceToPoint(pt));\n }\n\n /**\n * Returns array of intersection points between segment and other shape\n * @param {Shape} shape - Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectSegment2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Segment(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectSegment2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectSegment2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectSegment2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectSegment2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from segment to shape and return as array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from segment to shape\n * @returns {Segment} shortest segment between segment and shape (started at segment, ended at shape)\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2segment(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.segment2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.segment2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2segment(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Returns unit vector in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.start, this.end);\n return vec.normalize();\n }\n\n /**\n * Return unit vector in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.end, this.start);\n return vec.normalize();\n }\n\n /**\n * Returns new segment with swapped start and end points\n * @returns {Segment}\n */\n reverse() {\n return new Segment(this.end, this.start);\n }\n\n /**\n * When point belongs to segment, return array of two segments split by given point,\n * if point is inside segment. Returns clone of this segment if query point is incident\n * to start or end point of the segment. Returns empty array if point does not belong to segment\n * @param {Point} pt Query point\n * @returns {Segment[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n return [\n new Flatten.Segment(this.start, pt),\n new Flatten.Segment(pt, this.end)\n ]\n }\n\n /**\n * Return middle point of the segment\n * @returns {Point}\n */\n middle() {\n return new Flatten.Point((this.start.x + this.end.x) / 2, (this.start.y + this.end.y) / 2);\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the segment\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length == 0) return this.start;\n if (length == this.length) return this.end;\n let factor = length / this.length;\n return new Flatten.Point(\n (this.end.x - this.start.x) * factor + this.start.x,\n (this.end.y - this.start.y) * factor + this.start.y\n );\n }\n\n distanceToPoint(pt) {\n let [dist, ...rest] = Flatten.Distance.point2segment(pt, this);\n return dist;\n };\n\n definiteIntegral(ymin = 0.0) {\n let dx = this.end.x - this.start.x;\n let dy1 = this.start.y - ymin;\n let dy2 = this.end.y - ymin;\n return (dx * (dy1 + dy2) / 2);\n }\n\n /**\n * Return new segment transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Segment} - transformed segment\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Segment(this.ps.transform(matrix), this.pe.transform(matrix))\n }\n\n /**\n * Returns true if segment start is equal to segment end up to DP_TOL\n * @returns {boolean}\n */\n isZeroLength() {\n return this.ps.equalTo(this.pe)\n }\n\n /**\n * Sort given array of points from segment start to end, assuming all points lay on the segment\n * @param {Point[]} - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let line = new Flatten.Line(this.start, this.end);\n return line.sortPoints(pts);\n }\n\n get name() {\n return \"segment\"\n }\n\n /**\n * Return string to draw segment in svg\n * @param {Object} attrs - an object with attributes for svg path element,\n * like \"stroke\", \"strokeWidth\"
\n * Defaults are stroke:\"black\", strokeWidth:\"1\"\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n}\n\nFlatten.Segment = Segment;\n/**\n * Shortcut method to create new segment\n */\nconst segment = (...args) => new Flatten.Segment(...args);\nFlatten.segment = segment;\n\n/**\n * Created by Alex Bol on 2/20/2017.\n */\n\nlet {vector} = Flatten;\n\n/**\n * Class representing a line\n * @type {Line}\n */\nlet Line$1 = class Line extends Shape {\n /**\n * Line may be constructed by point and normal vector or by two points that a line passes through\n * @param {Point} pt - point that a line passes through\n * @param {Vector|Point} norm - normal vector to a line or second point a line passes through\n */\n constructor(...args) {\n super();\n /**\n * Point a line passes through\n * @type {Point}\n */\n this.pt = new Flatten.Point();\n /**\n * Normal vector to a line
\n * Vector is normalized (length == 1)
\n * Direction of the vector is chosen to satisfy inequality norm * p >= 0\n * @type {Vector}\n */\n this.norm = new Flatten.Vector(0, 1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"line\") {\n let {pt, norm} = args[0];\n this.pt = new Flatten.Point(pt);\n this.norm = new Flatten.Vector(norm);\n return;\n }\n\n if (args.length === 2) {\n let a1 = args[0];\n let a2 = args[1];\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Point) {\n this.pt = a1;\n this.norm = Line.points2norm(a1, a2);\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Point && a2 instanceof Flatten.Vector) {\n if (Flatten.Utils.EQ_0(a2.x) && Flatten.Utils.EQ_0(a2.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a1.clone();\n this.norm = a2.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n\n if (a1 instanceof Flatten.Vector && a2 instanceof Flatten.Point) {\n if (Flatten.Utils.EQ_0(a1.x) && Flatten.Utils.EQ_0(a1.y)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n this.pt = a2.clone();\n this.norm = a1.clone();\n this.norm = this.norm.normalize();\n if (this.norm.dot(vector(this.pt.x,this.pt.y)) >= 0) {\n this.norm.invert();\n }\n return;\n }\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of line\n * @returns {Line}\n */\n clone() {\n return new Flatten.Line(this.pt, this.norm);\n }\n\n /* The following methods need for implementation of Edge interface\n /**\n * Line has no start point\n * @returns {undefined}\n */\n get start() {return undefined;}\n\n /**\n * Line has no end point\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns infinite box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Middle point is undefined\n * @returns {undefined}\n */\n get middle() {return undefined}\n\n /**\n * Slope of the line - angle in radians between line and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Get coefficients [A,B,C] of a standard line equation in the form Ax + By = C\n * @code [A, B, C] = line.standard\n * @returns {number[]} - array of coefficients\n */\n get standard() {\n let A = this.norm.x;\n let B = this.norm.y;\n let C = this.norm.dot(vector(this.pt.x, this.pt.y));\n\n return [A, B, C];\n }\n\n /**\n * Return true if parallel or incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n parallelTo(other_line) {\n return Flatten.Utils.EQ_0(this.norm.cross(other_line.norm));\n }\n\n /**\n * Returns true if incident to other line\n * @param {Line} other_line - line to check\n * @returns {boolean}\n */\n incidentTo(other_line) {\n return this.parallelTo(other_line) && this.pt.on(other_line);\n }\n\n /**\n * Returns true if point belongs to line\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Line contains point if vector to point is orthogonal to the line normal vector */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec));\n }\n\n /**\n * Return coordinate of the point that lies on the line in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the line and does not check it\n * @param {Point} pt - point on a line\n * @returns {number}\n */\n coord(pt) {\n return vector(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Returns array of intersection points\n * @param {Shape} shape - shape to intersect with\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectLine2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectLine2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Line(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectLine2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectLine2Polygon(this, shape);\n }\n\n }\n\n /**\n * Calculate distance and shortest segment from line to shape and returns array [distance, shortest_segment]\n * @param {Shape} shape Shape of the one of the types Point, Circle, Segment, Arc, Polygon\n * @returns {[number, Segment]}\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2line(shape, this);\n return [distance, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n }\n\n /**\n * Split line with a point or array of points and return array of shapes\n * Assumed (but not checked) that all points lay on the line\n * @param {Point | Point[]} pt\n * @returns {MultilineShapes}\n */\n split(pt) {\n if (pt instanceof Flatten.Point) {\n return [new Flatten.Ray(pt, this.norm), new Flatten.Ray(pt, this.norm)]\n }\n else {\n let multiline = new Flatten.Multiline([this]);\n let sorted_points = this.sortPoints(pt);\n multiline.split(sorted_points);\n return multiline.toShapes();\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Line(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new line transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Line}\n */\n transform(m) {\n return new Flatten.Line(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n /**\n * Sort given array of points that lay on a line with respect to coordinate on a line\n * The method assumes that points lay on the line and does not check this\n * @param {Point[]} pts - array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n return pts.slice().sort( (pt1, pt2) => {\n if (this.coord(pt1) < this.coord(pt2)) {\n return -1;\n }\n if (this.coord(pt1) > this.coord(pt2)) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"line\"\n }\n\n /**\n * Return string to draw svg segment representing line inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg circle element\n */\n svg(box, attrs = {}) {\n let ip = intersectLine2Box(this, box);\n if (ip.length === 0)\n return \"\";\n let ps = ip[0];\n let pe = ip.length === 2 ? ip[1] : ip.find(pt => !pt.equalTo(ps));\n if (pe === undefined) pe = ps;\n let segment = new Flatten.Segment(ps, pe);\n return segment.svg(attrs);\n }\n\n static points2norm(pt1, pt2) {\n if (pt1.equalTo(pt2)) {\n throw Errors.ILLEGAL_PARAMETERS;\n }\n let vec = new Flatten.Vector(pt1, pt2);\n let unit = vec.normalize();\n return unit.rotate90CCW();\n }\n};\n\nFlatten.Line = Line$1;\n/**\n * Function to create line equivalent to \"new\" constructor\n * @param args\n */\nconst line = (...args) => new Flatten.Line(...args);\nFlatten.line = line;\n\n/**\n * Created by Alex Bol on 3/6/2017.\n */\n\n\n/**\n * Class representing a circle\n * @type {Circle}\n */\nlet Circle$1 = class Circle extends Shape {\n /**\n * Class private property\n * @type {string}\n */\n\n /**\n *\n * @param {Point} pc - circle center point\n * @param {number} r - circle radius\n */\n constructor(...args) {\n super();\n /**\n * Circle center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Circle radius\n * @type {number}\n */\n this.r = 1;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"circle\") {\n let {pc, r} = args[0];\n this.pc = new Flatten.Point(pc);\n this.r = r;\n } else {\n let [pc, r] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n }\n // throw Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of circle\n * @returns {Circle}\n */\n clone() {\n return new Flatten.Circle(this.pc.clone(), this.r);\n }\n\n /**\n * Circle center\n * @returns {Point}\n */\n get center() {\n return this.pc;\n }\n\n /**\n * Circle bounding box\n * @returns {Box}\n */\n get box() {\n return new Flatten.Box(\n this.pc.x - this.r,\n this.pc.y - this.r,\n this.pc.x + this.r,\n this.pc.y + this.r\n );\n }\n\n /**\n * Return true if circle contains shape: no point of shape lies outside of the circle\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return Flatten.Utils.LE(shape.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Segment) {\n return Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Arc) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.start.distanceTo(this.center)[0], this.r) &&\n Flatten.Utils.LE(shape.end.distanceTo(this.center)[0], this.r);\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.intersect(shape).length === 0 &&\n Flatten.Utils.LE(shape.r, this.r) &&\n Flatten.Utils.LE(shape.center.distanceTo(this.center)[0], this.r);\n }\n\n /* TODO: box, polygon */\n }\n\n /**\n * Transform circle to closed arc\n * @param {boolean} counterclockwise\n * @returns {Arc}\n */\n toArc(counterclockwise = true) {\n return new Flatten.Arc(this.center, this.r, Math.PI, -Math.PI, counterclockwise);\n }\n\n /**\n * Method scale is supported only for uniform scaling of the circle with (0,0) center\n * @param {number} sx\n * @param {number} sy\n * @returns {Circle}\n */\n scale(sx, sy) {\n if (sx !== sy)\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n if (!(this.pc.x === 0.0 && this.pc.y === 0.0))\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n return new Flatten.Circle(this.pc, this.r*sx)\n }\n\n /**\n * Return new circle transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Circle}\n */\n transform(matrix = new Flatten.Matrix()) {\n return new Flatten.Circle(this.pc.transform(matrix), this.r)\n }\n\n /**\n * Returns array of intersection points between circle and other shape\n * @param {Shape} shape Shape of the one of supported types\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Circle(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Circle(shape, this);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Circle(shape, this);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectCircle2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Circle(shape, this);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectCircle2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from circle to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from circle to shape\n * @returns {Segment} shortest segment between circle and shape (started at circle, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [distance, shortest_segment] = Flatten.Distance.point2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [distance, shortest_segment] = Flatten.Distance.circle2circle(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [distance, shortest_segment] = Flatten.Distance.circle2line(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [distance, shortest_segment] = Flatten.Distance.segment2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [distance, shortest_segment] = Flatten.Distance.arc2circle(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [distance, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [distance, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n get name() {\n return \"circle\"\n }\n\n /**\n * Return string to draw circle in svg\n * @param {Object} attrs - an object with attributes of svg circle element\n * @returns {string}\n */\n svg(attrs = {}) {\n return `\\n`;\n }\n\n};\n\nFlatten.Circle = Circle$1;\n/**\n * Shortcut to create new circle\n * @param args\n */\nconst circle = (...args) => new Flatten.Circle(...args);\nFlatten.circle = circle;\n\n/**\n * Created by Alex Bol on 3/10/2017.\n */\n\n\n/**\n * Class representing a circular arc\n * @type {Arc}\n */\nclass Arc extends Shape {\n /**\n *\n * @param {Point} pc - arc center\n * @param {number} r - arc radius\n * @param {number} startAngle - start angle in radians from 0 to 2*PI\n * @param {number} endAngle - end angle in radians from 0 to 2*PI\n * @param {boolean} counterClockwise - arc direction, true - clockwise, false - counterclockwise\n */\n constructor(...args) {\n super();\n /**\n * Arc center\n * @type {Point}\n */\n this.pc = new Flatten.Point();\n /**\n * Arc radius\n * @type {number}\n */\n this.r = 1;\n /**\n * Arc start angle in radians\n * @type {number}\n */\n this.startAngle = 0;\n /**\n * Arc end angle in radians\n * @type {number}\n */\n this.endAngle = 2 * Math.PI;\n /**\n * Arc orientation\n * @type {boolean}\n */\n this.counterClockwise = Flatten.CCW;\n\n if (args.length === 0)\n return;\n\n if (args.length === 1 && args[0] instanceof Object && args[0].name === \"arc\") {\n let {pc, r, startAngle, endAngle, counterClockwise} = args[0];\n this.pc = new Flatten.Point(pc.x, pc.y);\n this.r = r;\n this.startAngle = startAngle;\n this.endAngle = endAngle;\n this.counterClockwise = counterClockwise;\n } else {\n let [pc, r, startAngle, endAngle, counterClockwise] = [...args];\n if (pc && pc instanceof Flatten.Point) this.pc = pc.clone();\n if (r !== undefined) this.r = r;\n if (startAngle !== undefined) this.startAngle = startAngle;\n if (endAngle !== undefined) this.endAngle = endAngle;\n if (counterClockwise !== undefined) this.counterClockwise = counterClockwise;\n }\n\n // throw Flatten.Errors.ILLEGAL_PARAMETERS; unreachable code\n }\n\n /**\n * Return new cloned instance of arc\n * @returns {Arc}\n */\n clone() {\n return new Flatten.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n\n /**\n * Get sweep angle in radians. Sweep angle is non-negative number from 0 to 2*PI\n * @returns {number}\n */\n get sweep() {\n if (Flatten.Utils.EQ(this.startAngle, this.endAngle))\n return 0.0;\n if (Flatten.Utils.EQ(Math.abs(this.startAngle - this.endAngle), Flatten.PIx2)) {\n return Flatten.PIx2;\n }\n let sweep;\n if (this.counterClockwise) {\n sweep = Flatten.Utils.GT(this.endAngle, this.startAngle) ?\n this.endAngle - this.startAngle : this.endAngle - this.startAngle + Flatten.PIx2;\n } else {\n sweep = Flatten.Utils.GT(this.startAngle, this.endAngle) ?\n this.startAngle - this.endAngle : this.startAngle - this.endAngle + Flatten.PIx2;\n }\n\n if (Flatten.Utils.GT(sweep, Flatten.PIx2)) {\n sweep -= Flatten.PIx2;\n }\n if (Flatten.Utils.LT(sweep, 0)) {\n sweep += Flatten.PIx2;\n }\n return sweep;\n }\n\n /**\n * Get start point of arc\n * @returns {Point}\n */\n get start() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.startAngle, this.pc);\n }\n\n /**\n * Get end point of arc\n * @returns {Point}\n */\n get end() {\n let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y);\n return p0.rotate(this.endAngle, this.pc);\n }\n\n /**\n * Get center of arc\n * @returns {Point}\n */\n get center() {\n return this.pc.clone();\n }\n\n get vertices() {\n return [this.start.clone(), this.end.clone()];\n }\n\n /**\n * Get arc length\n * @returns {number}\n */\n get length() {\n return Math.abs(this.sweep * this.r);\n }\n\n /**\n * Get bounding box of the arc\n * @returns {Box}\n */\n get box() {\n let func_arcs = this.breakToFunctional();\n let box = func_arcs.reduce((acc, arc) => acc.merge(arc.start.box), new Flatten.Box());\n box = box.merge(this.end.box);\n return box;\n }\n\n /**\n * Returns true if arc contains point, false otherwise\n * @param {Point} pt - point to test\n * @returns {boolean}\n */\n contains(pt) {\n // first check if point on circle (pc,r)\n if (!Flatten.Utils.EQ(this.pc.distanceTo(pt)[0], this.r))\n return false;\n\n // point on circle\n\n if (pt.equalTo(this.start))\n return true;\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n let test_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise);\n return Flatten.Utils.LE(test_arc.length, this.length);\n }\n\n /**\n * When given point belongs to arc, return array of two arcs split by this point. If points is incident\n * to start or end point of the arc, return clone of the arc. If point does not belong to the arcs, return\n * empty array.\n * @param {Point} pt Query point\n * @returns {Arc[]}\n */\n split(pt) {\n if (this.start.equalTo(pt))\n return [null, this.clone()];\n\n if (this.end.equalTo(pt))\n return [this.clone(), null];\n\n let angle = new Flatten.Vector(this.pc, pt).slope;\n\n return [\n new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise),\n new Flatten.Arc(this.pc, this.r, angle, this.endAngle, this.counterClockwise)\n ]\n }\n\n /**\n * Return middle point of the arc\n * @returns {Point}\n */\n middle() {\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep / 2 : this.startAngle - this.sweep / 2;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the arc\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (length === 0) return this.start;\n if (length === this.length) return this.end;\n let factor = length / this.length;\n let endAngle = this.counterClockwise ? this.startAngle + this.sweep * factor : this.startAngle - this.sweep * factor;\n let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise);\n return arc.end;\n }\n\n /**\n * Returns chord height (\"sagitta\") of the arc\n * @returns {number}\n */\n chordHeight() {\n return (1.0 - Math.cos(Math.abs(this.sweep / 2.0))) * this.r;\n }\n\n /**\n * Returns array of intersection points between arc and other shape\n * @param {Shape} shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n if (shape instanceof Flatten.Line) {\n return intersectLine2Arc(shape, this);\n }\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Arc(shape, this);\n }\n if (shape instanceof Flatten.Circle) {\n return intersectArc2Circle(this, shape);\n }\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Arc(shape, this);\n }\n if (shape instanceof Flatten.Box) {\n return intersectArc2Box(this, shape);\n }\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Arc(this, shape);\n }\n if (shape instanceof Flatten.Polygon) {\n return intersectArc2Polygon(this, shape);\n }\n }\n\n /**\n * Calculate distance and shortest segment from arc to shape and return array [distance, shortest segment]\n * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set\n * @returns {number} distance from arc to shape\n * @returns {Segment} shortest segment between arc and shape (started at arc, ended at shape)\n\n */\n distanceTo(shape) {\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle) {\n let [dist, shortest_segment] = Flatten.Distance.arc2circle(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Line) {\n let [dist, shortest_segment] = Flatten.Distance.arc2line(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Segment) {\n let [dist, shortest_segment] = Flatten.Distance.segment2arc(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.arc2arc(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Polygon) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(this, shape);\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.PlanarSet) {\n let [dist, shortest_segment] = Flatten.Distance.shape2planarSet(this, shape);\n return [dist, shortest_segment];\n }\n }\n\n /**\n * Breaks arc in extreme point 0, pi/2, pi, 3*pi/2 and returns array of sub-arcs\n * @returns {Arc[]}\n */\n breakToFunctional() {\n let func_arcs_array = [];\n let angles = [0, Math.PI / 2, 2 * Math.PI / 2, 3 * Math.PI / 2];\n let pts = [\n this.pc.translate(this.r, 0),\n this.pc.translate(0, this.r),\n this.pc.translate(-this.r, 0),\n this.pc.translate(0, -this.r)\n ];\n\n // If arc contains extreme point,\n // create test arc started at start point and ended at this extreme point\n let test_arcs = [];\n for (let i = 0; i < 4; i++) {\n if (pts[i].on(this)) {\n test_arcs.push(new Flatten.Arc(this.pc, this.r, this.startAngle, angles[i], this.counterClockwise));\n }\n }\n\n if (test_arcs.length === 0) { // arc does contain any extreme point\n func_arcs_array.push(this.clone());\n } else { // arc passes extreme point\n // sort these arcs by length\n test_arcs.sort((arc1, arc2) => arc1.length - arc2.length);\n\n for (let i = 0; i < test_arcs.length; i++) {\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, test_arcs[i].endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, test_arcs[i].endAngle, this.counterClockwise);\n }\n if (!Flatten.Utils.EQ_0(new_arc.length)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n\n // add last sub arc\n let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined;\n let new_arc;\n if (prev_arc) {\n new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, this.endAngle, this.counterClockwise);\n } else {\n new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, this.endAngle, this.counterClockwise);\n }\n // It could be 2*PI when occasionally start = 0 and end = 2*PI but this is not valid for breakToFunctional\n if (!Flatten.Utils.EQ_0(new_arc.length) && !Flatten.Utils.EQ(new_arc.sweep, 2*Math.PI)) {\n func_arcs_array.push(new_arc.clone());\n }\n }\n return func_arcs_array;\n }\n\n /**\n * Return tangent unit vector in the start point in the direction from start to end\n * @returns {Vector}\n */\n tangentInStart() {\n let vec = new Flatten.Vector(this.pc, this.start);\n let angle = this.counterClockwise ? Math.PI / 2. : -Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Return tangent unit vector in the end point in the direction from end to start\n * @returns {Vector}\n */\n tangentInEnd() {\n let vec = new Flatten.Vector(this.pc, this.end);\n let angle = this.counterClockwise ? -Math.PI / 2. : Math.PI / 2.;\n return vec.rotate(angle).normalize();\n }\n\n /**\n * Returns new arc with swapped start and end angles and reversed direction\n * @returns {Arc}\n */\n reverse() {\n return new Flatten.Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise);\n }\n\n /**\n * Return new arc transformed using affine transformation matrix
\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Arc}\n */\n transform(matrix = new Flatten.Matrix()) {\n let newStart = this.start.transform(matrix);\n let newEnd = this.end.transform(matrix);\n let newCenter = this.pc.transform(matrix);\n let newDirection = this.counterClockwise;\n if (matrix.a * matrix.d < 0) {\n newDirection = !newDirection;\n }\n return Flatten.Arc.arcSE(newCenter, newStart, newEnd, newDirection);\n }\n\n static arcSE(center, start, end, counterClockwise) {\n let {vector} = Flatten;\n let startAngle = vector(center, start).slope;\n let endAngle = vector(center, end).slope;\n if (Flatten.Utils.EQ(startAngle, endAngle)) {\n endAngle += 2 * Math.PI;\n counterClockwise = true;\n }\n let r = vector(center, start).length;\n\n return new Flatten.Arc(center, r, startAngle, endAngle, counterClockwise);\n }\n\n definiteIntegral(ymin = 0) {\n let f_arcs = this.breakToFunctional();\n let area = f_arcs.reduce((acc, arc) => acc + arc.circularSegmentDefiniteIntegral(ymin), 0.0);\n return area;\n }\n\n circularSegmentDefiniteIntegral(ymin) {\n let line = new Flatten.Line(this.start, this.end);\n let onLeftSide = this.pc.leftTo(line);\n let segment = new Flatten.Segment(this.start, this.end);\n let areaTrapez = segment.definiteIntegral(ymin);\n let areaCircularSegment = this.circularSegmentArea();\n let area = onLeftSide ? areaTrapez - areaCircularSegment : areaTrapez + areaCircularSegment;\n return area;\n }\n\n circularSegmentArea() {\n return (0.5 * this.r * this.r * (this.sweep - Math.sin(this.sweep)))\n }\n\n /**\n * Sort given array of points from arc start to end, assuming all points lay on the arc\n * @param {Point[]} pts array of points\n * @returns {Point[]} new array sorted\n */\n sortPoints(pts) {\n let {vector} = Flatten;\n return pts.slice().sort( (pt1, pt2) => {\n let slope1 = vector(this.pc, pt1).slope;\n let slope2 = vector(this.pc, pt2).slope;\n if (slope1 < slope2) {\n return -1;\n }\n if (slope1 > slope2) {\n return 1;\n }\n return 0;\n })\n }\n\n get name() {\n return \"arc\"\n }\n\n /**\n * Return string to draw arc in svg\n * @param {Object} attrs - an object with attributes of svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let largeArcFlag = this.sweep <= Math.PI ? \"0\" : \"1\";\n let sweepFlag = this.counterClockwise ? \"1\" : \"0\";\n\n if (Flatten.Utils.EQ(this.sweep, 2 * Math.PI)) {\n let circle = new Flatten.Circle(this.pc, this.r);\n return circle.svg(attrs);\n } else {\n return `\\n`\n }\n }\n\n}\n\nFlatten.Arc = Arc;\n/**\n * Function to create arc equivalent to \"new\" constructor\n * @param args\n */\nconst arc = (...args) => new Flatten.Arc(...args);\nFlatten.arc = arc;\n\n/**\n * Created by Alex Bol on 3/7/2017.\n */\n\n/**\n * Class Box represents bounding box of the shape.\n * It may also represent axis-aligned rectangle\n * @type {Box}\n */\nclass Box extends Shape {\n /**\n *\n * @param {number} xmin - minimal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n constructor(xmin = undefined, ymin = undefined, xmax = undefined, ymax = undefined) {\n super();\n /**\n * Minimal x coordinate\n * @type {number}\n */\n this.xmin = xmin;\n /**\n * Minimal y coordinate\n * @type {number}\n */\n this.ymin = ymin;\n /**\n * Maximal x coordinate\n * @type {number}\n */\n this.xmax = xmax;\n /**\n * Maximal y coordinate\n * @type {number}\n */\n this.ymax = ymax;\n }\n\n /**\n * Return new cloned instance of box\n * @returns {Box}\n */\n clone() {\n return new Box(this.xmin, this.ymin, this.xmax, this.ymax);\n }\n\n /**\n * Property low need for interval tree interface\n * @returns {Point}\n */\n get low() {\n return new Flatten.Point(this.xmin, this.ymin);\n }\n\n /**\n * Property high need for interval tree interface\n * @returns {Point}\n */\n get high() {\n return new Flatten.Point(this.xmax, this.ymax);\n }\n\n /**\n * Property max returns the box itself !\n * @returns {Box}\n */\n get max() {\n return this.clone();\n }\n \n /**\n * Return center of the box\n * @returns {Point}\n */\n get center() {\n return new Flatten.Point((this.xmin + this.xmax) / 2, (this.ymin + this.ymax) / 2);\n }\n\n /**\n * Return the width of the box\n * @returns {number}\n */\n get width() {\n return Math.abs(this.xmax - this.xmin);\n }\n\n /**\n * Return the height of the box\n * @returns {number}\n */\n get height() {\n return Math.abs(this.ymax - this.ymin);\n }\n \n /**\n * Return property box like all other shapes\n * @returns {Box}\n */\n get box() {\n return this.clone();\n }\n\n /**\n * Returns true if not intersected with other box\n * @param {Box} other_box - other box to test\n * @returns {boolean}\n */\n not_intersect(other_box) {\n return (\n this.xmax < other_box.xmin ||\n this.xmin > other_box.xmax ||\n this.ymax < other_box.ymin ||\n this.ymin > other_box.ymax\n );\n }\n\n /**\n * Returns true if intersected with other box\n * @param {Box} other_box - Query box\n * @returns {boolean}\n */\n intersect(other_box) {\n return !this.not_intersect(other_box);\n }\n\n /**\n * Returns new box merged with other box\n * @param {Box} other_box - Other box to merge with\n * @returns {Box}\n */\n merge(other_box) {\n return new Box(\n this.xmin === undefined ? other_box.xmin : Math.min(this.xmin, other_box.xmin),\n this.ymin === undefined ? other_box.ymin : Math.min(this.ymin, other_box.ymin),\n this.xmax === undefined ? other_box.xmax : Math.max(this.xmax, other_box.xmax),\n this.ymax === undefined ? other_box.ymax : Math.max(this.ymax, other_box.ymax)\n );\n }\n\n /**\n * Defines predicate \"less than\" between two boxes. Need for interval index\n * @param {Box} other_box - other box\n * @returns {boolean} - true if this box less than other box, false otherwise\n */\n less_than(other_box) {\n if (this.low.lessThan(other_box.low))\n return true;\n if (this.low.equalTo(other_box.low) && this.high.lessThan(other_box.high))\n return true;\n return false;\n }\n\n /**\n * Returns true if this box is equal to other box, false otherwise\n * @param {Box} other_box - query box\n * @returns {boolean}\n */\n equal_to(other_box) {\n return (this.low.equalTo(other_box.low) && this.high.equalTo(other_box.high));\n }\n\n output() {\n return this.clone();\n }\n\n static comparable_max(box1, box2) {\n // return pt1.lessThan(pt2) ? pt2.clone() : pt1.clone();\n return box1.merge(box2);\n }\n\n static comparable_less_than(pt1, pt2) {\n return pt1.lessThan(pt2);\n }\n\n /**\n * Set new values to the box object\n * @param {number} xmin - mininal x coordinate\n * @param {number} ymin - minimal y coordinate\n * @param {number} xmax - maximal x coordinate\n * @param {number} ymax - maximal y coordinate\n */\n set(xmin, ymin, xmax, ymax) {\n this.xmin = xmin;\n this.ymin = ymin;\n this.xmax = xmax;\n this.ymax = ymax;\n }\n\n /**\n * Transform box into array of points from low left corner in counterclockwise\n * @returns {Point[]}\n */\n toPoints() {\n return [\n new Flatten.Point(this.xmin, this.ymin),\n new Flatten.Point(this.xmax, this.ymin),\n new Flatten.Point(this.xmax, this.ymax),\n new Flatten.Point(this.xmin, this.ymax)\n ];\n }\n\n /**\n * Transform box into array of segments from low left corner in counterclockwise\n * @returns {Segment[]}\n */\n toSegments() {\n let pts = this.toPoints();\n return [\n new Flatten.Segment(pts[0], pts[1]),\n new Flatten.Segment(pts[1], pts[2]),\n new Flatten.Segment(pts[2], pts[3]),\n new Flatten.Segment(pts[3], pts[0])\n ];\n }\n\n /**\n * Box rotation is not supported\n * Attempt to rotate box throws error\n * @param {number} angle - angle in radians\n * @param {Point} [center=(0,0)] center\n */\n rotate(angle, center = new Flatten.Point()) {\n throw Errors.OPERATION_IS_NOT_SUPPORTED\n }\n\n /**\n * Return new box transformed using affine transformation matrix\n * New box is a bounding box of transformed corner points\n * @param {Matrix} m - affine transformation matrix\n * @returns {Box}\n */\n transform(m = new Flatten.Matrix()) {\n const transformed_points = this.toPoints().map(pt => pt.transform(m));\n return transformed_points.reduce(\n (new_box, pt) => new_box.merge(pt.box), new Box())\n }\n\n /**\n * Return true if box contains shape: no point of shape lies outside the box\n * @param {AnyShape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);\n }\n\n if (shape instanceof Flatten.Segment) {\n return shape.vertices.every(vertex => this.contains(vertex))\n }\n\n if (shape instanceof Flatten.Box) {\n return shape.toSegments().every(segment => this.contains(segment))\n }\n\n if (shape instanceof Flatten.Circle) {\n return this.contains(shape.box)\n }\n\n if (shape instanceof Flatten.Arc) {\n return shape.vertices.every(vertex => this.contains(vertex)) &&\n shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)\n }\n\n if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {\n return false\n }\n\n if (shape instanceof Flatten.Multiline) {\n return shape.toShapes().every(shape => this.contains(shape))\n }\n\n if (shape instanceof Flatten.Polygon) {\n return this.contains(shape.box)\n }\n }\n\n get name() {\n return \"box\"\n }\n\n /**\n * Return string to draw box in svg\n * @param {Object} attrs - an object with attributes of svg rectangle element\n * @returns {string}\n */\n svg(attrs = {}) {\n const width = this.xmax - this.xmin;\n const height = this.ymax - this.ymin;\n return `\\n`;\n };\n}\n\nFlatten.Box = Box;\n/**\n * Shortcut to create new box\n * @param args\n * @returns {Box}\n */\nconst box = (...args) => new Flatten.Box(...args);\nFlatten.box = box;\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing an edge of polygon. Edge shape may be Segment or Arc.\n * Each edge contains references to the next and previous edges in the face of the polygon.\n *\n * @type {Edge}\n */\nclass Edge {\n /**\n * Construct new instance of edge\n * @param {Shape} shape Shape of type Segment or Arc\n */\n constructor(shape) {\n /**\n * Shape of the edge: Segment or Arc\n * @type {Segment|Arc}\n */\n this.shape = shape;\n /**\n * Pointer to the next edge in the face\n * @type {Edge}\n */\n this.next = undefined;\n /**\n * Pointer to the previous edge in the face\n * @type {Edge}\n */\n this.prev = undefined;\n /**\n * Pointer to the face containing this edge\n * @type {Face}\n */\n this.face = undefined;\n /**\n * \"Arc distance\" from the face start\n * @type {number}\n */\n this.arc_length = 0;\n /**\n * Start inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvStart = undefined;\n /**\n * End inclusion flag (inside/outside/boundary)\n * @type {*}\n */\n this.bvEnd = undefined;\n /**\n * Edge inclusion flag (Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY)\n * @type {*}\n */\n this.bv = undefined;\n /**\n * Overlap flag for boundary edge (Flatten.OVERLAP_SAME/Flatten.OVERLAP_OPPOSITE)\n * @type {*}\n */\n this.overlap = undefined;\n }\n\n /**\n * Get edge start point\n */\n get start() {\n return this.shape.start;\n }\n\n /**\n * Get edge end point\n */\n get end() {\n return this.shape.end;\n }\n\n /**\n * Get edge length\n */\n get length() {\n return this.shape.length;\n }\n\n /**\n * Get bounding box of the edge\n * @returns {Box}\n */\n get box() {\n return this.shape.box;\n }\n\n get isSegment() {\n return this.shape instanceof Flatten.Segment;\n }\n\n get isArc() {\n return this.shape instanceof Flatten.Arc;\n }\n\n get isLine() {\n return this.shape instanceof Flatten.Line;\n }\n\n get isRay() {\n return this.shape instanceof Flatten.Ray\n }\n\n /**\n * Get middle point of the edge\n * @returns {Point}\n */\n middle() {\n return this.shape.middle();\n }\n\n /**\n * Get point at given length\n * @param {number} length - The length along the edge\n * @returns {Point}\n */\n pointAtLength(length) {\n return this.shape.pointAtLength(length);\n }\n\n /**\n * Returns true if point belongs to the edge, false otherwise\n * @param {Point} pt - test point\n */\n contains(pt) {\n return this.shape.contains(pt);\n }\n\n /**\n * Set inclusion flag of the edge with respect to another polygon\n * Inclusion flag is one of Flatten.INSIDE, Flatten.OUTSIDE, Flatten.BOUNDARY\n * @param polygon\n */\n setInclusion(polygon) {\n if (this.bv !== undefined) return this.bv;\n\n if (this.shape instanceof Flatten.Line || this.shape instanceof Flatten.Ray) {\n this.bv = Flatten.OUTSIDE;\n return this.bv;\n }\n\n if (this.bvStart === undefined) {\n this.bvStart = ray_shoot(polygon, this.start);\n }\n if (this.bvEnd === undefined) {\n this.bvEnd = ray_shoot(polygon, this.end);\n }\n /* At least one end outside - the whole edge outside */\n if (this.bvStart === Flatten.OUTSIDE || this.bvEnd == Flatten.OUTSIDE) {\n this.bv = Flatten.OUTSIDE;\n }\n /* At least one end inside - the whole edge inside */\n else if (this.bvStart === Flatten.INSIDE || this.bvEnd == Flatten.INSIDE) {\n this.bv = Flatten.INSIDE;\n }\n /* Both are boundary - check the middle point */\n else {\n let bvMiddle = ray_shoot(polygon, this.middle());\n // let boundary = this.middle().distanceTo(polygon)[0] < 10*Flatten.DP_TOL;\n // let bvMiddle = boundary ? Flatten.BOUNDARY : ray_shoot(polygon, this.middle());\n this.bv = bvMiddle;\n }\n return this.bv;\n }\n\n /**\n * Set overlapping between two coincident boundary edges\n * Overlapping flag is one of Flatten.OVERLAP_SAME or Flatten.OVERLAP_OPPOSITE\n * @param edge\n */\n setOverlap(edge) {\n let flag = undefined;\n let shape1 = this.shape;\n let shape2 = edge.shape;\n\n if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end)) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start)) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Arc) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && /*shape1.counterClockwise === shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && /*shape1.counterClockwise !== shape2.counterClockwise &&*/\n shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n } else if (shape1 instanceof Flatten.Segment && shape2 instanceof Flatten.Arc ||\n shape1 instanceof Flatten.Arc && shape2 instanceof Flatten.Segment) {\n if (shape1.start.equalTo(shape2.start) && shape1.end.equalTo(shape2.end) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_SAME;\n } else if (shape1.start.equalTo(shape2.end) && shape1.end.equalTo(shape2.start) && shape1.middle().equalTo(shape2.middle())) {\n flag = Flatten.OVERLAP_OPPOSITE;\n }\n }\n\n /* Do not update overlap flag if already set on previous chain */\n if (this.overlap === undefined) this.overlap = flag;\n if (edge.overlap === undefined) edge.overlap = flag;\n }\n\n svg() {\n if (this.shape instanceof Flatten.Segment) {\n return ` L${this.shape.end.x},${this.shape.end.y}`;\n } else if (this.shape instanceof Flatten.Arc) {\n let arc = this.shape;\n let largeArcFlag;\n let sweepFlag = arc.counterClockwise ? \"1\" : \"0\";\n\n // Draw full circe arc as special case: split it into two half-circles\n if (Flatten.Utils.EQ(arc.sweep, 2 * Math.PI)) {\n let sign = arc.counterClockwise ? 1 : -1;\n let halfArc1 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle, arc.startAngle + sign * Math.PI, arc.counterClockwise);\n let halfArc2 = new Flatten.Arc(arc.pc, arc.r, arc.startAngle + sign * Math.PI, arc.endAngle, arc.counterClockwise);\n\n largeArcFlag = \"0\";\n\n return ` A${halfArc1.r},${halfArc1.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc1.end.x},${halfArc1.end.y}\n A${halfArc2.r},${halfArc2.r} 0 ${largeArcFlag},${sweepFlag} ${halfArc2.end.x},${halfArc2.end.y}`\n } else {\n largeArcFlag = arc.sweep <= Math.PI ? \"0\" : \"1\";\n\n return ` A${arc.r},${arc.r} 0 ${largeArcFlag},${sweepFlag} ${arc.end.x},${arc.end.y}`;\n }\n }\n }\n\n toJSON() {\n return this.shape.toJSON();\n }\n}\nFlatten.Edge = Edge;\n\n/**\n * Class implements circular bidirectional linked list
\n * LinkedListElement - object of any type that has properties next and prev.\n */\nclass CircularLinkedList extends LinkedList {\n constructor(first, last) {\n super(first, last);\n this.setCircularLinks();\n }\n\n setCircularLinks() {\n if (this.isEmpty()) return;\n this.last.next = this.first;\n this.first.prev = this.last;\n }\n\n [Symbol.iterator]() {\n let element = undefined;\n return {\n next: () => {\n let value = element ? element : this.first;\n let done = this.first ? (element ? element === this.first : false) : true;\n element = value ? value.next : undefined;\n return {value: value, done: done};\n }\n };\n };\n\n /**\n * Append new element to the end of the list\n * @param {LinkedListElement} element - new element to be appended\n * @returns {CircularLinkedList}\n */\n append(element) {\n super.append(element);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Insert new element to the list after elementBefore\n * @param {LinkedListElement} newElement - new element to be inserted\n * @param {LinkedListElement} elementBefore - element in the list to insert after it\n * @returns {CircularLinkedList}\n */\n insert(newElement, elementBefore) {\n super.insert(newElement, elementBefore);\n this.setCircularLinks();\n return this;\n }\n\n /**\n * Remove element from the list\n * @param {LinkedListElement} element - element to be removed from the list\n * @returns {CircularLinkedList}\n */\n remove(element) {\n super.remove(element);\n // this.setCircularLinks();\n return this;\n }\n}\n\n/**\n * Created by Alex Bol on 3/17/2017.\n */\n\n\n/**\n * Class representing a face (closed loop) in a [polygon]{@link Flatten.Polygon} object.\n * Face is a circular bidirectional linked list of [edges]{@link Flatten.Edge}.\n * Face object cannot be instantiated with a constructor.\n * Instead, use [polygon.addFace()]{@link Flatten.Polygon#addFace} method.\n *
\n * Note, that face only set entry point to the linked list of edges but does not contain edges by itself.\n * Container of edges is a property of the polygon object.
\n *\n * @example\n * // Face implements \"next\" iterator which enables to iterate edges in for loop:\n * for (let edge of face) {\n * console.log(edge.shape.length) // do something\n * }\n *\n * // Instead, it is possible to iterate edges as linked list, starting from face.first:\n * let edge = face.first;\n * do {\n * console.log(edge.shape.length); // do something\n * edge = edge.next;\n * } while (edge != face.first)\n */\nclass Face extends CircularLinkedList {\n constructor(polygon, ...args) {\n super(); // construct empty list of edges\n /**\n * Reference to the first edge in face\n */\n // this.first;\n /**\n * Reference to the last edge in face\n */\n // this.last;\n\n this._box = undefined; // new Box();\n this._orientation = undefined;\n\n if (args.length === 0) {\n return;\n }\n\n /* If passed an array it supposed to be:\n 1) array of shapes that performs close loop or\n 2) array of points that performs set of vertices\n */\n if (args.length === 1) {\n if (args[0] instanceof Array) {\n // let argsArray = args[0];\n let shapes = args[0]; // argsArray[0];\n if (shapes.length === 0)\n return;\n\n /* array of Flatten.Points */\n if (shapes.every((shape) => {return shape instanceof Flatten.Point})) {\n let segments = Face.points2segments(shapes);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of points as pairs of numbers */\n else if (shapes.every((shape) => {return shape instanceof Array && shape.length === 2})) {\n let points = shapes.map((shape) => new Flatten.Point(shape[0],shape[1]));\n let segments = Face.points2segments(points);\n this.shapes2face(polygon.edges, segments);\n }\n /* array of segments ot arcs */\n else if (shapes.every((shape) => {\n return (shape instanceof Flatten.Segment || shape instanceof Flatten.Arc)\n })) {\n this.shapes2face(polygon.edges, shapes);\n }\n // this is from JSON.parse object\n else if (shapes.every((shape) => {\n return (shape.name === \"segment\" || shape.name === \"arc\")\n })) {\n let flattenShapes = [];\n for (let shape of shapes) {\n let flattenShape;\n if (shape.name === \"segment\") {\n flattenShape = new Flatten.Segment(shape);\n } else {\n flattenShape = new Flatten.Arc(shape);\n }\n flattenShapes.push(flattenShape);\n }\n this.shapes2face(polygon.edges, flattenShapes);\n }\n }\n /* Create new face and copy edges into polygon.edges set */\n else if (args[0] instanceof Face) {\n let face = args[0];\n this.first = face.first;\n this.last = face.last;\n for (let edge of face) {\n polygon.edges.add(edge);\n }\n }\n /* Instantiate face from a circle in CCW orientation */\n else if (args[0] instanceof Flatten.Circle) {\n this.shapes2face(polygon.edges, [args[0].toArc(CCW)]);\n }\n /* Instantiate face from a box in CCW orientation */\n else if (args[0] instanceof Flatten.Box) {\n let box = args[0];\n this.shapes2face(polygon.edges, [\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymin), new Flatten.Point(box.xmax, box.ymin)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymin), new Flatten.Point(box.xmax, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmax, box.ymax), new Flatten.Point(box.xmin, box.ymax)),\n new Flatten.Segment(new Flatten.Point(box.xmin, box.ymax), new Flatten.Point(box.xmin, box.ymin))\n ]);\n }\n }\n /* If passed two edges, consider them as start and end of the face loop */\n /* THIS METHOD WILL BE USED BY BOOLEAN OPERATIONS */\n /* Assume that edges already copied to polygon.edges set in the clip algorithm !!! */\n if (args.length === 2 && args[0] instanceof Flatten.Edge && args[1] instanceof Flatten.Edge) {\n this.first = args[0]; // first edge in face or undefined\n this.last = args[1]; // last edge in face or undefined\n this.last.next = this.first;\n this.first.prev = this.last;\n\n // set arc length\n this.setArcLength();\n\n // this.box = this.getBox();\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n }\n\n /**\n * Return array of edges from first to last\n * @returns {Array}\n */\n get edges() {\n return this.toArray();\n }\n\n /**\n * Return array of shapes which comprise face\n * @returns {Array}\n */\n get shapes() {\n return this.edges.map(edge => edge.shape.clone());\n }\n\n /**\n * Return bounding box of the face\n * @returns {Box}\n */\n get box() {\n if (this._box === undefined) {\n let box = new Flatten.Box();\n for (let edge of this) {\n box = box.merge(edge.box);\n }\n this._box = box;\n }\n return this._box;\n }\n\n /**\n * Get all edges length\n * @returns {number}\n */\n get perimeter() {\n return this.last.arc_length + this.last.length\n }\n\n /**\n * Get point on face boundary at given length\n * @param {number} length - The length along the face boundary\n * @returns {Point}\n */\n pointAtLength(length) {\n if (length > this.perimeter || length < 0) return null;\n let point = null;\n for (let edge of this) {\n if (length >= edge.arc_length &&\n (edge === this.last || length < edge.next.arc_length)) {\n point = edge.pointAtLength(length - edge.arc_length);\n break;\n }\n }\n return point;\n }\n\n static points2segments(points) {\n let segments = [];\n for (let i = 0; i < points.length; i++) {\n // skip zero length segment\n if (points[i].equalTo(points[(i + 1) % points.length]))\n continue;\n segments.push(new Flatten.Segment(points[i], points[(i + 1) % points.length]));\n }\n return segments;\n }\n\n shapes2face(edges, shapes) {\n for (let shape of shapes) {\n let edge = new Flatten.Edge(shape);\n this.append(edge);\n // this.box = this.box.merge(shape.box);\n edges.add(edge);\n }\n // this.orientation = this.getOrientation(); // face direction cw or ccw\n }\n\n /**\n * Append edge after the last edge of the face (and before the first edge).
\n * @param {Edge} edge - Edge to be appended to the linked list\n * @returns {Face}\n */\n append(edge) {\n super.append(edge);\n // set arc length\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n // edges.add(edge); // Add new edges into edges container\n return this;\n }\n\n /**\n * Insert edge newEdge into the linked list after the edge edgeBefore
\n * @param {Edge} newEdge - Edge to be inserted into linked list\n * @param {Edge} edgeBefore - Edge to insert newEdge after it\n * @returns {Face}\n */\n insert(newEdge, edgeBefore) {\n super.insert(newEdge, edgeBefore);\n // set arc length\n this.setOneEdgeArcLength(newEdge);\n newEdge.face = this;\n return this;\n }\n\n /**\n * Remove the given edge from the linked list of the face
\n * @param {Edge} edge - Edge to be removed\n * @returns {Face}\n */\n remove(edge) {\n super.remove(edge);\n // Recalculate arc length\n this.setArcLength();\n return this;\n }\n\n /**\n * Merge current edge with the next edge. Given edge will be extended,\n * next edge after it will be removed. The distortion of the polygon\n * is on the responsibility of the user of this method\n * @param {Edge} edge - edge to be extended\n * @returns {Face}\n */\n merge_with_next_edge(edge) {\n edge.shape.end.x = edge.next.shape.end.x;\n edge.shape.end.y = edge.next.shape.end.y;\n this.remove(edge.next);\n return this;\n }\n\n /**\n * Reverse orientation of the face: first edge become last and vice a verse,\n * all edges starts and ends swapped, direction of arcs inverted. If face was oriented\n * clockwise, it becomes counterclockwise and vice versa\n */\n reverse() {\n // collect edges in revert order with reverted shapes\n let edges = [];\n let edge_tmp = this.last;\n do {\n // reverse shape\n edge_tmp.shape = edge_tmp.shape.reverse();\n edges.push(edge_tmp);\n edge_tmp = edge_tmp.prev;\n } while (edge_tmp !== this.last);\n\n // restore linked list\n this.first = undefined;\n this.last = undefined;\n for (let edge of edges) {\n if (this.first === undefined) {\n edge.prev = edge;\n edge.next = edge;\n this.first = edge;\n this.last = edge;\n } else {\n // append to end\n edge.prev = this.last;\n this.last.next = edge;\n\n // update edge to be last\n this.last = edge;\n\n // restore circular links\n this.last.next = this.first;\n this.first.prev = this.last;\n\n }\n // set arc length\n this.setOneEdgeArcLength(edge);\n }\n\n // Recalculate orientation, if set\n if (this._orientation !== undefined) {\n this._orientation = undefined;\n this._orientation = this.orientation();\n }\n }\n\n\n /**\n * Set arc_length property for each of the edges in the face.\n * Arc_length of the edge it the arc length from the first edge of the face\n */\n setArcLength() {\n for (let edge of this) {\n this.setOneEdgeArcLength(edge);\n edge.face = this;\n }\n }\n\n setOneEdgeArcLength(edge) {\n if (edge === this.first) {\n edge.arc_length = 0.0;\n } else {\n edge.arc_length = edge.prev.arc_length + edge.prev.length;\n }\n }\n\n /**\n * Returns the absolute value of the area of the face\n * @returns {number}\n */\n area() {\n return Math.abs(this.signedArea());\n }\n\n /**\n * Returns signed area of the simple face.\n * Face is simple if it has no self intersections that change its orientation.\n * Then the area will be positive if the orientation of the face is clockwise,\n * and negative if orientation is counterclockwise.\n * It may be zero if polygon is degenerated.\n * @returns {number}\n */\n signedArea() {\n let sArea = 0;\n let ymin = this.box.ymin;\n for (let edge of this) {\n sArea += edge.shape.definiteIntegral(ymin);\n }\n return sArea;\n }\n\n /**\n * Return face orientation: one of Flatten.ORIENTATION.CCW, Flatten.ORIENTATION.CW, Flatten.ORIENTATION.NOT_ORIENTABLE
\n * According to Green theorem the area of a closed curve may be calculated as double integral,\n * and the sign of the integral will be defined by the direction of the curve.\n * When the integral (\"signed area\") will be negative, direction is counterclockwise,\n * when positive - clockwise and when it is zero, polygon is not orientable.\n * See {@link https://mathinsight.org/greens_theorem_find_area}\n * @returns {number}\n */\n orientation() {\n if (this._orientation === undefined) {\n let area = this.signedArea();\n if (Flatten.Utils.EQ_0(area)) {\n this._orientation = ORIENTATION.NOT_ORIENTABLE;\n } else if (Flatten.Utils.LT(area, 0)) {\n this._orientation = ORIENTATION.CCW;\n } else {\n this._orientation = ORIENTATION.CW;\n }\n }\n return this._orientation;\n }\n\n /**\n * Returns true if face of the polygon is simple (no self-intersection points found)\n * NOTE: this method is incomplete because it does not exclude touching points.\n * Self intersection test should check if polygon change orientation in the test point.\n * @param {PlanarSet} edges - reference to polygon edges to provide search index\n * @returns {boolean}\n */\n isSimple(edges) {\n let ip = Face.getSelfIntersections(this, edges, true);\n return ip.length === 0;\n }\n\n static getSelfIntersections(face, edges, exitOnFirst = false) {\n let int_points = [];\n\n // calculate intersections\n for (let edge1 of face) {\n\n // request edges of polygon in the box of edge1\n let resp = edges.search(edge1.box);\n\n // for each edge2 in response\n for (let edge2 of resp) {\n\n // Skip itself\n if (edge1 === edge2)\n continue;\n\n // Skip is edge2 belongs to another face\n if (edge2.face !== face)\n continue;\n\n // Skip next and previous edge if both are segment (if one of them arc - calc intersection)\n if (edge1.shape instanceof Flatten.Segment && edge2.shape instanceof Flatten.Segment &&\n (edge1.next === edge2 || edge1.prev === edge2))\n continue;\n\n // calculate intersections between edge1 and edge2\n let ip = edge1.shape.intersect(edge2.shape);\n\n // for each intersection point\n for (let pt of ip) {\n\n // skip start-end connections\n if (pt.equalTo(edge1.start) && pt.equalTo(edge2.end) && edge2 === edge1.prev)\n continue;\n if (pt.equalTo(edge1.end) && pt.equalTo(edge2.start) && edge2 === edge1.next)\n continue;\n\n int_points.push(pt);\n\n if (exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n }\n\n if (int_points.length > 0 && exitOnFirst)\n break;\n\n }\n return int_points;\n }\n\n /**\n * Returns edge which contains given point\n * @param {Point} pt - test point\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edgeFound;\n for (let edge of this) {\n if (pt.equalTo(edge.shape.start)) continue\n if (pt.equalTo(edge.shape.end) || edge.shape.contains(pt)) {\n edgeFound = edge;\n break;\n }\n }\n return edgeFound;\n }\n\n /**\n * Returns new polygon created from one face\n * @returns {Polygon}\n */\n toPolygon() {\n return new Flatten.Polygon(this.shapes);\n }\n\n toJSON() {\n return this.edges.map(edge => edge.toJSON());\n }\n\n /**\n * Returns string to be assigned to \"d\" attribute inside defined \"path\"\n * @returns {string}\n */\n svg() {\n let svgStr = `\\nM${this.first.start.x},${this.first.start.y}`;\n for (let edge of this) {\n svgStr += edge.svg();\n }\n svgStr += ` z`;\n return svgStr;\n }\n\n}\n\nFlatten.Face = Face;\n\n/**\n * Class representing a ray (a half-infinite line).\n * @type {Ray}\n */\nclass Ray extends Shape {\n /**\n * Ray may be constructed by setting an origin point and a normal vector, so that any point x\n * on a ray fit an equation:
\n * (x - origin) * vector = 0
\n * Ray defined by constructor is a right semi-infinite line with respect to the normal vector
\n * If normal vector is omitted ray is considered horizontal (normal vector is (0,1)).
\n * Don't be confused: direction of the normal vector is orthogonal to the ray
\n * @param {Point} pt - start point\n * @param {Vector} norm - normal vector\n */\n constructor(...args) {\n super();\n this.pt = new Flatten.Point();\n this.norm = new Flatten.Vector(0,1);\n\n if (args.length === 0) {\n return;\n }\n\n if (args.length >= 1 && args[0] instanceof Flatten.Point) {\n this.pt = args[0].clone();\n }\n\n if (args.length === 1) {\n return;\n }\n\n if (args.length === 2 && args[1] instanceof Flatten.Vector) {\n this.norm = args[1].clone();\n return;\n }\n\n throw Errors.ILLEGAL_PARAMETERS;\n }\n\n /**\n * Return new cloned instance of ray\n * @returns {Ray}\n */\n clone() {\n return new Ray(this.pt, this.norm);\n }\n\n /**\n * Slope of the ray - angle in radians between ray and axe x from 0 to 2PI\n * @returns {number} - slope of the line\n */\n get slope() {\n let vec = new Flatten.Vector(this.norm.y, -this.norm.x);\n return vec.slope;\n }\n\n /**\n * Returns half-infinite bounding box of the ray\n * @returns {Box} - bounding box\n */\n get box() {\n let slope = this.slope;\n return new Flatten.Box(\n slope > Math.PI/2 && slope < 3*Math.PI/2 ? Number.NEGATIVE_INFINITY : this.pt.x,\n slope >= 0 && slope <= Math.PI ? this.pt.y : Number.NEGATIVE_INFINITY,\n slope >= Math.PI/2 && slope <= 3*Math.PI/2 ? this.pt.x : Number.POSITIVE_INFINITY,\n slope >= Math.PI && slope <= 2*Math.PI || slope === 0 ? this.pt.y : Number.POSITIVE_INFINITY\n )\n }\n\n /**\n * Return ray start point\n * @returns {Point} - ray start point\n */\n get start() {\n return this.pt;\n }\n\n /**\n * Ray has no end point?\n * @returns {undefined}\n */\n get end() {return undefined;}\n\n /**\n * Return positive infinity number as length\n * @returns {number}\n */\n get length() {return Number.POSITIVE_INFINITY;}\n\n /**\n * Returns true if point belongs to ray\n * @param {Point} pt Query point\n * @returns {boolean}\n */\n contains(pt) {\n if (this.pt.equalTo(pt)) {\n return true;\n }\n /* Ray contains point if vector to point is orthogonal to the ray normal vector\n and cross product from vector to point is positive */\n let vec = new Flatten.Vector(this.pt, pt);\n return Flatten.Utils.EQ_0(this.norm.dot(vec)) && Flatten.Utils.GE(vec.cross(this.norm),0);\n }\n\n /**\n * Return coordinate of the point that lies on the ray in the transformed\n * coordinate system where center is the projection of the point(0,0) to\n * the line containing this ray and axe y is collinear to the normal vector.
\n * This method assumes that point lies on the ray\n * @param {Point} pt - point on a ray\n * @returns {number}\n */\n coord(pt) {\n return vector$1(pt.x, pt.y).cross(this.norm);\n }\n\n /**\n * Split ray with point and return array of segment and new ray\n * @param {Point} pt\n * @returns [Segment,Ray]\n */\n split(pt) {\n if (!this.contains(pt))\n return [];\n\n if (this.pt.equalTo(pt)) {\n return [this]\n }\n\n return [\n new Flatten.Segment(this.pt, pt),\n new Flatten.Ray(pt, this.norm)\n ]\n }\n\n /**\n * Returns array of intersection points between ray and another shape\n * @param {Shape} shape - Shape to intersect with ray\n * @returns {Point[]} array of intersection points\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectRay2Segment(this, shape);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectRay2Arc(this, shape);\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectRay2Line(this, shape);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Ray(this, shape)\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectRay2Circle(this, shape);\n }\n\n if (shape instanceof Flatten.Box) {\n return intersectRay2Box(this, shape);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectRay2Polygon(this, shape);\n }\n }\n\n /**\n * Return new line rotated by angle\n * @param {number} angle - angle in radians\n * @param {Point} center - center of rotation\n */\n rotate(angle, center = new Flatten.Point()) {\n return new Flatten.Ray(\n this.pt.rotate(angle, center),\n this.norm.rotate(angle)\n )\n }\n\n /**\n * Return new ray transformed by affine transformation matrix\n * @param {Matrix} m - affine transformation matrix (a,b,c,d,tx,ty)\n * @returns {Ray}\n */\n transform(m) {\n return new Flatten.Ray(\n this.pt.transform(m),\n this.norm.clone()\n )\n }\n\n get name() {\n return \"ray\"\n }\n\n /**\n * Return string to draw svg segment representing ray inside given box\n * @param {Box} box Box representing drawing area\n * @param {Object} attrs - an object with attributes of svg segment element\n */\n svg(box, attrs = {}) {\n let line = new Flatten.Line(this.pt, this.norm);\n let ip = intersectLine2Box(line, box);\n ip = ip.filter( pt => this.contains(pt) );\n if (ip.length === 0 || ip.length === 2)\n return \"\";\n let segment = new Flatten.Segment(this.pt, ip[0]);\n return segment.svg(attrs);\n }\n\n}\n\nFlatten.Ray = Ray;\n\nconst ray = (...args) => new Flatten.Ray(...args);\nFlatten.ray = ray;\n\n/**\n * Created by Alex Bol on 3/15/2017.\n */\n\n\n/**\n * Class representing a polygon.
\n * Polygon in FlattenJS is a multipolygon comprised from a set of [faces]{@link Flatten.Face}.
\n * Face, in turn, is a closed loop of [edges]{@link Flatten.Edge}, where edge may be segment or circular arc
\n * @type {Polygon}\n */\nclass Polygon {\n /**\n * Constructor creates new instance of polygon. With no arguments new polygon is empty.
\n * Constructor accepts as argument array that define loop of shapes\n * or array of arrays in case of multi polygon
\n * Loop may be defined in different ways:
\n * - array of shapes of type Segment or Arc
\n * - array of points (Flatten.Point)
\n * - array of numeric pairs which represent points
\n * - box or circle object
\n * Alternatively, it is possible to use polygon.addFace method\n * @param {args} - array of shapes or array of arrays\n */\n constructor() {\n /**\n * Container of faces (closed loops), may be empty\n * @type {PlanarSet}\n */\n this.faces = new Flatten.PlanarSet();\n /**\n * Container of edges\n * @type {PlanarSet}\n */\n this.edges = new Flatten.PlanarSet();\n\n /* It may be array of something that may represent one loop (face) or\n array of arrays that represent multiple loops\n */\n let args = [...arguments];\n if (args.length === 1 &&\n ((args[0] instanceof Array && args[0].length > 0) ||\n args[0] instanceof Flatten.Circle || args[0] instanceof Flatten.Box)) {\n let argsArray = args[0];\n if (args[0] instanceof Array && args[0].every((loop) => {\n return loop instanceof Array\n })) {\n if (argsArray.every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon as array of pairs of numbers\n } else {\n for (let loop of argsArray) { // multi-loop polygon\n /* Check extra level of nesting for GeoJSON-style multi polygons */\n if (loop instanceof Array && loop[0] instanceof Array &&\n loop[0].every(el => {\n return el instanceof Array && el.length === 2 && typeof (el[0]) === \"number\" && typeof (el[1]) === \"number\"\n })) {\n for (let loop1 of loop) {\n this.faces.add(new Flatten.Face(this, loop1));\n }\n } else {\n this.faces.add(new Flatten.Face(this, loop));\n }\n }\n }\n } else {\n this.faces.add(new Flatten.Face(this, argsArray)); // one-loop polygon\n }\n }\n }\n\n /**\n * (Getter) Returns bounding box of the polygon\n * @returns {Box}\n */\n get box() {\n return [...this.faces].reduce((acc, face) => acc.merge(face.box), new Flatten.Box());\n }\n\n /**\n * (Getter) Returns array of vertices\n * @returns {Array}\n */\n get vertices() {\n return [...this.edges].map(edge => edge.start);\n }\n\n /**\n * Create new cloned instance of the polygon\n * @returns {Polygon}\n */\n clone() {\n let polygon = new Polygon();\n for (let face of this.faces) {\n polygon.addFace(face.shapes);\n }\n return polygon;\n }\n\n /**\n * Return true is polygon has no edges\n * @returns {boolean}\n */\n isEmpty() {\n return this.edges.size === 0;\n }\n\n /**\n * Return true if polygon is valid for boolean operations\n * Polygon is valid if
\n * 1. All faces are simple polygons (there are no self-intersected polygons)
\n * 2. All faces are orientable and there is no island inside island or hole inside hole - TODO
\n * 3. There is no intersections between faces (excluding touching) - TODO
\n * @returns {boolean}\n */\n isValid() {\n let valid = true;\n // 1. Polygon is invalid if at least one face is not simple\n for (let face of this.faces) {\n if (!face.isSimple(this.edges)) {\n valid = false;\n break;\n }\n }\n // 2. TODO: check if no island inside island and no hole inside hole\n // 3. TODO: check the there is no intersection between faces\n return valid;\n }\n\n /**\n * Returns area of the polygon. Area of an island will be added, area of a hole will be subtracted\n * @returns {number}\n */\n area() {\n let signedArea = [...this.faces].reduce((acc, face) => acc + face.signedArea(), 0);\n return Math.abs(signedArea);\n }\n\n /**\n * Add new face to polygon. Returns added face\n * @param {Point[]|Segment[]|Arc[]|Circle|Box} args - new face may be create with one of the following ways:
\n * 1) array of points that describe closed path (edges are segments)
\n * 2) array of shapes (segments and arcs) which describe closed path
\n * 3) circle - will be added as counterclockwise arc
\n * 4) box - will be added as counterclockwise rectangle
\n * You can chain method face.reverse() is you need to change direction of the creates face\n * @returns {Face}\n */\n addFace(...args) {\n let face = new Flatten.Face(this, ...args);\n this.faces.add(face);\n return face;\n }\n\n /**\n * Delete existing face from polygon\n * @param {Face} face Face to be deleted\n * @returns {boolean}\n */\n deleteFace(face) {\n for (let edge of face) {\n this.edges.delete(edge);\n }\n return this.faces.delete(face);\n }\n\n /**\n * Clear all faces and create new faces from edges\n */\n recreateFaces() {\n // Remove all faces\n this.faces.clear();\n for (let edge of this.edges) {\n edge.face = null;\n }\n\n // Restore faces\n let first;\n let unassignedEdgeFound = true;\n while (unassignedEdgeFound) {\n unassignedEdgeFound = false;\n for (let edge of this.edges) {\n if (edge.face === null) {\n first = edge;\n unassignedEdgeFound = true;\n break;\n }\n }\n\n if (unassignedEdgeFound) {\n let last = first;\n do {\n last = last.next;\n } while (last.next !== first)\n\n this.addFace(first, last);\n }\n }\n }\n\n /**\n * Delete chain of edges from the face.\n * @param {Face} face Face to remove chain\n * @param {Edge} edgeFrom Start of the chain of edges to be removed\n * @param {Edge} edgeTo End of the chain of edges to be removed\n */\n removeChain(face, edgeFrom, edgeTo) {\n // Special case: all edges removed\n if (edgeTo.next === edgeFrom) {\n this.deleteFace(face);\n return;\n }\n for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) {\n face.remove(edge);\n this.edges.delete(edge); // delete from PlanarSet of edges and update index\n if (face.isEmpty()) {\n this.deleteFace(face); // delete from PlanarSet of faces and update index\n break;\n }\n }\n }\n\n /**\n * Add point as a new vertex and split edge. Point supposed to belong to an edge.\n * When edge is split, new edge created from the start of the edge to the new vertex\n * and inserted before current edge.\n * Current edge is trimmed and updated.\n * Method returns new edge added. If no edge added, it returns edge before vertex\n * @param {Point} pt Point to be added as a new vertex\n * @param {Edge} edge Edge to be split with new vertex and then trimmed from start\n * @returns {Edge}\n */\n addVertex(pt, edge) {\n let shapes = edge.shape.split(pt);\n // if (shapes.length < 2) return;\n\n if (shapes[0] === null) // point incident to edge start vertex, return previous edge\n return edge.prev;\n\n if (shapes[1] === null) // point incident to edge end vertex, return edge itself\n return edge;\n\n let newEdge = new Flatten.Edge(shapes[0]);\n let edgeBefore = edge.prev;\n\n /* Insert first split edge into linked list after edgeBefore */\n edge.face.insert(newEdge, edgeBefore);\n\n // Remove old edge from edges container and 2d index\n this.edges.delete(edge);\n\n // Insert new edge to the edges container and 2d index\n this.edges.add(newEdge);\n\n // Update edge shape with second split edge keeping links\n edge.shape = shapes[1];\n\n // Add updated edge to the edges container and 2d index\n this.edges.add(edge);\n\n return newEdge;\n }\n\n /**\n * Merge given edge with next edge and remove vertex between them\n * @param {Edge} edge\n */\n removeEndVertex(edge) {\n const edge_next = edge.next;\n if (edge_next === edge) return\n edge.face.merge_with_next_edge(edge);\n this.edges.delete(edge_next);\n }\n\n /**\n * Cut polygon with multiline and return a new polygon\n * @param {Multiline} multiline\n * @returns {Polygon}\n */\n cut(multiline) {\n let newPoly = this.clone();\n\n // smart intersections\n let intersections = {\n int_points1: [],\n int_points2: [],\n int_points1_sorted: [],\n int_points2_sorted: []\n };\n\n // intersect each edge of multiline with each edge of the polygon\n // and create smart intersections\n for (let edge1 of multiline.edges) {\n for (let edge2 of newPoly.edges) {\n let ip = intersectEdge2Edge(edge1, edge2);\n // for each intersection point\n for (let pt of ip) {\n addToIntPoints(edge1, pt, intersections.int_points1);\n addToIntPoints(edge2, pt, intersections.int_points2);\n }\n }\n }\n\n // No intersections - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort smart intersections\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // split by intersection points\n splitByIntersections(multiline, intersections.int_points1_sorted);\n splitByIntersections(newPoly, intersections.int_points2_sorted);\n\n // filter duplicated intersection points\n filterDuplicatedIntersections(intersections);\n\n // sort intersection points again after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // initialize inclusion flags for edges of multiline incident to intersections\n initializeInclusionFlags(intersections.int_points1);\n\n // calculate inclusion flag for edges of multiline incident to intersections\n calculateInclusionFlags(intersections.int_points1, newPoly);\n\n // filter intersections between two edges that got same inclusion flag\n for (let int_point1 of intersections.int_points1_sorted) {\n if (int_point1.edge_before && int_point1.edge_after &&\n int_point1.edge_before.bv === int_point1.edge_after.bv) {\n intersections.int_points2[int_point1.id] = -1; // to be filtered out\n int_point1.id = -1; // to be filtered out\n }\n }\n intersections.int_points1 = intersections.int_points1.filter( int_point => int_point.id >= 0);\n intersections.int_points2 = intersections.int_points2.filter( int_point => int_point.id >= 0);\n\n // No intersections left after filtering - return a copy of the original polygon\n if (intersections.int_points1.length === 0)\n return newPoly;\n\n // sort intersection points 3d time after filtering\n intersections.int_points1_sorted = getSortedArray(intersections.int_points1);\n intersections.int_points2_sorted = getSortedArray(intersections.int_points2);\n\n // Add new inner edges between intersection points\n let int_point1_prev;\n let int_point1_curr;\n for (let i = 1; i < intersections.int_points1_sorted.length; i++) {\n int_point1_curr = intersections.int_points1_sorted[i];\n int_point1_prev = intersections.int_points1_sorted[i-1];\n if (int_point1_curr.edge_before && int_point1_curr.edge_before.bv === INSIDE$2) {\n let edgeFrom = int_point1_prev.edge_after;\n let edgeTo = int_point1_curr.edge_before;\n let newEdges = multiline.getChain(edgeFrom, edgeTo);\n insertBetweenIntPoints(intersections.int_points2[int_point1_prev.id], intersections.int_points2[int_point1_curr.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n\n newEdges = newEdges.reverse().map(edge => new Flatten.Edge(edge.shape.reverse()));\n for (let k=0; k < newEdges.length-1; k++) {\n newEdges[k].next = newEdges[k+1];\n newEdges[k+1].prev = newEdges[k];\n }\n insertBetweenIntPoints(intersections.int_points2[int_point1_curr.id], intersections.int_points2[int_point1_prev.id], newEdges);\n newEdges.forEach(edge => newPoly.edges.add(edge));\n }\n\n }\n\n // Recreate faces\n newPoly.recreateFaces();\n\n return newPoly\n }\n\n /**\n * A special case of cut() function\n * The return is a polygon cut with line\n * @param {Line} line - cutting line\n * @returns {Polygon} newPoly - resulted polygon\n */\n cutWithLine(line) {\n let multiline = new Multiline([line]);\n return this.cut(multiline);\n }\n\n /**\n * Returns the first found edge of polygon that contains given point\n * If point is a vertex, return the edge where the point is an end vertex, not a start one\n * @param {Point} pt\n * @returns {Edge}\n */\n findEdgeByPoint(pt) {\n let edge;\n for (let face of this.faces) {\n edge = face.findEdgeByPoint(pt);\n if (edge !== undefined)\n break;\n }\n return edge;\n }\n\n /**\n * Split polygon into array of polygons, where each polygon is an outer face with all\n * containing inner faces\n * @returns {Flatten.Polygon[]}\n */\n splitToIslands() {\n if (this.isEmpty()) return []; // return empty array if polygon is empty\n let polygons = this.toArray(); // split into array of one-loop polygons\n /* Sort polygons by area in descending order */\n polygons.sort((polygon1, polygon2) => polygon2.area() - polygon1.area());\n /* define orientation of the island by orientation of the first polygon in array */\n let orientation = [...polygons[0].faces][0].orientation();\n /* Create output array from polygons with same orientation as a first polygon (array of islands) */\n let newPolygons = polygons.filter(polygon => [...polygon.faces][0].orientation() === orientation);\n for (let polygon of polygons) {\n let face = [...polygon.faces][0];\n if (face.orientation() === orientation) continue; // skip same orientation\n /* Proceed with opposite orientation */\n /* Look if any of island polygons contains tested polygon as a hole */\n for (let islandPolygon of newPolygons) {\n if (face.shapes.every(shape => islandPolygon.contains(shape))) {\n islandPolygon.addFace(face.shapes); // add polygon as a hole in islandPolygon\n break;\n }\n }\n }\n // TODO: assert if not all polygons added into output\n return newPolygons;\n }\n\n /**\n * Reverse orientation of all faces to opposite\n * @returns {Polygon}\n */\n reverse() {\n for (let face of this.faces) {\n face.reverse();\n }\n return this;\n }\n\n /**\n * Returns true if polygon contains shape: no point of shape lay outside of the polygon,\n * false otherwise\n * @param {Shape} shape - test shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n let rel = ray_shoot(this, shape);\n return rel === INSIDE$2 || rel === BOUNDARY$1;\n } else {\n return cover(this, shape);\n }\n }\n\n /**\n * Return distance and shortest segment between polygon and other shape as array [distance, shortest_segment]\n * @param {Shape} shape Shape of one of the types Point, Circle, Line, Segment, Arc or Polygon\n * @returns {Number | Segment}\n */\n distanceTo(shape) {\n // let {Distance} = Flatten;\n\n if (shape instanceof Flatten.Point) {\n let [dist, shortest_segment] = Flatten.Distance.point2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n if (shape instanceof Flatten.Circle ||\n shape instanceof Flatten.Line ||\n shape instanceof Flatten.Segment ||\n shape instanceof Flatten.Arc) {\n let [dist, shortest_segment] = Flatten.Distance.shape2polygon(shape, this);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /* this method is bit faster */\n if (shape instanceof Flatten.Polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n let dist, shortest_segment;\n\n for (let edge of this.edges) {\n // let [dist, shortest_segment] = Distance.shape2polygon(edge.shape, shape);\n let min_stop = min_dist_and_segment[0];\n [dist, shortest_segment] = Flatten.Distance.shape2planarSet(edge.shape, shape.edges, min_stop);\n if (Flatten.Utils.LT(dist, min_stop)) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n }\n\n /**\n * Return array of intersection points between polygon and other shape\n * @param shape Shape of the one of supported types
\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Point) {\n return this.contains(shape) ? [shape] : [];\n }\n\n if (shape instanceof Flatten.Line) {\n return intersectLine2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Ray) {\n return intersectRay2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Circle) {\n return intersectCircle2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Segment) {\n return intersectSegment2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Arc) {\n return intersectArc2Polygon(shape, this);\n }\n\n if (shape instanceof Flatten.Polygon) {\n return intersectPolygon2Polygon(shape, this);\n }\n }\n\n /**\n * Returns new polygon translated by vector vec\n * @param {Vector} vec\n * @returns {Polygon}\n */\n translate(vec) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.translate(vec)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon rotated by given angle around given point\n * If point omitted, rotate around origin (0,0)\n * Positive value of angle defines rotation counterclockwise, negative - clockwise\n * @param {number} angle - rotation angle in radians\n * @param {Point} center - rotation center, default is (0,0)\n * @returns {Polygon} - new rotated polygon\n */\n rotate(angle = 0, center = new Flatten.Point()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.rotate(angle, center)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon with coordinates multiplied by scaling factor\n * @param {number} sx - x-axis scaling factor\n * @param {number} sy - y-axis scaling factor\n * @returns {Polygon}\n */\n scale(sx, sy) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.scale(sx, sy)));\n }\n return newPolygon;\n }\n\n /**\n * Return new polygon transformed using affine transformation matrix\n * @param {Matrix} matrix - affine transformation matrix\n * @returns {Polygon} - new polygon\n */\n transform(matrix = new Flatten.Matrix()) {\n let newPolygon = new Polygon();\n for (let face of this.faces) {\n newPolygon.addFace(face.shapes.map(shape => shape.transform(matrix)));\n }\n return newPolygon;\n }\n\n /**\n * This method returns an object that defines how data will be\n * serialized when called JSON.stringify() method\n * @returns {Object}\n */\n toJSON() {\n return [...this.faces].map(face => face.toJSON());\n }\n\n /**\n * Transform all faces into array of polygons\n * @returns {Flatten.Polygon[]}\n */\n toArray() {\n return [...this.faces].map(face => face.toPolygon());\n }\n\n /**\n * Return string to draw polygon in svg\n * @param attrs - an object with attributes for svg path element\n * @returns {string}\n */\n svg(attrs = {}) {\n let svgStr = `\\n\\n`;\n return svgStr;\n }\n}\n\nFlatten.Polygon = Polygon;\n\n/**\n * Shortcut method to create new polygon\n */\nconst polygon = (...args) => new Flatten.Polygon(...args);\nFlatten.polygon = polygon;\n\nconst {Circle, Line, Point, Vector, Utils} = Flatten;\n/**\n * Class Inversion represent operator of inversion in circle\n * Inversion is a transformation of the Euclidean plane that maps generalized circles\n * (where line is considered as a circle with infinite radius) into generalized circles\n * See also https://en.wikipedia.org/wiki/Inversive_geometry and\n * http://mathworld.wolfram.com/Inversion.html
\n * @type {Inversion}\n */\nclass Inversion {\n /**\n * Inversion constructor\n * @param {Circle} inversion_circle inversion circle\n */\n constructor(inversion_circle) {\n this.circle = inversion_circle;\n }\n\n\n get inversion_circle() {\n return this.circle;\n }\n\n static inversePoint(inversion_circle, point) {\n const v = new Vector(inversion_circle.pc, point);\n const k2 = inversion_circle.r * inversion_circle.r;\n const len2 = v.dot(v);\n const reflected_point = Utils.EQ_0(len2) ?\n new Point(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) :\n inversion_circle.pc.translate(v.multiply(k2 / len2));\n return reflected_point;\n }\n\n static inverseCircle(inversion_circle, circle) {\n const dist = inversion_circle.pc.distanceTo(circle.pc)[0];\n if (Utils.EQ(dist, circle.r)) { // Circle passing through inversion center mapped into line\n let d = (inversion_circle.r * inversion_circle.r) / (2 * circle.r);\n let v = new Vector(inversion_circle.pc, circle.pc);\n v = v.normalize();\n let pt = inversion_circle.pc.translate(v.multiply(d));\n\n return new Line(pt, v);\n } else { // Circle not passing through inversion center - map into another circle */\n /* Taken from http://mathworld.wolfram.com */\n let v = new Vector(inversion_circle.pc, circle.pc);\n let s = inversion_circle.r * inversion_circle.r / (v.dot(v) - circle.r * circle.r);\n let pc = inversion_circle.pc.translate(v.multiply(s));\n let r = Math.abs(s) * circle.r;\n\n return new Circle(pc, r);\n }\n }\n\n static inverseLine(inversion_circle, line) {\n const [dist, shortest_segment] = inversion_circle.pc.distanceTo(line);\n if (Utils.EQ_0(dist)) { // Line passing through inversion center, is mapping to itself\n return line.clone();\n } else { // Line not passing through inversion center is mapping into circle\n let r = inversion_circle.r * inversion_circle.r / (2 * dist);\n let v = new Vector(inversion_circle.pc, shortest_segment.end);\n v = v.multiply(r / dist);\n return new Circle(inversion_circle.pc.translate(v), r);\n }\n }\n\n inverse(shape) {\n if (shape instanceof Point) {\n return Inversion.inversePoint(this.circle, shape);\n }\n else if (shape instanceof Circle) {\n return Inversion.inverseCircle(this.circle, shape);\n }\n else if (shape instanceof Line) {\n return Inversion.inverseLine(this.circle, shape);\n }\n }\n}\nFlatten.Inversion = Inversion;\n\n/**\n * Shortcut to create inversion operator\n * @param circle\n * @returns {Inversion}\n */\nconst inversion = (circle) => new Flatten.Inversion(circle);\nFlatten.inversion = inversion;\n\nclass Distance {\n /**\n * Calculate distance and shortest segment between points\n * @param pt1\n * @param pt2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2point(pt1, pt2) {\n return pt1.distanceTo(pt2);\n }\n\n /**\n * Calculate distance and shortest segment between point and line\n * @param pt\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2line(pt, line) {\n let closest_point = pt.projectionOn(line);\n let vec = new Flatten.Vector(pt, closest_point);\n return [vec.length, new Flatten.Segment(pt, closest_point)];\n }\n\n /**\n * Calculate distance and shortest segment between point and circle\n * @param pt\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2circle(pt, circle) {\n let [dist2center, shortest_dist] = pt.distanceTo(circle.center);\n if (Flatten.Utils.EQ_0(dist2center)) {\n return [circle.r, new Flatten.Segment(pt, circle.toArc().start)];\n } else {\n let dist = Math.abs(dist2center - circle.r);\n let v = new Flatten.Vector(circle.pc, pt).normalize().multiply(circle.r);\n let closest_point = circle.pc.translate(v);\n return [dist, new Flatten.Segment(pt, closest_point)];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and segment\n * @param pt\n * @param segment\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2segment(pt, segment) {\n /* Degenerated case of zero-length segment */\n if (segment.start.equalTo(segment.end)) {\n return Distance.point2point(pt, segment.start);\n }\n\n let v_seg = new Flatten.Vector(segment.start, segment.end);\n let v_ps2pt = new Flatten.Vector(segment.start, pt);\n let v_pe2pt = new Flatten.Vector(segment.end, pt);\n let start_sp = v_seg.dot(v_ps2pt);\n /* dot product v_seg * v_ps2pt */\n let end_sp = -v_seg.dot(v_pe2pt);\n /* minus dot product v_seg * v_pe2pt */\n\n let dist;\n let closest_point;\n if (Flatten.Utils.GE(start_sp, 0) && Flatten.Utils.GE(end_sp, 0)) { /* point inside segment scope */\n let v_unit = segment.tangentInStart(); // new Flatten.Vector(v_seg.x / this.length, v_seg.y / this.length);\n /* unit vector ||v_unit|| = 1 */\n dist = Math.abs(v_unit.cross(v_ps2pt));\n /* dist = abs(v_unit x v_ps2pt) */\n closest_point = segment.start.translate(v_unit.multiply(v_unit.dot(v_ps2pt)));\n return [dist, new Flatten.Segment(pt, closest_point)];\n } else if (start_sp < 0) { /* point is out of scope closer to ps */\n return pt.distanceTo(segment.start);\n } else { /* point is out of scope closer to pe */\n return pt.distanceTo(segment.end);\n }\n };\n\n /**\n * Calculate distance and shortest segment between point and arc\n * @param pt\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2arc(pt, arc) {\n let circle = new Flatten.Circle(arc.pc, arc.r);\n let dist_and_segment = [];\n let dist, shortest_segment;\n [dist, shortest_segment] = Distance.point2circle(pt, circle);\n if (shortest_segment.end.on(arc)) {\n dist_and_segment.push(Distance.point2circle(pt, circle));\n }\n dist_and_segment.push(Distance.point2point(pt, arc.start));\n dist_and_segment.push(Distance.point2point(pt, arc.end));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and line\n * @param seg\n * @param line\n * @returns {Number | Segment}\n */\n static segment2line(seg, line) {\n let ip = seg.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(seg.start, line));\n dist_and_segment.push(Distance.point2line(seg.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n\n }\n\n /**\n * Calculate distance and shortest segment between two segments\n * @param seg1\n * @param seg2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2segment(seg1, seg2) {\n let ip = intersectSegment2Segment(seg1, seg2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n\n // Seg1 and seg2 not intersected\n let dist_and_segment = [];\n let dist_tmp, shortest_segment_tmp;\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.start, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n [dist_tmp, shortest_segment_tmp] = Distance.point2segment(seg2.end, seg1);\n dist_and_segment.push([dist_tmp, shortest_segment_tmp.reverse()]);\n dist_and_segment.push(Distance.point2segment(seg1.start, seg2));\n dist_and_segment.push(Distance.point2segment(seg1.end, seg2));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between segment and circle\n * @param seg\n * @param circle\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2circle(seg, circle) {\n /* Case 1 Segment and circle intersected. Return the first point and zero distance */\n let ip = seg.intersect(circle);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and circle\n\n /* Case 2. Distance to projection of center point to line bigger than radius\n * And projection point belong to segment\n * Then measure again distance from projection to circle and return it */\n let line = new Flatten.Line(seg.ps, seg.pe);\n let [dist, shortest_segment] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist, circle.r) && shortest_segment.end.on(seg)) {\n return Distance.point2circle(shortest_segment.end, circle);\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n else {\n let [dist_from_start, shortest_segment_from_start] = Distance.point2circle(seg.start, circle);\n let [dist_from_end, shortest_segment_from_end] = Distance.point2circle(seg.end, circle);\n return Flatten.Utils.LT(dist_from_start, dist_from_end) ?\n [dist_from_start, shortest_segment_from_start] :\n [dist_from_end, shortest_segment_from_end];\n }\n }\n\n /**\n * Calculate distance and shortest segment between segment and arc\n * @param seg\n * @param arc\n * @returns {Number | Segment} - distance and shortest segment\n */\n static segment2arc(seg, arc) {\n /* Case 1 Segment and arc intersected. Return the first point and zero distance */\n let ip = seg.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and arc\n let line = new Flatten.Line(seg.ps, seg.pe);\n let circle = new Flatten.Circle(arc.pc, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r) && shortest_segment_from_center.end.on(seg)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2arc(seg.start, arc));\n dist_and_segment.push(Distance.point2arc(seg.end, arc));\n\n let dist_tmp, segment_tmp;\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.start, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n [dist_tmp, segment_tmp] = Distance.point2segment(arc.end, seg);\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle1\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2circle(circle1, circle2) {\n let ip = circle1.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n // Case 1. Concentric circles. Convert to arcs and take distance between two arc starts\n if (circle1.center.equalTo(circle2.center)) {\n let arc1 = circle1.toArc();\n let arc2 = circle2.toArc();\n return Distance.point2point(arc1.start, arc2.start);\n } else {\n // Case 2. Not concentric circles\n let line = new Flatten.Line(circle1.center, circle2.center);\n let ip1 = line.intersect(circle1);\n let ip2 = line.intersect(circle2);\n\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[0], ip2[1]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[0]));\n dist_and_segment.push(Distance.point2point(ip1[1], ip2[1]));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two circles\n * @param circle\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static circle2line(circle, line) {\n let ip = circle.intersect(line);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n let [dist, shortest_segment] = Distance.point2circle(shortest_segment_from_center.end, circle);\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /**\n * Calculate distance and shortest segment between arc and line\n * @param arc\n * @param line\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2line(arc, line) {\n /* Case 1 Line and arc intersected. Return the first point and zero distance */\n let ip = line.intersect(arc);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle = new Flatten.Circle(arc.center, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\n * projection point belongs to segment AND\n * distance from projection point to circle belongs to arc =>\n * return this distance from projection to circle */\n let [dist_from_center, shortest_segment_from_center] = Distance.point2line(circle.center, line);\n if (Flatten.Utils.GE(dist_from_center, circle.r)) {\n let [dist_from_projection, shortest_segment_from_projection] =\n Distance.point2circle(shortest_segment_from_center.end, circle);\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n } else {\n let dist_and_segment = [];\n dist_and_segment.push(Distance.point2line(arc.start, line));\n dist_and_segment.push(Distance.point2line(arc.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between arc and circle\n * @param arc\n * @param circle2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2circle(arc, circle2) {\n let ip = arc.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc.center, arc.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2circle(arc.start, circle2));\n dist_and_segment.push(Distance.point2circle(arc.end, circle2));\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between two arcs\n * @param arc1\n * @param arc2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static arc2arc(arc1, arc2) {\n let ip = arc1.intersect(arc2);\n if (ip.length > 0) {\n return [0, new Flatten.Segment(ip[0], ip[0])];\n }\n\n let circle1 = new Flatten.Circle(arc1.center, arc1.r);\n let circle2 = new Flatten.Circle(arc2.center, arc2.r);\n\n let [dist, shortest_segment] = Distance.circle2circle(circle1, circle2);\n if (shortest_segment.start.on(arc1) && shortest_segment.end.on(arc2)) {\n return [dist, shortest_segment];\n } else {\n let dist_and_segment = [];\n\n let dist_tmp, segment_tmp;\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.start, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc1.end, arc2);\n if (segment_tmp.end.on(arc2)) {\n dist_and_segment.push([dist_tmp, segment_tmp]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.start, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2arc(arc2.end, arc1);\n if (segment_tmp.end.on(arc1)) {\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.start, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.start);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n [dist_tmp, segment_tmp] = Distance.point2point(arc1.end, arc2.end);\n dist_and_segment.push([dist_tmp, segment_tmp]);\n\n Distance.sort(dist_and_segment);\n\n return dist_and_segment[0];\n }\n }\n\n /**\n * Calculate distance and shortest segment between point and polygon\n * @param point\n * @param polygon\n * @returns {Number | Segment} - distance and shortest segment\n */\n static point2polygon(point, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = (edge.shape instanceof Flatten.Segment) ?\n Distance.point2segment(point, edge.shape) : Distance.point2arc(point, edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n static shape2polygon(shape, polygon) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of polygon.edges) {\n let [dist, shortest_segment] = shape.distanceTo(edge.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Calculate distance and shortest segment between two polygons\n * @param polygon1\n * @param polygon2\n * @returns {Number | Segment} - distance and shortest segment\n */\n static polygon2polygon(polygon1, polygon2) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge1 of polygon1.edges) {\n for (let edge2 of polygon2.edges) {\n let [dist, shortest_segment] = edge1.shape.distanceTo(edge2.shape);\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n }\n return min_dist_and_segment;\n }\n\n /**\n * Returns [mindist, maxdist] array of squared minimal and maximal distance between boxes\n * Minimal distance by x is\n * (box2.xmin - box1.xmax), if box1 is left to box2\n * (box1.xmin - box2.xmax), if box2 is left to box1\n * 0, if box1 and box2 are intersected by x\n * Minimal distance by y is defined in the same way\n *\n * Maximal distance is estimated as a sum of squared dimensions of the merged box\n *\n * @param box1\n * @param box2\n * @returns {Number | Number} - minimal and maximal distance\n */\n static box2box_minmax(box1, box2) {\n let mindist_x = Math.max(Math.max(box1.xmin - box2.xmax, 0), Math.max(box2.xmin - box1.xmax, 0));\n let mindist_y = Math.max(Math.max(box1.ymin - box2.ymax, 0), Math.max(box2.ymin - box1.ymax, 0));\n let mindist = mindist_x * mindist_x + mindist_y * mindist_y;\n\n let box = box1.merge(box2);\n let dx = box.xmax - box.xmin;\n let dy = box.ymax - box.ymin;\n let maxdist = dx * dx + dy * dy;\n\n return [mindist, maxdist];\n }\n\n static minmax_tree_process_level(shape, level, min_stop, tree) {\n // Calculate minmax distance to each shape in current level\n // Insert result into the interval tree for further processing\n // update min_stop with maxdist, it will be the new stop distance\n let mindist, maxdist;\n for (let node of level) {\n\n // [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n // if (Flatten.Utils.GT(mindist, min_stop))\n // continue;\n\n // Estimate min-max dist to the shape stored in the node.item, using node.item.key which is shape's box\n [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.item.key);\n if (node.item.value instanceof Flatten.Edge) {\n tree.insert([mindist, maxdist], node.item.value.shape);\n } else {\n tree.insert([mindist, maxdist], node.item.value);\n }\n if (Flatten.Utils.LT(maxdist, min_stop)) {\n min_stop = maxdist; // this will be the new distance estimation\n }\n }\n\n if (level.length === 0)\n return min_stop;\n\n // Calculate new level from left and right children of the current\n let new_level_left = level.map(node => node.left.isNil() ? undefined : node.left).filter(node => node !== undefined);\n let new_level_right = level.map(node => node.right.isNil() ? undefined : node.right).filter(node => node !== undefined);\n // Merge left and right subtrees and leave only relevant subtrees\n let new_level = [...new_level_left, ...new_level_right].filter(node => {\n // Node subtree quick reject, node.max is a subtree box\n let [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n return (Flatten.Utils.LE(mindist, min_stop));\n });\n\n min_stop = Distance.minmax_tree_process_level(shape, new_level, min_stop, tree);\n return min_stop;\n }\n\n /**\n * Calculates sorted tree of [mindist, maxdist] intervals between query shape\n * and shapes of the planar set.\n * @param shape\n * @param set\n */\n static minmax_tree(shape, set, min_stop) {\n let tree = new IntervalTree();\n let level = [set.index.root];\n let squared_min_stop = min_stop < Number.POSITIVE_INFINITY ? min_stop * min_stop : Number.POSITIVE_INFINITY;\n squared_min_stop = Distance.minmax_tree_process_level(shape, level, squared_min_stop, tree);\n return tree;\n }\n\n static minmax_tree_calc_distance(shape, node, min_dist_and_segment) {\n let min_dist_and_segment_new, stop;\n if (node != null && !node.isNil()) {\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.left, min_dist_and_segment);\n\n if (stop) {\n return [min_dist_and_segment_new, stop];\n }\n\n if (Flatten.Utils.LT(min_dist_and_segment_new[0], Math.sqrt(node.item.key.low))) {\n return [min_dist_and_segment_new, true]; // stop condition\n }\n\n let [dist, shortest_segment] = Distance.distance(shape, node.item.value);\n // console.log(dist)\n if (Flatten.Utils.LT(dist, min_dist_and_segment_new[0])) {\n min_dist_and_segment_new = [dist, shortest_segment];\n }\n\n [min_dist_and_segment_new, stop] = Distance.minmax_tree_calc_distance(shape, node.right, min_dist_and_segment_new);\n\n return [min_dist_and_segment_new, stop];\n }\n\n return [min_dist_and_segment, false];\n }\n\n /**\n * Calculates distance between shape and Planar Set of shapes\n * @param shape\n * @param {PlanarSet} set\n * @param {Number} min_stop\n * @returns {*}\n */\n static shape2planarSet(shape, set, min_stop = Number.POSITIVE_INFINITY) {\n let min_dist_and_segment = [min_stop, new Flatten.Segment()];\n let stop = false;\n if (set instanceof Flatten.PlanarSet) {\n let tree = Distance.minmax_tree(shape, set, min_stop);\n [min_dist_and_segment, stop] = Distance.minmax_tree_calc_distance(shape, tree.root, min_dist_and_segment);\n }\n return min_dist_and_segment;\n }\n\n static sort(dist_and_segment) {\n dist_and_segment.sort((d1, d2) => {\n if (Flatten.Utils.LT(d1[0], d2[0])) {\n return -1;\n }\n if (Flatten.Utils.GT(d1[0], d2[0])) {\n return 1;\n }\n return 0;\n });\n }\n\n static distance(shape1, shape2) {\n return shape1.distanceTo(shape2);\n }\n}\n\nFlatten.Distance = Distance;\n\n/**\n * Created by Alex Bol on 2/18/2017.\n */\n\n\nFlatten.BooleanOperations = BooleanOperations;\nFlatten.Relations = Relations;\n\nexport { Arc, BOUNDARY$1 as BOUNDARY, BooleanOperations, Box, CCW, CW, Circle$1 as Circle, Distance, Edge, Errors, Face, INSIDE$2 as INSIDE, Inversion, Line$1 as Line, Matrix, Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$1 as Point, Polygon, Ray, Relations, Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, line, matrix, multiline, point, polygon, ray, ray_shoot, segment, vector$1 as vector };\n","import type {LatLngExpression} from 'leaflet';\nimport L, {Bounds, LatLng, LatLngBounds, Path, Point, Util} from 'leaflet';\nimport Flatten from '@flatten-js/core';\nimport Matrix = Flatten.Matrix;\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport type {ShapeOptions, TrackSymbolOptions} from './options';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_LEADER_TIME = 60;\n\n/**\n * Track symbol.\n */\nexport class TrackSymbol\n extends Path {\n\n /** Default 'withHeading' shape points. */\n public static DEFAULT_HEADING_SHAPE_POINTS: Points = [[0.75, 0], [-0.25, 0.3], [-0.25, -0.3]];\n\n /** Default 'withoutHeading' shape points. */\n public static DEFAULT_NOHEADING_SHAPE_POINTS: Points = [[0.3, 0], [0, 0.3], [-0.3, 0], [0, -0.3]];\n\n /** Default shape set. */\n private static DEFAULT_SHAPE_SET: ShapeSet = {\n withHeading: {\n points: TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n withoutHeading: {\n points: TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS,\n length: DEFAULT_SIZE,\n breadth: DEFAULT_SIZE,\n units: \"pixels\",\n },\n };\n\n /** Location. */\n private _latLng: LatLng;\n /** Heading (radians, from north, clockwise. */\n private _heading?: number;\n /** Course (radians, from north, clockwise. */\n private _course?: number;\n /** Speed (m/s). */\n private _speed?: number;\n /** Shape options. */\n private _shapeOptions: ShapeOptions;\n\n /** Current shape points. */\n private _currentShapePoints: Point[] | undefined;\n /** Current leader points. */\n private _currentLeaderPoints: Point[] | undefined;\n /** Current bounds. */\n private _currentBounds: Bounds | undefined;\n /** Current lat/lng bounds. */\n private _currentLatLngBounds: LatLngBounds | undefined;\n\n /**\n * TrackSymbol constructor.\n *\n * @param latLng - Initial location.\n * @param options - Options.\n */\n constructor(latLng: LatLngExpression, options?: TrackSymbolOptions) {\n super();\n\n Util.setOptions(this, options);\n if (latLng == undefined) {\n throw Error(\"latLng required\");\n }\n options = options || {};\n this._latLng = L.latLng(latLng);\n this._heading = options.heading;\n this._course = options.course;\n this._speed = options.speed;\n this._shapeOptions = options.shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n this._setShapeOptions(options.shapeOptions);\n }\n\n // ---- Leaflet\n\n /**\n * Project to layer.\n *\n * [Leaflet internal]\n */\n protected _project() {\n this._currentShapePoints = this._getProjectedShapePoints();\n this._currentLeaderPoints = this._getLeaderShapePoints();\n\n const bounds = new Bounds();\n for (let i = 0; i < this._currentShapePoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n if (this._currentLeaderPoints !== undefined) {\n for (let i = 0; i < this._currentLeaderPoints.length; i++) {\n const point = this._currentShapePoints[i];\n bounds.extend(point);\n }\n }\n this._currentBounds = bounds;\n this._currentLatLngBounds = new LatLngBounds(\n this._map.layerPointToLatLng(bounds.getBottomLeft()),\n this._map.layerPointToLatLng(bounds.getTopRight())\n );\n }\n\n /**\n * Update element.\n *\n * [Leaflet internal]\n */\n protected _update() {\n if (!this._map) {\n return;\n }\n const el = this.getElement();\n if (el === undefined) {\n return;\n }\n const paths: string[] = [];\n if (this._currentShapePoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentShapePoints, true));\n }\n if (this._currentLeaderPoints !== undefined) {\n paths.push(TrackSymbol._toSVGPath(this._currentLeaderPoints, false));\n }\n const viewPath = paths.join(' ');\n el.setAttribute('d', viewPath);\n }\n\n // ----\n\n /**\n * Set shape options.\n *\n * @param shapeOptions - Shape options.\n */\n private _setShapeOptions(shapeOptions: ShapeOptions | undefined) {\n this._shapeOptions = shapeOptions || {\n leaderTime: DEFAULT_LEADER_TIME,\n defaultShapeSet: TrackSymbol.DEFAULT_SHAPE_SET,\n };\n if (this._shapeOptions.leaderTime === undefined) {\n this._shapeOptions.leaderTime = DEFAULT_LEADER_TIME;\n }\n if (this._shapeOptions.defaultShapeSet === undefined) {\n this._shapeOptions.defaultShapeSet = TrackSymbol.DEFAULT_SHAPE_SET;\n }\n if (this._shapeOptions.shapeSetEntries !== undefined) {\n this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel);\n }\n }\n\n // ---\n\n /**\n * Sets the location.\n *\n * @param latLng - Location.\n * @returns this\n */\n public setLatLng(latLng: LatLngExpression): this {\n const oldLatLng = this._latLng;\n this._latLng = L.latLng(latLng);\n this.fire('move', {\n oldLatLng: oldLatLng,\n latlng: this._latLng,\n });\n return this.redraw();\n }\n\n /**\n * Sets the heading.\n *\n * @param heading - Heading (unit: radians, from north, clockwise).\n * @returns this\n */\n public setHeading(heading: number | undefined): this {\n this._heading = heading;\n return this.redraw();\n }\n\n /**\n * Sets the course over ground.\n *\n * @param course - Course over ground (unit: radians, from north, clockwise).\n * @returns this\n */\n public setCourse(course: number | undefined): this {\n this._course = course;\n return this.redraw();\n }\n\n /**\n * Sets the speed.\n *\n * @param speed - Speed (unit: m/s).\n * @returns this\n */\n public setSpeed(speed: number | undefined): this {\n this._speed = speed;\n return this.redraw();\n }\n\n /**\n * Sets the shape options.\n *\n * @param shapeOptions - Shape options.\n * @returns this\n */\n public setShapeOptions(shapeOptions: ShapeOptions): this {\n this._setShapeOptions(shapeOptions);\n return this.redraw();\n }\n\n /**\n * Returns the bounding box.\n *\n * @returns The bounding box.\n */\n public getBounds(): LatLngBounds | undefined {\n return this._currentLatLngBounds;\n }\n\n /**\n * Returns the location.\n *\n * @returns The location.\n */\n public getLatLng(): LatLng {\n return this._latLng;\n }\n\n /**\n * Returns the speed.\n *\n * @returns The speed (m/s).\n */\n public getSpeed(): number | undefined {\n return this._speed;\n }\n\n /**\n * Returns the heading.\n *\n * @returns The heading (radians, from north, clockwise).\n */\n public getHeading(): number | undefined {\n return this._heading;\n }\n\n /**\n * Returns the course.\n *\n * @returns The course (radians, from north, clockwise).\n */\n public getCourse(): number | undefined {\n return this._course;\n }\n\n /**\n * Creates a shape.\n *\n * @param points - Points.\n * @param size - Size (units: pixels).\n * @returns The new shape.\n */\n public static createShape(points: Points, size: number): Shape {\n return {\n points: points,\n length: size,\n breadth: size,\n units: \"pixels\",\n };\n }\n\n /**\n * Creates a shape set.\n *\n * @param size - Size (units: pixels).\n * @returns The new shape set.\n */\n public static createShapeSet(size: number): ShapeSet {\n return {\n withHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_HEADING_SHAPE_POINTS, size),\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n /**\n * Get latitude size of y-distance.\n *\n * @param value - Y distance (m).\n * @returns dLat\n */\n private _getLatSizeOf(value: number): number {\n return (value / 40075017) * 360;\n }\n\n /**\n * Get longitude size of x-distance.\n *\n * @param value - X distance (m).\n * @returns dLng\n */\n private _getLngSizeOf(value: number): number {\n return ((value / 40075017) * 360) / Math.cos((Math.PI / 180) * this._latLng.lat);\n }\n\n /**\n * Get view angle from model.\n *\n * @param modelAngle - Model angle (radians).\n * @returns View angle from model (radians).\n */\n private _getViewAngleFromModel(modelAngle: number): number {\n return modelAngle - Math.PI / 2.0;\n }\n\n /**\n * Get leader shape points.\n *\n * @returns Points.\n */\n private _getLeaderShapePoints(): Point[] | undefined {\n if ((this._course === undefined) || (this._speed === undefined)\n || (this._shapeOptions === undefined) || (this._shapeOptions.leaderTime === undefined)) {\n return undefined;\n }\n const angle = this._getViewAngleFromModel(this._course);\n const leaderLength = this._speed * this._shapeOptions.leaderTime;\n const leaderEndLatLng = this._calcRelativeLatLng(this._latLng, leaderLength, angle);\n return this._latLngsToLayerPoints(this._latLng, leaderEndLatLng);\n }\n\n /**\n * Calculate relative lat/lng.\n *\n * @param latLng - LatLng.\n * @param distance - Distance (meters).\n * @param angle - Angle (radians).\n * @returns Calculated LatLng.\n */\n private _calcRelativeLatLng(latLng: LatLng, distance: number, angle: number): LatLng {\n return new LatLng(\n latLng.lat - this._getLatSizeOf(distance * Math.sin(angle)),\n latLng.lng + this._getLngSizeOf(distance * Math.cos(angle))\n );\n }\n\n /**\n * Convert LatLngs to map layer points.\n *\n * @param latLngs - LatLngs.\n * @returns Points.\n */\n private _latLngsToLayerPoints(...latLngs: LatLng[]): Point[] {\n return latLngs.map(latLng => this._map.latLngToLayerPoint(latLng));\n }\n\n /**\n * Gets the shape set.\n *\n * @returns The shape set.\n */\n private _getShapeSet(): ShapeSet {\n if ((this._shapeOptions.shapeSetEntries === undefined)\n || (this._shapeOptions.shapeSetEntries.length == 0)) {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n const zoomLevel = this._map.getZoom();\n const shapeSetEntriesFiltered = this._shapeOptions.shapeSetEntries\n .sort((a, b) => b.minZoomLevel - a.minZoomLevel)\n .filter(shapeSetEntry => zoomLevel >= shapeSetEntry.minZoomLevel);\n if (shapeSetEntriesFiltered.length > 0) {\n return shapeSetEntriesFiltered[0].shapeSet;\n } else {\n return this._shapeOptions.defaultShapeSet ? this._shapeOptions.defaultShapeSet : TrackSymbol.DEFAULT_SHAPE_SET;\n }\n }\n\n /**\n * Gets the shape.\n *\n * @returns The shape.\n */\n private _getShape(): Shape {\n const shapeSet = this._getShapeSet();\n return (this._heading !== undefined) ? shapeSet.withHeading : shapeSet.withoutHeading;\n }\n\n /**\n * Get transformed shape points.\n *\n * @returns Transformed points and units.\n */\n private _getTransformedShapePoints(): [Points, Units] {\n const shape = this._getShape();\n let m = new Matrix();\n if (this._heading !== undefined) {\n const headingAngle = this._getViewAngleFromModel(this._heading);\n m = m.rotate(headingAngle);\n }\n if (shape.center !== undefined) {\n m = m.translate(-shape.center[0], -shape.center[1]);\n }\n m = m.scale(shape.length, shape.breadth);\n const points = shape.points.map(point => m.transform(point));\n return [points, shape.units];\n }\n\n /**\n * Get projected shape points.\n *\n * @returns Points projected to map layer.\n */\n private _getProjectedShapePoints(): Point[] {\n const [points, units] = this._getTransformedShapePoints();\n switch (units) {\n case \"pixels\": {\n const p = this._map.latLngToLayerPoint(this._latLng);\n const m = new Matrix().translate(p.x, p.y);\n return points.map(point => {\n const p1 = m.transform(point);\n return new Point(p1[0], p1[1]);\n });\n }\n case \"meters\": {\n return points.map(point => this._map.latLngToLayerPoint(\n new LatLng(\n this._latLng.lat - this._getLatSizeOf(point[1]),\n this._latLng.lng + this._getLngSizeOf(point[0])\n )\n ));\n }\n default:\n throw `unsupported units: ${units}`;\n }\n }\n\n /**\n * Converts points to an SVG path string.\n *\n * @param points - Points.\n * @param close - Close path.\n * @returns SVG path string.\n */\n private static _toSVGPath(points: Point[], close: boolean): string {\n let result = '';\n for (let i = 0; i < points.length; i++) {\n const point = points[i];\n if (result === '') {\n result = `M ${point.x} ${point.y} `;\n } else {\n result += `L ${point.x} ${point.y} `;\n }\n }\n if (close) {\n result += 'Z';\n }\n return result;\n }\n}\n","import {TrackSymbol} from '../trackSymbol';\nimport type {ShapeOptions} from '../options';\nimport type {Points, ShapeSet} from '../types';\nimport type {AISTrackSymbolOptions} from './options';\nimport type {Dimension, ETA, PositionReport, ShipStaticData} from './types';\nimport {DomUtil, Util} from 'leaflet';\n\nconst DEFAULT_SIZE = 24;\nconst DEFAULT_MIN_ZOOM_LEVEL = 14;\nconst DEFAULT_LEADER_TIME = 60;\nconst KNOTS_PER_METER_PER_SECOND = 1.944;\nconst MAX_SOG_EXCLUSIVE = 102.3;\nconst MAX_COG_EXCLUSIVE = 360;\nconst MAX_HEADING_EXCLUSIVE = 360;\n\ninterface ShipType {\n name: string;\n color: string;\n fillColor: string;\n}\n\nconst RESERVED_COLOR = \"#000000\";\nconst RESERVED_FILL_COLOR = \"#d3d3d3\";\nconst WIG_COLOR = \"#000000\";\nconst WIG_FILL_COLOR = \"#d3d3d3\";\nconst TYPE_3X_COLOR = \"#8b008b\";\nconst TYPE_3X_FILL_COLOR = \"#ff00ff\";\nconst HSC_COLOR = \"#00008b\";\nconst HSC_FILL_COLOR = \"#ffff00\";\nconst TYPE_5X_COLOR = \"#008b8b\";\nconst TYPE_5X_FILL_COLOR = \"#00ffff\";\nconst PASSENGER_COLOR = \"#00008b\";\nconst PASSENGER_FILL_COLOR = \"#0000ff\";\nconst CARGO_COLOR = \"#006400\";\nconst CARGO_FILL_COLOR = \"#90ee90\";\nconst TANKER_COLOR = \"#8b0000\";\nconst TANKER_FILL_COLOR = \"#ff0000\";\nconst OTHER_COLOR = \"#008b8b\";\nconst OTHER_FILL_COLOR = \"#00ffff\";\n\nconst TYPES: { [key: number]: ShipType } = {\n 0: newShipType('Not available', WIG_COLOR, WIG_FILL_COLOR),\n 20: newShipType('Wing in ground (WIG), all ships of this type', WIG_COLOR, WIG_FILL_COLOR),\n 21: newShipType('Wing in ground (WIG), Hazardous category A', WIG_COLOR, WIG_FILL_COLOR),\n 22: newShipType('Wing in ground (WIG), Hazardous category B', WIG_COLOR, WIG_FILL_COLOR),\n 23: newShipType('Wing in ground (WIG), Hazardous category C', WIG_COLOR, WIG_FILL_COLOR),\n 24: newShipType('Wing in ground (WIG), Hazardous category D', WIG_COLOR, WIG_FILL_COLOR),\n 25: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 26: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 27: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 28: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 29: newShipType('Wing in ground (WIG), Reserved for future use', WIG_COLOR, WIG_FILL_COLOR),\n 30: newShipType('Fishing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 31: newShipType('Towing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 32: newShipType('Towing: length exceeds 200m or breadth exceeds 25m', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 33: newShipType('Dredging or underwater ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 34: newShipType('Diving ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 35: newShipType('Military ops', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 36: newShipType('Sailing', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 37: newShipType('Pleasure Craft', TYPE_3X_COLOR, TYPE_3X_FILL_COLOR),\n 40: newShipType('High speed craft (HSC), all ships of this type', HSC_COLOR, HSC_FILL_COLOR),\n 41: newShipType('High speed craft (HSC), Hazardous category A', HSC_COLOR, HSC_FILL_COLOR),\n 42: newShipType('High speed craft (HSC), Hazardous category B', HSC_COLOR, HSC_FILL_COLOR),\n 43: newShipType('High speed craft (HSC), Hazardous category C', HSC_COLOR, HSC_FILL_COLOR),\n 44: newShipType('High speed craft (HSC), Hazardous category D', HSC_COLOR, HSC_FILL_COLOR),\n 45: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 46: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 47: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 48: newShipType('High speed craft (HSC), Reserved for future use', HSC_COLOR, HSC_FILL_COLOR),\n 49: newShipType('High speed craft (HSC), No additional information', HSC_COLOR, HSC_FILL_COLOR),\n 50: newShipType('Pilot Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 51: newShipType('Search and Rescue vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 52: newShipType('Tug', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 53: newShipType('Port Tender', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 54: newShipType('Anti-pollution equipment', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 55: newShipType('Law Enforcement', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 56: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 57: newShipType('Spare - Local Vessel', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 58: newShipType('Medical Transport', TYPE_5X_COLOR, TYPE_5X_FILL_COLOR),\n 59: newShipType('Noncombatant ship according to RR Resolution No. 18', '', ''),\n 60: newShipType('Passenger, all ships of this type', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 61: newShipType('Passenger, Hazardous category A', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 62: newShipType('Passenger, Hazardous category B', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 63: newShipType('Passenger, Hazardous category C', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 64: newShipType('Passenger, Hazardous category D', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 65: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 66: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 67: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 68: newShipType('Passenger, Reserved for future use', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 69: newShipType('Passenger, No additional information', PASSENGER_COLOR, PASSENGER_FILL_COLOR),\n 70: newShipType('Cargo, all ships of this type', CARGO_COLOR, CARGO_FILL_COLOR),\n 71: newShipType('Cargo, Hazardous category A', CARGO_COLOR, CARGO_FILL_COLOR),\n 72: newShipType('Cargo, Hazardous category B', CARGO_COLOR, CARGO_FILL_COLOR),\n 73: newShipType('Cargo, Hazardous category C', CARGO_COLOR, CARGO_FILL_COLOR),\n 74: newShipType('Cargo, Hazardous category D', CARGO_COLOR, CARGO_FILL_COLOR),\n 75: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 76: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 77: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 78: newShipType('Cargo, Reserved for future use', CARGO_COLOR, CARGO_FILL_COLOR),\n 79: newShipType('Cargo, No additional information', CARGO_COLOR, CARGO_FILL_COLOR),\n 80: newShipType('Tanker, all ships of this type', TANKER_COLOR, TANKER_FILL_COLOR),\n 81: newShipType('Tanker, Hazardous category A', TANKER_COLOR, TANKER_FILL_COLOR),\n 82: newShipType('Tanker, Hazardous category B', TANKER_COLOR, TANKER_FILL_COLOR),\n 83: newShipType('Tanker, Hazardous category C', TANKER_COLOR, TANKER_FILL_COLOR),\n 84: newShipType('Tanker, Hazardous category D', TANKER_COLOR, TANKER_FILL_COLOR),\n 85: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 86: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 87: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 88: newShipType('Tanker, Reserved for future use', TANKER_COLOR, TANKER_FILL_COLOR),\n 89: newShipType('Tanker, No additional information', TANKER_COLOR, TANKER_FILL_COLOR),\n 90: newShipType('Other Type, all ships of this type', OTHER_COLOR, OTHER_FILL_COLOR),\n 91: newShipType('Other Type, Hazardous category A', OTHER_COLOR, OTHER_FILL_COLOR),\n 92: newShipType('Other Type, Hazardous category B', OTHER_COLOR, OTHER_FILL_COLOR),\n 93: newShipType('Other Type, Hazardous category C', OTHER_COLOR, OTHER_FILL_COLOR),\n 94: newShipType('Other Type, Hazardous category D', OTHER_COLOR, OTHER_FILL_COLOR),\n 95: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 96: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 97: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 98: newShipType('Other Type, Reserved for future use', OTHER_COLOR, OTHER_FILL_COLOR),\n 99: newShipType('Other Type, no additional information', OTHER_COLOR, OTHER_FILL_COLOR),\n};\nconst RESERVED_TYPE = newShipType('Reserved', RESERVED_COLOR, RESERVED_FILL_COLOR);\nconst UNKNOWN_TYPE = newShipType('Unknown', RESERVED_COLOR, RESERVED_FILL_COLOR);\n\nexport class AISTrackSymbol\n extends TrackSymbol {\n\n /** Default silhouette shape points. */\n public static DEFAULT_SILHOUETTE_SHAPE_POINTS: Points = [[1, 0.5], [0.75, 1], [0, 1], [0, 0], [0.75, 0]];\n\n private readonly _leaderTime: number;\n private readonly _minZoomLevel: number;\n private readonly _size: number;\n private _positionReport: PositionReport;\n private _shipStaticData?: ShipStaticData;\n\n /**\n * AISTrackSymbol constructor.\n *\n * @param positionReport - Position report.\n * @param options - Options.\n */\n constructor(positionReport: PositionReport, options?: AISTrackSymbolOptions) {\n super([positionReport.latitude, positionReport.longitude], options);\n\n Util.setOptions(this, options);\n options = options || {};\n this._leaderTime = options.leaderTime || DEFAULT_LEADER_TIME;\n this._minZoomLevel = options.minZoomLevel || DEFAULT_MIN_ZOOM_LEVEL;\n this._size = options.size || DEFAULT_SIZE;\n this._positionReport = positionReport;\n this.setPositionReport(positionReport);\n this.setShipStaticData(options.shipStaticData);\n }\n\n /**\n * Get ETA from Date.\n *\n * @param date - Date.\n * @returns ETA\n */\n public static etaFromDate(date: Date | null | undefined): ETA | undefined {\n if ((date === null) || (date === undefined)) {\n return undefined;\n }\n return {\n month: date.getMonth() + 1,\n day: date.getDate(),\n hour: date.getHours(),\n minute: date.getMinutes(),\n }\n }\n\n /**\n * Sets the position report.\n *\n * @param positionReport - Position report.\n * @returns this\n */\n public setPositionReport(positionReport: PositionReport): this {\n this._positionReport = positionReport;\n this.setLatLng([positionReport.latitude, positionReport.longitude]);\n if ((positionReport.trueHeading !== null) && (positionReport.trueHeading !== undefined) && (positionReport.trueHeading < MAX_HEADING_EXCLUSIVE)) {\n this.setHeading(toRadians(positionReport.trueHeading));\n } else {\n this.setHeading(undefined);\n }\n if ((positionReport.cog !== null) && (positionReport.cog !== undefined) && (positionReport.cog < MAX_COG_EXCLUSIVE)) {\n this.setCourse(toRadians(positionReport.cog));\n } else {\n this.setCourse(undefined);\n }\n if ((positionReport.sog !== null) && (positionReport.sog !== undefined) && (positionReport.sog < MAX_SOG_EXCLUSIVE)) {\n this.setSpeed(positionReport.sog / KNOTS_PER_METER_PER_SECOND);\n } else {\n this.setSpeed(undefined);\n }\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.redraw();\n }\n\n /**\n * Sets the ship static data.\n *\n * @param shipStaticData - Ship static data.\n * @returns this\n */\n public setShipStaticData(shipStaticData?: ShipStaticData): this {\n this._shipStaticData = shipStaticData;\n const shipType = getShipType((shipStaticData !== null) && (shipStaticData !== undefined) ? shipStaticData.type : undefined);\n this.setStyle({\n color: shipType.color,\n fill: true,\n fillOpacity: 1.0,\n fillColor: shipType.fillColor,\n });\n this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData));\n return this.setShapeOptions(AISTrackSymbol._getShapeOptions(this._leaderTime, this._minZoomLevel, this._size,\n shipStaticData));\n }\n\n private static _getShapeOptions(leaderTime: number, minZoomLevel: number, size: number,\n shipStaticData?: ShipStaticData): ShapeOptions {\n const shapeOptions: ShapeOptions = {\n leaderTime: leaderTime,\n defaultShapeSet: TrackSymbol.createShapeSet(size),\n };\n const shapeSet = AISTrackSymbol._getShapeSet(size, shipStaticData);\n if (shapeSet !== null) {\n shapeOptions.shapeSetEntries = [{\n shapeSet: shapeSet,\n minZoomLevel: minZoomLevel,\n }];\n }\n return shapeOptions;\n }\n\n private static _getShapeSet(size: number, shipStaticData?: ShipStaticData): ShapeSet | null {\n if ((shipStaticData === null) || (shipStaticData === undefined)\n || (shipStaticData.dimension === null) || (shipStaticData.dimension === undefined)\n || !isDimensionValid(shipStaticData.dimension)) {\n return null;\n }\n return {\n withHeading: {\n points: AISTrackSymbol.DEFAULT_SILHOUETTE_SHAPE_POINTS,\n center: [shipStaticData.dimension.B, shipStaticData.dimension.D],\n length: shipStaticData.dimension.A + shipStaticData.dimension.B,\n breadth: shipStaticData.dimension.C + shipStaticData.dimension.D,\n units: \"meters\",\n },\n withoutHeading: TrackSymbol.createShape(TrackSymbol.DEFAULT_NOHEADING_SHAPE_POINTS, size),\n };\n }\n\n private _getPopupContent(positionReport?: PositionReport, shipStaticData?: ShipStaticData): HTMLElement {\n let content = \"\";\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"User ID\", shipStaticData.userId);\n content += createTableRow(\"IMO Number\", shipStaticData.imoNumber);\n content += createTableRow(\"Call sign\", shipStaticData.callSign);\n content += createTableRow(\"Name\", shipStaticData.name);\n }\n if ((positionReport !== null) && (positionReport !== undefined)) {\n content += createTableRow(\"Location\", `${toFixed(positionReport.latitude, 5)}, ${toFixed(positionReport.longitude, 5)}`);\n content += createTableRow(\"SOG\",\n toFixed(positionReport.sog, 2, v => v < MAX_SOG_EXCLUSIVE), \"knots\");\n content += createTableRow(\"COG\",\n toFixed(positionReport.cog, 1), \"°\");\n content += createTableRow(\"Heading\",\n toFixed(positionReport.trueHeading, 1), \"°\");\n content += createTableRow(\"Navigation status\",\n toNavigationStatusString(positionReport.navigationalStatus));\n }\n if ((shipStaticData !== null) && (shipStaticData !== undefined)) {\n content += createTableRow(\"Type\", toTypeString(shipStaticData.type));\n if ((shipStaticData.dimension !== null) && (shipStaticData.dimension !== undefined)\n && isDimensionValid(shipStaticData.dimension)) {\n content += createTableRow(\"Ship length\",\n shipStaticData.dimension.A + shipStaticData.dimension.B, \"m\");\n content += createTableRow(\"Ship width\",\n shipStaticData.dimension.C + shipStaticData.dimension.D, \"m\");\n }\n content += createTableRow(\"Fix type\", toFixTypeString(shipStaticData.fixType));\n content += createTableRow(\"ETA\", toETAString(shipStaticData.eta));\n content += createTableRow(\"Maximum static draught\",\n toFixed(shipStaticData.maximumStaticDraught, 1), \"m\");\n content += createTableRow(\"Destination\", shipStaticData.destination);\n content += createTableRow(\"DTE\", shipStaticData.dte);\n }\n content += \"
\";\n const popupContent = DomUtil.create(\"div\");\n popupContent.innerHTML = content;\n return popupContent;\n }\n}\n\nfunction toFixed(v: number | null | undefined, fractionDigits?: number, isValid?: (v: number) => boolean): string | undefined {\n if ((v === null) || (v === undefined)) {\n return undefined;\n }\n if (isValid && !isValid(v)) {\n return undefined;\n }\n return v.toFixed(fractionDigits);\n}\n\nfunction toTypeString(type: number | null | undefined): string | undefined {\n if ((type === null) || (type === undefined)) {\n return undefined;\n }\n const shipType = getShipType(type);\n return shipType.name;\n}\n\nfunction toFixTypeString(fixType: number | null | undefined): string | undefined {\n if ((fixType === null) || (fixType === undefined)) {\n return undefined;\n }\n switch (fixType) {\n case 0:\n return undefined;\n case 1:\n return 'GPS';\n case 2:\n return 'GLONASS';\n case 3:\n return 'combined GPS/GLONASS';\n case 4:\n return 'Loran-C';\n case 5:\n return 'Chayka';\n case 6:\n return 'integrated navigation system';\n case 7:\n return 'surveyed';\n case 8:\n return 'Galileo';\n case 9:\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n return `not used (${fixType})`;\n case 15:\n return \"internal GNSS\";\n default:\n return `unknown (${fixType})`;\n }\n}\n\nfunction toNavigationStatusString(navigationStatus: number | null | undefined): string | undefined {\n if ((navigationStatus === null) || (navigationStatus === undefined)) {\n return undefined;\n }\n switch (navigationStatus) {\n case 0:\n return 'Under way using engine';\n case 1:\n return 'At anchor';\n case 2:\n return 'Not under command';\n case 3:\n return 'Restricted manoeuverability';\n case 4:\n return 'Constrained by her draught';\n case 5:\n return 'Moored';\n case 6:\n return 'Aground';\n case 7:\n return 'Engaged in Fishing';\n case 8:\n return 'Under way sailing';\n case 9:\n return 'Reserved for future amendment of Navigational Status for HSC';\n case 10:\n return 'Reserved for future amendment of Navigational Status for WIG';\n case 11:\n return 'Reserved for future use';\n case 12:\n return 'Reserved for future use';\n case 13:\n return 'Reserved for future use';\n case 14:\n return 'AIS-SART is active';\n case 15:\n return 'Not defined (default)';\n default:\n return `unknown (${navigationStatus})`;\n }\n}\n\nfunction toETAString(eta: ETA | null | undefined): string | undefined {\n if ((eta === null) || (eta === undefined)) {\n return undefined;\n }\n const parts: string[] = [];\n if (!isNullOrUndefined(eta.month) && !isNullOrUndefined(eta.day)) {\n parts.push(`${eta.month.toString().padStart(2, '0')}/${eta.day.toString().padStart(2, '0')}`);\n }\n if (!isNullOrUndefined(eta.hour) && !isNullOrUndefined(eta.minute)) {\n parts.push(`${eta.hour.toString().padStart(2, '0')}:${eta.minute.toString().padStart(2, '0')}`);\n }\n if (parts.length === 0) {\n return undefined;\n }\n return `${parts.join(' ')} UTC`;\n}\n\nfunction toRadians(degs: number | null | undefined): number | undefined {\n if ((degs === null) || (degs === undefined)) {\n return undefined;\n }\n return degs * Math.PI / 180;\n}\n\nfunction isNullOrUndefined(v: any): boolean {\n return (v === null) || (v === undefined);\n}\n\nfunction isDimensionValid(dimension: Dimension | null | undefined): boolean {\n return (dimension !== null) && (dimension !== undefined)\n && (dimension.A > 0) && (dimension.B > 0) && (dimension.C > 0) && (dimension.D > 0);\n}\n\nfunction createTableRow(name: string, value: any, unit?: string): string {\n if ((value === null) || (value === undefined)) {\n return '';\n }\n const sValue = String(value);\n return `${name}${sValue} ${isNullOrUndefined(unit) ? \"\" : unit}`;\n}\n\nfunction newShipType(name: string, color: string, fillColor: string): ShipType {\n return {\n name: name,\n color: color,\n fillColor: fillColor,\n };\n}\n\nfunction getShipType(type: number | null | undefined): ShipType {\n if ((type === null) || (type === undefined)) {\n return TYPES[0];\n }\n if ((type < 0) || (type > 99)) {\n return UNKNOWN_TYPE;\n }\n const shipType = TYPES[type];\n if (!isNullOrUndefined(shipType)) {\n return shipType;\n }\n return RESERVED_TYPE;\n}\n","//@ts-strict-ignore\nimport L from 'leaflet';\nimport type {LatLngExpression} from 'leaflet';\nimport {TrackSymbol} from './trackSymbol';\nimport type {ShapeSetEntry, ShapeOptions, TrackSymbolOptions} from './options';\nimport type {Points, Shape, ShapeSet, Units} from './types';\nimport {AISTrackSymbol} from './ais/aisTrackSymbol';\nimport type {AISTrackSymbolOptions} from './ais/options';\nimport type {AISMessage, Dimension, ETA, PositionReport, ShipStaticData} from './ais/types';\n\nexport {\n Points,\n Shape,\n ShapeOptions,\n ShapeSet,\n ShapeSetEntry,\n TrackSymbol,\n TrackSymbolOptions,\n Units,\n};\n\nexport {\n AISMessage,\n AISTrackSymbol,\n AISTrackSymbolOptions,\n Dimension,\n ETA,\n PositionReport,\n ShipStaticData,\n};\n\nL['trackSymbol'] = function(latLng: LatLngExpression, options?: TrackSymbolOptions): TrackSymbol {\n return new TrackSymbol(latLng, options);\n}\nL['TrackSymbol'] = TrackSymbol;\n\nL['aisTrackSymbol'] = function(positionReport: PositionReport, options?: AISTrackSymbolOptions): AISTrackSymbol {\n return new AISTrackSymbol(positionReport, options);\n}\nL['AISTrackSymbol'] = AISTrackSymbol;\n\nexport default TrackSymbol;\n"],"names":["ORIENTATION","PIx2","INSIDE$2","OUTSIDE$1","BOUNDARY$1","CONTAINS","INTERLACE","OVERLAP_SAME$1","OVERLAP_OPPOSITE$1","NOT_VERTEX$1","START_VERTEX$1","END_VERTEX$1","Constants","DP_TOL","setTolerance","tolerance","getTolerance","DECIMALS","EQ_0","x","EQ","y","GT","GE","LT","LE","Utils$1","Flatten","c","value","Errors","LinkedList","first","last","counter","edge","start","end","elements","from","to","element","newElement","elementBefore","elementAfter","controlEdge","addToIntPoints","pt","int_points","id","shapes","len","is_vertex","arc_length","sortIntersections","intersections","getSortedArray","faceMap","ip","compareFn","ip1","ip2","filterDuplicatedIntersections","do_squeeze","int_point_ref1","int_point_ref2","int_point_cur1","int_point_cur2","i","j","int_point","index","initializeInclusionFlags","calculateInclusionFlags","polygon","setOverlappingFlags","cur_face","first_int_point_in_face_id","next_int_point1","num_int_points","cur_int_point1","int_points_cur_pool_start","int_points_cur_pool_num","intPointsPoolCount","next_int_point_id","int_points_next_pool_num","next_int_point1_tmp","edge_from1","edge_to1","cur_int_point2","next_int_point2","edge_from2","edge_to2","cur_int_point_num","int_point_current","int_point_next","int_points_pool_num","splitByIntersections","newEdge","insertBetweenIntPoints","int_point1","int_point2","new_edges","edge_before","edge_after","INSIDE$1","OUTSIDE","BOUNDARY","OVERLAP_SAME","OVERLAP_OPPOSITE","NOT_VERTEX","START_VERTEX","END_VERTEX","BOOLEAN_UNION","BOOLEAN_INTERSECT","BOOLEAN_SUBTRACT","unify","polygon1","polygon2","res_poly","wrk_poly","booleanOpBinary","subtract","polygon2_reversed","intersect$1","innerClip","clip_shapes1","face","clip_shapes2","outerClip","calculateIntersections","getIntersections","ip_sorted1","ip_sorted2","filterNotRelevantEdges","op","notIntersectedFacesRes","getNotIntersectedFaces","notIntersectedFacesWrk","calcInclusionForNotIntersectedFaces","fixBoundaryConflicts","removeNotRelevantChains","removeNotRelevantNotIntersectedFaces","swapLinksAndRestore","copyWrkToRes","swapLinks","removeOldFaces","restoreFaces","restore","edge1","resp","edge2","poly","notIntersected","notIntersectedFaces","poly2","poly1","int_points1","int_points1_sorted","int_points2","iterate_more","edge_tmp","new_bv","dist","segment","newEdge1","int_point2_edge_after","newEdge2","is_res_polygon","first_int_point_in_face_num","int_points_from_pull_start","int_points_from_pull_num","next_int_point_num","int_points_to_pull_start","int_points_to_pull_num","edge_from","edge_to","k","res_polygon","wrk_polygon","other_int_points","int_point_tmp","rel","BooleanOperations","EQUAL","INTERSECT","TOUCH","INSIDE","COVERED","DE9IM","geom","e","intersectLine2Line","line1","line2","A1","B1","C1","A2","B2","C2","det","detX","detY","intersectLine2Circle","line","circle","prj","delta","v_trans","intersectLine2Box","box","ips","seg","ips_tmp","intersectSegment2Line","ptInIntPoints","intersectLine2Arc","arc","ip_tmp","intersectSegment2Segment","seg1","seg2","new_ip","isPointInSegmentBox","point","intersectSegment2Circle","_","intersectSegment2Arc","intersectSegment2Box","intersectCircle2Circle","circle1","circle2","vec","r1","r2","a","mid_pt","h","intersectCircle2Box","intersectArc2Arc","arc1","arc2","intersectArc2Circle","intersectArc2Box","intersectEdge2Segment","intersectEdge2Arc","intersectEdge2Line","intersectEdge2Ray","ray","intersectRay2Segment","intersectRay2Arc","intersectEdge2Circle","intersectSegment2Polygon","intersectArc2Polygon","intersectLine2Polygon","intersectCircle2Polygon","intersectEdge2Edge","intersectEdge2Polygon","resp_edges","resp_edge","intersectPolygon2Polygon","intersectShape2Polygon","shape","new_pt","createLineFromRay","intersectRay2Circle","intersectRay2Box","intersectRay2Line","intersectRay2Ray","ray1","ray2","intersectRay2Polygon","defaultAttributes","SVGAttributes","args","property","acc","key","SVGKey","str","convertToString","attrs","Multiline","v","edgeBefore","edgeFrom","edgeTo","edges","edgeFound","angle","center","matrix","svgStr","multiline","ray_shoot","contains","searchBox","faces","i1","i2","intersection","prev_edge","prev_tangent","prev_point","cur_tangent","cur_point","prev_on_the_left","cur_on_the_left","next_edge","next_tangent","next_point","next_on_the_left","equal","shape1","shape2","relate","intersect","touch","disjoint","inside","covered","contain","cover","relateLine2Line","relateLine2Circle","relateLine2Box","relateLine2Polygon","relateShape2Polygon","relatePolygon2Polygon","denim","ip_sorted","splitShapes","boolean_intersection","boolean_difference1","boolean_difference2","inner_clip_shapes1","inner_clip_shapes2","outer_clip_shapes1","outer_clip_shapes2","Relations","Matrix$1","Matrix","b","d","tx","ty","vector","other_matrix","centerX","centerY","cos","sin","sx","sy","Interval","low","high","other_interval","interval1","interval2","val1","val2","RB_TREE_COLOR_RED","RB_TREE_COLOR_BLACK","Node","left","right","parent","color","other_node","comparable_max","search_node","comparable_less_than","IntervalTree","count","res","node","insert_node","delete_node","interval","outputMapperFn","resp_nodes","visitor","callback","tree","node_current","current_node","parent_node","uncle_node","cut_node","fix_node","brother_node","found","node_min","node_max","node_successor","action","height","heightLeft","heightRight","PlanarSet","entry","size","deleted","Shape","Point$1","Point","arr","m","proj_vec","dx","dy","r","Vector$1","a1","a2","scalar","norm1","norm2","n","vector$1","Segment","coords","ps","pe","shortest_segment","length","factor","rest","ymin","dy1","dy2","pts","Line$1","Line","norm","A","B","C","other_line","distance","sorted_points","pt1","pt2","Circle$1","pc","counterclockwise","Arc","startAngle","endAngle","counterClockwise","sweep","test_arc","func_arcs_array","angles","test_arcs","prev_arc","new_arc","newStart","newEnd","newCenter","newDirection","onLeftSide","areaTrapez","areaCircularSegment","slope1","slope2","largeArcFlag","sweepFlag","Box","xmin","xmax","ymax","other_box","box1","box2","new_box","vertex","width","Edge","bvMiddle","flag","sign","halfArc1","halfArc2","CircularLinkedList","done","Face","segments","points","flattenShapes","flattenShape","sArea","area","exitOnFirst","Ray","slope","Polygon","argsArray","loop","el","loop1","valid","signedArea","unassignedEdgeFound","edge_next","newPoly","int_point1_prev","int_point1_curr","newEdges","polygons","orientation","newPolygons","islandPolygon","min_dist_and_segment","min_stop","newPolygon","Circle","Vector","Utils","Inversion","inversion_circle","k2","len2","s","inversion","Distance","closest_point","dist2center","shortest_dist","v_seg","v_ps2pt","v_pe2pt","start_sp","end_sp","v_unit","dist_and_segment","dist_tmp","shortest_segment_tmp","dist_from_start","shortest_segment_from_start","dist_from_end","shortest_segment_from_end","dist_from_center","shortest_segment_from_center","dist_from_projection","shortest_segment_from_projection","segment_tmp","mindist_x","mindist_y","mindist","maxdist","level","new_level_left","new_level_right","new_level","set","squared_min_stop","min_dist_and_segment_new","stop","d1","d2","DEFAULT_SIZE","DEFAULT_LEADER_TIME","_TrackSymbol","Path","latLng","options","Util","L","bounds","Bounds","LatLngBounds","paths","viewPath","shapeOptions","oldLatLng","heading","course","speed","modelAngle","leaderLength","leaderEndLatLng","LatLng","latLngs","zoomLevel","shapeSetEntriesFiltered","shapeSetEntry","shapeSet","headingAngle","units","p","p1","close","result","TrackSymbol","DEFAULT_MIN_ZOOM_LEVEL","KNOTS_PER_METER_PER_SECOND","MAX_SOG_EXCLUSIVE","MAX_COG_EXCLUSIVE","MAX_HEADING_EXCLUSIVE","RESERVED_COLOR","RESERVED_FILL_COLOR","WIG_COLOR","WIG_FILL_COLOR","TYPE_3X_COLOR","TYPE_3X_FILL_COLOR","HSC_COLOR","HSC_FILL_COLOR","TYPE_5X_COLOR","TYPE_5X_FILL_COLOR","PASSENGER_COLOR","PASSENGER_FILL_COLOR","CARGO_COLOR","CARGO_FILL_COLOR","TANKER_COLOR","TANKER_FILL_COLOR","OTHER_COLOR","OTHER_FILL_COLOR","TYPES","newShipType","RESERVED_TYPE","UNKNOWN_TYPE","_AISTrackSymbol","positionReport","date","toRadians","shipStaticData","shipType","getShipType","leaderTime","minZoomLevel","isDimensionValid","content","createTableRow","toFixed","toNavigationStatusString","toTypeString","toFixTypeString","toETAString","popupContent","DomUtil","AISTrackSymbol","fractionDigits","isValid","type","fixType","navigationStatus","eta","parts","isNullOrUndefined","degs","dimension","name","unit","sValue","fillColor"],"mappings":"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","x_google_ignoreList":[0]} \ No newline at end of file