@arl/leaflet-tracksymbol2
Version:
Leaflet track symbol
1,644 lines • 186 kB
JavaScript
import Qt, { LatLng as Lt, Path as On, Util as He, Bounds as Nn, LatLngBounds as Cn, Point as Rn, DomUtil as Mn } from "leaflet";
const Ge = !0, Un = !1, Dt = { CCW: -1, CW: 1, NOT_ORIENTABLE: 0 }, Fn = 2 * Math.PI, Wt = 1, qe = 0, D = 2, kn = 3, Bn = 4, Vn = 1, $n = 2, de = 0, bt = 1, mt = 2;
var zt = /* @__PURE__ */ Object.freeze({
__proto__: null,
BOUNDARY: D,
CCW: Ge,
CONTAINS: kn,
CW: Un,
END_VERTEX: mt,
INSIDE: Wt,
INTERLACE: Bn,
NOT_VERTEX: de,
ORIENTATION: Dt,
OUTSIDE: qe,
OVERLAP_OPPOSITE: $n,
OVERLAP_SAME: Vn,
PIx2: Fn,
START_VERTEX: bt
});
let Y = 1e-6;
function De(r) {
Y = r;
}
function We() {
return Y;
}
const Hn = 3;
function ie(r) {
return r < Y && r > -Y;
}
function rt(r, t) {
return r - t < Y && r - t > -Y;
}
function ze(r, t) {
return r - t > Y;
}
function Gn(r, t) {
return r - t > -Y;
}
function Ye(r, t) {
return r - t < -Y;
}
function qn(r, t) {
return r - t < Y;
}
var Dn = /* @__PURE__ */ Object.freeze({
__proto__: null,
DECIMALS: Hn,
EQ: rt,
EQ_0: ie,
GE: Gn,
GT: ze,
LE: qn,
LT: Ye,
getTolerance: We,
setTolerance: De
});
let i = {
Utils: Dn,
Errors: void 0,
Matrix: void 0,
Planar_set: void 0,
Point: void 0,
Vector: void 0,
Line: void 0,
Circle: void 0,
Segment: void 0,
Arc: void 0,
Box: void 0,
Edge: void 0,
Face: void 0,
Ray: void 0,
Ray_shooting: void 0,
Multiline: void 0,
Polygon: void 0,
Distance: void 0,
Inversion: void 0
};
for (let r in zt)
i[r] = zt[r];
Object.defineProperty(i, "DP_TOL", {
get: function() {
return We();
},
set: function(r) {
De(r);
}
});
class T {
/**
* Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter
* @returns {ReferenceError}
*/
static get ILLEGAL_PARAMETERS() {
return new ReferenceError("Illegal Parameters");
}
/**
* Throw error ZERO_DIVISION to catch situation of zero division
* @returns {Error}
*/
static get ZERO_DIVISION() {
return new Error("Zero division");
}
/**
* Error to throw from BooleanOperations module in case when fixBoundaryConflicts not capable to fix it
* @returns {Error}
*/
static get UNRESOLVED_BOUNDARY_CONFLICT() {
return new Error("Unresolved boundary conflict in boolean operation");
}
/**
* Error to throw from LinkedList:testInfiniteLoop static method
* in case when circular loop detected in linked list
* @returns {Error}
*/
static get INFINITE_LOOP() {
return new Error("Infinite loop");
}
static get CANNOT_COMPLETE_BOOLEAN_OPERATION() {
return new Error("Cannot complete boolean operation");
}
static get CANNOT_INVOKE_ABSTRACT_METHOD() {
return new Error("Abstract method cannot be invoked");
}
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 = T;
class ge {
constructor(t, e) {
this.first = t, this.last = e || this.first;
}
[Symbol.iterator]() {
let t;
return {
next: () => (t = t ? t.next : this.first, { value: t, done: t === void 0 })
};
}
/**
* Return number of elements in the list
* @returns {number}
*/
get size() {
let t = 0;
for (let e of this)
t++;
return t;
}
/**
* Return array of elements from start to end,
* If start or end not defined, take first as start, last as end
* @returns {Array}
*/
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 new element to the end of the list
* @param {LinkedListElement} element
* @returns {LinkedList}
*/
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 new element to the list after elementBefore
* @param {LinkedListElement} newElement
* @param {LinkedListElement} elementBefore
* @returns {LinkedList}
*/
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 element from the list
* @param {LinkedListElement} element
* @returns {LinkedList}
*/
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;
}
/**
* Return true if list is empty
* @returns {boolean}
*/
isEmpty() {
return this.first === void 0;
}
/**
* Throw an error if circular loop detected in the linked list
* @param {LinkedListElement} first element to start iteration
* @throws {Errors.INFINITE_LOOP}
*/
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 Se = {
stroke: "black"
};
class Wn {
constructor(t = Se) {
for (const e in t)
this[e] = t[e];
this.stroke = t.stroke ?? Se.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 ot(r) {
return new Wn(r).toAttributesString();
}
function It(r, t) {
let e = [], [n, s, l] = r.standard, [o, a, u] = t.standard, h = n * a - s * o, f = l * a - s * u, g = n * u - l * o;
if (!i.Utils.EQ_0(h)) {
let _, v;
s === 0 ? (_ = l / n, v = g / h) : a === 0 ? (_ = u / o, v = g / h) : n === 0 ? (_ = f / h, v = l / s) : o === 0 ? (_ = f / h, v = u / a) : (_ = f / h, v = g / h), e.push(new i.Point(_, v));
}
return e;
}
function lt(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 Et(r, t) {
let e = [];
for (let n of t.toSegments()) {
let s = Ft(n, r);
for (let l of s)
nn(l, e) || e.push(l);
}
return e;
}
function jt(r, t) {
let e = [];
if (Et(r, t.box).length === 0)
return e;
let n = new i.Circle(t.pc, t.r), s = lt(r, n);
for (let l of s)
l.on(t) && e.push(l);
return e;
}
function Ft(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 Zt(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 && ye(l[0], r) && ye(l[0], t) && e.push(l[0]);
}
return e;
}
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 Xt(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 = lt(n, t);
for (let l of s)
l.on(r) && e.push(l);
return e;
}
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 = lt(n, s);
for (let o of l)
o.on(r) && o.on(t) && e.push(o);
return e;
}
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 Qe(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 u = s * s / (2 * o) - l * l / (2 * o) + o / 2, h = r.pc.translate(u * n.x, u * n.y), f = Math.sqrt(s * s - u * u);
return a = h.translate(n.rotate90CCW().multiply(f)), e.push(a), a = h.translate(n.rotate90CW().multiply(f)), e.push(a), e;
}
function Yn(r, t) {
let e = [];
for (let n of t.toSegments()) {
let s = Xt(n, r);
for (let l of s)
e.push(l);
}
return e;
}
function je(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 pe(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 = Qe(n, s);
for (let o of l)
o.on(r) && e.push(o);
return e;
}
function Qn(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 Ze(r, t) {
return r.isSegment ? Zt(r.shape, t) : vt(t, r.shape);
}
function Xe(r, t) {
return r.isSegment ? vt(r.shape, t) : je(r.shape, t);
}
function Ke(r, t) {
return r.isSegment ? Ft(r.shape, t) : jt(t, r.shape);
}
function jn(r, t) {
return r.isSegment ? Ee(t, r.shape) : xe(t, r.shape);
}
function Zn(r, t) {
return r.isSegment ? Xt(r.shape, t) : pe(r.shape, t);
}
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 me(r, t) {
let e = [];
for (let n of t.edges)
for (let s of Xe(n, r))
e.push(s);
return e;
}
function kt(r, t) {
let e = [];
if (t.isEmpty())
return e;
for (let n of t.edges)
for (let s of Ke(n, r))
nn(s, e) || e.push(s);
return r.sortPoints(e);
}
function Je(r, t) {
let e = [];
if (t.isEmpty())
return e;
for (let n of t.edges)
for (let s of Zn(n, r))
e.push(s);
return e;
}
function tn(r, t) {
return r.isSegment ? Ze(t, r.shape) : r.isArc ? Xe(t, r.shape) : r.isLine ? Ke(t, r.shape) : r.isRay ? jn(t, r.shape) : [];
}
function en(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, ...tn(r, s)];
return e;
}
function Xn(r, t) {
let e = [];
if (t.isEmpty() || r.size === 0)
return e;
for (let n of r)
e = [...e, ...en(n, t)];
return e;
}
function Kn(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, ...en(n, t)];
return e;
}
function Jn(r, t) {
return r instanceof i.Line ? kt(r, t) : r instanceof i.Segment ? _e(r, t) : r instanceof i.Arc ? me(r, t) : [];
}
function nn(r, t) {
return t.some((e) => e.equalTo(r));
}
function nt(r) {
return new i.Line(r.start, r.norm);
}
function Ee(r, t) {
return Ft(t, nt(r)).filter((e) => r.contains(e));
}
function xe(r, t) {
return jt(nt(r), t).filter((e) => r.contains(e));
}
function rn(r, t) {
return lt(nt(r), t).filter((e) => r.contains(e));
}
function ti(r, t) {
return Et(nt(r), t).filter((e) => r.contains(e));
}
function sn(r, t) {
return It(nt(r), t).filter((e) => r.contains(e));
}
function ei(r, t) {
return It(nt(r), nt(t)).filter((e) => r.contains(e)).filter((e) => t.contains(e));
}
function on(r, t) {
return kt(nt(r), t).filter((e) => r.contains(e));
}
function ln(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, ...ln(r, n.shape)];
return e;
}
function ni(r, t) {
let e = [];
for (let n of r)
for (let s of t)
e = [...e, ...ln(n, s)];
return e;
}
let at = class At extends ge {
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 = (u) => u instanceof i.Segment || u instanceof i.Arc || u instanceof i.Ray || u instanceof i.Line, o = (u) => u instanceof i.Segment || u instanceof i.Arc || u instanceof i.Ray, a = (u) => u instanceof i.Segment || u 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(
(u) => u instanceof i.Ray || u instanceof i.Line
);
for (let u of n) {
let h = new i.Edge(u);
this.append(h);
}
this.setArcLength();
} else
throw i.Errors.ILLEGAL_PARAMETERS;
}
}
/**
* (Getter) Return array of edges
* @returns {Edge[]}
*/
get edges() {
return [...this];
}
/**
* (Getter) Return bounding box of the multiline
* @returns {Box}
*/
get box() {
return this.edges.reduce((t, e) => t.merge(e.box), new i.Box());
}
/**
* (Getter) Returns array of vertices
* @returns {Point[]}
*/
get vertices() {
let t = this.edges.map((e) => e.start);
return t.push(this.last.end), t;
}
/**
* (Getter) Returns length of the multiline, return POSITIVE_INFINITY if multiline is infinite
* @returns {number}
*/
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;
}
/**
* Return new cloned instance of Multiline
* @returns {Multiline}
*/
clone() {
return new At(this.toShapes());
}
/**
* 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
*/
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;
}
/**
* Return point on multiline at given length from the start of the multiline
* @param length
* @returns {Point | null}
*/
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;
}
/**
* 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}
*/
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 edges of multiline with intersection points and return mutated multiline
* @param {Point[]} ip - array of points to be added as new vertices
* @returns {Multiline}
*/
split(t) {
for (let e of t) {
let n = this.findEdgeByPoint(e);
this.addVertex(e, n);
}
return this;
}
/**
* Returns edge which contains given point
* @param {Point} pt
* @returns {Edge}
*/
findEdgeByPoint(t) {
let e;
for (let n of this)
if (n.shape.contains(t)) {
e = n;
break;
}
return e;
}
/**
* Calculate distance and shortest segment from any shape to multiline
* @param shape
* @returns {[number,Flatten.Segment]}
*/
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;
}
/**
* Calculate intersection of multiline with other shape
* @param {Shape} shape
* @returns {Point[]}
*/
intersect(t) {
return t instanceof i.Multiline ? ni(this, t) : Bt(t, this);
}
/**
* Return true if multiline contains the shape: no point of shape lies outside
* @param shape
* @returns {boolean}
*/
contains(t) {
if (t instanceof i.Point)
return this.edges.some((e) => e.shape.contains(t));
throw i.Errors.UNSUPPORTED_SHAPE_TYPE;
}
/**
* Returns new multiline translated by vector vec
* @param {Vector} vec
* @returns {Multiline}
*/
translate(t) {
return new At(this.edges.map((e) => e.shape.translate(t)));
}
/**
* 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
*/
rotate(t = 0, e = new i.Point()) {
return new At(this.edges.map((n) => n.shape.rotate(t, e)));
}
/**
* Return new multiline transformed using affine transformation matrix
* Method does not support unbounded shapes
* @param {Matrix} matrix - affine transformation matrix
* @returns {Multiline} - new multiline
*/
transform(t = new i.Matrix()) {
return new At(this.edges.map((e) => e.shape.transform(t)));
}
/**
* Transform multiline into array of shapes
* @returns {Shape[]}
*/
toShapes() {
return this.edges.map((t) => t.shape.clone());
}
/**
* 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 string to be inserted into 'points' attribute of <polyline> element
* @returns {string}
*/
svgPoints() {
return this.vertices.map((t) => `${t.x},${t.y}`).join(" ");
}
/**
* Return string to be assigned to 'd' attribute of <path> element
* @returns {*}
*/
dpath() {
let t = `M${this.first.start.x},${this.first.start.y}`;
for (let e of this)
t += e.svg();
return t;
}
/**
* 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 = `
<path ${ot({ fill: "none", ...t })} d="`;
e += `
M${this.first.start.x},${this.first.start.y}`;
for (let n of this)
e += n.svg();
return e += `" >
</path>`, e;
}
};
i.Multiline = at;
const ii = (...r) => new i.Multiline(...r);
i.multiline = ii;
function xt(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 = de;
rt(l, 0) && (o |= bt), rt(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
});
}
function Mt(r) {
r.int_points1_sorted = tt(r.int_points1), r.int_points2_sorted = tt(r.int_points2);
}
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(ri);
}
function ri(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 Te(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], !!rt(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 */
!rt(a.arc_length, n.arc_length)) {
n = a, e = r.int_points1[n.id];
continue;
}
let u = r.int_points1[a.id];
u.edge_before === e.edge_before && u.edge_after === e.edge_after && a.edge_before === n.edge_before && a.edge_after === n.edge_after && (u.id = -1, a.id = -1, t = !0);
}
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 re(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 se(r, t) {
for (let e of r)
e.edge_before && e.edge_before.setInclusion(t), e.edge_after && e.edge_after.setInclusion(t);
}
function si(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, u = Tt(r.int_points1_sorted, l, t), h;
a + u < s && r.int_points1_sorted[a + u].face === t ? h = a + u : h = e;
let f = Tt(r.int_points1_sorted, h, t);
n = null;
for (let E = h; E < h + f; 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 v = r.int_points2[o.id], I = r.int_points2[n.id], w = v.edge_after, S = I.edge_before;
w.bv === D && S.bv === D && w === S || (v = r.int_points2[n.id], I = r.int_points2[o.id], w = v.edge_after, S = I.edge_before), w.bv === D && S.bv === D && w === S && g.setOverlap(w);
}
}
function Tt(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 wt(r, t) {
if (t) {
for (let e of t) {
let n = e.edge_before;
if (e.is_vertex = de, 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 at && e.is_vertex & bt && (e.edge_after = r.first);
}
}
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: oi, OVERLAP_OPPOSITE: li } = zt, { NOT_VERTEX: mr, START_VERTEX: Ae, END_VERTEX: Le } = zt, Kt = 1, Vt = 2, st = 3;
function ai(r, t) {
let [e, n] = $t(r, t, Kt, !0);
return e;
}
function oe(r, t) {
let n = t.clone().reverse(), [s, l] = $t(r, n, st, !0);
return s;
}
function an(r, t) {
let [e, n] = $t(r, t, Vt, !0);
return e;
}
function fn(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 le(r, t) {
let [e, n] = $t(r, t, st, !1), s = [];
for (let l of e.faces)
s = [...s, ...[...l.edges].map((o) => o.shape)];
return s;
}
function un(r, t) {
let e = r.clone(), n = t.clone(), s = hn(e, n);
Mt(s), wt(e, s.int_points1_sorted), wt(n, s.int_points2_sorted), Te(s), Mt(s);
let l = s.int_points1_sorted.map((a) => a.pt), o = s.int_points2_sorted.map((a) => a.pt);
return [l, o];
}
function fi(r, t, e, n) {
let s = be(r, e.int_points1), l = be(t, e.int_points2);
for (Oe(s, t), Oe(l, r), re(e.int_points1), re(e.int_points2), se(e.int_points1, t), se(e.int_points2, r); hi(r, t, e.int_points1, e.int_points1_sorted, e.int_points2, e); ) ;
si(e), ae(r, n, e.int_points1_sorted, !0), ae(t, n, e.int_points2_sorted, !1), Ne(r, s, n, !0), Ne(t, l, n, !1);
}
function ui(r, t, e, n) {
ci(r, t, n, e.int_points2), di(r, t, e), fe(r, e.int_points1), fe(t, e.int_points2), ue(r, e.int_points1, e.int_points2), ue(r, e.int_points2, e.int_points1);
}
function $t(r, t, e, n) {
let s = r.clone(), l = t.clone(), o = hn(s, l);
return Mt(o), wt(s, o.int_points1_sorted), wt(l, o.int_points2_sorted), Te(o), Mt(o), fi(s, l, o, e), n && ui(s, l, o, e), [s, l];
}
function hn(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)
xt(n, a, e.int_points1), xt(l, a, e.int_points2);
}
}
return 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 Oe(r, t) {
for (let e of r)
e.first.bv = e.first.bvStart = e.first.bvEnd = void 0, e.first.setInclusion(t);
}
function hi(r, t, e, n, s, l) {
let o, a, u, h = n.length, f = !1;
for (let g = 0; g < h; g++) {
let _ = n[g];
_.face !== o && (a = g, o = _.face);
let v = g, I = Tt(n, g, o), w;
v + I < h && n[v + I].face === o ? w = v + I : w = a;
let S = Tt(n, w, o);
u = null;
for (let p = w; p < w + S; p++) {
let b = n[p];
if (b.face === o && s[b.id].face === s[_.id].face) {
u = b;
break;
}
}
if (u === null)
continue;
let E = _.edge_after, x = u.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, Jt] = p.shape.distanceTo(t);
if (b < 10 * i.DP_TOL) {
xt(p, Jt.ps, e);
let Z = e[e.length - 1];
if (Z.is_vertex & Ae)
Z.edge_after = p, Z.edge_before = p.prev, p.bvStart = P, p.bv = void 0, p.setInclusion(t);
else if (Z.is_vertex & Le)
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 ft = t.findEdgeByPoint(Jt.pe);
xt(ft, Jt.pe, s);
let X = s[s.length - 1];
if (X.is_vertex & Ae)
X.edge_after = ft, X.edge_before = ft.prev;
else if (X.is_vertex & Le)
X.edge_after = ft.next;
else {
let R = s.find((bn) => bn.edge_after === ft), O = t.addVertex(X.pt, ft);
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);
}
Mt(l), f = !0;
break;
}
}
p = p.next;
}
if (f)
break;
throw T.UNRESOLVED_BOUNDARY_CONFLICT;
}
}
return f;
}
function ae(r, t, e, n) {
if (!e) return;
let s, l, o, a;
for (let u = 0; u < e.length; u++) {
if (o = e[u], o.face !== s && (l = u, s = o.face), s.isEmpty())
continue;
let h = u, f = Tt(e, u, s), g;
h + f < e.length && e[h + f].face === o.face ? g = h + f : g = l, a = e[g];
let _ = g, v = Tt(e, _, s), I = o.edge_after, w = a.edge_before;
if (I.bv === W && w.bv === W && t === Kt || I.bv === z && w.bv === z && t === Vt || (I.bv === z || w.bv === z) && t === st && !n || (I.bv === W || w.bv === W) && t === st && n || I.bv === P && w.bv === P && I.overlap & oi && n || I.bv === P && w.bv === P && I.overlap & li) {
r.removeChain(s, I, w);
for (let S = h; S < h + f; S++)
e[S].edge_after = void 0;
for (let S = _; S < _ + v; S++)
e[S].edge_before = void 0;
}
u += f - 1;
}
}
function ci(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 di(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 fe(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 ue(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 {
ge.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);
}
}
function Ne(r, t, e, n) {
for (let s of t) {
let l = s.first.bv;
(e === Kt && l === W || e === st && l === W && n || e === st && l === z && !n || e === Vt && l === z) && r.deleteFace(s);
}
}
var gi = /* @__PURE__ */ Object.freeze({
__proto__: null,
BOOLEAN_INTERSECT: Vt,
BOOLEAN_SUBTRACT: st,
BOOLEAN_UNION: Kt,
calculateIntersections: un,
innerClip: fn,
intersect: an,
outerClip: le,
removeNotRelevantChains: ae,
removeOldFaces: fe,
restoreFaces: ue,
subtract: oe,
unify: ai
});
const pi = RegExp("T.F..FFF.|T.F...F.."), _i = RegExp("T........|.T.......|...T.....|....T...."), mi = RegExp("FT.......|F..T.....|F...T...."), Ei = RegExp("T.F..F..."), xi = 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);
}
/**
* Get Interior To Interior intersection
* @returns {Shape[] | undefined}
*/
get I2I() {
return this.m[0];
}
/**
* Set Interior To Interior intersection
* @param geom
*/
set I2I(t) {
this.m[0] = t;
}
/**
* Get Interior To Boundary intersection
* @returns {Shape[] | undefined}
*/
get I2B() {
return this.m[1];
}
/**
* Set Interior to Boundary intersection
* @param geomc
*/
set I2B(t) {
this.m[1] = t;
}
/**
* Get Interior To Exterior intersection
* @returns {Shape[] | undefined}
*/
get I2E() {
return this.m[2];
}
/**
* Set Interior to Exterior intersection
* @param geom
*/
set I2E(t) {
this.m[2] = t;
}
/**
* Get Boundary To Interior intersection
* @returns {Shape[] | undefined}
*/
get B2I() {
return this.m[3];
}
/**
* Set Boundary to Interior intersection
* @param geom
*/
set B2I(t) {
this.m[3] = t;
}
/**
* Get Boundary To Boundary intersection
* @returns {Shape[] | undefined}
*/
get B2B() {
return this.m[4];
}
/**
* Set Boundary to Boundary intersection
* @param geom
*/
set B2B(t) {
this.m[4] = t;
}
/**
* Get Boundary To Exterior intersection
* @returns {Shape[] | undefined}
*/
get B2E() {
return this.m[5];
}
/**
* Set Boundary to Exterior intersection
* @param geom
*/
set B2E(t) {
this.m[5] = t;
}
/**
* Get Exterior To Interior intersection
* @returns {Shape[] | undefined}
*/
get E2I() {
return this.m[6];
}
/**
* Set Exterior to Interior intersection
* @param geom
*/
set E2I(t) {
this.m[6] = t;
}
/**
* Get Exterior To Boundary intersection
* @returns {Shape[] | undefined}
*/
get E2B() {
return this.m[7];
}
/**
* Set Exterior to Boundary intersection
* @param geom
*/
set E2B(t) {
this.m[7] = t;
}
/**
* Get Exterior to Exterior intersection
* @returns {Shape[] | undefined}
*/
get E2E() {
return this.m[8];
}
/**
* Set Exterior to Exterior intersection
* @param geom
*/
set E2E(t) {
this.m[8] = t;
}
/**
* Return de9im matrix as string where<br/>
* - intersection is 'T'<br/>
* - not intersected is 'F'<br/>
* - not relevant is '*'<br/>
* For example, string 'FF**FF****' means 'DISJOINT'
* @returns {string}
*/
toString() {
return this.m.map((t) => t instanceof Array && t.length > 0 ? "T" : t instanceof Array && t.length === 0 ? "F" : "*").join("");
}
equal() {
return pi.test(this.toString());
}
intersect() {
return _i.test(this.toString());
}
touch() {
return mi.test(this.toString());
}
inside() {
return Ei.test(this.toString());
}
covered() {
return xi.test(this.toString());
}
}
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,
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], u = [];
for (let f of o)
for (let g of n.intersect(f.shape)) {
if (g.equalTo(t))
return i.BOUNDARY;
u.push({
pt: g,
edge: f,
face_index: a.indexOf(f.face)
});
}
u.sort((f, g) => Ye(f.pt.x, g.pt.x) ? -1 : ze(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 h = 0;
for (let f = 0; f < u.length; f++) {
let g = u[f];
if (g.pt.equalTo(g.edge.shape.start)) {
if (f > 0 && g.pt.equalTo(u[f - 1].pt) && g.face_index === u[f - 1].face_index && g.edge.prev === u[f - 1].edge)
continue;
let _ = g.edge.prev;
for (; ie(_.length); )
_ = _.prev;
let v = _.shape.tangentInEnd(), I = g.pt.translate(v), w = g.edge.shape.tangentInStart(), S = g.pt.translate(w), E = I.leftTo(s), x = S.leftTo(s);
(E && !x || !E && x) && h++;
} else if (g.pt.equalTo(g.edge.shape.end)) {
if (f > 0 && g.pt.equalTo(u[f - 1].pt) && g.face_index === u[f - 1].face_index && g.edge.next === u[f - 1].edge)
continue;
let _ = g.edge.next;
for (; ie(_.length); )
_ = _.next;
let v = _.shape.tangentInStart(), I = g.pt.translate(v), w = g.edge.shape.tangentInEnd(), S = g.pt.translate(w), E = I.leftTo(s), x = S.leftTo(s);
(E && !x || !E && x) && h++;
} else if (g.edge.shape instanceof i.Segment)
h++;
else {
let _ = g.edge.shape.box;
rt(g.pt.y, _.ymin) || rt(g.pt.y, _.ymax) || h++;
}
}
return e = h % 2 === 1 ? Wt : qe, e;
}
function Ti(r, t) {
return yt(r, t).equal();
}
function cn(r, t) {
return yt(r, t).intersect();
}
function wi(r, t) {
return yt(r, t).touch();
}
function Ii(r, t) {
return !cn(r, t);
}
function dn(r, t) {
return yt(r, t).inside();
}
function gn(r, t) {
return yt(r, t).covered();
}
function vi(r, t) {
return dn(t, r);
}
function pn(r, t) {
return gn(t, r);
}
function yt(r, t) {
if (r instanceof i.Line && t instanceof i.Line)
return Si(r, t);
if (r instanceof i.Line && t instanceof i.Circle)
return yi(r, t);
if (r instanceof i.Line && t instanceof i.Box)
return Pi(r, t);
if (r instanceof i.Line && t instanceof i.Polygon)
return Ai(r, t);
if ((r instanceof i.Segment || r instanceof i.Arc) && t instanceof i.Polygon)
return Ce(r, t);
if ((r instanceof i.Segment || r instanceof i.Arc) && (t instanceof i.Circle || t instanceof i.Box))
return Ce(r, new i.Polygon(t));
if (r instanceof i.Polygon && t instanceof i.Polygon)
return Ht(r, t);
if ((r instanceof i.Circle || r instanceof i.Box) && (t instanceof i.Circle || t instanceof i.Box))
return Ht(new i.Polygon(r), new i.Polygon(t));
if ((r instanceof i.Circle || r instanceof i.Box) && t instanceof i.Polygon)
return Ht(new i.Polygon(r), t);
if (r instanceof i.Polygon && (t instanceof i.Circle || t instanceof i.Box))
return Ht(r, new i.Polygon(t));
}
function Si(r, t) {
let e = new St(), n = It(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 yi(r, t) {
let e = new St(), n = lt(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 at([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 Pi(r, t) {
let e = new St(), n = Et(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 at([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 Ai(r, t) {
let e = new St(), n = kt(r, t), s = new at([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 Ce(r, t) {
let e = new St(), n = Jn(r, t), s = n.length > 0 ? n.slice() : r.sortPoints(n), l = new at([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 (Ot(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 Ht(r, t) {
let e = new St(), [n, s] = un(r, t), l = an(r, t), o = oe(r, t), a = oe(t, r), [u, h] = fn(r, t), f = le(r, t), g = le(t, r);
return e.I2I = l.isEmpty() ? [] : [l], e.I2B = h, e.I2E = o.isEmpty() ? [] : [o], e.B2I = u, e.B2B = n, e.B2E = f, e.E2I = a.isEmpty() ? [] : [a], e.E2B = g, e;
}
var Li = /* @__PURE__ */ Object.freeze({
__proto__: null,
contain: vi,
cover: pn,
covered: gn,
disjoint: Ii,
equal: Ti,
inside: dn,
intersect: cn,
relate: yt,
touch: wi
});
let Nt = class ct {
/**
* Construct new instance of affine transformation matrix <br/>
* If parameters omitted, construct identity matrix a = 1, d = 1
* @param {number} a - position(0,0) sx*cos(alpha)
* @param {number} b - position (0,1) sx*sin(alpha)
* @param {number} c - position (1,0) -sy*sin(alpha)
* @param {number} d - position (1,1) sy*cos(alpha)
* @param {number} tx - position (2,0) translation by x
* @param {number} ty - position (2,1) translation by y
*/
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;
}
/**
* Return new cloned instance of matrix
* @return {Matrix}
**/
clone() {
return new ct(this.a, this.b, this.c, this.d, this.tx, this.ty);
}
/**
* Transform vector [x,y] using transformation matrix. <br/>
* Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object <br/>
* The result is also an abstract vector [x',y'] = A * [x,y]:
* <code>
* [x' [ ax + by + tx
* y' = cx + dy + ty
* 1] 1 ]
* </code>
* @param {number[]} vector - array[2] of numbers
* @returns {number[]} transformation result - array[2] of numbers
*/
transform(t) {
return [
t[0] * this.a + t[1] * this.c + this.tx,
t[0] * this.b + t[1] * this.d + this.ty
];
}
/**
* Returns result of multiplication of this matrix by other matrix
* @param {Matrix} other_matrix - matrix to multiply by
* @returns {Matrix}
*/
multiply(t) {
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,
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
);
}
/**
* Return new matrix as a result of multiplication of the current matrix
* by the matrix(1,0,0,1,tx,ty)
* @param {Vector} vector - Translation by vector or
* @param {number} tx - translation by x-axis
* @param {number} ty - translation by y-axis
* @returns {Matrix}
*/
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 ct(1, 0, 0, 1, e, n));
}
/**
* Return new matrix as a result of multiplication of the current matrix
* by the matrix that defines rotation by given angle (in radians) around
* center of rotation (centerX,centerY) in counterclockwise direction
* @param {number} angle - angle in radians
* @param {number} centerX - center of rotation
* @param {number} centerY - center of rotation
* @returns {Matrix}
*/
rotate(t, e = 0, n = 0) {
let s = Math.cos(t), l = Math.sin(t);
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
* by the matrix (sx,0,0,sy,0,0) that defines scaling
* @param {number} sx
* @param {number} sy
* @returns {Matrix}
*/
scale(t, e) {
return this.multiply(new ct(t, 0, 0, e, 0, 0));
}
/**
* Returns true if two matrix are equal parameter by parameter
* @param {Matrix} matrix - other matrix
* @returns {boolean} true if equal, false otherwise
*/
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 = Nt;
const bi = (...r) => new i.Matrix(...r);
i.matrix = bi;
const Oi = class he {
/**
* Accept two comparable values and creates new instance of interval
* Predicate Interval.comparable_less(low, high) supposed to return true on these values
* @param low
* @param high
*/
constructor(t, e) {
this.low = t, this.high = e;
}
/**
* Clone interval
* @returns {Interval}
*/
clone() {
return new he(this.low, this.high);
}
/**
* Propery max returns clone of this interval
* @returns {Interval}
*/
get max() {
return this.clone();
}
/**
* Predicate returns true is this interval less than other interval
* @param other_interval
* @returns {boolean}
*/
less_than(t) {
return this.low < t.low || this.low == t.low && this.high < t.high;
}
/**
* Predicate returns true is this interval equals to other interval
* @param other_interval
* @returns {boolean}
*/
equal_to(t) {
return this.low == t.low && this.high == t.high;
}
/**
* Predicate returns true if this interval intersects other interval
* @param other_interval
* @returns {boolean}
*/
intersect(t) {
return !this.not_intersect(t);
}
/**
* Predicate returns true if this interval does not intersect other interval
* @param other_interval
* @returns {boolean}
*/
not_intersect(t) {
return this.high < t.low || t.high < this.low;
}
/**
* Returns new interval merged with other interval
* @param {Interval} interval - Other interval to merge with
* @returns {Interval}
*/
m