modern-path2d 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -69,12 +69,18 @@ parsedPaths.forEach((parsedPath) => {
69
69
  path.addPath(parsedPath)
70
70
  })
71
71
 
72
- // export to ctx
73
- path.strokeTo(document.getElementById('canvas').getContext('2d'))
74
-
75
72
  // export path data
76
73
  console.log(path.getData())
77
74
 
78
75
  // export path commands
79
76
  console.log(path.getCommands())
77
+
78
+ // export to ctx
79
+ path.drawTo(document.getElementById('canvas').getContext('2d'))
80
+
81
+ // export to canvas
82
+ document.body.append(path.toCanvas())
83
+
84
+ // export to svg
85
+ document.body.append(path.toSvg())
80
86
  ```
package/dist/index.cjs CHANGED
@@ -1007,9 +1007,6 @@ class Curve {
1007
1007
  this.transformPoint((point) => point.applyMatrix3(matrix));
1008
1008
  return this;
1009
1009
  }
1010
- getDivisions(divisions) {
1011
- return divisions;
1012
- }
1013
1010
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1014
1011
  this.getPoints().forEach((point) => {
1015
1012
  min.x = Math.min(min.x, point.x);
@@ -1144,12 +1141,45 @@ class CubicBezierCurve extends Curve {
1144
1141
  cb(this.end);
1145
1142
  return this;
1146
1143
  }
1144
+ _solveQuadratic(a, b, c) {
1145
+ const discriminant = b * b - 4 * a * c;
1146
+ if (discriminant < 0)
1147
+ return [];
1148
+ const sqrtDiscriminant = Math.sqrt(discriminant);
1149
+ const t1 = (-b + sqrtDiscriminant) / (2 * a);
1150
+ const t2 = (-b - sqrtDiscriminant) / (2 * a);
1151
+ return [t1, t2].filter((t) => t >= 0 && t <= 1);
1152
+ }
1147
1153
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1148
- const { start, startControl, endControl, end } = this;
1149
- min.x = Math.min(min.x, start.x, startControl.x, endControl.x, end.x);
1150
- min.y = Math.min(min.y, start.y, startControl.y, endControl.y, end.y);
1151
- max.x = Math.max(max.x, start.x, startControl.x, endControl.x, end.x);
1152
- max.y = Math.max(max.y, start.y, startControl.y, endControl.y, end.y);
1154
+ const p0 = this.start;
1155
+ const p1 = this.startControl;
1156
+ const p2 = this.endControl;
1157
+ const p3 = this.end;
1158
+ const dxRoots = this._solveQuadratic(
1159
+ 3 * (p1.x - p0.x),
1160
+ 6 * (p2.x - p1.x),
1161
+ 3 * (p3.x - p2.x)
1162
+ );
1163
+ const dyRoots = this._solveQuadratic(
1164
+ 3 * (p1.y - p0.y),
1165
+ 6 * (p2.y - p1.y),
1166
+ 3 * (p3.y - p2.y)
1167
+ );
1168
+ const tValues = [0, 1, ...dxRoots, ...dyRoots];
1169
+ const samplePoints = (tValues2, precision) => {
1170
+ for (const t of tValues2) {
1171
+ for (let i = 0; i <= precision; i++) {
1172
+ const delta = i / precision - 0.5;
1173
+ const refinedT = Math.min(1, Math.max(0, t + delta));
1174
+ const point = this.getPoint(refinedT);
1175
+ min.x = Math.min(min.x, point.x);
1176
+ min.y = Math.min(min.y, point.y);
1177
+ max.x = Math.max(max.x, point.x);
1178
+ max.y = Math.max(max.y, point.y);
1179
+ }
1180
+ }
1181
+ };
1182
+ samplePoints(tValues, 10);
1153
1183
  return { min, max };
1154
1184
  }
1155
1185
  getCommands() {
@@ -1224,9 +1254,6 @@ class EllipseCurve extends Curve {
1224
1254
  }
1225
1255
  return output.set(_x, _y);
1226
1256
  }
1227
- getDivisions(divisions = 12) {
1228
- return divisions * 2;
1229
- }
1230
1257
  getCommands() {
1231
1258
  const { center, radiusX: rx, radiusY: ry, startAngle, endAngle, clockwise, rotation } = this;
1232
1259
  const { x: cx, y: cy } = center;
@@ -1486,9 +1513,6 @@ class LineCurve extends Curve {
1486
1513
  cb(this.end);
1487
1514
  return this;
1488
1515
  }
1489
- getDivisions() {
1490
- return 1;
1491
- }
1492
1516
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1493
1517
  const { start, end } = this;
1494
1518
  min.x = Math.min(min.x, start.x, end.x);
@@ -1829,9 +1853,6 @@ class SplineCurve extends Curve {
1829
1853
  super();
1830
1854
  this.points = points;
1831
1855
  }
1832
- getDivisions(divisions = 12) {
1833
- return divisions * this.points.length;
1834
- }
1835
1856
  getPoint(t, output = new Vector2()) {
1836
1857
  const { points } = this;
1837
1858
  const p = (points.length - 1) * t;
@@ -1948,10 +1969,11 @@ class CurvePath extends Curve {
1948
1969
  }
1949
1970
  getPoints(divisions = 12) {
1950
1971
  const points = [];
1972
+ const curves = this.curves;
1951
1973
  let last;
1952
- for (let i = 0, curves = this.curves; i < curves.length; i++) {
1974
+ for (let i = 0, len = curves.length; i < len; i++) {
1953
1975
  const curve = curves[i];
1954
- const curvePoints = curve.getPoints(curve.getDivisions(divisions));
1976
+ const curvePoints = curve.getPoints(divisions);
1955
1977
  for (let i2 = 0; i2 < curvePoints.length; i2++) {
1956
1978
  const point = curvePoints[i2];
1957
1979
  if (last?.equals(point))
@@ -1977,7 +1999,7 @@ class CurvePath extends Curve {
1977
1999
  if (start) {
1978
2000
  const end = this.currentPoint;
1979
2001
  if (!start.equals(end)) {
1980
- this.curves.push(new LineCurve(end, start));
2002
+ this.curves.push(new LineCurve(end.clone(), start));
1981
2003
  this.currentPoint.copy(start);
1982
2004
  }
1983
2005
  this.startPoint = void 0;
@@ -1990,35 +2012,41 @@ class CurvePath extends Curve {
1990
2012
  return this;
1991
2013
  }
1992
2014
  lineTo(x, y) {
1993
- this.curves.push(
1994
- new LineCurve(
1995
- this.currentPoint.clone(),
1996
- new Vector2(x, y)
1997
- )
1998
- );
2015
+ if (!this.currentPoint.equals({ x, y })) {
2016
+ this.curves.push(
2017
+ new LineCurve(
2018
+ this.currentPoint.clone(),
2019
+ new Vector2(x, y)
2020
+ )
2021
+ );
2022
+ }
1999
2023
  this._setCurrentPoint({ x, y });
2000
2024
  return this;
2001
2025
  }
2002
2026
  bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
2003
- this.curves.push(
2004
- new CubicBezierCurve(
2005
- this.currentPoint.clone(),
2006
- new Vector2(cp1x, cp1y),
2007
- new Vector2(cp2x, cp2y),
2008
- new Vector2(x, y)
2009
- )
2010
- );
2027
+ if (!this.currentPoint.equals({ x, y })) {
2028
+ this.curves.push(
2029
+ new CubicBezierCurve(
2030
+ this.currentPoint.clone(),
2031
+ new Vector2(cp1x, cp1y),
2032
+ new Vector2(cp2x, cp2y),
2033
+ new Vector2(x, y)
2034
+ )
2035
+ );
2036
+ }
2011
2037
  this._setCurrentPoint({ x, y });
2012
2038
  return this;
2013
2039
  }
2014
2040
  quadraticCurveTo(cpx, cpy, x, y) {
2015
- this.curves.push(
2016
- new QuadraticBezierCurve(
2017
- this.currentPoint.clone(),
2018
- new Vector2(cpx, cpy),
2019
- new Vector2(x, y)
2020
- )
2021
- );
2041
+ if (!this.currentPoint.equals({ x, y })) {
2042
+ this.curves.push(
2043
+ new QuadraticBezierCurve(
2044
+ this.currentPoint.clone(),
2045
+ new Vector2(cpx, cpy),
2046
+ new Vector2(x, y)
2047
+ )
2048
+ );
2049
+ }
2022
2050
  this._setCurrentPoint({ x, y });
2023
2051
  return this;
2024
2052
  }
@@ -2231,23 +2259,38 @@ class Path2D {
2231
2259
  }
2232
2260
  transform(matrix) {
2233
2261
  this.forEachCurve((curve) => curve.transform(matrix));
2262
+ const vec = new Vector2();
2263
+ const transformX = (x) => {
2264
+ vec.x = x;
2265
+ vec.applyMatrix3(matrix);
2266
+ return vec.x;
2267
+ };
2268
+ const style = this.style;
2269
+ if (style.strokeWidth) {
2270
+ style.strokeWidth = transformX(style.strokeWidth);
2271
+ }
2272
+ if (style.strokeDashoffset) {
2273
+ style.strokeDashoffset = transformX(style.strokeDashoffset);
2274
+ }
2275
+ if (style.strokeDasharray) {
2276
+ style.strokeDasharray = style.strokeDasharray.map((v) => transformX(v));
2277
+ }
2234
2278
  return this;
2235
2279
  }
2236
- getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
2280
+ getMinMax(min = Vector2.MAX, max = Vector2.MIN, withStyle = true) {
2237
2281
  this.forEachCurve((curve) => curve.getMinMax(min, max));
2282
+ if (withStyle) {
2283
+ const strokeHalfWidth = this.strokeWidth / 2;
2284
+ min.x -= strokeHalfWidth;
2285
+ min.y -= strokeHalfWidth;
2286
+ max.x += strokeHalfWidth;
2287
+ max.y += strokeHalfWidth;
2288
+ }
2238
2289
  return { min, max };
2239
2290
  }
2240
- getBoundingBox(withStrokeWidth = true) {
2241
- const { min, max } = this.getMinMax();
2242
- const bbox = new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
2243
- if (withStrokeWidth) {
2244
- const strokeWidth = this.strokeWidth;
2245
- bbox.left -= strokeWidth / 2;
2246
- bbox.top -= strokeWidth / 2;
2247
- bbox.width += strokeWidth;
2248
- bbox.height += strokeWidth;
2249
- }
2250
- return bbox;
2291
+ getBoundingBox(withStyle = true) {
2292
+ const { min, max } = this.getMinMax(void 0, void 0, withStyle);
2293
+ return new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
2251
2294
  }
2252
2295
  getCommands() {
2253
2296
  return this.paths.flatMap((path) => path.getCommands());
package/dist/index.d.cts CHANGED
@@ -163,7 +163,6 @@ declare abstract class Curve {
163
163
  /** overrideable */
164
164
  transformPoint(cb: (point: Vector2) => void): this;
165
165
  transform(matrix: Matrix3): this;
166
- getDivisions(divisions: number): number;
167
166
  getMinMax(min?: Vector2, max?: Vector2): {
168
167
  min: Vector2;
169
168
  max: Vector2;
@@ -201,6 +200,7 @@ declare class CubicBezierCurve extends Curve {
201
200
  constructor(start?: Vector2, startControl?: Vector2, endControl?: Vector2, end?: Vector2);
202
201
  getPoint(t: number, output?: Vector2): Vector2;
203
202
  transformPoint(cb: (point: Vector2) => void): this;
203
+ protected _solveQuadratic(a: number, b: number, c: number): number[];
204
204
  getMinMax(min?: Vector2, max?: Vector2): {
205
205
  min: Vector2;
206
206
  max: Vector2;
@@ -220,7 +220,6 @@ declare class EllipseCurve extends Curve {
220
220
  clockwise: boolean;
221
221
  constructor(center?: Vector2, radiusX?: number, radiusY?: number, rotation?: number, startAngle?: number, endAngle?: number, clockwise?: boolean);
222
222
  getPoint(t: number, output?: Vector2): Vector2;
223
- getDivisions(divisions?: number): number;
224
223
  getCommands(): PathCommand[];
225
224
  drawTo(ctx: CanvasRenderingContext2D): this;
226
225
  transform(matrix: Matrix3): this;
@@ -242,7 +241,6 @@ declare class LineCurve extends Curve {
242
241
  getTangentAt(u: number, output?: Vector2): Vector2;
243
242
  getNormal(t: number, output?: Vector2): Vector2;
244
243
  transformPoint(cb: (point: Vector2) => void): this;
245
- getDivisions(): number;
246
244
  getMinMax(min?: Vector2, max?: Vector2): {
247
245
  min: Vector2;
248
246
  max: Vector2;
@@ -347,7 +345,6 @@ declare class RectangularCurve extends Curve {
347
345
  declare class SplineCurve extends Curve {
348
346
  points: Vector2[];
349
347
  constructor(points?: Vector2[]);
350
- getDivisions(divisions?: number): number;
351
348
  getPoint(t: number, output?: Vector2): Vector2;
352
349
  transformPoint(cb: (point: Vector2) => void): this;
353
350
  copy(source: SplineCurve): this;
@@ -421,11 +418,11 @@ declare class Path2D {
421
418
  forEachCurve(cb: (curve: Curve) => void): this;
422
419
  transformPoint(cb: (point: Vector2) => void): this;
423
420
  transform(matrix: Matrix3): this;
424
- getMinMax(min?: Vector2, max?: Vector2): {
421
+ getMinMax(min?: Vector2, max?: Vector2, withStyle?: boolean): {
425
422
  min: Vector2;
426
423
  max: Vector2;
427
424
  };
428
- getBoundingBox(withStrokeWidth?: boolean): BoundingBox;
425
+ getBoundingBox(withStyle?: boolean): BoundingBox;
429
426
  getCommands(): PathCommand[];
430
427
  getData(): string;
431
428
  getSvgPathXml(): string;
package/dist/index.d.mts CHANGED
@@ -163,7 +163,6 @@ declare abstract class Curve {
163
163
  /** overrideable */
164
164
  transformPoint(cb: (point: Vector2) => void): this;
165
165
  transform(matrix: Matrix3): this;
166
- getDivisions(divisions: number): number;
167
166
  getMinMax(min?: Vector2, max?: Vector2): {
168
167
  min: Vector2;
169
168
  max: Vector2;
@@ -201,6 +200,7 @@ declare class CubicBezierCurve extends Curve {
201
200
  constructor(start?: Vector2, startControl?: Vector2, endControl?: Vector2, end?: Vector2);
202
201
  getPoint(t: number, output?: Vector2): Vector2;
203
202
  transformPoint(cb: (point: Vector2) => void): this;
203
+ protected _solveQuadratic(a: number, b: number, c: number): number[];
204
204
  getMinMax(min?: Vector2, max?: Vector2): {
205
205
  min: Vector2;
206
206
  max: Vector2;
@@ -220,7 +220,6 @@ declare class EllipseCurve extends Curve {
220
220
  clockwise: boolean;
221
221
  constructor(center?: Vector2, radiusX?: number, radiusY?: number, rotation?: number, startAngle?: number, endAngle?: number, clockwise?: boolean);
222
222
  getPoint(t: number, output?: Vector2): Vector2;
223
- getDivisions(divisions?: number): number;
224
223
  getCommands(): PathCommand[];
225
224
  drawTo(ctx: CanvasRenderingContext2D): this;
226
225
  transform(matrix: Matrix3): this;
@@ -242,7 +241,6 @@ declare class LineCurve extends Curve {
242
241
  getTangentAt(u: number, output?: Vector2): Vector2;
243
242
  getNormal(t: number, output?: Vector2): Vector2;
244
243
  transformPoint(cb: (point: Vector2) => void): this;
245
- getDivisions(): number;
246
244
  getMinMax(min?: Vector2, max?: Vector2): {
247
245
  min: Vector2;
248
246
  max: Vector2;
@@ -347,7 +345,6 @@ declare class RectangularCurve extends Curve {
347
345
  declare class SplineCurve extends Curve {
348
346
  points: Vector2[];
349
347
  constructor(points?: Vector2[]);
350
- getDivisions(divisions?: number): number;
351
348
  getPoint(t: number, output?: Vector2): Vector2;
352
349
  transformPoint(cb: (point: Vector2) => void): this;
353
350
  copy(source: SplineCurve): this;
@@ -421,11 +418,11 @@ declare class Path2D {
421
418
  forEachCurve(cb: (curve: Curve) => void): this;
422
419
  transformPoint(cb: (point: Vector2) => void): this;
423
420
  transform(matrix: Matrix3): this;
424
- getMinMax(min?: Vector2, max?: Vector2): {
421
+ getMinMax(min?: Vector2, max?: Vector2, withStyle?: boolean): {
425
422
  min: Vector2;
426
423
  max: Vector2;
427
424
  };
428
- getBoundingBox(withStrokeWidth?: boolean): BoundingBox;
425
+ getBoundingBox(withStyle?: boolean): BoundingBox;
429
426
  getCommands(): PathCommand[];
430
427
  getData(): string;
431
428
  getSvgPathXml(): string;
package/dist/index.d.ts CHANGED
@@ -163,7 +163,6 @@ declare abstract class Curve {
163
163
  /** overrideable */
164
164
  transformPoint(cb: (point: Vector2) => void): this;
165
165
  transform(matrix: Matrix3): this;
166
- getDivisions(divisions: number): number;
167
166
  getMinMax(min?: Vector2, max?: Vector2): {
168
167
  min: Vector2;
169
168
  max: Vector2;
@@ -201,6 +200,7 @@ declare class CubicBezierCurve extends Curve {
201
200
  constructor(start?: Vector2, startControl?: Vector2, endControl?: Vector2, end?: Vector2);
202
201
  getPoint(t: number, output?: Vector2): Vector2;
203
202
  transformPoint(cb: (point: Vector2) => void): this;
203
+ protected _solveQuadratic(a: number, b: number, c: number): number[];
204
204
  getMinMax(min?: Vector2, max?: Vector2): {
205
205
  min: Vector2;
206
206
  max: Vector2;
@@ -220,7 +220,6 @@ declare class EllipseCurve extends Curve {
220
220
  clockwise: boolean;
221
221
  constructor(center?: Vector2, radiusX?: number, radiusY?: number, rotation?: number, startAngle?: number, endAngle?: number, clockwise?: boolean);
222
222
  getPoint(t: number, output?: Vector2): Vector2;
223
- getDivisions(divisions?: number): number;
224
223
  getCommands(): PathCommand[];
225
224
  drawTo(ctx: CanvasRenderingContext2D): this;
226
225
  transform(matrix: Matrix3): this;
@@ -242,7 +241,6 @@ declare class LineCurve extends Curve {
242
241
  getTangentAt(u: number, output?: Vector2): Vector2;
243
242
  getNormal(t: number, output?: Vector2): Vector2;
244
243
  transformPoint(cb: (point: Vector2) => void): this;
245
- getDivisions(): number;
246
244
  getMinMax(min?: Vector2, max?: Vector2): {
247
245
  min: Vector2;
248
246
  max: Vector2;
@@ -347,7 +345,6 @@ declare class RectangularCurve extends Curve {
347
345
  declare class SplineCurve extends Curve {
348
346
  points: Vector2[];
349
347
  constructor(points?: Vector2[]);
350
- getDivisions(divisions?: number): number;
351
348
  getPoint(t: number, output?: Vector2): Vector2;
352
349
  transformPoint(cb: (point: Vector2) => void): this;
353
350
  copy(source: SplineCurve): this;
@@ -421,11 +418,11 @@ declare class Path2D {
421
418
  forEachCurve(cb: (curve: Curve) => void): this;
422
419
  transformPoint(cb: (point: Vector2) => void): this;
423
420
  transform(matrix: Matrix3): this;
424
- getMinMax(min?: Vector2, max?: Vector2): {
421
+ getMinMax(min?: Vector2, max?: Vector2, withStyle?: boolean): {
425
422
  min: Vector2;
426
423
  max: Vector2;
427
424
  };
428
- getBoundingBox(withStrokeWidth?: boolean): BoundingBox;
425
+ getBoundingBox(withStyle?: boolean): BoundingBox;
429
426
  getCommands(): PathCommand[];
430
427
  getData(): string;
431
428
  getSvgPathXml(): string;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (function(d,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(d=typeof globalThis<"u"?globalThis:d||self,v(d.modernPath2d={}))})(this,function(d){"use strict";var Kt=Object.defineProperty;var te=(d,v,z)=>v in d?Kt(d,v,{enumerable:!0,configurable:!0,writable:!0,value:z}):d[v]=z;var w=(d,v,z)=>te(d,typeof v!="symbol"?v+"":v,z);const v={arcs:"bevel",bevel:"bevel",miter:"miter","miter-clip":"miter",round:"round"};function z(r,e){const{fill:t="#000",stroke:s="none",strokeWidth:n=s==="none"?0:1,strokeLinecap:o="round",strokeLinejoin:i="miter",strokeMiterlimit:c=0,strokeDasharray:h,strokeDashoffset:a=0,shadowOffsetX:u=0,shadowOffsetY:y=0,shadowBlur:f=0,shadowColor:p="rgba(0, 0, 0, 0)"}=e;r.fillStyle=t,r.strokeStyle=s,r.lineWidth=n,r.lineCap=o,r.lineJoin=v[i],r.miterLimit=c,h&&r.setLineDash(h),r.lineDashOffset=a,r.shadowOffsetX=u,r.shadowOffsetY=y,r.shadowBlur=f,r.shadowColor=p}class l{constructor(e=0,t=0){this.x=e,this.y=t}static get MAX(){return new l(1/0,1/0)}static get MIN(){return new l(-1/0,-1/0)}set(e,t){return this.x=e,this.y=t,this}add(e){return this.x+=e.x,this.y+=e.y,this}sub(e){return this.x-=e.x,this.y-=e.y,this}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const t=this.x-e.x,s=this.y-e.y;return t*t+s*s}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}multiplyScalar(e){return this.x*=e,this.y*=e,this}divideScalar(e){return this.multiplyScalar(1/e)}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}normalize(){return this.divideScalar(this.length()||1)}lerpVectors(e,t,s){return this.x=e.x+(t.x-e.x)*s,this.y=e.y+(t.y-e.y)*s,this}equals(e){return this.x===e.x&&this.y===e.y}applyMatrix3(e){const t=this.x,s=this.y,n=e.elements;return this.x=n[0]*t+n[3]*s+n[6],this.y=n[1]*t+n[4]*s+n[7],this}copy(e){return this.x=e.x,this.y=e.y,this}clone(){return new l(this.x,this.y)}}class q{constructor(e=0,t=0,s=0,n=0){this.left=e,this.top=t,this.width=s,this.height=n}get x(){return this.left}set x(e){this.left=e}get y(){return this.top}set y(e){this.top=e}get right(){return this.left+this.width}get bottom(){return this.top+this.height}static from(...e){const t=e[0],s=e.slice(1).reduce((n,o)=>(n.left=Math.min(n.left,o.left),n.top=Math.min(n.top,o.top),n.right=Math.max(n.right,o.right),n.bottom=Math.max(n.bottom,o.bottom),n),{left:(t==null?void 0:t.left)??0,top:(t==null?void 0:t.top)??0,right:(t==null?void 0:t.right)??0,bottom:(t==null?void 0:t.bottom)??0});return new q(s.left,s.top,s.right-s.left,s.bottom-s.top)}translate(e,t){return this.left+=e,this.top+=t,this}getCenterPoint(){return new l((this.left+this.right)/2,(this.top+this.bottom)/2)}clone(){return new q(this.left,this.top,this.width,this.height)}toArray(){return[this.left,this.top,this.width,this.height]}}class C{constructor(e=1,t=0,s=0,n=0,o=1,i=0,c=0,h=0,a=1){w(this,"elements",[]);this.set(e,t,s,n,o,i,c,h,a)}set(e,t,s,n,o,i,c,h,a){const u=this.elements;return u[0]=e,u[1]=n,u[2]=c,u[3]=t,u[4]=o,u[5]=h,u[6]=s,u[7]=i,u[8]=a,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(e){const t=this.elements,s=e.elements;return t[0]=s[0],t[1]=s[1],t[2]=s[2],t[3]=s[3],t[4]=s[4],t[5]=s[5],t[6]=s[6],t[7]=s[7],t[8]=s[8],this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){const s=e.elements,n=t.elements,o=this.elements,i=s[0],c=s[3],h=s[6],a=s[1],u=s[4],y=s[7],f=s[2],p=s[5],g=s[8],x=n[0],m=n[3],T=n[6],E=n[1],b=n[4],S=n[7],N=n[2],L=n[5],D=n[8];return o[0]=i*x+c*E+h*N,o[3]=i*m+c*b+h*L,o[6]=i*T+c*S+h*D,o[1]=a*x+u*E+y*N,o[4]=a*m+u*b+y*L,o[7]=a*T+u*S+y*D,o[2]=f*x+p*E+g*N,o[5]=f*m+p*b+g*L,o[8]=f*T+p*S+g*D,this}invert(){const e=this.elements,t=e[0],s=e[1],n=e[2],o=e[3],i=e[4],c=e[5],h=e[6],a=e[7],u=e[8],y=u*i-c*a,f=c*h-u*o,p=a*o-i*h,g=t*y+s*f+n*p;if(g===0)return this.set(0,0,0,0,0,0,0,0,0);const x=1/g;return e[0]=y*x,e[1]=(n*a-u*s)*x,e[2]=(c*s-n*i)*x,e[3]=f*x,e[4]=(u*t-n*h)*x,e[5]=(n*o-c*t)*x,e[6]=p*x,e[7]=(s*h-a*t)*x,e[8]=(i*t-s*o)*x,this}transpose(){let e;const t=this.elements;return e=t[1],t[1]=t[3],t[3]=e,e=t[2],t[2]=t[6],t[6]=e,e=t[5],t[5]=t[7],t[7]=e,this}scale(e,t){return this.premultiply(U.makeScale(e,t)),this}rotate(e){return this.premultiply(U.makeRotation(-e)),this}translate(e,t){return this.premultiply(U.makeTranslation(e,t)),this}makeTranslation(e,t){return this.set(1,0,e,0,1,t,0,0,1),this}makeRotation(e){const t=Math.cos(e),s=Math.sin(e);return this.set(t,-s,0,s,t,0,0,0,1),this}makeScale(e,t){return this.set(e,0,0,0,t,0,0,0,1),this}fromArray(e,t=0){for(let s=0;s<9;s++)this.elements[s]=e[s+t];return this}clone(){return new this.constructor().fromArray(this.elements)}}const U=new C;function Z(r,e,t,s){const n=r*t+e*s,o=Math.sqrt(r*r+e*e)*Math.sqrt(t*t+s*s);let i=Math.acos(Math.max(-1,Math.min(1,n/o)));return r*s-e*t<0&&(i=-i),i}function J(r,e,t,s,n,o,i,c){if(e===0||t===0){r.lineTo(c.x,c.y);return}s=s*Math.PI/180,e=Math.abs(e),t=Math.abs(t);const h=(i.x-c.x)/2,a=(i.y-c.y)/2,u=Math.cos(s)*h+Math.sin(s)*a,y=-Math.sin(s)*h+Math.cos(s)*a;let f=e*e,p=t*t;const g=u*u,x=y*y,m=g/f+x/p;if(m>1){const wt=Math.sqrt(m);e=wt*e,t=wt*t,f=e*e,p=t*t}const T=f*x+p*g,E=(f*p-T)/T;let b=Math.sqrt(Math.max(0,E));n===o&&(b=-b);const S=b*e*y/t,N=-b*t*u/e,L=Math.cos(s)*S-Math.sin(s)*N+(i.x+c.x)/2,D=Math.sin(s)*S+Math.cos(s)*N+(i.y+c.y)/2,B=Z(1,0,(u-S)/e,(y-N)/t),V=Z((u-S)/e,(y-N)/t,(-u-S)/e,(-y-N)/t)%(Math.PI*2);r.ellipse(L,D,e,t,s,B,B+V,o===1)}function O(r,e){return r-(e-r)}function W(r,e){const t=new l,s=new l;for(let n=0,o=r.length;n<o;n++){const i=r[n];if(i.type==="m"||i.type==="M")i.type==="m"?t.add(i):t.copy(i),e.moveTo(t.x,t.y),s.copy(t);else if(i.type==="h"||i.type==="H")i.type==="h"?t.x+=i.x:t.x=i.x,e.lineTo(t.x,t.y),s.copy(t);else if(i.type==="v"||i.type==="V")i.type==="v"?t.y+=i.y:t.y=i.y,e.lineTo(t.x,t.y),s.copy(t);else if(i.type==="l"||i.type==="L")i.type==="l"?t.add(i):t.copy(i),e.lineTo(t.x,t.y),s.copy(t);else if(i.type==="c"||i.type==="C")i.type==="c"?(e.bezierCurveTo(t.x+i.x1,t.y+i.y1,t.x+i.x2,t.y+i.y2,t.x+i.x,t.y+i.y),s.x=t.x+i.x2,s.y=t.y+i.y2,t.add(i)):(e.bezierCurveTo(i.x1,i.y1,i.x2,i.y2,i.x,i.y),s.x=i.x2,s.y=i.y2,t.copy(i));else if(i.type==="s"||i.type==="S")i.type==="s"?(e.bezierCurveTo(O(t.x,s.x),O(t.y,s.y),t.x+i.x2,t.y+i.y2,t.x+i.x,t.y+i.y),s.x=t.x+i.x2,s.y=t.y+i.y2,t.add(i)):(e.bezierCurveTo(O(t.x,s.x),O(t.y,s.y),i.x2,i.y2,i.x,i.y),s.x=i.x2,s.y=i.y2,t.copy(i));else if(i.type==="q"||i.type==="Q")i.type==="q"?(e.quadraticCurveTo(t.x+i.x1,t.y+i.y1,t.x+i.x,t.y+i.y),s.x=t.x+i.x1,s.y=t.y+i.y1,t.add(i)):(e.quadraticCurveTo(i.x1,i.y1,i.x,i.y),s.x=i.x1,s.y=i.y1,t.copy(i));else if(i.type==="t"||i.type==="T"){const c=O(t.x,s.x),h=O(t.y,s.y);s.x=c,s.y=h,i.type==="t"?(e.quadraticCurveTo(c,h,t.x+i.x,t.y+i.y),t.add(i)):(e.quadraticCurveTo(c,h,i.x,i.y),t.copy(i))}else if(i.type==="a"||i.type==="A"){const c=t.clone();if(i.type==="a"){if(i.x===0&&i.y===0)continue;t.add(i)}else{if(t.equals(i))continue;t.copy(i)}s.copy(t),J(e,i.rx,i.ry,i.angle,i.largeArcFlag,i.sweepFlag,c,t)}else i.type==="z"||i.type==="Z"?(e.startPoint&&t.copy(e.startPoint),e.closePath()):console.warn("Unsupported commands",i)}}const P={SEPARATOR:/[ \t\r\n,.\-+]/,WHITESPACE:/[ \t\r\n]/,DIGIT:/\d/,SIGN:/[-+]/,POINT:/\./,COMMA:/,/,EXP:/e/i,FLAGS:/[01]/};function A(r,e,t=0){let c=0,h=!0,a="",u="";const y=[];function f(m,T,E){const b=new SyntaxError(`Unexpected character "${m}" at index ${T}.`);throw b.partial=E,b}function p(){a!==""&&(u===""?y.push(Number(a)):y.push(Number(a)*10**Number(u))),a="",u=""}let g;const x=r.length;for(let m=0;m<x;m++){if(g=r[m],Array.isArray(e)&&e.includes(y.length%t)&&P.FLAGS.test(g)){c=1,a=g,p();continue}if(c===0){if(P.WHITESPACE.test(g))continue;if(P.DIGIT.test(g)||P.SIGN.test(g)){c=1,a=g;continue}if(P.POINT.test(g)){c=2,a=g;continue}P.COMMA.test(g)&&(h&&f(g,m,y),h=!0)}if(c===1){if(P.DIGIT.test(g)){a+=g;continue}if(P.POINT.test(g)){a+=g,c=2;continue}if(P.EXP.test(g)){c=3;continue}P.SIGN.test(g)&&a.length===1&&P.SIGN.test(a[0])&&f(g,m,y)}if(c===2){if(P.DIGIT.test(g)){a+=g;continue}if(P.EXP.test(g)){c=3;continue}P.POINT.test(g)&&a[a.length-1]==="."&&f(g,m,y)}if(c===3){if(P.DIGIT.test(g)){u+=g;continue}if(P.SIGN.test(g)){if(u===""){u+=g;continue}u.length===1&&P.SIGN.test(u)&&f(g,m,y)}}P.WHITESPACE.test(g)?(p(),c=0,h=!1):P.COMMA.test(g)?(p(),c=0,h=!0):P.SIGN.test(g)?(p(),c=1,a=g):P.POINT.test(g)?(p(),c=2,a=g):f(g,m,y)}return p(),y}function Tt(r){switch(r.type){case"m":case"M":return`${r.type} ${r.x} ${r.y}`;case"h":case"H":return`${r.type} ${r.x}`;case"v":case"V":return`${r.type} ${r.y}`;case"l":case"L":return`${r.type} ${r.x} ${r.y}`;case"c":case"C":return`${r.type} ${r.x1} ${r.y1} ${r.x2} ${r.y2} ${r.x} ${r.y}`;case"s":case"S":return`${r.type} ${r.x2} ${r.y2} ${r.x} ${r.y}`;case"q":case"Q":return`${r.type} ${r.x1} ${r.y1} ${r.x} ${r.y}`;case"t":case"T":return`${r.type} ${r.x} ${r.y}`;case"a":case"A":return`${r.type} ${r.rx} ${r.ry} ${r.angle} ${r.largeArcFlag} ${r.sweepFlag} ${r.x} ${r.y}`;case"z":case"Z":return r.type;default:return""}}function K(r){let e="";for(let t=0,s=r.length;t<s;t++)e+=`${Tt(r[t])} `;return e}const vt=/[a-df-z][^a-df-z]*/gi;function G(r){const e=[],t=r.match(vt);if(!t)return e;for(let s=0,n=t.length;s<n;s++){const o=t[s],i=o.charAt(0),c=o.slice(1).trim();let h;switch(i){case"m":case"M":h=A(c);for(let a=0,u=h.length;a<u;a+=2)a===0?e.push({type:i,x:h[a],y:h[a+1]}):e.push({type:i==="m"?"l":"L",x:h[a],y:h[a+1]});break;case"h":case"H":h=A(c);for(let a=0,u=h.length;a<u;a++)e.push({type:i,x:h[a]});break;case"v":case"V":h=A(c);for(let a=0,u=h.length;a<u;a++)e.push({type:i,y:h[a]});break;case"l":case"L":h=A(c);for(let a=0,u=h.length;a<u;a+=2)e.push({type:i,x:h[a],y:h[a+1]});break;case"c":case"C":h=A(c);for(let a=0,u=h.length;a<u;a+=6)e.push({type:i,x1:h[a],y1:h[a+1],x2:h[a+2],y2:h[a+3],x:h[a+4],y:h[a+5]});break;case"s":case"S":h=A(c);for(let a=0,u=h.length;a<u;a+=4)e.push({type:i,x2:h[a],y2:h[a+1],x:h[a+2],y:h[a+3]});break;case"q":case"Q":h=A(c);for(let a=0,u=h.length;a<u;a+=4)e.push({type:i,x1:h[a],y1:h[a+1],x:h[a+2],y:h[a+3]});break;case"t":case"T":h=A(c);for(let a=0,u=h.length;a<u;a+=2)e.push({type:i,x:h[a],y:h[a+1]});break;case"a":case"A":h=A(c,[3,4],7);for(let a=0,u=h.length;a<u;a+=7)e.push({type:i,rx:h[a],ry:h[a+1],angle:h[a+2],largeArcFlag:h[a+3],sweepFlag:h[a+4],x:h[a+5],y:h[a+6]});break;case"z":case"Z":e.push({type:i});break;default:console.warn(o)}}return e}class k{constructor(){w(this,"arcLengthDivisions",200);w(this,"_cacheArcLengths");w(this,"_needsUpdate",!1)}getPointAt(e,t=new l){return this.getPoint(this.getUtoTmapping(e),t)}getPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPoint(s/e));return t}getSpacedPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPointAt(s/e));return t}getLength(){const e=this.getLengths();return e[e.length-1]}getLengths(e=this.arcLengthDivisions){if(this._cacheArcLengths&&this._cacheArcLengths.length===e+1&&!this._needsUpdate)return this._cacheArcLengths;this._needsUpdate=!1;const t=[];let s,n=this.getPoint(0),o=0;t.push(0);for(let i=1;i<=e;i++)s=this.getPoint(i/e),o+=s.distanceTo(n),t.push(o),n=s;return this._cacheArcLengths=t,t}updateArcLengths(){this._needsUpdate=!0,this.getLengths()}getUtoTmapping(e,t){const s=this.getLengths();let n=0;const o=s.length;let i;t?i=t:i=e*s[o-1];let c=0,h=o-1,a;for(;c<=h;)if(n=Math.floor(c+(h-c)/2),a=s[n]-i,a<0)c=n+1;else if(a>0)h=n-1;else{h=n;break}if(n=h,s[n]===i)return n/(o-1);const u=s[n],f=s[n+1]-u,p=(i-u)/f;return(n+p)/(o-1)}getTangent(e,t=new l){const n=Math.max(0,e-1e-4),o=Math.min(1,e+1e-4);return t.copy(this.getPoint(o).sub(this.getPoint(n)).normalize())}getTangentAt(e,t){return this.getTangent(this.getUtoTmapping(e),t)}transformPoint(e){return this}transform(e){return this.transformPoint(t=>t.applyMatrix3(e)),this}getDivisions(e){return e}getMinMax(e=l.MAX,t=l.MIN){return this.getPoints().forEach(s=>{e.x=Math.min(e.x,s.x),e.y=Math.min(e.y,s.y),t.x=Math.max(t.x,s.x),t.y=Math.max(t.y,s.y)}),{min:e,max:t}}getBoundingBox(){const{min:e,max:t}=this.getMinMax();return new q(e.x,e.y,t.x-e.x,t.y-e.y)}getCommands(){return this.getPoints().map((e,t)=>t===0?{type:"M",x:e.x,y:e.y}:{type:"L",x:e.x,y:e.y})}getData(){return K(this.getCommands())}drawTo(e){return this}copy(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}clone(){return new this.constructor().copy(this)}}class F extends k{constructor(e,t,s=0,n=Math.PI*2){super(),this.center=e,this.radius=t,this.start=s,this.end=n}getPoint(e){const{radius:t,center:s}=this;return s.clone().add(this.getNormal(e).clone().multiplyScalar(t))}getTangent(e){const{x:t,y:s}=this.getNormal(e);return new l(-s,t)}getNormal(e){const{start:t,end:s}=this,n=e*(s-t)+t-.5*Math.PI;return new l(Math.cos(n),Math.sin(n))}transformPoint(e){return e(this.center),this}getMinMax(e=l.MAX,t=l.MIN){return e.x=Math.min(e.x,this.center.x-this.radius),e.y=Math.min(e.y,this.center.y-this.radius),t.x=Math.max(t.x,this.center.x+this.radius),t.y=Math.max(t.y,this.center.y+this.radius),{min:e,max:t}}}function tt(r,e,t,s,n){const o=(s-e)*.5,i=(n-t)*.5,c=r*r,h=r*c;return(2*t-2*s+o+i)*h+(-3*t+3*s-2*o-i)*c+o*r+t}function bt(r,e){const t=1-r;return t*t*e}function Ct(r,e){return 2*(1-r)*r*e}function At(r,e){return r*r*e}function et(r,e,t,s){return bt(r,e)+Ct(r,t)+At(r,s)}function kt(r,e){const t=1-r;return t*t*t*e}function It(r,e){const t=1-r;return 3*t*t*r*e}function St(r,e){return 3*(1-r)*r*r*e}function Nt(r,e){return r*r*r*e}function st(r,e,t,s,n){return kt(r,e)+It(r,t)+St(r,s)+Nt(r,n)}class nt extends k{constructor(e=new l,t=new l,s=new l,n=new l){super(),this.start=e,this.startControl=t,this.endControl=s,this.end=n}getPoint(e,t=new l){const{start:s,startControl:n,endControl:o,end:i}=this;return t.set(st(e,s.x,n.x,o.x,i.x),st(e,s.y,n.y,o.y,i.y)),t}transformPoint(e){return e(this.start),e(this.startControl),e(this.endControl),e(this.end),this}getMinMax(e=l.MAX,t=l.MIN){const{start:s,startControl:n,endControl:o,end:i}=this;return e.x=Math.min(e.x,s.x,n.x,o.x,i.x),e.y=Math.min(e.y,s.y,n.y,o.y,i.y),t.x=Math.max(t.x,s.x,n.x,o.x,i.x),t.y=Math.max(t.y,s.y,n.y,o.y,i.y),{min:e,max:t}}getCommands(){const{start:e,startControl:t,endControl:s,end:n}=this;return[{type:"M",x:e.x,y:e.y},{type:"C",x1:t.x,y1:t.y,x2:s.x,y2:s.y,x:n.x,y:n.y}]}drawTo(e){const{startControl:t,endControl:s,end:n}=this;return e.bezierCurveTo(t.x,t.y,s.x,s.y,n.x,n.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.startControl.copy(e.startControl),this.endControl.copy(e.endControl),this.end.copy(e.end),this}}const $t=new C,rt=new C,it=new C,_=new l;class ot extends k{constructor(e=new l,t=1,s=1,n=0,o=0,i=Math.PI*2,c=!1){super(),this.center=e,this.radiusX=t,this.radiusY=s,this.rotation=n,this.startAngle=o,this.endAngle=i,this.clockwise=c}getPoint(e,t=new l){const s=Math.PI*2;let n=this.endAngle-this.startAngle;const o=Math.abs(n)<Number.EPSILON;for(;n<0;)n+=s;for(;n>s;)n-=s;n<Number.EPSILON&&(o?n=0:n=s),this.clockwise&&!o&&(n===s?n=-s:n=n-s);const i=this.startAngle+e*n;let c=this.center.x+this.radiusX*Math.cos(i),h=this.center.y+this.radiusY*Math.sin(i);if(this.rotation!==0){const a=Math.cos(this.rotation),u=Math.sin(this.rotation),y=c-this.center.x,f=h-this.center.y;c=y*a-f*u+this.center.x,h=y*u+f*a+this.center.y}return t.set(c,h)}getDivisions(e=12){return e*2}getCommands(){const{center:e,radiusX:t,radiusY:s,startAngle:n,endAngle:o,clockwise:i,rotation:c}=this,{x:h,y:a}=e,u=h+t*Math.cos(n)*Math.cos(c)-s*Math.sin(n)*Math.sin(c),y=a+t*Math.cos(n)*Math.sin(c)+s*Math.sin(n)*Math.cos(c),f=Math.abs(n-o),p=f>Math.PI?1:0,g=i?1:0,x=c*180/Math.PI;if(f>=2*Math.PI){const m=n+Math.PI,T=h+t*Math.cos(m)*Math.cos(c)-s*Math.sin(m)*Math.sin(c),E=a+t*Math.cos(m)*Math.sin(c)+s*Math.sin(m)*Math.cos(c);return[{type:"M",x:u,y},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:0,sweepFlag:g,x:T,y:E},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:0,sweepFlag:g,x:u,y}]}else{const m=h+t*Math.cos(o)*Math.cos(c)-s*Math.sin(o)*Math.sin(c),T=a+t*Math.cos(o)*Math.sin(c)+s*Math.sin(o)*Math.cos(c);return[{type:"M",x:u,y},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:p,sweepFlag:g,x:m,y:T}]}}drawTo(e){const{center:t,radiusX:s,radiusY:n,rotation:o,startAngle:i,endAngle:c,clockwise:h}=this;return e.ellipse(t.x,t.y,s,n,o,i,c,!h),this}transform(e){return _.set(this.center.x,this.center.y),_.applyMatrix3(e),this.center.x=_.x,this.center.y=_.y,Dt(e)?Et(this,e):Lt(this,e),this}transformPoint(e){return e(this.center),this}getMinMax(e=l.MAX,t=l.MIN){const{center:s,radiusX:n,radiusY:o,rotation:i}=this,{x:c,y:h}=s,a=Math.cos(i),u=Math.sin(i),y=Math.sqrt(n*n*a*a+o*o*u*u),f=Math.sqrt(n*n*u*u+o*o*a*a);return e.x=Math.min(e.x,c-y),e.y=Math.min(e.y,h-f),t.x=Math.max(t.x,c+y),t.y=Math.max(t.y,h+f),{min:e,max:t}}copy(e){return super.copy(e),this.center.x=e.center.x,this.center.y=e.center.y,this.radiusX=e.radiusX,this.radiusY=e.radiusY,this.startAngle=e.startAngle,this.endAngle=e.endAngle,this.clockwise=e.clockwise,this.rotation=e.rotation,this}}function Et(r,e){const t=r.radiusX,s=r.radiusY,n=Math.cos(r.rotation),o=Math.sin(r.rotation),i=new l(t*n,t*o),c=new l(-s*o,s*n),h=i.applyMatrix3(e),a=c.applyMatrix3(e),u=$t.set(h.x,a.x,0,h.y,a.y,0,0,0,1),y=rt.copy(u).invert(),g=it.copy(y).transpose().multiply(y).elements,x=zt(g[0],g[1],g[4]),m=Math.sqrt(x.rt1),T=Math.sqrt(x.rt2);if(r.radiusX=1/m,r.radiusY=1/T,r.rotation=Math.atan2(x.sn,x.cs),!((r.endAngle-r.startAngle)%(2*Math.PI)<Number.EPSILON)){const b=rt.set(m,0,0,0,T,0,0,0,1),S=it.set(x.cs,x.sn,0,-x.sn,x.cs,0,0,0,1),N=b.multiply(S).multiply(u),L=D=>{const{x:B,y:V}=new l(Math.cos(D),Math.sin(D)).applyMatrix3(N);return Math.atan2(V,B)};r.startAngle=L(r.startAngle),r.endAngle=L(r.endAngle),at(e)&&(r.clockwise=!r.clockwise)}}function Lt(r,e){const t=ht(e),s=ct(e);r.radiusX*=t,r.radiusY*=s;const n=t>Number.EPSILON?Math.atan2(e.elements[1],e.elements[0]):Math.atan2(-e.elements[3],e.elements[4]);r.rotation+=n,at(e)&&(r.startAngle*=-1,r.endAngle*=-1,r.clockwise=!r.clockwise)}function at(r){const e=r.elements;return e[0]*e[4]-e[1]*e[3]<0}function Dt(r){const e=r.elements,t=e[0]*e[3]+e[1]*e[4];if(t===0)return!1;const s=ht(r),n=ct(r);return Math.abs(t/(s*n))>Number.EPSILON}function ht(r){const e=r.elements;return Math.sqrt(e[0]*e[0]+e[1]*e[1])}function ct(r){const e=r.elements;return Math.sqrt(e[3]*e[3]+e[4]*e[4])}function zt(r,e,t){let s,n,o,i,c;const h=r+t,a=r-t,u=Math.sqrt(a*a+4*e*e);return h>0?(s=.5*(h+u),c=1/s,n=r*c*t-e*c*e):h<0?n=.5*(h-u):(s=.5*u,n=-.5*u),a>0?o=a+u:o=a-u,Math.abs(o)>2*Math.abs(e)?(c=-2*e/o,i=1/Math.sqrt(1+c*c),o=c*i):Math.abs(e)===0?(o=1,i=0):(c=-.5*o/e,o=1/Math.sqrt(1+c*c),i=c*o),a>0&&(c=o,o=-i,i=c),{rt1:s,rt2:n,cs:o,sn:i}}class X extends k{constructor(e=new l,t=new l){super(),this.start=e,this.end=t}getPoint(e,t=new l){return e===1?t.copy(this.end):t.copy(this.end).sub(this.start).multiplyScalar(e).add(this.start),t}getPointAt(e,t=new l){return this.getPoint(e,t)}getTangent(e,t=new l){return t.subVectors(this.end,this.start).normalize()}getTangentAt(e,t=new l){return this.getTangent(e,t)}getNormal(e,t=new l){const{x:s,y:n}=this.getPoint(e).sub(this.start);return t.set(n,-s).normalize()}transformPoint(e){return e(this.start),e(this.end),this}getDivisions(){return 1}getMinMax(e=l.MAX,t=l.MIN){const{start:s,end:n}=this;return e.x=Math.min(e.x,s.x,n.x),e.y=Math.min(e.y,s.y,n.y),t.x=Math.max(t.x,s.x,n.x),t.y=Math.max(t.y,s.y,n.y),{min:e,max:t}}getCommands(){const{start:e,end:t}=this;return[{type:"M",x:e.x,y:e.y},{type:"L",x:t.x,y:t.y}]}drawTo(e){const{end:t}=this;return e.lineTo(t.x,t.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.end.copy(e.end),this}}class qt extends k{constructor(t,s,n=0,o=1){super();w(this,"curveT",0);this.center=t,this.size=s,this.start=n,this.end=o,this.update()}update(){const{x:t,y:s}=this.center,n=new l(t+.5*this.size,s-.5*this.size),o=new l(t-.5*this.size,s-.5*this.size),i=new l(t,s+.5*this.size),c=new F(n,Math.SQRT1_2*this.size,-.25*Math.PI,.75*Math.PI),h=new F(o,Math.SQRT1_2*this.size,-.75*Math.PI,.25*Math.PI),a=new F(i,.5*Math.SQRT1_2*this.size,.75*Math.PI,1.25*Math.PI),u=new l(t,s+this.size),y=new l(t+this.size,s),f=new l().lerpVectors(y,u,.75),p=new l(t-this.size,s),g=new l().lerpVectors(p,u,.75),x=new X(y,f),m=new X(g,p);return this.curves=[c,x,a,m,h],this}getPoint(t){return this.getCurve(t).getPoint(this.curveT)}getPointAt(t){return this.getPoint(t)}getCurve(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=9*Math.PI/8+1.5;let n;const o=.5*Math.PI;return s<o?(n=0,this.curveT=s/o):s<o+.75?(n=1,this.curveT=(s-o)/.75):s<5*Math.PI/8+.75?(n=2,this.curveT=(s-o-.75)/(Math.PI/8)):s<5*Math.PI/8+1.5?(n=3,this.curveT=(s-5*Math.PI/8-.75)/.75):(n=4,this.curveT=(s-5*Math.PI/8-1.5)/o),this.curves[n]}getTangent(t){return this.getCurve(t).getTangent(this.curveT)}getNormal(t){return this.getCurve(t).getNormal(this.curveT)}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class Xt extends k{constructor(t,s=0,n=0,o=0,i=1){super();w(this,"curves",[]);w(this,"curveT",0);w(this,"points",[]);this.center=t,this.radius=s,this.number=n,this.start=o,this.end=i,this.update()}update(){for(let t=0;t<this.number;t++){let s=t*2*Math.PI/this.number;s-=.5*Math.PI,this.points.push(new l(this.radius*Math.cos(s),this.radius*Math.sin(s)).add(this.center))}for(let t=0;t<this.number;t++)this.curves.push(new X(this.points[t],this.points[(t+1)%this.number]));return this}getCurve(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1);const n=s*this.number,o=Math.floor(n);return this.curveT=n-o,this.curves[o]}getPoint(t,s){return this.getCurve(t).getPoint(this.curveT,s)}getPointAt(t,s){return this.getPoint(t,s)}getTangent(t,s){return this.getCurve(t).getTangent(this.curveT,s)}getNormal(t,s){return this.getCurve(t).getNormal(this.curveT,s)}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class ut extends k{constructor(e=new l,t=new l,s=new l){super(),this.start=e,this.control=t,this.end=s}getPoint(e,t=new l){const{start:s,control:n,end:o}=this;return t.set(et(e,s.x,n.x,o.x),et(e,s.y,n.y,o.y)),t}transformPoint(e){return e(this.start),e(this.control),e(this.end),this}getMinMax(e=l.MAX,t=l.MIN){const{start:s,control:n,end:o}=this,i=.5*(s.x+n.x),c=.5*(s.y+n.y),h=.5*(s.x+o.x),a=.5*(s.y+o.y);return e.x=Math.min(e.x,s.x,o.x,i,h),e.y=Math.min(e.y,s.y,o.y,c,a),t.x=Math.max(t.x,s.x,o.x,i,h),t.y=Math.max(t.y,s.y,o.y,c,a),{min:e,max:t}}getCommands(){const{start:e,control:t,end:s}=this;return[{type:"M",x:e.x,y:e.y},{type:"Q",x1:t.x,y1:t.y,x:s.x,y:s.y}]}drawTo(e){const{control:t,end:s}=this;return e.quadraticCurveTo(t.x,t.y,s.x,s.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.control.copy(e.control),this.end.copy(e.end),this}}class lt extends k{constructor(t,s,n=1,o=0,i=1){super();w(this,"curves",[]);w(this,"curveT",0);this.center=t,this.rx=s,this.aspectRatio=n,this.start=o,this.end=i,this.update()}get x(){return this.center.x-this.rx}get y(){return this.center.y-this.rx/this.aspectRatio}get width(){return this.rx*2}get height(){return this.rx/this.aspectRatio*2}update(){const{x:t,y:s}=this.center,n=this.rx,o=this.rx/this.aspectRatio,i=[new l(t-n,s-o),new l(t+n,s-o),new l(t+n,s+o),new l(t-n,s+o)];for(let c=0;c<4;c++)this.curves.push(new X(i[c].clone(),i[(c+1)%4].clone()));return this}getCurve(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=(1+this.aspectRatio)*2;let n;return s<this.aspectRatio?(n=0,this.curveT=s/this.aspectRatio):s<this.aspectRatio+1?(n=1,this.curveT=(s-this.aspectRatio)/1):s<2*this.aspectRatio+1?(n=2,this.curveT=(s-this.aspectRatio-1)/this.aspectRatio):(n=3,this.curveT=(s-2*this.aspectRatio-1)/1),this.curves[n]}getPoint(t,s){return this.getCurve(t).getPoint(this.curveT,s)}getPointAt(t,s){return this.getPoint(t,s)}getTangent(t,s){return this.getCurve(t).getTangent(this.curveT,s)}getNormal(t,s){return this.getCurve(t).getNormal(this.curveT,s)}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class yt extends k{constructor(e=[]){super(),this.points=e}getDivisions(e=12){return e*this.points.length}getPoint(e,t=new l){const{points:s}=this,n=(s.length-1)*e,o=Math.floor(n),i=n-o,c=s[o===0?o:o-1],h=s[o],a=s[o>s.length-2?s.length-1:o+1],u=s[o>s.length-3?s.length-1:o+2];return t.set(tt(i,c.x,h.x,a.x,u.x),tt(i,c.y,h.y,a.y,u.y)),t}transformPoint(e){return this.points.forEach(t=>e(t)),this}copy(e){super.copy(e),this.points=[];for(let t=0,s=e.points.length;t<s;t++)this.points.push(e.points[t].clone());return this}}class R extends k{constructor(t){super();w(this,"curves",[]);w(this,"startPoint");w(this,"currentPoint",new l);w(this,"autoClose",!1);w(this,"_cacheLengths",[]);t&&this.addPoints(t)}addCurve(t){return this.curves.push(t),this}addPoints(t){this.moveTo(t[0].x,t[0].y);for(let s=1,n=t.length;s<n;s++){const{x:o,y:i}=t[s];this.lineTo(o,i)}return this}addCommands(t){return W(t,this),this}addData(t){return this.addCommands(G(t)),this}getPoint(t,s=new l){const n=t*this.getLength(),o=this.getCurveLengths();let i=0;for(;i<o.length;){if(o[i]>=n){const c=o[i]-n,h=this.curves[i],a=h.getLength();return h.getPointAt(a===0?0:1-c/a,s)}i++}return s}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){super.updateArcLengths(),this._cacheLengths=[],this.getCurveLengths()}getCurveLengths(){if(this._cacheLengths.length===this.curves.length)return this._cacheLengths;const t=[];let s=0;for(let n=0,o=this.curves.length;n<o;n++)s+=this.curves[n].getLength(),t.push(s);return this._cacheLengths=t,t}getSpacedPoints(t=40){const s=[];for(let n=0;n<=t;n++)s.push(this.getPoint(n/t));return this.autoClose&&s.push(s[0]),s}getPoints(t=12){const s=[];let n;for(let o=0,i=this.curves;o<i.length;o++){const c=i[o],h=c.getPoints(c.getDivisions(t));for(let a=0;a<h.length;a++){const u=h[a];n!=null&&n.equals(u)||(s.push(u),n=u)}}return this.autoClose&&s.length>1&&!s[s.length-1].equals(s[0])&&s.push(s[0]),s}_setCurrentPoint(t){return this.currentPoint.copy(t),this.startPoint||(this.startPoint=this.currentPoint.clone()),this}closePath(){const t=this.startPoint;if(t){const s=this.currentPoint;t.equals(s)||(this.curves.push(new X(s,t)),this.currentPoint.copy(t)),this.startPoint=void 0}return this}moveTo(t,s){return this.currentPoint.set(t,s),this.startPoint=this.currentPoint.clone(),this}lineTo(t,s){return this.curves.push(new X(this.currentPoint.clone(),new l(t,s))),this._setCurrentPoint({x:t,y:s}),this}bezierCurveTo(t,s,n,o,i,c){return this.curves.push(new nt(this.currentPoint.clone(),new l(t,s),new l(n,o),new l(i,c))),this._setCurrentPoint({x:i,y:c}),this}quadraticCurveTo(t,s,n,o){return this.curves.push(new ut(this.currentPoint.clone(),new l(t,s),new l(n,o))),this._setCurrentPoint({x:n,y:o}),this}arc(t,s,n,o,i,c){return this.ellipse(t,s,n,n,0,o,i,c),this}relativeArc(t,s,n,o,i,c){const h=this.currentPoint;return this.arc(t+h.x,s+h.y,n,o,i,c),this}arcTo(t,s,n,o,i){return console.warn("Method arcTo not supported yet"),this}ellipse(t,s,n,o,i,c,h,a=!0){const u=new ot(new l(t,s),n,o,i,c,h,!a);if(this.curves.length>0){const y=u.getPoint(0);y.equals(this.currentPoint)||this.lineTo(y.x,y.y)}return this.curves.push(u),this._setCurrentPoint(u.getPoint(1)),this}relativeEllipse(t,s,n,o,i,c,h,a){const u=this.currentPoint;return this.ellipse(t+u.x,s+u.y,n,o,i,c,h,a),this}rect(t,s,n,o){return this.curves.push(new lt(new l(t+n/2,s+o/2),n/2,n/o)),this._setCurrentPoint({x:t,y:s}),this}splineThru(t){return this.curves.push(new yt([this.currentPoint.clone()].concat(t))),this._setCurrentPoint(t[t.length-1]),this}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getBoundingBox(){const{min:t,max:s}=this.getMinMax();return new q(t.x,t.y,s.x-t.x,s.y-t.y)}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){var n;const s=(n=this.curves[0])==null?void 0:n.getPoint(0);return s&&t.moveTo(s.x,s.y),this.curves.forEach(o=>o.drawTo(t)),this.autoClose&&t.closePath(),this}copy(t){super.copy(t),this.curves=[];for(let s=0,n=t.curves.length;s<n;s++)this.curves.push(t.curves[s].clone());return this.autoClose=t.autoClose,this.currentPoint.copy(t.currentPoint),this}}function Ot(r){return r.replace(/[^a-z0-9]/gi,"-").replace(/\B([A-Z])/g,"-$1").toLowerCase()}class I{constructor(e){w(this,"currentPath",new R);w(this,"paths",[this.currentPath]);w(this,"style",{});e&&(e instanceof I?this.addPath(e):Array.isArray(e)?this.addCommands(e):this.addData(e))}get startPoint(){return this.currentPath.startPoint}get currentPoint(){return this.currentPath.currentPoint}get strokeWidth(){return this.style.strokeWidth??((this.style.stroke??"none")==="none"?0:1)}addPath(e){return e instanceof I?this.paths.push(...e.paths.map(t=>t.clone())):this.paths.push(e),this}closePath(){const e=this.startPoint;return e&&(this.currentPath.closePath(),this.currentPath.curves.length>0&&(this.currentPath=new R().moveTo(e.x,e.y),this.paths.push(this.currentPath))),this}moveTo(e,t){const{currentPoint:s,curves:n}=this.currentPath;return s.equals({x:e,y:t})||(n.length?(this.currentPath=new R().moveTo(e,t),this.paths.push(this.currentPath)):this.currentPath.moveTo(e,t)),this}lineTo(e,t){return this.currentPath.lineTo(e,t),this}bezierCurveTo(e,t,s,n,o,i){return this.currentPath.bezierCurveTo(e,t,s,n,o,i),this}quadraticCurveTo(e,t,s,n){return this.currentPath.quadraticCurveTo(e,t,s,n),this}arc(e,t,s,n,o,i){return this.currentPath.arc(e,t,s,n,o,i),this}arcTo(e,t,s,n,o){return this.currentPath.arcTo(e,t,s,n,o),this}ellipse(e,t,s,n,o,i,c,h){return this.currentPath.ellipse(e,t,s,n,o,i,c,h),this}rect(e,t,s,n){return this.currentPath.rect(e,t,s,n),this}addCommands(e){return W(e,this),this}addData(e){return this.addCommands(G(e)),this}splineThru(e){return this.currentPath.splineThru(e),this}forEachCurve(e){return this.paths.forEach(t=>t.curves.forEach(s=>e(s))),this}transformPoint(e){return this.forEachCurve(t=>t.transformPoint(e)),this}transform(e){return this.forEachCurve(t=>t.transform(e)),this}getMinMax(e=l.MAX,t=l.MIN){return this.forEachCurve(s=>s.getMinMax(e,t)),{min:e,max:t}}getBoundingBox(e=!0){const{min:t,max:s}=this.getMinMax(),n=new q(t.x,t.y,s.x-t.x,s.y-t.y);if(e){const o=this.strokeWidth;n.left-=o/2,n.top-=o/2,n.width+=o,n.height+=o}return n}getCommands(){return this.paths.flatMap(e=>e.getCommands())}getData(){return this.paths.map(e=>e.getData()).join(" ")}getSvgPathXml(){const e={...this.style,fill:this.style.fill??"#000",stroke:this.style.stroke??"none"},t={};for(const n in e)e[n]!==void 0&&(t[Ot(n)]=e[n]);Object.assign(t,{"stroke-width":`${this.strokeWidth}px`});let s="";for(const n in t)t[n]!==void 0&&(s+=`${n}:${t[n]};`);return`<path d="${this.getData()}" style="${s}"></path>`}getSvgXml(){const{x:e,y:t,width:s,height:n}=this.getBoundingBox(),o=this.getSvgPathXml();return`<svg viewBox="${e} ${t} ${s} ${n}" width="${s}px" height="${n}px" xmlns="http://www.w3.org/2000/svg">${o}</svg>`}getSvgDataUri(){return`data:image/svg+xml;base64,${btoa(this.getSvgXml())}`}drawTo(e,t=!0){const{fill:s="#000",stroke:n="none"}=this.style;t&&z(e,this.style),this.paths.forEach(o=>{o.drawTo(e)}),s!=="none"&&e.fill(),n!=="none"&&e.stroke()}copy(e){return this.currentPath=e.currentPath.clone(),this.paths=e.paths.map(t=>t.clone()),this.style={...e.style},this}toSvg(){return new DOMParser().parseFromString(this.getSvgXml(),"image/svg+xml").documentElement}toCanvas(e=2){const{left:t,top:s,width:n,height:o}=this.getBoundingBox(),i=document.createElement("canvas");i.width=n*e,i.height=o*e,i.style.width=`${n}px`,i.style.height=`${o}px`;const c=i.getContext("2d");return c&&(c.scale(e,e),c.translate(-t,-s),this.drawTo(c)),i}clone(){return new this.constructor().copy(this)}}const Q="px",gt=90,ft=["mm","cm","in","pt","pc","px"],H={mm:{mm:1,cm:.1,in:1/25.4,pt:72/25.4,pc:6/25.4,px:-1},cm:{mm:10,cm:1,in:1/2.54,pt:72/2.54,pc:6/2.54,px:-1},in:{mm:25.4,cm:2.54,in:1,pt:72,pc:6,px:-1},pt:{mm:25.4/72,cm:2.54/72,in:1/72,pt:1,pc:6/72,px:-1},pc:{mm:25.4/6,cm:2.54/6,in:1/6,pt:72/6,pc:1,px:-1},px:{px:1}};function M(r){let e="px";if(typeof r=="string"||r instanceof String)for(let s=0,n=ft.length;s<n;s++){const o=ft[s];if(r.endsWith(o)){e=o,r=r.substring(0,r.length-o.length);break}}let t;return e==="px"&&Q!=="px"?t=H.in[Q]/gt:(t=H[e][Q],t<0&&(t=H[e].in*gt)),t*Number.parseFloat(r)}const Rt=new C,Y=new C,pt=new C,dt=new C;function Ft(r,e,t){if(!(r.hasAttribute("transform")||r.nodeName==="use"&&(r.hasAttribute("x")||r.hasAttribute("y"))))return null;const s=_t(r);return t.length>0&&s.premultiply(t[t.length-1]),e.copy(s),t.push(s),s}function _t(r){const e=new C,t=Rt;if(r.nodeName==="use"&&(r.hasAttribute("x")||r.hasAttribute("y"))&&e.translate(M(r.getAttribute("x")),M(r.getAttribute("y"))),r.hasAttribute("transform")){const s=r.getAttribute("transform").split(")");for(let n=s.length-1;n>=0;n--){const o=s[n].trim();if(o==="")continue;const i=o.indexOf("("),c=o.length;if(i>0&&i<c){const h=o.slice(0,i),a=A(o.slice(i+1));switch(t.identity(),h){case"translate":if(a.length>=1){const u=a[0];let y=0;a.length>=2&&(y=a[1]),t.translate(u,y)}break;case"rotate":if(a.length>=1){let u=0,y=0,f=0;u=a[0]*Math.PI/180,a.length>=3&&(y=a[1],f=a[2]),Y.makeTranslation(-y,-f),pt.makeRotation(u),dt.multiplyMatrices(pt,Y),Y.makeTranslation(y,f),t.multiplyMatrices(Y,dt)}break;case"scale":a.length>=1&&t.scale(a[0],a[1]??a[0]);break;case"skewX":a.length===1&&t.set(1,Math.tan(a[0]*Math.PI/180),0,0,1,0,0,0,1);break;case"skewY":a.length===1&&t.set(1,0,0,Math.tan(a[0]*Math.PI/180),1,0,0,0,1);break;case"matrix":a.length===6&&t.set(a[0],a[2],a[4],a[1],a[3],a[5],0,0,1);break}}e.premultiply(t)}}return e}function Yt(r){return new I().addPath(new R().arc(M(r.getAttribute("cx")||0),M(r.getAttribute("cy")||0),M(r.getAttribute("r")||0),0,Math.PI*2))}function Bt(r,e){if(!(!r.sheet||!r.sheet.cssRules||!r.sheet.cssRules.length))for(let t=0;t<r.sheet.cssRules.length;t++){const s=r.sheet.cssRules[t];if(s.type!==1)continue;const n=s.selectorText.split(/,/g).filter(Boolean).map(o=>o.trim());for(let o=0;o<n.length;o++){const i=Object.fromEntries(Object.entries(s.style).filter(([,c])=>c!==""));e[n[o]]=Object.assign(e[n[o]]||{},i)}}}function Ut(r){return new I().addPath(new R().ellipse(M(r.getAttribute("cx")||0),M(r.getAttribute("cy")||0),M(r.getAttribute("rx")||0),M(r.getAttribute("ry")||0),0,0,Math.PI*2))}function Wt(r){return new I().moveTo(M(r.getAttribute("x1")||0),M(r.getAttribute("y1")||0)).lineTo(M(r.getAttribute("x2")||0),M(r.getAttribute("y2")||0))}function Gt(r){const e=new I,t=r.getAttribute("d");return!t||t==="none"?null:(e.addData(t),e)}const Qt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function Ht(r){var s;const e=new I;let t=0;return(s=r.getAttribute("points"))==null||s.replace(Qt,(n,o,i)=>{const c=M(o),h=M(i);return t===0?e.moveTo(c,h):e.lineTo(c,h),t++,n}),e.currentPath.autoClose=!0,e}const jt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function Vt(r){var s;const e=new I;let t=0;return(s=r.getAttribute("points"))==null||s.replace(jt,(n,o,i)=>{const c=M(o),h=M(i);return t===0?e.moveTo(c,h):e.lineTo(c,h),t++,n}),e.currentPath.autoClose=!1,e}function Zt(r){const e=M(r.getAttribute("x")||0),t=M(r.getAttribute("y")||0),s=M(r.getAttribute("rx")||r.getAttribute("ry")||0),n=M(r.getAttribute("ry")||r.getAttribute("rx")||0),o=M(r.getAttribute("width")),i=M(r.getAttribute("height")),c=1-.551915024494,h=new I;return h.moveTo(e+s,t),h.lineTo(e+o-s,t),(s!==0||n!==0)&&h.bezierCurveTo(e+o-s*c,t,e+o,t+n*c,e+o,t+n),h.lineTo(e+o,t+i-n),(s!==0||n!==0)&&h.bezierCurveTo(e+o,t+i-n*c,e+o-s*c,t+i,e+o-s,t+i),h.lineTo(e+s,t+i),(s!==0||n!==0)&&h.bezierCurveTo(e+s*c,t+i,e,t+i-n*c,e,t+i-n),h.lineTo(e,t+n),(s!==0||n!==0)&&h.bezierCurveTo(e,t+n*c,e+s*c,t,e+s,t),h}function $(r,e,t){e=Object.assign({},e);let s={};if(r.hasAttribute("class")){const h=r.getAttribute("class").split(/\s/).filter(Boolean).map(a=>a.trim());for(let a=0;a<h.length;a++)s=Object.assign(s,t[`.${h[a]}`])}r.hasAttribute("id")&&(s=Object.assign(s,t[`#${r.getAttribute("id")}`]));function n(h,a,u){u===void 0&&(u=function(f){return f.startsWith("url")&&console.warn("url access in attributes is not implemented."),f}),r.hasAttribute(h)&&(e[a]=u(r.getAttribute(h))),s[h]&&(e[a]=u(s[h])),r.style&&r.style[h]!==""&&(e[a]=u(r.style[h]))}function o(h){return Math.max(0,Math.min(1,M(h)))}function i(h){return Math.max(0,M(h))}function c(h){return h.split(" ").filter(a=>a!=="").map(a=>M(a))}return n("fill","fill"),n("fill-opacity","fillOpacity",o),n("fill-rule","fillRule"),n("opacity","opacity",o),n("stroke","stroke"),n("stroke-opacity","strokeOpacity",o),n("stroke-width","strokeWidth",i),n("stroke-linecap","strokeLinecap"),n("stroke-linejoin","strokeLinejoin"),n("stroke-miterlimit","strokeMiterlimit",i),n("stroke-dasharray","strokeDasharray",c),n("stroke-dashoffset","strokeDashoffset",M),n("visibility","visibility"),e}function j(r,e,t=[]){var u;if(r.nodeType!==1)return t;let s=!1,n=null;const o={};switch(r.nodeName){case"svg":e=$(r,e,o);break;case"style":Bt(r,o);break;case"g":e=$(r,e,o);break;case"path":e=$(r,e,o),r.hasAttribute("d")&&(n=Gt(r));break;case"rect":e=$(r,e,o),n=Zt(r);break;case"polygon":e=$(r,e,o),n=Ht(r);break;case"polyline":e=$(r,e,o),n=Vt(r);break;case"circle":e=$(r,e,o),n=Yt(r);break;case"ellipse":e=$(r,e,o),n=Ut(r);break;case"line":e=$(r,e,o),n=Wt(r);break;case"defs":s=!0;break;case"use":{e=$(r,e,o);const f=(r.getAttributeNS("http://www.w3.org/1999/xlink","href")||"").substring(1),p=(u=r.viewportElement)==null?void 0:u.getElementById(f);p?j(p,e,t):console.warn(`'use node' references non-existent node id: ${f}`);break}default:console.warn(r);break}const i=new C,c=[],h=Ft(r,i,c);n&&(n.transform(i),t.push(n),n.style=e);const a=r.childNodes;for(let y=0,f=a.length;y<f;y++){const p=a[y];s&&p.nodeName!=="style"&&p.nodeName!=="defs"||j(p,e,t)}return h&&(c.pop(),c.length>0?i.copy(c[c.length-1]):i.identity()),t}const xt="data:image/svg+xml;",mt=`${xt}base64,`,Mt=`${xt}charset=utf8,`;function Pt(r){if(typeof r=="string"){let e;return r.startsWith(mt)?(r=r.substring(mt.length,r.length),e=atob(r)):r.startsWith(Mt)?(r=r.substring(Mt.length,r.length),e=decodeURIComponent(r)):e=r,new DOMParser().parseFromString(e,"image/svg+xml").documentElement}else return r}function Jt(r){return j(Pt(r),{})}d.BoundingBox=q,d.CircleCurve=F,d.CubicBezierCurve=nt,d.Curve=k,d.CurvePath=R,d.EllipseCurve=ot,d.HeartCurve=qt,d.LineCurve=X,d.Matrix3=C,d.Path2D=I,d.PloygonCurve=Xt,d.QuadraticBezierCurve=ut,d.RectangularCurve=lt,d.SplineCurve=yt,d.Vector2=l,d.addPathCommandsToPath2D=W,d.parseArcCommand=J,d.parsePathDataArgs=A,d.parseSvg=Jt,d.parseSvgToDom=Pt,d.pathCommandsToPathData=K,d.pathDataToPathCommands=G,d.setCanvasContext=z,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
