diff --git a/README.md b/README.md index e2307308..2e57c87d 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ var context = infiniteCanvas.getContext("2d"); Include `InfiniteCanvas` in your web page: ```html - + ``` or install it using npm: diff --git a/dist/infinite-canvas.js b/dist/infinite-canvas.js index 134dea00..79c0b1a2 100644 --- a/dist/infinite-canvas.js +++ b/dist/infinite-canvas.js @@ -1,4 +1,4 @@ -let Zn = class { +let gi = class { constructor(t) { this.viewBox = t; } @@ -8,8 +8,11 @@ let Zn = class { save() { this.viewBox.saveState(); } + reset() { + this.viewBox.resetState(); + } }; -const le = class ot { +const ve = class at { constructor(t, e) { this.x = t, this.y = e; } @@ -20,10 +23,10 @@ const le = class ot { return this.x * this.x + this.y * this.y; } minus(t) { - return new ot(this.x - t.x, this.y - t.y); + return new at(this.x - t.x, this.y - t.y); } plus(t) { - return new ot(this.x + t.x, this.y + t.y); + return new at(this.x + t.x, this.y + t.y); } dot(t) { return this.x * t.x + this.y * t.y; @@ -35,16 +38,16 @@ const le = class ot { return this.x === t.x && this.y === t.y; } getPerpendicular() { - return new ot(-this.y, this.x); + return new at(-this.y, this.x); } scale(t) { - return new ot(t * this.x, t * this.y); + return new at(t * this.x, t * this.y); } projectOn(t) { return t.scale(this.dot(t) / t.modSq()); } matrix(t, e, n, i) { - return new ot(t * this.x + e * this.y, n * this.x + i * this.y); + return new at(t * this.x + e * this.y, n * this.x + i * this.y); } inSameDirectionAs(t) { return this.cross(t) === 0 && this.dot(t) >= 0; @@ -60,14 +63,14 @@ const le = class ot { return n > 0 ? t.cross(this) >= 0 && this.cross(e) >= 0 : n < 0 ? t.cross(this) <= 0 && this.cross(e) <= 0 : t.dot(e) > 0 ? this.cross(t) === 0 && this.dot(t) > 0 : !0; } }; -le.origin = new le(0, 0); -let l = le; -function rt(r) { - return r.toFixed(10).replace(/\.?0+$/, ""); +ve.origin = new ve(0, 0); +let h = ve; +function ot(s) { + return s.toFixed(10).replace(/\.?0+$/, ""); } -const ue = class O { - constructor(t, e, n, i, s, o) { - this.a = t, this.b = e, this.c = n, this.d = i, this.e = s, this.f = o, this.scale = Math.sqrt(t * i - e * n); +const we = class B { + constructor(t, e, n, i, r, o) { + this.a = t, this.b = e, this.c = n, this.d = i, this.e = r, this.f = o, this.scale = Math.sqrt(t * i - e * n); } getMaximumLineWidthScale() { const t = this.a + this.c, e = this.b + this.d, n = this.a - this.c, i = this.b - this.d; @@ -84,15 +87,15 @@ const ue = class O { return { direction: this.untranslated().apply(t.direction) }; } apply(t) { - return new l(this.a * t.x + this.c * t.y + this.e, this.b * t.x + this.d * t.y + this.f); + return new h(this.a * t.x + this.c * t.y + this.e, this.b * t.x + this.d * t.y + this.f); } untranslated() { - const { x: t, y: e } = this.apply(l.origin); - return this.before(O.translation(-t, -e)); + const { x: t, y: e } = this.apply(h.origin); + return this.before(B.translation(-t, -e)); } before(t) { - const e = t.a * this.a + t.c * this.b, n = t.b * this.a + t.d * this.b, i = t.a * this.c + t.c * this.d, s = t.b * this.c + t.d * this.d, o = t.a * this.e + t.c * this.f + t.e, a = t.b * this.e + t.d * this.f + t.f; - return new O(e, n, i, s, o, a); + const e = t.a * this.a + t.c * this.b, n = t.b * this.a + t.d * this.b, i = t.a * this.c + t.c * this.d, r = t.b * this.c + t.d * this.d, o = t.a * this.e + t.c * this.f + t.e, a = t.b * this.e + t.d * this.f + t.f; + return new B(e, n, i, r, o, a); } equals(t) { return this.a === t.a && this.b === t.b && this.c === t.c && this.d === t.d && this.e === t.e && this.f === t.f; @@ -101,57 +104,57 @@ const ue = class O { var t = this.a * this.d - this.b * this.c; if (t == 0) throw new Error("error calculating inverse: zero determinant"); - const e = this.d / t, n = -this.b / t, i = -this.c / t, s = this.a / t, o = (this.c * this.f - this.d * this.e) / t, a = (this.b * this.e - this.a * this.f) / t; - return new O(e, n, i, s, o, a); + const e = this.d / t, n = -this.b / t, i = -this.c / t, r = this.a / t, o = (this.c * this.f - this.d * this.e) / t, a = (this.b * this.e - this.a * this.f) / t; + return new B(e, n, i, r, o, a); } static translation(t, e) { - return new O(1, 0, 0, 1, t, e); + return new B(1, 0, 0, 1, t, e); } static scale(t) { - return new O(t, 0, 0, t, 0, 0); + return new B(t, 0, 0, t, 0, 0); } - static zoom(t, e, n, i, s) { + static zoom(t, e, n, i, r) { const o = 1 - n; - return i !== void 0 ? new O(n, 0, 0, n, t * o + i, e * o + s) : new O(n, 0, 0, n, t * o, e * o); + return i !== void 0 ? new B(n, 0, 0, n, t * o + i, e * o + r) : new B(n, 0, 0, n, t * o, e * o); } - static translateZoom(t, e, n, i, s, o, a, c) { - const h = n - t, d = i - e, u = h * h + d * d; + static translateZoom(t, e, n, i, r, o, a, l) { + const c = n - t, d = i - e, u = c * c + d * d; if (u === 0) throw new Error("divide by 0"); - const g = a - s, p = c - o, P = g * g + p * p, x = Math.sqrt(P / u); - return O.zoom(t, e, x, s - t, o - e); + const g = a - r, v = l - o, P = g * g + v * v, T = Math.sqrt(P / u); + return B.zoom(t, e, T, r - t, o - e); } static rotation(t, e, n) { - const i = Math.cos(n), s = Math.sin(n), o = 1 - i; - return new O( + const i = Math.cos(n), r = Math.sin(n), o = 1 - i; + return new B( i, - s, - -s, + r, + -r, i, - t * o + e * s, - -t * s + e * o + t * o + e * r, + -t * r + e * o ); } - static translateRotateZoom(t, e, n, i, s, o, a, c) { - const h = n - t, d = i - e, u = h * h + d * d; + static translateRotateZoom(t, e, n, i, r, o, a, l) { + const c = n - t, d = i - e, u = c * c + d * d; if (u === 0) throw new Error("divide by 0"); - const g = a - s, p = c - o, P = t * i - e * n, x = n * h + i * d, k = t * h + e * d, G = (h * g + d * p) / u, Q = (h * p - d * g) / u, mt = -Q, vt = G, pt = (s * x - a * k - P * p) / u, wt = (o * x - c * k + P * g) / u; - return new O(G, Q, mt, vt, pt, wt); + const g = a - r, v = l - o, P = t * i - e * n, T = n * c + i * d, L = t * c + e * d, k = (c * g + d * v) / u, N = (c * v - d * g) / u, _ = -N, vt = k, wt = (r * T - a * L - P * v) / u, Pt = (o * T - l * L + P * g) / u; + return new B(k, N, _, vt, wt, Pt); } static create(t) { - if (t instanceof O) + if (t instanceof B) return t; - const { a: e, b: n, c: i, d: s, e: o, f: a } = t; - return new O(e, n, i, s, o, a); + const { a: e, b: n, c: i, d: r, e: o, f: a } = t; + return new B(e, n, i, r, o, a); } toString() { - return `x: (${rt(this.a)}, ${rt(this.b)}), y: (${rt(this.c)}, ${rt(this.d)}), d: (${rt(this.e)}, ${rt(this.f)})`; + return `x: (${ot(this.a)}, ${ot(this.b)}), y: (${ot(this.c)}, ${ot(this.d)}), d: (${ot(this.e)}, ${ot(this.f)})`; } }; -ue.identity = new ue(1, 0, 0, 1, 0, 0); -let v = ue; -class I { +we.identity = new we(1, 0, 0, 1, 0, 0); +let p = we; +class S { constructor(t, e) { this.propertyName = t, this.noopInstruction = e; } @@ -168,21 +171,21 @@ class I { return !0; } } -const T = () => { +const y = () => { }; -class _n extends I { +class mi extends S { valuesAreEqual(t, e) { return t.equals(e); } changeToNewValue(t) { return (e, n) => { - const { a: i, b: s, c: o, d: a, e: c, f: h } = n.getTransformationForInstruction(t); - e.setTransform(i, s, o, a, c, h); + const { a: i, b: r, c: o, d: a, e: l, f: c } = n.getTransformationForInstruction(t); + e.setTransform(i, r, o, a, l, c); }; } } -const Mt = new _n("transformation", T); -class ti { +const Mt = new mi("transformation", y); +class pi { constructor(t) { this.viewBox = t; } @@ -200,30 +203,30 @@ class ti { } } resetTransform() { - this.viewBox.changeState((t) => Mt.changeInstanceValue(t, v.identity)); + this.viewBox.changeState((t) => Mt.changeInstanceValue(t, p.identity)); } rotate(t) { - this.addTransformation(v.rotation(0, 0, t)); + this.addTransformation(p.rotation(0, 0, t)); } scale(t, e) { - this.addTransformation(new v(t, 0, 0, e, 0, 0)); + this.addTransformation(new p(t, 0, 0, e, 0, 0)); } - setTransform(t, e, n, i, s, o) { - let a, c, h, d, u, g; - typeof t == "number" ? (a = t, c = e, h = n, d = i, u = s, g = o) : t.a !== void 0 ? (a = t.a, c = t.b, h = t.c, d = t.d, u = t.e, g = t.f) : (a = t.m11, c = t.m12, h = t.m21, d = t.m22, u = t.m41, g = t.m42), this.viewBox.changeState((p) => Mt.changeInstanceValue(p, new v(a, c, h, d, u, g))); + setTransform(t, e, n, i, r, o) { + let a, l, c, d, u, g; + typeof t == "number" ? (a = t, l = e, c = n, d = i, u = r, g = o) : t.a !== void 0 ? (a = t.a, l = t.b, c = t.c, d = t.d, u = t.e, g = t.f) : (a = t.m11, l = t.m12, c = t.m21, d = t.m22, u = t.m41, g = t.m42), this.viewBox.changeState((v) => Mt.changeInstanceValue(v, new p(a, l, c, d, u, g))); } - transform(t, e, n, i, s, o) { - this.addTransformation(new v(t, e, n, i, s, o)); + transform(t, e, n, i, r, o) { + this.addTransformation(new p(t, e, n, i, r, o)); } translate(t, e) { - this.addTransformation(v.translation(t, e)); + this.addTransformation(p.translation(t, e)); } addTransformation(t) { const e = this.viewBox.state.current.transformation, n = t.before(e); this.viewBox.changeState((i) => Mt.changeInstanceValue(i, n)); } } -class ei extends I { +class vi extends S { valuesAreEqual(t, e) { return t === e; } @@ -231,8 +234,8 @@ class ei extends I { return (e) => e.globalAlpha = t; } } -const en = new ei("globalAlpha", T); -class ni extends I { +const pn = new vi("globalAlpha", y); +class wi extends S { valuesAreEqual(t, e) { return t === e; } @@ -240,8 +243,8 @@ class ni extends I { return (e) => e.globalCompositeOperation = t; } } -const nn = new ni("globalCompositeOperation", T); -class ii { +const vn = new wi("globalCompositeOperation", y); +class Pi { constructor(t) { this.viewBox = t; } @@ -249,16 +252,16 @@ class ii { return this.viewBox.state.current.globalAlpha; } set globalAlpha(t) { - this.viewBox.changeState((e) => en.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => pn.changeInstanceValue(e, t)); } get globalCompositeOperation() { return this.viewBox.state.current.globalCompositeOperation; } set globalCompositeOperation(t) { - this.viewBox.changeState((e) => nn.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => vn.changeInstanceValue(e, t)); } } -class si extends I { +class Ci extends S { valuesAreEqual(t, e) { return t === e; } @@ -268,8 +271,8 @@ class si extends I { }; } } -const sn = new si("imageSmoothingEnabled", T); -class ri extends I { +const wn = new Ci("imageSmoothingEnabled", y); +class Ii extends S { valuesAreEqual(t, e) { return t === e; } @@ -279,8 +282,8 @@ class ri extends I { }; } } -const rn = new ri("imageSmoothingQuality", T); -class oi { +const Pn = new Ii("imageSmoothingQuality", y); +class Ti { constructor(t) { this.viewBox = t; } @@ -288,18 +291,18 @@ class oi { return this.viewBox.state.current.imageSmoothingEnabled; } set imageSmoothingEnabled(t) { - this.viewBox.changeState((e) => sn.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => wn.changeInstanceValue(e, t)); } get imageSmoothingQuality() { return this.viewBox.state.current.imageSmoothingQuality; } set imageSmoothingQuality(t) { - this.viewBox.changeState((e) => rn.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => Pn.changeInstanceValue(e, t)); } } -class Ht { +class qt { } -class on extends Ht { +class Cn extends qt { constructor(t) { super(), this.fillStrokeStyle = t; } @@ -317,7 +320,7 @@ class on extends Ht { }; } } -class an { +class In { constructor(t) { this.propName = t; } @@ -329,25 +332,25 @@ class an { } getInstructionToChange(t, e) { const n = e[this.propName]; - return this.isEqualForInstances(t, e) ? !(n instanceof Ht) || t.fillAndStrokeStylesTransformed === e.fillAndStrokeStylesTransformed ? () => { - } : e.fillAndStrokeStylesTransformed ? n.getInstructionToSetTransformed(this.propName) : n.getInstructionToSetUntransformed(this.propName) : n instanceof Ht ? e.fillAndStrokeStylesTransformed ? n.getInstructionToSetTransformed(this.propName) : n.getInstructionToSetUntransformed(this.propName) : (i) => { + return this.isEqualForInstances(t, e) ? !(n instanceof qt) || t.fillAndStrokeStylesTransformed === e.fillAndStrokeStylesTransformed ? () => { + } : e.fillAndStrokeStylesTransformed ? n.getInstructionToSetTransformed(this.propName) : n.getInstructionToSetUntransformed(this.propName) : n instanceof qt ? e.fillAndStrokeStylesTransformed ? n.getInstructionToSetTransformed(this.propName) : n.getInstructionToSetUntransformed(this.propName) : (i) => { i[this.propName] = e[this.propName]; }; } valueIsTransformableForInstance(t) { - return !(t[this.propName] instanceof on); + return !(t[this.propName] instanceof Cn); } } -const cn = new an("fillStyle"), hn = new an("strokeStyle"); -class ai { +const Tn = new In("fillStyle"), Sn = new In("strokeStyle"); +class Si { constructor(t) { this.viewBox = t; } set fillStyle(t) { - this.viewBox.changeState((e) => cn.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => Tn.changeInstanceValue(e, t)); } set strokeStyle(t) { - this.viewBox.changeState((e) => hn.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => Sn.changeInstanceValue(e, t)); } createLinearGradient(t, e, n, i) { return this.viewBox.createLinearGradient(t, e, n, i); @@ -355,14 +358,14 @@ class ai { createPattern(t, e) { return this.viewBox.createPattern(t, e); } - createRadialGradient(t, e, n, i, s, o) { - return this.viewBox.createRadialGradient(t, e, n, i, s, o); + createRadialGradient(t, e, n, i, r, o) { + return this.viewBox.createRadialGradient(t, e, n, i, r, o); } createConicGradient(t, e, n) { return this.viewBox.createConicGradient(t, e, n); } } -class ci extends I { +class yi extends S { valuesAreEqual(t, e) { return t === e; } @@ -372,11 +375,11 @@ class ci extends I { }; } } -const ln = new ci("shadowColor", T); -class hi extends I { +const yn = new yi("shadowColor", y); +class xi extends S { changeToNewValue(t) { return (e, n) => { - const i = v.translation(t.x, t.y), s = n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i), { x: o, y: a } = s.apply(l.origin); + const i = p.translation(t.x, t.y), r = n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i), { x: o, y: a } = r.apply(h.origin); e.shadowOffsetX = o, e.shadowOffsetY = a; }; } @@ -384,11 +387,11 @@ class hi extends I { return t.x === e.x && t.y == e.y; } } -const de = new hi("shadowOffset", T); -class li extends I { +const Pe = new xi("shadowOffset", y); +class bi extends S { changeToNewValue(t) { return (e, n) => { - const i = v.translation(t, 0), o = n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i).apply(l.origin).mod(); + const i = p.translation(t, 0), o = n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i).apply(h.origin).mod(); e.shadowBlur = o; }; } @@ -396,8 +399,8 @@ class li extends I { return t === e; } } -const un = new li("shadowBlur", T); -class ui { +const xn = new bi("shadowBlur", y); +class Oi { constructor(t) { this.viewBox = t; } @@ -405,35 +408,35 @@ class ui { return this.viewBox.state.current.shadowBlur; } set shadowBlur(t) { - this.viewBox.changeState((e) => un.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => xn.changeInstanceValue(e, t)); } get shadowOffsetX() { return this.viewBox.state.current.shadowOffset.x; } set shadowOffsetX(t) { - const e = new l(t, this.viewBox.state.current.shadowOffset.y); - this.viewBox.changeState((n) => de.changeInstanceValue(n, e)); + const e = new h(t, this.viewBox.state.current.shadowOffset.y); + this.viewBox.changeState((n) => Pe.changeInstanceValue(n, e)); } get shadowOffsetY() { return this.viewBox.state.current.shadowOffset.y; } set shadowOffsetY(t) { - const e = new l(this.viewBox.state.current.shadowOffset.x, t); - this.viewBox.changeState((n) => de.changeInstanceValue(n, e)); + const e = new h(this.viewBox.state.current.shadowOffset.x, t); + this.viewBox.changeState((n) => Pe.changeInstanceValue(n, e)); } get shadowColor() { return this.viewBox.state.current.shadowColor; } set shadowColor(t) { - this.viewBox.changeState((e) => ln.changeInstanceValue(e, t)); + this.viewBox.changeState((e) => yn.changeInstanceValue(e, t)); } } -const dn = "[+-]?(?:\\d*\\.)?\\d+(?:e[+-]?\\d+)?", fn = "[+-]?(?:0*\\.)?0+(?:e[+-]?\\d+)?", gn = "(?:ch|em|ex|ic|rem|vh|vw|vmax|vmin|vb|vi|cqw|cqh|cqi|cqb|cqmin|cqmax|px|cm|mm|Q|in|pc|pt)", Vt = `(?:${fn}|${dn}${gn})`, mn = `blur\\((${Vt})\\)`, He = "[^())\\s]+(?:\\([^)]*?\\))?", vn = `drop-shadow\\((${Vt})\\s+(${Vt})\\s*?(?:(?:(${Vt})\\s*?(${He})?)|(${He}))?\\)`, qe = `${mn}|${vn}`; -function L(r, t) { - const e = r.match(new RegExp(`(?:(${fn})|(${dn})(${gn}))`)); +const bn = "[+-]?(?:\\d*\\.)?\\d+(?:e[+-]?\\d+)?", On = "[+-]?(?:0*\\.)?0+(?:e[+-]?\\d+)?", Ln = "(?:ch|em|ex|ic|rem|vh|vw|vmax|vmin|vb|vi|cqw|cqh|cqi|cqb|cqmin|cqmax|px|cm|mm|Q|in|pc|pt)", Nt = `(?:${On}|${bn}${Ln})`, Bn = `blur\\((${Nt})\\)`, Ze = "[^())\\s]+(?:\\([^)]*?\\))?", An = `drop-shadow\\((${Nt})\\s+(${Nt})\\s*?(?:(?:(${Nt})\\s*?(${Ze})?)|(${Ze}))?\\)`, _e = `${Bn}|${An}`; +function R(s, t) { + const e = s.match(new RegExp(`(?:(${On})|(${bn})(${Ln}))`)); return e[1] ? 0 : t.getNumberOfPixels(Number.parseFloat(e[2]), e[3]); } -class pn { +class Dn { constructor(t) { this.stringRepresentation = t; } @@ -444,66 +447,66 @@ class pn { return null; } } -class ve { +class be { constructor(t, e) { this.stringRepresentation = t, this.size = e; } toTransformedString(t) { - return `blur(${t.translateInfiniteCanvasContextTransformationToBitmapTransformation(v.translation(this.size, 0)).apply(l.origin).mod()}px)`; + return `blur(${t.translateInfiniteCanvasContextTransformationToBitmapTransformation(p.translation(this.size, 0)).apply(h.origin).mod()}px)`; } getShadowOffset() { return null; } static tryCreate(t, e) { - const n = t.match(new RegExp(mn)); - return n === null ? null : new ve(t, L(n[1], e)); + const n = t.match(new RegExp(Bn)); + return n === null ? null : new be(t, R(n[1], e)); } } -class ct { - constructor(t, e, n, i, s) { - this.stringRepresentation = t, this.offsetX = e, this.offsetY = n, this.blurRadius = i, this.color = s; +class ht { + constructor(t, e, n, i, r) { + this.stringRepresentation = t, this.offsetX = e, this.offsetY = n, this.blurRadius = i, this.color = r; } toTransformedString(t) { - const e = t.translateInfiniteCanvasContextTransformationToBitmapTransformation(v.translation(this.offsetX, this.offsetY)), { x: n, y: i } = e.apply(l.origin); + const e = t.translateInfiniteCanvasContextTransformationToBitmapTransformation(p.translation(this.offsetX, this.offsetY)), { x: n, y: i } = e.apply(h.origin); if (this.blurRadius !== null) { - const o = t.translateInfiniteCanvasContextTransformationToBitmapTransformation(v.translation(this.blurRadius, 0)).apply(l.origin).mod(); + const o = t.translateInfiniteCanvasContextTransformationToBitmapTransformation(p.translation(this.blurRadius, 0)).apply(h.origin).mod(); return this.color ? `drop-shadow(${n}px ${i}px ${o}px ${this.color})` : `drop-shadow(${n}px ${i}px ${o}px)`; } return this.color ? `drop-shadow(${n}px ${i}px ${this.color})` : `drop-shadow(${n}px ${i}px)`; } getShadowOffset() { - return new l(this.offsetX, this.offsetY); + return new h(this.offsetX, this.offsetY); } static tryCreate(t, e) { - const n = t.match(new RegExp(vn)); - return n === null ? null : n[5] ? new ct( + const n = t.match(new RegExp(An)); + return n === null ? null : n[5] ? new ht( t, - L(n[1], e), - L(n[2], e), + R(n[1], e), + R(n[2], e), null, n[5] - ) : n[4] ? new ct( + ) : n[4] ? new ht( t, - L(n[1], e), - L(n[2], e), - L(n[3], e), + R(n[1], e), + R(n[2], e), + R(n[3], e), n[4] - ) : n[3] ? new ct( + ) : n[3] ? new ht( t, - L(n[1], e), - L(n[2], e), - L(n[3], e), + R(n[1], e), + R(n[2], e), + R(n[3], e), null - ) : new ct( + ) : new ht( t, - L(n[1], e), - L(n[2], e), + R(n[1], e), + R(n[2], e), null, null ); } } -const fe = class wn { +const Ce = class En { constructor(t, e) { this.stringRepresentation = t, this.parts = e; } @@ -522,17 +525,17 @@ const fe = class wn { return null; } static create(t, e) { - const i = t.match(new RegExp(`${qe}|((?!\\s|${qe}).)+`, "g")).map((s) => this.createPart(s, e)); - return new wn(t, i); + const i = t.match(new RegExp(`${_e}|((?!\\s|${_e}).)+`, "g")).map((r) => this.createPart(r, e)); + return new En(t, i); } static createPart(t, e) { - let n = ve.tryCreate(t, e); - return n !== null || (n = ct.tryCreate(t, e), n != null) ? n : new pn(t); + let n = be.tryCreate(t, e); + return n !== null || (n = ht.tryCreate(t, e), n != null) ? n : new Dn(t); } }; -fe.none = new fe("none", [new pn("none")]); -let Pn = fe; -class di extends I { +Ce.none = new Ce("none", [new Dn("none")]); +let Fn = Ce; +class Li extends S { valuesAreEqual(t, e) { return t.stringRepresentation === e.stringRepresentation; } @@ -540,8 +543,8 @@ class di extends I { return (e, n) => e.filter = t.toTransformedString(n); } } -const Cn = new di("filter", T); -class fi { +const Rn = new Li("filter", y); +class Bi { constructor(t, e) { this.viewBox = t, this.cssLengthConverterFactory = e; } @@ -549,11 +552,11 @@ class fi { return this.viewBox.state.current.filter.stringRepresentation; } set filter(t) { - const e = Pn.create(t, this.cssLengthConverterFactory.create()); - this.viewBox.changeState((n) => Cn.changeInstanceValue(n, e)); + const e = Fn.create(t, this.cssLengthConverterFactory.create()); + this.viewBox.changeState((n) => Rn.changeInstanceValue(n, e)); } } -class gi { +class Ai { constructor(t) { this.viewBox = t; } @@ -561,14 +564,14 @@ class gi { this.viewBox.clearArea(t, e, n, i); } fillRect(t, e, n, i) { - let s = (o) => o.fill(); - this.viewBox.fillRect(t, e, n, i, s); + let r = (o) => o.fill(); + this.viewBox.fillRect(t, e, n, i, r); } strokeRect(t, e, n, i) { this.viewBox.strokeRect(t, e, n, i); } } -class mi { +class Di { constructor(t) { this.viewBox = t; } @@ -606,26 +609,27 @@ class mi { this.viewBox.strokePath(); } } -class vi { +class Ei { drawFocusIfNeeded(t, e) { } scrollPathIntoView(t) { } } -var W = /* @__PURE__ */ ((r) => (r[r.None = 0] = "None", r[r.Relative = 1] = "Relative", r[r.Absolute = 2] = "Absolute", r))(W || {}); -function pi(r, t, e, n) { - const i = e.minus(r), s = n.cross(t), o = n.getPerpendicular().dot(i) / s; - return r.plus(t.scale(o)); +var M = /* @__PURE__ */ ((s) => (s[s.None = 0] = "None", s[s.Relative = 1] = "Relative", s[s.Absolute = 2] = "Absolute", s))(M || {}), I = /* @__PURE__ */ ((s) => (s[s.Positive = 0] = "Positive", s[s.Negative = 1] = "Negative", s))(I || {}); +const zt = { direction: new h(0, 1) }, Gt = { direction: new h(0, -1) }, Yt = { direction: new h(-1, 0) }, Xt = { direction: new h(1, 0) }; +function Fi(s, t, e, n) { + const i = e.minus(s), r = n.cross(t), o = n.getPerpendicular().dot(i) / r; + return s.plus(t.scale(o)); } -class et { +class it { constructor(t, e, n) { this.point = t, this.leftHalfPlane = e, this.rightHalfPlane = n, this.leftNormal = e.normalTowardInterior, this.rightNormal = n.normalTowardInterior; } replaceLeftHalfPlane(t) { - return new et(this.point, t, this.rightHalfPlane); + return new it(this.point, t, this.rightHalfPlane); } replaceRightHalfPlane(t) { - return new et(this.point, this.leftHalfPlane, t); + return new it(this.point, this.leftHalfPlane, t); } isContainedByHalfPlaneWithNormal(t) { return t.isInSmallerAngleBetweenPoints(this.leftNormal, this.rightNormal); @@ -649,7 +653,7 @@ class et { return e.dot(n) <= 0 && (e = e.scale(-1)), new w(t, e); } static create(t, e, n) { - return e.normalTowardInterior.cross(n.normalTowardInterior) >= 0 ? new et(t, e, n) : new et(t, n, e); + return e.normalTowardInterior.cross(n.normalTowardInterior) >= 0 ? new it(t, e, n) : new it(t, n, e); } } class w { @@ -687,7 +691,7 @@ class w { } intersectWithLine(t, e) { return { - point: pi(this.base, this.normalTowardInterior.getPerpendicular(), t, e), + point: Fi(this.base, this.normalTowardInterior.getPerpendicular(), t, e), halfPlane: this }; } @@ -696,13 +700,13 @@ class w { } getIntersectionWith(t) { const e = this.intersectWithLine(t.base, t.normalTowardInterior.getPerpendicular()); - return et.create(e.point, this, t); + return it.create(e.point, this, t); } static throughPointsAndContainingPoint(t, e, n) { const i = w.withBorderPoints(t, e); - for (let s of i) - if (s.containsPoint(n)) - return s; + for (let r of i) + if (r.containsPoint(n)) + return r; } static withBorderPointAndInfinityInDirection(t, e) { return w.withBorderPoints(t, t.plus(e)); @@ -715,7 +719,7 @@ class w { ]; } } -class wi { +class Ri { getVertices() { return []; } @@ -786,8 +790,8 @@ class wi { return !0; } } -const It = new wi(); -class Pi { +const gt = new Ri(); +class Wi { getVertices() { return []; } @@ -858,7 +862,7 @@ class Pi { return t; } } -const b = new Pi(); +const O = new Wi(); class m { constructor(t, e) { this.vertices = e, this.halfPlanes = t, this.vertices = this.vertices || m.getVertices(this.halfPlanes); @@ -916,14 +920,14 @@ class m { const i = this.getVerticesOnHalfPlane(n); if (i.length <= 1 && (n.isContainedByHalfPlane(e) || e.isContainedByHalfPlane(n))) return !1; - const s = n.getIntersectionWith(t), o = i.find((a) => a.point.equals(s.point)); + const r = n.getIntersectionWith(t), o = i.find((a) => a.point.equals(r.point)); if (o) { if (!o.isContainedByHalfPlaneWithNormal(t.normalTowardInterior)) return !1; } else { if (i.length === 0) return !1; - if (this.containsPoint(s.point)) + if (this.containsPoint(r.point)) return !1; } } @@ -938,7 +942,7 @@ class m { return new m(d); } const e = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(); - let i = null, s = null; + let i = null, r = null; const o = [], a = /* @__PURE__ */ new Set(); for (const d of this.vertices) { const u = d.leftHalfPlane; @@ -952,40 +956,40 @@ class m { i = d; continue; } - g.containsPoint(t) && (a.add(g), s = d); + g.containsPoint(t) && (a.add(g), r = d); } if (o.length === this.vertices.length) return this; - let c, h; + let l, c; if (i === null) { const d = [...e][0]; if (!d) return this; - c = d.expandToIncludePoint(t); + l = d.expandToIncludePoint(t); } else - c = i.getContainingHalfPlaneThroughPoint(t), c !== i.leftHalfPlane && o.push(i.replaceRightHalfPlane(c)); - if (s === null) { + l = i.getContainingHalfPlaneThroughPoint(t), l !== i.leftHalfPlane && o.push(i.replaceRightHalfPlane(l)); + if (r === null) { const d = [...n][0]; if (!d) return this; - h = d.expandToIncludePoint(t); + c = d.expandToIncludePoint(t); } else - h = s.getContainingHalfPlaneThroughPoint(t), h !== s.rightHalfPlane && o.push(s.replaceLeftHalfPlane(h)); - return a.add(c), a.add(h), o.push(new et(t, c, h)), new m([...a], o); + c = r.getContainingHalfPlaneThroughPoint(t), c !== r.rightHalfPlane && o.push(r.replaceLeftHalfPlane(c)); + return a.add(l), a.add(c), o.push(new it(t, l, c)), new m([...a], o); } expandToIncludeInfinityInDirection(t) { if (this.containsInfinityInDirection(t)) return this; let e = this.halfPlanes.filter((n) => n.containsInfinityInDirection(t)).concat(this.getTangentPlanesThroughInfinityInDirection(t)); - return e = m.getHalfPlanesNotContainingAnyOther(e), e.length === 0 ? It : new m(e); + return e = m.getHalfPlanesNotContainingAnyOther(e), e.length === 0 ? gt : new m(e); } getIntersectionsWithLine(t, e) { const n = []; for (let i of this.halfPlanes) { if (i.isParallelToLine(t, e)) continue; - const s = i.intersectWithLine(t, e), o = this.findVertex(s.point); - o && !o.containsLineSegmentWithDirection(e) || this.containsPoint(s.point) && n.push(s); + const r = i.intersectWithLine(t, e), o = this.findVertex(r.point); + o && !o.containsLineSegmentWithDirection(e) || this.containsPoint(r.point) && n.push(r); } return n; } @@ -1001,11 +1005,11 @@ class m { if (this.isContainedByConvexPolygon(t)) return this; if (this.isOutsideConvexPolygon(t)) - return b; - const e = m.getHalfPlanesNotContainingAnyOther(this.halfPlanes.concat(t.halfPlanes)), s = m.groupVerticesByPoint(m.getVertices(e)).map((a) => m.getVerticesNotContainingAnyOther(a)).reduce((a, c) => a.concat(c), []); - if (s.length === 0) + return O; + const e = m.getHalfPlanesNotContainingAnyOther(this.halfPlanes.concat(t.halfPlanes)), r = m.groupVerticesByPoint(m.getVertices(e)).map((a) => m.getVerticesNotContainingAnyOther(a)).reduce((a, l) => a.concat(l), []); + if (r.length === 0) return new m(e); - const o = m.getHalfPlanes(s); + const o = m.getHalfPlanes(r); return new m(o); } containsInfinityInDirection(t) { @@ -1058,8 +1062,8 @@ class m { const e = []; for (let n of this.vertices) { const i = w.withBorderPointAndInfinityInDirection(n.point, t); - for (let s of i) - this.isContainedByHalfPlane(s) && e.push(s); + for (let r of i) + this.isContainedByHalfPlane(r) && e.push(r); } return e; } @@ -1096,8 +1100,8 @@ class m { const e = []; for (let n = 0; n < t.length; n++) { let i = !0; - for (let s = 0; s < t.length; s++) - if (n !== s && t[s].isContainedByVertex(t[n])) { + for (let r = 0; r < t.length; r++) + if (n !== r && t[r].isContainedByVertex(t[n])) { i = !1; break; } @@ -1109,8 +1113,8 @@ class m { const e = []; for (let n of t) { let i = !0; - for (let s of e) - if (s.isContainedByHalfPlane(n)) { + for (let r of e) + if (r.isContainedByHalfPlane(n)) { i = !1; break; } @@ -1122,9 +1126,9 @@ class m { const e = []; for (let n of t) { let i; - for (let s of e) - if (s[0].point.equals(n.point)) { - i = s; + for (let r of e) + if (r[0].point.equals(n.point)) { + i = r; break; } i ? i.push(n) : e.push([n]); @@ -1135,31 +1139,31 @@ class m { const e = []; for (let n = 0; n < t.length; n++) for (let i = n + 1; i < t.length; i++) { - const s = t[n], o = t[i]; - if (s.complement().isContainedByHalfPlane(o)) + const r = t[n], o = t[i]; + if (r.complement().isContainedByHalfPlane(o)) continue; - const a = s.getIntersectionWith(o); - let c = !0; - for (let h = 0; h < t.length; h++) { - if (h === n || h === i) + const a = r.getIntersectionWith(o); + let l = !0; + for (let c = 0; c < t.length; c++) { + if (c === n || c === i) continue; - if (!t[h].containsPoint(a.point)) { - c = !1; + if (!t[c].containsPoint(a.point)) { + l = !1; break; } } - c && e.push(a); + l && e.push(a); } return e; } static createTriangleWithInfinityInTwoDirections(t, e, n) { - const i = e.getPerpendicular(), s = n.getPerpendicular(); + const i = e.getPerpendicular(), r = n.getPerpendicular(); return e.cross(n) < 0 ? new m([ new w(t, i.scale(-1)), - new w(t, s) + new w(t, r) ]) : new m([ new w(t, i), - new w(t, s.scale(-1)) + new w(t, r.scale(-1)) ]); } static createFromHalfPlane(t) { @@ -1180,1121 +1184,965 @@ class m { w.throughPointsAndContainingPoint(e, n, t) ]); } - static createRectangle(t, e, n, i) { - const s = []; - return Number.isFinite(t) && (s.push(new w(new l(t, 0), n > 0 ? new l(1, 0) : new l(-1, 0))), Number.isFinite(n) && s.push(new w(new l(t + n, 0), n > 0 ? new l(-1, 0) : new l(1, 0)))), Number.isFinite(e) && (s.push(new w(new l(0, e), i > 0 ? new l(0, 1) : new l(0, -1))), Number.isFinite(i) && s.push(new w(new l(0, e + i), i > 0 ? new l(0, -1) : new l(0, 1)))), new m(s); - } } -class Ci { - constructor(t) { - this.viewBox = t; +function $(...s) { + return (...t) => { + for (const e of s) + e && e(...t); + }; +} +function ki(s, t) { + return t ? (e, n) => { + e.save(), t(e, n), s(e, n), e.restore(); + } : s; +} +function Hi(s) { + return s === M.Relative ? (t, e) => { + const { a: n, b: i, c: r, d: o, e: a, f: l } = e.getBitmapTransformationToTransformedInfiniteCanvasContext(); + t.transform(n, i, r, o, a, l); + } : s === M.Absolute ? (t, e) => { + const { a: n, b: i, c: r, d: o, e: a, f: l } = e.getBitmapTransformationToInfiniteCanvasContext(); + t.setTransform(n, i, r, o, a, l); + } : null; +} +function Vi(s, t) { + let e = s.area; + return e && t.lineWidth > 0 && (e = e.expandByDistance(t.lineWidth / 2)), e; +} +function Mi(s) { + return { + lineWidth: s.current.getMaximumLineWidth(), + lineDashPeriod: s.current.getLineDashPeriod(), + shadowOffsets: s.current.getShadowOffsets() + }; +} +function Ni(s) { + return { + lineWidth: 0, + lineDashPeriod: 0, + shadowOffsets: s.current.getShadowOffsets() + }; +} +class H { + constructor(t, e, n, i, r, o, a) { + this.instruction = t, this.area = e, this.build = n, this.takeClippingRegionIntoAccount = i, this.transformationKind = r, this.state = o, this.tempState = a; } - fillText(t, e, n, i) { - let s = i === void 0 ? (o) => { - o.fillText(t, e, n); - } : (o) => { - o.fillText(t, e, n, i); - }; - this.viewBox.addDrawing(s, this.getDrawnRectangle(e, n, t), W.Relative, !0); + static forStrokingPath(t, e, n) { + return H.forPath(t, e, Mi, n); } - measureText(t) { - return this.viewBox.measureText(t); + static forFillingPath(t, e, n) { + return H.forPath(t, e, Ni, n); } - strokeText(t, e, n, i) { - let s = i === void 0 ? (o) => { - o.strokeText(t, e, n); - } : (o) => { - o.strokeText(t, e, n, i); - }; - this.viewBox.addDrawing(s, this.getDrawnRectangle(e, n, t), W.Relative, !0); + static forPath(t, e, n, i) { + const r = e.current.isTransformable(), o = r ? M.None : M.Relative, a = e.currentlyTransformed(r), l = n(a), c = i(a), d = Vi(c, l); + return new H( + t, + d, + (u) => c.drawPath(u, a, l), + !0, + o, + a + ); } - getDrawnRectangle(t, e, n) { - const i = this.viewBox.measureText(n); - let s; - i.actualBoundingBoxRight !== void 0 ? s = Math.abs(i.actualBoundingBoxRight - i.actualBoundingBoxLeft) : s = i.width; - const o = i.actualBoundingBoxAscent !== void 0 ? i.actualBoundingBoxAscent + i.actualBoundingBoxDescent : 1, a = i.actualBoundingBoxAscent !== void 0 ? i.actualBoundingBoxAscent : 0; - return m.createRectangle(t, e - a, s, o); + getDrawnArea() { + let t = this.area; + const e = this.state; + if (e.current.shadowBlur !== 0 || !e.current.shadowOffset.equals(h.origin)) { + const n = t.expandByDistance(e.current.shadowBlur).transform(p.translation(e.current.shadowOffset.x, e.current.shadowOffset.y)); + t = t.join(n); + } + return e.current.clippingRegion && this.takeClippingRegionIntoAccount && (t = t.intersectWith(e.current.clippingRegion)), t; + } + getModifiedInstruction() { + let t = Hi(this.transformationKind); + if (this.tempState) { + const n = this.takeClippingRegionIntoAccount ? this.state.getInstructionToConvertToStateWithClippedPath(this.tempState) : this.state.getInstructionToConvertToState(this.tempState); + t = $(t, n); + } + return ki(this.instruction, t); } } -class Ii { +class Oe { constructor(t) { - this.viewBox = t; - } - drawImage() { - const t = Array.prototype.slice.apply(arguments); - let e, n, i, s, o, a, c, h, d; - arguments.length <= 5 ? [e, a, c, h, d] = t : [e, n, i, s, o, a, c, h, d] = t; - const u = this.getDrawnLength(e.width, n, s, h), g = this.getDrawnLength(e.height, i, o, d), p = m.createRectangle(a, c, u, g), P = this.getDrawImageInstruction(arguments.length, e, n, i, s, o, a, c, h, d); - this.viewBox.addDrawing(P, p, W.Relative, !0); + this.initiallyWithState = t, this.added = []; } - getDrawImageInstruction(t, e, n, i, s, o, a, c, h, d) { - switch (t) { - case 3: - return (u) => { - u.drawImage(e, a, c); - }; - case 5: - return (u) => { - u.drawImage(e, a, c, h, d); - }; - case 9: - return (u) => { - u.drawImage(e, n, i, s, o, a, c, h, d); - }; - default: - throw new TypeError(`Failed to execute 'drawImage' on 'CanvasRenderingContext2D': Valid arities are: [3, 5, 9], but ${t} arguments provided.`); - } + get length() { + return this.added.length; } - getDrawnLength(t, e, n, i) { - const s = this.getLength(t); - return i !== void 0 ? i : e !== void 0 ? n !== void 0 ? n : s - e : s; + get currentlyWithState() { + return this.addedLast ? this.addedLast : this.initiallyWithState; } - getLength(t) { - return typeof t == "number" ? t : t.baseVal.value; + reconstructState(t, e) { + e.setInitialState(t); } -} -function Ti(r, t, e, n, i) { - t = t === void 0 ? 0 : t, e = e === void 0 ? 0 : e, n = n === void 0 ? r.width : n, i = i === void 0 ? r.height : i; - const s = r.data, o = new Uint8ClampedArray(4 * n * i); - for (let a = 0; a < i; a++) - for (let c = 0; c < n; c++) { - const h = 4 * ((e + a) * r.width + t + c), d = 4 * (a * n + c); - o[d] = s[h], o[d + 1] = s[h + 1], o[d + 2] = s[h + 2], o[d + 3] = s[h + 3]; - } - return new ImageData(o, n, i); -} -class qt { - constructor(t, e, n) { - this.area = t, this.latestClippedPath = e, this.previouslyClippedPaths = n; + get stateOfFirstInstruction() { + return this.initiallyWithState.stateOfFirstInstruction; } - withClippedPath(t) { - const e = t.area.intersectWith(this.area); - return new qt(e, t, this); + get state() { + return this.currentlyWithState.state; } get initialState() { - return this.previouslyClippedPaths ? this.previouslyClippedPaths.initialState : this.latestClippedPath.initialState; + return this.initiallyWithState.initialState; } - except(t) { - if (t !== this) - return this.previouslyClippedPaths ? new qt(this.area, this.latestClippedPath, this.previouslyClippedPaths.except(t)) : this; + addClippedPath(t) { + this.currentlyWithState.addClippedPath(t); + } + add(t) { + this.added.push(t), this.addedLast = t; + } + removeAll(t) { + let e; + for (; (e = this.added.findIndex(t)) > -1; ) + this.removeAtIndex(e); } contains(t) { - return t ? this === t ? !0 : this.previouslyClippedPaths ? this.previouslyClippedPaths.contains(t) : !1 : !1; + return !!this.added.find(t); } - getInstructionToRecreate() { - const t = (e, n) => { - this.latestClippedPath.execute(e, n); - }; - if (this.previouslyClippedPaths) { - const e = this.previouslyClippedPaths.getInstructionToRecreate(), n = this.previouslyClippedPaths.latestClippedPath.state.getInstructionToConvertToState(this.latestClippedPath.initialState); - return (i, s) => { - e(i, s), n(i, s), t(i, s); - }; - } - return t; + setInitialState(t) { + this.initiallyWithState.setInitialState(t); } -} -class Si extends I { - valuesAreEqual(t, e) { - return t === e; + setInitialStateWithClippedPaths(t) { + this.initiallyWithState.setInitialStateWithClippedPaths(t); } - changeToNewValue(t) { - return (e) => { - e.direction = t; - }; + beforeIndex(t) { + return t === 0 ? this.initiallyWithState.state : this.added[t - 1].state; } -} -const pe = new Si("direction", T); -class yi extends I { - valuesAreEqual(t, e) { - return t === e; + removeAtIndex(t) { + t === this.added.length - 1 ? this.added.length === 1 ? this.addedLast = void 0 : this.addedLast = this.added[t - 1] : this.reconstructState(this.beforeIndex(t), this.added[t + 1]), this.added.splice(t, 1); } - changeToNewValue(t) { - return (e) => { - e.font = t; +} +class Le { + constructor(t, e) { + this.initialState = t, this.state = e, this.stateConversion = () => { }; } -} -const we = new yi("font", T); -class In { - constructor(t) { - this.propertyName = t; + setInitialState(t) { + this.initialState = t; + const e = this.initialState.getInstructionToConvertToState(this.state); + this.stateConversion = e; } - changeInstanceValue(t, e) { - return this.valuesAreEqual(t[this.propertyName], e) ? t : t.changeProperty(this.propertyName, e); + get stateOfFirstInstruction() { + return this.state; } - isEqualForInstances(t, e) { - return this.valuesAreEqual(t[this.propertyName], e[this.propertyName]); + addClippedPath(t) { + this.state = this.state.withClippedPath(t); } - valueIsTransformableForInstance(t) { - return !0; + setInitialStateWithClippedPaths(t) { + this.initialState = t; + const e = this.initialState.getInstructionToConvertToStateWithClippedPath(this.state); + this.stateConversion = e; } - changeToNewValue(t, e) { - return e ? this.changeToNewValueTransformed(t) : this.changeToNewValueUntransformed(t); +} +class U extends Le { + constructor(t, e, n, i) { + super(t, e), this.instruction = n, this.stateConversion = i; } - getInstructionToChange(t, e) { - const n = t[this.propertyName], i = e[this.propertyName]; - return this.valuesAreEqual(n, i) && (t.fillAndStrokeStylesTransformed === e.fillAndStrokeStylesTransformed || this.valuesAreEqualWhenTransformed(n, i)) ? () => { - } : this.changeToNewValue(i, e.fillAndStrokeStylesTransformed); + execute(t, e) { + this.stateConversion && this.stateConversion(t, e), this.instruction(t, e); + } + static create(t, e) { + return new U(t, t, e, () => { + }); } } -class Tn extends In { - constructor(t) { - super(t); +class ft extends Le { + constructor(t, e, n, i) { + super(t, e), this.instruction = n, this.stateConversion = i; } - valuesAreEqual(t, e) { - return t === e; + makeExecutable() { + return new U(this.initialState, this.state, this.instruction, this.stateConversion); } - changeToNewValueTransformed(t) { - return (e, n) => { - const i = n.userTransformation; - e[this.propertyName] = t * i.scale; - }; + static create(t, e) { + return new ft(t, t, e, () => { + }); } - changeToNewValueUntransformed(t) { - return (e) => { - e[this.propertyName] = t; - }; +} +function C(s) { + return s.direction !== void 0; +} +function Q(s, t) { + return C(s) ? t.applyToPointAtInfinity(s) : t.apply(s); +} +class qi { + constructor(t, e) { + this.areaBuilder = t, this.transformation = e; } - valuesAreEqualWhenTransformed(t, e) { - return t === 0 && e === 0; + addPosition(t) { + this.areaBuilder.addPosition(Q(t, this.transformation)); } } -const Sn = new Tn("lineWidth"), yn = new Tn("lineDashOffset"); -class bi extends In { - valuesAreEqual(t, e) { - if (t.length !== e.length) - return !1; - for (let n = 0; n < t.length; n++) - if (t[n] !== e[n]) - return !1; - return !0; +class Be { + constructor(t, e) { + this.base = t, this.direction = e; } - changeToNewValueTransformed(t) { - return (e, n) => { - const i = n.userTransformation; - e.setLineDash(t.map((s) => s * i.scale)); - }; + pointIsOnSameLine(t) { + return t.minus(this.base).cross(this.direction) === 0; } - changeToNewValueUntransformed(t) { - return (e) => { - e.setLineDash(t); - }; + comesBefore(t, e) { + return e.minus(t).dot(this.direction) >= 0; } - valuesAreEqualWhenTransformed(t, e) { - return t.length === 0 && e.length === 0; + lineSegmentIsOnSameLine(t) { + return this.direction.cross(t.direction) === 0 && this.pointIsOnSameLine(t.point1); } -} -const bn = new bi("lineDash"); -class xi extends I { - valuesAreEqual(t, e) { - return t === e; + expandLineByDistance(t) { + const e = this.direction.getPerpendicular(), n = new w(this.base, e).expandByDistance(t), i = new w(this.base, e.scale(-1)).expandByDistance(t); + return new m([n, i]); } - changeToNewValue(t) { - return (e) => { - e.textAlign = t; - }; + getPointsInSameDirection(t, e) { + return this.comesBefore(e, t) ? { point1: e, point2: t } : { point1: t, point2: e }; } -} -const Pe = new xi("textAlign", T); -class Oi extends I { - valuesAreEqual(t, e) { - return t === e; + pointIsBetweenPoints(t, e, n) { + return t.minus(e).dot(this.direction) * t.minus(n).dot(this.direction) <= 0; } - changeToNewValue(t) { - return (e) => { - e.textBaseline = t; - }; + intersectsConvexPolygon(t) { + if (this.isContainedByConvexPolygon(t)) + return !0; + const e = t.getIntersectionsWithLine(this.base, this.direction); + for (let n of e) + if (this.interiorContainsPoint(n.point)) + return !0; + return !1; } } -const Ce = new Oi("textBaseline", T); -class Bi extends I { - valuesAreEqual(t, e) { - return t === e; +class ie extends Be { + getVertices() { + return []; } - changeToNewValue(t) { - return (e) => e.lineCap = t; + intersectWith(t) { + return t.intersectWithLine(this); } -} -const xn = new Bi("lineCap", T); -class Ai extends I { - valuesAreEqual(t, e) { - return t === e; + join(t) { + return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1)); } - changeToNewValue(t) { - return (e) => e.lineJoin = t; + intersectWithConvexPolygon(t) { + if (!this.intersectsConvexPolygon(t)) + return O; + if (this.isContainedByConvexPolygon(t)) + return this; + const e = t.getIntersectionsWithLine(this.base, this.direction); + let n, i; + for (let r of e) + (!n && !i || !n && this.comesBefore(r.point, i) || !i && this.comesBefore(n, r.point) || n && i && this.pointIsBetweenPoints(r.point, n, i)) && (r.halfPlane.normalTowardInterior.dot(this.direction) > 0 ? n = r.point : i = r.point); + return n && i ? new D(n, i) : n ? new V(n, this.direction) : new V(i, this.direction.scale(-1)); } -} -const On = new Ai("lineJoin", T); -class Di extends I { - valuesAreEqual(t, e) { - return t === e; + intersectWithLine(t) { + return this.intersectsLine(t) ? this : O; } - changeToNewValue(t) { - return (e) => e.miterLimit = t; + intersectWithLineSegment(t) { + return this.lineSegmentIsOnSameLine(t) ? t : O; } -} -const Bn = new Di("miterLimit", T), oe = [ - pe, - sn, - rn, - cn, - yn, - bn, - xn, - On, - Bn, - en, - nn, - Cn, - Sn, - hn, - Pe, - Ce, - Mt, - we, - de, - un, - ln -], Li = [ - we, - Pe, - Ce, - pe -]; -function q(...r) { - return (...t) => { - for (const e of r) - e && e(...t); - }; -} -function Ei(r, t) { - return t ? (e, n) => { - e.save(), t(e, n), r(e, n), e.restore(); - } : r; -} -function Fi(r) { - return r === W.Relative ? (t, e) => { - const { a: n, b: i, c: s, d: o, e: a, f: c } = e.getBitmapTransformationToTransformedInfiniteCanvasContext(); - t.transform(n, i, s, o, a, c); - } : r === W.Absolute ? (t, e) => { - const { a: n, b: i, c: s, d: o, e: a, f: c } = e.getBitmapTransformationToInfiniteCanvasContext(); - t.setTransform(n, i, s, o, a, c); - } : null; -} -const Gt = class An { - constructor(t) { - this.fillStyle = t.fillStyle, this.lineWidth = t.lineWidth, this.lineCap = t.lineCap, this.lineJoin = t.lineJoin, this.lineDash = t.lineDash, this.miterLimit = t.miterLimit, this.globalAlpha = t.globalAlpha, this.globalCompositeOperation = t.globalCompositeOperation, this.filter = t.filter, this.strokeStyle = t.strokeStyle, this.lineDashOffset = t.lineDashOffset, this.transformation = t.transformation, this.direction = t.direction, this.imageSmoothingEnabled = t.imageSmoothingEnabled, this.imageSmoothingQuality = t.imageSmoothingQuality, this.font = t.font, this.textAlign = t.textAlign, this.textBaseline = t.textBaseline, this.clippedPaths = t.clippedPaths, this.fillAndStrokeStylesTransformed = t.fillAndStrokeStylesTransformed, this.shadowOffset = t.shadowOffset, this.shadowColor = t.shadowColor, this.shadowBlur = t.shadowBlur; + intersectWithRay(t) { + return this.intersectsRay(t) ? t : O; } - changeProperty(t, e) { - const { - fillStyle: n, - lineWidth: i, - lineDash: s, - lineCap: o, - lineJoin: a, - miterLimit: c, - globalAlpha: h, - globalCompositeOperation: d, - filter: u, - strokeStyle: g, - lineDashOffset: p, - transformation: P, - direction: x, - imageSmoothingEnabled: k, - imageSmoothingQuality: G, - font: Q, - textAlign: mt, - textBaseline: vt, - clippedPaths: pt, - fillAndStrokeStylesTransformed: wt, - shadowOffset: ne, - shadowColor: ie, - shadowBlur: se - } = this, Dt = { - fillStyle: n, - lineWidth: i, - lineDash: s, - lineCap: o, - lineJoin: a, - miterLimit: c, - globalAlpha: h, - globalCompositeOperation: d, - filter: u, - strokeStyle: g, - lineDashOffset: p, - transformation: P, - direction: x, - imageSmoothingEnabled: k, - imageSmoothingQuality: G, - font: Q, - textAlign: mt, - textBaseline: vt, - clippedPaths: pt, - fillAndStrokeStylesTransformed: wt, - shadowOffset: ne, - shadowColor: ie, - shadowBlur: se - }; - return Dt[t] = e, new An(Dt); + isContainedByConvexPolygon(t) { + return t.containsPoint(this.base) && t.containsInfinityInDirection(this.direction) && t.containsInfinityInDirection(this.direction.scale(-1)); } - get clippingRegion() { - return this.clippedPaths ? this.clippedPaths.area : void 0; + isContainedByLine(t) { + return this.intersectsSubsetOfLine(t); } - equals(t) { - for (let e of oe) - if (!e.isEqualForInstances(this, t)) - return !1; - return (!this.clippedPaths && !t.clippedPaths || this.clippedPaths && this.clippedPaths === t.clippedPaths) && this.fillAndStrokeStylesTransformed === t.fillAndStrokeStylesTransformed; + isContainedByLineSegment(t) { + return !1; } - getMaximumLineWidth() { - return this.lineWidth * this.transformation.getMaximumLineWidthScale(); + isContainedByRay(t) { + return !1; } - getLineDashPeriod() { - return this.lineDash.reduce((t, e) => t + e, 0); + contains(t) { + return t.isContainedByLine(this); } - isTransformable() { - for (let t of oe) - if (!t.valueIsTransformableForInstance(this)) - return !1; - return !0; + intersectsLine(t) { + return this.intersectsSubsetOfLine(t); } - getShadowOffsets() { - const t = [], e = this.filter.getShadowOffset(); - return e !== null && t.push(e), this.shadowOffset.equals(l.origin) || t.push(this.shadowOffset), t; + intersectsSubsetOfLine(t) { + return this.pointIsOnSameLine(t.base) && this.direction.cross(t.direction) === 0; } - getInstructionToConvertToState(t) { - return this.getInstructionToConvertToStateOnDimensions(t, oe); + intersectsLineSegment(t) { + return this.lineSegmentIsOnSameLine(t); } - withClippedPath(t) { - const e = this.clippedPaths ? this.clippedPaths.withClippedPath(t) : new qt(t.area, t); - return this.changeProperty("clippedPaths", e); + intersectsRay(t) { + return this.intersectsSubsetOfLine(t); } - getInstructionToConvertToStateOnDimensions(t, e) { - const n = e.map((i) => i.getInstructionToChange(this, t)); - return q(...n); + intersects(t) { + return t.intersectsLine(this); } -}; -Gt.default = new Gt({ - fillStyle: "#000", - lineWidth: 1, - lineDash: [], - lineCap: "butt", - lineJoin: "miter", - miterLimit: 10, - globalAlpha: 1, - globalCompositeOperation: "source-over", - filter: Pn.none, - strokeStyle: "#000", - lineDashOffset: 0, - transformation: v.identity, - direction: "inherit", - imageSmoothingEnabled: !0, - imageSmoothingQuality: "low", - font: "10px sans-serif", - textAlign: "start", - textBaseline: "alphabetic", - clippedPaths: void 0, - fillAndStrokeStylesTransformed: !1, - shadowOffset: l.origin, - shadowColor: "rgba(0, 0, 0, 0)", - shadowBlur: 0 -}); -Gt.setDefault = () => { -}; -let M = Gt; -class Wi { - constructor(t) { - this.viewBox = t; + expandToIncludePoint(t) { + return this.pointIsOnSameLine(t) ? this : m.createTriangleWithInfinityInDirection(this.base, t, this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1)); } - createImageData(t, e) { + expandByDistance(t) { + return this.expandLineByDistance(t); } - getImageData(t, e, n, i) { + expandToIncludeInfinityInDirection(t) { + const e = t.cross(this.direction), n = this.direction.getPerpendicular(); + return e === 0 ? this : e > 0 ? m.createFromHalfPlane(new w(this.base, n.scale(-1))) : m.createFromHalfPlane(new w(this.base, n)); } - putImageData(t, e, n, i, s, o, a) { - t = Ti(t, i, s, o, a); - let c, h = this.viewBox.getDrawingLock(); - this.viewBox.createPatternFromImageData(t).then((u) => { - c = u, h.release(); - }), this.viewBox.addDrawing((u) => { - u.translate(e, n), u.fillStyle = c, u.fillRect(0, 0, t.width, t.height); - }, m.createRectangle(e, n, t.width, t.height), W.Absolute, !1, (u) => u.changeProperty("shadowColor", M.default.shadowColor).changeProperty("shadowOffset", M.default.shadowOffset).changeProperty("shadowBlur", M.default.shadowBlur).changeProperty("globalAlpha", M.default.globalAlpha).changeProperty("globalCompositeOperation", M.default.globalCompositeOperation).changeProperty("imageSmoothingEnabled", !1).changeProperty("filter", M.default.filter)); + transform(t) { + const e = t.apply(this.base); + return new ie(e, t.apply(this.base.plus(this.direction)).minus(e)); + } + interiorContainsPoint(t) { + return this.pointIsOnSameLine(t); } } -class ki { - constructor(t) { - this.viewBox = t; +class V extends Be { + getVertices() { + return [this.base]; } - get lineCap() { - return this.viewBox.state.current.lineCap; + intersectWith(t) { + return t.intersectWithRay(this); } - set lineCap(t) { - this.viewBox.changeState((e) => xn.changeInstanceValue(e, t)); + join(t) { + return t.expandToIncludePoint(this.base).expandToIncludeInfinityInDirection(this.direction); } - get lineDashOffset() { - return this.viewBox.state.current.lineDashOffset; + intersectWithConvexPolygon(t) { + if (!this.intersectsConvexPolygon(t)) + return O; + if (this.isContainedByConvexPolygon(t)) + return this; + const e = t.getIntersectionsWithLine(this.base, this.direction); + let n = this.base, i; + for (let r of e) + (!i && this.comesBefore(n, r.point) || i && this.pointIsBetweenPoints(r.point, n, i)) && (r.halfPlane.normalTowardInterior.dot(this.direction) > 0 ? n = r.point : i = r.point); + return i ? new D(n, i) : new V(n, this.direction); } - set lineDashOffset(t) { - this.viewBox.changeState((e) => yn.changeInstanceValue(e, t)); + intersectWithRay(t) { + return this.isContainedByRay(t) ? this : t.isContainedByRay(this) ? t : this.interiorContainsPoint(t.base) ? new D(this.base, t.base) : O; } - get lineJoin() { - return this.viewBox.state.current.lineJoin; + intersectWithLine(t) { + return t.intersectWithRay(this); } - set lineJoin(t) { - this.viewBox.changeState((e) => On.changeInstanceValue(e, t)); + intersectWithLineSegment(t) { + if (t.isContainedByRay(this)) + return t; + if (!this.lineSegmentIsOnSameLine(t)) + return O; + let { point2: e } = this.getPointsInSameDirection(t.point1, t.point2); + return this.comesBefore(e, this.base) ? O : new D(this.base, e); } - get lineWidth() { - return this.viewBox.state.current.lineWidth; + isContainedByConvexPolygon(t) { + return t.containsPoint(this.base) && t.containsInfinityInDirection(this.direction); } - set lineWidth(t) { - this.viewBox.changeState((e) => Sn.changeInstanceValue(e, t)); + isContainedByRay(t) { + return t.containsPoint(this.base) && t.containsInfinityInDirection(this.direction); } - get miterLimit() { - return this.viewBox.state.current.miterLimit; + isContainedByLine(t) { + return t.intersectsSubsetOfLine(this); } - set miterLimit(t) { - this.viewBox.changeState((e) => Bn.changeInstanceValue(e, t)); + isContainedByLineSegment(t) { + return !1; } - getLineDash() { - return this.viewBox.state.current.lineDash; + contains(t) { + return t.isContainedByRay(this); } - setLineDash(t) { - t.length % 2 === 1 && (t = t.concat(t)), this.viewBox.changeState((e) => bn.changeInstanceValue(e, t)); + intersectsRay(t) { + return this.isContainedByRay(t) || t.isContainedByRay(this) || this.interiorContainsPoint(t.base); } -} -class Ri { - constructor(t) { - this.viewBox = t; + intersectsLine(t) { + return t.intersectsSubsetOfLine(this); } - set direction(t) { - this.viewBox.changeState((e) => pe.changeInstanceValue(e, t)); + intersectsLineSegment(t) { + if (t.isContainedByRay(this)) + return !0; + if (!this.lineSegmentIsOnSameLine(t)) + return !1; + let { point2: e } = this.getPointsInSameDirection(t.point1, t.point2); + return !this.comesBefore(e, this.base); } - set font(t) { - this.viewBox.changeState((e) => we.changeInstanceValue(e, t)); + intersects(t) { + return t.intersectsRay(this); } - set textAlign(t) { - this.viewBox.changeState((e) => Pe.changeInstanceValue(e, t)); + expandToIncludePoint(t) { + return this.containsPoint(t) ? this : this.pointIsOnSameLine(t) ? new V(t, this.direction) : m.createTriangleWithInfinityInDirection(this.base, t, this.direction); } - set textBaseline(t) { - this.viewBox.changeState((e) => Ce.changeInstanceValue(e, t)); + expandByDistance(t) { + const e = this.expandLineByDistance(t), n = new w(this.base, this.direction).expandByDistance(t); + return e.intersectWithConvexPolygon(new m([n])); } -} -function C(r) { - return r.direction !== void 0; -} -class Pt { - static arc(t, e, n, i, s, o) { - return { - instruction: (h, d) => { - const u = d.userTransformation, g = u.getRotationAngle(), { x: p, y: P } = u.apply(new l(t, e)); - h.arc(p, P, n * u.scale, i + g, s + g, o); - }, - changeArea: (h) => { - h.addPosition(new l(t - n, e - n)), h.addPosition(new l(t - n, e + n)), h.addPosition(new l(t + n, e - n)), h.addPosition(new l(t + n, e + n)); - }, - positionChange: new l(t, e).plus(v.rotation(0, 0, s).apply(new l(n, 0))), - initialPoint: new l(t, e).plus(v.rotation(0, 0, i).apply(new l(n, 0))) - }; + expandToIncludeInfinityInDirection(t) { + return t.inSameDirectionAs(this.direction) ? this : this.direction.cross(t) === 0 ? new ie(this.base, this.direction) : m.createTriangleWithInfinityInTwoDirections(this.base, this.direction, t); } - static arcTo(t, e, n, i, s) { - const o = new l(t, e), a = new l(n, i); - return { - instruction: (d, u) => { - const g = u.userTransformation, p = g.apply(o), P = g.apply(a); - d.arcTo(p.x, p.y, P.x, P.y, s * g.scale); - }, - changeArea: (d) => { - d.addPosition(o), d.addPosition(a); - }, - positionChange: new l(n, i) - }; + transform(t) { + const e = t.apply(this.base); + return new V(e, t.apply(this.base.plus(this.direction)).minus(e)); } - static ellipse(t, e, n, i, s, o, a, c) { - return { - instruction: (h, d) => { - const u = d.userTransformation, g = u.apply(new l(t, e)), p = u.getRotationAngle(); - h.ellipse(g.x, g.y, n * u.scale, i * u.scale, s + p, o, a, c); - }, - changeArea: (h) => { - h.addPosition(new l(t - n, e - i)), h.addPosition(new l(t - n, e + i)), h.addPosition(new l(t + n, e - i)), h.addPosition(new l(t + n, e + i)); - }, - positionChange: new l(t, e).plus( - v.rotation(0, 0, a).before( - new v(n, 0, 0, i, 0, 0) - ).before( - v.rotation(0, 0, s) - ).apply(new l(1, 0)) - ), - initialPoint: new l(t, e).plus( - v.rotation(0, 0, o).before( - new v(n, 0, 0, i, 0, 0) - ).before( - v.rotation(0, 0, s) - ).apply(new l(1, 0)) - ) - }; + interiorContainsPoint(t) { + return this.pointIsOnSameLine(t) && !this.comesBefore(t, this.base); } - static bezierCurveTo(t, e, n, i, s, o) { - return { - instruction: (a, c) => { - const h = c.userTransformation, d = h.apply(new l(t, e)), u = h.apply(new l(n, i)), g = h.apply(new l(s, o)); - a.bezierCurveTo(d.x, d.y, u.x, u.y, g.x, g.y); - }, - changeArea: (a, c) => { - C(c) || (a.addPosition(new l((c.x + t) / 2, (c.y + e) / 2)), a.addPosition(new l((t + n) / 2, (e + i) / 2)), a.addPosition(new l((n + s) / 2, (i + o) / 2)), a.addPosition(new l(s, o))); - }, - positionChange: new l(s, o) - }; + containsInfinityInDirection(t) { + return this.direction.inSameDirectionAs(t); } - static quadraticCurveTo(t, e, n, i) { - return { - instruction: (s, o) => { - const a = o.userTransformation, c = a.apply(new l(t, e)), h = a.apply(new l(n, i)); - s.quadraticCurveTo(c.x, c.y, h.x, h.y); - }, - changeArea: (s, o) => { - C(o) || (s.addPosition(new l((o.x + t) / 2, (o.y + e) / 2)), s.addPosition(new l((t + n) / 2, (e + i) / 2)), s.addPosition(new l(n, i))); - }, - positionChange: new l(n, i) - }; + containsPoint(t) { + return this.pointIsOnSameLine(t) && this.comesBefore(this.base, t); } } -class Ni { - constructor(t) { - this.viewBox = t; - } - arc(t, e, n, i, s, o) { - this.viewBox.addPathInstruction(Pt.arc(t, e, n, i, s, o)); +class D extends Be { + constructor(t, e) { + super(t, e.minus(t)), this.point1 = t, this.point2 = e; } - arcTo(t, e, n, i, s) { - this.viewBox.addPathInstruction(Pt.arcTo(t, e, n, i, s)); + getVertices() { + return [this.point1, this.point2]; } - closePath() { - this.viewBox.closePath(); + join(t) { + return t.expandToIncludePoint(this.point1).expandToIncludePoint(this.point2); } - ellipse(t, e, n, i, s, o, a, c) { - this.viewBox.addPathInstruction(Pt.ellipse(t, e, n, i, s, o, a, c)); + intersectWith(t) { + return t.intersectWithLineSegment(this); } - lineTo(t, e) { - this.viewBox.lineTo(new l(t, e)); + intersectWithLineSegment(t) { + if (this.isContainedByLineSegment(t)) + return this; + if (t.isContainedByLineSegment(this)) + return t; + if (!this.lineSegmentIsOnSameLine(t)) + return O; + let { point1: e, point2: n } = this.getPointsInSameDirection(t.point1, t.point2); + return this.comesBefore(n, this.point1) || this.comesBefore(this.point2, e) ? O : this.comesBefore(this.point1, e) ? new D(e, this.point2) : new D(this.point1, n); } - lineToInfinityInDirection(t, e) { - this.viewBox.lineTo({ direction: new l(t, e) }); + intersectWithRay(t) { + return t.intersectWithLineSegment(this); } - moveTo(t, e) { - this.viewBox.moveTo(new l(t, e)); + intersectWithLine(t) { + return t.intersectWithLineSegment(this); } - moveToInfinityInDirection(t, e) { - this.viewBox.moveTo({ direction: new l(t, e) }); + isContainedByRay(t) { + return t.containsPoint(this.point1) && t.containsPoint(this.point2); } - quadraticCurveTo(t, e, n, i) { - this.viewBox.addPathInstruction(Pt.quadraticCurveTo(t, e, n, i)); + isContainedByLine(t) { + return t.intersectsSubsetOfLine(this); } - bezierCurveTo(t, e, n, i, s, o) { - this.viewBox.addPathInstruction(Pt.bezierCurveTo(t, e, n, i, s, o)); + isContainedByLineSegment(t) { + return t.containsPoint(this.point1) && t.containsPoint(this.point2); } - rect(t, e, n, i) { - this.viewBox.rect(t, e, n, i); + intersectWithConvexPolygon(t) { + if (!this.intersectsConvexPolygon(t)) + return O; + if (this.isContainedByConvexPolygon(t)) + return this; + const e = t.getIntersectionsWithLine(this.point1, this.direction); + let n = this.point1, i = this.point2; + for (let r of e) + this.pointIsBetweenPoints(r.point, n, i) && (r.halfPlane.normalTowardInterior.dot(this.direction) > 0 ? n = r.point : i = r.point); + return new D(n, i); } -} -class Mi { - constructor(t, e, n) { - this.canvas = t, this.canvasState = new Zn(e), this.canvasTransform = new ti(e), this.canvasCompositing = new ii(e), this.canvasImageSmoothing = new oi(e), this.canvasStrokeStyles = new ai(e), this.canvasShadowStyles = new ui(e), this.canvasFilters = new fi(e, n), this.canvasRect = new gi(e), this.canvasDrawPath = new mi(e), this.canvasUserInterface = new vi(), this.canvasText = new Ci(e), this.canvasDrawImage = new Ii(e), this.canvasImageData = new Wi(e), this.canvasPathDrawingStyles = new ki(e), this.canvasTextDrawingStyles = new Ri(e), this.canvasPath = new Ni(e); + isContainedByConvexPolygon(t) { + return t.containsPoint(this.point1) && t.containsPoint(this.point2); } - getContextAttributes() { - return this.canvas.getContext("2d").getContextAttributes(); + contains(t) { + return t.isContainedByLineSegment(this); } - save() { - this.canvasState.save(); + pointIsStrictlyBetweenPoints(t, e, n) { + return t.minus(e).dot(this.direction) * t.minus(n).dot(this.direction) < 0; } - restore() { - this.canvasState.restore(); + containsPoint(t) { + return this.pointIsOnSameLine(t) && this.pointIsBetweenPoints(t, this.point1, this.point2); } - getTransform() { - return this.canvasTransform.getTransform(); + interiorContainsPoint(t) { + return this.pointIsOnSameLine(t) && this.pointIsStrictlyBetweenPoints(t, this.point1, this.point2); } - resetTransform() { - this.canvasTransform.resetTransform(); + intersectsRay(t) { + return t.intersectsLineSegment(this); } - rotate(t) { - this.canvasTransform.rotate(t); + intersectsLineSegment(t) { + if (this.isContainedByLineSegment(t) || t.isContainedByLineSegment(this)) + return !0; + if (!this.lineSegmentIsOnSameLine(t)) + return !1; + const { point1: e, point2: n } = this.getPointsInSameDirection(t.point1, t.point2); + return !this.comesBefore(n, this.point1) && !this.comesBefore(this.point2, e); } - scale(t, e) { - this.canvasTransform.scale(t, e); + intersectsLine(t) { + return t.intersectsSubsetOfLine(this); } - setTransform(t, e, n, i, s, o) { - this.canvasTransform.setTransform(t, e, n, i, s, o); + intersects(t) { + return t.intersectsLineSegment(this); } - transform(t, e, n, i, s, o) { - this.canvasTransform.transform(t, e, n, i, s, o); + expandByDistance(t) { + const e = this.expandLineByDistance(t), n = new w(this.base, this.direction).expandByDistance(t), i = new w(this.point2, this.direction.scale(-1)).expandByDistance(t); + return e.intersectWithConvexPolygon(new m([n, i])); } - translate(t, e) { - this.canvasTransform.translate(t, e); + expandToIncludePoint(t) { + return this.containsPoint(t) ? this : this.pointIsOnSameLine(t) ? this.comesBefore(t, this.point1) ? new D(t, this.point2) : new D(this.point1, t) : m.createTriangle(this.point1, t, this.point2); } - set globalAlpha(t) { - this.canvasCompositing.globalAlpha = t; + expandToIncludeInfinityInDirection(t) { + return t.inSameDirectionAs(this.direction) ? new V(this.point1, t) : t.cross(this.direction) === 0 ? new V(this.point2, t) : m.createTriangleWithInfinityInDirection(this.point1, this.point2, t); } - set globalCompositeOperation(t) { - this.canvasCompositing.globalCompositeOperation = t; + transform(t) { + return new D(t.apply(this.point1), t.apply(this.point2)); } - set imageSmoothingEnabled(t) { - this.canvasImageSmoothing.imageSmoothingEnabled = t; +} +class zi { + addPoint(t) { + return gt; } - set imageSmoothingQuality(t) { - this.canvasImageSmoothing.imageSmoothingQuality = t; + addPointAtInfinity(t) { + return this; } - set fillStyle(t) { - this.canvasStrokeStyles.fillStyle = t; + addArea(t) { + return gt; } - set strokeStyle(t) { - this.canvasStrokeStyles.strokeStyle = t; +} +const Ae = new zi(); +class Ie { + constructor(t) { + this.towardsMiddle = t; } - createLinearGradient(t, e, n, i) { - return this.canvasStrokeStyles.createLinearGradient(t, e, n, i); + addPoint(t) { + return m.createFromHalfPlane(new w(t, this.towardsMiddle)); } - createPattern(t, e) { - return this.canvasStrokeStyles.createPattern(t, e); + addPointAtInfinity(t) { + return t.dot(this.towardsMiddle) >= 0 ? this : Ae; } - createRadialGradient(t, e, n, i, s, o) { - return this.canvasStrokeStyles.createRadialGradient(t, e, n, i, s, o); + addArea(t) { + const e = this.towardsMiddle.getPerpendicular(); + return t.expandToIncludeInfinityInDirection(this.towardsMiddle).expandToIncludeInfinityInDirection(e).expandToIncludeInfinityInDirection(e.scale(-1)); } - createConicGradient(t, e, n) { - return this.canvasStrokeStyles.createConicGradient(t, e, n); +} +class $t { + constructor(t, e) { + this.direction1 = t, this.direction2 = e; } - set shadowBlur(t) { - this.canvasShadowStyles.shadowBlur = t; + addPoint(t) { + return m.createTriangleWithInfinityInTwoDirections(t, this.direction1, this.direction2); } - set shadowColor(t) { - this.canvasShadowStyles.shadowColor = t; + addPointAtInfinity(t) { + return t.isInSmallerAngleBetweenPoints(this.direction1, this.direction2) ? this : t.cross(this.direction1) === 0 ? new Ie(this.direction2.projectOn(this.direction1.getPerpendicular())) : t.cross(this.direction2) === 0 ? new Ie(this.direction1.projectOn(this.direction2.getPerpendicular())) : this.direction1.isInSmallerAngleBetweenPoints(t, this.direction2) ? new $t(t, this.direction2) : this.direction2.isInSmallerAngleBetweenPoints(t, this.direction1) ? new $t(t, this.direction1) : Ae; } - set shadowOffsetX(t) { - this.canvasShadowStyles.shadowOffsetX = t; + addArea(t) { + return t.expandToIncludeInfinityInDirection(this.direction1).expandToIncludeInfinityInDirection(this.direction2); } - set shadowOffsetY(t) { - this.canvasShadowStyles.shadowOffsetY = t; +} +class Gi { + constructor(t) { + this.direction = t; } - set filter(t) { - this.canvasFilters.filter = t; + addPoint(t) { + return new ie(t, this.direction); } - clearRect(t, e, n, i) { - this.canvasRect.clearRect(t, e, n, i); + addPointAtInfinity(t) { + return t.cross(this.direction) === 0 ? this : new Ie(t.projectOn(this.direction.getPerpendicular())); } - fillRect(t, e, n, i) { - this.canvasRect.fillRect(t, e, n, i); + addArea(t) { + return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1)); } - strokeRect(t, e, n, i) { - this.canvasRect.strokeRect(t, e, n, i); +} +class Yi { + constructor(t) { + this.direction = t; } - beginPath() { - this.canvasDrawPath.beginPath(); + addPointAtInfinity(t) { + return t.inSameDirectionAs(this.direction) ? this : t.cross(this.direction) === 0 ? new Gi(this.direction) : new $t(this.direction, t); } - clip(t, e) { - this.canvasDrawPath.clip(t, e); + addPoint(t) { + return new V(t, this.direction); } - fill(t, e) { - this.canvasDrawPath.fill(t, e); + addArea(t) { + return t.expandToIncludeInfinityInDirection(this.direction); } - isPointInPath(t, e, n, i) { - return this.canvasDrawPath.isPointInPath(t, e, n, i); +} +class Xi { + constructor(t, e, n) { + this._area = t, this.firstPoint = e, this.subsetOfLineAtInfinity = n; } - isPointInStroke(t, e, n) { - return this.canvasDrawPath.isPointInStroke(t, e, n); + get area() { + return this._area || O; } - stroke(t) { - this.canvasDrawPath.stroke(t); + addPoint(t) { + this._area ? this._area = this._area.expandToIncludePoint(t) : this.firstPoint ? t.equals(this.firstPoint) || (this._area = new D(this.firstPoint, t)) : this.subsetOfLineAtInfinity ? this._area = this.subsetOfLineAtInfinity.addPoint(t) : this.firstPoint = t; } - drawFocusIfNeeded(t, e) { - this.canvasUserInterface.drawFocusIfNeeded(t, e); + addPosition(t) { + C(t) ? this.addInfinityInDirection(t.direction) : this.addPoint(t); } - scrollPathIntoView(t) { - this.canvasUserInterface.scrollPathIntoView(t); + addInfinityInDirection(t) { + this._area ? this._area = this._area.expandToIncludeInfinityInDirection(t) : this.firstPoint ? this._area = new V(this.firstPoint, t) : this.subsetOfLineAtInfinity ? (this.subsetOfLineAtInfinity = this.subsetOfLineAtInfinity.addPointAtInfinity(t), this.subsetOfLineAtInfinity === Ae && (this._area = gt)) : this.subsetOfLineAtInfinity = new Yi(t); } - fillText(t, e, n, i) { - this.canvasText.fillText(t, e, n, i); + transformedWith(t) { + return new qi(this, t); } - measureText(t) { - return this.canvasText.measureText(t); +} +class Ut extends Le { + constructor(t, e, n, i) { + super(t, e), this.instruction = n, this.stateConversion = i; } - strokeText(t, e, n, i) { - this.canvasText.strokeText(t, e, n, i); + replaceInstruction(t) { + this.instruction = t; } - drawImage() { - this.canvasDrawImage.drawImage.apply(this.canvasDrawImage, arguments); + makeExecutable(t) { + const e = t.getInfinity(this.state), n = this.instruction, i = (r, o) => n(r, o, e); + return new U(this.initialState, this.state, i, this.stateConversion); } - createImageData(t, e) { - return this.canvasImageData.createImageData(t, e); + static create(t, e) { + return new Ut(t, t, e, () => { + }); } - getImageData(t, e, n, i) { - return this.canvasImageData.getImageData(t, e, n, i); +} +function $i(s, t) { + return s ? t ? C(s) ? C(t) && s.direction.equals(t.direction) : !C(t) && s.equals(t) : !s : !t; +} +class bt { + constructor(t) { + this.shape = t; } - putImageData(t, e, n, i, s, o, a) { - this.canvasImageData.putImageData(t, e, n, i, s, o, a); + getInstructionToDrawLineTo(t, e) { + return this.getInstructionToExtendShapeWithLineTo(this.shape.transform(e.current.transformation.inverse()), t); } - set lineCap(t) { - this.canvasPathDrawingStyles.lineCap = t; + getInstructionToMoveToBeginning(t) { + return this.getInstructionToMoveToBeginningOfShape(this.shape.transform(t.current.transformation.inverse())); } - set lineDashOffset(t) { - this.canvasPathDrawingStyles.lineDashOffset = t; + get currentPosition() { + return this.shape.currentPosition; } - set lineJoin(t) { - this.canvasPathDrawingStyles.lineJoin = t; + moveToInfinityFromPointInDirection(t, e) { + return (n, i, r) => { + r.moveToInfinityFromPointInDirection(n, i, t, e); + }; } - set lineWidth(t) { - this.canvasPathDrawingStyles.lineWidth = t; + lineFromInfinityFromPointToInfinityFromPoint(t, e, n) { + return (i, r, o) => { + o.drawLineFromInfinityFromPointToInfinityFromPoint(i, r, t, e, n); + }; } - set miterLimit(t) { - this.canvasPathDrawingStyles.miterLimit = t; - } - getLineDash() { - return this.canvasPathDrawingStyles.getLineDash(); + lineFromInfinityFromPointToPoint(t, e) { + return (n, i, r) => { + r.drawLineFromInfinityFromPointToPoint(n, i, t, e); + }; } - setLineDash(t) { - this.canvasPathDrawingStyles.setLineDash(t); + lineToInfinityFromPointInDirection(t, e) { + return (n, i, r) => { + r.drawLineToInfinityFromPointInDirection(n, i, t, e); + }; } - set direction(t) { - this.canvasTextDrawingStyles.direction = t; + lineToInfinityFromInfinityFromPoint(t, e, n) { + return (i, r, o) => { + o.drawLineToInfinityFromInfinityFromPoint(i, r, t, e, n); + }; } - set font(t) { - this.canvasTextDrawingStyles.font = t; + lineTo(t) { + return (e, n) => { + const { x: i, y: r } = n.userTransformation.apply(t); + e.lineTo(i, r); + }; } - set textAlign(t) { - this.canvasTextDrawingStyles.textAlign = t; + moveTo(t) { + return (e, n) => { + const { x: i, y: r } = n.userTransformation.apply(t); + e.moveTo(i, r); + }; } - set textBaseline(t) { - this.canvasTextDrawingStyles.textBaseline = t; +} +class se { + constructor(t, e, n, i) { + this.initialPosition = t, this.firstFinitePoint = e, this.lastFinitePoint = n, this.currentPosition = i; } - arc(t, e, n, i, s, o) { - this.canvasPath.arc(t, e, n, i, s, o); + transform(t) { + return new se( + t.applyToPointAtInfinity(this.initialPosition), + t.apply(this.firstFinitePoint), + t.apply(this.lastFinitePoint), + t.applyToPointAtInfinity(this.currentPosition) + ); } - arcTo(t, e, n, i, s) { - this.canvasPath.arcTo(t, e, n, i, s); +} +class Ot { + constructor(t, e, n) { + this.initialPosition = t, this.firstFinitePoint = e, this.currentPosition = n; } - bezierCurveTo(t, e, n, i, s, o) { - this.canvasPath.bezierCurveTo(t, e, n, i, s, o); + transform(t) { + return new Ot( + t.applyToPointAtInfinity(this.initialPosition), + t.apply(this.firstFinitePoint), + t.apply(this.currentPosition) + ); } - closePath() { - this.canvasPath.closePath(); +} +class Ui extends bt { + constructor(t, e) { + super(e), this.pathBuilderProvider = t; } - ellipse(t, e, n, i, s, o, a, c) { - this.canvasPath.ellipse(t, e, n, i, s, o, a); + getInstructionToMoveToBeginningOfShape(t) { + return t.initialPosition.direction.cross(t.currentPosition.direction) === 0 ? this.moveToInfinityFromPointInDirection(t.firstFinitePoint, t.initialPosition.direction) : $( + this.moveToInfinityFromPointInDirection(t.lastFinitePoint, t.currentPosition.direction), + this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint, t.currentPosition.direction, t.initialPosition.direction), + this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint, t.firstFinitePoint, t.initialPosition.direction) + ); } - lineTo(t, e) { - this.canvasPath.lineTo(t, e); + getInstructionToExtendShapeWithLineTo(t, e) { + return C(e) ? this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint, t.currentPosition.direction, e.direction) : $( + this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint, e, t.currentPosition.direction), + this.lineFromInfinityFromPointToPoint(e, t.currentPosition.direction) + ); } - lineToInfinityInDirection(t, e) { - this.canvasPath.lineToInfinityInDirection(t, e); + containsFinitePoint() { + return !0; } - moveTo(t, e) { - this.canvasPath.moveTo(t, e); + surroundsFinitePoint() { + return !0; } - moveToInfinityInDirection(t, e) { - this.canvasPath.moveToInfinityInDirection(t, e); + isClosable() { + return !this.shape.initialPosition.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); } - quadraticCurveTo(t, e, n, i) { - this.canvasPath.quadraticCurveTo(t, e, n, i); + canAddLineTo(t) { + return !C(t) || !t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); } - rect(t, e, n, i) { - if (!Number.isFinite(t) && !Number.isFinite(e)) - throw new Error(`The starting coordinates provided (${t} and ${e}) do not determine a direction.`); - this.canvasPath.rect(t, e, n, i); + addPosition(t) { + return C(t) ? this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new se(this.shape.initialPosition, this.shape.firstFinitePoint, this.shape.lastFinitePoint, t)) : this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ot(this.shape.initialPosition, this.shape.firstFinitePoint, t)); } } -class Ie extends Ht { - constructor() { - super(...arguments), this.colorStops = []; +class Ki extends bt { + constructor(t, e) { + super(e), this.pathBuilderProvider = t; } - addColorStopsToGradient(t) { - for (const e of this.colorStops) - t.addColorStop(e.offset, e.color); + getInstructionToMoveToBeginningOfShape(t) { + const e = this.moveToInfinityFromPointInDirection(t.currentPosition, t.initialPosition.direction); + if (t.currentPosition.equals(t.firstFinitePoint)) + return e; + const n = this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition, t.firstFinitePoint, t.initialPosition.direction); + return $(e, n); } - addColorStop(t, e) { - this.colorStops.push({ offset: t, color: e }); + getInstructionToExtendShapeWithLineTo(t, e) { + return C(e) ? this.lineToInfinityFromPointInDirection(t.currentPosition, e.direction) : this.lineTo(e); } - getInstructionToSetTransformed(t) { - return (e, n) => { - const i = n.userTransformation; - e[t] = this.createTransformedGradient(i); - }; + canAddLineTo(t) { + return !0; } - getInstructionToSetUntransformed(t) { - return (e) => { - e[t] = this.createGradient(); - }; + containsFinitePoint() { + return !0; } -} -class Vi extends Ie { - constructor(t, e, n, i, s) { - super(), this.context = t, this.x0 = e, this.y0 = n, this.x1 = i, this.y1 = s; + surroundsFinitePoint() { + return !0; } - createTransformedGradient(t) { - const { x: e, y: n } = t.apply(new l(this.x0, this.y0)), { x: i, y: s } = t.apply(new l(this.x1, this.y1)), o = this.context.createLinearGradient(e, n, i, s); - return this.addColorStopsToGradient(o), o; + isClosable() { + return !0; } - createGradient() { - const t = this.context.createLinearGradient(this.x0, this.y0, this.x1, this.y1); - return this.addColorStopsToGradient(t), t; + addPosition(t) { + return C(t) ? this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new se(this.shape.initialPosition, this.shape.firstFinitePoint, this.shape.currentPosition, t)) : this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ot(this.shape.initialPosition, this.shape.firstFinitePoint, t)); } } -class Hi extends Ie { - constructor(t, e, n, i, s, o, a) { - super(), this.context = t, this.x0 = e, this.y0 = n, this.r0 = i, this.x1 = s, this.y1 = o, this.r1 = a; +class re { + constructor(t, e) { + this.initialPoint = t, this.currentPosition = e; } - createTransformedGradient(t) { - const { x: e, y: n } = t.apply(new l(this.x0, this.y0)), { x: i, y: s } = t.apply(new l(this.x1, this.y1)), o = this.r0 * t.scale, a = this.r1 * t.scale, c = this.context.createRadialGradient(e, n, o, i, s, a); - return this.addColorStopsToGradient(c), c; + transform(t) { + return new re( + t.apply(this.initialPoint), + t.applyToPointAtInfinity(this.currentPosition) + ); } - createGradient() { - const t = this.context.createRadialGradient(this.x0, this.y0, this.r0, this.x1, this.y1, this.r1); - return this.addColorStopsToGradient(t), t; +} +class Lt { + constructor(t, e) { + this.initialPoint = t, this.currentPosition = e; + } + transform(t) { + return new Lt( + t.apply(this.initialPoint), + t.apply(this.currentPosition) + ); } } -class Te { - constructor(t) { - this.initiallyWithState = t, this.added = []; +class ji extends bt { + constructor(t, e) { + super(e), this.pathBuilderProvider = t; } - get length() { - return this.added.length; + getInstructionToMoveToBeginningOfShape(t) { + return this.moveTo(t.initialPoint); } - get currentlyWithState() { - return this.addedLast ? this.addedLast : this.initiallyWithState; + getInstructionToExtendShapeWithLineTo(t, e) { + return C(e) ? e.direction.inSameDirectionAs(t.currentPosition.direction) ? () => { + } : this.lineToInfinityFromInfinityFromPoint(t.initialPoint, t.currentPosition.direction, e.direction) : $(this.lineFromInfinityFromPointToInfinityFromPoint(t.initialPoint, e, t.currentPosition.direction), this.lineFromInfinityFromPointToPoint(e, t.currentPosition.direction)); } - reconstructState(t, e) { - e.setInitialState(t); + canAddLineTo(t) { + return !C(t) || !t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); } - get stateOfFirstInstruction() { - return this.initiallyWithState.stateOfFirstInstruction; + containsFinitePoint() { + return !0; } - get state() { - return this.currentlyWithState.state; + surroundsFinitePoint() { + return !0; } - get initialState() { - return this.initiallyWithState.initialState; + isClosable() { + return !0; } - addClippedPath(t) { - this.currentlyWithState.addClippedPath(t); + addPosition(t) { + return C(t) ? this.pathBuilderProvider.fromPointToPointAtInfinity(new re(this.shape.initialPoint, t)) : this.pathBuilderProvider.fromPointToPoint(new Lt(this.shape.initialPoint, t)); } - add(t) { - this.added.push(t), this.addedLast = t; +} +class tn extends bt { + constructor(t, e) { + super(e), this.pathBuilderProvider = t; } - removeAll(t) { - let e; - for (; (e = this.added.findIndex(t)) > -1; ) - this.removeAtIndex(e); + getInstructionToMoveToBeginningOfShape(t) { + return this.moveTo(t.initialPoint); } - contains(t) { - return !!this.added.find(t); + getInstructionToExtendShapeWithLineTo(t, e) { + if (C(e)) { + const n = this.lineToInfinityFromPointInDirection(t.currentPosition, e.direction); + if (t.currentPosition.minus(t.initialPoint).cross(e.direction) === 0) + return n; + const i = this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition, t.initialPoint, e.direction); + return $(n, i); + } + return this.lineTo(e); } - setInitialState(t) { - this.initiallyWithState.setInitialState(t); + canAddLineTo(t) { + return !0; } - setInitialStateWithClippedPaths(t) { - this.initiallyWithState.setInitialStateWithClippedPaths(t); + containsFinitePoint() { + return !0; } - beforeIndex(t) { - return t === 0 ? this.initiallyWithState.state : this.added[t - 1].state; + surroundsFinitePoint() { + return !0; } - removeAtIndex(t) { - t === this.added.length - 1 ? this.added.length === 1 ? this.addedLast = void 0 : this.addedLast = this.added[t - 1] : this.reconstructState(this.beforeIndex(t), this.added[t + 1]), this.added.splice(t, 1); + isClosable() { + return !0; + } + addPosition(t) { + return C(t) ? this.pathBuilderProvider.fromPointToPointAtInfinity(new re(this.shape.initialPoint, t)) : this.pathBuilderProvider.fromPointToPoint(new Lt(this.shape.initialPoint, t)); } } -class Se extends Te { - constructor(t) { - super(t), this._initiallyWithState = t; +class oe { + constructor(t, e, n, i) { + this.initialPosition = t, this.surroundsFinitePoint = e, this.positionsSoFar = n, this.currentPosition = i; } - execute(t, e) { - this._initiallyWithState.execute(t, e); - for (const n of this.added) - n.execute(t, e); + transform(t) { + return new oe( + t.applyToPointAtInfinity(this.initialPosition), + this.surroundsFinitePoint, + this.positionsSoFar.map((e) => t.applyToPointAtInfinity(e)), + t.applyToPointAtInfinity(this.currentPosition) + ); } } -class Dn { - constructor(t) { - this.currentState = t, this.instructions = []; - } - restore() { - this.addChangeToState(this.currentState.restored(), (t) => { - t.restore(); - }); +class en extends bt { + constructor(t, e) { + super(e), this.pathBuilderProvider = t; } - save() { - this.addChangeToState(this.currentState.saved(), (t) => { - t.save(); - }); + getInstructionToMoveToBeginningOfShape(t) { + return t.surroundsFinitePoint ? (e, n, i) => i.addPathAroundViewbox(e, n) : () => { + }; } - changeCurrentInstanceTo(t) { - if (this.currentState.current.equals(t)) + getInstructionToExtendShapeWithLineTo(t, e) { + if (C(e)) return; - const e = this.currentState.current.getInstructionToConvertToState(t), n = this.currentState.withCurrentState(t); - this.addChangeToState(n, e); + if (t.positionsSoFar.length === 1) + return this.lineFromInfinityFromPointToPoint(e, t.positionsSoFar[0].direction); + const n = t.positionsSoFar.slice(1); + let i = t.initialPosition; + const r = []; + for (let o of n) + r.push(this.lineToInfinityFromInfinityFromPoint(e, i.direction, o.direction)), i = o; + return $($(...r), this.lineFromInfinityFromPointToPoint(e, i.direction)); } - addChangeToState(t, e) { - this.currentState = t, e && this.instructions.push(e); + canAddLineTo(t) { + return !C(t) || !t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); } - get instruction() { - if (this.instructions.length !== 0) - return (t, e) => { - for (const n of this.instructions) - n(t, e); - }; + containsFinitePoint() { + return !1; } -} -class ye extends Dn { - changeCurrentInstanceTo(t) { - if (!this.currentState.current.equals(t)) { - if (!ye.canConvert(this.currentState.current, t)) - if (this.currentState.stack.length > 0) - this.restore(), this.save(); - else { - super.changeCurrentInstanceTo(t); - return; - } - if (t.clippedPaths) { - const e = this.currentState, i = e.current.clippedPaths; - if (t.clippedPaths === i) - super.changeCurrentInstanceTo(t); - else { - const o = t.clippedPaths.except(i); - this.convertToState(o.initialState), this.addChangeToState(o.latestClippedPath.state, o.getInstructionToRecreate()), this.convertToState(e.replaceCurrent(t)); - } - } else - super.changeCurrentInstanceTo(t); - } + surroundsFinitePoint() { + return this.shape.surroundsFinitePoint; } - convertToState(t) { - const e = this.currentState.getInstructionToConvertToState(t); - this.addChangeToState(t, e); + isClosable() { + return !0; } - static canConvert(t, e) { - return t.clippedPaths ? e.clippedPaths ? e.clippedPaths.contains(t.clippedPaths) : !1 : !0; + addPosition(t) { + if (C(t)) { + const n = t.direction.isOnSameSideOfOriginAs(this.shape.initialPosition.direction, this.shape.currentPosition.direction) ? this.shape.surroundsFinitePoint : !this.shape.surroundsFinitePoint; + return this.pathBuilderProvider.atInfinity(new oe(this.shape.initialPosition, n, this.shape.positionsSoFar.concat([t]), t)); + } + return this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ot(this.shape.initialPosition, t, t)); } } -class Y { - constructor(t, e = []) { - this.current = t, this.stack = e; - } - replaceCurrent(t) { - return new Y(t, this.stack); - } - withCurrentState(t) { - return new Y(t, this.stack); - } - currentlyTransformed(t) { - return this.withCurrentState(this.current.changeProperty("fillAndStrokeStylesTransformed", t)); - } - withClippedPath(t) { - return new Y(this.current.withClippedPath(t), this.stack); - } - saved() { - return new Y(this.current, (this.stack || []).concat([this.current])); +class Qi { + fromPointAtInfinityToPointAtInfinity(t) { + return new Ui(this, t); } - restored() { - if (!this.stack || this.stack.length === 0) - return this; - const t = this.stack[this.stack.length - 1]; - return new Y(t, this.stack.slice(0, this.stack.length - 1)); + fromPointAtInfinityToPoint(t) { + return new Ki(this, t); } - convertToLastSavedInstance(t, e) { - for (let n = this.stack.length - 1; n > e; n--) - t.restore(); + fromPointToPointAtInfinity(t) { + return new ji(this, t); } - convertFromLastSavedInstance(t, e) { - for (let n = e + 1; n < this.stack.length; n++) - t.changeCurrentInstanceTo(this.stack[n]), t.save(); - t.changeCurrentInstanceTo(this.current); + fromPointToPoint(t) { + return new tn(this, t); } - getInstructionToConvertToStateUsingConversion(t, e) { - const n = Y.findIndexOfHighestCommon(this.stack, e.stack); - return this.convertToLastSavedInstance(t, n), e.convertFromLastSavedInstance(t, n), t.instruction; + atInfinity(t) { + return new en(this, t); } - getInstructionToConvertToState(t) { - return this.getInstructionToConvertToStateUsingConversion(new Dn(this), t); + getBuilderFromPosition(t) { + return C(t) ? new en(this, new oe(t, !1, [t], t)) : new tn(this, new Lt(t, t)); } - getInstructionToConvertToStateWithClippedPath(t) { - return this.getInstructionToConvertToStateUsingConversion(new ye(this), t); +} +class De extends Oe { + constructor(t) { + super(t), this._initiallyWithState = t; } - static findIndexOfHighestCommon(t, e) { - let n = 0, i = Math.min(t.length - 1, e.length - 1); - for (; n <= i; ) { - if (!t[n].equals(e[n])) - return n - 1; - n++; - } - return n - 1; + execute(t, e) { + this._initiallyWithState.execute(t, e); + for (const n of this.added) + n.execute(t, e); } } -const Ge = new Y(M.default, []); -class be { +class Ee extends Oe { constructor(t, e) { - this.initialState = t, this.state = e, this.stateConversion = () => { - }; - } - setInitialState(t) { - this.initialState = t; - const e = this.initialState.getInstructionToConvertToState(this.state); - this.stateConversion = e; - } - get stateOfFirstInstruction() { - return this.state; + super(t), this._initiallyWithState = t, this.pathInstructionBuilder = e; } - addClippedPath(t) { - this.state = this.state.withClippedPath(t); + get currentPosition() { + return this.pathInstructionBuilder.currentPosition; } - setInitialStateWithClippedPaths(t) { - this.initialState = t; - const e = this.initialState.getInstructionToConvertToStateWithClippedPath(this.state); - this.stateConversion = e; + addInstruction(t) { + t.setInitialState(this.state), this.add(t); } -} -class st extends be { - constructor(t, e, n, i) { - super(t, e), this.instruction = n, this.stateConversion = i; + closePath() { + const t = ft.create(this.state, (e) => { + e.closePath(); + }); + this.add(t); } - execute(t, e) { - this.stateConversion && this.stateConversion(t, e), this.instruction(t, e); + makeExecutable(t) { + const e = new De(this._initiallyWithState.makeExecutable(t)); + for (const n of this.added) + e.add(n.makeExecutable(t)); + return e; } - static create(t, e) { - return new st(t, t, e, () => { - }); + surroundsFinitePoint() { + return this.pathInstructionBuilder.surroundsFinitePoint(); } -} -class qi { - constructor(t) { - this.area = t; + isClosable() { + return this.pathInstructionBuilder.isClosable(); } - hasDrawingAcrossBorderOf(t) { - return !1; + canAddLineTo(t) { + return this.pathInstructionBuilder.canAddLineTo(t); } - intersects(t) { - return this.area.intersects(t); + lineTo(t, e) { + const n = Q(t, e.current.transformation); + (!C(t) || this.pathInstructionBuilder.containsFinitePoint()) && this.addInstructionToDrawLineTo(t, e), this.pathInstructionBuilder = this.pathInstructionBuilder.addPosition(n); + const i = this.pathInstructionBuilder.getInstructionToMoveToBeginning(this._initiallyWithState.state); + this._initiallyWithState.replaceInstruction((r, o, a) => { + i(r, o, a); + }); } - isContainedBy(t) { - return t.contains(this.area); + addInstructionToDrawLineTo(t, e) { + const n = this.pathInstructionBuilder.getInstructionToDrawLineTo(t, e), i = Ut.create(e, n); + i.setInitialState(this.state), this.add(i); } -} -class xe extends st { - constructor(t, e, n, i, s) { - super(t, e, n, i), this.drawingArea = new qi(s); + addPathInstruction(t, e, n) { + t.initialPoint && !$i(this.pathInstructionBuilder.currentPosition, t.initialPoint) && this.lineTo(t.initialPoint, n), t.positionChange && (this.pathInstructionBuilder = this.pathInstructionBuilder.addPosition(Q(t.positionChange, n.current.transformation))), e.setInitialState(this.state), this.add(e); } - static createClearRect(t, e, n, i, s, o, a) { - return new xe(t, t, (c, h) => { - n.clearRect(c, h, i, s, o, a); - }, () => { - }, e); + static create(t, e) { + const n = Q(e, t.current.transformation), i = new Qi().getBuilderFromPosition(n), r = i.getInstructionToMoveToBeginning(t), o = Ut.create(t, r); + return new Ee(o, i); } } -const z = { direction: new l(0, 1) }, U = { direction: new l(0, -1) }, _ = { direction: new l(-1, 0) }, tt = { direction: new l(1, 0) }; -function Gi(r, t, e) { +function Ji(s, t, e) { let n = 0, i; - for (let s of r) { - const o = s.minus(t).dot(e); - o > n && (i = s, n = o); + for (let r of s) { + const o = r.minus(t).dot(e); + o > n && (i = r, n = o); } return i ? t.plus(i.minus(t).projectOn(e)) : t; } -function D(r, t, e) { - return Gi(r.getVertices(), t, e); +function F(s, t, e) { + return Ji(s.getVertices(), t, e); } -class Xi { +class Zi { constructor(t, e) { this.state = t, this.drawnPathProperties = e; } @@ -2306,62 +2154,62 @@ class Xi { let n = t.polygon; n = n.transform(e.inverse()).expandByDistance(this.drawnPathProperties.lineWidth); for (const i of this.drawnPathProperties.shadowOffsets) { - const s = n.transform(v.translation(-i.x, -i.y)); - n = n.join(s); + const r = n.transform(p.translation(-i.x, -i.y)); + n = n.join(r); } return n; } - clearRect(t, e, n, i, s, o) { - const a = this.getTransformedViewbox(e), { a: c, b: h, c: d, d: u, e: g, f: p } = e.userTransformation; - t.save(), t.transform(c, h, d, u, g, p); - const P = Number.isFinite(n) ? n : D(a, new l(0, 0), n > 0 ? tt.direction : _.direction).x, x = Number.isFinite(s) ? n + s : D(a, new l(0, 0), s > 0 ? tt.direction : _.direction).x, k = Number.isFinite(i) ? i : D(a, new l(0, 0), i > 0 ? z.direction : U.direction).y, G = Number.isFinite(o) ? i + o : D(a, new l(0, 0), o > 0 ? z.direction : U.direction).y; - t.clearRect(P, k, x - P, G - k), t.restore(); + clearRect(t, e, n, i, r, o) { + const a = this.getTransformedViewbox(e), { a: l, b: c, c: d, d: u, e: g, f: v } = e.userTransformation; + t.save(), t.transform(l, c, d, u, g, v); + const P = Number.isFinite(n) ? n : F(a, new h(0, 0), n > 0 ? Xt.direction : Yt.direction).x, T = Number.isFinite(r) ? n + r : F(a, new h(0, 0), r > 0 ? Xt.direction : Yt.direction).x, L = Number.isFinite(i) ? i : F(a, new h(0, 0), i > 0 ? zt.direction : Gt.direction).y, k = Number.isFinite(o) ? i + o : F(a, new h(0, 0), o > 0 ? zt.direction : Gt.direction).y; + t.clearRect(P, L, T - P, k - L), t.restore(); } moveToInfinityFromPointInDirection(t, e, n, i) { - const s = D(this.getTransformedViewbox(e), n, i); - this.moveToTransformed(t, s, e.userTransformation); + const r = F(this.getTransformedViewbox(e), n, i); + this.moveToTransformed(t, r, e.userTransformation); } - drawLineToInfinityFromInfinityFromPoint(t, e, n, i, s) { - const o = this.getTransformedViewbox(e), a = D(o, n, i), c = D(o, n, s), h = e.userTransformation, u = o.expandToIncludePoint(n).expandToIncludePoint(a).expandToIncludePoint(c).getVertices().filter((P) => !P.equals(a) && !P.equals(c) && !P.equals(n) && P.minus(n).isInSmallerAngleBetweenPoints(i, s)); - u.sort((P, x) => P.minus(n).isInSmallerAngleBetweenPoints(x.minus(n), i) ? -1 : 1); - let g = a, p = 0; + drawLineToInfinityFromInfinityFromPoint(t, e, n, i, r) { + const o = this.getTransformedViewbox(e), a = F(o, n, i), l = F(o, n, r), c = e.userTransformation, u = o.expandToIncludePoint(n).expandToIncludePoint(a).expandToIncludePoint(l).getVertices().filter((P) => !P.equals(a) && !P.equals(l) && !P.equals(n) && P.minus(n).isInSmallerAngleBetweenPoints(i, r)); + u.sort((P, T) => P.minus(n).isInSmallerAngleBetweenPoints(T.minus(n), i) ? -1 : 1); + let g = a, v = 0; for (let P of u) - p += P.minus(g).mod(), this.lineToTransformed(t, P, h), g = P; - p += c.minus(g).mod(), this.lineToTransformed(t, c, h), this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, h, p, c, s); + v += P.minus(g).mod(), this.lineToTransformed(t, P, c), g = P; + v += l.minus(g).mod(), this.lineToTransformed(t, l, c), this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, c, v, l, r); } - drawLineFromInfinityFromPointToInfinityFromPoint(t, e, n, i, s) { - const o = this.getTransformedViewbox(e), a = D(o, n, s), c = e.userTransformation, h = D(o, i, s); - this.lineToTransformed(t, h, c); - const d = h.minus(a).mod(); - this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, c, d, h, s); + drawLineFromInfinityFromPointToInfinityFromPoint(t, e, n, i, r) { + const o = this.getTransformedViewbox(e), a = F(o, n, r), l = e.userTransformation, c = F(o, i, r); + this.lineToTransformed(t, c, l); + const d = c.minus(a).mod(); + this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, l, d, c, r); } drawLineFromInfinityFromPointToPoint(t, e, n, i) { - const s = D(this.getTransformedViewbox(e), n, i), o = n.minus(s).mod(), a = e.userTransformation; - this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, a, o, s, i), this.lineToTransformed(t, n, a); + const r = F(this.getTransformedViewbox(e), n, i), o = n.minus(r).mod(), a = e.userTransformation; + this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, a, o, r, i), this.lineToTransformed(t, n, a); } drawLineToInfinityFromPointInDirection(t, e, n, i) { - const s = D(this.getTransformedViewbox(e), n, i), o = e.userTransformation; - this.lineToTransformed(t, s, o); - const a = s.minus(n).mod(); - this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, o, a, s, i); + const r = F(this.getTransformedViewbox(e), n, i), o = e.userTransformation; + this.lineToTransformed(t, r, o); + const a = r.minus(n).mod(); + this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, o, a, r, i); } - ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, e, n, i, s) { + ensureDistanceCoveredIsMultipleOfLineDashPeriod(t, e, n, i, r) { const o = this.drawnPathProperties.lineDashPeriod; if (o === 0) return; const a = this.getDistanceLeft(n, o); if (a === 0) return; - const c = i.plus(s.scale(a / (2 * s.mod()))); - this.lineToTransformed(t, c, e), this.lineToTransformed(t, i, e); + const l = i.plus(r.scale(a / (2 * r.mod()))); + this.lineToTransformed(t, l, e), this.lineToTransformed(t, i, e); } lineToTransformed(t, e, n) { - const { x: i, y: s } = n.apply(e); - t.lineTo(i, s); + const { x: i, y: r } = n.apply(e); + t.lineTo(i, r); } moveToTransformed(t, e, n) { - const { x: i, y: s } = n.apply(e); - t.moveTo(i, s); + const { x: i, y: r } = n.apply(e); + t.moveTo(i, r); } getDistanceLeft(t, e) { if (e === 0) @@ -2370,956 +2218,1851 @@ class Xi { return t - e * n === 0 ? 0 : (n + 1) * e - t; } } -class Ln { +class Fe { constructor(t) { this.drawnPathProperties = t; } getInfinity(t) { - return new Xi(t, this.drawnPathProperties); + return new Zi(t, this.drawnPathProperties); } } -class Oe extends Se { - reconstructState(t, e) { - e.setInitialStateWithClippedPaths(t); - } - hasDrawingAcrossBorderOf(t) { - return this.contains((e) => e.drawingArea.hasDrawingAcrossBorderOf(t)); - } - intersects(t) { - return this.contains((e) => e.drawingArea.intersects(t)); +class _i { + constructor(t, e) { + this.instructions = t, this.area = e; } - addClearRect(t, e, n, i, s, o) { - const c = new Ln({ lineWidth: 0, lineDashPeriod: 0, shadowOffsets: [] }).getInfinity(e), h = xe.createClearRect(e, t, c, n, i, s, o); - h.setInitialState(this.state), this.add(h); + get state() { + return this.instructions.state; } - clearContentsInsideArea(t) { - this.removeAll((e) => e.drawingArea.isContainedBy(t)); + get initialState() { + return this.instructions.initialState; } - static create() { - return new Oe(new st(Ge, Ge, M.setDefault, () => { - })); + execute(t, e) { + this.instructions.execute(t, e); } } -class $ extends be { - constructor(t, e, n, i) { - super(t, e), this.instruction = n, this.stateConversion = i; - } - copy() { - return new $(this.initialState, this.state, this.instruction, this.stateConversion); - } - makeExecutable() { - return new st(this.initialState, this.state, this.instruction, this.stateConversion); +class Tt extends Oe { + constructor(t) { + super(t), this._initiallyWithState = t, this.areaBuilder = new Xi(); } - static create(t, e) { - return new $(t, t, e, () => { - }); + get area() { + return this.areaBuilder.area; } -} -function K(r, t) { - return C(r) ? t.applyToPointAtInfinity(r) : t.apply(r); -} -class Yi { - constructor(t, e) { - this.areaBuilder = t, this.transformation = e; + surroundsFinitePoint() { + for (const t of this.added) + if (t.surroundsFinitePoint()) + return !0; + return !1; } - addPosition(t) { - this.areaBuilder.addPosition(K(t, this.transformation)); + currentSubpathIsClosable() { + return this.added.length === 0 ? !0 : this.added[this.added.length - 1].isClosable(); } -} -class Be { - constructor(t, e) { - this.base = t, this.direction = e; + allSubpathsAreClosable() { + if (this.added.length === 0) + return !0; + for (const t of this.added) + if (!t.isClosable()) + return !1; + return !0; } - pointIsOnSameLine(t) { - return t.minus(this.base).cross(this.direction) === 0; + drawPath(t, e, n) { + if (this.added.length === 0) + return; + const i = U.create(e, t), r = this.makeExecutable(n); + return i.setInitialState(r.state), r.add(i), r; } - comesBefore(t, e) { - return e.minus(t).dot(this.direction) >= 0; + makeExecutable(t) { + const e = new De(this._initiallyWithState.makeExecutable()), n = new Fe(t); + for (const i of this.added) + e.add(i.makeExecutable(n)); + return e; } - lineSegmentIsOnSameLine(t) { - return this.direction.cross(t.direction) === 0 && this.pointIsOnSameLine(t.point1); + getInstructionsToClip() { + const t = this.makeExecutable({ lineWidth: 0, lineDashPeriod: 0, shadowOffsets: [] }); + return t.setInitialState(t.stateOfFirstInstruction), new _i(t, this.area); } - expandLineByDistance(t) { - const e = this.direction.getPerpendicular(), n = new w(this.base, e).expandByDistance(t), i = new w(this.base, e.scale(-1)).expandByDistance(t); - return new m([n, i]); + clipPath(t, e) { + if (this.added.length === 0) + return; + const n = this.added[this.added.length - 1], i = ft.create(e, t); + n.addInstruction(i); + const r = this.getInstructionsToClip(); + this.addClippedPath(r); } - getPointsInSameDirection(t, e) { - return this.comesBefore(e, t) ? { point1: e, point2: t } : { point1: t, point2: e }; + closePath() { + if (this.added.length === 0) + return; + this.added[this.added.length - 1].closePath(); } - pointIsBetweenPoints(t, e, n) { - return t.minus(e).dot(this.direction) * t.minus(n).dot(this.direction) <= 0; + moveTo(t, e) { + const n = Q(t, e.current.transformation); + this.areaBuilder.addPosition(n); + const i = Ee.create(e, t); + i.setInitialState(this.state), this.add(i); } - intersectsConvexPolygon(t) { - if (this.isContainedByConvexPolygon(t)) + canAddLineTo(t, e) { + if (this.added.length === 0) return !0; - const e = t.getIntersectionsWithLine(this.base, this.direction); - for (let n of e) - if (this.interiorContainsPoint(n.point)) - return !0; - return !1; + const n = Q(t, e.current.transformation); + return this.added[this.added.length - 1].canAddLineTo(n); } -} -class Jt extends Be { - getVertices() { - return []; + lineTo(t, e) { + if (this.added.length === 0) { + this.moveTo(t, e); + return; + } + const n = this.added[this.added.length - 1], i = Q(t, e.current.transformation); + this.areaBuilder.addPosition(i), n.lineTo(t, e); } - intersectWith(t) { - return t.intersectWithLine(this); + addPathInstruction(t, e) { + if (this.added.length === 0) + if (t.initialPoint) + this.moveTo(t.initialPoint, e); + else + return; + const n = this.added[this.added.length - 1], i = n.currentPosition, r = Q(i, e.current.transformation.inverse()); + t.changeArea(this.areaBuilder.transformedWith(e.current.transformation), r); + const o = ft.create(e, t.instruction); + n.addPathInstruction(t, o, e); } - join(t) { - return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1)); + static create(t) { + return new Tt(ft.create(t, (e) => { + e.beginPath(); + })); } - intersectWithConvexPolygon(t) { - if (!this.intersectsConvexPolygon(t)) - return b; - if (this.isContainedByConvexPolygon(t)) - return this; - const e = t.getIntersectionsWithLine(this.base, this.direction); - let n, i; - for (let s of e) - (!n && !i || !n && this.comesBefore(s.point, i) || !i && this.comesBefore(n, s.point) || n && i && this.pointIsBetweenPoints(s.point, n, i)) && (s.halfPlane.normalTowardInterior.dot(this.direction) > 0 ? n = s.point : i = s.point); - return n && i ? new A(n, i) : n ? new F(n, this.direction) : new F(i, this.direction.scale(-1)); +} +class E { + constructor(t, ...e) { + this.topLeftCorner = t, this.corners = e; } - intersectWithLine(t) { - return this.intersectsLine(t) ? this : b; + addSubpaths(t, e) { + this.topLeftCorner.moveToEndingPoint(t, e); + for (const n of this.corners) + n.draw(t, e); + this.topLeftCorner.finishRect(t, e); } - intersectWithLineSegment(t) { - return this.lineSegmentIsOnSameLine(t) ? t : b; + stroke(t, e) { + return H.forStrokingPath(e, t, (n) => { + const i = Tt.create(n); + return this.addSubpaths(i, n), i; + }); } - intersectWithRay(t) { - return this.intersectsRay(t) ? t : b; + fill(t, e) { + return H.forFillingPath(e, t, (n) => { + const i = Tt.create(n); + return this.addSubpaths(i, n), i; + }); } - isContainedByConvexPolygon(t) { - return t.containsPoint(this.base) && t.containsInfinityInDirection(this.direction) && t.containsInfinityInDirection(this.direction.scale(-1)); +} +class ts extends E { + constructor(t, e, ...n) { + super(e, ...n), this.horizontal = t; } - isContainedByLine(t) { - return this.intersectsSubsetOfLine(t); + getRoundRect() { + return this; } - isContainedByLineSegment(t) { - return !1; + getArea() { + return new m(this.horizontal.getHalfPlanesWithHorizontalCrossSection()); } - isContainedByRay(t) { - return !1; +} +class es extends E { + constructor(t, e, ...n) { + super(e, ...n), this.vertical = t; } - contains(t) { - return t.isContainedByLine(this); + getRoundRect() { + return this; } - intersectsLine(t) { - return this.intersectsSubsetOfLine(t); + getArea() { + return new m(this.vertical.getHalfPlanesWithVerticalCrossSection()); } - intersectsSubsetOfLine(t) { - return this.pointIsOnSameLine(t.base) && this.direction.cross(t.direction) === 0; +} +class ns extends E { + constructor(t, e, n, i, r) { + super(n, i, r), this.horizontal = t, this.vertical = e, this.topLeft = n, this.right = i, this.bottom = r; } - intersectsLineSegment(t) { - return this.lineSegmentIsOnSameLine(t); + getRoundRect(t) { + const e = this.topLeft.round(t.upperLeft); + return new E( + e, + this.right, + this.bottom + ); } - intersectsRay(t) { - return this.intersectsSubsetOfLine(t); + getArea() { + return new m([ + ...this.vertical.getHalfPlanesWithVerticalCrossSection(), + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection() + ]); } - intersects(t) { - return t.intersectsLine(this); +} +class is extends E { + constructor(t, e, ...n) { + super(e, ...n), this.horizontal = t; } - expandToIncludePoint(t) { - return this.pointIsOnSameLine(t) ? this : m.createTriangleWithInfinityInDirection(this.base, t, this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1)); + getRoundRect() { + return this; } - expandByDistance(t) { - return this.expandLineByDistance(t); + getArea() { + return new m(this.horizontal.getHalfPlanesWithHorizontalCrossSection()); } - expandToIncludeInfinityInDirection(t) { - const e = t.cross(this.direction), n = this.direction.getPerpendicular(); - return e === 0 ? this : e > 0 ? m.createFromHalfPlane(new w(this.base, n.scale(-1))) : m.createFromHalfPlane(new w(this.base, n)); +} +function ss(s) { + return s.x !== void 0; +} +function nn(s) { + if (typeof s == "number") { + if (Number.isNaN(s)) + return; + if (s < 0) + throw new RangeError(`Radius value ${s} is negative.`); + return { x: s, y: s, circular: !0 }; } - transform(t) { - const e = t.apply(this.base); - return new Jt(e, t.apply(this.base.plus(this.direction)).minus(e)); + const { x: t, y: e } = s; + if (!(Number.isNaN(t) || Number.isNaN(e))) { + if (t < 0) + throw new RangeError(`X-radius value ${s} is negative.`); + if (e < 0) + throw new RangeError(`Y-radius value ${s} is negative.`); + return { x: t, y: e, circular: !1 }; } - interiorContainsPoint(t) { - return this.pointIsOnSameLine(t); +} +function At(s, t) { + const { x: e, y: n, circular: i } = s; + return { x: e * t, y: n * t, circular: i }; +} +function Re(s, t) { + const { upperLeft: e, upperRight: n, lowerLeft: i, lowerRight: r } = s; + return { + upperLeft: At(e, t), + upperRight: At(n, t), + lowerLeft: At(i, t), + lowerRight: At(r, t) + }; +} +function rs(s) { + if (typeof s == "number" || ss(s)) { + const n = nn(s); + return n ? { upperLeft: n, upperRight: n, lowerLeft: n, lowerRight: n } : void 0; + } + const t = [...s], e = t.slice(0, 4).map(nn); + if (!e.includes(void 0)) { + if (e.length === 4) { + const [n, i, r, o] = e; + return { + upperLeft: n, + upperRight: i, + lowerRight: r, + lowerLeft: o + }; + } + if (e.length === 3) { + const [n, i, r] = e; + return { + upperLeft: n, + upperRight: i, + lowerRight: r, + lowerLeft: i + }; + } + if (e.length === 2) { + const [n, i] = e; + return { + upperLeft: n, + upperRight: i, + lowerRight: n, + lowerLeft: i + }; + } + if (e.length === 1) { + const [n] = e; + return { + upperLeft: n, + upperRight: n, + lowerRight: n, + lowerLeft: n + }; + } + throw new RangeError(`${t.length} radii provided. Between one and four radii are necessary.`); } } -class F extends Be { - getVertices() { - return [this.base]; +class os extends E { + constructor(t, e, n, i, r) { + super(n, i, r), this.horizontal = t, this.vertical = e, this.topLeft = n, this.topRightCorner = i, this.bottom = r; } - intersectWith(t) { - return t.intersectWithRay(this); + getRoundRect(t) { + const e = this.horizontal.getLength(), n = t.upperLeft.x + t.upperRight.x, i = e / n; + i < 1 && (t = Re(t, i)); + const r = this.topRightCorner.round(t.upperRight), o = this.topLeft.round(t.upperLeft); + return new E( + o, + r, + this.bottom + ); } - join(t) { - return t.expandToIncludePoint(this.base).expandToIncludeInfinityInDirection(this.direction); + getArea() { + return new m([ + ...this.vertical.getHalfPlanesWithVerticalCrossSection(), + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection() + ]); } - intersectWithConvexPolygon(t) { - if (!this.intersectsConvexPolygon(t)) - return b; - if (this.isContainedByConvexPolygon(t)) - return this; - const e = t.getIntersectionsWithLine(this.base, this.direction); - let n = this.base, i; - for (let s of e) - (!i && this.comesBefore(n, s.point) || i && this.pointIsBetweenPoints(s.point, n, i)) && (s.halfPlane.normalTowardInterior.dot(this.direction) > 0 ? n = s.point : i = s.point); - return i ? new A(n, i) : new F(n, this.direction); +} +class as extends E { + constructor(t, e, ...n) { + super(e, ...n), this.vertical = t; } - intersectWithRay(t) { - return this.isContainedByRay(t) ? this : t.isContainedByRay(this) ? t : this.interiorContainsPoint(t.base) ? new A(this.base, t.base) : b; + getRoundRect() { + return this; } - intersectWithLine(t) { - return t.intersectWithRay(this); + getArea() { + return new m(this.vertical.getHalfPlanesWithVerticalCrossSection()); } - intersectWithLineSegment(t) { - if (t.isContainedByRay(this)) - return t; - if (!this.lineSegmentIsOnSameLine(t)) - return b; - let { point2: e } = this.getPointsInSameDirection(t.point1, t.point2); - return this.comesBefore(e, this.base) ? b : new A(this.base, e); +} +class cs extends E { + constructor(t, e, n, i, r) { + super(n, i, r), this.vertical = t, this.horizontal = e, this.topLeft = n, this.right = i, this.bottomLeftCorner = r; } - isContainedByConvexPolygon(t) { - return t.containsPoint(this.base) && t.containsInfinityInDirection(this.direction); + getRoundRect(t) { + const e = this.vertical.getLength(), n = t.upperLeft.y + t.lowerLeft.y, i = e / n; + i < 1 && (t = Re(t, i)); + const r = this.topLeft.round(t.upperLeft), o = this.bottomLeftCorner.round(t.lowerLeft); + return new E( + r, + this.right, + o + ); } - isContainedByRay(t) { - return t.containsPoint(this.base) && t.containsInfinityInDirection(this.direction); + getArea() { + return new m([ + ...this.vertical.getHalfPlanesWithVerticalCrossSection(), + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection() + ]); } - isContainedByLine(t) { - return t.intersectsSubsetOfLine(this); +} +class hs extends E { + constructor(t, e, n, i, r, o) { + super(n, i, r, o), this.vertical = t, this.horizontal = e, this.topLeft = n, this.topRight = i, this.bottomRight = r, this.bottomLeft = o; } - isContainedByLineSegment(t) { - return !1; + getRoundRect(t) { + const e = this.vertical.getLength(), n = this.horizontal.getLength(), i = Math.min( + e / (t.upperLeft.y + t.lowerLeft.y), + e / (t.upperRight.y + t.lowerRight.y), + n / (t.upperLeft.x + t.upperRight.x), + n / (t.lowerLeft.x + t.lowerRight.x) + ); + i < 1 && (t = Re(t, i)); + const r = this.bottomRight.round(t.lowerRight), o = this.topLeft.round(t.upperLeft), a = this.topRight.round(t.upperRight), l = this.bottomLeft.round(t.lowerLeft); + return new E( + o, + a, + r, + l + ); } - contains(t) { - return t.isContainedByRay(this); + getArea() { + return new m([ + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection(), + ...this.vertical.getHalfPlanesWithVerticalCrossSection() + ]); } - intersectsRay(t) { - return this.isContainedByRay(t) || t.isContainedByRay(this) || this.interiorContainsPoint(t.base); +} +class Kt { + constructor(t) { + this.topLeftPosition = t; } - intersectsLine(t) { - return t.intersectsSubsetOfLine(this); + addSubpaths(t, e) { + t.moveTo(this.topLeftPosition, e); } - intersectsLineSegment(t) { - if (t.isContainedByRay(this)) - return !0; - if (!this.lineSegmentIsOnSameLine(t)) - return !1; - let { point2: e } = this.getPointsInSameDirection(t.point1, t.point2); - return !this.comesBefore(e, this.base); + getRoundRect() { + return this; } - intersects(t) { - return t.intersectsRay(this); + getArea() { } - expandToIncludePoint(t) { - return this.containsPoint(t) ? this : this.pointIsOnSameLine(t) ? new F(t, this.direction) : m.createTriangleWithInfinityInDirection(this.base, t, this.direction); + stroke() { } - expandByDistance(t) { - const e = this.expandLineByDistance(t), n = new w(this.base, this.direction).expandByDistance(t); - return e.intersectWithConvexPolygon(new m([n])); + fill() { } - expandToIncludeInfinityInDirection(t) { - return t.inSameDirectionAs(this.direction) ? this : this.direction.cross(t) === 0 ? new Jt(this.base, this.direction) : m.createTriangleWithInfinityInTwoDirections(this.base, this.direction, t); +} +class ls { + constructor() { + this.area = gt; } - transform(t) { - const e = t.apply(this.base); - return new F(e, t.apply(this.base.plus(this.direction)).minus(e)); + drawPath(t, e, n) { + const r = new Fe(n).getInfinity(e); + return U.create(e, (o, a) => { + o.beginPath(), r.addPathAroundViewbox(o, a), t(o, a); + }); } - interiorContainsPoint(t) { - return this.pointIsOnSameLine(t) && !this.comesBefore(t, this.base); +} +const us = new ls(); +function Wn(s, t) { + throw new Error(`The starting coordinates provided (${s.start} and ${t.start}) do not determine a direction.`); +} +class ds { + constructor(t, e) { + this.horizontal = t, this.vertical = e; } - containsInfinityInDirection(t) { - return this.direction.inSameDirectionAs(t); + addSubpaths() { + Wn(this.horizontal, this.vertical); } - containsPoint(t) { - return this.pointIsOnSameLine(t) && this.comesBefore(this.base, t); + getRoundRect() { + return this; + } + getArea() { + return gt; + } + stroke() { + } + fill(t, e) { + return H.forFillingPath(e, t, () => us); } } -class A extends Be { +class Te { constructor(t, e) { - super(t, e.minus(t)), this.point1 = t, this.point2 = e; + this.horizontal = t, this.vertical = e; } - getVertices() { - return [this.point1, this.point2]; + addSubpaths() { + Wn(this.horizontal, this.vertical); } - join(t) { - return t.expandToIncludePoint(this.point1).expandToIncludePoint(this.point2); + getRoundRect() { + return this; } - intersectWith(t) { - return t.intersectWithLineSegment(this); + getArea() { } - intersectWithLineSegment(t) { - if (this.isContainedByLineSegment(t)) - return this; - if (t.isContainedByLineSegment(this)) - return t; - if (!this.lineSegmentIsOnSameLine(t)) - return b; - let { point1: e, point2: n } = this.getPointsInSameDirection(t.point1, t.point2); - return this.comesBefore(n, this.point1) || this.comesBefore(this.point2, e) ? b : this.comesBefore(this.point1, e) ? new A(e, this.point2) : new A(this.point1, n); + stroke() { } - intersectWithRay(t) { - return t.intersectWithLineSegment(this); + fill() { } - intersectWithLine(t) { - return t.intersectWithLineSegment(this); +} +class nt { + static arc(t, e, n, i, r, o) { + return { + instruction: (c, d) => { + const u = d.userTransformation, { x: g, y: v } = u.apply(new h(t, e)), { a: P, b: T, c: L, d: k, e: N, f: _ } = u.untranslated().before(p.translation(g, v)); + c.save(), c.transform(P, T, L, k, N, _), c.arc(0, 0, n, i, r, o), c.restore(); + }, + changeArea: (c) => { + c.addPosition(new h(t - n, e - n)), c.addPosition(new h(t - n, e + n)), c.addPosition(new h(t + n, e - n)), c.addPosition(new h(t + n, e + n)); + }, + positionChange: new h(t, e).plus(p.rotation(0, 0, r).apply(new h(n, 0))), + initialPoint: new h(t, e).plus(p.rotation(0, 0, i).apply(new h(n, 0))) + }; } - isContainedByRay(t) { - return t.containsPoint(this.point1) && t.containsPoint(this.point2); + static arcTo(t, e, n, i, r) { + const o = new h(t, e), a = new h(n, i); + return { + instruction: (d, u) => { + const g = u.userTransformation, v = g.apply(o), P = g.apply(a); + d.arcTo(v.x, v.y, P.x, P.y, r * g.scale); + }, + changeArea: (d) => { + d.addPosition(o), d.addPosition(a); + }, + positionChange: new h(n, i) + }; + } + static ellipse(t, e, n, i, r, o, a, l) { + return { + instruction: (c, d) => { + const u = d.userTransformation, g = u.apply(new h(t, e)), v = u.getRotationAngle(); + c.ellipse(g.x, g.y, n * u.scale, i * u.scale, r + v, o, a, l); + }, + changeArea: (c) => { + c.addPosition(new h(t - n, e - i)), c.addPosition(new h(t - n, e + i)), c.addPosition(new h(t + n, e - i)), c.addPosition(new h(t + n, e + i)); + }, + positionChange: new h(t, e).plus( + p.rotation(0, 0, a).before( + new p(n, 0, 0, i, 0, 0) + ).before( + p.rotation(0, 0, r) + ).apply(new h(1, 0)) + ), + initialPoint: new h(t, e).plus( + p.rotation(0, 0, o).before( + new p(n, 0, 0, i, 0, 0) + ).before( + p.rotation(0, 0, r) + ).apply(new h(1, 0)) + ) + }; + } + static bezierCurveTo(t, e, n, i, r, o) { + return { + instruction: (a, l) => { + const c = l.userTransformation, d = c.apply(new h(t, e)), u = c.apply(new h(n, i)), g = c.apply(new h(r, o)); + a.bezierCurveTo(d.x, d.y, u.x, u.y, g.x, g.y); + }, + changeArea: (a, l) => { + C(l) || (a.addPosition(new h((l.x + t) / 2, (l.y + e) / 2)), a.addPosition(new h((t + n) / 2, (e + i) / 2)), a.addPosition(new h((n + r) / 2, (i + o) / 2)), a.addPosition(new h(r, o))); + }, + positionChange: new h(r, o) + }; + } + static quadraticCurveTo(t, e, n, i) { + return { + instruction: (r, o) => { + const a = o.userTransformation, l = a.apply(new h(t, e)), c = a.apply(new h(n, i)); + r.quadraticCurveTo(l.x, l.y, c.x, c.y); + }, + changeArea: (r, o) => { + C(o) || (r.addPosition(new h((o.x + t) / 2, (o.y + e) / 2)), r.addPosition(new h((t + n) / 2, (e + i) / 2)), r.addPosition(new h(n, i))); + }, + positionChange: new h(n, i) + }; + } +} +var X = /* @__PURE__ */ ((s) => (s[s.TOPLEFT = 0] = "TOPLEFT", s[s.TOPRIGHT = 1] = "TOPRIGHT", s[s.BOTTOMLEFT = 2] = "BOTTOMLEFT", s[s.BOTTOMRIGHT = 3] = "BOTTOMRIGHT", s))(X || {}); +function fs(s) { + switch (s) { + case 0: + return 2; + case 1: + return 3; + case 3: + return 1; + case 2: + return 0; + } +} +function gs(s) { + switch (s) { + case 0: + return 1; + case 1: + return 0; + case 3: + return 2; + case 2: + return 3; + } +} +class kn { + constructor(t, e, n, i, r) { + this.corner = e, n = ps(n, i, r); + const o = r === i; + let { center: a, start: l, end: c } = vs(n, e, t); + o || ({ start: l, end: c } = { start: c, end: l }), this.radii = t, this.clockwise = o, this.center = a, this.start = l, this.end = c; + } + draw(t, e) { + t.lineTo(this.start.point, e), this.radii.circular ? t.addPathInstruction(nt.arc( + this.center.x, + this.center.y, + this.radii.x, + this.start.angle, + this.end.angle, + !this.clockwise + ), e) : t.addPathInstruction(nt.ellipse( + this.center.x, + this.center.y, + this.radii.x, + this.radii.y, + 0, + this.start.angle, + this.end.angle, + !this.clockwise + ), e); + } +} +class ms extends kn { + moveToEndingPoint(t, e) { + t.moveTo(this.end.point, e); + } + finishRect(t, e) { + this.draw(t, e), t.moveTo(this.corner, e); + } +} +function ps(s, t, e) { + return t === I.Negative && (s = gs(s)), e === I.Negative && (s = fs(s)), s; +} +function vs(s, t, e) { + switch (s) { + case X.TOPLEFT: + return { + center: new h(t.x + e.x, t.y + e.y), + start: { + angle: Math.PI, + point: new h(t.x, t.y + e.y) + }, + end: { + angle: 3 * Math.PI / 2, + point: new h(t.x + e.x, t.y) + } + }; + case X.TOPRIGHT: + return { + center: new h(t.x - e.x, t.y + e.y), + start: { + angle: 3 * Math.PI / 2, + point: new h(t.x - e.x, t.y) + }, + end: { + angle: 0, + point: new h(t.x, t.y + e.y) + } + }; + case X.BOTTOMRIGHT: + return { + center: new h(t.x - e.x, t.y - e.y), + start: { + angle: 0, + point: new h(t.x, t.y - e.y) + }, + end: { + angle: Math.PI / 2, + point: new h(t.x - e.x, t.y) + } + }; + case X.BOTTOMLEFT: + return { + center: new h(t.x + e.x, t.y - e.y), + start: { + angle: Math.PI / 2, + point: new h(t.x + e.x, t.y) + }, + end: { + angle: Math.PI, + point: new h(t.x, t.y - e.y) + } + }; + } +} +class Se { + constructor(t, e, n, i) { + this.corner = t, this.cornerOrientation = e, this.horizontalOrientation = n, this.verticalOrientation = i; + } + draw(t, e) { + t.lineTo(this.corner, e); + } + round(t) { + return t.x === 0 || t.y === 0 ? this : new kn( + t, + this.corner, + this.cornerOrientation, + this.horizontalOrientation, + this.verticalOrientation + ); + } +} +class ws { + constructor(t, e, n, i) { + this.corner = t, this.cornerOrientation = e, this.horizontalOrientation = n, this.verticalOrientation = i; + } + moveToEndingPoint(t, e) { + t.moveTo(this.corner, e); + } + finishRect(t, e) { + t.closePath(), t.moveTo(this.corner, e); + } + round(t) { + return t.x === 0 || t.y === 0 ? this : new ms( + t, + this.corner, + this.cornerOrientation, + this.horizontalOrientation, + this.verticalOrientation + ); + } +} +class We { + constructor(t, e) { + this.point = t, this.direction = e; + } + draw(t, e) { + t.lineTo(this.point, e), t.lineTo(this.direction, e); + } +} +class Ps { + constructor(t, e) { + this.point = t, this.direction = e; + } + moveToEndingPoint(t, e) { + t.moveTo(this.direction, e); + } + finishRect(t, e) { + t.lineTo(this.point, e), t.lineTo(this.direction, e), t.closePath(), t.moveTo(this.direction, e); + } +} +class ye { + constructor(t) { + this.direction = t; + } + draw(t, e) { + t.lineTo(this.direction, e); + } +} +class Cs { + constructor(t) { + this.direction = t; + } + moveToEndingPoint(t, e) { + t.moveTo(this.direction, e); + } + finishRect(t, e) { + t.closePath(), t.moveTo(this.direction, e); + } +} +class ke { + constructor(t, e) { + this.start = t, this.orientation = e, this.horizontalLineStart = e === I.Positive ? Yt : Xt, this.horizontalLineEnd = e === I.Positive ? Xt : Yt, this.verticalLineStart = e === I.Positive ? Gt : zt, this.verticalLineEnd = e === I.Positive ? zt : Gt; + } + createTopLeftAtVerticalInfinity(t) { + return new Ps(new h(t.finiteStart, 0), this.verticalLineStart); + } + createBottomRightAtInfinity(t) { + return new We(new h(t.end, 0), this.verticalLineEnd); + } + createRightAtInfinity(t) { + return new ye(t.horizontalLineEnd); + } + createBottomAtInfinity() { + return new ye(this.verticalLineEnd); + } + addVerticalDimension(t) { + return t.addEntireHorizontalDimension(this); + } + addEntireHorizontalDimension(t) { + return new ds(t, this); + } + addHorizontalDimensionAtInfinity(t) { + return new Te(t, this); + } + addHorizontalDimensionWithStart(t) { + const e = this.createTopLeftAtVerticalInfinity(t), n = this.createRightAtInfinity(t), i = this.createBottomAtInfinity(); + return new ts(t, e, n, i); + } + addHorizontalDimensionWithStartAndEnd(t) { + const e = this.createTopLeftAtVerticalInfinity(t), n = this.createBottomRightAtInfinity(t); + return new is(t, e, n); + } +} +class Dt extends ke { + addVerticalDimension(t) { + return t.addHorizontalDimensionAtInfinity(this); + } + addEntireHorizontalDimension(t) { + return new Te(t, this); + } + addHorizontalDimensionAtInfinity(t) { + return new Te(t, this); + } + addHorizontalDimensionWithStart() { + return new Kt(this.verticalLineEnd); + } + addHorizontalDimensionWithStartAndEnd() { + return new Kt(this.verticalLineEnd); + } +} +class Hn extends ke { + constructor(t, e) { + super(e, t), this.finiteStart = e; + } + createBottomLeftAtInfinity(t) { + return new ye(t.horizontalLineStart); + } + createLeftAtInfinity(t) { + return new Cs(t.horizontalLineStart); + } + createTopRightAtHorizontalInfinity(t) { + return new We(new h(0, this.finiteStart), t.horizontalLineEnd); + } + createTopLeft(t) { + return new ws( + new h(t.finiteStart, this.finiteStart), + X.TOPLEFT, + t.orientation, + this.orientation + ); + } + createTopRight(t) { + return new Se( + new h(t.end, this.finiteStart), + X.TOPRIGHT, + t.orientation, + this.orientation + ); + } + getStartingHalfPlaneWithHorizontalCrossSection() { + const t = this.orientation === I.Positive ? new h(1, 0) : new h(-1, 0), e = new h(this.finiteStart, 0); + return new w(e, t); + } + getStartingHalfPlaneWithVerticalCrossSection() { + const t = this.orientation === I.Positive ? new h(0, 1) : new h(0, -1), e = new h(0, this.finiteStart); + return new w(e, t); + } + addVerticalDimension(t) { + return t.addHorizontalDimensionWithStart(this); + } + addEntireHorizontalDimension(t) { + const e = this.createLeftAtInfinity(t), n = this.createTopRightAtHorizontalInfinity(t), i = this.createBottomAtInfinity(), r = this.createBottomLeftAtInfinity(t); + return new es(this, e, n, i, r); + } + addHorizontalDimensionAtInfinity(t) { + return new Kt(t.horizontalLineEnd); + } + addHorizontalDimensionWithStart(t) { + const e = this.createRightAtInfinity(t), n = this.createBottomAtInfinity(), i = this.createTopLeft(t); + return new ns(t, this, i, e, n); + } + addHorizontalDimensionWithStartAndEnd(t) { + const e = this.createBottomAtInfinity(), n = this.createTopLeft(t), i = this.createTopRight(t); + return new os(t, this, n, i, e); + } + getHalfPlanesWithHorizontalCrossSection() { + return [this.getStartingHalfPlaneWithHorizontalCrossSection()]; + } + getHalfPlanesWithVerticalCrossSection() { + return [this.getStartingHalfPlaneWithVerticalCrossSection()]; + } +} +class Vn extends Hn { + constructor(t, e, n) { + super(t, e), this.end = n; + } + createBottomLeftAtHorizontalInfinity(t) { + return new We(new h(0, this.end), t.horizontalLineStart); + } + getEndingHalfPlaneWithHorizontalCrossSection() { + const t = this.orientation === I.Positive ? new h(-1, 0) : new h(1, 0), e = new h(this.end, 0); + return new w(e, t); + } + getEndingHalfPlaneWithVerticalCrossSection() { + const t = this.orientation === I.Positive ? new h(0, -1) : new h(0, 1), e = new h(0, this.end); + return new w(e, t); + } + createBottomLeft(t) { + return new Se( + new h(t.finiteStart, this.end), + X.BOTTOMLEFT, + t.orientation, + this.orientation + ); + } + createBottomRight(t) { + return new Se( + new h(t.end, this.end), + X.BOTTOMRIGHT, + t.orientation, + this.orientation + ); + } + getLength() { + return Math.abs(this.end - this.finiteStart); + } + addEntireHorizontalDimension(t) { + const e = this.createLeftAtInfinity(t), n = this.createTopRightAtHorizontalInfinity(t), i = this.createBottomLeftAtHorizontalInfinity(t); + return new as(this, e, n, i); + } + addHorizontalDimensionAtInfinity(t) { + return new Kt(t.horizontalLineEnd); + } + addVerticalDimension(t) { + return t.addHorizontalDimensionWithStartAndEnd(this); + } + addHorizontalDimensionWithStart(t) { + const e = this.createRightAtInfinity(t), n = this.createTopLeft(t), i = this.createBottomLeft(t); + return new cs(this, t, n, e, i); + } + addHorizontalDimensionWithStartAndEnd(t) { + const e = this.createTopLeft(t), n = this.createTopRight(t), i = this.createBottomLeft(t), r = this.createBottomRight(t); + return new hs( + this, + t, + e, + n, + r, + i + ); + } + getHalfPlanesWithHorizontalCrossSection() { + return [ + this.getStartingHalfPlaneWithHorizontalCrossSection(), + this.getEndingHalfPlaneWithHorizontalCrossSection() + ]; + } + getHalfPlanesWithVerticalCrossSection() { + return [ + this.getStartingHalfPlaneWithVerticalCrossSection(), + this.getEndingHalfPlaneWithVerticalCrossSection() + ]; + } +} +function sn(s, t) { + const e = t > 0 ? I.Positive : I.Negative; + return new Vn(e, s, s + t); +} +function rn(s, t) { + const e = t > 0 ? I.Positive : I.Negative, n = new ke(s, e); + return Number.isFinite(s) ? Number.isFinite(t) ? new Vn(e, s, s + t) : new Hn(e, s) : Number.isFinite(t) ? s < 0 ? new Dt(s, I.Negative) : new Dt(s, I.Positive) : s > 0 ? e === I.Positive ? new Dt(s, I.Positive) : n : e === I.Positive ? n : new Dt(s, I.Negative); +} +function J(s, t, e, n) { + const i = rn(s, e), r = rn(t, n); + return i.addVerticalDimension(r); +} +function on(s, t, e, n) { + const i = sn(s, e); + return sn(t, n).addHorizontalDimensionWithStartAndEnd(i); +} +class Is { + constructor(t) { + this.viewBox = t; + } + fillText(t, e, n, i) { + let r = i === void 0 ? (o) => { + o.fillText(t, e, n); + } : (o) => { + o.fillText(t, e, n, i); + }; + this.viewBox.addDrawing(r, this.getDrawnRectangle(e, n, t), M.Relative, !0); + } + measureText(t) { + return this.viewBox.measureText(t); + } + strokeText(t, e, n, i) { + let r = i === void 0 ? (o) => { + o.strokeText(t, e, n); + } : (o) => { + o.strokeText(t, e, n, i); + }; + this.viewBox.addDrawing(r, this.getDrawnRectangle(e, n, t), M.Relative, !0); + } + getDrawnRectangle(t, e, n) { + const i = this.viewBox.measureText(n); + let r; + i.actualBoundingBoxRight !== void 0 ? r = Math.abs(i.actualBoundingBoxRight - i.actualBoundingBoxLeft) : r = i.width; + const o = i.actualBoundingBoxAscent !== void 0 ? i.actualBoundingBoxAscent + i.actualBoundingBoxDescent : 1, a = i.actualBoundingBoxAscent !== void 0 ? i.actualBoundingBoxAscent : 0; + return J(t, e - a, r, o).getArea(); + } +} +function Ts(s) { + return typeof s.duration < "u"; +} +function Ss(s) { + return Ts(s) ? { + width: s.displayWidth, + height: s.displayHeight + } : { + width: s.width, + height: s.height + }; +} +class ys { + constructor(t) { + this.viewBox = t; + } + drawImage() { + const t = Array.prototype.slice.apply(arguments); + let e, n, i, r, o, a, l, c, d; + arguments.length <= 5 ? [e, a, l, c, d] = t : [e, n, i, r, o, a, l, c, d] = t; + const { width: u, height: g } = Ss(e), v = this.getDrawnLength(u, n, r, c), P = this.getDrawnLength(g, i, o, d), T = J(a, l, v, P).getArea(), L = this.getDrawImageInstruction(arguments.length, e, n, i, r, o, a, l, c, d); + this.viewBox.addDrawing(L, T, M.Relative, !0); + } + getDrawImageInstruction(t, e, n, i, r, o, a, l, c, d) { + switch (t) { + case 3: + return (u) => { + u.drawImage(e, a, l); + }; + case 5: + return (u) => { + u.drawImage(e, a, l, c, d); + }; + case 9: + return (u) => { + u.drawImage(e, n, i, r, o, a, l, c, d); + }; + default: + throw new TypeError(`Failed to execute 'drawImage' on 'CanvasRenderingContext2D': Valid arities are: [3, 5, 9], but ${t} arguments provided.`); + } + } + getDrawnLength(t, e, n, i) { + const r = this.getLength(t); + return i !== void 0 ? i : e !== void 0 ? n !== void 0 ? n : r - e : r; + } + getLength(t) { + return typeof t == "number" ? t : t.baseVal.value; + } +} +function xs(s, t, e, n, i) { + t = t === void 0 ? 0 : t, e = e === void 0 ? 0 : e, n = n === void 0 ? s.width : n, i = i === void 0 ? s.height : i; + const r = s.data, o = new Uint8ClampedArray(4 * n * i); + for (let a = 0; a < i; a++) + for (let l = 0; l < n; l++) { + const c = 4 * ((e + a) * s.width + t + l), d = 4 * (a * n + l); + o[d] = r[c], o[d + 1] = r[c + 1], o[d + 2] = r[c + 2], o[d + 3] = r[c + 3]; + } + return new ImageData(o, n, i); +} +class jt { + constructor(t, e, n) { + this.area = t, this.latestClippedPath = e, this.previouslyClippedPaths = n; + } + withClippedPath(t) { + const e = t.area.intersectWith(this.area); + return new jt(e, t, this); + } + get initialState() { + return this.previouslyClippedPaths ? this.previouslyClippedPaths.initialState : this.latestClippedPath.initialState; + } + except(t) { + if (t !== this) + return this.previouslyClippedPaths ? new jt(this.area, this.latestClippedPath, this.previouslyClippedPaths.except(t)) : this; + } + contains(t) { + return t ? this === t ? !0 : this.previouslyClippedPaths ? this.previouslyClippedPaths.contains(t) : !1 : !1; + } + getInstructionToRecreate() { + const t = (e, n) => { + this.latestClippedPath.execute(e, n); + }; + if (this.previouslyClippedPaths) { + const e = this.previouslyClippedPaths.getInstructionToRecreate(), n = this.previouslyClippedPaths.latestClippedPath.state.getInstructionToConvertToState(this.latestClippedPath.initialState); + return (i, r) => { + e(i, r), n(i, r), t(i, r); + }; + } + return t; + } +} +class bs extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => { + e.direction = t; + }; + } +} +const He = new bs("direction", y); +class Os extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => { + e.font = t; + }; + } +} +const Ve = new Os("font", y); +class Mn { + constructor(t) { + this.propertyName = t; + } + changeInstanceValue(t, e) { + return this.valuesAreEqual(t[this.propertyName], e) ? t : t.changeProperty(this.propertyName, e); + } + isEqualForInstances(t, e) { + return this.valuesAreEqual(t[this.propertyName], e[this.propertyName]); + } + valueIsTransformableForInstance(t) { + return !0; + } + changeToNewValue(t, e) { + return e ? this.changeToNewValueTransformed(t) : this.changeToNewValueUntransformed(t); + } + getInstructionToChange(t, e) { + const n = t[this.propertyName], i = e[this.propertyName]; + return this.valuesAreEqual(n, i) && (t.fillAndStrokeStylesTransformed === e.fillAndStrokeStylesTransformed || this.valuesAreEqualWhenTransformed(n, i)) ? () => { + } : this.changeToNewValue(i, e.fillAndStrokeStylesTransformed); + } +} +class Nn extends Mn { + constructor(t) { + super(t); + } + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValueTransformed(t) { + return (e, n) => { + const i = n.userTransformation; + e[this.propertyName] = t * i.scale; + }; + } + changeToNewValueUntransformed(t) { + return (e) => { + e[this.propertyName] = t; + }; + } + valuesAreEqualWhenTransformed(t, e) { + return t === 0 && e === 0; + } +} +const qn = new Nn("lineWidth"), zn = new Nn("lineDashOffset"); +class Ls extends Mn { + valuesAreEqual(t, e) { + if (t.length !== e.length) + return !1; + for (let n = 0; n < t.length; n++) + if (t[n] !== e[n]) + return !1; + return !0; + } + changeToNewValueTransformed(t) { + return (e, n) => { + const i = n.userTransformation; + e.setLineDash(t.map((r) => r * i.scale)); + }; + } + changeToNewValueUntransformed(t) { + return (e) => { + e.setLineDash(t); + }; + } + valuesAreEqualWhenTransformed(t, e) { + return t.length === 0 && e.length === 0; + } +} +const Gn = new Ls("lineDash"); +class Bs extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => { + e.textAlign = t; + }; + } +} +const Me = new Bs("textAlign", y); +class As extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => { + e.textBaseline = t; + }; + } +} +const Ne = new As("textBaseline", y); +class Ds extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => e.lineCap = t; + } +} +const Yn = new Ds("lineCap", y); +class Es extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => e.lineJoin = t; + } +} +const Xn = new Es("lineJoin", y); +class Fs extends S { + valuesAreEqual(t, e) { + return t === e; + } + changeToNewValue(t) { + return (e) => e.miterLimit = t; + } +} +const $n = new Fs("miterLimit", y), fe = [ + He, + wn, + Pn, + Tn, + zn, + Gn, + Yn, + Xn, + $n, + pn, + vn, + Rn, + qn, + Sn, + Me, + Ne, + Mt, + Ve, + Pe, + xn, + yn +], Rs = [ + Ve, + Me, + Ne, + He +], Qt = class Un { + constructor(t) { + this.fillStyle = t.fillStyle, this.fontKerning = t.fontKerning, this.lineWidth = t.lineWidth, this.lineCap = t.lineCap, this.lineJoin = t.lineJoin, this.lineDash = t.lineDash, this.miterLimit = t.miterLimit, this.globalAlpha = t.globalAlpha, this.globalCompositeOperation = t.globalCompositeOperation, this.filter = t.filter, this.strokeStyle = t.strokeStyle, this.lineDashOffset = t.lineDashOffset, this.transformation = t.transformation, this.direction = t.direction, this.imageSmoothingEnabled = t.imageSmoothingEnabled, this.imageSmoothingQuality = t.imageSmoothingQuality, this.font = t.font, this.textAlign = t.textAlign, this.textBaseline = t.textBaseline, this.clippedPaths = t.clippedPaths, this.fillAndStrokeStylesTransformed = t.fillAndStrokeStylesTransformed, this.shadowOffset = t.shadowOffset, this.shadowColor = t.shadowColor, this.shadowBlur = t.shadowBlur; + } + changeProperty(t, e) { + const { + fillStyle: n, + fontKerning: i, + lineWidth: r, + lineDash: o, + lineCap: a, + lineJoin: l, + miterLimit: c, + globalAlpha: d, + globalCompositeOperation: u, + filter: g, + strokeStyle: v, + lineDashOffset: P, + transformation: T, + direction: L, + imageSmoothingEnabled: k, + imageSmoothingQuality: N, + font: _, + textAlign: vt, + textBaseline: wt, + clippedPaths: Pt, + fillAndStrokeStylesTransformed: ce, + shadowOffset: he, + shadowColor: le, + shadowBlur: ue + } = this, Ct = { + fillStyle: n, + fontKerning: i, + lineWidth: r, + lineDash: o, + lineCap: a, + lineJoin: l, + miterLimit: c, + globalAlpha: d, + globalCompositeOperation: u, + filter: g, + strokeStyle: v, + lineDashOffset: P, + transformation: T, + direction: L, + imageSmoothingEnabled: k, + imageSmoothingQuality: N, + font: _, + textAlign: vt, + textBaseline: wt, + clippedPaths: Pt, + fillAndStrokeStylesTransformed: ce, + shadowOffset: he, + shadowColor: le, + shadowBlur: ue + }; + return Ct[t] = e, new Un(Ct); + } + get clippingRegion() { + return this.clippedPaths ? this.clippedPaths.area : void 0; + } + equals(t) { + for (let e of fe) + if (!e.isEqualForInstances(this, t)) + return !1; + return (!this.clippedPaths && !t.clippedPaths || this.clippedPaths && this.clippedPaths === t.clippedPaths) && this.fillAndStrokeStylesTransformed === t.fillAndStrokeStylesTransformed; + } + getMaximumLineWidth() { + return this.lineWidth * this.transformation.getMaximumLineWidthScale(); + } + getLineDashPeriod() { + return this.lineDash.reduce((t, e) => t + e, 0); + } + isTransformable() { + for (let t of fe) + if (!t.valueIsTransformableForInstance(this)) + return !1; + return !0; + } + getShadowOffsets() { + const t = [], e = this.filter.getShadowOffset(); + return e !== null && t.push(e), this.shadowOffset.equals(h.origin) || t.push(this.shadowOffset), t; + } + getInstructionToConvertToState(t) { + return this.getInstructionToConvertToStateOnDimensions(t, fe); + } + withClippedPath(t) { + const e = this.clippedPaths ? this.clippedPaths.withClippedPath(t) : new jt(t.area, t); + return this.changeProperty("clippedPaths", e); + } + getInstructionToConvertToStateOnDimensions(t, e) { + const n = e.map((i) => i.getInstructionToChange(this, t)); + return $(...n); + } +}; +Qt.default = new Qt({ + fillStyle: "#000", + fontKerning: "auto", + lineWidth: 1, + lineDash: [], + lineCap: "butt", + lineJoin: "miter", + miterLimit: 10, + globalAlpha: 1, + globalCompositeOperation: "source-over", + filter: Fn.none, + strokeStyle: "#000", + lineDashOffset: 0, + transformation: p.identity, + direction: "inherit", + imageSmoothingEnabled: !0, + imageSmoothingQuality: "low", + font: "10px sans-serif", + textAlign: "start", + textBaseline: "alphabetic", + clippedPaths: void 0, + fillAndStrokeStylesTransformed: !1, + shadowOffset: h.origin, + shadowColor: "rgba(0, 0, 0, 0)", + shadowBlur: 0 +}); +Qt.setDefault = () => { +}; +let G = Qt; +class Ws { + constructor(t) { + this.viewBox = t; } - isContainedByLine(t) { - return t.intersectsSubsetOfLine(this); + createImageData(t, e) { } - isContainedByLineSegment(t) { - return t.containsPoint(this.point1) && t.containsPoint(this.point2); + getImageData(t, e, n, i) { } - intersectWithConvexPolygon(t) { - if (!this.intersectsConvexPolygon(t)) - return b; - if (this.isContainedByConvexPolygon(t)) - return this; - const e = t.getIntersectionsWithLine(this.point1, this.direction); - let n = this.point1, i = this.point2; - for (let s of e) - this.pointIsBetweenPoints(s.point, n, i) && (s.halfPlane.normalTowardInterior.dot(this.direction) > 0 ? n = s.point : i = s.point); - return new A(n, i); + putImageData(t, e, n, i, r, o, a) { + t = xs(t, i, r, o, a); + let l, c = this.viewBox.getDrawingLock(); + this.viewBox.createPatternFromImageData(t).then((u) => { + l = u, c.release(); + }), this.viewBox.addDrawing((u) => { + u.translate(e, n), u.fillStyle = l, u.fillRect(0, 0, t.width, t.height); + }, J(e, n, t.width, t.height).getArea(), M.Absolute, !1, (u) => u.changeProperty("shadowColor", G.default.shadowColor).changeProperty("shadowOffset", G.default.shadowOffset).changeProperty("shadowBlur", G.default.shadowBlur).changeProperty("globalAlpha", G.default.globalAlpha).changeProperty("globalCompositeOperation", G.default.globalCompositeOperation).changeProperty("imageSmoothingEnabled", !1).changeProperty("filter", G.default.filter)); } - isContainedByConvexPolygon(t) { - return t.containsPoint(this.point1) && t.containsPoint(this.point2); +} +class ks { + constructor(t) { + this.viewBox = t; } - contains(t) { - return t.isContainedByLineSegment(this); + get lineCap() { + return this.viewBox.state.current.lineCap; } - pointIsStrictlyBetweenPoints(t, e, n) { - return t.minus(e).dot(this.direction) * t.minus(n).dot(this.direction) < 0; + set lineCap(t) { + this.viewBox.changeState((e) => Yn.changeInstanceValue(e, t)); } - containsPoint(t) { - return this.pointIsOnSameLine(t) && this.pointIsBetweenPoints(t, this.point1, this.point2); + get lineDashOffset() { + return this.viewBox.state.current.lineDashOffset; } - interiorContainsPoint(t) { - return this.pointIsOnSameLine(t) && this.pointIsStrictlyBetweenPoints(t, this.point1, this.point2); + set lineDashOffset(t) { + this.viewBox.changeState((e) => zn.changeInstanceValue(e, t)); } - intersectsRay(t) { - return t.intersectsLineSegment(this); + get lineJoin() { + return this.viewBox.state.current.lineJoin; } - intersectsLineSegment(t) { - if (this.isContainedByLineSegment(t) || t.isContainedByLineSegment(this)) - return !0; - if (!this.lineSegmentIsOnSameLine(t)) - return !1; - const { point1: e, point2: n } = this.getPointsInSameDirection(t.point1, t.point2); - return !this.comesBefore(n, this.point1) && !this.comesBefore(this.point2, e); + set lineJoin(t) { + this.viewBox.changeState((e) => Xn.changeInstanceValue(e, t)); } - intersectsLine(t) { - return t.intersectsSubsetOfLine(this); + get lineWidth() { + return this.viewBox.state.current.lineWidth; } - intersects(t) { - return t.intersectsLineSegment(this); + set lineWidth(t) { + this.viewBox.changeState((e) => qn.changeInstanceValue(e, t)); } - expandByDistance(t) { - const e = this.expandLineByDistance(t), n = new w(this.base, this.direction).expandByDistance(t), i = new w(this.point2, this.direction.scale(-1)).expandByDistance(t); - return e.intersectWithConvexPolygon(new m([n, i])); + get miterLimit() { + return this.viewBox.state.current.miterLimit; } - expandToIncludePoint(t) { - return this.containsPoint(t) ? this : this.pointIsOnSameLine(t) ? this.comesBefore(t, this.point1) ? new A(t, this.point2) : new A(this.point1, t) : m.createTriangle(this.point1, t, this.point2); + set miterLimit(t) { + this.viewBox.changeState((e) => $n.changeInstanceValue(e, t)); } - expandToIncludeInfinityInDirection(t) { - return t.inSameDirectionAs(this.direction) ? new F(this.point1, t) : t.cross(this.direction) === 0 ? new F(this.point2, t) : m.createTriangleWithInfinityInDirection(this.point1, this.point2, t); + getLineDash() { + return this.viewBox.state.current.lineDash; } - transform(t) { - return new A(t.apply(this.point1), t.apply(this.point2)); + setLineDash(t) { + t.length % 2 === 1 && (t = t.concat(t)), this.viewBox.changeState((e) => Gn.changeInstanceValue(e, t)); } } -class zi { - addPoint(t) { - return It; - } - addPointAtInfinity(t) { - return this; +class Hs extends S { + valuesAreEqual(t, e) { + return t === e; } - addArea(t) { - return It; + changeToNewValue(t) { + return (e) => e.fontKerning = t; } } -const Ae = new zi(); -class ge { +const Vs = new Hs("fontKerning", y); +class Ms { constructor(t) { - this.towardsMiddle = t; + this.viewBox = t; } - addPoint(t) { - return m.createFromHalfPlane(new w(t, this.towardsMiddle)); + set direction(t) { + this.viewBox.changeState((e) => He.changeInstanceValue(e, t)); } - addPointAtInfinity(t) { - return t.dot(this.towardsMiddle) >= 0 ? this : Ae; + set font(t) { + this.viewBox.changeState((e) => Ve.changeInstanceValue(e, t)); } - addArea(t) { - const e = this.towardsMiddle.getPerpendicular(); - return t.expandToIncludeInfinityInDirection(this.towardsMiddle).expandToIncludeInfinityInDirection(e).expandToIncludeInfinityInDirection(e.scale(-1)); + set textAlign(t) { + this.viewBox.changeState((e) => Me.changeInstanceValue(e, t)); + } + set textBaseline(t) { + this.viewBox.changeState((e) => Ne.changeInstanceValue(e, t)); + } + set fontKerning(t) { + this.viewBox.changeState((e) => Vs.changeInstanceValue(e, t)); } } -class Xt { - constructor(t, e) { - this.direction1 = t, this.direction2 = e; +class Ns { + constructor(t) { + this.viewBox = t; } - addPoint(t) { - return m.createTriangleWithInfinityInTwoDirections(t, this.direction1, this.direction2); + arc(t, e, n, i, r, o) { + this.viewBox.addPathInstruction(nt.arc(t, e, n, i, r, o)); } - addPointAtInfinity(t) { - return t.isInSmallerAngleBetweenPoints(this.direction1, this.direction2) ? this : t.cross(this.direction1) === 0 ? new ge(this.direction2.projectOn(this.direction1.getPerpendicular())) : t.cross(this.direction2) === 0 ? new ge(this.direction1.projectOn(this.direction2.getPerpendicular())) : this.direction1.isInSmallerAngleBetweenPoints(t, this.direction2) ? new Xt(t, this.direction2) : this.direction2.isInSmallerAngleBetweenPoints(t, this.direction1) ? new Xt(t, this.direction1) : Ae; + arcTo(t, e, n, i, r) { + this.viewBox.addPathInstruction(nt.arcTo(t, e, n, i, r)); } - addArea(t) { - return t.expandToIncludeInfinityInDirection(this.direction1).expandToIncludeInfinityInDirection(this.direction2); + closePath() { + this.viewBox.closePath(); } -} -class Ui { - constructor(t) { - this.direction = t; + ellipse(t, e, n, i, r, o, a, l) { + this.viewBox.addPathInstruction(nt.ellipse(t, e, n, i, r, o, a, l)); } - addPoint(t) { - return new Jt(t, this.direction); + lineTo(t, e) { + this.viewBox.lineTo(new h(t, e)); } - addPointAtInfinity(t) { - return t.cross(this.direction) === 0 ? this : new ge(t.projectOn(this.direction.getPerpendicular())); + lineToInfinityInDirection(t, e) { + this.viewBox.lineTo({ direction: new h(t, e) }); } - addArea(t) { - return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1)); + moveTo(t, e) { + this.viewBox.moveTo(new h(t, e)); } -} -class $i { - constructor(t) { - this.direction = t; + moveToInfinityInDirection(t, e) { + this.viewBox.moveTo({ direction: new h(t, e) }); } - addPointAtInfinity(t) { - return t.inSameDirectionAs(this.direction) ? this : t.cross(this.direction) === 0 ? new Ui(this.direction) : new Xt(this.direction, t); + quadraticCurveTo(t, e, n, i) { + this.viewBox.addPathInstruction(nt.quadraticCurveTo(t, e, n, i)); } - addPoint(t) { - return new F(t, this.direction); + bezierCurveTo(t, e, n, i, r, o) { + this.viewBox.addPathInstruction(nt.bezierCurveTo(t, e, n, i, r, o)); } - addArea(t) { - return t.expandToIncludeInfinityInDirection(this.direction); + rect(t, e, n, i) { + this.viewBox.rect(t, e, n, i); + } + roundRect(t, e, n, i, r) { + this.viewBox.roundRect(t, e, n, i, r); } } -class De { +class qs { constructor(t, e, n) { - this._area = t, this.firstPoint = e, this.subsetOfLineAtInfinity = n; + this.canvas = t, this.canvasState = new gi(e), this.canvasTransform = new pi(e), this.canvasCompositing = new Pi(e), this.canvasImageSmoothing = new Ti(e), this.canvasStrokeStyles = new Si(e), this.canvasShadowStyles = new Oi(e), this.canvasFilters = new Bi(e, n), this.canvasRect = new Ai(e), this.canvasDrawPath = new Di(e), this.canvasUserInterface = new Ei(), this.canvasText = new Is(e), this.canvasDrawImage = new ys(e), this.canvasImageData = new Ws(e), this.canvasPathDrawingStyles = new ks(e), this.canvasTextDrawingStyles = new Ms(e), this.canvasPath = new Ns(e); } - get area() { - return this._area || b; + getContextAttributes() { + return this.canvas.getContext("2d").getContextAttributes(); } - addPoint(t) { - this._area ? this._area = this._area.expandToIncludePoint(t) : this.firstPoint ? t.equals(this.firstPoint) || (this._area = new A(this.firstPoint, t)) : this.subsetOfLineAtInfinity ? this._area = this.subsetOfLineAtInfinity.addPoint(t) : this.firstPoint = t; + save() { + this.canvasState.save(); } - addPosition(t) { - C(t) ? this.addInfinityInDirection(t.direction) : this.addPoint(t); + restore() { + this.canvasState.restore(); } - addInfinityInDirection(t) { - this._area ? this._area = this._area.expandToIncludeInfinityInDirection(t) : this.firstPoint ? this._area = new F(this.firstPoint, t) : this.subsetOfLineAtInfinity ? (this.subsetOfLineAtInfinity = this.subsetOfLineAtInfinity.addPointAtInfinity(t), this.subsetOfLineAtInfinity === Ae && (this._area = It)) : this.subsetOfLineAtInfinity = new $i(t); + reset() { + this.canvasState.reset(); } - transformedWith(t) { - return new Yi(this, t); + getTransform() { + return this.canvasTransform.getTransform(); } - copy() { - return new De(this._area, this.firstPoint, this.subsetOfLineAtInfinity); + resetTransform() { + this.canvasTransform.resetTransform(); } -} -class Tt extends be { - constructor(t, e, n, i) { - super(t, e), this.instruction = n, this.stateConversion = i; + rotate(t) { + this.canvasTransform.rotate(t); } - replaceInstruction(t) { - this.instruction = t; + scale(t, e) { + this.canvasTransform.scale(t, e); } - copy() { - return new Tt(this.initialState, this.state, this.instruction, this.stateConversion); + setTransform(t, e, n, i, r, o) { + this.canvasTransform.setTransform(t, e, n, i, r, o); } - makeExecutable(t) { - const e = t.getInfinity(this.state), n = this.instruction, i = (s, o) => n(s, o, e); - return new st(this.initialState, this.state, i, this.stateConversion); + transform(t, e, n, i, r, o) { + this.canvasTransform.transform(t, e, n, i, r, o); } - static create(t, e) { - return new Tt(t, t, e, () => { - }); + translate(t, e) { + this.canvasTransform.translate(t, e); } -} -function Ki(r, t) { - return r ? t ? C(r) ? C(t) && r.direction.equals(t.direction) : !C(t) && r.equals(t) : !r : !t; -} -class xt { - constructor(t) { - this.shape = t; + set globalAlpha(t) { + this.canvasCompositing.globalAlpha = t; } - getInstructionToDrawLineTo(t, e) { - return this.getInstructionToExtendShapeWithLineTo(this.shape.transform(e.current.transformation.inverse()), t); + set globalCompositeOperation(t) { + this.canvasCompositing.globalCompositeOperation = t; } - getInstructionToMoveToBeginning(t) { - return this.getInstructionToMoveToBeginningOfShape(this.shape.transform(t.current.transformation.inverse())); + set imageSmoothingEnabled(t) { + this.canvasImageSmoothing.imageSmoothingEnabled = t; } - get currentPosition() { - return this.shape.currentPosition; + set imageSmoothingQuality(t) { + this.canvasImageSmoothing.imageSmoothingQuality = t; } - moveToInfinityFromPointInDirection(t, e) { - return (n, i, s) => { - s.moveToInfinityFromPointInDirection(n, i, t, e); - }; + set fillStyle(t) { + this.canvasStrokeStyles.fillStyle = t; } - lineFromInfinityFromPointToInfinityFromPoint(t, e, n) { - return (i, s, o) => { - o.drawLineFromInfinityFromPointToInfinityFromPoint(i, s, t, e, n); - }; + set strokeStyle(t) { + this.canvasStrokeStyles.strokeStyle = t; } - lineFromInfinityFromPointToPoint(t, e) { - return (n, i, s) => { - s.drawLineFromInfinityFromPointToPoint(n, i, t, e); - }; + createLinearGradient(t, e, n, i) { + return this.canvasStrokeStyles.createLinearGradient(t, e, n, i); } - lineToInfinityFromPointInDirection(t, e) { - return (n, i, s) => { - s.drawLineToInfinityFromPointInDirection(n, i, t, e); - }; + createPattern(t, e) { + return this.canvasStrokeStyles.createPattern(t, e); } - lineToInfinityFromInfinityFromPoint(t, e, n) { - return (i, s, o) => { - o.drawLineToInfinityFromInfinityFromPoint(i, s, t, e, n); - }; + createRadialGradient(t, e, n, i, r, o) { + return this.canvasStrokeStyles.createRadialGradient(t, e, n, i, r, o); } - lineTo(t) { - return (e, n) => { - const { x: i, y: s } = n.userTransformation.apply(t); - e.lineTo(i, s); - }; + createConicGradient(t, e, n) { + return this.canvasStrokeStyles.createConicGradient(t, e, n); } - moveTo(t) { - return (e, n) => { - const { x: i, y: s } = n.userTransformation.apply(t); - e.moveTo(i, s); - }; + set shadowBlur(t) { + this.canvasShadowStyles.shadowBlur = t; } -} -class Zt { - constructor(t, e, n, i) { - this.initialPosition = t, this.firstFinitePoint = e, this.lastFinitePoint = n, this.currentPosition = i; + set shadowColor(t) { + this.canvasShadowStyles.shadowColor = t; } - transform(t) { - return new Zt( - t.applyToPointAtInfinity(this.initialPosition), - t.apply(this.firstFinitePoint), - t.apply(this.lastFinitePoint), - t.applyToPointAtInfinity(this.currentPosition) - ); + set shadowOffsetX(t) { + this.canvasShadowStyles.shadowOffsetX = t; } -} -class Ot { - constructor(t, e, n) { - this.initialPosition = t, this.firstFinitePoint = e, this.currentPosition = n; + set shadowOffsetY(t) { + this.canvasShadowStyles.shadowOffsetY = t; } - transform(t) { - return new Ot( - t.applyToPointAtInfinity(this.initialPosition), - t.apply(this.firstFinitePoint), - t.apply(this.currentPosition) - ); + set filter(t) { + this.canvasFilters.filter = t; } -} -class ji extends xt { - constructor(t, e) { - super(e), this.pathBuilderProvider = t; + clearRect(t, e, n, i) { + this.canvasRect.clearRect(t, e, n, i); } - getInstructionToMoveToBeginningOfShape(t) { - return t.initialPosition.direction.cross(t.currentPosition.direction) === 0 ? this.moveToInfinityFromPointInDirection(t.firstFinitePoint, t.initialPosition.direction) : q( - this.moveToInfinityFromPointInDirection(t.lastFinitePoint, t.currentPosition.direction), - this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint, t.currentPosition.direction, t.initialPosition.direction), - this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint, t.firstFinitePoint, t.initialPosition.direction) - ); + fillRect(t, e, n, i) { + this.canvasRect.fillRect(t, e, n, i); + } + strokeRect(t, e, n, i) { + this.canvasRect.strokeRect(t, e, n, i); + } + beginPath() { + this.canvasDrawPath.beginPath(); + } + clip(t, e) { + this.canvasDrawPath.clip(t, e); + } + fill(t, e) { + this.canvasDrawPath.fill(t, e); + } + isPointInPath(t, e, n, i) { + return this.canvasDrawPath.isPointInPath(t, e, n, i); + } + isPointInStroke(t, e, n) { + return this.canvasDrawPath.isPointInStroke(t, e, n); } - getInstructionToExtendShapeWithLineTo(t, e) { - return C(e) ? this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint, t.currentPosition.direction, e.direction) : q( - this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint, e, t.currentPosition.direction), - this.lineFromInfinityFromPointToPoint(e, t.currentPosition.direction) - ); + stroke(t) { + this.canvasDrawPath.stroke(t); } - containsFinitePoint() { - return !0; + drawFocusIfNeeded(t, e) { + this.canvasUserInterface.drawFocusIfNeeded(t, e); } - surroundsFinitePoint() { - return !0; + scrollPathIntoView(t) { + this.canvasUserInterface.scrollPathIntoView(t); } - isClosable() { - return !this.shape.initialPosition.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); + fillText(t, e, n, i) { + this.canvasText.fillText(t, e, n, i); } - canAddLineTo(t) { - return !C(t) || !t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); + measureText(t) { + return this.canvasText.measureText(t); } - addPosition(t) { - return C(t) ? this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new Zt(this.shape.initialPosition, this.shape.firstFinitePoint, this.shape.lastFinitePoint, t)) : this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ot(this.shape.initialPosition, this.shape.firstFinitePoint, t)); + strokeText(t, e, n, i) { + this.canvasText.strokeText(t, e, n, i); } -} -class Qi extends xt { - constructor(t, e) { - super(e), this.pathBuilderProvider = t; + drawImage() { + this.canvasDrawImage.drawImage.apply(this.canvasDrawImage, arguments); } - getInstructionToMoveToBeginningOfShape(t) { - const e = this.moveToInfinityFromPointInDirection(t.currentPosition, t.initialPosition.direction); - if (t.currentPosition.equals(t.firstFinitePoint)) - return e; - const n = this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition, t.firstFinitePoint, t.initialPosition.direction); - return q(e, n); + createImageData(t, e) { + return this.canvasImageData.createImageData(t, e); } - getInstructionToExtendShapeWithLineTo(t, e) { - return C(e) ? this.lineToInfinityFromPointInDirection(t.currentPosition, e.direction) : this.lineTo(e); + getImageData(t, e, n, i) { + return this.canvasImageData.getImageData(t, e, n, i); } - canAddLineTo(t) { - return !0; + putImageData(t, e, n, i, r, o, a) { + this.canvasImageData.putImageData(t, e, n, i, r, o, a); } - containsFinitePoint() { - return !0; + set lineCap(t) { + this.canvasPathDrawingStyles.lineCap = t; } - surroundsFinitePoint() { - return !0; + set lineDashOffset(t) { + this.canvasPathDrawingStyles.lineDashOffset = t; } - isClosable() { - return !0; + set lineJoin(t) { + this.canvasPathDrawingStyles.lineJoin = t; } - addPosition(t) { - return C(t) ? this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new Zt(this.shape.initialPosition, this.shape.firstFinitePoint, this.shape.currentPosition, t)) : this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ot(this.shape.initialPosition, this.shape.firstFinitePoint, t)); + set lineWidth(t) { + this.canvasPathDrawingStyles.lineWidth = t; } -} -class _t { - constructor(t, e) { - this.initialPoint = t, this.currentPosition = e; + set miterLimit(t) { + this.canvasPathDrawingStyles.miterLimit = t; } - transform(t) { - return new _t( - t.apply(this.initialPoint), - t.applyToPointAtInfinity(this.currentPosition) - ); + getLineDash() { + return this.canvasPathDrawingStyles.getLineDash(); } -} -class Bt { - constructor(t, e) { - this.initialPoint = t, this.currentPosition = e; + setLineDash(t) { + this.canvasPathDrawingStyles.setLineDash(t); } - transform(t) { - return new Bt( - t.apply(this.initialPoint), - t.apply(this.currentPosition) - ); + set direction(t) { + this.canvasTextDrawingStyles.direction = t; } -} -class Ji extends xt { - constructor(t, e) { - super(e), this.pathBuilderProvider = t; + set font(t) { + this.canvasTextDrawingStyles.font = t; } - getInstructionToMoveToBeginningOfShape(t) { - return this.moveTo(t.initialPoint); + set textAlign(t) { + this.canvasTextDrawingStyles.textAlign = t; } - getInstructionToExtendShapeWithLineTo(t, e) { - return C(e) ? e.direction.inSameDirectionAs(t.currentPosition.direction) ? () => { - } : this.lineToInfinityFromInfinityFromPoint(t.initialPoint, t.currentPosition.direction, e.direction) : q(this.lineFromInfinityFromPointToInfinityFromPoint(t.initialPoint, e, t.currentPosition.direction), this.lineFromInfinityFromPointToPoint(e, t.currentPosition.direction)); + set textBaseline(t) { + this.canvasTextDrawingStyles.textBaseline = t; } - canAddLineTo(t) { - return !C(t) || !t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); + set fontKerning(t) { + this.canvasTextDrawingStyles.fontKerning = t; } - containsFinitePoint() { - return !0; + arc(t, e, n, i, r, o) { + this.canvasPath.arc(t, e, n, i, r, o); } - surroundsFinitePoint() { - return !0; + arcTo(t, e, n, i, r) { + this.canvasPath.arcTo(t, e, n, i, r); } - isClosable() { - return !0; + bezierCurveTo(t, e, n, i, r, o) { + this.canvasPath.bezierCurveTo(t, e, n, i, r, o); } - addPosition(t) { - return C(t) ? this.pathBuilderProvider.fromPointToPointAtInfinity(new _t(this.shape.initialPoint, t)) : this.pathBuilderProvider.fromPointToPoint(new Bt(this.shape.initialPoint, t)); + closePath() { + this.canvasPath.closePath(); } -} -class Xe extends xt { - constructor(t, e) { - super(e), this.pathBuilderProvider = t; + ellipse(t, e, n, i, r, o, a, l) { + this.canvasPath.ellipse(t, e, n, i, r, o, a); } - getInstructionToMoveToBeginningOfShape(t) { - return this.moveTo(t.initialPoint); + lineTo(t, e) { + this.canvasPath.lineTo(t, e); } - getInstructionToExtendShapeWithLineTo(t, e) { - if (C(e)) { - const n = this.lineToInfinityFromPointInDirection(t.currentPosition, e.direction); - if (t.currentPosition.minus(t.initialPoint).cross(e.direction) === 0) - return n; - const i = this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition, t.initialPoint, e.direction); - return q(n, i); - } - return this.lineTo(e); + lineToInfinityInDirection(t, e) { + this.canvasPath.lineToInfinityInDirection(t, e); } - canAddLineTo(t) { - return !0; + moveTo(t, e) { + this.canvasPath.moveTo(t, e); } - containsFinitePoint() { - return !0; + moveToInfinityInDirection(t, e) { + this.canvasPath.moveToInfinityInDirection(t, e); } - surroundsFinitePoint() { - return !0; + quadraticCurveTo(t, e, n, i) { + this.canvasPath.quadraticCurveTo(t, e, n, i); } - isClosable() { - return !0; + rect(t, e, n, i) { + this.canvasPath.rect(t, e, n, i); } - addPosition(t) { - return C(t) ? this.pathBuilderProvider.fromPointToPointAtInfinity(new _t(this.shape.initialPoint, t)) : this.pathBuilderProvider.fromPointToPoint(new Bt(this.shape.initialPoint, t)); + roundRect(t, e, n, i, r) { + this.canvasPath.roundRect(t, e, n, i, r); } } -class te { - constructor(t, e, n, i) { - this.initialPosition = t, this.surroundsFinitePoint = e, this.positionsSoFar = n, this.currentPosition = i; +class qe extends qt { + constructor() { + super(...arguments), this.colorStops = []; } - transform(t) { - return new te( - t.applyToPointAtInfinity(this.initialPosition), - this.surroundsFinitePoint, - this.positionsSoFar.map((e) => t.applyToPointAtInfinity(e)), - t.applyToPointAtInfinity(this.currentPosition) - ); + addColorStopsToGradient(t) { + for (const e of this.colorStops) + t.addColorStop(e.offset, e.color); } -} -class Ye extends xt { - constructor(t, e) { - super(e), this.pathBuilderProvider = t; + addColorStop(t, e) { + this.colorStops.push({ offset: t, color: e }); } - getInstructionToMoveToBeginningOfShape(t) { - return t.surroundsFinitePoint ? (e, n, i) => i.addPathAroundViewbox(e, n) : () => { + getInstructionToSetTransformed(t) { + return (e, n) => { + const i = n.userTransformation; + e[t] = this.createTransformedGradient(i); }; } - getInstructionToExtendShapeWithLineTo(t, e) { - if (C(e)) - return; - if (t.positionsSoFar.length === 1) - return this.lineFromInfinityFromPointToPoint(e, t.positionsSoFar[0].direction); - const n = t.positionsSoFar.slice(1); - let i = t.initialPosition; - const s = []; - for (let o of n) - s.push(this.lineToInfinityFromInfinityFromPoint(e, i.direction, o.direction)), i = o; - return q(q(...s), this.lineFromInfinityFromPointToPoint(e, i.direction)); + getInstructionToSetUntransformed(t) { + return (e) => { + e[t] = this.createGradient(); + }; } - canAddLineTo(t) { - return !C(t) || !t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction); +} +class zs extends qe { + constructor(t, e, n, i, r) { + super(), this.context = t, this.x0 = e, this.y0 = n, this.x1 = i, this.y1 = r; } - containsFinitePoint() { - return !1; + createTransformedGradient(t) { + const { x: e, y: n } = t.apply(new h(this.x0, this.y0)), { x: i, y: r } = t.apply(new h(this.x1, this.y1)), o = this.context.createLinearGradient(e, n, i, r); + return this.addColorStopsToGradient(o), o; } - surroundsFinitePoint() { - return this.shape.surroundsFinitePoint; + createGradient() { + const t = this.context.createLinearGradient(this.x0, this.y0, this.x1, this.y1); + return this.addColorStopsToGradient(t), t; } - isClosable() { - return !0; +} +class Gs extends qe { + constructor(t, e, n, i, r, o, a) { + super(), this.context = t, this.x0 = e, this.y0 = n, this.r0 = i, this.x1 = r, this.y1 = o, this.r1 = a; } - addPosition(t) { - if (C(t)) { - const n = t.direction.isOnSameSideOfOriginAs(this.shape.initialPosition.direction, this.shape.currentPosition.direction) ? this.shape.surroundsFinitePoint : !this.shape.surroundsFinitePoint; - return this.pathBuilderProvider.atInfinity(new te(this.shape.initialPosition, n, this.shape.positionsSoFar.concat([t]), t)); - } - return this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ot(this.shape.initialPosition, t, t)); + createTransformedGradient(t) { + const { x: e, y: n } = t.apply(new h(this.x0, this.y0)), { x: i, y: r } = t.apply(new h(this.x1, this.y1)), o = this.r0 * t.scale, a = this.r1 * t.scale, l = this.context.createRadialGradient(e, n, o, i, r, a); + return this.addColorStopsToGradient(l), l; + } + createGradient() { + const t = this.context.createRadialGradient(this.x0, this.y0, this.r0, this.x1, this.y1, this.r1); + return this.addColorStopsToGradient(t), t; } } -class Zi { - fromPointAtInfinityToPointAtInfinity(t) { - return new ji(this, t); +class Kn { + constructor(t) { + this.currentState = t, this.instructions = []; } - fromPointAtInfinityToPoint(t) { - return new Qi(this, t); + restore() { + this.addChangeToState(this.currentState.restored(), (t) => { + t.restore(); + }); } - fromPointToPointAtInfinity(t) { - return new Ji(this, t); + save() { + this.addChangeToState(this.currentState.saved(), (t) => { + t.save(); + }); } - fromPointToPoint(t) { - return new Xe(this, t); + changeCurrentInstanceTo(t) { + if (this.currentState.current.equals(t)) + return; + const e = this.currentState.current.getInstructionToConvertToState(t), n = this.currentState.withCurrentState(t); + this.addChangeToState(n, e); + } + addChangeToState(t, e) { + this.currentState = t, e && this.instructions.push(e); + } + get instruction() { + if (this.instructions.length !== 0) + return (t, e) => { + for (const n of this.instructions) + n(t, e); + }; + } +} +class ze extends Kn { + changeCurrentInstanceTo(t) { + if (!this.currentState.current.equals(t)) { + if (!ze.canConvert(this.currentState.current, t)) + if (this.currentState.stack.length > 0) + this.restore(), this.save(); + else { + super.changeCurrentInstanceTo(t); + return; + } + if (t.clippedPaths) { + const e = this.currentState, i = e.current.clippedPaths; + if (t.clippedPaths === i) + super.changeCurrentInstanceTo(t); + else { + const o = t.clippedPaths.except(i); + this.convertToState(o.initialState), this.addChangeToState(o.latestClippedPath.state, o.getInstructionToRecreate()), this.convertToState(e.replaceCurrent(t)); + } + } else + super.changeCurrentInstanceTo(t); + } } - atInfinity(t) { - return new Ye(this, t); + convertToState(t) { + const e = this.currentState.getInstructionToConvertToState(t); + this.addChangeToState(t, e); } - getBuilderFromPosition(t) { - return C(t) ? new Ye(this, new te(t, !1, [t], t)) : new Xe(this, new Bt(t, t)); + static canConvert(t, e) { + return t.clippedPaths ? e.clippedPaths ? e.clippedPaths.contains(t.clippedPaths) : !1 : !0; } } -class Yt extends Te { - constructor(t, e) { - super(t), this._initiallyWithState = t, this.pathInstructionBuilder = e; - } - get currentPosition() { - return this.pathInstructionBuilder.currentPosition; - } - addInstruction(t) { - t.setInitialState(this.state), this.add(t); - } - closePath() { - const t = $.create(this.state, (e) => { - e.closePath(); - }); - t.setInitialState(this.state), this.add(t); - } - copy() { - const t = new Yt(this._initiallyWithState.copy(), this.pathInstructionBuilder); - for (const e of this.added) - t.add(e.copy()); - return t; +class j { + constructor(t, e = []) { + this.current = t, this.stack = e; } - makeExecutable(t) { - const e = new Se(this._initiallyWithState.makeExecutable(t)); - for (const n of this.added) - e.add(n.makeExecutable(t)); - return e; + replaceCurrent(t) { + return new j(t, this.stack); } - surroundsFinitePoint() { - return this.pathInstructionBuilder.surroundsFinitePoint(); + withCurrentState(t) { + return new j(t, this.stack); } - isClosable() { - return this.pathInstructionBuilder.isClosable(); + currentlyTransformed(t) { + return this.withCurrentState(this.current.changeProperty("fillAndStrokeStylesTransformed", t)); } - canAddLineTo(t) { - return this.pathInstructionBuilder.canAddLineTo(t); + withClippedPath(t) { + return new j(this.current.withClippedPath(t), this.stack); } - lineTo(t, e) { - const n = K(t, e.current.transformation); - (!C(t) || this.pathInstructionBuilder.containsFinitePoint()) && this.addInstructionToDrawLineTo(t, e), this.pathInstructionBuilder = this.pathInstructionBuilder.addPosition(n); - const i = this.pathInstructionBuilder.getInstructionToMoveToBeginning(this._initiallyWithState.state); - this._initiallyWithState.replaceInstruction((s, o, a) => { - i(s, o, a); - }); + saved() { + return new j(this.current, (this.stack || []).concat([this.current])); } - addInstructionToDrawLineTo(t, e) { - const n = this.pathInstructionBuilder.getInstructionToDrawLineTo(t, e), i = Tt.create(e, n); - i.setInitialState(this.state), this.add(i); + restored() { + if (!this.stack || this.stack.length === 0) + return this; + const t = this.stack[this.stack.length - 1]; + return new j(t, this.stack.slice(0, this.stack.length - 1)); } - addPathInstruction(t, e, n) { - t.initialPoint && !Ki(this.pathInstructionBuilder.currentPosition, t.initialPoint) && this.lineTo(t.initialPoint, n), t.positionChange && (this.pathInstructionBuilder = this.pathInstructionBuilder.addPosition(K(t.positionChange, n.current.transformation))), e.setInitialState(this.state), this.add(e); + convertToLastSavedInstance(t, e) { + for (let n = this.stack.length - 1; n > e; n--) + t.restore(); } - static create(t, e) { - const n = K(e, t.current.transformation), i = new Zi().getBuilderFromPosition(n), s = i.getInstructionToMoveToBeginning(t), o = Tt.create(t, s); - return new Yt(o, i); + convertFromLastSavedInstance(t, e) { + for (let n = e + 1; n < this.stack.length; n++) + t.changeCurrentInstanceTo(this.stack[n]), t.save(); + t.changeCurrentInstanceTo(this.current); } -} -function ze(r, t) { - return Number.isFinite(r) ? !0 : Number.isFinite(t) ? !1 : r < 0 && t > 0 || r > 0 && t < 0; -} -function zt(r, t, e, n) { - return ze(r, e) && ze(t, n); -} -class _i { - constructor(t, e) { - this.instructions = t, this.area = e; + getInstructionToConvertToStateUsingConversion(t, e) { + const n = j.findIndexOfHighestCommon(this.stack, e.stack); + return this.convertToLastSavedInstance(t, n), e.convertFromLastSavedInstance(t, n), t.instruction; } - get state() { - return this.instructions.state; + getInstructionToConvertToState(t) { + return this.getInstructionToConvertToStateUsingConversion(new Kn(this), t); } - get initialState() { - return this.instructions.initialState; + getInstructionToConvertToStateWithClippedPath(t) { + return this.getInstructionToConvertToStateUsingConversion(new ze(this), t); } - execute(t, e) { - this.instructions.execute(t, e); + static findIndexOfHighestCommon(t, e) { + let n = 0, i = Math.min(t.length - 1, e.length - 1); + for (; n <= i; ) { + if (!t[n].equals(e[n])) + return n - 1; + n++; + } + return n - 1; } } -class dt extends Te { +const an = new j(G.default, []); +class Ys { constructor(t) { - super(t), this._initiallyWithState = t, this.areaBuilder = new De(); - } - get area() { - return this.areaBuilder.area; + this.area = t; } - surroundsFinitePoint() { - for (const t of this.added) - if (t.surroundsFinitePoint()) - return !0; + hasDrawingAcrossBorderOf(t) { return !1; } - currentSubpathIsClosable() { - return this.added.length === 0 ? !0 : this.added[this.added.length - 1].isClosable(); - } - allSubpathsAreClosable() { - if (this.added.length === 0) - return !0; - for (const t of this.added) - if (!t.isClosable()) - return !1; - return !0; - } - drawPath(t, e, n) { - if (this.added.length === 0) - return; - const i = this.added[this.added.length - 1], s = $.create(e, t); - return i.addInstruction(s), this.makeExecutable(n); - } - makeExecutable(t) { - const e = new Se(this._initiallyWithState.makeExecutable()), n = new Ln(t); - for (const i of this.added) - e.add(i.makeExecutable(n)); - return e; - } - clipPath(t, e) { - if (this.added.length === 0) - return; - const n = this.added[this.added.length - 1], i = $.create(e, t); - n.addInstruction(i); - const s = this.recreatePath(); - this.addClippedPath(s.getInstructionsToClip()); - } - closePath() { - if (this.added.length === 0) - return; - this.added[this.added.length - 1].closePath(); + intersects(t) { + return this.area.intersects(t); } - moveTo(t, e) { - const n = K(t, e.current.transformation); - this.areaBuilder.addPosition(n); - const i = Yt.create(e, t); - i.setInitialState(this.state), this.add(i); + isContainedBy(t) { + return t.contains(this.area); } - canAddLineTo(t, e) { - if (this.added.length === 0) - return !0; - const n = K(t, e.current.transformation); - return this.added[this.added.length - 1].canAddLineTo(n); +} +class Ge extends U { + constructor(t, e, n, i, r) { + super(t, e, n, i), this.drawingArea = new Ys(r); } - lineTo(t, e) { - if (this.added.length === 0) { - this.moveTo(t, e); - return; - } - const n = this.added[this.added.length - 1], i = K(t, e.current.transformation); - this.areaBuilder.addPosition(i), n.lineTo(t, e); + static createClearRect(t, e, n, i, r, o, a) { + return new Ge(t, t, (l, c) => { + n.clearRect(l, c, i, r, o, a); + }, () => { + }, e); } - moveToPositionDeterminedBy(t, e, n) { - Number.isFinite(t) ? Number.isFinite(e) ? this.moveTo(new l(t, e), n) : this.moveTo(e < 0 ? U : z, n) : this.moveTo(t < 0 ? _ : tt, n); +} +class Jt extends De { + reconstructState(t, e) { + e.setInitialStateWithClippedPaths(t); } - rect(t, e, n, i, s) { - if (!Number.isFinite(t) && !Number.isFinite(e)) { - this.moveTo({ direction: new l(1, 0) }, s), this.lineTo({ direction: new l(0, 1) }, s), this.lineTo({ direction: new l(-1, -1) }, s); - return; - } - this.moveToPositionDeterminedBy(t, e, s), zt(t, e, n, i) && (Number.isFinite(t) ? Number.isFinite(e) ? (Number.isFinite(n) ? (this.lineTo(new l(t + n, e), s), Number.isFinite(i) ? (this.lineTo(new l(t + n, e + i), s), this.lineTo(new l(t, e + i), s)) : this.lineTo(i > 0 ? z : U, s)) : (this.lineTo(n > 0 ? tt : _, s), Number.isFinite(i) ? this.lineTo(new l(t, e + i), s) : this.lineTo(i > 0 ? z : U, s)), this.lineTo(new l(t, e), s)) : (Number.isFinite(n) ? this.lineTo(new l(t + n, 0), s) : this.lineTo(n > 0 ? tt : _, s), this.lineTo(i > 0 ? z : U, s), this.lineTo(new l(t, 0), s), this.lineTo(e < 0 ? U : z, s)) : (this.lineTo(new l(0, e), s), this.lineTo(n > 0 ? tt : _, s), Number.isFinite(i) ? this.lineTo(new l(0, e + i), s) : this.lineTo(i > 0 ? z : U, s), this.lineTo(t < 0 ? _ : tt, s)), this.closePath(), this.moveToPositionDeterminedBy(t, e, s)); + hasDrawingAcrossBorderOf(t) { + return this.contains((e) => e.drawingArea.hasDrawingAcrossBorderOf(t)); } - addPathInstruction(t, e) { - if (this.added.length === 0) - if (t.initialPoint) - this.moveTo(t.initialPoint, e); - else - return; - const n = this.added[this.added.length - 1], i = n.currentPosition, s = K(i, e.current.transformation.inverse()); - t.changeArea(this.areaBuilder.transformedWith(e.current.transformation), s); - const o = $.create(e, t.instruction); - n.addPathInstruction(t, o, e); + intersects(t) { + return this.contains((e) => e.drawingArea.intersects(t)); } - getInstructionsToClip() { - return new _i(this.makeExecutable({ lineWidth: 0, lineDashPeriod: 0, shadowOffsets: [] }), this.area); + addClearRect(t, e, n, i, r, o) { + const l = new Fe({ lineWidth: 0, lineDashPeriod: 0, shadowOffsets: [] }).getInfinity(e), c = Ge.createClearRect(e, t, l, n, i, r, o); + c.setInitialState(this.state), this.add(c); } - recreatePath() { - const t = new dt(this._initiallyWithState.copy()); - for (const e of this.added) - t.add(e.copy()); - return t.areaBuilder = this.areaBuilder.copy(), t.setInitialState(t.stateOfFirstInstruction), t; + clearContentsInsideArea(t) { + this.removeAll((e) => e.drawingArea.isContainedBy(t)); } - static create(t) { - return new dt($.create(t, (e) => { - e.beginPath(); + static create() { + return new Jt(new U(an, an, G.setDefault, () => { })); } } -function Ue(r, t) { - return Number.isFinite(r) || Number.isFinite(t) ? !1 : r < 0 && t > 0 || r > 0 && t < 0; -} -function En(r, t, e, n) { - return Ue(r, e) && Ue(t, n); -} -class ts { +class Xs { constructor(t) { this.area = t; } @@ -3333,9 +4076,9 @@ class ts { return this.area.intersects(t); } } -class es { +class $s { constructor(t, e) { - this.instructions = t, this.drawingArea = new ts(e); + this.instructions = t, this.drawingArea = new Xs(e); } get state() { return this.instructions.state; @@ -3359,69 +4102,22 @@ class es { this.instructions.execute(t, e); } } -function ns(r, t) { - let e = r.area; - return e && t.lineWidth > 0 && (e = e.expandByDistance(t.lineWidth / 2)), e; -} -function is(r) { - return { - lineWidth: r.current.getMaximumLineWidth(), - lineDashPeriod: r.current.getLineDashPeriod(), - shadowOffsets: r.current.getShadowOffsets() - }; -} -function ss(r) { - return { - lineWidth: 0, - lineDashPeriod: 0, - shadowOffsets: r.current.getShadowOffsets() - }; -} -class H { - constructor(t, e, n, i, s, o, a) { - this.instruction = t, this.area = e, this.build = n, this.takeClippingRegionIntoAccount = i, this.transformationKind = s, this.state = o, this.tempState = a; - } - static forStrokingPath(t, e, n) { - return H.forPath(t, e, is, n); - } - static forFillingPath(t, e, n) { - return H.forPath(t, e, ss, n); - } - static forPath(t, e, n, i) { - const s = e.current.isTransformable(), o = s ? W.None : W.Relative, a = e.currentlyTransformed(s), c = n(a), h = i(a), d = ns(h, c); - return new H( - t, - d, - (u) => h.drawPath(u, a, c), - !0, - o, - a - ); - } - getDrawnArea() { - let t = this.area; - const e = this.state; - if (e.current.shadowBlur !== 0 || !e.current.shadowOffset.equals(l.origin)) { - const n = t.expandByDistance(e.current.shadowBlur).transform(v.translation(e.current.shadowOffset.x, e.current.shadowOffset.y)); - t = t.join(n); - } - return e.current.clippingRegion && this.takeClippingRegionIntoAccount && (t = t.intersectWith(e.current.clippingRegion)), t; - } - getModifiedInstruction() { - let t = Fi(this.transformationKind); - if (this.tempState) { - const n = this.takeClippingRegionIntoAccount ? this.state.getInstructionToConvertToStateWithClippedPath(this.tempState) : this.state.getInstructionToConvertToState(this.tempState); - t = q(t, n); - } - return Ei(this.instruction, t); +function Us(s, t, e, n) { + if (e === void 0) { + t.addSubpaths(s, n); + return; } + let i = rs(e); + if (!i) + return; + t.getRoundRect(i).addSubpaths(s, n); } -class rs { +class Ks { constructor(t) { - this.onChange = t, this.previousInstructionsWithPath = Oe.create(), this.state = this.previousInstructionsWithPath.state; + this.onChange = t, this.previousInstructionsWithPath = Jt.create(), this.state = this.previousInstructionsWithPath.state; } beginPath() { - const t = dt.create(this.state); + const t = Tt.create(this.state); t.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state), this.currentInstructionsWithPath = t; } changeState(t) { @@ -3433,6 +4129,9 @@ class rs { restoreState() { this.state = this.state.restored(); } + resetState() { + this.previousInstructionsWithPath = Jt.create(), this.state = this.previousInstructionsWithPath.state, this.currentInstructionsWithPath = void 0, this.onChange(); + } allSubpathsAreClosable() { return !this.currentInstructionsWithPath || this.currentInstructionsWithPath.allSubpathsAreClosable(); } @@ -3456,30 +4155,24 @@ class rs { }, this.state, () => this.currentInstructionsWithPath); this.state = t.state, this.incorporateDrawingInstruction(t); } - fillRect(t, e, n, i, s) { - const o = H.forFillingPath(s, this.state, (a) => { - const c = dt.create(a); - return c.rect(t, e, n, i, a), c; - }); - this.incorporateDrawingInstruction(o); + fillRect(t, e) { + const n = t.fill(this.state, e); + n && this.incorporateDrawingInstruction(n); } - strokeRect(t, e, n, i) { - const s = H.forStrokingPath((o) => { - o.stroke(); - }, this.state, (o) => { - const a = dt.create(o); - return a.rect(t, e, n, i, o), a; + strokeRect(t) { + const e = t.stroke(this.state, (n) => { + n.stroke(); }); - this.incorporateDrawingInstruction(s); + e && this.incorporateDrawingInstruction(e); } - addDrawing(t, e, n, i, s) { + addDrawing(t, e, n, i, r) { const o = this.state.currentlyTransformed(!1); - n === W.Relative && (e = e.transform(this.state.current.transformation)); + n === M.Relative && (e = e.transform(this.state.current.transformation)); let a; - s && (a = o.withCurrentState(s(o.current))), this.incorporateDrawingInstruction(new H( + r && (a = o.withCurrentState(r(o.current))), this.incorporateDrawingInstruction(new H( t, e, - (c) => st.create(o, c), + (l) => U.create(o, l), i, n, o, @@ -3491,18 +4184,13 @@ class rs { } incorporateDrawingInstruction(t) { const e = t.getDrawnArea(); - if (e === b) + if (e === O) return; const n = t.getModifiedInstruction(); - if (this.currentInstructionsWithPath) { - const i = this.currentInstructionsWithPath.recreatePath(); - this.addToPreviousInstructions(n, e, t.build), i.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state), this.currentInstructionsWithPath = i; - } else - this.addToPreviousInstructions(n, e, t.build), this.state = this.previousInstructionsWithPath.state; - this.onChange(); + this.addToPreviousInstructions(n, e, t.build), this.currentInstructionsWithPath || (this.state = this.previousInstructionsWithPath.state), this.onChange(); } addToPreviousInstructions(t, e, n) { - const i = new es(n(t), e); + const i = new $s(n(t), e); i.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state), this.previousInstructionsWithPath.add(i); } clipCurrentPath(t) { @@ -3523,8 +4211,11 @@ class rs { lineTo(t) { this.currentInstructionsWithPath && this.currentInstructionsWithPath.lineTo(t, this.state); } - rect(t, e, n, i) { - this.currentInstructionsWithPath && this.currentInstructionsWithPath.rect(t, e, n, i, this.state); + rect(t) { + this.currentInstructionsWithPath && t.addSubpaths(this.currentInstructionsWithPath, this.state); + } + roundRect(t, e) { + this.currentInstructionsWithPath && Us(this.currentInstructionsWithPath, t, e, this.state); } intersects(t) { return this.previousInstructionsWithPath.intersects(t); @@ -3533,34 +4224,35 @@ class rs { this.previousInstructionsWithPath.clearContentsInsideArea(t), this.currentInstructionsWithPath && this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state); } clearArea(t, e, n, i) { - if (!zt(t, e, n, i)) + const o = J(t, e, n, i).getArea(); + if (!o) return; - const s = En(t, e, n, i) ? It : m.createRectangle(t, e, n, i), o = s.transform(this.state.current.transformation); - this.intersects(o) && (this.clearContentsInsideArea(o), this.previousInstructionsWithPath.hasDrawingAcrossBorderOf(o) && (this.previousInstructionsWithPath.addClearRect(s, this.state, t, e, n, i), this.currentInstructionsWithPath && this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.state)), this.onChange()); + const a = o.transform(this.state.current.transformation); + this.intersects(a) && (this.clearContentsInsideArea(a), this.previousInstructionsWithPath.hasDrawingAcrossBorderOf(a) && (this.previousInstructionsWithPath.addClearRect(o, this.state, t, e, n, i), this.currentInstructionsWithPath && this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.state)), this.onChange()); } execute(t, e) { this.previousInstructionsWithPath.length && this.previousInstructionsWithPath.execute(t, e); const i = this.previousInstructionsWithPath.state.stack.length; - for (let s = 0; s < i; s++) + for (let r = 0; r < i; r++) t.restore(); } } -class os extends Ie { +class js extends qe { constructor(t, e, n, i) { super(), this.context = t, this.startAngle = e, this.x = n, this.y = i; } createTransformedGradient(t) { - const { x: e, y: n } = t.apply(new l(this.x, this.y)), i = t.getRotationAngle(), s = this.context.createConicGradient(this.startAngle + i, e, n); - return this.addColorStopsToGradient(s), s; + const { x: e, y: n } = t.apply(new h(this.x, this.y)), i = t.getRotationAngle(), r = this.context.createConicGradient(this.startAngle + i, e, n); + return this.addColorStopsToGradient(r), r; } createGradient() { const t = this.context.createConicGradient(this.startAngle, this.x, this.y); return this.addColorStopsToGradient(t), t; } } -class as { - constructor(t, e, n, i, s) { - this.rectangleManager = t, this.context = e, this.drawingIterationProvider = n, this.drawLockProvider = i, this.isTransforming = s, this.instructionSet = new rs(() => this.draw()); +class Qs { + constructor(t, e, n, i, r) { + this.rectangleManager = t, this.context = e, this.drawingIterationProvider = n, this.drawLockProvider = i, this.isTransforming = r, this.instructionSet = new Ks(() => this.draw()); } get width() { return this.rectangleManager.rectangle.viewboxWidth; @@ -3584,7 +4276,7 @@ class as { this.instructionSet.changeState(t); } measureText(t) { - this.context.save(), M.default.getInstructionToConvertToStateOnDimensions(this.state.currentlyTransformed(!1).current, Li)(this.context); + this.context.save(), G.default.getInstructionToConvertToStateOnDimensions(this.state.currentlyTransformed(!1).current, Rs)(this.context); const n = this.context.measureText(t); return this.context.restore(), n; } @@ -3594,6 +4286,9 @@ class as { restoreState() { this.instructionSet.restoreState(); } + resetState() { + this.instructionSet.resetState(); + } beginPath() { this.instructionSet.beginPath(); } @@ -3601,8 +4296,8 @@ class as { const e = await createImageBitmap(t); return this.context.createPattern(e, "no-repeat"); } - addDrawing(t, e, n, i, s) { - this.instructionSet.addDrawing(t, e, n, i, s); + addDrawing(t, e, n, i, r) { + this.instructionSet.addDrawing(t, e, n, i, r); } addPathInstruction(t) { this.instructionSet.addPathInstruction(t); @@ -3617,7 +4312,12 @@ class as { this.instructionSet.canAddLineTo(t) && this.instructionSet.lineTo(t); } rect(t, e, n, i) { - this.instructionSet.rect(t, e, n, i); + const r = J(t, e, n, i); + this.instructionSet.rect(r); + } + roundRect(t, e, n, i, r) { + const o = J(t, e, n, i); + this.instructionSet.roundRect(o, r); } currentPathCanBeFilled() { return this.instructionSet.allSubpathsAreClosable() && this.instructionSet.currentPathSurroundsFinitePoint(); @@ -3628,11 +4328,13 @@ class as { strokePath() { this.instructionSet.strokePath(); } - fillRect(t, e, n, i, s) { - zt(t, e, n, i) && this.instructionSet.fillRect(t, e, n, i, s); + fillRect(t, e, n, i, r) { + const o = J(t, e, n, i); + this.instructionSet.fillRect(o, r); } strokeRect(t, e, n, i) { - !zt(t, e, n, i) || En(t, e, n, i) || this.instructionSet.strokeRect(t, e, n, i); + const r = J(t, e, n, i); + this.instructionSet.strokeRect(r); } clipPath(t) { this.instructionSet.clipPath(t); @@ -3641,37 +4343,37 @@ class as { this.instructionSet.clearArea(t, e, n, i); } createLinearGradient(t, e, n, i) { - return new Vi(this.context, t, e, n, i); + return new zs(this.context, t, e, n, i); } - createRadialGradient(t, e, n, i, s, o) { - return new Hi(this.context, t, e, n, i, s, o); + createRadialGradient(t, e, n, i, r, o) { + return new Gs(this.context, t, e, n, i, r, o); } createConicGradient(t, e, n) { - return new os(this.context, t, e, n); + return new js(this.context, t, e, n); } createPattern(t, e) { let n; - return n = new on(this.context.createPattern(t, e)), n; + return n = new Cn(this.context.createPattern(t, e)), n; } draw() { this.drawingIterationProvider.provideDrawingIteration(() => (this.isTransforming() || this.rectangleManager.measure(), this.rectangleManager.rectangle ? (this.context.restore(), this.context.save(), this.context.clearRect(0, 0, this.width, this.height), this.setInitialTransformation(), this.instructionSet.execute(this.context, this.rectangleManager.rectangle), !0) : !1)); } setInitialTransformation() { const t = this.rectangleManager.rectangle.initialBitmapTransformation; - if (t.equals(v.identity)) + if (t.equals(p.identity)) return; - const { a: e, b: n, c: i, d: s, e: o, f: a } = t; - this.context.setTransform(e, n, i, s, o, a); + const { a: e, b: n, c: i, d: r, e: o, f: a } = t; + this.context.setTransform(e, n, i, r, o, a); } } -class cs { +class Js { constructor(t, e) { this.context = e, this.initialTransformation = e.transformation, this.angularVelocity = Math.PI / 100, this.point = t.onMoved(() => { this.setTransformation(); }, !1); } setTransformation() { - this.context.transformation = this.initialTransformation.before(v.rotation( + this.context.transformation = this.initialTransformation.before(p.rotation( this.point.initial.x, this.point.initial.y, (this.point.initial.x - this.point.current.x) * this.angularVelocity @@ -3687,9 +4389,9 @@ class cs { this.point.cancel(); } } -class hs { - constructor(t, e, n, i, s) { - this.transformable = t, this.centerX = e, this.centerY = n, this.onFinish = s, this.initialTransformation = t.transformation, this.maxScaleLogStep = 0.1, this.currentScaleLog = 0, this.targetScaleLog = Math.log(i), this.makeStep(); +class Zs { + constructor(t, e, n, i, r) { + this.transformable = t, this.centerX = e, this.centerY = n, this.onFinish = r, this.initialTransformation = t.transformation, this.maxScaleLogStep = 0.1, this.currentScaleLog = 0, this.targetScaleLog = Math.log(i), this.makeStep(); } makeStep() { const t = this.targetScaleLog - this.currentScaleLog; @@ -3697,7 +4399,7 @@ class hs { } setTransformToCurrentScaleLog() { this.transformable.transformation = this.initialTransformation.before( - v.zoom( + p.zoom( this.centerX, this.centerY, Math.exp(this.currentScaleLog) @@ -3708,7 +4410,7 @@ class hs { this.stepTimeout !== void 0 && clearTimeout(this.stepTimeout); } } -class ls { +class _s { constructor(t, e) { this.anchor = t, this.context = e, this.initialTransformation = e.transformation, this.point = t.onMoved(() => { this.setTransformation(); @@ -3718,7 +4420,7 @@ class ls { this.context.transformation = this.initialTransformation.before(this.getTranslation()); } getTranslation() { - return v.translation(this.point.current.x - this.point.initial.x, this.point.current.y - this.point.initial.y); + return p.translation(this.point.current.x - this.point.initial.x, this.point.current.y - this.point.initial.y); } withAnchor(t) { return t === this.anchor ? this : this.context.getGestureForTwoAnchors(this.point.cancel(), t); @@ -3727,7 +4429,7 @@ class ls { this.point.cancel(); } } -class Fn { +class jn { constructor(t, e, n) { this.context = n, this.initialTransformation = n.transformation, this.point1 = t.onMoved(() => this.setTransformation(), this.fixesFirstAnchorOnInfiniteCanvas()), this.point2 = e.onMoved(() => this.setTransformation(), this.fixesSecondAnchorOnInfiniteCanvas()); } @@ -3742,7 +4444,7 @@ class Fn { return this.context.getGestureForOneAnchor(e); } } -class us extends Fn { +class tr extends jn { constructor(t, e, n) { super(t, e, n); } @@ -3753,7 +4455,7 @@ class us extends Fn { return !1; } setTransformation() { - this.context.transformation = this.initialTransformation.before(v.translateZoom( + this.context.transformation = this.initialTransformation.before(p.translateZoom( this.point1.initial.x, this.point1.initial.y, this.point2.initial.x, @@ -3765,7 +4467,7 @@ class us extends Fn { )); } } -class ds extends Fn { +class er extends jn { constructor(t, e, n) { super(t, e, n); } @@ -3776,7 +4478,7 @@ class ds extends Fn { return !0; } setTransformation() { - this.context.transformation = this.initialTransformation.before(v.translateRotateZoom( + this.context.transformation = this.initialTransformation.before(p.translateRotateZoom( this.point1.initial.x, this.point1.initial.y, this.point2.initial.x, @@ -3788,7 +4490,7 @@ class ds extends Fn { )); } } -class At { +class Bt { constructor() { this.mapped = []; } @@ -3805,7 +4507,7 @@ class At { this.onRemoved(n); } } -class j extends At { +class Z extends Bt { map(t) { return t; } @@ -3827,9 +4529,9 @@ class j extends At { n(t); } } -class fs { +class nr { constructor(t, e) { - this.setNewValue = t, this.timeoutInMs = e, this._changing = !1, this._firstChange = new j(), this._subsequentChange = new j(), this._changeEnd = new j(); + this.setNewValue = t, this.timeoutInMs = e, this._changing = !1, this._firstChange = new Z(), this._subsequentChange = new Z(), this._changeEnd = new Z(); } get firstChange() { return this._firstChange; @@ -3852,9 +4554,9 @@ class fs { this.setNewValue(t), this._changing || (this._changing = !0, this._firstChange.dispatch()), this._subsequentChange.dispatch(), this.refreshTimeout(); } } -class gs { +class ir { constructor(t, e) { - this.viewBox = t, this.config = e, this._transformationChangeMonitor = new fs((n) => this.viewBox.transformation = n, 100); + this.viewBox = t, this.config = e, this._transformationChangeMonitor = new nr((n) => this.viewBox.transformation = n, 100); } get isTransforming() { return this._transformationChangeMonitor.changing; @@ -3875,21 +4577,21 @@ class gs { this._transformationChangeMonitor.setValue(t); } getGestureForOneAnchor(t) { - return new ls(t, this); + return new _s(t, this); } getGestureForTwoAnchors(t, e) { - return this.config.rotationEnabled ? new ds(t, e, this) : new us(t, e, this); + return this.config.rotationEnabled ? new er(t, e, this) : new tr(t, e, this); } releaseAnchor(t) { this.gesture && (this.gesture = this.gesture.withoutAnchor(t)); } zoom(t, e, n) { - this._zoom && this._zoom.cancel(), this._zoom = new hs(this, t, e, n, () => { + this._zoom && this._zoom.cancel(), this._zoom = new Zs(this, t, e, n, () => { this._zoom = void 0; }); } addRotationAnchor(t) { - this.gesture = new cs(t, this); + this.gesture = new Js(t, this); } addAnchor(t) { if (!this.gesture) { @@ -3900,7 +4602,7 @@ class gs { e && (this.gesture = e); } } -class ms { +class sr { constructor() { this.animationFrameRequested = !1; } @@ -3910,9 +4612,9 @@ class ms { })); } } -class vs { +class rr { constructor(t) { - this.drawingIterationProvider = t, this._drawHappened = new j(); + this.drawingIterationProvider = t, this._drawHappened = new Z(); } get drawHappened() { return this._drawHappened; @@ -3924,7 +4626,7 @@ class vs { }); } } -class ps { +class or { constructor(t) { this.drawingIterationProvider = t, this._locks = []; } @@ -3942,8 +4644,8 @@ class ps { } }, this._locks.push(t), t; } } -var S = /* @__PURE__ */ ((r) => (r[r.CSS = 0] = "CSS", r[r.CANVAS = 1] = "CANVAS", r))(S || {}); -class B { +var x = /* @__PURE__ */ ((s) => (s[s.CSS = 0] = "CSS", s[s.CANVAS = 1] = "CANVAS", s))(x || {}); +class A { constructor(t) { this.base = t, this.inverseBase = t.inverse(); } @@ -3962,14 +4664,14 @@ class St { this.userCoordinates = t, this.canvasBitmap = e, this.virtualBitmapBase = n, this.setDerivedProperties(); } withCanvasBitmapDistortion(t) { - const e = this.canvasBitmap.representBase(t), n = this.userCoordinates.representSimilarTransformation(e), i = this.virtualBitmapBase.before(n), s = new B(t); - return new St(this.userCoordinates, s, i); + const e = this.canvasBitmap.representBase(t), n = this.userCoordinates.representSimilarTransformation(e), i = this.virtualBitmapBase.before(n), r = new A(t); + return new St(this.userCoordinates, r, i); } withUserTransformation(t) { - return new St(new B(t), this.canvasBitmap, this.virtualBitmapBase); + return new St(new A(t), this.canvasBitmap, this.virtualBitmapBase); } setDerivedProperties() { - this.infiniteCanvasContext = new B(this.virtualBitmapBase.before(this.userCoordinates.base)), this.userCoordinatesInsideCanvasBitmap = new B(this.userCoordinates.base.before(this.canvasBitmap.base)), this.initialBitmapTransformation = this.canvasBitmap.representBase(this.userCoordinates.getSimilarTransformation(this.virtualBitmapBase)), this.icContextFromCanvasBitmap = new B(this.infiniteCanvasContext.base.before(this.canvasBitmap.inverseBase)); + this.infiniteCanvasContext = new A(this.virtualBitmapBase.before(this.userCoordinates.base)), this.userCoordinatesInsideCanvasBitmap = new A(this.userCoordinates.base.before(this.canvasBitmap.base)), this.initialBitmapTransformation = this.canvasBitmap.representBase(this.userCoordinates.getSimilarTransformation(this.virtualBitmapBase)), this.icContextFromCanvasBitmap = new A(this.infiniteCanvasContext.base.before(this.canvasBitmap.inverseBase)); } } class yt { @@ -3980,20 +4682,20 @@ class yt { return this.userCoordinates; } withUserTransformation(t) { - return new yt(new B(t), this.canvasBitmap); + return new yt(new A(t), this.canvasBitmap); } withCanvasBitmapDistortion(t) { - return new yt(this.userCoordinates, new B(t)); + return new yt(this.userCoordinates, new A(t)); } setDerivedProperties() { - this.userCoordinatesInsideCanvasBitmap = new B(this.userCoordinates.base.before(this.canvasBitmap.base)), this.initialBitmapTransformation = this.canvasBitmap.inverseBase, this.icContextFromCanvasBitmap = new B(this.userCoordinates.base.before(this.canvasBitmap.inverseBase)); + this.userCoordinatesInsideCanvasBitmap = new A(this.userCoordinates.base.before(this.canvasBitmap.base)), this.initialBitmapTransformation = this.canvasBitmap.inverseBase, this.icContextFromCanvasBitmap = new A(this.userCoordinates.base.before(this.canvasBitmap.inverseBase)); } } -function $e(r) { - const { screenWidth: t, screenHeight: e, viewboxWidth: n, viewboxHeight: i } = r; - return new v(t / n, 0, 0, e / i, 0, 0); +function cn(s) { + const { screenWidth: t, screenHeight: e, viewboxWidth: n, viewboxHeight: i } = s; + return new p(t / n, 0, 0, e / i, 0, 0); } -class ht { +class lt { constructor(t, e) { this.units = t, this.coordinates = e; } @@ -4013,35 +4715,35 @@ class ht { return this.coordinates.icContextFromCanvasBitmap.base; } translateInfiniteCanvasContextTransformationToBitmapTransformation(t) { - return this.coordinates.icContextFromCanvasBitmap.getSimilarTransformation(v.create(t)); + return this.coordinates.icContextFromCanvasBitmap.getSimilarTransformation(p.create(t)); } getTransformationForInstruction(t) { - const e = v.create(t).before(this.coordinates.infiniteCanvasContext.base), n = this.coordinates.userCoordinatesInsideCanvasBitmap.representBase(e); + const e = p.create(t).before(this.coordinates.infiniteCanvasContext.base), n = this.coordinates.userCoordinatesInsideCanvasBitmap.representBase(e); return this.coordinates.userCoordinates.getSimilarTransformation(n); } withUserTransformation(t) { const e = this.coordinates.withUserTransformation(t); - return new ht(this.units, e); + return new lt(this.units, e); } withCanvasMeasurement(t) { - const e = $e(t), n = this.coordinates.withCanvasBitmapDistortion(e); - return new ht(this.units, n); + const e = cn(t), n = this.coordinates.withCanvasBitmapDistortion(e); + return new lt(this.units, n); } withUnits(t) { if (t === this.units) return this; let e; - return t === S.CANVAS ? e = new St(this.coordinates.userCoordinates, this.coordinates.canvasBitmap, this.coordinates.canvasBitmap.base) : e = new yt(this.coordinates.userCoordinates, this.coordinates.canvasBitmap), new ht(t, e); + return t === x.CANVAS ? e = new St(this.coordinates.userCoordinates, this.coordinates.canvasBitmap, this.coordinates.canvasBitmap.base) : e = new yt(this.coordinates.userCoordinates, this.coordinates.canvasBitmap), new lt(t, e); } static create(t, e) { - const n = $e(e), i = t === S.CANVAS ? new St(new B(v.identity), new B(n), n) : new yt(new B(v.identity), new B(n)); - return new ht(t, i); + const n = cn(e), i = t === x.CANVAS ? new St(new A(p.identity), new A(n), n) : new yt(new A(p.identity), new A(n)); + return new lt(t, i); } } -function ws(r, t) { - return r ? t ? r.viewboxWidth === t.viewboxWidth && r.viewboxHeight === t.viewboxHeight && r.screenWidth === t.screenWidth && r.screenHeight === t.screenHeight : !1 : !t; +function ar(s, t) { + return s ? t ? s.viewboxWidth === t.viewboxWidth && s.viewboxHeight === t.viewboxHeight && s.screenWidth === t.screenWidth && s.screenHeight === t.screenHeight : !1 : !t; } -class lt { +class ut { constructor(t, e, n) { this.coordinates = t, this.measurement = e, this.polygon = n; } @@ -4062,21 +4764,21 @@ class lt { } withUnits(t) { const e = this.coordinates.withUnits(t); - return new lt(e, this.measurement, this.polygon); + return new ut(e, this.measurement, this.polygon); } withTransformation(t) { - const e = this.coordinates.withUserTransformation(v.create(t)); - return new lt(e, this.measurement, this.polygon); + const e = this.coordinates.withUserTransformation(p.create(t)); + return new ut(e, this.measurement, this.polygon); } withMeasurement(t) { - if (ws(this.measurement, t)) + if (ar(this.measurement, t)) return this; - const { viewboxWidth: n, viewboxHeight: i } = t, s = m.createRectangle(0, 0, n, i), o = this.coordinates.withCanvasMeasurement(t); - return new lt(o, t, s); + const { viewboxWidth: n, viewboxHeight: i } = t, r = on(0, 0, n, i).getArea(), o = this.coordinates.withCanvasMeasurement(t); + return new ut(o, t, r); } getCSSPosition(t, e) { const { left: n, top: i } = this.measurement; - return new l(t - n, e - i); + return new h(t - n, e - i); } getTransformationForInstruction(t) { return this.coordinates.getTransformationForInstruction(t); @@ -4095,23 +4797,23 @@ class lt { t.save(), t.setTransform(1, 0, 0, 1, 0, 0), t.rect(-e, -e, n, i), t.restore(); } static create(t, e) { - const { viewboxWidth: n, viewboxHeight: i } = t, s = m.createRectangle(0, 0, n, i), o = ht.create(e, t); - return new lt(o, t, s); + const { viewboxWidth: n, viewboxHeight: i } = t, r = on(0, 0, n, i).getArea(), o = lt.create(e, t); + return new ut(o, t, r); } } -class Ps { +class cr { constructor(t, e) { - this.measurementProvider = t, this.config = e, this.transformation = v.identity; + this.measurementProvider = t, this.config = e, this.transformation = p.identity; } setTransformation(t) { this.rectangle ? this.rectangle = this.rectangle.withTransformation(t) : this.transformation = t; } measure() { - const t = this.config.units === S.CSS ? S.CSS : S.CANVAS, e = this.measurementProvider.measure(); - e.screenWidth === 0 || e.screenHeight === 0 ? this.rectangle = void 0 : this.rectangle ? this.rectangle = this.rectangle.withUnits(t).withMeasurement(e) : this.rectangle = lt.create(e, t).withTransformation(this.transformation); + const t = this.config.units === x.CSS ? x.CSS : x.CANVAS, e = this.measurementProvider.measure(); + e.screenWidth === 0 || e.screenHeight === 0 ? this.rectangle = void 0 : this.rectangle ? this.rectangle = this.rectangle.withUnits(t).withMeasurement(e) : this.rectangle = ut.create(e, t).withTransformation(this.transformation); } } -class Cs { +class hr { constructor(t) { this.canvas = t; } @@ -4127,15 +4829,15 @@ class Cs { }; } } -function ft(r) { - const { a: t, b: e, c: n, d: i, e: s, f: o } = r; - return { a: t, b: e, c: n, d: i, e: s, f: o }; +function mt(s) { + const { a: t, b: e, c: n, d: i, e: r, f: o } = s; + return { a: t, b: e, c: n, d: i, e: r, f: o }; } -const Is = { +const lr = { transformationstart: null, transformationchange: null, transformationend: null -}, Wn = { +}, Qn = { auxclick: null, click: null, contextmenu: null, @@ -4145,13 +4847,13 @@ const Is = { mouseout: null, mouseover: null, mouseup: null -}, kn = { +}, Jn = { gotpointercapture: null, lostpointercapture: null, pointerenter: null, pointerout: null, pointerover: null -}, Rn = { +}, Zn = { drag: null, dragend: null, dragenter: null, @@ -4159,15 +4861,15 @@ const Is = { dragover: null, dragstart: null, drop: null -}, Nn = { +}, _n = { touchcancel: null, touchend: null -}, Ts = { - ...Wn, - ...kn, - ...Rn, - ...Nn -}, Mn = { +}, ur = { + ...Qn, + ...Jn, + ...Zn, + ..._n +}, ti = { mousedown: null, mousemove: null, pointerdown: null, @@ -4181,28 +4883,28 @@ const Is = { wheelignored: null, touchignored: null }; -function Lt(r) { - return Is.hasOwnProperty(r); +function Et(s) { + return lr.hasOwnProperty(s); } -function Et(r) { - return Ts.hasOwnProperty(r) || Mn.hasOwnProperty(r); +function Ft(s) { + return ur.hasOwnProperty(s) || ti.hasOwnProperty(s); } -function Ft(r) { - return Mn.hasOwnProperty(r); +function Rt(s) { + return ti.hasOwnProperty(s); } -function Wt(r) { - return Wn.hasOwnProperty(r); +function Wt(s) { + return Qn.hasOwnProperty(s); } -function kt(r) { - return kn.hasOwnProperty(r); +function kt(s) { + return Jn.hasOwnProperty(s); } -function Rt(r) { - return Rn.hasOwnProperty(r); +function Ht(s) { + return Zn.hasOwnProperty(s); } -function Nt(r) { - return Nn.hasOwnProperty(r); +function Vt(s) { + return _n.hasOwnProperty(s); } -class Ss extends At { +class dr extends Bt { constructor(t) { super(), this.source = t; } @@ -4225,9 +4927,9 @@ class Ss extends At { this.remove({ listener: t }); } } -class ys extends At { +class fr extends Bt { constructor(t, e) { - super(), this.transform = e, this.old = new Ss(t); + super(), this.transform = e, this.old = new dr(t); } map(t) { const e = { @@ -4254,18 +4956,18 @@ class ys extends At { this.remove({ listener: t }); } } -function nt(r, t) { - return new ys(r, t); +function st(s, t) { + return new fr(s, t); } -function V(r, t) { - return nt(r, (e) => (n) => { +function Y(s, t) { + return st(s, (e) => (n) => { e(t(n)); }); } -function Ut(r) { - return !!r && typeof r.handleEvent == "function"; +function Zt(s) { + return !!s && typeof s.handleEvent == "function"; } -class bs extends At { +class gr extends Bt { constructor(t) { super(), this.source = t; } @@ -4275,49 +4977,49 @@ class bs extends At { map(t) { const { listenerObject: e, removedCallback: n } = t, i = (o) => { e.handleEvent(o); - }, s = () => { + }, r = () => { this.remove(t), n && n(); }; - return this.source.addListener(i, s), { listener: i, listenerObject: e, removedCallback: s }; + return this.source.addListener(i, r), { listener: i, listenerObject: e, removedCallback: r }; } onRemoved(t) { this.source.removeListener(t.listener), t.removedCallback(); } } -class xs { +class mr { constructor(t) { - this.source = t, this.listenerObjectCollection = new bs(t); + this.source = t, this.listenerObjectCollection = new gr(t); } addListener(t, e) { - Ut(t) ? this.listenerObjectCollection.add({ listenerObject: t, removedCallback: e }) : this.source.addListener(t, e); + Zt(t) ? this.listenerObjectCollection.add({ listenerObject: t, removedCallback: e }) : this.source.addListener(t, e); } removeListener(t) { - Ut(t) ? this.listenerObjectCollection.remove({ listenerObject: t }) : this.source.removeListener(t); + Zt(t) ? this.listenerObjectCollection.remove({ listenerObject: t }) : this.source.removeListener(t); } } -function Ke(r) { - return new xs(r); +function hn(s) { + return new mr(s); } -function Os(r, t, e) { - Ut(t), r.addListener(t, e); +function pr(s, t, e) { + Zt(t), s.addListener(t, e); } -function Bs(r, t, e) { - Ut(t), r.removeListener(t, e); +function vr(s, t, e) { + Zt(t), s.removeListener(t, e); } -function As(r) { - const t = nt(r, (e) => (n) => { +function wr(s) { + const t = st(s, (e) => (n) => { e(n), t.removeListener(e); }); return t; } -function Ds(r, t) { - return nt(r, (e) => (n) => { +function Pr(s, t) { + return st(s, (e) => (n) => { e.apply(t, [n]); }); } -class Ls { +class Cr { constructor(t) { - this.source = t, this.firstDispatcher = new j(), this.secondDispatcher = new j(), this.numberOfListeners = 0, this.sourceListener = (e) => this.dispatchEvent(e); + this.source = t, this.firstDispatcher = new Z(), this.secondDispatcher = new Z(), this.numberOfListeners = 0, this.sourceListener = (e) => this.dispatchEvent(e); } add() { this.numberOfListeners === 0 && this.source.addListener(this.sourceListener), this.numberOfListeners++; @@ -4330,22 +5032,22 @@ class Ls { } build() { return { - first: nt(this.firstDispatcher, (t, e) => (this.add(), e(() => this.remove()), t)), - second: nt(this.secondDispatcher, (t, e) => (this.add(), e(() => this.remove()), t)) + first: st(this.firstDispatcher, (t, e) => (this.add(), e(() => this.remove()), t)), + second: st(this.secondDispatcher, (t, e) => (this.add(), e(() => this.remove()), t)) }; } } -function je(r) { - return new Ls(r).build(); +function ln(s) { + return new Cr(s).build(); } -function N(r, t) { - return nt(r, (e) => (n) => { +function z(s, t) { + return st(s, (e) => (n) => { t(n) && e(n); }); } -class Qe { +class un { constructor(t, e) { - t = Ds(t, e), this._onceSource = Ke(As(t)), this.source = Ke(t); + t = Pr(t, e), this._onceSource = hn(wr(t)), this.source = hn(t); } addListener(t, e) { e && e.once ? this._onceSource.addListener(t) : this.source.addListener(t); @@ -4354,7 +5056,7 @@ class Qe { this.source.removeListener(t), this._onceSource.removeListener(t); } } -class Es { +class Ir { constructor(t, e) { this.captureSource = t, this.bubbleSource = e; } @@ -4374,39 +5076,39 @@ class Es { (typeof e == "boolean" ? e : e && e.capture) ? this.captureSource.removeListener(t) : this.bubbleSource.removeListener(t); } } -function Fs(r, t, e) { - return new Es( - new Qe(r, e), - new Qe(t, e) +function Tr(s, t, e) { + return new Ir( + new un(s, e), + new un(t, e) ); } -function J(r, t, e, n) { - const i = V(N(r, (o) => !o.immediatePropagationStopped), (o) => o.getResultEvent(e.rectangle)), s = V(N(t, (o) => !o.propagationStopped && !o.immediatePropagationStopped), (o) => o.getResultEvent(e.rectangle)); - return Fs(i, s, n); +function tt(s, t, e, n) { + const i = Y(z(s, (o) => !o.immediatePropagationStopped), (o) => o.getResultEvent(e.rectangle)), r = Y(z(t, (o) => !o.propagationStopped && !o.immediatePropagationStopped), (o) => o.getResultEvent(e.rectangle)); + return Tr(i, r, n); } -function Z(r) { - const { first: t, second: e } = je(r), { first: n, second: i } = je(e); +function et(s) { + const { first: t, second: e } = ln(s), { first: n, second: i } = ln(e); return { captureSource: t, bubbleSource: n, afterBubble: i }; } -function Ws(r, t, e) { - const { captureSource: n, bubbleSource: i } = Z(r); - return J( +function Sr(s, t, e) { + const { captureSource: n, bubbleSource: i } = et(s); + return tt( n, i, t, e ); } -class Le { +class Ye { constructor(t, e) { this.rectangleManager = t, this.infiniteCanvas = e, this.cache = {}; } map(t, e) { - return Ws(V(t, e), this.rectangleManager, this.infiniteCanvas); + return Sr(Y(t, e), this.rectangleManager, this.infiniteCanvas); } setOn(t, e) { if (e) @@ -4421,20 +5123,20 @@ class Le { return this.cache[t] ? this.cache[t].on : null; } addEventListener(t, e, n) { - this.cache[t] || (this.cache[t] = this.getEventSource(t)), Os(this.cache[t], e, n); + this.cache[t] || (this.cache[t] = this.getEventSource(t)), pr(this.cache[t], e, n); } removeEventListener(t, e, n) { - this.cache[t] && Bs(this.cache[t], e, n); + this.cache[t] && vr(this.cache[t], e, n); } } -class Vn extends Le { +class ei extends Ye { getEventSource(t) { return (!this.cache || !this.cache[t]) && (this.cache = this.createEvents()), this.cache[t]; } } -class Hn { +class ni { constructor(t, e) { - this.canvasEvent = t, this.preventableDefault = e; + this.canvasEvent = t, this.preventableDefault = e, this.AT_TARGET = 2, this.BUBBLING_PHASE = 3, this.CAPTURING_PHASE = 1, this.NONE = 0; } get bubbles() { return !1; @@ -4451,18 +5153,6 @@ class Hn { get defaultPrevented() { return this.preventableDefault.defaultPrevented; } - get AT_TARGET() { - return Event.AT_TARGET; - } - get BUBBLING_PHASE() { - return Event.BUBBLING_PHASE; - } - get CAPTURING_PHASE() { - return Event.CAPTURING_PHASE; - } - get NONE() { - return Event.NONE; - } initEvent(t, e, n) { } preventDefault() { @@ -4475,7 +5165,7 @@ class Hn { this.canvasEvent.stopPropagation(); } } -class Ee extends Hn { +class Xe extends ni { constructor(t, e, n) { super(t, e), this.type = n; } @@ -4504,7 +5194,7 @@ class Ee extends Hn { return []; } } -class qn { +class ii { constructor(t) { this.preventableDefault = t, this.propagationStopped = !1, this.immediatePropagationStopped = !1; } @@ -4521,7 +5211,7 @@ class qn { return this.resultEvent || (this.resultEvent = this.createResultEvent(t)), this.resultEvent; } } -class ks { +class yr { get defaultPrevented() { return this._defaultPrevented; } @@ -4535,7 +5225,7 @@ class ks { this._defaultPrevented = !0; } } -class Rs { +class xr { get infiniteCanvasDefaultPrevented() { return !1; } @@ -4548,70 +5238,70 @@ class Rs { preventDefault() { } } -class Fe extends qn { +class $e extends ii { constructor(t) { - super(t ? new ks() : new Rs()); + super(t ? new yr() : new xr()); } } -class Ns extends Ee { +class br extends Xe { constructor(t, e) { super(t, e, "draw"), this.transformation = t.transformation, this.inverseTransformation = t.inverseTransformation; } } -class Ms extends Fe { +class Or extends $e { constructor() { super(!1); } createResultEvent(t) { - return this.transformation = ft(t.infiniteCanvasContext.inverseBase), this.inverseTransformation = ft(t.infiniteCanvasContext.base), new Ns(this, this.preventableDefault); + return this.transformation = mt(t.infiniteCanvasContext.inverseBase), this.inverseTransformation = mt(t.infiniteCanvasContext.base), new br(this, this.preventableDefault); } } -class Vs extends Vn { +class Lr extends ei { constructor(t, e, n) { super(e, n), this.drawingIterationProvider = t; } createEvents() { return { - draw: this.map(this.drawingIterationProvider.drawHappened, () => new Ms()) + draw: this.map(this.drawingIterationProvider.drawHappened, () => new Or()) }; } } -class Hs extends Ee { +class Br extends Xe { constructor(t, e, n) { super(t, e, n), this.transformation = t.transformation, this.inverseTransformation = t.inverseTransformation; } } -class ae extends Fe { +class ge extends $e { constructor(t) { super(!1), this.type = t; } createResultEvent(t) { - return this.transformation = ft(t.infiniteCanvasContext.inverseBase), this.inverseTransformation = ft(t.infiniteCanvasContext.base), new Hs(this, this.preventableDefault, this.type); + return this.transformation = mt(t.infiniteCanvasContext.inverseBase), this.inverseTransformation = mt(t.infiniteCanvasContext.base), new Br(this, this.preventableDefault, this.type); } } -class qs extends Vn { +class Ar extends ei { constructor(t, e, n) { super(e, n), this.transformer = t; } createEvents() { return { - transformationstart: this.map(this.transformer.transformationStart, () => new ae("transformationstart")), - transformationchange: this.map(this.transformer.transformationChange, () => new ae("transformationchange")), - transformationend: this.map(this.transformer.transformationEnd, () => new ae("transformationend")) + transformationstart: this.map(this.transformer.transformationStart, () => new ge("transformationstart")), + transformationchange: this.map(this.transformer.transformationChange, () => new ge("transformationchange")), + transformationend: this.map(this.transformer.transformationEnd, () => new ge("transformationend")) }; } } -function E(r, t) { +function W(s, t) { return { addListener(e) { - r.addEventListener(t, e); + s.addEventListener(t, e); }, removeListener(e) { - r.removeEventListener(t, e); + s.removeEventListener(t, e); } }; } -class Gs { +class Dr { constructor(t) { this.event = t; } @@ -4634,7 +5324,7 @@ class Gs { this.event.preventDefault(); } } -class Xs { +class Er { constructor(t) { this.event = t; } @@ -4657,9 +5347,9 @@ class Xs { this._defaultPrevented = !0, t && this.event.preventDefault(); } } -class gt extends qn { +class pt extends ii { constructor(t, e) { - super(e ? new Xs(t) : new Gs(t)), this.event = t; + super(e ? new Er(t) : new Dr(t)), this.event = t; } stopPropagation() { super.stopPropagation(), this.event && this.event.stopPropagation(); @@ -4668,19 +5358,19 @@ class gt extends qn { super.stopImmediatePropagation(), this.event && this.event.stopImmediatePropagation(); } } -class it { +class rt { constructor(t, e, n, i) { this.offsetX = t, this.offsetY = e, this.movementX = n, this.movementY = i; } toInfiniteCanvasCoordinates(t) { - const { x: e, y: n } = t.infiniteCanvasContext.inverseBase.apply(new l(this.offsetX, this.offsetY)), { x: i, y: s } = t.infiniteCanvasContext.inverseBase.untranslated().apply(new l(this.movementX, this.movementY)); - return new it(e, n, i, s); + const { x: e, y: n } = t.infiniteCanvasContext.inverseBase.apply(new h(this.offsetX, this.offsetY)), { x: i, y: r } = t.infiniteCanvasContext.inverseBase.untranslated().apply(new h(this.movementX, this.movementY)); + return new rt(e, n, i, r); } static create(t) { - return new it(t.offsetX, t.offsetY, t.movementX, t.movementY); + return new rt(t.offsetX, t.offsetY, t.movementX, t.movementY); } } -class Ys extends Hn { +class Fr extends ni { constructor(t, e, n) { super(t, e), this.event = n; } @@ -4721,7 +5411,7 @@ class Ys extends Hn { return this.event.composedPath(); } } -class Gn extends Ys { +class si extends Fr { get detail() { return this.event.detail; } @@ -4731,10 +5421,10 @@ class Gn extends Ys { get which() { return this.event.which; } - initUIEvent(t, e, n, i, s) { + initUIEvent(t, e, n, i, r) { } } -class ee extends Gn { +class ae extends si { constructor(t, e, n, i) { super(t, e, n), this.offsetX = i.offsetX, this.offsetY = i.offsetY, this.movementX = i.movementX, this.movementY = i.movementY; } @@ -4786,45 +5476,45 @@ class ee extends Gn { getModifierState(t) { return this.event.getModifierState(t); } - initMouseEvent(t, e, n, i, s, o, a, c, h, d, u, g, p, P, x) { + initMouseEvent(t, e, n, i, r, o, a, l, c, d, u, g, v, P, T) { } } -class me extends gt { +class xe extends pt { constructor(t, e) { - super(t, e), this.props = it.create(t); + super(t, e), this.props = rt.create(t); } createResultEvent(t) { - return new ee(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); + return new ae(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); } } -class $t extends it { - constructor(t, e, n, i, s, o) { - super(t, e, n, i), this.width = s, this.height = o; +class _t extends rt { + constructor(t, e, n, i, r, o) { + super(t, e, n, i), this.width = r, this.height = o; } toInfiniteCanvasCoordinates(t) { - const { offsetX: e, offsetY: n, movementX: i, movementY: s } = super.toInfiniteCanvasCoordinates(t), { x: o, y: a } = t.infiniteCanvasContext.inverseBase.untranslated().apply(new l(this.width, this.height)); - return new $t( + const { offsetX: e, offsetY: n, movementX: i, movementY: r } = super.toInfiniteCanvasCoordinates(t), { x: o, y: a } = t.infiniteCanvasContext.inverseBase.untranslated().apply(new h(this.width, this.height)); + return new _t( e, n, i, - s, + r, o, a ); } static create(t) { - const { offsetX: e, offsetY: n, movementX: i, movementY: s } = super.create(t); - return new $t( + const { offsetX: e, offsetY: n, movementX: i, movementY: r } = super.create(t); + return new _t( e, n, i, - s, + r, t.width, t.height ); } } -class zs extends ee { +class Rr extends ae { constructor(t, e, n, i) { super(t, e, n, i); } @@ -4859,22 +5549,22 @@ class zs extends ee { return console.warn("`PointerEvent.getPredictedEvents()` is currently not supported by InfiniteCanvas"), []; } } -class at extends gt { +class ct extends pt { constructor(t, e) { - super(t, e), this.props = $t.create(t); + super(t, e), this.props = _t.create(t); } createResultEvent(t) { - return new zs(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); + return new Rr(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); } } -class Us { +class Wr { constructor(t, e) { this.initial = t, this.cancel = e, this.current = t; } } -class $s { +class kr { constructor(t) { - this.point = t, this.moveEventDispatcher = new j(), this._fixedOnInfiniteCanvas = !1; + this.point = t, this.moveEventDispatcher = new Z(), this._fixedOnInfiniteCanvas = !1; } get fixedOnInfiniteCanvas() { return this._fixedOnInfiniteCanvas; @@ -4883,21 +5573,21 @@ class $s { this.moveEventDispatcher.removeListener(t); } moveTo(t, e) { - const n = new l(t, e); + const n = new h(t, e); this.point = n, this.moveEventDispatcher.dispatch(n); } onMoved(t, e) { let n; this._fixedOnInfiniteCanvas = e; - const i = (s) => { - n.current = s, t(); + const i = (r) => { + n.current = r, t(); }; - return this.moveEventDispatcher.addListener(i), n = new Us(this.point, () => (this.removeHandler(i), this._fixedOnInfiniteCanvas = !1, this)), n; + return this.moveEventDispatcher.addListener(i), n = new Wr(this.point, () => (this.removeHandler(i), this._fixedOnInfiniteCanvas = !1, this)), n; } } -class Ks { +class Hr { constructor(t) { - this.pointerEvent = t, this._defaultPrevented = !1, this.anchor = new $s(new l(t.offsetX, t.offsetY)); + this.pointerEvent = t, this._defaultPrevented = !1, this.anchor = new kr(new h(t.offsetX, t.offsetY)); } get defaultPrevented() { return this._defaultPrevented; @@ -4918,7 +5608,7 @@ class Ks { this.pointerEvent = t, this.anchor.moveTo(t.offsetX, t.offsetY); } } -class js { +class Vr { constructor() { this.anchors = []; } @@ -4932,7 +5622,7 @@ class js { return this.anchors.find((e) => e.touchId === t); } addAnchorForPointerEvent(t) { - const e = new Ks(t); + const e = new Hr(t); this.anchors.push(e); } updateAnchorForPointerEvent(t) { @@ -4951,36 +5641,36 @@ class js { e > -1 && this.anchors.splice(e, 1); } } -class Kt extends it { - constructor(t, e, n, i, s, o) { - super(t, e, n, i), this.deltaX = s, this.deltaY = o; +class te extends rt { + constructor(t, e, n, i, r, o) { + super(t, e, n, i), this.deltaX = r, this.deltaY = o; } toInfiniteCanvasCoordinates(t) { - const { offsetX: e, offsetY: n, movementX: i, movementY: s } = super.toInfiniteCanvasCoordinates(t), { x: o, y: a } = t.infiniteCanvasContext.inverseBase.untranslated().apply(new l(this.deltaX, this.deltaY)); - return new Kt( + const { offsetX: e, offsetY: n, movementX: i, movementY: r } = super.toInfiniteCanvasCoordinates(t), { x: o, y: a } = t.infiniteCanvasContext.inverseBase.untranslated().apply(new h(this.deltaX, this.deltaY)); + return new te( e, n, i, - s, + r, o, a ); } static create(t) { - const { offsetX: e, offsetY: n, movementX: i, movementY: s } = super.create(t); - return new Kt( + const { offsetX: e, offsetY: n, movementX: i, movementY: r } = super.create(t); + return new te( e, n, i, - s, + r, t.deltaX, t.deltaY ); } } -class Qs extends ee { +class Mr extends ae { constructor(t, e, n, i) { - super(t, e, n, i), this.deltaX = i.deltaX, this.deltaY = i.deltaY; + super(t, e, n, i), this.DOM_DELTA_LINE = 1, this.DOM_DELTA_PAGE = 2, this.DOM_DELTA_PIXEL = 0, this.deltaX = i.deltaX, this.deltaY = i.deltaY; } get deltaMode() { return this.event.deltaMode; @@ -4988,42 +5678,33 @@ class Qs extends ee { get deltaZ() { return this.event.deltaZ; } - get DOM_DELTA_LINE() { - return this.event.DOM_DELTA_LINE; - } - get DOM_DELTA_PAGE() { - return this.event.DOM_DELTA_PAGE; - } - get DOM_DELTA_PIXEL() { - return this.event.DOM_DELTA_PIXEL; - } } -class Js extends gt { +class Nr extends pt { constructor(t, e) { - super(t, e), this.props = Kt.create(t); + super(t, e), this.props = te.create(t); } createResultEvent(t) { - return new Qs(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); + return new Mr(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); } } -function ut(r, t) { +function dt(s, t) { const e = []; - for (let n = 0; n < r.length; n++) { - const i = r[n]; + for (let n = 0; n < s.length; n++) { + const i = s[n]; (!t || t(i)) && e.push(i); } return e; } -class jt { - constructor(t, e, n, i, s, o) { - this.x = t, this.y = e, this.radiusX = n, this.radiusY = i, this.rotationAngle = s, this.identifier = o; +class ee { + constructor(t, e, n, i, r, o) { + this.x = t, this.y = e, this.radiusX = n, this.radiusY = i, this.rotationAngle = r, this.identifier = o; } toInfiniteCanvasCoordinates(t) { - const e = t.infiniteCanvasContext.inverseBase, { x: n, y: i } = e.apply(new l(this.x, this.y)), s = this.radiusX * e.scale, o = this.radiusY * e.scale, a = this.rotationAngle + e.getRotationAngle(); - return new jt( + const e = t.infiniteCanvasContext.inverseBase, { x: n, y: i } = e.apply(new h(this.x, this.y)), r = this.radiusX * e.scale, o = this.radiusY * e.scale, a = this.rotationAngle + e.getRotationAngle(); + return new ee( n, i, - s, + r, o, a, this.identifier @@ -5031,7 +5712,7 @@ class jt { } static create(t, e) { const { x: n, y: i } = e.getCSSPosition(t.clientX, t.clientY); - return new jt( + return new ee( n, i, t.radiusX, @@ -5041,7 +5722,7 @@ class jt { ); } } -class Je { +class dn { constructor() { this.translatedProps = [], this.createdProps = []; } @@ -5051,18 +5732,18 @@ class Je { } createProps(t, e) { let n = this.createdProps.find((i) => i.identifier === t.identifier); - return n || (n = jt.create(t, e), this.createdProps.push(n), n); + return n || (n = ee.create(t, e), this.createdProps.push(n), n); } dispose() { this.translatedProps.splice(0, this.translatedProps.length), this.createdProps.splice(0, this.createdProps.length); } } -class Qt { +class ne { constructor(t, e, n) { this.targetTouches = t, this.changedTouches = e, this.touches = n; } toInfiniteCanvasCoordinates(t) { - const e = new Je(), n = new Qt( + const e = new dn(), n = new ne( this.targetTouches.map((i) => e.toInfiniteCanvasCoordinates(i, t)), this.changedTouches.map((i) => e.toInfiniteCanvasCoordinates(i, t)), this.touches.map((i) => e.toInfiniteCanvasCoordinates(i, t)) @@ -5070,15 +5751,15 @@ class Qt { return e.dispose(), n; } static create(t, e, n) { - const i = new Je(), s = e.map((a) => i.createProps(a, t)), o = n.map((a) => i.createProps(a, t)); - return i.dispose(), new Qt( - s, + const i = new dn(), r = e.map((a) => i.createProps(a, t)), o = n.map((a) => i.createProps(a, t)); + return i.dispose(), new ne( + r, o, - s + r ); } } -class Zs { +class qr { constructor(t, e) { this.touch = t, this.infiniteCanvasX = e.x, this.infiniteCanvasY = e.y, this.radiusX = e.radiusX, this.radiusY = e.radiusY, this.rotationAngle = e.rotationAngle; } @@ -5110,37 +5791,37 @@ class Zs { return this.touch.target; } } -class _s extends Array { +class zr extends Array { item(t) { return this[t]; } } -function tr(r, t) { - const e = r.length; +function Gr(s, t) { + const e = s.length; for (let n = 0; n < e; n++) { - const i = r[n]; + const i = s[n]; if (i.identifier === t) return i; } } -function er(r, t) { - for (let e of r) { - const n = tr(e, t); +function Yr(s, t) { + for (let e of s) { + const n = Gr(e, t); if (n) return n; } } -function ce(r, t) { +function me(s, t) { const e = []; for (const n of t) { - const i = er(r, n.identifier); - i && e.push(new Zs(i, n)); + const i = Yr(s, n.identifier); + i && e.push(new qr(i, n)); } - return new _s(...e); + return new zr(...e); } -class nr extends Gn { +class Xr extends si { constructor(t, e, n, i) { - super(t, e, n), this.touches = ce([n.touches], i.touches), this.targetTouches = ce([n.touches], i.targetTouches), this.changedTouches = ce([n.touches, n.changedTouches], i.changedTouches); + super(t, e, n), this.touches = me([n.touches], i.touches), this.targetTouches = me([n.touches], i.targetTouches), this.changedTouches = me([n.touches, n.changedTouches], i.changedTouches); } get altKey() { return this.event.altKey; @@ -5155,19 +5836,19 @@ class nr extends Gn { return this.event.shiftKey; } } -class bt extends gt { +class xt extends pt { constructor(t, e, n) { super(t, n), this.props = e; } createResultEvent(t) { - return new nr(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); + return new Xr(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); } - static create(t, e, n, i, s) { - const o = Qt.create(t, n, i); - return new bt(e, o, s); + static create(t, e, n, i, r) { + const o = ne.create(t, n, i); + return new xt(e, o, r); } } -class Ze { +class fn { constructor(t, e) { this.source = t, this.listener = e, t.addListener(e); } @@ -5175,26 +5856,26 @@ class Ze { this.source.removeListener(this.listener); } } -class ir { +class $r { constructor(t, e, n, i) { this.listener = n, this.onRemoved = i; - let s; - this.otherSubscription = new Ze(e, (o) => { - s = o; - }), this.subscription = new Ze(t, (o) => { - n([o, s]); + let r; + this.otherSubscription = new fn(e, (o) => { + r = o; + }), this.subscription = new fn(t, (o) => { + n([o, r]); }); } remove() { this.subscription.remove(), this.otherSubscription.remove(), this.onRemoved && this.onRemoved(); } } -class sr extends At { +class Ur extends Bt { constructor(t, e) { super(), this.source = t, this.otherSource = e; } map(t) { - return new ir(this.source, this.otherSource, t.listener, t.onRemoved); + return new $r(this.source, this.otherSource, t.listener, t.onRemoved); } mapsTo(t, e) { return t.listener === e.listener; @@ -5209,32 +5890,32 @@ class sr extends At { this.remove({ listener: t }); } } -function he(r, t) { - return new sr(r, t); +function pe(s, t) { + return new Ur(s, t); } -function rr(r, t) { - for (let e = 0; e < r.length; e++) { - const n = r[e]; +function Kr(s, t) { + for (let e = 0; e < s.length; e++) { + const n = s[e]; if (t(n)) return !0; } return !1; } -function or(r, t) { - return nt(r, (e) => { +function jr(s, t) { + return st(s, (e) => { let n = !1; const i = []; - function s() { + function r() { n || i.length === 0 || (n = !0, t(i.shift()).addListener(e, () => { - n = !1, s(); + n = !1, r(); })); } return (o) => { - i.push(o), s(); + i.push(o), r(); }; }); } -class ar { +class Qr { constructor(t) { this.sequence = t; } @@ -5246,99 +5927,99 @@ class ar { removeListener(t) { } } -function cr(r) { - return new ar(r); +function Jr(s) { + return new Qr(s); } -class _e extends Fe { +class gn extends $e { constructor(t) { super(!0), this.type = t; } createResultEvent() { - return new Ee(this, this.preventableDefault, this.type); + return new Xe(this, this.preventableDefault, this.type); } } -class hr extends Le { - constructor(t, e, n, i, s) { - super(n, i), this.transformer = e, this.config = s, this.anchorSet = new js(); - const o = E(t, "pointerdown"), a = E(t, "pointerleave"), c = E(t, "pointermove"), h = E(t, "pointerup"), d = E(t, "pointercancel"), u = N( - E(t, "touchmove"), - (f) => rr(f.targetTouches, (y) => !this.hasFixedAnchorForTouch(y.identifier)) +class Zr extends Ye { + constructor(t, e, n, i, r) { + super(n, i), this.transformer = e, this.config = r, this.anchorSet = new Vr(); + const o = W(t, "pointerdown"), a = W(t, "pointerleave"), l = W(t, "pointermove"), c = W(t, "pointerup"), d = W(t, "pointercancel"), u = z( + W(t, "touchmove"), + (f) => Kr(f.targetTouches, (b) => !this.hasFixedAnchorForTouch(b.identifier)) ); - o.addListener((f) => this.anchorSet.updateAnchorForPointerEvent(f)), c.addListener((f) => this.anchorSet.updateAnchorForPointerEvent(f)), h.addListener((f) => this.removePointer(f)), a.addListener((f) => this.removePointer(f)); - const g = V(E(t, "mousedown"), (f) => new me(f, !0)), p = V(E(t, "wheel"), (f) => new Js(f, !0)), P = V(E(t, "touchstart"), (f) => { - const y = ut(f.targetTouches), R = ut(f.changedTouches); - return bt.create( + o.addListener((f) => this.anchorSet.updateAnchorForPointerEvent(f)), l.addListener((f) => this.anchorSet.updateAnchorForPointerEvent(f)), c.addListener((f) => this.removePointer(f)), a.addListener((f) => this.removePointer(f)); + const g = Y(W(t, "mousedown"), (f) => new xe(f, !0)), v = Y(W(t, "wheel"), (f) => new Nr(f, !0)), P = Y(W(t, "touchstart"), (f) => { + const b = dt(f.targetTouches), q = dt(f.changedTouches); + return xt.create( this.rectangleManager.rectangle, f, - y, - R, + b, + q, !0 ); - }), x = V(o, (f) => new at(f, !0)), { captureSource: k, bubbleSource: G, afterBubble: Q } = Z(x), { captureSource: mt, bubbleSource: vt, afterBubble: pt } = Z(g), { captureSource: wt, bubbleSource: ne, afterBubble: ie } = Z(P), { captureSource: se, bubbleSource: Dt, afterBubble: Re } = Z(p), Xn = V( - N(Re, (f) => !this.config.greedyGestureHandling && !f.event.ctrlKey && !f.infiniteCanvasDefaultPrevented), - () => new _e("wheelignored") - ), { captureSource: Yn, bubbleSource: zn, afterBubble: Un } = Z(Xn); - Re.addListener((f) => { + }), T = Y(o, (f) => new ct(f, !0)), { captureSource: L, bubbleSource: k, afterBubble: N } = et(T), { captureSource: _, bubbleSource: vt, afterBubble: wt } = et(g), { captureSource: Pt, bubbleSource: ce, afterBubble: he } = et(P), { captureSource: le, bubbleSource: ue, afterBubble: Ct } = et(v), ri = Y( + z(Ct, (f) => !this.config.greedyGestureHandling && !f.event.ctrlKey && !f.infiniteCanvasDefaultPrevented), + () => new gn("wheelignored") + ), { captureSource: oi, bubbleSource: ai, afterBubble: ci } = et(ri); + Ct.addListener((f) => { f.infiniteCanvasDefaultPrevented || this.zoom(f.event); - }), Un.addListener((f) => { + }), ci.addListener((f) => { f.infiniteCanvasDefaultPrevented || console.warn("use ctrl + scroll to zoom"); - }), he(pt, Q).addListener(([f, y]) => { - !f.infiniteCanvasDefaultPrevented && !y.infiniteCanvasDefaultPrevented && this.transformUsingPointer(f.event, y.event); + }), pe(wt, N).addListener(([f, b]) => { + !f.infiniteCanvasDefaultPrevented && !b.infiniteCanvasDefaultPrevented && this.transformUsingPointer(f.event, b.event); }); - const $n = N(ie, (f) => f.event.changedTouches.length === 1), Ne = he($n, Q); - Ne.addListener(([f, y]) => { - const R = f.event.changedTouches[0], X = this.anchorSet.getAnchorForPointerEvent(y.event); - if (X) - if (X.setTouchId(R.identifier), !f.infiniteCanvasDefaultPrevented && !y.infiniteCanvasDefaultPrevented) + const hi = z(he, (f) => f.event.changedTouches.length === 1), je = pe(hi, N); + je.addListener(([f, b]) => { + const q = f.event.changedTouches[0], K = this.anchorSet.getAnchorForPointerEvent(b.event); + if (K) + if (K.setTouchId(q.identifier), !f.infiniteCanvasDefaultPrevented && !b.infiniteCanvasDefaultPrevented) if (this.config.greedyGestureHandling) - this.rectangleManager.measure(), this.transformer.addAnchor(X.anchor), f.event.preventDefault(); + this.rectangleManager.measure(), this.transformer.addAnchor(K.anchor), f.event.preventDefault(); else { - const Ve = this.anchorSet.find((re) => re.touchId !== void 0 && re !== X && !re.defaultPrevented); - if (!Ve) + const Je = this.anchorSet.find((de) => de.touchId !== void 0 && de !== K && !de.defaultPrevented); + if (!Je) return; - this.rectangleManager.measure(), this.transformer.addAnchor(Ve.anchor), this.transformer.addAnchor(X.anchor), f.event.preventDefault(); + this.rectangleManager.measure(), this.transformer.addAnchor(Je.anchor), this.transformer.addAnchor(K.anchor), f.event.preventDefault(); } else - X.preventDefault(); + K.preventDefault(); }); - const Me = N( - he(d, Ne), - ([f, [y, R]]) => f.pointerId === R.event.pointerId + const Qe = z( + pe(d, je), + ([f, [b, q]]) => f.pointerId === q.event.pointerId ); - Me.addListener(([f]) => { + Qe.addListener(([f]) => { this.removePointer(f); }); - const Kn = V( - N(Me, ([f, [y, R]]) => !this.config.greedyGestureHandling && !y.infiniteCanvasDefaultPrevented && !R.infiniteCanvasDefaultPrevented), - () => new _e("touchignored") - ), { captureSource: jn, bubbleSource: Qn, afterBubble: Jn } = Z(Kn); - Jn.addListener((f) => { + const li = Y( + z(Qe, ([f, [b, q]]) => !this.config.greedyGestureHandling && !b.infiniteCanvasDefaultPrevented && !q.infiniteCanvasDefaultPrevented), + () => new gn("touchignored") + ), { captureSource: ui, bubbleSource: di, afterBubble: fi } = et(li); + fi.addListener((f) => { f.infiniteCanvasDefaultPrevented || console.warn("use two fingers to move"); }), this.cache = { - mousemove: this.map(N(E(t, "mousemove"), () => !this.mouseAnchorIsFixed()), (f) => new me(f)), - mousedown: J(mt, vt, n, i), - pointerdown: J(k, G, n, i), + mousemove: this.map(z(W(t, "mousemove"), () => !this.mouseAnchorIsFixed()), (f) => new xe(f)), + mousedown: tt(_, vt, n, i), + pointerdown: tt(L, k, n, i), pointermove: this.map( - or( - N(c, () => this.hasNonFixedAnchorForSomePointer()), - () => cr(this.anchorSet.getAll((f) => !f.anchor.fixedOnInfiniteCanvas).map((f) => f.pointerEvent)) + jr( + z(l, () => this.hasNonFixedAnchorForSomePointer()), + () => Jr(this.anchorSet.getAll((f) => !f.anchor.fixedOnInfiniteCanvas).map((f) => f.pointerEvent)) ), - (f) => new at(f) + (f) => new ct(f) ), - pointerleave: this.map(a, (f) => new at(f)), - pointerup: this.map(h, (f) => new at(f)), - pointercancel: this.map(d, (f) => new at(f)), - wheel: J(se, Dt, n, i), - wheelignored: J(Yn, zn, n, i), - touchstart: J(wt, ne, n, i), - touchignored: J(jn, Qn, n, i), + pointerleave: this.map(a, (f) => new ct(f)), + pointerup: this.map(c, (f) => new ct(f)), + pointercancel: this.map(d, (f) => new ct(f)), + wheel: tt(le, ue, n, i), + wheelignored: tt(oi, ai, n, i), + touchstart: tt(Pt, ce, n, i), + touchignored: tt(ui, di, n, i), touchmove: this.map(u, (f) => { - const y = ut(f.targetTouches), R = ut(f.targetTouches, (X) => !this.hasFixedAnchorForTouch(X.identifier)); - return bt.create( + const b = dt(f.targetTouches), q = dt(f.targetTouches, (K) => !this.hasFixedAnchorForTouch(K.identifier)); + return xt.create( this.rectangleManager.rectangle, f, - y, - R + b, + q ); }) }; @@ -5371,52 +6052,52 @@ class hr extends Le { return; const { offsetX: e, offsetY: n } = t; let i = t.deltaY; - const s = Math.pow(2, -i / 300); - this.rectangleManager.measure(), this.transformer.zoom(e, n, s), t.preventDefault(); + const r = Math.pow(2, -i / 300); + this.rectangleManager.measure(), this.transformer.zoom(e, n, r), t.preventDefault(); } } -class lr { +class _r { constructor(t, e) { this.handledOrFilteredEventCollection = t, this.mappingCollection = e; } setOn(t, e) { - Ft(t) ? this.handledOrFilteredEventCollection.setOn(t, e) : this.mappingCollection.setOn(t, e); + Rt(t) ? this.handledOrFilteredEventCollection.setOn(t, e) : this.mappingCollection.setOn(t, e); } getOn(t) { - return Ft(t) ? this.handledOrFilteredEventCollection.getOn(t) : this.mappingCollection.getOn(t); + return Rt(t) ? this.handledOrFilteredEventCollection.getOn(t) : this.mappingCollection.getOn(t); } addEventListener(t, e, n) { - Ft(t) ? this.handledOrFilteredEventCollection.addEventListener(t, e, n) : this.mappingCollection.addEventListener(t, e, n); + Rt(t) ? this.handledOrFilteredEventCollection.addEventListener(t, e, n) : this.mappingCollection.addEventListener(t, e, n); } removeEventListener(t, e, n) { - Ft(t) ? this.handledOrFilteredEventCollection.removeEventListener(t, e, n) : this.mappingCollection.removeEventListener(t, e, n); + Rt(t) ? this.handledOrFilteredEventCollection.removeEventListener(t, e, n) : this.mappingCollection.removeEventListener(t, e, n); } } -class ur { +class to { constructor(t, e, n, i) { this.mappedMouseEventCollection = t, this.mappedTouchEventCollection = e, this.mappedOnlyPointerEventCollection = n, this.mappedDragEventCollection = i; } setOn(t, e) { - Wt(t) ? this.mappedMouseEventCollection.setOn(t, e) : Nt(t) ? this.mappedTouchEventCollection.setOn(t, e) : kt(t) ? this.mappedOnlyPointerEventCollection.setOn(t, e) : Rt(t) && this.mappedDragEventCollection.setOn(t, e); + Wt(t) ? this.mappedMouseEventCollection.setOn(t, e) : Vt(t) ? this.mappedTouchEventCollection.setOn(t, e) : kt(t) ? this.mappedOnlyPointerEventCollection.setOn(t, e) : Ht(t) && this.mappedDragEventCollection.setOn(t, e); } getOn(t) { if (Wt(t)) return this.mappedMouseEventCollection.getOn(t); - if (Nt(t)) + if (Vt(t)) return this.mappedTouchEventCollection.getOn(t); if (kt(t)) return this.mappedOnlyPointerEventCollection.getOn(t); - if (Rt(t)) + if (Ht(t)) return this.mappedDragEventCollection.getOn(t); } addEventListener(t, e, n) { - Wt(t) ? this.mappedMouseEventCollection.addEventListener(t, e, n) : Nt(t) ? this.mappedTouchEventCollection.addEventListener(t, e, n) : kt(t) ? this.mappedOnlyPointerEventCollection.addEventListener(t, e, n) : Rt(t) && this.mappedDragEventCollection.addEventListener(t, e, n); + Wt(t) ? this.mappedMouseEventCollection.addEventListener(t, e, n) : Vt(t) ? this.mappedTouchEventCollection.addEventListener(t, e, n) : kt(t) ? this.mappedOnlyPointerEventCollection.addEventListener(t, e, n) : Ht(t) && this.mappedDragEventCollection.addEventListener(t, e, n); } removeEventListener(t, e, n) { - Wt(t) ? this.mappedMouseEventCollection.removeEventListener(t, e, n) : Nt(t) ? this.mappedTouchEventCollection.removeEventListener(t, e, n) : kt(t) ? this.mappedOnlyPointerEventCollection.removeEventListener(t, e, n) : Rt(t) && this.mappedDragEventCollection.removeEventListener(t, e, n); + Wt(t) ? this.mappedMouseEventCollection.removeEventListener(t, e, n) : Vt(t) ? this.mappedTouchEventCollection.removeEventListener(t, e, n) : kt(t) ? this.mappedOnlyPointerEventCollection.removeEventListener(t, e, n) : Ht(t) && this.mappedDragEventCollection.removeEventListener(t, e, n); } } -class Ct extends Le { +class It extends Ye { constructor(t, e, n, i) { super(n, i), this.canvasEl = t, this.createInternalEvent = e, this.cache = {}; } @@ -5424,124 +6105,124 @@ class Ct extends Le { return this.cache[t] || (this.cache[t] = this.createEventSource(t)), this.cache[t]; } createEventSource(t) { - return this.map(E(this.canvasEl, t), (e) => this.createInternalEvent(e)); + return this.map(W(this.canvasEl, t), (e) => this.createInternalEvent(e)); } } -class dr extends ee { +class eo extends ae { get dataTransfer() { return this.event.dataTransfer; } } -class fr extends gt { +class no extends pt { constructor(t, e) { - super(t, e), this.props = it.create(t); + super(t, e), this.props = rt.create(t); } createResultEvent(t) { - return new dr(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); + return new eo(this, this.preventableDefault, this.event, this.props.toInfiniteCanvasCoordinates(t)); } } -class gr extends gt { +class io extends pt { createResultEvent() { return this.event; } } -class We { +class Ue { constructor(t, e, n, i) { this.drawEventCollection = t, this.transformationEventCollection = e, this.pointerEventCollection = n, this.unmappedEventCollection = i; } setOn(t, e) { - t === "draw" ? this.drawEventCollection.setOn("draw", e) : Lt(t) ? this.transformationEventCollection.setOn(t, e) : Et(t) ? this.pointerEventCollection.setOn(t, e) : this.unmappedEventCollection.setOn(t, e); + t === "draw" ? this.drawEventCollection.setOn("draw", e) : Et(t) ? this.transformationEventCollection.setOn(t, e) : Ft(t) ? this.pointerEventCollection.setOn(t, e) : this.unmappedEventCollection.setOn(t, e); } getOn(t) { - return t === "draw" ? this.drawEventCollection.getOn("draw") : Lt(t) ? this.transformationEventCollection.getOn(t) : Et(t) ? this.pointerEventCollection.getOn(t) : this.unmappedEventCollection.getOn(t); + return t === "draw" ? this.drawEventCollection.getOn("draw") : Et(t) ? this.transformationEventCollection.getOn(t) : Ft(t) ? this.pointerEventCollection.getOn(t) : this.unmappedEventCollection.getOn(t); } addEventListener(t, e, n) { - t === "draw" ? this.drawEventCollection.addEventListener("draw", e, n) : Lt(t) ? this.transformationEventCollection.addEventListener(t, e, n) : Et(t) ? this.pointerEventCollection.addEventListener(t, e, n) : this.unmappedEventCollection.addEventListener(t, e, n); + t === "draw" ? this.drawEventCollection.addEventListener("draw", e, n) : Et(t) ? this.transformationEventCollection.addEventListener(t, e, n) : Ft(t) ? this.pointerEventCollection.addEventListener(t, e, n) : this.unmappedEventCollection.addEventListener(t, e, n); } removeEventListener(t, e, n) { - t === "draw" ? this.drawEventCollection.removeEventListener("draw", e, n) : Lt(t) ? this.transformationEventCollection.removeEventListener(t, e, n) : Et(t) ? this.pointerEventCollection.removeEventListener(t, e, n) : this.unmappedEventCollection.removeEventListener(t, e, n); + t === "draw" ? this.drawEventCollection.removeEventListener("draw", e, n) : Et(t) ? this.transformationEventCollection.removeEventListener(t, e, n) : Ft(t) ? this.pointerEventCollection.removeEventListener(t, e, n) : this.unmappedEventCollection.removeEventListener(t, e, n); } - static create(t, e, n, i, s, o) { - const a = new Vs(o, n, i), c = new qs(e, n, i), h = new hr( + static create(t, e, n, i, r, o) { + const a = new Lr(o, n, i), l = new Ar(e, n, i), c = new Zr( t, e, n, i, - s - ), d = new lr( - h, - new ur( - new Ct(t, (u) => new me(u), n, i), - new Ct(t, (u) => { - const g = ut(u.targetTouches), p = ut(u.changedTouches); - return bt.create( + r + ), d = new _r( + c, + new to( + new It(t, (u) => new xe(u), n, i), + new It(t, (u) => { + const g = dt(u.targetTouches), v = dt(u.changedTouches); + return xt.create( n.rectangle, u, g, - p + v ); }, n, i), - new Ct(t, (u) => new at(u), n, i), - new Ct(t, (u) => new fr(u), n, i) + new It(t, (u) => new ct(u), n, i), + new It(t, (u) => new no(u), n, i) ) ); - return new We( + return new Ue( a, - c, + l, d, - new Ct(t, (u) => new gr(u), n, i) + new It(t, (u) => new io(u), n, i) ); } } -function mr(r, t) { +function so(s, t) { let e = -1; - const n = r.canvas.width; - r.save(), r.fillStyle = "#fff", r.fillRect(0, 0, n, 5), r.filter = `drop-shadow(${t} 0)`, r.fillRect(0, 0, 1, 5); - const s = r.getImageData(0, 0, n, 3).data; + const n = s.canvas.width; + s.save(), s.fillStyle = "#fff", s.fillRect(0, 0, n, 5), s.filter = `drop-shadow(${t} 0)`, s.fillRect(0, 0, 1, 5); + const r = s.getImageData(0, 0, n, 3).data; for (let o = 0; o < n; o++) { const a = 4 * (2 * n + o); - if (s[a] !== 255) { + if (r[a] !== 255) { e = o; break; } } - return r.restore(), e; + return s.restore(), e; } -function vr(r, t) { - const e = r.canvas.width; - let n = 1, i = 1, s = -1; - return d(), c(), o(), { numerator: n, denominator: i, pixels: s }; +function ro(s, t) { + const e = s.canvas.width; + let n = 1, i = 1, r = -1; + return d(), l(), o(), { numerator: n, denominator: i, pixels: r }; function o() { let u = 0; do { - const g = s; - if (a(), s === g) + const g = r; + if (a(), r === g) break; u++; } while (u < 10); } function a() { - const u = e / (s + 1); - let g = s === 0 ? u : Math.min((e - 1) / s, u), p; - for (; (p = Math.floor(g)) < 2; ) + const u = e / (r + 1); + let g = r === 0 ? u : Math.min((e - 1) / r, u), v; + for (; (v = Math.floor(g)) < 2; ) g *= 10, i *= 10; - n *= p, d(), h(); + n *= v, d(), c(); } - function c() { + function l() { let u = 0; - for (; s === -1 && u < 10; ) + for (; r === -1 && u < 10; ) i *= 10, d(), u++; - h(); + c(); } - function h() { - if (s === -1) + function c() { + if (r === -1) throw new Error(`something went wrong while getting measurement for unit '${t}' on canvas with width ${e}`); } function d() { - s = mr(r, `${n / i}${t}`); + r = so(s, `${n / i}${t}`); } } -class pr { +class oo { constructor(t) { this.ctx = t, this.cache = {}; } @@ -5551,12 +6232,12 @@ class pr { if (e === "px") return t; let n = this.cache[e]; - return n || (n = vr(this.ctx, e), this.cache[e] = n), t * n.pixels * n.denominator / n.numerator; + return n || (n = ro(this.ctx, e), this.cache[e] = n), t * n.pixels * n.denominator / n.numerator; } } -class wr { +class ao { constructor(t) { - this.canvas = t, this.dispatcher = new j(), this.numberOfListeners = 0; + this.canvas = t, this.dispatcher = new Z(), this.numberOfListeners = 0; } addListener(t, e) { this.dispatcher.addListener(t, () => { @@ -5583,19 +6264,19 @@ class wr { this.observer && (this.observer.disconnect(), this.observer = void 0); } } -function tn(r) { - const { screenWidth: t, screenHeight: e } = r; +function mn(s) { + const { screenWidth: t, screenHeight: e } = s; return t > 0 && e > 0; } -class Pr { +class co { constructor(t, e, n) { this.measurementProvider = t, this.resizes = e, this.viewBox = n, this.currentlyVisible = !1; } observe() { const t = this.measurementProvider.measure(); - this.currentlyVisible = tn(t); + this.currentlyVisible = mn(t); const e = (n) => { - const i = tn(n); + const i = mn(n); i && !this.currentlyVisible && this.viewBox.draw(), this.currentlyVisible = i; }; this.resizes.addListener(e), this.listener = e; @@ -5604,40 +6285,40 @@ class Pr { this.listener && (this.resizes.removeListener(this.listener), this.listener = void 0); } } -class ke { +class Ke { constructor(t, e) { - this.canvas = t, this.config = { rotationEnabled: !0, greedyGestureHandling: !1, units: S.CANVAS }, e && Object.assign(this.config, e); - const n = new wr(t); + this.canvas = t, this.config = { rotationEnabled: !0, greedyGestureHandling: !1, units: x.CANVAS }, e && Object.assign(this.config, e); + const n = new ao(t); this.canvasResizes = n, this.cssUnitsCanvasResizeListener = () => { this.canvas.parentElement !== null && this.viewBox.draw(); }; - const i = new vs(new ms()), s = new ps(i), o = new Cs(t); - this.rectangleManager = new Ps(o, this.config); + const i = new rr(new sr()), r = new or(i), o = new hr(t); + this.rectangleManager = new cr(o, this.config); let a; - const c = t.getContext("2d"); + const l = t.getContext("2d"); this.cssLengthConverterFactory = { - create: () => new pr(c) + create: () => new oo(l) }; - const h = new as( + const c = new Qs( this.rectangleManager, - c, - s, - () => s.getLock(), + l, + r, + () => r.getLock(), () => a.isTransforming ); - this.viewBox = h, this.canvasUnitsCanvasResizeObserver = new Pr(o, n, h), a = new gs(this.viewBox, this.config), this.eventCollection = We.create(t, a, this.rectangleManager, this, this.config, i), this.config.units === S.CSS ? this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener) : this.config.units === S.CANVAS && this.canvasUnitsCanvasResizeObserver.observe(); + this.viewBox = c, this.canvasUnitsCanvasResizeObserver = new co(o, n, c), a = new ir(this.viewBox, this.config), this.eventCollection = Ue.create(t, a, this.rectangleManager, this, this.config, i), this.config.units === x.CSS ? this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener) : this.config.units === x.CANVAS && this.canvasUnitsCanvasResizeObserver.observe(); } setUnits(t) { - t === S.CSS && this.config.units !== S.CSS && (this.canvasUnitsCanvasResizeObserver.disconnect(), this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener)), t === S.CANVAS && this.config.units !== S.CANVAS && (this.canvasResizes.removeListener(this.cssUnitsCanvasResizeListener), this.canvasUnitsCanvasResizeObserver.observe()), this.config.units = t, this.rectangleManager.measure(), this.viewBox.draw(); + t === x.CSS && this.config.units !== x.CSS && (this.canvasUnitsCanvasResizeObserver.disconnect(), this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener)), t === x.CANVAS && this.config.units !== x.CANVAS && (this.canvasResizes.removeListener(this.cssUnitsCanvasResizeListener), this.canvasUnitsCanvasResizeObserver.observe()), this.config.units = t, this.rectangleManager.measure(), this.viewBox.draw(); } getContext() { - return this.context || (this.context = new Mi(this.canvas, this.viewBox, this.cssLengthConverterFactory)), this.context; + return this.context || (this.context = new qs(this.canvas, this.viewBox, this.cssLengthConverterFactory)), this.context; } get transformation() { - return ft(this.rectangleManager.rectangle.infiniteCanvasContext.inverseBase); + return mt(this.rectangleManager.rectangle.infiniteCanvasContext.inverseBase); } get inverseTransformation() { - return ft(this.rectangleManager.rectangle.infiniteCanvasContext.base); + return mt(this.rectangleManager.rectangle.infiniteCanvasContext.base); } get rotationEnabled() { return this.config.rotationEnabled; @@ -5693,6 +6374,18 @@ class ke { get ontouchignored() { return this.eventCollection.getOn("touchignored"); } + set onbeforeinput(t) { + this.eventCollection.setOn("beforeinput", t); + } + get onbeforeinput() { + return this.eventCollection.getOn("beforeinput"); + } + set oncancel(t) { + this.eventCollection.setOn("cancel", t); + } + get oncancel() { + return this.eventCollection.getOn("cancel"); + } set oncopy(t) { this.eventCollection.setOn("copy", t); } @@ -5801,6 +6494,12 @@ class ke { set ondblclick(t) { this.eventCollection.setOn("dblclick", t); } + get onscrollend() { + return this.eventCollection.getOn("scrollend"); + } + set onscrollend(t) { + this.eventCollection.setOn("scrollend", t); + } get ondrag() { return this.eventCollection.getOn("drag"); } @@ -6252,10 +6951,10 @@ class ke { this.eventCollection.removeEventListener(t, e, n); } } -ke.CANVAS_UNITS = S.CANVAS; -ke.CSS_UNITS = S.CSS; -const Ir = ke; +Ke.CANVAS_UNITS = x.CANVAS; +Ke.CSS_UNITS = x.CSS; +const lo = Ke; export { - S as Units, - Ir as default + x as Units, + lo as default }; diff --git a/dist/infinite-canvas.umd.cjs b/dist/infinite-canvas.umd.cjs index 174e982e..ade9b60d 100644 --- a/dist/infinite-canvas.umd.cjs +++ b/dist/infinite-canvas.umd.cjs @@ -1 +1 @@ -(function(vt,Q){typeof exports=="object"&&typeof module<"u"?module.exports=Q():typeof define=="function"&&define.amd?define(Q):(vt=typeof globalThis<"u"?globalThis:vt||self,vt.InfiniteCanvas=Q())})(this,function(){"use strict";let vt=class{constructor(t){this.viewBox=t}restore(){this.viewBox.restoreState()}save(){this.viewBox.saveState()}};const Q=class mt{constructor(t,e){this.x=t,this.y=e}mod(){return Math.sqrt(this.modSq())}modSq(){return this.x*this.x+this.y*this.y}minus(t){return new mt(this.x-t.x,this.y-t.y)}plus(t){return new mt(this.x+t.x,this.y+t.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}equals(t){return this.x===t.x&&this.y===t.y}getPerpendicular(){return new mt(-this.y,this.x)}scale(t){return new mt(t*this.x,t*this.y)}projectOn(t){return t.scale(this.dot(t)/t.modSq())}matrix(t,e,n,i){return new mt(t*this.x+e*this.y,n*this.x+i*this.y)}inSameDirectionAs(t){return this.cross(t)===0&&this.dot(t)>=0}isInOppositeDirectionAs(t){return this.cross(t)===0&&this.dot(t)<0}isOnSameSideOfOriginAs(t,e){return this.isInSmallerAngleBetweenPoints(t,e)||t.isInSmallerAngleBetweenPoints(this,e)||e.isInSmallerAngleBetweenPoints(this,t)}isInSmallerAngleBetweenPoints(t,e){const n=t.cross(e);return n>0?t.cross(this)>=0&&this.cross(e)>=0:n<0?t.cross(this)<=0&&this.cross(e)<=0:t.dot(e)>0?this.cross(t)===0&&this.dot(t)>0:!0}};Q.origin=new Q(0,0);let h=Q;function ot(r){return r.toFixed(10).replace(/\.?0+$/,"")}const se=class B{constructor(t,e,n,i,s,o){this.a=t,this.b=e,this.c=n,this.d=i,this.e=s,this.f=o,this.scale=Math.sqrt(t*i-e*n)}getMaximumLineWidthScale(){const t=this.a+this.c,e=this.b+this.d,n=this.a-this.c,i=this.b-this.d;return Math.sqrt(Math.max(t*t+e*e,n*n+i*i))}getRotationAngle(){const t=this.a/this.scale,e=this.b/this.scale;if(t===0)return e>0?Math.PI/2:3*Math.PI/2;const n=Math.atan(e/t);return t>0?e>0?n:e===0?0:2*Math.PI+n:e>0?Math.PI+n:e===0?Math.PI:Math.PI+n}applyToPointAtInfinity(t){return{direction:this.untranslated().apply(t.direction)}}apply(t){return new h(this.a*t.x+this.c*t.y+this.e,this.b*t.x+this.d*t.y+this.f)}untranslated(){const{x:t,y:e}=this.apply(h.origin);return this.before(B.translation(-t,-e))}before(t){const e=t.a*this.a+t.c*this.b,n=t.b*this.a+t.d*this.b,i=t.a*this.c+t.c*this.d,s=t.b*this.c+t.d*this.d,o=t.a*this.e+t.c*this.f+t.e,a=t.b*this.e+t.d*this.f+t.f;return new B(e,n,i,s,o,a)}equals(t){return this.a===t.a&&this.b===t.b&&this.c===t.c&&this.d===t.d&&this.e===t.e&&this.f===t.f}inverse(){var t=this.a*this.d-this.b*this.c;if(t==0)throw new Error("error calculating inverse: zero determinant");const e=this.d/t,n=-this.b/t,i=-this.c/t,s=this.a/t,o=(this.c*this.f-this.d*this.e)/t,a=(this.b*this.e-this.a*this.f)/t;return new B(e,n,i,s,o,a)}static translation(t,e){return new B(1,0,0,1,t,e)}static scale(t){return new B(t,0,0,t,0,0)}static zoom(t,e,n,i,s){const o=1-n;return i!==void 0?new B(n,0,0,n,t*o+i,e*o+s):new B(n,0,0,n,t*o,e*o)}static translateZoom(t,e,n,i,s,o,a,c){const l=n-t,d=i-e,u=l*l+d*d;if(u===0)throw new Error("divide by 0");const g=a-s,w=c-o,P=g*g+w*w,O=Math.sqrt(P/u);return B.zoom(t,e,O,s-t,o-e)}static rotation(t,e,n){const i=Math.cos(n),s=Math.sin(n),o=1-i;return new B(i,s,-s,i,t*o+e*s,-t*s+e*o)}static translateRotateZoom(t,e,n,i,s,o,a,c){const l=n-t,d=i-e,u=l*l+d*d;if(u===0)throw new Error("divide by 0");const g=a-s,w=c-o,P=t*i-e*n,O=n*l+i*d,H=t*l+e*d,K=(l*g+d*w)/u,rt=(l*w-d*g)/u,Bt=-rt,At=K,Dt=(s*O-a*H-P*w)/u,Lt=(o*O-c*H+P*g)/u;return new B(K,rt,Bt,At,Dt,Lt)}static create(t){if(t instanceof B)return t;const{a:e,b:n,c:i,d:s,e:o,f:a}=t;return new B(e,n,i,s,o,a)}toString(){return`x: (${ot(this.a)}, ${ot(this.b)}), y: (${ot(this.c)}, ${ot(this.d)}), d: (${ot(this.e)}, ${ot(this.f)})`}};se.identity=new se(1,0,0,1,0,0);let v=se;class I{constructor(t,e){this.propertyName=t,this.noopInstruction=e}changeInstanceValue(t,e){return this.valuesAreEqual(t[this.propertyName],e)?t:t.changeProperty(this.propertyName,e)}isEqualForInstances(t,e){return this.valuesAreEqual(t[this.propertyName],e[this.propertyName])}getInstructionToChange(t,e){return this.valuesAreEqual(t[this.propertyName],e[this.propertyName])?this.noopInstruction:this.changeToNewValue(e[this.propertyName])}valueIsTransformableForInstance(t){return!0}}const T=()=>{};class Un extends I{valuesAreEqual(t,e){return t.equals(e)}changeToNewValue(t){return(e,n)=>{const{a:i,b:s,c:o,d:a,e:c,f:l}=n.getTransformationForInstruction(t);e.setTransform(i,s,o,a,c,l)}}}const Et=new Un("transformation",T);class zn{constructor(t){this.viewBox=t}getTransform(){if(DOMMatrix){const t=this.viewBox.state.current.transformation;return new DOMMatrix([t.a,t.b,t.c,t.d,t.e,t.f])}}resetTransform(){this.viewBox.changeState(t=>Et.changeInstanceValue(t,v.identity))}rotate(t){this.addTransformation(v.rotation(0,0,t))}scale(t,e){this.addTransformation(new v(t,0,0,e,0,0))}setTransform(t,e,n,i,s,o){let a,c,l,d,u,g;typeof t=="number"?(a=t,c=e,l=n,d=i,u=s,g=o):t.a!==void 0?(a=t.a,c=t.b,l=t.c,d=t.d,u=t.e,g=t.f):(a=t.m11,c=t.m12,l=t.m21,d=t.m22,u=t.m41,g=t.m42),this.viewBox.changeState(w=>Et.changeInstanceValue(w,new v(a,c,l,d,u,g)))}transform(t,e,n,i,s,o){this.addTransformation(new v(t,e,n,i,s,o))}translate(t,e){this.addTransformation(v.translation(t,e))}addTransformation(t){const e=this.viewBox.state.current.transformation,n=t.before(e);this.viewBox.changeState(i=>Et.changeInstanceValue(i,n))}}class $n extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.globalAlpha=t}}const Ne=new $n("globalAlpha",T);class Kn extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.globalCompositeOperation=t}}const Me=new Kn("globalCompositeOperation",T);class jn{constructor(t){this.viewBox=t}get globalAlpha(){return this.viewBox.state.current.globalAlpha}set globalAlpha(t){this.viewBox.changeState(e=>Ne.changeInstanceValue(e,t))}get globalCompositeOperation(){return this.viewBox.state.current.globalCompositeOperation}set globalCompositeOperation(t){this.viewBox.changeState(e=>Me.changeInstanceValue(e,t))}}class Qn extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.imageSmoothingEnabled=t}}}const Ve=new Qn("imageSmoothingEnabled",T);class Jn extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.imageSmoothingQuality=t}}}const He=new Jn("imageSmoothingQuality",T);class Zn{constructor(t){this.viewBox=t}get imageSmoothingEnabled(){return this.viewBox.state.current.imageSmoothingEnabled}set imageSmoothingEnabled(t){this.viewBox.changeState(e=>Ve.changeInstanceValue(e,t))}get imageSmoothingQuality(){return this.viewBox.state.current.imageSmoothingQuality}set imageSmoothingQuality(t){this.viewBox.changeState(e=>He.changeInstanceValue(e,t))}}class Ft{}class qe extends Ft{constructor(t){super(),this.fillStrokeStyle=t}setTransform(t){this.fillStrokeStyle.setTransform(t)}getInstructionToSetUntransformed(t){return e=>{e[t]=this.fillStrokeStyle}}getInstructionToSetTransformed(t){return e=>{e[t]=this.fillStrokeStyle}}}class Ge{constructor(t){this.propName=t}changeInstanceValue(t,e){return t.changeProperty(this.propName,e)}isEqualForInstances(t,e){return t[this.propName]===e[this.propName]}getInstructionToChange(t,e){const n=e[this.propName];return this.isEqualForInstances(t,e)?!(n instanceof Ft)||t.fillAndStrokeStylesTransformed===e.fillAndStrokeStylesTransformed?()=>{}:e.fillAndStrokeStylesTransformed?n.getInstructionToSetTransformed(this.propName):n.getInstructionToSetUntransformed(this.propName):n instanceof Ft?e.fillAndStrokeStylesTransformed?n.getInstructionToSetTransformed(this.propName):n.getInstructionToSetUntransformed(this.propName):i=>{i[this.propName]=e[this.propName]}}valueIsTransformableForInstance(t){return!(t[this.propName]instanceof qe)}}const Xe=new Ge("fillStyle"),Ye=new Ge("strokeStyle");class _n{constructor(t){this.viewBox=t}set fillStyle(t){this.viewBox.changeState(e=>Xe.changeInstanceValue(e,t))}set strokeStyle(t){this.viewBox.changeState(e=>Ye.changeInstanceValue(e,t))}createLinearGradient(t,e,n,i){return this.viewBox.createLinearGradient(t,e,n,i)}createPattern(t,e){return this.viewBox.createPattern(t,e)}createRadialGradient(t,e,n,i,s,o){return this.viewBox.createRadialGradient(t,e,n,i,s,o)}createConicGradient(t,e,n){return this.viewBox.createConicGradient(t,e,n)}}class ti extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.shadowColor=t}}}const Ue=new ti("shadowColor",T);class ei extends I{changeToNewValue(t){return(e,n)=>{const i=v.translation(t.x,t.y),s=n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i),{x:o,y:a}=s.apply(h.origin);e.shadowOffsetX=o,e.shadowOffsetY=a}}valuesAreEqual(t,e){return t.x===e.x&&t.y==e.y}}const re=new ei("shadowOffset",T);class ni extends I{changeToNewValue(t){return(e,n)=>{const i=v.translation(t,0),o=n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i).apply(h.origin).mod();e.shadowBlur=o}}valuesAreEqual(t,e){return t===e}}const ze=new ni("shadowBlur",T);class ii{constructor(t){this.viewBox=t}get shadowBlur(){return this.viewBox.state.current.shadowBlur}set shadowBlur(t){this.viewBox.changeState(e=>ze.changeInstanceValue(e,t))}get shadowOffsetX(){return this.viewBox.state.current.shadowOffset.x}set shadowOffsetX(t){const e=new h(t,this.viewBox.state.current.shadowOffset.y);this.viewBox.changeState(n=>re.changeInstanceValue(n,e))}get shadowOffsetY(){return this.viewBox.state.current.shadowOffset.y}set shadowOffsetY(t){const e=new h(this.viewBox.state.current.shadowOffset.x,t);this.viewBox.changeState(n=>re.changeInstanceValue(n,e))}get shadowColor(){return this.viewBox.state.current.shadowColor}set shadowColor(t){this.viewBox.changeState(e=>Ue.changeInstanceValue(e,t))}}const $e="[+-]?(?:\\d*\\.)?\\d+(?:e[+-]?\\d+)?",Ke="[+-]?(?:0*\\.)?0+(?:e[+-]?\\d+)?",je="(?:ch|em|ex|ic|rem|vh|vw|vmax|vmin|vb|vi|cqw|cqh|cqi|cqb|cqmin|cqmax|px|cm|mm|Q|in|pc|pt)",Wt=`(?:${Ke}|${$e}${je})`,Qe=`blur\\((${Wt})\\)`,Je="[^())\\s]+(?:\\([^)]*?\\))?",Ze=`drop-shadow\\((${Wt})\\s+(${Wt})\\s*?(?:(?:(${Wt})\\s*?(${Je})?)|(${Je}))?\\)`,_e=`${Qe}|${Ze}`;function D(r,t){const e=r.match(new RegExp(`(?:(${Ke})|(${$e})(${je}))`));return e[1]?0:t.getNumberOfPixels(Number.parseFloat(e[2]),e[3])}class tn{constructor(t){this.stringRepresentation=t}toTransformedString(){return this.stringRepresentation}getShadowOffset(){return null}}class oe{constructor(t,e){this.stringRepresentation=t,this.size=e}toTransformedString(t){return`blur(${t.translateInfiniteCanvasContextTransformationToBitmapTransformation(v.translation(this.size,0)).apply(h.origin).mod()}px)`}getShadowOffset(){return null}static tryCreate(t,e){const n=t.match(new RegExp(Qe));return n===null?null:new oe(t,D(n[1],e))}}class at{constructor(t,e,n,i,s){this.stringRepresentation=t,this.offsetX=e,this.offsetY=n,this.blurRadius=i,this.color=s}toTransformedString(t){const e=t.translateInfiniteCanvasContextTransformationToBitmapTransformation(v.translation(this.offsetX,this.offsetY)),{x:n,y:i}=e.apply(h.origin);if(this.blurRadius!==null){const o=t.translateInfiniteCanvasContextTransformationToBitmapTransformation(v.translation(this.blurRadius,0)).apply(h.origin).mod();return this.color?`drop-shadow(${n}px ${i}px ${o}px ${this.color})`:`drop-shadow(${n}px ${i}px ${o}px)`}return this.color?`drop-shadow(${n}px ${i}px ${this.color})`:`drop-shadow(${n}px ${i}px)`}getShadowOffset(){return new h(this.offsetX,this.offsetY)}static tryCreate(t,e){const n=t.match(new RegExp(Ze));return n===null?null:n[5]?new at(t,D(n[1],e),D(n[2],e),null,n[5]):n[4]?new at(t,D(n[1],e),D(n[2],e),D(n[3],e),n[4]):n[3]?new at(t,D(n[1],e),D(n[2],e),D(n[3],e),null):new at(t,D(n[1],e),D(n[2],e),null,null)}}const ae=class Xn{constructor(t,e){this.stringRepresentation=t,this.parts=e}toString(){return this.parts.map(t=>t.stringRepresentation).join(" ")}toTransformedString(t){return this.parts.map(e=>e.toTransformedString(t)).join(" ")}getShadowOffset(){for(const t of this.parts){const e=t.getShadowOffset();if(e!==null)return e}return null}static create(t,e){const i=t.match(new RegExp(`${_e}|((?!\\s|${_e}).)+`,"g")).map(s=>this.createPart(s,e));return new Xn(t,i)}static createPart(t,e){let n=oe.tryCreate(t,e);return n!==null||(n=at.tryCreate(t,e),n!=null)?n:new tn(t)}};ae.none=new ae("none",[new tn("none")]);let en=ae;class si extends I{valuesAreEqual(t,e){return t.stringRepresentation===e.stringRepresentation}changeToNewValue(t){return(e,n)=>e.filter=t.toTransformedString(n)}}const nn=new si("filter",T);class ri{constructor(t,e){this.viewBox=t,this.cssLengthConverterFactory=e}get filter(){return this.viewBox.state.current.filter.stringRepresentation}set filter(t){const e=en.create(t,this.cssLengthConverterFactory.create());this.viewBox.changeState(n=>nn.changeInstanceValue(n,e))}}class oi{constructor(t){this.viewBox=t}clearRect(t,e,n,i){this.viewBox.clearArea(t,e,n,i)}fillRect(t,e,n,i){let s=o=>o.fill();this.viewBox.fillRect(t,e,n,i,s)}strokeRect(t,e,n,i){this.viewBox.strokeRect(t,e,n,i)}}class ai{constructor(t){this.viewBox=t}isFillRule(t){return t==="evenodd"||t==="nonzero"}beginPath(){this.viewBox.beginPath()}clip(t,e){let n=this.isFillRule(t)?i=>{i.clip(t)}:i=>{i.clip()};this.viewBox.clipPath(n)}fill(t,e){if((!t||this.isFillRule(t))&&!this.viewBox.currentPathCanBeFilled())return;let n=this.isFillRule(t)?i=>{i.fill(t)}:i=>{i.fill()};this.viewBox.fillPath(n)}isPointInPath(t,e,n,i){return!0}isPointInStroke(t,e,n){return!0}stroke(t){this.viewBox.strokePath()}}class ci{drawFocusIfNeeded(t,e){}scrollPathIntoView(t){}}var F=(r=>(r[r.None=0]="None",r[r.Relative=1]="Relative",r[r.Absolute=2]="Absolute",r))(F||{});function hi(r,t,e,n){const i=e.minus(r),s=n.cross(t),o=n.getPerpendicular().dot(i)/s;return r.plus(t.scale(o))}class J{constructor(t,e,n){this.point=t,this.leftHalfPlane=e,this.rightHalfPlane=n,this.leftNormal=e.normalTowardInterior,this.rightNormal=n.normalTowardInterior}replaceLeftHalfPlane(t){return new J(this.point,t,this.rightHalfPlane)}replaceRightHalfPlane(t){return new J(this.point,this.leftHalfPlane,t)}isContainedByHalfPlaneWithNormal(t){return t.isInSmallerAngleBetweenPoints(this.leftNormal,this.rightNormal)}containsPoint(t){return this.leftHalfPlane.containsPoint(t)&&this.rightHalfPlane.containsPoint(t)}containsLineSegmentWithDirection(t){return this.containsPoint(this.point.plus(t))||this.containsPoint(this.point.minus(t))}isContainedByVertex(t){return this.isContainedByHalfPlaneWithNormal(t.leftNormal)&&this.isContainedByHalfPlaneWithNormal(t.rightNormal)}getContainingHalfPlaneThroughPoint(t){let e=t.minus(this.point).getPerpendicular();if(e.cross(this.leftHalfPlane.normalTowardInterior)===0)return this.leftHalfPlane;if(e.cross(this.rightHalfPlane.normalTowardInterior)===0)return this.rightHalfPlane;const n=this.leftNormal.plus(this.rightNormal);return e.dot(n)<=0&&(e=e.scale(-1)),new p(t,e)}static create(t,e,n){return e.normalTowardInterior.cross(n.normalTowardInterior)>=0?new J(t,e,n):new J(t,n,e)}}class p{constructor(t,e){this.base=t,this.normalTowardInterior=e,this.lengthOfNormal=e.mod()}getDistanceFromEdge(t){return t.minus(this.base).dot(this.normalTowardInterior)/this.lengthOfNormal}transform(t){const e=t.apply(this.base),n=t.apply(this.base.plus(this.normalTowardInterior.getPerpendicular())),i=t.apply(this.base.plus(this.normalTowardInterior));return p.throughPointsAndContainingPoint(e,n,i)}complement(){return new p(this.base,this.normalTowardInterior.scale(-1))}expandByDistance(t){const e=this.base.plus(this.normalTowardInterior.scale(-t/this.normalTowardInterior.mod()));return new p(e,this.normalTowardInterior)}expandToIncludePoint(t){return this.containsPoint(t)?this:new p(t,this.normalTowardInterior)}containsPoint(t){return this.getDistanceFromEdge(t)>=0}interiorContainsPoint(t){return this.getDistanceFromEdge(t)>0}containsInfinityInDirection(t){return t.dot(this.normalTowardInterior)>=0}isContainedByHalfPlane(t){return this.normalTowardInterior.inSameDirectionAs(t.normalTowardInterior)&&t.getDistanceFromEdge(this.base)>=0}intersectWithLine(t,e){return{point:hi(this.base,this.normalTowardInterior.getPerpendicular(),t,e),halfPlane:this}}isParallelToLine(t,e){return this.normalTowardInterior.getPerpendicular().cross(e)===0}getIntersectionWith(t){const e=this.intersectWithLine(t.base,t.normalTowardInterior.getPerpendicular());return J.create(e.point,this,t)}static throughPointsAndContainingPoint(t,e,n){const i=p.withBorderPoints(t,e);for(let s of i)if(s.containsPoint(n))return s}static withBorderPointAndInfinityInDirection(t,e){return p.withBorderPoints(t,t.plus(e))}static withBorderPoints(t,e){const n=e.minus(t).getPerpendicular();return[new p(t,n),new p(t,n.scale(-1))]}}class li{getVertices(){return[]}expandToIncludePoint(t){return this}expandToIncludePolygon(t){return this}expandToIncludeInfinityInDirection(t){return this}expandByDistance(t){return this}intersects(t){return!0}expandToInclude(t){return this}transform(t){return this}intersectWithLineSegment(t){return t}contains(t){return!0}intersectWith(t){return t}join(t){return this}intersectWithRay(t){return t}intersectWithLine(t){return t}intersectWithConvexPolygon(t){return t}isContainedByRay(t){return!1}isContainedByLineSegment(t){return!1}isContainedByLine(t){return!1}isContainedByConvexPolygon(t){return!1}intersectsRay(t){return!0}intersectsLineSegment(t){return!0}intersectsLine(t){return!0}intersectsConvexPolygon(t){return!0}}const pt=new li;class ui{getVertices(){return[]}intersectWith(t){return this}join(t){return t}intersectWithConvexPolygon(t){return this}intersects(t){return!1}intersectWithLineSegment(t){return this}intersectWithRay(t){return this}intersectWithLine(t){return this}expandToInclude(t){return t}transform(t){return this}contains(t){return!1}isContainedByConvexPolygon(t){return!0}isContainedByRay(t){return!0}isContainedByLineSegment(t){return!0}isContainedByLine(t){return!0}intersectsRay(t){return!1}intersectsConvexPolygon(t){return!1}intersectsLineSegment(t){return!1}intersectsLine(t){return!1}expandByDistance(t){return this}expandToIncludePoint(t){return this}expandToIncludeInfinityInDirection(t){return this}expandToIncludePolygon(t){return t}}const y=new ui;class m{constructor(t,e){this.vertices=e,this.halfPlanes=t,this.vertices=this.vertices||m.getVertices(this.halfPlanes)}findVertex(t){for(let e of this.vertices)if(e.point.equals(t))return e}intersects(t){return t.intersectsConvexPolygon(this)}intersectWith(t){return t.intersectWithConvexPolygon(this)}join(t){if(this.contains(t))return this;if(t.contains(this))return t;let e=t;for(let n of this.vertices)e=e.expandToIncludePoint(n.point);for(let n of this.getPointsAtInfinityFromHalfPlanes())this.containsInfinityInDirection(n)&&(e=e.expandToIncludeInfinityInDirection(n));return e}intersectWithRay(t){return t.intersectWithConvexPolygon(this)}intersectWithLine(t){return t.intersectWithConvexPolygon(this)}intersectWithLineSegment(t){return t.intersectWithConvexPolygon(this)}contains(t){return t.isContainedByConvexPolygon(this)}containsHalfPlane(t){for(let e of this.halfPlanes)if(!t.isContainedByHalfPlane(e))return!1;return!0}isContainedByHalfPlane(t){for(let n of this.vertices)if(!t.containsPoint(n.point))return!1;const e=t.complement();for(let n of this.halfPlanes)if(n.isContainedByHalfPlane(t))return!0;for(let n of this.halfPlanes){const i=this.getVerticesOnHalfPlane(n);if(i.length<=1&&(n.isContainedByHalfPlane(e)||e.isContainedByHalfPlane(n)))return!1;const s=n.getIntersectionWith(t),o=i.find(a=>a.point.equals(s.point));if(o){if(!o.isContainedByHalfPlaneWithNormal(t.normalTowardInterior))return!1}else{if(i.length===0)return!1;if(this.containsPoint(s.point))return!1}}return!this.containsHalfPlane(t)}getVertices(){return this.vertices.map(t=>t.point)}expandToIncludePoint(t){if(this.vertices.length===0){const d=this.halfPlanes.map(u=>u.expandToIncludePoint(t));return new m(d)}const e=new Set,n=new Set;let i=null,s=null;const o=[],a=new Set;for(const d of this.vertices){const u=d.leftHalfPlane;n.has(u)?n.delete(u):e.add(u);const g=d.rightHalfPlane;if(e.has(g)?e.delete(g):n.add(g),u.containsPoint(t)){if(a.add(u),g.containsPoint(t)){a.add(g),o.push(d);continue}i=d;continue}g.containsPoint(t)&&(a.add(g),s=d)}if(o.length===this.vertices.length)return this;let c,l;if(i===null){const d=[...e][0];if(!d)return this;c=d.expandToIncludePoint(t)}else c=i.getContainingHalfPlaneThroughPoint(t),c!==i.leftHalfPlane&&o.push(i.replaceRightHalfPlane(c));if(s===null){const d=[...n][0];if(!d)return this;l=d.expandToIncludePoint(t)}else l=s.getContainingHalfPlaneThroughPoint(t),l!==s.rightHalfPlane&&o.push(s.replaceLeftHalfPlane(l));return a.add(c),a.add(l),o.push(new J(t,c,l)),new m([...a],o)}expandToIncludeInfinityInDirection(t){if(this.containsInfinityInDirection(t))return this;let e=this.halfPlanes.filter(n=>n.containsInfinityInDirection(t)).concat(this.getTangentPlanesThroughInfinityInDirection(t));return e=m.getHalfPlanesNotContainingAnyOther(e),e.length===0?pt:new m(e)}getIntersectionsWithLine(t,e){const n=[];for(let i of this.halfPlanes){if(i.isParallelToLine(t,e))continue;const s=i.intersectWithLine(t,e),o=this.findVertex(s.point);o&&!o.containsLineSegmentWithDirection(e)||this.containsPoint(s.point)&&n.push(s)}return n}expandByDistance(t){return new m(this.halfPlanes.map(e=>e.expandByDistance(t)))}transform(t){return new m(this.halfPlanes.map(e=>e.transform(t)))}intersectWithConvexPolygon(t){if(t.isContainedByConvexPolygon(this))return t;if(this.isContainedByConvexPolygon(t))return this;if(this.isOutsideConvexPolygon(t))return y;const e=m.getHalfPlanesNotContainingAnyOther(this.halfPlanes.concat(t.halfPlanes)),s=m.groupVerticesByPoint(m.getVertices(e)).map(a=>m.getVerticesNotContainingAnyOther(a)).reduce((a,c)=>a.concat(c),[]);if(s.length===0)return new m(e);const o=m.getHalfPlanes(s);return new m(o)}containsInfinityInDirection(t){for(let e of this.halfPlanes)if(!e.containsInfinityInDirection(t))return!1;return!0}containsPoint(t){for(let e of this.halfPlanes)if(!e.containsPoint(t))return!1;return!0}intersectsRay(t){return t.intersectsConvexPolygon(this)}intersectsLineSegment(t){return t.intersectsConvexPolygon(this)}intersectsLine(t){return t.intersectsConvexPolygon(this)}intersectsConvexPolygon(t){return this.isContainedByConvexPolygon(t)||t.isContainedByConvexPolygon(this)?!0:!this.isOutsideConvexPolygon(t)}isOutsideConvexPolygon(t){for(let e of t.halfPlanes)if(this.isContainedByHalfPlane(e.complement()))return!0;for(let e of this.halfPlanes)if(t.isContainedByHalfPlane(e.complement()))return!0;return!1}getVerticesOnHalfPlane(t){const e=[];for(let n of this.vertices)(n.leftHalfPlane===t||n.rightHalfPlane===t)&&e.push(n);return e}hasAtMostOneVertex(t){let e=0;for(let n of this.vertices)if((n.leftHalfPlane===t||n.rightHalfPlane===t)&&(e++,e>1))return!1;return!0}getTangentPlanesThroughInfinityInDirection(t){const e=[];for(let n of this.vertices){const i=p.withBorderPointAndInfinityInDirection(n.point,t);for(let s of i)this.isContainedByHalfPlane(s)&&e.push(s)}return e}getPointsAtInfinityFromHalfPlanes(){const t=[];for(let e of this.halfPlanes){const n=e.normalTowardInterior,i=n.getPerpendicular();t.push(n),t.push(i),t.push(i.scale(-1))}return t}isContainedByRay(t){return!1}isContainedByLineSegment(t){return!1}isContainedByLine(t){return!1}isContainedByConvexPolygon(t){for(let e of t.halfPlanes)if(!this.isContainedByHalfPlane(e))return!1;return!0}static getHalfPlanes(t){const e=[];for(let n of t)e.indexOf(n.leftHalfPlane)===-1&&e.push(n.leftHalfPlane),e.indexOf(n.rightHalfPlane)===-1&&e.push(n.rightHalfPlane);return e}static getVerticesNotContainingAnyOther(t){const e=[];for(let n=0;n0?new h(1,0):new h(-1,0))),Number.isFinite(n)&&s.push(new p(new h(t+n,0),n>0?new h(-1,0):new h(1,0)))),Number.isFinite(e)&&(s.push(new p(new h(0,e),i>0?new h(0,1):new h(0,-1))),Number.isFinite(i)&&s.push(new p(new h(0,e+i),i>0?new h(0,-1):new h(0,1)))),new m(s)}}class di{constructor(t){this.viewBox=t}fillText(t,e,n,i){let s=i===void 0?o=>{o.fillText(t,e,n)}:o=>{o.fillText(t,e,n,i)};this.viewBox.addDrawing(s,this.getDrawnRectangle(e,n,t),F.Relative,!0)}measureText(t){return this.viewBox.measureText(t)}strokeText(t,e,n,i){let s=i===void 0?o=>{o.strokeText(t,e,n)}:o=>{o.strokeText(t,e,n,i)};this.viewBox.addDrawing(s,this.getDrawnRectangle(e,n,t),F.Relative,!0)}getDrawnRectangle(t,e,n){const i=this.viewBox.measureText(n);let s;i.actualBoundingBoxRight!==void 0?s=Math.abs(i.actualBoundingBoxRight-i.actualBoundingBoxLeft):s=i.width;const o=i.actualBoundingBoxAscent!==void 0?i.actualBoundingBoxAscent+i.actualBoundingBoxDescent:1,a=i.actualBoundingBoxAscent!==void 0?i.actualBoundingBoxAscent:0;return m.createRectangle(t,e-a,s,o)}}class fi{constructor(t){this.viewBox=t}drawImage(){const t=Array.prototype.slice.apply(arguments);let e,n,i,s,o,a,c,l,d;arguments.length<=5?[e,a,c,l,d]=t:[e,n,i,s,o,a,c,l,d]=t;const u=this.getDrawnLength(e.width,n,s,l),g=this.getDrawnLength(e.height,i,o,d),w=m.createRectangle(a,c,u,g),P=this.getDrawImageInstruction(arguments.length,e,n,i,s,o,a,c,l,d);this.viewBox.addDrawing(P,w,F.Relative,!0)}getDrawImageInstruction(t,e,n,i,s,o,a,c,l,d){switch(t){case 3:return u=>{u.drawImage(e,a,c)};case 5:return u=>{u.drawImage(e,a,c,l,d)};case 9:return u=>{u.drawImage(e,n,i,s,o,a,c,l,d)};default:throw new TypeError(`Failed to execute 'drawImage' on 'CanvasRenderingContext2D': Valid arities are: [3, 5, 9], but ${t} arguments provided.`)}}getDrawnLength(t,e,n,i){const s=this.getLength(t);return i!==void 0?i:e!==void 0?n!==void 0?n:s-e:s}getLength(t){return typeof t=="number"?t:t.baseVal.value}}function gi(r,t,e,n,i){t=t===void 0?0:t,e=e===void 0?0:e,n=n===void 0?r.width:n,i=i===void 0?r.height:i;const s=r.data,o=new Uint8ClampedArray(4*n*i);for(let a=0;a{this.latestClippedPath.execute(e,n)};if(this.previouslyClippedPaths){const e=this.previouslyClippedPaths.getInstructionToRecreate(),n=this.previouslyClippedPaths.latestClippedPath.state.getInstructionToConvertToState(this.latestClippedPath.initialState);return(i,s)=>{e(i,s),n(i,s),t(i,s)}}return t}}class mi extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.direction=t}}}const ce=new mi("direction",T);class vi extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.font=t}}}const he=new vi("font",T);class sn{constructor(t){this.propertyName=t}changeInstanceValue(t,e){return this.valuesAreEqual(t[this.propertyName],e)?t:t.changeProperty(this.propertyName,e)}isEqualForInstances(t,e){return this.valuesAreEqual(t[this.propertyName],e[this.propertyName])}valueIsTransformableForInstance(t){return!0}changeToNewValue(t,e){return e?this.changeToNewValueTransformed(t):this.changeToNewValueUntransformed(t)}getInstructionToChange(t,e){const n=t[this.propertyName],i=e[this.propertyName];return this.valuesAreEqual(n,i)&&(t.fillAndStrokeStylesTransformed===e.fillAndStrokeStylesTransformed||this.valuesAreEqualWhenTransformed(n,i))?()=>{}:this.changeToNewValue(i,e.fillAndStrokeStylesTransformed)}}class rn extends sn{constructor(t){super(t)}valuesAreEqual(t,e){return t===e}changeToNewValueTransformed(t){return(e,n)=>{const i=n.userTransformation;e[this.propertyName]=t*i.scale}}changeToNewValueUntransformed(t){return e=>{e[this.propertyName]=t}}valuesAreEqualWhenTransformed(t,e){return t===0&&e===0}}const on=new rn("lineWidth"),an=new rn("lineDashOffset");class pi extends sn{valuesAreEqual(t,e){if(t.length!==e.length)return!1;for(let n=0;n{const i=n.userTransformation;e.setLineDash(t.map(s=>s*i.scale))}}changeToNewValueUntransformed(t){return e=>{e.setLineDash(t)}}valuesAreEqualWhenTransformed(t,e){return t.length===0&&e.length===0}}const cn=new pi("lineDash");class wi extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.textAlign=t}}}const le=new wi("textAlign",T);class Pi extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.textBaseline=t}}}const ue=new Pi("textBaseline",T);class Ci extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.lineCap=t}}const hn=new Ci("lineCap",T);class Ii extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.lineJoin=t}}const ln=new Ii("lineJoin",T);class Ti extends I{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.miterLimit=t}}const un=new Ti("miterLimit",T),de=[ce,Ve,He,Xe,an,cn,hn,ln,un,Ne,Me,nn,on,Ye,le,ue,Et,he,re,ze,Ue],Si=[he,le,ue,ce];function k(...r){return(...t)=>{for(const e of r)e&&e(...t)}}function yi(r,t){return t?(e,n)=>{e.save(),t(e,n),r(e,n),e.restore()}:r}function bi(r){return r===F.Relative?(t,e)=>{const{a:n,b:i,c:s,d:o,e:a,f:c}=e.getBitmapTransformationToTransformedInfiniteCanvasContext();t.transform(n,i,s,o,a,c)}:r===F.Absolute?(t,e)=>{const{a:n,b:i,c:s,d:o,e:a,f:c}=e.getBitmapTransformationToInfiniteCanvasContext();t.setTransform(n,i,s,o,a,c)}:null}const Rt=class Yn{constructor(t){this.fillStyle=t.fillStyle,this.lineWidth=t.lineWidth,this.lineCap=t.lineCap,this.lineJoin=t.lineJoin,this.lineDash=t.lineDash,this.miterLimit=t.miterLimit,this.globalAlpha=t.globalAlpha,this.globalCompositeOperation=t.globalCompositeOperation,this.filter=t.filter,this.strokeStyle=t.strokeStyle,this.lineDashOffset=t.lineDashOffset,this.transformation=t.transformation,this.direction=t.direction,this.imageSmoothingEnabled=t.imageSmoothingEnabled,this.imageSmoothingQuality=t.imageSmoothingQuality,this.font=t.font,this.textAlign=t.textAlign,this.textBaseline=t.textBaseline,this.clippedPaths=t.clippedPaths,this.fillAndStrokeStylesTransformed=t.fillAndStrokeStylesTransformed,this.shadowOffset=t.shadowOffset,this.shadowColor=t.shadowColor,this.shadowBlur=t.shadowBlur}changeProperty(t,e){const{fillStyle:n,lineWidth:i,lineDash:s,lineCap:o,lineJoin:a,miterLimit:c,globalAlpha:l,globalCompositeOperation:d,filter:u,strokeStyle:g,lineDashOffset:w,transformation:P,direction:O,imageSmoothingEnabled:H,imageSmoothingQuality:K,font:rt,textAlign:Bt,textBaseline:At,clippedPaths:Dt,fillAndStrokeStylesTransformed:Lt,shadowOffset:Fe,shadowColor:We,shadowBlur:ke}=this,ie={fillStyle:n,lineWidth:i,lineDash:s,lineCap:o,lineJoin:a,miterLimit:c,globalAlpha:l,globalCompositeOperation:d,filter:u,strokeStyle:g,lineDashOffset:w,transformation:P,direction:O,imageSmoothingEnabled:H,imageSmoothingQuality:K,font:rt,textAlign:Bt,textBaseline:At,clippedPaths:Dt,fillAndStrokeStylesTransformed:Lt,shadowOffset:Fe,shadowColor:We,shadowBlur:ke};return ie[t]=e,new Yn(ie)}get clippingRegion(){return this.clippedPaths?this.clippedPaths.area:void 0}equals(t){for(let e of de)if(!e.isEqualForInstances(this,t))return!1;return(!this.clippedPaths&&!t.clippedPaths||this.clippedPaths&&this.clippedPaths===t.clippedPaths)&&this.fillAndStrokeStylesTransformed===t.fillAndStrokeStylesTransformed}getMaximumLineWidth(){return this.lineWidth*this.transformation.getMaximumLineWidthScale()}getLineDashPeriod(){return this.lineDash.reduce((t,e)=>t+e,0)}isTransformable(){for(let t of de)if(!t.valueIsTransformableForInstance(this))return!1;return!0}getShadowOffsets(){const t=[],e=this.filter.getShadowOffset();return e!==null&&t.push(e),this.shadowOffset.equals(h.origin)||t.push(this.shadowOffset),t}getInstructionToConvertToState(t){return this.getInstructionToConvertToStateOnDimensions(t,de)}withClippedPath(t){const e=this.clippedPaths?this.clippedPaths.withClippedPath(t):new kt(t.area,t);return this.changeProperty("clippedPaths",e)}getInstructionToConvertToStateOnDimensions(t,e){const n=e.map(i=>i.getInstructionToChange(this,t));return k(...n)}};Rt.default=new Rt({fillStyle:"#000",lineWidth:1,lineDash:[],lineCap:"butt",lineJoin:"miter",miterLimit:10,globalAlpha:1,globalCompositeOperation:"source-over",filter:en.none,strokeStyle:"#000",lineDashOffset:0,transformation:v.identity,direction:"inherit",imageSmoothingEnabled:!0,imageSmoothingQuality:"low",font:"10px sans-serif",textAlign:"start",textBaseline:"alphabetic",clippedPaths:void 0,fillAndStrokeStylesTransformed:!1,shadowOffset:h.origin,shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0}),Rt.setDefault=()=>{};let R=Rt;class xi{constructor(t){this.viewBox=t}createImageData(t,e){}getImageData(t,e,n,i){}putImageData(t,e,n,i,s,o,a){t=gi(t,i,s,o,a);let c,l=this.viewBox.getDrawingLock();this.viewBox.createPatternFromImageData(t).then(u=>{c=u,l.release()}),this.viewBox.addDrawing(u=>{u.translate(e,n),u.fillStyle=c,u.fillRect(0,0,t.width,t.height)},m.createRectangle(e,n,t.width,t.height),F.Absolute,!1,u=>u.changeProperty("shadowColor",R.default.shadowColor).changeProperty("shadowOffset",R.default.shadowOffset).changeProperty("shadowBlur",R.default.shadowBlur).changeProperty("globalAlpha",R.default.globalAlpha).changeProperty("globalCompositeOperation",R.default.globalCompositeOperation).changeProperty("imageSmoothingEnabled",!1).changeProperty("filter",R.default.filter))}}class Oi{constructor(t){this.viewBox=t}get lineCap(){return this.viewBox.state.current.lineCap}set lineCap(t){this.viewBox.changeState(e=>hn.changeInstanceValue(e,t))}get lineDashOffset(){return this.viewBox.state.current.lineDashOffset}set lineDashOffset(t){this.viewBox.changeState(e=>an.changeInstanceValue(e,t))}get lineJoin(){return this.viewBox.state.current.lineJoin}set lineJoin(t){this.viewBox.changeState(e=>ln.changeInstanceValue(e,t))}get lineWidth(){return this.viewBox.state.current.lineWidth}set lineWidth(t){this.viewBox.changeState(e=>on.changeInstanceValue(e,t))}get miterLimit(){return this.viewBox.state.current.miterLimit}set miterLimit(t){this.viewBox.changeState(e=>un.changeInstanceValue(e,t))}getLineDash(){return this.viewBox.state.current.lineDash}setLineDash(t){t.length%2===1&&(t=t.concat(t)),this.viewBox.changeState(e=>cn.changeInstanceValue(e,t))}}class Bi{constructor(t){this.viewBox=t}set direction(t){this.viewBox.changeState(e=>ce.changeInstanceValue(e,t))}set font(t){this.viewBox.changeState(e=>he.changeInstanceValue(e,t))}set textAlign(t){this.viewBox.changeState(e=>le.changeInstanceValue(e,t))}set textBaseline(t){this.viewBox.changeState(e=>ue.changeInstanceValue(e,t))}}function C(r){return r.direction!==void 0}class wt{static arc(t,e,n,i,s,o){return{instruction:(l,d)=>{const u=d.userTransformation,g=u.getRotationAngle(),{x:w,y:P}=u.apply(new h(t,e));l.arc(w,P,n*u.scale,i+g,s+g,o)},changeArea:l=>{l.addPosition(new h(t-n,e-n)),l.addPosition(new h(t-n,e+n)),l.addPosition(new h(t+n,e-n)),l.addPosition(new h(t+n,e+n))},positionChange:new h(t,e).plus(v.rotation(0,0,s).apply(new h(n,0))),initialPoint:new h(t,e).plus(v.rotation(0,0,i).apply(new h(n,0)))}}static arcTo(t,e,n,i,s){const o=new h(t,e),a=new h(n,i);return{instruction:(d,u)=>{const g=u.userTransformation,w=g.apply(o),P=g.apply(a);d.arcTo(w.x,w.y,P.x,P.y,s*g.scale)},changeArea:d=>{d.addPosition(o),d.addPosition(a)},positionChange:new h(n,i)}}static ellipse(t,e,n,i,s,o,a,c){return{instruction:(l,d)=>{const u=d.userTransformation,g=u.apply(new h(t,e)),w=u.getRotationAngle();l.ellipse(g.x,g.y,n*u.scale,i*u.scale,s+w,o,a,c)},changeArea:l=>{l.addPosition(new h(t-n,e-i)),l.addPosition(new h(t-n,e+i)),l.addPosition(new h(t+n,e-i)),l.addPosition(new h(t+n,e+i))},positionChange:new h(t,e).plus(v.rotation(0,0,a).before(new v(n,0,0,i,0,0)).before(v.rotation(0,0,s)).apply(new h(1,0))),initialPoint:new h(t,e).plus(v.rotation(0,0,o).before(new v(n,0,0,i,0,0)).before(v.rotation(0,0,s)).apply(new h(1,0)))}}static bezierCurveTo(t,e,n,i,s,o){return{instruction:(a,c)=>{const l=c.userTransformation,d=l.apply(new h(t,e)),u=l.apply(new h(n,i)),g=l.apply(new h(s,o));a.bezierCurveTo(d.x,d.y,u.x,u.y,g.x,g.y)},changeArea:(a,c)=>{C(c)||(a.addPosition(new h((c.x+t)/2,(c.y+e)/2)),a.addPosition(new h((t+n)/2,(e+i)/2)),a.addPosition(new h((n+s)/2,(i+o)/2)),a.addPosition(new h(s,o)))},positionChange:new h(s,o)}}static quadraticCurveTo(t,e,n,i){return{instruction:(s,o)=>{const a=o.userTransformation,c=a.apply(new h(t,e)),l=a.apply(new h(n,i));s.quadraticCurveTo(c.x,c.y,l.x,l.y)},changeArea:(s,o)=>{C(o)||(s.addPosition(new h((o.x+t)/2,(o.y+e)/2)),s.addPosition(new h((t+n)/2,(e+i)/2)),s.addPosition(new h(n,i)))},positionChange:new h(n,i)}}}class Ai{constructor(t){this.viewBox=t}arc(t,e,n,i,s,o){this.viewBox.addPathInstruction(wt.arc(t,e,n,i,s,o))}arcTo(t,e,n,i,s){this.viewBox.addPathInstruction(wt.arcTo(t,e,n,i,s))}closePath(){this.viewBox.closePath()}ellipse(t,e,n,i,s,o,a,c){this.viewBox.addPathInstruction(wt.ellipse(t,e,n,i,s,o,a,c))}lineTo(t,e){this.viewBox.lineTo(new h(t,e))}lineToInfinityInDirection(t,e){this.viewBox.lineTo({direction:new h(t,e)})}moveTo(t,e){this.viewBox.moveTo(new h(t,e))}moveToInfinityInDirection(t,e){this.viewBox.moveTo({direction:new h(t,e)})}quadraticCurveTo(t,e,n,i){this.viewBox.addPathInstruction(wt.quadraticCurveTo(t,e,n,i))}bezierCurveTo(t,e,n,i,s,o){this.viewBox.addPathInstruction(wt.bezierCurveTo(t,e,n,i,s,o))}rect(t,e,n,i){this.viewBox.rect(t,e,n,i)}}class Di{constructor(t,e,n){this.canvas=t,this.canvasState=new vt(e),this.canvasTransform=new zn(e),this.canvasCompositing=new jn(e),this.canvasImageSmoothing=new Zn(e),this.canvasStrokeStyles=new _n(e),this.canvasShadowStyles=new ii(e),this.canvasFilters=new ri(e,n),this.canvasRect=new oi(e),this.canvasDrawPath=new ai(e),this.canvasUserInterface=new ci,this.canvasText=new di(e),this.canvasDrawImage=new fi(e),this.canvasImageData=new xi(e),this.canvasPathDrawingStyles=new Oi(e),this.canvasTextDrawingStyles=new Bi(e),this.canvasPath=new Ai(e)}getContextAttributes(){return this.canvas.getContext("2d").getContextAttributes()}save(){this.canvasState.save()}restore(){this.canvasState.restore()}getTransform(){return this.canvasTransform.getTransform()}resetTransform(){this.canvasTransform.resetTransform()}rotate(t){this.canvasTransform.rotate(t)}scale(t,e){this.canvasTransform.scale(t,e)}setTransform(t,e,n,i,s,o){this.canvasTransform.setTransform(t,e,n,i,s,o)}transform(t,e,n,i,s,o){this.canvasTransform.transform(t,e,n,i,s,o)}translate(t,e){this.canvasTransform.translate(t,e)}set globalAlpha(t){this.canvasCompositing.globalAlpha=t}set globalCompositeOperation(t){this.canvasCompositing.globalCompositeOperation=t}set imageSmoothingEnabled(t){this.canvasImageSmoothing.imageSmoothingEnabled=t}set imageSmoothingQuality(t){this.canvasImageSmoothing.imageSmoothingQuality=t}set fillStyle(t){this.canvasStrokeStyles.fillStyle=t}set strokeStyle(t){this.canvasStrokeStyles.strokeStyle=t}createLinearGradient(t,e,n,i){return this.canvasStrokeStyles.createLinearGradient(t,e,n,i)}createPattern(t,e){return this.canvasStrokeStyles.createPattern(t,e)}createRadialGradient(t,e,n,i,s,o){return this.canvasStrokeStyles.createRadialGradient(t,e,n,i,s,o)}createConicGradient(t,e,n){return this.canvasStrokeStyles.createConicGradient(t,e,n)}set shadowBlur(t){this.canvasShadowStyles.shadowBlur=t}set shadowColor(t){this.canvasShadowStyles.shadowColor=t}set shadowOffsetX(t){this.canvasShadowStyles.shadowOffsetX=t}set shadowOffsetY(t){this.canvasShadowStyles.shadowOffsetY=t}set filter(t){this.canvasFilters.filter=t}clearRect(t,e,n,i){this.canvasRect.clearRect(t,e,n,i)}fillRect(t,e,n,i){this.canvasRect.fillRect(t,e,n,i)}strokeRect(t,e,n,i){this.canvasRect.strokeRect(t,e,n,i)}beginPath(){this.canvasDrawPath.beginPath()}clip(t,e){this.canvasDrawPath.clip(t,e)}fill(t,e){this.canvasDrawPath.fill(t,e)}isPointInPath(t,e,n,i){return this.canvasDrawPath.isPointInPath(t,e,n,i)}isPointInStroke(t,e,n){return this.canvasDrawPath.isPointInStroke(t,e,n)}stroke(t){this.canvasDrawPath.stroke(t)}drawFocusIfNeeded(t,e){this.canvasUserInterface.drawFocusIfNeeded(t,e)}scrollPathIntoView(t){this.canvasUserInterface.scrollPathIntoView(t)}fillText(t,e,n,i){this.canvasText.fillText(t,e,n,i)}measureText(t){return this.canvasText.measureText(t)}strokeText(t,e,n,i){this.canvasText.strokeText(t,e,n,i)}drawImage(){this.canvasDrawImage.drawImage.apply(this.canvasDrawImage,arguments)}createImageData(t,e){return this.canvasImageData.createImageData(t,e)}getImageData(t,e,n,i){return this.canvasImageData.getImageData(t,e,n,i)}putImageData(t,e,n,i,s,o,a){this.canvasImageData.putImageData(t,e,n,i,s,o,a)}set lineCap(t){this.canvasPathDrawingStyles.lineCap=t}set lineDashOffset(t){this.canvasPathDrawingStyles.lineDashOffset=t}set lineJoin(t){this.canvasPathDrawingStyles.lineJoin=t}set lineWidth(t){this.canvasPathDrawingStyles.lineWidth=t}set miterLimit(t){this.canvasPathDrawingStyles.miterLimit=t}getLineDash(){return this.canvasPathDrawingStyles.getLineDash()}setLineDash(t){this.canvasPathDrawingStyles.setLineDash(t)}set direction(t){this.canvasTextDrawingStyles.direction=t}set font(t){this.canvasTextDrawingStyles.font=t}set textAlign(t){this.canvasTextDrawingStyles.textAlign=t}set textBaseline(t){this.canvasTextDrawingStyles.textBaseline=t}arc(t,e,n,i,s,o){this.canvasPath.arc(t,e,n,i,s,o)}arcTo(t,e,n,i,s){this.canvasPath.arcTo(t,e,n,i,s)}bezierCurveTo(t,e,n,i,s,o){this.canvasPath.bezierCurveTo(t,e,n,i,s,o)}closePath(){this.canvasPath.closePath()}ellipse(t,e,n,i,s,o,a,c){this.canvasPath.ellipse(t,e,n,i,s,o,a)}lineTo(t,e){this.canvasPath.lineTo(t,e)}lineToInfinityInDirection(t,e){this.canvasPath.lineToInfinityInDirection(t,e)}moveTo(t,e){this.canvasPath.moveTo(t,e)}moveToInfinityInDirection(t,e){this.canvasPath.moveToInfinityInDirection(t,e)}quadraticCurveTo(t,e,n,i){this.canvasPath.quadraticCurveTo(t,e,n,i)}rect(t,e,n,i){if(!Number.isFinite(t)&&!Number.isFinite(e))throw new Error(`The starting coordinates provided (${t} and ${e}) do not determine a direction.`);this.canvasPath.rect(t,e,n,i)}}class fe extends Ft{constructor(){super(...arguments),this.colorStops=[]}addColorStopsToGradient(t){for(const e of this.colorStops)t.addColorStop(e.offset,e.color)}addColorStop(t,e){this.colorStops.push({offset:t,color:e})}getInstructionToSetTransformed(t){return(e,n)=>{const i=n.userTransformation;e[t]=this.createTransformedGradient(i)}}getInstructionToSetUntransformed(t){return e=>{e[t]=this.createGradient()}}}class Li extends fe{constructor(t,e,n,i,s){super(),this.context=t,this.x0=e,this.y0=n,this.x1=i,this.y1=s}createTransformedGradient(t){const{x:e,y:n}=t.apply(new h(this.x0,this.y0)),{x:i,y:s}=t.apply(new h(this.x1,this.y1)),o=this.context.createLinearGradient(e,n,i,s);return this.addColorStopsToGradient(o),o}createGradient(){const t=this.context.createLinearGradient(this.x0,this.y0,this.x1,this.y1);return this.addColorStopsToGradient(t),t}}class Ei extends fe{constructor(t,e,n,i,s,o,a){super(),this.context=t,this.x0=e,this.y0=n,this.r0=i,this.x1=s,this.y1=o,this.r1=a}createTransformedGradient(t){const{x:e,y:n}=t.apply(new h(this.x0,this.y0)),{x:i,y:s}=t.apply(new h(this.x1,this.y1)),o=this.r0*t.scale,a=this.r1*t.scale,c=this.context.createRadialGradient(e,n,o,i,s,a);return this.addColorStopsToGradient(c),c}createGradient(){const t=this.context.createRadialGradient(this.x0,this.y0,this.r0,this.x1,this.y1,this.r1);return this.addColorStopsToGradient(t),t}}class ge{constructor(t){this.initiallyWithState=t,this.added=[]}get length(){return this.added.length}get currentlyWithState(){return this.addedLast?this.addedLast:this.initiallyWithState}reconstructState(t,e){e.setInitialState(t)}get stateOfFirstInstruction(){return this.initiallyWithState.stateOfFirstInstruction}get state(){return this.currentlyWithState.state}get initialState(){return this.initiallyWithState.initialState}addClippedPath(t){this.currentlyWithState.addClippedPath(t)}add(t){this.added.push(t),this.addedLast=t}removeAll(t){let e;for(;(e=this.added.findIndex(t))>-1;)this.removeAtIndex(e)}contains(t){return!!this.added.find(t)}setInitialState(t){this.initiallyWithState.setInitialState(t)}setInitialStateWithClippedPaths(t){this.initiallyWithState.setInitialStateWithClippedPaths(t)}beforeIndex(t){return t===0?this.initiallyWithState.state:this.added[t-1].state}removeAtIndex(t){t===this.added.length-1?this.added.length===1?this.addedLast=void 0:this.addedLast=this.added[t-1]:this.reconstructState(this.beforeIndex(t),this.added[t+1]),this.added.splice(t,1)}}class me extends ge{constructor(t){super(t),this._initiallyWithState=t}execute(t,e){this._initiallyWithState.execute(t,e);for(const n of this.added)n.execute(t,e)}}class dn{constructor(t){this.currentState=t,this.instructions=[]}restore(){this.addChangeToState(this.currentState.restored(),t=>{t.restore()})}save(){this.addChangeToState(this.currentState.saved(),t=>{t.save()})}changeCurrentInstanceTo(t){if(this.currentState.current.equals(t))return;const e=this.currentState.current.getInstructionToConvertToState(t),n=this.currentState.withCurrentState(t);this.addChangeToState(n,e)}addChangeToState(t,e){this.currentState=t,e&&this.instructions.push(e)}get instruction(){if(this.instructions.length!==0)return(t,e)=>{for(const n of this.instructions)n(t,e)}}}class ve extends dn{changeCurrentInstanceTo(t){if(!this.currentState.current.equals(t)){if(!ve.canConvert(this.currentState.current,t))if(this.currentState.stack.length>0)this.restore(),this.save();else{super.changeCurrentInstanceTo(t);return}if(t.clippedPaths){const e=this.currentState,i=e.current.clippedPaths;if(t.clippedPaths===i)super.changeCurrentInstanceTo(t);else{const o=t.clippedPaths.except(i);this.convertToState(o.initialState),this.addChangeToState(o.latestClippedPath.state,o.getInstructionToRecreate()),this.convertToState(e.replaceCurrent(t))}}else super.changeCurrentInstanceTo(t)}}convertToState(t){const e=this.currentState.getInstructionToConvertToState(t);this.addChangeToState(t,e)}static canConvert(t,e){return t.clippedPaths?e.clippedPaths?e.clippedPaths.contains(t.clippedPaths):!1:!0}}class G{constructor(t,e=[]){this.current=t,this.stack=e}replaceCurrent(t){return new G(t,this.stack)}withCurrentState(t){return new G(t,this.stack)}currentlyTransformed(t){return this.withCurrentState(this.current.changeProperty("fillAndStrokeStylesTransformed",t))}withClippedPath(t){return new G(this.current.withClippedPath(t),this.stack)}saved(){return new G(this.current,(this.stack||[]).concat([this.current]))}restored(){if(!this.stack||this.stack.length===0)return this;const t=this.stack[this.stack.length-1];return new G(t,this.stack.slice(0,this.stack.length-1))}convertToLastSavedInstance(t,e){for(let n=this.stack.length-1;n>e;n--)t.restore()}convertFromLastSavedInstance(t,e){for(let n=e+1;n{}}setInitialState(t){this.initialState=t;const e=this.initialState.getInstructionToConvertToState(this.state);this.stateConversion=e}get stateOfFirstInstruction(){return this.state}addClippedPath(t){this.state=this.state.withClippedPath(t)}setInitialStateWithClippedPaths(t){this.initialState=t;const e=this.initialState.getInstructionToConvertToStateWithClippedPath(this.state);this.stateConversion=e}}class Z extends pe{constructor(t,e,n,i){super(t,e),this.instruction=n,this.stateConversion=i}execute(t,e){this.stateConversion&&this.stateConversion(t,e),this.instruction(t,e)}static create(t,e){return new Z(t,t,e,()=>{})}}class Fi{constructor(t){this.area=t}hasDrawingAcrossBorderOf(t){return!1}intersects(t){return this.area.intersects(t)}isContainedBy(t){return t.contains(this.area)}}class we extends Z{constructor(t,e,n,i,s){super(t,e,n,i),this.drawingArea=new Fi(s)}static createClearRect(t,e,n,i,s,o,a){return new we(t,t,(c,l)=>{n.clearRect(c,l,i,s,o,a)},()=>{},e)}}const X={direction:new h(0,1)},Y={direction:new h(0,-1)},_={direction:new h(-1,0)},tt={direction:new h(1,0)};function Wi(r,t,e){let n=0,i;for(let s of r){const o=s.minus(t).dot(e);o>n&&(i=s,n=o)}return i?t.plus(i.minus(t).projectOn(e)):t}function L(r,t,e){return Wi(r.getVertices(),t,e)}class ki{constructor(t,e){this.state=t,this.drawnPathProperties=e}addPathAroundViewbox(t,e){e.addPathAroundViewbox(t,this.drawnPathProperties.lineWidth)}getTransformedViewbox(t){const e=this.state.current.transformation.before(t.getBitmapTransformationToInfiniteCanvasContext());let n=t.polygon;n=n.transform(e.inverse()).expandByDistance(this.drawnPathProperties.lineWidth);for(const i of this.drawnPathProperties.shadowOffsets){const s=n.transform(v.translation(-i.x,-i.y));n=n.join(s)}return n}clearRect(t,e,n,i,s,o){const a=this.getTransformedViewbox(e),{a:c,b:l,c:d,d:u,e:g,f:w}=e.userTransformation;t.save(),t.transform(c,l,d,u,g,w);const P=Number.isFinite(n)?n:L(a,new h(0,0),n>0?tt.direction:_.direction).x,O=Number.isFinite(s)?n+s:L(a,new h(0,0),s>0?tt.direction:_.direction).x,H=Number.isFinite(i)?i:L(a,new h(0,0),i>0?X.direction:Y.direction).y,K=Number.isFinite(o)?i+o:L(a,new h(0,0),o>0?X.direction:Y.direction).y;t.clearRect(P,H,O-P,K-H),t.restore()}moveToInfinityFromPointInDirection(t,e,n,i){const s=L(this.getTransformedViewbox(e),n,i);this.moveToTransformed(t,s,e.userTransformation)}drawLineToInfinityFromInfinityFromPoint(t,e,n,i,s){const o=this.getTransformedViewbox(e),a=L(o,n,i),c=L(o,n,s),l=e.userTransformation,u=o.expandToIncludePoint(n).expandToIncludePoint(a).expandToIncludePoint(c).getVertices().filter(P=>!P.equals(a)&&!P.equals(c)&&!P.equals(n)&&P.minus(n).isInSmallerAngleBetweenPoints(i,s));u.sort((P,O)=>P.minus(n).isInSmallerAngleBetweenPoints(O.minus(n),i)?-1:1);let g=a,w=0;for(let P of u)w+=P.minus(g).mod(),this.lineToTransformed(t,P,l),g=P;w+=c.minus(g).mod(),this.lineToTransformed(t,c,l),this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,l,w,c,s)}drawLineFromInfinityFromPointToInfinityFromPoint(t,e,n,i,s){const o=this.getTransformedViewbox(e),a=L(o,n,s),c=e.userTransformation,l=L(o,i,s);this.lineToTransformed(t,l,c);const d=l.minus(a).mod();this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,c,d,l,s)}drawLineFromInfinityFromPointToPoint(t,e,n,i){const s=L(this.getTransformedViewbox(e),n,i),o=n.minus(s).mod(),a=e.userTransformation;this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,a,o,s,i),this.lineToTransformed(t,n,a)}drawLineToInfinityFromPointInDirection(t,e,n,i){const s=L(this.getTransformedViewbox(e),n,i),o=e.userTransformation;this.lineToTransformed(t,s,o);const a=s.minus(n).mod();this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,o,a,s,i)}ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,e,n,i,s){const o=this.drawnPathProperties.lineDashPeriod;if(o===0)return;const a=this.getDistanceLeft(n,o);if(a===0)return;const c=i.plus(s.scale(a/(2*s.mod())));this.lineToTransformed(t,c,e),this.lineToTransformed(t,i,e)}lineToTransformed(t,e,n){const{x:i,y:s}=n.apply(e);t.lineTo(i,s)}moveToTransformed(t,e,n){const{x:i,y:s}=n.apply(e);t.moveTo(i,s)}getDistanceLeft(t,e){if(e===0)return 0;const n=t/e|0;return t-e*n===0?0:(n+1)*e-t}}class gn{constructor(t){this.drawnPathProperties=t}getInfinity(t){return new ki(t,this.drawnPathProperties)}}class Pe extends me{reconstructState(t,e){e.setInitialStateWithClippedPaths(t)}hasDrawingAcrossBorderOf(t){return this.contains(e=>e.drawingArea.hasDrawingAcrossBorderOf(t))}intersects(t){return this.contains(e=>e.drawingArea.intersects(t))}addClearRect(t,e,n,i,s,o){const c=new gn({lineWidth:0,lineDashPeriod:0,shadowOffsets:[]}).getInfinity(e),l=we.createClearRect(e,t,c,n,i,s,o);l.setInitialState(this.state),this.add(l)}clearContentsInsideArea(t){this.removeAll(e=>e.drawingArea.isContainedBy(t))}static create(){return new Pe(new Z(fn,fn,R.setDefault,()=>{}))}}class U extends pe{constructor(t,e,n,i){super(t,e),this.instruction=n,this.stateConversion=i}copy(){return new U(this.initialState,this.state,this.instruction,this.stateConversion)}makeExecutable(){return new Z(this.initialState,this.state,this.instruction,this.stateConversion)}static create(t,e){return new U(t,t,e,()=>{})}}function z(r,t){return C(r)?t.applyToPointAtInfinity(r):t.apply(r)}class Ri{constructor(t,e){this.areaBuilder=t,this.transformation=e}addPosition(t){this.areaBuilder.addPosition(z(t,this.transformation))}}class Ce{constructor(t,e){this.base=t,this.direction=e}pointIsOnSameLine(t){return t.minus(this.base).cross(this.direction)===0}comesBefore(t,e){return e.minus(t).dot(this.direction)>=0}lineSegmentIsOnSameLine(t){return this.direction.cross(t.direction)===0&&this.pointIsOnSameLine(t.point1)}expandLineByDistance(t){const e=this.direction.getPerpendicular(),n=new p(this.base,e).expandByDistance(t),i=new p(this.base,e.scale(-1)).expandByDistance(t);return new m([n,i])}getPointsInSameDirection(t,e){return this.comesBefore(e,t)?{point1:e,point2:t}:{point1:t,point2:e}}pointIsBetweenPoints(t,e,n){return t.minus(e).dot(this.direction)*t.minus(n).dot(this.direction)<=0}intersectsConvexPolygon(t){if(this.isContainedByConvexPolygon(t))return!0;const e=t.getIntersectionsWithLine(this.base,this.direction);for(let n of e)if(this.interiorContainsPoint(n.point))return!0;return!1}}class Nt extends Ce{getVertices(){return[]}intersectWith(t){return t.intersectWithLine(this)}join(t){return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1))}intersectWithConvexPolygon(t){if(!this.intersectsConvexPolygon(t))return y;if(this.isContainedByConvexPolygon(t))return this;const e=t.getIntersectionsWithLine(this.base,this.direction);let n,i;for(let s of e)(!n&&!i||!n&&this.comesBefore(s.point,i)||!i&&this.comesBefore(n,s.point)||n&&i&&this.pointIsBetweenPoints(s.point,n,i))&&(s.halfPlane.normalTowardInterior.dot(this.direction)>0?n=s.point:i=s.point);return n&&i?new A(n,i):n?new W(n,this.direction):new W(i,this.direction.scale(-1))}intersectWithLine(t){return this.intersectsLine(t)?this:y}intersectWithLineSegment(t){return this.lineSegmentIsOnSameLine(t)?t:y}intersectWithRay(t){return this.intersectsRay(t)?t:y}isContainedByConvexPolygon(t){return t.containsPoint(this.base)&&t.containsInfinityInDirection(this.direction)&&t.containsInfinityInDirection(this.direction.scale(-1))}isContainedByLine(t){return this.intersectsSubsetOfLine(t)}isContainedByLineSegment(t){return!1}isContainedByRay(t){return!1}contains(t){return t.isContainedByLine(this)}intersectsLine(t){return this.intersectsSubsetOfLine(t)}intersectsSubsetOfLine(t){return this.pointIsOnSameLine(t.base)&&this.direction.cross(t.direction)===0}intersectsLineSegment(t){return this.lineSegmentIsOnSameLine(t)}intersectsRay(t){return this.intersectsSubsetOfLine(t)}intersects(t){return t.intersectsLine(this)}expandToIncludePoint(t){return this.pointIsOnSameLine(t)?this:m.createTriangleWithInfinityInDirection(this.base,t,this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1))}expandByDistance(t){return this.expandLineByDistance(t)}expandToIncludeInfinityInDirection(t){const e=t.cross(this.direction),n=this.direction.getPerpendicular();return e===0?this:e>0?m.createFromHalfPlane(new p(this.base,n.scale(-1))):m.createFromHalfPlane(new p(this.base,n))}transform(t){const e=t.apply(this.base);return new Nt(e,t.apply(this.base.plus(this.direction)).minus(e))}interiorContainsPoint(t){return this.pointIsOnSameLine(t)}}class W extends Ce{getVertices(){return[this.base]}intersectWith(t){return t.intersectWithRay(this)}join(t){return t.expandToIncludePoint(this.base).expandToIncludeInfinityInDirection(this.direction)}intersectWithConvexPolygon(t){if(!this.intersectsConvexPolygon(t))return y;if(this.isContainedByConvexPolygon(t))return this;const e=t.getIntersectionsWithLine(this.base,this.direction);let n=this.base,i;for(let s of e)(!i&&this.comesBefore(n,s.point)||i&&this.pointIsBetweenPoints(s.point,n,i))&&(s.halfPlane.normalTowardInterior.dot(this.direction)>0?n=s.point:i=s.point);return i?new A(n,i):new W(n,this.direction)}intersectWithRay(t){return this.isContainedByRay(t)?this:t.isContainedByRay(this)?t:this.interiorContainsPoint(t.base)?new A(this.base,t.base):y}intersectWithLine(t){return t.intersectWithRay(this)}intersectWithLineSegment(t){if(t.isContainedByRay(this))return t;if(!this.lineSegmentIsOnSameLine(t))return y;let{point2:e}=this.getPointsInSameDirection(t.point1,t.point2);return this.comesBefore(e,this.base)?y:new A(this.base,e)}isContainedByConvexPolygon(t){return t.containsPoint(this.base)&&t.containsInfinityInDirection(this.direction)}isContainedByRay(t){return t.containsPoint(this.base)&&t.containsInfinityInDirection(this.direction)}isContainedByLine(t){return t.intersectsSubsetOfLine(this)}isContainedByLineSegment(t){return!1}contains(t){return t.isContainedByRay(this)}intersectsRay(t){return this.isContainedByRay(t)||t.isContainedByRay(this)||this.interiorContainsPoint(t.base)}intersectsLine(t){return t.intersectsSubsetOfLine(this)}intersectsLineSegment(t){if(t.isContainedByRay(this))return!0;if(!this.lineSegmentIsOnSameLine(t))return!1;let{point2:e}=this.getPointsInSameDirection(t.point1,t.point2);return!this.comesBefore(e,this.base)}intersects(t){return t.intersectsRay(this)}expandToIncludePoint(t){return this.containsPoint(t)?this:this.pointIsOnSameLine(t)?new W(t,this.direction):m.createTriangleWithInfinityInDirection(this.base,t,this.direction)}expandByDistance(t){const e=this.expandLineByDistance(t),n=new p(this.base,this.direction).expandByDistance(t);return e.intersectWithConvexPolygon(new m([n]))}expandToIncludeInfinityInDirection(t){return t.inSameDirectionAs(this.direction)?this:this.direction.cross(t)===0?new Nt(this.base,this.direction):m.createTriangleWithInfinityInTwoDirections(this.base,this.direction,t)}transform(t){const e=t.apply(this.base);return new W(e,t.apply(this.base.plus(this.direction)).minus(e))}interiorContainsPoint(t){return this.pointIsOnSameLine(t)&&!this.comesBefore(t,this.base)}containsInfinityInDirection(t){return this.direction.inSameDirectionAs(t)}containsPoint(t){return this.pointIsOnSameLine(t)&&this.comesBefore(this.base,t)}}class A extends Ce{constructor(t,e){super(t,e.minus(t)),this.point1=t,this.point2=e}getVertices(){return[this.point1,this.point2]}join(t){return t.expandToIncludePoint(this.point1).expandToIncludePoint(this.point2)}intersectWith(t){return t.intersectWithLineSegment(this)}intersectWithLineSegment(t){if(this.isContainedByLineSegment(t))return this;if(t.isContainedByLineSegment(this))return t;if(!this.lineSegmentIsOnSameLine(t))return y;let{point1:e,point2:n}=this.getPointsInSameDirection(t.point1,t.point2);return this.comesBefore(n,this.point1)||this.comesBefore(this.point2,e)?y:this.comesBefore(this.point1,e)?new A(e,this.point2):new A(this.point1,n)}intersectWithRay(t){return t.intersectWithLineSegment(this)}intersectWithLine(t){return t.intersectWithLineSegment(this)}isContainedByRay(t){return t.containsPoint(this.point1)&&t.containsPoint(this.point2)}isContainedByLine(t){return t.intersectsSubsetOfLine(this)}isContainedByLineSegment(t){return t.containsPoint(this.point1)&&t.containsPoint(this.point2)}intersectWithConvexPolygon(t){if(!this.intersectsConvexPolygon(t))return y;if(this.isContainedByConvexPolygon(t))return this;const e=t.getIntersectionsWithLine(this.point1,this.direction);let n=this.point1,i=this.point2;for(let s of e)this.pointIsBetweenPoints(s.point,n,i)&&(s.halfPlane.normalTowardInterior.dot(this.direction)>0?n=s.point:i=s.point);return new A(n,i)}isContainedByConvexPolygon(t){return t.containsPoint(this.point1)&&t.containsPoint(this.point2)}contains(t){return t.isContainedByLineSegment(this)}pointIsStrictlyBetweenPoints(t,e,n){return t.minus(e).dot(this.direction)*t.minus(n).dot(this.direction)<0}containsPoint(t){return this.pointIsOnSameLine(t)&&this.pointIsBetweenPoints(t,this.point1,this.point2)}interiorContainsPoint(t){return this.pointIsOnSameLine(t)&&this.pointIsStrictlyBetweenPoints(t,this.point1,this.point2)}intersectsRay(t){return t.intersectsLineSegment(this)}intersectsLineSegment(t){if(this.isContainedByLineSegment(t)||t.isContainedByLineSegment(this))return!0;if(!this.lineSegmentIsOnSameLine(t))return!1;const{point1:e,point2:n}=this.getPointsInSameDirection(t.point1,t.point2);return!this.comesBefore(n,this.point1)&&!this.comesBefore(this.point2,e)}intersectsLine(t){return t.intersectsSubsetOfLine(this)}intersects(t){return t.intersectsLineSegment(this)}expandByDistance(t){const e=this.expandLineByDistance(t),n=new p(this.base,this.direction).expandByDistance(t),i=new p(this.point2,this.direction.scale(-1)).expandByDistance(t);return e.intersectWithConvexPolygon(new m([n,i]))}expandToIncludePoint(t){return this.containsPoint(t)?this:this.pointIsOnSameLine(t)?this.comesBefore(t,this.point1)?new A(t,this.point2):new A(this.point1,t):m.createTriangle(this.point1,t,this.point2)}expandToIncludeInfinityInDirection(t){return t.inSameDirectionAs(this.direction)?new W(this.point1,t):t.cross(this.direction)===0?new W(this.point2,t):m.createTriangleWithInfinityInDirection(this.point1,this.point2,t)}transform(t){return new A(t.apply(this.point1),t.apply(this.point2))}}class Ni{addPoint(t){return pt}addPointAtInfinity(t){return this}addArea(t){return pt}}const Ie=new Ni;class Te{constructor(t){this.towardsMiddle=t}addPoint(t){return m.createFromHalfPlane(new p(t,this.towardsMiddle))}addPointAtInfinity(t){return t.dot(this.towardsMiddle)>=0?this:Ie}addArea(t){const e=this.towardsMiddle.getPerpendicular();return t.expandToIncludeInfinityInDirection(this.towardsMiddle).expandToIncludeInfinityInDirection(e).expandToIncludeInfinityInDirection(e.scale(-1))}}class Mt{constructor(t,e){this.direction1=t,this.direction2=e}addPoint(t){return m.createTriangleWithInfinityInTwoDirections(t,this.direction1,this.direction2)}addPointAtInfinity(t){return t.isInSmallerAngleBetweenPoints(this.direction1,this.direction2)?this:t.cross(this.direction1)===0?new Te(this.direction2.projectOn(this.direction1.getPerpendicular())):t.cross(this.direction2)===0?new Te(this.direction1.projectOn(this.direction2.getPerpendicular())):this.direction1.isInSmallerAngleBetweenPoints(t,this.direction2)?new Mt(t,this.direction2):this.direction2.isInSmallerAngleBetweenPoints(t,this.direction1)?new Mt(t,this.direction1):Ie}addArea(t){return t.expandToIncludeInfinityInDirection(this.direction1).expandToIncludeInfinityInDirection(this.direction2)}}class Mi{constructor(t){this.direction=t}addPoint(t){return new Nt(t,this.direction)}addPointAtInfinity(t){return t.cross(this.direction)===0?this:new Te(t.projectOn(this.direction.getPerpendicular()))}addArea(t){return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1))}}class Vi{constructor(t){this.direction=t}addPointAtInfinity(t){return t.inSameDirectionAs(this.direction)?this:t.cross(this.direction)===0?new Mi(this.direction):new Mt(this.direction,t)}addPoint(t){return new W(t,this.direction)}addArea(t){return t.expandToIncludeInfinityInDirection(this.direction)}}class Se{constructor(t,e,n){this._area=t,this.firstPoint=e,this.subsetOfLineAtInfinity=n}get area(){return this._area||y}addPoint(t){this._area?this._area=this._area.expandToIncludePoint(t):this.firstPoint?t.equals(this.firstPoint)||(this._area=new A(this.firstPoint,t)):this.subsetOfLineAtInfinity?this._area=this.subsetOfLineAtInfinity.addPoint(t):this.firstPoint=t}addPosition(t){C(t)?this.addInfinityInDirection(t.direction):this.addPoint(t)}addInfinityInDirection(t){this._area?this._area=this._area.expandToIncludeInfinityInDirection(t):this.firstPoint?this._area=new W(this.firstPoint,t):this.subsetOfLineAtInfinity?(this.subsetOfLineAtInfinity=this.subsetOfLineAtInfinity.addPointAtInfinity(t),this.subsetOfLineAtInfinity===Ie&&(this._area=pt)):this.subsetOfLineAtInfinity=new Vi(t)}transformedWith(t){return new Ri(this,t)}copy(){return new Se(this._area,this.firstPoint,this.subsetOfLineAtInfinity)}}class Pt extends pe{constructor(t,e,n,i){super(t,e),this.instruction=n,this.stateConversion=i}replaceInstruction(t){this.instruction=t}copy(){return new Pt(this.initialState,this.state,this.instruction,this.stateConversion)}makeExecutable(t){const e=t.getInfinity(this.state),n=this.instruction,i=(s,o)=>n(s,o,e);return new Z(this.initialState,this.state,i,this.stateConversion)}static create(t,e){return new Pt(t,t,e,()=>{})}}function Hi(r,t){return r?t?C(r)?C(t)&&r.direction.equals(t.direction):!C(t)&&r.equals(t):!r:!t}class Ct{constructor(t){this.shape=t}getInstructionToDrawLineTo(t,e){return this.getInstructionToExtendShapeWithLineTo(this.shape.transform(e.current.transformation.inverse()),t)}getInstructionToMoveToBeginning(t){return this.getInstructionToMoveToBeginningOfShape(this.shape.transform(t.current.transformation.inverse()))}get currentPosition(){return this.shape.currentPosition}moveToInfinityFromPointInDirection(t,e){return(n,i,s)=>{s.moveToInfinityFromPointInDirection(n,i,t,e)}}lineFromInfinityFromPointToInfinityFromPoint(t,e,n){return(i,s,o)=>{o.drawLineFromInfinityFromPointToInfinityFromPoint(i,s,t,e,n)}}lineFromInfinityFromPointToPoint(t,e){return(n,i,s)=>{s.drawLineFromInfinityFromPointToPoint(n,i,t,e)}}lineToInfinityFromPointInDirection(t,e){return(n,i,s)=>{s.drawLineToInfinityFromPointInDirection(n,i,t,e)}}lineToInfinityFromInfinityFromPoint(t,e,n){return(i,s,o)=>{o.drawLineToInfinityFromInfinityFromPoint(i,s,t,e,n)}}lineTo(t){return(e,n)=>{const{x:i,y:s}=n.userTransformation.apply(t);e.lineTo(i,s)}}moveTo(t){return(e,n)=>{const{x:i,y:s}=n.userTransformation.apply(t);e.moveTo(i,s)}}}class Vt{constructor(t,e,n,i){this.initialPosition=t,this.firstFinitePoint=e,this.lastFinitePoint=n,this.currentPosition=i}transform(t){return new Vt(t.applyToPointAtInfinity(this.initialPosition),t.apply(this.firstFinitePoint),t.apply(this.lastFinitePoint),t.applyToPointAtInfinity(this.currentPosition))}}class It{constructor(t,e,n){this.initialPosition=t,this.firstFinitePoint=e,this.currentPosition=n}transform(t){return new It(t.applyToPointAtInfinity(this.initialPosition),t.apply(this.firstFinitePoint),t.apply(this.currentPosition))}}class qi extends Ct{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return t.initialPosition.direction.cross(t.currentPosition.direction)===0?this.moveToInfinityFromPointInDirection(t.firstFinitePoint,t.initialPosition.direction):k(this.moveToInfinityFromPointInDirection(t.lastFinitePoint,t.currentPosition.direction),this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint,t.currentPosition.direction,t.initialPosition.direction),this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint,t.firstFinitePoint,t.initialPosition.direction))}getInstructionToExtendShapeWithLineTo(t,e){return C(e)?this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint,t.currentPosition.direction,e.direction):k(this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint,e,t.currentPosition.direction),this.lineFromInfinityFromPointToPoint(e,t.currentPosition.direction))}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!this.shape.initialPosition.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}canAddLineTo(t){return!C(t)||!t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new Vt(this.shape.initialPosition,this.shape.firstFinitePoint,this.shape.lastFinitePoint,t)):this.pathBuilderProvider.fromPointAtInfinityToPoint(new It(this.shape.initialPosition,this.shape.firstFinitePoint,t))}}class Gi extends Ct{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){const e=this.moveToInfinityFromPointInDirection(t.currentPosition,t.initialPosition.direction);if(t.currentPosition.equals(t.firstFinitePoint))return e;const n=this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition,t.firstFinitePoint,t.initialPosition.direction);return k(e,n)}getInstructionToExtendShapeWithLineTo(t,e){return C(e)?this.lineToInfinityFromPointInDirection(t.currentPosition,e.direction):this.lineTo(e)}canAddLineTo(t){return!0}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!0}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new Vt(this.shape.initialPosition,this.shape.firstFinitePoint,this.shape.currentPosition,t)):this.pathBuilderProvider.fromPointAtInfinityToPoint(new It(this.shape.initialPosition,this.shape.firstFinitePoint,t))}}class Ht{constructor(t,e){this.initialPoint=t,this.currentPosition=e}transform(t){return new Ht(t.apply(this.initialPoint),t.applyToPointAtInfinity(this.currentPosition))}}class Tt{constructor(t,e){this.initialPoint=t,this.currentPosition=e}transform(t){return new Tt(t.apply(this.initialPoint),t.apply(this.currentPosition))}}class Xi extends Ct{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return this.moveTo(t.initialPoint)}getInstructionToExtendShapeWithLineTo(t,e){return C(e)?e.direction.inSameDirectionAs(t.currentPosition.direction)?()=>{}:this.lineToInfinityFromInfinityFromPoint(t.initialPoint,t.currentPosition.direction,e.direction):k(this.lineFromInfinityFromPointToInfinityFromPoint(t.initialPoint,e,t.currentPosition.direction),this.lineFromInfinityFromPointToPoint(e,t.currentPosition.direction))}canAddLineTo(t){return!C(t)||!t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!0}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointToPointAtInfinity(new Ht(this.shape.initialPoint,t)):this.pathBuilderProvider.fromPointToPoint(new Tt(this.shape.initialPoint,t))}}class mn extends Ct{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return this.moveTo(t.initialPoint)}getInstructionToExtendShapeWithLineTo(t,e){if(C(e)){const n=this.lineToInfinityFromPointInDirection(t.currentPosition,e.direction);if(t.currentPosition.minus(t.initialPoint).cross(e.direction)===0)return n;const i=this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition,t.initialPoint,e.direction);return k(n,i)}return this.lineTo(e)}canAddLineTo(t){return!0}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!0}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointToPointAtInfinity(new Ht(this.shape.initialPoint,t)):this.pathBuilderProvider.fromPointToPoint(new Tt(this.shape.initialPoint,t))}}class qt{constructor(t,e,n,i){this.initialPosition=t,this.surroundsFinitePoint=e,this.positionsSoFar=n,this.currentPosition=i}transform(t){return new qt(t.applyToPointAtInfinity(this.initialPosition),this.surroundsFinitePoint,this.positionsSoFar.map(e=>t.applyToPointAtInfinity(e)),t.applyToPointAtInfinity(this.currentPosition))}}class vn extends Ct{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return t.surroundsFinitePoint?(e,n,i)=>i.addPathAroundViewbox(e,n):()=>{}}getInstructionToExtendShapeWithLineTo(t,e){if(C(e))return;if(t.positionsSoFar.length===1)return this.lineFromInfinityFromPointToPoint(e,t.positionsSoFar[0].direction);const n=t.positionsSoFar.slice(1);let i=t.initialPosition;const s=[];for(let o of n)s.push(this.lineToInfinityFromInfinityFromPoint(e,i.direction,o.direction)),i=o;return k(k(...s),this.lineFromInfinityFromPointToPoint(e,i.direction))}canAddLineTo(t){return!C(t)||!t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}containsFinitePoint(){return!1}surroundsFinitePoint(){return this.shape.surroundsFinitePoint}isClosable(){return!0}addPosition(t){if(C(t)){const n=t.direction.isOnSameSideOfOriginAs(this.shape.initialPosition.direction,this.shape.currentPosition.direction)?this.shape.surroundsFinitePoint:!this.shape.surroundsFinitePoint;return this.pathBuilderProvider.atInfinity(new qt(this.shape.initialPosition,n,this.shape.positionsSoFar.concat([t]),t))}return this.pathBuilderProvider.fromPointAtInfinityToPoint(new It(this.shape.initialPosition,t,t))}}class Yi{fromPointAtInfinityToPointAtInfinity(t){return new qi(this,t)}fromPointAtInfinityToPoint(t){return new Gi(this,t)}fromPointToPointAtInfinity(t){return new Xi(this,t)}fromPointToPoint(t){return new mn(this,t)}atInfinity(t){return new vn(this,t)}getBuilderFromPosition(t){return C(t)?new vn(this,new qt(t,!1,[t],t)):new mn(this,new Tt(t,t))}}class Gt extends ge{constructor(t,e){super(t),this._initiallyWithState=t,this.pathInstructionBuilder=e}get currentPosition(){return this.pathInstructionBuilder.currentPosition}addInstruction(t){t.setInitialState(this.state),this.add(t)}closePath(){const t=U.create(this.state,e=>{e.closePath()});t.setInitialState(this.state),this.add(t)}copy(){const t=new Gt(this._initiallyWithState.copy(),this.pathInstructionBuilder);for(const e of this.added)t.add(e.copy());return t}makeExecutable(t){const e=new me(this._initiallyWithState.makeExecutable(t));for(const n of this.added)e.add(n.makeExecutable(t));return e}surroundsFinitePoint(){return this.pathInstructionBuilder.surroundsFinitePoint()}isClosable(){return this.pathInstructionBuilder.isClosable()}canAddLineTo(t){return this.pathInstructionBuilder.canAddLineTo(t)}lineTo(t,e){const n=z(t,e.current.transformation);(!C(t)||this.pathInstructionBuilder.containsFinitePoint())&&this.addInstructionToDrawLineTo(t,e),this.pathInstructionBuilder=this.pathInstructionBuilder.addPosition(n);const i=this.pathInstructionBuilder.getInstructionToMoveToBeginning(this._initiallyWithState.state);this._initiallyWithState.replaceInstruction((s,o,a)=>{i(s,o,a)})}addInstructionToDrawLineTo(t,e){const n=this.pathInstructionBuilder.getInstructionToDrawLineTo(t,e),i=Pt.create(e,n);i.setInitialState(this.state),this.add(i)}addPathInstruction(t,e,n){t.initialPoint&&!Hi(this.pathInstructionBuilder.currentPosition,t.initialPoint)&&this.lineTo(t.initialPoint,n),t.positionChange&&(this.pathInstructionBuilder=this.pathInstructionBuilder.addPosition(z(t.positionChange,n.current.transformation))),e.setInitialState(this.state),this.add(e)}static create(t,e){const n=z(e,t.current.transformation),i=new Yi().getBuilderFromPosition(n),s=i.getInstructionToMoveToBeginning(t),o=Pt.create(t,s);return new Gt(o,i)}}function pn(r,t){return Number.isFinite(r)?!0:Number.isFinite(t)?!1:r<0&&t>0||r>0&&t<0}function Xt(r,t,e,n){return pn(r,e)&&pn(t,n)}class Ui{constructor(t,e){this.instructions=t,this.area=e}get state(){return this.instructions.state}get initialState(){return this.instructions.initialState}execute(t,e){this.instructions.execute(t,e)}}class ct extends ge{constructor(t){super(t),this._initiallyWithState=t,this.areaBuilder=new Se}get area(){return this.areaBuilder.area}surroundsFinitePoint(){for(const t of this.added)if(t.surroundsFinitePoint())return!0;return!1}currentSubpathIsClosable(){return this.added.length===0?!0:this.added[this.added.length-1].isClosable()}allSubpathsAreClosable(){if(this.added.length===0)return!0;for(const t of this.added)if(!t.isClosable())return!1;return!0}drawPath(t,e,n){if(this.added.length===0)return;const i=this.added[this.added.length-1],s=U.create(e,t);return i.addInstruction(s),this.makeExecutable(n)}makeExecutable(t){const e=new me(this._initiallyWithState.makeExecutable()),n=new gn(t);for(const i of this.added)e.add(i.makeExecutable(n));return e}clipPath(t,e){if(this.added.length===0)return;const n=this.added[this.added.length-1],i=U.create(e,t);n.addInstruction(i);const s=this.recreatePath();this.addClippedPath(s.getInstructionsToClip())}closePath(){if(this.added.length===0)return;this.added[this.added.length-1].closePath()}moveTo(t,e){const n=z(t,e.current.transformation);this.areaBuilder.addPosition(n);const i=Gt.create(e,t);i.setInitialState(this.state),this.add(i)}canAddLineTo(t,e){if(this.added.length===0)return!0;const n=z(t,e.current.transformation);return this.added[this.added.length-1].canAddLineTo(n)}lineTo(t,e){if(this.added.length===0){this.moveTo(t,e);return}const n=this.added[this.added.length-1],i=z(t,e.current.transformation);this.areaBuilder.addPosition(i),n.lineTo(t,e)}moveToPositionDeterminedBy(t,e,n){Number.isFinite(t)?Number.isFinite(e)?this.moveTo(new h(t,e),n):this.moveTo(e<0?Y:X,n):this.moveTo(t<0?_:tt,n)}rect(t,e,n,i,s){if(!Number.isFinite(t)&&!Number.isFinite(e)){this.moveTo({direction:new h(1,0)},s),this.lineTo({direction:new h(0,1)},s),this.lineTo({direction:new h(-1,-1)},s);return}this.moveToPositionDeterminedBy(t,e,s),Xt(t,e,n,i)&&(Number.isFinite(t)?Number.isFinite(e)?(Number.isFinite(n)?(this.lineTo(new h(t+n,e),s),Number.isFinite(i)?(this.lineTo(new h(t+n,e+i),s),this.lineTo(new h(t,e+i),s)):this.lineTo(i>0?X:Y,s)):(this.lineTo(n>0?tt:_,s),Number.isFinite(i)?this.lineTo(new h(t,e+i),s):this.lineTo(i>0?X:Y,s)),this.lineTo(new h(t,e),s)):(Number.isFinite(n)?this.lineTo(new h(t+n,0),s):this.lineTo(n>0?tt:_,s),this.lineTo(i>0?X:Y,s),this.lineTo(new h(t,0),s),this.lineTo(e<0?Y:X,s)):(this.lineTo(new h(0,e),s),this.lineTo(n>0?tt:_,s),Number.isFinite(i)?this.lineTo(new h(0,e+i),s):this.lineTo(i>0?X:Y,s),this.lineTo(t<0?_:tt,s)),this.closePath(),this.moveToPositionDeterminedBy(t,e,s))}addPathInstruction(t,e){if(this.added.length===0)if(t.initialPoint)this.moveTo(t.initialPoint,e);else return;const n=this.added[this.added.length-1],i=n.currentPosition,s=z(i,e.current.transformation.inverse());t.changeArea(this.areaBuilder.transformedWith(e.current.transformation),s);const o=U.create(e,t.instruction);n.addPathInstruction(t,o,e)}getInstructionsToClip(){return new Ui(this.makeExecutable({lineWidth:0,lineDashPeriod:0,shadowOffsets:[]}),this.area)}recreatePath(){const t=new ct(this._initiallyWithState.copy());for(const e of this.added)t.add(e.copy());return t.areaBuilder=this.areaBuilder.copy(),t.setInitialState(t.stateOfFirstInstruction),t}static create(t){return new ct(U.create(t,e=>{e.beginPath()}))}}function wn(r,t){return Number.isFinite(r)||Number.isFinite(t)?!1:r<0&&t>0||r>0&&t<0}function Pn(r,t,e,n){return wn(r,e)&&wn(t,n)}class zi{constructor(t){this.area=t}hasDrawingAcrossBorderOf(t){return this.isContainedBy(t)?!1:this.intersects(t)}isContainedBy(t){return t.contains(this.area)}intersects(t){return this.area.intersects(t)}}class $i{constructor(t,e){this.instructions=t,this.drawingArea=new zi(e)}get state(){return this.instructions.state}get initialState(){return this.instructions.initialState}get stateOfFirstInstruction(){return this.instructions.stateOfFirstInstruction}setInitialState(t){this.instructions.setInitialState(t)}setInitialStateWithClippedPaths(t){this.instructions.setInitialStateWithClippedPaths(t)}addClippedPath(t){this.instructions.addClippedPath(t)}execute(t,e){this.instructions.execute(t,e)}}function Ki(r,t){let e=r.area;return e&&t.lineWidth>0&&(e=e.expandByDistance(t.lineWidth/2)),e}function ji(r){return{lineWidth:r.current.getMaximumLineWidth(),lineDashPeriod:r.current.getLineDashPeriod(),shadowOffsets:r.current.getShadowOffsets()}}function Qi(r){return{lineWidth:0,lineDashPeriod:0,shadowOffsets:r.current.getShadowOffsets()}}class N{constructor(t,e,n,i,s,o,a){this.instruction=t,this.area=e,this.build=n,this.takeClippingRegionIntoAccount=i,this.transformationKind=s,this.state=o,this.tempState=a}static forStrokingPath(t,e,n){return N.forPath(t,e,ji,n)}static forFillingPath(t,e,n){return N.forPath(t,e,Qi,n)}static forPath(t,e,n,i){const s=e.current.isTransformable(),o=s?F.None:F.Relative,a=e.currentlyTransformed(s),c=n(a),l=i(a),d=Ki(l,c);return new N(t,d,u=>l.drawPath(u,a,c),!0,o,a)}getDrawnArea(){let t=this.area;const e=this.state;if(e.current.shadowBlur!==0||!e.current.shadowOffset.equals(h.origin)){const n=t.expandByDistance(e.current.shadowBlur).transform(v.translation(e.current.shadowOffset.x,e.current.shadowOffset.y));t=t.join(n)}return e.current.clippingRegion&&this.takeClippingRegionIntoAccount&&(t=t.intersectWith(e.current.clippingRegion)),t}getModifiedInstruction(){let t=bi(this.transformationKind);if(this.tempState){const n=this.takeClippingRegionIntoAccount?this.state.getInstructionToConvertToStateWithClippedPath(this.tempState):this.state.getInstructionToConvertToState(this.tempState);t=k(t,n)}return yi(this.instruction,t)}}class Ji{constructor(t){this.onChange=t,this.previousInstructionsWithPath=Pe.create(),this.state=this.previousInstructionsWithPath.state}beginPath(){const t=ct.create(this.state);t.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state),this.currentInstructionsWithPath=t}changeState(t){this.state=this.state.withCurrentState(t(this.state.current))}saveState(){this.state=this.state.saved()}restoreState(){this.state=this.state.restored()}allSubpathsAreClosable(){return!this.currentInstructionsWithPath||this.currentInstructionsWithPath.allSubpathsAreClosable()}currentPathSurroundsFinitePoint(){return this.currentInstructionsWithPath&&this.currentInstructionsWithPath.surroundsFinitePoint()}currentSubpathIsClosable(){return!this.currentInstructionsWithPath||this.currentInstructionsWithPath.currentSubpathIsClosable()}fillPath(t){if(!this.currentInstructionsWithPath)return;const e=N.forFillingPath(t,this.state,()=>this.currentInstructionsWithPath);this.state=e.state,this.incorporateDrawingInstruction(e)}strokePath(){if(!this.currentInstructionsWithPath)return;const t=N.forStrokingPath(e=>{e.stroke()},this.state,()=>this.currentInstructionsWithPath);this.state=t.state,this.incorporateDrawingInstruction(t)}fillRect(t,e,n,i,s){const o=N.forFillingPath(s,this.state,a=>{const c=ct.create(a);return c.rect(t,e,n,i,a),c});this.incorporateDrawingInstruction(o)}strokeRect(t,e,n,i){const s=N.forStrokingPath(o=>{o.stroke()},this.state,o=>{const a=ct.create(o);return a.rect(t,e,n,i,o),a});this.incorporateDrawingInstruction(s)}addDrawing(t,e,n,i,s){const o=this.state.currentlyTransformed(!1);n===F.Relative&&(e=e.transform(this.state.current.transformation));let a;s&&(a=o.withCurrentState(s(o.current))),this.incorporateDrawingInstruction(new N(t,e,c=>Z.create(o,c),i,n,o,a))}clipPath(t){this.clipCurrentPath(t)}incorporateDrawingInstruction(t){const e=t.getDrawnArea();if(e===y)return;const n=t.getModifiedInstruction();if(this.currentInstructionsWithPath){const i=this.currentInstructionsWithPath.recreatePath();this.addToPreviousInstructions(n,e,t.build),i.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state),this.currentInstructionsWithPath=i}else this.addToPreviousInstructions(n,e,t.build),this.state=this.previousInstructionsWithPath.state;this.onChange()}addToPreviousInstructions(t,e,n){const i=new $i(n(t),e);i.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state),this.previousInstructionsWithPath.add(i)}clipCurrentPath(t){this.currentInstructionsWithPath&&(this.currentInstructionsWithPath.clipPath(t,this.state),this.state=this.currentInstructionsWithPath.state)}addPathInstruction(t){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.addPathInstruction(t,this.state)}closePath(){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.closePath()}moveTo(t){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.moveTo(t,this.state)}canAddLineTo(t){return!this.currentInstructionsWithPath||this.currentInstructionsWithPath.canAddLineTo(t,this.state)}lineTo(t){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.lineTo(t,this.state)}rect(t,e,n,i){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.rect(t,e,n,i,this.state)}intersects(t){return this.previousInstructionsWithPath.intersects(t)}clearContentsInsideArea(t){this.previousInstructionsWithPath.clearContentsInsideArea(t),this.currentInstructionsWithPath&&this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state)}clearArea(t,e,n,i){if(!Xt(t,e,n,i))return;const s=Pn(t,e,n,i)?pt:m.createRectangle(t,e,n,i),o=s.transform(this.state.current.transformation);this.intersects(o)&&(this.clearContentsInsideArea(o),this.previousInstructionsWithPath.hasDrawingAcrossBorderOf(o)&&(this.previousInstructionsWithPath.addClearRect(s,this.state,t,e,n,i),this.currentInstructionsWithPath&&this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.state)),this.onChange())}execute(t,e){this.previousInstructionsWithPath.length&&this.previousInstructionsWithPath.execute(t,e);const i=this.previousInstructionsWithPath.state.stack.length;for(let s=0;sthis.draw())}get width(){return this.rectangleManager.rectangle.viewboxWidth}get height(){return this.rectangleManager.rectangle.viewboxHeight}get state(){return this.instructionSet.state}get transformation(){return this.rectangleManager.rectangle.userTransformation}set transformation(t){this.rectangleManager.setTransformation(t),this.draw()}getDrawingLock(){return this.drawLockProvider()}changeState(t){this.instructionSet.changeState(t)}measureText(t){this.context.save(),R.default.getInstructionToConvertToStateOnDimensions(this.state.currentlyTransformed(!1).current,Si)(this.context);const n=this.context.measureText(t);return this.context.restore(),n}saveState(){this.instructionSet.saveState()}restoreState(){this.instructionSet.restoreState()}beginPath(){this.instructionSet.beginPath()}async createPatternFromImageData(t){const e=await createImageBitmap(t);return this.context.createPattern(e,"no-repeat")}addDrawing(t,e,n,i,s){this.instructionSet.addDrawing(t,e,n,i,s)}addPathInstruction(t){this.instructionSet.addPathInstruction(t)}closePath(){this.instructionSet.currentSubpathIsClosable()&&this.instructionSet.closePath()}moveTo(t){this.instructionSet.moveTo(t)}lineTo(t){this.instructionSet.canAddLineTo(t)&&this.instructionSet.lineTo(t)}rect(t,e,n,i){this.instructionSet.rect(t,e,n,i)}currentPathCanBeFilled(){return this.instructionSet.allSubpathsAreClosable()&&this.instructionSet.currentPathSurroundsFinitePoint()}fillPath(t){this.instructionSet.fillPath(t)}strokePath(){this.instructionSet.strokePath()}fillRect(t,e,n,i,s){Xt(t,e,n,i)&&this.instructionSet.fillRect(t,e,n,i,s)}strokeRect(t,e,n,i){!Xt(t,e,n,i)||Pn(t,e,n,i)||this.instructionSet.strokeRect(t,e,n,i)}clipPath(t){this.instructionSet.clipPath(t)}clearArea(t,e,n,i){this.instructionSet.clearArea(t,e,n,i)}createLinearGradient(t,e,n,i){return new Li(this.context,t,e,n,i)}createRadialGradient(t,e,n,i,s,o){return new Ei(this.context,t,e,n,i,s,o)}createConicGradient(t,e,n){return new Zi(this.context,t,e,n)}createPattern(t,e){let n;return n=new qe(this.context.createPattern(t,e)),n}draw(){this.drawingIterationProvider.provideDrawingIteration(()=>(this.isTransforming()||this.rectangleManager.measure(),this.rectangleManager.rectangle?(this.context.restore(),this.context.save(),this.context.clearRect(0,0,this.width,this.height),this.setInitialTransformation(),this.instructionSet.execute(this.context,this.rectangleManager.rectangle),!0):!1))}setInitialTransformation(){const t=this.rectangleManager.rectangle.initialBitmapTransformation;if(t.equals(v.identity))return;const{a:e,b:n,c:i,d:s,e:o,f:a}=t;this.context.setTransform(e,n,i,s,o,a)}}class ts{constructor(t,e){this.context=e,this.initialTransformation=e.transformation,this.angularVelocity=Math.PI/100,this.point=t.onMoved(()=>{this.setTransformation()},!1)}setTransformation(){this.context.transformation=this.initialTransformation.before(v.rotation(this.point.initial.x,this.point.initial.y,(this.point.initial.x-this.point.current.x)*this.angularVelocity))}withAnchor(t){return this}withoutAnchor(t){this.point.cancel()}end(){this.point.cancel()}}class es{constructor(t,e,n,i,s){this.transformable=t,this.centerX=e,this.centerY=n,this.onFinish=s,this.initialTransformation=t.transformation,this.maxScaleLogStep=.1,this.currentScaleLog=0,this.targetScaleLog=Math.log(i),this.makeStep()}makeStep(){const t=this.targetScaleLog-this.currentScaleLog;Math.abs(t)<=this.maxScaleLogStep?(this.currentScaleLog+=t,this.setTransformToCurrentScaleLog(),this.onFinish()):(this.currentScaleLog+=t<0?-this.maxScaleLogStep:this.maxScaleLogStep,this.setTransformToCurrentScaleLog(),this.stepTimeout=setTimeout(()=>this.makeStep(),20))}setTransformToCurrentScaleLog(){this.transformable.transformation=this.initialTransformation.before(v.zoom(this.centerX,this.centerY,Math.exp(this.currentScaleLog)))}cancel(){this.stepTimeout!==void 0&&clearTimeout(this.stepTimeout)}}class ns{constructor(t,e){this.anchor=t,this.context=e,this.initialTransformation=e.transformation,this.point=t.onMoved(()=>{this.setTransformation()},!0)}setTransformation(){this.context.transformation=this.initialTransformation.before(this.getTranslation())}getTranslation(){return v.translation(this.point.current.x-this.point.initial.x,this.point.current.y-this.point.initial.y)}withAnchor(t){return t===this.anchor?this:this.context.getGestureForTwoAnchors(this.point.cancel(),t)}withoutAnchor(t){this.point.cancel()}}class Cn{constructor(t,e,n){this.context=n,this.initialTransformation=n.transformation,this.point1=t.onMoved(()=>this.setTransformation(),this.fixesFirstAnchorOnInfiniteCanvas()),this.point2=e.onMoved(()=>this.setTransformation(),this.fixesSecondAnchorOnInfiniteCanvas())}withAnchor(t){return this}withoutAnchor(t){const e=this.point1.cancel(),n=this.point2.cancel();if(t===e)return this.context.getGestureForOneAnchor(n);if(t===n)return this.context.getGestureForOneAnchor(e)}}class is extends Cn{constructor(t,e,n){super(t,e,n)}fixesFirstAnchorOnInfiniteCanvas(){return!0}fixesSecondAnchorOnInfiniteCanvas(){return!1}setTransformation(){this.context.transformation=this.initialTransformation.before(v.translateZoom(this.point1.initial.x,this.point1.initial.y,this.point2.initial.x,this.point2.initial.y,this.point1.current.x,this.point1.current.y,this.point2.current.x,this.point2.current.y))}}class ss extends Cn{constructor(t,e,n){super(t,e,n)}fixesFirstAnchorOnInfiniteCanvas(){return!0}fixesSecondAnchorOnInfiniteCanvas(){return!0}setTransformation(){this.context.transformation=this.initialTransformation.before(v.translateRotateZoom(this.point1.initial.x,this.point1.initial.y,this.point2.initial.x,this.point2.initial.y,this.point1.current.x,this.point1.current.y,this.point2.current.x,this.point2.current.y))}}class St{constructor(){this.mapped=[]}onRemoved(t){}add(t){this.mapped.some(e=>this.mapsTo(e,t))||this.mapped.push(this.map(t))}remove(t){const e=this.mapped.findIndex(i=>this.mapsTo(i,t));if(e===-1)return;const[n]=this.mapped.splice(e,1);this.onRemoved(n)}}class $ extends St{map(t){return t}mapsTo(t,e){return t.listener===e.listener}onRemoved(t){t.removedCallback&&t.removedCallback()}addListener(t,e){this.add({listener:t,removedCallback:e})}removeListener(t){this.remove({listener:t})}dispatch(t){const e=this.mapped.map(n=>n.listener);for(let n of e)n(t)}}class rs{constructor(t,e){this.setNewValue=t,this.timeoutInMs=e,this._changing=!1,this._firstChange=new $,this._subsequentChange=new $,this._changeEnd=new $}get firstChange(){return this._firstChange}get subsequentChange(){return this._subsequentChange}get changeEnd(){return this._changeEnd}get changing(){return this._changing}refreshTimeout(){this.currentTimeout!==void 0&&clearTimeout(this.currentTimeout),this.currentTimeout=setTimeout(()=>{this._changing=!1,this.currentTimeout=void 0,this._changeEnd.dispatch()},this.timeoutInMs)}setValue(t){this.setNewValue(t),this._changing||(this._changing=!0,this._firstChange.dispatch()),this._subsequentChange.dispatch(),this.refreshTimeout()}}class os{constructor(t,e){this.viewBox=t,this.config=e,this._transformationChangeMonitor=new rs(n=>this.viewBox.transformation=n,100)}get isTransforming(){return this._transformationChangeMonitor.changing}get transformationStart(){return this._transformationChangeMonitor.firstChange}get transformationChange(){return this._transformationChangeMonitor.subsequentChange}get transformationEnd(){return this._transformationChangeMonitor.changeEnd}get transformation(){return this.viewBox.transformation}set transformation(t){this._transformationChangeMonitor.setValue(t)}getGestureForOneAnchor(t){return new ns(t,this)}getGestureForTwoAnchors(t,e){return this.config.rotationEnabled?new ss(t,e,this):new is(t,e,this)}releaseAnchor(t){this.gesture&&(this.gesture=this.gesture.withoutAnchor(t))}zoom(t,e,n){this._zoom&&this._zoom.cancel(),this._zoom=new es(this,t,e,n,()=>{this._zoom=void 0})}addRotationAnchor(t){this.gesture=new ts(t,this)}addAnchor(t){if(!this.gesture){this.gesture=this.getGestureForOneAnchor(t);return}const e=this.gesture.withAnchor(t);e&&(this.gesture=e)}}class as{constructor(){this.animationFrameRequested=!1}provideDrawingIteration(t){this.animationFrameRequested||(this.animationFrameRequested=!0,requestAnimationFrame(()=>{t(),this.animationFrameRequested=!1}))}}class cs{constructor(t){this.drawingIterationProvider=t,this._drawHappened=new $}get drawHappened(){return this._drawHappened}provideDrawingIteration(t){this.drawingIterationProvider.provideDrawingIteration(()=>{const e=t();return e&&this._drawHappened.dispatch(),e})}}class hs{constructor(t){this.drawingIterationProvider=t,this._locks=[]}removeLock(t){const e=this._locks.indexOf(t);this._locks.splice(e,1),this._locks.length===0&&this._draw&&this.drawingIterationProvider.provideDrawingIteration(this._draw)}provideDrawingIteration(t){this._locks.length?this._draw=t:this.drawingIterationProvider.provideDrawingIteration(t)}getLock(){let t;return t={release:()=>{this.removeLock(t)}},this._locks.push(t),t}}var S=(r=>(r[r.CSS=0]="CSS",r[r.CANVAS=1]="CANVAS",r))(S||{});class x{constructor(t){this.base=t,this.inverseBase=t.inverse()}getSimilarTransformation(t){return this.inverseBase.before(t).before(this.base)}representSimilarTransformation(t){return this.base.before(t).before(this.inverseBase)}representBase(t){return t.before(this.inverseBase)}}class yt{constructor(t,e,n){this.userCoordinates=t,this.canvasBitmap=e,this.virtualBitmapBase=n,this.setDerivedProperties()}withCanvasBitmapDistortion(t){const e=this.canvasBitmap.representBase(t),n=this.userCoordinates.representSimilarTransformation(e),i=this.virtualBitmapBase.before(n),s=new x(t);return new yt(this.userCoordinates,s,i)}withUserTransformation(t){return new yt(new x(t),this.canvasBitmap,this.virtualBitmapBase)}setDerivedProperties(){this.infiniteCanvasContext=new x(this.virtualBitmapBase.before(this.userCoordinates.base)),this.userCoordinatesInsideCanvasBitmap=new x(this.userCoordinates.base.before(this.canvasBitmap.base)),this.initialBitmapTransformation=this.canvasBitmap.representBase(this.userCoordinates.getSimilarTransformation(this.virtualBitmapBase)),this.icContextFromCanvasBitmap=new x(this.infiniteCanvasContext.base.before(this.canvasBitmap.inverseBase))}}class bt{constructor(t,e){this.userCoordinates=t,this.canvasBitmap=e,this.setDerivedProperties()}get infiniteCanvasContext(){return this.userCoordinates}withUserTransformation(t){return new bt(new x(t),this.canvasBitmap)}withCanvasBitmapDistortion(t){return new bt(this.userCoordinates,new x(t))}setDerivedProperties(){this.userCoordinatesInsideCanvasBitmap=new x(this.userCoordinates.base.before(this.canvasBitmap.base)),this.initialBitmapTransformation=this.canvasBitmap.inverseBase,this.icContextFromCanvasBitmap=new x(this.userCoordinates.base.before(this.canvasBitmap.inverseBase))}}function In(r){const{screenWidth:t,screenHeight:e,viewboxWidth:n,viewboxHeight:i}=r;return new v(t/n,0,0,e/i,0,0)}class ht{constructor(t,e){this.units=t,this.coordinates=e}get userTransformation(){return this.coordinates.userCoordinates.base}get infiniteCanvasContext(){return this.coordinates.infiniteCanvasContext}get initialBitmapTransformation(){return this.coordinates.initialBitmapTransformation}getBitmapTransformationToTransformedInfiniteCanvasContext(){return this.coordinates.userCoordinates.base}getBitmapTransformationToInfiniteCanvasContext(){return this.coordinates.icContextFromCanvasBitmap.base}translateInfiniteCanvasContextTransformationToBitmapTransformation(t){return this.coordinates.icContextFromCanvasBitmap.getSimilarTransformation(v.create(t))}getTransformationForInstruction(t){const e=v.create(t).before(this.coordinates.infiniteCanvasContext.base),n=this.coordinates.userCoordinatesInsideCanvasBitmap.representBase(e);return this.coordinates.userCoordinates.getSimilarTransformation(n)}withUserTransformation(t){const e=this.coordinates.withUserTransformation(t);return new ht(this.units,e)}withCanvasMeasurement(t){const e=In(t),n=this.coordinates.withCanvasBitmapDistortion(e);return new ht(this.units,n)}withUnits(t){if(t===this.units)return this;let e;return t===S.CANVAS?e=new yt(this.coordinates.userCoordinates,this.coordinates.canvasBitmap,this.coordinates.canvasBitmap.base):e=new bt(this.coordinates.userCoordinates,this.coordinates.canvasBitmap),new ht(t,e)}static create(t,e){const n=In(e),i=t===S.CANVAS?new yt(new x(v.identity),new x(n),n):new bt(new x(v.identity),new x(n));return new ht(t,i)}}function ls(r,t){return r?t?r.viewboxWidth===t.viewboxWidth&&r.viewboxHeight===t.viewboxHeight&&r.screenWidth===t.screenWidth&&r.screenHeight===t.screenHeight:!1:!t}class lt{constructor(t,e,n){this.coordinates=t,this.measurement=e,this.polygon=n}get viewboxWidth(){return this.measurement.viewboxWidth}get viewboxHeight(){return this.measurement.viewboxHeight}get userTransformation(){return this.coordinates.userTransformation}get infiniteCanvasContext(){return this.coordinates.infiniteCanvasContext}get initialBitmapTransformation(){return this.coordinates.initialBitmapTransformation}withUnits(t){const e=this.coordinates.withUnits(t);return new lt(e,this.measurement,this.polygon)}withTransformation(t){const e=this.coordinates.withUserTransformation(v.create(t));return new lt(e,this.measurement,this.polygon)}withMeasurement(t){if(ls(this.measurement,t))return this;const{viewboxWidth:n,viewboxHeight:i}=t,s=m.createRectangle(0,0,n,i),o=this.coordinates.withCanvasMeasurement(t);return new lt(o,t,s)}getCSSPosition(t,e){const{left:n,top:i}=this.measurement;return new h(t-n,e-i)}getTransformationForInstruction(t){return this.coordinates.getTransformationForInstruction(t)}translateInfiniteCanvasContextTransformationToBitmapTransformation(t){return this.coordinates.translateInfiniteCanvasContextTransformationToBitmapTransformation(t)}getBitmapTransformationToTransformedInfiniteCanvasContext(){return this.coordinates.getBitmapTransformationToTransformedInfiniteCanvasContext()}getBitmapTransformationToInfiniteCanvasContext(){return this.coordinates.getBitmapTransformationToInfiniteCanvasContext()}addPathAroundViewbox(t,e){const n=this.viewboxWidth+2*e,i=this.viewboxHeight+2*e;t.save(),t.setTransform(1,0,0,1,0,0),t.rect(-e,-e,n,i),t.restore()}static create(t,e){const{viewboxWidth:n,viewboxHeight:i}=t,s=m.createRectangle(0,0,n,i),o=ht.create(e,t);return new lt(o,t,s)}}class us{constructor(t,e){this.measurementProvider=t,this.config=e,this.transformation=v.identity}setTransformation(t){this.rectangle?this.rectangle=this.rectangle.withTransformation(t):this.transformation=t}measure(){const t=this.config.units===S.CSS?S.CSS:S.CANVAS,e=this.measurementProvider.measure();e.screenWidth===0||e.screenHeight===0?this.rectangle=void 0:this.rectangle?this.rectangle=this.rectangle.withUnits(t).withMeasurement(e):this.rectangle=lt.create(e,t).withTransformation(this.transformation)}}class ds{constructor(t){this.canvas=t}measure(){const t=this.canvas.getBoundingClientRect();return{left:t.left,top:t.top,screenWidth:t.width,screenHeight:t.height,viewboxWidth:this.canvas.width,viewboxHeight:this.canvas.height}}}function ut(r){const{a:t,b:e,c:n,d:i,e:s,f:o}=r;return{a:t,b:e,c:n,d:i,e:s,f:o}}const fs={transformationstart:null,transformationchange:null,transformationend:null},Tn={auxclick:null,click:null,contextmenu:null,dblclick:null,mouseenter:null,mouseleave:null,mouseout:null,mouseover:null,mouseup:null},Sn={gotpointercapture:null,lostpointercapture:null,pointerenter:null,pointerout:null,pointerover:null},yn={drag:null,dragend:null,dragenter:null,dragleave:null,dragover:null,dragstart:null,drop:null},bn={touchcancel:null,touchend:null},gs={...Tn,...Sn,...yn,...bn},xn={mousedown:null,mousemove:null,pointerdown:null,pointermove:null,pointerleave:null,pointercancel:null,pointerup:null,wheel:null,touchstart:null,touchmove:null,wheelignored:null,touchignored:null};function Yt(r){return fs.hasOwnProperty(r)}function Ut(r){return gs.hasOwnProperty(r)||xn.hasOwnProperty(r)}function zt(r){return xn.hasOwnProperty(r)}function $t(r){return Tn.hasOwnProperty(r)}function Kt(r){return Sn.hasOwnProperty(r)}function jt(r){return yn.hasOwnProperty(r)}function Qt(r){return bn.hasOwnProperty(r)}class ms extends St{constructor(t){super(),this.source=t}map(t){const e=()=>{this.remove(t),t.removedCallback&&t.removedCallback()};return this.source.addListener(t.listener,e),{listener:t.listener,removedCallback:e}}mapsTo(t,e){return t.listener===e.listener}onRemoved(t){t.removedCallback(),this.source.removeListener(t.listener)}addListener(t,e){this.add({listener:t,removedCallback:e})}removeListener(t){this.remove({listener:t})}}class vs extends St{constructor(t,e){super(),this.transform=e,this.old=new ms(t)}map(t){const e={oldListener:void 0,newListener:t.listener,removedCallback:()=>{t.removedCallback&&t.removedCallback()}};return e.oldListener=this.transform(t.listener,n=>e.removedCallback=()=>{t.removedCallback&&t.removedCallback(),n()}),this.old.addListener(e.oldListener,()=>this.removeListener(t.listener)),e}mapsTo(t,e){return t.newListener===e.listener}onRemoved(t){this.old.removeListener(t.oldListener),t.removedCallback()}addListener(t,e){this.add({listener:t,removedCallback:e})}removeListener(t){this.remove({listener:t})}}function et(r,t){return new vs(r,t)}function M(r,t){return et(r,e=>n=>{e(t(n))})}function Jt(r){return!!r&&typeof r.handleEvent=="function"}class ps extends St{constructor(t){super(),this.source=t}mapsTo(t,e){return t.listenerObject===e.listenerObject}map(t){const{listenerObject:e,removedCallback:n}=t,i=o=>{e.handleEvent(o)},s=()=>{this.remove(t),n&&n()};return this.source.addListener(i,s),{listener:i,listenerObject:e,removedCallback:s}}onRemoved(t){this.source.removeListener(t.listener),t.removedCallback()}}class ws{constructor(t){this.source=t,this.listenerObjectCollection=new ps(t)}addListener(t,e){Jt(t)?this.listenerObjectCollection.add({listenerObject:t,removedCallback:e}):this.source.addListener(t,e)}removeListener(t){Jt(t)?this.listenerObjectCollection.remove({listenerObject:t}):this.source.removeListener(t)}}function On(r){return new ws(r)}function Ps(r,t,e){Jt(t),r.addListener(t,e)}function Cs(r,t,e){Jt(t),r.removeListener(t,e)}function Is(r){const t=et(r,e=>n=>{e(n),t.removeListener(e)});return t}function Ts(r,t){return et(r,e=>n=>{e.apply(t,[n])})}class Ss{constructor(t){this.source=t,this.firstDispatcher=new $,this.secondDispatcher=new $,this.numberOfListeners=0,this.sourceListener=e=>this.dispatchEvent(e)}add(){this.numberOfListeners===0&&this.source.addListener(this.sourceListener),this.numberOfListeners++}remove(){this.numberOfListeners--,this.numberOfListeners===0&&this.source.removeListener(this.sourceListener)}dispatchEvent(t){this.firstDispatcher.dispatch(t),this.secondDispatcher.dispatch(t)}build(){return{first:et(this.firstDispatcher,(t,e)=>(this.add(),e(()=>this.remove()),t)),second:et(this.secondDispatcher,(t,e)=>(this.add(),e(()=>this.remove()),t))}}}function Bn(r){return new Ss(r).build()}function V(r,t){return et(r,e=>n=>{t(n)&&e(n)})}class An{constructor(t,e){t=Ts(t,e),this._onceSource=On(Is(t)),this.source=On(t)}addListener(t,e){e&&e.once?this._onceSource.addListener(t):this.source.addListener(t)}removeListener(t){this.source.removeListener(t),this._onceSource.removeListener(t)}}class ys{constructor(t,e){this.captureSource=t,this.bubbleSource=e}get on(){return this.onEventHandler}set on(t){t?(this.wrappedOnEventHandler=function(e){return t.apply(this,[e])},this.onEventHandler=t,this.bubbleSource.addListener(this.wrappedOnEventHandler)):(this.bubbleSource.removeListener(this.wrappedOnEventHandler),this.wrappedOnEventHandler=null,this.onEventHandler=null)}addListener(t,e){const n=e&&(typeof e=="boolean"?void 0:e);(typeof e=="boolean"?e:e&&e.capture)?this.captureSource.addListener(t,n):this.bubbleSource.addListener(t,n)}removeListener(t,e){(typeof e=="boolean"?e:e&&e.capture)?this.captureSource.removeListener(t):this.bubbleSource.removeListener(t)}}function bs(r,t,e){return new ys(new An(r,e),new An(t,e))}function nt(r,t,e,n){const i=M(V(r,o=>!o.immediatePropagationStopped),o=>o.getResultEvent(e.rectangle)),s=M(V(t,o=>!o.propagationStopped&&!o.immediatePropagationStopped),o=>o.getResultEvent(e.rectangle));return bs(i,s,n)}function it(r){const{first:t,second:e}=Bn(r),{first:n,second:i}=Bn(e);return{captureSource:t,bubbleSource:n,afterBubble:i}}function xs(r,t,e){const{captureSource:n,bubbleSource:i}=it(r);return nt(n,i,t,e)}class ye{constructor(t,e){this.rectangleManager=t,this.infiniteCanvas=e,this.cache={}}map(t,e){return xs(M(t,e),this.rectangleManager,this.infiniteCanvas)}setOn(t,e){if(e)this.cache[t]||(this.cache[t]=this.getEventSource(t)),this.cache[t].on=e;else{if(!this.cache[t])return;this.cache[t].on=null}}getOn(t){return this.cache[t]?this.cache[t].on:null}addEventListener(t,e,n){this.cache[t]||(this.cache[t]=this.getEventSource(t)),Ps(this.cache[t],e,n)}removeEventListener(t,e,n){this.cache[t]&&Cs(this.cache[t],e,n)}}class Dn extends ye{getEventSource(t){return(!this.cache||!this.cache[t])&&(this.cache=this.createEvents()),this.cache[t]}}class Ln{constructor(t,e){this.canvasEvent=t,this.preventableDefault=e}get bubbles(){return!1}get isTrusted(){return!1}get eventPhase(){return Event.AT_TARGET}get cancelable(){return this.preventableDefault.cancelable}get defaultPrevented(){return this.preventableDefault.defaultPrevented}get AT_TARGET(){return Event.AT_TARGET}get BUBBLING_PHASE(){return Event.BUBBLING_PHASE}get CAPTURING_PHASE(){return Event.CAPTURING_PHASE}get NONE(){return Event.NONE}initEvent(t,e,n){}preventDefault(){this.preventableDefault.preventDefault()}stopImmediatePropagation(){this.canvasEvent.stopImmediatePropagation()}stopPropagation(){this.canvasEvent.stopPropagation()}}class be extends Ln{constructor(t,e,n){super(t,e),this.type=n}get cancelBubble(){return!1}get composed(){return!1}get currentTarget(){return null}get returnValue(){return!0}get srcElement(){return null}get target(){return null}get timeStamp(){return 0}composedPath(){return[]}}class En{constructor(t){this.preventableDefault=t,this.propagationStopped=!1,this.immediatePropagationStopped=!1}get infiniteCanvasDefaultPrevented(){return this.preventableDefault.infiniteCanvasDefaultPrevented}stopPropagation(){this.propagationStopped=!0}stopImmediatePropagation(){this.immediatePropagationStopped=!0}getResultEvent(t){return this.resultEvent||(this.resultEvent=this.createResultEvent(t)),this.resultEvent}}class Os{get defaultPrevented(){return this._defaultPrevented}get infiniteCanvasDefaultPrevented(){return this._defaultPrevented}get cancelable(){return!0}preventDefault(){this._defaultPrevented=!0}}class Bs{get infiniteCanvasDefaultPrevented(){return!1}get defaultPrevented(){return!1}get cancelable(){return!1}preventDefault(){}}class xe extends En{constructor(t){super(t?new Os:new Bs)}}class As extends be{constructor(t,e){super(t,e,"draw"),this.transformation=t.transformation,this.inverseTransformation=t.inverseTransformation}}class Ds extends xe{constructor(){super(!1)}createResultEvent(t){return this.transformation=ut(t.infiniteCanvasContext.inverseBase),this.inverseTransformation=ut(t.infiniteCanvasContext.base),new As(this,this.preventableDefault)}}class Ls extends Dn{constructor(t,e,n){super(e,n),this.drawingIterationProvider=t}createEvents(){return{draw:this.map(this.drawingIterationProvider.drawHappened,()=>new Ds)}}}class Es extends be{constructor(t,e,n){super(t,e,n),this.transformation=t.transformation,this.inverseTransformation=t.inverseTransformation}}class Oe extends xe{constructor(t){super(!1),this.type=t}createResultEvent(t){return this.transformation=ut(t.infiniteCanvasContext.inverseBase),this.inverseTransformation=ut(t.infiniteCanvasContext.base),new Es(this,this.preventableDefault,this.type)}}class Fs extends Dn{constructor(t,e,n){super(e,n),this.transformer=t}createEvents(){return{transformationstart:this.map(this.transformer.transformationStart,()=>new Oe("transformationstart")),transformationchange:this.map(this.transformer.transformationChange,()=>new Oe("transformationchange")),transformationend:this.map(this.transformer.transformationEnd,()=>new Oe("transformationend"))}}}function E(r,t){return{addListener(e){r.addEventListener(t,e)},removeListener(e){r.removeEventListener(t,e)}}}class Ws{constructor(t){this.event=t}get infiniteCanvasDefaultPrevented(){return!1}get nativeDefaultPrevented(){return this.event.defaultPrevented}get nativeCancelable(){return this.event.cancelable}get defaultPrevented(){return this.event.defaultPrevented}get cancelable(){return this.event.cancelable}preventDefault(){this.event.preventDefault()}}class ks{constructor(t){this.event=t}get infiniteCanvasDefaultPrevented(){return this._defaultPrevented}get nativeDefaultPrevented(){return this.event.defaultPrevented}get nativeCancelable(){return this.event.cancelable}get defaultPrevented(){return this._defaultPrevented}get cancelable(){return!0}preventDefault(t){this._defaultPrevented=!0,t&&this.event.preventDefault()}}class dt extends En{constructor(t,e){super(e?new ks(t):new Ws(t)),this.event=t}stopPropagation(){super.stopPropagation(),this.event&&this.event.stopPropagation()}stopImmediatePropagation(){super.stopImmediatePropagation(),this.event&&this.event.stopImmediatePropagation()}}class st{constructor(t,e,n,i){this.offsetX=t,this.offsetY=e,this.movementX=n,this.movementY=i}toInfiniteCanvasCoordinates(t){const{x:e,y:n}=t.infiniteCanvasContext.inverseBase.apply(new h(this.offsetX,this.offsetY)),{x:i,y:s}=t.infiniteCanvasContext.inverseBase.untranslated().apply(new h(this.movementX,this.movementY));return new st(e,n,i,s)}static create(t){return new st(t.offsetX,t.offsetY,t.movementX,t.movementY)}}class Rs extends Ln{constructor(t,e,n){super(t,e),this.event=n}get nativeDefaultPrevented(){return this.preventableDefault.nativeDefaultPrevented}get nativeCancelable(){return this.preventableDefault.nativeCancelable}get cancelBubble(){return this.event.cancelBubble}get composed(){return this.event.composed}get currentTarget(){return this.event.currentTarget}get returnValue(){return this.event.returnValue}get srcElement(){return this.event.srcElement}get target(){return this.event.target}get timeStamp(){return this.event.timeStamp}get type(){return this.event.type}preventDefault(t){this.preventableDefault.preventDefault(t)}composedPath(){return this.event.composedPath()}}class Fn extends Rs{get detail(){return this.event.detail}get view(){return this.event.view}get which(){return this.event.which}initUIEvent(t,e,n,i,s){}}class Zt extends Fn{constructor(t,e,n,i){super(t,e,n),this.offsetX=i.offsetX,this.offsetY=i.offsetY,this.movementX=i.movementX,this.movementY=i.movementY}get altKey(){return this.event.altKey}get button(){return this.event.button}get buttons(){return this.event.buttons}get clientX(){return this.event.clientX}get clientY(){return this.event.clientY}get ctrlKey(){return this.event.ctrlKey}get metaKey(){return this.event.metaKey}get pageX(){return this.event.pageX}get pageY(){return this.event.pageY}get relatedTarget(){return this.event.relatedTarget}get screenX(){return this.event.screenX}get screenY(){return this.event.screenY}get shiftKey(){return this.event.shiftKey}get x(){return this.event.x}get y(){return this.event.y}getModifierState(t){return this.event.getModifierState(t)}initMouseEvent(t,e,n,i,s,o,a,c,l,d,u,g,w,P,O){}}class Be extends dt{constructor(t,e){super(t,e),this.props=st.create(t)}createResultEvent(t){return new Zt(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}class _t extends st{constructor(t,e,n,i,s,o){super(t,e,n,i),this.width=s,this.height=o}toInfiniteCanvasCoordinates(t){const{offsetX:e,offsetY:n,movementX:i,movementY:s}=super.toInfiniteCanvasCoordinates(t),{x:o,y:a}=t.infiniteCanvasContext.inverseBase.untranslated().apply(new h(this.width,this.height));return new _t(e,n,i,s,o,a)}static create(t){const{offsetX:e,offsetY:n,movementX:i,movementY:s}=super.create(t);return new _t(e,n,i,s,t.width,t.height)}}class Ns extends Zt{constructor(t,e,n,i){super(t,e,n,i)}get isPrimary(){return this.event.isPrimary}get pointerId(){return this.event.pointerId}get pointerType(){return this.event.pointerType}get pressure(){return this.event.pressure}get tangentialPressure(){return this.event.tangentialPressure}get tiltX(){return this.event.tiltX}get tiltY(){return this.event.tiltY}get twist(){return this.event.twist}getCoalescedEvents(){return console.warn("`PointerEvent.getCoalescedEvents()` is currently not supported by InfiniteCanvas"),[]}getPredictedEvents(){return console.warn("`PointerEvent.getPredictedEvents()` is currently not supported by InfiniteCanvas"),[]}}class ft extends dt{constructor(t,e){super(t,e),this.props=_t.create(t)}createResultEvent(t){return new Ns(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}class Ms{constructor(t,e){this.initial=t,this.cancel=e,this.current=t}}class Vs{constructor(t){this.point=t,this.moveEventDispatcher=new $,this._fixedOnInfiniteCanvas=!1}get fixedOnInfiniteCanvas(){return this._fixedOnInfiniteCanvas}removeHandler(t){this.moveEventDispatcher.removeListener(t)}moveTo(t,e){const n=new h(t,e);this.point=n,this.moveEventDispatcher.dispatch(n)}onMoved(t,e){let n;this._fixedOnInfiniteCanvas=e;const i=s=>{n.current=s,t()};return this.moveEventDispatcher.addListener(i),n=new Ms(this.point,()=>(this.removeHandler(i),this._fixedOnInfiniteCanvas=!1,this)),n}}class Hs{constructor(t){this.pointerEvent=t,this._defaultPrevented=!1,this.anchor=new Vs(new h(t.offsetX,t.offsetY))}get defaultPrevented(){return this._defaultPrevented}get touchId(){return this._touchId}get pointerId(){return this.pointerEvent.pointerId}preventDefault(){this._defaultPrevented=!0}setTouchId(t){this._touchId=t}updatePointerEvent(t){this.pointerEvent=t,this.anchor.moveTo(t.offsetX,t.offsetY)}}class qs{constructor(){this.anchors=[]}find(t){return this.anchors.find(t)}getAll(t){return this.anchors.filter(t)}getAnchorForTouch(t){return this.anchors.find(e=>e.touchId===t)}addAnchorForPointerEvent(t){const e=new Hs(t);this.anchors.push(e)}updateAnchorForPointerEvent(t){const e=this.getAnchorForPointerEvent(t);if(!e){this.addAnchorForPointerEvent(t);return}e.updatePointerEvent(t)}getAnchorForPointerEvent(t){return this.anchors.find(e=>e.pointerId===t.pointerId)}removeAnchor(t){const e=this.anchors.findIndex(n=>n===t);e>-1&&this.anchors.splice(e,1)}}class te extends st{constructor(t,e,n,i,s,o){super(t,e,n,i),this.deltaX=s,this.deltaY=o}toInfiniteCanvasCoordinates(t){const{offsetX:e,offsetY:n,movementX:i,movementY:s}=super.toInfiniteCanvasCoordinates(t),{x:o,y:a}=t.infiniteCanvasContext.inverseBase.untranslated().apply(new h(this.deltaX,this.deltaY));return new te(e,n,i,s,o,a)}static create(t){const{offsetX:e,offsetY:n,movementX:i,movementY:s}=super.create(t);return new te(e,n,i,s,t.deltaX,t.deltaY)}}class Gs extends Zt{constructor(t,e,n,i){super(t,e,n,i),this.deltaX=i.deltaX,this.deltaY=i.deltaY}get deltaMode(){return this.event.deltaMode}get deltaZ(){return this.event.deltaZ}get DOM_DELTA_LINE(){return this.event.DOM_DELTA_LINE}get DOM_DELTA_PAGE(){return this.event.DOM_DELTA_PAGE}get DOM_DELTA_PIXEL(){return this.event.DOM_DELTA_PIXEL}}class Xs extends dt{constructor(t,e){super(t,e),this.props=te.create(t)}createResultEvent(t){return new Gs(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}function gt(r,t){const e=[];for(let n=0;ni.identifier===t.identifier);return n||(n=t.toInfiniteCanvasCoordinates(e),this.translatedProps.push(n),n)}createProps(t,e){let n=this.createdProps.find(i=>i.identifier===t.identifier);return n||(n=ee.create(t,e),this.createdProps.push(n),n)}dispose(){this.translatedProps.splice(0,this.translatedProps.length),this.createdProps.splice(0,this.createdProps.length)}}class ne{constructor(t,e,n){this.targetTouches=t,this.changedTouches=e,this.touches=n}toInfiniteCanvasCoordinates(t){const e=new Wn,n=new ne(this.targetTouches.map(i=>e.toInfiniteCanvasCoordinates(i,t)),this.changedTouches.map(i=>e.toInfiniteCanvasCoordinates(i,t)),this.touches.map(i=>e.toInfiniteCanvasCoordinates(i,t)));return e.dispose(),n}static create(t,e,n){const i=new Wn,s=e.map(a=>i.createProps(a,t)),o=n.map(a=>i.createProps(a,t));return i.dispose(),new ne(s,o,s)}}class Ys{constructor(t,e){this.touch=t,this.infiniteCanvasX=e.x,this.infiniteCanvasY=e.y,this.radiusX=e.radiusX,this.radiusY=e.radiusY,this.rotationAngle=e.rotationAngle}get clientX(){return this.touch.clientX}get clientY(){return this.touch.clientY}get force(){return this.touch.force}get identifier(){return this.touch.identifier}get pageX(){return this.touch.pageX}get pageY(){return this.touch.pageY}get screenX(){return this.touch.screenX}get screenY(){return this.touch.screenY}get target(){return this.touch.target}}class Us extends Array{item(t){return this[t]}}function zs(r,t){const e=r.length;for(let n=0;n{s=o}),this.subscription=new kn(t,o=>{n([o,s])})}remove(){this.subscription.remove(),this.otherSubscription.remove(),this.onRemoved&&this.onRemoved()}}class Qs extends St{constructor(t,e){super(),this.source=t,this.otherSource=e}map(t){return new js(this.source,this.otherSource,t.listener,t.onRemoved)}mapsTo(t,e){return t.listener===e.listener}onRemoved(t){t.remove()}addListener(t,e){this.add({listener:t,onRemoved:e})}removeListener(t){this.remove({listener:t})}}function De(r,t){return new Qs(r,t)}function Js(r,t){for(let e=0;e{let n=!1;const i=[];function s(){n||i.length===0||(n=!0,t(i.shift()).addListener(e,()=>{n=!1,s()}))}return o=>{i.push(o),s()}})}class _s{constructor(t){this.sequence=t}addListener(t,e){for(const n of this.sequence)t(n);e&&e()}removeListener(t){}}function tr(r){return new _s(r)}class Rn extends xe{constructor(t){super(!0),this.type=t}createResultEvent(){return new be(this,this.preventableDefault,this.type)}}class er extends ye{constructor(t,e,n,i,s){super(n,i),this.transformer=e,this.config=s,this.anchorSet=new qs;const o=E(t,"pointerdown"),a=E(t,"pointerleave"),c=E(t,"pointermove"),l=E(t,"pointerup"),d=E(t,"pointercancel"),u=V(E(t,"touchmove"),f=>Js(f.targetTouches,b=>!this.hasFixedAnchorForTouch(b.identifier)));o.addListener(f=>this.anchorSet.updateAnchorForPointerEvent(f)),c.addListener(f=>this.anchorSet.updateAnchorForPointerEvent(f)),l.addListener(f=>this.removePointer(f)),a.addListener(f=>this.removePointer(f));const g=M(E(t,"mousedown"),f=>new Be(f,!0)),w=M(E(t,"wheel"),f=>new Xs(f,!0)),P=M(E(t,"touchstart"),f=>{const b=gt(f.targetTouches),q=gt(f.changedTouches);return xt.create(this.rectangleManager.rectangle,f,b,q,!0)}),O=M(o,f=>new ft(f,!0)),{captureSource:H,bubbleSource:K,afterBubble:rt}=it(O),{captureSource:Bt,bubbleSource:At,afterBubble:Dt}=it(g),{captureSource:Lt,bubbleSource:Fe,afterBubble:We}=it(P),{captureSource:ke,bubbleSource:ie,afterBubble:Vn}=it(w),dr=M(V(Vn,f=>!this.config.greedyGestureHandling&&!f.event.ctrlKey&&!f.infiniteCanvasDefaultPrevented),()=>new Rn("wheelignored")),{captureSource:fr,bubbleSource:gr,afterBubble:mr}=it(dr);Vn.addListener(f=>{f.infiniteCanvasDefaultPrevented||this.zoom(f.event)}),mr.addListener(f=>{f.infiniteCanvasDefaultPrevented||console.warn("use ctrl + scroll to zoom")}),De(Dt,rt).addListener(([f,b])=>{!f.infiniteCanvasDefaultPrevented&&!b.infiniteCanvasDefaultPrevented&&this.transformUsingPointer(f.event,b.event)});const vr=V(We,f=>f.event.changedTouches.length===1),Hn=De(vr,rt);Hn.addListener(([f,b])=>{const q=f.event.changedTouches[0],j=this.anchorSet.getAnchorForPointerEvent(b.event);if(j)if(j.setTouchId(q.identifier),!f.infiniteCanvasDefaultPrevented&&!b.infiniteCanvasDefaultPrevented)if(this.config.greedyGestureHandling)this.rectangleManager.measure(),this.transformer.addAnchor(j.anchor),f.event.preventDefault();else{const Gn=this.anchorSet.find(Re=>Re.touchId!==void 0&&Re!==j&&!Re.defaultPrevented);if(!Gn)return;this.rectangleManager.measure(),this.transformer.addAnchor(Gn.anchor),this.transformer.addAnchor(j.anchor),f.event.preventDefault()}else j.preventDefault()});const qn=V(De(d,Hn),([f,[b,q]])=>f.pointerId===q.event.pointerId);qn.addListener(([f])=>{this.removePointer(f)});const pr=M(V(qn,([f,[b,q]])=>!this.config.greedyGestureHandling&&!b.infiniteCanvasDefaultPrevented&&!q.infiniteCanvasDefaultPrevented),()=>new Rn("touchignored")),{captureSource:wr,bubbleSource:Pr,afterBubble:Cr}=it(pr);Cr.addListener(f=>{f.infiniteCanvasDefaultPrevented||console.warn("use two fingers to move")}),this.cache={mousemove:this.map(V(E(t,"mousemove"),()=>!this.mouseAnchorIsFixed()),f=>new Be(f)),mousedown:nt(Bt,At,n,i),pointerdown:nt(H,K,n,i),pointermove:this.map(Zs(V(c,()=>this.hasNonFixedAnchorForSomePointer()),()=>tr(this.anchorSet.getAll(f=>!f.anchor.fixedOnInfiniteCanvas).map(f=>f.pointerEvent))),f=>new ft(f)),pointerleave:this.map(a,f=>new ft(f)),pointerup:this.map(l,f=>new ft(f)),pointercancel:this.map(d,f=>new ft(f)),wheel:nt(ke,ie,n,i),wheelignored:nt(fr,gr,n,i),touchstart:nt(Lt,Fe,n,i),touchignored:nt(wr,Pr,n,i),touchmove:this.map(u,f=>{const b=gt(f.targetTouches),q=gt(f.targetTouches,j=>!this.hasFixedAnchorForTouch(j.identifier));return xt.create(this.rectangleManager.rectangle,f,b,q)})}}getEventSource(t){return this.cache[t]}mouseAnchorIsFixed(){const t=this.anchorSet.find(e=>e.pointerEvent.pointerType==="mouse");return t?t.anchor.fixedOnInfiniteCanvas:!1}hasFixedAnchorForTouch(t){const e=this.anchorSet.getAnchorForTouch(t);return!!e&&e.anchor.fixedOnInfiniteCanvas}hasNonFixedAnchorForSomePointer(){return!!this.anchorSet.find(t=>!t.anchor.fixedOnInfiniteCanvas)}transformUsingPointer(t,e){this.rectangleManager.measure();const n=this.anchorSet.getAnchorForPointerEvent(e);e.button===1&&this.config.rotationEnabled?(t.preventDefault(),this.transformer.addRotationAnchor(n.anchor)):e.button===0&&this.transformer.addAnchor(n.anchor)}removePointer(t){const e=this.anchorSet.getAnchorForPointerEvent(t);e&&(this.transformer.releaseAnchor(e.anchor),this.anchorSet.removeAnchor(e))}zoom(t){if(!this.config.greedyGestureHandling&&!t.ctrlKey)return;const{offsetX:e,offsetY:n}=t;let i=t.deltaY;const s=Math.pow(2,-i/300);this.rectangleManager.measure(),this.transformer.zoom(e,n,s),t.preventDefault()}}class nr{constructor(t,e){this.handledOrFilteredEventCollection=t,this.mappingCollection=e}setOn(t,e){zt(t)?this.handledOrFilteredEventCollection.setOn(t,e):this.mappingCollection.setOn(t,e)}getOn(t){return zt(t)?this.handledOrFilteredEventCollection.getOn(t):this.mappingCollection.getOn(t)}addEventListener(t,e,n){zt(t)?this.handledOrFilteredEventCollection.addEventListener(t,e,n):this.mappingCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){zt(t)?this.handledOrFilteredEventCollection.removeEventListener(t,e,n):this.mappingCollection.removeEventListener(t,e,n)}}class ir{constructor(t,e,n,i){this.mappedMouseEventCollection=t,this.mappedTouchEventCollection=e,this.mappedOnlyPointerEventCollection=n,this.mappedDragEventCollection=i}setOn(t,e){$t(t)?this.mappedMouseEventCollection.setOn(t,e):Qt(t)?this.mappedTouchEventCollection.setOn(t,e):Kt(t)?this.mappedOnlyPointerEventCollection.setOn(t,e):jt(t)&&this.mappedDragEventCollection.setOn(t,e)}getOn(t){if($t(t))return this.mappedMouseEventCollection.getOn(t);if(Qt(t))return this.mappedTouchEventCollection.getOn(t);if(Kt(t))return this.mappedOnlyPointerEventCollection.getOn(t);if(jt(t))return this.mappedDragEventCollection.getOn(t)}addEventListener(t,e,n){$t(t)?this.mappedMouseEventCollection.addEventListener(t,e,n):Qt(t)?this.mappedTouchEventCollection.addEventListener(t,e,n):Kt(t)?this.mappedOnlyPointerEventCollection.addEventListener(t,e,n):jt(t)&&this.mappedDragEventCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){$t(t)?this.mappedMouseEventCollection.removeEventListener(t,e,n):Qt(t)?this.mappedTouchEventCollection.removeEventListener(t,e,n):Kt(t)?this.mappedOnlyPointerEventCollection.removeEventListener(t,e,n):jt(t)&&this.mappedDragEventCollection.removeEventListener(t,e,n)}}class Ot extends ye{constructor(t,e,n,i){super(n,i),this.canvasEl=t,this.createInternalEvent=e,this.cache={}}getEventSource(t){return this.cache[t]||(this.cache[t]=this.createEventSource(t)),this.cache[t]}createEventSource(t){return this.map(E(this.canvasEl,t),e=>this.createInternalEvent(e))}}class sr extends Zt{get dataTransfer(){return this.event.dataTransfer}}class rr extends dt{constructor(t,e){super(t,e),this.props=st.create(t)}createResultEvent(t){return new sr(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}class or extends dt{createResultEvent(){return this.event}}class Le{constructor(t,e,n,i){this.drawEventCollection=t,this.transformationEventCollection=e,this.pointerEventCollection=n,this.unmappedEventCollection=i}setOn(t,e){t==="draw"?this.drawEventCollection.setOn("draw",e):Yt(t)?this.transformationEventCollection.setOn(t,e):Ut(t)?this.pointerEventCollection.setOn(t,e):this.unmappedEventCollection.setOn(t,e)}getOn(t){return t==="draw"?this.drawEventCollection.getOn("draw"):Yt(t)?this.transformationEventCollection.getOn(t):Ut(t)?this.pointerEventCollection.getOn(t):this.unmappedEventCollection.getOn(t)}addEventListener(t,e,n){t==="draw"?this.drawEventCollection.addEventListener("draw",e,n):Yt(t)?this.transformationEventCollection.addEventListener(t,e,n):Ut(t)?this.pointerEventCollection.addEventListener(t,e,n):this.unmappedEventCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){t==="draw"?this.drawEventCollection.removeEventListener("draw",e,n):Yt(t)?this.transformationEventCollection.removeEventListener(t,e,n):Ut(t)?this.pointerEventCollection.removeEventListener(t,e,n):this.unmappedEventCollection.removeEventListener(t,e,n)}static create(t,e,n,i,s,o){const a=new Ls(o,n,i),c=new Fs(e,n,i),l=new er(t,e,n,i,s),d=new nr(l,new ir(new Ot(t,u=>new Be(u),n,i),new Ot(t,u=>{const g=gt(u.targetTouches),w=gt(u.changedTouches);return xt.create(n.rectangle,u,g,w)},n,i),new Ot(t,u=>new ft(u),n,i),new Ot(t,u=>new rr(u),n,i)));return new Le(a,c,d,new Ot(t,u=>new or(u),n,i))}}function ar(r,t){let e=-1;const n=r.canvas.width;r.save(),r.fillStyle="#fff",r.fillRect(0,0,n,5),r.filter=`drop-shadow(${t} 0)`,r.fillRect(0,0,1,5);const s=r.getImageData(0,0,n,3).data;for(let o=0;o{e==null||e(),this.numberOfListeners=Math.max(this.numberOfListeners-1,0),this.numberOfListeners===0&&this.disconnect()}),this.numberOfListeners++,this.connectIfNeeded()}removeListener(t){this.dispatcher.removeListener(t)}connectIfNeeded(){this.observer||(this.observer=new ResizeObserver(t=>this.dispatcher.dispatch(this.createCanvasMeasurement(t))),this.observer.observe(this.canvas))}createCanvasMeasurement([{contentRect:t}]){return{left:t.left,top:t.top,screenWidth:t.width,screenHeight:t.height,viewboxWidth:this.canvas.width,viewboxHeight:this.canvas.height}}disconnect(){this.observer&&(this.observer.disconnect(),this.observer=void 0)}}function Nn(r){const{screenWidth:t,screenHeight:e}=r;return t>0&&e>0}class ur{constructor(t,e,n){this.measurementProvider=t,this.resizes=e,this.viewBox=n,this.currentlyVisible=!1}observe(){const t=this.measurementProvider.measure();this.currentlyVisible=Nn(t);const e=n=>{const i=Nn(n);i&&!this.currentlyVisible&&this.viewBox.draw(),this.currentlyVisible=i};this.resizes.addListener(e),this.listener=e}disconnect(){this.listener&&(this.resizes.removeListener(this.listener),this.listener=void 0)}}class Ee{constructor(t,e){this.canvas=t,this.config={rotationEnabled:!0,greedyGestureHandling:!1,units:S.CANVAS},e&&Object.assign(this.config,e);const n=new lr(t);this.canvasResizes=n,this.cssUnitsCanvasResizeListener=()=>{this.canvas.parentElement!==null&&this.viewBox.draw()};const i=new cs(new as),s=new hs(i),o=new ds(t);this.rectangleManager=new us(o,this.config);let a;const c=t.getContext("2d");this.cssLengthConverterFactory={create:()=>new hr(c)};const l=new _i(this.rectangleManager,c,s,()=>s.getLock(),()=>a.isTransforming);this.viewBox=l,this.canvasUnitsCanvasResizeObserver=new ur(o,n,l),a=new os(this.viewBox,this.config),this.eventCollection=Le.create(t,a,this.rectangleManager,this,this.config,i),this.config.units===S.CSS?this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener):this.config.units===S.CANVAS&&this.canvasUnitsCanvasResizeObserver.observe()}setUnits(t){t===S.CSS&&this.config.units!==S.CSS&&(this.canvasUnitsCanvasResizeObserver.disconnect(),this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener)),t===S.CANVAS&&this.config.units!==S.CANVAS&&(this.canvasResizes.removeListener(this.cssUnitsCanvasResizeListener),this.canvasUnitsCanvasResizeObserver.observe()),this.config.units=t,this.rectangleManager.measure(),this.viewBox.draw()}getContext(){return this.context||(this.context=new Di(this.canvas,this.viewBox,this.cssLengthConverterFactory)),this.context}get transformation(){return ut(this.rectangleManager.rectangle.infiniteCanvasContext.inverseBase)}get inverseTransformation(){return ut(this.rectangleManager.rectangle.infiniteCanvasContext.base)}get rotationEnabled(){return this.config.rotationEnabled}set rotationEnabled(t){this.config.rotationEnabled=t}get units(){return this.config.units}set units(t){this.setUnits(t)}get greedyGestureHandling(){return this.config.greedyGestureHandling}set greedyGestureHandling(t){this.config.greedyGestureHandling=t}set ontransformationstart(t){this.eventCollection.setOn("transformationstart",t)}get ontransformationstart(){return this.eventCollection.getOn("transformationstart")}set ontransformationchange(t){this.eventCollection.setOn("transformationchange",t)}get ontransformationchange(){return this.eventCollection.getOn("transformationchange")}set ontransformationend(t){this.eventCollection.setOn("transformationend",t)}get ontransformationend(){return this.eventCollection.getOn("transformationend")}set ondraw(t){this.eventCollection.setOn("draw",t)}get ondraw(){return this.eventCollection.getOn("draw")}set onwheelignored(t){this.eventCollection.setOn("wheelignored",t)}get onwheelignored(){return this.eventCollection.getOn("wheelignored")}set ontouchignored(t){this.eventCollection.setOn("touchignored",t)}get ontouchignored(){return this.eventCollection.getOn("touchignored")}set oncopy(t){this.eventCollection.setOn("copy",t)}get oncopy(){return this.eventCollection.getOn("copy")}set oncut(t){this.eventCollection.setOn("cut",t)}get oncut(){return this.eventCollection.getOn("cut")}set onpaste(t){this.eventCollection.setOn("paste",t)}get onpaste(){return this.eventCollection.getOn("paste")}set onabort(t){this.eventCollection.setOn("abort",t)}get onabort(){return this.eventCollection.getOn("abort")}set onanimationcancel(t){this.eventCollection.setOn("animationcancel",t)}get onanimationcancel(){return this.eventCollection.getOn("animationcancel")}set onanimationend(t){this.eventCollection.setOn("animationend",t)}get onanimationend(){return this.eventCollection.getOn("animationend")}set onanimationiteration(t){this.eventCollection.setOn("animationiteration",t)}get onanimationiteration(){return this.eventCollection.getOn("animationiteration")}set onanimationstart(t){this.eventCollection.setOn("animationstart",t)}get onanimationstart(){return this.eventCollection.getOn("animationstart")}set onauxclick(t){this.eventCollection.setOn("auxclick",t)}get onauxclick(){return this.eventCollection.getOn("auxclick")}set onblur(t){this.eventCollection.setOn("blur",t)}get onblur(){return this.eventCollection.getOn("blur")}get oncanplay(){return this.eventCollection.getOn("canplay")}set oncanplay(t){this.eventCollection.setOn("canplay",t)}get oncanplaythrough(){return this.eventCollection.getOn("canplaythrough")}set oncanplaythrough(t){this.eventCollection.setOn("canplaythrough",t)}get onchange(){return this.eventCollection.getOn("change")}set onchange(t){this.eventCollection.setOn("change",t)}get onclick(){return this.eventCollection.getOn("click")}set onclick(t){this.eventCollection.setOn("click",t)}get onclose(){return this.eventCollection.getOn("close")}set onclose(t){this.eventCollection.setOn("close",t)}get oncontextmenu(){return this.eventCollection.getOn("contextmenu")}set oncontextmenu(t){this.eventCollection.setOn("contextmenu",t)}get oncuechange(){return this.eventCollection.getOn("cuechange")}set oncuechange(t){this.eventCollection.setOn("cuechange",t)}get ondblclick(){return this.eventCollection.getOn("dblclick")}set ondblclick(t){this.eventCollection.setOn("dblclick",t)}get ondrag(){return this.eventCollection.getOn("drag")}set ondrag(t){this.eventCollection.setOn("drag",t)}get ondragend(){return this.eventCollection.getOn("dragend")}set ondragend(t){this.eventCollection.setOn("dragend",t)}get ondragenter(){return this.eventCollection.getOn("dragenter")}set ondragenter(t){this.eventCollection.setOn("dragenter",t)}get onformdata(){return this.eventCollection.getOn("formdata")}set onformdata(t){this.eventCollection.setOn("formdata",t)}get onwebkitanimationend(){return this.eventCollection.getOn("webkitanimationend")}set onwebkitanimationend(t){this.eventCollection.setOn("webkitanimationend",t)}get onwebkitanimationstart(){return this.eventCollection.getOn("webkitanimationstart")}set onwebkitanimationstart(t){this.eventCollection.setOn("webkitanimationstart",t)}get onwebkitanimationiteration(){return this.eventCollection.getOn("webkitanimationiteration")}set onwebkitanimationiteration(t){this.eventCollection.setOn("webkitanimationiteration",t)}get onwebkittransitionend(){return this.eventCollection.getOn("webkittransitionend")}set onwebkittransitionend(t){this.eventCollection.setOn("webkittransitionend",t)}get onslotchange(){return this.eventCollection.getOn("slotchange")}set onslotchange(t){this.eventCollection.setOn("slotchange",t)}get ondragleave(){return this.eventCollection.getOn("dragleave")}set ondragleave(t){this.eventCollection.setOn("dragleave",t)}get ondragover(){return this.eventCollection.getOn("dragover")}set ondragover(t){this.eventCollection.setOn("dragover",t)}get ondragstart(){return this.eventCollection.getOn("dragstart")}set ondragstart(t){this.eventCollection.setOn("dragstart",t)}get ondrop(){return this.eventCollection.getOn("drop")}set ondrop(t){this.eventCollection.setOn("drop",t)}get ondurationchange(){return this.eventCollection.getOn("durationchange")}set ondurationchange(t){this.eventCollection.setOn("durationchange",t)}get onemptied(){return this.eventCollection.getOn("emptied")}set onemptied(t){this.eventCollection.setOn("emptied",t)}get onended(){return this.eventCollection.getOn("ended")}set onended(t){this.eventCollection.setOn("ended",t)}get onerror(){return this.eventCollection.getOn("error")}set onerror(t){this.eventCollection.setOn("error",t)}get onfocus(){return this.eventCollection.getOn("focus")}set onfocus(t){this.eventCollection.setOn("focus",t)}get ongotpointercapture(){return this.eventCollection.getOn("gotpointercapture")}set ongotpointercapture(t){this.eventCollection.setOn("gotpointercapture",t)}get oninput(){return this.eventCollection.getOn("input")}set oninput(t){this.eventCollection.setOn("input",t)}get oninvalid(){return this.eventCollection.getOn("invalid")}set oninvalid(t){this.eventCollection.setOn("invalid",t)}get onkeydown(){return this.eventCollection.getOn("keydown")}set onkeydown(t){this.eventCollection.setOn("keydown",t)}get onkeypress(){return this.eventCollection.getOn("keypress")}set onkeypress(t){this.eventCollection.setOn("keypress",t)}get onkeyup(){return this.eventCollection.getOn("keyup")}set onkeyup(t){this.eventCollection.setOn("keyup",t)}get onload(){return this.eventCollection.getOn("load")}set onload(t){this.eventCollection.setOn("load",t)}get onloadeddata(){return this.eventCollection.getOn("loadeddata")}set onloadeddata(t){this.eventCollection.setOn("loadeddata",t)}get onloadedmetadata(){return this.eventCollection.getOn("loadedmetadata")}set onloadedmetadata(t){this.eventCollection.setOn("loadedmetadata",t)}get onloadstart(){return this.eventCollection.getOn("loadstart")}set onloadstart(t){this.eventCollection.setOn("loadstart",t)}get onlostpointercapture(){return this.eventCollection.getOn("lostpointercapture")}set onlostpointercapture(t){this.eventCollection.setOn("lostpointercapture",t)}get onmousedown(){return this.eventCollection.getOn("mousedown")}set onmousedown(t){this.eventCollection.setOn("mousedown",t)}get onmouseenter(){return this.eventCollection.getOn("mouseenter")}set onmouseenter(t){this.eventCollection.setOn("mouseenter",t)}get onmouseleave(){return this.eventCollection.getOn("mouseleave")}set onmouseleave(t){this.eventCollection.setOn("mouseleave",t)}get onmousemove(){return this.eventCollection.getOn("mousemove")}set onmousemove(t){this.eventCollection.setOn("mousemove",t)}get onmouseout(){return this.eventCollection.getOn("mouseout")}set onmouseout(t){this.eventCollection.setOn("mouseout",t)}get onmouseover(){return this.eventCollection.getOn("mouseover")}set onmouseover(t){this.eventCollection.setOn("mouseover",t)}get onmouseup(){return this.eventCollection.getOn("mouseup")}set onmouseup(t){this.eventCollection.setOn("mouseup",t)}get onpause(){return this.eventCollection.getOn("pause")}set onpause(t){this.eventCollection.setOn("pause",t)}get onplay(){return this.eventCollection.getOn("play")}set onplay(t){this.eventCollection.setOn("play",t)}get onplaying(){return this.eventCollection.getOn("playing")}set onplaying(t){this.eventCollection.setOn("playing",t)}get onpointercancel(){return this.eventCollection.getOn("pointercancel")}set onpointercancel(t){this.eventCollection.setOn("pointercancel",t)}get onpointerdown(){return this.eventCollection.getOn("pointerdown")}set onpointerdown(t){this.eventCollection.setOn("pointerdown",t)}get onpointerenter(){return this.eventCollection.getOn("pointerenter")}set onpointerenter(t){this.eventCollection.setOn("pointerenter",t)}get onpointerleave(){return this.eventCollection.getOn("pointerleave")}set onpointerleave(t){this.eventCollection.setOn("pointerleave",t)}get onpointermove(){return this.eventCollection.getOn("pointermove")}set onpointermove(t){this.eventCollection.setOn("pointermove",t)}get onpointerout(){return this.eventCollection.getOn("pointerout")}set onpointerout(t){this.eventCollection.setOn("pointerout",t)}get onpointerover(){return this.eventCollection.getOn("pointerover")}set onpointerover(t){this.eventCollection.setOn("pointerover",t)}get onpointerup(){return this.eventCollection.getOn("pointerup")}set onpointerup(t){this.eventCollection.setOn("pointerup",t)}get onprogress(){return this.eventCollection.getOn("progress")}set onprogress(t){this.eventCollection.setOn("progress",t)}get onratechange(){return this.eventCollection.getOn("ratechange")}set onratechange(t){this.eventCollection.setOn("ratechange",t)}get onreset(){return this.eventCollection.getOn("reset")}set onreset(t){this.eventCollection.setOn("reset",t)}get onresize(){return this.eventCollection.getOn("resize")}set onresize(t){this.eventCollection.setOn("resize",t)}get onscroll(){return this.eventCollection.getOn("scroll")}set onscroll(t){this.eventCollection.setOn("scroll",t)}get onsecuritypolicyviolation(){return this.eventCollection.getOn("securitypolicyviolation")}set onsecuritypolicyviolation(t){this.eventCollection.setOn("securitypolicyviolation",t)}get onseeked(){return this.eventCollection.getOn("seeked")}set onseeked(t){this.eventCollection.setOn("seeked",t)}get onseeking(){return this.eventCollection.getOn("seeking")}set onseeking(t){this.eventCollection.setOn("seeking",t)}get onselect(){return this.eventCollection.getOn("select")}set onselect(t){this.eventCollection.setOn("select",t)}get onselectionchange(){return this.eventCollection.getOn("selectionchange")}set onselectionchange(t){this.eventCollection.setOn("selectionchange",t)}get onselectstart(){return this.eventCollection.getOn("selectstart")}set onselectstart(t){this.eventCollection.setOn("selectstart",t)}get onstalled(){return this.eventCollection.getOn("stalled")}set onstalled(t){this.eventCollection.setOn("stalled",t)}get onsubmit(){return this.eventCollection.getOn("submit")}set onsubmit(t){this.eventCollection.setOn("submit",t)}get onsuspend(){return this.eventCollection.getOn("suspend")}set onsuspend(t){this.eventCollection.setOn("suspend",t)}get ontimeupdate(){return this.eventCollection.getOn("timeupdate")}set ontimeupdate(t){this.eventCollection.setOn("timeupdate",t)}get ontoggle(){return this.eventCollection.getOn("toggle")}set ontoggle(t){this.eventCollection.setOn("toggle",t)}get ontouchcancel(){return this.eventCollection.getOn("touchcancel")}set ontouchcancel(t){this.eventCollection.setOn("touchcancel",t)}get ontouchend(){return this.eventCollection.getOn("touchend")}set ontouchend(t){this.eventCollection.setOn("touchend",t)}get ontouchmove(){return this.eventCollection.getOn("touchmove")}set ontouchmove(t){this.eventCollection.setOn("touchmove",t)}get ontouchstart(){return this.eventCollection.getOn("touchstart")}set ontouchstart(t){this.eventCollection.setOn("touchstart",t)}get ontransitioncancel(){return this.eventCollection.getOn("transitioncancel")}set ontransitioncancel(t){this.eventCollection.setOn("transitioncancel",t)}get ontransitionend(){return this.eventCollection.getOn("transitionend")}set ontransitionend(t){this.eventCollection.setOn("transitionend",t)}get ontransitionrun(){return this.eventCollection.getOn("transitionrun")}set ontransitionrun(t){this.eventCollection.setOn("transitionrun",t)}get ontransitionstart(){return this.eventCollection.getOn("transitionstart")}set ontransitionstart(t){this.eventCollection.setOn("transitionstart",t)}get onvolumechange(){return this.eventCollection.getOn("volumechange")}set onvolumechange(t){this.eventCollection.setOn("volumechange",t)}get onwaiting(){return this.eventCollection.getOn("waiting")}set onwaiting(t){this.eventCollection.setOn("waiting",t)}get onwheel(){return this.eventCollection.getOn("wheel")}set onwheel(t){this.eventCollection.setOn("wheel",t)}addEventListener(t,e,n){this.eventCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){this.eventCollection.removeEventListener(t,e,n)}}Ee.CANVAS_UNITS=S.CANVAS,Ee.CSS_UNITS=S.CSS;const Mn=Ee;return Mn.Units=S,Mn}); +(function(wt,_){typeof exports=="object"&&typeof module<"u"?module.exports=_():typeof define=="function"&&define.amd?define(_):(wt=typeof globalThis<"u"?globalThis:wt||self,wt.InfiniteCanvas=_())})(this,function(){"use strict";let wt=class{constructor(t){this.viewBox=t}restore(){this.viewBox.restoreState()}save(){this.viewBox.saveState()}reset(){this.viewBox.resetState()}};const _=class vt{constructor(t,e){this.x=t,this.y=e}mod(){return Math.sqrt(this.modSq())}modSq(){return this.x*this.x+this.y*this.y}minus(t){return new vt(this.x-t.x,this.y-t.y)}plus(t){return new vt(this.x+t.x,this.y+t.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}equals(t){return this.x===t.x&&this.y===t.y}getPerpendicular(){return new vt(-this.y,this.x)}scale(t){return new vt(t*this.x,t*this.y)}projectOn(t){return t.scale(this.dot(t)/t.modSq())}matrix(t,e,n,i){return new vt(t*this.x+e*this.y,n*this.x+i*this.y)}inSameDirectionAs(t){return this.cross(t)===0&&this.dot(t)>=0}isInOppositeDirectionAs(t){return this.cross(t)===0&&this.dot(t)<0}isOnSameSideOfOriginAs(t,e){return this.isInSmallerAngleBetweenPoints(t,e)||t.isInSmallerAngleBetweenPoints(this,e)||e.isInSmallerAngleBetweenPoints(this,t)}isInSmallerAngleBetweenPoints(t,e){const n=t.cross(e);return n>0?t.cross(this)>=0&&this.cross(e)>=0:n<0?t.cross(this)<=0&&this.cross(e)<=0:t.dot(e)>0?this.cross(t)===0&&this.dot(t)>0:!0}};_.origin=new _(0,0);let c=_;function at(s){return s.toFixed(10).replace(/\.?0+$/,"")}const le=class A{constructor(t,e,n,i,r,o){this.a=t,this.b=e,this.c=n,this.d=i,this.e=r,this.f=o,this.scale=Math.sqrt(t*i-e*n)}getMaximumLineWidthScale(){const t=this.a+this.c,e=this.b+this.d,n=this.a-this.c,i=this.b-this.d;return Math.sqrt(Math.max(t*t+e*e,n*n+i*i))}getRotationAngle(){const t=this.a/this.scale,e=this.b/this.scale;if(t===0)return e>0?Math.PI/2:3*Math.PI/2;const n=Math.atan(e/t);return t>0?e>0?n:e===0?0:2*Math.PI+n:e>0?Math.PI+n:e===0?Math.PI:Math.PI+n}applyToPointAtInfinity(t){return{direction:this.untranslated().apply(t.direction)}}apply(t){return new c(this.a*t.x+this.c*t.y+this.e,this.b*t.x+this.d*t.y+this.f)}untranslated(){const{x:t,y:e}=this.apply(c.origin);return this.before(A.translation(-t,-e))}before(t){const e=t.a*this.a+t.c*this.b,n=t.b*this.a+t.d*this.b,i=t.a*this.c+t.c*this.d,r=t.b*this.c+t.d*this.d,o=t.a*this.e+t.c*this.f+t.e,a=t.b*this.e+t.d*this.f+t.f;return new A(e,n,i,r,o,a)}equals(t){return this.a===t.a&&this.b===t.b&&this.c===t.c&&this.d===t.d&&this.e===t.e&&this.f===t.f}inverse(){var t=this.a*this.d-this.b*this.c;if(t==0)throw new Error("error calculating inverse: zero determinant");const e=this.d/t,n=-this.b/t,i=-this.c/t,r=this.a/t,o=(this.c*this.f-this.d*this.e)/t,a=(this.b*this.e-this.a*this.f)/t;return new A(e,n,i,r,o,a)}static translation(t,e){return new A(1,0,0,1,t,e)}static scale(t){return new A(t,0,0,t,0,0)}static zoom(t,e,n,i,r){const o=1-n;return i!==void 0?new A(n,0,0,n,t*o+i,e*o+r):new A(n,0,0,n,t*o,e*o)}static translateZoom(t,e,n,i,r,o,a,l){const h=n-t,d=i-e,u=h*h+d*d;if(u===0)throw new Error("divide by 0");const g=a-r,w=l-o,P=g*g+w*w,y=Math.sqrt(P/u);return A.zoom(t,e,y,r-t,o-e)}static rotation(t,e,n){const i=Math.cos(n),r=Math.sin(n),o=1-i;return new A(i,r,-r,i,t*o+e*r,-t*r+e*o)}static translateRotateZoom(t,e,n,i,r,o,a,l){const h=n-t,d=i-e,u=h*h+d*d;if(u===0)throw new Error("divide by 0");const g=a-r,w=l-o,P=t*i-e*n,y=n*h+i*d,B=t*h+e*d,M=(h*g+d*w)/u,$=(h*w-d*g)/u,ot=-$,Lt=M,Bt=(r*y-a*B-P*w)/u,At=(o*y-l*B+P*g)/u;return new A(M,$,ot,Lt,Bt,At)}static create(t){if(t instanceof A)return t;const{a:e,b:n,c:i,d:r,e:o,f:a}=t;return new A(e,n,i,r,o,a)}toString(){return`x: (${at(this.a)}, ${at(this.b)}), y: (${at(this.c)}, ${at(this.d)}), d: (${at(this.e)}, ${at(this.f)})`}};le.identity=new le(1,0,0,1,0,0);let p=le;class T{constructor(t,e){this.propertyName=t,this.noopInstruction=e}changeInstanceValue(t,e){return this.valuesAreEqual(t[this.propertyName],e)?t:t.changeProperty(this.propertyName,e)}isEqualForInstances(t,e){return this.valuesAreEqual(t[this.propertyName],e[this.propertyName])}getInstructionToChange(t,e){return this.valuesAreEqual(t[this.propertyName],e[this.propertyName])?this.noopInstruction:this.changeToNewValue(e[this.propertyName])}valueIsTransformableForInstance(t){return!0}}const S=()=>{};class ai extends T{valuesAreEqual(t,e){return t.equals(e)}changeToNewValue(t){return(e,n)=>{const{a:i,b:r,c:o,d:a,e:l,f:h}=n.getTransformationForInstruction(t);e.setTransform(i,r,o,a,l,h)}}}const Et=new ai("transformation",S);class ci{constructor(t){this.viewBox=t}getTransform(){if(DOMMatrix){const t=this.viewBox.state.current.transformation;return new DOMMatrix([t.a,t.b,t.c,t.d,t.e,t.f])}}resetTransform(){this.viewBox.changeState(t=>Et.changeInstanceValue(t,p.identity))}rotate(t){this.addTransformation(p.rotation(0,0,t))}scale(t,e){this.addTransformation(new p(t,0,0,e,0,0))}setTransform(t,e,n,i,r,o){let a,l,h,d,u,g;typeof t=="number"?(a=t,l=e,h=n,d=i,u=r,g=o):t.a!==void 0?(a=t.a,l=t.b,h=t.c,d=t.d,u=t.e,g=t.f):(a=t.m11,l=t.m12,h=t.m21,d=t.m22,u=t.m41,g=t.m42),this.viewBox.changeState(w=>Et.changeInstanceValue(w,new p(a,l,h,d,u,g)))}transform(t,e,n,i,r,o){this.addTransformation(new p(t,e,n,i,r,o))}translate(t,e){this.addTransformation(p.translation(t,e))}addTransformation(t){const e=this.viewBox.state.current.transformation,n=t.before(e);this.viewBox.changeState(i=>Et.changeInstanceValue(i,n))}}class hi extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.globalAlpha=t}}const Qe=new hi("globalAlpha",S);class li extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.globalCompositeOperation=t}}const Je=new li("globalCompositeOperation",S);class ui{constructor(t){this.viewBox=t}get globalAlpha(){return this.viewBox.state.current.globalAlpha}set globalAlpha(t){this.viewBox.changeState(e=>Qe.changeInstanceValue(e,t))}get globalCompositeOperation(){return this.viewBox.state.current.globalCompositeOperation}set globalCompositeOperation(t){this.viewBox.changeState(e=>Je.changeInstanceValue(e,t))}}class di extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.imageSmoothingEnabled=t}}}const Ze=new di("imageSmoothingEnabled",S);class fi extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.imageSmoothingQuality=t}}}const _e=new fi("imageSmoothingQuality",S);class gi{constructor(t){this.viewBox=t}get imageSmoothingEnabled(){return this.viewBox.state.current.imageSmoothingEnabled}set imageSmoothingEnabled(t){this.viewBox.changeState(e=>Ze.changeInstanceValue(e,t))}get imageSmoothingQuality(){return this.viewBox.state.current.imageSmoothingQuality}set imageSmoothingQuality(t){this.viewBox.changeState(e=>_e.changeInstanceValue(e,t))}}class Ft{}class tn extends Ft{constructor(t){super(),this.fillStrokeStyle=t}setTransform(t){this.fillStrokeStyle.setTransform(t)}getInstructionToSetUntransformed(t){return e=>{e[t]=this.fillStrokeStyle}}getInstructionToSetTransformed(t){return e=>{e[t]=this.fillStrokeStyle}}}class en{constructor(t){this.propName=t}changeInstanceValue(t,e){return t.changeProperty(this.propName,e)}isEqualForInstances(t,e){return t[this.propName]===e[this.propName]}getInstructionToChange(t,e){const n=e[this.propName];return this.isEqualForInstances(t,e)?!(n instanceof Ft)||t.fillAndStrokeStylesTransformed===e.fillAndStrokeStylesTransformed?()=>{}:e.fillAndStrokeStylesTransformed?n.getInstructionToSetTransformed(this.propName):n.getInstructionToSetUntransformed(this.propName):n instanceof Ft?e.fillAndStrokeStylesTransformed?n.getInstructionToSetTransformed(this.propName):n.getInstructionToSetUntransformed(this.propName):i=>{i[this.propName]=e[this.propName]}}valueIsTransformableForInstance(t){return!(t[this.propName]instanceof tn)}}const nn=new en("fillStyle"),sn=new en("strokeStyle");class mi{constructor(t){this.viewBox=t}set fillStyle(t){this.viewBox.changeState(e=>nn.changeInstanceValue(e,t))}set strokeStyle(t){this.viewBox.changeState(e=>sn.changeInstanceValue(e,t))}createLinearGradient(t,e,n,i){return this.viewBox.createLinearGradient(t,e,n,i)}createPattern(t,e){return this.viewBox.createPattern(t,e)}createRadialGradient(t,e,n,i,r,o){return this.viewBox.createRadialGradient(t,e,n,i,r,o)}createConicGradient(t,e,n){return this.viewBox.createConicGradient(t,e,n)}}class pi extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.shadowColor=t}}}const rn=new pi("shadowColor",S);class vi extends T{changeToNewValue(t){return(e,n)=>{const i=p.translation(t.x,t.y),r=n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i),{x:o,y:a}=r.apply(c.origin);e.shadowOffsetX=o,e.shadowOffsetY=a}}valuesAreEqual(t,e){return t.x===e.x&&t.y==e.y}}const ue=new vi("shadowOffset",S);class wi extends T{changeToNewValue(t){return(e,n)=>{const i=p.translation(t,0),o=n.translateInfiniteCanvasContextTransformationToBitmapTransformation(i).apply(c.origin).mod();e.shadowBlur=o}}valuesAreEqual(t,e){return t===e}}const on=new wi("shadowBlur",S);class Pi{constructor(t){this.viewBox=t}get shadowBlur(){return this.viewBox.state.current.shadowBlur}set shadowBlur(t){this.viewBox.changeState(e=>on.changeInstanceValue(e,t))}get shadowOffsetX(){return this.viewBox.state.current.shadowOffset.x}set shadowOffsetX(t){const e=new c(t,this.viewBox.state.current.shadowOffset.y);this.viewBox.changeState(n=>ue.changeInstanceValue(n,e))}get shadowOffsetY(){return this.viewBox.state.current.shadowOffset.y}set shadowOffsetY(t){const e=new c(this.viewBox.state.current.shadowOffset.x,t);this.viewBox.changeState(n=>ue.changeInstanceValue(n,e))}get shadowColor(){return this.viewBox.state.current.shadowColor}set shadowColor(t){this.viewBox.changeState(e=>rn.changeInstanceValue(e,t))}}const an="[+-]?(?:\\d*\\.)?\\d+(?:e[+-]?\\d+)?",cn="[+-]?(?:0*\\.)?0+(?:e[+-]?\\d+)?",hn="(?:ch|em|ex|ic|rem|vh|vw|vmax|vmin|vb|vi|cqw|cqh|cqi|cqb|cqmin|cqmax|px|cm|mm|Q|in|pc|pt)",Rt=`(?:${cn}|${an}${hn})`,ln=`blur\\((${Rt})\\)`,un="[^())\\s]+(?:\\([^)]*?\\))?",dn=`drop-shadow\\((${Rt})\\s+(${Rt})\\s*?(?:(?:(${Rt})\\s*?(${un})?)|(${un}))?\\)`,fn=`${ln}|${dn}`;function F(s,t){const e=s.match(new RegExp(`(?:(${cn})|(${an})(${hn}))`));return e[1]?0:t.getNumberOfPixels(Number.parseFloat(e[2]),e[3])}class gn{constructor(t){this.stringRepresentation=t}toTransformedString(){return this.stringRepresentation}getShadowOffset(){return null}}class de{constructor(t,e){this.stringRepresentation=t,this.size=e}toTransformedString(t){return`blur(${t.translateInfiniteCanvasContextTransformationToBitmapTransformation(p.translation(this.size,0)).apply(c.origin).mod()}px)`}getShadowOffset(){return null}static tryCreate(t,e){const n=t.match(new RegExp(ln));return n===null?null:new de(t,F(n[1],e))}}class ct{constructor(t,e,n,i,r){this.stringRepresentation=t,this.offsetX=e,this.offsetY=n,this.blurRadius=i,this.color=r}toTransformedString(t){const e=t.translateInfiniteCanvasContextTransformationToBitmapTransformation(p.translation(this.offsetX,this.offsetY)),{x:n,y:i}=e.apply(c.origin);if(this.blurRadius!==null){const o=t.translateInfiniteCanvasContextTransformationToBitmapTransformation(p.translation(this.blurRadius,0)).apply(c.origin).mod();return this.color?`drop-shadow(${n}px ${i}px ${o}px ${this.color})`:`drop-shadow(${n}px ${i}px ${o}px)`}return this.color?`drop-shadow(${n}px ${i}px ${this.color})`:`drop-shadow(${n}px ${i}px)`}getShadowOffset(){return new c(this.offsetX,this.offsetY)}static tryCreate(t,e){const n=t.match(new RegExp(dn));return n===null?null:n[5]?new ct(t,F(n[1],e),F(n[2],e),null,n[5]):n[4]?new ct(t,F(n[1],e),F(n[2],e),F(n[3],e),n[4]):n[3]?new ct(t,F(n[1],e),F(n[2],e),F(n[3],e),null):new ct(t,F(n[1],e),F(n[2],e),null,null)}}const fe=class ri{constructor(t,e){this.stringRepresentation=t,this.parts=e}toString(){return this.parts.map(t=>t.stringRepresentation).join(" ")}toTransformedString(t){return this.parts.map(e=>e.toTransformedString(t)).join(" ")}getShadowOffset(){for(const t of this.parts){const e=t.getShadowOffset();if(e!==null)return e}return null}static create(t,e){const i=t.match(new RegExp(`${fn}|((?!\\s|${fn}).)+`,"g")).map(r=>this.createPart(r,e));return new ri(t,i)}static createPart(t,e){let n=de.tryCreate(t,e);return n!==null||(n=ct.tryCreate(t,e),n!=null)?n:new gn(t)}};fe.none=new fe("none",[new gn("none")]);let mn=fe;class Ci extends T{valuesAreEqual(t,e){return t.stringRepresentation===e.stringRepresentation}changeToNewValue(t){return(e,n)=>e.filter=t.toTransformedString(n)}}const pn=new Ci("filter",S);class Ii{constructor(t,e){this.viewBox=t,this.cssLengthConverterFactory=e}get filter(){return this.viewBox.state.current.filter.stringRepresentation}set filter(t){const e=mn.create(t,this.cssLengthConverterFactory.create());this.viewBox.changeState(n=>pn.changeInstanceValue(n,e))}}class Ti{constructor(t){this.viewBox=t}clearRect(t,e,n,i){this.viewBox.clearArea(t,e,n,i)}fillRect(t,e,n,i){let r=o=>o.fill();this.viewBox.fillRect(t,e,n,i,r)}strokeRect(t,e,n,i){this.viewBox.strokeRect(t,e,n,i)}}class Si{constructor(t){this.viewBox=t}isFillRule(t){return t==="evenodd"||t==="nonzero"}beginPath(){this.viewBox.beginPath()}clip(t,e){let n=this.isFillRule(t)?i=>{i.clip(t)}:i=>{i.clip()};this.viewBox.clipPath(n)}fill(t,e){if((!t||this.isFillRule(t))&&!this.viewBox.currentPathCanBeFilled())return;let n=this.isFillRule(t)?i=>{i.fill(t)}:i=>{i.fill()};this.viewBox.fillPath(n)}isPointInPath(t,e,n,i){return!0}isPointInStroke(t,e,n){return!0}stroke(t){this.viewBox.strokePath()}}class yi{drawFocusIfNeeded(t,e){}scrollPathIntoView(t){}}var k=(s=>(s[s.None=0]="None",s[s.Relative=1]="Relative",s[s.Absolute=2]="Absolute",s))(k||{}),I=(s=>(s[s.Positive=0]="Positive",s[s.Negative=1]="Negative",s))(I||{});const Wt={direction:new c(0,1)},kt={direction:new c(0,-1)},Ht={direction:new c(-1,0)},Vt={direction:new c(1,0)};function xi(s,t,e,n){const i=e.minus(s),r=n.cross(t),o=n.getPerpendicular().dot(i)/r;return s.plus(t.scale(o))}class tt{constructor(t,e,n){this.point=t,this.leftHalfPlane=e,this.rightHalfPlane=n,this.leftNormal=e.normalTowardInterior,this.rightNormal=n.normalTowardInterior}replaceLeftHalfPlane(t){return new tt(this.point,t,this.rightHalfPlane)}replaceRightHalfPlane(t){return new tt(this.point,this.leftHalfPlane,t)}isContainedByHalfPlaneWithNormal(t){return t.isInSmallerAngleBetweenPoints(this.leftNormal,this.rightNormal)}containsPoint(t){return this.leftHalfPlane.containsPoint(t)&&this.rightHalfPlane.containsPoint(t)}containsLineSegmentWithDirection(t){return this.containsPoint(this.point.plus(t))||this.containsPoint(this.point.minus(t))}isContainedByVertex(t){return this.isContainedByHalfPlaneWithNormal(t.leftNormal)&&this.isContainedByHalfPlaneWithNormal(t.rightNormal)}getContainingHalfPlaneThroughPoint(t){let e=t.minus(this.point).getPerpendicular();if(e.cross(this.leftHalfPlane.normalTowardInterior)===0)return this.leftHalfPlane;if(e.cross(this.rightHalfPlane.normalTowardInterior)===0)return this.rightHalfPlane;const n=this.leftNormal.plus(this.rightNormal);return e.dot(n)<=0&&(e=e.scale(-1)),new v(t,e)}static create(t,e,n){return e.normalTowardInterior.cross(n.normalTowardInterior)>=0?new tt(t,e,n):new tt(t,n,e)}}class v{constructor(t,e){this.base=t,this.normalTowardInterior=e,this.lengthOfNormal=e.mod()}getDistanceFromEdge(t){return t.minus(this.base).dot(this.normalTowardInterior)/this.lengthOfNormal}transform(t){const e=t.apply(this.base),n=t.apply(this.base.plus(this.normalTowardInterior.getPerpendicular())),i=t.apply(this.base.plus(this.normalTowardInterior));return v.throughPointsAndContainingPoint(e,n,i)}complement(){return new v(this.base,this.normalTowardInterior.scale(-1))}expandByDistance(t){const e=this.base.plus(this.normalTowardInterior.scale(-t/this.normalTowardInterior.mod()));return new v(e,this.normalTowardInterior)}expandToIncludePoint(t){return this.containsPoint(t)?this:new v(t,this.normalTowardInterior)}containsPoint(t){return this.getDistanceFromEdge(t)>=0}interiorContainsPoint(t){return this.getDistanceFromEdge(t)>0}containsInfinityInDirection(t){return t.dot(this.normalTowardInterior)>=0}isContainedByHalfPlane(t){return this.normalTowardInterior.inSameDirectionAs(t.normalTowardInterior)&&t.getDistanceFromEdge(this.base)>=0}intersectWithLine(t,e){return{point:xi(this.base,this.normalTowardInterior.getPerpendicular(),t,e),halfPlane:this}}isParallelToLine(t,e){return this.normalTowardInterior.getPerpendicular().cross(e)===0}getIntersectionWith(t){const e=this.intersectWithLine(t.base,t.normalTowardInterior.getPerpendicular());return tt.create(e.point,this,t)}static throughPointsAndContainingPoint(t,e,n){const i=v.withBorderPoints(t,e);for(let r of i)if(r.containsPoint(n))return r}static withBorderPointAndInfinityInDirection(t,e){return v.withBorderPoints(t,t.plus(e))}static withBorderPoints(t,e){const n=e.minus(t).getPerpendicular();return[new v(t,n),new v(t,n.scale(-1))]}}class bi{getVertices(){return[]}expandToIncludePoint(t){return this}expandToIncludePolygon(t){return this}expandToIncludeInfinityInDirection(t){return this}expandByDistance(t){return this}intersects(t){return!0}expandToInclude(t){return this}transform(t){return this}intersectWithLineSegment(t){return t}contains(t){return!0}intersectWith(t){return t}join(t){return this}intersectWithRay(t){return t}intersectWithLine(t){return t}intersectWithConvexPolygon(t){return t}isContainedByRay(t){return!1}isContainedByLineSegment(t){return!1}isContainedByLine(t){return!1}isContainedByConvexPolygon(t){return!1}intersectsRay(t){return!0}intersectsLineSegment(t){return!0}intersectsLine(t){return!0}intersectsConvexPolygon(t){return!0}}const ht=new bi;class Oi{getVertices(){return[]}intersectWith(t){return this}join(t){return t}intersectWithConvexPolygon(t){return this}intersects(t){return!1}intersectWithLineSegment(t){return this}intersectWithRay(t){return this}intersectWithLine(t){return this}expandToInclude(t){return t}transform(t){return this}contains(t){return!1}isContainedByConvexPolygon(t){return!0}isContainedByRay(t){return!0}isContainedByLineSegment(t){return!0}isContainedByLine(t){return!0}intersectsRay(t){return!1}intersectsConvexPolygon(t){return!1}intersectsLineSegment(t){return!1}intersectsLine(t){return!1}expandByDistance(t){return this}expandToIncludePoint(t){return this}expandToIncludeInfinityInDirection(t){return this}expandToIncludePolygon(t){return t}}const b=new Oi;class m{constructor(t,e){this.vertices=e,this.halfPlanes=t,this.vertices=this.vertices||m.getVertices(this.halfPlanes)}findVertex(t){for(let e of this.vertices)if(e.point.equals(t))return e}intersects(t){return t.intersectsConvexPolygon(this)}intersectWith(t){return t.intersectWithConvexPolygon(this)}join(t){if(this.contains(t))return this;if(t.contains(this))return t;let e=t;for(let n of this.vertices)e=e.expandToIncludePoint(n.point);for(let n of this.getPointsAtInfinityFromHalfPlanes())this.containsInfinityInDirection(n)&&(e=e.expandToIncludeInfinityInDirection(n));return e}intersectWithRay(t){return t.intersectWithConvexPolygon(this)}intersectWithLine(t){return t.intersectWithConvexPolygon(this)}intersectWithLineSegment(t){return t.intersectWithConvexPolygon(this)}contains(t){return t.isContainedByConvexPolygon(this)}containsHalfPlane(t){for(let e of this.halfPlanes)if(!t.isContainedByHalfPlane(e))return!1;return!0}isContainedByHalfPlane(t){for(let n of this.vertices)if(!t.containsPoint(n.point))return!1;const e=t.complement();for(let n of this.halfPlanes)if(n.isContainedByHalfPlane(t))return!0;for(let n of this.halfPlanes){const i=this.getVerticesOnHalfPlane(n);if(i.length<=1&&(n.isContainedByHalfPlane(e)||e.isContainedByHalfPlane(n)))return!1;const r=n.getIntersectionWith(t),o=i.find(a=>a.point.equals(r.point));if(o){if(!o.isContainedByHalfPlaneWithNormal(t.normalTowardInterior))return!1}else{if(i.length===0)return!1;if(this.containsPoint(r.point))return!1}}return!this.containsHalfPlane(t)}getVertices(){return this.vertices.map(t=>t.point)}expandToIncludePoint(t){if(this.vertices.length===0){const d=this.halfPlanes.map(u=>u.expandToIncludePoint(t));return new m(d)}const e=new Set,n=new Set;let i=null,r=null;const o=[],a=new Set;for(const d of this.vertices){const u=d.leftHalfPlane;n.has(u)?n.delete(u):e.add(u);const g=d.rightHalfPlane;if(e.has(g)?e.delete(g):n.add(g),u.containsPoint(t)){if(a.add(u),g.containsPoint(t)){a.add(g),o.push(d);continue}i=d;continue}g.containsPoint(t)&&(a.add(g),r=d)}if(o.length===this.vertices.length)return this;let l,h;if(i===null){const d=[...e][0];if(!d)return this;l=d.expandToIncludePoint(t)}else l=i.getContainingHalfPlaneThroughPoint(t),l!==i.leftHalfPlane&&o.push(i.replaceRightHalfPlane(l));if(r===null){const d=[...n][0];if(!d)return this;h=d.expandToIncludePoint(t)}else h=r.getContainingHalfPlaneThroughPoint(t),h!==r.rightHalfPlane&&o.push(r.replaceLeftHalfPlane(h));return a.add(l),a.add(h),o.push(new tt(t,l,h)),new m([...a],o)}expandToIncludeInfinityInDirection(t){if(this.containsInfinityInDirection(t))return this;let e=this.halfPlanes.filter(n=>n.containsInfinityInDirection(t)).concat(this.getTangentPlanesThroughInfinityInDirection(t));return e=m.getHalfPlanesNotContainingAnyOther(e),e.length===0?ht:new m(e)}getIntersectionsWithLine(t,e){const n=[];for(let i of this.halfPlanes){if(i.isParallelToLine(t,e))continue;const r=i.intersectWithLine(t,e),o=this.findVertex(r.point);o&&!o.containsLineSegmentWithDirection(e)||this.containsPoint(r.point)&&n.push(r)}return n}expandByDistance(t){return new m(this.halfPlanes.map(e=>e.expandByDistance(t)))}transform(t){return new m(this.halfPlanes.map(e=>e.transform(t)))}intersectWithConvexPolygon(t){if(t.isContainedByConvexPolygon(this))return t;if(this.isContainedByConvexPolygon(t))return this;if(this.isOutsideConvexPolygon(t))return b;const e=m.getHalfPlanesNotContainingAnyOther(this.halfPlanes.concat(t.halfPlanes)),r=m.groupVerticesByPoint(m.getVertices(e)).map(a=>m.getVerticesNotContainingAnyOther(a)).reduce((a,l)=>a.concat(l),[]);if(r.length===0)return new m(e);const o=m.getHalfPlanes(r);return new m(o)}containsInfinityInDirection(t){for(let e of this.halfPlanes)if(!e.containsInfinityInDirection(t))return!1;return!0}containsPoint(t){for(let e of this.halfPlanes)if(!e.containsPoint(t))return!1;return!0}intersectsRay(t){return t.intersectsConvexPolygon(this)}intersectsLineSegment(t){return t.intersectsConvexPolygon(this)}intersectsLine(t){return t.intersectsConvexPolygon(this)}intersectsConvexPolygon(t){return this.isContainedByConvexPolygon(t)||t.isContainedByConvexPolygon(this)?!0:!this.isOutsideConvexPolygon(t)}isOutsideConvexPolygon(t){for(let e of t.halfPlanes)if(this.isContainedByHalfPlane(e.complement()))return!0;for(let e of this.halfPlanes)if(t.isContainedByHalfPlane(e.complement()))return!0;return!1}getVerticesOnHalfPlane(t){const e=[];for(let n of this.vertices)(n.leftHalfPlane===t||n.rightHalfPlane===t)&&e.push(n);return e}hasAtMostOneVertex(t){let e=0;for(let n of this.vertices)if((n.leftHalfPlane===t||n.rightHalfPlane===t)&&(e++,e>1))return!1;return!0}getTangentPlanesThroughInfinityInDirection(t){const e=[];for(let n of this.vertices){const i=v.withBorderPointAndInfinityInDirection(n.point,t);for(let r of i)this.isContainedByHalfPlane(r)&&e.push(r)}return e}getPointsAtInfinityFromHalfPlanes(){const t=[];for(let e of this.halfPlanes){const n=e.normalTowardInterior,i=n.getPerpendicular();t.push(n),t.push(i),t.push(i.scale(-1))}return t}isContainedByRay(t){return!1}isContainedByLineSegment(t){return!1}isContainedByLine(t){return!1}isContainedByConvexPolygon(t){for(let e of t.halfPlanes)if(!this.isContainedByHalfPlane(e))return!1;return!0}static getHalfPlanes(t){const e=[];for(let n of t)e.indexOf(n.leftHalfPlane)===-1&&e.push(n.leftHalfPlane),e.indexOf(n.rightHalfPlane)===-1&&e.push(n.rightHalfPlane);return e}static getVerticesNotContainingAnyOther(t){const e=[];for(let n=0;n{for(const e of s)e&&e(...t)}}function Li(s,t){return t?(e,n)=>{e.save(),t(e,n),s(e,n),e.restore()}:s}function Bi(s){return s===k.Relative?(t,e)=>{const{a:n,b:i,c:r,d:o,e:a,f:l}=e.getBitmapTransformationToTransformedInfiniteCanvasContext();t.transform(n,i,r,o,a,l)}:s===k.Absolute?(t,e)=>{const{a:n,b:i,c:r,d:o,e:a,f:l}=e.getBitmapTransformationToInfiniteCanvasContext();t.setTransform(n,i,r,o,a,l)}:null}function Ai(s,t){let e=s.area;return e&&t.lineWidth>0&&(e=e.expandByDistance(t.lineWidth/2)),e}function Di(s){return{lineWidth:s.current.getMaximumLineWidth(),lineDashPeriod:s.current.getLineDashPeriod(),shadowOffsets:s.current.getShadowOffsets()}}function Ei(s){return{lineWidth:0,lineDashPeriod:0,shadowOffsets:s.current.getShadowOffsets()}}class H{constructor(t,e,n,i,r,o,a){this.instruction=t,this.area=e,this.build=n,this.takeClippingRegionIntoAccount=i,this.transformationKind=r,this.state=o,this.tempState=a}static forStrokingPath(t,e,n){return H.forPath(t,e,Di,n)}static forFillingPath(t,e,n){return H.forPath(t,e,Ei,n)}static forPath(t,e,n,i){const r=e.current.isTransformable(),o=r?k.None:k.Relative,a=e.currentlyTransformed(r),l=n(a),h=i(a),d=Ai(h,l);return new H(t,d,u=>h.drawPath(u,a,l),!0,o,a)}getDrawnArea(){let t=this.area;const e=this.state;if(e.current.shadowBlur!==0||!e.current.shadowOffset.equals(c.origin)){const n=t.expandByDistance(e.current.shadowBlur).transform(p.translation(e.current.shadowOffset.x,e.current.shadowOffset.y));t=t.join(n)}return e.current.clippingRegion&&this.takeClippingRegionIntoAccount&&(t=t.intersectWith(e.current.clippingRegion)),t}getModifiedInstruction(){let t=Bi(this.transformationKind);if(this.tempState){const n=this.takeClippingRegionIntoAccount?this.state.getInstructionToConvertToStateWithClippedPath(this.tempState):this.state.getInstructionToConvertToState(this.tempState);t=N(t,n)}return Li(this.instruction,t)}}class ge{constructor(t){this.initiallyWithState=t,this.added=[]}get length(){return this.added.length}get currentlyWithState(){return this.addedLast?this.addedLast:this.initiallyWithState}reconstructState(t,e){e.setInitialState(t)}get stateOfFirstInstruction(){return this.initiallyWithState.stateOfFirstInstruction}get state(){return this.currentlyWithState.state}get initialState(){return this.initiallyWithState.initialState}addClippedPath(t){this.currentlyWithState.addClippedPath(t)}add(t){this.added.push(t),this.addedLast=t}removeAll(t){let e;for(;(e=this.added.findIndex(t))>-1;)this.removeAtIndex(e)}contains(t){return!!this.added.find(t)}setInitialState(t){this.initiallyWithState.setInitialState(t)}setInitialStateWithClippedPaths(t){this.initiallyWithState.setInitialStateWithClippedPaths(t)}beforeIndex(t){return t===0?this.initiallyWithState.state:this.added[t-1].state}removeAtIndex(t){t===this.added.length-1?this.added.length===1?this.addedLast=void 0:this.addedLast=this.added[t-1]:this.reconstructState(this.beforeIndex(t),this.added[t+1]),this.added.splice(t,1)}}class me{constructor(t,e){this.initialState=t,this.state=e,this.stateConversion=()=>{}}setInitialState(t){this.initialState=t;const e=this.initialState.getInstructionToConvertToState(this.state);this.stateConversion=e}get stateOfFirstInstruction(){return this.state}addClippedPath(t){this.state=this.state.withClippedPath(t)}setInitialStateWithClippedPaths(t){this.initialState=t;const e=this.initialState.getInstructionToConvertToStateWithClippedPath(this.state);this.stateConversion=e}}class q extends me{constructor(t,e,n,i){super(t,e),this.instruction=n,this.stateConversion=i}execute(t,e){this.stateConversion&&this.stateConversion(t,e),this.instruction(t,e)}static create(t,e){return new q(t,t,e,()=>{})}}class lt extends me{constructor(t,e,n,i){super(t,e),this.instruction=n,this.stateConversion=i}makeExecutable(){return new q(this.initialState,this.state,this.instruction,this.stateConversion)}static create(t,e){return new lt(t,t,e,()=>{})}}function C(s){return s.direction!==void 0}function K(s,t){return C(s)?t.applyToPointAtInfinity(s):t.apply(s)}class Fi{constructor(t,e){this.areaBuilder=t,this.transformation=e}addPosition(t){this.areaBuilder.addPosition(K(t,this.transformation))}}class pe{constructor(t,e){this.base=t,this.direction=e}pointIsOnSameLine(t){return t.minus(this.base).cross(this.direction)===0}comesBefore(t,e){return e.minus(t).dot(this.direction)>=0}lineSegmentIsOnSameLine(t){return this.direction.cross(t.direction)===0&&this.pointIsOnSameLine(t.point1)}expandLineByDistance(t){const e=this.direction.getPerpendicular(),n=new v(this.base,e).expandByDistance(t),i=new v(this.base,e.scale(-1)).expandByDistance(t);return new m([n,i])}getPointsInSameDirection(t,e){return this.comesBefore(e,t)?{point1:e,point2:t}:{point1:t,point2:e}}pointIsBetweenPoints(t,e,n){return t.minus(e).dot(this.direction)*t.minus(n).dot(this.direction)<=0}intersectsConvexPolygon(t){if(this.isContainedByConvexPolygon(t))return!0;const e=t.getIntersectionsWithLine(this.base,this.direction);for(let n of e)if(this.interiorContainsPoint(n.point))return!0;return!1}}class Mt extends pe{getVertices(){return[]}intersectWith(t){return t.intersectWithLine(this)}join(t){return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1))}intersectWithConvexPolygon(t){if(!this.intersectsConvexPolygon(t))return b;if(this.isContainedByConvexPolygon(t))return this;const e=t.getIntersectionsWithLine(this.base,this.direction);let n,i;for(let r of e)(!n&&!i||!n&&this.comesBefore(r.point,i)||!i&&this.comesBefore(n,r.point)||n&&i&&this.pointIsBetweenPoints(r.point,n,i))&&(r.halfPlane.normalTowardInterior.dot(this.direction)>0?n=r.point:i=r.point);return n&&i?new D(n,i):n?new V(n,this.direction):new V(i,this.direction.scale(-1))}intersectWithLine(t){return this.intersectsLine(t)?this:b}intersectWithLineSegment(t){return this.lineSegmentIsOnSameLine(t)?t:b}intersectWithRay(t){return this.intersectsRay(t)?t:b}isContainedByConvexPolygon(t){return t.containsPoint(this.base)&&t.containsInfinityInDirection(this.direction)&&t.containsInfinityInDirection(this.direction.scale(-1))}isContainedByLine(t){return this.intersectsSubsetOfLine(t)}isContainedByLineSegment(t){return!1}isContainedByRay(t){return!1}contains(t){return t.isContainedByLine(this)}intersectsLine(t){return this.intersectsSubsetOfLine(t)}intersectsSubsetOfLine(t){return this.pointIsOnSameLine(t.base)&&this.direction.cross(t.direction)===0}intersectsLineSegment(t){return this.lineSegmentIsOnSameLine(t)}intersectsRay(t){return this.intersectsSubsetOfLine(t)}intersects(t){return t.intersectsLine(this)}expandToIncludePoint(t){return this.pointIsOnSameLine(t)?this:m.createTriangleWithInfinityInDirection(this.base,t,this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1))}expandByDistance(t){return this.expandLineByDistance(t)}expandToIncludeInfinityInDirection(t){const e=t.cross(this.direction),n=this.direction.getPerpendicular();return e===0?this:e>0?m.createFromHalfPlane(new v(this.base,n.scale(-1))):m.createFromHalfPlane(new v(this.base,n))}transform(t){const e=t.apply(this.base);return new Mt(e,t.apply(this.base.plus(this.direction)).minus(e))}interiorContainsPoint(t){return this.pointIsOnSameLine(t)}}class V extends pe{getVertices(){return[this.base]}intersectWith(t){return t.intersectWithRay(this)}join(t){return t.expandToIncludePoint(this.base).expandToIncludeInfinityInDirection(this.direction)}intersectWithConvexPolygon(t){if(!this.intersectsConvexPolygon(t))return b;if(this.isContainedByConvexPolygon(t))return this;const e=t.getIntersectionsWithLine(this.base,this.direction);let n=this.base,i;for(let r of e)(!i&&this.comesBefore(n,r.point)||i&&this.pointIsBetweenPoints(r.point,n,i))&&(r.halfPlane.normalTowardInterior.dot(this.direction)>0?n=r.point:i=r.point);return i?new D(n,i):new V(n,this.direction)}intersectWithRay(t){return this.isContainedByRay(t)?this:t.isContainedByRay(this)?t:this.interiorContainsPoint(t.base)?new D(this.base,t.base):b}intersectWithLine(t){return t.intersectWithRay(this)}intersectWithLineSegment(t){if(t.isContainedByRay(this))return t;if(!this.lineSegmentIsOnSameLine(t))return b;let{point2:e}=this.getPointsInSameDirection(t.point1,t.point2);return this.comesBefore(e,this.base)?b:new D(this.base,e)}isContainedByConvexPolygon(t){return t.containsPoint(this.base)&&t.containsInfinityInDirection(this.direction)}isContainedByRay(t){return t.containsPoint(this.base)&&t.containsInfinityInDirection(this.direction)}isContainedByLine(t){return t.intersectsSubsetOfLine(this)}isContainedByLineSegment(t){return!1}contains(t){return t.isContainedByRay(this)}intersectsRay(t){return this.isContainedByRay(t)||t.isContainedByRay(this)||this.interiorContainsPoint(t.base)}intersectsLine(t){return t.intersectsSubsetOfLine(this)}intersectsLineSegment(t){if(t.isContainedByRay(this))return!0;if(!this.lineSegmentIsOnSameLine(t))return!1;let{point2:e}=this.getPointsInSameDirection(t.point1,t.point2);return!this.comesBefore(e,this.base)}intersects(t){return t.intersectsRay(this)}expandToIncludePoint(t){return this.containsPoint(t)?this:this.pointIsOnSameLine(t)?new V(t,this.direction):m.createTriangleWithInfinityInDirection(this.base,t,this.direction)}expandByDistance(t){const e=this.expandLineByDistance(t),n=new v(this.base,this.direction).expandByDistance(t);return e.intersectWithConvexPolygon(new m([n]))}expandToIncludeInfinityInDirection(t){return t.inSameDirectionAs(this.direction)?this:this.direction.cross(t)===0?new Mt(this.base,this.direction):m.createTriangleWithInfinityInTwoDirections(this.base,this.direction,t)}transform(t){const e=t.apply(this.base);return new V(e,t.apply(this.base.plus(this.direction)).minus(e))}interiorContainsPoint(t){return this.pointIsOnSameLine(t)&&!this.comesBefore(t,this.base)}containsInfinityInDirection(t){return this.direction.inSameDirectionAs(t)}containsPoint(t){return this.pointIsOnSameLine(t)&&this.comesBefore(this.base,t)}}class D extends pe{constructor(t,e){super(t,e.minus(t)),this.point1=t,this.point2=e}getVertices(){return[this.point1,this.point2]}join(t){return t.expandToIncludePoint(this.point1).expandToIncludePoint(this.point2)}intersectWith(t){return t.intersectWithLineSegment(this)}intersectWithLineSegment(t){if(this.isContainedByLineSegment(t))return this;if(t.isContainedByLineSegment(this))return t;if(!this.lineSegmentIsOnSameLine(t))return b;let{point1:e,point2:n}=this.getPointsInSameDirection(t.point1,t.point2);return this.comesBefore(n,this.point1)||this.comesBefore(this.point2,e)?b:this.comesBefore(this.point1,e)?new D(e,this.point2):new D(this.point1,n)}intersectWithRay(t){return t.intersectWithLineSegment(this)}intersectWithLine(t){return t.intersectWithLineSegment(this)}isContainedByRay(t){return t.containsPoint(this.point1)&&t.containsPoint(this.point2)}isContainedByLine(t){return t.intersectsSubsetOfLine(this)}isContainedByLineSegment(t){return t.containsPoint(this.point1)&&t.containsPoint(this.point2)}intersectWithConvexPolygon(t){if(!this.intersectsConvexPolygon(t))return b;if(this.isContainedByConvexPolygon(t))return this;const e=t.getIntersectionsWithLine(this.point1,this.direction);let n=this.point1,i=this.point2;for(let r of e)this.pointIsBetweenPoints(r.point,n,i)&&(r.halfPlane.normalTowardInterior.dot(this.direction)>0?n=r.point:i=r.point);return new D(n,i)}isContainedByConvexPolygon(t){return t.containsPoint(this.point1)&&t.containsPoint(this.point2)}contains(t){return t.isContainedByLineSegment(this)}pointIsStrictlyBetweenPoints(t,e,n){return t.minus(e).dot(this.direction)*t.minus(n).dot(this.direction)<0}containsPoint(t){return this.pointIsOnSameLine(t)&&this.pointIsBetweenPoints(t,this.point1,this.point2)}interiorContainsPoint(t){return this.pointIsOnSameLine(t)&&this.pointIsStrictlyBetweenPoints(t,this.point1,this.point2)}intersectsRay(t){return t.intersectsLineSegment(this)}intersectsLineSegment(t){if(this.isContainedByLineSegment(t)||t.isContainedByLineSegment(this))return!0;if(!this.lineSegmentIsOnSameLine(t))return!1;const{point1:e,point2:n}=this.getPointsInSameDirection(t.point1,t.point2);return!this.comesBefore(n,this.point1)&&!this.comesBefore(this.point2,e)}intersectsLine(t){return t.intersectsSubsetOfLine(this)}intersects(t){return t.intersectsLineSegment(this)}expandByDistance(t){const e=this.expandLineByDistance(t),n=new v(this.base,this.direction).expandByDistance(t),i=new v(this.point2,this.direction.scale(-1)).expandByDistance(t);return e.intersectWithConvexPolygon(new m([n,i]))}expandToIncludePoint(t){return this.containsPoint(t)?this:this.pointIsOnSameLine(t)?this.comesBefore(t,this.point1)?new D(t,this.point2):new D(this.point1,t):m.createTriangle(this.point1,t,this.point2)}expandToIncludeInfinityInDirection(t){return t.inSameDirectionAs(this.direction)?new V(this.point1,t):t.cross(this.direction)===0?new V(this.point2,t):m.createTriangleWithInfinityInDirection(this.point1,this.point2,t)}transform(t){return new D(t.apply(this.point1),t.apply(this.point2))}}class Ri{addPoint(t){return ht}addPointAtInfinity(t){return this}addArea(t){return ht}}const ve=new Ri;class we{constructor(t){this.towardsMiddle=t}addPoint(t){return m.createFromHalfPlane(new v(t,this.towardsMiddle))}addPointAtInfinity(t){return t.dot(this.towardsMiddle)>=0?this:ve}addArea(t){const e=this.towardsMiddle.getPerpendicular();return t.expandToIncludeInfinityInDirection(this.towardsMiddle).expandToIncludeInfinityInDirection(e).expandToIncludeInfinityInDirection(e.scale(-1))}}class Nt{constructor(t,e){this.direction1=t,this.direction2=e}addPoint(t){return m.createTriangleWithInfinityInTwoDirections(t,this.direction1,this.direction2)}addPointAtInfinity(t){return t.isInSmallerAngleBetweenPoints(this.direction1,this.direction2)?this:t.cross(this.direction1)===0?new we(this.direction2.projectOn(this.direction1.getPerpendicular())):t.cross(this.direction2)===0?new we(this.direction1.projectOn(this.direction2.getPerpendicular())):this.direction1.isInSmallerAngleBetweenPoints(t,this.direction2)?new Nt(t,this.direction2):this.direction2.isInSmallerAngleBetweenPoints(t,this.direction1)?new Nt(t,this.direction1):ve}addArea(t){return t.expandToIncludeInfinityInDirection(this.direction1).expandToIncludeInfinityInDirection(this.direction2)}}class Wi{constructor(t){this.direction=t}addPoint(t){return new Mt(t,this.direction)}addPointAtInfinity(t){return t.cross(this.direction)===0?this:new we(t.projectOn(this.direction.getPerpendicular()))}addArea(t){return t.expandToIncludeInfinityInDirection(this.direction).expandToIncludeInfinityInDirection(this.direction.scale(-1))}}class ki{constructor(t){this.direction=t}addPointAtInfinity(t){return t.inSameDirectionAs(this.direction)?this:t.cross(this.direction)===0?new Wi(this.direction):new Nt(this.direction,t)}addPoint(t){return new V(t,this.direction)}addArea(t){return t.expandToIncludeInfinityInDirection(this.direction)}}class Hi{constructor(t,e,n){this._area=t,this.firstPoint=e,this.subsetOfLineAtInfinity=n}get area(){return this._area||b}addPoint(t){this._area?this._area=this._area.expandToIncludePoint(t):this.firstPoint?t.equals(this.firstPoint)||(this._area=new D(this.firstPoint,t)):this.subsetOfLineAtInfinity?this._area=this.subsetOfLineAtInfinity.addPoint(t):this.firstPoint=t}addPosition(t){C(t)?this.addInfinityInDirection(t.direction):this.addPoint(t)}addInfinityInDirection(t){this._area?this._area=this._area.expandToIncludeInfinityInDirection(t):this.firstPoint?this._area=new V(this.firstPoint,t):this.subsetOfLineAtInfinity?(this.subsetOfLineAtInfinity=this.subsetOfLineAtInfinity.addPointAtInfinity(t),this.subsetOfLineAtInfinity===ve&&(this._area=ht)):this.subsetOfLineAtInfinity=new ki(t)}transformedWith(t){return new Fi(this,t)}}class qt extends me{constructor(t,e,n,i){super(t,e),this.instruction=n,this.stateConversion=i}replaceInstruction(t){this.instruction=t}makeExecutable(t){const e=t.getInfinity(this.state),n=this.instruction,i=(r,o)=>n(r,o,e);return new q(this.initialState,this.state,i,this.stateConversion)}static create(t,e){return new qt(t,t,e,()=>{})}}function Vi(s,t){return s?t?C(s)?C(t)&&s.direction.equals(t.direction):!C(t)&&s.equals(t):!s:!t}class Pt{constructor(t){this.shape=t}getInstructionToDrawLineTo(t,e){return this.getInstructionToExtendShapeWithLineTo(this.shape.transform(e.current.transformation.inverse()),t)}getInstructionToMoveToBeginning(t){return this.getInstructionToMoveToBeginningOfShape(this.shape.transform(t.current.transformation.inverse()))}get currentPosition(){return this.shape.currentPosition}moveToInfinityFromPointInDirection(t,e){return(n,i,r)=>{r.moveToInfinityFromPointInDirection(n,i,t,e)}}lineFromInfinityFromPointToInfinityFromPoint(t,e,n){return(i,r,o)=>{o.drawLineFromInfinityFromPointToInfinityFromPoint(i,r,t,e,n)}}lineFromInfinityFromPointToPoint(t,e){return(n,i,r)=>{r.drawLineFromInfinityFromPointToPoint(n,i,t,e)}}lineToInfinityFromPointInDirection(t,e){return(n,i,r)=>{r.drawLineToInfinityFromPointInDirection(n,i,t,e)}}lineToInfinityFromInfinityFromPoint(t,e,n){return(i,r,o)=>{o.drawLineToInfinityFromInfinityFromPoint(i,r,t,e,n)}}lineTo(t){return(e,n)=>{const{x:i,y:r}=n.userTransformation.apply(t);e.lineTo(i,r)}}moveTo(t){return(e,n)=>{const{x:i,y:r}=n.userTransformation.apply(t);e.moveTo(i,r)}}}class zt{constructor(t,e,n,i){this.initialPosition=t,this.firstFinitePoint=e,this.lastFinitePoint=n,this.currentPosition=i}transform(t){return new zt(t.applyToPointAtInfinity(this.initialPosition),t.apply(this.firstFinitePoint),t.apply(this.lastFinitePoint),t.applyToPointAtInfinity(this.currentPosition))}}class Ct{constructor(t,e,n){this.initialPosition=t,this.firstFinitePoint=e,this.currentPosition=n}transform(t){return new Ct(t.applyToPointAtInfinity(this.initialPosition),t.apply(this.firstFinitePoint),t.apply(this.currentPosition))}}class Mi extends Pt{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return t.initialPosition.direction.cross(t.currentPosition.direction)===0?this.moveToInfinityFromPointInDirection(t.firstFinitePoint,t.initialPosition.direction):N(this.moveToInfinityFromPointInDirection(t.lastFinitePoint,t.currentPosition.direction),this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint,t.currentPosition.direction,t.initialPosition.direction),this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint,t.firstFinitePoint,t.initialPosition.direction))}getInstructionToExtendShapeWithLineTo(t,e){return C(e)?this.lineToInfinityFromInfinityFromPoint(t.lastFinitePoint,t.currentPosition.direction,e.direction):N(this.lineFromInfinityFromPointToInfinityFromPoint(t.lastFinitePoint,e,t.currentPosition.direction),this.lineFromInfinityFromPointToPoint(e,t.currentPosition.direction))}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!this.shape.initialPosition.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}canAddLineTo(t){return!C(t)||!t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new zt(this.shape.initialPosition,this.shape.firstFinitePoint,this.shape.lastFinitePoint,t)):this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ct(this.shape.initialPosition,this.shape.firstFinitePoint,t))}}class Ni extends Pt{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){const e=this.moveToInfinityFromPointInDirection(t.currentPosition,t.initialPosition.direction);if(t.currentPosition.equals(t.firstFinitePoint))return e;const n=this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition,t.firstFinitePoint,t.initialPosition.direction);return N(e,n)}getInstructionToExtendShapeWithLineTo(t,e){return C(e)?this.lineToInfinityFromPointInDirection(t.currentPosition,e.direction):this.lineTo(e)}canAddLineTo(t){return!0}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!0}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointAtInfinityToPointAtInfinity(new zt(this.shape.initialPosition,this.shape.firstFinitePoint,this.shape.currentPosition,t)):this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ct(this.shape.initialPosition,this.shape.firstFinitePoint,t))}}class Gt{constructor(t,e){this.initialPoint=t,this.currentPosition=e}transform(t){return new Gt(t.apply(this.initialPoint),t.applyToPointAtInfinity(this.currentPosition))}}class It{constructor(t,e){this.initialPoint=t,this.currentPosition=e}transform(t){return new It(t.apply(this.initialPoint),t.apply(this.currentPosition))}}class qi extends Pt{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return this.moveTo(t.initialPoint)}getInstructionToExtendShapeWithLineTo(t,e){return C(e)?e.direction.inSameDirectionAs(t.currentPosition.direction)?()=>{}:this.lineToInfinityFromInfinityFromPoint(t.initialPoint,t.currentPosition.direction,e.direction):N(this.lineFromInfinityFromPointToInfinityFromPoint(t.initialPoint,e,t.currentPosition.direction),this.lineFromInfinityFromPointToPoint(e,t.currentPosition.direction))}canAddLineTo(t){return!C(t)||!t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!0}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointToPointAtInfinity(new Gt(this.shape.initialPoint,t)):this.pathBuilderProvider.fromPointToPoint(new It(this.shape.initialPoint,t))}}class vn extends Pt{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return this.moveTo(t.initialPoint)}getInstructionToExtendShapeWithLineTo(t,e){if(C(e)){const n=this.lineToInfinityFromPointInDirection(t.currentPosition,e.direction);if(t.currentPosition.minus(t.initialPoint).cross(e.direction)===0)return n;const i=this.lineFromInfinityFromPointToInfinityFromPoint(t.currentPosition,t.initialPoint,e.direction);return N(n,i)}return this.lineTo(e)}canAddLineTo(t){return!0}containsFinitePoint(){return!0}surroundsFinitePoint(){return!0}isClosable(){return!0}addPosition(t){return C(t)?this.pathBuilderProvider.fromPointToPointAtInfinity(new Gt(this.shape.initialPoint,t)):this.pathBuilderProvider.fromPointToPoint(new It(this.shape.initialPoint,t))}}class Yt{constructor(t,e,n,i){this.initialPosition=t,this.surroundsFinitePoint=e,this.positionsSoFar=n,this.currentPosition=i}transform(t){return new Yt(t.applyToPointAtInfinity(this.initialPosition),this.surroundsFinitePoint,this.positionsSoFar.map(e=>t.applyToPointAtInfinity(e)),t.applyToPointAtInfinity(this.currentPosition))}}class wn extends Pt{constructor(t,e){super(e),this.pathBuilderProvider=t}getInstructionToMoveToBeginningOfShape(t){return t.surroundsFinitePoint?(e,n,i)=>i.addPathAroundViewbox(e,n):()=>{}}getInstructionToExtendShapeWithLineTo(t,e){if(C(e))return;if(t.positionsSoFar.length===1)return this.lineFromInfinityFromPointToPoint(e,t.positionsSoFar[0].direction);const n=t.positionsSoFar.slice(1);let i=t.initialPosition;const r=[];for(let o of n)r.push(this.lineToInfinityFromInfinityFromPoint(e,i.direction,o.direction)),i=o;return N(N(...r),this.lineFromInfinityFromPointToPoint(e,i.direction))}canAddLineTo(t){return!C(t)||!t.direction.isInOppositeDirectionAs(this.shape.currentPosition.direction)}containsFinitePoint(){return!1}surroundsFinitePoint(){return this.shape.surroundsFinitePoint}isClosable(){return!0}addPosition(t){if(C(t)){const n=t.direction.isOnSameSideOfOriginAs(this.shape.initialPosition.direction,this.shape.currentPosition.direction)?this.shape.surroundsFinitePoint:!this.shape.surroundsFinitePoint;return this.pathBuilderProvider.atInfinity(new Yt(this.shape.initialPosition,n,this.shape.positionsSoFar.concat([t]),t))}return this.pathBuilderProvider.fromPointAtInfinityToPoint(new Ct(this.shape.initialPosition,t,t))}}class zi{fromPointAtInfinityToPointAtInfinity(t){return new Mi(this,t)}fromPointAtInfinityToPoint(t){return new Ni(this,t)}fromPointToPointAtInfinity(t){return new qi(this,t)}fromPointToPoint(t){return new vn(this,t)}atInfinity(t){return new wn(this,t)}getBuilderFromPosition(t){return C(t)?new wn(this,new Yt(t,!1,[t],t)):new vn(this,new It(t,t))}}class Pe extends ge{constructor(t){super(t),this._initiallyWithState=t}execute(t,e){this._initiallyWithState.execute(t,e);for(const n of this.added)n.execute(t,e)}}class Ce extends ge{constructor(t,e){super(t),this._initiallyWithState=t,this.pathInstructionBuilder=e}get currentPosition(){return this.pathInstructionBuilder.currentPosition}addInstruction(t){t.setInitialState(this.state),this.add(t)}closePath(){const t=lt.create(this.state,e=>{e.closePath()});this.add(t)}makeExecutable(t){const e=new Pe(this._initiallyWithState.makeExecutable(t));for(const n of this.added)e.add(n.makeExecutable(t));return e}surroundsFinitePoint(){return this.pathInstructionBuilder.surroundsFinitePoint()}isClosable(){return this.pathInstructionBuilder.isClosable()}canAddLineTo(t){return this.pathInstructionBuilder.canAddLineTo(t)}lineTo(t,e){const n=K(t,e.current.transformation);(!C(t)||this.pathInstructionBuilder.containsFinitePoint())&&this.addInstructionToDrawLineTo(t,e),this.pathInstructionBuilder=this.pathInstructionBuilder.addPosition(n);const i=this.pathInstructionBuilder.getInstructionToMoveToBeginning(this._initiallyWithState.state);this._initiallyWithState.replaceInstruction((r,o,a)=>{i(r,o,a)})}addInstructionToDrawLineTo(t,e){const n=this.pathInstructionBuilder.getInstructionToDrawLineTo(t,e),i=qt.create(e,n);i.setInitialState(this.state),this.add(i)}addPathInstruction(t,e,n){t.initialPoint&&!Vi(this.pathInstructionBuilder.currentPosition,t.initialPoint)&&this.lineTo(t.initialPoint,n),t.positionChange&&(this.pathInstructionBuilder=this.pathInstructionBuilder.addPosition(K(t.positionChange,n.current.transformation))),e.setInitialState(this.state),this.add(e)}static create(t,e){const n=K(e,t.current.transformation),i=new zi().getBuilderFromPosition(n),r=i.getInstructionToMoveToBeginning(t),o=qt.create(t,r);return new Ce(o,i)}}function Gi(s,t,e){let n=0,i;for(let r of s){const o=r.minus(t).dot(e);o>n&&(i=r,n=o)}return i?t.plus(i.minus(t).projectOn(e)):t}function R(s,t,e){return Gi(s.getVertices(),t,e)}class Yi{constructor(t,e){this.state=t,this.drawnPathProperties=e}addPathAroundViewbox(t,e){e.addPathAroundViewbox(t,this.drawnPathProperties.lineWidth)}getTransformedViewbox(t){const e=this.state.current.transformation.before(t.getBitmapTransformationToInfiniteCanvasContext());let n=t.polygon;n=n.transform(e.inverse()).expandByDistance(this.drawnPathProperties.lineWidth);for(const i of this.drawnPathProperties.shadowOffsets){const r=n.transform(p.translation(-i.x,-i.y));n=n.join(r)}return n}clearRect(t,e,n,i,r,o){const a=this.getTransformedViewbox(e),{a:l,b:h,c:d,d:u,e:g,f:w}=e.userTransformation;t.save(),t.transform(l,h,d,u,g,w);const P=Number.isFinite(n)?n:R(a,new c(0,0),n>0?Vt.direction:Ht.direction).x,y=Number.isFinite(r)?n+r:R(a,new c(0,0),r>0?Vt.direction:Ht.direction).x,B=Number.isFinite(i)?i:R(a,new c(0,0),i>0?Wt.direction:kt.direction).y,M=Number.isFinite(o)?i+o:R(a,new c(0,0),o>0?Wt.direction:kt.direction).y;t.clearRect(P,B,y-P,M-B),t.restore()}moveToInfinityFromPointInDirection(t,e,n,i){const r=R(this.getTransformedViewbox(e),n,i);this.moveToTransformed(t,r,e.userTransformation)}drawLineToInfinityFromInfinityFromPoint(t,e,n,i,r){const o=this.getTransformedViewbox(e),a=R(o,n,i),l=R(o,n,r),h=e.userTransformation,u=o.expandToIncludePoint(n).expandToIncludePoint(a).expandToIncludePoint(l).getVertices().filter(P=>!P.equals(a)&&!P.equals(l)&&!P.equals(n)&&P.minus(n).isInSmallerAngleBetweenPoints(i,r));u.sort((P,y)=>P.minus(n).isInSmallerAngleBetweenPoints(y.minus(n),i)?-1:1);let g=a,w=0;for(let P of u)w+=P.minus(g).mod(),this.lineToTransformed(t,P,h),g=P;w+=l.minus(g).mod(),this.lineToTransformed(t,l,h),this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,h,w,l,r)}drawLineFromInfinityFromPointToInfinityFromPoint(t,e,n,i,r){const o=this.getTransformedViewbox(e),a=R(o,n,r),l=e.userTransformation,h=R(o,i,r);this.lineToTransformed(t,h,l);const d=h.minus(a).mod();this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,l,d,h,r)}drawLineFromInfinityFromPointToPoint(t,e,n,i){const r=R(this.getTransformedViewbox(e),n,i),o=n.minus(r).mod(),a=e.userTransformation;this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,a,o,r,i),this.lineToTransformed(t,n,a)}drawLineToInfinityFromPointInDirection(t,e,n,i){const r=R(this.getTransformedViewbox(e),n,i),o=e.userTransformation;this.lineToTransformed(t,r,o);const a=r.minus(n).mod();this.ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,o,a,r,i)}ensureDistanceCoveredIsMultipleOfLineDashPeriod(t,e,n,i,r){const o=this.drawnPathProperties.lineDashPeriod;if(o===0)return;const a=this.getDistanceLeft(n,o);if(a===0)return;const l=i.plus(r.scale(a/(2*r.mod())));this.lineToTransformed(t,l,e),this.lineToTransformed(t,i,e)}lineToTransformed(t,e,n){const{x:i,y:r}=n.apply(e);t.lineTo(i,r)}moveToTransformed(t,e,n){const{x:i,y:r}=n.apply(e);t.moveTo(i,r)}getDistanceLeft(t,e){if(e===0)return 0;const n=t/e|0;return t-e*n===0?0:(n+1)*e-t}}class Ie{constructor(t){this.drawnPathProperties=t}getInfinity(t){return new Yi(t,this.drawnPathProperties)}}class Xi{constructor(t,e){this.instructions=t,this.area=e}get state(){return this.instructions.state}get initialState(){return this.instructions.initialState}execute(t,e){this.instructions.execute(t,e)}}class Tt extends ge{constructor(t){super(t),this._initiallyWithState=t,this.areaBuilder=new Hi}get area(){return this.areaBuilder.area}surroundsFinitePoint(){for(const t of this.added)if(t.surroundsFinitePoint())return!0;return!1}currentSubpathIsClosable(){return this.added.length===0?!0:this.added[this.added.length-1].isClosable()}allSubpathsAreClosable(){if(this.added.length===0)return!0;for(const t of this.added)if(!t.isClosable())return!1;return!0}drawPath(t,e,n){if(this.added.length===0)return;const i=q.create(e,t),r=this.makeExecutable(n);return i.setInitialState(r.state),r.add(i),r}makeExecutable(t){const e=new Pe(this._initiallyWithState.makeExecutable()),n=new Ie(t);for(const i of this.added)e.add(i.makeExecutable(n));return e}getInstructionsToClip(){const t=this.makeExecutable({lineWidth:0,lineDashPeriod:0,shadowOffsets:[]});return t.setInitialState(t.stateOfFirstInstruction),new Xi(t,this.area)}clipPath(t,e){if(this.added.length===0)return;const n=this.added[this.added.length-1],i=lt.create(e,t);n.addInstruction(i);const r=this.getInstructionsToClip();this.addClippedPath(r)}closePath(){if(this.added.length===0)return;this.added[this.added.length-1].closePath()}moveTo(t,e){const n=K(t,e.current.transformation);this.areaBuilder.addPosition(n);const i=Ce.create(e,t);i.setInitialState(this.state),this.add(i)}canAddLineTo(t,e){if(this.added.length===0)return!0;const n=K(t,e.current.transformation);return this.added[this.added.length-1].canAddLineTo(n)}lineTo(t,e){if(this.added.length===0){this.moveTo(t,e);return}const n=this.added[this.added.length-1],i=K(t,e.current.transformation);this.areaBuilder.addPosition(i),n.lineTo(t,e)}addPathInstruction(t,e){if(this.added.length===0)if(t.initialPoint)this.moveTo(t.initialPoint,e);else return;const n=this.added[this.added.length-1],i=n.currentPosition,r=K(i,e.current.transformation.inverse());t.changeArea(this.areaBuilder.transformedWith(e.current.transformation),r);const o=lt.create(e,t.instruction);n.addPathInstruction(t,o,e)}static create(t){return new Tt(lt.create(t,e=>{e.beginPath()}))}}class E{constructor(t,...e){this.topLeftCorner=t,this.corners=e}addSubpaths(t,e){this.topLeftCorner.moveToEndingPoint(t,e);for(const n of this.corners)n.draw(t,e);this.topLeftCorner.finishRect(t,e)}stroke(t,e){return H.forStrokingPath(e,t,n=>{const i=Tt.create(n);return this.addSubpaths(i,n),i})}fill(t,e){return H.forFillingPath(e,t,n=>{const i=Tt.create(n);return this.addSubpaths(i,n),i})}}class $i extends E{constructor(t,e,...n){super(e,...n),this.horizontal=t}getRoundRect(){return this}getArea(){return new m(this.horizontal.getHalfPlanesWithHorizontalCrossSection())}}class Ui extends E{constructor(t,e,...n){super(e,...n),this.vertical=t}getRoundRect(){return this}getArea(){return new m(this.vertical.getHalfPlanesWithVerticalCrossSection())}}class Ki extends E{constructor(t,e,n,i,r){super(n,i,r),this.horizontal=t,this.vertical=e,this.topLeft=n,this.right=i,this.bottom=r}getRoundRect(t){const e=this.topLeft.round(t.upperLeft);return new E(e,this.right,this.bottom)}getArea(){return new m([...this.vertical.getHalfPlanesWithVerticalCrossSection(),...this.horizontal.getHalfPlanesWithHorizontalCrossSection()])}}class ji extends E{constructor(t,e,...n){super(e,...n),this.horizontal=t}getRoundRect(){return this}getArea(){return new m(this.horizontal.getHalfPlanesWithHorizontalCrossSection())}}function Qi(s){return s.x!==void 0}function Pn(s){if(typeof s=="number"){if(Number.isNaN(s))return;if(s<0)throw new RangeError(`Radius value ${s} is negative.`);return{x:s,y:s,circular:!0}}const{x:t,y:e}=s;if(!(Number.isNaN(t)||Number.isNaN(e))){if(t<0)throw new RangeError(`X-radius value ${s} is negative.`);if(e<0)throw new RangeError(`Y-radius value ${s} is negative.`);return{x:t,y:e,circular:!1}}}function Xt(s,t){const{x:e,y:n,circular:i}=s;return{x:e*t,y:n*t,circular:i}}function Te(s,t){const{upperLeft:e,upperRight:n,lowerLeft:i,lowerRight:r}=s;return{upperLeft:Xt(e,t),upperRight:Xt(n,t),lowerLeft:Xt(i,t),lowerRight:Xt(r,t)}}function Ji(s){if(typeof s=="number"||Qi(s)){const n=Pn(s);return n?{upperLeft:n,upperRight:n,lowerLeft:n,lowerRight:n}:void 0}const t=[...s],e=t.slice(0,4).map(Pn);if(!e.includes(void 0)){if(e.length===4){const[n,i,r,o]=e;return{upperLeft:n,upperRight:i,lowerRight:r,lowerLeft:o}}if(e.length===3){const[n,i,r]=e;return{upperLeft:n,upperRight:i,lowerRight:r,lowerLeft:i}}if(e.length===2){const[n,i]=e;return{upperLeft:n,upperRight:i,lowerRight:n,lowerLeft:i}}if(e.length===1){const[n]=e;return{upperLeft:n,upperRight:n,lowerRight:n,lowerLeft:n}}throw new RangeError(`${t.length} radii provided. Between one and four radii are necessary.`)}}class Zi extends E{constructor(t,e,n,i,r){super(n,i,r),this.horizontal=t,this.vertical=e,this.topLeft=n,this.topRightCorner=i,this.bottom=r}getRoundRect(t){const e=this.horizontal.getLength(),n=t.upperLeft.x+t.upperRight.x,i=e/n;i<1&&(t=Te(t,i));const r=this.topRightCorner.round(t.upperRight),o=this.topLeft.round(t.upperLeft);return new E(o,r,this.bottom)}getArea(){return new m([...this.vertical.getHalfPlanesWithVerticalCrossSection(),...this.horizontal.getHalfPlanesWithHorizontalCrossSection()])}}class _i extends E{constructor(t,e,...n){super(e,...n),this.vertical=t}getRoundRect(){return this}getArea(){return new m(this.vertical.getHalfPlanesWithVerticalCrossSection())}}class ts extends E{constructor(t,e,n,i,r){super(n,i,r),this.vertical=t,this.horizontal=e,this.topLeft=n,this.right=i,this.bottomLeftCorner=r}getRoundRect(t){const e=this.vertical.getLength(),n=t.upperLeft.y+t.lowerLeft.y,i=e/n;i<1&&(t=Te(t,i));const r=this.topLeft.round(t.upperLeft),o=this.bottomLeftCorner.round(t.lowerLeft);return new E(r,this.right,o)}getArea(){return new m([...this.vertical.getHalfPlanesWithVerticalCrossSection(),...this.horizontal.getHalfPlanesWithHorizontalCrossSection()])}}class es extends E{constructor(t,e,n,i,r,o){super(n,i,r,o),this.vertical=t,this.horizontal=e,this.topLeft=n,this.topRight=i,this.bottomRight=r,this.bottomLeft=o}getRoundRect(t){const e=this.vertical.getLength(),n=this.horizontal.getLength(),i=Math.min(e/(t.upperLeft.y+t.lowerLeft.y),e/(t.upperRight.y+t.lowerRight.y),n/(t.upperLeft.x+t.upperRight.x),n/(t.lowerLeft.x+t.lowerRight.x));i<1&&(t=Te(t,i));const r=this.bottomRight.round(t.lowerRight),o=this.topLeft.round(t.upperLeft),a=this.topRight.round(t.upperRight),l=this.bottomLeft.round(t.lowerLeft);return new E(o,a,r,l)}getArea(){return new m([...this.horizontal.getHalfPlanesWithHorizontalCrossSection(),...this.vertical.getHalfPlanesWithVerticalCrossSection()])}}class $t{constructor(t){this.topLeftPosition=t}addSubpaths(t,e){t.moveTo(this.topLeftPosition,e)}getRoundRect(){return this}getArea(){}stroke(){}fill(){}}class ns{constructor(){this.area=ht}drawPath(t,e,n){const r=new Ie(n).getInfinity(e);return q.create(e,(o,a)=>{o.beginPath(),r.addPathAroundViewbox(o,a),t(o,a)})}}const is=new ns;function Cn(s,t){throw new Error(`The starting coordinates provided (${s.start} and ${t.start}) do not determine a direction.`)}class ss{constructor(t,e){this.horizontal=t,this.vertical=e}addSubpaths(){Cn(this.horizontal,this.vertical)}getRoundRect(){return this}getArea(){return ht}stroke(){}fill(t,e){return H.forFillingPath(e,t,()=>is)}}class Se{constructor(t,e){this.horizontal=t,this.vertical=e}addSubpaths(){Cn(this.horizontal,this.vertical)}getRoundRect(){return this}getArea(){}stroke(){}fill(){}}class et{static arc(t,e,n,i,r,o){return{instruction:(h,d)=>{const u=d.userTransformation,{x:g,y:w}=u.apply(new c(t,e)),{a:P,b:y,c:B,d:M,e:$,f:ot}=u.untranslated().before(p.translation(g,w));h.save(),h.transform(P,y,B,M,$,ot),h.arc(0,0,n,i,r,o),h.restore()},changeArea:h=>{h.addPosition(new c(t-n,e-n)),h.addPosition(new c(t-n,e+n)),h.addPosition(new c(t+n,e-n)),h.addPosition(new c(t+n,e+n))},positionChange:new c(t,e).plus(p.rotation(0,0,r).apply(new c(n,0))),initialPoint:new c(t,e).plus(p.rotation(0,0,i).apply(new c(n,0)))}}static arcTo(t,e,n,i,r){const o=new c(t,e),a=new c(n,i);return{instruction:(d,u)=>{const g=u.userTransformation,w=g.apply(o),P=g.apply(a);d.arcTo(w.x,w.y,P.x,P.y,r*g.scale)},changeArea:d=>{d.addPosition(o),d.addPosition(a)},positionChange:new c(n,i)}}static ellipse(t,e,n,i,r,o,a,l){return{instruction:(h,d)=>{const u=d.userTransformation,g=u.apply(new c(t,e)),w=u.getRotationAngle();h.ellipse(g.x,g.y,n*u.scale,i*u.scale,r+w,o,a,l)},changeArea:h=>{h.addPosition(new c(t-n,e-i)),h.addPosition(new c(t-n,e+i)),h.addPosition(new c(t+n,e-i)),h.addPosition(new c(t+n,e+i))},positionChange:new c(t,e).plus(p.rotation(0,0,a).before(new p(n,0,0,i,0,0)).before(p.rotation(0,0,r)).apply(new c(1,0))),initialPoint:new c(t,e).plus(p.rotation(0,0,o).before(new p(n,0,0,i,0,0)).before(p.rotation(0,0,r)).apply(new c(1,0)))}}static bezierCurveTo(t,e,n,i,r,o){return{instruction:(a,l)=>{const h=l.userTransformation,d=h.apply(new c(t,e)),u=h.apply(new c(n,i)),g=h.apply(new c(r,o));a.bezierCurveTo(d.x,d.y,u.x,u.y,g.x,g.y)},changeArea:(a,l)=>{C(l)||(a.addPosition(new c((l.x+t)/2,(l.y+e)/2)),a.addPosition(new c((t+n)/2,(e+i)/2)),a.addPosition(new c((n+r)/2,(i+o)/2)),a.addPosition(new c(r,o)))},positionChange:new c(r,o)}}static quadraticCurveTo(t,e,n,i){return{instruction:(r,o)=>{const a=o.userTransformation,l=a.apply(new c(t,e)),h=a.apply(new c(n,i));r.quadraticCurveTo(l.x,l.y,h.x,h.y)},changeArea:(r,o)=>{C(o)||(r.addPosition(new c((o.x+t)/2,(o.y+e)/2)),r.addPosition(new c((t+n)/2,(e+i)/2)),r.addPosition(new c(n,i)))},positionChange:new c(n,i)}}}var z=(s=>(s[s.TOPLEFT=0]="TOPLEFT",s[s.TOPRIGHT=1]="TOPRIGHT",s[s.BOTTOMLEFT=2]="BOTTOMLEFT",s[s.BOTTOMRIGHT=3]="BOTTOMRIGHT",s))(z||{});function rs(s){switch(s){case 0:return 2;case 1:return 3;case 3:return 1;case 2:return 0}}function os(s){switch(s){case 0:return 1;case 1:return 0;case 3:return 2;case 2:return 3}}class In{constructor(t,e,n,i,r){this.corner=e,n=cs(n,i,r);const o=r===i;let{center:a,start:l,end:h}=hs(n,e,t);o||({start:l,end:h}={start:h,end:l}),this.radii=t,this.clockwise=o,this.center=a,this.start=l,this.end=h}draw(t,e){t.lineTo(this.start.point,e),this.radii.circular?t.addPathInstruction(et.arc(this.center.x,this.center.y,this.radii.x,this.start.angle,this.end.angle,!this.clockwise),e):t.addPathInstruction(et.ellipse(this.center.x,this.center.y,this.radii.x,this.radii.y,0,this.start.angle,this.end.angle,!this.clockwise),e)}}class as extends In{moveToEndingPoint(t,e){t.moveTo(this.end.point,e)}finishRect(t,e){this.draw(t,e),t.moveTo(this.corner,e)}}function cs(s,t,e){return t===I.Negative&&(s=os(s)),e===I.Negative&&(s=rs(s)),s}function hs(s,t,e){switch(s){case z.TOPLEFT:return{center:new c(t.x+e.x,t.y+e.y),start:{angle:Math.PI,point:new c(t.x,t.y+e.y)},end:{angle:3*Math.PI/2,point:new c(t.x+e.x,t.y)}};case z.TOPRIGHT:return{center:new c(t.x-e.x,t.y+e.y),start:{angle:3*Math.PI/2,point:new c(t.x-e.x,t.y)},end:{angle:0,point:new c(t.x,t.y+e.y)}};case z.BOTTOMRIGHT:return{center:new c(t.x-e.x,t.y-e.y),start:{angle:0,point:new c(t.x,t.y-e.y)},end:{angle:Math.PI/2,point:new c(t.x-e.x,t.y)}};case z.BOTTOMLEFT:return{center:new c(t.x+e.x,t.y-e.y),start:{angle:Math.PI/2,point:new c(t.x+e.x,t.y)},end:{angle:Math.PI,point:new c(t.x,t.y-e.y)}}}}class ye{constructor(t,e,n,i){this.corner=t,this.cornerOrientation=e,this.horizontalOrientation=n,this.verticalOrientation=i}draw(t,e){t.lineTo(this.corner,e)}round(t){return t.x===0||t.y===0?this:new In(t,this.corner,this.cornerOrientation,this.horizontalOrientation,this.verticalOrientation)}}class ls{constructor(t,e,n,i){this.corner=t,this.cornerOrientation=e,this.horizontalOrientation=n,this.verticalOrientation=i}moveToEndingPoint(t,e){t.moveTo(this.corner,e)}finishRect(t,e){t.closePath(),t.moveTo(this.corner,e)}round(t){return t.x===0||t.y===0?this:new as(t,this.corner,this.cornerOrientation,this.horizontalOrientation,this.verticalOrientation)}}class xe{constructor(t,e){this.point=t,this.direction=e}draw(t,e){t.lineTo(this.point,e),t.lineTo(this.direction,e)}}class us{constructor(t,e){this.point=t,this.direction=e}moveToEndingPoint(t,e){t.moveTo(this.direction,e)}finishRect(t,e){t.lineTo(this.point,e),t.lineTo(this.direction,e),t.closePath(),t.moveTo(this.direction,e)}}class be{constructor(t){this.direction=t}draw(t,e){t.lineTo(this.direction,e)}}class ds{constructor(t){this.direction=t}moveToEndingPoint(t,e){t.moveTo(this.direction,e)}finishRect(t,e){t.closePath(),t.moveTo(this.direction,e)}}class Oe{constructor(t,e){this.start=t,this.orientation=e,this.horizontalLineStart=e===I.Positive?Ht:Vt,this.horizontalLineEnd=e===I.Positive?Vt:Ht,this.verticalLineStart=e===I.Positive?kt:Wt,this.verticalLineEnd=e===I.Positive?Wt:kt}createTopLeftAtVerticalInfinity(t){return new us(new c(t.finiteStart,0),this.verticalLineStart)}createBottomRightAtInfinity(t){return new xe(new c(t.end,0),this.verticalLineEnd)}createRightAtInfinity(t){return new be(t.horizontalLineEnd)}createBottomAtInfinity(){return new be(this.verticalLineEnd)}addVerticalDimension(t){return t.addEntireHorizontalDimension(this)}addEntireHorizontalDimension(t){return new ss(t,this)}addHorizontalDimensionAtInfinity(t){return new Se(t,this)}addHorizontalDimensionWithStart(t){const e=this.createTopLeftAtVerticalInfinity(t),n=this.createRightAtInfinity(t),i=this.createBottomAtInfinity();return new $i(t,e,n,i)}addHorizontalDimensionWithStartAndEnd(t){const e=this.createTopLeftAtVerticalInfinity(t),n=this.createBottomRightAtInfinity(t);return new ji(t,e,n)}}class Ut extends Oe{addVerticalDimension(t){return t.addHorizontalDimensionAtInfinity(this)}addEntireHorizontalDimension(t){return new Se(t,this)}addHorizontalDimensionAtInfinity(t){return new Se(t,this)}addHorizontalDimensionWithStart(){return new $t(this.verticalLineEnd)}addHorizontalDimensionWithStartAndEnd(){return new $t(this.verticalLineEnd)}}class Tn extends Oe{constructor(t,e){super(e,t),this.finiteStart=e}createBottomLeftAtInfinity(t){return new be(t.horizontalLineStart)}createLeftAtInfinity(t){return new ds(t.horizontalLineStart)}createTopRightAtHorizontalInfinity(t){return new xe(new c(0,this.finiteStart),t.horizontalLineEnd)}createTopLeft(t){return new ls(new c(t.finiteStart,this.finiteStart),z.TOPLEFT,t.orientation,this.orientation)}createTopRight(t){return new ye(new c(t.end,this.finiteStart),z.TOPRIGHT,t.orientation,this.orientation)}getStartingHalfPlaneWithHorizontalCrossSection(){const t=this.orientation===I.Positive?new c(1,0):new c(-1,0),e=new c(this.finiteStart,0);return new v(e,t)}getStartingHalfPlaneWithVerticalCrossSection(){const t=this.orientation===I.Positive?new c(0,1):new c(0,-1),e=new c(0,this.finiteStart);return new v(e,t)}addVerticalDimension(t){return t.addHorizontalDimensionWithStart(this)}addEntireHorizontalDimension(t){const e=this.createLeftAtInfinity(t),n=this.createTopRightAtHorizontalInfinity(t),i=this.createBottomAtInfinity(),r=this.createBottomLeftAtInfinity(t);return new Ui(this,e,n,i,r)}addHorizontalDimensionAtInfinity(t){return new $t(t.horizontalLineEnd)}addHorizontalDimensionWithStart(t){const e=this.createRightAtInfinity(t),n=this.createBottomAtInfinity(),i=this.createTopLeft(t);return new Ki(t,this,i,e,n)}addHorizontalDimensionWithStartAndEnd(t){const e=this.createBottomAtInfinity(),n=this.createTopLeft(t),i=this.createTopRight(t);return new Zi(t,this,n,i,e)}getHalfPlanesWithHorizontalCrossSection(){return[this.getStartingHalfPlaneWithHorizontalCrossSection()]}getHalfPlanesWithVerticalCrossSection(){return[this.getStartingHalfPlaneWithVerticalCrossSection()]}}class Sn extends Tn{constructor(t,e,n){super(t,e),this.end=n}createBottomLeftAtHorizontalInfinity(t){return new xe(new c(0,this.end),t.horizontalLineStart)}getEndingHalfPlaneWithHorizontalCrossSection(){const t=this.orientation===I.Positive?new c(-1,0):new c(1,0),e=new c(this.end,0);return new v(e,t)}getEndingHalfPlaneWithVerticalCrossSection(){const t=this.orientation===I.Positive?new c(0,-1):new c(0,1),e=new c(0,this.end);return new v(e,t)}createBottomLeft(t){return new ye(new c(t.finiteStart,this.end),z.BOTTOMLEFT,t.orientation,this.orientation)}createBottomRight(t){return new ye(new c(t.end,this.end),z.BOTTOMRIGHT,t.orientation,this.orientation)}getLength(){return Math.abs(this.end-this.finiteStart)}addEntireHorizontalDimension(t){const e=this.createLeftAtInfinity(t),n=this.createTopRightAtHorizontalInfinity(t),i=this.createBottomLeftAtHorizontalInfinity(t);return new _i(this,e,n,i)}addHorizontalDimensionAtInfinity(t){return new $t(t.horizontalLineEnd)}addVerticalDimension(t){return t.addHorizontalDimensionWithStartAndEnd(this)}addHorizontalDimensionWithStart(t){const e=this.createRightAtInfinity(t),n=this.createTopLeft(t),i=this.createBottomLeft(t);return new ts(this,t,n,e,i)}addHorizontalDimensionWithStartAndEnd(t){const e=this.createTopLeft(t),n=this.createTopRight(t),i=this.createBottomLeft(t),r=this.createBottomRight(t);return new es(this,t,e,n,r,i)}getHalfPlanesWithHorizontalCrossSection(){return[this.getStartingHalfPlaneWithHorizontalCrossSection(),this.getEndingHalfPlaneWithHorizontalCrossSection()]}getHalfPlanesWithVerticalCrossSection(){return[this.getStartingHalfPlaneWithVerticalCrossSection(),this.getEndingHalfPlaneWithVerticalCrossSection()]}}function yn(s,t){const e=t>0?I.Positive:I.Negative;return new Sn(e,s,s+t)}function xn(s,t){const e=t>0?I.Positive:I.Negative,n=new Oe(s,e);return Number.isFinite(s)?Number.isFinite(t)?new Sn(e,s,s+t):new Tn(e,s):Number.isFinite(t)?s<0?new Ut(s,I.Negative):new Ut(s,I.Positive):s>0?e===I.Positive?new Ut(s,I.Positive):n:e===I.Positive?n:new Ut(s,I.Negative)}function j(s,t,e,n){const i=xn(s,e),r=xn(t,n);return i.addVerticalDimension(r)}function bn(s,t,e,n){const i=yn(s,e);return yn(t,n).addHorizontalDimensionWithStartAndEnd(i)}class fs{constructor(t){this.viewBox=t}fillText(t,e,n,i){let r=i===void 0?o=>{o.fillText(t,e,n)}:o=>{o.fillText(t,e,n,i)};this.viewBox.addDrawing(r,this.getDrawnRectangle(e,n,t),k.Relative,!0)}measureText(t){return this.viewBox.measureText(t)}strokeText(t,e,n,i){let r=i===void 0?o=>{o.strokeText(t,e,n)}:o=>{o.strokeText(t,e,n,i)};this.viewBox.addDrawing(r,this.getDrawnRectangle(e,n,t),k.Relative,!0)}getDrawnRectangle(t,e,n){const i=this.viewBox.measureText(n);let r;i.actualBoundingBoxRight!==void 0?r=Math.abs(i.actualBoundingBoxRight-i.actualBoundingBoxLeft):r=i.width;const o=i.actualBoundingBoxAscent!==void 0?i.actualBoundingBoxAscent+i.actualBoundingBoxDescent:1,a=i.actualBoundingBoxAscent!==void 0?i.actualBoundingBoxAscent:0;return j(t,e-a,r,o).getArea()}}function gs(s){return typeof s.duration<"u"}function ms(s){return gs(s)?{width:s.displayWidth,height:s.displayHeight}:{width:s.width,height:s.height}}class ps{constructor(t){this.viewBox=t}drawImage(){const t=Array.prototype.slice.apply(arguments);let e,n,i,r,o,a,l,h,d;arguments.length<=5?[e,a,l,h,d]=t:[e,n,i,r,o,a,l,h,d]=t;const{width:u,height:g}=ms(e),w=this.getDrawnLength(u,n,r,h),P=this.getDrawnLength(g,i,o,d),y=j(a,l,w,P).getArea(),B=this.getDrawImageInstruction(arguments.length,e,n,i,r,o,a,l,h,d);this.viewBox.addDrawing(B,y,k.Relative,!0)}getDrawImageInstruction(t,e,n,i,r,o,a,l,h,d){switch(t){case 3:return u=>{u.drawImage(e,a,l)};case 5:return u=>{u.drawImage(e,a,l,h,d)};case 9:return u=>{u.drawImage(e,n,i,r,o,a,l,h,d)};default:throw new TypeError(`Failed to execute 'drawImage' on 'CanvasRenderingContext2D': Valid arities are: [3, 5, 9], but ${t} arguments provided.`)}}getDrawnLength(t,e,n,i){const r=this.getLength(t);return i!==void 0?i:e!==void 0?n!==void 0?n:r-e:r}getLength(t){return typeof t=="number"?t:t.baseVal.value}}function vs(s,t,e,n,i){t=t===void 0?0:t,e=e===void 0?0:e,n=n===void 0?s.width:n,i=i===void 0?s.height:i;const r=s.data,o=new Uint8ClampedArray(4*n*i);for(let a=0;a{this.latestClippedPath.execute(e,n)};if(this.previouslyClippedPaths){const e=this.previouslyClippedPaths.getInstructionToRecreate(),n=this.previouslyClippedPaths.latestClippedPath.state.getInstructionToConvertToState(this.latestClippedPath.initialState);return(i,r)=>{e(i,r),n(i,r),t(i,r)}}return t}}class ws extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.direction=t}}}const Le=new ws("direction",S);class Ps extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.font=t}}}const Be=new Ps("font",S);class On{constructor(t){this.propertyName=t}changeInstanceValue(t,e){return this.valuesAreEqual(t[this.propertyName],e)?t:t.changeProperty(this.propertyName,e)}isEqualForInstances(t,e){return this.valuesAreEqual(t[this.propertyName],e[this.propertyName])}valueIsTransformableForInstance(t){return!0}changeToNewValue(t,e){return e?this.changeToNewValueTransformed(t):this.changeToNewValueUntransformed(t)}getInstructionToChange(t,e){const n=t[this.propertyName],i=e[this.propertyName];return this.valuesAreEqual(n,i)&&(t.fillAndStrokeStylesTransformed===e.fillAndStrokeStylesTransformed||this.valuesAreEqualWhenTransformed(n,i))?()=>{}:this.changeToNewValue(i,e.fillAndStrokeStylesTransformed)}}class Ln extends On{constructor(t){super(t)}valuesAreEqual(t,e){return t===e}changeToNewValueTransformed(t){return(e,n)=>{const i=n.userTransformation;e[this.propertyName]=t*i.scale}}changeToNewValueUntransformed(t){return e=>{e[this.propertyName]=t}}valuesAreEqualWhenTransformed(t,e){return t===0&&e===0}}const Bn=new Ln("lineWidth"),An=new Ln("lineDashOffset");class Cs extends On{valuesAreEqual(t,e){if(t.length!==e.length)return!1;for(let n=0;n{const i=n.userTransformation;e.setLineDash(t.map(r=>r*i.scale))}}changeToNewValueUntransformed(t){return e=>{e.setLineDash(t)}}valuesAreEqualWhenTransformed(t,e){return t.length===0&&e.length===0}}const Dn=new Cs("lineDash");class Is extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.textAlign=t}}}const Ae=new Is("textAlign",S);class Ts extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>{e.textBaseline=t}}}const De=new Ts("textBaseline",S);class Ss extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.lineCap=t}}const En=new Ss("lineCap",S);class ys extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.lineJoin=t}}const Fn=new ys("lineJoin",S);class xs extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.miterLimit=t}}const Rn=new xs("miterLimit",S),Ee=[Le,Ze,_e,nn,An,Dn,En,Fn,Rn,Qe,Je,pn,Bn,sn,Ae,De,Et,Be,ue,on,rn],bs=[Be,Ae,De,Le],jt=class oi{constructor(t){this.fillStyle=t.fillStyle,this.fontKerning=t.fontKerning,this.lineWidth=t.lineWidth,this.lineCap=t.lineCap,this.lineJoin=t.lineJoin,this.lineDash=t.lineDash,this.miterLimit=t.miterLimit,this.globalAlpha=t.globalAlpha,this.globalCompositeOperation=t.globalCompositeOperation,this.filter=t.filter,this.strokeStyle=t.strokeStyle,this.lineDashOffset=t.lineDashOffset,this.transformation=t.transformation,this.direction=t.direction,this.imageSmoothingEnabled=t.imageSmoothingEnabled,this.imageSmoothingQuality=t.imageSmoothingQuality,this.font=t.font,this.textAlign=t.textAlign,this.textBaseline=t.textBaseline,this.clippedPaths=t.clippedPaths,this.fillAndStrokeStylesTransformed=t.fillAndStrokeStylesTransformed,this.shadowOffset=t.shadowOffset,this.shadowColor=t.shadowColor,this.shadowBlur=t.shadowBlur}changeProperty(t,e){const{fillStyle:n,fontKerning:i,lineWidth:r,lineDash:o,lineCap:a,lineJoin:l,miterLimit:h,globalAlpha:d,globalCompositeOperation:u,filter:g,strokeStyle:w,lineDashOffset:P,transformation:y,direction:B,imageSmoothingEnabled:M,imageSmoothingQuality:$,font:ot,textAlign:Lt,textBaseline:Bt,clippedPaths:At,fillAndStrokeStylesTransformed:Xe,shadowOffset:$e,shadowColor:Ue,shadowBlur:Ke}=this,Dt={fillStyle:n,fontKerning:i,lineWidth:r,lineDash:o,lineCap:a,lineJoin:l,miterLimit:h,globalAlpha:d,globalCompositeOperation:u,filter:g,strokeStyle:w,lineDashOffset:P,transformation:y,direction:B,imageSmoothingEnabled:M,imageSmoothingQuality:$,font:ot,textAlign:Lt,textBaseline:Bt,clippedPaths:At,fillAndStrokeStylesTransformed:Xe,shadowOffset:$e,shadowColor:Ue,shadowBlur:Ke};return Dt[t]=e,new oi(Dt)}get clippingRegion(){return this.clippedPaths?this.clippedPaths.area:void 0}equals(t){for(let e of Ee)if(!e.isEqualForInstances(this,t))return!1;return(!this.clippedPaths&&!t.clippedPaths||this.clippedPaths&&this.clippedPaths===t.clippedPaths)&&this.fillAndStrokeStylesTransformed===t.fillAndStrokeStylesTransformed}getMaximumLineWidth(){return this.lineWidth*this.transformation.getMaximumLineWidthScale()}getLineDashPeriod(){return this.lineDash.reduce((t,e)=>t+e,0)}isTransformable(){for(let t of Ee)if(!t.valueIsTransformableForInstance(this))return!1;return!0}getShadowOffsets(){const t=[],e=this.filter.getShadowOffset();return e!==null&&t.push(e),this.shadowOffset.equals(c.origin)||t.push(this.shadowOffset),t}getInstructionToConvertToState(t){return this.getInstructionToConvertToStateOnDimensions(t,Ee)}withClippedPath(t){const e=this.clippedPaths?this.clippedPaths.withClippedPath(t):new Kt(t.area,t);return this.changeProperty("clippedPaths",e)}getInstructionToConvertToStateOnDimensions(t,e){const n=e.map(i=>i.getInstructionToChange(this,t));return N(...n)}};jt.default=new jt({fillStyle:"#000",fontKerning:"auto",lineWidth:1,lineDash:[],lineCap:"butt",lineJoin:"miter",miterLimit:10,globalAlpha:1,globalCompositeOperation:"source-over",filter:mn.none,strokeStyle:"#000",lineDashOffset:0,transformation:p.identity,direction:"inherit",imageSmoothingEnabled:!0,imageSmoothingQuality:"low",font:"10px sans-serif",textAlign:"start",textBaseline:"alphabetic",clippedPaths:void 0,fillAndStrokeStylesTransformed:!1,shadowOffset:c.origin,shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0}),jt.setDefault=()=>{};let G=jt;class Os{constructor(t){this.viewBox=t}createImageData(t,e){}getImageData(t,e,n,i){}putImageData(t,e,n,i,r,o,a){t=vs(t,i,r,o,a);let l,h=this.viewBox.getDrawingLock();this.viewBox.createPatternFromImageData(t).then(u=>{l=u,h.release()}),this.viewBox.addDrawing(u=>{u.translate(e,n),u.fillStyle=l,u.fillRect(0,0,t.width,t.height)},j(e,n,t.width,t.height).getArea(),k.Absolute,!1,u=>u.changeProperty("shadowColor",G.default.shadowColor).changeProperty("shadowOffset",G.default.shadowOffset).changeProperty("shadowBlur",G.default.shadowBlur).changeProperty("globalAlpha",G.default.globalAlpha).changeProperty("globalCompositeOperation",G.default.globalCompositeOperation).changeProperty("imageSmoothingEnabled",!1).changeProperty("filter",G.default.filter))}}class Ls{constructor(t){this.viewBox=t}get lineCap(){return this.viewBox.state.current.lineCap}set lineCap(t){this.viewBox.changeState(e=>En.changeInstanceValue(e,t))}get lineDashOffset(){return this.viewBox.state.current.lineDashOffset}set lineDashOffset(t){this.viewBox.changeState(e=>An.changeInstanceValue(e,t))}get lineJoin(){return this.viewBox.state.current.lineJoin}set lineJoin(t){this.viewBox.changeState(e=>Fn.changeInstanceValue(e,t))}get lineWidth(){return this.viewBox.state.current.lineWidth}set lineWidth(t){this.viewBox.changeState(e=>Bn.changeInstanceValue(e,t))}get miterLimit(){return this.viewBox.state.current.miterLimit}set miterLimit(t){this.viewBox.changeState(e=>Rn.changeInstanceValue(e,t))}getLineDash(){return this.viewBox.state.current.lineDash}setLineDash(t){t.length%2===1&&(t=t.concat(t)),this.viewBox.changeState(e=>Dn.changeInstanceValue(e,t))}}class Bs extends T{valuesAreEqual(t,e){return t===e}changeToNewValue(t){return e=>e.fontKerning=t}}const As=new Bs("fontKerning",S);class Ds{constructor(t){this.viewBox=t}set direction(t){this.viewBox.changeState(e=>Le.changeInstanceValue(e,t))}set font(t){this.viewBox.changeState(e=>Be.changeInstanceValue(e,t))}set textAlign(t){this.viewBox.changeState(e=>Ae.changeInstanceValue(e,t))}set textBaseline(t){this.viewBox.changeState(e=>De.changeInstanceValue(e,t))}set fontKerning(t){this.viewBox.changeState(e=>As.changeInstanceValue(e,t))}}class Es{constructor(t){this.viewBox=t}arc(t,e,n,i,r,o){this.viewBox.addPathInstruction(et.arc(t,e,n,i,r,o))}arcTo(t,e,n,i,r){this.viewBox.addPathInstruction(et.arcTo(t,e,n,i,r))}closePath(){this.viewBox.closePath()}ellipse(t,e,n,i,r,o,a,l){this.viewBox.addPathInstruction(et.ellipse(t,e,n,i,r,o,a,l))}lineTo(t,e){this.viewBox.lineTo(new c(t,e))}lineToInfinityInDirection(t,e){this.viewBox.lineTo({direction:new c(t,e)})}moveTo(t,e){this.viewBox.moveTo(new c(t,e))}moveToInfinityInDirection(t,e){this.viewBox.moveTo({direction:new c(t,e)})}quadraticCurveTo(t,e,n,i){this.viewBox.addPathInstruction(et.quadraticCurveTo(t,e,n,i))}bezierCurveTo(t,e,n,i,r,o){this.viewBox.addPathInstruction(et.bezierCurveTo(t,e,n,i,r,o))}rect(t,e,n,i){this.viewBox.rect(t,e,n,i)}roundRect(t,e,n,i,r){this.viewBox.roundRect(t,e,n,i,r)}}class Fs{constructor(t,e,n){this.canvas=t,this.canvasState=new wt(e),this.canvasTransform=new ci(e),this.canvasCompositing=new ui(e),this.canvasImageSmoothing=new gi(e),this.canvasStrokeStyles=new mi(e),this.canvasShadowStyles=new Pi(e),this.canvasFilters=new Ii(e,n),this.canvasRect=new Ti(e),this.canvasDrawPath=new Si(e),this.canvasUserInterface=new yi,this.canvasText=new fs(e),this.canvasDrawImage=new ps(e),this.canvasImageData=new Os(e),this.canvasPathDrawingStyles=new Ls(e),this.canvasTextDrawingStyles=new Ds(e),this.canvasPath=new Es(e)}getContextAttributes(){return this.canvas.getContext("2d").getContextAttributes()}save(){this.canvasState.save()}restore(){this.canvasState.restore()}reset(){this.canvasState.reset()}getTransform(){return this.canvasTransform.getTransform()}resetTransform(){this.canvasTransform.resetTransform()}rotate(t){this.canvasTransform.rotate(t)}scale(t,e){this.canvasTransform.scale(t,e)}setTransform(t,e,n,i,r,o){this.canvasTransform.setTransform(t,e,n,i,r,o)}transform(t,e,n,i,r,o){this.canvasTransform.transform(t,e,n,i,r,o)}translate(t,e){this.canvasTransform.translate(t,e)}set globalAlpha(t){this.canvasCompositing.globalAlpha=t}set globalCompositeOperation(t){this.canvasCompositing.globalCompositeOperation=t}set imageSmoothingEnabled(t){this.canvasImageSmoothing.imageSmoothingEnabled=t}set imageSmoothingQuality(t){this.canvasImageSmoothing.imageSmoothingQuality=t}set fillStyle(t){this.canvasStrokeStyles.fillStyle=t}set strokeStyle(t){this.canvasStrokeStyles.strokeStyle=t}createLinearGradient(t,e,n,i){return this.canvasStrokeStyles.createLinearGradient(t,e,n,i)}createPattern(t,e){return this.canvasStrokeStyles.createPattern(t,e)}createRadialGradient(t,e,n,i,r,o){return this.canvasStrokeStyles.createRadialGradient(t,e,n,i,r,o)}createConicGradient(t,e,n){return this.canvasStrokeStyles.createConicGradient(t,e,n)}set shadowBlur(t){this.canvasShadowStyles.shadowBlur=t}set shadowColor(t){this.canvasShadowStyles.shadowColor=t}set shadowOffsetX(t){this.canvasShadowStyles.shadowOffsetX=t}set shadowOffsetY(t){this.canvasShadowStyles.shadowOffsetY=t}set filter(t){this.canvasFilters.filter=t}clearRect(t,e,n,i){this.canvasRect.clearRect(t,e,n,i)}fillRect(t,e,n,i){this.canvasRect.fillRect(t,e,n,i)}strokeRect(t,e,n,i){this.canvasRect.strokeRect(t,e,n,i)}beginPath(){this.canvasDrawPath.beginPath()}clip(t,e){this.canvasDrawPath.clip(t,e)}fill(t,e){this.canvasDrawPath.fill(t,e)}isPointInPath(t,e,n,i){return this.canvasDrawPath.isPointInPath(t,e,n,i)}isPointInStroke(t,e,n){return this.canvasDrawPath.isPointInStroke(t,e,n)}stroke(t){this.canvasDrawPath.stroke(t)}drawFocusIfNeeded(t,e){this.canvasUserInterface.drawFocusIfNeeded(t,e)}scrollPathIntoView(t){this.canvasUserInterface.scrollPathIntoView(t)}fillText(t,e,n,i){this.canvasText.fillText(t,e,n,i)}measureText(t){return this.canvasText.measureText(t)}strokeText(t,e,n,i){this.canvasText.strokeText(t,e,n,i)}drawImage(){this.canvasDrawImage.drawImage.apply(this.canvasDrawImage,arguments)}createImageData(t,e){return this.canvasImageData.createImageData(t,e)}getImageData(t,e,n,i){return this.canvasImageData.getImageData(t,e,n,i)}putImageData(t,e,n,i,r,o,a){this.canvasImageData.putImageData(t,e,n,i,r,o,a)}set lineCap(t){this.canvasPathDrawingStyles.lineCap=t}set lineDashOffset(t){this.canvasPathDrawingStyles.lineDashOffset=t}set lineJoin(t){this.canvasPathDrawingStyles.lineJoin=t}set lineWidth(t){this.canvasPathDrawingStyles.lineWidth=t}set miterLimit(t){this.canvasPathDrawingStyles.miterLimit=t}getLineDash(){return this.canvasPathDrawingStyles.getLineDash()}setLineDash(t){this.canvasPathDrawingStyles.setLineDash(t)}set direction(t){this.canvasTextDrawingStyles.direction=t}set font(t){this.canvasTextDrawingStyles.font=t}set textAlign(t){this.canvasTextDrawingStyles.textAlign=t}set textBaseline(t){this.canvasTextDrawingStyles.textBaseline=t}set fontKerning(t){this.canvasTextDrawingStyles.fontKerning=t}arc(t,e,n,i,r,o){this.canvasPath.arc(t,e,n,i,r,o)}arcTo(t,e,n,i,r){this.canvasPath.arcTo(t,e,n,i,r)}bezierCurveTo(t,e,n,i,r,o){this.canvasPath.bezierCurveTo(t,e,n,i,r,o)}closePath(){this.canvasPath.closePath()}ellipse(t,e,n,i,r,o,a,l){this.canvasPath.ellipse(t,e,n,i,r,o,a)}lineTo(t,e){this.canvasPath.lineTo(t,e)}lineToInfinityInDirection(t,e){this.canvasPath.lineToInfinityInDirection(t,e)}moveTo(t,e){this.canvasPath.moveTo(t,e)}moveToInfinityInDirection(t,e){this.canvasPath.moveToInfinityInDirection(t,e)}quadraticCurveTo(t,e,n,i){this.canvasPath.quadraticCurveTo(t,e,n,i)}rect(t,e,n,i){this.canvasPath.rect(t,e,n,i)}roundRect(t,e,n,i,r){this.canvasPath.roundRect(t,e,n,i,r)}}class Fe extends Ft{constructor(){super(...arguments),this.colorStops=[]}addColorStopsToGradient(t){for(const e of this.colorStops)t.addColorStop(e.offset,e.color)}addColorStop(t,e){this.colorStops.push({offset:t,color:e})}getInstructionToSetTransformed(t){return(e,n)=>{const i=n.userTransformation;e[t]=this.createTransformedGradient(i)}}getInstructionToSetUntransformed(t){return e=>{e[t]=this.createGradient()}}}class Rs extends Fe{constructor(t,e,n,i,r){super(),this.context=t,this.x0=e,this.y0=n,this.x1=i,this.y1=r}createTransformedGradient(t){const{x:e,y:n}=t.apply(new c(this.x0,this.y0)),{x:i,y:r}=t.apply(new c(this.x1,this.y1)),o=this.context.createLinearGradient(e,n,i,r);return this.addColorStopsToGradient(o),o}createGradient(){const t=this.context.createLinearGradient(this.x0,this.y0,this.x1,this.y1);return this.addColorStopsToGradient(t),t}}class Ws extends Fe{constructor(t,e,n,i,r,o,a){super(),this.context=t,this.x0=e,this.y0=n,this.r0=i,this.x1=r,this.y1=o,this.r1=a}createTransformedGradient(t){const{x:e,y:n}=t.apply(new c(this.x0,this.y0)),{x:i,y:r}=t.apply(new c(this.x1,this.y1)),o=this.r0*t.scale,a=this.r1*t.scale,l=this.context.createRadialGradient(e,n,o,i,r,a);return this.addColorStopsToGradient(l),l}createGradient(){const t=this.context.createRadialGradient(this.x0,this.y0,this.r0,this.x1,this.y1,this.r1);return this.addColorStopsToGradient(t),t}}class Wn{constructor(t){this.currentState=t,this.instructions=[]}restore(){this.addChangeToState(this.currentState.restored(),t=>{t.restore()})}save(){this.addChangeToState(this.currentState.saved(),t=>{t.save()})}changeCurrentInstanceTo(t){if(this.currentState.current.equals(t))return;const e=this.currentState.current.getInstructionToConvertToState(t),n=this.currentState.withCurrentState(t);this.addChangeToState(n,e)}addChangeToState(t,e){this.currentState=t,e&&this.instructions.push(e)}get instruction(){if(this.instructions.length!==0)return(t,e)=>{for(const n of this.instructions)n(t,e)}}}class Re extends Wn{changeCurrentInstanceTo(t){if(!this.currentState.current.equals(t)){if(!Re.canConvert(this.currentState.current,t))if(this.currentState.stack.length>0)this.restore(),this.save();else{super.changeCurrentInstanceTo(t);return}if(t.clippedPaths){const e=this.currentState,i=e.current.clippedPaths;if(t.clippedPaths===i)super.changeCurrentInstanceTo(t);else{const o=t.clippedPaths.except(i);this.convertToState(o.initialState),this.addChangeToState(o.latestClippedPath.state,o.getInstructionToRecreate()),this.convertToState(e.replaceCurrent(t))}}else super.changeCurrentInstanceTo(t)}}convertToState(t){const e=this.currentState.getInstructionToConvertToState(t);this.addChangeToState(t,e)}static canConvert(t,e){return t.clippedPaths?e.clippedPaths?e.clippedPaths.contains(t.clippedPaths):!1:!0}}class Q{constructor(t,e=[]){this.current=t,this.stack=e}replaceCurrent(t){return new Q(t,this.stack)}withCurrentState(t){return new Q(t,this.stack)}currentlyTransformed(t){return this.withCurrentState(this.current.changeProperty("fillAndStrokeStylesTransformed",t))}withClippedPath(t){return new Q(this.current.withClippedPath(t),this.stack)}saved(){return new Q(this.current,(this.stack||[]).concat([this.current]))}restored(){if(!this.stack||this.stack.length===0)return this;const t=this.stack[this.stack.length-1];return new Q(t,this.stack.slice(0,this.stack.length-1))}convertToLastSavedInstance(t,e){for(let n=this.stack.length-1;n>e;n--)t.restore()}convertFromLastSavedInstance(t,e){for(let n=e+1;n{n.clearRect(l,h,i,r,o,a)},()=>{},e)}}class Qt extends Pe{reconstructState(t,e){e.setInitialStateWithClippedPaths(t)}hasDrawingAcrossBorderOf(t){return this.contains(e=>e.drawingArea.hasDrawingAcrossBorderOf(t))}intersects(t){return this.contains(e=>e.drawingArea.intersects(t))}addClearRect(t,e,n,i,r,o){const l=new Ie({lineWidth:0,lineDashPeriod:0,shadowOffsets:[]}).getInfinity(e),h=We.createClearRect(e,t,l,n,i,r,o);h.setInitialState(this.state),this.add(h)}clearContentsInsideArea(t){this.removeAll(e=>e.drawingArea.isContainedBy(t))}static create(){return new Qt(new q(kn,kn,G.setDefault,()=>{}))}}class Hs{constructor(t){this.area=t}hasDrawingAcrossBorderOf(t){return this.isContainedBy(t)?!1:this.intersects(t)}isContainedBy(t){return t.contains(this.area)}intersects(t){return this.area.intersects(t)}}class Vs{constructor(t,e){this.instructions=t,this.drawingArea=new Hs(e)}get state(){return this.instructions.state}get initialState(){return this.instructions.initialState}get stateOfFirstInstruction(){return this.instructions.stateOfFirstInstruction}setInitialState(t){this.instructions.setInitialState(t)}setInitialStateWithClippedPaths(t){this.instructions.setInitialStateWithClippedPaths(t)}addClippedPath(t){this.instructions.addClippedPath(t)}execute(t,e){this.instructions.execute(t,e)}}function Ms(s,t,e,n){if(e===void 0){t.addSubpaths(s,n);return}let i=Ji(e);if(!i)return;t.getRoundRect(i).addSubpaths(s,n)}class Ns{constructor(t){this.onChange=t,this.previousInstructionsWithPath=Qt.create(),this.state=this.previousInstructionsWithPath.state}beginPath(){const t=Tt.create(this.state);t.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state),this.currentInstructionsWithPath=t}changeState(t){this.state=this.state.withCurrentState(t(this.state.current))}saveState(){this.state=this.state.saved()}restoreState(){this.state=this.state.restored()}resetState(){this.previousInstructionsWithPath=Qt.create(),this.state=this.previousInstructionsWithPath.state,this.currentInstructionsWithPath=void 0,this.onChange()}allSubpathsAreClosable(){return!this.currentInstructionsWithPath||this.currentInstructionsWithPath.allSubpathsAreClosable()}currentPathSurroundsFinitePoint(){return this.currentInstructionsWithPath&&this.currentInstructionsWithPath.surroundsFinitePoint()}currentSubpathIsClosable(){return!this.currentInstructionsWithPath||this.currentInstructionsWithPath.currentSubpathIsClosable()}fillPath(t){if(!this.currentInstructionsWithPath)return;const e=H.forFillingPath(t,this.state,()=>this.currentInstructionsWithPath);this.state=e.state,this.incorporateDrawingInstruction(e)}strokePath(){if(!this.currentInstructionsWithPath)return;const t=H.forStrokingPath(e=>{e.stroke()},this.state,()=>this.currentInstructionsWithPath);this.state=t.state,this.incorporateDrawingInstruction(t)}fillRect(t,e){const n=t.fill(this.state,e);n&&this.incorporateDrawingInstruction(n)}strokeRect(t){const e=t.stroke(this.state,n=>{n.stroke()});e&&this.incorporateDrawingInstruction(e)}addDrawing(t,e,n,i,r){const o=this.state.currentlyTransformed(!1);n===k.Relative&&(e=e.transform(this.state.current.transformation));let a;r&&(a=o.withCurrentState(r(o.current))),this.incorporateDrawingInstruction(new H(t,e,l=>q.create(o,l),i,n,o,a))}clipPath(t){this.clipCurrentPath(t)}incorporateDrawingInstruction(t){const e=t.getDrawnArea();if(e===b)return;const n=t.getModifiedInstruction();this.addToPreviousInstructions(n,e,t.build),this.currentInstructionsWithPath||(this.state=this.previousInstructionsWithPath.state),this.onChange()}addToPreviousInstructions(t,e,n){const i=new Vs(n(t),e);i.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state),this.previousInstructionsWithPath.add(i)}clipCurrentPath(t){this.currentInstructionsWithPath&&(this.currentInstructionsWithPath.clipPath(t,this.state),this.state=this.currentInstructionsWithPath.state)}addPathInstruction(t){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.addPathInstruction(t,this.state)}closePath(){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.closePath()}moveTo(t){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.moveTo(t,this.state)}canAddLineTo(t){return!this.currentInstructionsWithPath||this.currentInstructionsWithPath.canAddLineTo(t,this.state)}lineTo(t){this.currentInstructionsWithPath&&this.currentInstructionsWithPath.lineTo(t,this.state)}rect(t){this.currentInstructionsWithPath&&t.addSubpaths(this.currentInstructionsWithPath,this.state)}roundRect(t,e){this.currentInstructionsWithPath&&Ms(this.currentInstructionsWithPath,t,e,this.state)}intersects(t){return this.previousInstructionsWithPath.intersects(t)}clearContentsInsideArea(t){this.previousInstructionsWithPath.clearContentsInsideArea(t),this.currentInstructionsWithPath&&this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state)}clearArea(t,e,n,i){const o=j(t,e,n,i).getArea();if(!o)return;const a=o.transform(this.state.current.transformation);this.intersects(a)&&(this.clearContentsInsideArea(a),this.previousInstructionsWithPath.hasDrawingAcrossBorderOf(a)&&(this.previousInstructionsWithPath.addClearRect(o,this.state,t,e,n,i),this.currentInstructionsWithPath&&this.currentInstructionsWithPath.setInitialStateWithClippedPaths(this.state)),this.onChange())}execute(t,e){this.previousInstructionsWithPath.length&&this.previousInstructionsWithPath.execute(t,e);const i=this.previousInstructionsWithPath.state.stack.length;for(let r=0;rthis.draw())}get width(){return this.rectangleManager.rectangle.viewboxWidth}get height(){return this.rectangleManager.rectangle.viewboxHeight}get state(){return this.instructionSet.state}get transformation(){return this.rectangleManager.rectangle.userTransformation}set transformation(t){this.rectangleManager.setTransformation(t),this.draw()}getDrawingLock(){return this.drawLockProvider()}changeState(t){this.instructionSet.changeState(t)}measureText(t){this.context.save(),G.default.getInstructionToConvertToStateOnDimensions(this.state.currentlyTransformed(!1).current,bs)(this.context);const n=this.context.measureText(t);return this.context.restore(),n}saveState(){this.instructionSet.saveState()}restoreState(){this.instructionSet.restoreState()}resetState(){this.instructionSet.resetState()}beginPath(){this.instructionSet.beginPath()}async createPatternFromImageData(t){const e=await createImageBitmap(t);return this.context.createPattern(e,"no-repeat")}addDrawing(t,e,n,i,r){this.instructionSet.addDrawing(t,e,n,i,r)}addPathInstruction(t){this.instructionSet.addPathInstruction(t)}closePath(){this.instructionSet.currentSubpathIsClosable()&&this.instructionSet.closePath()}moveTo(t){this.instructionSet.moveTo(t)}lineTo(t){this.instructionSet.canAddLineTo(t)&&this.instructionSet.lineTo(t)}rect(t,e,n,i){const r=j(t,e,n,i);this.instructionSet.rect(r)}roundRect(t,e,n,i,r){const o=j(t,e,n,i);this.instructionSet.roundRect(o,r)}currentPathCanBeFilled(){return this.instructionSet.allSubpathsAreClosable()&&this.instructionSet.currentPathSurroundsFinitePoint()}fillPath(t){this.instructionSet.fillPath(t)}strokePath(){this.instructionSet.strokePath()}fillRect(t,e,n,i,r){const o=j(t,e,n,i);this.instructionSet.fillRect(o,r)}strokeRect(t,e,n,i){const r=j(t,e,n,i);this.instructionSet.strokeRect(r)}clipPath(t){this.instructionSet.clipPath(t)}clearArea(t,e,n,i){this.instructionSet.clearArea(t,e,n,i)}createLinearGradient(t,e,n,i){return new Rs(this.context,t,e,n,i)}createRadialGradient(t,e,n,i,r,o){return new Ws(this.context,t,e,n,i,r,o)}createConicGradient(t,e,n){return new qs(this.context,t,e,n)}createPattern(t,e){let n;return n=new tn(this.context.createPattern(t,e)),n}draw(){this.drawingIterationProvider.provideDrawingIteration(()=>(this.isTransforming()||this.rectangleManager.measure(),this.rectangleManager.rectangle?(this.context.restore(),this.context.save(),this.context.clearRect(0,0,this.width,this.height),this.setInitialTransformation(),this.instructionSet.execute(this.context,this.rectangleManager.rectangle),!0):!1))}setInitialTransformation(){const t=this.rectangleManager.rectangle.initialBitmapTransformation;if(t.equals(p.identity))return;const{a:e,b:n,c:i,d:r,e:o,f:a}=t;this.context.setTransform(e,n,i,r,o,a)}}class Gs{constructor(t,e){this.context=e,this.initialTransformation=e.transformation,this.angularVelocity=Math.PI/100,this.point=t.onMoved(()=>{this.setTransformation()},!1)}setTransformation(){this.context.transformation=this.initialTransformation.before(p.rotation(this.point.initial.x,this.point.initial.y,(this.point.initial.x-this.point.current.x)*this.angularVelocity))}withAnchor(t){return this}withoutAnchor(t){this.point.cancel()}end(){this.point.cancel()}}class Ys{constructor(t,e,n,i,r){this.transformable=t,this.centerX=e,this.centerY=n,this.onFinish=r,this.initialTransformation=t.transformation,this.maxScaleLogStep=.1,this.currentScaleLog=0,this.targetScaleLog=Math.log(i),this.makeStep()}makeStep(){const t=this.targetScaleLog-this.currentScaleLog;Math.abs(t)<=this.maxScaleLogStep?(this.currentScaleLog+=t,this.setTransformToCurrentScaleLog(),this.onFinish()):(this.currentScaleLog+=t<0?-this.maxScaleLogStep:this.maxScaleLogStep,this.setTransformToCurrentScaleLog(),this.stepTimeout=setTimeout(()=>this.makeStep(),20))}setTransformToCurrentScaleLog(){this.transformable.transformation=this.initialTransformation.before(p.zoom(this.centerX,this.centerY,Math.exp(this.currentScaleLog)))}cancel(){this.stepTimeout!==void 0&&clearTimeout(this.stepTimeout)}}class Xs{constructor(t,e){this.anchor=t,this.context=e,this.initialTransformation=e.transformation,this.point=t.onMoved(()=>{this.setTransformation()},!0)}setTransformation(){this.context.transformation=this.initialTransformation.before(this.getTranslation())}getTranslation(){return p.translation(this.point.current.x-this.point.initial.x,this.point.current.y-this.point.initial.y)}withAnchor(t){return t===this.anchor?this:this.context.getGestureForTwoAnchors(this.point.cancel(),t)}withoutAnchor(t){this.point.cancel()}}class Hn{constructor(t,e,n){this.context=n,this.initialTransformation=n.transformation,this.point1=t.onMoved(()=>this.setTransformation(),this.fixesFirstAnchorOnInfiniteCanvas()),this.point2=e.onMoved(()=>this.setTransformation(),this.fixesSecondAnchorOnInfiniteCanvas())}withAnchor(t){return this}withoutAnchor(t){const e=this.point1.cancel(),n=this.point2.cancel();if(t===e)return this.context.getGestureForOneAnchor(n);if(t===n)return this.context.getGestureForOneAnchor(e)}}class $s extends Hn{constructor(t,e,n){super(t,e,n)}fixesFirstAnchorOnInfiniteCanvas(){return!0}fixesSecondAnchorOnInfiniteCanvas(){return!1}setTransformation(){this.context.transformation=this.initialTransformation.before(p.translateZoom(this.point1.initial.x,this.point1.initial.y,this.point2.initial.x,this.point2.initial.y,this.point1.current.x,this.point1.current.y,this.point2.current.x,this.point2.current.y))}}class Us extends Hn{constructor(t,e,n){super(t,e,n)}fixesFirstAnchorOnInfiniteCanvas(){return!0}fixesSecondAnchorOnInfiniteCanvas(){return!0}setTransformation(){this.context.transformation=this.initialTransformation.before(p.translateRotateZoom(this.point1.initial.x,this.point1.initial.y,this.point2.initial.x,this.point2.initial.y,this.point1.current.x,this.point1.current.y,this.point2.current.x,this.point2.current.y))}}class St{constructor(){this.mapped=[]}onRemoved(t){}add(t){this.mapped.some(e=>this.mapsTo(e,t))||this.mapped.push(this.map(t))}remove(t){const e=this.mapped.findIndex(i=>this.mapsTo(i,t));if(e===-1)return;const[n]=this.mapped.splice(e,1);this.onRemoved(n)}}class J extends St{map(t){return t}mapsTo(t,e){return t.listener===e.listener}onRemoved(t){t.removedCallback&&t.removedCallback()}addListener(t,e){this.add({listener:t,removedCallback:e})}removeListener(t){this.remove({listener:t})}dispatch(t){const e=this.mapped.map(n=>n.listener);for(let n of e)n(t)}}class Ks{constructor(t,e){this.setNewValue=t,this.timeoutInMs=e,this._changing=!1,this._firstChange=new J,this._subsequentChange=new J,this._changeEnd=new J}get firstChange(){return this._firstChange}get subsequentChange(){return this._subsequentChange}get changeEnd(){return this._changeEnd}get changing(){return this._changing}refreshTimeout(){this.currentTimeout!==void 0&&clearTimeout(this.currentTimeout),this.currentTimeout=setTimeout(()=>{this._changing=!1,this.currentTimeout=void 0,this._changeEnd.dispatch()},this.timeoutInMs)}setValue(t){this.setNewValue(t),this._changing||(this._changing=!0,this._firstChange.dispatch()),this._subsequentChange.dispatch(),this.refreshTimeout()}}class js{constructor(t,e){this.viewBox=t,this.config=e,this._transformationChangeMonitor=new Ks(n=>this.viewBox.transformation=n,100)}get isTransforming(){return this._transformationChangeMonitor.changing}get transformationStart(){return this._transformationChangeMonitor.firstChange}get transformationChange(){return this._transformationChangeMonitor.subsequentChange}get transformationEnd(){return this._transformationChangeMonitor.changeEnd}get transformation(){return this.viewBox.transformation}set transformation(t){this._transformationChangeMonitor.setValue(t)}getGestureForOneAnchor(t){return new Xs(t,this)}getGestureForTwoAnchors(t,e){return this.config.rotationEnabled?new Us(t,e,this):new $s(t,e,this)}releaseAnchor(t){this.gesture&&(this.gesture=this.gesture.withoutAnchor(t))}zoom(t,e,n){this._zoom&&this._zoom.cancel(),this._zoom=new Ys(this,t,e,n,()=>{this._zoom=void 0})}addRotationAnchor(t){this.gesture=new Gs(t,this)}addAnchor(t){if(!this.gesture){this.gesture=this.getGestureForOneAnchor(t);return}const e=this.gesture.withAnchor(t);e&&(this.gesture=e)}}class Qs{constructor(){this.animationFrameRequested=!1}provideDrawingIteration(t){this.animationFrameRequested||(this.animationFrameRequested=!0,requestAnimationFrame(()=>{t(),this.animationFrameRequested=!1}))}}class Js{constructor(t){this.drawingIterationProvider=t,this._drawHappened=new J}get drawHappened(){return this._drawHappened}provideDrawingIteration(t){this.drawingIterationProvider.provideDrawingIteration(()=>{const e=t();return e&&this._drawHappened.dispatch(),e})}}class Zs{constructor(t){this.drawingIterationProvider=t,this._locks=[]}removeLock(t){const e=this._locks.indexOf(t);this._locks.splice(e,1),this._locks.length===0&&this._draw&&this.drawingIterationProvider.provideDrawingIteration(this._draw)}provideDrawingIteration(t){this._locks.length?this._draw=t:this.drawingIterationProvider.provideDrawingIteration(t)}getLock(){let t;return t={release:()=>{this.removeLock(t)}},this._locks.push(t),t}}var x=(s=>(s[s.CSS=0]="CSS",s[s.CANVAS=1]="CANVAS",s))(x||{});class L{constructor(t){this.base=t,this.inverseBase=t.inverse()}getSimilarTransformation(t){return this.inverseBase.before(t).before(this.base)}representSimilarTransformation(t){return this.base.before(t).before(this.inverseBase)}representBase(t){return t.before(this.inverseBase)}}class yt{constructor(t,e,n){this.userCoordinates=t,this.canvasBitmap=e,this.virtualBitmapBase=n,this.setDerivedProperties()}withCanvasBitmapDistortion(t){const e=this.canvasBitmap.representBase(t),n=this.userCoordinates.representSimilarTransformation(e),i=this.virtualBitmapBase.before(n),r=new L(t);return new yt(this.userCoordinates,r,i)}withUserTransformation(t){return new yt(new L(t),this.canvasBitmap,this.virtualBitmapBase)}setDerivedProperties(){this.infiniteCanvasContext=new L(this.virtualBitmapBase.before(this.userCoordinates.base)),this.userCoordinatesInsideCanvasBitmap=new L(this.userCoordinates.base.before(this.canvasBitmap.base)),this.initialBitmapTransformation=this.canvasBitmap.representBase(this.userCoordinates.getSimilarTransformation(this.virtualBitmapBase)),this.icContextFromCanvasBitmap=new L(this.infiniteCanvasContext.base.before(this.canvasBitmap.inverseBase))}}class xt{constructor(t,e){this.userCoordinates=t,this.canvasBitmap=e,this.setDerivedProperties()}get infiniteCanvasContext(){return this.userCoordinates}withUserTransformation(t){return new xt(new L(t),this.canvasBitmap)}withCanvasBitmapDistortion(t){return new xt(this.userCoordinates,new L(t))}setDerivedProperties(){this.userCoordinatesInsideCanvasBitmap=new L(this.userCoordinates.base.before(this.canvasBitmap.base)),this.initialBitmapTransformation=this.canvasBitmap.inverseBase,this.icContextFromCanvasBitmap=new L(this.userCoordinates.base.before(this.canvasBitmap.inverseBase))}}function Vn(s){const{screenWidth:t,screenHeight:e,viewboxWidth:n,viewboxHeight:i}=s;return new p(t/n,0,0,e/i,0,0)}class ut{constructor(t,e){this.units=t,this.coordinates=e}get userTransformation(){return this.coordinates.userCoordinates.base}get infiniteCanvasContext(){return this.coordinates.infiniteCanvasContext}get initialBitmapTransformation(){return this.coordinates.initialBitmapTransformation}getBitmapTransformationToTransformedInfiniteCanvasContext(){return this.coordinates.userCoordinates.base}getBitmapTransformationToInfiniteCanvasContext(){return this.coordinates.icContextFromCanvasBitmap.base}translateInfiniteCanvasContextTransformationToBitmapTransformation(t){return this.coordinates.icContextFromCanvasBitmap.getSimilarTransformation(p.create(t))}getTransformationForInstruction(t){const e=p.create(t).before(this.coordinates.infiniteCanvasContext.base),n=this.coordinates.userCoordinatesInsideCanvasBitmap.representBase(e);return this.coordinates.userCoordinates.getSimilarTransformation(n)}withUserTransformation(t){const e=this.coordinates.withUserTransformation(t);return new ut(this.units,e)}withCanvasMeasurement(t){const e=Vn(t),n=this.coordinates.withCanvasBitmapDistortion(e);return new ut(this.units,n)}withUnits(t){if(t===this.units)return this;let e;return t===x.CANVAS?e=new yt(this.coordinates.userCoordinates,this.coordinates.canvasBitmap,this.coordinates.canvasBitmap.base):e=new xt(this.coordinates.userCoordinates,this.coordinates.canvasBitmap),new ut(t,e)}static create(t,e){const n=Vn(e),i=t===x.CANVAS?new yt(new L(p.identity),new L(n),n):new xt(new L(p.identity),new L(n));return new ut(t,i)}}function _s(s,t){return s?t?s.viewboxWidth===t.viewboxWidth&&s.viewboxHeight===t.viewboxHeight&&s.screenWidth===t.screenWidth&&s.screenHeight===t.screenHeight:!1:!t}class dt{constructor(t,e,n){this.coordinates=t,this.measurement=e,this.polygon=n}get viewboxWidth(){return this.measurement.viewboxWidth}get viewboxHeight(){return this.measurement.viewboxHeight}get userTransformation(){return this.coordinates.userTransformation}get infiniteCanvasContext(){return this.coordinates.infiniteCanvasContext}get initialBitmapTransformation(){return this.coordinates.initialBitmapTransformation}withUnits(t){const e=this.coordinates.withUnits(t);return new dt(e,this.measurement,this.polygon)}withTransformation(t){const e=this.coordinates.withUserTransformation(p.create(t));return new dt(e,this.measurement,this.polygon)}withMeasurement(t){if(_s(this.measurement,t))return this;const{viewboxWidth:n,viewboxHeight:i}=t,r=bn(0,0,n,i).getArea(),o=this.coordinates.withCanvasMeasurement(t);return new dt(o,t,r)}getCSSPosition(t,e){const{left:n,top:i}=this.measurement;return new c(t-n,e-i)}getTransformationForInstruction(t){return this.coordinates.getTransformationForInstruction(t)}translateInfiniteCanvasContextTransformationToBitmapTransformation(t){return this.coordinates.translateInfiniteCanvasContextTransformationToBitmapTransformation(t)}getBitmapTransformationToTransformedInfiniteCanvasContext(){return this.coordinates.getBitmapTransformationToTransformedInfiniteCanvasContext()}getBitmapTransformationToInfiniteCanvasContext(){return this.coordinates.getBitmapTransformationToInfiniteCanvasContext()}addPathAroundViewbox(t,e){const n=this.viewboxWidth+2*e,i=this.viewboxHeight+2*e;t.save(),t.setTransform(1,0,0,1,0,0),t.rect(-e,-e,n,i),t.restore()}static create(t,e){const{viewboxWidth:n,viewboxHeight:i}=t,r=bn(0,0,n,i).getArea(),o=ut.create(e,t);return new dt(o,t,r)}}class tr{constructor(t,e){this.measurementProvider=t,this.config=e,this.transformation=p.identity}setTransformation(t){this.rectangle?this.rectangle=this.rectangle.withTransformation(t):this.transformation=t}measure(){const t=this.config.units===x.CSS?x.CSS:x.CANVAS,e=this.measurementProvider.measure();e.screenWidth===0||e.screenHeight===0?this.rectangle=void 0:this.rectangle?this.rectangle=this.rectangle.withUnits(t).withMeasurement(e):this.rectangle=dt.create(e,t).withTransformation(this.transformation)}}class er{constructor(t){this.canvas=t}measure(){const t=this.canvas.getBoundingClientRect();return{left:t.left,top:t.top,screenWidth:t.width,screenHeight:t.height,viewboxWidth:this.canvas.width,viewboxHeight:this.canvas.height}}}function ft(s){const{a:t,b:e,c:n,d:i,e:r,f:o}=s;return{a:t,b:e,c:n,d:i,e:r,f:o}}const nr={transformationstart:null,transformationchange:null,transformationend:null},Mn={auxclick:null,click:null,contextmenu:null,dblclick:null,mouseenter:null,mouseleave:null,mouseout:null,mouseover:null,mouseup:null},Nn={gotpointercapture:null,lostpointercapture:null,pointerenter:null,pointerout:null,pointerover:null},qn={drag:null,dragend:null,dragenter:null,dragleave:null,dragover:null,dragstart:null,drop:null},zn={touchcancel:null,touchend:null},ir={...Mn,...Nn,...qn,...zn},Gn={mousedown:null,mousemove:null,pointerdown:null,pointermove:null,pointerleave:null,pointercancel:null,pointerup:null,wheel:null,touchstart:null,touchmove:null,wheelignored:null,touchignored:null};function Jt(s){return nr.hasOwnProperty(s)}function Zt(s){return ir.hasOwnProperty(s)||Gn.hasOwnProperty(s)}function _t(s){return Gn.hasOwnProperty(s)}function te(s){return Mn.hasOwnProperty(s)}function ee(s){return Nn.hasOwnProperty(s)}function ne(s){return qn.hasOwnProperty(s)}function ie(s){return zn.hasOwnProperty(s)}class sr extends St{constructor(t){super(),this.source=t}map(t){const e=()=>{this.remove(t),t.removedCallback&&t.removedCallback()};return this.source.addListener(t.listener,e),{listener:t.listener,removedCallback:e}}mapsTo(t,e){return t.listener===e.listener}onRemoved(t){t.removedCallback(),this.source.removeListener(t.listener)}addListener(t,e){this.add({listener:t,removedCallback:e})}removeListener(t){this.remove({listener:t})}}class rr extends St{constructor(t,e){super(),this.transform=e,this.old=new sr(t)}map(t){const e={oldListener:void 0,newListener:t.listener,removedCallback:()=>{t.removedCallback&&t.removedCallback()}};return e.oldListener=this.transform(t.listener,n=>e.removedCallback=()=>{t.removedCallback&&t.removedCallback(),n()}),this.old.addListener(e.oldListener,()=>this.removeListener(t.listener)),e}mapsTo(t,e){return t.newListener===e.listener}onRemoved(t){this.old.removeListener(t.oldListener),t.removedCallback()}addListener(t,e){this.add({listener:t,removedCallback:e})}removeListener(t){this.remove({listener:t})}}function nt(s,t){return new rr(s,t)}function Y(s,t){return nt(s,e=>n=>{e(t(n))})}function se(s){return!!s&&typeof s.handleEvent=="function"}class or extends St{constructor(t){super(),this.source=t}mapsTo(t,e){return t.listenerObject===e.listenerObject}map(t){const{listenerObject:e,removedCallback:n}=t,i=o=>{e.handleEvent(o)},r=()=>{this.remove(t),n&&n()};return this.source.addListener(i,r),{listener:i,listenerObject:e,removedCallback:r}}onRemoved(t){this.source.removeListener(t.listener),t.removedCallback()}}class ar{constructor(t){this.source=t,this.listenerObjectCollection=new or(t)}addListener(t,e){se(t)?this.listenerObjectCollection.add({listenerObject:t,removedCallback:e}):this.source.addListener(t,e)}removeListener(t){se(t)?this.listenerObjectCollection.remove({listenerObject:t}):this.source.removeListener(t)}}function Yn(s){return new ar(s)}function cr(s,t,e){se(t),s.addListener(t,e)}function hr(s,t,e){se(t),s.removeListener(t,e)}function lr(s){const t=nt(s,e=>n=>{e(n),t.removeListener(e)});return t}function ur(s,t){return nt(s,e=>n=>{e.apply(t,[n])})}class dr{constructor(t){this.source=t,this.firstDispatcher=new J,this.secondDispatcher=new J,this.numberOfListeners=0,this.sourceListener=e=>this.dispatchEvent(e)}add(){this.numberOfListeners===0&&this.source.addListener(this.sourceListener),this.numberOfListeners++}remove(){this.numberOfListeners--,this.numberOfListeners===0&&this.source.removeListener(this.sourceListener)}dispatchEvent(t){this.firstDispatcher.dispatch(t),this.secondDispatcher.dispatch(t)}build(){return{first:nt(this.firstDispatcher,(t,e)=>(this.add(),e(()=>this.remove()),t)),second:nt(this.secondDispatcher,(t,e)=>(this.add(),e(()=>this.remove()),t))}}}function Xn(s){return new dr(s).build()}function X(s,t){return nt(s,e=>n=>{t(n)&&e(n)})}class $n{constructor(t,e){t=ur(t,e),this._onceSource=Yn(lr(t)),this.source=Yn(t)}addListener(t,e){e&&e.once?this._onceSource.addListener(t):this.source.addListener(t)}removeListener(t){this.source.removeListener(t),this._onceSource.removeListener(t)}}class fr{constructor(t,e){this.captureSource=t,this.bubbleSource=e}get on(){return this.onEventHandler}set on(t){t?(this.wrappedOnEventHandler=function(e){return t.apply(this,[e])},this.onEventHandler=t,this.bubbleSource.addListener(this.wrappedOnEventHandler)):(this.bubbleSource.removeListener(this.wrappedOnEventHandler),this.wrappedOnEventHandler=null,this.onEventHandler=null)}addListener(t,e){const n=e&&(typeof e=="boolean"?void 0:e);(typeof e=="boolean"?e:e&&e.capture)?this.captureSource.addListener(t,n):this.bubbleSource.addListener(t,n)}removeListener(t,e){(typeof e=="boolean"?e:e&&e.capture)?this.captureSource.removeListener(t):this.bubbleSource.removeListener(t)}}function gr(s,t,e){return new fr(new $n(s,e),new $n(t,e))}function it(s,t,e,n){const i=Y(X(s,o=>!o.immediatePropagationStopped),o=>o.getResultEvent(e.rectangle)),r=Y(X(t,o=>!o.propagationStopped&&!o.immediatePropagationStopped),o=>o.getResultEvent(e.rectangle));return gr(i,r,n)}function st(s){const{first:t,second:e}=Xn(s),{first:n,second:i}=Xn(e);return{captureSource:t,bubbleSource:n,afterBubble:i}}function mr(s,t,e){const{captureSource:n,bubbleSource:i}=st(s);return it(n,i,t,e)}class ke{constructor(t,e){this.rectangleManager=t,this.infiniteCanvas=e,this.cache={}}map(t,e){return mr(Y(t,e),this.rectangleManager,this.infiniteCanvas)}setOn(t,e){if(e)this.cache[t]||(this.cache[t]=this.getEventSource(t)),this.cache[t].on=e;else{if(!this.cache[t])return;this.cache[t].on=null}}getOn(t){return this.cache[t]?this.cache[t].on:null}addEventListener(t,e,n){this.cache[t]||(this.cache[t]=this.getEventSource(t)),cr(this.cache[t],e,n)}removeEventListener(t,e,n){this.cache[t]&&hr(this.cache[t],e,n)}}class Un extends ke{getEventSource(t){return(!this.cache||!this.cache[t])&&(this.cache=this.createEvents()),this.cache[t]}}class Kn{constructor(t,e){this.canvasEvent=t,this.preventableDefault=e,this.AT_TARGET=2,this.BUBBLING_PHASE=3,this.CAPTURING_PHASE=1,this.NONE=0}get bubbles(){return!1}get isTrusted(){return!1}get eventPhase(){return Event.AT_TARGET}get cancelable(){return this.preventableDefault.cancelable}get defaultPrevented(){return this.preventableDefault.defaultPrevented}initEvent(t,e,n){}preventDefault(){this.preventableDefault.preventDefault()}stopImmediatePropagation(){this.canvasEvent.stopImmediatePropagation()}stopPropagation(){this.canvasEvent.stopPropagation()}}class He extends Kn{constructor(t,e,n){super(t,e),this.type=n}get cancelBubble(){return!1}get composed(){return!1}get currentTarget(){return null}get returnValue(){return!0}get srcElement(){return null}get target(){return null}get timeStamp(){return 0}composedPath(){return[]}}class jn{constructor(t){this.preventableDefault=t,this.propagationStopped=!1,this.immediatePropagationStopped=!1}get infiniteCanvasDefaultPrevented(){return this.preventableDefault.infiniteCanvasDefaultPrevented}stopPropagation(){this.propagationStopped=!0}stopImmediatePropagation(){this.immediatePropagationStopped=!0}getResultEvent(t){return this.resultEvent||(this.resultEvent=this.createResultEvent(t)),this.resultEvent}}class pr{get defaultPrevented(){return this._defaultPrevented}get infiniteCanvasDefaultPrevented(){return this._defaultPrevented}get cancelable(){return!0}preventDefault(){this._defaultPrevented=!0}}class vr{get infiniteCanvasDefaultPrevented(){return!1}get defaultPrevented(){return!1}get cancelable(){return!1}preventDefault(){}}class Ve extends jn{constructor(t){super(t?new pr:new vr)}}class wr extends He{constructor(t,e){super(t,e,"draw"),this.transformation=t.transformation,this.inverseTransformation=t.inverseTransformation}}class Pr extends Ve{constructor(){super(!1)}createResultEvent(t){return this.transformation=ft(t.infiniteCanvasContext.inverseBase),this.inverseTransformation=ft(t.infiniteCanvasContext.base),new wr(this,this.preventableDefault)}}class Cr extends Un{constructor(t,e,n){super(e,n),this.drawingIterationProvider=t}createEvents(){return{draw:this.map(this.drawingIterationProvider.drawHappened,()=>new Pr)}}}class Ir extends He{constructor(t,e,n){super(t,e,n),this.transformation=t.transformation,this.inverseTransformation=t.inverseTransformation}}class Me extends Ve{constructor(t){super(!1),this.type=t}createResultEvent(t){return this.transformation=ft(t.infiniteCanvasContext.inverseBase),this.inverseTransformation=ft(t.infiniteCanvasContext.base),new Ir(this,this.preventableDefault,this.type)}}class Tr extends Un{constructor(t,e,n){super(e,n),this.transformer=t}createEvents(){return{transformationstart:this.map(this.transformer.transformationStart,()=>new Me("transformationstart")),transformationchange:this.map(this.transformer.transformationChange,()=>new Me("transformationchange")),transformationend:this.map(this.transformer.transformationEnd,()=>new Me("transformationend"))}}}function W(s,t){return{addListener(e){s.addEventListener(t,e)},removeListener(e){s.removeEventListener(t,e)}}}class Sr{constructor(t){this.event=t}get infiniteCanvasDefaultPrevented(){return!1}get nativeDefaultPrevented(){return this.event.defaultPrevented}get nativeCancelable(){return this.event.cancelable}get defaultPrevented(){return this.event.defaultPrevented}get cancelable(){return this.event.cancelable}preventDefault(){this.event.preventDefault()}}class yr{constructor(t){this.event=t}get infiniteCanvasDefaultPrevented(){return this._defaultPrevented}get nativeDefaultPrevented(){return this.event.defaultPrevented}get nativeCancelable(){return this.event.cancelable}get defaultPrevented(){return this._defaultPrevented}get cancelable(){return!0}preventDefault(t){this._defaultPrevented=!0,t&&this.event.preventDefault()}}class gt extends jn{constructor(t,e){super(e?new yr(t):new Sr(t)),this.event=t}stopPropagation(){super.stopPropagation(),this.event&&this.event.stopPropagation()}stopImmediatePropagation(){super.stopImmediatePropagation(),this.event&&this.event.stopImmediatePropagation()}}class rt{constructor(t,e,n,i){this.offsetX=t,this.offsetY=e,this.movementX=n,this.movementY=i}toInfiniteCanvasCoordinates(t){const{x:e,y:n}=t.infiniteCanvasContext.inverseBase.apply(new c(this.offsetX,this.offsetY)),{x:i,y:r}=t.infiniteCanvasContext.inverseBase.untranslated().apply(new c(this.movementX,this.movementY));return new rt(e,n,i,r)}static create(t){return new rt(t.offsetX,t.offsetY,t.movementX,t.movementY)}}class xr extends Kn{constructor(t,e,n){super(t,e),this.event=n}get nativeDefaultPrevented(){return this.preventableDefault.nativeDefaultPrevented}get nativeCancelable(){return this.preventableDefault.nativeCancelable}get cancelBubble(){return this.event.cancelBubble}get composed(){return this.event.composed}get currentTarget(){return this.event.currentTarget}get returnValue(){return this.event.returnValue}get srcElement(){return this.event.srcElement}get target(){return this.event.target}get timeStamp(){return this.event.timeStamp}get type(){return this.event.type}preventDefault(t){this.preventableDefault.preventDefault(t)}composedPath(){return this.event.composedPath()}}class Qn extends xr{get detail(){return this.event.detail}get view(){return this.event.view}get which(){return this.event.which}initUIEvent(t,e,n,i,r){}}class re extends Qn{constructor(t,e,n,i){super(t,e,n),this.offsetX=i.offsetX,this.offsetY=i.offsetY,this.movementX=i.movementX,this.movementY=i.movementY}get altKey(){return this.event.altKey}get button(){return this.event.button}get buttons(){return this.event.buttons}get clientX(){return this.event.clientX}get clientY(){return this.event.clientY}get ctrlKey(){return this.event.ctrlKey}get metaKey(){return this.event.metaKey}get pageX(){return this.event.pageX}get pageY(){return this.event.pageY}get relatedTarget(){return this.event.relatedTarget}get screenX(){return this.event.screenX}get screenY(){return this.event.screenY}get shiftKey(){return this.event.shiftKey}get x(){return this.event.x}get y(){return this.event.y}getModifierState(t){return this.event.getModifierState(t)}initMouseEvent(t,e,n,i,r,o,a,l,h,d,u,g,w,P,y){}}class Ne extends gt{constructor(t,e){super(t,e),this.props=rt.create(t)}createResultEvent(t){return new re(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}class oe extends rt{constructor(t,e,n,i,r,o){super(t,e,n,i),this.width=r,this.height=o}toInfiniteCanvasCoordinates(t){const{offsetX:e,offsetY:n,movementX:i,movementY:r}=super.toInfiniteCanvasCoordinates(t),{x:o,y:a}=t.infiniteCanvasContext.inverseBase.untranslated().apply(new c(this.width,this.height));return new oe(e,n,i,r,o,a)}static create(t){const{offsetX:e,offsetY:n,movementX:i,movementY:r}=super.create(t);return new oe(e,n,i,r,t.width,t.height)}}class br extends re{constructor(t,e,n,i){super(t,e,n,i)}get isPrimary(){return this.event.isPrimary}get pointerId(){return this.event.pointerId}get pointerType(){return this.event.pointerType}get pressure(){return this.event.pressure}get tangentialPressure(){return this.event.tangentialPressure}get tiltX(){return this.event.tiltX}get tiltY(){return this.event.tiltY}get twist(){return this.event.twist}getCoalescedEvents(){return console.warn("`PointerEvent.getCoalescedEvents()` is currently not supported by InfiniteCanvas"),[]}getPredictedEvents(){return console.warn("`PointerEvent.getPredictedEvents()` is currently not supported by InfiniteCanvas"),[]}}class mt extends gt{constructor(t,e){super(t,e),this.props=oe.create(t)}createResultEvent(t){return new br(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}class Or{constructor(t,e){this.initial=t,this.cancel=e,this.current=t}}class Lr{constructor(t){this.point=t,this.moveEventDispatcher=new J,this._fixedOnInfiniteCanvas=!1}get fixedOnInfiniteCanvas(){return this._fixedOnInfiniteCanvas}removeHandler(t){this.moveEventDispatcher.removeListener(t)}moveTo(t,e){const n=new c(t,e);this.point=n,this.moveEventDispatcher.dispatch(n)}onMoved(t,e){let n;this._fixedOnInfiniteCanvas=e;const i=r=>{n.current=r,t()};return this.moveEventDispatcher.addListener(i),n=new Or(this.point,()=>(this.removeHandler(i),this._fixedOnInfiniteCanvas=!1,this)),n}}class Br{constructor(t){this.pointerEvent=t,this._defaultPrevented=!1,this.anchor=new Lr(new c(t.offsetX,t.offsetY))}get defaultPrevented(){return this._defaultPrevented}get touchId(){return this._touchId}get pointerId(){return this.pointerEvent.pointerId}preventDefault(){this._defaultPrevented=!0}setTouchId(t){this._touchId=t}updatePointerEvent(t){this.pointerEvent=t,this.anchor.moveTo(t.offsetX,t.offsetY)}}class Ar{constructor(){this.anchors=[]}find(t){return this.anchors.find(t)}getAll(t){return this.anchors.filter(t)}getAnchorForTouch(t){return this.anchors.find(e=>e.touchId===t)}addAnchorForPointerEvent(t){const e=new Br(t);this.anchors.push(e)}updateAnchorForPointerEvent(t){const e=this.getAnchorForPointerEvent(t);if(!e){this.addAnchorForPointerEvent(t);return}e.updatePointerEvent(t)}getAnchorForPointerEvent(t){return this.anchors.find(e=>e.pointerId===t.pointerId)}removeAnchor(t){const e=this.anchors.findIndex(n=>n===t);e>-1&&this.anchors.splice(e,1)}}class ae extends rt{constructor(t,e,n,i,r,o){super(t,e,n,i),this.deltaX=r,this.deltaY=o}toInfiniteCanvasCoordinates(t){const{offsetX:e,offsetY:n,movementX:i,movementY:r}=super.toInfiniteCanvasCoordinates(t),{x:o,y:a}=t.infiniteCanvasContext.inverseBase.untranslated().apply(new c(this.deltaX,this.deltaY));return new ae(e,n,i,r,o,a)}static create(t){const{offsetX:e,offsetY:n,movementX:i,movementY:r}=super.create(t);return new ae(e,n,i,r,t.deltaX,t.deltaY)}}class Dr extends re{constructor(t,e,n,i){super(t,e,n,i),this.DOM_DELTA_LINE=1,this.DOM_DELTA_PAGE=2,this.DOM_DELTA_PIXEL=0,this.deltaX=i.deltaX,this.deltaY=i.deltaY}get deltaMode(){return this.event.deltaMode}get deltaZ(){return this.event.deltaZ}}class Er extends gt{constructor(t,e){super(t,e),this.props=ae.create(t)}createResultEvent(t){return new Dr(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}function pt(s,t){const e=[];for(let n=0;ni.identifier===t.identifier);return n||(n=t.toInfiniteCanvasCoordinates(e),this.translatedProps.push(n),n)}createProps(t,e){let n=this.createdProps.find(i=>i.identifier===t.identifier);return n||(n=ce.create(t,e),this.createdProps.push(n),n)}dispose(){this.translatedProps.splice(0,this.translatedProps.length),this.createdProps.splice(0,this.createdProps.length)}}class he{constructor(t,e,n){this.targetTouches=t,this.changedTouches=e,this.touches=n}toInfiniteCanvasCoordinates(t){const e=new Jn,n=new he(this.targetTouches.map(i=>e.toInfiniteCanvasCoordinates(i,t)),this.changedTouches.map(i=>e.toInfiniteCanvasCoordinates(i,t)),this.touches.map(i=>e.toInfiniteCanvasCoordinates(i,t)));return e.dispose(),n}static create(t,e,n){const i=new Jn,r=e.map(a=>i.createProps(a,t)),o=n.map(a=>i.createProps(a,t));return i.dispose(),new he(r,o,r)}}class Fr{constructor(t,e){this.touch=t,this.infiniteCanvasX=e.x,this.infiniteCanvasY=e.y,this.radiusX=e.radiusX,this.radiusY=e.radiusY,this.rotationAngle=e.rotationAngle}get clientX(){return this.touch.clientX}get clientY(){return this.touch.clientY}get force(){return this.touch.force}get identifier(){return this.touch.identifier}get pageX(){return this.touch.pageX}get pageY(){return this.touch.pageY}get screenX(){return this.touch.screenX}get screenY(){return this.touch.screenY}get target(){return this.touch.target}}class Rr extends Array{item(t){return this[t]}}function Wr(s,t){const e=s.length;for(let n=0;n{r=o}),this.subscription=new Zn(t,o=>{n([o,r])})}remove(){this.subscription.remove(),this.otherSubscription.remove(),this.onRemoved&&this.onRemoved()}}class Mr extends St{constructor(t,e){super(),this.source=t,this.otherSource=e}map(t){return new Vr(this.source,this.otherSource,t.listener,t.onRemoved)}mapsTo(t,e){return t.listener===e.listener}onRemoved(t){t.remove()}addListener(t,e){this.add({listener:t,onRemoved:e})}removeListener(t){this.remove({listener:t})}}function ze(s,t){return new Mr(s,t)}function Nr(s,t){for(let e=0;e{let n=!1;const i=[];function r(){n||i.length===0||(n=!0,t(i.shift()).addListener(e,()=>{n=!1,r()}))}return o=>{i.push(o),r()}})}class zr{constructor(t){this.sequence=t}addListener(t,e){for(const n of this.sequence)t(n);e&&e()}removeListener(t){}}function Gr(s){return new zr(s)}class _n extends Ve{constructor(t){super(!0),this.type=t}createResultEvent(){return new He(this,this.preventableDefault,this.type)}}class Yr extends ke{constructor(t,e,n,i,r){super(n,i),this.transformer=e,this.config=r,this.anchorSet=new Ar;const o=W(t,"pointerdown"),a=W(t,"pointerleave"),l=W(t,"pointermove"),h=W(t,"pointerup"),d=W(t,"pointercancel"),u=X(W(t,"touchmove"),f=>Nr(f.targetTouches,O=>!this.hasFixedAnchorForTouch(O.identifier)));o.addListener(f=>this.anchorSet.updateAnchorForPointerEvent(f)),l.addListener(f=>this.anchorSet.updateAnchorForPointerEvent(f)),h.addListener(f=>this.removePointer(f)),a.addListener(f=>this.removePointer(f));const g=Y(W(t,"mousedown"),f=>new Ne(f,!0)),w=Y(W(t,"wheel"),f=>new Er(f,!0)),P=Y(W(t,"touchstart"),f=>{const O=pt(f.targetTouches),U=pt(f.changedTouches);return bt.create(this.rectangleManager.rectangle,f,O,U,!0)}),y=Y(o,f=>new mt(f,!0)),{captureSource:B,bubbleSource:M,afterBubble:$}=st(y),{captureSource:ot,bubbleSource:Lt,afterBubble:Bt}=st(g),{captureSource:At,bubbleSource:Xe,afterBubble:$e}=st(P),{captureSource:Ue,bubbleSource:Ke,afterBubble:Dt}=st(w),eo=Y(X(Dt,f=>!this.config.greedyGestureHandling&&!f.event.ctrlKey&&!f.infiniteCanvasDefaultPrevented),()=>new _n("wheelignored")),{captureSource:no,bubbleSource:io,afterBubble:so}=st(eo);Dt.addListener(f=>{f.infiniteCanvasDefaultPrevented||this.zoom(f.event)}),so.addListener(f=>{f.infiniteCanvasDefaultPrevented||console.warn("use ctrl + scroll to zoom")}),ze(Bt,$).addListener(([f,O])=>{!f.infiniteCanvasDefaultPrevented&&!O.infiniteCanvasDefaultPrevented&&this.transformUsingPointer(f.event,O.event)});const ro=X($e,f=>f.event.changedTouches.length===1),ni=ze(ro,$);ni.addListener(([f,O])=>{const U=f.event.changedTouches[0],Z=this.anchorSet.getAnchorForPointerEvent(O.event);if(Z)if(Z.setTouchId(U.identifier),!f.infiniteCanvasDefaultPrevented&&!O.infiniteCanvasDefaultPrevented)if(this.config.greedyGestureHandling)this.rectangleManager.measure(),this.transformer.addAnchor(Z.anchor),f.event.preventDefault();else{const si=this.anchorSet.find(je=>je.touchId!==void 0&&je!==Z&&!je.defaultPrevented);if(!si)return;this.rectangleManager.measure(),this.transformer.addAnchor(si.anchor),this.transformer.addAnchor(Z.anchor),f.event.preventDefault()}else Z.preventDefault()});const ii=X(ze(d,ni),([f,[O,U]])=>f.pointerId===U.event.pointerId);ii.addListener(([f])=>{this.removePointer(f)});const oo=Y(X(ii,([f,[O,U]])=>!this.config.greedyGestureHandling&&!O.infiniteCanvasDefaultPrevented&&!U.infiniteCanvasDefaultPrevented),()=>new _n("touchignored")),{captureSource:ao,bubbleSource:co,afterBubble:ho}=st(oo);ho.addListener(f=>{f.infiniteCanvasDefaultPrevented||console.warn("use two fingers to move")}),this.cache={mousemove:this.map(X(W(t,"mousemove"),()=>!this.mouseAnchorIsFixed()),f=>new Ne(f)),mousedown:it(ot,Lt,n,i),pointerdown:it(B,M,n,i),pointermove:this.map(qr(X(l,()=>this.hasNonFixedAnchorForSomePointer()),()=>Gr(this.anchorSet.getAll(f=>!f.anchor.fixedOnInfiniteCanvas).map(f=>f.pointerEvent))),f=>new mt(f)),pointerleave:this.map(a,f=>new mt(f)),pointerup:this.map(h,f=>new mt(f)),pointercancel:this.map(d,f=>new mt(f)),wheel:it(Ue,Ke,n,i),wheelignored:it(no,io,n,i),touchstart:it(At,Xe,n,i),touchignored:it(ao,co,n,i),touchmove:this.map(u,f=>{const O=pt(f.targetTouches),U=pt(f.targetTouches,Z=>!this.hasFixedAnchorForTouch(Z.identifier));return bt.create(this.rectangleManager.rectangle,f,O,U)})}}getEventSource(t){return this.cache[t]}mouseAnchorIsFixed(){const t=this.anchorSet.find(e=>e.pointerEvent.pointerType==="mouse");return t?t.anchor.fixedOnInfiniteCanvas:!1}hasFixedAnchorForTouch(t){const e=this.anchorSet.getAnchorForTouch(t);return!!e&&e.anchor.fixedOnInfiniteCanvas}hasNonFixedAnchorForSomePointer(){return!!this.anchorSet.find(t=>!t.anchor.fixedOnInfiniteCanvas)}transformUsingPointer(t,e){this.rectangleManager.measure();const n=this.anchorSet.getAnchorForPointerEvent(e);e.button===1&&this.config.rotationEnabled?(t.preventDefault(),this.transformer.addRotationAnchor(n.anchor)):e.button===0&&this.transformer.addAnchor(n.anchor)}removePointer(t){const e=this.anchorSet.getAnchorForPointerEvent(t);e&&(this.transformer.releaseAnchor(e.anchor),this.anchorSet.removeAnchor(e))}zoom(t){if(!this.config.greedyGestureHandling&&!t.ctrlKey)return;const{offsetX:e,offsetY:n}=t;let i=t.deltaY;const r=Math.pow(2,-i/300);this.rectangleManager.measure(),this.transformer.zoom(e,n,r),t.preventDefault()}}class Xr{constructor(t,e){this.handledOrFilteredEventCollection=t,this.mappingCollection=e}setOn(t,e){_t(t)?this.handledOrFilteredEventCollection.setOn(t,e):this.mappingCollection.setOn(t,e)}getOn(t){return _t(t)?this.handledOrFilteredEventCollection.getOn(t):this.mappingCollection.getOn(t)}addEventListener(t,e,n){_t(t)?this.handledOrFilteredEventCollection.addEventListener(t,e,n):this.mappingCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){_t(t)?this.handledOrFilteredEventCollection.removeEventListener(t,e,n):this.mappingCollection.removeEventListener(t,e,n)}}class $r{constructor(t,e,n,i){this.mappedMouseEventCollection=t,this.mappedTouchEventCollection=e,this.mappedOnlyPointerEventCollection=n,this.mappedDragEventCollection=i}setOn(t,e){te(t)?this.mappedMouseEventCollection.setOn(t,e):ie(t)?this.mappedTouchEventCollection.setOn(t,e):ee(t)?this.mappedOnlyPointerEventCollection.setOn(t,e):ne(t)&&this.mappedDragEventCollection.setOn(t,e)}getOn(t){if(te(t))return this.mappedMouseEventCollection.getOn(t);if(ie(t))return this.mappedTouchEventCollection.getOn(t);if(ee(t))return this.mappedOnlyPointerEventCollection.getOn(t);if(ne(t))return this.mappedDragEventCollection.getOn(t)}addEventListener(t,e,n){te(t)?this.mappedMouseEventCollection.addEventListener(t,e,n):ie(t)?this.mappedTouchEventCollection.addEventListener(t,e,n):ee(t)?this.mappedOnlyPointerEventCollection.addEventListener(t,e,n):ne(t)&&this.mappedDragEventCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){te(t)?this.mappedMouseEventCollection.removeEventListener(t,e,n):ie(t)?this.mappedTouchEventCollection.removeEventListener(t,e,n):ee(t)?this.mappedOnlyPointerEventCollection.removeEventListener(t,e,n):ne(t)&&this.mappedDragEventCollection.removeEventListener(t,e,n)}}class Ot extends ke{constructor(t,e,n,i){super(n,i),this.canvasEl=t,this.createInternalEvent=e,this.cache={}}getEventSource(t){return this.cache[t]||(this.cache[t]=this.createEventSource(t)),this.cache[t]}createEventSource(t){return this.map(W(this.canvasEl,t),e=>this.createInternalEvent(e))}}class Ur extends re{get dataTransfer(){return this.event.dataTransfer}}class Kr extends gt{constructor(t,e){super(t,e),this.props=rt.create(t)}createResultEvent(t){return new Ur(this,this.preventableDefault,this.event,this.props.toInfiniteCanvasCoordinates(t))}}class jr extends gt{createResultEvent(){return this.event}}class Ge{constructor(t,e,n,i){this.drawEventCollection=t,this.transformationEventCollection=e,this.pointerEventCollection=n,this.unmappedEventCollection=i}setOn(t,e){t==="draw"?this.drawEventCollection.setOn("draw",e):Jt(t)?this.transformationEventCollection.setOn(t,e):Zt(t)?this.pointerEventCollection.setOn(t,e):this.unmappedEventCollection.setOn(t,e)}getOn(t){return t==="draw"?this.drawEventCollection.getOn("draw"):Jt(t)?this.transformationEventCollection.getOn(t):Zt(t)?this.pointerEventCollection.getOn(t):this.unmappedEventCollection.getOn(t)}addEventListener(t,e,n){t==="draw"?this.drawEventCollection.addEventListener("draw",e,n):Jt(t)?this.transformationEventCollection.addEventListener(t,e,n):Zt(t)?this.pointerEventCollection.addEventListener(t,e,n):this.unmappedEventCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){t==="draw"?this.drawEventCollection.removeEventListener("draw",e,n):Jt(t)?this.transformationEventCollection.removeEventListener(t,e,n):Zt(t)?this.pointerEventCollection.removeEventListener(t,e,n):this.unmappedEventCollection.removeEventListener(t,e,n)}static create(t,e,n,i,r,o){const a=new Cr(o,n,i),l=new Tr(e,n,i),h=new Yr(t,e,n,i,r),d=new Xr(h,new $r(new Ot(t,u=>new Ne(u),n,i),new Ot(t,u=>{const g=pt(u.targetTouches),w=pt(u.changedTouches);return bt.create(n.rectangle,u,g,w)},n,i),new Ot(t,u=>new mt(u),n,i),new Ot(t,u=>new Kr(u),n,i)));return new Ge(a,l,d,new Ot(t,u=>new jr(u),n,i))}}function Qr(s,t){let e=-1;const n=s.canvas.width;s.save(),s.fillStyle="#fff",s.fillRect(0,0,n,5),s.filter=`drop-shadow(${t} 0)`,s.fillRect(0,0,1,5);const r=s.getImageData(0,0,n,3).data;for(let o=0;o{e==null||e(),this.numberOfListeners=Math.max(this.numberOfListeners-1,0),this.numberOfListeners===0&&this.disconnect()}),this.numberOfListeners++,this.connectIfNeeded()}removeListener(t){this.dispatcher.removeListener(t)}connectIfNeeded(){this.observer||(this.observer=new ResizeObserver(t=>this.dispatcher.dispatch(this.createCanvasMeasurement(t))),this.observer.observe(this.canvas))}createCanvasMeasurement([{contentRect:t}]){return{left:t.left,top:t.top,screenWidth:t.width,screenHeight:t.height,viewboxWidth:this.canvas.width,viewboxHeight:this.canvas.height}}disconnect(){this.observer&&(this.observer.disconnect(),this.observer=void 0)}}function ti(s){const{screenWidth:t,screenHeight:e}=s;return t>0&&e>0}class to{constructor(t,e,n){this.measurementProvider=t,this.resizes=e,this.viewBox=n,this.currentlyVisible=!1}observe(){const t=this.measurementProvider.measure();this.currentlyVisible=ti(t);const e=n=>{const i=ti(n);i&&!this.currentlyVisible&&this.viewBox.draw(),this.currentlyVisible=i};this.resizes.addListener(e),this.listener=e}disconnect(){this.listener&&(this.resizes.removeListener(this.listener),this.listener=void 0)}}class Ye{constructor(t,e){this.canvas=t,this.config={rotationEnabled:!0,greedyGestureHandling:!1,units:x.CANVAS},e&&Object.assign(this.config,e);const n=new _r(t);this.canvasResizes=n,this.cssUnitsCanvasResizeListener=()=>{this.canvas.parentElement!==null&&this.viewBox.draw()};const i=new Js(new Qs),r=new Zs(i),o=new er(t);this.rectangleManager=new tr(o,this.config);let a;const l=t.getContext("2d");this.cssLengthConverterFactory={create:()=>new Zr(l)};const h=new zs(this.rectangleManager,l,r,()=>r.getLock(),()=>a.isTransforming);this.viewBox=h,this.canvasUnitsCanvasResizeObserver=new to(o,n,h),a=new js(this.viewBox,this.config),this.eventCollection=Ge.create(t,a,this.rectangleManager,this,this.config,i),this.config.units===x.CSS?this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener):this.config.units===x.CANVAS&&this.canvasUnitsCanvasResizeObserver.observe()}setUnits(t){t===x.CSS&&this.config.units!==x.CSS&&(this.canvasUnitsCanvasResizeObserver.disconnect(),this.canvasResizes.addListener(this.cssUnitsCanvasResizeListener)),t===x.CANVAS&&this.config.units!==x.CANVAS&&(this.canvasResizes.removeListener(this.cssUnitsCanvasResizeListener),this.canvasUnitsCanvasResizeObserver.observe()),this.config.units=t,this.rectangleManager.measure(),this.viewBox.draw()}getContext(){return this.context||(this.context=new Fs(this.canvas,this.viewBox,this.cssLengthConverterFactory)),this.context}get transformation(){return ft(this.rectangleManager.rectangle.infiniteCanvasContext.inverseBase)}get inverseTransformation(){return ft(this.rectangleManager.rectangle.infiniteCanvasContext.base)}get rotationEnabled(){return this.config.rotationEnabled}set rotationEnabled(t){this.config.rotationEnabled=t}get units(){return this.config.units}set units(t){this.setUnits(t)}get greedyGestureHandling(){return this.config.greedyGestureHandling}set greedyGestureHandling(t){this.config.greedyGestureHandling=t}set ontransformationstart(t){this.eventCollection.setOn("transformationstart",t)}get ontransformationstart(){return this.eventCollection.getOn("transformationstart")}set ontransformationchange(t){this.eventCollection.setOn("transformationchange",t)}get ontransformationchange(){return this.eventCollection.getOn("transformationchange")}set ontransformationend(t){this.eventCollection.setOn("transformationend",t)}get ontransformationend(){return this.eventCollection.getOn("transformationend")}set ondraw(t){this.eventCollection.setOn("draw",t)}get ondraw(){return this.eventCollection.getOn("draw")}set onwheelignored(t){this.eventCollection.setOn("wheelignored",t)}get onwheelignored(){return this.eventCollection.getOn("wheelignored")}set ontouchignored(t){this.eventCollection.setOn("touchignored",t)}get ontouchignored(){return this.eventCollection.getOn("touchignored")}set onbeforeinput(t){this.eventCollection.setOn("beforeinput",t)}get onbeforeinput(){return this.eventCollection.getOn("beforeinput")}set oncancel(t){this.eventCollection.setOn("cancel",t)}get oncancel(){return this.eventCollection.getOn("cancel")}set oncopy(t){this.eventCollection.setOn("copy",t)}get oncopy(){return this.eventCollection.getOn("copy")}set oncut(t){this.eventCollection.setOn("cut",t)}get oncut(){return this.eventCollection.getOn("cut")}set onpaste(t){this.eventCollection.setOn("paste",t)}get onpaste(){return this.eventCollection.getOn("paste")}set onabort(t){this.eventCollection.setOn("abort",t)}get onabort(){return this.eventCollection.getOn("abort")}set onanimationcancel(t){this.eventCollection.setOn("animationcancel",t)}get onanimationcancel(){return this.eventCollection.getOn("animationcancel")}set onanimationend(t){this.eventCollection.setOn("animationend",t)}get onanimationend(){return this.eventCollection.getOn("animationend")}set onanimationiteration(t){this.eventCollection.setOn("animationiteration",t)}get onanimationiteration(){return this.eventCollection.getOn("animationiteration")}set onanimationstart(t){this.eventCollection.setOn("animationstart",t)}get onanimationstart(){return this.eventCollection.getOn("animationstart")}set onauxclick(t){this.eventCollection.setOn("auxclick",t)}get onauxclick(){return this.eventCollection.getOn("auxclick")}set onblur(t){this.eventCollection.setOn("blur",t)}get onblur(){return this.eventCollection.getOn("blur")}get oncanplay(){return this.eventCollection.getOn("canplay")}set oncanplay(t){this.eventCollection.setOn("canplay",t)}get oncanplaythrough(){return this.eventCollection.getOn("canplaythrough")}set oncanplaythrough(t){this.eventCollection.setOn("canplaythrough",t)}get onchange(){return this.eventCollection.getOn("change")}set onchange(t){this.eventCollection.setOn("change",t)}get onclick(){return this.eventCollection.getOn("click")}set onclick(t){this.eventCollection.setOn("click",t)}get onclose(){return this.eventCollection.getOn("close")}set onclose(t){this.eventCollection.setOn("close",t)}get oncontextmenu(){return this.eventCollection.getOn("contextmenu")}set oncontextmenu(t){this.eventCollection.setOn("contextmenu",t)}get oncuechange(){return this.eventCollection.getOn("cuechange")}set oncuechange(t){this.eventCollection.setOn("cuechange",t)}get ondblclick(){return this.eventCollection.getOn("dblclick")}set ondblclick(t){this.eventCollection.setOn("dblclick",t)}get onscrollend(){return this.eventCollection.getOn("scrollend")}set onscrollend(t){this.eventCollection.setOn("scrollend",t)}get ondrag(){return this.eventCollection.getOn("drag")}set ondrag(t){this.eventCollection.setOn("drag",t)}get ondragend(){return this.eventCollection.getOn("dragend")}set ondragend(t){this.eventCollection.setOn("dragend",t)}get ondragenter(){return this.eventCollection.getOn("dragenter")}set ondragenter(t){this.eventCollection.setOn("dragenter",t)}get onformdata(){return this.eventCollection.getOn("formdata")}set onformdata(t){this.eventCollection.setOn("formdata",t)}get onwebkitanimationend(){return this.eventCollection.getOn("webkitanimationend")}set onwebkitanimationend(t){this.eventCollection.setOn("webkitanimationend",t)}get onwebkitanimationstart(){return this.eventCollection.getOn("webkitanimationstart")}set onwebkitanimationstart(t){this.eventCollection.setOn("webkitanimationstart",t)}get onwebkitanimationiteration(){return this.eventCollection.getOn("webkitanimationiteration")}set onwebkitanimationiteration(t){this.eventCollection.setOn("webkitanimationiteration",t)}get onwebkittransitionend(){return this.eventCollection.getOn("webkittransitionend")}set onwebkittransitionend(t){this.eventCollection.setOn("webkittransitionend",t)}get onslotchange(){return this.eventCollection.getOn("slotchange")}set onslotchange(t){this.eventCollection.setOn("slotchange",t)}get ondragleave(){return this.eventCollection.getOn("dragleave")}set ondragleave(t){this.eventCollection.setOn("dragleave",t)}get ondragover(){return this.eventCollection.getOn("dragover")}set ondragover(t){this.eventCollection.setOn("dragover",t)}get ondragstart(){return this.eventCollection.getOn("dragstart")}set ondragstart(t){this.eventCollection.setOn("dragstart",t)}get ondrop(){return this.eventCollection.getOn("drop")}set ondrop(t){this.eventCollection.setOn("drop",t)}get ondurationchange(){return this.eventCollection.getOn("durationchange")}set ondurationchange(t){this.eventCollection.setOn("durationchange",t)}get onemptied(){return this.eventCollection.getOn("emptied")}set onemptied(t){this.eventCollection.setOn("emptied",t)}get onended(){return this.eventCollection.getOn("ended")}set onended(t){this.eventCollection.setOn("ended",t)}get onerror(){return this.eventCollection.getOn("error")}set onerror(t){this.eventCollection.setOn("error",t)}get onfocus(){return this.eventCollection.getOn("focus")}set onfocus(t){this.eventCollection.setOn("focus",t)}get ongotpointercapture(){return this.eventCollection.getOn("gotpointercapture")}set ongotpointercapture(t){this.eventCollection.setOn("gotpointercapture",t)}get oninput(){return this.eventCollection.getOn("input")}set oninput(t){this.eventCollection.setOn("input",t)}get oninvalid(){return this.eventCollection.getOn("invalid")}set oninvalid(t){this.eventCollection.setOn("invalid",t)}get onkeydown(){return this.eventCollection.getOn("keydown")}set onkeydown(t){this.eventCollection.setOn("keydown",t)}get onkeypress(){return this.eventCollection.getOn("keypress")}set onkeypress(t){this.eventCollection.setOn("keypress",t)}get onkeyup(){return this.eventCollection.getOn("keyup")}set onkeyup(t){this.eventCollection.setOn("keyup",t)}get onload(){return this.eventCollection.getOn("load")}set onload(t){this.eventCollection.setOn("load",t)}get onloadeddata(){return this.eventCollection.getOn("loadeddata")}set onloadeddata(t){this.eventCollection.setOn("loadeddata",t)}get onloadedmetadata(){return this.eventCollection.getOn("loadedmetadata")}set onloadedmetadata(t){this.eventCollection.setOn("loadedmetadata",t)}get onloadstart(){return this.eventCollection.getOn("loadstart")}set onloadstart(t){this.eventCollection.setOn("loadstart",t)}get onlostpointercapture(){return this.eventCollection.getOn("lostpointercapture")}set onlostpointercapture(t){this.eventCollection.setOn("lostpointercapture",t)}get onmousedown(){return this.eventCollection.getOn("mousedown")}set onmousedown(t){this.eventCollection.setOn("mousedown",t)}get onmouseenter(){return this.eventCollection.getOn("mouseenter")}set onmouseenter(t){this.eventCollection.setOn("mouseenter",t)}get onmouseleave(){return this.eventCollection.getOn("mouseleave")}set onmouseleave(t){this.eventCollection.setOn("mouseleave",t)}get onmousemove(){return this.eventCollection.getOn("mousemove")}set onmousemove(t){this.eventCollection.setOn("mousemove",t)}get onmouseout(){return this.eventCollection.getOn("mouseout")}set onmouseout(t){this.eventCollection.setOn("mouseout",t)}get onmouseover(){return this.eventCollection.getOn("mouseover")}set onmouseover(t){this.eventCollection.setOn("mouseover",t)}get onmouseup(){return this.eventCollection.getOn("mouseup")}set onmouseup(t){this.eventCollection.setOn("mouseup",t)}get onpause(){return this.eventCollection.getOn("pause")}set onpause(t){this.eventCollection.setOn("pause",t)}get onplay(){return this.eventCollection.getOn("play")}set onplay(t){this.eventCollection.setOn("play",t)}get onplaying(){return this.eventCollection.getOn("playing")}set onplaying(t){this.eventCollection.setOn("playing",t)}get onpointercancel(){return this.eventCollection.getOn("pointercancel")}set onpointercancel(t){this.eventCollection.setOn("pointercancel",t)}get onpointerdown(){return this.eventCollection.getOn("pointerdown")}set onpointerdown(t){this.eventCollection.setOn("pointerdown",t)}get onpointerenter(){return this.eventCollection.getOn("pointerenter")}set onpointerenter(t){this.eventCollection.setOn("pointerenter",t)}get onpointerleave(){return this.eventCollection.getOn("pointerleave")}set onpointerleave(t){this.eventCollection.setOn("pointerleave",t)}get onpointermove(){return this.eventCollection.getOn("pointermove")}set onpointermove(t){this.eventCollection.setOn("pointermove",t)}get onpointerout(){return this.eventCollection.getOn("pointerout")}set onpointerout(t){this.eventCollection.setOn("pointerout",t)}get onpointerover(){return this.eventCollection.getOn("pointerover")}set onpointerover(t){this.eventCollection.setOn("pointerover",t)}get onpointerup(){return this.eventCollection.getOn("pointerup")}set onpointerup(t){this.eventCollection.setOn("pointerup",t)}get onprogress(){return this.eventCollection.getOn("progress")}set onprogress(t){this.eventCollection.setOn("progress",t)}get onratechange(){return this.eventCollection.getOn("ratechange")}set onratechange(t){this.eventCollection.setOn("ratechange",t)}get onreset(){return this.eventCollection.getOn("reset")}set onreset(t){this.eventCollection.setOn("reset",t)}get onresize(){return this.eventCollection.getOn("resize")}set onresize(t){this.eventCollection.setOn("resize",t)}get onscroll(){return this.eventCollection.getOn("scroll")}set onscroll(t){this.eventCollection.setOn("scroll",t)}get onsecuritypolicyviolation(){return this.eventCollection.getOn("securitypolicyviolation")}set onsecuritypolicyviolation(t){this.eventCollection.setOn("securitypolicyviolation",t)}get onseeked(){return this.eventCollection.getOn("seeked")}set onseeked(t){this.eventCollection.setOn("seeked",t)}get onseeking(){return this.eventCollection.getOn("seeking")}set onseeking(t){this.eventCollection.setOn("seeking",t)}get onselect(){return this.eventCollection.getOn("select")}set onselect(t){this.eventCollection.setOn("select",t)}get onselectionchange(){return this.eventCollection.getOn("selectionchange")}set onselectionchange(t){this.eventCollection.setOn("selectionchange",t)}get onselectstart(){return this.eventCollection.getOn("selectstart")}set onselectstart(t){this.eventCollection.setOn("selectstart",t)}get onstalled(){return this.eventCollection.getOn("stalled")}set onstalled(t){this.eventCollection.setOn("stalled",t)}get onsubmit(){return this.eventCollection.getOn("submit")}set onsubmit(t){this.eventCollection.setOn("submit",t)}get onsuspend(){return this.eventCollection.getOn("suspend")}set onsuspend(t){this.eventCollection.setOn("suspend",t)}get ontimeupdate(){return this.eventCollection.getOn("timeupdate")}set ontimeupdate(t){this.eventCollection.setOn("timeupdate",t)}get ontoggle(){return this.eventCollection.getOn("toggle")}set ontoggle(t){this.eventCollection.setOn("toggle",t)}get ontouchcancel(){return this.eventCollection.getOn("touchcancel")}set ontouchcancel(t){this.eventCollection.setOn("touchcancel",t)}get ontouchend(){return this.eventCollection.getOn("touchend")}set ontouchend(t){this.eventCollection.setOn("touchend",t)}get ontouchmove(){return this.eventCollection.getOn("touchmove")}set ontouchmove(t){this.eventCollection.setOn("touchmove",t)}get ontouchstart(){return this.eventCollection.getOn("touchstart")}set ontouchstart(t){this.eventCollection.setOn("touchstart",t)}get ontransitioncancel(){return this.eventCollection.getOn("transitioncancel")}set ontransitioncancel(t){this.eventCollection.setOn("transitioncancel",t)}get ontransitionend(){return this.eventCollection.getOn("transitionend")}set ontransitionend(t){this.eventCollection.setOn("transitionend",t)}get ontransitionrun(){return this.eventCollection.getOn("transitionrun")}set ontransitionrun(t){this.eventCollection.setOn("transitionrun",t)}get ontransitionstart(){return this.eventCollection.getOn("transitionstart")}set ontransitionstart(t){this.eventCollection.setOn("transitionstart",t)}get onvolumechange(){return this.eventCollection.getOn("volumechange")}set onvolumechange(t){this.eventCollection.setOn("volumechange",t)}get onwaiting(){return this.eventCollection.getOn("waiting")}set onwaiting(t){this.eventCollection.setOn("waiting",t)}get onwheel(){return this.eventCollection.getOn("wheel")}set onwheel(t){this.eventCollection.setOn("wheel",t)}addEventListener(t,e,n){this.eventCollection.addEventListener(t,e,n)}removeEventListener(t,e,n){this.eventCollection.removeEventListener(t,e,n)}}Ye.CANVAS_UNITS=x.CANVAS,Ye.CSS_UNITS=x.CSS;const ei=Ye;return ei.Units=x,ei}); diff --git a/dist/types/draw-event.d.ts b/dist/types/draw-event.d.ts index 8de88f3f..941c3b3b 100644 --- a/dist/types/draw-event.d.ts +++ b/dist/types/draw-event.d.ts @@ -1,3 +1,3 @@ -import { Transformed } from "./transformed"; +import type { Transformed } from "./transformed"; export interface DrawEvent extends Event, Transformed { } diff --git a/dist/types/event-map.d.ts b/dist/types/event-map.d.ts index fb5b5730..bb9f6a23 100644 --- a/dist/types/event-map.d.ts +++ b/dist/types/event-map.d.ts @@ -1,7 +1,7 @@ -import { DrawEvent } from "./draw-event"; -import { InfiniteCanvasEventWithDefaultBehavior } from "./infinite-canvas-event-with-default-behavior"; -import { InfiniteCanvasTouchEvent } from "./infinite-canvas-touch-event"; -import { TransformationEvent } from "./transformation-event"; +import type { DrawEvent } from "./draw-event"; +import type { InfiniteCanvasEventWithDefaultBehavior } from "./infinite-canvas-event-with-default-behavior"; +import type { InfiniteCanvasTouchEvent } from "./infinite-canvas-touch-event"; +import type { TransformationEvent } from "./transformation-event"; export interface EventMap extends HTMLElementEventMap { /** * Emitted when {@link InfiniteCanvas} begins transforming (for example when the user begins to pan) diff --git a/dist/types/infinite-canvas-touch-event.d.ts b/dist/types/infinite-canvas-touch-event.d.ts index ebc6c6a1..75c0a068 100644 --- a/dist/types/infinite-canvas-touch-event.d.ts +++ b/dist/types/infinite-canvas-touch-event.d.ts @@ -1,4 +1,4 @@ -import { InfiniteCanvasTouchList } from "./infinite-canvas-touch-list"; +import type { InfiniteCanvasTouchList } from "./infinite-canvas-touch-list"; export interface InfiniteCanvasTouchEvent extends TouchEvent { readonly targetTouches: InfiniteCanvasTouchList; readonly changedTouches: InfiniteCanvasTouchList; diff --git a/dist/types/infinite-canvas-touch-list.d.ts b/dist/types/infinite-canvas-touch-list.d.ts index 6374997f..c1ff4197 100644 --- a/dist/types/infinite-canvas-touch-list.d.ts +++ b/dist/types/infinite-canvas-touch-list.d.ts @@ -1,4 +1,4 @@ -import { InfiniteCanvasTouch } from "./infinite-canvas-touch"; +import type { InfiniteCanvasTouch } from "./infinite-canvas-touch"; export interface InfiniteCanvasTouchList extends TouchList { [Symbol.iterator](): IterableIterator; item(index: number): InfiniteCanvasTouch | null; diff --git a/dist/types/infinite-canvas.d.ts b/dist/types/infinite-canvas.d.ts index e115135b..d73b5f50 100644 --- a/dist/types/infinite-canvas.d.ts +++ b/dist/types/infinite-canvas.d.ts @@ -1,10 +1,10 @@ -import { Config } from "./config"; +import type { Config } from "./config"; import { Units } from "./units"; -import { InfiniteCanvasRenderingContext2D } from "./infinite-canvas-rendering-context-2d"; -import { EventMap } from "./event-map"; -import { TransformationEvent } from "./transformation-event"; -import { Transformed } from './transformed'; -export interface InfiniteCanvasEventHandlers extends DocumentAndElementEventHandlers, GlobalEventHandlers { +import type { InfiniteCanvasRenderingContext2D } from "./infinite-canvas-rendering-context-2d"; +import type { EventMap } from "./event-map"; +import type { TransformationEvent } from "./transformation-event"; +import type { Transformed } from './transformed'; +export interface InfiniteCanvasEventHandlers extends GlobalEventHandlers { /** * The [event handler property](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_handler_properties) for the {@link EventMap.transformationstart} event */ diff --git a/dist/types/transformation-event.d.ts b/dist/types/transformation-event.d.ts index 5471fe7b..6fdc0602 100644 --- a/dist/types/transformation-event.d.ts +++ b/dist/types/transformation-event.d.ts @@ -1,3 +1,3 @@ -import { Transformed } from "./transformed"; +import type { Transformed } from "./transformed"; export interface TransformationEvent extends Event, Transformed { } diff --git a/dist/types/transformed.d.ts b/dist/types/transformed.d.ts index f0b33943..7e3e8436 100644 --- a/dist/types/transformed.d.ts +++ b/dist/types/transformed.d.ts @@ -1,4 +1,4 @@ -import { TransformationRepresentation } from "./transformation-representation"; +import type { TransformationRepresentation } from "./transformation-representation"; export interface Transformed { /** * The transformation that, when applied to a point `(x, y)` in the CSS-pixel-base coordinate system of the `` (which has its origin at the top-left corner of the canvas), returns the corresponding point in the {@link InfiniteCanvas}'s coordinate system diff --git a/docs/.vitepress/api-docs/create-application.ts b/docs/.vitepress/api-docs/create-application.ts index d5bfc35c..7cbe9edc 100644 --- a/docs/.vitepress/api-docs/create-application.ts +++ b/docs/.vitepress/api-docs/create-application.ts @@ -3,10 +3,8 @@ import { Application, TSConfigReader, type TypeDocOptions } from 'typedoc' export const outDir = fileURLToPath(new URL('./.temp', import.meta.url)); -export async function createApplication(): Promise{ - const application = new Application(); - application.options.addReader(new TSConfigReader()) - await application.bootstrapWithPlugins({ +export async function createApplication(): Promise{ + const application = await Application.bootstrapWithPlugins({ entryPoints: [fileURLToPath(new URL('../../../src/api-surface/infinite-canvas.ts', import.meta.url))], entryPointStrategy: 'expand', tsconfig: fileURLToPath(new URL('../../../ts-config-types.json', import.meta.url)), @@ -19,6 +17,7 @@ export async function createApplication(): Promise{ readme: 'none', entryDocument: 'index.md' } as Partial) + application.options.addReader(new TSConfigReader()) return application; } diff --git a/examples/catalog/resetting/example.json b/examples/catalog/resetting/example.json new file mode 100644 index 00000000..056f5771 --- /dev/null +++ b/examples/catalog/resetting/example.json @@ -0,0 +1,8 @@ +{ + "title": "resetting", + "files": { + "index.html": "index.html", + "index.js": "index.js", + "index.css": "index.css" + } +} \ No newline at end of file diff --git a/examples/catalog/resetting/index.css b/examples/catalog/resetting/index.css new file mode 100644 index 00000000..8d01dedd --- /dev/null +++ b/examples/catalog/resetting/index.css @@ -0,0 +1,3 @@ +#toggle-reset { + display: block; + } \ No newline at end of file diff --git a/examples/catalog/resetting/index.html b/examples/catalog/resetting/index.html new file mode 100644 index 00000000..fc44dceb --- /dev/null +++ b/examples/catalog/resetting/index.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/examples/catalog/resetting/index.js b/examples/catalog/resetting/index.js new file mode 100644 index 00000000..adf3126a --- /dev/null +++ b/examples/catalog/resetting/index.js @@ -0,0 +1,48 @@ +import InfiniteCanvas from 'ef-infinite-canvas'; +import './index.css'; + +// Get the 2d context +const canvas = new InfiniteCanvas(document.getElementById("my-house")); +const ctx = canvas.getContext("2d"); + +function drawRect() { + // Set line width + ctx.lineWidth = 10; + + // Stroke rect outline + ctx.strokeRect(50, 50, 150, 100); + + // Create filled text + ctx.font = "50px serif"; + ctx.fillText("Rect!", 70, 110); +} + +function drawCircle() { + // Set line width + ctx.lineWidth = 5; + + // Stroke out circle + ctx.beginPath(); + ctx.arc(300, 100, 50, 0, 2 * Math.PI); + ctx.stroke(); + + // Create filled text + ctx.font = "25px sans-serif"; + ctx.fillText("Circle!", 265, 100); +} + +drawRect(); + +// Toggle between circle and rectangle using button +let toggle = true; +const mybutton = document.getElementById("toggle-reset"); + +mybutton.addEventListener("click", () => { + ctx.reset(); // Clear the context! + if (toggle) { + drawCircle(); + } else { + drawRect(); + } + toggle = !toggle; +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cadf464c..216fdf67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ef-infinite-canvas", - "version": "0.6.5", + "version": "0.6.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ef-infinite-canvas", - "version": "0.6.5", + "version": "0.6.6", "license": "MIT", "devDependencies": { "@stackblitz/sdk": "^1.9.0", @@ -23,9 +23,9 @@ "npm-run-all": "^4.1.5", "puppeteer": "^21.0.3", "rxjs": "^7.8.1", - "typedoc": "^0.24.8", + "typedoc": "^0.25.13", "typedoc-plugin-markdown": "^3.15.4", - "typescript": "4.6.4", + "typescript": "^5.2.2", "vite": "^4.4.4", "vitepress": "^1.0.0-beta.7", "vitest": "^0.34.2", @@ -9318,9 +9318,9 @@ } }, "node_modules/shiki": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", - "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", "dev": true, "dependencies": { "ansi-sequence-parser": "^1.1.0", @@ -10059,24 +10059,24 @@ } }, "node_modules/typedoc": { - "version": "0.24.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz", - "integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==", + "version": "0.25.13", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.13.tgz", + "integrity": "sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==", "dev": true, "dependencies": { "lunr": "^2.3.9", "marked": "^4.3.0", - "minimatch": "^9.0.0", - "shiki": "^0.14.1" + "minimatch": "^9.0.3", + "shiki": "^0.14.7" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 14.14" + "node": ">= 16" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x" + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x" } }, "node_modules/typedoc-plugin-markdown": { @@ -10116,16 +10116,16 @@ } }, "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/ufo": { @@ -17925,9 +17925,9 @@ "dev": true }, "shiki": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", - "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", "dev": true, "requires": { "ansi-sequence-parser": "^1.1.0", @@ -18504,15 +18504,15 @@ } }, "typedoc": { - "version": "0.24.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz", - "integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==", + "version": "0.25.13", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.13.tgz", + "integrity": "sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==", "dev": true, "requires": { "lunr": "^2.3.9", "marked": "^4.3.0", - "minimatch": "^9.0.0", - "shiki": "^0.14.1" + "minimatch": "^9.0.3", + "shiki": "^0.14.7" }, "dependencies": { "brace-expansion": { @@ -18545,9 +18545,9 @@ } }, "typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, "ufo": { diff --git a/package.json b/package.json index 5c4f44a5..0c00a3cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ef-infinite-canvas", "type": "module", - "version": "0.6.5", + "version": "0.6.6", "description": "An infinite version of the html canvas", "main": "./dist/infinite-canvas.umd.cjs", "module": "./dist/infinite-canvas.js", @@ -60,9 +60,9 @@ "npm-run-all": "^4.1.5", "puppeteer": "^21.0.3", "rxjs": "^7.8.1", - "typedoc": "^0.24.8", + "typedoc": "^0.25.13", "typedoc-plugin-markdown": "^3.15.4", - "typescript": "4.6.4", + "typescript": "^5.2.2", "vite": "^4.4.4", "vitepress": "^1.0.0-beta.7", "vitest": "^0.34.2", diff --git a/src/api-surface/draw-event.ts b/src/api-surface/draw-event.ts index 84636fba..359d4f31 100644 --- a/src/api-surface/draw-event.ts +++ b/src/api-surface/draw-event.ts @@ -1,4 +1,4 @@ -import { Transformed } from "./transformed"; +import type { Transformed } from "./transformed"; export interface DrawEvent extends Event, Transformed{ } diff --git a/src/api-surface/event-map.ts b/src/api-surface/event-map.ts index 224adc81..2340ca42 100644 --- a/src/api-surface/event-map.ts +++ b/src/api-surface/event-map.ts @@ -1,7 +1,7 @@ -import { DrawEvent } from "./draw-event"; -import { InfiniteCanvasEventWithDefaultBehavior } from "./infinite-canvas-event-with-default-behavior"; -import { InfiniteCanvasTouchEvent } from "./infinite-canvas-touch-event"; -import { TransformationEvent } from "./transformation-event"; +import type { DrawEvent } from "./draw-event"; +import type { InfiniteCanvasEventWithDefaultBehavior } from "./infinite-canvas-event-with-default-behavior"; +import type { InfiniteCanvasTouchEvent } from "./infinite-canvas-touch-event"; +import type { TransformationEvent } from "./transformation-event"; export interface EventMap extends HTMLElementEventMap { /** diff --git a/src/api-surface/infinite-canvas-touch-event.ts b/src/api-surface/infinite-canvas-touch-event.ts index 21f07a04..d601ab2c 100644 --- a/src/api-surface/infinite-canvas-touch-event.ts +++ b/src/api-surface/infinite-canvas-touch-event.ts @@ -1,4 +1,4 @@ -import { InfiniteCanvasTouchList } from "./infinite-canvas-touch-list"; +import type { InfiniteCanvasTouchList } from "./infinite-canvas-touch-list"; export interface InfiniteCanvasTouchEvent extends TouchEvent{ readonly targetTouches: InfiniteCanvasTouchList; diff --git a/src/api-surface/infinite-canvas-touch-list.ts b/src/api-surface/infinite-canvas-touch-list.ts index 78dac498..988812a9 100644 --- a/src/api-surface/infinite-canvas-touch-list.ts +++ b/src/api-surface/infinite-canvas-touch-list.ts @@ -1,4 +1,4 @@ -import { InfiniteCanvasTouch } from "./infinite-canvas-touch"; +import type { InfiniteCanvasTouch } from "./infinite-canvas-touch"; export interface InfiniteCanvasTouchList extends TouchList{ [Symbol.iterator](): IterableIterator; diff --git a/src/api-surface/infinite-canvas.ts b/src/api-surface/infinite-canvas.ts index bd5fe118..3f3cd2ec 100644 --- a/src/api-surface/infinite-canvas.ts +++ b/src/api-surface/infinite-canvas.ts @@ -1,11 +1,11 @@ -import {Config} from "./config"; +import type {Config} from "./config"; import { Units } from "./units"; -import {InfiniteCanvasRenderingContext2D} from "./infinite-canvas-rendering-context-2d"; -import {EventMap} from "./event-map"; -import { TransformationEvent } from "./transformation-event"; -import { Transformed } from './transformed'; +import type {InfiniteCanvasRenderingContext2D} from "./infinite-canvas-rendering-context-2d"; +import type {EventMap} from "./event-map"; +import type { TransformationEvent } from "./transformation-event"; +import type { Transformed } from './transformed'; -export interface InfiniteCanvasEventHandlers extends DocumentAndElementEventHandlers, GlobalEventHandlers { +export interface InfiniteCanvasEventHandlers extends GlobalEventHandlers { /** * The [event handler property](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_handler_properties) for the {@link EventMap.transformationstart} event */ diff --git a/src/api-surface/transformation-event.ts b/src/api-surface/transformation-event.ts index 716ff39f..5ce96ab2 100644 --- a/src/api-surface/transformation-event.ts +++ b/src/api-surface/transformation-event.ts @@ -1,4 +1,4 @@ -import { Transformed } from "./transformed"; +import type { Transformed } from "./transformed"; export interface TransformationEvent extends Event, Transformed{ } diff --git a/src/api-surface/transformed.ts b/src/api-surface/transformed.ts index 99162cdf..ab50d89a 100644 --- a/src/api-surface/transformed.ts +++ b/src/api-surface/transformed.ts @@ -1,4 +1,4 @@ -import { TransformationRepresentation } from "./transformation-representation"; +import type { TransformationRepresentation } from "./transformation-representation"; export interface Transformed{ /** diff --git a/src/areas/infinite-canvas-area-builder.ts b/src/areas/infinite-canvas-area-builder.ts index 4dc7d356..f9d9ae6c 100644 --- a/src/areas/infinite-canvas-area-builder.ts +++ b/src/areas/infinite-canvas-area-builder.ts @@ -58,7 +58,4 @@ export class InfiniteCanvasAreaBuilder { public transformedWith(transformation: Transformation): AreaBuilder{ return new TransformedAreaBuilder(this, transformation); } - public copy(): InfiniteCanvasAreaBuilder{ - return new InfiniteCanvasAreaBuilder(this._area, this.firstPoint, this.subsetOfLineAtInfinity); - } } diff --git a/src/areas/polygons/convex-polygon.ts b/src/areas/polygons/convex-polygon.ts index eab822cc..1ec5a9f7 100644 --- a/src/areas/polygons/convex-polygon.ts +++ b/src/areas/polygons/convex-polygon.ts @@ -469,21 +469,4 @@ export class ConvexPolygon implements Area{ HalfPlane.throughPointsAndContainingPoint(point2, point3, point1), ]) } - - public static createRectangle(x: number, y: number, width: number, height: number): ConvexPolygon{ - const halfPlanes: HalfPlane[] = []; - if(Number.isFinite(x)){ - halfPlanes.push(new HalfPlane(new Point(x, 0), width > 0 ? new Point(1, 0): new Point(-1, 0))); - if(Number.isFinite(width)){ - halfPlanes.push(new HalfPlane(new Point(x + width, 0), width > 0 ? new Point(-1, 0) : new Point(1, 0))) - } - } - if(Number.isFinite(y)){ - halfPlanes.push(new HalfPlane(new Point(0, y), height > 0 ? new Point(0, 1): new Point(0, -1))); - if(Number.isFinite(height)){ - halfPlanes.push(new HalfPlane(new Point(0, y + height), height > 0 ? new Point(0, -1): new Point(0, 1))) - } - } - return new ConvexPolygon(halfPlanes); - } } diff --git a/src/drawing-instruction.ts b/src/drawing-instruction.ts index 41124556..e4447bc3 100644 --- a/src/drawing-instruction.ts +++ b/src/drawing-instruction.ts @@ -7,9 +7,9 @@ import { Point } from "./geometry/point" import { Transformation } from "./transformation" import { getTempStateFnFromTransformationKind, sequence, useTempState } from "./instruction-utils" import { DrawnPathProperties } from "./interfaces/drawn-path-properties" -import { CurrentPath } from "./interfaces/current-path" +import { DrawablePath } from "./interfaces/drawable-path" -function getAreaOfPath(path: CurrentPath, drawnPathProperties: DrawnPathProperties): Area{ +function getAreaOfPath(path: DrawablePath, drawnPathProperties: DrawnPathProperties): Area{ let newlyDrawnArea: Area = path.area if(newlyDrawnArea && drawnPathProperties.lineWidth > 0){ newlyDrawnArea = newlyDrawnArea.expandByDistance(drawnPathProperties.lineWidth / 2) @@ -48,20 +48,20 @@ export class DrawingInstruction{ public static forStrokingPath( instruction: Instruction, state: InfiniteCanvasState, - getPath: (state: InfiniteCanvasState) => CurrentPath): DrawingInstruction{ + getPath: (state: InfiniteCanvasState) => DrawablePath): DrawingInstruction{ return DrawingInstruction.forPath(instruction, state, getDrawnPathPropertiesWhenStroked, getPath); } public static forFillingPath( instruction: Instruction, state: InfiniteCanvasState, - getPath: (state: InfiniteCanvasState) => CurrentPath): DrawingInstruction{ + getPath: (state: InfiniteCanvasState) => DrawablePath): DrawingInstruction{ return DrawingInstruction.forPath(instruction, state, getDrawnPathPropertiesWhenFilled, getPath); } - public static forPath( + private static forPath( instruction: Instruction, state: InfiniteCanvasState, getDrawnPathProperties: (state: InfiniteCanvasState) => DrawnPathProperties, - getPath: (state: InfiniteCanvasState) => CurrentPath): DrawingInstruction{ + getPath: (state: InfiniteCanvasState) => DrawablePath): DrawingInstruction{ const stateIsTransformable: boolean = state.current.isTransformable(); const transformationKind = stateIsTransformable ? TransformationKind.None : TransformationKind.Relative; const stateToDrawWith: InfiniteCanvasState = state.currentlyTransformed(stateIsTransformable); diff --git a/src/events/event-impl.ts b/src/events/event-impl.ts index 54795919..fbe72bcd 100644 --- a/src/events/event-impl.ts +++ b/src/events/event-impl.ts @@ -11,10 +11,10 @@ export class EventImpl { public get eventPhase(): number{return Event.AT_TARGET;} public get cancelable(): boolean{return this.preventableDefault.cancelable;} public get defaultPrevented(): boolean{return this.preventableDefault.defaultPrevented;} - public get AT_TARGET(): number{return Event.AT_TARGET} - public get BUBBLING_PHASE(): number{return Event.BUBBLING_PHASE} - public get CAPTURING_PHASE(): number{return Event.CAPTURING_PHASE} - public get NONE(): number{return Event.NONE} + public AT_TARGET = 2 as const + public BUBBLING_PHASE = 3 as const + public CAPTURING_PHASE = 1 as const + public NONE: 0 = 0 initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void { } diff --git a/src/events/mouse-events/wheel-event-impl.ts b/src/events/mouse-events/wheel-event-impl.ts index 3b2a39b1..23a55e43 100644 --- a/src/events/mouse-events/wheel-event-impl.ts +++ b/src/events/mouse-events/wheel-event-impl.ts @@ -13,7 +13,7 @@ export class WheelEventImpl extends MouseEventImpl implements WheelE } public get deltaMode(): number{return this.event.deltaMode;} public get deltaZ(): number{return this.event.deltaZ;} - public get DOM_DELTA_LINE(): number{return this.event.DOM_DELTA_LINE;} - public get DOM_DELTA_PAGE(): number{return this.event.DOM_DELTA_PAGE;} - public get DOM_DELTA_PIXEL(): number{return this.event.DOM_DELTA_PIXEL;} + public DOM_DELTA_LINE = 1 as const + public DOM_DELTA_PAGE = 2 as const + public DOM_DELTA_PIXEL = 0 as const } diff --git a/src/geometry/rectangle-has-area.ts b/src/geometry/rectangle-has-area.ts deleted file mode 100644 index 4789ecdc..00000000 --- a/src/geometry/rectangle-has-area.ts +++ /dev/null @@ -1,13 +0,0 @@ -function lineSegmentHasLength(start: number, length: number): boolean{ - if(Number.isFinite(start)){ - return true; - } - if(Number.isFinite(length)){ - return false; - } - return start < 0 && length > 0 || start > 0 && length < 0; -} - -export function rectangleHasArea(x: number, y: number, width: number, height: number): boolean{ - return lineSegmentHasLength(x, width) && lineSegmentHasLength(y, height); -} diff --git a/src/geometry/rectangle-is-plane.ts b/src/geometry/rectangle-is-plane.ts deleted file mode 100644 index 09f27493..00000000 --- a/src/geometry/rectangle-is-plane.ts +++ /dev/null @@ -1,10 +0,0 @@ -function lineSegmentIsLine(start: number, length: number): boolean{ - if(Number.isFinite(start) || Number.isFinite(length)){ - return false; - } - return start < 0 && length > 0 || start > 0 && length < 0; -} - -export function rectangleIsPlane(x: number, y: number, width: number, height: number): boolean{ - return lineSegmentIsLine(x, width) && lineSegmentIsLine(y, height); -} diff --git a/src/infinite-canvas-instruction-set.ts b/src/infinite-canvas-instruction-set.ts index d02270e0..225512fb 100644 --- a/src/infinite-canvas-instruction-set.ts +++ b/src/infinite-canvas-instruction-set.ts @@ -9,15 +9,14 @@ import { TransformationKind } from "./transformation-kind"; import { Area } from "./areas/area"; import { empty } from "./areas/empty"; import { Position } from "./geometry/position" -import { rectangleHasArea } from "./geometry/rectangle-has-area"; -import { rectangleIsPlane } from "./geometry/rectangle-is-plane"; -import { plane } from "./areas/plane"; -import { ConvexPolygon } from "./areas/polygons/convex-polygon"; import { ExecutableInstructionWithState } from "./instructions/executable-instruction-with-state"; import { InstructionsWithPositiveDrawnArea } from "./instructions/instructions-with-positive-drawn-area"; import { ExecutableStateChangingInstructionSet } from "./interfaces/executable-state-changing-instruction-set"; import { DrawingInstruction } from './drawing-instruction' import { CanvasRectangle } from "./rectangle/canvas-rectangle"; +import { roundRect } from "./rect/round-rect"; +import { getRectStrategy} from "./rect/get-rect-strategy"; +import { Rect } from './rect/rect' export class InfiniteCanvasInstructionSet{ private currentInstructionsWithPath: CurrentPath; @@ -41,6 +40,12 @@ export class InfiniteCanvasInstructionSet{ public restoreState(): void{ this.state = this.state.restored(); } + public resetState(): void{ + this.previousInstructionsWithPath = PreviousInstructions.create(); + this.state = this.previousInstructionsWithPath.state; + this.currentInstructionsWithPath = undefined; + this.onChange(); + } public allSubpathsAreClosable(): boolean{ return !this.currentInstructionsWithPath || this.currentInstructionsWithPath.allSubpathsAreClosable(); } @@ -66,21 +71,19 @@ export class InfiniteCanvasInstructionSet{ this.state = drawingInstruction.state; this.incorporateDrawingInstruction(drawingInstruction) } - public fillRect(x: number, y: number, w: number, h: number, instruction: Instruction): void{ - const drawingInstruction = DrawingInstruction.forFillingPath(instruction, this.state, (state) => { - const result = InstructionsWithPath.create(state); - result.rect(x, y, w, h, state); - return result; - }) + public fillRect(rect: Rect, instruction: Instruction): void{ + const drawingInstruction = rect.fill(this.state, instruction) + if(!drawingInstruction){ + return + } this.incorporateDrawingInstruction(drawingInstruction); } - public strokeRect(x: number, y: number, w: number, h: number): void{ - const drawingInstruction = DrawingInstruction.forStrokingPath((context) => {context.stroke();}, this.state, (state) => { - const result = InstructionsWithPath.create(state); - result.rect(x, y, w, h, state); - return result; - }) + public strokeRect(rect: Rect): void{ + const drawingInstruction = rect.stroke(this.state, (context) => {context.stroke();}) + if(!drawingInstruction){ + return + } this.incorporateDrawingInstruction(drawingInstruction); } @@ -123,13 +126,8 @@ export class InfiniteCanvasInstructionSet{ return; } const modifiedInstruction = instruction.getModifiedInstruction(); - if(this.currentInstructionsWithPath){ - const recreated = this.currentInstructionsWithPath.recreatePath(); - this.addToPreviousInstructions(modifiedInstruction, area, instruction.build); - recreated.setInitialStateWithClippedPaths(this.previousInstructionsWithPath.state); - this.currentInstructionsWithPath = recreated; - }else{ - this.addToPreviousInstructions(modifiedInstruction, area, instruction.build); + this.addToPreviousInstructions(modifiedInstruction, area, instruction.build); + if(!this.currentInstructionsWithPath){ this.state = this.previousInstructionsWithPath.state; } this.onChange(); @@ -177,10 +175,20 @@ export class InfiniteCanvasInstructionSet{ this.currentInstructionsWithPath.lineTo(position, this.state); } } - public rect(x: number, y: number, w: number, h: number): void{ - if(this.currentInstructionsWithPath){ - this.currentInstructionsWithPath.rect(x, y, w, h, this.state); + public rect(rect: Rect): void{ + if(!this.currentInstructionsWithPath){ + return; } + rect.addSubpaths(this.currentInstructionsWithPath, this.state) + } + public roundRect( + rect: Rect, + radii: number | DOMPointInit | Iterable | undefined + ): void{ + if(!this.currentInstructionsWithPath){ + return; + } + roundRect(this.currentInstructionsWithPath, rect, radii, this.state); } private intersects(area: Area): boolean{ return this.previousInstructionsWithPath.intersects(area); @@ -194,10 +202,11 @@ export class InfiniteCanvasInstructionSet{ } public clearArea(x: number, y: number, width: number, height: number): void{ - if(!rectangleHasArea(x, y, width, height)){ - return; - } - const rectangle: Area = rectangleIsPlane(x, y, width, height) ? plane : ConvexPolygon.createRectangle(x, y, width, height); + const rectStrategy = getRectStrategy(x, y, width, height) + const rectangle: Area = rectStrategy.getArea(); + if(!rectangle){ + return; + } const transformedRectangle: Area = rectangle.transform(this.state.current.transformation) if(!this.intersects(transformedRectangle)){ return; diff --git a/src/infinite-canvas-viewbox.ts b/src/infinite-canvas-viewbox.ts index 2d5fb5d9..8fb93323 100644 --- a/src/infinite-canvas-viewbox.ts +++ b/src/infinite-canvas-viewbox.ts @@ -13,11 +13,10 @@ import { TransformationKind } from "./transformation-kind"; import { InfiniteCanvasInstructionSet } from "./infinite-canvas-instruction-set"; import { Area } from "./areas/area"; import { Position } from "./geometry/position" -import {rectangleHasArea} from "./geometry/rectangle-has-area"; -import {rectangleIsPlane} from "./geometry/rectangle-is-plane"; import { RectangleManager } from "./rectangle/rectangle-manager"; import { InfiniteCanvasConicGradient } from "./styles/infinite-canvas-conic-gradient"; import { textDrawingStylesDimensions } from "./state/dimensions/all-dimensions"; +import { getRectStrategy } from "./rect/get-rect-strategy"; export class InfiniteCanvasViewBox implements ViewBox{ private instructionSet: InfiniteCanvasInstructionSet; @@ -57,6 +56,9 @@ export class InfiniteCanvasViewBox implements ViewBox{ public restoreState(): void{ this.instructionSet.restoreState(); } + public resetState(): void{ + this.instructionSet.resetState(); + } public beginPath(): void{ this.instructionSet.beginPath(); } @@ -85,7 +87,18 @@ export class InfiniteCanvasViewBox implements ViewBox{ } } public rect(x: number, y: number, w: number, h: number): void{ - this.instructionSet.rect(x, y, w, h); + const rectStrategy = getRectStrategy(x, y, w, h) + this.instructionSet.rect(rectStrategy); + } + public roundRect( + x: number, + y: number, + w: number, + h: number, + radii?: number | DOMPointInit | Iterable + ): void{ + const rectStrategy = getRectStrategy(x, y, w, h) + this.instructionSet.roundRect(rectStrategy, radii) } public currentPathCanBeFilled(): boolean{ return this.instructionSet.allSubpathsAreClosable() && this.instructionSet.currentPathSurroundsFinitePoint(); @@ -97,16 +110,12 @@ export class InfiniteCanvasViewBox implements ViewBox{ this.instructionSet.strokePath(); } public fillRect(x: number, y: number, w: number, h: number, instruction: Instruction): void{ - if(!rectangleHasArea(x, y, w, h)){ - return; - } - this.instructionSet.fillRect(x, y, w, h, instruction); + const rectStrategy = getRectStrategy(x, y, w, h) + this.instructionSet.fillRect(rectStrategy, instruction); } public strokeRect(x: number, y: number, w: number, h: number): void{ - if(!rectangleHasArea(x, y, w, h) || rectangleIsPlane(x, y, w, h)){ - return; - } - this.instructionSet.strokeRect(x, y, w, h); + const rectStrategy = getRectStrategy(x, y, w, h) + this.instructionSet.strokeRect(rectStrategy); } public clipPath(instruction: Instruction): void{ this.instructionSet.clipPath(instruction); diff --git a/src/infinite-canvas.ts b/src/infinite-canvas.ts index 6de86ce5..59d3dda2 100644 --- a/src/infinite-canvas.ts +++ b/src/infinite-canvas.ts @@ -157,6 +157,18 @@ class InfiniteCanvas implements InfiniteCanvasInterface{ public get ontouchignored(): (this: InfiniteCanvasInterface, event: Event) => any{ return this.eventCollection.getOn('touchignored'); } + public set onbeforeinput(value: (this: InfiniteCanvasInterface, event: InputEvent) => any){ + this.eventCollection.setOn('beforeinput', value); + } + public get onbeforeinput(): (this: InfiniteCanvasInterface, event: InputEvent) => any{ + return this.eventCollection.getOn('beforeinput'); + } + public set oncancel(value: (this: InfiniteCanvasInterface, event: Event) => any){ + this.eventCollection.setOn('cancel', value); + } + public get oncancel(): (this: InfiniteCanvasInterface, event: Event) => any{ + return this.eventCollection.getOn('cancel'); + } public set oncopy(value: (this: InfiniteCanvasInterface, event: ClipboardEvent) => any){ this.eventCollection.setOn('copy', value); } @@ -265,6 +277,12 @@ class InfiniteCanvas implements InfiniteCanvasInterface{ public set ondblclick(value: (this: InfiniteCanvasInterface, event: MouseEvent) => any){ this.eventCollection.setOn('dblclick', value); } + public get onscrollend(): (this: InfiniteCanvasInterface, event: Event) => any{ + return this.eventCollection.getOn('scrollend'); + } + public set onscrollend(value: (this: InfiniteCanvasInterface, event: Event) => any){ + this.eventCollection.setOn('scrollend', value); + } public get ondrag(): (this: InfiniteCanvasInterface, event: DragEvent) => any{ return this.eventCollection.getOn('drag'); } diff --git a/src/infinite-context/infinite-canvas-draw-image.ts b/src/infinite-context/infinite-canvas-draw-image.ts index a2b875f3..2aa7f5fd 100644 --- a/src/infinite-context/infinite-canvas-draw-image.ts +++ b/src/infinite-context/infinite-canvas-draw-image.ts @@ -2,7 +2,24 @@ import { ViewBox } from "../interfaces/viewbox"; import { Instruction } from "../instructions/instruction"; import { TransformationKind } from "../transformation-kind"; import {Area} from "../areas/area"; -import {ConvexPolygon} from "../areas/polygons/convex-polygon"; +import { getRectStrategy } from "../rect/get-rect-strategy"; + +function isVideoFrame(image: CanvasImageSource): image is VideoFrame{ + return typeof (image as VideoFrame).duration !== 'undefined' +} + +function getWidthAndHeight(image: CanvasImageSource): {width: number | SVGAnimatedLength, height: number| SVGAnimatedLength}{ + if(isVideoFrame(image)){ + return { + width: image.displayWidth, + height: image.displayHeight + } + } + return { + width: image.width, + height: image.height + } +} export class InfiniteCanvasDrawImage implements CanvasDrawImage{ constructor(private readonly viewBox: ViewBox){} @@ -22,9 +39,10 @@ export class InfiniteCanvasDrawImage implements CanvasDrawImage{ }else{ [image, sx, sy, sw, sh, dx, dy, dw, dh] = argumentsArray; } - const drawnWidth: number = this.getDrawnLength(image.width, sx, sw, dw); - const drawnHeight: number = this.getDrawnLength(image.height, sy, sh, dh); - const drawnRectangle: Area = ConvexPolygon.createRectangle(dx, dy, drawnWidth, drawnHeight); + const { width, height } = getWidthAndHeight(image) + const drawnWidth: number = this.getDrawnLength(width, sx, sw, dw); + const drawnHeight: number = this.getDrawnLength(height, sy, sh, dh); + const drawnRectangle: Area = getRectStrategy(dx, dy, drawnWidth, drawnHeight).getArea() const drawingInstruction: Instruction = this.getDrawImageInstruction(arguments.length, image, sx, sy, sw, sh, dx, dy, dw, dh); this.viewBox.addDrawing(drawingInstruction, drawnRectangle, TransformationKind.Relative, true); } diff --git a/src/infinite-context/infinite-canvas-image-data.ts b/src/infinite-context/infinite-canvas-image-data.ts index 8d1dec63..116e0f03 100644 --- a/src/infinite-context/infinite-canvas-image-data.ts +++ b/src/infinite-context/infinite-canvas-image-data.ts @@ -2,8 +2,8 @@ import { ViewBox } from "../interfaces/viewbox"; import { sliceImageData } from "./slice-image-data"; import { DrawingLock } from "../drawing-lock"; import { TransformationKind } from "../transformation-kind"; -import {ConvexPolygon} from "../areas/polygons/convex-polygon"; import { InfiniteCanvasStateInstance } from "../state/infinite-canvas-state-instance"; +import { getRectStrategy } from "../rect/get-rect-strategy"; export class InfiniteCanvasImageData implements CanvasImageData{ constructor(private viewBox: ViewBox){ @@ -24,7 +24,7 @@ export class InfiniteCanvasImageData implements CanvasImageData{ context.translate(dx, dy); context.fillStyle = pattern; context.fillRect(0, 0, imagedata.width, imagedata.height); - }, ConvexPolygon.createRectangle(dx, dy, imagedata.width, imagedata.height), TransformationKind.Absolute, false, state => state + }, getRectStrategy(dx, dy, imagedata.width, imagedata.height).getArea(), TransformationKind.Absolute, false, state => state .changeProperty('shadowColor', InfiniteCanvasStateInstance.default.shadowColor) .changeProperty('shadowOffset', InfiniteCanvasStateInstance.default.shadowOffset) .changeProperty('shadowBlur', InfiniteCanvasStateInstance.default.shadowBlur) diff --git a/src/infinite-context/infinite-canvas-path.ts b/src/infinite-context/infinite-canvas-path.ts index 212229ec..e2e998f7 100644 --- a/src/infinite-context/infinite-canvas-path.ts +++ b/src/infinite-context/infinite-canvas-path.ts @@ -37,4 +37,13 @@ export class InfiniteCanvasPath implements CanvasPath{ public rect(x: number, y: number, w: number, h: number): void{ this.viewBox.rect(x, y, w, h); } + public roundRect( + x: number, + y: number, + w: number, + h: number, + radii?: number | DOMPointInit | Iterable + ): void{ + this.viewBox.roundRect(x, y, w, h, radii) + } } \ No newline at end of file diff --git a/src/infinite-context/infinite-canvas-state.ts b/src/infinite-context/infinite-canvas-state.ts index d309eeb6..81d80d1d 100644 --- a/src/infinite-context/infinite-canvas-state.ts +++ b/src/infinite-context/infinite-canvas-state.ts @@ -8,4 +8,7 @@ export class InfiniteCanvasState implements CanvasState{ public save(): void{ this.viewBox.saveState(); } + public reset(): void{ + this.viewBox.resetState(); + } } \ No newline at end of file diff --git a/src/infinite-context/infinite-canvas-text-drawing-styles.ts b/src/infinite-context/infinite-canvas-text-drawing-styles.ts index b52416ae..df2e6dfe 100644 --- a/src/infinite-context/infinite-canvas-text-drawing-styles.ts +++ b/src/infinite-context/infinite-canvas-text-drawing-styles.ts @@ -1,6 +1,7 @@ import { ViewBox } from "../interfaces/viewbox"; import { direction } from "../state/dimensions/direction"; import { font } from "../state/dimensions/font"; +import { fontKerning } from "../state/dimensions/font-kerning"; import { textAlign } from "../state/dimensions/text-align"; import { textBaseline } from "../state/dimensions/text-baseline"; @@ -18,4 +19,7 @@ export class InfiniteCanvasTextDrawingStyles implements CanvasTextDrawingStyles{ public set textBaseline(value: CanvasTextBaseline){ this.viewBox.changeState(s => textBaseline.changeInstanceValue(s, value)); } + public set fontKerning(value: CanvasFontKerning){ + this.viewBox.changeState(s => fontKerning.changeInstanceValue(s, value)) + } } \ No newline at end of file diff --git a/src/infinite-context/infinite-canvas-text.ts b/src/infinite-context/infinite-canvas-text.ts index afa53690..8c3c4dbc 100644 --- a/src/infinite-context/infinite-canvas-text.ts +++ b/src/infinite-context/infinite-canvas-text.ts @@ -2,7 +2,7 @@ import { ViewBox } from "../interfaces/viewbox"; import { Instruction } from "../instructions/instruction"; import { TransformationKind } from "../transformation-kind"; import {Area} from "../areas/area"; -import {ConvexPolygon} from "../areas/polygons/convex-polygon"; +import { getRectStrategy } from "../rect/get-rect-strategy"; export class InfiniteCanvasText implements CanvasText{ constructor(private readonly viewBox: ViewBox){} @@ -33,6 +33,6 @@ export class InfiniteCanvasText implements CanvasText{ } const height: number = measured.actualBoundingBoxAscent !== undefined ? measured.actualBoundingBoxAscent + measured.actualBoundingBoxDescent : 1; const ascent: number = measured.actualBoundingBoxAscent !== undefined ? measured.actualBoundingBoxAscent : 0; - return ConvexPolygon.createRectangle(x, y - ascent, width, height); + return getRectStrategy(x, y - ascent, width, height).getArea(); } } \ No newline at end of file diff --git a/src/infinite-context/infinite-context.ts b/src/infinite-context/infinite-context.ts index 727b5dcb..dc9b64ce 100644 --- a/src/infinite-context/infinite-context.ts +++ b/src/infinite-context/infinite-context.ts @@ -62,6 +62,9 @@ export class InfiniteContext implements InfiniteCanvasRenderingContext2D{ public restore(): void{ this.canvasState.restore(); } + public reset(): void{ + this.canvasState.reset(); + } public getTransform(): DOMMatrix{ return this.canvasTransform.getTransform(); } @@ -215,6 +218,9 @@ export class InfiniteContext implements InfiniteCanvasRenderingContext2D{ public set textBaseline(value: CanvasTextBaseline){ this.canvasTextDrawingStyles.textBaseline = value; } + public set fontKerning(value: CanvasFontKerning){ + this.canvasTextDrawingStyles.fontKerning = value; + } public arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void{ this.canvasPath.arc(x, y, radius, startAngle, endAngle, anticlockwise); } @@ -246,9 +252,15 @@ export class InfiniteContext implements InfiniteCanvasRenderingContext2D{ this.canvasPath.quadraticCurveTo(cpx, cpy, x, y); } public rect(x: number, y: number, w: number, h: number): void{ - if(!Number.isFinite(x) && !Number.isFinite(y)){ - throw new Error(`The starting coordinates provided (${x} and ${y}) do not determine a direction.`) - } this.canvasPath.rect(x, y, w, h); } + public roundRect( + x: number, + y: number, + w: number, + h: number, + radii?: number | DOMPointInit | Iterable + ): void{ + this.canvasPath.roundRect(x, y, w, h, radii); + } } diff --git a/src/instructions/instructions-with-path.ts b/src/instructions/instructions-with-path.ts index 2ca740a3..33d113b0 100644 --- a/src/instructions/instructions-with-path.ts +++ b/src/instructions/instructions-with-path.ts @@ -1,5 +1,5 @@ import { StateChangingInstructionSequence } from "./state-changing-instruction-sequence"; -import { CopyableInstructionWithState } from "./copyable-instruction-with-state"; +import { PreExecutableInstructionWithState } from "./pre-executable-instruction-with-state"; import { CurrentPath } from "../interfaces/current-path"; import { PathInstruction } from "../interfaces/path-instruction"; import { InfiniteCanvasState } from "../state/infinite-canvas-state"; @@ -8,21 +8,18 @@ import { Area } from "../areas/area"; import { InfiniteCanvasAreaBuilder } from "../areas/infinite-canvas-area-builder"; import { Position } from "../geometry/position"; import { transformPosition } from "../geometry/transform-position"; -import { Point } from "../geometry/point"; import { InstructionsWithSubpath } from "./instructions-with-subpath"; -import {down, left, right, up} from "../geometry/points-at-infinity"; -import {rectangleHasArea} from "../geometry/rectangle-has-area"; import { DrawnPathProperties } from "../interfaces/drawn-path-properties"; import { InfiniteCanvasPathInfinityProvider } from "../infinite-canvas-path-infinity-provider"; import { InstructionsToClip } from "../interfaces/instructions-to-clip"; import { InstructionsToClipImpl } from "./instructions-to-clip-impl"; import { ExecutableStateChangingInstructionSet } from "../interfaces/executable-state-changing-instruction-set"; import { ExecutableStateChangingInstructionSequence } from "./executable-state-changing-instruction-sequence"; -import { CanvasRectangle } from "../rectangle/canvas-rectangle"; +import { ExecutableInstructionWithState } from "./executable-instruction-with-state"; export class InstructionsWithPath extends StateChangingInstructionSequence implements CurrentPath{ private areaBuilder: InfiniteCanvasAreaBuilder = new InfiniteCanvasAreaBuilder(); - constructor(private _initiallyWithState: CopyableInstructionWithState){ + constructor(private _initiallyWithState: PreExecutableInstructionWithState){ super(_initiallyWithState); } public get area(): Area{return this.areaBuilder.area;} @@ -55,12 +52,13 @@ export class InstructionsWithPath extends StateChangingInstructionSequence{ const result = new ExecutableStateChangingInstructionSequence(this._initiallyWithState.makeExecutable()); const pathInfinityProvider = new InfiniteCanvasPathInfinityProvider(drawnPathProperties) for(const added of this.added){ @@ -68,15 +66,20 @@ export class InstructionsWithPath extends StateChangingInstructionSequence 0 ? down : up, state); - } - }else{ - this.lineTo(w > 0 ? right : left, state); - if(Number.isFinite(h)){ - this.lineTo(new Point(x, y + h), state); - }else{ - this.lineTo(h > 0 ? down : up, state); - } - } - this.lineTo(new Point(x, y), state); - }else{ - if(Number.isFinite(w)){ - this.lineTo(new Point(x + w, 0), state); - }else{ - this.lineTo(w > 0 ? right : left, state); - } - this.lineTo(h > 0 ? down : up, state); - this.lineTo(new Point(x, 0), state); - this.lineTo(y < 0 ? up : down, state); - } - }else{ - this.lineTo(new Point(0, y), state); - this.lineTo(w > 0 ? right : left, state); - if(Number.isFinite(h)){ - this.lineTo(new Point(0, y + h), state); - }else{ - this.lineTo(h > 0 ? down : up, state) - } - this.lineTo(x < 0 ? left : right, state); - } - this.closePath(); - this.moveToPositionDeterminedBy(x, y, state); - } public addPathInstruction(pathInstruction: PathInstruction, state: InfiniteCanvasState): void{ if(this.added.length === 0){ if(pathInstruction.initialPoint){ @@ -185,22 +124,10 @@ export class InstructionsWithPath extends StateChangingInstructionSequence {context.beginPath();})); + return new InstructionsWithPath(PreExecutableInstructionWithState.create(initialState, (context: CanvasRenderingContext2D) => {context.beginPath();})); } } diff --git a/src/instructions/instructions-with-subpath.ts b/src/instructions/instructions-with-subpath.ts index 41d27079..12ae34f8 100644 --- a/src/instructions/instructions-with-subpath.ts +++ b/src/instructions/instructions-with-subpath.ts @@ -9,35 +9,27 @@ import { positionsAreEqual } from "../geometry/positions-are-equal"; import { PathInstructionBuilder } from "./path-instruction-builders/path-instruction-builder"; import { InfiniteCanvasPathInstructionBuilderProvider } from "./path-instruction-builders/infinite-canvas-path-instruction-builder-provider"; import { PathInfinityProvider } from "../interfaces/path-infinity-provider"; -import { CopyableInstructionWithState } from "./copyable-instruction-with-state"; +import { PreExecutableInstructionWithState } from "./pre-executable-instruction-with-state"; import { ViewboxInfinity } from "../interfaces/viewbox-infinity"; import { InstructionUsingInfinity } from "./instruction-using-infinity"; -import { CopyableInstructionSet } from "../interfaces/copyable-instruction-set"; +import { PreExecutableInstructionSet } from "../interfaces/pre-executable-instruction-set"; import { ExecutableStateChangingInstructionSet } from "../interfaces/executable-state-changing-instruction-set"; import { ExecutableStateChangingInstructionSequence } from "./executable-state-changing-instruction-sequence"; import { CanvasRectangle } from "../rectangle/canvas-rectangle"; -export class InstructionsWithSubpath extends StateChangingInstructionSequence{ +export class InstructionsWithSubpath extends StateChangingInstructionSequence{ constructor(private readonly _initiallyWithState: PathInstructionWithState, private pathInstructionBuilder: PathInstructionBuilder){ super(_initiallyWithState); } public get currentPosition(): Position{return this.pathInstructionBuilder.currentPosition;} - public addInstruction(instruction: CopyableInstructionWithState): void{ + public addInstruction(instruction: PreExecutableInstructionWithState): void{ instruction.setInitialState(this.state); this.add(instruction); } public closePath(): void{ - const toAdd: CopyableInstructionWithState = CopyableInstructionWithState.create(this.state, (context: CanvasRenderingContext2D) => {context.closePath();}) - toAdd.setInitialState(this.state); + const toAdd: PreExecutableInstructionWithState = PreExecutableInstructionWithState.create(this.state, (context: CanvasRenderingContext2D) => {context.closePath();}) this.add(toAdd); } - public copy(): InstructionsWithSubpath{ - const result: InstructionsWithSubpath = new InstructionsWithSubpath(this._initiallyWithState.copy(), this.pathInstructionBuilder); - for(const added of this.added){ - result.add(added.copy()); - } - return result; - } public makeExecutable(infinityProvider: PathInfinityProvider): ExecutableStateChangingInstructionSet{ const result = new ExecutableStateChangingInstructionSequence(this._initiallyWithState.makeExecutable(infinityProvider)); for(const added of this.added){ @@ -71,7 +63,7 @@ export class InstructionsWithSubpath extends StateChangingInstructionSequence { + context.beginPath(); + infinity.addPathAroundViewbox(context, rectangle) + instruction(context, rectangle) + }) + } +} + +export const pathAroundViewbox = new PathAroundViewbox(); \ No newline at end of file diff --git a/src/instructions/path-instruction-with-state.ts b/src/instructions/path-instruction-with-state.ts index 494cb3cd..4b0b728c 100644 --- a/src/instructions/path-instruction-with-state.ts +++ b/src/instructions/path-instruction-with-state.ts @@ -2,12 +2,12 @@ import { InfiniteCanvasState } from "../state/infinite-canvas-state"; import { Instruction } from "./instruction"; import { InstructionWithState } from "./instruction-with-state"; import { InstructionUsingInfinity } from "./instruction-using-infinity"; -import { CopyableInstructionSet } from "../interfaces/copyable-instruction-set"; +import { PreExecutableInstructionSet } from "../interfaces/pre-executable-instruction-set"; import { PathInfinityProvider } from "../interfaces/path-infinity-provider"; import { ExecutableStateChangingInstructionSet } from "../interfaces/executable-state-changing-instruction-set"; import { ExecutableInstructionWithState } from "./executable-instruction-with-state"; -export class PathInstructionWithState extends InstructionWithState implements CopyableInstructionSet{ +export class PathInstructionWithState extends InstructionWithState implements PreExecutableInstructionSet{ constructor(initialState: InfiniteCanvasState, state: InfiniteCanvasState, private instruction: InstructionUsingInfinity, stateConversion: Instruction){ super(initialState, state); this.stateConversion = stateConversion; @@ -15,9 +15,6 @@ export class PathInstructionWithState extends InstructionWithState implements Co public replaceInstruction(instruction: InstructionUsingInfinity): void{ this.instruction = instruction; } - public copy(): PathInstructionWithState { - return new PathInstructionWithState(this.initialState, this.state, this.instruction, this.stateConversion); - } public makeExecutable(infinityProvider: PathInfinityProvider): ExecutableStateChangingInstructionSet{ const infinity = infinityProvider.getInfinity(this.state); const oldInstruction = this.instruction; diff --git a/src/instructions/path-instructions.ts b/src/instructions/path-instructions.ts index 6b15a0fd..890a0c41 100644 --- a/src/instructions/path-instructions.ts +++ b/src/instructions/path-instructions.ts @@ -13,9 +13,12 @@ export class PathInstructions{ public static arc(_x: number, _y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): PathInstruction{ const instruction: Instruction = (context: CanvasRenderingContext2D, rectangle: CanvasRectangle) => { const transformation = rectangle.userTransformation; - const transformationAngle: number = transformation.getRotationAngle(); const {x, y} = transformation.apply(new Point(_x, _y)); - context.arc(x, y, radius * transformation.scale, startAngle + transformationAngle, endAngle + transformationAngle, anticlockwise); + const {a, b, c, d, e, f} = transformation.untranslated().before(Transformation.translation(x, y)) + context.save(); + context.transform(a, b, c, d, e, f) + context.arc(0, 0, radius, startAngle, endAngle, anticlockwise); + context.restore(); }; const changeArea: AreaChange = (builder: AreaBuilder) => { builder.addPosition(new Point(_x - radius, _y - radius)); diff --git a/src/instructions/copyable-instruction-with-state.ts b/src/instructions/pre-executable-instruction-with-state.ts similarity index 64% rename from src/instructions/copyable-instruction-with-state.ts rename to src/instructions/pre-executable-instruction-with-state.ts index eb8c68f0..0c347349 100644 --- a/src/instructions/copyable-instruction-with-state.ts +++ b/src/instructions/pre-executable-instruction-with-state.ts @@ -1,22 +1,19 @@ import { InfiniteCanvasState } from "../state/infinite-canvas-state"; -import { CopyableInstructionSet } from "../interfaces/copyable-instruction-set"; +import { PreExecutableInstructionSet } from "../interfaces/pre-executable-instruction-set"; import { InstructionWithState } from "./instruction-with-state"; import { Instruction } from "./instruction"; import { ExecutableStateChangingInstructionSet } from "../interfaces/executable-state-changing-instruction-set"; import { ExecutableInstructionWithState } from "./executable-instruction-with-state"; -export class CopyableInstructionWithState extends InstructionWithState implements CopyableInstructionSet{ +export class PreExecutableInstructionWithState extends InstructionWithState implements PreExecutableInstructionSet{ constructor(initialState: InfiniteCanvasState, state: InfiniteCanvasState, protected instruction: Instruction, stateConversion: Instruction){ super(initialState, state); this.stateConversion = stateConversion; } - public copy(): CopyableInstructionWithState{ - return new CopyableInstructionWithState(this.initialState, this.state, this.instruction, this.stateConversion); - } public makeExecutable(): ExecutableStateChangingInstructionSet{ return new ExecutableInstructionWithState(this.initialState, this.state, this.instruction, this.stateConversion); } - public static create(state: InfiniteCanvasState, instruction: Instruction): CopyableInstructionWithState{ - return new CopyableInstructionWithState(state, state, instruction, () => {}); + public static create(state: InfiniteCanvasState, instruction: Instruction): PreExecutableInstructionWithState{ + return new PreExecutableInstructionWithState(state, state, instruction, () => {}); } } \ No newline at end of file diff --git a/src/interfaces/current-path.ts b/src/interfaces/current-path.ts index 73fea9f3..96c1c859 100644 --- a/src/interfaces/current-path.ts +++ b/src/interfaces/current-path.ts @@ -3,24 +3,16 @@ import { PathInstruction } from "./path-instruction"; import { StateChangingInstructionSet } from './state-changing-instruction-set' import { InfiniteCanvasState } from "../state/infinite-canvas-state"; import { Position } from "../geometry/position" -import { InstructionsToClip } from "./instructions-to-clip"; -import { DrawnPathProperties } from './drawn-path-properties' -import { Area } from '../areas/area' -import { ExecutableStateChangingInstructionSet } from "./executable-state-changing-instruction-set"; +import { DrawablePath } from "./drawable-path"; -export interface CurrentPath extends StateChangingInstructionSet{ - area: Area +export interface CurrentPath extends StateChangingInstructionSet, DrawablePath{ allSubpathsAreClosable(): boolean; currentSubpathIsClosable(): boolean; surroundsFinitePoint(): boolean; - drawPath(instruction: Instruction, state: InfiniteCanvasState, drawnPathProperties: DrawnPathProperties): ExecutableStateChangingInstructionSet clipPath(instruction: Instruction, state: InfiniteCanvasState): void; addPathInstruction(pathInstruction: PathInstruction, state: InfiniteCanvasState): void; closePath(): void; moveTo(position: Position, state: InfiniteCanvasState): void; canAddLineTo(position: Position, state: InfiniteCanvasState): boolean; lineTo(position: Position, state: InfiniteCanvasState): void; - rect(x: number, y: number, w: number, h: number, state: InfiniteCanvasState): void; - recreatePath(): CurrentPath; - getInstructionsToClip(): InstructionsToClip; } \ No newline at end of file diff --git a/src/interfaces/current-state.ts b/src/interfaces/current-state.ts index d5226382..e7761827 100644 --- a/src/interfaces/current-state.ts +++ b/src/interfaces/current-state.ts @@ -6,4 +6,5 @@ export interface CurrentState{ changeState(change: (state: InfiniteCanvasStateInstance) => InfiniteCanvasStateInstance): void; saveState(): void; restoreState(): void; + resetState(): void } \ No newline at end of file diff --git a/src/interfaces/drawable-path.ts b/src/interfaces/drawable-path.ts new file mode 100644 index 00000000..edaa6686 --- /dev/null +++ b/src/interfaces/drawable-path.ts @@ -0,0 +1,10 @@ +import { Area } from "../areas/area"; +import { Instruction } from "../instructions/instruction"; +import { InfiniteCanvasState } from "../state/infinite-canvas-state"; +import { DrawnPathProperties } from './drawn-path-properties' +import { ExecutableStateChangingInstructionSet } from "./executable-state-changing-instruction-set"; + +export interface DrawablePath{ + area: Area + drawPath(instruction: Instruction, state: InfiniteCanvasState, drawnPathProperties: DrawnPathProperties): ExecutableStateChangingInstructionSet +} \ No newline at end of file diff --git a/src/interfaces/copyable-instruction-set.ts b/src/interfaces/pre-executable-instruction-set.ts similarity index 75% rename from src/interfaces/copyable-instruction-set.ts rename to src/interfaces/pre-executable-instruction-set.ts index 74a68cba..0626310b 100644 --- a/src/interfaces/copyable-instruction-set.ts +++ b/src/interfaces/pre-executable-instruction-set.ts @@ -2,7 +2,6 @@ import { StateChangingInstructionSet } from "./state-changing-instruction-set"; import { ExecutableStateChangingInstructionSet } from "./executable-state-changing-instruction-set"; import { PathInfinityProvider } from "./path-infinity-provider"; -export interface CopyableInstructionSet extends StateChangingInstructionSet{ - copy(): CopyableInstructionSet +export interface PreExecutableInstructionSet extends StateChangingInstructionSet{ makeExecutable(infinityProvider: PathInfinityProvider): ExecutableStateChangingInstructionSet } \ No newline at end of file diff --git a/src/interfaces/viewbox.ts b/src/interfaces/viewbox.ts index 0e3bfb58..cd177bb9 100644 --- a/src/interfaces/viewbox.ts +++ b/src/interfaces/viewbox.ts @@ -36,4 +36,11 @@ export interface ViewBox extends Transformable, CurrentState{ moveTo(position: Position): void; lineTo(position: Position): void; rect(x: number, y: number, w: number, h: number): void; + roundRect( + x: number, + y: number, + w: number, + h: number, + radii?: number | DOMPointInit | Iterable + ): void; } diff --git a/src/rect/corner-radii.ts b/src/rect/corner-radii.ts new file mode 100644 index 00000000..d53eb184 --- /dev/null +++ b/src/rect/corner-radii.ts @@ -0,0 +1,106 @@ +export interface SingleCornerRadii{ + x: number + y: number + circular: boolean +} + +export interface CornerRadii{ + upperLeft: SingleCornerRadii + upperRight: SingleCornerRadii + lowerLeft: SingleCornerRadii + lowerRight: SingleCornerRadii +} + +function isDomPointInit(radii: DOMPointInit | Iterable): radii is DOMPointInit{ + return (radii as DOMPointInit).x !== undefined; +} + +function getSingleCornerRadii(radii: number | DOMPointInit): SingleCornerRadii | undefined{ + if(typeof radii === 'number'){ + if(Number.isNaN(radii)){ + return undefined; + } + if(radii < 0){ + throw new RangeError(`Radius value ${radii} is negative.`) + } + return {x: radii, y: radii, circular: true} + } + const {x, y} = radii; + if(Number.isNaN(x) || Number.isNaN(y)){ + return undefined; + } + if(x < 0){ + throw new RangeError(`X-radius value ${radii} is negative.`) + } + if(y < 0){ + throw new RangeError(`Y-radius value ${radii} is negative.`) + } + return {x, y, circular: false}; +} + +function scaleSingleCornerRadii(radii: SingleCornerRadii, scale: number): SingleCornerRadii{ + const {x, y, circular} = radii; + return {x: x * scale, y: y * scale, circular} +} + +export function scaleCornerRadii(cornerRadii: CornerRadii, scale: number): CornerRadii{ + const { upperLeft, upperRight, lowerLeft, lowerRight } = cornerRadii; + return { + upperLeft: scaleSingleCornerRadii(upperLeft, scale), + upperRight: scaleSingleCornerRadii(upperRight, scale), + lowerLeft: scaleSingleCornerRadii(lowerLeft, scale), + lowerRight: scaleSingleCornerRadii(lowerRight, scale) + } +} + +export function getCornerRadii(radii: number | DOMPointInit | Iterable): CornerRadii | undefined{ + if(typeof radii === 'number' || isDomPointInit(radii)){ + const single = getSingleCornerRadii(radii); + if(!single){ + return undefined; + } + return {upperLeft: single, upperRight: single, lowerLeft: single, lowerRight: single}; + } + const radiiAsArray = [...radii]; + const singleRadii = radiiAsArray.slice(0, 4).map(getSingleCornerRadii); + if(singleRadii.includes(undefined)){ + return undefined; + } + if(singleRadii.length === 4){ + const [upperLeft, upperRight, lowerRight, lowerLeft] = singleRadii; + return { + upperLeft, + upperRight, + lowerRight, + lowerLeft + }; + } + if(singleRadii.length === 3){ + const [upperLeft, upperRightLowerLeft, lowerRight] = singleRadii; + return { + upperLeft, + upperRight: upperRightLowerLeft, + lowerRight, + lowerLeft: upperRightLowerLeft + }; + } + if(singleRadii.length === 2){ + const [upperLeftLowerRight, upperRightLowerLeft] = singleRadii; + return { + upperLeft: upperLeftLowerRight, + upperRight: upperRightLowerLeft, + lowerRight: upperLeftLowerRight, + lowerLeft: upperRightLowerLeft + } + } + if(singleRadii.length === 1){ + const [single] = singleRadii; + return { + upperLeft: single, + upperRight: single, + lowerRight: single, + lowerLeft: single + } + } + throw new RangeError(`${radiiAsArray.length} radii provided. Between one and four radii are necessary.`) +} \ No newline at end of file diff --git a/src/rect/corners/corner-orientation.ts b/src/rect/corners/corner-orientation.ts new file mode 100644 index 00000000..42df43d2 --- /dev/null +++ b/src/rect/corners/corner-orientation.ts @@ -0,0 +1,24 @@ +export enum CornerOrientation{ + TOPLEFT, + TOPRIGHT, + BOTTOMLEFT, + BOTTOMRIGHT +} + +export function invertVertical(orientation: CornerOrientation): CornerOrientation{ + switch(orientation){ + case CornerOrientation.TOPLEFT: return CornerOrientation.BOTTOMLEFT; + case CornerOrientation.TOPRIGHT: return CornerOrientation.BOTTOMRIGHT; + case CornerOrientation.BOTTOMRIGHT: return CornerOrientation.TOPRIGHT; + case CornerOrientation.BOTTOMLEFT: return CornerOrientation.TOPLEFT; + } +} + +export function invertHorizontal(orientation: CornerOrientation): CornerOrientation{ + switch(orientation){ + case CornerOrientation.TOPLEFT: return CornerOrientation.TOPRIGHT; + case CornerOrientation.TOPRIGHT: return CornerOrientation.TOPLEFT; + case CornerOrientation.BOTTOMRIGHT: return CornerOrientation.BOTTOMLEFT; + case CornerOrientation.BOTTOMLEFT: return CornerOrientation.BOTTOMRIGHT; + } +} \ No newline at end of file diff --git a/src/rect/corners/corner-strategy-impl.ts b/src/rect/corners/corner-strategy-impl.ts new file mode 100644 index 00000000..d07981cc --- /dev/null +++ b/src/rect/corners/corner-strategy-impl.ts @@ -0,0 +1,106 @@ +import { Point } from "../../geometry/point"; +import { PointAtInfinity } from "../../geometry/point-at-infinity"; +import { CurrentPath } from "../../interfaces/current-path"; +import { InfiniteCanvasState } from "../../state/infinite-canvas-state"; +import { Corner, VisibleCorner, VisibleTopLeftCorner, TopLeftCorner } from "./corner-strategy"; +import { CornerOrientation } from "./corner-orientation"; +import { EdgeOrientation } from "../edge-orientation"; +import { SingleCornerRadii } from "../corner-radii"; +import { RoundCornerStrategyImpl, RoundTopLeftCornerStrategyImpl } from "./round-corner-strategy-impl"; + +export class VisibleCornerImpl implements VisibleCorner{ + constructor( + protected readonly corner: Point, + protected readonly cornerOrientation: CornerOrientation, + protected readonly horizontalOrientation: EdgeOrientation, + protected readonly verticalOrientation: EdgeOrientation){} + public draw(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.lineTo(this.corner, state) + } + public round(radii: SingleCornerRadii): Corner{ + if(radii.x === 0 || radii.y === 0){ + return this; + } + return new RoundCornerStrategyImpl( + radii, + this.corner, + this.cornerOrientation, + this.horizontalOrientation, + this.verticalOrientation + ) + } +} + +export class VisibleTopLeftCornerImpl implements VisibleTopLeftCorner{ + constructor( + protected readonly corner: Point, + protected readonly cornerOrientation: CornerOrientation, + protected readonly horizontalOrientation: EdgeOrientation, + protected readonly verticalOrientation: EdgeOrientation){} + + public moveToEndingPoint(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.moveTo(this.corner, state) + } + + public finishRect(currentPath: CurrentPath, state: InfiniteCanvasState): void { + currentPath.closePath(); + currentPath.moveTo(this.corner, state) + } + + public round(radii: SingleCornerRadii): TopLeftCorner{ + if(radii.x === 0 || radii.y === 0){ + return this; + } + return new RoundTopLeftCornerStrategyImpl( + radii, + this.corner, + this.cornerOrientation, + this.horizontalOrientation, + this.verticalOrientation + ) + } + +} + +export class InfiniteCornerFromInfinityToInfinity implements Corner{ + constructor(private readonly point: Point, protected readonly direction: PointAtInfinity){} + public draw(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.lineTo(this.point, state) + currentPath.lineTo(this.direction, state) + } +} + +export class InfiniteTopLeftCornerFromInfinityToInfinity implements TopLeftCorner{ + constructor(private readonly point: Point, protected readonly direction: PointAtInfinity){} + + public moveToEndingPoint(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.moveTo(this.direction, state) + } + + public finishRect(currentPath: CurrentPath, state: InfiniteCanvasState): void { + currentPath.lineTo(this.point, state) + currentPath.lineTo(this.direction, state) + currentPath.closePath(); + currentPath.moveTo(this.direction, state) + } +} + +export class InfiniteCorner implements Corner{ + constructor(protected readonly direction: PointAtInfinity){} + public draw(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.lineTo(this.direction, state) + } +} + +export class InfiniteTopLeftCorner implements TopLeftCorner{ + constructor(private readonly direction: PointAtInfinity){} + + public moveToEndingPoint(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.moveTo(this.direction, state) + } + + public finishRect(currentPath: CurrentPath, state: InfiniteCanvasState): void { + currentPath.closePath(); + currentPath.moveTo(this.direction, state) + } +} \ No newline at end of file diff --git a/src/rect/corners/corner-strategy.ts b/src/rect/corners/corner-strategy.ts new file mode 100644 index 00000000..176f4d20 --- /dev/null +++ b/src/rect/corners/corner-strategy.ts @@ -0,0 +1,24 @@ +import { CurrentPath } from "../../interfaces/current-path"; +import { InfiniteCanvasState } from "../../state/infinite-canvas-state"; +import { SingleCornerRadii } from "../corner-radii"; + +export interface Corner{ + draw(currentPath: CurrentPath, state: InfiniteCanvasState): void +} + +export interface TopLeftCorner { + moveToEndingPoint(currentPath: CurrentPath, state: InfiniteCanvasState): void + finishRect(currentPath: CurrentPath, state: InfiniteCanvasState): void +} + +export interface RoundableCorner{ + round(radii: SingleCornerRadii): TCorner +} + +export interface VisibleCorner extends Corner, RoundableCorner{ + +} + +export interface VisibleTopLeftCorner extends TopLeftCorner, RoundableCorner{ + +} \ No newline at end of file diff --git a/src/rect/corners/round-corner-strategy-impl.ts b/src/rect/corners/round-corner-strategy-impl.ts new file mode 100644 index 00000000..e4bbdbad --- /dev/null +++ b/src/rect/corners/round-corner-strategy-impl.ts @@ -0,0 +1,147 @@ +import { Point } from "../../geometry/point"; +import { PathInstructions } from "../../instructions/path-instructions"; +import { CurrentPath } from "../../interfaces/current-path"; +import { InfiniteCanvasState } from "../../state/infinite-canvas-state"; +import { SingleCornerRadii } from "../corner-radii"; +import { EdgeOrientation } from "../edge-orientation"; +import { CornerOrientation, invertHorizontal, invertVertical } from "./corner-orientation"; +import { Corner, TopLeftCorner } from "./corner-strategy"; + +interface CornerTerminus{ + angle: number + point: Point +} + +interface CornerLocations{ + center: Point + start: CornerTerminus + end: CornerTerminus +} + +export class RoundCornerStrategyImpl implements Corner{ + private readonly center: Point + private readonly start: CornerTerminus + protected readonly end: CornerTerminus + private readonly radii: SingleCornerRadii + private readonly clockwise: boolean + + constructor( + radii: SingleCornerRadii, + protected readonly corner: Point, + orientation: CornerOrientation, + horizontalOrientation: EdgeOrientation, + verticalOrientation: EdgeOrientation + ){ + orientation = getAdjustedOrientation(orientation, horizontalOrientation, verticalOrientation) + const clockwise = verticalOrientation === horizontalOrientation + let {center, start, end} = getCornerLocations(orientation, corner, radii) + if(!clockwise){ + ({start, end} = {start: end, end: start}) + } + this.radii = radii + this.clockwise = clockwise + this.center = center + this.start = start; + this.end = end; + } + + public draw(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.lineTo(this.start.point, state) + if(this.radii.circular){ + currentPath.addPathInstruction(PathInstructions.arc( + this.center.x, + this.center.y, + this.radii.x, + this.start.angle, + this.end.angle, + !this.clockwise + ), state) + }else{ + currentPath.addPathInstruction(PathInstructions.ellipse( + this.center.x, + this.center.y, + this.radii.x, + this.radii.y, + 0, + this.start.angle, + this.end.angle, + !this.clockwise + ), state) + } + } +} + +export class RoundTopLeftCornerStrategyImpl extends RoundCornerStrategyImpl implements TopLeftCorner{ + + public moveToEndingPoint(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.moveTo(this.end.point, state) + } + + public finishRect(currentPath: CurrentPath, state: InfiniteCanvasState): void { + this.draw(currentPath, state) + currentPath.moveTo(this.corner, state) + } +} + +function getAdjustedOrientation( + orientation: CornerOrientation, + horizontalOrientation: EdgeOrientation, + verticalOrientation: EdgeOrientation +): CornerOrientation{ + if(horizontalOrientation === EdgeOrientation.Negative){ + orientation = invertHorizontal(orientation) + } + if(verticalOrientation === EdgeOrientation.Negative){ + orientation = invertVertical(orientation) + } + return orientation +} + +function getCornerLocations(orientation: CornerOrientation, corner: Point, radii: SingleCornerRadii): CornerLocations{ + switch(orientation){ + case CornerOrientation.TOPLEFT: return { + center: new Point(corner.x + radii.x, corner.y + radii.y), + start: { + angle: Math.PI, + point: new Point(corner.x, corner.y + radii.y) + }, + end: { + angle: 3 * Math.PI / 2, + point: new Point(corner.x + radii.x, corner.y) + } + } + case CornerOrientation.TOPRIGHT: return { + center: new Point(corner.x - radii.x, corner.y + radii.y), + start: { + angle: 3 * Math.PI / 2, + point: new Point(corner.x - radii.x, corner.y) + }, + end: { + angle: 0, + point: new Point(corner.x, corner.y + radii.y) + } + } + case CornerOrientation.BOTTOMRIGHT: return { + center: new Point(corner.x - radii.x, corner.y - radii.y), + start: { + angle: 0, + point: new Point(corner.x, corner.y - radii.y) + }, + end: { + angle: Math.PI / 2, + point: new Point(corner.x - radii.x, corner.y) + } + } + case CornerOrientation.BOTTOMLEFT: return { + center: new Point(corner.x + radii.x, corner.y - radii.y), + start: { + angle: Math.PI / 2, + point: new Point(corner.x + radii.x, corner.y) + }, + end: { + angle: Math.PI, + point: new Point(corner.x, corner.y - radii.y) + } + } + } +} \ No newline at end of file diff --git a/src/rect/dimension-impl.ts b/src/rect/dimension-impl.ts new file mode 100644 index 00000000..3e04800e --- /dev/null +++ b/src/rect/dimension-impl.ts @@ -0,0 +1,274 @@ +import { EdgeOrientation } from "./edge-orientation"; +import { down, left, right, up } from "../geometry/points-at-infinity"; +import { PointAtInfinity } from "../geometry/point-at-infinity"; +import { Dimension, WithStart, WithStartAndEnd } from "./dimension"; +import { Rect, RectWithFourEdges } from "./rect"; +import { RectWithLeft } from "./rect-strategies/rect-with-left"; +import { RectWithTop } from "./rect-strategies/rect-with-top"; +import { RectWithTopAndLeft } from "./rect-strategies/rect-with-top-and-left"; +import { RectWithLeftAndRight } from "./rect-strategies/rect-with-left-and-right"; +import { RectWithTopAndLeftAndRight } from "./rect-strategies/rect-with-top-and-left-and-right"; +import { RectWithTopAndBottom } from "./rect-strategies/rect-with-top-and-bottom"; +import { RectWithTopAndLeftAndBottom } from "./rect-strategies/rect-with-top-and-left-and-bottom"; +import { RectWithFourEdgesImpl } from "./rect-strategies/rect-with-four-edges"; +import { RectAtInfinity } from "./rect-strategies/rect-at-infinity"; +import { PlaneRect } from "./rect-strategies/plane-rect"; +import { UndrawableRectangle } from "./rect-strategies/undrawable-rectangle"; +import { VisibleTopLeftCornerImpl, InfiniteCorner, InfiniteTopLeftCornerFromInfinityToInfinity, InfiniteTopLeftCorner, InfiniteCornerFromInfinityToInfinity, VisibleCornerImpl } from "./corners/corner-strategy-impl"; +import { Corner, VisibleCorner, VisibleTopLeftCorner, TopLeftCorner } from "./corners/corner-strategy"; +import { Point } from "../geometry/point"; +import { CornerOrientation } from "./corners/corner-orientation"; +import { HalfPlane } from "../areas/polygons/half-plane"; + +class LineImpl implements Dimension{ + public readonly horizontalLineEnd: PointAtInfinity + public readonly horizontalLineStart: PointAtInfinity + public readonly verticalLineEnd: PointAtInfinity + public readonly verticalLineStart: PointAtInfinity + constructor( + public readonly start: number, + public readonly orientation: EdgeOrientation){ + this.horizontalLineStart = orientation === EdgeOrientation.Positive ? left : right; + this.horizontalLineEnd = orientation === EdgeOrientation.Positive ? right : left; + this.verticalLineStart = orientation === EdgeOrientation.Positive ? up : down; + this.verticalLineEnd = orientation === EdgeOrientation.Positive ? down : up; + } + private createTopLeftAtVerticalInfinity(horizontal: WithStart): TopLeftCorner{ + return new InfiniteTopLeftCornerFromInfinityToInfinity(new Point(horizontal.finiteStart, 0), this.verticalLineStart); + } + private createBottomRightAtInfinity(horizontal: WithStartAndEnd): Corner{ + return new InfiniteCornerFromInfinityToInfinity(new Point(horizontal.end, 0), this.verticalLineEnd); + } + protected createRightAtInfinity(horizontal: WithStart): Corner{ + return new InfiniteCorner(horizontal.horizontalLineEnd) + } + protected createBottomAtInfinity(): Corner{ + return new InfiniteCorner(this.verticalLineEnd) + } + public addVerticalDimension(verticalSide: Dimension): Rect{ + return verticalSide.addEntireHorizontalDimension(this) + } + public addEntireHorizontalDimension(horizontal: Dimension): Rect{ + return new PlaneRect(horizontal, this); + } + public addHorizontalDimensionAtInfinity(horizontal: Dimension): Rect{ + return new UndrawableRectangle(horizontal, this); + } + public addHorizontalDimensionWithStart(horizontal: WithStart): Rect{ + const topLeft = this.createTopLeftAtVerticalInfinity(horizontal) + const right = this.createRightAtInfinity(horizontal) + const bottom = this.createBottomAtInfinity() + return new RectWithLeft(horizontal, topLeft, right, bottom); + } + public addHorizontalDimensionWithStartAndEnd(horizontal: WithStartAndEnd): Rect{ + const topLeft = this.createTopLeftAtVerticalInfinity(horizontal) + const bottomRight = this.createBottomRightAtInfinity(horizontal) + return new RectWithLeftAndRight(horizontal, topLeft, bottomRight) + } +} + +class DimensionAtInfinity extends LineImpl implements Dimension{ + + public addVerticalDimension(verticalSide: Dimension): Rect{ + return verticalSide.addHorizontalDimensionAtInfinity(this) + } + public addEntireHorizontalDimension(horizontal: Dimension): Rect{ + return new UndrawableRectangle(horizontal, this); + } + public addHorizontalDimensionAtInfinity(horizontal: Dimension): Rect{ + return new UndrawableRectangle(horizontal, this); + } + public addHorizontalDimensionWithStart(): Rect{ + return new RectAtInfinity(this.verticalLineEnd) + } + public addHorizontalDimensionWithStartAndEnd(): Rect{ + return new RectAtInfinity(this.verticalLineEnd) + } +} + +class WithStartImpl extends LineImpl implements WithStart{ + constructor( + orientation: EdgeOrientation, + public readonly finiteStart: number){ + super(finiteStart, orientation) + } + private createBottomLeftAtInfinity(horizontal: Dimension): Corner{ + return new InfiniteCorner(horizontal.horizontalLineStart) + } + protected createLeftAtInfinity(horizontal: Dimension): TopLeftCorner{ + return new InfiniteTopLeftCorner(horizontal.horizontalLineStart) + } + protected createTopRightAtHorizontalInfinity(horizontal: Dimension): Corner{ + return new InfiniteCornerFromInfinityToInfinity(new Point(0, this.finiteStart), horizontal.horizontalLineEnd); + } + protected createTopLeft(horizontal: WithStart): VisibleTopLeftCorner{ + return new VisibleTopLeftCornerImpl( + new Point(horizontal.finiteStart, this.finiteStart), + CornerOrientation.TOPLEFT, + horizontal.orientation, + this.orientation) + } + protected createTopRight(horizontal: WithStartAndEnd): VisibleCorner{ + return new VisibleCornerImpl( + new Point(horizontal.end, this.finiteStart), + CornerOrientation.TOPRIGHT, + horizontal.orientation, + this.orientation) + } + protected getStartingHalfPlaneWithHorizontalCrossSection(): HalfPlane { + const normal = this.orientation === EdgeOrientation.Positive ? new Point(1, 0) : new Point(-1, 0) + const base = new Point(this.finiteStart, 0) + return new HalfPlane(base, normal) + } + protected getStartingHalfPlaneWithVerticalCrossSection(): HalfPlane { + const normal = this.orientation === EdgeOrientation.Positive ? new Point(0, 1) : new Point(0, -1) + const base = new Point(0, this.finiteStart) + return new HalfPlane(base, normal) + } + public addVerticalDimension(verticalSide: Dimension): Rect{ + return verticalSide.addHorizontalDimensionWithStart(this) + } + public addEntireHorizontalDimension(horizontal: Dimension): Rect{ + const left = this.createLeftAtInfinity(horizontal) + const topRight = this.createTopRightAtHorizontalInfinity(horizontal) + const bottomRight = this.createBottomAtInfinity() + const bottomLeft = this.createBottomLeftAtInfinity(horizontal) + return new RectWithTop(this, left, topRight, bottomRight, bottomLeft); + } + public addHorizontalDimensionAtInfinity(horizontal: Dimension): Rect{ + return new RectAtInfinity(horizontal.horizontalLineEnd) + } + public addHorizontalDimensionWithStart(horizontal: WithStart): Rect{ + const right = this.createRightAtInfinity(horizontal) + const bottom = this.createBottomAtInfinity() + const topLeft = this.createTopLeft(horizontal) + return new RectWithTopAndLeft(horizontal, this, topLeft, right, bottom); + } + public addHorizontalDimensionWithStartAndEnd(horizontal: WithStartAndEnd): Rect{ + const bottom = this.createBottomAtInfinity() + const finiteTopLeft = this.createTopLeft(horizontal) + const topRight = this.createTopRight(horizontal) + return new RectWithTopAndLeftAndRight(horizontal, this, finiteTopLeft, topRight, bottom); + } + public getHalfPlanesWithHorizontalCrossSection(): HalfPlane[] { + return [this.getStartingHalfPlaneWithHorizontalCrossSection()] + } + public getHalfPlanesWithVerticalCrossSection(): HalfPlane[] { + return [this.getStartingHalfPlaneWithVerticalCrossSection()] + } +} + +class RectSideWithStartAndEndImpl extends WithStartImpl implements WithStartAndEnd{ + constructor( + orientation: EdgeOrientation, + start: number, + public readonly end: number){ + super(orientation, start) + } + private createBottomLeftAtHorizontalInfinity(horizontal: Dimension): Corner{ + return new InfiniteCornerFromInfinityToInfinity(new Point(0, this.end), horizontal.horizontalLineStart); + } + private getEndingHalfPlaneWithHorizontalCrossSection(): HalfPlane { + const normal = this.orientation === EdgeOrientation.Positive ? new Point(-1, 0) : new Point(1, 0) + const base = new Point(this.end, 0) + return new HalfPlane(base, normal) + } + private getEndingHalfPlaneWithVerticalCrossSection(): HalfPlane { + const normal = this.orientation === EdgeOrientation.Positive ? new Point(0, -1) : new Point(0, 1) + const base = new Point(0, this.end) + return new HalfPlane(base, normal) + } + private createBottomLeft(horizontal: WithStart): VisibleCorner{ + return new VisibleCornerImpl( + new Point(horizontal.finiteStart, this.end), + CornerOrientation.BOTTOMLEFT, + horizontal.orientation, + this.orientation) + } + private createBottomRight(horizontal: WithStartAndEnd): VisibleCorner{ + return new VisibleCornerImpl( + new Point(horizontal.end, this.end), + CornerOrientation.BOTTOMRIGHT, + horizontal.orientation, + this.orientation) + } + public getLength(): number{ + return Math.abs(this.end - this.finiteStart) + } + public addEntireHorizontalDimension(horizontal: Dimension): Rect{ + const left = this.createLeftAtInfinity(horizontal) + const topRight = this.createTopRightAtHorizontalInfinity(horizontal) + const bottomLeft = this.createBottomLeftAtHorizontalInfinity(horizontal) + return new RectWithTopAndBottom(this, left, topRight, bottomLeft) + } + public addHorizontalDimensionAtInfinity(horizontal: Dimension): Rect{ + return new RectAtInfinity(horizontal.horizontalLineEnd) + } + public addVerticalDimension(verticalSide: Dimension): Rect{ + return verticalSide.addHorizontalDimensionWithStartAndEnd(this) + } + public addHorizontalDimensionWithStart(horizontal: WithStart): Rect{ + const right = this.createRightAtInfinity(horizontal) + const finiteTopLeft = this.createTopLeft(horizontal) + const bottomLeft = this.createBottomLeft(horizontal) + return new RectWithTopAndLeftAndBottom(this, horizontal, finiteTopLeft, right, bottomLeft); + } + public addHorizontalDimensionWithStartAndEnd(horizontal: WithStartAndEnd): RectWithFourEdges{ + const topLeft = this.createTopLeft(horizontal) + const topRight = this.createTopRight(horizontal) + const bottomLeft = this.createBottomLeft(horizontal) + const bottomRight = this.createBottomRight(horizontal) + return new RectWithFourEdgesImpl( + this, + horizontal, + topLeft, + topRight, + bottomRight, + bottomLeft + ); + } + public getHalfPlanesWithHorizontalCrossSection(): HalfPlane[] { + return [ + this.getStartingHalfPlaneWithHorizontalCrossSection(), + this.getEndingHalfPlaneWithHorizontalCrossSection() + ] + } + public getHalfPlanesWithVerticalCrossSection(): HalfPlane[] { + return [ + this.getStartingHalfPlaneWithVerticalCrossSection(), + this.getEndingHalfPlaneWithVerticalCrossSection() + ] + } +} + +export function getWithStartAndEnd(start: number, length: number): WithStartAndEnd{ + const orientation = length > 0 ? EdgeOrientation.Positive : EdgeOrientation.Negative; + return new RectSideWithStartAndEndImpl(orientation, start, start + length) +} + +export function getDimension(start: number, length: number): Dimension{ + const orientation = length > 0 ? EdgeOrientation.Positive : EdgeOrientation.Negative; + const line = new LineImpl(start, orientation) + if(Number.isFinite(start)){ + if(Number.isFinite(length)){ + return new RectSideWithStartAndEndImpl(orientation, start, start + length) + } + return new WithStartImpl(orientation, start); + } + if(Number.isFinite(length)){ + if(start < 0){ + return new DimensionAtInfinity(start, EdgeOrientation.Negative) + } + return new DimensionAtInfinity(start, EdgeOrientation.Positive) + } + if(start > 0){ + if(orientation === EdgeOrientation.Positive){ + return new DimensionAtInfinity(start, EdgeOrientation.Positive) + } + return line + } + if(orientation === EdgeOrientation.Positive){ + return line + } + return new DimensionAtInfinity(start, EdgeOrientation.Negative) +} \ No newline at end of file diff --git a/src/rect/dimension.ts b/src/rect/dimension.ts new file mode 100644 index 00000000..f0ccfdeb --- /dev/null +++ b/src/rect/dimension.ts @@ -0,0 +1,30 @@ +import { HalfPlane } from "../areas/polygons/half-plane" +import { PointAtInfinity } from "../geometry/point-at-infinity" +import { EdgeOrientation } from "./edge-orientation" +import { Rect, RectWithFourEdges } from "./rect" + +export interface Dimension{ + start: number + orientation: EdgeOrientation + horizontalLineEnd: PointAtInfinity + horizontalLineStart: PointAtInfinity + verticalLineEnd: PointAtInfinity + verticalLineStart: PointAtInfinity + addVerticalDimension(vertical: Dimension): Rect + addEntireHorizontalDimension(horizontal: Dimension): Rect + addHorizontalDimensionAtInfinity(horizontal: Dimension): Rect + addHorizontalDimensionWithStart(horizontal: WithStart): Rect + addHorizontalDimensionWithStartAndEnd(horizontal: WithStartAndEnd): Rect +} + +export interface WithStart extends Dimension{ + finiteStart: number + getHalfPlanesWithHorizontalCrossSection(): HalfPlane[] + getHalfPlanesWithVerticalCrossSection(): HalfPlane[] +} + +export interface WithStartAndEnd extends WithStart{ + end: number + getLength(): number + addHorizontalDimensionWithStartAndEnd(horizontal: WithStartAndEnd): RectWithFourEdges +} \ No newline at end of file diff --git a/src/rect/edge-orientation.ts b/src/rect/edge-orientation.ts new file mode 100644 index 00000000..2d6aea5f --- /dev/null +++ b/src/rect/edge-orientation.ts @@ -0,0 +1 @@ +export enum EdgeOrientation { Positive, Negative } \ No newline at end of file diff --git a/src/rect/get-rect-strategy.ts b/src/rect/get-rect-strategy.ts new file mode 100644 index 00000000..b550745b --- /dev/null +++ b/src/rect/get-rect-strategy.ts @@ -0,0 +1,14 @@ +import { getDimension, getWithStartAndEnd } from "./dimension-impl"; +import { Rect, RectWithFourEdges } from './rect' + +export function getRectStrategy(x: number, y: number, w: number, h: number): Rect{ + const horizontalSide = getDimension(x, w) + const verticalSide = getDimension(y, h) + return horizontalSide.addVerticalDimension(verticalSide) +} + +export function getRectWithFourEdges(x: number, y: number, w: number, h: number): RectWithFourEdges{ + const horizontalSide = getWithStartAndEnd(x, w) + const verticalSide = getWithStartAndEnd(y, h) + return verticalSide.addHorizontalDimensionWithStartAndEnd(horizontalSide); +} \ No newline at end of file diff --git a/src/rect/rect-strategies/plane-rect.ts b/src/rect/rect-strategies/plane-rect.ts new file mode 100644 index 00000000..c1b4ed81 --- /dev/null +++ b/src/rect/rect-strategies/plane-rect.ts @@ -0,0 +1,35 @@ +import { Area } from "../../areas/area"; +import { plane } from "../../areas/plane"; +import { DrawingInstruction } from "../../drawing-instruction"; +import { Instruction } from "../../instructions/instruction"; +import { pathAroundViewbox } from "../../instructions/path-around-viewbox"; +import { InfiniteCanvasState } from "../../state/infinite-canvas-state"; +import { Dimension } from "../dimension"; +import { Rect, Shape } from '../rect' +import { throwNoTopLeftLocationError } from "./top-left-location-error"; + +export class PlaneRect implements Rect{ + constructor( + private readonly horizontal: Dimension, + private readonly vertical: Dimension + ){ + + } + public addSubpaths(): void{ + throwNoTopLeftLocationError(this.horizontal, this.vertical) + } + public getRoundRect(): Shape{ + return this; + } + public getArea(): Area { + return plane; + } + public stroke(): DrawingInstruction{ + return undefined; + } + public fill(state: InfiniteCanvasState, instruction: Instruction): DrawingInstruction{ + return DrawingInstruction.forFillingPath(instruction, state, () => { + return pathAroundViewbox + }) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-at-infinity.ts b/src/rect/rect-strategies/rect-at-infinity.ts new file mode 100644 index 00000000..e4a35c91 --- /dev/null +++ b/src/rect/rect-strategies/rect-at-infinity.ts @@ -0,0 +1,25 @@ +import { Area } from "../../areas/area"; +import { DrawingInstruction } from "../../drawing-instruction"; +import { PointAtInfinity } from "../../geometry/point-at-infinity"; +import { CurrentPath } from "../../interfaces/current-path"; +import { InfiniteCanvasState } from "../../state/infinite-canvas-state"; +import { Rect, Shape } from '../rect' + +export class RectAtInfinity implements Rect{ + constructor(private readonly topLeftPosition: PointAtInfinity){} + public addSubpaths(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + currentPath.moveTo(this.topLeftPosition, state); + } + public getRoundRect(): Shape{ + return this; + } + public getArea(): Area { + return undefined; + } + public stroke(): DrawingInstruction{ + return undefined; + } + public fill(): DrawingInstruction{ + return undefined; + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-like-shape.ts b/src/rect/rect-strategies/rect-like-shape.ts new file mode 100644 index 00000000..c07daedb --- /dev/null +++ b/src/rect/rect-strategies/rect-like-shape.ts @@ -0,0 +1,38 @@ +import { DrawingInstruction } from "../../drawing-instruction"; +import { Instruction } from "../../instructions/instruction"; +import { InstructionsWithPath } from "../../instructions/instructions-with-path"; +import { CurrentPath } from "../../interfaces/current-path"; +import { InfiniteCanvasState } from "../../state/infinite-canvas-state"; +import { Corner, TopLeftCorner } from "../corners/corner-strategy"; +import { Shape } from "../rect"; + +export class RectLikeShape implements Shape{ + private readonly corners: Corner[] + constructor( + private readonly topLeftCorner: TopLeftCorner, + ...corners: Corner[] + ){ + this.corners = corners; + } + public addSubpaths(currentPath: CurrentPath, state: InfiniteCanvasState): void{ + this.topLeftCorner.moveToEndingPoint(currentPath, state) + for(const corner of this.corners){ + corner.draw(currentPath, state) + } + this.topLeftCorner.finishRect(currentPath, state) + } + public stroke(state: InfiniteCanvasState, instruction: Instruction): DrawingInstruction{ + return DrawingInstruction.forStrokingPath(instruction, state, (_state) => { + const result = InstructionsWithPath.create(_state); + this.addSubpaths(result, _state) + return result; + }) + } + public fill(state: InfiniteCanvasState, instruction: Instruction): DrawingInstruction{ + return DrawingInstruction.forFillingPath(instruction, state, (_state) => { + const result = InstructionsWithPath.create(_state); + this.addSubpaths(result, _state) + return result; + }) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-four-edges.ts b/src/rect/rect-strategies/rect-with-four-edges.ts new file mode 100644 index 00000000..53d6fbd2 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-four-edges.ts @@ -0,0 +1,47 @@ +import { RectWithFourEdges, Shape } from '../rect' +import { CornerRadii, scaleCornerRadii } from "../corner-radii"; +import { VisibleCorner, VisibleTopLeftCorner } from "../corners/corner-strategy"; +import { WithStartAndEnd } from "../dimension"; +import { RectLikeShape } from "./rect-like-shape"; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; + +export class RectWithFourEdgesImpl extends RectLikeShape implements RectWithFourEdges{ + constructor( + private readonly vertical: WithStartAndEnd, + private readonly horizontal: WithStartAndEnd, + private readonly topLeft: VisibleTopLeftCorner, + private readonly topRight: VisibleCorner, + private readonly bottomRight: VisibleCorner, + private readonly bottomLeft: VisibleCorner){ + super(topLeft, topRight, bottomRight, bottomLeft) + } + public getRoundRect(cornerRadii: CornerRadii): Shape{ + const leftSideLength = this.vertical.getLength(); + const topSideLength = this.horizontal.getLength() + const minRatio = Math.min( + leftSideLength / (cornerRadii.upperLeft.y + cornerRadii.lowerLeft.y), + leftSideLength / (cornerRadii.upperRight.y + cornerRadii.lowerRight.y), + topSideLength / (cornerRadii.upperLeft.x + cornerRadii.upperRight.x), + topSideLength / (cornerRadii.lowerLeft.x + cornerRadii.lowerRight.x) + ) + if(minRatio < 1){ + cornerRadii = scaleCornerRadii(cornerRadii, minRatio) + } + const bottomRightCorner = this.bottomRight.round(cornerRadii.lowerRight) + const topLeftCorner = this.topLeft.round(cornerRadii.upperLeft) + const topRightCorner = this.topRight.round(cornerRadii.upperRight) + const bottomLeftCorner = this.bottomLeft.round(cornerRadii.lowerLeft) + return new RectLikeShape( + topLeftCorner, + topRightCorner, + bottomRightCorner, + bottomLeftCorner + ) + } + public getArea(): ConvexPolygon { + return new ConvexPolygon([ + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection(), + ...this.vertical.getHalfPlanesWithVerticalCrossSection() + ]) + } +} diff --git a/src/rect/rect-strategies/rect-with-left-and-right.ts b/src/rect/rect-strategies/rect-with-left-and-right.ts new file mode 100644 index 00000000..a195564b --- /dev/null +++ b/src/rect/rect-strategies/rect-with-left-and-right.ts @@ -0,0 +1,24 @@ +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; +import { Corner, TopLeftCorner } from '../corners/corner-strategy'; +import { WithStartAndEnd } from '../dimension'; +import { Rect, Shape } from '../rect' +import { RectLikeShape } from "./rect-like-shape"; + +export class RectWithLeftAndRight extends RectLikeShape implements Rect{ + constructor( + private readonly horizontal: WithStartAndEnd, + topLeftCorner: TopLeftCorner, + ...corners: Corner[] + ){ + super(topLeftCorner, ...corners) + } + + public getRoundRect(): Shape{ + return this; + } + + public getArea(): Area { + return new ConvexPolygon(this.horizontal.getHalfPlanesWithHorizontalCrossSection()) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-left.ts b/src/rect/rect-strategies/rect-with-left.ts new file mode 100644 index 00000000..c4afa4b5 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-left.ts @@ -0,0 +1,25 @@ +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; +import { Corner, TopLeftCorner } from '../corners/corner-strategy'; +import { WithStart } from '../dimension'; +import { Rect, Shape } from '../rect' +import { RectLikeShape } from "./rect-like-shape"; + +export class RectWithLeft extends RectLikeShape implements Rect{ + + constructor( + private readonly horizontal: WithStart, + topLeftCorner: TopLeftCorner, + ...corners: Corner[] + ){ + super(topLeftCorner, ...corners) + } + + public getRoundRect(): Shape{ + return this; + } + + public getArea(): Area { + return new ConvexPolygon(this.horizontal.getHalfPlanesWithHorizontalCrossSection()) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-top-and-bottom.ts b/src/rect/rect-strategies/rect-with-top-and-bottom.ts new file mode 100644 index 00000000..a3248e74 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-top-and-bottom.ts @@ -0,0 +1,25 @@ +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; +import { Corner, TopLeftCorner } from '../corners/corner-strategy'; +import { WithStartAndEnd } from '../dimension'; +import { Rect, Shape } from '../rect' +import { RectLikeShape } from "./rect-like-shape"; + +export class RectWithTopAndBottom extends RectLikeShape implements Rect{ + + constructor( + private readonly vertical: WithStartAndEnd, + topLeftCorner: TopLeftCorner, + ...corners: Corner[] + ){ + super(topLeftCorner, ...corners) + } + + public getRoundRect(): Shape{ + return this; + } + + public getArea(): Area { + return new ConvexPolygon(this.vertical.getHalfPlanesWithVerticalCrossSection()) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-top-and-left-and-bottom.ts b/src/rect/rect-strategies/rect-with-top-and-left-and-bottom.ts new file mode 100644 index 00000000..87ffc5f5 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-top-and-left-and-bottom.ts @@ -0,0 +1,40 @@ +import { Rect, Shape } from '../rect' +import { CornerRadii, scaleCornerRadii } from "../corner-radii"; +import { Corner, VisibleCorner, VisibleTopLeftCorner } from "../corners/corner-strategy"; +import { WithStart, WithStartAndEnd } from "../dimension"; +import { RectLikeShape } from "./rect-like-shape"; +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; + +export class RectWithTopAndLeftAndBottom extends RectLikeShape implements Rect{ + constructor( + private readonly vertical: WithStartAndEnd, + private readonly horizontal: WithStart, + private readonly topLeft: VisibleTopLeftCorner, + private readonly right: Corner, + private readonly bottomLeftCorner: VisibleCorner){ + super(topLeft, right, bottomLeftCorner) + } + public getRoundRect(cornerRadii: CornerRadii): Shape{ + const leftSideLength = this.vertical.getLength() + const cornerRadiiSum = cornerRadii.upperLeft.y + cornerRadii.lowerLeft.y; + const ratio = leftSideLength / cornerRadiiSum; + if(ratio < 1){ + cornerRadii = scaleCornerRadii(cornerRadii, ratio) + } + const topLeftRoundCorner = this.topLeft.round(cornerRadii.upperLeft) + const bottomLeftCorner = this.bottomLeftCorner.round(cornerRadii.lowerLeft) + return new RectLikeShape( + topLeftRoundCorner, + this.right, + bottomLeftCorner + ) + } + + public getArea(): Area { + return new ConvexPolygon([ + ...this.vertical.getHalfPlanesWithVerticalCrossSection(), + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection() + ]) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-top-and-left-and-right.ts b/src/rect/rect-strategies/rect-with-top-and-left-and-right.ts new file mode 100644 index 00000000..4d959ea9 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-top-and-left-and-right.ts @@ -0,0 +1,41 @@ +import { Rect, Shape } from '../rect' +import { CornerRadii, scaleCornerRadii } from "../corner-radii"; +import { Corner, VisibleCorner, VisibleTopLeftCorner } from "../corners/corner-strategy"; +import { WithStart, WithStartAndEnd } from "../dimension"; +import { RectLikeShape } from "./rect-like-shape"; +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; + +export class RectWithTopAndLeftAndRight extends RectLikeShape implements Rect{ + constructor( + private readonly horizontal: WithStartAndEnd, + private readonly vertical: WithStart, + private readonly topLeft: VisibleTopLeftCorner, + private readonly topRightCorner: VisibleCorner, + private readonly bottom: Corner + ){ + super(topLeft, topRightCorner, bottom) + } + public getRoundRect(cornerRadii: CornerRadii): Shape{ + const topSideLength = this.horizontal.getLength() + const cornerRadiiSum = cornerRadii.upperLeft.x + cornerRadii.upperRight.x; + const ratio = topSideLength / cornerRadiiSum; + if(ratio < 1){ + cornerRadii = scaleCornerRadii(cornerRadii, ratio) + } + const topRightCorner = this.topRightCorner.round(cornerRadii.upperRight) + const topLeftCorner = this.topLeft.round(cornerRadii.upperLeft) + return new RectLikeShape( + topLeftCorner, + topRightCorner, + this.bottom + ) + } + + public getArea(): Area { + return new ConvexPolygon([ + ...this.vertical.getHalfPlanesWithVerticalCrossSection(), + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection() + ]) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-top-and-left.ts b/src/rect/rect-strategies/rect-with-top-and-left.ts new file mode 100644 index 00000000..db545162 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-top-and-left.ts @@ -0,0 +1,33 @@ +import { Rect, Shape } from '../rect' +import { CornerRadii } from "../corner-radii"; +import { Corner, VisibleTopLeftCorner } from "../corners/corner-strategy"; +import { RectLikeShape } from "./rect-like-shape"; +import { WithStart } from '../dimension'; +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; + +export class RectWithTopAndLeft extends RectLikeShape implements Rect{ + constructor( + private readonly horizontal: WithStart, + private readonly vertical: WithStart, + private readonly topLeft: VisibleTopLeftCorner, + private readonly right: Corner, + private readonly bottom: Corner){ + super(topLeft, right, bottom) + } + public getRoundRect(cornerRadii: CornerRadii): Shape{ + const roundCorner = this.topLeft.round(cornerRadii.upperLeft) + return new RectLikeShape( + roundCorner, + this.right, + this.bottom + ) + } + + public getArea(): Area { + return new ConvexPolygon([ + ...this.vertical.getHalfPlanesWithVerticalCrossSection(), + ...this.horizontal.getHalfPlanesWithHorizontalCrossSection() + ]) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/rect-with-top.ts b/src/rect/rect-strategies/rect-with-top.ts new file mode 100644 index 00000000..7cfd5c98 --- /dev/null +++ b/src/rect/rect-strategies/rect-with-top.ts @@ -0,0 +1,25 @@ +import { Area } from '../../areas/area'; +import { ConvexPolygon } from '../../areas/polygons/convex-polygon'; +import { Corner, TopLeftCorner } from '../corners/corner-strategy'; +import { WithStart } from '../dimension'; +import { Rect, Shape } from '../rect' +import { RectLikeShape } from "./rect-like-shape"; + +export class RectWithTop extends RectLikeShape implements Rect{ + + constructor( + private readonly vertical: WithStart, + topLeftCorner: TopLeftCorner, + ...corners: Corner[] + ){ + super(topLeftCorner, ...corners) + } + + public getRoundRect(): Shape{ + return this; + } + + public getArea(): Area { + return new ConvexPolygon(this.vertical.getHalfPlanesWithVerticalCrossSection()) + } +} \ No newline at end of file diff --git a/src/rect/rect-strategies/top-left-location-error.ts b/src/rect/rect-strategies/top-left-location-error.ts new file mode 100644 index 00000000..01748e65 --- /dev/null +++ b/src/rect/rect-strategies/top-left-location-error.ts @@ -0,0 +1,8 @@ +import { Dimension } from "../dimension"; + +export function throwNoTopLeftLocationError( + horizontal: Dimension, + vertical: Dimension +): never{ + throw new Error(`The starting coordinates provided (${horizontal.start} and ${vertical.start}) do not determine a direction.`) +} \ No newline at end of file diff --git a/src/rect/rect-strategies/undrawable-rectangle.ts b/src/rect/rect-strategies/undrawable-rectangle.ts new file mode 100644 index 00000000..b07c667f --- /dev/null +++ b/src/rect/rect-strategies/undrawable-rectangle.ts @@ -0,0 +1,30 @@ +import { Area } from '../../areas/area'; +import { DrawingInstruction } from '../../drawing-instruction'; +import { Dimension } from '../dimension'; +import { Rect, Shape } from '../rect' +import { throwNoTopLeftLocationError } from './top-left-location-error'; + +export class UndrawableRectangle implements Rect{ + constructor( + private readonly horizontal: Dimension, + private readonly vertical: Dimension + ){ + + } + public addSubpaths(): void{ + throwNoTopLeftLocationError(this.horizontal, this.vertical) + } + public getRoundRect(): Shape{ + return this; + } + + public getArea(): Area { + return undefined; + } + public stroke(): DrawingInstruction{ + return undefined; + } + public fill(): DrawingInstruction{ + return undefined; + } +} \ No newline at end of file diff --git a/src/rect/rect.ts b/src/rect/rect.ts new file mode 100644 index 00000000..5f97ff54 --- /dev/null +++ b/src/rect/rect.ts @@ -0,0 +1,22 @@ +import { Area } from "../areas/area" +import { ConvexPolygon } from "../areas/polygons/convex-polygon" +import { DrawingInstruction } from "../drawing-instruction" +import { Instruction } from "../instructions/instruction" +import { CurrentPath } from "../interfaces/current-path" +import { InfiniteCanvasState } from "../state/infinite-canvas-state" +import { CornerRadii } from "./corner-radii" + +export interface Shape { + addSubpaths(currentPath: CurrentPath, state: InfiniteCanvasState): void + stroke(state: InfiniteCanvasState, instruction: Instruction): DrawingInstruction + fill(state: InfiniteCanvasState, instruction: Instruction): DrawingInstruction +} + +export interface Rect extends Shape{ + getRoundRect(cornerRadii: CornerRadii): Shape + getArea(): Area | undefined +} + +export interface RectWithFourEdges extends Rect{ + getArea(): ConvexPolygon +} \ No newline at end of file diff --git a/src/rect/round-rect.ts b/src/rect/round-rect.ts new file mode 100644 index 00000000..405e0108 --- /dev/null +++ b/src/rect/round-rect.ts @@ -0,0 +1,22 @@ +import { CurrentPath } from "../interfaces/current-path"; +import { InfiniteCanvasState } from "../state/infinite-canvas-state"; +import { getCornerRadii } from "./corner-radii"; +import { Rect } from "./rect"; + +export function roundRect( + currentPath: CurrentPath, + rectStrategy: Rect, + radii: number | DOMPointInit | Iterable | undefined, + state: InfiniteCanvasState +): void{ + if(radii === undefined){ + rectStrategy.addSubpaths(currentPath, state); + return; + } + let cornerRadii = getCornerRadii(radii); + if(!cornerRadii){ + return; + } + const roundRectStrategy = rectStrategy.getRoundRect(cornerRadii); + roundRectStrategy.addSubpaths(currentPath, state) +} \ No newline at end of file diff --git a/src/rectangle/canvas-rectangle-impl.ts b/src/rectangle/canvas-rectangle-impl.ts index f74e08e7..04a80309 100644 --- a/src/rectangle/canvas-rectangle-impl.ts +++ b/src/rectangle/canvas-rectangle-impl.ts @@ -7,6 +7,7 @@ import { TransformationRepresentation } from "../api-surface/transformation-repr import { Transformation } from "../transformation"; import { Units } from "../api-surface/units"; import { CoordinateSystem } from './coordinate-system'; +import { getRectWithFourEdges } from '../rect/get-rect-strategy'; function measurementsAreOfEqualSize(one: CanvasMeasurement, other: CanvasMeasurement): boolean{ if(!one){ @@ -49,7 +50,7 @@ export class CanvasRectangleImpl implements CanvasRectangle{ return this; } const {viewboxWidth, viewboxHeight} = measurement; - const polygon = ConvexPolygon.createRectangle(0, 0, viewboxWidth, viewboxHeight); + const polygon = getRectWithFourEdges(0, 0, viewboxWidth, viewboxHeight).getArea(); const coordinatesSwitch = this.coordinates.withCanvasMeasurement(measurement); return new CanvasRectangleImpl(coordinatesSwitch, measurement, polygon) } @@ -86,7 +87,7 @@ export class CanvasRectangleImpl implements CanvasRectangle{ public static create(measurement: CanvasMeasurement, units: Units): CanvasRectangleImpl{ const {viewboxWidth, viewboxHeight} = measurement; - const polygon = ConvexPolygon.createRectangle(0, 0, viewboxWidth, viewboxHeight); + const polygon = getRectWithFourEdges(0, 0, viewboxWidth, viewboxHeight).getArea(); const coordinates = CoordinatesSwitch.create(units, measurement); return new CanvasRectangleImpl(coordinates, measurement, polygon) } diff --git a/src/state/dimensions/font-kerning.ts b/src/state/dimensions/font-kerning.ts new file mode 100644 index 00000000..8e63a1f4 --- /dev/null +++ b/src/state/dimensions/font-kerning.ts @@ -0,0 +1,14 @@ +import { MinimalInstruction, noopInstruction } from "../../instructions/instruction"; +import { InfiniteCanvasStateInstanceDimension } from "./infinite-canvas-state-instance-dimension"; +import { TypedStateInstanceDimension } from "./typed-state-instance-dimension"; + +class FontKerning extends InfiniteCanvasStateInstanceDimension<'fontKerning', MinimalInstruction>{ + protected valuesAreEqual(oldValue: CanvasFontKerning, newValue: CanvasFontKerning): boolean{ + return oldValue === newValue; + } + protected changeToNewValue(newValue: CanvasFontKerning): MinimalInstruction{ + return (ctx) => ctx.fontKerning = newValue; + } +} + +export const fontKerning: TypedStateInstanceDimension = new FontKerning('fontKerning', noopInstruction) \ No newline at end of file diff --git a/src/state/infinite-canvas-state-instance.ts b/src/state/infinite-canvas-state-instance.ts index 1d03657f..596a76ae 100644 --- a/src/state/infinite-canvas-state-instance.ts +++ b/src/state/infinite-canvas-state-instance.ts @@ -12,6 +12,7 @@ import { sequence } from "../instruction-utils"; export class InfiniteCanvasStateInstance implements StateInstanceProperties{ public readonly fillStyle: string | CanvasGradient | CanvasPattern; + public readonly fontKerning: CanvasFontKerning; public readonly lineWidth: number; public readonly lineDash: number[]; public readonly lineCap: CanvasLineCap; @@ -38,6 +39,7 @@ export class InfiniteCanvasStateInstance implements StateInstanceProperties{ props: StateInstanceProperties ){ this.fillStyle = props.fillStyle; + this.fontKerning = props.fontKerning; this.lineWidth = props.lineWidth; this.lineCap = props.lineCap; this.lineJoin = props.lineJoin; @@ -63,6 +65,7 @@ export class InfiniteCanvasStateInstance implements StateInstanceProperties{ } public changeProperty(property: K, newValue: StateInstanceProperties[K]): InfiniteCanvasStateInstance{ const {fillStyle, + fontKerning, lineWidth, lineDash, lineCap, @@ -87,6 +90,7 @@ export class InfiniteCanvasStateInstance implements StateInstanceProperties{ shadowBlur} = this; const newProps: StateInstanceProperties = { fillStyle, + fontKerning, lineWidth, lineDash, lineCap, @@ -167,6 +171,7 @@ export class InfiniteCanvasStateInstance implements StateInstanceProperties{ public static default: InfiniteCanvasStateInstance = new InfiniteCanvasStateInstance({ fillStyle: '#000', + fontKerning: 'auto', lineWidth: 1, lineDash: [], lineCap: 'butt', diff --git a/src/state/state-instance-properties.ts b/src/state/state-instance-properties.ts index 17afb63d..1382f466 100644 --- a/src/state/state-instance-properties.ts +++ b/src/state/state-instance-properties.ts @@ -5,6 +5,7 @@ import { TransformableFilter } from "./dimensions/transformable-filter"; export interface StateInstanceProperties { fillStyle: string | CanvasGradient | CanvasPattern; + fontKerning: CanvasFontKerning, lineWidth: number; lineCap: CanvasLineCap; lineJoin: CanvasLineJoin; diff --git a/test-e2e/__image_snapshots__/make-path-save-clip-fill-stroke.png b/test-e2e/__image_snapshots__/make-path-save-clip-fill-stroke.png new file mode 100644 index 00000000..caaca529 Binary files /dev/null and b/test-e2e/__image_snapshots__/make-path-save-clip-fill-stroke.png differ diff --git a/test-e2e/__image_snapshots__/round-rect.png b/test-e2e/__image_snapshots__/round-rect.png new file mode 100644 index 00000000..ad9abdd6 Binary files /dev/null and b/test-e2e/__image_snapshots__/round-rect.png differ diff --git a/test-e2e/resolve-test-cases.ts b/test-e2e/resolve-test-cases.ts index 786e3df3..d6ed369e 100644 --- a/test-e2e/resolve-test-cases.ts +++ b/test-e2e/resolve-test-cases.ts @@ -2,9 +2,9 @@ import fs from 'fs/promises' import { fileURLToPath } from 'url'; import type { PluginOption } from 'vite' -async function getTestCaseByPath(dirUrl: URL, id: string): Promise<{title: string, id: string, dependsOnEnvironments: string[] | undefined}>{ - const {default: {title, dependsOnEnvironments}} = await import(new URL(id, dirUrl).toString()) - return {id, title, dependsOnEnvironments}; +async function getTestCaseByPath(dirUrl: URL, id: string): Promise<{title: string, id: string, dependsOnEnvironments: string[] | undefined, skip?: boolean}>{ + const {default: {title, dependsOnEnvironments, skip}} = await import(new URL(id, dirUrl).toString()) + return {id, title, dependsOnEnvironments, skip}; } export function resolveTestCases(): PluginOption{ diff --git a/test-e2e/test-cases-1.spec.ts b/test-e2e/test-cases-1.spec.ts index 2903b500..3db596a8 100644 --- a/test-e2e/test-cases-1.spec.ts +++ b/test-e2e/test-cases-1.spec.ts @@ -15,9 +15,11 @@ describe('the test cases', () => { ({page, cleanup} = await getPageInBrowser(browser, '/test-case/')); }) - it.each(testCases)('$title', async ({id, dependsOnEnvironments}) => { - await page.evaluate((id) => window.TestCaseLib.drawTestCase(id), id) - expect(await getScreenshot(page)).toMatchImageSnapshotCustom({identifier: id.replace(/\.mjs$/,''), dependsOnEnvironments}) + describe.each(testCases)('$title', ({id, dependsOnEnvironments, skip}) => { + it.skipIf(skip)('', async () => { + await page.evaluate((id) => window.TestCaseLib.drawTestCase(id), id) + expect(await getScreenshot(page)).toMatchImageSnapshotCustom({identifier: id.replace(/\.mjs$/,''), dependsOnEnvironments}) + }) }) afterAll(async () => { diff --git a/test-e2e/test-cases-2.spec.ts b/test-e2e/test-cases-2.spec.ts index 8147f487..46d99ea0 100644 --- a/test-e2e/test-cases-2.spec.ts +++ b/test-e2e/test-cases-2.spec.ts @@ -15,9 +15,11 @@ describe('the test cases', () => { ({page, cleanup} = await getPageInBrowser(browser, '/test-case/')); }) - it.each(testCases)('$title', async ({id, dependsOnEnvironments}) => { - await page.evaluate((id) => window.TestCaseLib.drawTestCase(id), id) - expect(await getScreenshot(page)).toMatchImageSnapshotCustom({identifier: id.replace(/\.mjs$/,''), dependsOnEnvironments}) + describe.each(testCases)('$title', ({id, dependsOnEnvironments, skip}) => { + it.skipIf(skip)('', async () => { + await page.evaluate((id) => window.TestCaseLib.drawTestCase(id), id) + expect(await getScreenshot(page)).toMatchImageSnapshotCustom({identifier: id.replace(/\.mjs$/,''), dependsOnEnvironments}) + }) }) afterAll(async () => { diff --git a/test-e2e/test-cases-3.spec.ts b/test-e2e/test-cases-3.spec.ts index 33a3cb97..6052757e 100644 --- a/test-e2e/test-cases-3.spec.ts +++ b/test-e2e/test-cases-3.spec.ts @@ -15,9 +15,11 @@ describe('the test cases', () => { ({page, cleanup} = await getPageInBrowser(browser, '/test-case/')); }) - it.each(testCases)('$title', async ({id, dependsOnEnvironments}) => { - await page.evaluate((id) => window.TestCaseLib.drawTestCase(id), id) - expect(await getScreenshot(page)).toMatchImageSnapshotCustom({identifier: id.replace(/\.mjs$/,''), dependsOnEnvironments}) + describe.each(testCases)('$title', ({id, dependsOnEnvironments, skip}) => { + it.skipIf(skip)('', async () => { + await page.evaluate((id) => window.TestCaseLib.drawTestCase(id), id) + expect(await getScreenshot(page)).toMatchImageSnapshotCustom({identifier: id.replace(/\.mjs$/,''), dependsOnEnvironments}) + }) }) afterAll(async () => { diff --git a/test-e2e/test-cases.d.ts b/test-e2e/test-cases.d.ts index aa040883..3e535b5f 100644 --- a/test-e2e/test-cases.d.ts +++ b/test-e2e/test-cases.d.ts @@ -2,7 +2,8 @@ declare module 'virtual:test-cases-*' { export interface TestCase{ id: string title: string, - dependsOnEnvironments: string[] | undefined + dependsOnEnvironments: string[] | undefined, + skip?: boolean } const testCases: TestCase[]; export default testCases; diff --git a/test-e2e/test-cases/make-path-save-clip-fill-stroke.mjs b/test-e2e/test-cases/make-path-save-clip-fill-stroke.mjs new file mode 100644 index 00000000..38b188b6 --- /dev/null +++ b/test-e2e/test-cases/make-path-save-clip-fill-stroke.mjs @@ -0,0 +1,11 @@ +export default { + code: function(ctx){ + ctx.beginPath(); + ctx.rect(10, 10, 50, 50); + ctx.save(); + ctx.clip(); + ctx.fillRect(0, 0, 20, 20); + ctx.stroke(); + }, + title: "make a path, save state, clip, fill a rect and then stroke the path" +} \ No newline at end of file diff --git a/test-e2e/test-cases/round-rect.mjs b/test-e2e/test-cases/round-rect.mjs new file mode 100644 index 00000000..338b2c54 --- /dev/null +++ b/test-e2e/test-cases/round-rect.mjs @@ -0,0 +1,34 @@ +export default { + code: (ctx) => { + // Rounded rectangle with zero radius (specified as a number) + ctx.strokeStyle = "red"; + ctx.beginPath(); + ctx.roundRect(10, 20, 150, 100, 0); + ctx.stroke(); + + // Rounded rectangle with 40px radius (single element list) + ctx.strokeStyle = "blue"; + ctx.beginPath(); + ctx.roundRect(10, 20, 150, 100, [40]); + ctx.stroke(); + + // Rounded rectangle with 2 different radii + ctx.strokeStyle = "orange"; + ctx.beginPath(); + ctx.roundRect(10, 150, 150, 100, [10, 40]); + ctx.stroke(); + + // Rounded rectangle with four different radii + ctx.strokeStyle = "green"; + ctx.beginPath(); + ctx.roundRect(190, 20, 200, 100, [0, 30, 50, 60]); + ctx.stroke(); + + // Same rectangle drawn backwards + ctx.strokeStyle = "magenta"; + ctx.beginPath(); + ctx.roundRect(390, 150, -200, 100, [0, 30, 50, 60]); + ctx.stroke(); + }, + title: 'round rect' +} \ No newline at end of file diff --git a/test-unit/__snapshots__/infinite-canvas-viewbox.test.ts.snap b/test-unit/__snapshots__/infinite-canvas-viewbox.test.ts.snap index f5ec0256..b1f6f1fc 100644 --- a/test-unit/__snapshots__/infinite-canvas-viewbox.test.ts.snap +++ b/test-unit/__snapshots__/infinite-canvas-viewbox.test.ts.snap @@ -454,7 +454,6 @@ exports[`an infinite canvas context > fills a rect, begins a path, clips it and "context.lineTo(100,0)", "context.lineTo(100,100)", "context.lineTo(0,100)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -482,7 +481,6 @@ exports[`an infinite canvas context > fills a rect, begins a path, clips it and "context.lineTo(100,0)", "context.lineTo(100,100)", "context.lineTo(0,100)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -515,7 +513,6 @@ exports[`an infinite canvas context > fills a rect, begins a path, clips it and "context.lineTo(100,0)", "context.lineTo(100,100)", "context.lineTo(0,100)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -543,7 +540,6 @@ exports[`an infinite canvas context > fills a rect, begins a path, clips it and "context.lineTo(100,0)", "context.lineTo(100,100)", "context.lineTo(0,100)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -562,7 +558,6 @@ exports[`an infinite canvas context > fills a rect, begins a path, clips it and "context.lineTo(100,0)", "context.lineTo(100,100)", "context.lineTo(0,100)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -591,7 +586,6 @@ exports[`an infinite canvas context > saves, changes state, begins drawing a pat "context.lineTo(30,10)", "context.lineTo(30,30)", "context.lineTo(10,30)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.fill()", @@ -601,7 +595,6 @@ exports[`an infinite canvas context > saves, changes state, begins drawing a pat "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.restore()", @@ -622,7 +615,6 @@ exports[`an infinite canvas context > saves, changes state, begins drawing a pat "context.lineTo(30,10)", "context.lineTo(30,30)", "context.lineTo(10,30)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.fill()", @@ -634,7 +626,6 @@ exports[`an infinite canvas context > saves, changes state, begins drawing a pat "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.restore()", @@ -643,6 +634,356 @@ exports[`an infinite canvas context > saves, changes state, begins drawing a pat ] `; +exports[`an infinite canvas context > should have drawn round rect like this 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(104,100)", + "context.lineTo(104,100)", + "context.ellipse(104,108,16,8,0,4.71238898,0,false)", + "context.lineTo(120,116)", + "context.save()", + "context.transform(1,0,0,1,116,116)", + "context.arc(0,0,4,0,1.57079633,false)", + "context.restore()", + "context.lineTo(116,120)", + "context.ellipse(116,112,16,8,0,1.57079633,3.14159265,false)", + "context.lineTo(100,104)", + "context.save()", + "context.transform(1,0,0,1,104,104)", + "context.arc(0,0,4,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 2`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(115,100)", + "context.lineTo(115,100)", + "context.lineTo(115,100)", + "context.ellipse(115,130,60,30,0,4.71238898,0,false)", + "context.lineTo(175,130)", + "context.save()", + "context.transform(1,0,0,1,160,130)", + "context.arc(0,0,15,0,1.57079633,false)", + "context.restore()", + "context.lineTo(160,145)", + "context.ellipse(160,115,60,30,0,1.57079633,3.14159265,false)", + "context.lineTo(100,115)", + "context.save()", + "context.transform(1,0,0,1,115,115)", + "context.arc(0,0,15,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 3`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(115,100)", + "context.lineTo(140,100)", + "context.ellipse(140,130,60,30,0,4.71238898,0,false)", + "context.lineTo(200,185)", + "context.save()", + "context.transform(1,0,0,1,185,185)", + "context.arc(0,0,15,0,1.57079633,false)", + "context.restore()", + "context.lineTo(160,200)", + "context.ellipse(160,170,60,30,0,1.57079633,3.14159265,false)", + "context.lineTo(100,115)", + "context.save()", + "context.transform(1,0,0,1,115,115)", + "context.arc(0,0,15,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 4`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(106.66666667,100)", + "context.lineTo(201.41421356,100)", + "context.lineTo(201.41421356,120)", + "context.lineTo(126.66666667,120)", + "context.ellipse(126.66666667,106.66666667,26.66666667,13.33333333,0,1.57079633,3.14159265,false)", + "context.lineTo(100,106.66666667)", + "context.save()", + "context.transform(1,0,0,1,106.66666667,106.66666667)", + "context.arc(0,0,6.66666667,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 5`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(106.66666667,100)", + "context.lineTo(201.41421356,100)", + "context.lineTo(201.41421356,80)", + "context.lineTo(126.66666667,80)", + "context.ellipse(126.66666667,93.33333333,26.66666667,13.33333333,0,4.71238898,3.14159265,true)", + "context.lineTo(100,93.33333333)", + "context.save()", + "context.transform(1,0,0,1,106.66666667,93.33333333)", + "context.arc(0,0,6.66666667,3.14159265,1.57079633,true)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 6`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(93.33333333,100)", + "context.lineTo(-1.41421356,100)", + "context.lineTo(-1.41421356,120)", + "context.lineTo(73.33333333,120)", + "context.ellipse(73.33333333,106.66666667,26.66666667,13.33333333,0,1.57079633,0,true)", + "context.lineTo(100,106.66666667)", + "context.save()", + "context.transform(1,0,0,1,93.33333333,106.66666667)", + "context.arc(0,0,6.66666667,0,4.71238898,true)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 7`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(93.33333333,100)", + "context.lineTo(-1.41421356,100)", + "context.lineTo(-1.41421356,80)", + "context.lineTo(73.33333333,80)", + "context.ellipse(73.33333333,93.33333333,26.66666667,13.33333333,0,4.71238898,0,false)", + "context.lineTo(100,93.33333333)", + "context.save()", + "context.transform(1,0,0,1,93.33333333,93.33333333)", + "context.arc(0,0,6.66666667,0,1.57079633,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 8`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(104,100)", + "context.lineTo(104,100)", + "context.ellipse(104,108,16,8,0,4.71238898,0,false)", + "context.lineTo(120,201.41421356)", + "context.lineTo(104,201.41421356)", + "context.lineTo(100,201.41421356)", + "context.lineTo(100,104)", + "context.save()", + "context.transform(1,0,0,1,104,104)", + "context.arc(0,0,4,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 9`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(104,100)", + "context.lineTo(104,100)", + "context.ellipse(104,92,16,8,0,1.57079633,0,true)", + "context.lineTo(120,-1.41421356)", + "context.lineTo(104,-1.41421356)", + "context.lineTo(100,-1.41421356)", + "context.lineTo(100,96)", + "context.save()", + "context.transform(1,0,0,1,104,96)", + "context.arc(0,0,4,3.14159265,1.57079633,true)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 10`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(96,100)", + "context.lineTo(96,100)", + "context.ellipse(96,108,16,8,0,4.71238898,3.14159265,true)", + "context.lineTo(80,201.41421356)", + "context.lineTo(96,201.41421356)", + "context.lineTo(100,201.41421356)", + "context.lineTo(100,104)", + "context.save()", + "context.transform(1,0,0,1,96,104)", + "context.arc(0,0,4,0,4.71238898,true)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 11`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(96,100)", + "context.lineTo(96,100)", + "context.ellipse(96,92,16,8,0,1.57079633,3.14159265,false)", + "context.lineTo(80,-1.41421356)", + "context.lineTo(96,-1.41421356)", + "context.lineTo(100,-1.41421356)", + "context.lineTo(100,96)", + "context.save()", + "context.transform(1,0,0,1,96,96)", + "context.arc(0,0,4,0,1.57079633,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 12`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(115,100)", + "context.lineTo(201.41421356,100)", + "context.lineTo(201.41421356,201.41421356)", + "context.lineTo(115,201.41421356)", + "context.lineTo(100,201.41421356)", + "context.lineTo(100,115)", + "context.save()", + "context.transform(1,0,0,1,115,115)", + "context.arc(0,0,15,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 13`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(115,100)", + "context.lineTo(201.41421356,100)", + "context.lineTo(201.41421356,-1.41421356)", + "context.lineTo(115,-1.41421356)", + "context.lineTo(100,-1.41421356)", + "context.lineTo(100,85)", + "context.save()", + "context.transform(1,0,0,1,115,85)", + "context.arc(0,0,15,3.14159265,1.57079633,true)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 14`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(85,100)", + "context.lineTo(-1.41421356,100)", + "context.lineTo(-1.41421356,201.41421356)", + "context.lineTo(85,201.41421356)", + "context.lineTo(100,201.41421356)", + "context.lineTo(100,115)", + "context.save()", + "context.transform(1,0,0,1,85,115)", + "context.arc(0,0,15,0,4.71238898,true)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > should have drawn round rect like this 15`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(85,100)", + "context.lineTo(-1.41421356,100)", + "context.lineTo(-1.41421356,-1.41421356)", + "context.lineTo(85,-1.41421356)", + "context.lineTo(100,-1.41421356)", + "context.lineTo(100,85)", + "context.save()", + "context.transform(1,0,0,1,85,85)", + "context.arc(0,0,15,0,1.57079633,false)", + "context.restore()", + "context.moveTo(100,100)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + exports[`an infinite canvas context > that adds a drawing that depends on the transformation > and then draws using a non-identity transformation > should have set the transformed version of the state 1`] = ` [ "context.restore()", @@ -656,7 +997,6 @@ exports[`an infinite canvas context > that adds a drawing that depends on the tr "context.lineTo(20,0)", "context.lineTo(20,20)", "context.lineTo(0,20)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -684,7 +1024,6 @@ exports[`an infinite canvas context > that alters its state and draws a rectangl "context.lineTo(2,1)", "context.lineTo(2,2)", "context.lineTo(1,2)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -984,7 +1323,6 @@ exports[`an infinite canvas context > that begins path > and then builds it and "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1052,7 +1390,6 @@ exports[`an infinite canvas context > that begins path > and then changes state "context.lineTo(2,0)", "context.lineTo(2,2)", "context.lineTo(0,2)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1064,7 +1401,6 @@ exports[`an infinite canvas context > that begins path > and then changes state "context.lineTo(2,2)", "context.lineTo(2,4)", "context.lineTo(0,4)", - "context.lineTo(0,2)", "context.closePath()", "context.moveTo(0,2)", "context.lineWidth = 1", @@ -1084,7 +1420,6 @@ exports[`an infinite canvas context > that begins path > and then changes state "context.lineTo(2,0)", "context.lineTo(2,2)", "context.lineTo(0,2)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1102,7 +1437,6 @@ exports[`an infinite canvas context > that begins path > and then changes state, "context.lineTo(2,0)", "context.lineTo(2,2)", "context.lineTo(0,2)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 1", @@ -1144,7 +1478,6 @@ exports[`an infinite canvas context > that clips and then fills a rect outside t "context.lineTo(50,30)", "context.lineTo(50,50)", "context.lineTo(30,50)", - "context.lineTo(30,30)", "context.closePath()", "context.moveTo(30,30)", "context.clip()", @@ -1154,7 +1487,6 @@ exports[`an infinite canvas context > that clips and then fills a rect outside t "context.lineTo(45,35)", "context.lineTo(45,45)", "context.lineTo(35,45)", - "context.lineTo(35,35)", "context.closePath()", "context.moveTo(35,35)", "context.fill()", @@ -1192,7 +1524,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(9,1)", "context.lineTo(9,9)", "context.lineTo(1,9)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.clip()", @@ -1201,7 +1532,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(8,2)", "context.lineTo(8,8)", "context.lineTo(2,8)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -1211,7 +1541,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(6,5)", "context.lineTo(6,7)", "context.lineTo(5,7)", - "context.lineTo(5,5)", "context.closePath()", "context.moveTo(5,5)", "context.fill()", @@ -1228,7 +1557,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(9,1)", "context.lineTo(9,9)", "context.lineTo(1,9)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.clip()", @@ -1238,7 +1566,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(2,5)", "context.lineTo(2,7)", "context.lineTo(0,7)", - "context.lineTo(0,5)", "context.closePath()", "context.moveTo(0,5)", "context.fill()", @@ -1248,7 +1575,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(8,2)", "context.lineTo(8,8)", "context.lineTo(2,8)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -1258,7 +1584,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(6,5)", "context.lineTo(6,7)", "context.lineTo(5,7)", - "context.lineTo(5,5)", "context.closePath()", "context.moveTo(5,5)", "context.fill()", @@ -1275,7 +1600,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(9,1)", "context.lineTo(9,9)", "context.lineTo(1,9)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.clip()", @@ -1285,7 +1609,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(2,5)", "context.lineTo(2,7)", "context.lineTo(0,7)", - "context.lineTo(0,5)", "context.closePath()", "context.moveTo(0,5)", "context.fill()", @@ -1295,7 +1618,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(8,2)", "context.lineTo(8,8)", "context.lineTo(2,8)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -1305,7 +1627,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(9,5)", "context.lineTo(9,7)", "context.lineTo(7,7)", - "context.lineTo(7,5)", "context.closePath()", "context.moveTo(7,5)", "context.fill()", @@ -1314,7 +1635,6 @@ exports[`an infinite canvas context > that clips with a rect, fills a rect, clip "context.lineTo(6,5)", "context.lineTo(6,7)", "context.lineTo(5,7)", - "context.lineTo(5,5)", "context.closePath()", "context.moveTo(5,5)", "context.fill()", @@ -1420,7 +1740,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1438,7 +1757,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1450,7 +1768,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.fill()", @@ -1468,7 +1785,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1486,7 +1802,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1498,7 +1813,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.fill()", @@ -1516,7 +1830,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1528,7 +1841,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.fill()", @@ -1537,7 +1849,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.fill()", @@ -1555,7 +1866,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1567,7 +1877,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.fill()", @@ -1585,7 +1894,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1603,7 +1911,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1615,7 +1922,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.stroke()", @@ -1633,7 +1939,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1651,7 +1956,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1663,7 +1967,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.stroke()", @@ -1681,7 +1984,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1693,7 +1995,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.stroke()", @@ -1702,7 +2003,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.stroke()", @@ -1720,7 +2020,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1732,7 +2031,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.stroke()", @@ -1750,7 +2048,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1768,7 +2065,6 @@ exports[`an infinite canvas context > that creates a linear gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -1786,7 +2082,6 @@ exports[`an infinite canvas context > that creates a pattern > and then uses it "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.save()", @@ -1796,6 +2091,24 @@ exports[`an infinite canvas context > that creates a pattern > and then uses it ] `; +exports[`an infinite canvas context > that creates a pattern > and then uses it to fill the entire plane > should wrap the fill command in a transform 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.fillStyle = \\"[pattern-0]\\"", + "context.beginPath()", + "context.save()", + "context.setTransform(1,0,0,1,0,0)", + "context.rect(0,0,200,200)", + "context.restore()", + "context.save()", + "context.transform(1,0,0,1,0,0)", + "context.fill()", + "context.restore()", +] +`; + exports[`an infinite canvas context > that creates a radial gradient > and then creates a path > and then fills using the radial gradient > and then clears the drawing > and then fills the path again > should create a radial gradient again 1`] = ` [ "context.restore()", @@ -1895,7 +2208,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1913,7 +2225,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1925,7 +2236,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.fill()", @@ -1943,7 +2253,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1961,7 +2270,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -1973,7 +2281,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.fill()", @@ -1991,7 +2298,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -2003,7 +2309,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.fill()", @@ -2012,7 +2317,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.fill()", @@ -2030,7 +2334,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -2042,7 +2345,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.fill()", @@ -2060,7 +2362,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2078,7 +2379,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2090,7 +2390,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.stroke()", @@ -2108,7 +2407,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2126,7 +2424,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2138,7 +2435,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.stroke()", @@ -2156,7 +2452,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2168,7 +2463,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.stroke()", @@ -2177,7 +2471,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(60,0)", "context.lineTo(60,10)", "context.lineTo(50,10)", - "context.lineTo(50,0)", "context.closePath()", "context.moveTo(50,0)", "context.stroke()", @@ -2195,7 +2488,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2207,7 +2499,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(40,0)", "context.lineTo(40,10)", "context.lineTo(30,10)", - "context.lineTo(30,0)", "context.closePath()", "context.moveTo(30,0)", "context.stroke()", @@ -2225,7 +2516,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -2243,7 +2533,6 @@ exports[`an infinite canvas context > that creates a radial gradient > and then "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.stroke()", @@ -2260,7 +2549,6 @@ exports[`an infinite canvas context > that creates a rect that extends to infini "context.lineTo(201.41421356,50)", "context.lineTo(201.41421356,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.lineWidth = 1", @@ -2271,7 +2559,6 @@ exports[`an infinite canvas context > that creates a rect that extends to infini "context.lineTo(205.65685425,50)", "context.lineTo(205.65685425,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.lineWidth = 4", @@ -2289,7 +2576,6 @@ exports[`an infinite canvas context > that creates a rect that extends to infini "context.lineTo(201.41421356,50)", "context.lineTo(201.41421356,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.lineWidth = 1", @@ -2309,7 +2595,6 @@ exports[`an infinite canvas context > that creates a rectangular path, fills ano "context.lineTo(100,50)", "context.lineTo(100,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.fill()", @@ -2319,7 +2604,6 @@ exports[`an infinite canvas context > that creates a rectangular path, fills ano "context.lineTo(50,0)", "context.lineTo(50,50)", "context.lineTo(0,50)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 1", @@ -2339,7 +2623,6 @@ exports[`an infinite canvas context > that creates a rectangular path, strokes a "context.lineTo(100,50)", "context.lineTo(100,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.stroke()", @@ -2349,7 +2632,6 @@ exports[`an infinite canvas context > that creates a rectangular path, strokes a "context.lineTo(50,0)", "context.lineTo(50,50)", "context.lineTo(0,50)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 1", @@ -2432,7 +2714,6 @@ exports[`an infinite canvas context > that does this > should have done this 1`] "context.lineTo(25,0)", "context.lineTo(25,25)", "context.lineTo(0,25)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -2442,7 +2723,6 @@ exports[`an infinite canvas context > that does this > should have done this 1`] "context.lineTo(25,0)", "context.lineTo(25,25)", "context.lineTo(0,25)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -2610,7 +2890,6 @@ exports[`an infinite canvas context > that draws a path, transforms and then str "context.lineTo(110,10)", "context.lineTo(110,110)", "context.lineTo(10,110)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.lineWidth = 6", @@ -2673,6 +2952,122 @@ exports[`an infinite canvas context > that draws a quadratic curve > should draw ] `; +exports[`an infinite canvas context > that draws a round rect > should have given these instructions 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(15,10)", + "context.lineTo(45,10)", + "context.save()", + "context.transform(1,0,0,1,45,15)", + "context.arc(0,0,5,4.71238898,0,false)", + "context.restore()", + "context.lineTo(50,45)", + "context.save()", + "context.transform(1,0,0,1,45,45)", + "context.arc(0,0,5,0,1.57079633,false)", + "context.restore()", + "context.lineTo(15,50)", + "context.save()", + "context.transform(1,0,0,1,15,45)", + "context.arc(0,0,5,1.57079633,3.14159265,false)", + "context.restore()", + "context.lineTo(10,15)", + "context.save()", + "context.transform(1,0,0,1,15,15)", + "context.arc(0,0,5,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(10,10)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > that draws a round rect with a radius that is zero > should have given these instructions 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(10,10)", + "context.lineTo(45,10)", + "context.save()", + "context.transform(1,0,0,1,45,15)", + "context.arc(0,0,5,4.71238898,0,false)", + "context.restore()", + "context.lineTo(50,50)", + "context.lineTo(15,50)", + "context.save()", + "context.transform(1,0,0,1,15,45)", + "context.arc(0,0,5,1.57079633,3.14159265,false)", + "context.restore()", + "context.closePath()", + "context.moveTo(10,10)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > that draws a round rect with big radii > should have scaled the radii 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(37.5,30)", + "context.lineTo(95,30)", + "context.save()", + "context.transform(1,0,0,1,95,45)", + "context.arc(0,0,15,4.71238898,0,false)", + "context.restore()", + "context.lineTo(110,45)", + "context.save()", + "context.transform(1,0,0,1,95,45)", + "context.arc(0,0,15,0,1.57079633,false)", + "context.restore()", + "context.lineTo(37.5,60)", + "context.save()", + "context.transform(1,0,0,1,37.5,52.5)", + "context.arc(0,0,7.5,1.57079633,3.14159265,false)", + "context.restore()", + "context.lineTo(30,37.5)", + "context.save()", + "context.transform(1,0,0,1,37.5,37.5)", + "context.arc(0,0,7.5,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(30,30)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + +exports[`an infinite canvas context > that draws a round rect with big radii on invisible corners > should not have scaled the radii 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", + "context.beginPath()", + "context.moveTo(45,30)", + "context.lineTo(201.41421356,30)", + "context.lineTo(201.41421356,60)", + "context.lineTo(45,60)", + "context.save()", + "context.transform(1,0,0,1,45,45)", + "context.arc(0,0,15,1.57079633,3.14159265,false)", + "context.restore()", + "context.lineTo(30,45)", + "context.save()", + "context.transform(1,0,0,1,45,45)", + "context.arc(0,0,15,3.14159265,4.71238898,false)", + "context.restore()", + "context.moveTo(30,30)", + "context.lineWidth = 1", + "context.stroke()", +] +`; + exports[`an infinite canvas context > that draws a square by translating > and then fully clears the drawn square > should not have added a clearRect 1`] = ` [ "context.restore()", @@ -2732,7 +3127,10 @@ exports[`an infinite canvas context > that draws an arc > should draw an arc 1`] "context.clearRect(0,0,200,200)", "context.beginPath()", "context.moveTo(60,30)", - "context.arc(30,30,30,0,6.28318531,)", + "context.save()", + "context.transform(1,0,0,1,30,30)", + "context.arc(0,0,30,0,6.28318531,)", + "context.restore()", "context.lineWidth = 1", "context.fill()", ] @@ -2762,7 +3160,6 @@ exports[`an infinite canvas context > that fills a rect and adds a clearRect tha "context.lineTo(100,50)", "context.lineTo(100,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.fill()", @@ -2784,8 +3181,6 @@ exports[`an infinite canvas context > that fills a rect with finite width and ne "context.lineTo(50,20)", "context.lineTo(50,0)", "context.lineTo(20,0)", - "context.lineTo(20,0)", - "context.lineTo(20,20)", "context.closePath()", "context.moveTo(20,20)", "context.fill()", @@ -2803,8 +3198,6 @@ exports[`an infinite canvas context > that fills a rect with finite width and po "context.lineTo(50,20)", "context.lineTo(50,200)", "context.lineTo(20,200)", - "context.lineTo(20,200)", - "context.lineTo(20,20)", "context.closePath()", "context.moveTo(20,20)", "context.fill()", @@ -2822,7 +3215,6 @@ exports[`an infinite canvas context > that fills a rect with negative infinite w "context.lineTo(0,20)", "context.lineTo(0,50)", "context.lineTo(20,50)", - "context.lineTo(20,20)", "context.closePath()", "context.moveTo(20,20)", "context.fill()", @@ -2876,7 +3268,6 @@ exports[`an infinite canvas context > that fills a rect with positive infinite w "context.lineTo(200,20)", "context.lineTo(200,50)", "context.lineTo(20,50)", - "context.lineTo(20,20)", "context.closePath()", "context.moveTo(20,20)", "context.fill()", @@ -2968,7 +3359,6 @@ exports[`an infinite canvas context > that fills a rect, begins a new path, tran "context.lineTo(5,0)", "context.lineTo(5,5)", "context.lineTo(0,5)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -2991,7 +3381,6 @@ exports[`an infinite canvas context > that fills a rectangle, clears part of it "context.lineTo(5,0)", "context.lineTo(5,5)", "context.lineTo(0,5)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3014,7 +3403,6 @@ exports[`an infinite canvas context > that fills a rectangle, creates a path ins "context.lineTo(100,0)", "context.lineTo(100,100)", "context.lineTo(0,100)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3044,7 +3432,6 @@ exports[`an infinite canvas context > that fills a rectangle, fills a smaller re "context.lineTo(5,0)", "context.lineTo(5,5)", "context.lineTo(0,5)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3055,6 +3442,14 @@ exports[`an infinite canvas context > that fills a rectangle, fills a smaller re ] `; +exports[`an infinite canvas context > that fills the entire plane > and then clears the entire plane > should have cleared the plane 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", +] +`; + exports[`an infinite canvas context > that fills the entire plane > should fill the entire viewbox 1`] = ` [ "context.restore()", @@ -3083,7 +3478,6 @@ exports[`an infinite canvas context > that has this screen transformation > and "context.lineTo(0,120)", "context.lineTo(80,120)", "context.lineTo(80,200)", - "context.lineTo(0,200)", "context.closePath()", "context.moveTo(0,200)", "context.fill()", @@ -3105,7 +3499,6 @@ exports[`an infinite canvas context > that has this screen transformation > and "context.lineTo(0,120)", "context.lineTo(80,120)", "context.lineTo(80,200)", - "context.lineTo(0,200)", "context.closePath()", "context.moveTo(0,200)", "context.fill()", @@ -3125,7 +3518,6 @@ exports[`an infinite canvas context > that has this screen transformation > and "context.lineTo(0,120)", "context.lineTo(80,120)", "context.lineTo(80,200)", - "context.lineTo(0,200)", "context.closePath()", "context.moveTo(0,200)", "context.fill()", @@ -3147,7 +3539,6 @@ exports[`an infinite canvas context > that has this screen transformation > and "context.lineTo(0,120)", "context.lineTo(80,120)", "context.lineTo(80,200)", - "context.lineTo(0,200)", "context.closePath()", "context.moveTo(0,200)", "context.fill()", @@ -3165,7 +3556,6 @@ exports[`an infinite canvas context > that is translated > and then adds a recta "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 1", @@ -3189,7 +3579,6 @@ exports[`an infinite canvas context > that is translated > and then draws a rect "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3212,7 +3601,6 @@ exports[`an infinite canvas context > that is translated > and then draws a rect "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3231,13 +3619,22 @@ exports[`an infinite canvas context > that is translated > and then the viewbox "context.lineTo(2,0)", "context.lineTo(2,2)", "context.lineTo(0,2)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", ] `; +exports[`an infinite canvas context > that makes a drawing and then resets > and then calls fill > should have done nothing 1`] = `[]`; + +exports[`an infinite canvas context > that makes a drawing and then resets > should have no drawing anymore 1`] = ` +[ + "context.restore()", + "context.save()", + "context.clearRect(0,0,200,200)", +] +`; + exports[`an infinite canvas context > that makes a path consisting of two subpaths > and the fills it using a fill rule > should take the fill rule into account 1`] = ` [ "context.restore()", @@ -3248,14 +3645,12 @@ exports[`an infinite canvas context > that makes a path consisting of two subpat "context.lineTo(110,10)", "context.lineTo(110,110)", "context.lineTo(10,110)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.moveTo(30,30)", "context.lineTo(60,30)", "context.lineTo(60,60)", "context.lineTo(30,60)", - "context.lineTo(30,30)", "context.closePath()", "context.moveTo(30,30)", "context.lineWidth = 1", @@ -3318,7 +3713,6 @@ exports[`an infinite canvas context > that makes a path, fills a rect, fills the "context.lineTo(4,3)", "context.lineTo(4,4)", "context.lineTo(3,4)", - "context.lineTo(3,3)", "context.closePath()", "context.moveTo(3,3)", "context.fill()", @@ -3345,7 +3739,6 @@ exports[`an infinite canvas context > that makes a path, fills it and then fills "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -3383,7 +3776,6 @@ exports[`an infinite canvas context > that makes a path, fills it and then fills "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -3417,7 +3809,6 @@ exports[`an infinite canvas context > that makes a path, saves state, clips, fil "context.lineTo(60,10)", "context.lineTo(60,60)", "context.lineTo(10,60)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.save()", @@ -3428,7 +3819,6 @@ exports[`an infinite canvas context > that makes a path, saves state, clips, fil "context.lineTo(20,0)", "context.lineTo(20,20)", "context.lineTo(0,20)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3438,7 +3828,6 @@ exports[`an infinite canvas context > that makes a path, saves state, clips, fil "context.lineTo(60,10)", "context.lineTo(60,60)", "context.lineTo(10,60)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.save()", @@ -3461,7 +3850,6 @@ exports[`an infinite canvas context > that makes a rect, strokes it and then str "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 2", @@ -3486,7 +3874,6 @@ exports[`an infinite canvas context > that saves and fills a rect > should call "context.lineTo(30,10)", "context.lineTo(30,30)", "context.lineTo(10,30)", - "context.lineTo(10,10)", "context.closePath()", "context.moveTo(10,10)", "context.fill()", @@ -3505,7 +3892,6 @@ exports[`an infinite canvas context > that saves state, begins a path, restores "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3523,7 +3909,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3550,7 +3935,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3560,7 +3944,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3587,7 +3970,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3597,7 +3979,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,4)", "context.lineTo(6,6)", "context.lineTo(0,6)", - "context.lineTo(0,4)", "context.closePath()", "context.moveTo(0,4)", "context.fill()", @@ -3616,7 +3997,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3626,7 +4006,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3645,7 +4024,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3655,7 +4033,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3664,7 +4041,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,4)", "context.lineTo(6,6)", "context.lineTo(0,6)", - "context.lineTo(0,4)", "context.closePath()", "context.moveTo(0,4)", "context.fill()", @@ -3682,7 +4058,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.lineWidth = 1", @@ -3701,7 +4076,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3711,7 +4085,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3721,7 +4094,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.lineWidth = 1", @@ -3740,7 +4112,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.fill()", @@ -3758,7 +4129,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3768,7 +4138,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3779,7 +4148,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.fill()", @@ -3797,7 +4165,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3807,7 +4174,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3826,7 +4192,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3836,7 +4201,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(6,0)", "context.lineTo(6,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -3855,7 +4219,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3889,7 +4252,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.lineWidth = 1", @@ -3908,7 +4270,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3926,7 +4287,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.lineWidth = 1", @@ -3945,7 +4305,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.fill()", @@ -3963,7 +4322,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -3982,7 +4340,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(8,0)", "context.lineTo(8,1)", "context.lineTo(7,1)", - "context.lineTo(7,0)", "context.closePath()", "context.moveTo(7,0)", "context.fill()", @@ -4000,7 +4357,6 @@ exports[`an infinite canvas context > that saves state, makes a rect and clips i "context.lineTo(5,2)", "context.lineTo(5,5)", "context.lineTo(2,5)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.clip()", @@ -4035,7 +4391,6 @@ exports[`an infinite canvas context > that saves, begins a path, begins another "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4056,7 +4411,6 @@ exports[`an infinite canvas context > that saves, creates a path, fills two rect "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4065,7 +4419,6 @@ exports[`an infinite canvas context > that saves, creates a path, fills two rect "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4075,7 +4428,6 @@ exports[`an infinite canvas context > that saves, creates a path, fills two rect "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 1", @@ -4087,7 +4439,6 @@ exports[`an infinite canvas context > that saves, creates a path, fills two rect "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4107,7 +4458,6 @@ exports[`an infinite canvas context > that sets a line width, makes a rect, stro "context.lineTo(10,0)", "context.lineTo(10,10)", "context.lineTo(0,10)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.lineWidth = 4", @@ -4132,7 +4482,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(4,2)", "context.lineTo(4,4)", "context.lineTo(2,4)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.fill()", @@ -4141,7 +4490,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(20,2)", "context.lineTo(20,4)", "context.lineTo(18,4)", - "context.lineTo(18,2)", "context.closePath()", "context.moveTo(18,2)", "context.fill()", @@ -4160,7 +4508,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(4,2)", "context.lineTo(4,4)", "context.lineTo(2,4)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.fill()", @@ -4172,7 +4519,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(12,2)", "context.lineTo(12,4)", "context.lineTo(10,4)", - "context.lineTo(10,2)", "context.closePath()", "context.moveTo(10,2)", "context.save()", @@ -4187,7 +4533,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(20,2)", "context.lineTo(20,4)", "context.lineTo(18,4)", - "context.lineTo(18,2)", "context.closePath()", "context.moveTo(18,2)", "context.fill()", @@ -4206,7 +4551,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(4,2)", "context.lineTo(4,4)", "context.lineTo(2,4)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.fill()", @@ -4218,7 +4562,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(12,2)", "context.lineTo(12,4)", "context.lineTo(10,4)", - "context.lineTo(10,2)", "context.closePath()", "context.moveTo(10,2)", "context.save()", @@ -4240,7 +4583,6 @@ exports[`an infinite canvas context > that sets a nonzero line dash and fills a "context.lineTo(4,2)", "context.lineTo(4,4)", "context.lineTo(2,4)", - "context.lineTo(2,2)", "context.closePath()", "context.moveTo(2,2)", "context.fill()", @@ -4279,7 +4621,6 @@ exports[`an infinite canvas context > that strokes a rect that extends to infini "context.lineTo(201.41421356,50)", "context.lineTo(201.41421356,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.stroke()", @@ -4289,7 +4630,6 @@ exports[`an infinite canvas context > that strokes a rect that extends to infini "context.lineTo(205.65685425,50)", "context.lineTo(205.65685425,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.stroke()", @@ -4307,7 +4647,6 @@ exports[`an infinite canvas context > that strokes a rect that extends to infini "context.lineTo(201.41421356,50)", "context.lineTo(201.41421356,100)", "context.lineTo(50,100)", - "context.lineTo(50,50)", "context.closePath()", "context.moveTo(50,50)", "context.stroke()", @@ -4533,7 +4872,6 @@ exports[`an infinite canvas context > that uses shadow styles > and then transfo "context.lineTo(-5,75)", "context.lineTo(-55,75)", "context.lineTo(-55,25)", - "context.lineTo(-5,25)", "context.closePath()", "context.moveTo(-5,25)", "context.fill()", @@ -4555,7 +4893,6 @@ exports[`an infinite canvas context > that uses shadow styles > should use shado "context.lineTo(130,30)", "context.lineTo(130,130)", "context.lineTo(30,130)", - "context.lineTo(30,30)", "context.closePath()", "context.moveTo(30,30)", "context.fill()", @@ -4574,7 +4911,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(0,20)", "context.lineTo(0,0)", "context.lineTo(20,0)", - "context.lineTo(20,20)", "context.closePath()", "context.moveTo(20,20)", "context.fill()", @@ -4583,7 +4919,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(5,15)", "context.lineTo(5,5)", "context.lineTo(15,5)", - "context.lineTo(15,15)", "context.closePath()", "context.moveTo(15,15)", "context.fill()", @@ -4602,7 +4937,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(0,0)", "context.lineTo(20,0)", "context.lineTo(20,20)", - "context.lineTo(0,20)", "context.closePath()", "context.moveTo(0,20)", "context.fill()", @@ -4611,7 +4945,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(5,5)", "context.lineTo(15,5)", "context.lineTo(15,15)", - "context.lineTo(5,15)", "context.closePath()", "context.moveTo(5,15)", "context.fill()", @@ -4630,7 +4963,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(0,0)", "context.lineTo(20,0)", "context.lineTo(20,20)", - "context.lineTo(0,20)", "context.closePath()", "context.moveTo(0,20)", "context.fill()", @@ -4648,7 +4980,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(20,0)", "context.lineTo(20,20)", "context.lineTo(0,20)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4667,7 +4998,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(0,0)", "context.lineTo(20,0)", "context.lineTo(20,20)", - "context.lineTo(0,20)", "context.closePath()", "context.moveTo(0,20)", "context.fill()", @@ -4686,7 +5016,6 @@ exports[`an infinite canvas context > whose canvas has a non-identity screen tra "context.lineTo(20,0)", "context.lineTo(20,20)", "context.lineTo(0,20)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4705,7 +5034,6 @@ exports[`an infinite canvas context > whose state is changed > and then draws so "context.lineTo(20,0)", "context.lineTo(20,20)", "context.lineTo(0,20)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -4724,7 +5052,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -4738,7 +5065,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(4,1)", "context.lineTo(4,2)", "context.lineTo(3,2)", - "context.lineTo(3,1)", "context.closePath()", "context.moveTo(3,1)", "context.fill()", @@ -4757,7 +5083,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -4776,7 +5101,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -4803,7 +5127,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(6,1)", "context.lineTo(6,3)", "context.lineTo(4,3)", - "context.lineTo(4,1)", "context.closePath()", "context.moveTo(4,1)", "context.fill()", @@ -4822,7 +5145,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(6,1)", "context.lineTo(6,3)", "context.lineTo(4,3)", - "context.lineTo(4,1)", "context.closePath()", "context.moveTo(4,1)", "context.fill()", @@ -4845,7 +5167,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -4854,7 +5175,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(6,1)", "context.lineTo(6,3)", "context.lineTo(4,3)", - "context.lineTo(4,1)", "context.closePath()", "context.moveTo(4,1)", "context.fill()", @@ -4873,7 +5193,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -4882,7 +5201,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(11,1)", "context.lineTo(11,3)", "context.lineTo(9,3)", - "context.lineTo(9,1)", "context.closePath()", "context.moveTo(9,1)", "context.fill()", @@ -4901,7 +5219,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", @@ -4911,7 +5228,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(7,1)", "context.lineTo(7,3)", "context.lineTo(5,3)", - "context.lineTo(5,1)", "context.closePath()", "context.moveTo(5,1)", "context.fill()", @@ -4921,7 +5237,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(11,1)", "context.lineTo(11,3)", "context.lineTo(9,3)", - "context.lineTo(9,1)", "context.closePath()", "context.moveTo(9,1)", "context.fill()", @@ -4940,7 +5255,6 @@ exports[`an infinite canvas context > whose state is changed and who draws somet "context.lineTo(3,1)", "context.lineTo(3,3)", "context.lineTo(1,3)", - "context.lineTo(1,1)", "context.closePath()", "context.moveTo(1,1)", "context.fill()", diff --git a/test-unit/__snapshots__/instruction-set.test.ts.snap b/test-unit/__snapshots__/instruction-set.test.ts.snap index c6f44a62..02e761ae 100644 --- a/test-unit/__snapshots__/instruction-set.test.ts.snap +++ b/test-unit/__snapshots__/instruction-set.test.ts.snap @@ -24,7 +24,6 @@ exports[`an instruction set > that changes state and draws a rectangle > and cha "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", @@ -34,7 +33,6 @@ exports[`an instruction set > that changes state and draws a rectangle > and cha "context.lineTo(3,0)", "context.lineTo(3,1)", "context.lineTo(2,1)", - "context.lineTo(2,0)", "context.closePath()", "context.moveTo(2,0)", "context.fill()", @@ -52,7 +50,6 @@ exports[`an instruction set > that changes state and draws a rectangle > and the "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.fill()", diff --git a/test-unit/__snapshots__/instructions-with-path.test.ts.snap b/test-unit/__snapshots__/instructions-with-path.test.ts.snap index 7bae75eb..3c88b4b1 100644 --- a/test-unit/__snapshots__/instructions-with-path.test.ts.snap +++ b/test-unit/__snapshots__/instructions-with-path.test.ts.snap @@ -7,10 +7,8 @@ exports[`a set of instructions that describe a rectangle path that is drawn > an "context.lineTo(1,0)", "context.lineTo(1,1)", "context.lineTo(0,1)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", - "context.fill()", "context.fillStyle = \\"#f00\\"", "context.fill()", ] @@ -34,8 +32,6 @@ exports[`a set of instructions that is also about a path > that receives a chang "context.beginPath()", "context.fillStyle = \\"#f00\\"", "context.moveTo(0,0)", - "context.fillStyle = \\"#00f\\"", - "context.fill()", "context.fillStyle = \\"#ff0\\"", "context.fill()", ] diff --git a/test-unit/__snapshots__/state.test.ts.snap b/test-unit/__snapshots__/state.test.ts.snap index feedcac9..186e54e0 100644 --- a/test-unit/__snapshots__/state.test.ts.snap +++ b/test-unit/__snapshots__/state.test.ts.snap @@ -51,7 +51,6 @@ exports[`a state with a clipped path > and another one with another clipped path "context.lineTo(3,0)", "context.lineTo(3,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.clip()", @@ -71,7 +70,6 @@ exports[`a state with a clipped path > and another one with, higher up its stack "context.lineTo(3,0)", "context.lineTo(3,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.clip()", @@ -94,7 +92,6 @@ exports[`a state with a clipped path > and another one with, higher up its stack "context.lineTo(3,0)", "context.lineTo(3,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.clip()", @@ -113,7 +110,6 @@ exports[`a state with a clipped path > and another one without a clipped path > "context.lineTo(3,0)", "context.lineTo(3,3)", "context.lineTo(0,3)", - "context.lineTo(0,0)", "context.closePath()", "context.moveTo(0,0)", "context.clip()", diff --git a/test-unit/convex-polygon.test.ts b/test-unit/convex-polygon.test.ts index 74bf7dbe..521596bb 100644 --- a/test-unit/convex-polygon.test.ts +++ b/test-unit/convex-polygon.test.ts @@ -12,6 +12,7 @@ import { p, ls, hp, r, l } from "./builders"; import { expectPolygonsToBeEqual, expectAreasToBeEqual } from "./expectations"; import { Ray } from "../src/areas/line/ray"; import { Line } from "../src/areas/line/line"; +import { createRectangle } from './create-rectangle'; describe('this convex polygon', () => { let convexPolygon: ConvexPolygon; @@ -98,7 +99,7 @@ describe("a rectangle", () => { let rectangle: ConvexPolygon; beforeEach(() => { - rectangle = ConvexPolygon.createRectangle(0, 0, 1, 1); + rectangle = createRectangle(0, 0, 1, 1); }); describe("when it is expanded to include a point", () => { @@ -118,7 +119,7 @@ describe("a rectangle", () => { }); }); - it.each([[ConvexPolygon.createRectangle(2, 2, 1, 1), p(p => p + it.each([[createRectangle(2, 2, 1, 1), p(p => p .with(hp => hp.base(0, 0).normal(0, 1)) .with(hp => hp.base(0, 0).normal(1, 0)) .with(hp => hp.base(3, 3).normal(0, -1)) diff --git a/test-unit/create-rectangle.ts b/test-unit/create-rectangle.ts new file mode 100644 index 00000000..e0394788 --- /dev/null +++ b/test-unit/create-rectangle.ts @@ -0,0 +1,21 @@ +import { ConvexPolygon } from "../src/areas/polygons/convex-polygon"; +import { HalfPlane } from "../src/areas/polygons/half-plane"; +import { Point } from "../src/geometry/point"; + +export function createRectangle( + x: number, + y: number, + width: number, + height: number +): ConvexPolygon{ + const toRight = new Point(1, 0); + const toLeft = new Point(-1, 0); + const up = new Point(0, -1); + const down = new Point(0, 1); + return new ConvexPolygon([ + new HalfPlane(new Point(x, 0), width > 0 ? toRight: toLeft), + new HalfPlane(new Point(x + width, 0), width > 0 ? toLeft : toRight), + new HalfPlane(new Point(0, y), height > 0 ? down: up), + new HalfPlane(new Point(0, y + height), height > 0 ? up: down) + ]); +} \ No newline at end of file diff --git a/test-unit/infinite-canvas-viewbox.test.ts b/test-unit/infinite-canvas-viewbox.test.ts index b935b412..da5c796c 100644 --- a/test-unit/infinite-canvas-viewbox.test.ts +++ b/test-unit/infinite-canvas-viewbox.test.ts @@ -1476,7 +1476,7 @@ describe("an infinite canvas context", () => { }); createImageBitmapSpy = vi.spyOn(window, 'createImageBitmap').mockImplementation(() => imageBitmapPromise); const array: Uint8ClampedArray = new Uint8ClampedArray(4 * width * height); - imageData = {data: array, height: height, width: width}; + imageData = {data: array, height: height, width: width, colorSpace: "srgb"}; }); afterEach(() => { @@ -1631,6 +1631,19 @@ describe("an infinite canvas context", () => { expect(contextMock.getLog()).toMatchSnapshot(); }); }); + + describe('and then uses it to fill the entire plane', () => { + + beforeEach(() => { + infiniteContext.fillStyle = pattern; + contextMock.clear(); + infiniteContext.fillRect(-Infinity, -Infinity, Infinity, Infinity); + }); + + it("should wrap the fill command in a transform", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) }); describe("that clips and then puts image data", () => { @@ -1653,7 +1666,7 @@ describe("an infinite canvas context", () => { const imageBitmap: ImageBitmap = {width: imageDataWidth, height: imageDataHeight, close(){}}; createImageBitmapSpy = vi.spyOn(window, 'createImageBitmap').mockImplementation(() => new Promise((res) => {resolveImageBitmap = res;})); const array: Uint8ClampedArray = new Uint8ClampedArray(4 * width * height); - const imageData: ImageData = {data: array, height: height, width: width}; + const imageData: ImageData = {data: array, height: height, width: width, colorSpace: "srgb"}; infiniteContext.putImageData(imageData, 0, 0); resolveImageBitmap(imageBitmap); await new Promise((done) => { @@ -2755,6 +2768,12 @@ describe("an infinite canvas context", () => { }).toThrow(); }); + it("should get an error if it tries to add a round rect with x and y that do not determine a direction", () => { + expect(() => { + infiniteContext.roundRect(-Infinity, -Infinity, Infinity, Infinity, 2); + }).toThrow(); + }); + describe("and then adds a rect that has no area", () => { beforeEach(() => { @@ -2870,6 +2889,18 @@ describe("an infinite canvas context", () => { it("should fill the entire viewbox", () => { expect(contextMock.getLog()).toMatchSnapshot(); }); + + describe('and then clears the entire plane', () => { + + beforeEach(() => { + contextMock.clear(); + infiniteContext.clearRect(-Infinity, -Infinity, Infinity, Infinity) + }) + + it("should have cleared the plane", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) }); describe("that fills a rect with negative infinite width and a finite height", () => { @@ -3801,4 +3832,110 @@ describe("an infinite canvas context", () => { expect(contextMock.getLog()).toMatchSnapshot(); }); }) + + describe('that draws a round rect', () => { + + beforeEach(() => { + infiniteContext.beginPath(); + infiniteContext.roundRect(10, 10, 40, 40, 5) + infiniteContext.stroke(); + }) + + it("should have given these instructions", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) + + describe('that draws a round rect with a radius that is zero', () => { + + beforeEach(() => { + infiniteContext.beginPath(); + infiniteContext.roundRect(10, 10, 40, 40, [0, 5]) + infiniteContext.stroke(); + }) + + it("should have given these instructions", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) + + describe('that draws a round rect with big radii', () => { + + beforeEach(() => { + infiniteContext.beginPath(); + infiniteContext.roundRect(30, 30, 80, 30, [15, 30, 30, 15]); + infiniteContext.stroke(); + }) + + it("should have scaled the radii", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) + + describe('that draws a round rect with big radii on invisible corners', () => { + + beforeEach(() => { + infiniteContext.beginPath(); + infiniteContext.roundRect(30, 30, Infinity, 30, [15, 30, 30, 15]); + infiniteContext.stroke(); + }) + + it("should not have scaled the radii", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) + + it.each([ + [20, 20], + [75, 45], + [100, 100], + [Infinity, 20], + [Infinity, -20], + [-Infinity, 20], + [-Infinity, -20], + [20, Infinity], + [20, -Infinity], + [-20, Infinity], + [-20, -Infinity], + [Infinity, Infinity], + [Infinity, -Infinity], + [-Infinity, Infinity], + [-Infinity, -Infinity] + ])('should have drawn round rect like this', (w: number, h: number) => { + const radii = [15, {x: 60, y: 30}, 15, {x: 60, y: 30}] + + infiniteContext.beginPath(); + infiniteContext.roundRect(100, 100, w, h, radii) + infiniteContext.stroke(); + + expect(contextMock.getLog()).toMatchSnapshot(); + }) + + describe('that makes a drawing and then resets', () => { + + beforeEach(() => { + infiniteContext.fillStyle = '#f00' + infiniteContext.beginPath(); + infiniteContext.rect(0, 0, 10, 10) + infiniteContext.fill(); + contextMock.clear(); + infiniteContext.reset(); + }) + + it("should have no drawing anymore", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + + describe('and then calls fill', () => { + + beforeEach(() => { + contextMock.clear(); + infiniteContext.fill(); + }) + + it("should have done nothing", () => { + expect(contextMock.getLog()).toMatchSnapshot(); + }); + }) + }) }) diff --git a/test-unit/instruction-set.test.ts b/test-unit/instruction-set.test.ts index e450b86a..2ef12c81 100644 --- a/test-unit/instruction-set.test.ts +++ b/test-unit/instruction-set.test.ts @@ -3,6 +3,7 @@ import { logInstruction } from "./log-instruction"; import { fillStyle } from "../src/state/dimensions/fill-stroke-style"; import { InfiniteCanvasInstructionSet } from "../src/infinite-canvas-instruction-set"; import { Point } from "../src/geometry/point"; +import { getRectStrategy } from '../src/rect/get-rect-strategy'; describe("an instruction set", () => { let instructionSet: InfiniteCanvasInstructionSet; @@ -60,7 +61,7 @@ describe("an instruction set", () => { beforeEach(() => { instructionSet.changeState(s => fillStyle.changeInstanceValue(s, "#f00")); - instructionSet.fillRect(0, 0, 1, 1, (context: CanvasRenderingContext2D) => { + instructionSet.fillRect(getRectStrategy(0, 0, 1, 1), (context: CanvasRenderingContext2D) => { context.fill(); }); }); @@ -109,7 +110,7 @@ describe("an instruction set", () => { beforeEach(() => { instructionSet.changeState(s => fillStyle.changeInstanceValue(s, "#00f")); - instructionSet.fillRect(2, 0, 1, 1, (context: CanvasRenderingContext2D) => { + instructionSet.fillRect(getRectStrategy(2, 0, 1, 1), (context: CanvasRenderingContext2D) => { context.fill(); }); }); diff --git a/test-unit/instructions-with-path.test.ts b/test-unit/instructions-with-path.test.ts index 9b42a5c6..3e3c297e 100644 --- a/test-unit/instructions-with-path.test.ts +++ b/test-unit/instructions-with-path.test.ts @@ -6,6 +6,8 @@ import { fillStyle } from "../src/state/dimensions/fill-stroke-style"; import { InstructionsWithPath } from "../src/instructions/instructions-with-path"; import { CurrentPath } from '../src/interfaces/current-path'; import { Point } from "../src/geometry/point"; +import { getRectStrategy } from '../src/rect/get-rect-strategy'; +import { ExecutableStateChangingInstructionSet } from '../src/interfaces/executable-state-changing-instruction-set'; function drawAndLog(instructionsWithPath: CurrentPath, state: InfiniteCanvasState): string[]{ const result = instructionsWithPath.drawPath( @@ -72,7 +74,7 @@ describe("a set of instructions that is also about a path", () => { }); describe("that describes a path that is drawn, altered and then recreated", () => { - let recreatedPath: CurrentPath; + let recreatedPath: ExecutableStateChangingInstructionSet; beforeEach(() => { instructionsWithPath.moveTo(new Point(0, 0), currentState); @@ -81,11 +83,10 @@ describe("a set of instructions that is also about a path", () => { instructionsWithPath.lineTo(new Point(0, 10), currentState); currentState = currentState.withCurrentState(fillStyle.changeInstanceValue(currentState.current, "#00f")); instructionsWithPath.lineTo(new Point(5, 5), currentState); - recreatedPath = instructionsWithPath.recreatePath(); - }); - - it("should have the same area", () => { - expect(recreatedPath.getInstructionsToClip().area).toEqual(instructionsWithPath.getInstructionsToClip().area); + recreatedPath = instructionsWithPath.drawPath( + (context) => context.fill(), + currentState, + {lineWidth: 0, lineDashPeriod: 0, shadowOffsets: []}); }); describe("and then the recreated path changes state", () => { @@ -108,7 +109,8 @@ describe("a set of instructions that describe a rectangle path that is drawn", ( beforeEach(() => { currentState = defaultState; instructionsWithPath = InstructionsWithPath.create(currentState); - instructionsWithPath.rect(0, 0, 1, 1, currentState); + + getRectStrategy(0, 0, 1, 1).addSubpaths(instructionsWithPath, currentState) instructionsWithPath.drawPath((context: CanvasRenderingContext2D) => { context.fill(); }, currentState, {lineWidth: 0, lineDashPeriod: 0, shadowOffsets: []}) diff --git a/test-unit/mock-rectangle.ts b/test-unit/mock-rectangle.ts index b34efd68..7c226132 100644 --- a/test-unit/mock-rectangle.ts +++ b/test-unit/mock-rectangle.ts @@ -4,6 +4,7 @@ import { CoordinateSystem } from "../src/rectangle/coordinate-system"; import { CanvasRectangle } from "../src/rectangle/canvas-rectangle"; import { Transformation } from "../src/transformation"; import { Point } from '../src/geometry/point' +import { createRectangle } from "./create-rectangle"; export class MockRectangle implements CanvasRectangle{ public viewboxWidth: number = 200; @@ -14,7 +15,7 @@ export class MockRectangle implements CanvasRectangle{ public initialBitmapTransformation: Transformation = Transformation.identity; constructor(){ - this.polygon = ConvexPolygon.createRectangle(0, 0, this.viewboxWidth, this.viewboxHeight); + this.polygon = createRectangle(0, 0, this.viewboxWidth, this.viewboxHeight); } public addPathAroundViewbox(): void{ diff --git a/test-unit/state.test.ts b/test-unit/state.test.ts index 4414108d..70658e9d 100644 --- a/test-unit/state.test.ts +++ b/test-unit/state.test.ts @@ -9,6 +9,7 @@ import { fillStyle, strokeStyle } from "../src/state/dimensions/fill-stroke-styl import { InstructionsWithPath } from "../src/instructions/instructions-with-path"; import { Point } from "../src/geometry/point"; import { TransformableFilter } from "../src/state/dimensions/transformable-filter"; +import { getRectStrategy } from '../src/rect/get-rect-strategy'; function applyChangeToCurrentState(state: InfiniteCanvasState, change: (instance: InfiniteCanvasStateInstance) => InfiniteCanvasStateInstance): InfiniteCanvasState{ const newInstance: InfiniteCanvasStateInstance = change(state.current); @@ -24,7 +25,7 @@ describe("a state with a clipped path", () => { currentState = defaultState; currentPath = InstructionsWithPath.create(defaultState); currentState = applyChangeToCurrentState(currentState, s => fillStyle.changeInstanceValue(s, "#f00")); - currentPath.rect(0, 0, 3, 3, currentState); + getRectStrategy(0, 0, 3, 3).addSubpaths(currentPath, currentState) currentPath.clipPath((context: CanvasRenderingContext2D) => context.clip(), currentState); currentState = currentPath.state; stateWithOneClippedPath = currentState; @@ -276,6 +277,7 @@ describe("a default state", () => { textAlign: "start", //same textBaseline: "alphabetic", //same clippedPaths: undefined, //same + fontKerning: 'auto', //same fillAndStrokeStylesTransformed: false, shadowOffset: Point.origin, shadowColor: 'rgba(0, 0, 0, 0)', diff --git a/ts-config-docs-app.json b/ts-config-docs-app.json index ec3c9107..ab6864ec 100644 --- a/ts-config-docs-app.json +++ b/ts-config-docs-app.json @@ -4,9 +4,11 @@ "rootDir": ".", "composite": true, "moduleResolution": "node", + "baseUrl": ".", "paths": { "infinite-canvas": ["src/api-surface/infinite-canvas.ts"] - } + }, + "noEmit": true }, "include": ["docs/.vitepress/theme/**/*.*", "docs/.vitepress/shared/**/*", "examples/shared/**/*", "utils/**/*", "src/api-surface/**/*"] } \ No newline at end of file