diff --git a/dist/leaflet-tracksymbol2.es.js b/dist/leaflet-tracksymbol2.es.js index c220466..d8c8b76 100644 --- a/dist/leaflet-tracksymbol2.es.js +++ b/dist/leaflet-tracksymbol2.es.js @@ -1,62 +1,62 @@ -import xt, { Path as pn, Util as Be, Bounds as mn, LatLngBounds as xn, LatLng as Ee, Point as En, DomUtil as vn } from "leaflet"; -const ke = !0, wn = !1, $t = { CCW: -1, CW: 1, NOT_ORIENTABLE: 0 }, Tn = 2 * Math.PI, qt = 1, Fe = 0, z = 2, Sn = 3, In = 4, yn = 1, bn = 2, ue = 0, Gt = 1, mt = 2; -var Dt = /* @__PURE__ */ Object.freeze({ +import Et, { Path as bn, Util as $e, Bounds as On, LatLngBounds as Nn, LatLng as Se, Point as Cn, DomUtil as Rn } from "leaflet"; +const He = !0, Un = !1, Dt = { CCW: -1, CW: 1, NOT_ORIENTABLE: 0 }, Mn = 2 * Math.PI, Wt = 1, Ge = 0, D = 2, kn = 3, Fn = 4, Bn = 1, Vn = 2, ce = 0, bt = 1, mt = 2; +var zt = /* @__PURE__ */ Object.freeze({ __proto__: null, - BOUNDARY: z, - CCW: ke, - CONTAINS: Sn, - CW: wn, + BOUNDARY: D, + CCW: He, + CONTAINS: kn, + CW: Un, END_VERTEX: mt, - INSIDE: qt, - INTERLACE: In, - NOT_VERTEX: ue, - ORIENTATION: $t, - OUTSIDE: Fe, - OVERLAP_OPPOSITE: bn, - OVERLAP_SAME: yn, - PIx2: Tn, - START_VERTEX: Gt + INSIDE: Wt, + INTERLACE: Fn, + NOT_VERTEX: ce, + ORIENTATION: Dt, + OUTSIDE: Ge, + OVERLAP_OPPOSITE: Vn, + OVERLAP_SAME: Bn, + PIx2: Mn, + START_VERTEX: bt }); let Y = 1e-6; -function Ve(r) { +function qe(r) { Y = r; } -function He() { +function De() { return Y; } -const An = 3; -function ee(r) { +const $n = 3; +function ne(r) { return r < Y && r > -Y; } -function ot(r, t) { +function st(r, t) { return r - t < Y && r - t > -Y; } -function $e(r, t) { +function We(r, t) { return r - t > Y; } -function Pn(r, t) { +function Hn(r, t) { return r - t > -Y; } -function qe(r, t) { +function ze(r, t) { return r - t < -Y; } -function Ln(r, t) { +function Gn(r, t) { return r - t < Y; } -var On = /* @__PURE__ */ Object.freeze({ +var qn = /* @__PURE__ */ Object.freeze({ __proto__: null, - DECIMALS: An, - EQ: ot, - EQ_0: ee, - GE: Pn, - GT: $e, - LE: Ln, - LT: qe, - getTolerance: He, - setTolerance: Ve + DECIMALS: $n, + EQ: st, + EQ_0: ne, + GE: Hn, + GT: We, + LE: Gn, + LT: ze, + getTolerance: De, + setTolerance: qe }); let i = { - Utils: On, + Utils: qn, Errors: void 0, Matrix: void 0, Planar_set: void 0, @@ -76,17 +76,17 @@ let i = { Distance: void 0, Inversion: void 0 }; -for (let r in Dt) - i[r] = Dt[r]; +for (let r in zt) + i[r] = zt[r]; Object.defineProperty(i, "DP_TOL", { get: function() { - return He(); + return De(); }, set: function(r) { - Ve(r); + qe(r); } }); -class w { +class T { /** * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter * @returns {ReferenceError} @@ -125,9 +125,12 @@ class w { static get OPERATION_IS_NOT_SUPPORTED() { return new Error("Operation is not supported"); } + static get UNSUPPORTED_SHAPE_TYPE() { + return new Error("Unsupported shape type"); + } } -i.Errors = w; -class he { +i.Errors = T; +class de { constructor(t, e) { this.first = t, this.last = e || this.first; } @@ -154,8 +157,7 @@ class he { */ 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; + if (o === void 0) return n; do n.push(o), o = o.next; while (o !== l.next); @@ -210,981 +212,1097 @@ class he { let e = t, n = t; do { if (e != t && e === n) - throw w.INFINITE_LOOP; + throw T.INFINITE_LOOP; e = e.next, n = n.next.next; } while (e != t); } } -function Et(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 = ue; - ot(l, 0) && (o |= Gt), ot(l, r.shape.length) && (o |= mt); - let a; - l === 1 / 0 ? a = s[0].coord(t) : a = o & mt && 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 - }); +const ve = { + stroke: "black" +}; +class Dn { + constructor(t = ve) { + for (const e in t) + this[e] = t[e]; + this.stroke = t.stroke ?? ve.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 Nt(r) { - r.int_points1_sorted = et(r.int_points1), r.int_points2_sorted = et(r.int_points2); +function lt(r) { + return new Dn(r).toAttributesString(); } -function et(r) { - let t = /* @__PURE__ */ 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(Cn); +function St(r, t) { + let e = [], [n, s, l] = r.standard, [o, a, f] = t.standard, h = n * a - s * o, u = l * a - s * f, g = n * f - l * o; + if (!i.Utils.EQ_0(h)) { + let _, S; + s === 0 ? (_ = l / n, S = g / h) : a === 0 ? (_ = f / o, S = g / h) : n === 0 ? (_ = u / h, S = l / s) : o === 0 ? (_ = u / h, S = f / a) : (_ = u / h, S = g / h), e.push(new i.Point(_, S)); + } + return e; } -function Cn(r, t) { - return r.faceId < t.faceId ? -1 : r.faceId > t.faceId ? 1 : r.arc_length < t.arc_length ? -1 : r.arc_length > t.arc_length ? 1 : 0; +function at(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 ce(r) { - if (r.int_points1.length < 2) - return; - let t = !1, e, n, s, l; - for (let o = 0; o < r.int_points1_sorted.length; o++) - if (r.int_points1_sorted[o].id !== -1) { - e = r.int_points1_sorted[o], n = r.int_points2[e.id]; - for (let a = o + 1; a < r.int_points1_sorted.length && (s = r.int_points1_sorted[a], !!ot(s.arc_length, e.arc_length)); a++) - s.id !== -1 && (l = r.int_points2[s.id], l.id !== -1 && s.edge_before === e.edge_before && s.edge_after === e.edge_after && l.edge_before === n.edge_before && l.edge_after === n.edge_after && (s.id = -1, l.id = -1, t = !0)); - } - n = r.int_points2_sorted[0], e = r.int_points1[n.id]; - for (let o = 1; o < r.int_points2_sorted.length; o++) { - let a = r.int_points2_sorted[o]; - if (a.id === -1) - continue; - if (n.id === -1 || /* can't be reference if already deleted */ - !ot(a.arc_length, n.arc_length)) { - n = a, e = r.int_points1[n.id]; - continue; - } - let h = r.int_points1[a.id]; - h.edge_before === e.edge_before && h.edge_after === e.edge_after && a.edge_before === n.edge_before && a.edge_after === n.edge_after && (h.id = -1, a.id = -1, t = !0); +function xt(r, t) { + let e = []; + for (let n of t.toSegments()) { + let s = kt(n, r); + for (let l of s) + en(l, e) || e.push(l); } - t && (r.int_points1 = r.int_points1.filter((o) => o.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)); + return e; } -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 = z), t.edge_after && (t.edge_after.bvStart = z); +function Qt(r, t) { + let e = []; + if (xt(r, t.box).length === 0) + return e; + let n = new i.Circle(t.pc, t.r), s = at(r, n); + for (let l of s) + l.on(t) && e.push(l); + return e; } -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 kt(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 St(n, t); } -function Nn(r) { - let t, e, n, s = r.int_points1.length; - for (let l = 0; l < s; l++) { - let o = r.int_points1_sorted[l]; - o.face !== t && (e = l, t = o.face); - let a = l, h = vt(r.int_points1_sorted, l, t), u; - 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 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, p = n.edge_before; - if (!(g.bv === z && p.bv === z) || g !== p) - continue; - 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 jt(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 = St(n, s); + l.length > 0 && ye(l[0], r) && ye(l[0], t) && e.push(l[0]); } + return e; } -function vt(r, t, e) { - let n, s, l = 1; - if (r.length === 1) - return 1; - n = r[t]; - for (let o = t + 1; o < r.length && !(n.face !== e || (s = r[o], !(s.pt.equalTo(n.pt) && s.edge_before === n.edge_before && s.edge_after === n.edge_after))); o++) - l++; - return l; +function ye(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) { - if (t) { - for (let e of t) { - let n = e.edge_before; - if (e.is_vertex = ue, n.shape.start && n.shape.start.equalTo(e.pt) && (e.is_vertex |= Gt), n.shape.end && n.shape.end.equalTo(e.pt) && (e.is_vertex |= mt), e.is_vertex & Gt) { - n.prev ? (e.edge_before = n.prev, e.is_vertex = mt) : (e.edge_after = e.edge_before, e.edge_before = n.prev); - continue; - } - if (e.is_vertex & mt) - continue; - let s = r.addVertex(e.pt, n); - e.edge_before = s; - } - for (let e of t) - e.edge_before && (e.edge_after = e.edge_before.next); +function Zt(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 = at(n, t); + for (let l of s) + l.on(r) && e.push(l); + return e; } -function ve(r, t, e) { - const n = r.edge_before, s = t.edge_after, l = e.length; - n.next = e[0], e[0].prev = n, e[l - 1].next = s, s.prev = e[l - 1]; +function vt(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 = at(n, s); + for (let o of l) + o.on(r) && o.on(t) && e.push(o); + return e; } -const { INSIDE: Q, OUTSIDE: W, BOUNDARY: b, OVERLAP_SAME: Rn, OVERLAP_OPPOSITE: Un } = Dt, { NOT_VERTEX: Qi, START_VERTEX: we, END_VERTEX: Te } = Dt, Wt = 1, Ut = 2, lt = 3; -function Mn(r, t) { - let [e, n] = Mt(r, t, Wt, !0); +function Wn(r, t) { + let e = []; + for (let n of t.toSegments()) { + let s = jt(n, r); + for (let l of s) + e.push(l); + } return e; } -function re(r, t) { - let n = t.clone().reverse(), [s, l] = Mt(r, n, lt, !0); - return s; +function Ye(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 f = s * s / (2 * o) - l * l / (2 * o) + o / 2, h = r.pc.translate(f * n.x, f * n.y), u = Math.sqrt(s * s - f * f); + return a = h.translate(n.rotate90CCW().multiply(u)), e.push(a), a = h.translate(n.rotate90CW().multiply(u)), e.push(a), e; } -function Ge(r, t) { - let [e, n] = Mt(r, t, Ut, !0); +function zn(r, t) { + let e = []; + for (let n of t.toSegments()) { + let s = Zt(n, r); + for (let l of s) + e.push(l); + } return e; } -function De(r, t) { - let [e, n] = Mt(r, t, Ut, !1), s = []; - for (let o of e.faces) - s = [...s, ...[...o.edges].map((a) => a.shape)]; - let l = []; - for (let o of n.faces) - l = [...l, ...[...o.edges].map((a) => a.shape)]; - return [s, l]; +function Qe(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 se(r, t) { - let [e, n] = Mt(r, t, lt, !1), s = []; - for (let l of e.faces) - s = [...s, ...[...l.edges].map((o) => o.shape)]; - return s; +function ge(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 = Ye(n, s); + for (let o of l) + o.on(r) && e.push(o); + return e; } -function ze(r, t) { - let e = r.clone(), n = t.clone(), s = Qe(e, n); - Nt(s), wt(e, s.int_points1_sorted), wt(n, s.int_points2_sorted), ce(s), Nt(s); - let l = s.int_points1_sorted.map((a) => a.pt), o = s.int_points2_sorted.map((a) => a.pt); - return [l, o]; +function Yn(r, t) { + let e = []; + for (let n of t.toSegments()) { + let s = vt(n, r); + for (let l of s) + e.push(l); + } + return e; } -function Bn(r, t, e, n) { - let s = Se(r, e.int_points1), l = Se(t, e.int_points2); - for (Ie(s, t), Ie(l, r), ne(e.int_points1), ne(e.int_points2), ie(e.int_points1, t), ie(e.int_points2, r); Fn(r, t, e.int_points1, e.int_points1_sorted, e.int_points2, e); ) - ; - Nn(e), oe(r, n, e.int_points1_sorted, !0), oe(t, n, e.int_points2_sorted, !1), ye(r, s, n, !0), ye(t, l, n, !1); +function je(r, t) { + return r.isSegment ? jt(r.shape, t) : vt(t, r.shape); } -function kn(r, t, e, n) { - Vn(r, t, n, e.int_points2), Hn(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 Ze(r, t) { + return r.isSegment ? vt(r.shape, t) : Qe(r.shape, t); } -function Mt(r, t, e, n) { - let s = r.clone(), l = t.clone(), o = Qe(s, l); - return Nt(o), wt(s, o.int_points1_sorted), wt(l, o.int_points2_sorted), ce(o), Nt(o), Bn(s, l, o, e), n && kn(s, l, o, e), [s, l]; +function Xe(r, t) { + return r.isSegment ? kt(r.shape, t) : Qt(t, r.shape); } -function Qe(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) - Et(n, a, e.int_points1), Et(l, a, e.int_points2); - } - } - return e; +function Qn(r, t) { + return r.isSegment ? me(t, r.shape) : Ee(t, r.shape); } -function Se(r, t) { +function jn(r, t) { + return r.isSegment ? Zt(r.shape, t) : ge(r.shape, t); +} +function pe(r, t) { let e = []; - for (let n of r.faces) - t.find((s) => s.face === n) || e.push(n); + for (let n of t.edges) + for (let s of je(n, r)) + e.push(s); return e; } -function Ie(r, t) { - for (let e of r) - e.first.bv = e.first.bvStart = e.first.bvEnd = void 0, e.first.setInclusion(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 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 _ = v; _ < v + I; _++) { - let L = n[_]; - if (L.face === o && s[L.id].face === s[p.id].face) { - h = L; - break; - } - } - if (h === null) - continue; - let x = p.edge_after, E = h.edge_before; - if (x.bv === b && E.bv != b) { - x.bv = E.bv; - continue; - } - if (x.bv != b && E.bv === b) { - E.bv = x.bv; - continue; - } - 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 (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 w.UNRESOLVED_BOUNDARY_CONFLICT; - } - _ = _.next; - } - L != null && (x.bv = L, E.bv = L); - continue; - } - 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); - let X = e[e.length - 1]; - if (X.is_vertex & we) - X.edge_after = _, X.edge_before = _.prev, _.bvStart = b, _.bv = void 0, _.setInclusion(t); - else if (X.is_vertex & Te) - X.edge_after = _.next, _.bvEnd = b, _.bv = void 0, _.setInclusion(t); - else { - let U = t.addVertex(X.pt, _); - X.edge_before = U, X.edge_after = U.next, U.setInclusion(t), U.next.bvStart = b, U.next.bvEnd = void 0, U.next.bv = void 0, U.next.setInclusion(t); - } - let ut = t.findEdgeByPoint(Xt.pe); - Et(ut, Xt.pe, s); - let K = s[s.length - 1]; - if (K.is_vertex & we) - K.edge_after = ut, K.edge_before = ut.prev; - else if (K.is_vertex & Te) - K.edge_after = ut.next; - else { - let U = s.find((_n) => _n.edge_after === ut), O = t.addVertex(K.pt, ut); - K.edge_before = O, K.edge_after = O.next, U && (U.edge_after = O), O.bvStart = void 0, O.bvEnd = b, O.bv = void 0, O.setInclusion(r), O.next.bvStart = b, O.next.bvEnd = void 0, O.next.bv = void 0, O.next.setInclusion(r); - } - Nt(l), f = !0; - break; - } - } - _ = _.next; - } - if (f) - break; - throw w.UNRESOLVED_BOUNDARY_CONFLICT; - } - } - return f; +function _e(r, t) { + let e = []; + for (let n of t.edges) + for (let s of Ze(n, r)) + e.push(s); + return e; } -function oe(r, t, e, n) { - if (!e) - return; - let s, l, o, a; - for (let h = 0; h < e.length; h++) { - if (o = e[h], o.face !== s && (l = h, s = o.face), s.isEmpty()) - 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 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; - } +function Ft(r, t) { + let e = []; + if (t.isEmpty()) + return e; + for (let n of t.edges) + for (let s of Xe(n, r)) + en(s, e) || e.push(s); + return r.sortPoints(e); } -function Vn(r, t, e, n) { - for (let s of t.faces) { - for (let l of s) - r.edges.add(l); - /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/ - n.find((l) => l.face === s) === void 0 && r.addFace(s.first, s.last); - } +function Ke(r, t) { + let e = []; + if (t.isEmpty()) + return e; + for (let n of t.edges) + for (let s of jn(n, r)) + e.push(s); + return e; } -function Hn(r, t, e) { - if (e.int_points1.length !== 0) - for (let n = 0; n < e.int_points1.length; n++) { - let s = e.int_points1[n], l = e.int_points2[n]; - if (s.edge_before !== void 0 && s.edge_after === void 0 && l.edge_before === void 0 && l.edge_after !== void 0 && (s.edge_before.next = l.edge_after, l.edge_after.prev = s.edge_before, s.edge_after = l.edge_after, l.edge_before = s.edge_before), l.edge_before !== void 0 && l.edge_after === void 0 && s.edge_before === void 0 && s.edge_after !== void 0 && (l.edge_before.next = s.edge_after, s.edge_after.prev = l.edge_before, l.edge_after = s.edge_after, s.edge_before = l.edge_before), s.edge_before !== void 0 && s.edge_after === void 0) - for (let o of e.int_points1_sorted) - o !== s && o.edge_before === void 0 && o.edge_after !== void 0 && o.pt.equalTo(s.pt) && (s.edge_before.next = o.edge_after, o.edge_after.prev = s.edge_before, s.edge_after = o.edge_after, o.edge_before = s.edge_before); - if (l.edge_before !== void 0 && l.edge_after === void 0) - for (let o of e.int_points2_sorted) - o !== l && o.edge_before === void 0 && o.edge_after !== void 0 && o.pt.equalTo(l.pt) && (l.edge_before.next = o.edge_after, o.edge_after.prev = l.edge_before, l.edge_after = o.edge_after, o.edge_before = l.edge_before); - } +function Je(r, t) { + return r.isSegment ? je(t, r.shape) : r.isArc ? Ze(t, r.shape) : r.isLine ? Xe(t, r.shape) : r.isRay ? Qn(t, r.shape) : []; } -function le(r, t) { - for (let e of t) - r.faces.delete(e.face), e.face = void 0, e.edge_before && (e.edge_before.face = void 0), e.edge_after && (e.edge_after.face = void 0); +function tn(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, ...Je(r, s)]; + return e; } -function ae(r, t, e) { - for (let n of t) { - if (n.edge_before === void 0 || n.edge_after === void 0 || n.face || n.edge_after.face || n.edge_before.face) - continue; - let s = n.edge_after, l = n.edge_before; - try { - he.testInfiniteLoop(s); - } catch { - throw w.CANNOT_COMPLETE_BOOLEAN_OPERATION; - } - let o = r.addFace(s, l); - for (let a of t) - a.edge_before && a.edge_after && a.edge_before.face === o && a.edge_after.face === o && (a.face = o); - for (let a of e) - a.edge_before && a.edge_after && a.edge_before.face === o && a.edge_after.face === o && (a.face = o); - } +function Zn(r, t) { + let e = []; + if (t.isEmpty() || r.size === 0) + return e; + for (let n of r) + e = [...e, ...tn(n, t)]; + return e; } -function ye(r, t, e, n) { - for (let s of t) { - let l = s.first.bv; - (e === Wt && l === Q || e === lt && l === Q && n || e === lt && l === W && !n || e === Ut && l === W) && r.deleteFace(s); - } +function Xn(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, ...tn(n, t)]; + return e; } -var $n = /* @__PURE__ */ Object.freeze({ - __proto__: null, - BOOLEAN_INTERSECT: Ut, - BOOLEAN_SUBTRACT: lt, - BOOLEAN_UNION: Wt, - calculateIntersections: ze, - innerClip: De, - intersect: Ge, - outerClip: se, - removeNotRelevantChains: oe, - removeOldFaces: le, - restoreFaces: ae, - subtract: re, - unify: Mn -}); -const qn = RegExp("T.F..FFF.|T.F...F.."), Gn = RegExp("T........|.T.......|...T.....|....T...."), Dn = RegExp("FT.......|F..T.....|F...T...."), zn = RegExp("T.F..F..."), Qn = RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."); -class St { - /** - * Create new instance of DE9IM matrix - */ - constructor() { - this.m = new Array(9).fill(void 0); +function Kn(r, t) { + return r instanceof i.Line ? Ft(r, t) : r instanceof i.Segment ? pe(r, t) : r instanceof i.Arc ? _e(r, t) : []; +} +function en(r, t) { + return t.some((e) => e.equalTo(r)); +} +function nt(r) { + return new i.Line(r.start, r.norm); +} +function me(r, t) { + return kt(t, nt(r)).filter((e) => r.contains(e)); +} +function Ee(r, t) { + return Qt(nt(r), t).filter((e) => r.contains(e)); +} +function nn(r, t) { + return at(nt(r), t).filter((e) => r.contains(e)); +} +function Jn(r, t) { + return xt(nt(r), t).filter((e) => r.contains(e)); +} +function rn(r, t) { + return St(nt(r), t).filter((e) => r.contains(e)); +} +function ti(r, t) { + return St(nt(r), nt(t)).filter((e) => r.contains(e)).filter((e) => t.contains(e)); +} +function sn(r, t) { + return Ft(nt(r), t).filter((e) => r.contains(e)); +} +function on(r, t) { + if (r.intersect && r.intersect instanceof Function) + return r.intersect(t); + throw T.UNSUPPORTED_SHAPE_TYPE; +} +function Bt(r, t) { + let e = []; + for (let n of t) + e = [...e, ...on(n, n.shape)]; + return e; +} +function ei(r, t) { + let e = []; + for (let n of r) + for (let s of t) + e = [...e, ...on(n, s)]; + return e; +} +let ft = class At extends de { + constructor(...t) { + if (super(), this.isInfinite = !1, t.length === 1 && t[0] instanceof Array && t[0].length > 0) { + let e = !1; + const n = t[0], s = n.length, l = (f) => f instanceof i.Segment || f instanceof i.Arc || f instanceof i.Ray || f instanceof i.Line, o = (f) => f instanceof i.Segment || f instanceof i.Arc || f instanceof i.Ray, a = (f) => f instanceof i.Segment || f instanceof i.Arc; + if (e = s === 1 && l(n[0]) || s > 1 && o(n[0]) && o(n[s - 1]) && n.slice(1, s - 1).every(a), e) { + this.isInfinite = n.some( + (f) => f instanceof i.Ray || f instanceof i.Line + ); + for (let f of n) { + let h = new i.Edge(f); + this.append(h); + } + this.setArcLength(); + } else + throw i.Errors.ILLEGAL_PARAMETERS; + } } /** - * Get Interior To Interior intersection - * @returns {Shape[] | undefined} + * (Getter) Return array of edges + * @returns {Edge[]} */ - get I2I() { - return this.m[0]; + get edges() { + return [...this]; } /** - * Set Interior To Interior intersection - * @param geom + * (Getter) Return bounding box of the multiline + * @returns {Box} */ - set I2I(t) { - this.m[0] = t; + get box() { + return this.edges.reduce((t, e) => t.merge(e.box), new i.Box()); } /** - * Get Interior To Boundary intersection - * @returns {Shape[] | undefined} + * (Getter) Returns array of vertices + * @returns {Point[]} */ - get I2B() { - return this.m[1]; + get vertices() { + let t = this.edges.map((e) => e.start); + return t.push(this.last.end), t; } /** - * Set Interior to Boundary intersection - * @param geomc + * (Getter) Returns length of the multiline, return POSITIVE_INFINITY if multiline is infinite + * @returns {number} */ - set I2B(t) { - this.m[1] = t; + get length() { + if (this.isEmpty()) return 0; + if (this.isInfinite) return Number.POSITIVE_INFINITY; + let t = 0; + for (let e of this) + t += e.length; + return t; } /** - * Get Interior To Exterior intersection - * @returns {Shape[] | undefined} + * Return new cloned instance of Multiline + * @returns {Multiline} */ - get I2E() { - return this.m[2]; + clone() { + return new At(this.toShapes()); } /** - * Set Interior to Exterior intersection - * @param geom + * Set arc_length property for each of the edges in the multiline. + * Arc_length of the edge is the arc length from the multiline start vertex to the edge start vertex */ - set I2E(t) { - this.m[2] = t; + setArcLength() { + for (let t of this) + this.setOneEdgeArcLength(t); } - /** - * Get Boundary To Interior intersection - * @returns {Shape[] | undefined} - */ - get B2I() { - return this.m[3]; + setOneEdgeArcLength(t) { + t === this.first ? t.arc_length = 0 : t.arc_length = t.prev.arc_length + t.prev.length; } /** - * Set Boundary to Interior intersection - * @param geom + * Return point on multiline at given length from the start of the multiline + * @param length + * @returns {Point | null} */ - set B2I(t) { - this.m[3] = t; + pointAtLength(t) { + if (t > this.length || t < 0 || this.isInfinite) return null; + let e = null; + for (let n of this) + if (t >= n.arc_length && (n === this.last || t < n.next.arc_length)) { + e = n.pointAtLength(t - n.arc_length); + break; + } + return e; } /** - * Get Boundary To Boundary intersection - * @returns {Shape[] | undefined} + * Split edge and add new vertex, return new edge inserted + * @param {Point} pt - point on edge that will be added as new vertex + * @param {Edge} edge - edge to split + * @returns {Edge} */ - get B2B() { - return this.m[4]; + 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; } - /** - * Set Boundary to Boundary intersection - * @param geom - */ - set B2B(t) { - this.m[4] = t; + getChain(t, e) { + let n = []; + for (let s = t; s !== e.next; s = s.next) + n.push(s); + return n; } /** - * Get Boundary To Exterior intersection - * @returns {Shape[] | undefined} + * Split edges of multiline with intersection points and return mutated multiline + * @param {Point[]} ip - array of points to be added as new vertices + * @returns {Multiline} */ - get B2E() { - return this.m[5]; + split(t) { + for (let e of t) { + let n = this.findEdgeByPoint(e); + this.addVertex(e, n); + } + return this; } /** - * Set Boundary to Exterior intersection - * @param geom + * Returns edge which contains given point + * @param {Point} pt + * @returns {Edge} */ - set B2E(t) { - this.m[5] = t; + findEdgeByPoint(t) { + let e; + for (let n of this) + if (n.shape.contains(t)) { + e = n; + break; + } + return e; } /** - * Get Exterior To Interior intersection - * @returns {Shape[] | undefined} + * Calculate distance and shortest segment from any shape to multiline + * @param shape + * @returns {[number,Flatten.Segment]} */ - get E2I() { - return this.m[6]; + distanceTo(t) { + if (t instanceof Point) { + const [e, n] = i.Distance.shape2multiline(t, this); + return [e, n.reverse()]; + } + if (t instanceof i.Line) { + const [e, n] = i.Distance.shape2multiline(t, this); + return [e, n.reverse()]; + } + if (t instanceof i.Circle) { + const [e, n] = i.Distance.shape2multiline(t, this); + return [e, n.reverse()]; + } + if (t instanceof i.Segment) { + const [e, n] = i.Distance.shape2multiline(t, this); + return [e, n.reverse()]; + } + if (t instanceof i.Arc) { + const [e, n] = i.Distance.shape2multiline(t, this); + return [e, n.reverse()]; + } + if (t instanceof i.Multiline) + return i.Distance.multiline2multiline(this, t); + throw i.Errors.UNSUPPORTED_SHAPE_TYPE; } /** - * Set Exterior to Interior intersection - * @param geom + * Calculate intersection of multiline with other shape + * @param {Shape} shape + * @returns {Point[]} */ - set E2I(t) { - this.m[6] = t; + intersect(t) { + return t instanceof i.Multiline ? ei(this, t) : Bt(t, this); } /** - * Get Exterior To Boundary intersection - * @returns {Shape[] | undefined} + * Return true if multiline contains the shape: no point of shape lies outside + * @param shape + * @returns {boolean} */ - get E2B() { - return this.m[7]; + contains(t) { + if (t instanceof i.Point) + return this.edges.some((e) => e.shape.contains(t)); + throw i.Errors.UNSUPPORTED_SHAPE_TYPE; } /** - * Set Exterior to Boundary intersection - * @param geom + * Returns new multiline translated by vector vec + * @param {Vector} vec + * @returns {Multiline} */ - set E2B(t) { - this.m[7] = t; + translate(t) { + return new At(this.edges.map((e) => e.shape.translate(t))); } /** - * Get Exterior to Exterior intersection - * @returns {Shape[] | undefined} + * Return new multiline rotated by given angle around given point + * If point omitted, rotate around origin (0,0) + * Positive value of angle defines rotation counterclockwise, negative - clockwise + * @param {number} angle - rotation angle in radians + * @param {Point} center - rotation center, default is (0,0) + * @returns {Multiline} - new rotated polygon */ - get E2E() { - return this.m[8]; + rotate(t = 0, e = new i.Point()) { + return new At(this.edges.map((n) => n.shape.rotate(t, e))); } /** - * Set Exterior to Exterior intersection - * @param geom + * Return new multiline transformed using affine transformation matrix + * Method does not support unbounded shapes + * @param {Matrix} matrix - affine transformation matrix + * @returns {Multiline} - new multiline */ - set E2E(t) { - this.m[8] = t; + transform(t = new i.Matrix()) { + return new At(this.edges.map((e) => e.shape.transform(t))); } /** - * Return de9im matrix as string where
- * - intersection is 'T'
- * - not intersected is 'F'
- * - not relevant is '*'
- * For example, string 'FF**FF****' means 'DISJOINT' - * @returns {string} + * Transform multiline into array of shapes + * @returns {Shape[]} */ - toString() { - return this.m.map((t) => t instanceof Array && t.length > 0 ? "T" : t instanceof Array && t.length === 0 ? "F" : "*").join(""); - } - equal() { - return qn.test(this.toString()); - } - intersect() { - return Gn.test(this.toString()); - } - touch() { - return Dn.test(this.toString()); - } - inside() { - return zn.test(this.toString()); - } - covered() { - return Qn.test(this.toString()); - } -} -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 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 at(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); + toShapes() { + return this.edges.map((t) => t.shape.clone()); } - return e; -} -function Tt(r, t) { - let e = []; - for (let n of t.toSegments()) { - let s = Bt(n, r); - for (let l of s) - tn(l, e) || e.push(l); + /** + * This method returns an object that defines how data will be + * serialized when called JSON.stringify() method + * @returns {Object} + */ + toJSON() { + return this.edges.map((t) => t.toJSON()); } - return e; -} -function Yt(r, t) { - let e = []; - if (Tt(r, t.box).length === 0) - return e; - let n = new i.Circle(t.pc, t.r), s = at(r, n); - for (let l of s) - l.on(t) && e.push(l); - return e; -} -function Bt(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 It(n, t); -} -function jt(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 = It(n, s); - l.length > 0 && be(l[0], r) && be(l[0], t) && e.push(l[0]); + /** + * Return string to be inserted into 'points' attribute of element + * @returns {string} + */ + svgPoints() { + return this.vertices.map((t) => `${t.x},${t.y}`).join(" "); } - return e; -} -function be(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 Zt(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; + /** + * Return string to be assigned to 'd' attribute of element + * @returns {*} + */ + dpath() { + let t = `M${this.first.start.x},${this.first.start.y}`; + for (let e of this) + t += e.svg(); + return t; } - let n = new i.Line(r.ps, r.pe), s = at(n, t); - for (let l of s) - l.on(r) && e.push(l); - return e; -} -function yt(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 = at(n, s); - for (let o of l) - o.on(r) && o.on(t) && e.push(o); - return e; -} -function Wn(r, t) { - let e = []; - for (let n of t.toSegments()) { - let s = jt(n, r); - for (let l of s) - e.push(l); + /** + * Return string to draw multiline in svg + * @param attrs - an object with attributes for svg path element + * TODO: support semi-infinite Ray and infinite Line + * @returns {string} + */ + svg(t = {}) { + let e = ` + +`, e; } - return e; -} -function We(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; +}; +i.Multiline = ft; +const ni = (...r) => new i.Multiline(...r); +i.multiline = ni; +function Tt(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 = ce; + st(l, 0) && (o |= bt), st(l, r.shape.length) && (o |= mt); 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; + l === 1 / 0 ? a = s[0].coord(t) : a = o & mt && 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 Yn(r, t) { - let e = []; - for (let n of t.toSegments()) { - let s = Zt(n, r); - for (let l of s) - e.push(l); - } - return e; +function Ut(r) { + r.int_points1_sorted = tt(r.int_points1), r.int_points2_sorted = tt(r.int_points2); } -function Ye(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 tt(r) { + let t = /* @__PURE__ */ 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(ii); } -function de(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 = We(n, s); - for (let o of l) - o.on(r) && e.push(o); - return e; +function ii(r, t) { + return r.faceId < t.faceId ? -1 : r.faceId > t.faceId ? 1 : r.arc_length < t.arc_length ? -1 : r.arc_length > t.arc_length ? 1 : 0; } -function jn(r, t) { - let e = []; - for (let n of t.toSegments()) { - let s = yt(n, r); - for (let l of s) - e.push(l); +function xe(r) { + if (r.int_points1.length < 2) return; + let t = !1, e, n, s, l; + for (let o = 0; o < r.int_points1_sorted.length; o++) + if (r.int_points1_sorted[o].id !== -1) { + e = r.int_points1_sorted[o], n = r.int_points2[e.id]; + for (let a = o + 1; a < r.int_points1_sorted.length && (s = r.int_points1_sorted[a], !!st(s.arc_length, e.arc_length)); a++) + s.id !== -1 && (l = r.int_points2[s.id], l.id !== -1 && s.edge_before === e.edge_before && s.edge_after === e.edge_after && l.edge_before === n.edge_before && l.edge_after === n.edge_after && (s.id = -1, l.id = -1, t = !0)); + } + n = r.int_points2_sorted[0], e = r.int_points1[n.id]; + for (let o = 1; o < r.int_points2_sorted.length; o++) { + let a = r.int_points2_sorted[o]; + if (a.id === -1) continue; + if (n.id === -1 || /* can't be reference if already deleted */ + !st(a.arc_length, n.arc_length)) { + n = a, e = r.int_points1[n.id]; + continue; + } + let f = r.int_points1[a.id]; + f.edge_before === e.edge_before && f.edge_after === e.edge_after && a.edge_before === n.edge_before && a.edge_after === n.edge_after && (f.id = -1, a.id = -1, t = !0); } - return e; -} -function je(r, t) { - return r.isSegment ? jt(r.shape, t) : yt(t, r.shape); + t && (r.int_points1 = r.int_points1.filter((o) => o.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 Ze(r, t) { - return r.isSegment ? yt(r.shape, t) : Ye(r.shape, t); +function ie(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 = D), t.edge_after && (t.edge_after.bvStart = D); } -function Xe(r, t) { - return r.isSegment ? Bt(r.shape, t) : Yt(t, r.shape); +function re(r, t) { + for (let e of r) + e.edge_before && e.edge_before.setInclusion(t), e.edge_after && e.edge_after.setInclusion(t); } -function Zn(r, t) { - return r.isSegment ? pe(t, r.shape) : me(t, r.shape); +function ri(r) { + let t, e, n, s = r.int_points1.length; + for (let l = 0; l < s; l++) { + let o = r.int_points1_sorted[l]; + o.face !== t && (e = l, t = o.face); + let a = l, f = wt(r.int_points1_sorted, l, t), h; + a + f < s && r.int_points1_sorted[a + f].face === t ? h = a + f : h = e; + let u = wt(r.int_points1_sorted, h, t); + n = null; + for (let E = h; E < h + u; E++) { + let x = r.int_points1_sorted[E]; + if (x.face === t && r.int_points2[x.id].face === r.int_points2[o.id].face) { + n = x; + break; + } + } + if (n === null) + continue; + let g = o.edge_after, _ = n.edge_before; + if (!(g.bv === D && _.bv === D) || g !== _) + continue; + let S = r.int_points2[o.id], I = r.int_points2[n.id], w = S.edge_after, v = I.edge_before; + w.bv === D && v.bv === D && w === v || (S = r.int_points2[n.id], I = r.int_points2[o.id], w = S.edge_after, v = I.edge_before), w.bv === D && v.bv === D && w === v && g.setOverlap(w); + } } -function Xn(r, t) { - return r.isSegment ? Zt(r.shape, t) : de(r.shape, t); +function wt(r, t, e) { + let n, s, l = 1; + if (r.length === 1) return 1; + n = r[t]; + for (let o = t + 1; o < r.length && !(n.face !== e || (s = r[o], !(s.pt.equalTo(n.pt) && s.edge_before === n.edge_before && s.edge_after === n.edge_after))); o++) + l++; + return l; } -function ge(r, t) { - let e = []; - for (let n of t.edges) - for (let s of je(n, r)) - e.push(s); - return e; +function It(r, t) { + if (t) { + for (let e of t) { + let n = e.edge_before; + if (e.is_vertex = ce, n.shape.start && n.shape.start.equalTo(e.pt) && (e.is_vertex |= bt), n.shape.end && n.shape.end.equalTo(e.pt) && (e.is_vertex |= mt), e.is_vertex & bt) { + e.edge_before = n.prev, n.prev && (e.is_vertex = mt); + continue; + } + if (e.is_vertex & mt) + continue; + let s = r.addVertex(e.pt, n); + e.edge_before = s; + } + for (let e of t) + e.edge_before ? e.edge_after = e.edge_before.next : r instanceof ft && e.is_vertex & bt && (e.edge_after = r.first); + } } -function _e(r, t) { - let e = []; - for (let n of t.edges) - for (let s of Ze(n, r)) - e.push(s); +function Pe(r, t, e) { + const n = r.edge_before, s = t.edge_after, l = e.length; + n.next = e[0], e[0].prev = n, e[l - 1].next = s, s.prev = e[l - 1]; +} +const { INSIDE: W, OUTSIDE: z, BOUNDARY: P, OVERLAP_SAME: si, OVERLAP_OPPOSITE: oi } = zt, { NOT_VERTEX: _r, START_VERTEX: Le, END_VERTEX: Ae } = zt, Xt = 1, Vt = 2, ot = 3; +function li(r, t) { + let [e, n] = $t(r, t, Xt, !0); return e; } -function kt(r, t) { - let e = []; - if (t.isEmpty()) - return e; - for (let n of t.edges) - for (let s of Xe(n, r)) - tn(s, e) || e.push(s); - return r.sortPoints(e); +function se(r, t) { + let n = t.clone().reverse(), [s, l] = $t(r, n, ot, !0); + return s; } -function Ke(r, t) { - let e = []; - if (t.isEmpty()) - return e; - for (let n of t.edges) - for (let s of Xn(n, r)) - e.push(s); +function ln(r, t) { + let [e, n] = $t(r, t, Vt, !0); return e; } -function Je(r, t) { - return r.isSegment ? je(t, r.shape) : r.isArc ? Ze(t, r.shape) : r.isLine ? Xe(t, r.shape) : r.isRay ? Zn(t, r.shape) : []; +function an(r, t) { + let [e, n] = $t(r, t, Vt, !1), s = []; + for (let o of e.faces) + s = [...s, ...[...o.edges].map((a) => a.shape)]; + let l = []; + for (let o of n.faces) + l = [...l, ...[...o.edges].map((a) => a.shape)]; + return [s, l]; } -function Kn(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, ...Je(r, s)]; - return e; +function oe(r, t) { + let [e, n] = $t(r, t, ot, !1), s = []; + for (let l of e.faces) + s = [...s, ...[...l.edges].map((o) => o.shape)]; + return s; } -function Jn(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, ...Kn(n, t)]; - return e; +function fn(r, t) { + let e = r.clone(), n = t.clone(), s = un(e, n); + Ut(s), It(e, s.int_points1_sorted), It(n, s.int_points2_sorted), xe(s), Ut(s); + let l = s.int_points1_sorted.map((a) => a.pt), o = s.int_points2_sorted.map((a) => a.pt); + return [l, o]; } -function ti(r, t) { - return r instanceof i.Line ? kt(r, t) : r instanceof i.Segment ? ge(r, t) : r instanceof i.Arc ? _e(r, t) : []; +function ai(r, t, e, n) { + let s = be(r, e.int_points1), l = be(t, e.int_points2); + for (Oe(s, t), Oe(l, r), ie(e.int_points1), ie(e.int_points2), re(e.int_points1, t), re(e.int_points2, r); ui(r, t, e.int_points1, e.int_points1_sorted, e.int_points2, e); ) ; + ri(e), le(r, n, e.int_points1_sorted, !0), le(t, n, e.int_points2_sorted, !1), Ne(r, s, n, !0), Ne(t, l, n, !1); } -function tn(r, t) { - return t.some((e) => e.equalTo(r)); +function fi(r, t, e, n) { + hi(r, t, n, e.int_points2), ci(r, t, e), ae(r, e.int_points1), ae(t, e.int_points2), fe(r, e.int_points1, e.int_points2), fe(r, e.int_points2, e.int_points1); } -function it(r) { - return new i.Line(r.start, r.norm); +function $t(r, t, e, n) { + let s = r.clone(), l = t.clone(), o = un(s, l); + return Ut(o), It(s, o.int_points1_sorted), It(l, o.int_points2_sorted), xe(o), Ut(o), ai(s, l, o, e), n && fi(s, l, o, e), [s, l]; } -function pe(r, t) { - return Bt(t, it(r)).filter((e) => r.contains(e)); +function un(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) + Tt(n, a, e.int_points1), Tt(l, a, e.int_points2); + } + } + return e; } -function me(r, t) { - return Yt(it(r), t).filter((e) => r.contains(e)); +function be(r, t) { + let e = []; + for (let n of r.faces) + t.find((s) => s.face === n) || e.push(n); + return e; } -function en(r, t) { - return at(it(r), t).filter((e) => r.contains(e)); +function Oe(r, t) { + for (let e of r) + e.first.bv = e.first.bvStart = e.first.bvEnd = void 0, e.first.setInclusion(t); } -function ei(r, t) { - return Tt(it(r), t).filter((e) => r.contains(e)); +function ui(r, t, e, n, s, l) { + let o, a, f, h = n.length, u = !1; + for (let g = 0; g < h; g++) { + let _ = n[g]; + _.face !== o && (a = g, o = _.face); + let S = g, I = wt(n, g, o), w; + S + I < h && n[S + I].face === o ? w = S + I : w = a; + let v = wt(n, w, o); + f = null; + for (let p = w; p < w + v; p++) { + let b = n[p]; + if (b.face === o && s[b.id].face === s[_.id].face) { + f = b; + break; + } + } + if (f === null) + continue; + let E = _.edge_after, x = f.edge_before; + if (E.bv === P && x.bv != P) { + E.bv = x.bv; + continue; + } + if (E.bv != P && x.bv === P) { + x.bv = E.bv; + continue; + } + if (E.bv === P && x.bv === P && E != x || E.bv === W && x.bv === z || E.bv === z && x.bv === W) { + let p = E.next; + for (; p != x; ) + p.bvStart = void 0, p.bvEnd = void 0, p.bv = void 0, p.setInclusion(t), p = p.next; + } + if (E.bv === P && x.bv === P && E != x) { + let p = E.next, b; + for (; p != x; ) { + if (p.bv != P) { + if (b === void 0) + b = p.bv; + else if (p.bv != b) + throw T.UNRESOLVED_BOUNDARY_CONFLICT; + } + p = p.next; + } + b != null && (E.bv = b, x.bv = b); + continue; + } + if (E.bv === W && x.bv === z || E.bv === z && x.bv === W) { + let p = E; + for (; p != x; ) { + if (p.bvStart === E.bv && p.bvEnd === x.bv) { + let [b, Kt] = p.shape.distanceTo(t); + if (b < 10 * i.DP_TOL) { + Tt(p, Kt.ps, e); + let Z = e[e.length - 1]; + if (Z.is_vertex & Le) + Z.edge_after = p, Z.edge_before = p.prev, p.bvStart = P, p.bv = void 0, p.setInclusion(t); + else if (Z.is_vertex & Ae) + Z.edge_after = p.next, p.bvEnd = P, p.bv = void 0, p.setInclusion(t); + else { + let R = t.addVertex(Z.pt, p); + Z.edge_before = R, Z.edge_after = R.next, R.setInclusion(t), R.next.bvStart = P, R.next.bvEnd = void 0, R.next.bv = void 0, R.next.setInclusion(t); + } + let ut = t.findEdgeByPoint(Kt.pe); + Tt(ut, Kt.pe, s); + let X = s[s.length - 1]; + if (X.is_vertex & Le) + X.edge_after = ut, X.edge_before = ut.prev; + else if (X.is_vertex & Ae) + X.edge_after = ut.next; + else { + let R = s.find((An) => An.edge_after === ut), O = t.addVertex(X.pt, ut); + X.edge_before = O, X.edge_after = O.next, R && (R.edge_after = O), O.bvStart = void 0, O.bvEnd = P, O.bv = void 0, O.setInclusion(r), O.next.bvStart = P, O.next.bvEnd = void 0, O.next.bv = void 0, O.next.setInclusion(r); + } + Ut(l), u = !0; + break; + } + } + p = p.next; + } + if (u) + break; + throw T.UNRESOLVED_BOUNDARY_CONFLICT; + } + } + return u; } -function nn(r, t) { - return It(it(r), t).filter((e) => r.contains(e)); +function le(r, t, e, n) { + if (!e) return; + let s, l, o, a; + for (let f = 0; f < e.length; f++) { + if (o = e[f], o.face !== s && (l = f, s = o.face), s.isEmpty()) + continue; + let h = f, u = wt(e, f, s), g; + h + u < e.length && e[h + u].face === o.face ? g = h + u : g = l, a = e[g]; + let _ = g, S = wt(e, _, s), I = o.edge_after, w = a.edge_before; + if (I.bv === W && w.bv === W && t === Xt || I.bv === z && w.bv === z && t === Vt || (I.bv === z || w.bv === z) && t === ot && !n || (I.bv === W || w.bv === W) && t === ot && n || I.bv === P && w.bv === P && I.overlap & si && n || I.bv === P && w.bv === P && I.overlap & oi) { + r.removeChain(s, I, w); + for (let v = h; v < h + u; v++) + e[v].edge_after = void 0; + for (let v = _; v < _ + S; v++) + e[v].edge_before = void 0; + } + f += u - 1; + } } -function ni(r, t) { - return It(it(r), it(t)).filter((e) => r.contains(e)).filter((e) => t.contains(e)); +function hi(r, t, e, n) { + for (let s of t.faces) { + for (let l of s) + r.edges.add(l); + /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/ + n.find((l) => l.face === s) === void 0 && r.addFace(s.first, s.last); + } } -function rn(r, t) { - return kt(it(r), t).filter((e) => r.contains(e)); +function ci(r, t, e) { + if (e.int_points1.length !== 0) + for (let n = 0; n < e.int_points1.length; n++) { + let s = e.int_points1[n], l = e.int_points2[n]; + if (s.edge_before !== void 0 && s.edge_after === void 0 && l.edge_before === void 0 && l.edge_after !== void 0 && (s.edge_before.next = l.edge_after, l.edge_after.prev = s.edge_before, s.edge_after = l.edge_after, l.edge_before = s.edge_before), l.edge_before !== void 0 && l.edge_after === void 0 && s.edge_before === void 0 && s.edge_after !== void 0 && (l.edge_before.next = s.edge_after, s.edge_after.prev = l.edge_before, l.edge_after = s.edge_after, s.edge_before = l.edge_before), s.edge_before !== void 0 && s.edge_after === void 0) + for (let o of e.int_points1_sorted) + o !== s && o.edge_before === void 0 && o.edge_after !== void 0 && o.pt.equalTo(s.pt) && (s.edge_before.next = o.edge_after, o.edge_after.prev = s.edge_before, s.edge_after = o.edge_after, o.edge_before = s.edge_before); + if (l.edge_before !== void 0 && l.edge_after === void 0) + for (let o of e.int_points2_sorted) + o !== l && o.edge_before === void 0 && o.edge_after !== void 0 && o.pt.equalTo(l.pt) && (l.edge_before.next = o.edge_after, o.edge_after.prev = l.edge_before, l.edge_after = o.edge_after, o.edge_before = l.edge_before); + } } -const Ae = { - stroke: "black" -}; -class ii { - constructor(t = Ae) { - for (const e in t) - this[e] = t[e]; - this.stroke = t.stroke ?? Ae.stroke; +function ae(r, t) { + for (let e of t) + r.faces.delete(e.face), e.face = void 0, e.edge_before && (e.edge_before.face = void 0), e.edge_after && (e.edge_after.face = void 0); +} +function fe(r, t, e) { + for (let n of t) { + if (n.edge_before === void 0 || n.edge_after === void 0 || n.face || n.edge_after.face || n.edge_before.face) + continue; + let s = n.edge_after, l = n.edge_before; + try { + de.testInfiniteLoop(s); + } catch { + throw T.CANNOT_COMPLETE_BOOLEAN_OPERATION; + } + let o = r.addFace(s, l); + for (let a of t) + a.edge_before && a.edge_after && a.edge_before.face === o && a.edge_after.face === o && (a.face = o); + for (let a of e) + a.edge_before && a.edge_after && a.edge_before.face === o && a.edge_after.face === o && (a.face = o); } - toAttributesString() { - return Object.keys(this).reduce( - (t, e) => t + (this[e] !== void 0 ? this.toAttrString(e, this[e]) : ""), - "" - ); +} +function Ne(r, t, e, n) { + for (let s of t) { + let l = s.first.bv; + (e === Xt && l === W || e === ot && l === W && n || e === ot && l === z && !n || e === Vt && l === z) && r.deleteFace(s); } - toAttrString(t, e) { - const n = t === "className" ? "class" : this.convertCamelToKebabCase(t); - return e === null ? `${n} ` : `${n}="${e.toString()}" `; +} +var di = /* @__PURE__ */ Object.freeze({ + __proto__: null, + BOOLEAN_INTERSECT: Vt, + BOOLEAN_SUBTRACT: ot, + BOOLEAN_UNION: Xt, + calculateIntersections: fn, + innerClip: an, + intersect: ln, + outerClip: oe, + removeNotRelevantChains: le, + removeOldFaces: ae, + restoreFaces: fe, + subtract: se, + unify: li +}); +const gi = RegExp("T.F..FFF.|T.F...F.."), pi = RegExp("T........|.T.......|...T.....|....T...."), _i = RegExp("FT.......|F..T.....|F...T...."), mi = RegExp("T.F..F..."), Ei = RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."); +class yt { + /** + * Create new instance of DE9IM matrix + */ + constructor() { + this.m = new Array(9).fill(void 0); } - 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(); + /** + * Get Interior To Interior intersection + * @returns {Shape[] | undefined} + */ + get I2I() { + return this.m[0]; } -} -function ft(r) { - return new ii(r).toAttributesString(); -} -class R extends he { - 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(); - } + /** + * Set Interior To Interior intersection + * @param geom + */ + set I2I(t) { + this.m[0] = t; } /** - * (Getter) Return array of edges - * @returns {Edge[]} + * Get Interior To Boundary intersection + * @returns {Shape[] | undefined} */ - get edges() { - return [...this]; + get I2B() { + return this.m[1]; } /** - * (Getter) Return bounding box of the multiline - * @returns {Box} + * Set Interior to Boundary intersection + * @param geomc */ - get box() { - return this.edges.reduce((t, e) => t.merge(e.box), new i.Box()); + set I2B(t) { + this.m[1] = t; } /** - * (Getter) Returns array of vertices - * @returns {Point[]} + * Get Interior To Exterior intersection + * @returns {Shape[] | undefined} */ - get vertices() { - let t = this.edges.map((e) => e.start); - return t.push(this.last.end), t; + get I2E() { + return this.m[2]; } /** - * Return new cloned instance of Multiline - * @returns {Multiline} + * Set Interior to Exterior intersection + * @param geom */ - clone() { - return new R(this.toShapes()); + set I2E(t) { + this.m[2] = t; } /** - * Set arc_length property for each of the edges in the face. - * Arc_length of the edge it the arc length from the first edge of the face + * Get Boundary To Interior intersection + * @returns {Shape[] | undefined} */ - setArcLength() { - for (let t of this) - this.setOneEdgeArcLength(t); + get B2I() { + return this.m[3]; } - setOneEdgeArcLength(t) { - t === this.first ? t.arc_length = 0 : t.arc_length = t.prev.arc_length + t.prev.length; + /** + * Set Boundary to Interior intersection + * @param geom + */ + set B2I(t) { + this.m[3] = t; } /** - * Split edge and add new vertex, return new edge inserted - * @param {Point} pt - point on edge that will be added as new vertex - * @param {Edge} edge - edge to split - * @returns {Edge} + * Get Boundary To Boundary intersection + * @returns {Shape[] | undefined} */ - 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; + get B2B() { + return this.m[4]; } - getChain(t, e) { - let n = []; - for (let s = t; s !== e.next; s = s.next) - n.push(s); - return n; + /** + * Set Boundary to Boundary intersection + * @param geom + */ + set B2B(t) { + this.m[4] = t; } /** - * Split edges of multiline with intersection points and return mutated multiline - * @param {Point[]} ip - array of points to be added as new vertices - * @returns {Multiline} + * Get Boundary To Exterior intersection + * @returns {Shape[] | undefined} */ - split(t) { - for (let e of t) { - let n = this.findEdgeByPoint(e); - this.addVertex(e, n); - } - return this; + get B2E() { + return this.m[5]; } /** - * Returns edge which contains given point - * @param {Point} pt - * @returns {Edge} + * Set Boundary to Exterior intersection + * @param geom */ - findEdgeByPoint(t) { - let e; - for (let n of this) - if (n.shape.contains(t)) { - e = n; - break; - } - return e; + set B2E(t) { + this.m[5] = t; } /** - * Returns new multiline translated by vector vec - * @param {Vector} vec - * @returns {Multiline} + * Get Exterior To Interior intersection + * @returns {Shape[] | undefined} */ - translate(t) { - return new R(this.edges.map((e) => e.shape.translate(t))); + get E2I() { + return this.m[6]; } /** - * Return new multiline rotated by given angle around given point - * If point omitted, rotate around origin (0,0) - * Positive value of angle defines rotation counterclockwise, negative - clockwise - * @param {number} angle - rotation angle in radians - * @param {Point} center - rotation center, default is (0,0) - * @returns {Multiline} - new rotated polygon + * Set Exterior to Interior intersection + * @param geom */ - rotate(t = 0, e = new i.Point()) { - return new R(this.edges.map((n) => n.shape.rotate(t, e))); + set E2I(t) { + this.m[6] = t; } /** - * Return new multiline transformed using affine transformation matrix - * Method does not support unbounded shapes - * @param {Matrix} matrix - affine transformation matrix - * @returns {Multiline} - new multiline + * Get Exterior To Boundary intersection + * @returns {Shape[] | undefined} */ - transform(t = new i.Matrix()) { - return new R(this.edges.map((e) => e.shape.transform(t))); + get E2B() { + return this.m[7]; } /** - * Transform multiline into array of shapes - * @returns {Shape[]} + * Set Exterior to Boundary intersection + * @param geom */ - toShapes() { - return this.edges.map((t) => t.shape.clone()); + set E2B(t) { + this.m[7] = t; } /** - * This method returns an object that defines how data will be - * serialized when called JSON.stringify() method - * @returns {Object} + * Get Exterior to Exterior intersection + * @returns {Shape[] | undefined} */ - toJSON() { - return this.edges.map((t) => t.toJSON()); + get E2E() { + return this.m[8]; } /** - * Return string to draw multiline in svg - * @param attrs - an object with attributes for svg path element - * TODO: support semi-infinite Ray and infinite Line + * Set Exterior to Exterior intersection + * @param geom + */ + set E2E(t) { + this.m[8] = t; + } + /** + * Return de9im matrix as string where
+ * - intersection is 'T'
+ * - not intersected is 'F'
+ * - not relevant is '*'
+ * For example, string 'FF**FF****' means 'DISJOINT' * @returns {string} */ - svg(t = {}) { - let e = ` - -`, e; + toString() { + return this.m.map((t) => t instanceof Array && t.length > 0 ? "T" : t instanceof Array && t.length === 0 ? "F" : "*").join(""); + } + equal() { + return gi.test(this.toString()); + } + intersect() { + return pi.test(this.toString()); + } + touch() { + return _i.test(this.toString()); + } + inside() { + return mi.test(this.toString()); + } + covered() { + return Ei.test(this.toString()); } } -i.Multiline = R; -const ri = (...r) => new i.Multiline(...r); -i.multiline = ri; -function Pt(r, t) { +function Ot(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, @@ -1197,136 +1315,136 @@ function Pt(r, t) { let o = r.edges.search(l); if (o.length === 0) return i.OUTSIDE; - for (let f of o) - if (f.shape.contains(t)) + for (let u of o) + if (u.shape.contains(t)) return i.BOUNDARY; - let a = [...r.faces], h = []; - for (let f of o) - for (let g of n.intersect(f.shape)) { + let a = [...r.faces], f = []; + for (let u of o) + for (let g of n.intersect(u.shape)) { if (g.equalTo(t)) return i.BOUNDARY; - h.push({ + f.push({ pt: g, - edge: f, - face_index: a.indexOf(f.face) + edge: u, + face_index: a.indexOf(u.face) }); } - 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]; + f.sort((u, g) => ze(u.pt.x, g.pt.x) ? -1 : We(u.pt.x, g.pt.x) ? 1 : u.face_index < g.face_index ? -1 : u.face_index > g.face_index ? 1 : u.edge.arc_length < g.edge.arc_length ? -1 : u.edge.arc_length > g.edge.arc_length ? 1 : 0); + let h = 0; + for (let u = 0; u < f.length; u++) { + let g = f[u]; 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) + if (u > 0 && g.pt.equalTo(f[u - 1].pt) && g.face_index === f[u - 1].face_index && g.edge.prev === f[u - 1].edge) continue; - 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++; + let _ = g.edge.prev; + for (; ne(_.length); ) + _ = _.prev; + let S = _.shape.tangentInEnd(), I = g.pt.translate(S), w = g.edge.shape.tangentInStart(), v = g.pt.translate(w), E = I.leftTo(s), x = v.leftTo(s); + (E && !x || !E && x) && h++; } 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) + if (u > 0 && g.pt.equalTo(f[u - 1].pt) && g.face_index === f[u - 1].face_index && g.edge.next === f[u - 1].edge) continue; - 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++; + let _ = g.edge.next; + for (; ne(_.length); ) + _ = _.next; + let S = _.shape.tangentInStart(), I = g.pt.translate(S), w = g.edge.shape.tangentInEnd(), v = g.pt.translate(w), E = I.leftTo(s), x = v.leftTo(s); + (E && !x || !E && x) && h++; } else if (g.edge.shape instanceof i.Segment) - u++; + h++; else { - let p = g.edge.shape.box; - ot(g.pt.y, p.ymin) || ot(g.pt.y, p.ymax) || u++; + let _ = g.edge.shape.box; + st(g.pt.y, _.ymin) || st(g.pt.y, _.ymax) || h++; } } - return e = u % 2 === 1 ? qt : Fe, e; + return e = h % 2 === 1 ? Wt : Ge, e; } -function si(r, t) { - return bt(r, t).equal(); +function xi(r, t) { + return Pt(r, t).equal(); } -function sn(r, t) { - return bt(r, t).intersect(); +function hn(r, t) { + return Pt(r, t).intersect(); } -function oi(r, t) { - return bt(r, t).touch(); +function Ti(r, t) { + return Pt(r, t).touch(); } -function li(r, t) { - return !sn(r, t); +function wi(r, t) { + return !hn(r, t); } -function on(r, t) { - return bt(r, t).inside(); +function cn(r, t) { + return Pt(r, t).inside(); } -function ln(r, t) { - return bt(r, t).covered(); +function dn(r, t) { + return Pt(r, t).covered(); } -function ai(r, t) { - return on(t, r); +function Ii(r, t) { + return cn(t, r); } -function an(r, t) { - return ln(t, r); +function gn(r, t) { + return dn(t, r); } -function bt(r, t) { +function Pt(r, t) { if (r instanceof i.Line && t instanceof i.Line) - return fi(r, t); + return Si(r, t); if (r instanceof i.Line && t instanceof i.Circle) - return ui(r, t); + return vi(r, t); if (r instanceof i.Line && t instanceof i.Box) - return hi(r, t); + return yi(r, t); if (r instanceof i.Line && t instanceof i.Polygon) - return ci(r, t); + return Pi(r, t); if ((r instanceof i.Segment || r instanceof i.Arc) && t instanceof i.Polygon) - return Pe(r, t); + return Ce(r, t); if ((r instanceof i.Segment || r instanceof i.Arc) && (t instanceof i.Circle || t instanceof i.Box)) - return Pe(r, new i.Polygon(t)); + return Ce(r, new i.Polygon(t)); if (r instanceof i.Polygon && t instanceof i.Polygon) - return Ft(r, t); + return Ht(r, t); if ((r instanceof i.Circle || r instanceof i.Box) && (t instanceof i.Circle || t instanceof i.Box)) - return Ft(new i.Polygon(r), new i.Polygon(t)); + return Ht(new i.Polygon(r), new i.Polygon(t)); if ((r instanceof i.Circle || r instanceof i.Box) && t instanceof i.Polygon) - return Ft(new i.Polygon(r), t); + return Ht(new i.Polygon(r), t); if (r instanceof i.Polygon && (t instanceof i.Circle || t instanceof i.Box)) - return Ft(r, new i.Polygon(t)); + return Ht(r, new i.Polygon(t)); } -function fi(r, t) { - let e = new St(), n = It(r, t); +function Si(r, t) { + let e = new yt(), n = St(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 ui(r, t) { - let e = new St(), n = at(r, t); +function vi(r, t) { + let e = new yt(), n = at(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 R([r]), l = r.sortPoints(n); + let s = new ft([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 hi(r, t) { - let e = new St(), n = Tt(r, t); +function yi(r, t) { + let e = new yt(), 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 R([r]), l = r.sortPoints(n); + let s = new ft([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 ci(r, t) { - let e = new St(), n = kt(r, t), s = new R([r]), l = n.length > 0 ? n.slice() : r.sortPoints(n); +function Pi(r, t) { + let e = new yt(), n = Ft(r, t), s = new ft([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 Pe(r, t) { - let e = new St(), n = ti(r, t), s = n.length > 0 ? n.slice() : r.sortPoints(n), l = new R([r]); +function Ce(r, t) { + let e = new yt(), n = Kn(r, t), s = n.length > 0 ? n.slice() : r.sortPoints(n), l = new ft([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 (Pt(t, o)) { + switch (Ot(t, o)) { case i.INSIDE: e.B2I.push(o); break; @@ -1339,23 +1457,23 @@ function Pe(r, t) { } return e; } -function Ft(r, t) { - let e = new St(), [n, s] = ze(r, t), l = Ge(r, t), o = re(r, t), a = re(t, r), [h, u] = De(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; +function Ht(r, t) { + let e = new yt(), [n, s] = fn(r, t), l = ln(r, t), o = se(r, t), a = se(t, r), [f, h] = an(r, t), u = oe(r, t), g = oe(t, r); + return e.I2I = l.isEmpty() ? [] : [l], e.I2B = h, e.I2E = o.isEmpty() ? [] : [o], e.B2I = f, e.B2B = n, e.B2E = u, e.E2I = a.isEmpty() ? [] : [a], e.E2B = g, e; } -var di = /* @__PURE__ */ Object.freeze({ +var Li = /* @__PURE__ */ Object.freeze({ __proto__: null, - contain: ai, - cover: an, - covered: ln, - disjoint: li, - equal: si, - inside: on, - intersect: sn, - relate: bt, - touch: oi + contain: Ii, + cover: gn, + covered: dn, + disjoint: wi, + equal: xi, + inside: cn, + intersect: hn, + relate: Pt, + touch: Ti }); -let Lt = class dt { +let Nt = class ct { /** * Construct new instance of affine transformation matrix
* If parameters omitted, construct identity matrix a = 1, d = 1 @@ -1374,7 +1492,7 @@ let Lt = class dt { * @return {Matrix} **/ clone() { - return new dt(this.a, this.b, this.c, this.d, this.tx, this.ty); + return new ct(this.a, this.b, this.c, this.d, this.tx, this.ty); } /** * Transform vector [x,y] using transformation matrix.
@@ -1400,7 +1518,7 @@ let Lt = class dt { * @returns {Matrix} */ multiply(t) { - return new dt( + return new ct( this.a * t.a + this.c * t.b, this.b * t.a + this.d * t.b, this.a * t.c + this.c * t.d, @@ -1424,8 +1542,8 @@ 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 w.ILLEGAL_PARAMETERS; - return this.multiply(new dt(1, 0, 0, 1, e, n)); + throw T.ILLEGAL_PARAMETERS; + return this.multiply(new ct(1, 0, 0, 1, e, n)); } /** * Return new matrix as a result of multiplication of the current matrix @@ -1438,7 +1556,7 @@ let Lt = class dt { */ rotate(t, e = 0, n = 0) { let s = Math.cos(t), l = Math.sin(t); - return this.translate(e, n).multiply(new dt(s, l, -l, s, 0, 0)).translate(-e, -n); + return this.translate(e, n).multiply(new ct(s, l, -l, s, 0, 0)).translate(-e, -n); } /** * Return new matrix as a result of multiplication of the current matrix @@ -1448,7 +1566,7 @@ let Lt = class dt { * @returns {Matrix} */ scale(t, e) { - return this.multiply(new dt(t, 0, 0, e, 0, 0)); + return this.multiply(new ct(t, 0, 0, e, 0, 0)); } /** * Returns true if two matrix are equal parameter by parameter @@ -1459,10 +1577,10 @@ let Lt = class dt { 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 = Lt; -const gi = (...r) => new i.Matrix(...r); -i.matrix = gi; -const _i = class fe { +i.Matrix = Nt; +const Ai = (...r) => new i.Matrix(...r); +i.matrix = Ai; +const bi = class ue { /** * Accept two comparable values and creates new instance of interval * Predicate Interval.comparable_less(low, high) supposed to return true on these values @@ -1477,7 +1595,7 @@ const _i = class fe { * @returns {Interval} */ clone() { - return new fe(this.low, this.high); + return new ue(this.low, this.high); } /** * Propery max returns clone of this interval @@ -1492,7 +1610,7 @@ const _i = class fe { * @returns {boolean} */ less_than(t) { - return this.low < t.low || this.low == t.low && this.high < t.high; + return this.low < t.low || this.low === t.low && this.high < t.high; } /** * Predicate returns true is this interval equals to other interval @@ -1500,7 +1618,7 @@ const _i = class fe { * @returns {boolean} */ equal_to(t) { - return this.low == t.low && this.high == t.high; + return this.low === t.low && this.high === t.high; } /** * Predicate returns true if this interval intersects other interval @@ -1520,13 +1638,13 @@ const _i = class fe { } /** * Returns new interval merged with other interval - * @param {Interval} interval - Other interval to merge with + * @param {Interval} other_interval - Other interval to merge with * @returns {Interval} */ merge(t) { - return new fe( - this.low === void 0 ? t.low : Math.min(this.low, t.low), - this.high === void 0 ? t.high : Math.max(this.high, t.high) + return new ue( + this.low === void 0 ? t.low : this.low < t.low ? this.low : t.low, + this.high === void 0 ? t.high : this.high > t.high ? this.high : t.high ); } /** @@ -1553,10 +1671,14 @@ const _i = class fe { static comparable_less_than(t, e) { return t < e; } -}, A = 0, m = 1; -class ht { +}, L = 0, m = 1; +class rt { 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; + if (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])) { + let [a, f] = t; + a > f && ([a, f] = [f, a]), this.item.key = new bi(a, f); + } + 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 === m; @@ -1568,7 +1690,7 @@ class ht { return this.item.value === this.item.key && t.item.value === t.item.key ? this.item.key.less_than(t.item.key) : this.item.key.less_than(t.item.key) || this.item.key.equal_to(t.item.key) && this._value_less_than(t); } _value_equal(t) { - return this.item.value && t.item.value && this.item.value.equal_to ? this.item.value.equal_to(t.item.value) : this.item.value == t.item.value; + return this.item.value && t.item.value && this.item.value.equal_to ? this.item.value.equal_to(t.item.value) : this.item.value === t.item.value; } equal_to(t) { return this.item.value === this.item.key && t.item.value === t.item.key ? this.item.key.equal_to(t.item.key) : this.item.key.equal_to(t.item.key) && this._value_equal(t); @@ -1602,12 +1724,12 @@ class ht { return e(t.item.key.high, n); } } -class Rt { +class Mt { /** * Construct new empty instance of IntervalTree */ constructor() { - this.root = null, this.nil_node = new ht(); + this.root = null, this.nil_node = new rt(); } /** * Returns number of items stored in the interval tree @@ -1651,7 +1773,7 @@ class Rt { * @returns {boolean} */ isEmpty() { - return this.root == null || this.root == this.nil_node; + return this.root == null || this.root === this.nil_node; } /** * Clear tree @@ -1666,9 +1788,8 @@ class Rt { * @returns {Node} returns reference to inserted node as an object {key:interval, value: value} */ insert(t, e = t) { - if (t === void 0) - return; - let n = new ht(t, e, this.nil_node, this.nil_node, null, A); + if (t === void 0) return; + let n = new rt(t, e, this.nil_node, this.nil_node, null, L); return this.tree_insert(n), this.recalc_max(n), n; } /** @@ -1678,7 +1799,7 @@ class Rt { * @returns {boolean} true if item {key, value} exist in the tree, false otherwise */ exist(t, e = t) { - let n = new ht(t, e); + let n = new rt(t, e); return !!this.tree_search(this.root, n); } /** @@ -1688,7 +1809,7 @@ class Rt { * @returns {boolean} true if item {key, value} deleted, false if not found */ remove(t, e = t) { - let n = new ht(t, e), s = this.tree_search(this.root, n); + let n = new rt(t, e), s = this.tree_search(this.root, n); return s && this.tree_delete(s), s; } /** @@ -1699,7 +1820,7 @@ class Rt { * @returns {Array} */ search(t, e = (n, s) => n === s ? s.output() : n) { - let n = new ht(t), s = []; + let n = new rt(t), s = []; return this.tree_search_interval(this.root, n, s), s.map((l) => e(l.item.value, l.item.key)); } /** @@ -1708,7 +1829,7 @@ class Rt { * @returns {boolean} */ intersect_any(t) { - let e = new ht(t); + let e = new rt(t); return this.tree_find_any_interval(this.root, e); } /** @@ -1719,13 +1840,24 @@ class Rt { forEach(t) { this.tree_walk(this.root, (e) => t(e.item.key, e.item.value)); } - /** Value Mapper. Walk through every node and map node value to another value - * @param callback(value,key) - function to be called for each tree item - */ + /** + * Value Mapper. Walk through every node and map node value to another value + * @param callback(value,key) - function to be called for each tree item + */ map(t) { - const e = new Rt(); + const e = new Mt(); return this.tree_walk(this.root, (n) => e.insert(n.item.key, t(n.item.value, n.item.key))), e; } + /** + * @param {Interval} interval - optional if the iterator is intended to start from the beginning + * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output + * @returns {Iterator} + */ + *iterate(t, e = (n, s) => n === s ? s.output() : n) { + let n; + for (t ? n = this.tree_search_nearest_forward(this.root, new rt(t)) : this.root && (n = this.local_minimum(this.root)); n; ) + yield e(n.item.value, n.item.key), n = this.tree_successor(n); + } recalc_max(t) { let e = t; for (; e.parent != null; ) @@ -1733,10 +1865,10 @@ class Rt { } tree_insert(t) { let e = this.root, n = null; - if (this.root == null || this.root == this.nil_node) + if (this.root == null || this.root === this.nil_node) this.root = t; else { - for (; e != this.nil_node; ) + 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; } @@ -1746,53 +1878,59 @@ class Rt { // Go upwords to the root and re-color until violation will be resolved 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 = 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))); + for (e = t; e !== this.root && e.parent.color === L; ) + e.parent === e.parent.parent.left ? (n = e.parent.parent.right, n.color === L ? (e.parent.color = m, n.color = m, e.parent.parent.color = L, e = e.parent.parent) : (e === e.parent.right && (e = e.parent, this.rotate_left(e)), e.parent.color = m, e.parent.parent.color = L, this.rotate_right(e.parent.parent))) : (n = e.parent.parent.left, n.color === L ? (e.parent.color = m, n.color = m, e.parent.parent.color = L, e = e.parent.parent) : (e === e.parent.left && (e = e.parent, this.rotate_right(e)), e.parent.color = m, e.parent.parent.color = L, 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 == m && this.delete_fixup(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 === 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 == 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)); + for (; e !== this.root && e.parent != null && e.color === m; ) + e === e.parent.left ? (n = e.parent.right, n.color === L && (n.color = m, e.parent.color = L, this.rotate_left(e.parent), n = e.parent.right), n.left.color === m && n.right.color === m ? (n.color = L, e = e.parent) : (n.right.color === m && (n.color = L, 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 === L && (n.color = m, e.parent.color = L, this.rotate_right(e.parent), n = e.parent.left), n.left.color === m && n.right.color === m ? (n.color = L, e = e.parent) : (n.left.color === m && (n.color = L, 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)) + 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_nearest_forward(t, e) { + let n, s = t; + for (; s && s !== this.nil_node; ) + s.less_than(e) ? s.intersect(e) ? (n = s, s = s.left) : s = s.right : ((!n || s.less_than(n)) && (n = s), s = s.left); + return n || null; + } // Original search_interval method; container res support push() insertion // Search all intervals intersecting given one 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)); + 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; + 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; ) + for (; e.left != null && e.left !== this.nil_node; ) e = e.left; return e; } // not in use local_maximum(t) { let e = t; - for (; e.right != null && e.right != this.nil_node; ) + 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) + if (t.right !== this.nil_node) e = this.local_minimum(t.right); else { - for (n = t, s = t.parent; s != null && s.right == n; ) + for (n = t, s = t.parent; s != null && s.right === n; ) n = s, s = s.parent; e = s; } @@ -1806,38 +1944,38 @@ class Rt { // a b b c 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(); + 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(); + 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)); + t != null && t !== this.nil_node && (this.tree_walk(t.left, e), e(t), this.tree_walk(t.right, e)); } /* Return true if all red nodes have exactly two black child nodes */ testRedBlackProperty() { let t = !0; return this.tree_walk(this.root, function(e) { - e.color == A && (e.left.color == m && e.right.color == m || (t = !1)); + e.color === L && (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 == 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) + 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 pi extends Set { +class Oi extends Set { /** * Create new instance of PlanarSet * @param shapes - array or set of geometric objects to store in planar set * Each object should have a box property */ constructor(t) { - super(t), this.index = new Rt(), this.forEach((e) => this.index.insert(e)); + super(t), this.index = new Mt(), this.forEach((e) => this.index.insert(e)); } /** * Add new shape to planar set and to its spatial index.
@@ -1868,7 +2006,7 @@ class pi extends Set { * Clear planar set */ clear() { - super.clear(), this.index = new Rt(); + super.clear(), this.index = new Mt(); } /** * 2d range search in planar set.
@@ -1896,16 +2034,16 @@ class pi extends Set { return [...this].reduce((e, n) => e + n.svg(), ""); } } -i.PlanarSet = pi; -class rt { +i.PlanarSet = Oi; +class it { get name() { - throw w.CANNOT_INVOKE_ABSTRACT_METHOD; + throw T.CANNOT_INVOKE_ABSTRACT_METHOD; } get box() { - throw w.CANNOT_INVOKE_ABSTRACT_METHOD; + throw T.CANNOT_INVOKE_ABSTRACT_METHOD; } clone() { - throw w.CANNOT_INVOKE_ABSTRACT_METHOD; + throw T.CANNOT_INVOKE_ABSTRACT_METHOD; } /** * Returns new shape translated by given vector. @@ -1915,7 +2053,7 @@ class rt { * @returns {Shape} */ translate(...t) { - return this.transform(new Lt().translate(...t)); + return this.transform(new Nt().translate(...t)); } /** * Returns new shape rotated by given angle around given center point. @@ -1927,7 +2065,7 @@ class rt { * @returns {Shape} */ rotate(t, e = new i.Point()) { - return this.transform(new Lt().rotate(t, e.x, e.y)); + return this.transform(new Nt().rotate(t, e.x, e.y)); } /** * Return new shape with coordinates multiplied by scaling factor @@ -1936,10 +2074,10 @@ class rt { * @returns {Shape} */ scale(t, e) { - return this.transform(new Lt().scale(t, e)); + return this.transform(new Nt().scale(t, e)); } transform(...t) { - throw w.CANNOT_INVOKE_ABSTRACT_METHOD; + throw T.CANNOT_INVOKE_ABSTRACT_METHOD; } /** * This method returns an object that defines how data will be @@ -1950,10 +2088,10 @@ class rt { return Object.assign({}, this, { name: this.name }); } svg(t = {}) { - throw w.CANNOT_INVOKE_ABSTRACT_METHOD; + throw T.CANNOT_INVOKE_ABSTRACT_METHOD; } } -let mi = class fn extends rt { +let Ni = class pn extends it { /** * Point may be constructed by two numbers, or by array of two numbers * @param {number} x - x-coordinate (float number) @@ -1977,7 +2115,7 @@ let mi = class fn extends rt { this.x = t[0], this.y = t[1]; return; } - throw w.ILLEGAL_PARAMETERS; + throw T.ILLEGAL_PARAMETERS; } } /** @@ -2054,7 +2192,7 @@ let mi = class fn extends rt { * @returns {Segment} shortest segment between point and shape (started at point, ended at shape) */ distanceTo(t) { - if (t instanceof fn) { + if (t instanceof pn) { let e = t.x - this.x, n = t.y - this.y; return [Math.sqrt(e * e + n * n), new i.Segment(this, t)]; } @@ -2070,6 +2208,8 @@ let mi = class fn extends rt { return i.Distance.point2polygon(this, t); if (t instanceof i.PlanarSet) return i.Distance.shape2planarSet(this, t); + if (t instanceof i.Multiline) + return i.Distance.shape2multiline(this, t); } /** * Returns true if point is on a shape, false otherwise @@ -2079,20 +2219,9 @@ let mi = class fn extends rt { 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) + if (t.contains && t.contains instanceof Function) return t.contains(this); + throw i.Errors.UNSUPPORTED_SHAPE_TYPE; } get name() { return "point"; @@ -2114,13 +2243,13 @@ let mi = class fn extends rt { const e = t.r ?? 3; return ` `; + ${lt({ fill: "red", ...t })} />`; } }; -i.Point = mi; -const xi = (...r) => new i.Point(...r); -i.point = xi; -let Ei = class extends rt { +i.Point = Ni; +const Ci = (...r) => new i.Point(...r); +i.point = Ci; +let Ri = class extends it { /** * Vector may be constructed by two points, or by two float numbers, * or by array of two numbers @@ -2152,7 +2281,7 @@ let Ei = class extends rt { return; } } - throw w.ILLEGAL_PARAMETERS; + throw T.ILLEGAL_PARAMETERS; } } /** @@ -2220,7 +2349,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 w.ZERO_DIVISION; + throw T.ZERO_DIVISION; } /** * Returns new vector rotated by given angle, @@ -2232,8 +2361,8 @@ 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 w.OPERATION_IS_NOT_SUPPORTED; + return this.transform(new Nt().rotate(t)); + throw T.OPERATION_IS_NOT_SUPPORTED; } /** * Return new vector transformed by affine transformation matrix m @@ -2304,10 +2433,10 @@ let Ei = class extends rt { return "vector"; } }; -i.Vector = Ei; -const un = (...r) => new i.Vector(...r); -i.vector = un; -class zt extends rt { +i.Vector = Ri; +const _n = (...r) => new i.Vector(...r); +i.vector = _n; +let Ui = class he extends it { /** * * @param {Point} ps - start point @@ -2337,7 +2466,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 w.ILLEGAL_PARAMETERS; + throw T.ILLEGAL_PARAMETERS; } } /** @@ -2396,7 +2525,7 @@ class zt extends rt { } /** * Returns true if equals to query segment, false otherwise - * @param {Seg} seg - query segment + * @param {Segment} seg - query segment * @returns {boolean} */ equalTo(t) { @@ -2419,9 +2548,9 @@ class zt extends rt { if (t instanceof i.Point) return this.contains(t) ? [t] : []; if (t instanceof i.Line) - return Bt(this, t); + return kt(this, t); if (t instanceof i.Ray) - return pe(t, this); + return me(t, this); if (t instanceof i.Segment) return jt(this, t); if (t instanceof i.Circle) @@ -2429,15 +2558,16 @@ class zt extends rt { if (t instanceof i.Box) return Wn(this, t); if (t instanceof i.Arc) - return yt(this, t); + return vt(this, t); if (t instanceof i.Polygon) - return ge(this, t); + return pe(this, t); + if (t instanceof i.Multiline) + return Bt(this, t); } /** * Calculate distance and shortest segment from segment to shape and return as array [distance, shortest segment] * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set - * @returns {number} distance from segment to shape - * @returns {Segment} shortest segment between segment and shape (started at segment, ended at shape) + * @returns {[number, Segment]} shortest segment between segment and shape (started at segment, ended at shape) */ distanceTo(t) { if (t instanceof i.Point) { @@ -2468,6 +2598,8 @@ class zt extends rt { let [e, n] = i.Distance.shape2planarSet(this, t); return [e, n]; } + if (t instanceof i.Multiline) + return i.Distance.shape2multiline(this, t); } /** * Returns unit vector in the direction from start to end @@ -2488,7 +2620,7 @@ class zt extends rt { * @returns {Segment} */ reverse() { - return new zt(this.end, this.start); + return new he(this.end, this.start); } /** * When point belongs to segment, return array of two segments split by given point, @@ -2516,12 +2648,9 @@ class zt extends rt { * @returns {Point} */ pointAtLength(t) { - if (t > this.length || t < 0) - return null; - if (t == 0) - return this.start; - if (t == this.length) - return this.end; + 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, @@ -2542,7 +2671,7 @@ class zt extends rt { * @returns {Segment} - transformed segment */ transform(t = new i.Matrix()) { - return new zt(this.ps.transform(t), this.pe.transform(t)); + return new he(this.ps.transform(t), this.pe.transform(t)); } /** * Returns true if segment start is equal to segment end up to DP_TOL @@ -2571,13 +2700,13 @@ class zt extends rt { */ svg(t = {}) { return ` -`; +`; } -} -i.Segment = zt; -const vi = (...r) => new i.Segment(...r); -i.segment = vi; -let { vector: At } = i, wi = class hn extends rt { +}; +i.Segment = Ui; +const Mi = (...r) => new i.Segment(...r); +i.segment = Mi; +let { vector: Lt } = i, ki = class mn extends it { /** * Line may be constructed by point and normal vector or by two points that a line passes through * @param {Point} pt - point that a line passes through @@ -2593,23 +2722,23 @@ let { vector: At } = i, wi = class hn extends rt { 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 = hn.points2norm(e, n), this.norm.dot(At(this.pt.x, this.pt.y)) >= 0 && this.norm.invert(); + this.pt = e, this.norm = mn.points2norm(e, n), this.norm.dot(Lt(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 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(); + throw T.ILLEGAL_PARAMETERS; + this.pt = e.clone(), this.norm = n.clone(), this.norm = this.norm.normalize(), this.norm.dot(Lt(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 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(); + throw T.ILLEGAL_PARAMETERS; + this.pt = n.clone(), this.norm = e.clone(), this.norm = this.norm.normalize(), this.norm.dot(Lt(this.pt.x, this.pt.y)) >= 0 && this.norm.invert(); return; } } - throw w.ILLEGAL_PARAMETERS; + throw T.ILLEGAL_PARAMETERS; } } /** @@ -2669,7 +2798,7 @@ let { vector: At } = i, wi = class hn extends rt { * @returns {number[]} - array of coefficients */ get standard() { - let t = this.norm.x, e = this.norm.y, n = this.norm.dot(At(this.pt.x, this.pt.y)); + let t = this.norm.x, e = this.norm.y, n = this.norm.dot(Lt(this.pt.x, this.pt.y)); return [t, e, n]; } /** @@ -2708,7 +2837,7 @@ let { vector: At } = i, wi = class hn extends rt { * @returns {number} */ coord(t) { - return At(t.x, t.y).cross(this.norm); + return Lt(t.x, t.y).cross(this.norm); } /** * Returns array of intersection points @@ -2719,19 +2848,21 @@ let { vector: At } = i, wi = class hn extends rt { if (t instanceof i.Point) return this.contains(t) ? [t] : []; if (t instanceof i.Line) - return It(this, t); + return St(this, t); if (t instanceof i.Ray) - return nn(t, this); + return rn(t, this); if (t instanceof i.Circle) return at(this, t); if (t instanceof i.Box) - return Tt(this, t); + return xt(this, t); if (t instanceof i.Segment) - return Bt(t, this); + return kt(t, this); if (t instanceof i.Arc) - return Yt(this, t); + return Qt(this, t); if (t instanceof i.Polygon) - return kt(this, t); + return Ft(this, t); + if (t instanceof i.Multiline) + return Bt(this, t); } /** * Calculate distance and shortest segment from line to shape and returns array [distance, shortest_segment] @@ -2814,7 +2945,7 @@ let { vector: At } = i, wi = class hn extends rt { * @param {Object} attrs - an object with attributes of svg circle element */ svg(t, e = {}) { - let n = Tt(this, t); + 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)); @@ -2822,14 +2953,14 @@ let { vector: At } = i, wi = class hn extends rt { } static points2norm(t, e) { if (t.equalTo(e)) - throw w.ILLEGAL_PARAMETERS; + throw T.ILLEGAL_PARAMETERS; return new i.Vector(t, e).normalize().rotate90CCW(); } }; -i.Line = wi; -const Ti = (...r) => new i.Line(...r); -i.line = Ti; -let Si = class extends rt { +i.Line = ki; +const Fi = (...r) => new i.Line(...r); +i.line = Fi; +let Bi = class extends it { /** * Class private property * @type {string} @@ -2905,7 +3036,7 @@ let Si = class extends rt { */ scale(t, e) { if (t !== e || !(this.pc.x === 0 && this.pc.y === 0)) - throw w.OPERATION_IS_NOT_SUPPORTED; + throw T.OPERATION_IS_NOT_SUPPORTED; return new i.Circle(this.pc, this.r * t); } /** @@ -2927,17 +3058,19 @@ let Si = class extends rt { if (t instanceof i.Line) return at(t, this); if (t instanceof i.Ray) - return en(t, this); + return nn(t, this); if (t instanceof i.Segment) return Zt(t, this); if (t instanceof i.Circle) - return We(t, this); + return Ye(t, this); if (t instanceof i.Box) - return Yn(this, t); + return zn(this, t); if (t instanceof i.Arc) - return de(t, this); + return ge(t, this); if (t instanceof i.Polygon) return Ke(this, t); + if (t instanceof i.Multiline) + return Bt(this, t); } /** * Calculate distance and shortest segment from circle to shape and return array [distance, shortest segment] @@ -2975,6 +3108,10 @@ let Si = class extends rt { let [e, n] = i.Distance.shape2planarSet(this, t); return [e, n]; } + if (t instanceof i.Multiline) { + let [e, n] = i.Distance.shape2multiline(this, t); + return [e, n]; + } } get name() { return "circle"; @@ -2987,13 +3124,13 @@ let Si = class extends rt { svg(t = {}) { return ` `; + ${lt({ fill: "none", ...t })} />`; } }; -i.Circle = Si; -const Ii = (...r) => new i.Circle(...r); -i.circle = Ii; -class yi extends rt { +i.Circle = Bi; +const Vi = (...r) => new i.Circle(...r); +i.circle = Vi; +class $i extends it { /** * * @param {Point} pc - arc center @@ -3115,12 +3252,9 @@ class yi extends rt { * @returns {Point} */ pointAtLength(t) { - if (t > this.length || t < 0) - return null; - if (t === 0) - return this.start; - if (t === this.length) - return this.end; + 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; } @@ -3140,19 +3274,21 @@ class yi extends rt { if (t instanceof i.Point) return this.contains(t) ? [t] : []; if (t instanceof i.Line) - return Yt(t, this); + return Qt(t, this); if (t instanceof i.Ray) - return me(t, this); + return Ee(t, this); if (t instanceof i.Circle) - return de(this, t); + return ge(this, t); if (t instanceof i.Segment) - return yt(t, this); + return vt(t, this); if (t instanceof i.Box) - return jn(this, t); + return Yn(this, t); if (t instanceof i.Arc) - return Ye(this, t); + return Qe(this, t); if (t instanceof i.Polygon) return _e(this, t); + if (t instanceof i.Multiline) + return Bt(this, t); } /** * Calculate distance and shortest segment from arc to shape and return array [distance, shortest segment] @@ -3190,6 +3326,8 @@ class yi extends rt { let [e, n] = i.Distance.shape2planarSet(this, t); return [e, n]; } + if (t instanceof i.Multiline) + return i.Distance.shape2multiline(this, t); } /** * Breaks arc in extreme point 0, pi/2, pi, 3*pi/2 and returns array of sub-arcs @@ -3207,10 +3345,10 @@ class yi extends rt { if (s.length === 0) t.push(this.clone()); else { - s.sort((a, h) => a.length - h.length); + s.sort((a, f) => a.length - f.length); for (let a = 0; a < s.length; a++) { - let h = t.length > 0 ? 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 f = t.length > 0 ? t[t.length - 1] : void 0, h; + f ? h = new i.Arc(this.pc, this.r, f.endAngle, s[a].endAngle, this.counterClockwise) : h = new i.Arc(this.pc, this.r, this.startAngle, s[a].endAngle, this.counterClockwise), i.Utils.EQ_0(h.length) || t.push(h.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()); @@ -3252,8 +3390,8 @@ class yi extends rt { 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); + let f = l(t, e).length; + return new i.Arc(t, f, o, a, s); } definiteIntegral(t = 0) { return this.breakToFunctional().reduce((s, l) => s + l.circularSegmentDefiniteIntegral(t), 0); @@ -3290,13 +3428,13 @@ class yi extends rt { return i.Utils.EQ(this.sweep, 2 * Math.PI) ? new i.Circle(this.pc, this.r).svg(t) : ` `; + ${lt({ fill: "none", ...t })} />`; } } -i.Arc = yi; -const bi = (...r) => new i.Arc(...r); -i.arc = bi; -class Ot extends rt { +i.Arc = $i; +const Hi = (...r) => new i.Arc(...r); +i.arc = Hi; +class Ct extends it { /** * * @param {number} xmin - minimal x coordinate @@ -3312,7 +3450,7 @@ class Ot extends rt { * @returns {Box} */ clone() { - return new Ot(this.xmin, this.ymin, this.xmax, this.ymax); + return new Ct(this.xmin, this.ymin, this.xmax, this.ymax); } /** * Property low need for interval tree interface @@ -3385,7 +3523,7 @@ class Ot extends rt { * @returns {Box} */ merge(t) { - return new Ot( + return new Ct( 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), @@ -3459,7 +3597,7 @@ class Ot extends rt { * @param {Point} [center=(0,0)] center */ rotate(t, e = new i.Point()) { - throw w.OPERATION_IS_NOT_SUPPORTED; + throw T.OPERATION_IS_NOT_SUPPORTED; } /** * Return new box transformed using affine transformation matrix @@ -3470,7 +3608,7 @@ class Ot extends rt { transform(t = new i.Matrix()) { return this.toPoints().map((n) => n.transform(t)).reduce( (n, s) => n.merge(s.box), - new Ot() + new Ct() ); } /** @@ -3488,7 +3626,7 @@ class Ot extends rt { 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) => yt(e, t).length === 0); + return t.vertices.every((e) => this.contains(e)) && t.toSegments().every((e) => vt(e, t).length === 0); if (t instanceof i.Line || t instanceof i.Ray) return !1; if (t instanceof i.Multiline) @@ -3496,6 +3634,22 @@ class Ot extends rt { if (t instanceof i.Polygon) return this.contains(t.box); } + /** + * Calculate distance and shortest segment from box to shape and return as array [distance, shortest segment] + * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set + * @returns {number} distance from box to shape + * @returns {Segment} shortest segment between box and shape (started at box, ended at shape) + */ + distanceTo(t) { + const e = this.toSegments().map((s) => s.distanceTo(t)); + let n = [ + Number.MAX_SAFE_INTEGER, + null + ]; + return e.forEach((s) => { + s[0] < n[0] && (n = s); + }), n; + } get name() { return "box"; } @@ -3507,14 +3661,14 @@ class Ot extends rt { svg(t = {}) { const e = this.xmax - this.xmin, n = this.ymax - this.ymin; return ` -`; +`; } } -i.Box = Ot; -const Ai = (...r) => new i.Box(...r); -i.box = Ai; -class Pi { +i.Box = Ct; +const Gi = (...r) => new i.Box(...r); +i.box = Gi; +class qi { /** * Construct new instance of edge * @param {Shape} shape Shape of type Segment or Arc @@ -3587,16 +3741,15 @@ class Pi { * @param polygon */ setInclusion(t) { - if (this.bv !== void 0) - return this.bv; + 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 = Pt(t, this.start)), this.bvEnd === void 0 && (this.bvEnd = Pt(t, this.end)), this.bvStart === i.OUTSIDE || this.bvEnd == i.OUTSIDE) + if (this.bvStart === void 0 && (this.bvStart = Ot(t, this.start)), this.bvEnd === void 0 && (this.bvEnd = Ot(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 = Pt(t, this.middle()); + let e = Ot(t, this.middle()); this.bv = e; } return this.bv; @@ -3627,8 +3780,8 @@ class Pi { return this.shape.toJSON(); } } -i.Edge = Pi; -class Li extends he { +i.Edge = qi; +class Di extends de { constructor(t, e) { super(t, e), this.setCircularLinks(); } @@ -3670,7 +3823,7 @@ class Li extends he { return super.remove(t), this; } } -class gt extends Li { +class gt extends Di { constructor(t, ...e) { if (super(), this._box = void 0, this._orientation = void 0, e.length !== 0) { if (e.length === 1) { @@ -3700,7 +3853,7 @@ class gt extends Li { for (let s of n) t.edges.add(s); } else if (e[0] instanceof i.Circle) - this.shapes2face(t.edges, [e[0].toArc(ke)]); + this.shapes2face(t.edges, [e[0].toArc(He)]); else if (e[0] instanceof i.Box) { let n = e[0]; this.shapes2face(t.edges, [ @@ -3754,8 +3907,7 @@ class gt extends Li { * @returns {Point} */ pointAtLength(t) { - if (t > this.perimeter || t < 0) - return null; + if (t > this.perimeter || t < 0) return null; let e = null; for (let n of this) if (t >= n.arc_length && (n === this.last || t < n.next.arc_length)) { @@ -3870,7 +4022,7 @@ class gt extends Li { orientation() { if (this._orientation === void 0) { let t = this.signedArea(); - i.Utils.EQ_0(t) ? this._orientation = $t.NOT_ORIENTABLE : i.Utils.LT(t, 0) ? this._orientation = $t.CCW : this._orientation = $t.CW; + i.Utils.EQ_0(t) ? this._orientation = Dt.NOT_ORIENTABLE : i.Utils.LT(t, 0) ? this._orientation = Dt.CCW : this._orientation = Dt.CW; } return this._orientation; } @@ -3891,9 +4043,9 @@ class gt extends Li { for (let a of o) { if (l === a || a.face !== t || l.shape instanceof i.Segment && a.shape instanceof i.Segment && (l.next === a || l.prev === a)) continue; - let h = l.shape.intersect(a.shape); - for (let u of h) - if (!(u.equalTo(l.start) && u.equalTo(a.end) && a === l.prev) && !(u.equalTo(l.end) && u.equalTo(a.start) && a === l.next) && (s.push(u), n)) + let f = l.shape.intersect(a.shape); + for (let h of f) + if (!(h.equalTo(l.start) && h.equalTo(a.end) && a === l.prev) && !(h.equalTo(l.end) && h.equalTo(a.start) && a === l.next) && (s.push(h), n)) break; if (s.length > 0 && n) break; @@ -3932,15 +4084,14 @@ class gt extends Li { * @returns {string} */ svg() { - let t = ` -M${this.first.start.x},${this.first.start.y}`; + 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 = gt; -class xe extends rt { +class Te extends it { /** * Ray may be constructed by setting an origin point and a normal vector, so that any point x * on a ray fit an equation:
@@ -3957,7 +4108,7 @@ class xe extends rt { this.norm = t[1].clone(); return; } - throw w.ILLEGAL_PARAMETERS; + throw T.ILLEGAL_PARAMETERS; } } /** @@ -3965,7 +4116,7 @@ class xe extends rt { * @returns {Ray} */ clone() { - return new xe(this.pt, this.norm); + return new Te(this.pt, this.norm); } /** * Slope of the ray - angle in radians between ray and axe x from 0 to 2PI @@ -4027,7 +4178,7 @@ class xe extends rt { * @returns {number} */ coord(t) { - return un(t.x, t.y).cross(this.norm); + return _n(t.x, t.y).cross(this.norm); } /** * Split ray with point and return array of segment and new ray @@ -4049,19 +4200,19 @@ class xe extends rt { if (t instanceof i.Point) return this.contains(t) ? [t] : []; if (t instanceof i.Segment) - return pe(this, t); - if (t instanceof i.Arc) return me(this, t); + if (t instanceof i.Arc) + return Ee(this, t); if (t instanceof i.Line) - return nn(this, t); + return rn(this, t); if (t instanceof i.Ray) - return ni(this, t); + return ti(this, t); if (t instanceof i.Circle) - return en(this, t); + return nn(this, t); if (t instanceof i.Box) - return ei(this, t); + return Jn(this, t); if (t instanceof i.Polygon) - return rn(this, t); + return sn(this, t); } /** * Return new line rotated by angle @@ -4094,14 +4245,14 @@ class xe extends rt { * @param {Object} attrs - an object with attributes of svg segment element */ svg(t, e = {}) { - let n = new i.Line(this.pt, this.norm), s = Tt(n, t); + 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 = xe; -const Oi = (...r) => new i.Ray(...r); -i.ray = Oi; -class st { +i.Ray = Te; +const Wi = (...r) => new i.Ray(...r); +i.ray = Wi; +let zi = class dt { /** * Constructor creates new instance of polygon. With no arguments new polygon is empty.
* Constructor accepts as argument array that define loop of shapes @@ -4152,7 +4303,7 @@ class st { * @returns {Polygon} */ clone() { - let t = new st(); + let t = new dt(); for (let e of this.faces) t.addFace(e.shapes); return t; @@ -4295,26 +4446,30 @@ class st { }; for (let o of t.edges) for (let a of e.edges) { - let h = Je(o, a); - for (let u of h) - Et(o, u, n.int_points1), Et(a, u, n.int_points2); + let f = Je(o, a); + for (let h of f) + Tt(o, h, n.int_points1), Tt(a, h, n.int_points2); } if (n.int_points1.length === 0) return e; - n.int_points1_sorted = et(n.int_points1), n.int_points2_sorted = et(n.int_points2), wt(t, n.int_points1_sorted), wt(e, n.int_points2_sorted), ce(n), n.int_points1_sorted = et(n.int_points1), n.int_points2_sorted = et(n.int_points2), ne(n.int_points1), ie(n.int_points1, e); + n.int_points1_sorted = tt(n.int_points1), n.int_points2_sorted = tt(n.int_points2), It(t, n.int_points1_sorted), It(e, n.int_points2_sorted), xe(n), n.int_points1_sorted = tt(n.int_points1), n.int_points2_sorted = tt(n.int_points2), ie(n.int_points1), re(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) + 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.forEach((o, a) => { + o.id = a; + }), n.int_points2.forEach((o, a) => { + o.id = a; + }), n.int_points1.length === 0) return e; - n.int_points1_sorted = et(n.int_points1), n.int_points2_sorted = et(n.int_points2); + n.int_points1_sorted = tt(n.int_points1), n.int_points2_sorted = tt(n.int_points2); let s, l; for (let o = 1; o < n.int_points1_sorted.length; o++) - if (l = n.int_points1_sorted[o], s = n.int_points1_sorted[o - 1], l.edge_before && l.edge_before.bv === qt) { - let a = s.edge_after, h = l.edge_before, u = t.getChain(a, h); - ve(n.int_points2[s.id], n.int_points2[l.id], u), u.forEach((f) => e.edges.add(f)), u = u.reverse().map((f) => new i.Edge(f.shape.reverse())); - for (let f = 0; f < u.length - 1; f++) - u[f].next = u[f + 1], u[f + 1].prev = u[f]; - ve(n.int_points2[l.id], n.int_points2[s.id], u), u.forEach((f) => e.edges.add(f)); + if (l = n.int_points1_sorted[o], s = n.int_points1_sorted[o - 1], l.edge_before && l.edge_before.bv === Wt) { + let a = s.edge_after, f = l.edge_before, h = t.getChain(a, f); + Pe(n.int_points2[s.id], n.int_points2[l.id], h), h.forEach((u) => e.edges.add(u)), h = h.reverse().map((u) => new i.Edge(u.shape.reverse())); + for (let u = 0; u < h.length - 1; u++) + h[u].next = h[u + 1], h[u + 1].prev = h[u]; + Pe(n.int_points2[l.id], n.int_points2[s.id], h), h.forEach((u) => e.edges.add(u)); } return e.recreateFaces(), e; } @@ -4325,7 +4480,7 @@ class st { * @returns {Polygon} newPoly - resulted polygon */ cutWithLine(t) { - let e = new R([t]); + let e = new ft([t]); return this.cut(e); } /** @@ -4347,8 +4502,7 @@ class st { * @returns {Flatten.Polygon[]} */ splitToIslands() { - if (this.isEmpty()) - return []; + 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); @@ -4381,10 +4535,10 @@ class st { */ contains(t) { if (t instanceof i.Point) { - let e = Pt(this, t); - return e === qt || e === z; + let e = Ot(this, t); + return e === Wt || e === D; } else - return an(this, t); + return gn(this, t); } /** * Return distance and shortest segment between polygon and other shape as array [distance, shortest_segment] @@ -4418,17 +4572,19 @@ class st { if (t instanceof i.Point) return this.contains(t) ? [t] : []; if (t instanceof i.Line) - return kt(t, this); + return Ft(t, this); if (t instanceof i.Ray) - return rn(t, this); + return sn(t, this); if (t instanceof i.Circle) return Ke(t, this); if (t instanceof i.Segment) - return ge(t, this); + return pe(t, this); if (t instanceof i.Arc) return _e(t, this); if (t instanceof i.Polygon) - return Jn(t, this); + return Xn(t, this); + if (t instanceof i.Multiline) + return Zn(t, this); } /** * Returns new polygon translated by vector vec @@ -4436,7 +4592,7 @@ class st { * @returns {Polygon} */ translate(t) { - let e = new st(); + let e = new dt(); for (let n of this.faces) e.addFace(n.shapes.map((s) => s.translate(t))); return e; @@ -4450,7 +4606,7 @@ class st { * @returns {Polygon} - new rotated polygon */ rotate(t = 0, e = new i.Point()) { - let n = new st(); + let n = new dt(); for (let s of this.faces) n.addFace(s.shapes.map((l) => l.rotate(t, e))); return n; @@ -4462,7 +4618,7 @@ class st { * @returns {Polygon} */ scale(t, e) { - let n = new st(); + let n = new dt(); for (let s of this.faces) n.addFace(s.shapes.map((l) => l.scale(t, e))); return n; @@ -4473,7 +4629,7 @@ class st { * @returns {Polygon} - new polygon */ transform(t = new i.Matrix()) { - let e = new st(); + let e = new dt(); for (let n of this.faces) e.addFace(n.shapes.map((s) => s.transform(t))); return e; @@ -4493,6 +4649,13 @@ class st { toArray() { return [...this.faces].map((t) => t.toPolygon()); } + /** + * Return string to be assigned to 'd' attribute of element + * @returns {*} + */ + dpath() { + return [...this.faces].reduce((t, e) => t + e.svg(), ""); + } /** * Return string to draw polygon in svg * @param attrs - an object with attributes for svg path element @@ -4500,18 +4663,19 @@ class st { */ svg(t = {}) { let e = ` - `, e; } -} -i.Polygon = st; -const Ci = (...r) => new i.Polygon(...r); -i.polygon = Ci; -const { Circle: Kt, Line: Le, Point: Oe, Vector: Vt, Utils: Jt } = i; -class Ct { +}; +i.Polygon = zi; +const Yi = (...r) => new i.Polygon(...r); +i.polygon = Yi; +const { Circle: Jt, Line: Re, Point: Ue, Vector: Gt, Utils: te } = i; +class Rt { /** * Inversion constructor * @param {Circle} inversion_circle inversion circle @@ -4523,48 +4687,48 @@ class Ct { return this.circle; } static inversePoint(t, e) { - const n = new Vt(t.pc, e), s = t.r * t.r, l = n.dot(n); - return Jt.EQ_0(l) ? new Oe(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) : t.pc.translate(n.multiply(s / l)); + const n = new Gt(t.pc, e), s = t.r * t.r, l = n.dot(n); + return te.EQ_0(l) ? new Ue(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 (Jt.EQ(n, e.r)) { - let s = t.r * t.r / (2 * e.r), l = new Vt(t.pc, e.pc); + if (te.EQ(n, e.r)) { + let s = t.r * t.r / (2 * e.r), l = new Gt(t.pc, e.pc); l = l.normalize(); let o = t.pc.translate(l.multiply(s)); - return new Le(o, l); + return new Re(o, l); } else { - let s = new Vt(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 Kt(o, a); + let s = new Gt(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 Jt(o, a); } } static inverseLine(t, e) { const [n, s] = t.pc.distanceTo(e); - if (Jt.EQ_0(n)) + if (te.EQ_0(n)) return e.clone(); { - let l = t.r * t.r / (2 * n), o = new Vt(t.pc, s.end); - return o = o.multiply(l / n), new Kt(t.pc.translate(o), l); + let l = t.r * t.r / (2 * n), o = new Gt(t.pc, s.end); + return o = o.multiply(l / n), new Jt(t.pc.translate(o), l); } } inverse(t) { - if (t instanceof Oe) - return Ct.inversePoint(this.circle, t); - if (t instanceof Kt) - return Ct.inverseCircle(this.circle, t); - if (t instanceof Le) - return Ct.inverseLine(this.circle, t); + if (t instanceof Ue) + return Rt.inversePoint(this.circle, t); + if (t instanceof Jt) + return Rt.inverseCircle(this.circle, t); + if (t instanceof Re) + return Rt.inverseLine(this.circle, t); } } -i.Inversion = Ct; -const Ni = (r) => new i.Inversion(r); -i.inversion = Ni; +i.Inversion = Rt; +const Qi = (r) => new i.Inversion(r); +i.inversion = Qi; class d { /** * Calculate distance and shortest segment between points * @param pt1 * @param pt2 - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static point2point(t, e) { return t.distanceTo(e); @@ -4573,7 +4737,7 @@ class d { * Calculate distance and shortest segment between point and line * @param pt * @param line - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static point2line(t, e) { let n = t.projectionOn(e); @@ -4583,7 +4747,7 @@ class d { * Calculate distance and shortest segment between point and circle * @param pt * @param circle - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static point2circle(t, e) { let [n, s] = t.distanceTo(e.center); @@ -4598,33 +4762,41 @@ class d { * Calculate distance and shortest segment between point and segment * @param pt * @param segment - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ 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; + 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), f, h; 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); + let u = e.tangentInStart(); + return f = Math.abs(u.cross(s)), h = e.start.translate(u.multiply(u.dot(s))), [f, new i.Segment(t, h)]; + } else return o < 0 ? t.distanceTo(e.start) : t.distanceTo(e.end); } /** * Calculate distance and shortest segment between point and arc * @param pt * @param arc - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ 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]; } + /** + * Calculate distance and shortest segment between point and edge + * @param pt + * @param edge + * @returns {[number, Flatten.Segment]} + */ + static point2edge(t, e) { + return e.shape instanceof i.Segment ? d.point2segment(t, e.shape) : d.point2arc(t, e.shape); + } /** * Calculate distance and shortest segment between segment and line * @param seg * @param line - * @returns {Number | Segment} + * @returns {[number, Flatten.Segment]} */ static segment2line(t, e) { let n = t.intersect(e); @@ -4637,7 +4809,7 @@ class d { * Calculate distance and shortest segment between two segments * @param seg1 * @param seg2 - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static segment2segment(t, e) { let n = jt(t, e); @@ -4650,7 +4822,7 @@ class d { * Calculate distance and shortest segment between segment and circle * @param seg * @param circle - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static segment2circle(t, e) { let n = t.intersect(e); @@ -4660,15 +4832,15 @@ class d { 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]; + let [a, f] = d.point2circle(t.start, e), [h, u] = d.point2circle(t.end, e); + return i.Utils.LT(a, h) ? [a, f] : [h, u]; } } /** * Calculate distance and shortest segment between segment and arc * @param seg * @param arc - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static segment2arc(t, e) { let n = t.intersect(e); @@ -4676,20 +4848,20 @@ 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, p] = d.point2circle(a.end, l); - if (p.end.on(e)) - return [g, p]; + let [g, _] = d.point2circle(a.end, l); + if (_.end.on(e)) + return [g, _]; } - 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]; + let f = []; + f.push(d.point2arc(t.start, e)), f.push(d.point2arc(t.end, e)); + let h, u; + return [h, u] = d.point2segment(e.start, t), f.push([h, u.reverse()]), [h, u] = d.point2segment(e.end, t), f.push([h, u.reverse()]), d.sort(f), f[0]; } /** * Calculate distance and shortest segment between two circles * @param circle1 * @param circle2 - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static circle2circle(t, e) { let n = t.intersect(e); @@ -4707,7 +4879,7 @@ class d { * Calculate distance and shortest segment between two circles * @param circle * @param line - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static circle2line(t, e) { let n = t.intersect(e); @@ -4720,7 +4892,7 @@ class d { * Calculate distance and shortest segment between arc and line * @param arc * @param line - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static arc2line(t, e) { let n = e.intersect(t); @@ -4728,9 +4900,9 @@ class d { 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]; + let [a, f] = d.point2circle(o.end, s); + if (f.end.on(t)) + return [a, f]; } else { let a = []; return a.push(d.point2line(t.start, e)), a.push(d.point2line(t.end, e)), d.sort(a), a[0]; @@ -4740,7 +4912,7 @@ class d { * Calculate distance and shortest segment between arc and circle * @param arc * @param circle2 - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static arc2circle(t, e) { let n = t.intersect(e); @@ -4758,7 +4930,7 @@ class d { * Calculate distance and shortest segment between two arcs * @param arc1 * @param arc2 - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static arc2arc(t, e) { let n = t.intersect(e); @@ -4768,20 +4940,20 @@ class d { 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]; + let f = [], h, u; + return [h, u] = d.point2arc(t.start, e), u.end.on(e) && f.push([h, u]), [h, u] = d.point2arc(t.end, e), u.end.on(e) && f.push([h, u]), [h, u] = d.point2arc(e.start, t), u.end.on(t) && f.push([h, u.reverse()]), [h, u] = d.point2arc(e.end, t), u.end.on(t) && f.push([h, u.reverse()]), [h, u] = d.point2point(t.start, e.start), f.push([h, u]), [h, u] = d.point2point(t.start, e.end), f.push([h, u]), [h, u] = d.point2point(t.end, e.start), f.push([h, u]), [h, u] = d.point2point(t.end, e.end), f.push([h, u]), d.sort(f), f[0]; } } /** * Calculate distance and shortest segment between point and polygon * @param point * @param polygon - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ 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); + let [l, o] = d.point2edge(t, s); i.Utils.LT(l, n[0]) && (n = [l, o]); } return n; @@ -4798,7 +4970,7 @@ class d { * Calculate distance and shortest segment between two polygons * @param polygon1 * @param polygon2 - * @returns {Number | Segment} - distance and shortest segment + * @returns {[number, Flatten.Segment]} - distance and shortest segment */ static polygon2polygon(t, e) { let n = [Number.POSITIVE_INFINITY, new i.Segment()]; @@ -4824,20 +4996,20 @@ class d { * @returns {Number | Number} - minimal and maximal distance */ 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]; + 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, f = o.ymax - o.ymin, h = a * a + f * f; + return [l, h]; } 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); + for (let u of e) + [l, o] = d.box2box_minmax(t.box, u.item.key), u.item.value instanceof i.Edge ? s.insert([l, o], u.item.value.shape) : s.insert([l, o], u.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); + let a = e.map((u) => u.left.isNil() ? void 0 : u.left).filter((u) => u !== void 0), f = e.map((u) => u.right.isNil() ? void 0 : u.right).filter((u) => u !== void 0), h = [...a, ...f].filter((u) => { + let [g, _] = d.box2box_minmax(t.box, u.max); return i.Utils.LE(g, n); }); - return n = d.minmax_tree_process_level(t, u, n, s), n; + return n = d.minmax_tree_process_level(t, h, n, s), n; } /** * Calculates sorted tree of [mindist, maxdist] intervals between query shape @@ -4846,7 +5018,7 @@ class d { * @param set */ static minmax_tree(t, e, n) { - let s = new Rt(), l = [e.index.root], o = n < Number.POSITIVE_INFINITY ? n * n : Number.POSITIVE_INFINITY; + let s = new Mt(), l = [e.index.root], o = n < Number.POSITIVE_INFINITY ? n * n : Number.POSITIVE_INFINITY; return o = d.minmax_tree_process_level(t, l, o, s), s; } static minmax_tree_calc_distance(t, e, n) { @@ -4882,11 +5054,130 @@ class d { static distance(t, e) { return t.distanceTo(e); } + /** + * Calculate distance and shortest segment any shape and multiline + * @param shape + * @param multiline + * @returns {[number, Flatten.Segment]} + */ + static shape2multiline(t, e) { + let n = [Number.POSITIVE_INFINITY, new i.Segment()]; + for (let s of e) { + let [l, o] = d.distance(t, s.shape); + i.Utils.LT(l, n[0]) && (n = [l, o]); + } + return n; + } + /** + * Calculate distance and shortest segment between two multilines + * @param multiline1 + * @param multiline2 + * @returns {[number, Flatten.Segment]} + */ + static multiline2multiline(t, e) { + let n = [Number.POSITIVE_INFINITY, new i.Segment()]; + for (let s of t) + for (let l of e) { + let [o, a] = d.distance(s.shape, l.shape); + i.Utils.LT(o, n[0]) && (n = [o, a]); + } + return n; + } } i.Distance = d; -i.BooleanOperations = $n; -i.Relations = di; -const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { +const { Multiline: ji, Point: En, Segment: Zi, Polygon: xn } = i; +function we(r) { + return new En(r.split(" ").map(Number)); +} +function Tn(r) { + return r.split(", ").map(we); +} +function Ie(r) { + const t = Tn(r); + let e = []; + for (let n = 0; n < t.length - 1; n++) + e.push(new Zi(t[n], t[n + 1])); + return new ji(e); +} +function Xi(r) { + return r.replace(/\(\(/, "").replace(/\)\)$/, "").split("), (").map(Ie); +} +function wn(r) { + const t = r.replace(/\(\(/, "").replace(/\)\)$/, "").split("), ("), e = new xn(); + let n; + return t.forEach((s, l) => { + let o = s.split(", ").map((f) => new En(f.split(" ").map(Number))); + const a = e.addFace(o); + l === 0 ? n = a.orientation() : a.orientation() === n && a.reverse(); + }), e; +} +function Ki(r) { + const e = r.split(/\)\), \(\(/).map((l) => "((" + l + "))").map(wn), n = new xn(); + return e.reduce((l, o) => [...l, ...o == null ? void 0 : o.faces], []).forEach((l) => n.addFace([...l == null ? void 0 : l.shapes])), n; +} +function Ji(r) { + if (r.startsWith("POLYGON")) { + const t = r.replace(/^POLYGON /, ""); + return wn(t); + } else { + const t = r.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/, "$1"); + return Ki(t); + } +} +function tr(r) { + return r.split(` +`).map((e) => e.match(/\(([^)]+)\)/)[1]).map(we); +} +function er(r) { + return r.split(` +`).map((e) => e.match(/\(([^)]+)\)/)[1]).map(Ie).reduce((e, n) => [...e, ...n], []); +} +function In(r) { + if (r.startsWith("POINT")) { + const t = r.replace(/^POINT \(/, "").replace(/\)$/, ""); + return we(t); + } else if (r.startsWith("MULTIPOINT")) { + const t = r.replace(/^MULTIPOINT \(/, "").replace(/\)$/, ""); + return Tn(t); + } else if (r.startsWith("LINESTRING")) { + const t = r.replace(/^LINESTRING \(/, "").replace(/\)$/, ""); + return Ie(t); + } else if (r.startsWith("MULTILINESTRING")) { + const t = r.replace(/^MULTILINESTRING /, ""); + return Xi(t); + } else { + if (r.startsWith("POLYGON") || r.startsWith("MULTIPOLYGON")) + return Ji(r); + if (r.startsWith("GEOMETRYCOLLECTION")) { + const t = /(?POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g, e = r.match(t); + return e[0].startsWith("GEOMETRYCOLLECTION") && (e[0] = e[0].replace("GEOMETRYCOLLECTION (", "")), e.map(In).map((s) => s instanceof Array ? s : [s]).reduce((s, l) => [...s, ...l], []); + } else { + if (Sn(r)) + return tr(r); + if (vn(r)) + return er(r); + } + } + return []; +} +function Sn(r) { + var t; + return (t = r.split(` +`)) == null ? void 0 : t.every((e) => e.includes("POINT")); +} +function vn(r) { + var t; + return (t = r.split(` +`)) == null ? void 0 : t.every((e) => e.includes("LINESTRING")); +} +function nr(r) { + return r.startsWith("POINT") || Sn(r) || r.startsWith("LINESTRING") || vn(r) || r.startsWith("MULTILINESTRING") || r.startsWith("POLYGON") || r.startsWith("MULTIPOINT") || r.startsWith("MULTIPOLYGON") || r.startsWith("GEOMETRYCOLLECTION"); +} +i.isWktString = nr; +i.parseWKT = In; +i.BooleanOperations = di; +i.Relations = Li; +const Me = i.Matrix, qt = 24, ee = 60, y = class y extends bn { /** * TrackSymbol constructor. * @@ -4894,10 +5185,10 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { * @param options - Options. */ constructor(t, e) { - if (super(), Be.setOptions(this, e), t == null) + if (super(), $e.setOptions(this, e), t == null) throw Error("latLng required"); - e = e || {}, this._latLng = xt.latLng(t), this._heading = e.heading, this._course = e.course, this._speed = e.speed, this._shapeOptions = e.shapeOptions || { - leaderTime: te, + e = e || {}, this._latLng = Et.latLng(t), this._heading = e.heading, this._course = e.course, this._speed = e.speed, this._shapeOptions = e.shapeOptions || { + leaderTime: ee, defaultShapeSet: y.DEFAULT_SHAPE_SET }, this._setShapeOptions(e.shapeOptions); } @@ -4909,7 +5200,7 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { */ _project() { this._currentShapePoints = this._getProjectedShapePoints(), this._currentLeaderPoints = this._getLeaderShapePoints(); - const t = new mn(); + const t = new On(); for (let e = 0; e < this._currentShapePoints.length; e++) { const n = this._currentShapePoints[e]; t.extend(n); @@ -4919,7 +5210,7 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { const n = this._currentShapePoints[e]; t.extend(n); } - this._currentBounds = t, this._currentLatLngBounds = new xn( + this._currentBounds = t, this._currentLatLngBounds = new Nn( this._map.layerPointToLatLng(t.getBottomLeft()), this._map.layerPointToLatLng(t.getTopRight()) ); @@ -4948,9 +5239,9 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { */ _setShapeOptions(t) { this._shapeOptions = t || { - leaderTime: te, + leaderTime: ee, defaultShapeSet: y.DEFAULT_SHAPE_SET - }, this._shapeOptions.leaderTime === void 0 && (this._shapeOptions.leaderTime = te), this._shapeOptions.defaultShapeSet === void 0 && (this._shapeOptions.defaultShapeSet = y.DEFAULT_SHAPE_SET), this._shapeOptions.shapeSetEntries !== void 0 && this._shapeOptions.shapeSetEntries.sort((e, n) => n.minZoomLevel - e.minZoomLevel); + }, this._shapeOptions.leaderTime === void 0 && (this._shapeOptions.leaderTime = ee), this._shapeOptions.defaultShapeSet === void 0 && (this._shapeOptions.defaultShapeSet = y.DEFAULT_SHAPE_SET), this._shapeOptions.shapeSetEntries !== void 0 && this._shapeOptions.shapeSetEntries.sort((e, n) => n.minZoomLevel - e.minZoomLevel); } // --- /** @@ -4961,7 +5252,7 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { */ setLatLng(t) { const e = this._latLng; - return this._latLng = xt.latLng(t), this.fire("move", { + return this._latLng = Et.latLng(t), this.fire("move", { oldLatLng: e, latlng: this._latLng }), this.redraw(); @@ -5116,7 +5407,7 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { * @returns Calculated LatLng. */ _calcRelativeLatLng(t, e, n) { - return new Ee( + return new Se( t.lat - this._getLatSizeOf(e * Math.sin(n)), t.lng + this._getLngSizeOf(e * Math.cos(n)) ); @@ -5157,7 +5448,7 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { */ _getTransformedShapePoints() { const t = this._getShape(); - let e = new Ce(); + let e = new Me(); if (this._heading !== void 0) { const s = this._getViewAngleFromModel(this._heading); e = e.rotate(s); @@ -5173,15 +5464,15 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { const [t, e] = this._getTransformedShapePoints(); switch (e) { case "pixels": { - const n = this._map.latLngToLayerPoint(this._latLng), s = new Ce().translate(n.x, n.y); + const n = this._map.latLngToLayerPoint(this._latLng), s = new Me().translate(n.x, n.y); return t.map((l) => { const o = s.transform(l); - return new En(o[0], o[1]); + return new Cn(o[0], o[1]); }); } case "meters": return t.map((n) => this._map.latLngToLayerPoint( - new Ee( + new Se( this._latLng.lat - this._getLatSizeOf(n[1]), this._latLng.lng + this._getLngSizeOf(n[0]) ) @@ -5209,57 +5500,57 @@ const Ce = i.Matrix, Ht = 24, te = 60, y = class y extends pn { y.DEFAULT_HEADING_SHAPE_POINTS = [[0.75, 0], [-0.25, 0.3], [-0.25, -0.3]], y.DEFAULT_NOHEADING_SHAPE_POINTS = [[0.3, 0], [0, 0.3], [-0.3, 0], [0, -0.3]], y.DEFAULT_SHAPE_SET = { withHeading: { points: y.DEFAULT_HEADING_SHAPE_POINTS, - length: Ht, - breadth: Ht, + length: qt, + breadth: qt, units: "pixels" }, withoutHeading: { points: y.DEFAULT_NOHEADING_SHAPE_POINTS, - length: Ht, - breadth: Ht, + length: qt, + breadth: qt, units: "pixels" } }; -let nt = y; -const Ri = 24, Ui = 14, Mi = 60, Bi = 1.944, Ne = 102.3, ki = 360, Fi = 360, cn = "#000000", dn = "#d3d3d3", C = "#000000", N = "#d3d3d3", J = "#8b008b", tt = "#ff00ff", M = "#00008b", B = "#ffff00", j = "#008b8b", Z = "#00ffff", k = "#00008b", F = "#0000ff", V = "#006400", H = "#90ee90", $ = "#8b0000", q = "#ff0000", G = "#008b8b", D = "#00ffff", Re = { - 0: c("Not available", C, N), - 20: c("Wing in ground (WIG), all ships of this type", C, N), - 21: c("Wing in ground (WIG), Hazardous category A", C, N), - 22: c("Wing in ground (WIG), Hazardous category B", C, N), - 23: c("Wing in ground (WIG), Hazardous category C", C, N), - 24: c("Wing in ground (WIG), Hazardous category D", C, N), - 25: c("Wing in ground (WIG), Reserved for future use", C, N), - 26: c("Wing in ground (WIG), Reserved for future use", C, N), - 27: c("Wing in ground (WIG), Reserved for future use", C, N), - 28: c("Wing in ground (WIG), Reserved for future use", C, N), - 29: c("Wing in ground (WIG), Reserved for future use", C, N), - 30: c("Fishing", J, tt), - 31: c("Towing", J, tt), - 32: c("Towing: length exceeds 200m or breadth exceeds 25m", J, tt), - 33: c("Dredging or underwater ops", J, tt), - 34: c("Diving ops", J, tt), - 35: c("Military ops", J, tt), - 36: c("Sailing", J, tt), - 37: c("Pleasure Craft", J, tt), - 40: c("High speed craft (HSC), all ships of this type", M, B), - 41: c("High speed craft (HSC), Hazardous category A", M, B), - 42: c("High speed craft (HSC), Hazardous category B", M, B), - 43: c("High speed craft (HSC), Hazardous category C", M, B), - 44: c("High speed craft (HSC), Hazardous category D", M, B), - 45: c("High speed craft (HSC), Reserved for future use", M, B), - 46: c("High speed craft (HSC), Reserved for future use", M, B), - 47: c("High speed craft (HSC), Reserved for future use", M, B), - 48: c("High speed craft (HSC), Reserved for future use", M, B), - 49: c("High speed craft (HSC), No additional information", M, B), - 50: c("Pilot Vessel", j, Z), - 51: c("Search and Rescue vessel", j, Z), - 52: c("Tug", j, Z), - 53: c("Port Tender", j, Z), - 54: c("Anti-pollution equipment", j, Z), - 55: c("Law Enforcement", j, Z), - 56: c("Spare - Local Vessel", j, Z), - 57: c("Spare - Local Vessel", j, Z), - 58: c("Medical Transport", j, Z), +let et = y; +const ir = 24, rr = 14, sr = 60, or = 1.944, ke = 102.3, lr = 360, ar = 360, yn = "#000000", Pn = "#d3d3d3", N = "#000000", C = "#d3d3d3", K = "#8b008b", J = "#ff00ff", U = "#00008b", M = "#ffff00", Q = "#008b8b", j = "#00ffff", k = "#00008b", F = "#0000ff", B = "#006400", V = "#90ee90", $ = "#8b0000", H = "#ff0000", G = "#008b8b", q = "#00ffff", Fe = { + 0: c("Not available", N, C), + 20: c("Wing in ground (WIG), all ships of this type", N, C), + 21: c("Wing in ground (WIG), Hazardous category A", N, C), + 22: c("Wing in ground (WIG), Hazardous category B", N, C), + 23: c("Wing in ground (WIG), Hazardous category C", N, C), + 24: c("Wing in ground (WIG), Hazardous category D", N, C), + 25: c("Wing in ground (WIG), Reserved for future use", N, C), + 26: c("Wing in ground (WIG), Reserved for future use", N, C), + 27: c("Wing in ground (WIG), Reserved for future use", N, C), + 28: c("Wing in ground (WIG), Reserved for future use", N, C), + 29: c("Wing in ground (WIG), Reserved for future use", N, C), + 30: c("Fishing", K, J), + 31: c("Towing", K, J), + 32: c("Towing: length exceeds 200m or breadth exceeds 25m", K, J), + 33: c("Dredging or underwater ops", K, J), + 34: c("Diving ops", K, J), + 35: c("Military ops", K, J), + 36: c("Sailing", K, J), + 37: c("Pleasure Craft", K, J), + 40: c("High speed craft (HSC), all ships of this type", U, M), + 41: c("High speed craft (HSC), Hazardous category A", U, M), + 42: c("High speed craft (HSC), Hazardous category B", U, M), + 43: c("High speed craft (HSC), Hazardous category C", U, M), + 44: c("High speed craft (HSC), Hazardous category D", U, M), + 45: c("High speed craft (HSC), Reserved for future use", U, M), + 46: c("High speed craft (HSC), Reserved for future use", U, M), + 47: c("High speed craft (HSC), Reserved for future use", U, M), + 48: c("High speed craft (HSC), Reserved for future use", U, M), + 49: c("High speed craft (HSC), No additional information", U, M), + 50: c("Pilot Vessel", Q, j), + 51: c("Search and Rescue vessel", Q, j), + 52: c("Tug", Q, j), + 53: c("Port Tender", Q, j), + 54: c("Anti-pollution equipment", Q, j), + 55: c("Law Enforcement", Q, j), + 56: c("Spare - Local Vessel", Q, j), + 57: c("Spare - Local Vessel", Q, j), + 58: c("Medical Transport", Q, j), 59: c("Noncombatant ship according to RR Resolution No. 18", "", ""), 60: c("Passenger, all ships of this type", k, F), 61: c("Passenger, Hazardous category A", k, F), @@ -5271,37 +5562,37 @@ const Ri = 24, Ui = 14, Mi = 60, Bi = 1.944, Ne = 102.3, ki = 360, Fi = 360, cn 67: c("Passenger, Reserved for future use", k, F), 68: c("Passenger, Reserved for future use", k, F), 69: c("Passenger, No additional information", k, F), - 70: c("Cargo, all ships of this type", V, H), - 71: c("Cargo, Hazardous category A", V, H), - 72: c("Cargo, Hazardous category B", V, H), - 73: c("Cargo, Hazardous category C", V, H), - 74: c("Cargo, Hazardous category D", V, H), - 75: c("Cargo, Reserved for future use", V, H), - 76: c("Cargo, Reserved for future use", V, H), - 77: c("Cargo, Reserved for future use", V, H), - 78: c("Cargo, Reserved for future use", V, H), - 79: c("Cargo, No additional information", V, H), - 80: c("Tanker, all ships of this type", $, q), - 81: c("Tanker, Hazardous category A", $, q), - 82: c("Tanker, Hazardous category B", $, q), - 83: c("Tanker, Hazardous category C", $, q), - 84: c("Tanker, Hazardous category D", $, q), - 85: c("Tanker, Reserved for future use", $, q), - 86: c("Tanker, Reserved for future use", $, q), - 87: c("Tanker, Reserved for future use", $, q), - 88: c("Tanker, Reserved for future use", $, q), - 89: c("Tanker, No additional information", $, q), - 90: c("Other Type, all ships of this type", G, D), - 91: c("Other Type, Hazardous category A", G, D), - 92: c("Other Type, Hazardous category B", G, D), - 93: c("Other Type, Hazardous category C", G, D), - 94: c("Other Type, Hazardous category D", G, D), - 95: c("Other Type, Reserved for future use", G, D), - 96: c("Other Type, Reserved for future use", G, D), - 97: c("Other Type, Reserved for future use", G, D), - 98: c("Other Type, Reserved for future use", G, D), - 99: c("Other Type, no additional information", G, D) -}, Vi = c("Reserved", cn, dn), Hi = c("Unknown", cn, dn), pt = class pt extends nt { + 70: c("Cargo, all ships of this type", B, V), + 71: c("Cargo, Hazardous category A", B, V), + 72: c("Cargo, Hazardous category B", B, V), + 73: c("Cargo, Hazardous category C", B, V), + 74: c("Cargo, Hazardous category D", B, V), + 75: c("Cargo, Reserved for future use", B, V), + 76: c("Cargo, Reserved for future use", B, V), + 77: c("Cargo, Reserved for future use", B, V), + 78: c("Cargo, Reserved for future use", B, V), + 79: c("Cargo, No additional information", B, V), + 80: c("Tanker, all ships of this type", $, H), + 81: c("Tanker, Hazardous category A", $, H), + 82: c("Tanker, Hazardous category B", $, H), + 83: c("Tanker, Hazardous category C", $, H), + 84: c("Tanker, Hazardous category D", $, H), + 85: c("Tanker, Reserved for future use", $, H), + 86: c("Tanker, Reserved for future use", $, H), + 87: c("Tanker, Reserved for future use", $, H), + 88: c("Tanker, Reserved for future use", $, H), + 89: c("Tanker, No additional information", $, H), + 90: c("Other Type, all ships of this type", G, q), + 91: c("Other Type, Hazardous category A", G, q), + 92: c("Other Type, Hazardous category B", G, q), + 93: c("Other Type, Hazardous category C", G, q), + 94: c("Other Type, Hazardous category D", G, q), + 95: c("Other Type, Reserved for future use", G, q), + 96: c("Other Type, Reserved for future use", G, q), + 97: c("Other Type, Reserved for future use", G, q), + 98: c("Other Type, Reserved for future use", G, q), + 99: c("Other Type, no additional information", G, q) +}, fr = c("Reserved", yn, Pn), ur = c("Unknown", yn, Pn), _t = class _t extends et { /** * AISTrackSymbol constructor. * @@ -5309,7 +5600,7 @@ const Ri = 24, Ui = 14, Mi = 60, Bi = 1.944, Ne = 102.3, ki = 360, Fi = 360, cn * @param options - Options. */ constructor(t, e) { - super([t.latitude, t.longitude], e), Be.setOptions(this, e), e = e || {}, this._leaderTime = e.leaderTime || Mi, this._minZoomLevel = e.minZoomLevel || Ui, this._size = e.size || Ri, this._positionReport = t, this.setPositionReport(t), this.setShipStaticData(e.shipStaticData); + super([t.latitude, t.longitude], e), $e.setOptions(this, e), e = e || {}, this._leaderTime = e.leaderTime || sr, this._minZoomLevel = e.minZoomLevel || rr, this._size = e.size || ir, this._positionReport = t, this.setPositionReport(t), this.setShipStaticData(e.shipStaticData); } /** * Get ETA from Date. @@ -5333,7 +5624,7 @@ const Ri = 24, Ui = 14, Mi = 60, Bi = 1.944, Ne = 102.3, ki = 360, Fi = 360, cn * @returns this */ setPositionReport(t) { - return this._positionReport = t, this.setLatLng([t.latitude, t.longitude]), t.trueHeading !== null && t.trueHeading !== void 0 && t.trueHeading < Fi ? this.setHeading(Ue(t.trueHeading)) : this.setHeading(void 0), t.cog !== null && t.cog !== void 0 && t.cog < ki ? this.setCourse(Ue(t.cog)) : this.setCourse(void 0), t.sog !== null && t.sog !== void 0 && t.sog < Ne ? this.setSpeed(t.sog / Bi) : this.setSpeed(void 0), this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData)), this.redraw(); + return this._positionReport = t, this.setLatLng([t.latitude, t.longitude]), t.trueHeading !== null && t.trueHeading !== void 0 && t.trueHeading < ar ? this.setHeading(Be(t.trueHeading)) : this.setHeading(void 0), t.cog !== null && t.cog !== void 0 && t.cog < lr ? this.setCourse(Be(t.cog)) : this.setCourse(void 0), t.sog !== null && t.sog !== void 0 && t.sog < ke ? this.setSpeed(t.sog / or) : this.setSpeed(void 0), this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData)), this.redraw(); } /** * Sets the ship static data. @@ -5343,13 +5634,13 @@ const Ri = 24, Ui = 14, Mi = 60, Bi = 1.944, Ne = 102.3, ki = 360, Fi = 360, cn */ setShipStaticData(t) { this._shipStaticData = t; - const e = gn(t != null ? t.type : void 0); + const e = Ln(t != null ? t.type : void 0); return this.setStyle({ color: e.color, fill: !0, fillOpacity: 1, fillColor: e.fillColor - }), this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData)), this.setShapeOptions(pt._getShapeOptions( + }), this.bindPopup(this._getPopupContent(this._positionReport, this._shipStaticData)), this.setShapeOptions(_t._getShapeOptions( this._leaderTime, this._minZoomLevel, this._size, @@ -5359,69 +5650,69 @@ const Ri = 24, Ui = 14, Mi = 60, Bi = 1.944, Ne = 102.3, ki = 360, Fi = 360, cn static _getShapeOptions(t, e, n, s) { const l = { leaderTime: t, - defaultShapeSet: nt.createShapeSet(n) - }, o = pt._getShapeSet(n, s); + defaultShapeSet: et.createShapeSet(n) + }, o = _t._getShapeSet(n, s); return o !== null && (l.shapeSetEntries = [{ shapeSet: o, minZoomLevel: e }]), l; } static _getShapeSet(t, e) { - return e == null || e.dimension === null || e.dimension === void 0 || !Me(e.dimension) ? null : { + return e == null || e.dimension === null || e.dimension === void 0 || !Ve(e.dimension) ? null : { withHeading: { - points: pt.DEFAULT_SILHOUETTE_SHAPE_POINTS, + points: _t.DEFAULT_SILHOUETTE_SHAPE_POINTS, center: [e.dimension.B, e.dimension.D], length: e.dimension.A + e.dimension.B, breadth: e.dimension.C + e.dimension.D, units: "meters" }, - withoutHeading: nt.createShape(nt.DEFAULT_NOHEADING_SHAPE_POINTS, t) + withoutHeading: et.createShape(et.DEFAULT_NOHEADING_SHAPE_POINTS, t) }; } _getPopupContent(t, e) { let n = ""; - e != null && (n += P("User ID", e.userId), n += P("IMO Number", e.imoNumber), n += P("Call sign", e.callSign), n += P("Name", e.name)), t != null && (n += P("Location", `${ct(t.latitude, 5)}, ${ct(t.longitude, 5)}`), n += P( + e != null && (n += A("User ID", e.userId), n += A("IMO Number", e.imoNumber), n += A("Call sign", e.callSign), n += A("Name", e.name)), t != null && (n += A("Location", `${ht(t.latitude, 5)}, ${ht(t.longitude, 5)}`), n += A( "SOG", - ct(t.sog, 2, (l) => l < Ne), + ht(t.sog, 2, (l) => l < ke), "knots" - ), n += P( + ), n += A( "COG", - ct(t.cog, 1), + ht(t.cog, 1), "°" - ), n += P( + ), n += A( "Heading", - ct(t.trueHeading, 1), + ht(t.trueHeading, 1), "°" - ), n += P( + ), n += A( "Navigation status", - Gi(t.navigationalStatus) - )), e != null && (n += P("Type", $i(e.type)), e.dimension !== null && e.dimension !== void 0 && Me(e.dimension) && (n += P( + dr(t.navigationalStatus) + )), e != null && (n += A("Type", hr(e.type)), e.dimension !== null && e.dimension !== void 0 && Ve(e.dimension) && (n += A( "Ship length", e.dimension.A + e.dimension.B, "m" - ), n += P( + ), n += A( "Ship width", e.dimension.C + e.dimension.D, "m" - )), n += P("Fix type", qi(e.fixType)), n += P("ETA", Di(e.eta)), n += P( + )), n += A("Fix type", cr(e.fixType)), n += A("ETA", gr(e.eta)), n += A( "Maximum static draught", - ct(e.maximumStaticDraught, 1), + ht(e.maximumStaticDraught, 1), "m" - ), n += P("Destination", e.destination), n += P("DTE", e.dte)), n += "
"; - const s = vn.create("div"); + ), n += A("Destination", e.destination), n += A("DTE", e.dte)), n += ""; + const s = Rn.create("div"); return s.innerHTML = n, s; } }; -pt.DEFAULT_SILHOUETTE_SHAPE_POINTS = [[1, 0.5], [0.75, 1], [0, 1], [0, 0], [0.75, 0]]; -let Qt = pt; -function ct(r, t, e) { +_t.DEFAULT_SILHOUETTE_SHAPE_POINTS = [[1, 0.5], [0.75, 1], [0, 1], [0, 0], [0.75, 0]]; +let Yt = _t; +function ht(r, t, e) { if (r != null && !(e && !e(r))) return r.toFixed(t); } -function $i(r) { - return r == null ? void 0 : gn(r).name; +function hr(r) { + return r == null ? void 0 : Ln(r).name; } -function qi(r) { +function cr(r) { if (r != null) switch (r) { case 0: @@ -5455,7 +5746,7 @@ function qi(r) { return `unknown (${r})`; } } -function Gi(r) { +function dr(r) { if (r != null) switch (r) { case 0: @@ -5494,28 +5785,28 @@ function Gi(r) { return `unknown (${r})`; } } -function Di(r) { +function gr(r) { if (r == null) return; const t = []; - if (!_t(r.month) && !_t(r.day) && t.push(`${r.month.toString().padStart(2, "0")}/${r.day.toString().padStart(2, "0")}`), !_t(r.hour) && !_t(r.minute) && t.push(`${r.hour.toString().padStart(2, "0")}:${r.minute.toString().padStart(2, "0")}`), t.length !== 0) + if (!pt(r.month) && !pt(r.day) && t.push(`${r.month.toString().padStart(2, "0")}/${r.day.toString().padStart(2, "0")}`), !pt(r.hour) && !pt(r.minute) && t.push(`${r.hour.toString().padStart(2, "0")}:${r.minute.toString().padStart(2, "0")}`), t.length !== 0) return `${t.join(" ")} UTC`; } -function Ue(r) { +function Be(r) { if (r != null) return r * Math.PI / 180; } -function _t(r) { +function pt(r) { return r == null; } -function Me(r) { +function Ve(r) { return r != null && r.A > 0 && r.B > 0 && r.C > 0 && r.D > 0; } -function P(r, t, e) { +function A(r, t, e) { if (t == null) return ""; const n = String(t); - return `${r}${n} ${_t(e) ? "" : e}`; + return `${r}${n} ${pt(e) ? "" : e}`; } function c(r, t, e) { return { @@ -5524,25 +5815,25 @@ function c(r, t, e) { fillColor: e }; } -function gn(r) { +function Ln(r) { if (r == null) - return Re[0]; + return Fe[0]; if (r < 0 || r > 99) - return Hi; - const t = Re[r]; - return _t(t) ? Vi : t; + return ur; + const t = Fe[r]; + return pt(t) ? fr : t; } -xt.trackSymbol = function(r, t) { - return new nt(r, t); +Et.trackSymbol = function(r, t) { + return new et(r, t); }; -xt.TrackSymbol = nt; -xt.aisTrackSymbol = function(r, t) { - return new Qt(r, t); +Et.TrackSymbol = et; +Et.aisTrackSymbol = function(r, t) { + return new Yt(r, t); }; -xt.AISTrackSymbol = Qt; +Et.AISTrackSymbol = Yt; export { - Qt as AISTrackSymbol, - nt as TrackSymbol, - nt as default + Yt as AISTrackSymbol, + et as TrackSymbol, + et as default }; //# sourceMappingURL=leaflet-tracksymbol2.es.js.map diff --git a/dist/leaflet-tracksymbol2.es.js.map b/dist/leaflet-tracksymbol2.es.js.map index 4ce4a87..54b4916 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.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 +{"version":3,"file":"leaflet-tracksymbol2.es.js","sources":["../node_modules/.pnpm/@flatten-js+core@1.6.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 static get UNSUPPORTED_SHAPE_TYPE() {\n return new Error('Unsupported shape type')\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\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 * 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 intersectMultiline2Polygon(multiline, polygon) {\n let ip = [];\n\n if (polygon.isEmpty() || multiline.size === 0) {\n return ip;\n }\n\n for (let edge of multiline) {\n ip = [...ip, ...intersectEdge2Polygon(edge, polygon)];\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\nfunction intersectShape2Shape(shape1, shape2) {\n if (shape1.intersect && shape1.intersect instanceof Function) {\n return shape1.intersect(shape2)\n }\n throw Errors.UNSUPPORTED_SHAPE_TYPE\n}\n\nfunction intersectShape2Multiline(shape, multiline) {\n let ip = [];\n for (let edge of multiline) {\n ip = [...ip, ...intersectShape2Shape(edge, edge.shape)];\n }\n return ip;\n}\n\nfunction intersectMultiline2Multiline(multiline1, multiline2) {\n let ip = [];\n for (let edge1 of multiline1) {\n for (let edge2 of multiline2) {\n ip = [...ip, ...intersectShape2Shape(edge1, edge2)];\n }\n }\n return ip;\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 */\nlet Multiline$1 = class Multiline extends LinkedList {\n constructor(...args) {\n super();\n this.isInfinite = false;\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length > 0) {\n // there may be only one line and\n // only first and last may be rays\n let validShapes = false;\n const shapes = args[0];\n const L = shapes.length;\n const anyShape = (s) =>\n s instanceof Flatten.Segment || s instanceof Flatten.Arc ||\n s instanceof Flatten.Ray || s instanceof Flatten.Line;\n const anyShapeExceptLine = (s) =>\n s instanceof Flatten.Segment || s instanceof Flatten.Arc || s instanceof Flatten.Ray;\n const shapeSegmentOrArc = (s) => s instanceof Flatten.Segment || s instanceof Flatten.Arc;\n validShapes =\n L === 1 && anyShape(shapes[0]) ||\n L > 1 && anyShapeExceptLine(shapes[0]) && anyShapeExceptLine(shapes[L - 1]) &&\n shapes.slice(1, L - 1).every(shapeSegmentOrArc);\n\n if (validShapes) {\n this.isInfinite = shapes.some(shape =>\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 } else {\n throw Flatten.Errors.ILLEGAL_PARAMETERS;\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 * (Getter) Returns length of the multiline, return POSITIVE_INFINITY if multiline is infinite\n * @returns {number}\n */\n get length() {\n if (this.isEmpty()) return 0;\n if (this.isInfinite) return Number.POSITIVE_INFINITY;\n\n let len = 0;\n for (let edge of this) {\n len += edge.length;\n }\n return len\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 multiline.\n * Arc_length of the edge is the arc length from the multiline start vertex to the edge start vertex\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 * Return point on multiline at given length from the start of the multiline\n * @param length\n * @returns {Point | null}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (this.isInfinite) return null\n\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 /**\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 * Calculate distance and shortest segment from any shape to multiline\n * @param shape\n * @returns {[number,Flatten.Segment]}\n */\n distanceTo(shape) {\n if (shape instanceof Point) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Line) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Circle) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Segment) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Arc) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.multiline2multiline(this, shape);\n }\n\n throw Flatten.Errors.UNSUPPORTED_SHAPE_TYPE;\n }\n\n /**\n * Calculate intersection of multiline with other shape\n * @param {Shape} shape\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Multiline) {\n return intersectMultiline2Multiline(this, shape);\n }\n else {\n return intersectShape2Multiline(shape, this);\n }\n }\n\n /**\n * Return true if multiline contains the shape: no point of shape lies outside\n * @param shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return this.edges.some(edge => edge.shape.contains(shape));\n }\n\n throw Flatten.Errors.UNSUPPORTED_SHAPE_TYPE;\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 be inserted into 'points' attribute of element\n * @returns {string}\n */\n svgPoints() {\n return this.vertices.map(p => `${p.x},${p.y}`).join(' ')\n }\n\n /**\n * Return string to be assigned to 'd' attribute of element\n * @returns {*}\n */\n dpath() {\n let dPathStr = `M${this.first.start.x},${this.first.start.y}`;\n for (let edge of this) {\n dPathStr += edge.svg();\n }\n return dPathStr\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$1;\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 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 // augment intersections with new sorted arrays\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\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 int_point.edge_before = edge.prev;\n if (edge.prev) {\n int_point.is_vertex = END_VERTEX$1; // polygon\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 else {\n if (polygon instanceof Multiline$1 && int_point.is_vertex & START_VERTEX$1) {\n int_point.edge_after = polygon.first;\n }\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 * @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$1([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$1([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$1([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$1([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 a 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} other_interval - Other interval to merge with\n * @returns {Interval}\n */\n merge(other_interval) {\n return new Interval(\n this.low === undefined ?\n other_interval.low : (this.low < other_interval.low ? this.low : other_interval.low),\n this.high === undefined ?\n other_interval.high : (this.high > other_interval.high ? 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 let [low, high] = key;\n if (low > high) [low, high] = [high, low];\n this.item.key = new Interval(low, high);\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);\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 return this.tree_find_any_interval(this.root, search_node);\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 /**\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 /**\n * @param {Interval} interval - optional if the iterator is intended to start from the beginning\n * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output\n * @returns {Iterator}\n */\n *iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {\n let node;\n if (interval) {\n node = this.tree_search_nearest_forward(this.root, new Node(interval));\n } else if (this.root) {\n node = this.local_minimum(this.root);\n }\n while (node) {\n yield outputMapperFn(node.item.value, node.item.key);\n node = this.tree_successor(node);\n }\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 tree_search_nearest_forward(node, search_node) {\n let best;\n let curr = node;\n while (curr && curr !== this.nil_node) {\n if (curr.less_than(search_node)) {\n if (curr.intersect(search_node)) {\n best = curr;\n curr = curr.left;\n } else {\n curr = curr.right;\n }\n } else {\n if (!best || curr.less_than(best)) best = curr;\n curr = curr.left;\n }\n }\n return best || null;\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.not_intersect_left_subtree(search_node)) {\n found = this.tree_find_any_interval(node.left, search_node);\n }\n if (!found) {\n found = node.intersect(search_node);\n }\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$3 = 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 if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.shape2multiline(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.contains && shape.contains instanceof Function) {\n return shape.contains(this);\n }\n\n throw Flatten.Errors.UNSUPPORTED_SHAPE_TYPE;\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$3;\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 */\nlet Segment$1 = class 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 {Segment} 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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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, 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 if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.shape2multiline(this, shape);\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$1;\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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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 if (shape instanceof Flatten.Multiline) {\n let [dist, shortest_segment] = Flatten.Distance.shape2multiline(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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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 if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.shape2multiline(this, shape);\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 /**\n * Calculate distance and shortest segment from box 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 box to shape\n * @returns {Segment} shortest segment between box and shape (started at box, ended at shape)\n */\n distanceTo(shape) {\n const distanceInfos = this.toSegments()\n .map(segment => segment.distanceTo(shape));\n let shortestDistanceInfo = [\n Number.MAX_SAFE_INTEGER,\n null,\n ];\n distanceInfos.forEach(distanceInfo => {\n if (distanceInfo[0] < shortestDistanceInfo[0]) {\n shortestDistanceInfo = distanceInfo;\n }\n });\n return shortestDistanceInfo;\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 bidirectionally 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 = `M${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 */\nlet Polygon$1 = class 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 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 // 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$1([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 if (shape instanceof Flatten.Multiline) {\n return intersectMultiline2Polygon(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 be assigned to 'd' attribute of element\n * @returns {*}\n */\n dpath() {\n return [...this.faces].reduce((acc, face) => acc + face.svg(), \"\")\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$1;\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: Point$2, 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$2(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$2) {\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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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 point and edge\n * @param pt\n * @param edge\n * @returns {[number, Flatten.Segment]}\n */\n static point2edge(pt, edge) {\n return edge.shape instanceof Flatten.Segment ?\n Distance.point2segment(pt, edge.shape) :\n Distance.point2arc(pt, edge.shape);\n }\n\n /**\n * Calculate distance and shortest segment between segment and line\n * @param seg\n * @param line\n * @returns {[number, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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] = Distance.point2edge(point, edge);\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, Flatten.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 /**\n * Calculate distance and shortest segment any shape and multiline\n * @param shape\n * @param multiline\n * @returns {[number, Flatten.Segment]}\n */\n static shape2multiline(shape, multiline) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of multiline) {\n let [dist, shortest_segment] = Distance.distance(shape, 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 multilines\n * @param multiline1\n * @param multiline2\n * @returns {[number, Flatten.Segment]}\n */\n static multiline2multiline(multiline1, multiline2) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge1 of multiline1) {\n for (let edge2 of multiline2) {\n let [dist, shortest_segment] = Distance.distance(edge1.shape, 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\nFlatten.Distance = Distance;\n\nconst {Multiline, Point: Point$1, Segment, Polygon} = Flatten;\n\n// POINT (30 10)\n// MULTIPOINT (10 40, 40 30, 20 20, 30 10)\n// LINESTRING (30 10, 10 30, 40 40)\n// MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))\n// MULTILINESTRING ((8503.732 4424.547, 8963.747 3964.532), (8963.747 3964.532, 8707.468 3708.253), (8707.468 3708.253, 8247.454 4168.268), (8247.454 4168.268, 8503.732 4424.547))\n// POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))\n// MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))\n// GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (0 0, 1440 900), POLYGON ((0 0, 0 1024, 1024 1024, 1024 0, 0 0)))\n// GEOMETRYCOLLECTION (POINT (40 10), LINESTRING (10 10, 20 20, 10 40), POLYGON ((40 40, 20 45, 45 30, 40 40)))\n\nfunction parseSinglePoint(pointStr) {\n return new Point$1(pointStr.split(' ').map(Number))\n}\n\nfunction parseMultiPoint(multipointStr) {\n return multipointStr.split(', ').map(parseSinglePoint)\n}\n\nfunction parseLineString(lineStr) {\n const points = parseMultiPoint(lineStr);\n let segments = [];\n for (let i = 0; i < points.length-1; i++) {\n segments.push(new Segment(points[i], points[i+1]));\n }\n return new Multiline(segments)\n}\n\nfunction parseMultiLineString(multilineStr) {\n const lineStrings = multilineStr.replace(/\\(\\(/, '').replace(/\\)\\)$/, '').split('), (');\n return lineStrings.map(parseLineString)\n}\n\nfunction parseSinglePolygon(polygonStr) {\n const facesStr = polygonStr.replace(/\\(\\(/, '').replace(/\\)\\)$/, '').split('), (');\n const polygon = new Polygon();\n let orientation;\n facesStr.forEach((facesStr, idx) => {\n let points = facesStr.split(', ').map(coordStr => {\n return new Point$1(coordStr.split(' ').map(Number))\n });\n const face = polygon.addFace(points);\n if (idx === 0) {\n orientation = face.orientation();\n }\n else {\n if (face.orientation() === orientation) {\n face.reverse();\n }\n }\n });\n return polygon\n}\n\nfunction parseMutliPolygon(multiPolygonString) {\n // const polygonStrings = multiPolygonString.split('?')\n // Split the string by the delimiter \")), ((\" which separates the polygons\n const polygonStrings = multiPolygonString.split(/\\)\\), \\(\\(/).map(polygon => '((' + polygon + '))');\n\n const polygons = polygonStrings.map(parseSinglePolygon);\n const polygon = new Polygon();\n const faces = polygons.reduce((acc, polygon) => [...acc, ...polygon?.faces], []);\n faces.forEach(face => polygon.addFace([...face?.shapes]));\n return polygon;\n}\n\nfunction parsePolygon(wkt) {\n if (wkt.startsWith(\"POLYGON\")) {\n const polygonStr = wkt.replace(/^POLYGON /, '');\n return parseSinglePolygon(polygonStr)\n }\n else {\n // const multiPolygonString = wkt.replace(/^MULTIPOLYGON \\(/, '').replace(/\\)$/, '').replace(/\\)\\), \\(\\(/,'))?((')\n const multiPolygonString = wkt.replace(/^MULTIPOLYGON \\(\\(\\((.*)\\)\\)\\)$/, '$1');\n return parseMutliPolygon(multiPolygonString)\n }\n}\n\nfunction parseArrayOfPoints(str) {\n const arr = str.split('\\n').map(x => x.match(/\\(([^)]+)\\)/)[1]);\n return arr.map(parseSinglePoint)\n}\n\nfunction parseArrayOfLineStrings(str) {\n const arr = str.split('\\n').map(x => x.match(/\\(([^)]+)\\)/)[1]);\n return arr.map(parseLineString).reduce((acc, x) => [...acc, ...x], [])\n}\n\n/**\n * Convert WKT string to array of Flatten shapes.\n * @param str\n * @returns {Point | Point[] | Multiline | Multiline[] | Polygon | Shape[] | null}\n */\nfunction parseWKT(str) {\n if (str.startsWith(\"POINT\")) {\n const pointStr = str.replace(/^POINT \\(/, '').replace(/\\)$/, '');\n return parseSinglePoint(pointStr)\n }\n else if (str.startsWith(\"MULTIPOINT\")) {\n const multiPointStr = str.replace(/^MULTIPOINT \\(/, '').replace(/\\)$/, '');\n return parseMultiPoint(multiPointStr)\n }\n else if (str.startsWith(\"LINESTRING\")) {\n const lineStr = str.replace(/^LINESTRING \\(/, '').replace(/\\)$/, '');\n return parseLineString(lineStr)\n }\n else if (str.startsWith(\"MULTILINESTRING\")) {\n const multilineStr = str.replace(/^MULTILINESTRING /, '');\n return parseMultiLineString(multilineStr)\n }\n else if (str.startsWith(\"POLYGON\") || str.startsWith(\"MULTIPOLYGON\")) {\n return parsePolygon(str)\n }\n else if (str.startsWith(\"GEOMETRYCOLLECTION\")) {\n // const regex = /(POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION) \\([^\\)]+\\)/g\n /* Explanation:\n(?POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON):\nThis named group will capture the geometry type. The type label helps with understanding the structure but\n is not necessary unless you process the matches programmatically and want easy access to the geometry type.\n\\( and \\): Match the opening and closing parentheses.\n(?:[^\\(\\)]|\\([^\\)]*\\))*: A non-capturing group that allows for:\n[^\\(\\)]: Matching any character except parentheses, handling simple geometries.\n|\\([^\\)]*\\): Handling nested parentheses for geometries like POLYGON and MULTILINESTRING.\n* after the non-capturing group: Allows for repeating the pattern zero or more times to match all contents between the outermost parentheses. */\n const regex = /(?POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \\((?:[^\\(\\)]|\\([^\\)]*\\))*\\)/g;\n const wktArray = str.match(regex);\n if (wktArray[0].startsWith('GEOMETRYCOLLECTION')) {\n wktArray[0] = wktArray[0].replace('GEOMETRYCOLLECTION (','');\n }\n const flArray = wktArray.map(parseWKT).map(x => x instanceof Array ? x : [x]);\n return flArray.reduce((acc, x) => [...acc, ...x], [])\n }\n else if (isArrayOfPoints(str)) {\n return parseArrayOfPoints(str)\n }\n else if (isArrayOfLines(str)) {\n return parseArrayOfLineStrings(str)\n }\n return []\n}\n\nfunction isArrayOfPoints(str) {\n return str.split('\\n')?.every(str => str.includes('POINT'))\n}\n\nfunction isArrayOfLines(str) {\n return str.split('\\n')?.every(str => str.includes('LINESTRING'))\n}\n\n/**\n * Return true if given string starts with one of WKT tags and possibly contains WKT string,\n * @param str\n * @returns {boolean}\n */\nfunction isWktString(str) {\n return (\n str.startsWith(\"POINT\") || isArrayOfPoints(str) ||\n str.startsWith(\"LINESTRING\") || isArrayOfLines(str) ||\n str.startsWith(\"MULTILINESTRING\") ||\n str.startsWith(\"POLYGON\") ||\n str.startsWith(\"MULTIPOINT\") ||\n str.startsWith(\"MULTIPOLYGON\") ||\n str.startsWith(\"GEOMETRYCOLLECTION\")\n )\n}\n\nFlatten.isWktString = isWktString;\nFlatten.parseWKT = parseWKT;\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$1 as Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$3 as Point, Polygon$1 as Polygon, Ray, Relations, Segment$1 as Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, isWktString, line, matrix, multiline, parseWKT, 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","defaultAttributes","SVGAttributes","args","property","acc","key","SVGKey","str","convertToString","attrs","intersectLine2Line","line1","line2","ip","A1","B1","C1","A2","B2","C2","det","detX","detY","intersectLine2Circle","line","circle","prj","dist","delta","v_trans","pt","intersectLine2Box","box","ips","seg","ips_tmp","intersectSegment2Line","ptInIntPoints","intersectLine2Arc","arc","ip_tmp","intersectSegment2Segment","seg1","seg2","new_ip","isPointInSegmentBox","point","segment","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","polygon","intersectArc2Polygon","intersectLine2Polygon","intersectCircle2Polygon","intersectEdge2Edge","edge1","edge2","intersectEdge2Polygon","resp_edges","resp_edge","intersectMultiline2Polygon","multiline","intersectPolygon2Polygon","polygon1","polygon2","intersectShape2Polygon","shape","new_pt","createLineFromRay","intersectRay2Circle","intersectRay2Box","intersectRay2Line","intersectRay2Ray","ray1","ray2","intersectRay2Polygon","intersectShape2Shape","shape1","shape2","intersectShape2Multiline","intersectMultiline2Multiline","multiline1","multiline2","Multiline$1","Multiline","validShapes","shapes","L","anyShape","s","anyShapeExceptLine","shapeSegmentOrArc","v","len","length","newEdge","edgeBefore","edgeFrom","edgeTo","edges","edgeFound","shortest_segment","angle","center","matrix","p","dPathStr","svgStr","addToIntPoints","int_points","id","is_vertex","arc_length","sortIntersections","intersections","getSortedArray","faceMap","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","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","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","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","resp","poly","notIntersected","notIntersectedFaces","poly2","poly1","int_points1","int_points1_sorted","int_points2","iterate_more","edge_tmp","new_bv","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","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","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","best","curr","found","node_min","node_max","node_successor","action","height","heightLeft","heightRight","PlanarSet","entry","size","deleted","Shape","Point$3","Point","arr","m","proj_vec","dx","dy","r","Vector$1","a1","a2","scalar","norm1","norm2","n","vector$1","Segment$1","Segment","coords","ps","pe","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","distanceInfos","shortestDistanceInfo","distanceInfo","width","Edge","bvMiddle","flag","sign","halfArc1","halfArc2","CircularLinkedList","done","Face","segments","points","flattenShapes","flattenShape","sArea","area","exitOnFirst","Ray","slope","Polygon$1","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","Point$2","Vector","Utils","Inversion","inversion_circle","k2","len2","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","Point$1","parseSinglePoint","pointStr","parseMultiPoint","multipointStr","parseLineString","lineStr","parseMultiLineString","multilineStr","parseSinglePolygon","polygonStr","facesStr","idx","coordStr","parseMutliPolygon","multiPolygonString","parsePolygon","wkt","parseArrayOfPoints","parseArrayOfLineStrings","parseWKT","multiPointStr","regex","wktArray","isArrayOfPoints","isArrayOfLines","_a","isWktString","DEFAULT_SIZE","DEFAULT_LEADER_TIME","_TrackSymbol","Path","latLng","options","Util","bounds","Bounds","LatLngBounds","paths","viewPath","shapeOptions","oldLatLng","heading","course","speed","modelAngle","leaderLength","leaderEndLatLng","LatLng","latLngs","zoomLevel","shapeSetEntriesFiltered","shapeSetEntry","shapeSet","headingAngle","units","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 2ca708a..625f413 100644 --- a/dist/leaflet-tracksymbol2.umd.js +++ b/dist/leaflet-tracksymbol2.umd.js @@ -1,19 +1,23 @@ -(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=` --M}function ot(r,t){return r-t-M}function Ae(r,t){return r-t>M}function Cn(r,t){return r-t>-M}function be(r,t){return r-t<-M}function Rn(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 T.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}}const Le={stroke:"black"};class Mn{constructor(t=Le){for(const e in t)this[e]=t[e];this.stroke=t.stroke??Le.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 lt(r){return new Mn(r).toAttributesString()}function dt(r,t){let e=[],[n,s,l]=r.standard,[o,a,f]=t.standard,h=n*a-s*o,u=l*a-s*f,g=n*f-l*o;if(!i.Utils.EQ_0(h)){let _,S;s===0?(_=l/n,S=g/h):a===0?(_=f/o,S=g/h):n===0?(_=u/h,S=l/s):o===0?(_=u/h,S=f/a):(_=u/h,S=g/h),e.push(new i.Point(_,S))}return e}function at(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 gt(r,t){let e=[];for(let n of t.toSegments()){let s=Lt(n,r);for(let l of s)Ve(l,e)||e.push(l)}return e}function zt(r,t){let e=[];if(gt(r,t.box).length===0)return e;let n=new i.Circle(t.pc,t.r),s=at(r,n);for(let l of s)l.on(t)&&e.push(l);return e}function Lt(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 dt(n,t)}function Yt(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=dt(n,s);l.length>0&&Oe(l[0],r)&&Oe(l[0],t)&&e.push(l[0])}return e}function Oe(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 Qt(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=at(n,t);for(let l of s)l.on(r)&&e.push(l);return e}function pt(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=at(n,s);for(let o of l)o.on(r)&&o.on(t)&&e.push(o);return e}function kn(r,t){let e=[];for(let n of t.toSegments()){let s=Yt(n,r);for(let l of s)e.push(l)}return e}function Ne(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 f=s*s/(2*o)-l*l/(2*o)+o/2,h=r.pc.translate(f*n.x,f*n.y),u=Math.sqrt(s*s-f*f);return a=h.translate(n.rotate90CCW().multiply(u)),e.push(a),a=h.translate(n.rotate90CW().multiply(u)),e.push(a),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 Ce(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 ne(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=Ne(n,s);for(let o of l)o.on(r)&&e.push(o);return e}function Bn(r,t){let e=[];for(let n of t.toSegments()){let s=pt(n,r);for(let l of s)e.push(l)}return e}function Re(r,t){return r.isSegment?Yt(r.shape,t):pt(t,r.shape)}function Ue(r,t){return r.isSegment?pt(r.shape,t):Ce(r.shape,t)}function Me(r,t){return r.isSegment?Lt(r.shape,t):zt(t,r.shape)}function Vn(r,t){return r.isSegment?se(t,r.shape):oe(t,r.shape)}function Hn(r,t){return r.isSegment?Qt(r.shape,t):ne(r.shape,t)}function ie(r,t){let e=[];for(let n of t.edges)for(let s of Re(n,r))e.push(s);return e}function re(r,t){let e=[];for(let n of t.edges)for(let s of Ue(n,r))e.push(s);return e}function Ot(r,t){let e=[];if(t.isEmpty())return e;for(let n of t.edges)for(let s of Me(n,r))Ve(s,e)||e.push(s);return r.sortPoints(e)}function ke(r,t){let e=[];if(t.isEmpty())return e;for(let n of t.edges)for(let s of Hn(n,r))e.push(s);return e}function Fe(r,t){return r.isSegment?Re(t,r.shape):r.isArc?Ue(t,r.shape):r.isLine?Me(t,r.shape):r.isRay?Vn(t,r.shape):[]}function Be(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,...Fe(r,s)];return e}function $n(r,t){let e=[];if(t.isEmpty()||r.size===0)return e;for(let n of r)e=[...e,...Be(n,t)];return e}function Gn(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,...Be(n,t)];return e}function qn(r,t){return r instanceof i.Line?Ot(r,t):r instanceof i.Segment?ie(r,t):r instanceof i.Arc?re(r,t):[]}function Ve(r,t){return t.some(e=>e.equalTo(r))}function J(r){return new i.Line(r.start,r.norm)}function se(r,t){return Lt(t,J(r)).filter(e=>r.contains(e))}function oe(r,t){return zt(J(r),t).filter(e=>r.contains(e))}function He(r,t){return at(J(r),t).filter(e=>r.contains(e))}function Dn(r,t){return gt(J(r),t).filter(e=>r.contains(e))}function $e(r,t){return dt(J(r),t).filter(e=>r.contains(e))}function Wn(r,t){return dt(J(r),J(t)).filter(e=>r.contains(e)).filter(e=>t.contains(e))}function Ge(r,t){return Ot(J(r),t).filter(e=>r.contains(e))}function qe(r,t){if(r.intersect&&r.intersect instanceof Function)return r.intersect(t);throw T.UNSUPPORTED_SHAPE_TYPE}function Nt(r,t){let e=[];for(let n of t)e=[...e,...qe(n,n.shape)];return e}function zn(r,t){let e=[];for(let n of r)for(let s of t)e=[...e,...qe(n,s)];return e}let ft=class Gt extends ee{constructor(...t){if(super(),this.isInfinite=!1,t.length===1&&t[0]instanceof Array&&t[0].length>0){let e=!1;const n=t[0],s=n.length,l=f=>f instanceof i.Segment||f instanceof i.Arc||f instanceof i.Ray||f instanceof i.Line,o=f=>f instanceof i.Segment||f instanceof i.Arc||f instanceof i.Ray,a=f=>f instanceof i.Segment||f instanceof i.Arc;if(e=s===1&&l(n[0])||s>1&&o(n[0])&&o(n[s-1])&&n.slice(1,s-1).every(a),e){this.isInfinite=n.some(f=>f instanceof i.Ray||f instanceof i.Line);for(let f of n){let h=new i.Edge(f);this.append(h)}this.setArcLength()}else throw i.Errors.ILLEGAL_PARAMETERS}}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}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let e of this)t+=e.length;return t}clone(){return new Gt(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}pointAtLength(t){if(t>this.length||t<0||this.isInfinite)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||te.shape.contains(t));throw i.Errors.UNSUPPORTED_SHAPE_TYPE}translate(t){return new Gt(this.edges.map(e=>e.shape.translate(t)))}rotate(t=0,e=new i.Point){return new Gt(this.edges.map(n=>n.shape.rotate(t,e)))}transform(t=new i.Matrix){return new Gt(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())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t}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 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` +`,e}};i.Multiline=ft;const Yn=(...r)=>new i.Multiline(...r);i.multiline=Yn;function _t(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=Jt;ot(l,0)&&(o|=bt),ot(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 Ct(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(Qn)}function Qn(r,t){return r.faceIdt.faceId?1:r.arc_lengtht.arc_length?1:0}function le(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 ae(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=U),t.edge_after&&(t.edge_after.bvStart=U)}function fe(r,t){for(let e of r)e.edge_before&&e.edge_before.setInclusion(t),e.edge_after&&e.edge_after.setInclusion(t)}function jn(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 he(r,t){let[e,n]=Ut(r,t,ut,!1),s=[];for(let l of e.faces)s=[...s,...[...l.edges].map(o=>o.shape)];return s}function je(r,t){let e=r.clone(),n=t.clone(),s=Ze(e,n);Ct(s),Et(e,s.int_points1_sorted),Et(n,s.int_points2_sorted),le(s),Ct(s);let l=s.int_points1_sorted.map(a=>a.pt),o=s.int_points2_sorted.map(a=>a.pt);return[l,o]}function Jn(r,t,e,n){let s=Xe(r,e.int_points1),l=Xe(t,e.int_points2);for(Ke(s,t),Ke(l,r),ae(e.int_points1),ae(e.int_points2),fe(e.int_points1,t),fe(e.int_points2,r);ei(r,t,e.int_points1,e.int_points1_sorted,e.int_points2,e););jn(e),ce(r,n,e.int_points1_sorted,!0),ce(t,n,e.int_points2_sorted,!1),Je(r,s,n,!0),Je(t,l,n,!1)}function ti(r,t,e,n){ni(r,t,n,e.int_points2),ii(r,t,e),de(r,e.int_points1),de(t,e.int_points2),ge(r,e.int_points1,e.int_points2),ge(r,e.int_points2,e.int_points1)}function Ut(r,t,e,n){let s=r.clone(),l=t.clone(),o=Ze(s,l);return Ct(o),Et(s,o.int_points1_sorted),Et(l,o.int_points2_sorted),le(o),Ct(o),Jn(s,l,o,e),n&&ti(s,l,o,e),[s,l]}function Ze(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)_t(n,a,e.int_points1),_t(l,a,e.int_points2)}}return e}function Xe(r,t){let e=[];for(let n of r.faces)t.find(s=>s.face===n)||e.push(n);return e}function Ke(r,t){for(let e of r)e.first.bv=e.first.bvStart=e.first.bvEnd=void 0,e.first.setInclusion(t)}function ei(r,t,e,n,s,l){let o,a,f,h=n.length,u=!1;for(let g=0;gor.edge_after===yt),R=t.addVertex(st.pt,yt);st.edge_before=R,st.edge_after=R.next,j&&(j.edge_after=R),R.bvStart=void 0,R.bvEnd=P,R.bv=void 0,R.setInclusion(r),R.next.bvStart=P,R.next.bvEnd=void 0,R.next.bv=void 0,R.next.setInclusion(r)}Ct(l),u=!0;break}}p=p.next}if(u)break;throw T.UNRESOLVED_BOUNDARY_CONFLICT}}return u}function ce(r,t,e,n){if(!e)return;let s,l,o,a;for(let f=0;fl.face===s)===void 0&&r.addFace(s.first,s.last)}}function ii(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 si.test(this.toString())}intersect(){return oi.test(this.toString())}touch(){return li.test(this.toString())}inside(){return ai.test(this.toString())}covered(){return fi.test(this.toString())}}function Mt(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=[...r.faces],f=[];for(let u of o)for(let g of n.intersect(u.shape)){if(g.equalTo(t))return i.BOUNDARY;f.push({pt:g,edge:u,face_index:a.indexOf(u.face)})}f.sort((u,g)=>be(u.pt.x,g.pt.x)?-1:Ae(u.pt.x,g.pt.x)?1:u.face_indexg.face_index?1:u.edge.arc_lengthg.edge.arc_length?1:0);let h=0;for(let u=0;u0&&g.pt.equalTo(f[u-1].pt)&&g.face_index===f[u-1].face_index&&g.edge.prev===f[u-1].edge)continue;let _=g.edge.prev;for(;te(_.length);)_=_.prev;let S=_.shape.tangentInEnd(),I=g.pt.translate(S),w=g.edge.shape.tangentInStart(),y=g.pt.translate(w),E=I.leftTo(s),x=y.leftTo(s);(E&&!x||!E&&x)&&h++}else if(g.pt.equalTo(g.edge.shape.end)){if(u>0&&g.pt.equalTo(f[u-1].pt)&&g.face_index===f[u-1].face_index&&g.edge.next===f[u-1].edge)continue;let _=g.edge.next;for(;te(_.length);)_=_.next;let S=_.shape.tangentInStart(),I=g.pt.translate(S),w=g.edge.shape.tangentInEnd(),y=g.pt.translate(w),E=I.leftTo(s),x=y.leftTo(s);(E&&!x||!E&&x)&&h++}else if(g.edge.shape instanceof i.Segment)h++;else{let _=g.edge.shape.box;ot(g.pt.y,_.ymin)||ot(g.pt.y,_.ymax)||h++}}return e=h%2===1?Dt:ve,e}function ui(r,t){return Tt(r,t).equal()}function tn(r,t){return Tt(r,t).intersect()}function hi(r,t){return Tt(r,t).touch()}function ci(r,t){return!tn(r,t)}function en(r,t){return Tt(r,t).inside()}function nn(r,t){return Tt(r,t).covered()}function di(r,t){return en(t,r)}function rn(r,t){return nn(t,r)}function Tt(r,t){if(r instanceof i.Line&&t instanceof i.Line)return gi(r,t);if(r instanceof i.Line&&t instanceof i.Circle)return pi(r,t);if(r instanceof i.Line&&t instanceof i.Box)return _i(r,t);if(r instanceof i.Line&&t instanceof i.Polygon)return mi(r,t);if((r instanceof i.Segment||r instanceof i.Arc)&&t instanceof i.Polygon)return sn(r,t);if((r instanceof i.Segment||r instanceof i.Arc)&&(t instanceof i.Circle||t instanceof i.Box))return sn(r,new i.Polygon(t));if(r instanceof i.Polygon&&t instanceof i.Polygon)return Zt(r,t);if((r instanceof i.Circle||r instanceof i.Box)&&(t instanceof i.Circle||t instanceof i.Box))return Zt(new i.Polygon(r),new i.Polygon(t));if((r instanceof i.Circle||r instanceof i.Box)&&t instanceof i.Polygon)return Zt(new i.Polygon(r),t);if(r instanceof i.Polygon&&(t instanceof i.Circle||t instanceof i.Box))return Zt(r,new i.Polygon(t))}function gi(r,t){let e=new xt,n=dt(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 pi(r,t){let e=new xt,n=at(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 ft([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 _i(r,t){let e=new xt,n=gt(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 ft([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 mi(r,t){let e=new xt,n=Ot(r,t),s=new ft([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 sn(r,t){let e=new xt,n=qn(r,t),s=n.length>0?n.slice():r.sortPoints(n),l=new ft([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(Mt(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 Zt(r,t){let e=new xt,[n,s]=je(r,t),l=Ye(r,t),o=ue(r,t),a=ue(t,r),[f,h]=Qe(r,t),u=he(r,t),g=he(t,r);return e.I2I=l.isEmpty()?[]:[l],e.I2B=h,e.I2E=o.isEmpty()?[]:[o],e.B2I=f,e.B2B=n,e.B2E=u,e.E2I=a.isEmpty()?[]:[a],e.E2B=g,e}var Ei=Object.freeze({__proto__:null,contain:di,cover:rn,covered:nn,disjoint:ci,equal:ui,inside:en,intersect:tn,relate:Tt,touch:hi});let kt=class Pt{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 Pt(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 Pt(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 T.ILLEGAL_PARAMETERS;return this.multiply(new Pt(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 Pt(s,l,-l,s,0,0)).translate(-e,-n)}scale(t,e){return this.multiply(new Pt(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=kt;const xi=(...r)=>new i.Matrix(...r);i.matrix=xi;const Ti=class Ie{constructor(t,e){this.low=t,this.high=e}clone(){return new Ie(this.low,this.high)}get max(){return this.clone()}less_than(t){return this.lowt.high?this.high:t.high)}output(){return[this.low,this.high]}static comparable_max(t,e){return t.merge(e)}static comparable_less_than(t,e){return tf&&([a,f]=[f,a]),this.item.key=new Ti(a,f)}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===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.valuet++),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 ht(t,e,this.nil_node,this.nil_node,null,b);return this.tree_insert(n),this.recalc_max(n),n}exist(t,e=t){let n=new ht(t,e);return!!this.tree_search(this.root,n)}remove(t,e=t){let n=new ht(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 ht(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 ht(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 Ft;return this.tree_walk(this.root,n=>e.insert(n.item.key,t(n.item.value,n.item.key))),e}*iterate(t,e=(n,s)=>n===s?s.output():n){let n;for(t?n=this.tree_search_nearest_forward(this.root,new ht(t)):this.root&&(n=this.local_minimum(this.root));n;)yield e(n.item.value,n.item.key),n=this.tree_successor(n)}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===b;)e.parent===e.parent.parent.left?(n=e.parent.parent.right,n.color===b?(e.parent.color=m,n.color=m,e.parent.parent.color=b,e=e.parent.parent):(e===e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=m,e.parent.parent.color=b,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,n.color===b?(e.parent.color=m,n.color=m,e.parent.parent.color=b,e=e.parent.parent):(e===e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=m,e.parent.parent.color=b,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===b&&(n.color=m,e.parent.color=b,this.rotate_left(e.parent),n=e.parent.right),n.left.color===m&&n.right.color===m?(n.color=b,e=e.parent):(n.right.color===m&&(n.color=b,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===b&&(n.color=m,e.parent.color=b,this.rotate_right(e.parent),n=e.parent.left),n.left.color===m&&n.right.color===m?(n.color=b,e=e.parent):(n.left.color===m&&(n.color=b,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_nearest_forward(t,e){let n,s=t;for(;s&&s!==this.nil_node;)s.less_than(e)?s.intersect(e)?(n=s,s=s.left):s=s.right:((!n||s.less_than(n))&&(n=s),s=s.left);return n||null}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===b&&(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 wi extends Set{constructor(t){super(t),this.index=new Ft,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 Ft}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=wi;class et{get name(){throw T.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw T.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw T.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform(new kt().translate(...t))}rotate(t,e=new i.Point){return this.transform(new kt().rotate(t,e.x,e.y))}scale(t,e){return this.transform(new kt().scale(t,e))}transform(...t){throw T.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw T.CANNOT_INVOKE_ABSTRACT_METHOD}}let Ii=class vn extends et{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 T.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 vn){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);if(t instanceof i.Multiline)return i.Distance.shape2multiline(this,t)}on(t){if(t instanceof i.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw i.Errors.UNSUPPORTED_SHAPE_TYPE}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 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` + ${lt({fill:"red",...t})} />`}};i.Point=Ii;const Si=(...r)=>new i.Point(...r);i.point=Si;let vi=class extends et{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 T.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 T.ZERO_DIVISION}rotate(t,e=new i.Point){if(e.x===0&&e.y===0)return this.transform(new kt().rotate(t));throw T.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=vi;const on=(...r)=>new i.Vector(...r);i.vector=on;let yi=class Se extends et{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 T.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 Lt(this,t);if(t instanceof i.Ray)return se(t,this);if(t instanceof i.Segment)return Yt(this,t);if(t instanceof i.Circle)return Qt(this,t);if(t instanceof i.Box)return kn(this,t);if(t instanceof i.Arc)return pt(this,t);if(t instanceof i.Polygon)return ie(this,t);if(t instanceof i.Multiline)return Nt(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]}if(t instanceof i.Multiline)return i.Distance.shape2multiline(this,t)}tangentInStart(){return new i.Vector(this.start,this.end).normalize()}tangentInEnd(){return new i.Vector(this.end,this.start).normalize()}reverse(){return new Se(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 Se(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=yi;const Pi=(...r)=>new i.Segment(...r);i.segment=Pi;let{vector:Bt}=i,Ai=class yn extends et{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=yn.points2norm(e,n),this.norm.dot(Bt(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 T.ILLEGAL_PARAMETERS;this.pt=e.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),this.norm.dot(Bt(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 T.ILLEGAL_PARAMETERS;this.pt=n.clone(),this.norm=e.clone(),this.norm=this.norm.normalize(),this.norm.dot(Bt(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}}throw T.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(Bt(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 Bt(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 dt(this,t);if(t instanceof i.Ray)return $e(t,this);if(t instanceof i.Circle)return at(this,t);if(t instanceof i.Box)return gt(this,t);if(t instanceof i.Segment)return Lt(t,this);if(t instanceof i.Arc)return zt(this,t);if(t instanceof i.Polygon)return Ot(this,t);if(t instanceof i.Multiline)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=gt(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 T.ILLEGAL_PARAMETERS;return new i.Vector(t,e).normalize().rotate90CCW()}};i.Line=Ai;const bi=(...r)=>new i.Line(...r);i.line=bi;let Li=class extends et{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 T.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 at(t,this);if(t instanceof i.Ray)return He(t,this);if(t instanceof i.Segment)return Qt(t,this);if(t instanceof i.Circle)return Ne(t,this);if(t instanceof i.Box)return Fn(this,t);if(t instanceof i.Arc)return ne(t,this);if(t instanceof i.Polygon)return ke(this,t);if(t instanceof i.Multiline)return Nt(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]}if(t instanceof i.Multiline){let[e,n]=i.Distance.shape2multiline(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):` + ${lt({fill:"none",...t})} />`}};i.Circle=Li;const Oi=(...r)=>new i.Circle(...r);i.circle=Oi;class Ni extends et{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 oe(t,this);if(t instanceof i.Circle)return ne(this,t);if(t instanceof i.Segment)return pt(t,this);if(t instanceof i.Box)return Bn(this,t);if(t instanceof i.Arc)return Ce(this,t);if(t instanceof i.Polygon)return re(this,t);if(t instanceof i.Multiline)return Nt(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]}if(t instanceof i.Multiline)return i.Distance.shape2multiline(this,t)}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,f)=>a.length-f.length);for(let a=0;a0?t[t.length-1]:void 0,h;f?h=new i.Arc(this.pc,this.r,f.endAngle,s[a].endAngle,this.counterClockwise):h=new i.Arc(this.pc,this.r,this.startAngle,s[a].endAngle,this.counterClockwise),i.Utils.EQ_0(h.length)||t.push(h.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 f=l(t,e).length;return new i.Arc(t,f,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 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 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,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"}})}); + ${lt({fill:"none",...t})} />`}}i.Arc=Ni;const Ci=(...r)=>new i.Arc(...r);i.arc=Ci;class Vt extends et{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 Vt(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 Vt(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 T.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 Vt)}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=>pt(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)}distanceTo(t){const e=this.toSegments().map(s=>s.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(s=>{s[0]`}}i.Box=Vt;const Ri=(...r)=>new i.Box(...r);i.box=Ri;class Ui{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=Mt(t,this.start)),this.bvEnd===void 0&&(this.bvEnd=Mt(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=Mt(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=Ui;class Mi extends ee{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 wt extends Mi{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=wt.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=wt.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 wt){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=wt;class pe extends et{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 T.ILLEGAL_PARAMETERS}}clone(){return new pe(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 on(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 se(this,t);if(t instanceof i.Arc)return oe(this,t);if(t instanceof i.Line)return $e(this,t);if(t instanceof i.Ray)return Wn(this,t);if(t instanceof i.Circle)return He(this,t);if(t instanceof i.Box)return Dn(this,t);if(t instanceof i.Polygon)return Ge(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=gt(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=pe;const ki=(...r)=>new i.Ray(...r);i.ray=ki;let Fi=class At{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 At;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 f=Fe(o,a);for(let h of f)_t(o,h,n.int_points1),_t(a,h,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),Et(t,n.int_points1_sorted),Et(e,n.int_points2_sorted),le(n),n.int_points1_sorted=tt(n.int_points1),n.int_points2_sorted=tt(n.int_points2),ae(n.int_points1),fe(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.forEach((o,a)=>{o.id=a}),n.int_points2.forEach((o,a)=>{o.id=a}),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(u)),h=h.reverse().map(u=>new i.Edge(u.shape.reverse()));for(let u=0;ue.edges.add(u))}return e.recreateFaces(),e}cutWithLine(t){let e=new ft([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=Mt(this,t);return e===Dt||e===U}else return rn(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 Ot(t,this);if(t instanceof i.Ray)return Ge(t,this);if(t instanceof i.Circle)return ke(t,this);if(t instanceof i.Segment)return ie(t,this);if(t instanceof i.Arc)return re(t,this);if(t instanceof i.Polygon)return Gn(t,this);if(t instanceof i.Multiline)return $n(t,this)}translate(t){let e=new At;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 At;for(let s of this.faces)n.addFace(s.shapes.map(l=>l.rotate(t,e)));return n}scale(t,e){let n=new At;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 At;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())}dpath(){return[...this.faces].reduce((t,e)=>t+e.svg(),"")}svg(t={}){let e=` + +`,e}};i.Polygon=Fi;const Bi=(...r)=>new i.Polygon(...r);i.polygon=Bi;const{Circle:_e,Line:ln,Point:an,Vector:Xt,Utils:me}=i;class Ht{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new Xt(t.pc,e),s=t.r*t.r,l=n.dot(n);return me.EQ_0(l)?new an(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(me.EQ(n,e.r)){let s=t.r*t.r/(2*e.r),l=new Xt(t.pc,e.pc);l=l.normalize();let o=t.pc.translate(l.multiply(s));return new ln(o,l)}else{let s=new Xt(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(me.EQ_0(n))return e.clone();{let l=t.r*t.r/(2*n),o=new Xt(t.pc,s.end);return o=o.multiply(l/n),new _e(t.pc.translate(o),l)}}inverse(t){if(t instanceof an)return Ht.inversePoint(this.circle,t);if(t instanceof _e)return Ht.inverseCircle(this.circle,t);if(t instanceof ln)return Ht.inverseLine(this.circle,t)}}i.Inversion=Ht;const Vi=r=>new i.Inversion(r);i.inversion=Vi;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),f,h;if(i.Utils.GE(o,0)&&i.Utils.GE(a,0)){let u=e.tangentInStart();return f=Math.abs(u.cross(s)),h=e.start.translate(u.multiply(u.dot(s))),[f,new i.Segment(t,h)]}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 point2edge(t,e){return e.shape instanceof i.Segment?d.point2segment(t,e.shape):d.point2arc(t,e.shape)}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=Yt(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,f]=d.point2circle(t.start,e),[h,u]=d.point2circle(t.end,e);return i.Utils.LT(a,h)?[a,f]:[h,u]}}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,_]=d.point2circle(a.end,l);if(_.end.on(e))return[g,_]}let f=[];f.push(d.point2arc(t.start,e)),f.push(d.point2arc(t.end,e));let h,u;return[h,u]=d.point2segment(e.start,t),f.push([h,u.reverse()]),[h,u]=d.point2segment(e.end,t),f.push([h,u.reverse()]),d.sort(f),f[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,f]=d.point2circle(o.end,s);if(f.end.on(t))return[a,f]}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 f=[],h,u;return[h,u]=d.point2arc(t.start,e),u.end.on(e)&&f.push([h,u]),[h,u]=d.point2arc(t.end,e),u.end.on(e)&&f.push([h,u]),[h,u]=d.point2arc(e.start,t),u.end.on(t)&&f.push([h,u.reverse()]),[h,u]=d.point2arc(e.end,t),u.end.on(t)&&f.push([h,u.reverse()]),[h,u]=d.point2point(t.start,e.start),f.push([h,u]),[h,u]=d.point2point(t.start,e.end),f.push([h,u]),[h,u]=d.point2point(t.end,e.start),f.push([h,u]),[h,u]=d.point2point(t.end,e.end),f.push([h,u]),d.sort(f),f[0]}}static point2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of e.edges){let[l,o]=d.point2edge(t,s);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,f=o.ymax-o.ymin,h=a*a+f*f;return[l,h]}static minmax_tree_process_level(t,e,n,s){let l,o;for(let u of e)[l,o]=d.box2box_minmax(t.box,u.item.key),u.item.value instanceof i.Edge?s.insert([l,o],u.item.value.shape):s.insert([l,o],u.item.value),i.Utils.LT(o,n)&&(n=o);if(e.length===0)return n;let a=e.map(u=>u.left.isNil()?void 0:u.left).filter(u=>u!==void 0),f=e.map(u=>u.right.isNil()?void 0:u.right).filter(u=>u!==void 0),h=[...a,...f].filter(u=>{let[g,_]=d.box2box_minmax(t.box,u.max);return i.Utils.LE(g,n)});return n=d.minmax_tree_process_level(t,h,n,s),n}static minmax_tree(t,e,n){let s=new Ft,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)}static shape2multiline(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of e){let[l,o]=d.distance(t,s.shape);i.Utils.LT(l,n[0])&&(n=[l,o])}return n}static multiline2multiline(t,e){let n=[Number.POSITIVE_INFINITY,new i.Segment];for(let s of t)for(let l of e){let[o,a]=d.distance(s.shape,l.shape);i.Utils.LT(o,n[0])&&(n=[o,a])}return n}}i.Distance=d;const{Multiline:Hi,Point:fn,Segment:$i,Polygon:un}=i;function Ee(r){return new fn(r.split(" ").map(Number))}function hn(r){return r.split(", ").map(Ee)}function xe(r){const t=hn(r);let e=[];for(let n=0;n{let o=s.split(", ").map(f=>new fn(f.split(" ").map(Number)));const a=e.addFace(o);l===0?n=a.orientation():a.orientation()===n&&a.reverse()}),e}function qi(r){const e=r.split(/\)\), \(\(/).map(l=>"(("+l+"))").map(cn),n=new un;return e.reduce((l,o)=>[...l,...o==null?void 0:o.faces],[]).forEach(l=>n.addFace([...l==null?void 0:l.shapes])),n}function Di(r){if(r.startsWith("POLYGON")){const t=r.replace(/^POLYGON /,"");return cn(t)}else{const t=r.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1");return qi(t)}}function Wi(r){return r.split(` +`).map(e=>e.match(/\(([^)]+)\)/)[1]).map(Ee)}function zi(r){return r.split(` +`).map(e=>e.match(/\(([^)]+)\)/)[1]).map(xe).reduce((e,n)=>[...e,...n],[])}function dn(r){if(r.startsWith("POINT")){const t=r.replace(/^POINT \(/,"").replace(/\)$/,"");return Ee(t)}else if(r.startsWith("MULTIPOINT")){const t=r.replace(/^MULTIPOINT \(/,"").replace(/\)$/,"");return hn(t)}else if(r.startsWith("LINESTRING")){const t=r.replace(/^LINESTRING \(/,"").replace(/\)$/,"");return xe(t)}else if(r.startsWith("MULTILINESTRING")){const t=r.replace(/^MULTILINESTRING /,"");return Gi(t)}else{if(r.startsWith("POLYGON")||r.startsWith("MULTIPOLYGON"))return Di(r);if(r.startsWith("GEOMETRYCOLLECTION")){const t=/(?POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,e=r.match(t);return e[0].startsWith("GEOMETRYCOLLECTION")&&(e[0]=e[0].replace("GEOMETRYCOLLECTION (","")),e.map(dn).map(s=>s instanceof Array?s:[s]).reduce((s,l)=>[...s,...l],[])}else{if(gn(r))return Wi(r);if(pn(r))return zi(r)}}return[]}function gn(r){var t;return(t=r.split(` +`))==null?void 0:t.every(e=>e.includes("POINT"))}function pn(r){var t;return(t=r.split(` +`))==null?void 0:t.every(e=>e.includes("LINESTRING"))}function Yi(r){return r.startsWith("POINT")||gn(r)||r.startsWith("LINESTRING")||pn(r)||r.startsWith("MULTILINESTRING")||r.startsWith("POLYGON")||r.startsWith("MULTIPOINT")||r.startsWith("MULTIPOLYGON")||r.startsWith("GEOMETRYCOLLECTION")}i.isWktString=Yi,i.parseWKT=dn,i.BooleanOperations=ri,i.Relations=Ei;const _n=i.Matrix,Kt=24,Te=60,A=class A extends v.Path{constructor(t,e){if(super(),v.Util.setOptions(this,e),t==null)throw Error("latLng required");e=e||{},this._latLng=v.latLng(t),this._heading=e.heading,this._course=e.course,this._speed=e.speed,this._shapeOptions=e.shapeOptions||{leaderTime:Te,defaultShapeSet:A.DEFAULT_SHAPE_SET},this._setShapeOptions(e.shapeOptions)}_project(){this._currentShapePoints=this._getProjectedShapePoints(),this._currentLeaderPoints=this._getLeaderShapePoints();const t=new v.Bounds;for(let e=0;en.minZoomLevel-e.minZoomLevel)}setLatLng(t){const e=this._latLng;return this._latLng=v.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 v.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 _n;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 _n().translate(n.x,n.y);return t.map(l=>{const o=s.transform(l);return new v.Point(o[0],o[1])})}case"meters":return t.map(n=>this._map.latLngToLayerPoint(new v.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=v.DomUtil.create("div");return s.innerHTML=n,s}};vt.DEFAULT_SILHOUETTE_SHAPE_POINTS=[[1,.5],[.75,1],[0,1],[0,0],[.75,0]];let $t=vt;function It(r,t,e){if(r!=null&&!(e&&!e(r)))return r.toFixed(t)}function nr(r){return r==null?void 0:Sn(r).name}function ir(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 rr(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 sr(r){if(r==null)return;const t=[];if(!St(r.month)&&!St(r.day)&&t.push(`${r.month.toString().padStart(2,"0")}/${r.day.toString().padStart(2,"0")}`),!St(r.hour)&&!St(r.minute)&&t.push(`${r.hour.toString().padStart(2,"0")}:${r.minute.toString().padStart(2,"0")}`),t.length!==0)return`${t.join(" ")} UTC`}function wn(r){if(r!=null)return r*Math.PI/180}function St(r){return r==null}function In(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} ${St(e)?"":e}`}function c(r,t,e){return{name:r,color:t,fillColor:e}}function Sn(r){if(r==null)return Tn[0];if(r<0||r>99)return er;const t=Tn[r];return St(t)?tr:t}v.trackSymbol=function(r,t){return new B(r,t)},v.TrackSymbol=B,v.aisTrackSymbol=function(r,t){return new $t(r,t)},v.AISTrackSymbol=$t,Z.AISTrackSymbol=$t,Z.TrackSymbol=B,Z.default=B,Object.defineProperties(Z,{__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 4534ead..ee27102 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.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 +{"version":3,"file":"leaflet-tracksymbol2.umd.js","sources":["../node_modules/.pnpm/@flatten-js+core@1.6.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 static get UNSUPPORTED_SHAPE_TYPE() {\n return new Error('Unsupported shape type')\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\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 * 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 intersectMultiline2Polygon(multiline, polygon) {\n let ip = [];\n\n if (polygon.isEmpty() || multiline.size === 0) {\n return ip;\n }\n\n for (let edge of multiline) {\n ip = [...ip, ...intersectEdge2Polygon(edge, polygon)];\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\nfunction intersectShape2Shape(shape1, shape2) {\n if (shape1.intersect && shape1.intersect instanceof Function) {\n return shape1.intersect(shape2)\n }\n throw Errors.UNSUPPORTED_SHAPE_TYPE\n}\n\nfunction intersectShape2Multiline(shape, multiline) {\n let ip = [];\n for (let edge of multiline) {\n ip = [...ip, ...intersectShape2Shape(edge, edge.shape)];\n }\n return ip;\n}\n\nfunction intersectMultiline2Multiline(multiline1, multiline2) {\n let ip = [];\n for (let edge1 of multiline1) {\n for (let edge2 of multiline2) {\n ip = [...ip, ...intersectShape2Shape(edge1, edge2)];\n }\n }\n return ip;\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 */\nlet Multiline$1 = class Multiline extends LinkedList {\n constructor(...args) {\n super();\n this.isInfinite = false;\n\n if (args.length === 1 && args[0] instanceof Array && args[0].length > 0) {\n // there may be only one line and\n // only first and last may be rays\n let validShapes = false;\n const shapes = args[0];\n const L = shapes.length;\n const anyShape = (s) =>\n s instanceof Flatten.Segment || s instanceof Flatten.Arc ||\n s instanceof Flatten.Ray || s instanceof Flatten.Line;\n const anyShapeExceptLine = (s) =>\n s instanceof Flatten.Segment || s instanceof Flatten.Arc || s instanceof Flatten.Ray;\n const shapeSegmentOrArc = (s) => s instanceof Flatten.Segment || s instanceof Flatten.Arc;\n validShapes =\n L === 1 && anyShape(shapes[0]) ||\n L > 1 && anyShapeExceptLine(shapes[0]) && anyShapeExceptLine(shapes[L - 1]) &&\n shapes.slice(1, L - 1).every(shapeSegmentOrArc);\n\n if (validShapes) {\n this.isInfinite = shapes.some(shape =>\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 } else {\n throw Flatten.Errors.ILLEGAL_PARAMETERS;\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 * (Getter) Returns length of the multiline, return POSITIVE_INFINITY if multiline is infinite\n * @returns {number}\n */\n get length() {\n if (this.isEmpty()) return 0;\n if (this.isInfinite) return Number.POSITIVE_INFINITY;\n\n let len = 0;\n for (let edge of this) {\n len += edge.length;\n }\n return len\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 multiline.\n * Arc_length of the edge is the arc length from the multiline start vertex to the edge start vertex\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 * Return point on multiline at given length from the start of the multiline\n * @param length\n * @returns {Point | null}\n */\n pointAtLength(length) {\n if (length > this.length || length < 0) return null;\n if (this.isInfinite) return null\n\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 /**\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 * Calculate distance and shortest segment from any shape to multiline\n * @param shape\n * @returns {[number,Flatten.Segment]}\n */\n distanceTo(shape) {\n if (shape instanceof Point) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Line) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Circle) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Segment) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Arc) {\n const [dist, shortest_segment] = Flatten.Distance.shape2multiline(shape, this);\n return [dist, shortest_segment.reverse()];\n }\n\n if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.multiline2multiline(this, shape);\n }\n\n throw Flatten.Errors.UNSUPPORTED_SHAPE_TYPE;\n }\n\n /**\n * Calculate intersection of multiline with other shape\n * @param {Shape} shape\n * @returns {Point[]}\n */\n intersect(shape) {\n if (shape instanceof Flatten.Multiline) {\n return intersectMultiline2Multiline(this, shape);\n }\n else {\n return intersectShape2Multiline(shape, this);\n }\n }\n\n /**\n * Return true if multiline contains the shape: no point of shape lies outside\n * @param shape\n * @returns {boolean}\n */\n contains(shape) {\n if (shape instanceof Flatten.Point) {\n return this.edges.some(edge => edge.shape.contains(shape));\n }\n\n throw Flatten.Errors.UNSUPPORTED_SHAPE_TYPE;\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 be inserted into 'points' attribute of element\n * @returns {string}\n */\n svgPoints() {\n return this.vertices.map(p => `${p.x},${p.y}`).join(' ')\n }\n\n /**\n * Return string to be assigned to 'd' attribute of element\n * @returns {*}\n */\n dpath() {\n let dPathStr = `M${this.first.start.x},${this.first.start.y}`;\n for (let edge of this) {\n dPathStr += edge.svg();\n }\n return dPathStr\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$1;\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 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 // augment intersections with new sorted arrays\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\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 int_point.edge_before = edge.prev;\n if (edge.prev) {\n int_point.is_vertex = END_VERTEX$1; // polygon\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 else {\n if (polygon instanceof Multiline$1 && int_point.is_vertex & START_VERTEX$1) {\n int_point.edge_after = polygon.first;\n }\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 * @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$1([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$1([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$1([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$1([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 a 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} other_interval - Other interval to merge with\n * @returns {Interval}\n */\n merge(other_interval) {\n return new Interval(\n this.low === undefined ?\n other_interval.low : (this.low < other_interval.low ? this.low : other_interval.low),\n this.high === undefined ?\n other_interval.high : (this.high > other_interval.high ? 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 let [low, high] = key;\n if (low > high) [low, high] = [high, low];\n this.item.key = new Interval(low, high);\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);\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 return this.tree_find_any_interval(this.root, search_node);\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 /**\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 /**\n * @param {Interval} interval - optional if the iterator is intended to start from the beginning\n * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output\n * @returns {Iterator}\n */\n *iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {\n let node;\n if (interval) {\n node = this.tree_search_nearest_forward(this.root, new Node(interval));\n } else if (this.root) {\n node = this.local_minimum(this.root);\n }\n while (node) {\n yield outputMapperFn(node.item.value, node.item.key);\n node = this.tree_successor(node);\n }\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 tree_search_nearest_forward(node, search_node) {\n let best;\n let curr = node;\n while (curr && curr !== this.nil_node) {\n if (curr.less_than(search_node)) {\n if (curr.intersect(search_node)) {\n best = curr;\n curr = curr.left;\n } else {\n curr = curr.right;\n }\n } else {\n if (!best || curr.less_than(best)) best = curr;\n curr = curr.left;\n }\n }\n return best || null;\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.not_intersect_left_subtree(search_node)) {\n found = this.tree_find_any_interval(node.left, search_node);\n }\n if (!found) {\n found = node.intersect(search_node);\n }\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$3 = 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 if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.shape2multiline(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.contains && shape.contains instanceof Function) {\n return shape.contains(this);\n }\n\n throw Flatten.Errors.UNSUPPORTED_SHAPE_TYPE;\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$3;\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 */\nlet Segment$1 = class 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 {Segment} 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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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, 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 if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.shape2multiline(this, shape);\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$1;\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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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 if (shape instanceof Flatten.Multiline) {\n let [dist, shortest_segment] = Flatten.Distance.shape2multiline(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 if (shape instanceof Flatten.Multiline) {\n return intersectShape2Multiline(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 if (shape instanceof Flatten.Multiline) {\n return Flatten.Distance.shape2multiline(this, shape);\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 /**\n * Calculate distance and shortest segment from box 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 box to shape\n * @returns {Segment} shortest segment between box and shape (started at box, ended at shape)\n */\n distanceTo(shape) {\n const distanceInfos = this.toSegments()\n .map(segment => segment.distanceTo(shape));\n let shortestDistanceInfo = [\n Number.MAX_SAFE_INTEGER,\n null,\n ];\n distanceInfos.forEach(distanceInfo => {\n if (distanceInfo[0] < shortestDistanceInfo[0]) {\n shortestDistanceInfo = distanceInfo;\n }\n });\n return shortestDistanceInfo;\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 bidirectionally 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 = `M${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 */\nlet Polygon$1 = class 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 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 // 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$1([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 if (shape instanceof Flatten.Multiline) {\n return intersectMultiline2Polygon(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 be assigned to 'd' attribute of element\n * @returns {*}\n */\n dpath() {\n return [...this.faces].reduce((acc, face) => acc + face.svg(), \"\")\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$1;\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: Point$2, 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$2(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$2) {\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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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 point and edge\n * @param pt\n * @param edge\n * @returns {[number, Flatten.Segment]}\n */\n static point2edge(pt, edge) {\n return edge.shape instanceof Flatten.Segment ?\n Distance.point2segment(pt, edge.shape) :\n Distance.point2arc(pt, edge.shape);\n }\n\n /**\n * Calculate distance and shortest segment between segment and line\n * @param seg\n * @param line\n * @returns {[number, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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, Flatten.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] = Distance.point2edge(point, edge);\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, Flatten.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 /**\n * Calculate distance and shortest segment any shape and multiline\n * @param shape\n * @param multiline\n * @returns {[number, Flatten.Segment]}\n */\n static shape2multiline(shape, multiline) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge of multiline) {\n let [dist, shortest_segment] = Distance.distance(shape, 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 multilines\n * @param multiline1\n * @param multiline2\n * @returns {[number, Flatten.Segment]}\n */\n static multiline2multiline(multiline1, multiline2) {\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n for (let edge1 of multiline1) {\n for (let edge2 of multiline2) {\n let [dist, shortest_segment] = Distance.distance(edge1.shape, 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\nFlatten.Distance = Distance;\n\nconst {Multiline, Point: Point$1, Segment, Polygon} = Flatten;\n\n// POINT (30 10)\n// MULTIPOINT (10 40, 40 30, 20 20, 30 10)\n// LINESTRING (30 10, 10 30, 40 40)\n// MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))\n// MULTILINESTRING ((8503.732 4424.547, 8963.747 3964.532), (8963.747 3964.532, 8707.468 3708.253), (8707.468 3708.253, 8247.454 4168.268), (8247.454 4168.268, 8503.732 4424.547))\n// POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))\n// MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))\n// GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (0 0, 1440 900), POLYGON ((0 0, 0 1024, 1024 1024, 1024 0, 0 0)))\n// GEOMETRYCOLLECTION (POINT (40 10), LINESTRING (10 10, 20 20, 10 40), POLYGON ((40 40, 20 45, 45 30, 40 40)))\n\nfunction parseSinglePoint(pointStr) {\n return new Point$1(pointStr.split(' ').map(Number))\n}\n\nfunction parseMultiPoint(multipointStr) {\n return multipointStr.split(', ').map(parseSinglePoint)\n}\n\nfunction parseLineString(lineStr) {\n const points = parseMultiPoint(lineStr);\n let segments = [];\n for (let i = 0; i < points.length-1; i++) {\n segments.push(new Segment(points[i], points[i+1]));\n }\n return new Multiline(segments)\n}\n\nfunction parseMultiLineString(multilineStr) {\n const lineStrings = multilineStr.replace(/\\(\\(/, '').replace(/\\)\\)$/, '').split('), (');\n return lineStrings.map(parseLineString)\n}\n\nfunction parseSinglePolygon(polygonStr) {\n const facesStr = polygonStr.replace(/\\(\\(/, '').replace(/\\)\\)$/, '').split('), (');\n const polygon = new Polygon();\n let orientation;\n facesStr.forEach((facesStr, idx) => {\n let points = facesStr.split(', ').map(coordStr => {\n return new Point$1(coordStr.split(' ').map(Number))\n });\n const face = polygon.addFace(points);\n if (idx === 0) {\n orientation = face.orientation();\n }\n else {\n if (face.orientation() === orientation) {\n face.reverse();\n }\n }\n });\n return polygon\n}\n\nfunction parseMutliPolygon(multiPolygonString) {\n // const polygonStrings = multiPolygonString.split('?')\n // Split the string by the delimiter \")), ((\" which separates the polygons\n const polygonStrings = multiPolygonString.split(/\\)\\), \\(\\(/).map(polygon => '((' + polygon + '))');\n\n const polygons = polygonStrings.map(parseSinglePolygon);\n const polygon = new Polygon();\n const faces = polygons.reduce((acc, polygon) => [...acc, ...polygon?.faces], []);\n faces.forEach(face => polygon.addFace([...face?.shapes]));\n return polygon;\n}\n\nfunction parsePolygon(wkt) {\n if (wkt.startsWith(\"POLYGON\")) {\n const polygonStr = wkt.replace(/^POLYGON /, '');\n return parseSinglePolygon(polygonStr)\n }\n else {\n // const multiPolygonString = wkt.replace(/^MULTIPOLYGON \\(/, '').replace(/\\)$/, '').replace(/\\)\\), \\(\\(/,'))?((')\n const multiPolygonString = wkt.replace(/^MULTIPOLYGON \\(\\(\\((.*)\\)\\)\\)$/, '$1');\n return parseMutliPolygon(multiPolygonString)\n }\n}\n\nfunction parseArrayOfPoints(str) {\n const arr = str.split('\\n').map(x => x.match(/\\(([^)]+)\\)/)[1]);\n return arr.map(parseSinglePoint)\n}\n\nfunction parseArrayOfLineStrings(str) {\n const arr = str.split('\\n').map(x => x.match(/\\(([^)]+)\\)/)[1]);\n return arr.map(parseLineString).reduce((acc, x) => [...acc, ...x], [])\n}\n\n/**\n * Convert WKT string to array of Flatten shapes.\n * @param str\n * @returns {Point | Point[] | Multiline | Multiline[] | Polygon | Shape[] | null}\n */\nfunction parseWKT(str) {\n if (str.startsWith(\"POINT\")) {\n const pointStr = str.replace(/^POINT \\(/, '').replace(/\\)$/, '');\n return parseSinglePoint(pointStr)\n }\n else if (str.startsWith(\"MULTIPOINT\")) {\n const multiPointStr = str.replace(/^MULTIPOINT \\(/, '').replace(/\\)$/, '');\n return parseMultiPoint(multiPointStr)\n }\n else if (str.startsWith(\"LINESTRING\")) {\n const lineStr = str.replace(/^LINESTRING \\(/, '').replace(/\\)$/, '');\n return parseLineString(lineStr)\n }\n else if (str.startsWith(\"MULTILINESTRING\")) {\n const multilineStr = str.replace(/^MULTILINESTRING /, '');\n return parseMultiLineString(multilineStr)\n }\n else if (str.startsWith(\"POLYGON\") || str.startsWith(\"MULTIPOLYGON\")) {\n return parsePolygon(str)\n }\n else if (str.startsWith(\"GEOMETRYCOLLECTION\")) {\n // const regex = /(POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION) \\([^\\)]+\\)/g\n /* Explanation:\n(?POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON):\nThis named group will capture the geometry type. The type label helps with understanding the structure but\n is not necessary unless you process the matches programmatically and want easy access to the geometry type.\n\\( and \\): Match the opening and closing parentheses.\n(?:[^\\(\\)]|\\([^\\)]*\\))*: A non-capturing group that allows for:\n[^\\(\\)]: Matching any character except parentheses, handling simple geometries.\n|\\([^\\)]*\\): Handling nested parentheses for geometries like POLYGON and MULTILINESTRING.\n* after the non-capturing group: Allows for repeating the pattern zero or more times to match all contents between the outermost parentheses. */\n const regex = /(?POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \\((?:[^\\(\\)]|\\([^\\)]*\\))*\\)/g;\n const wktArray = str.match(regex);\n if (wktArray[0].startsWith('GEOMETRYCOLLECTION')) {\n wktArray[0] = wktArray[0].replace('GEOMETRYCOLLECTION (','');\n }\n const flArray = wktArray.map(parseWKT).map(x => x instanceof Array ? x : [x]);\n return flArray.reduce((acc, x) => [...acc, ...x], [])\n }\n else if (isArrayOfPoints(str)) {\n return parseArrayOfPoints(str)\n }\n else if (isArrayOfLines(str)) {\n return parseArrayOfLineStrings(str)\n }\n return []\n}\n\nfunction isArrayOfPoints(str) {\n return str.split('\\n')?.every(str => str.includes('POINT'))\n}\n\nfunction isArrayOfLines(str) {\n return str.split('\\n')?.every(str => str.includes('LINESTRING'))\n}\n\n/**\n * Return true if given string starts with one of WKT tags and possibly contains WKT string,\n * @param str\n * @returns {boolean}\n */\nfunction isWktString(str) {\n return (\n str.startsWith(\"POINT\") || isArrayOfPoints(str) ||\n str.startsWith(\"LINESTRING\") || isArrayOfLines(str) ||\n str.startsWith(\"MULTILINESTRING\") ||\n str.startsWith(\"POLYGON\") ||\n str.startsWith(\"MULTIPOINT\") ||\n str.startsWith(\"MULTIPOLYGON\") ||\n str.startsWith(\"GEOMETRYCOLLECTION\")\n )\n}\n\nFlatten.isWktString = isWktString;\nFlatten.parseWKT = parseWKT;\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$1 as Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$3 as Point, Polygon$1 as Polygon, Ray, Relations, Segment$1 as Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, isWktString, line, matrix, multiline, parseWKT, 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","defaultAttributes","SVGAttributes","args","property","acc","key","SVGKey","str","convertToString","attrs","intersectLine2Line","line1","line2","ip","A1","B1","C1","A2","B2","C2","det","detX","detY","intersectLine2Circle","line","circle","prj","dist","delta","v_trans","pt","intersectLine2Box","box","ips","seg","ips_tmp","intersectSegment2Line","ptInIntPoints","intersectLine2Arc","arc","ip_tmp","intersectSegment2Segment","seg1","seg2","new_ip","isPointInSegmentBox","point","segment","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","polygon","intersectArc2Polygon","intersectLine2Polygon","intersectCircle2Polygon","intersectEdge2Edge","edge1","edge2","intersectEdge2Polygon","resp_edges","resp_edge","intersectMultiline2Polygon","multiline","intersectPolygon2Polygon","polygon1","polygon2","intersectShape2Polygon","shape","new_pt","createLineFromRay","intersectRay2Circle","intersectRay2Box","intersectRay2Line","intersectRay2Ray","ray1","ray2","intersectRay2Polygon","intersectShape2Shape","shape1","shape2","intersectShape2Multiline","intersectMultiline2Multiline","multiline1","multiline2","Multiline$1","Multiline","validShapes","shapes","L","anyShape","s","anyShapeExceptLine","shapeSegmentOrArc","v","len","length","newEdge","edgeBefore","edgeFrom","edgeTo","edges","edgeFound","shortest_segment","angle","center","matrix","p","dPathStr","svgStr","addToIntPoints","int_points","id","is_vertex","arc_length","sortIntersections","intersections","getSortedArray","faceMap","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","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","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","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","resp","poly","notIntersected","notIntersectedFaces","poly2","poly1","int_points1","int_points1_sorted","int_points2","iterate_more","edge_tmp","new_bv","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","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","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","best","curr","found","node_min","node_max","node_successor","action","height","heightLeft","heightRight","PlanarSet","entry","size","deleted","Shape","Point$3","Point","arr","m","proj_vec","dx","dy","r","Vector$1","a1","a2","scalar","norm1","norm2","n","vector$1","Segment$1","Segment","coords","ps","pe","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","distanceInfos","shortestDistanceInfo","distanceInfo","width","Edge","bvMiddle","flag","sign","halfArc1","halfArc2","CircularLinkedList","done","Face","segments","points","flattenShapes","flattenShape","sArea","area","exitOnFirst","Ray","slope","Polygon$1","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","Point$2","Vector","Utils","Inversion","inversion_circle","k2","len2","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","Point$1","parseSinglePoint","pointStr","parseMultiPoint","multipointStr","parseLineString","lineStr","parseMultiLineString","multilineStr","parseSinglePolygon","polygonStr","facesStr","idx","coordStr","parseMutliPolygon","multiPolygonString","parsePolygon","wkt","parseArrayOfPoints","parseArrayOfLineStrings","parseWKT","multiPointStr","regex","wktArray","isArrayOfPoints","isArrayOfLines","_a","isWktString","DEFAULT_SIZE","DEFAULT_LEADER_TIME","_TrackSymbol","Path","latLng","options","Util","bounds","Bounds","LatLngBounds","paths","viewPath","shapeOptions","oldLatLng","heading","course","speed","modelAngle","leaderLength","leaderEndLatLng","LatLng","latLngs","zoomLevel","shapeSetEntriesFiltered","shapeSetEntry","shapeSet","headingAngle","units","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