1
+ (function(x,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(x=typeof globalThis<"u"?globalThis:x||self,v(x.modernPath2d={}))})(this,function(x){"use strict";var Kt=Object.defineProperty;var te=(x,v,q)=>v in x?Kt(x,v,{enumerable:!0,configurable:!0,writable:!0,value:q}):x[v]=q;var w=(x,v,q)=>te(x,typeof v!="symbol"?v+"":v,q);const v={arcs:"bevel",bevel:"bevel",miter:"miter","miter-clip":"miter",round:"round"};function q(r,e){const{fill:t="#000",stroke:s="none",strokeWidth:n=s==="none"?0:1,strokeLinecap:o="round",strokeLinejoin:i="miter",strokeMiterlimit:c=0,strokeDasharray:h,strokeDashoffset:a=0,shadowOffsetX:u=0,shadowOffsetY:f=0,shadowBlur:g=0,shadowColor:p="rgba(0, 0, 0, 0)"}=e;r.fillStyle=t,r.strokeStyle=s,r.lineWidth=n,r.lineCap=o,r.lineJoin=v[i],r.miterLimit=c,h&&r.setLineDash(h),r.lineDashOffset=a,r.shadowOffsetX=u,r.shadowOffsetY=f,r.shadowBlur=g,r.shadowColor=p}class l{constructor(e=0,t=0){this.x=e,this.y=t}static get MAX(){return new l(1/0,1/0)}static get MIN(){return new l(-1/0,-1/0)}set(e,t){return this.x=e,this.y=t,this}add(e){return this.x+=e.x,this.y+=e.y,this}sub(e){return this.x-=e.x,this.y-=e.y,this}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const t=this.x-e.x,s=this.y-e.y;return t*t+s*s}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}multiplyScalar(e){return this.x*=e,this.y*=e,this}divideScalar(e){return this.multiplyScalar(1/e)}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}normalize(){return this.divideScalar(this.length()||1)}lerpVectors(e,t,s){return this.x=e.x+(t.x-e.x)*s,this.y=e.y+(t.y-e.y)*s,this}equals(e){return this.x===e.x&&this.y===e.y}applyMatrix3(e){const t=this.x,s=this.y,n=e.elements;return this.x=n[0]*t+n[3]*s+n[6],this.y=n[1]*t+n[4]*s+n[7],this}copy(e){return this.x=e.x,this.y=e.y,this}clone(){return new l(this.x,this.y)}}class z{constructor(e=0,t=0,s=0,n=0){this.left=e,this.top=t,this.width=s,this.height=n}get x(){return this.left}set x(e){this.left=e}get y(){return this.top}set y(e){this.top=e}get right(){return this.left+this.width}get bottom(){return this.top+this.height}static from(...e){const t=e[0],s=e.slice(1).reduce((n,o)=>(n.left=Math.min(n.left,o.left),n.top=Math.min(n.top,o.top),n.right=Math.max(n.right,o.right),n.bottom=Math.max(n.bottom,o.bottom),n),{left:(t==null?void 0:t.left)??0,top:(t==null?void 0:t.top)??0,right:(t==null?void 0:t.right)??0,bottom:(t==null?void 0:t.bottom)??0});return new z(s.left,s.top,s.right-s.left,s.bottom-s.top)}translate(e,t){return this.left+=e,this.top+=t,this}getCenterPoint(){return new l((this.left+this.right)/2,(this.top+this.bottom)/2)}clone(){return new z(this.left,this.top,this.width,this.height)}toArray(){return[this.left,this.top,this.width,this.height]}}class C{constructor(e=1,t=0,s=0,n=0,o=1,i=0,c=0,h=0,a=1){w(this,"elements",[]);this.set(e,t,s,n,o,i,c,h,a)}set(e,t,s,n,o,i,c,h,a){const u=this.elements;return u[0]=e,u[1]=n,u[2]=c,u[3]=t,u[4]=o,u[5]=h,u[6]=s,u[7]=i,u[8]=a,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(e){const t=this.elements,s=e.elements;return t[0]=s[0],t[1]=s[1],t[2]=s[2],t[3]=s[3],t[4]=s[4],t[5]=s[5],t[6]=s[6],t[7]=s[7],t[8]=s[8],this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){const s=e.elements,n=t.elements,o=this.elements,i=s[0],c=s[3],h=s[6],a=s[1],u=s[4],f=s[7],g=s[2],p=s[5],y=s[8],d=n[0],m=n[3],T=n[6],E=n[1],b=n[4],S=n[7],N=n[2],L=n[5],D=n[8];return o[0]=i*d+c*E+h*N,o[3]=i*m+c*b+h*L,o[6]=i*T+c*S+h*D,o[1]=a*d+u*E+f*N,o[4]=a*m+u*b+f*L,o[7]=a*T+u*S+f*D,o[2]=g*d+p*E+y*N,o[5]=g*m+p*b+y*L,o[8]=g*T+p*S+y*D,this}invert(){const e=this.elements,t=e[0],s=e[1],n=e[2],o=e[3],i=e[4],c=e[5],h=e[6],a=e[7],u=e[8],f=u*i-c*a,g=c*h-u*o,p=a*o-i*h,y=t*f+s*g+n*p;if(y===0)return this.set(0,0,0,0,0,0,0,0,0);const d=1/y;return e[0]=f*d,e[1]=(n*a-u*s)*d,e[2]=(c*s-n*i)*d,e[3]=g*d,e[4]=(u*t-n*h)*d,e[5]=(n*o-c*t)*d,e[6]=p*d,e[7]=(s*h-a*t)*d,e[8]=(i*t-s*o)*d,this}transpose(){let e;const t=this.elements;return e=t[1],t[1]=t[3],t[3]=e,e=t[2],t[2]=t[6],t[6]=e,e=t[5],t[5]=t[7],t[7]=e,this}scale(e,t){return this.premultiply(B.makeScale(e,t)),this}rotate(e){return this.premultiply(B.makeRotation(-e)),this}translate(e,t){return this.premultiply(B.makeTranslation(e,t)),this}makeTranslation(e,t){return this.set(1,0,e,0,1,t,0,0,1),this}makeRotation(e){const t=Math.cos(e),s=Math.sin(e);return this.set(t,-s,0,s,t,0,0,0,1),this}makeScale(e,t){return this.set(e,0,0,0,t,0,0,0,1),this}fromArray(e,t=0){for(let s=0;s<9;s++)this.elements[s]=e[s+t];return this}clone(){return new this.constructor().fromArray(this.elements)}}const B=new C;function Z(r,e,t,s){const n=r*t+e*s,o=Math.sqrt(r*r+e*e)*Math.sqrt(t*t+s*s);let i=Math.acos(Math.max(-1,Math.min(1,n/o)));return r*s-e*t<0&&(i=-i),i}function J(r,e,t,s,n,o,i,c){if(e===0||t===0){r.lineTo(c.x,c.y);return}s=s*Math.PI/180,e=Math.abs(e),t=Math.abs(t);const h=(i.x-c.x)/2,a=(i.y-c.y)/2,u=Math.cos(s)*h+Math.sin(s)*a,f=-Math.sin(s)*h+Math.cos(s)*a;let g=e*e,p=t*t;const y=u*u,d=f*f,m=y/g+d/p;if(m>1){const Tt=Math.sqrt(m);e=Tt*e,t=Tt*t,g=e*e,p=t*t}const T=g*d+p*y,E=(g*p-T)/T;let b=Math.sqrt(Math.max(0,E));n===o&&(b=-b);const S=b*e*f/t,N=-b*t*u/e,L=Math.cos(s)*S-Math.sin(s)*N+(i.x+c.x)/2,D=Math.sin(s)*S+Math.cos(s)*N+(i.y+c.y)/2,Y=Z(1,0,(u-S)/e,(f-N)/t),j=Z((u-S)/e,(f-N)/t,(-u-S)/e,(-f-N)/t)%(Math.PI*2);r.ellipse(L,D,e,t,s,Y,Y+j,o===1)}function O(r,e){return r-(e-r)}function U(r,e){const t=new l,s=new l;for(let n=0,o=r.length;n<o;n++){const i=r[n];if(i.type==="m"||i.type==="M")i.type==="m"?t.add(i):t.copy(i),e.moveTo(t.x,t.y),s.copy(t);else if(i.type==="h"||i.type==="H")i.type==="h"?t.x+=i.x:t.x=i.x,e.lineTo(t.x,t.y),s.copy(t);else if(i.type==="v"||i.type==="V")i.type==="v"?t.y+=i.y:t.y=i.y,e.lineTo(t.x,t.y),s.copy(t);else if(i.type==="l"||i.type==="L")i.type==="l"?t.add(i):t.copy(i),e.lineTo(t.x,t.y),s.copy(t);else if(i.type==="c"||i.type==="C")i.type==="c"?(e.bezierCurveTo(t.x+i.x1,t.y+i.y1,t.x+i.x2,t.y+i.y2,t.x+i.x,t.y+i.y),s.x=t.x+i.x2,s.y=t.y+i.y2,t.add(i)):(e.bezierCurveTo(i.x1,i.y1,i.x2,i.y2,i.x,i.y),s.x=i.x2,s.y=i.y2,t.copy(i));else if(i.type==="s"||i.type==="S")i.type==="s"?(e.bezierCurveTo(O(t.x,s.x),O(t.y,s.y),t.x+i.x2,t.y+i.y2,t.x+i.x,t.y+i.y),s.x=t.x+i.x2,s.y=t.y+i.y2,t.add(i)):(e.bezierCurveTo(O(t.x,s.x),O(t.y,s.y),i.x2,i.y2,i.x,i.y),s.x=i.x2,s.y=i.y2,t.copy(i));else if(i.type==="q"||i.type==="Q")i.type==="q"?(e.quadraticCurveTo(t.x+i.x1,t.y+i.y1,t.x+i.x,t.y+i.y),s.x=t.x+i.x1,s.y=t.y+i.y1,t.add(i)):(e.quadraticCurveTo(i.x1,i.y1,i.x,i.y),s.x=i.x1,s.y=i.y1,t.copy(i));else if(i.type==="t"||i.type==="T"){const c=O(t.x,s.x),h=O(t.y,s.y);s.x=c,s.y=h,i.type==="t"?(e.quadraticCurveTo(c,h,t.x+i.x,t.y+i.y),t.add(i)):(e.quadraticCurveTo(c,h,i.x,i.y),t.copy(i))}else if(i.type==="a"||i.type==="A"){const c=t.clone();if(i.type==="a"){if(i.x===0&&i.y===0)continue;t.add(i)}else{if(t.equals(i))continue;t.copy(i)}s.copy(t),J(e,i.rx,i.ry,i.angle,i.largeArcFlag,i.sweepFlag,c,t)}else i.type==="z"||i.type==="Z"?(e.startPoint&&t.copy(e.startPoint),e.closePath()):console.warn("Unsupported commands",i)}}const P={SEPARATOR:/[ \t\r\n,.\-+]/,WHITESPACE:/[ \t\r\n]/,DIGIT:/\d/,SIGN:/[-+]/,POINT:/\./,COMMA:/,/,EXP:/e/i,FLAGS:/[01]/};function A(r,e,t=0){let c=0,h=!0,a="",u="";const f=[];function g(m,T,E){const b=new SyntaxError(`Unexpected character "${m}" at index ${T}.`);throw b.partial=E,b}function p(){a!==""&&(u===""?f.push(Number(a)):f.push(Number(a)*10**Number(u))),a="",u=""}let y;const d=r.length;for(let m=0;m<d;m++){if(y=r[m],Array.isArray(e)&&e.includes(f.length%t)&&P.FLAGS.test(y)){c=1,a=y,p();continue}if(c===0){if(P.WHITESPACE.test(y))continue;if(P.DIGIT.test(y)||P.SIGN.test(y)){c=1,a=y;continue}if(P.POINT.test(y)){c=2,a=y;continue}P.COMMA.test(y)&&(h&&g(y,m,f),h=!0)}if(c===1){if(P.DIGIT.test(y)){a+=y;continue}if(P.POINT.test(y)){a+=y,c=2;continue}if(P.EXP.test(y)){c=3;continue}P.SIGN.test(y)&&a.length===1&&P.SIGN.test(a[0])&&g(y,m,f)}if(c===2){if(P.DIGIT.test(y)){a+=y;continue}if(P.EXP.test(y)){c=3;continue}P.POINT.test(y)&&a[a.length-1]==="."&&g(y,m,f)}if(c===3){if(P.DIGIT.test(y)){u+=y;continue}if(P.SIGN.test(y)){if(u===""){u+=y;continue}u.length===1&&P.SIGN.test(u)&&g(y,m,f)}}P.WHITESPACE.test(y)?(p(),c=0,h=!1):P.COMMA.test(y)?(p(),c=0,h=!0):P.SIGN.test(y)?(p(),c=1,a=y):P.POINT.test(y)?(p(),c=2,a=y):g(y,m,f)}return p(),f}function wt(r){switch(r.type){case"m":case"M":return`${r.type} ${r.x} ${r.y}`;case"h":case"H":return`${r.type} ${r.x}`;case"v":case"V":return`${r.type} ${r.y}`;case"l":case"L":return`${r.type} ${r.x} ${r.y}`;case"c":case"C":return`${r.type} ${r.x1} ${r.y1} ${r.x2} ${r.y2} ${r.x} ${r.y}`;case"s":case"S":return`${r.type} ${r.x2} ${r.y2} ${r.x} ${r.y}`;case"q":case"Q":return`${r.type} ${r.x1} ${r.y1} ${r.x} ${r.y}`;case"t":case"T":return`${r.type} ${r.x} ${r.y}`;case"a":case"A":return`${r.type} ${r.rx} ${r.ry} ${r.angle} ${r.largeArcFlag} ${r.sweepFlag} ${r.x} ${r.y}`;case"z":case"Z":return r.type;default:return""}}function K(r){let e="";for(let t=0,s=r.length;t<s;t++)e+=`${wt(r[t])} `;return e}const vt=/[a-df-z][^a-df-z]*/gi;function G(r){const e=[],t=r.match(vt);if(!t)return e;for(let s=0,n=t.length;s<n;s++){const o=t[s],i=o.charAt(0),c=o.slice(1).trim();let h;switch(i){case"m":case"M":h=A(c);for(let a=0,u=h.length;a<u;a+=2)a===0?e.push({type:i,x:h[a],y:h[a+1]}):e.push({type:i==="m"?"l":"L",x:h[a],y:h[a+1]});break;case"h":case"H":h=A(c);for(let a=0,u=h.length;a<u;a++)e.push({type:i,x:h[a]});break;case"v":case"V":h=A(c);for(let a=0,u=h.length;a<u;a++)e.push({type:i,y:h[a]});break;case"l":case"L":h=A(c);for(let a=0,u=h.length;a<u;a+=2)e.push({type:i,x:h[a],y:h[a+1]});break;case"c":case"C":h=A(c);for(let a=0,u=h.length;a<u;a+=6)e.push({type:i,x1:h[a],y1:h[a+1],x2:h[a+2],y2:h[a+3],x:h[a+4],y:h[a+5]});break;case"s":case"S":h=A(c);for(let a=0,u=h.length;a<u;a+=4)e.push({type:i,x2:h[a],y2:h[a+1],x:h[a+2],y:h[a+3]});break;case"q":case"Q":h=A(c);for(let a=0,u=h.length;a<u;a+=4)e.push({type:i,x1:h[a],y1:h[a+1],x:h[a+2],y:h[a+3]});break;case"t":case"T":h=A(c);for(let a=0,u=h.length;a<u;a+=2)e.push({type:i,x:h[a],y:h[a+1]});break;case"a":case"A":h=A(c,[3,4],7);for(let a=0,u=h.length;a<u;a+=7)e.push({type:i,rx:h[a],ry:h[a+1],angle:h[a+2],largeArcFlag:h[a+3],sweepFlag:h[a+4],x:h[a+5],y:h[a+6]});break;case"z":case"Z":e.push({type:i});break;default:console.warn(o)}}return e}class k{constructor(){w(this,"arcLengthDivisions",200);w(this,"_cacheArcLengths");w(this,"_needsUpdate",!1)}getPointAt(e,t=new l){return this.getPoint(this.getUtoTmapping(e),t)}getPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPoint(s/e));return t}getSpacedPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPointAt(s/e));return t}getLength(){const e=this.getLengths();return e[e.length-1]}getLengths(e=this.arcLengthDivisions){if(this._cacheArcLengths&&this._cacheArcLengths.length===e+1&&!this._needsUpdate)return this._cacheArcLengths;this._needsUpdate=!1;const t=[];let s,n=this.getPoint(0),o=0;t.push(0);for(let i=1;i<=e;i++)s=this.getPoint(i/e),o+=s.distanceTo(n),t.push(o),n=s;return this._cacheArcLengths=t,t}updateArcLengths(){this._needsUpdate=!0,this.getLengths()}getUtoTmapping(e,t){const s=this.getLengths();let n=0;const o=s.length;let i;t?i=t:i=e*s[o-1];let c=0,h=o-1,a;for(;c<=h;)if(n=Math.floor(c+(h-c)/2),a=s[n]-i,a<0)c=n+1;else if(a>0)h=n-1;else{h=n;break}if(n=h,s[n]===i)return n/(o-1);const u=s[n],g=s[n+1]-u,p=(i-u)/g;return(n+p)/(o-1)}getTangent(e,t=new l){const n=Math.max(0,e-1e-4),o=Math.min(1,e+1e-4);return t.copy(this.getPoint(o).sub(this.getPoint(n)).normalize())}getTangentAt(e,t){return this.getTangent(this.getUtoTmapping(e),t)}transformPoint(e){return this}transform(e){return this.transformPoint(t=>t.applyMatrix3(e)),this}getMinMax(e=l.MAX,t=l.MIN){return this.getPoints().forEach(s=>{e.x=Math.min(e.x,s.x),e.y=Math.min(e.y,s.y),t.x=Math.max(t.x,s.x),t.y=Math.max(t.y,s.y)}),{min:e,max:t}}getBoundingBox(){const{min:e,max:t}=this.getMinMax();return new z(e.x,e.y,t.x-e.x,t.y-e.y)}getCommands(){return this.getPoints().map((e,t)=>t===0?{type:"M",x:e.x,y:e.y}:{type:"L",x:e.x,y:e.y})}getData(){return K(this.getCommands())}drawTo(e){return this}copy(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}clone(){return new this.constructor().copy(this)}}class _ extends k{constructor(e,t,s=0,n=Math.PI*2){super(),this.center=e,this.radius=t,this.start=s,this.end=n}getPoint(e){const{radius:t,center:s}=this;return s.clone().add(this.getNormal(e).clone().multiplyScalar(t))}getTangent(e){const{x:t,y:s}=this.getNormal(e);return new l(-s,t)}getNormal(e){const{start:t,end:s}=this,n=e*(s-t)+t-.5*Math.PI;return new l(Math.cos(n),Math.sin(n))}transformPoint(e){return e(this.center),this}getMinMax(e=l.MAX,t=l.MIN){return e.x=Math.min(e.x,this.center.x-this.radius),e.y=Math.min(e.y,this.center.y-this.radius),t.x=Math.max(t.x,this.center.x+this.radius),t.y=Math.max(t.y,this.center.y+this.radius),{min:e,max:t}}}function tt(r,e,t,s,n){const o=(s-e)*.5,i=(n-t)*.5,c=r*r,h=r*c;return(2*t-2*s+o+i)*h+(-3*t+3*s-2*o-i)*c+o*r+t}function bt(r,e){const t=1-r;return t*t*e}function Ct(r,e){return 2*(1-r)*r*e}function At(r,e){return r*r*e}function et(r,e,t,s){return bt(r,e)+Ct(r,t)+At(r,s)}function kt(r,e){const t=1-r;return t*t*t*e}function It(r,e){const t=1-r;return 3*t*t*r*e}function St(r,e){return 3*(1-r)*r*r*e}function Nt(r,e){return r*r*r*e}function st(r,e,t,s,n){return kt(r,e)+It(r,t)+St(r,s)+Nt(r,n)}class nt extends k{constructor(e=new l,t=new l,s=new l,n=new l){super(),this.start=e,this.startControl=t,this.endControl=s,this.end=n}getPoint(e,t=new l){const{start:s,startControl:n,endControl:o,end:i}=this;return t.set(st(e,s.x,n.x,o.x,i.x),st(e,s.y,n.y,o.y,i.y)),t}transformPoint(e){return e(this.start),e(this.startControl),e(this.endControl),e(this.end),this}_solveQuadratic(e,t,s){const n=t*t-4*e*s;if(n<0)return[];const o=Math.sqrt(n),i=(-t+o)/(2*e),c=(-t-o)/(2*e);return[i,c].filter(h=>h>=0&&h<=1)}getMinMax(e=l.MAX,t=l.MIN){const s=this.start,n=this.startControl,o=this.endControl,i=this.end,c=this._solveQuadratic(3*(n.x-s.x),6*(o.x-n.x),3*(i.x-o.x)),h=this._solveQuadratic(3*(n.y-s.y),6*(o.y-n.y),3*(i.y-o.y)),a=[0,1,...c,...h];return((f,g)=>{for(const p of f)for(let y=0;y<=g;y++){const d=y/g-.5,m=Math.min(1,Math.max(0,p+d)),T=this.getPoint(m);e.x=Math.min(e.x,T.x),e.y=Math.min(e.y,T.y),t.x=Math.max(t.x,T.x),t.y=Math.max(t.y,T.y)}})(a,10),{min:e,max:t}}getCommands(){const{start:e,startControl:t,endControl:s,end:n}=this;return[{type:"M",x:e.x,y:e.y},{type:"C",x1:t.x,y1:t.y,x2:s.x,y2:s.y,x:n.x,y:n.y}]}drawTo(e){const{startControl:t,endControl:s,end:n}=this;return e.bezierCurveTo(t.x,t.y,s.x,s.y,n.x,n.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.startControl.copy(e.startControl),this.endControl.copy(e.endControl),this.end.copy(e.end),this}}const $t=new C,rt=new C,it=new C,F=new l;class ot extends k{constructor(e=new l,t=1,s=1,n=0,o=0,i=Math.PI*2,c=!1){super(),this.center=e,this.radiusX=t,this.radiusY=s,this.rotation=n,this.startAngle=o,this.endAngle=i,this.clockwise=c}getPoint(e,t=new l){const s=Math.PI*2;let n=this.endAngle-this.startAngle;const o=Math.abs(n)<Number.EPSILON;for(;n<0;)n+=s;for(;n>s;)n-=s;n<Number.EPSILON&&(o?n=0:n=s),this.clockwise&&!o&&(n===s?n=-s:n=n-s);const i=this.startAngle+e*n;let c=this.center.x+this.radiusX*Math.cos(i),h=this.center.y+this.radiusY*Math.sin(i);if(this.rotation!==0){const a=Math.cos(this.rotation),u=Math.sin(this.rotation),f=c-this.center.x,g=h-this.center.y;c=f*a-g*u+this.center.x,h=f*u+g*a+this.center.y}return t.set(c,h)}getCommands(){const{center:e,radiusX:t,radiusY:s,startAngle:n,endAngle:o,clockwise:i,rotation:c}=this,{x:h,y:a}=e,u=h+t*Math.cos(n)*Math.cos(c)-s*Math.sin(n)*Math.sin(c),f=a+t*Math.cos(n)*Math.sin(c)+s*Math.sin(n)*Math.cos(c),g=Math.abs(n-o),p=g>Math.PI?1:0,y=i?1:0,d=c*180/Math.PI;if(g>=2*Math.PI){const m=n+Math.PI,T=h+t*Math.cos(m)*Math.cos(c)-s*Math.sin(m)*Math.sin(c),E=a+t*Math.cos(m)*Math.sin(c)+s*Math.sin(m)*Math.cos(c);return[{type:"M",x:u,y:f},{type:"A",rx:t,ry:s,angle:d,largeArcFlag:0,sweepFlag:y,x:T,y:E},{type:"A",rx:t,ry:s,angle:d,largeArcFlag:0,sweepFlag:y,x:u,y:f}]}else{const m=h+t*Math.cos(o)*Math.cos(c)-s*Math.sin(o)*Math.sin(c),T=a+t*Math.cos(o)*Math.sin(c)+s*Math.sin(o)*Math.cos(c);return[{type:"M",x:u,y:f},{type:"A",rx:t,ry:s,angle:d,largeArcFlag:p,sweepFlag:y,x:m,y:T}]}}drawTo(e){const{center:t,radiusX:s,radiusY:n,rotation:o,startAngle:i,endAngle:c,clockwise:h}=this;return e.ellipse(t.x,t.y,s,n,o,i,c,!h),this}transform(e){return F.set(this.center.x,this.center.y),F.applyMatrix3(e),this.center.x=F.x,this.center.y=F.y,Dt(e)?Et(this,e):Lt(this,e),this}transformPoint(e){return e(this.center),this}getMinMax(e=l.MAX,t=l.MIN){const{center:s,radiusX:n,radiusY:o,rotation:i}=this,{x:c,y:h}=s,a=Math.cos(i),u=Math.sin(i),f=Math.sqrt(n*n*a*a+o*o*u*u),g=Math.sqrt(n*n*u*u+o*o*a*a);return e.x=Math.min(e.x,c-f),e.y=Math.min(e.y,h-g),t.x=Math.max(t.x,c+f),t.y=Math.max(t.y,h+g),{min:e,max:t}}copy(e){return super.copy(e),this.center.x=e.center.x,this.center.y=e.center.y,this.radiusX=e.radiusX,this.radiusY=e.radiusY,this.startAngle=e.startAngle,this.endAngle=e.endAngle,this.clockwise=e.clockwise,this.rotation=e.rotation,this}}function Et(r,e){const t=r.radiusX,s=r.radiusY,n=Math.cos(r.rotation),o=Math.sin(r.rotation),i=new l(t*n,t*o),c=new l(-s*o,s*n),h=i.applyMatrix3(e),a=c.applyMatrix3(e),u=$t.set(h.x,a.x,0,h.y,a.y,0,0,0,1),f=rt.copy(u).invert(),y=it.copy(f).transpose().multiply(f).elements,d=qt(y[0],y[1],y[4]),m=Math.sqrt(d.rt1),T=Math.sqrt(d.rt2);if(r.radiusX=1/m,r.radiusY=1/T,r.rotation=Math.atan2(d.sn,d.cs),!((r.endAngle-r.startAngle)%(2*Math.PI)<Number.EPSILON)){const b=rt.set(m,0,0,0,T,0,0,0,1),S=it.set(d.cs,d.sn,0,-d.sn,d.cs,0,0,0,1),N=b.multiply(S).multiply(u),L=D=>{const{x:Y,y:j}=new l(Math.cos(D),Math.sin(D)).applyMatrix3(N);return Math.atan2(j,Y)};r.startAngle=L(r.startAngle),r.endAngle=L(r.endAngle),at(e)&&(r.clockwise=!r.clockwise)}}function Lt(r,e){const t=ht(e),s=ct(e);r.radiusX*=t,r.radiusY*=s;const n=t>Number.EPSILON?Math.atan2(e.elements[1],e.elements[0]):Math.atan2(-e.elements[3],e.elements[4]);r.rotation+=n,at(e)&&(r.startAngle*=-1,r.endAngle*=-1,r.clockwise=!r.clockwise)}function at(r){const e=r.elements;return e[0]*e[4]-e[1]*e[3]<0}function Dt(r){const e=r.elements,t=e[0]*e[3]+e[1]*e[4];if(t===0)return!1;const s=ht(r),n=ct(r);return Math.abs(t/(s*n))>Number.EPSILON}function ht(r){const e=r.elements;return Math.sqrt(e[0]*e[0]+e[1]*e[1])}function ct(r){const e=r.elements;return Math.sqrt(e[3]*e[3]+e[4]*e[4])}function qt(r,e,t){let s,n,o,i,c;const h=r+t,a=r-t,u=Math.sqrt(a*a+4*e*e);return h>0?(s=.5*(h+u),c=1/s,n=r*c*t-e*c*e):h<0?n=.5*(h-u):(s=.5*u,n=-.5*u),a>0?o=a+u:o=a-u,Math.abs(o)>2*Math.abs(e)?(c=-2*e/o,i=1/Math.sqrt(1+c*c),o=c*i):Math.abs(e)===0?(o=1,i=0):(c=-.5*o/e,o=1/Math.sqrt(1+c*c),i=c*o),a>0&&(c=o,o=-i,i=c),{rt1:s,rt2:n,cs:o,sn:i}}class X extends k{constructor(e=new l,t=new l){super(),this.start=e,this.end=t}getPoint(e,t=new l){return e===1?t.copy(this.end):t.copy(this.end).sub(this.start).multiplyScalar(e).add(this.start),t}getPointAt(e,t=new l){return this.getPoint(e,t)}getTangent(e,t=new l){return t.subVectors(this.end,this.start).normalize()}getTangentAt(e,t=new l){return this.getTangent(e,t)}getNormal(e,t=new l){const{x:s,y:n}=this.getPoint(e).sub(this.start);return t.set(n,-s).normalize()}transformPoint(e){return e(this.start),e(this.end),this}getMinMax(e=l.MAX,t=l.MIN){const{start:s,end:n}=this;return e.x=Math.min(e.x,s.x,n.x),e.y=Math.min(e.y,s.y,n.y),t.x=Math.max(t.x,s.x,n.x),t.y=Math.max(t.y,s.y,n.y),{min:e,max:t}}getCommands(){const{start:e,end:t}=this;return[{type:"M",x:e.x,y:e.y},{type:"L",x:t.x,y:t.y}]}drawTo(e){const{end:t}=this;return e.lineTo(t.x,t.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.end.copy(e.end),this}}class zt extends k{constructor(t,s,n=0,o=1){super();w(this,"curveT",0);this.center=t,this.size=s,this.start=n,this.end=o,this.update()}update(){const{x:t,y:s}=this.center,n=new l(t+.5*this.size,s-.5*this.size),o=new l(t-.5*this.size,s-.5*this.size),i=new l(t,s+.5*this.size),c=new _(n,Math.SQRT1_2*this.size,-.25*Math.PI,.75*Math.PI),h=new _(o,Math.SQRT1_2*this.size,-.75*Math.PI,.25*Math.PI),a=new _(i,.5*Math.SQRT1_2*this.size,.75*Math.PI,1.25*Math.PI),u=new l(t,s+this.size),f=new l(t+this.size,s),g=new l().lerpVectors(f,u,.75),p=new l(t-this.size,s),y=new l().lerpVectors(p,u,.75),d=new X(f,g),m=new X(y,p);return this.curves=[c,d,a,m,h],this}getPoint(t){return this.getCurve(t).getPoint(this.curveT)}getPointAt(t){return this.getPoint(t)}getCurve(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=9*Math.PI/8+1.5;let n;const o=.5*Math.PI;return s<o?(n=0,this.curveT=s/o):s<o+.75?(n=1,this.curveT=(s-o)/.75):s<5*Math.PI/8+.75?(n=2,this.curveT=(s-o-.75)/(Math.PI/8)):s<5*Math.PI/8+1.5?(n=3,this.curveT=(s-5*Math.PI/8-.75)/.75):(n=4,this.curveT=(s-5*Math.PI/8-1.5)/o),this.curves[n]}getTangent(t){return this.getCurve(t).getTangent(this.curveT)}getNormal(t){return this.getCurve(t).getNormal(this.curveT)}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class Xt extends k{constructor(t,s=0,n=0,o=0,i=1){super();w(this,"curves",[]);w(this,"curveT",0);w(this,"points",[]);this.center=t,this.radius=s,this.number=n,this.start=o,this.end=i,this.update()}update(){for(let t=0;t<this.number;t++){let s=t*2*Math.PI/this.number;s-=.5*Math.PI,this.points.push(new l(this.radius*Math.cos(s),this.radius*Math.sin(s)).add(this.center))}for(let t=0;t<this.number;t++)this.curves.push(new X(this.points[t],this.points[(t+1)%this.number]));return this}getCurve(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1);const n=s*this.number,o=Math.floor(n);return this.curveT=n-o,this.curves[o]}getPoint(t,s){return this.getCurve(t).getPoint(this.curveT,s)}getPointAt(t,s){return this.getPoint(t,s)}getTangent(t,s){return this.getCurve(t).getTangent(this.curveT,s)}getNormal(t,s){return this.getCurve(t).getNormal(this.curveT,s)}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class ut extends k{constructor(e=new l,t=new l,s=new l){super(),this.start=e,this.control=t,this.end=s}getPoint(e,t=new l){const{start:s,control:n,end:o}=this;return t.set(et(e,s.x,n.x,o.x),et(e,s.y,n.y,o.y)),t}transformPoint(e){return e(this.start),e(this.control),e(this.end),this}getMinMax(e=l.MAX,t=l.MIN){const{start:s,control:n,end:o}=this,i=.5*(s.x+n.x),c=.5*(s.y+n.y),h=.5*(s.x+o.x),a=.5*(s.y+o.y);return e.x=Math.min(e.x,s.x,o.x,i,h),e.y=Math.min(e.y,s.y,o.y,c,a),t.x=Math.max(t.x,s.x,o.x,i,h),t.y=Math.max(t.y,s.y,o.y,c,a),{min:e,max:t}}getCommands(){const{start:e,control:t,end:s}=this;return[{type:"M",x:e.x,y:e.y},{type:"Q",x1:t.x,y1:t.y,x:s.x,y:s.y}]}drawTo(e){const{control:t,end:s}=this;return e.quadraticCurveTo(t.x,t.y,s.x,s.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.control.copy(e.control),this.end.copy(e.end),this}}class lt extends k{constructor(t,s,n=1,o=0,i=1){super();w(this,"curves",[]);w(this,"curveT",0);this.center=t,this.rx=s,this.aspectRatio=n,this.start=o,this.end=i,this.update()}get x(){return this.center.x-this.rx}get y(){return this.center.y-this.rx/this.aspectRatio}get width(){return this.rx*2}get height(){return this.rx/this.aspectRatio*2}update(){const{x:t,y:s}=this.center,n=this.rx,o=this.rx/this.aspectRatio,i=[new l(t-n,s-o),new l(t+n,s-o),new l(t+n,s+o),new l(t-n,s+o)];for(let c=0;c<4;c++)this.curves.push(new X(i[c].clone(),i[(c+1)%4].clone()));return this}getCurve(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=(1+this.aspectRatio)*2;let n;return s<this.aspectRatio?(n=0,this.curveT=s/this.aspectRatio):s<this.aspectRatio+1?(n=1,this.curveT=(s-this.aspectRatio)/1):s<2*this.aspectRatio+1?(n=2,this.curveT=(s-this.aspectRatio-1)/this.aspectRatio):(n=3,this.curveT=(s-2*this.aspectRatio-1)/1),this.curves[n]}getPoint(t,s){return this.getCurve(t).getPoint(this.curveT,s)}getPointAt(t,s){return this.getPoint(t,s)}getTangent(t,s){return this.getCurve(t).getTangent(this.curveT,s)}getNormal(t,s){return this.getCurve(t).getNormal(this.curveT,s)}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class ft extends k{constructor(e=[]){super(),this.points=e}getPoint(e,t=new l){const{points:s}=this,n=(s.length-1)*e,o=Math.floor(n),i=n-o,c=s[o===0?o:o-1],h=s[o],a=s[o>s.length-2?s.length-1:o+1],u=s[o>s.length-3?s.length-1:o+2];return t.set(tt(i,c.x,h.x,a.x,u.x),tt(i,c.y,h.y,a.y,u.y)),t}transformPoint(e){return this.points.forEach(t=>e(t)),this}copy(e){super.copy(e),this.points=[];for(let t=0,s=e.points.length;t<s;t++)this.points.push(e.points[t].clone());return this}}class R extends k{constructor(t){super();w(this,"curves",[]);w(this,"startPoint");w(this,"currentPoint",new l);w(this,"autoClose",!1);w(this,"_cacheLengths",[]);t&&this.addPoints(t)}addCurve(t){return this.curves.push(t),this}addPoints(t){this.moveTo(t[0].x,t[0].y);for(let s=1,n=t.length;s<n;s++){const{x:o,y:i}=t[s];this.lineTo(o,i)}return this}addCommands(t){return U(t,this),this}addData(t){return this.addCommands(G(t)),this}getPoint(t,s=new l){const n=t*this.getLength(),o=this.getCurveLengths();let i=0;for(;i<o.length;){if(o[i]>=n){const c=o[i]-n,h=this.curves[i],a=h.getLength();return h.getPointAt(a===0?0:1-c/a,s)}i++}return s}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){super.updateArcLengths(),this._cacheLengths=[],this.getCurveLengths()}getCurveLengths(){if(this._cacheLengths.length===this.curves.length)return this._cacheLengths;const t=[];let s=0;for(let n=0,o=this.curves.length;n<o;n++)s+=this.curves[n].getLength(),t.push(s);return this._cacheLengths=t,t}getSpacedPoints(t=40){const s=[];for(let n=0;n<=t;n++)s.push(this.getPoint(n/t));return this.autoClose&&s.push(s[0]),s}getPoints(t=12){const s=[],n=this.curves;let o;for(let i=0,c=n.length;i<c;i++){const a=n[i].getPoints(t);for(let u=0;u<a.length;u++){const f=a[u];o!=null&&o.equals(f)||(s.push(f),o=f)}}return this.autoClose&&s.length>1&&!s[s.length-1].equals(s[0])&&s.push(s[0]),s}_setCurrentPoint(t){return this.currentPoint.copy(t),this.startPoint||(this.startPoint=this.currentPoint.clone()),this}closePath(){const t=this.startPoint;if(t){const s=this.currentPoint;t.equals(s)||(this.curves.push(new X(s.clone(),t)),this.currentPoint.copy(t)),this.startPoint=void 0}return this}moveTo(t,s){return this.currentPoint.set(t,s),this.startPoint=this.currentPoint.clone(),this}lineTo(t,s){return this.currentPoint.equals({x:t,y:s})||this.curves.push(new X(this.currentPoint.clone(),new l(t,s))),this._setCurrentPoint({x:t,y:s}),this}bezierCurveTo(t,s,n,o,i,c){return this.currentPoint.equals({x:i,y:c})||this.curves.push(new nt(this.currentPoint.clone(),new l(t,s),new l(n,o),new l(i,c))),this._setCurrentPoint({x:i,y:c}),this}quadraticCurveTo(t,s,n,o){return this.currentPoint.equals({x:n,y:o})||this.curves.push(new ut(this.currentPoint.clone(),new l(t,s),new l(n,o))),this._setCurrentPoint({x:n,y:o}),this}arc(t,s,n,o,i,c){return this.ellipse(t,s,n,n,0,o,i,c),this}relativeArc(t,s,n,o,i,c){const h=this.currentPoint;return this.arc(t+h.x,s+h.y,n,o,i,c),this}arcTo(t,s,n,o,i){return console.warn("Method arcTo not supported yet"),this}ellipse(t,s,n,o,i,c,h,a=!0){const u=new ot(new l(t,s),n,o,i,c,h,!a);if(this.curves.length>0){const f=u.getPoint(0);f.equals(this.currentPoint)||this.lineTo(f.x,f.y)}return this.curves.push(u),this._setCurrentPoint(u.getPoint(1)),this}relativeEllipse(t,s,n,o,i,c,h,a){const u=this.currentPoint;return this.ellipse(t+u.x,s+u.y,n,o,i,c,h,a),this}rect(t,s,n,o){return this.curves.push(new lt(new l(t+n/2,s+o/2),n/2,n/o)),this._setCurrentPoint({x:t,y:s}),this}splineThru(t){return this.curves.push(new ft([this.currentPoint.clone()].concat(t))),this._setCurrentPoint(t[t.length-1]),this}transformPoint(t){return this.curves.forEach(s=>s.transformPoint(t)),this}getMinMax(t=l.MAX,s=l.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getBoundingBox(){const{min:t,max:s}=this.getMinMax();return new z(t.x,t.y,s.x-t.x,s.y-t.y)}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){var n;const s=(n=this.curves[0])==null?void 0:n.getPoint(0);return s&&t.moveTo(s.x,s.y),this.curves.forEach(o=>o.drawTo(t)),this.autoClose&&t.closePath(),this}copy(t){super.copy(t),this.curves=[];for(let s=0,n=t.curves.length;s<n;s++)this.curves.push(t.curves[s].clone());return this.autoClose=t.autoClose,this.currentPoint.copy(t.currentPoint),this}}function Ot(r){return r.replace(/[^a-z0-9]/gi,"-").replace(/\B([A-Z])/g,"-$1").toLowerCase()}class I{constructor(e){w(this,"currentPath",new R);w(this,"paths",[this.currentPath]);w(this,"style",{});e&&(e instanceof I?this.addPath(e):Array.isArray(e)?this.addCommands(e):this.addData(e))}get startPoint(){return this.currentPath.startPoint}get currentPoint(){return this.currentPath.currentPoint}get strokeWidth(){return this.style.strokeWidth??((this.style.stroke??"none")==="none"?0:1)}addPath(e){return e instanceof I?this.paths.push(...e.paths.map(t=>t.clone())):this.paths.push(e),this}closePath(){const e=this.startPoint;return e&&(this.currentPath.closePath(),this.currentPath.curves.length>0&&(this.currentPath=new R().moveTo(e.x,e.y),this.paths.push(this.currentPath))),this}moveTo(e,t){const{currentPoint:s,curves:n}=this.currentPath;return s.equals({x:e,y:t})||(n.length?(this.currentPath=new R().moveTo(e,t),this.paths.push(this.currentPath)):this.currentPath.moveTo(e,t)),this}lineTo(e,t){return this.currentPath.lineTo(e,t),this}bezierCurveTo(e,t,s,n,o,i){return this.currentPath.bezierCurveTo(e,t,s,n,o,i),this}quadraticCurveTo(e,t,s,n){return this.currentPath.quadraticCurveTo(e,t,s,n),this}arc(e,t,s,n,o,i){return this.currentPath.arc(e,t,s,n,o,i),this}arcTo(e,t,s,n,o){return this.currentPath.arcTo(e,t,s,n,o),this}ellipse(e,t,s,n,o,i,c,h){return this.currentPath.ellipse(e,t,s,n,o,i,c,h),this}rect(e,t,s,n){return this.currentPath.rect(e,t,s,n),this}addCommands(e){return U(e,this),this}addData(e){return this.addCommands(G(e)),this}splineThru(e){return this.currentPath.splineThru(e),this}forEachCurve(e){return this.paths.forEach(t=>t.curves.forEach(s=>e(s))),this}transformPoint(e){return this.forEachCurve(t=>t.transformPoint(e)),this}transform(e){this.forEachCurve(o=>o.transform(e));const t=new l,s=o=>(t.x=o,t.applyMatrix3(e),t.x),n=this.style;return n.strokeWidth&&(n.strokeWidth=s(n.strokeWidth)),n.strokeDashoffset&&(n.strokeDashoffset=s(n.strokeDashoffset)),n.strokeDasharray&&(n.strokeDasharray=n.strokeDasharray.map(o=>s(o))),this}getMinMax(e=l.MAX,t=l.MIN,s=!0){if(this.forEachCurve(n=>n.getMinMax(e,t)),s){const n=this.strokeWidth/2;e.x-=n,e.y-=n,t.x+=n,t.y+=n}return{min:e,max:t}}getBoundingBox(e=!0){const{min:t,max:s}=this.getMinMax(void 0,void 0,e);return new z(t.x,t.y,s.x-t.x,s.y-t.y)}getCommands(){return this.paths.flatMap(e=>e.getCommands())}getData(){return this.paths.map(e=>e.getData()).join(" ")}getSvgPathXml(){const e={...this.style,fill:this.style.fill??"#000",stroke:this.style.stroke??"none"},t={};for(const n in e)e[n]!==void 0&&(t[Ot(n)]=e[n]);Object.assign(t,{"stroke-width":`${this.strokeWidth}px`});let s="";for(const n in t)t[n]!==void 0&&(s+=`${n}:${t[n]};`);return`<path d="${this.getData()}" style="${s}"></path>`}getSvgXml(){const{x:e,y:t,width:s,height:n}=this.getBoundingBox(),o=this.getSvgPathXml();return`<svg viewBox="${e} ${t} ${s} ${n}" width="${s}px" height="${n}px" xmlns="http://www.w3.org/2000/svg">${o}</svg>`}getSvgDataUri(){return`data:image/svg+xml;base64,${btoa(this.getSvgXml())}`}drawTo(e,t=!0){const{fill:s="#000",stroke:n="none"}=this.style;t&&q(e,this.style),this.paths.forEach(o=>{o.drawTo(e)}),s!=="none"&&e.fill(),n!=="none"&&e.stroke()}copy(e){return this.currentPath=e.currentPath.clone(),this.paths=e.paths.map(t=>t.clone()),this.style={...e.style},this}toSvg(){return new DOMParser().parseFromString(this.getSvgXml(),"image/svg+xml").documentElement}toCanvas(e=2){const{left:t,top:s,width:n,height:o}=this.getBoundingBox(),i=document.createElement("canvas");i.width=n*e,i.height=o*e,i.style.width=`${n}px`,i.style.height=`${o}px`;const c=i.getContext("2d");return c&&(c.scale(e,e),c.translate(-t,-s),this.drawTo(c)),i}clone(){return new this.constructor().copy(this)}}const Q="px",yt=90,gt=["mm","cm","in","pt","pc","px"],H={mm:{mm:1,cm:.1,in:1/25.4,pt:72/25.4,pc:6/25.4,px:-1},cm:{mm:10,cm:1,in:1/2.54,pt:72/2.54,pc:6/2.54,px:-1},in:{mm:25.4,cm:2.54,in:1,pt:72,pc:6,px:-1},pt:{mm:25.4/72,cm:2.54/72,in:1/72,pt:1,pc:6/72,px:-1},pc:{mm:25.4/6,cm:2.54/6,in:1/6,pt:72/6,pc:1,px:-1},px:{px:1}};function M(r){let e="px";if(typeof r=="string"||r instanceof String)for(let s=0,n=gt.length;s<n;s++){const o=gt[s];if(r.endsWith(o)){e=o,r=r.substring(0,r.length-o.length);break}}let t;return e==="px"&&Q!=="px"?t=H.in[Q]/yt:(t=H[e][Q],t<0&&(t=H[e].in*yt)),t*Number.parseFloat(r)}const Rt=new C,W=new C,pt=new C,dt=new C;function _t(r,e,t){if(!(r.hasAttribute("transform")||r.nodeName==="use"&&(r.hasAttribute("x")||r.hasAttribute("y"))))return null;const s=Ft(r);return t.length>0&&s.premultiply(t[t.length-1]),e.copy(s),t.push(s),s}function Ft(r){const e=new C,t=Rt;if(r.nodeName==="use"&&(r.hasAttribute("x")||r.hasAttribute("y"))&&e.translate(M(r.getAttribute("x")),M(r.getAttribute("y"))),r.hasAttribute("transform")){const s=r.getAttribute("transform").split(")");for(let n=s.length-1;n>=0;n--){const o=s[n].trim();if(o==="")continue;const i=o.indexOf("("),c=o.length;if(i>0&&i<c){const h=o.slice(0,i),a=A(o.slice(i+1));switch(t.identity(),h){case"translate":if(a.length>=1){const u=a[0];let f=0;a.length>=2&&(f=a[1]),t.translate(u,f)}break;case"rotate":if(a.length>=1){let u=0,f=0,g=0;u=a[0]*Math.PI/180,a.length>=3&&(f=a[1],g=a[2]),W.makeTranslation(-f,-g),pt.makeRotation(u),dt.multiplyMatrices(pt,W),W.makeTranslation(f,g),t.multiplyMatrices(W,dt)}break;case"scale":a.length>=1&&t.scale(a[0],a[1]??a[0]);break;case"skewX":a.length===1&&t.set(1,Math.tan(a[0]*Math.PI/180),0,0,1,0,0,0,1);break;case"skewY":a.length===1&&t.set(1,0,0,Math.tan(a[0]*Math.PI/180),1,0,0,0,1);break;case"matrix":a.length===6&&t.set(a[0],a[2],a[4],a[1],a[3],a[5],0,0,1);break}}e.premultiply(t)}}return e}function Wt(r){return new I().addPath(new R().arc(M(r.getAttribute("cx")||0),M(r.getAttribute("cy")||0),M(r.getAttribute("r")||0),0,Math.PI*2))}function Yt(r,e){if(!(!r.sheet||!r.sheet.cssRules||!r.sheet.cssRules.length))for(let t=0;t<r.sheet.cssRules.length;t++){const s=r.sheet.cssRules[t];if(s.type!==1)continue;const n=s.selectorText.split(/,/g).filter(Boolean).map(o=>o.trim());for(let o=0;o<n.length;o++){const i=Object.fromEntries(Object.entries(s.style).filter(([,c])=>c!==""));e[n[o]]=Object.assign(e[n[o]]||{},i)}}}function Bt(r){return new I().addPath(new R().ellipse(M(r.getAttribute("cx")||0),M(r.getAttribute("cy")||0),M(r.getAttribute("rx")||0),M(r.getAttribute("ry")||0),0,0,Math.PI*2))}function Ut(r){return new I().moveTo(M(r.getAttribute("x1")||0),M(r.getAttribute("y1")||0)).lineTo(M(r.getAttribute("x2")||0),M(r.getAttribute("y2")||0))}function Gt(r){const e=new I,t=r.getAttribute("d");return!t||t==="none"?null:(e.addData(t),e)}const Qt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function Ht(r){var s;const e=new I;let t=0;return(s=r.getAttribute("points"))==null||s.replace(Qt,(n,o,i)=>{const c=M(o),h=M(i);return t===0?e.moveTo(c,h):e.lineTo(c,h),t++,n}),e.currentPath.autoClose=!0,e}const Vt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function jt(r){var s;const e=new I;let t=0;return(s=r.getAttribute("points"))==null||s.replace(Vt,(n,o,i)=>{const c=M(o),h=M(i);return t===0?e.moveTo(c,h):e.lineTo(c,h),t++,n}),e.currentPath.autoClose=!1,e}function Zt(r){const e=M(r.getAttribute("x")||0),t=M(r.getAttribute("y")||0),s=M(r.getAttribute("rx")||r.getAttribute("ry")||0),n=M(r.getAttribute("ry")||r.getAttribute("rx")||0),o=M(r.getAttribute("width")),i=M(r.getAttribute("height")),c=1-.551915024494,h=new I;return h.moveTo(e+s,t),h.lineTo(e+o-s,t),(s!==0||n!==0)&&h.bezierCurveTo(e+o-s*c,t,e+o,t+n*c,e+o,t+n),h.lineTo(e+o,t+i-n),(s!==0||n!==0)&&h.bezierCurveTo(e+o,t+i-n*c,e+o-s*c,t+i,e+o-s,t+i),h.lineTo(e+s,t+i),(s!==0||n!==0)&&h.bezierCurveTo(e+s*c,t+i,e,t+i-n*c,e,t+i-n),h.lineTo(e,t+n),(s!==0||n!==0)&&h.bezierCurveTo(e,t+n*c,e+s*c,t,e+s,t),h}function $(r,e,t){e=Object.assign({},e);let s={};if(r.hasAttribute("class")){const h=r.getAttribute("class").split(/\s/).filter(Boolean).map(a=>a.trim());for(let a=0;a<h.length;a++)s=Object.assign(s,t[`.${h[a]}`])}r.hasAttribute("id")&&(s=Object.assign(s,t[`#${r.getAttribute("id")}`]));function n(h,a,u){u===void 0&&(u=function(g){return g.startsWith("url")&&console.warn("url access in attributes is not implemented."),g}),r.hasAttribute(h)&&(e[a]=u(r.getAttribute(h))),s[h]&&(e[a]=u(s[h])),r.style&&r.style[h]!==""&&(e[a]=u(r.style[h]))}function o(h){return Math.max(0,Math.min(1,M(h)))}function i(h){return Math.max(0,M(h))}function c(h){return h.split(" ").filter(a=>a!=="").map(a=>M(a))}return n("fill","fill"),n("fill-opacity","fillOpacity",o),n("fill-rule","fillRule"),n("opacity","opacity",o),n("stroke","stroke"),n("stroke-opacity","strokeOpacity",o),n("stroke-width","strokeWidth",i),n("stroke-linecap","strokeLinecap"),n("stroke-linejoin","strokeLinejoin"),n("stroke-miterlimit","strokeMiterlimit",i),n("stroke-dasharray","strokeDasharray",c),n("stroke-dashoffset","strokeDashoffset",M),n("visibility","visibility"),e}function V(r,e,t=[]){var u;if(r.nodeType!==1)return t;let s=!1,n=null;const o={};switch(r.nodeName){case"svg":e=$(r,e,o);break;case"style":Yt(r,o);break;case"g":e=$(r,e,o);break;case"path":e=$(r,e,o),r.hasAttribute("d")&&(n=Gt(r));break;case"rect":e=$(r,e,o),n=Zt(r);break;case"polygon":e=$(r,e,o),n=Ht(r);break;case"polyline":e=$(r,e,o),n=jt(r);break;case"circle":e=$(r,e,o),n=Wt(r);break;case"ellipse":e=$(r,e,o),n=Bt(r);break;case"line":e=$(r,e,o),n=Ut(r);break;case"defs":s=!0;break;case"use":{e=$(r,e,o);const g=(r.getAttributeNS("http://www.w3.org/1999/xlink","href")||"").substring(1),p=(u=r.viewportElement)==null?void 0:u.getElementById(g);p?V(p,e,t):console.warn(`'use node' references non-existent node id: ${g}`);break}default:console.warn(r);break}const i=new C,c=[],h=_t(r,i,c);n&&(n.transform(i),t.push(n),n.style=e);const a=r.childNodes;for(let f=0,g=a.length;f<g;f++){const p=a[f];s&&p.nodeName!=="style"&&p.nodeName!=="defs"||V(p,e,t)}return h&&(c.pop(),c.length>0?i.copy(c[c.length-1]):i.identity()),t}const xt="data:image/svg+xml;",mt=`${xt}base64,`,Mt=`${xt}charset=utf8,`;function Pt(r){if(typeof r=="string"){let e;return r.startsWith(mt)?(r=r.substring(mt.length,r.length),e=atob(r)):r.startsWith(Mt)?(r=r.substring(Mt.length,r.length),e=decodeURIComponent(r)):e=r,new DOMParser().parseFromString(e,"image/svg+xml").documentElement}else return r}function Jt(r){return V(Pt(r),{})}x.BoundingBox=z,x.CircleCurve=_,x.CubicBezierCurve=nt,x.Curve=k,x.CurvePath=R,x.EllipseCurve=ot,x.HeartCurve=zt,x.LineCurve=X,x.Matrix3=C,x.Path2D=I,x.PloygonCurve=Xt,x.QuadraticBezierCurve=ut,x.RectangularCurve=lt,x.SplineCurve=ft,x.Vector2=l,x.addPathCommandsToPath2D=U,x.parseArcCommand=J,x.parsePathDataArgs=A,x.parseSvg=Jt,x.parseSvgToDom=Pt,x.pathCommandsToPathData=K,x.pathDataToPathCommands=G,x.setCanvasContext=q,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"})});
package/dist/index.mjs CHANGED
@@ -1005,9 +1005,6 @@ class Curve {
1005
1005
  this.transformPoint((point) => point.applyMatrix3(matrix));
1006
1006
  return this;
1007
1007
  }
1008
- getDivisions(divisions) {
1009
- return divisions;
1010
- }
1011
1008
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1012
1009
  this.getPoints().forEach((point) => {
1013
1010
  min.x = Math.min(min.x, point.x);
@@ -1142,12 +1139,45 @@ class CubicBezierCurve extends Curve {
1142
1139
  cb(this.end);
1143
1140
  return this;
1144
1141
  }
1142
+ _solveQuadratic(a, b, c) {
1143
+ const discriminant = b * b - 4 * a * c;
1144
+ if (discriminant < 0)
1145
+ return [];
1146
+ const sqrtDiscriminant = Math.sqrt(discriminant);
1147
+ const t1 = (-b + sqrtDiscriminant) / (2 * a);
1148
+ const t2 = (-b - sqrtDiscriminant) / (2 * a);
1149
+ return [t1, t2].filter((t) => t >= 0 && t <= 1);
1150
+ }
1145
1151
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1146
- const { start, startControl, endControl, end } = this;
1147
- min.x = Math.min(min.x, start.x, startControl.x, endControl.x, end.x);
1148
- min.y = Math.min(min.y, start.y, startControl.y, endControl.y, end.y);
1149
- max.x = Math.max(max.x, start.x, startControl.x, endControl.x, end.x);
1150
- max.y = Math.max(max.y, start.y, startControl.y, endControl.y, end.y);
1152
+ const p0 = this.start;
1153
+ const p1 = this.startControl;
1154
+ const p2 = this.endControl;
1155
+ const p3 = this.end;
1156
+ const dxRoots = this._solveQuadratic(
1157
+ 3 * (p1.x - p0.x),
1158
+ 6 * (p2.x - p1.x),
1159
+ 3 * (p3.x - p2.x)
1160
+ );
1161
+ const dyRoots = this._solveQuadratic(
1162
+ 3 * (p1.y - p0.y),
1163
+ 6 * (p2.y - p1.y),
1164
+ 3 * (p3.y - p2.y)
1165
+ );
1166
+ const tValues = [0, 1, ...dxRoots, ...dyRoots];
1167
+ const samplePoints = (tValues2, precision) => {
1168
+ for (const t of tValues2) {
1169
+ for (let i = 0; i <= precision; i++) {
1170
+ const delta = i / precision - 0.5;
1171
+ const refinedT = Math.min(1, Math.max(0, t + delta));
1172
+ const point = this.getPoint(refinedT);
1173
+ min.x = Math.min(min.x, point.x);
1174
+ min.y = Math.min(min.y, point.y);
1175
+ max.x = Math.max(max.x, point.x);
1176
+ max.y = Math.max(max.y, point.y);
1177
+ }
1178
+ }
1179
+ };
1180
+ samplePoints(tValues, 10);
1151
1181
  return { min, max };
1152
1182
  }
1153
1183
  getCommands() {
@@ -1222,9 +1252,6 @@ class EllipseCurve extends Curve {
1222
1252
  }
1223
1253
  return output.set(_x, _y);
1224
1254
  }
1225
- getDivisions(divisions = 12) {
1226
- return divisions * 2;
1227
- }
1228
1255
  getCommands() {
1229
1256
  const { center, radiusX: rx, radiusY: ry, startAngle, endAngle, clockwise, rotation } = this;
1230
1257
  const { x: cx, y: cy } = center;
@@ -1484,9 +1511,6 @@ class LineCurve extends Curve {
1484
1511
  cb(this.end);
1485
1512
  return this;
1486
1513
  }
1487
- getDivisions() {
1488
- return 1;
1489
- }
1490
1514
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1491
1515
  const { start, end } = this;
1492
1516
  min.x = Math.min(min.x, start.x, end.x);
@@ -1827,9 +1851,6 @@ class SplineCurve extends Curve {
1827
1851
  super();
1828
1852
  this.points = points;
1829
1853
  }
1830
- getDivisions(divisions = 12) {
1831
- return divisions * this.points.length;
1832
- }
1833
1854
  getPoint(t, output = new Vector2()) {
1834
1855
  const { points } = this;
1835
1856
  const p = (points.length - 1) * t;
@@ -1946,10 +1967,11 @@ class CurvePath extends Curve {
1946
1967
  }
1947
1968
  getPoints(divisions = 12) {
1948
1969
  const points = [];
1970
+ const curves = this.curves;
1949
1971
  let last;
1950
- for (let i = 0, curves = this.curves; i < curves.length; i++) {
1972
+ for (let i = 0, len = curves.length; i < len; i++) {
1951
1973
  const curve = curves[i];
1952
- const curvePoints = curve.getPoints(curve.getDivisions(divisions));
1974
+ const curvePoints = curve.getPoints(divisions);
1953
1975
  for (let i2 = 0; i2 < curvePoints.length; i2++) {
1954
1976
  const point = curvePoints[i2];
1955
1977
  if (last?.equals(point))
@@ -1975,7 +1997,7 @@ class CurvePath extends Curve {
1975
1997
  if (start) {
1976
1998
  const end = this.currentPoint;
1977
1999
  if (!start.equals(end)) {
1978
- this.curves.push(new LineCurve(end, start));
2000
+ this.curves.push(new LineCurve(end.clone(), start));
1979
2001
  this.currentPoint.copy(start);
1980
2002
  }
1981
2003
  this.startPoint = void 0;
@@ -1988,35 +2010,41 @@ class CurvePath extends Curve {
1988
2010
  return this;
1989
2011
  }
1990
2012
  lineTo(x, y) {
1991
- this.curves.push(
1992
- new LineCurve(
1993
- this.currentPoint.clone(),
1994
- new Vector2(x, y)
1995
- )
1996
- );
2013
+ if (!this.currentPoint.equals({ x, y })) {
2014
+ this.curves.push(
2015
+ new LineCurve(
2016
+ this.currentPoint.clone(),
2017
+ new Vector2(x, y)
2018
+ )
2019
+ );
2020
+ }
1997
2021
  this._setCurrentPoint({ x, y });
1998
2022
  return this;
1999
2023
  }
2000
2024
  bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
2001
- this.curves.push(
2002
- new CubicBezierCurve(
2003
- this.currentPoint.clone(),
2004
- new Vector2(cp1x, cp1y),
2005
- new Vector2(cp2x, cp2y),
2006
- new Vector2(x, y)
2007
- )
2008
- );
2025
+ if (!this.currentPoint.equals({ x, y })) {
2026
+ this.curves.push(
2027
+ new CubicBezierCurve(
2028
+ this.currentPoint.clone(),
2029
+ new Vector2(cp1x, cp1y),
2030
+ new Vector2(cp2x, cp2y),
2031
+ new Vector2(x, y)
2032
+ )
2033
+ );
2034
+ }
2009
2035
  this._setCurrentPoint({ x, y });
2010
2036
  return this;
2011
2037
  }
2012
2038
  quadraticCurveTo(cpx, cpy, x, y) {
2013
- this.curves.push(
2014
- new QuadraticBezierCurve(
2015
- this.currentPoint.clone(),
2016
- new Vector2(cpx, cpy),
2017
- new Vector2(x, y)
2018
- )
2019
- );
2039
+ if (!this.currentPoint.equals({ x, y })) {
2040
+ this.curves.push(
2041
+ new QuadraticBezierCurve(
2042
+ this.currentPoint.clone(),
2043
+ new Vector2(cpx, cpy),
2044
+ new Vector2(x, y)
2045
+ )
2046
+ );
2047
+ }
2020
2048
  this._setCurrentPoint({ x, y });
2021
2049
  return this;
2022
2050
  }
@@ -2229,23 +2257,38 @@ class Path2D {
2229
2257
  }
2230
2258
  transform(matrix) {
2231
2259
  this.forEachCurve((curve) => curve.transform(matrix));
2260
+ const vec = new Vector2();
2261
+ const transformX = (x) => {
2262
+ vec.x = x;
2263
+ vec.applyMatrix3(matrix);
2264
+ return vec.x;
2265
+ };
2266
+ const style = this.style;
2267
+ if (style.strokeWidth) {
2268
+ style.strokeWidth = transformX(style.strokeWidth);
2269
+ }
2270
+ if (style.strokeDashoffset) {
2271
+ style.strokeDashoffset = transformX(style.strokeDashoffset);
2272
+ }
2273
+ if (style.strokeDasharray) {
2274
+ style.strokeDasharray = style.strokeDasharray.map((v) => transformX(v));
2275
+ }
2232
2276
  return this;
2233
2277
  }
2234
- getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
2278
+ getMinMax(min = Vector2.MAX, max = Vector2.MIN, withStyle = true) {
2235
2279
  this.forEachCurve((curve) => curve.getMinMax(min, max));
2280
+ if (withStyle) {
2281
+ const strokeHalfWidth = this.strokeWidth / 2;
2282
+ min.x -= strokeHalfWidth;
2283
+ min.y -= strokeHalfWidth;
2284
+ max.x += strokeHalfWidth;
2285
+ max.y += strokeHalfWidth;
2286
+ }
2236
2287
  return { min, max };
2237
2288
  }
2238
- getBoundingBox(withStrokeWidth = true) {
2239
- const { min, max } = this.getMinMax();
2240
- const bbox = new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
2241
- if (withStrokeWidth) {
2242
- const strokeWidth = this.strokeWidth;
2243
- bbox.left -= strokeWidth / 2;
2244
- bbox.top -= strokeWidth / 2;
2245
- bbox.width += strokeWidth;
2246
- bbox.height += strokeWidth;
2247
- }
2248
- return bbox;
2289
+ getBoundingBox(withStyle = true) {
2290
+ const { min, max } = this.getMinMax(void 0, void 0, withStyle);
2291
+ return new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
2249
2292
  }
2250
2293
  getCommands() {
2251
2294
  return this.paths.flatMap((path) => path.getCommands());
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-path2d",
3
3
  "type": "module",
4
- "version": "0.1.13",
4
+ "version": "0.1.15",
5
5
  "packageManager": "pnpm@9.9.0",
6
6
  "description": "A modern Path2D library, fully compatible with Web Path2D, with additional support for path animation, path deformation, path playback, etc.",
7
7
  "author": "wxm",