modern-path2d 0.2.1 → 0.2.3

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/dist/index.cjs CHANGED
@@ -118,6 +118,16 @@ class Vector2 {
118
118
  this.y = target.y + (dy + Math.tan(ay) * dx);
119
119
  return this;
120
120
  }
121
+ min(...vecs) {
122
+ this.x = Math.min(this.x, ...vecs.map((v) => v.x));
123
+ this.y = Math.min(this.y, ...vecs.map((v) => v.y));
124
+ return this;
125
+ }
126
+ max(...vecs) {
127
+ this.x = Math.max(this.x, ...vecs.map((v) => v.x));
128
+ this.y = Math.max(this.y, ...vecs.map((v) => v.y));
129
+ return this;
130
+ }
121
131
  normalize() {
122
132
  return this.scale(1 / (this.length() || 1));
123
133
  }
@@ -785,46 +795,77 @@ function parsePathDataArgs(input, flags, stride = 0) {
785
795
  return result;
786
796
  }
787
797
 
788
- function commandToData(cmd) {
789
- switch (cmd.type) {
790
- case "m":
791
- case "M":
792
- return `${cmd.type} ${cmd.x} ${cmd.y}`;
793
- case "h":
794
- case "H":
795
- return `${cmd.type} ${cmd.x}`;
796
- case "v":
797
- case "V":
798
- return `${cmd.type} ${cmd.y}`;
799
- case "l":
800
- case "L":
801
- return `${cmd.type} ${cmd.x} ${cmd.y}`;
802
- case "c":
803
- case "C":
804
- return `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
805
- case "s":
806
- case "S":
807
- return `${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
808
- case "q":
809
- case "Q":
810
- return `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`;
811
- case "t":
812
- case "T":
813
- return `${cmd.type} ${cmd.x} ${cmd.y}`;
814
- case "a":
815
- case "A":
816
- return `${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`;
817
- case "z":
818
- case "Z":
819
- return cmd.type;
820
- default:
821
- return "";
822
- }
823
- }
824
798
  function pathCommandsToPathData(commands) {
799
+ const first = { x: 0, y: 0 };
800
+ const prev = { x: 0, y: 0 };
825
801
  let data = "";
826
802
  for (let i = 0, len = commands.length; i < len; i++) {
827
- data += `${commandToData(commands[i])} `;
803
+ const cmd = commands[i];
804
+ switch (cmd.type) {
805
+ case "m":
806
+ case "M":
807
+ if (cmd.x === prev.x && cmd.y === prev.y) {
808
+ continue;
809
+ }
810
+ data += `${cmd.type} ${cmd.x} ${cmd.y}`;
811
+ prev.x = cmd.x;
812
+ prev.y = cmd.y;
813
+ first.x = cmd.x;
814
+ first.y = cmd.y;
815
+ break;
816
+ case "h":
817
+ case "H":
818
+ data += `${cmd.type} ${cmd.x}`;
819
+ prev.x = cmd.x;
820
+ break;
821
+ case "v":
822
+ case "V":
823
+ data += `${cmd.type} ${cmd.y}`;
824
+ prev.y = cmd.y;
825
+ break;
826
+ case "l":
827
+ case "L":
828
+ data += `${cmd.type} ${cmd.x} ${cmd.y}`;
829
+ prev.x = cmd.x;
830
+ prev.y = cmd.y;
831
+ break;
832
+ case "c":
833
+ case "C":
834
+ data += `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
835
+ prev.x = cmd.x;
836
+ prev.y = cmd.y;
837
+ break;
838
+ case "s":
839
+ case "S":
840
+ data += `${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
841
+ prev.x = cmd.x;
842
+ prev.y = cmd.y;
843
+ break;
844
+ case "q":
845
+ case "Q":
846
+ data += `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`;
847
+ prev.x = cmd.x;
848
+ prev.y = cmd.y;
849
+ break;
850
+ case "t":
851
+ case "T":
852
+ data += `${cmd.type} ${cmd.x} ${cmd.y}`;
853
+ prev.x = cmd.x;
854
+ prev.y = cmd.y;
855
+ break;
856
+ case "a":
857
+ case "A":
858
+ data += `${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`;
859
+ prev.x = cmd.x;
860
+ prev.y = cmd.y;
861
+ break;
862
+ case "z":
863
+ case "Z":
864
+ data += cmd.type;
865
+ prev.x = first.x;
866
+ prev.y = first.y;
867
+ break;
868
+ }
828
869
  }
829
870
  return data;
830
871
  }
@@ -2451,14 +2492,35 @@ class Path2D {
2451
2492
  return this;
2452
2493
  }
2453
2494
  getMinMax(min = Vector2.MAX, max = Vector2.MIN, withStyle = true) {
2454
- this.getCurves().forEach((curve) => curve.getMinMax(min, max));
2455
- if (withStyle) {
2456
- const strokeHalfWidth = this.strokeWidth / 2;
2457
- min.x -= strokeHalfWidth;
2458
- min.y -= strokeHalfWidth;
2459
- max.x += strokeHalfWidth;
2460
- max.y += strokeHalfWidth;
2461
- }
2495
+ const strokeWidth = this.strokeWidth;
2496
+ this.getCurves().forEach((curve) => {
2497
+ curve.getMinMax(min, max);
2498
+ if (withStyle) {
2499
+ if (strokeWidth > 1) {
2500
+ const halfStrokeWidth = strokeWidth / 2;
2501
+ const isClockwise = curve.isClockwise();
2502
+ const points = [];
2503
+ for (let t = 0; t <= 1; t += 1 / curve.arcLengthDivisions) {
2504
+ const point = curve.getPoint(t);
2505
+ const normal = curve.getNormal(t);
2506
+ const dist1 = normal.clone().scale(isClockwise ? halfStrokeWidth : -halfStrokeWidth);
2507
+ const dist2 = normal.clone().scale(isClockwise ? -halfStrokeWidth : halfStrokeWidth);
2508
+ points.push(
2509
+ point.clone().add(dist1),
2510
+ point.clone().add(dist2),
2511
+ point.clone().add({ x: halfStrokeWidth, y: 0 }),
2512
+ point.clone().add({ x: -halfStrokeWidth, y: 0 }),
2513
+ point.clone().add({ x: 0, y: halfStrokeWidth }),
2514
+ point.clone().add({ x: 0, y: -halfStrokeWidth }),
2515
+ point.clone().add({ x: halfStrokeWidth, y: halfStrokeWidth }),
2516
+ point.clone().add({ x: -halfStrokeWidth, y: -halfStrokeWidth })
2517
+ );
2518
+ }
2519
+ min.min(...points);
2520
+ max.max(...points);
2521
+ }
2522
+ }
2523
+ });
2462
2524
  return { min, max };
2463
2525
  }
2464
2526
  getBoundingBox(withStyle = true) {
@@ -2932,20 +2994,22 @@ function parseStyle(node, style, stylesheets) {
2932
2994
  if (node.hasAttribute("id")) {
2933
2995
  stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`#${node.getAttribute("id")}`]);
2934
2996
  }
2935
- function addStyle(svgName, jsName, adjustFunction) {
2936
- if (adjustFunction === void 0) {
2937
- adjustFunction = function copy(v) {
2938
- if (v.startsWith("url"))
2939
- console.warn("url access in attributes is not implemented.");
2940
- return v;
2941
- };
2942
- }
2997
+ for (let len = node.style.length, i = 0; i < len; i++) {
2998
+ const name = node.style.item(i);
2999
+ const value = node.style.getPropertyValue(name);
3000
+ style[name] = value;
3001
+ stylesheetStyles[name] = value;
3002
+ }
3003
+ function addStyle(svgName, jsName, adjustFunction = copy) {
2943
3004
  if (node.hasAttribute(svgName))
2944
3005
  style[jsName] = adjustFunction(node.getAttribute(svgName));
2945
3006
  if (stylesheetStyles[svgName])
2946
3007
  style[jsName] = adjustFunction(stylesheetStyles[svgName]);
2947
- if (node.style && node.style[svgName] !== "")
2948
- style[jsName] = adjustFunction(node.style[svgName]);
3008
+ }
3009
+ function copy(v) {
3010
+ if (v.startsWith("url"))
3011
+ console.warn("url access in attributes is not implemented.");
3012
+ return v;
2949
3013
  }
2950
3014
  function clamp(v) {
2951
3015
  return Math.max(0, Math.min(1, parseFloatWithUnits(v)));
@@ -2977,56 +3041,57 @@ function parseNode(node, style, paths = []) {
2977
3041
  return paths;
2978
3042
  let isDefsNode = false;
2979
3043
  let path = null;
3044
+ let _style = { ...style };
2980
3045
  const stylesheets = {};
2981
3046
  switch (node.nodeName) {
2982
3047
  case "svg":
2983
- style = parseStyle(node, style, stylesheets);
3048
+ _style = parseStyle(node, _style, stylesheets);
2984
3049
  break;
2985
3050
  case "style":
2986
3051
  parseCSSStylesheet(node, stylesheets);
2987
3052
  break;
2988
3053
  case "g":
2989
- style = parseStyle(node, style, stylesheets);
3054
+ _style = parseStyle(node, _style, stylesheets);
2990
3055
  break;
2991
3056
  case "path":
2992
- style = parseStyle(node, style, stylesheets);
3057
+ _style = parseStyle(node, _style, stylesheets);
2993
3058
  if (node.hasAttribute("d"))
2994
3059
  path = parsePathNode(node);
2995
3060
  break;
2996
3061
  case "rect":
2997
- style = parseStyle(node, style, stylesheets);
3062
+ _style = parseStyle(node, _style, stylesheets);
2998
3063
  path = parseRectNode(node);
2999
3064
  break;
3000
3065
  case "polygon":
3001
- style = parseStyle(node, style, stylesheets);
3066
+ _style = parseStyle(node, _style, stylesheets);
3002
3067
  path = parsePolygonNode(node);
3003
3068
  break;
3004
3069
  case "polyline":
3005
- style = parseStyle(node, style, stylesheets);
3070
+ _style = parseStyle(node, _style, stylesheets);
3006
3071
  path = parsePolylineNode(node);
3007
3072
  break;
3008
3073
  case "circle":
3009
- style = parseStyle(node, style, stylesheets);
3074
+ _style = parseStyle(node, _style, stylesheets);
3010
3075
  path = parseCircleNode(node);
3011
3076
  break;
3012
3077
  case "ellipse":
3013
- style = parseStyle(node, style, stylesheets);
3078
+ _style = parseStyle(node, _style, stylesheets);
3014
3079
  path = parseEllipseNode(node);
3015
3080
  break;
3016
3081
  case "line":
3017
- style = parseStyle(node, style, stylesheets);
3082
+ _style = parseStyle(node, _style, stylesheets);
3018
3083
  path = parseLineNode(node);
3019
3084
  break;
3020
3085
  case "defs":
3021
3086
  isDefsNode = true;
3022
3087
  break;
3023
3088
  case "use": {
3024
- style = parseStyle(node, style, stylesheets);
3089
+ _style = parseStyle(node, _style, stylesheets);
3025
3090
  const href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href") || "";
3026
3091
  const usedNodeId = href.substring(1);
3027
3092
  const usedNode = node.viewportElement?.getElementById(usedNodeId);
3028
3093
  if (usedNode) {
3029
- parseNode(usedNode, style, paths);
3094
+ parseNode(usedNode, _style, paths);
3030
3095
  } else {
3031
3096
  console.warn(`'use node' references non-existent node id: ${usedNodeId}`);
3032
3097
  }
@@ -3036,6 +3101,10 @@ function parseNode(node, style, paths = []) {
3036
3101
  console.warn(node);
3037
3102
  break;
3038
3103
  }
3104
+ if (_style.display === "none") {
3105
+ return paths;
3106
+ }
3107
+ Object.assign(style, _style);
3039
3108
  const currentTransform = new Matrix3();
3040
3109
  const transformStack = [];
3041
3110
  const transform = getNodeTransform(node, currentTransform, transformStack);
@@ -3089,15 +3158,44 @@ function parseSvg(svg) {
3089
3158
  return parseNode(parseSvgToDom(svg), {});
3090
3159
  }
3091
3160
 
3092
- function getPathsBoundingBox(paths) {
3161
+ function getPathsBoundingBox(paths, withStyle = true) {
3093
3162
  if (!paths.length) {
3094
3163
  return void 0;
3095
3164
  }
3096
3165
  const min = Vector2.MAX;
3097
3166
  const max = Vector2.MIN;
3098
- paths.forEach((path) => path.getMinMax(min, max));
3167
+ paths.forEach((path) => path.getMinMax(min, max, withStyle));
3099
3168
  return new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
3100
3169
  }
3170
+ function pathsToSvgString(paths) {
3171
+ const { x, y, width, height } = getPathsBoundingBox(paths);
3172
+ const content = paths.map((path) => path.toSvgPathString()).join("");
3173
+ return `<svg viewBox="${x} ${y} ${width} ${height}" width="${width}px" height="${height}px" xmlns="http://www.w3.org/2000/svg">${content}</svg>`;
3174
+ }
3175
+ function pathsToSvgUrl(paths) {
3176
+ return `data:image/svg+xml;base64,${btoa(pathsToSvgString(paths))}`;
3177
+ }
3178
+ function pathsToSvg(paths) {
3179
+ return new DOMParser().parseFromString(pathsToSvgString(paths), "image/svg+xml").documentElement;
3180
+ }
3181
+ function pathsToCanvas(paths, options = {}) {
3182
+ const { pixelRatio = 2, ...style } = options;
3183
+ const { left, top, width, height } = getPathsBoundingBox(paths);
3184
+ const canvas = document.createElement("canvas");
3185
+ canvas.width = width * pixelRatio;
3186
+ canvas.height = height * pixelRatio;
3187
+ canvas.style.width = `${width}px`;
3188
+ canvas.style.height = `${height}px`;
3189
+ const ctx = canvas.getContext("2d");
3190
+ if (ctx) {
3191
+ ctx.scale(pixelRatio, pixelRatio);
3192
+ ctx.translate(-left, -top);
3193
+ paths.forEach((path) => {
3194
+ path.drawTo(ctx, style);
3195
+ });
3196
+ }
3197
+ return canvas;
3198
+ }
3101
3199
 
3102
3200
  exports.BoundingBox = BoundingBox;
3103
3201
  exports.CircleCurve = CircleCurve;
@@ -3122,4 +3220,8 @@ exports.parseSvg = parseSvg;
3122
3220
  exports.parseSvgToDom = parseSvgToDom;
3123
3221
  exports.pathCommandsToPathData = pathCommandsToPathData;
3124
3222
  exports.pathDataToPathCommands = pathDataToPathCommands;
3223
+ exports.pathsToCanvas = pathsToCanvas;
3224
+ exports.pathsToSvg = pathsToSvg;
3225
+ exports.pathsToSvgString = pathsToSvgString;
3226
+ exports.pathsToSvgUrl = pathsToSvgUrl;
3125
3227
  exports.setCanvasContext = setCanvasContext;
package/dist/index.d.cts CHANGED
@@ -124,6 +124,8 @@ declare class Vector2 {
124
124
  length(): number;
125
125
  scale(sx: number, sy?: number, target?: VectorLike): this;
126
126
  skew(ax: number, ay?: number, target?: VectorLike): this;
127
+ min(...vecs: VectorLike[]): this;
128
+ max(...vecs: VectorLike[]): this;
127
129
  normalize(): this;
128
130
  addVectors(a: VectorLike, b: VectorLike): this;
129
131
  subVectors(a: VectorLike, b: VectorLike): this;
@@ -481,6 +483,12 @@ declare function pathDataToPathCommands(d: string): PathCommand[];
481
483
  declare function parseSvgToDom(svg: string | SVGElement): SVGElement;
482
484
  declare function parseSvg(svg: string | SVGElement): Path2D[];
483
485
 
484
- declare function getPathsBoundingBox(paths: Path2D[]): BoundingBox | undefined;
486
+ declare function getPathsBoundingBox(paths: Path2D[], withStyle?: boolean): BoundingBox | undefined;
487
+ declare function pathsToSvgString(paths: Path2D[]): string;
488
+ declare function pathsToSvgUrl(paths: Path2D[]): string;
489
+ declare function pathsToSvg(paths: Path2D[]): SVGElement;
490
+ declare function pathsToCanvas(paths: Path2D[], options?: Partial<PathStyle & {
491
+ pixelRatio: number;
492
+ }>): HTMLCanvasElement;
485
493
 
486
- export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, type FillRule, HeartCurve, LineCurve, Matrix3, Path2D, type PathCommand, type PathDrawStyle, type PathStyle, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, type StrokeLinecap, type StrokeLinejoin, Vector2, type VectorLike, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, setCanvasContext };
494
+ export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, type FillRule, HeartCurve, LineCurve, Matrix3, Path2D, type PathCommand, type PathDrawStyle, type PathStyle, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, type StrokeLinecap, type StrokeLinejoin, Vector2, type VectorLike, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, pathsToCanvas, pathsToSvg, pathsToSvgString, pathsToSvgUrl, setCanvasContext };
package/dist/index.d.mts CHANGED
@@ -124,6 +124,8 @@ declare class Vector2 {
124
124
  length(): number;
125
125
  scale(sx: number, sy?: number, target?: VectorLike): this;
126
126
  skew(ax: number, ay?: number, target?: VectorLike): this;
127
+ min(...vecs: VectorLike[]): this;
128
+ max(...vecs: VectorLike[]): this;
127
129
  normalize(): this;
128
130
  addVectors(a: VectorLike, b: VectorLike): this;
129
131
  subVectors(a: VectorLike, b: VectorLike): this;
@@ -481,6 +483,12 @@ declare function pathDataToPathCommands(d: string): PathCommand[];
481
483
  declare function parseSvgToDom(svg: string | SVGElement): SVGElement;
482
484
  declare function parseSvg(svg: string | SVGElement): Path2D[];
483
485
 
484
- declare function getPathsBoundingBox(paths: Path2D[]): BoundingBox | undefined;
486
+ declare function getPathsBoundingBox(paths: Path2D[], withStyle?: boolean): BoundingBox | undefined;
487
+ declare function pathsToSvgString(paths: Path2D[]): string;
488
+ declare function pathsToSvgUrl(paths: Path2D[]): string;
489
+ declare function pathsToSvg(paths: Path2D[]): SVGElement;
490
+ declare function pathsToCanvas(paths: Path2D[], options?: Partial<PathStyle & {
491
+ pixelRatio: number;
492
+ }>): HTMLCanvasElement;
485
493
 
486
- export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, type FillRule, HeartCurve, LineCurve, Matrix3, Path2D, type PathCommand, type PathDrawStyle, type PathStyle, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, type StrokeLinecap, type StrokeLinejoin, Vector2, type VectorLike, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, setCanvasContext };
494
+ export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, type FillRule, HeartCurve, LineCurve, Matrix3, Path2D, type PathCommand, type PathDrawStyle, type PathStyle, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, type StrokeLinecap, type StrokeLinejoin, Vector2, type VectorLike, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, pathsToCanvas, pathsToSvg, pathsToSvgString, pathsToSvgUrl, setCanvasContext };
package/dist/index.d.ts CHANGED
@@ -124,6 +124,8 @@ declare class Vector2 {
124
124
  length(): number;
125
125
  scale(sx: number, sy?: number, target?: VectorLike): this;
126
126
  skew(ax: number, ay?: number, target?: VectorLike): this;
127
+ min(...vecs: VectorLike[]): this;
128
+ max(...vecs: VectorLike[]): this;
127
129
  normalize(): this;
128
130
  addVectors(a: VectorLike, b: VectorLike): this;
129
131
  subVectors(a: VectorLike, b: VectorLike): this;
@@ -481,6 +483,12 @@ declare function pathDataToPathCommands(d: string): PathCommand[];
481
483
  declare function parseSvgToDom(svg: string | SVGElement): SVGElement;
482
484
  declare function parseSvg(svg: string | SVGElement): Path2D[];
483
485
 
484
- declare function getPathsBoundingBox(paths: Path2D[]): BoundingBox | undefined;
486
+ declare function getPathsBoundingBox(paths: Path2D[], withStyle?: boolean): BoundingBox | undefined;
487
+ declare function pathsToSvgString(paths: Path2D[]): string;
488
+ declare function pathsToSvgUrl(paths: Path2D[]): string;
489
+ declare function pathsToSvg(paths: Path2D[]): SVGElement;
490
+ declare function pathsToCanvas(paths: Path2D[], options?: Partial<PathStyle & {
491
+ pixelRatio: number;
492
+ }>): HTMLCanvasElement;
485
493
 
486
- export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, type FillRule, HeartCurve, LineCurve, Matrix3, Path2D, type PathCommand, type PathDrawStyle, type PathStyle, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, type StrokeLinecap, type StrokeLinejoin, Vector2, type VectorLike, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, setCanvasContext };
494
+ export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, type FillRule, HeartCurve, LineCurve, Matrix3, Path2D, type PathCommand, type PathDrawStyle, type PathStyle, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, type StrokeLinecap, type StrokeLinejoin, Vector2, type VectorLike, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, pathsToCanvas, pathsToSvg, pathsToSvgString, pathsToSvgUrl, setCanvasContext };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (function(d,C){typeof exports=="object"&&typeof module<"u"?C(exports):typeof define=="function"&&define.amd?define(["exports"],C):(d=typeof globalThis<"u"?globalThis:d||self,C(d.modernPath2d={}))})(this,function(d){"use strict";var ee=Object.defineProperty;var se=(d,C,q)=>C in d?ee(d,C,{enumerable:!0,configurable:!0,writable:!0,value:q}):d[C]=q;var T=(d,C,q)=>se(d,typeof C!="symbol"?C+"":C,q);const C={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:a=[],strokeDashoffset:h=0,shadowOffsetX:l=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=C[i],r.miterLimit=c,r.setLineDash(a),r.lineDashOffset=h,r.shadowOffsetX=l,r.shadowOffsetY=y,r.shadowBlur=f,r.shadowColor=p}class u{constructor(e=0,t=0){this.x=e,this.y=t}static get MAX(){return new u(1/0,1/0)}static get MIN(){return new u(-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}multiply(e){return this.x*=e.x,this.y*=e.y,this}divide(e){return this.x/=e.x,this.y/=e.y,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}rotate(e,t={x:0,y:0}){const s=-e/180*Math.PI,n=this.x-t.x,o=-(this.y-t.y),i=Math.sin(s),c=Math.cos(s);return this.set(t.x+(n*c-o*i),t.y-(n*i+o*c)),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}lengthSquared(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.lengthSquared())}scale(e,t=e,s={x:0,y:0}){const n=e<0?s.x-this.x+s.x:this.x,o=t<0?s.y-this.y+s.y:this.y;return this.x=n*Math.abs(e),this.y=o*Math.abs(t),this}skew(e,t=0,s={x:0,y:0}){const n=this.x-s.x,o=this.y-s.y;return this.x=s.x+(n+Math.tan(e)*o),this.y=s.y+(o+Math.tan(t)*n),this}normalize(){return this.scale(1/(this.length()||1))}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}multiplyVectors(e,t){return this.x=e.x*t.x,this.y=e.y*t.y,this}divideVectors(e,t){return this.x=e.x/t.x,this.y=e.y/t.y,this}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 u(this.x,this.y)}}class L{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){if(e.length===0)return new L;if(e.length===1)return e[0].clone();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 L(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 u((this.left+this.right)/2,(this.top+this.bottom)/2)}clone(){return new L(this.left,this.top,this.width,this.height)}toArray(){return[this.left,this.top,this.width,this.height]}}class b{constructor(e=1,t=0,s=0,n=0,o=1,i=0,c=0,a=0,h=1){T(this,"elements",[]);this.set(e,t,s,n,o,i,c,a,h)}set(e,t,s,n,o,i,c,a,h){const l=this.elements;return l[0]=e,l[1]=n,l[2]=c,l[3]=t,l[4]=o,l[5]=a,l[6]=s,l[7]=i,l[8]=h,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],a=s[6],h=s[1],l=s[4],y=s[7],f=s[2],p=s[5],g=s[8],x=n[0],M=n[3],w=n[6],$=n[1],v=n[4],S=n[7],N=n[2],z=n[5],D=n[8];return o[0]=i*x+c*$+a*N,o[3]=i*M+c*v+a*z,o[6]=i*w+c*S+a*D,o[1]=h*x+l*$+y*N,o[4]=h*M+l*v+y*z,o[7]=h*w+l*S+y*D,o[2]=f*x+p*$+g*N,o[5]=f*M+p*v+g*z,o[8]=f*w+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],a=e[6],h=e[7],l=e[8],y=l*i-c*h,f=c*a-l*o,p=h*o-i*a,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*h-l*s)*x,e[2]=(c*s-n*i)*x,e[3]=f*x,e[4]=(l*t-n*a)*x,e[5]=(n*o-c*t)*x,e[6]=p*x,e[7]=(s*a-h*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(Y.makeScale(e,t)),this}rotate(e){return this.premultiply(Y.makeRotation(-e)),this}translate(e,t){return this.premultiply(Y.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 Y=new b;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 a=(i.x-c.x)/2,h=(i.y-c.y)/2,l=Math.cos(s)*a+Math.sin(s)*h,y=-Math.sin(s)*a+Math.cos(s)*h;let f=e*e,p=t*t;const g=l*l,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 w=f*x+p*g,$=(f*p-w)/w;let v=Math.sqrt(Math.max(0,$));n===o&&(v=-v);const S=v*e*y/t,N=-v*t*l/e,z=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,U=Z(1,0,(l-S)/e,(y-N)/t),j=Z((l-S)/e,(y-N)/t,(-l-S)/e,(-y-N)/t)%(Math.PI*2);r.ellipse(z,D,e,t,s,U,U+j,o===1)}function O(r,e){return r-(e-r)}function W(r,e){const t=new u,s=new u;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),a=O(t.y,s.y);s.x=c,s.y=a,i.type==="t"?(e.quadraticCurveTo(c,a,t.x+i.x,t.y+i.y),t.add(i)):(e.quadraticCurveTo(c,a,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 m={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,a=!0,h="",l="";const y=[];function f(M,w,$){const v=new SyntaxError(`Unexpected character "${M}" at index ${w}.`);throw v.partial=$,v}function p(){h!==""&&(l===""?y.push(Number(h)):y.push(Number(h)*10**Number(l))),h="",l=""}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)&&m.FLAGS.test(g)){c=1,h=g,p();continue}if(c===0){if(m.WHITESPACE.test(g))continue;if(m.DIGIT.test(g)||m.SIGN.test(g)){c=1,h=g;continue}if(m.POINT.test(g)){c=2,h=g;continue}m.COMMA.test(g)&&(a&&f(g,M,y),a=!0)}if(c===1){if(m.DIGIT.test(g)){h+=g;continue}if(m.POINT.test(g)){h+=g,c=2;continue}if(m.EXP.test(g)){c=3;continue}m.SIGN.test(g)&&h.length===1&&m.SIGN.test(h[0])&&f(g,M,y)}if(c===2){if(m.DIGIT.test(g)){h+=g;continue}if(m.EXP.test(g)){c=3;continue}m.POINT.test(g)&&h[h.length-1]==="."&&f(g,M,y)}if(c===3){if(m.DIGIT.test(g)){l+=g;continue}if(m.SIGN.test(g)){if(l===""){l+=g;continue}l.length===1&&m.SIGN.test(l)&&f(g,M,y)}}m.WHITESPACE.test(g)?(p(),c=0,a=!1):m.COMMA.test(g)?(p(),c=0,a=!0):m.SIGN.test(g)?(p(),c=1,h=g):m.POINT.test(g)?(p(),c=2,h=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 Ct=/[a-df-z][^a-df-z]*/gi;function G(r){const e=[],t=r.match(Ct);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 a;switch(i){case"m":case"M":a=A(c);for(let h=0,l=a.length;h<l;h+=2)h===0?e.push({type:i,x:a[h],y:a[h+1]}):e.push({type:i==="m"?"l":"L",x:a[h],y:a[h+1]});break;case"h":case"H":a=A(c);for(let h=0,l=a.length;h<l;h++)e.push({type:i,x:a[h]});break;case"v":case"V":a=A(c);for(let h=0,l=a.length;h<l;h++)e.push({type:i,y:a[h]});break;case"l":case"L":a=A(c);for(let h=0,l=a.length;h<l;h+=2)e.push({type:i,x:a[h],y:a[h+1]});break;case"c":case"C":a=A(c);for(let h=0,l=a.length;h<l;h+=6)e.push({type:i,x1:a[h],y1:a[h+1],x2:a[h+2],y2:a[h+3],x:a[h+4],y:a[h+5]});break;case"s":case"S":a=A(c);for(let h=0,l=a.length;h<l;h+=4)e.push({type:i,x2:a[h],y2:a[h+1],x:a[h+2],y:a[h+3]});break;case"q":case"Q":a=A(c);for(let h=0,l=a.length;h<l;h+=4)e.push({type:i,x1:a[h],y1:a[h+1],x:a[h+2],y:a[h+3]});break;case"t":case"T":a=A(c);for(let h=0,l=a.length;h<l;h+=2)e.push({type:i,x:a[h],y:a[h+1]});break;case"a":case"A":a=A(c,[3,4],7);for(let h=0,l=a.length;h<l;h+=7)e.push({type:i,rx:a[h],ry:a[h+1],angle:a[h+2],largeArcFlag:a[h+3],sweepFlag:a[h+4],x:a[h+5],y:a[h+6]});break;case"z":case"Z":e.push({type:i});break;default:console.warn(o)}}return e}class k{constructor(){T(this,"arcLengthDivisions",200);T(this,"_cacheArcLengths");T(this,"_needsUpdate",!1)}isClockwise(){const e=this.getPoint(1),t=this.getPoint(.5),s=this.getPoint(1);return(t.x-e.x)*(s.y-t.y)-(t.y-e.y)*(s.x-t.x)<0}getPointAt(e,t=new u){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}forEachControlPoints(e){return this.getControlPoints().forEach(e),this}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,a=o-1,h;for(;c<=a;)if(n=Math.floor(c+(a-c)/2),h=s[n]-i,h<0)c=n+1;else if(h>0)a=n-1;else{a=n;break}if(n=a,s[n]===i)return n/(o-1);const l=s[n],f=s[n+1]-l,p=(i-l)/f;return(n+p)/(o-1)}getTangent(e,t=new u){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)}getNormal(e,t=new u){return this.getTangent(e,t),t.set(-t.y,t.x).normalize()}getNormalAt(e,t){return this.getNormal(this.getUToTMapping(e),t)}getTForPoint(e,t=.001){let s=0,n=1,o=(s+n)/2;for(;n-s>t;){o=(s+n)/2;const i=this.getPoint(o);if(i.distanceTo(e)<t)return o;i.x<e.x?s=o:n=o}return o}matrix(e){return this.forEachControlPoints(t=>t.applyMatrix3(e)),this}getMinMax(e=u.MAX,t=u.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 L(e.x,e.y,t.x-e.x,t.y-e.y)}toCommands(){return this.getPoints().map((e,t)=>t===0?{type:"M",x:e.x,y:e.y}:{type:"L",x:e.x,y:e.y})}toData(){return K(this.toCommands())}drawTo(e){return this.toCommands().forEach(t=>{switch(t.type){case"M":e.moveTo(t.x,t.y);break;case"L":e.lineTo(t.x,t.y);break}}),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().scale(t))}getTangent(e,t=new u){const{x:s,y:n}=this.getNormal(e);return t.set(-n,s)}getNormal(e,t=new u){const{start:s,end:n}=this,o=e*(n-s)+s-.5*Math.PI;return t.set(Math.cos(o),Math.sin(o))}getControlPoints(){return[this.center]}getMinMax(e=u.MAX,t=u.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,a=r*c;return(2*t-2*s+o+i)*a+(-3*t+3*s-2*o-i)*c+o*r+t}function vt(r,e){const t=1-r;return t*t*e}function bt(r,e){return 2*(1-r)*r*e}function At(r,e){return r*r*e}function et(r,e,t,s){return vt(r,e)+bt(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 u,t=new u,s=new u,n=new u){super(),this.start=e,this.startControl=t,this.endControl=s,this.end=n}getPoint(e,t=new u){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))}getControlPoints(){return[this.start,this.startControl,this.endControl,this.end]}_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(a=>a>=0&&a<=1)}getMinMax(e=u.MAX,t=u.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)),a=this._solveQuadratic(3*(n.y-s.y),6*(o.y-n.y),3*(i.y-o.y)),h=[0,1,...c,...a];return((y,f)=>{for(const p of y)for(let g=0;g<=f;g++){const x=g/f-.5,M=Math.min(1,Math.max(0,p+x)),w=this.getPoint(M);e.x=Math.min(e.x,w.x),e.y=Math.min(e.y,w.y),t.x=Math.max(t.x,w.x),t.y=Math.max(t.y,w.y)}})(h,10),{min:e,max:t}}toCommands(){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{start:t,startControl:s,endControl:n,end:o}=this;return e.lineTo(t.x,t.y),e.bezierCurveTo(s.x,s.y,n.x,n.y,o.x,o.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 Et=new b,rt=new b,it=new b,F=new u;class ot extends k{constructor(e=new u,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}isClockwise(){return this.clockwise}getPoint(e,t=new u){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),a=this.center.y+this.radiusY*Math.sin(i);if(this.rotation!==0){const h=Math.cos(this.rotation),l=Math.sin(this.rotation),y=c-this.center.x,f=a-this.center.y;c=y*h-f*l+this.center.x,a=y*l+f*h+this.center.y}return t.set(c,a)}toCommands(){const{center:e,radiusX:t,radiusY:s,startAngle:n,endAngle:o,clockwise:i,rotation:c}=this,{x:a,y:h}=e,l=a+t*Math.cos(n)*Math.cos(c)-s*Math.sin(n)*Math.sin(c),y=h+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,w=a+t*Math.cos(M)*Math.cos(c)-s*Math.sin(M)*Math.sin(c),$=h+t*Math.cos(M)*Math.sin(c)+s*Math.sin(M)*Math.cos(c);return[{type:"M",x:l,y},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:0,sweepFlag:g,x:w,y:$},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:0,sweepFlag:g,x:l,y}]}else{const M=a+t*Math.cos(o)*Math.cos(c)-s*Math.sin(o)*Math.sin(c),w=h+t*Math.cos(o)*Math.sin(c)+s*Math.sin(o)*Math.cos(c);return[{type:"M",x:l,y},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:p,sweepFlag:g,x:M,y:w}]}}drawTo(e){const{center:t,radiusX:s,radiusY:n,rotation:o,startAngle:i,endAngle:c,clockwise:a}=this;return e.ellipse(t.x,t.y,s,n,o,i,c,!a),this}matrix(e){return F.set(this.center.x,this.center.y),F.applyMatrix3(e),this.center.x=F.x,this.center.y=F.y,qt(e)?$t(this,e):Lt(this,e),this}getControlPoints(){return[this.center]}getMinMax(e=u.MAX,t=u.MIN){const{center:s,radiusX:n,radiusY:o,rotation:i}=this,{x:c,y:a}=s,h=Math.cos(i),l=Math.sin(i),y=Math.sqrt(n*n*h*h+o*o*l*l),f=Math.sqrt(n*n*l*l+o*o*h*h);return e.x=Math.min(e.x,c-y),e.y=Math.min(e.y,a-f),t.x=Math.max(t.x,c+y),t.y=Math.max(t.y,a+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 $t(r,e){const t=r.radiusX,s=r.radiusY,n=Math.cos(r.rotation),o=Math.sin(r.rotation),i=new u(t*n,t*o),c=new u(-s*o,s*n),a=i.applyMatrix3(e),h=c.applyMatrix3(e),l=Et.set(a.x,h.x,0,a.y,h.y,0,0,0,1),y=rt.copy(l).invert(),g=it.copy(y).transpose().multiply(y).elements,x=zt(g[0],g[1],g[4]),M=Math.sqrt(x.rt1),w=Math.sqrt(x.rt2);if(r.radiusX=1/M,r.radiusY=1/w,r.rotation=Math.atan2(x.sn,x.cs),!((r.endAngle-r.startAngle)%(2*Math.PI)<Number.EPSILON)){const v=rt.set(M,0,0,0,w,0,0,0,1),S=it.set(x.cs,x.sn,0,-x.sn,x.cs,0,0,0,1),N=v.multiply(S).multiply(l),z=D=>{const{x:U,y:j}=new u(Math.cos(D),Math.sin(D)).applyMatrix3(N);return Math.atan2(j,U)};r.startAngle=z(r.startAngle),r.endAngle=z(r.endAngle),ht(e)&&(r.clockwise=!r.clockwise)}}function Lt(r,e){const t=at(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,ht(e)&&(r.startAngle*=-1,r.endAngle*=-1,r.clockwise=!r.clockwise)}function ht(r){const e=r.elements;return e[0]*e[4]-e[1]*e[3]<0}function qt(r){const e=r.elements,t=e[0]*e[3]+e[1]*e[4];if(t===0)return!1;const s=at(r),n=ct(r);return Math.abs(t/(s*n))>Number.EPSILON}function at(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 a=r+t,h=r-t,l=Math.sqrt(h*h+4*e*e);return a>0?(s=.5*(a+l),c=1/s,n=r*c*t-e*c*e):a<0?n=.5*(a-l):(s=.5*l,n=-.5*l),h>0?o=h+l:o=h-l,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),h>0&&(c=o,o=-i,i=c),{rt1:s,rt2:n,cs:o,sn:i}}class X extends k{constructor(e=new u,t=new u){super(),this.start=e,this.end=t}getPoint(e,t=new u){return e===1?t.copy(this.end):t.copy(this.end).sub(this.start).scale(e).add(this.start),t}getPointAt(e,t=new u){return this.getPoint(e,t)}getTangent(e,t=new u){return t.subVectors(this.end,this.start).normalize()}getTangentAt(e,t=new u){return this.getTangent(e,t)}getControlPoints(){return[this.start,this.end]}getMinMax(e=u.MAX,t=u.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}}toCommands(){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{start:t,end:s}=this;return e.lineTo(t.x,t.y),e.lineTo(s.x,s.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.end.copy(e.end),this}}class Dt extends k{constructor(t,s,n=0,o=1){super();T(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 u(t+.5*this.size,s-.5*this.size),o=new u(t-.5*this.size,s-.5*this.size),i=new u(t,s+.5*this.size),c=new _(n,Math.SQRT1_2*this.size,-.25*Math.PI,.75*Math.PI),a=new _(o,Math.SQRT1_2*this.size,-.75*Math.PI,.25*Math.PI),h=new _(i,.5*Math.SQRT1_2*this.size,.75*Math.PI,1.25*Math.PI),l=new u(t,s+this.size),y=new u(t+this.size,s),f=new u().lerpVectors(y,l,.75),p=new u(t-this.size,s),g=new u().lerpVectors(p,l,.75),x=new X(y,f),M=new X(g,p);return this.curves=[c,x,h,M,a],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,s){return this.getCurve(t).getTangent(this.curveT,s)}getNormal(t,s){return this.getCurve(t).getNormal(this.curveT,s)}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}toCommands(){return this.curves.flatMap(t=>t.toCommands())}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();T(this,"curves",[]);T(this,"curveT",0);T(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 u(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)}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}toCommands(){return this.curves.flatMap(t=>t.toCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class lt extends k{constructor(e=new u,t=new u,s=new u){super(),this.start=e,this.control=t,this.end=s}getPoint(e,t=new u){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}getControlPoints(){return[this.start,this.control,this.end]}getMinMax(e=u.MAX,t=u.MIN){const{start:s,control:n,end:o}=this,i=.5*(s.x+n.x),c=.5*(s.y+n.y),a=.5*(s.x+o.x),h=.5*(s.y+o.y);return e.x=Math.min(e.x,s.x,o.x,i,a),e.y=Math.min(e.y,s.y,o.y,c,h),t.x=Math.max(t.x,s.x,o.x,i,a),t.y=Math.max(t.y,s.y,o.y,c,h),{min:e,max:t}}toCommands(){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{start:t,control:s,end:n}=this;return e.lineTo(t.x,t.y),e.quadraticCurveTo(s.x,s.y,n.x,n.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 ut extends k{constructor(t,s,n=1,o=0,i=1){super();T(this,"curves",[]);T(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 u(t-n,s-o),new u(t+n,s-o),new u(t+n,s+o),new u(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)}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}toCommands(){return this.curves.flatMap(t=>t.toCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class yt extends k{constructor(e=[]){super(),this.points=e}getPoint(e,t=new u){const{points:s}=this,n=(s.length-1)*e,o=Math.floor(n),i=n-o,c=s[o===0?o:o-1],a=s[o],h=s[o>s.length-2?s.length-1:o+1],l=s[o>s.length-3?s.length-1:o+2];return t.set(tt(i,c.x,a.x,h.x,l.x),tt(i,c.y,a.y,h.y,l.y)),t}getControlPoints(){return this.points}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();T(this,"curves",[]);T(this,"startPoint");T(this,"currentPoint",new u);T(this,"autoClose",!1);T(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 u){const n=t*this.getLength(),o=this.getCurveLengths();let i=0;for(;i<o.length;){if(o[i]>=n){const c=o[i]-n,a=this.curves[i],h=a.getLength();return a.getPointAt(h===0?0:1-c/h,s)}i++}return s}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}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 h=n[i].getPoints(t);for(let l=0;l<h.length;l++){const y=h[l];o!=null&&o.equals(y)||(s.push(y),o=y)}}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 u(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 u(t,s),new u(n,o),new u(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 lt(this.currentPoint.clone(),new u(t,s),new u(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 a=this.currentPoint;return this.arc(t+a.x,s+a.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,a,h=!0){const l=new ot(new u(t,s),n,o,i,c,a,!h);if(this.curves.length>0){const y=l.getPoint(0);y.equals(this.currentPoint)||this.lineTo(y.x,y.y)}return this.curves.push(l),this._setCurrentPoint(l.getPoint(1)),this}relativeEllipse(t,s,n,o,i,c,a,h){const l=this.currentPoint;return this.ellipse(t+l.x,s+l.y,n,o,i,c,a,h),this}rect(t,s,n,o){return this.curves.push(new ut(new u(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}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}getBoundingBox(){const{min:t,max:s}=this.getMinMax();return new L(t.x,t.y,s.x-t.x,s.y-t.y)}toCommands(){return this.curves.flatMap(t=>t.toCommands())}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()}function Rt(r,e,t,s){const n=e.clone().sub(r),o=s.clone().sub(t),i=t.clone().sub(r),c=n.cross(o);if(c===0)return new u((r.x+t.x)/2,(r.y+t.y)/2);const a=i.cross(o)/c;return Math.abs(a)>1?new u((r.x+t.x)/2,(r.y+t.y)/2):new u(r.x+a*n.x,r.y+a*n.y)}class I{constructor(e){T(this,"currentPath",new R);T(this,"paths",[this.currentPath]);T(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,a){return this.currentPath.ellipse(e,t,s,n,o,i,c,a),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}getControlPoints(){return this.paths.flatMap(e=>e.getControlPoints())}getCurves(){return this.paths.flatMap(e=>e.curves)}scale(e,t=e,s={x:0,y:0}){return this.getControlPoints().forEach(n=>{n.scale(e,t,s)}),this}skew(e,t=0,s={x:0,y:0}){return this.getControlPoints().forEach(n=>{n.skew(e,t,s)}),this}rotate(e,t={x:0,y:0}){return this.getControlPoints().forEach(s=>{s.rotate(e,t)}),this}bold(e){if(e===0)return this;const t=this.getCurves(),s=[],n=[],o=[];t.forEach((c,a)=>{const h=c.getControlPoints(),l=c.isClockwise();o[a]=h,n[a]=l;const y=h[0],f=h[h.length-1]??y;s.push({start:l?f:y,end:l?y:f,index:a})});const i=[];return s.forEach((c,a)=>{i[a]=[],s.forEach((h,l)=>{l!==a&&h.start.equals(c.end)&&i[a].push(h.index)})}),t.forEach((c,a)=>{const h=n[a];o[a].forEach(y=>{const f=c.getTForPoint(y),p=c.getNormal(f).scale(h?e:-e);y.add(p)})}),i.forEach((c,a)=>{const h=o[a];c.forEach(l=>{const y=o[l],f=Rt(h[h.length-1],h[h.length-2]??h[h.length-1],y[0],y[1]??y[0]);f&&(h[h.length-1].copy(f),y[0].copy(f))})}),this}matrix(e){return this.getCurves().forEach(t=>t.matrix(e)),this}getMinMax(e=u.MAX,t=u.MIN,s=!0){if(this.getCurves().forEach(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 L(t.x,t.y,s.x-t.x,s.y-t.y)}drawTo(e,t={}){t={...this.style,...t};const{fill:s="#000",stroke:n="none"}=t;return e.beginPath(),e.save(),q(e,t),this.paths.forEach(o=>{o.drawTo(e)}),s!=="none"&&e.fill(),n!=="none"&&e.stroke(),e.restore(),this}drawControlPointsTo(e,t={}){t={...this.style,...t};const{fill:s="#000",stroke:n="none"}=t;return e.beginPath(),e.save(),q(e,t),this.getControlPoints().forEach(o=>{e.moveTo(o.x,o.y),e.arc(o.x,o.y,4,0,Math.PI*2)}),s!=="none"&&e.fill(),n!=="none"&&e.stroke(),e.restore(),this}toCommands(){return this.paths.flatMap(e=>e.toCommands())}toData(){return this.paths.map(e=>e.toData()).join(" ")}toSvgPathString(){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.toData()}" style="${s}"></path>`}toSvgString(){const{x:e,y:t,width:s,height:n}=this.getBoundingBox(),o=this.toSvgPathString();return`<svg viewBox="${e} ${t} ${s} ${n}" width="${s}px" height="${n}px" xmlns="http://www.w3.org/2000/svg">${o}</svg>`}toSvgUrl(){return`data:image/svg+xml;base64,${btoa(this.toSvgString())}`}toSvg(){return new DOMParser().parseFromString(this.toSvgString(),"image/svg+xml").documentElement}toCanvas(e={}){const{pixelRatio:t=2,...s}=e,{left:n,top:o,width:i,height:c}=this.getBoundingBox(),a=document.createElement("canvas");a.width=i*t,a.height=c*t,a.style.width=`${i}px`,a.style.height=`${c}px`;const h=a.getContext("2d");return h&&(h.scale(t,t),h.translate(-n,-o),this.drawTo(h,s)),a}copy(e){return this.currentPath=e.currentPath.clone(),this.paths=e.paths.map(t=>t.clone()),this.style={...e.style},this}clone(){return new this.constructor().copy(this)}}const Q="px",gt=90,ft=["mm","cm","in","pt","pc","px"],V={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 P(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=V.in[Q]/gt:(t=V[e][Q],t<0&&(t=V[e].in*gt)),t*Number.parseFloat(r)}const _t=new b,B=new b,pt=new b,dt=new b;function Ft(r,e,t){if(!(r.hasAttribute("transform")||r.nodeName==="use"&&(r.hasAttribute("x")||r.hasAttribute("y"))))return null;const s=Bt(r);return t.length>0&&s.premultiply(t[t.length-1]),e.copy(s),t.push(s),s}function Bt(r){const e=new b,t=_t;if(r.nodeName==="use"&&(r.hasAttribute("x")||r.hasAttribute("y"))&&e.translate(P(r.getAttribute("x")),P(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 a=o.slice(0,i),h=A(o.slice(i+1));switch(t.identity(),a){case"translate":if(h.length>=1){const l=h[0];let y=0;h.length>=2&&(y=h[1]),t.translate(l,y)}break;case"rotate":if(h.length>=1){let l=0,y=0,f=0;l=h[0]*Math.PI/180,h.length>=3&&(y=h[1],f=h[2]),B.makeTranslation(-y,-f),pt.makeRotation(l),dt.multiplyMatrices(pt,B),B.makeTranslation(y,f),t.multiplyMatrices(B,dt)}break;case"scale":h.length>=1&&t.scale(h[0],h[1]??h[0]);break;case"skewX":h.length===1&&t.set(1,Math.tan(h[0]*Math.PI/180),0,0,1,0,0,0,1);break;case"skewY":h.length===1&&t.set(1,0,0,Math.tan(h[0]*Math.PI/180),1,0,0,0,1);break;case"matrix":h.length===6&&t.set(h[0],h[2],h[4],h[1],h[3],h[5],0,0,1);break}}e.premultiply(t)}}return e}function Ut(r){return new I().addPath(new R().arc(P(r.getAttribute("cx")||0),P(r.getAttribute("cy")||0),P(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 Wt(r){return new I().addPath(new R().ellipse(P(r.getAttribute("cx")||0),P(r.getAttribute("cy")||0),P(r.getAttribute("rx")||0),P(r.getAttribute("ry")||0),0,0,Math.PI*2))}function Gt(r){return new I().moveTo(P(r.getAttribute("x1")||0),P(r.getAttribute("y1")||0)).lineTo(P(r.getAttribute("x2")||0),P(r.getAttribute("y2")||0))}function Qt(r){const e=new I,t=r.getAttribute("d");return!t||t==="none"?null:(e.addData(t),e)}const Vt=/([+-]?(?:\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(Vt,(n,o,i)=>{const c=P(o),a=P(i);return t===0?e.moveTo(c,a):e.lineTo(c,a),t++,n}),e.currentPath.autoClose=!0,e}const jt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function Zt(r){var s;const e=new I;let t=0;return(s=r.getAttribute("points"))==null||s.replace(jt,(n,o,i)=>{const c=P(o),a=P(i);return t===0?e.moveTo(c,a):e.lineTo(c,a),t++,n}),e.currentPath.autoClose=!1,e}function Jt(r){const e=P(r.getAttribute("x")||0),t=P(r.getAttribute("y")||0),s=P(r.getAttribute("rx")||r.getAttribute("ry")||0),n=P(r.getAttribute("ry")||r.getAttribute("rx")||0),o=P(r.getAttribute("width")),i=P(r.getAttribute("height")),c=1-.551915024494,a=new I;return a.moveTo(e+s,t),a.lineTo(e+o-s,t),(s!==0||n!==0)&&a.bezierCurveTo(e+o-s*c,t,e+o,t+n*c,e+o,t+n),a.lineTo(e+o,t+i-n),(s!==0||n!==0)&&a.bezierCurveTo(e+o,t+i-n*c,e+o-s*c,t+i,e+o-s,t+i),a.lineTo(e+s,t+i),(s!==0||n!==0)&&a.bezierCurveTo(e+s*c,t+i,e,t+i-n*c,e,t+i-n),a.lineTo(e,t+n),(s!==0||n!==0)&&a.bezierCurveTo(e,t+n*c,e+s*c,t,e+s,t),a}function E(r,e,t){e=Object.assign({},e);let s={};if(r.hasAttribute("class")){const a=r.getAttribute("class").split(/\s/).filter(Boolean).map(h=>h.trim());for(let h=0;h<a.length;h++)s=Object.assign(s,t[`.${a[h]}`])}r.hasAttribute("id")&&(s=Object.assign(s,t[`#${r.getAttribute("id")}`]));function n(a,h,l){l===void 0&&(l=function(f){return f.startsWith("url")&&console.warn("url access in attributes is not implemented."),f}),r.hasAttribute(a)&&(e[h]=l(r.getAttribute(a))),s[a]&&(e[h]=l(s[a])),r.style&&r.style[a]!==""&&(e[h]=l(r.style[a]))}function o(a){return Math.max(0,Math.min(1,P(a)))}function i(a){return Math.max(0,P(a))}function c(a){return a.split(" ").filter(h=>h!=="").map(h=>P(h))}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",P),n("visibility","visibility"),e}function H(r,e,t=[]){var l;if(r.nodeType!==1)return t;let s=!1,n=null;const o={};switch(r.nodeName){case"svg":e=E(r,e,o);break;case"style":Yt(r,o);break;case"g":e=E(r,e,o);break;case"path":e=E(r,e,o),r.hasAttribute("d")&&(n=Qt(r));break;case"rect":e=E(r,e,o),n=Jt(r);break;case"polygon":e=E(r,e,o),n=Ht(r);break;case"polyline":e=E(r,e,o),n=Zt(r);break;case"circle":e=E(r,e,o),n=Ut(r);break;case"ellipse":e=E(r,e,o),n=Wt(r);break;case"line":e=E(r,e,o),n=Gt(r);break;case"defs":s=!0;break;case"use":{e=E(r,e,o);const f=(r.getAttributeNS("http://www.w3.org/1999/xlink","href")||"").substring(1),p=(l=r.viewportElement)==null?void 0:l.getElementById(f);p?H(p,e,t):console.warn(`'use node' references non-existent node id: ${f}`);break}default:console.warn(r);break}const i=new b,c=[],a=Ft(r,i,c);n&&(n.matrix(i),t.push(n),n.style=e);const h=r.childNodes;for(let y=0,f=h.length;y<f;y++){const p=h[y];s&&p.nodeName!=="style"&&p.nodeName!=="defs"||H(p,e,t)}return a&&(c.pop(),c.length>0?i.copy(c[c.length-1]):i.identity()),t}const xt="data:image/svg+xml;",Mt=`${xt}base64,`,Pt=`${xt}charset=utf8,`;function mt(r){if(typeof r=="string"){let e;return r.startsWith(Mt)?(r=r.substring(Mt.length,r.length),e=atob(r)):r.startsWith(Pt)?(r=r.substring(Pt.length,r.length),e=decodeURIComponent(r)):e=r,new DOMParser().parseFromString(e,"image/svg+xml").documentElement}else return r}function Kt(r){return H(mt(r),{})}function te(r){if(!r.length)return;const e=u.MAX,t=u.MIN;return r.forEach(s=>s.getMinMax(e,t)),new L(e.x,e.y,t.x-e.x,t.y-e.y)}d.BoundingBox=L,d.CircleCurve=_,d.CubicBezierCurve=nt,d.Curve=k,d.CurvePath=R,d.EllipseCurve=ot,d.HeartCurve=Dt,d.LineCurve=X,d.Matrix3=b,d.Path2D=I,d.PloygonCurve=Xt,d.QuadraticBezierCurve=lt,d.RectangularCurve=ut,d.SplineCurve=yt,d.Vector2=u,d.addPathCommandsToPath2D=W,d.getPathsBoundingBox=te,d.parseArcCommand=J,d.parsePathDataArgs=A,d.parseSvg=Kt,d.parseSvgToDom=mt,d.pathCommandsToPathData=K,d.pathDataToPathCommands=G,d.setCanvasContext=q,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
1
+ (function(p,C){typeof exports=="object"&&typeof module<"u"?C(exports):typeof define=="function"&&define.amd?define(["exports"],C):(p=typeof globalThis<"u"?globalThis:p||self,C(p.modernPath2d={}))})(this,function(p){"use strict";var re=Object.defineProperty;var ie=(p,C,q)=>C in p?re(p,C,{enumerable:!0,configurable:!0,writable:!0,value:q}):p[C]=q;var T=(p,C,q)=>ie(p,typeof C!="symbol"?C+"":C,q);const C={arcs:"bevel",bevel:"bevel",miter:"miter","miter-clip":"miter",round:"round"};function q(o,e){const{fill:t="#000",stroke:s="none",strokeWidth:r=s==="none"?0:1,strokeLinecap:i="round",strokeLinejoin:n="miter",strokeMiterlimit:c=0,strokeDasharray:h=[],strokeDashoffset:a=0,shadowOffsetX:l=0,shadowOffsetY:y=0,shadowBlur:f=0,shadowColor:d="rgba(0, 0, 0, 0)"}=e;o.fillStyle=t,o.strokeStyle=s,o.lineWidth=r,o.lineCap=i,o.lineJoin=C[n],o.miterLimit=c,o.setLineDash(h),o.lineDashOffset=a,o.shadowOffsetX=l,o.shadowOffsetY=y,o.shadowBlur=f,o.shadowColor=d}class u{constructor(e=0,t=0){this.x=e,this.y=t}static get MAX(){return new u(1/0,1/0)}static get MIN(){return new u(-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}multiply(e){return this.x*=e.x,this.y*=e.y,this}divide(e){return this.x/=e.x,this.y/=e.y,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}rotate(e,t={x:0,y:0}){const s=-e/180*Math.PI,r=this.x-t.x,i=-(this.y-t.y),n=Math.sin(s),c=Math.cos(s);return this.set(t.x+(r*c-i*n),t.y-(r*n+i*c)),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}lengthSquared(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.lengthSquared())}scale(e,t=e,s={x:0,y:0}){const r=e<0?s.x-this.x+s.x:this.x,i=t<0?s.y-this.y+s.y:this.y;return this.x=r*Math.abs(e),this.y=i*Math.abs(t),this}skew(e,t=0,s={x:0,y:0}){const r=this.x-s.x,i=this.y-s.y;return this.x=s.x+(r+Math.tan(e)*i),this.y=s.y+(i+Math.tan(t)*r),this}min(...e){return this.x=Math.min(this.x,...e.map(t=>t.x)),this.y=Math.min(this.y,...e.map(t=>t.y)),this}max(...e){return this.x=Math.max(this.x,...e.map(t=>t.x)),this.y=Math.max(this.y,...e.map(t=>t.y)),this}normalize(){return this.scale(1/(this.length()||1))}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}multiplyVectors(e,t){return this.x=e.x*t.x,this.y=e.y*t.y,this}divideVectors(e,t){return this.x=e.x/t.x,this.y=e.y/t.y,this}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,r=e.elements;return this.x=r[0]*t+r[3]*s+r[6],this.y=r[1]*t+r[4]*s+r[7],this}copy(e){return this.x=e.x,this.y=e.y,this}clone(){return new u(this.x,this.y)}}class L{constructor(e=0,t=0,s=0,r=0){this.left=e,this.top=t,this.width=s,this.height=r}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){if(e.length===0)return new L;if(e.length===1)return e[0].clone();const t=e[0],s=e.slice(1).reduce((r,i)=>(r.left=Math.min(r.left,i.left),r.top=Math.min(r.top,i.top),r.right=Math.max(r.right,i.right),r.bottom=Math.max(r.bottom,i.bottom),r),{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 L(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 u((this.left+this.right)/2,(this.top+this.bottom)/2)}clone(){return new L(this.left,this.top,this.width,this.height)}toArray(){return[this.left,this.top,this.width,this.height]}}class b{constructor(e=1,t=0,s=0,r=0,i=1,n=0,c=0,h=0,a=1){T(this,"elements",[]);this.set(e,t,s,r,i,n,c,h,a)}set(e,t,s,r,i,n,c,h,a){const l=this.elements;return l[0]=e,l[1]=r,l[2]=c,l[3]=t,l[4]=i,l[5]=h,l[6]=s,l[7]=n,l[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,r=t.elements,i=this.elements,n=s[0],c=s[3],h=s[6],a=s[1],l=s[4],y=s[7],f=s[2],d=s[5],g=s[8],x=r[0],m=r[3],w=r[6],E=r[1],v=r[4],S=r[7],N=r[2],z=r[5],D=r[8];return i[0]=n*x+c*E+h*N,i[3]=n*m+c*v+h*z,i[6]=n*w+c*S+h*D,i[1]=a*x+l*E+y*N,i[4]=a*m+l*v+y*z,i[7]=a*w+l*S+y*D,i[2]=f*x+d*E+g*N,i[5]=f*m+d*v+g*z,i[8]=f*w+d*S+g*D,this}invert(){const e=this.elements,t=e[0],s=e[1],r=e[2],i=e[3],n=e[4],c=e[5],h=e[6],a=e[7],l=e[8],y=l*n-c*a,f=c*h-l*i,d=a*i-n*h,g=t*y+s*f+r*d;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]=(r*a-l*s)*x,e[2]=(c*s-r*n)*x,e[3]=f*x,e[4]=(l*t-r*h)*x,e[5]=(r*i-c*t)*x,e[6]=d*x,e[7]=(s*h-a*t)*x,e[8]=(n*t-s*i)*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(W.makeScale(e,t)),this}rotate(e){return this.premultiply(W.makeRotation(-e)),this}translate(e,t){return this.premultiply(W.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 W=new b;function K(o,e,t,s){const r=o*t+e*s,i=Math.sqrt(o*o+e*e)*Math.sqrt(t*t+s*s);let n=Math.acos(Math.max(-1,Math.min(1,r/i)));return o*s-e*t<0&&(n=-n),n}function tt(o,e,t,s,r,i,n,c){if(e===0||t===0){o.lineTo(c.x,c.y);return}s=s*Math.PI/180,e=Math.abs(e),t=Math.abs(t);const h=(n.x-c.x)/2,a=(n.y-c.y)/2,l=Math.cos(s)*h+Math.sin(s)*a,y=-Math.sin(s)*h+Math.cos(s)*a;let f=e*e,d=t*t;const g=l*l,x=y*y,m=g/f+x/d;if(m>1){const Ct=Math.sqrt(m);e=Ct*e,t=Ct*t,f=e*e,d=t*t}const w=f*x+d*g,E=(f*d-w)/w;let v=Math.sqrt(Math.max(0,E));r===i&&(v=-v);const S=v*e*y/t,N=-v*t*l/e,z=Math.cos(s)*S-Math.sin(s)*N+(n.x+c.x)/2,D=Math.sin(s)*S+Math.cos(s)*N+(n.y+c.y)/2,U=K(1,0,(l-S)/e,(y-N)/t),J=K((l-S)/e,(y-N)/t,(-l-S)/e,(-y-N)/t)%(Math.PI*2);o.ellipse(z,D,e,t,s,U,U+J,i===1)}function X(o,e){return o-(e-o)}function Y(o,e){const t=new u,s=new u;for(let r=0,i=o.length;r<i;r++){const n=o[r];if(n.type==="m"||n.type==="M")n.type==="m"?t.add(n):t.copy(n),e.moveTo(t.x,t.y),s.copy(t);else if(n.type==="h"||n.type==="H")n.type==="h"?t.x+=n.x:t.x=n.x,e.lineTo(t.x,t.y),s.copy(t);else if(n.type==="v"||n.type==="V")n.type==="v"?t.y+=n.y:t.y=n.y,e.lineTo(t.x,t.y),s.copy(t);else if(n.type==="l"||n.type==="L")n.type==="l"?t.add(n):t.copy(n),e.lineTo(t.x,t.y),s.copy(t);else if(n.type==="c"||n.type==="C")n.type==="c"?(e.bezierCurveTo(t.x+n.x1,t.y+n.y1,t.x+n.x2,t.y+n.y2,t.x+n.x,t.y+n.y),s.x=t.x+n.x2,s.y=t.y+n.y2,t.add(n)):(e.bezierCurveTo(n.x1,n.y1,n.x2,n.y2,n.x,n.y),s.x=n.x2,s.y=n.y2,t.copy(n));else if(n.type==="s"||n.type==="S")n.type==="s"?(e.bezierCurveTo(X(t.x,s.x),X(t.y,s.y),t.x+n.x2,t.y+n.y2,t.x+n.x,t.y+n.y),s.x=t.x+n.x2,s.y=t.y+n.y2,t.add(n)):(e.bezierCurveTo(X(t.x,s.x),X(t.y,s.y),n.x2,n.y2,n.x,n.y),s.x=n.x2,s.y=n.y2,t.copy(n));else if(n.type==="q"||n.type==="Q")n.type==="q"?(e.quadraticCurveTo(t.x+n.x1,t.y+n.y1,t.x+n.x,t.y+n.y),s.x=t.x+n.x1,s.y=t.y+n.y1,t.add(n)):(e.quadraticCurveTo(n.x1,n.y1,n.x,n.y),s.x=n.x1,s.y=n.y1,t.copy(n));else if(n.type==="t"||n.type==="T"){const c=X(t.x,s.x),h=X(t.y,s.y);s.x=c,s.y=h,n.type==="t"?(e.quadraticCurveTo(c,h,t.x+n.x,t.y+n.y),t.add(n)):(e.quadraticCurveTo(c,h,n.x,n.y),t.copy(n))}else if(n.type==="a"||n.type==="A"){const c=t.clone();if(n.type==="a"){if(n.x===0&&n.y===0)continue;t.add(n)}else{if(t.equals(n))continue;t.copy(n)}s.copy(t),tt(e,n.rx,n.ry,n.angle,n.largeArcFlag,n.sweepFlag,c,t)}else n.type==="z"||n.type==="Z"?(e.startPoint&&t.copy(e.startPoint),e.closePath()):console.warn("Unsupported commands",n)}}const P={SEPARATOR:/[ \t\r\n,.\-+]/,WHITESPACE:/[ \t\r\n]/,DIGIT:/\d/,SIGN:/[-+]/,POINT:/\./,COMMA:/,/,EXP:/e/i,FLAGS:/[01]/};function A(o,e,t=0){let c=0,h=!0,a="",l="";const y=[];function f(m,w,E){const v=new SyntaxError(`Unexpected character "${m}" at index ${w}.`);throw v.partial=E,v}function d(){a!==""&&(l===""?y.push(Number(a)):y.push(Number(a)*10**Number(l))),a="",l=""}let g;const x=o.length;for(let m=0;m<x;m++){if(g=o[m],Array.isArray(e)&&e.includes(y.length%t)&&P.FLAGS.test(g)){c=1,a=g,d();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)){l+=g;continue}if(P.SIGN.test(g)){if(l===""){l+=g;continue}l.length===1&&P.SIGN.test(l)&&f(g,m,y)}}P.WHITESPACE.test(g)?(d(),c=0,h=!1):P.COMMA.test(g)?(d(),c=0,h=!0):P.SIGN.test(g)?(d(),c=1,a=g):P.POINT.test(g)?(d(),c=2,a=g):f(g,m,y)}return d(),y}function et(o){const e={x:0,y:0},t={x:0,y:0};let s="";for(let r=0,i=o.length;r<i;r++){const n=o[r];switch(n.type){case"m":case"M":if(n.x===t.x&&n.y===t.y)continue;s+=`${n.type} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y,e.x=n.x,e.y=n.y;break;case"h":case"H":s+=`${n.type} ${n.x}`,t.x=n.x;break;case"v":case"V":s+=`${n.type} ${n.y}`,t.y=n.y;break;case"l":case"L":s+=`${n.type} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y;break;case"c":case"C":s+=`${n.type} ${n.x1} ${n.y1} ${n.x2} ${n.y2} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y;break;case"s":case"S":s+=`${n.type} ${n.x2} ${n.y2} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y;break;case"q":case"Q":s+=`${n.type} ${n.x1} ${n.y1} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y;break;case"t":case"T":s+=`${n.type} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y;break;case"a":case"A":s+=`${n.type} ${n.rx} ${n.ry} ${n.angle} ${n.largeArcFlag} ${n.sweepFlag} ${n.x} ${n.y}`,t.x=n.x,t.y=n.y;break;case"z":case"Z":s+=n.type,t.x=e.x,t.y=e.y;break}}return s}const vt=/[a-df-z][^a-df-z]*/gi;function G(o){const e=[],t=o.match(vt);if(!t)return e;for(let s=0,r=t.length;s<r;s++){const i=t[s],n=i.charAt(0),c=i.slice(1).trim();let h;switch(n){case"m":case"M":h=A(c);for(let a=0,l=h.length;a<l;a+=2)a===0?e.push({type:n,x:h[a],y:h[a+1]}):e.push({type:n==="m"?"l":"L",x:h[a],y:h[a+1]});break;case"h":case"H":h=A(c);for(let a=0,l=h.length;a<l;a++)e.push({type:n,x:h[a]});break;case"v":case"V":h=A(c);for(let a=0,l=h.length;a<l;a++)e.push({type:n,y:h[a]});break;case"l":case"L":h=A(c);for(let a=0,l=h.length;a<l;a+=2)e.push({type:n,x:h[a],y:h[a+1]});break;case"c":case"C":h=A(c);for(let a=0,l=h.length;a<l;a+=6)e.push({type:n,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,l=h.length;a<l;a+=4)e.push({type:n,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,l=h.length;a<l;a+=4)e.push({type:n,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,l=h.length;a<l;a+=2)e.push({type:n,x:h[a],y:h[a+1]});break;case"a":case"A":h=A(c,[3,4],7);for(let a=0,l=h.length;a<l;a+=7)e.push({type:n,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:n});break;default:console.warn(i)}}return e}class k{constructor(){T(this,"arcLengthDivisions",200);T(this,"_cacheArcLengths");T(this,"_needsUpdate",!1)}isClockwise(){const e=this.getPoint(1),t=this.getPoint(.5),s=this.getPoint(1);return(t.x-e.x)*(s.y-t.y)-(t.y-e.y)*(s.x-t.x)<0}getPointAt(e,t=new u){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}forEachControlPoints(e){return this.getControlPoints().forEach(e),this}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,r=this.getPoint(0),i=0;t.push(0);for(let n=1;n<=e;n++)s=this.getPoint(n/e),i+=s.distanceTo(r),t.push(i),r=s;return this._cacheArcLengths=t,t}updateArcLengths(){this._needsUpdate=!0,this.getLengths()}getUToTMapping(e,t){const s=this.getLengths();let r=0;const i=s.length;let n;t?n=t:n=e*s[i-1];let c=0,h=i-1,a;for(;c<=h;)if(r=Math.floor(c+(h-c)/2),a=s[r]-n,a<0)c=r+1;else if(a>0)h=r-1;else{h=r;break}if(r=h,s[r]===n)return r/(i-1);const l=s[r],f=s[r+1]-l,d=(n-l)/f;return(r+d)/(i-1)}getTangent(e,t=new u){const r=Math.max(0,e-1e-4),i=Math.min(1,e+1e-4);return t.copy(this.getPoint(i).sub(this.getPoint(r)).normalize())}getTangentAt(e,t){return this.getTangent(this.getUToTMapping(e),t)}getNormal(e,t=new u){return this.getTangent(e,t),t.set(-t.y,t.x).normalize()}getNormalAt(e,t){return this.getNormal(this.getUToTMapping(e),t)}getTForPoint(e,t=.001){let s=0,r=1,i=(s+r)/2;for(;r-s>t;){i=(s+r)/2;const n=this.getPoint(i);if(n.distanceTo(e)<t)return i;n.x<e.x?s=i:r=i}return i}matrix(e){return this.forEachControlPoints(t=>t.applyMatrix3(e)),this}getMinMax(e=u.MAX,t=u.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 L(e.x,e.y,t.x-e.x,t.y-e.y)}toCommands(){return this.getPoints().map((e,t)=>t===0?{type:"M",x:e.x,y:e.y}:{type:"L",x:e.x,y:e.y})}toData(){return et(this.toCommands())}drawTo(e){return this.toCommands().forEach(t=>{switch(t.type){case"M":e.moveTo(t.x,t.y);break;case"L":e.lineTo(t.x,t.y);break}}),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,r=Math.PI*2){super(),this.center=e,this.radius=t,this.start=s,this.end=r}getPoint(e){const{radius:t,center:s}=this;return s.clone().add(this.getNormal(e).clone().scale(t))}getTangent(e,t=new u){const{x:s,y:r}=this.getNormal(e);return t.set(-r,s)}getNormal(e,t=new u){const{start:s,end:r}=this,i=e*(r-s)+s-.5*Math.PI;return t.set(Math.cos(i),Math.sin(i))}getControlPoints(){return[this.center]}getMinMax(e=u.MAX,t=u.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 st(o,e,t,s,r){const i=(s-e)*.5,n=(r-t)*.5,c=o*o,h=o*c;return(2*t-2*s+i+n)*h+(-3*t+3*s-2*i-n)*c+i*o+t}function bt(o,e){const t=1-o;return t*t*e}function At(o,e){return 2*(1-o)*o*e}function kt(o,e){return o*o*e}function nt(o,e,t,s){return bt(o,e)+At(o,t)+kt(o,s)}function It(o,e){const t=1-o;return t*t*t*e}function St(o,e){const t=1-o;return 3*t*t*o*e}function Nt(o,e){return 3*(1-o)*o*o*e}function $t(o,e){return o*o*o*e}function rt(o,e,t,s,r){return It(o,e)+St(o,t)+Nt(o,s)+$t(o,r)}class it extends k{constructor(e=new u,t=new u,s=new u,r=new u){super(),this.start=e,this.startControl=t,this.endControl=s,this.end=r}getPoint(e,t=new u){const{start:s,startControl:r,endControl:i,end:n}=this;return t.set(rt(e,s.x,r.x,i.x,n.x),rt(e,s.y,r.y,i.y,n.y))}getControlPoints(){return[this.start,this.startControl,this.endControl,this.end]}_solveQuadratic(e,t,s){const r=t*t-4*e*s;if(r<0)return[];const i=Math.sqrt(r),n=(-t+i)/(2*e),c=(-t-i)/(2*e);return[n,c].filter(h=>h>=0&&h<=1)}getMinMax(e=u.MAX,t=u.MIN){const s=this.start,r=this.startControl,i=this.endControl,n=this.end,c=this._solveQuadratic(3*(r.x-s.x),6*(i.x-r.x),3*(n.x-i.x)),h=this._solveQuadratic(3*(r.y-s.y),6*(i.y-r.y),3*(n.y-i.y)),a=[0,1,...c,...h];return((y,f)=>{for(const d of y)for(let g=0;g<=f;g++){const x=g/f-.5,m=Math.min(1,Math.max(0,d+x)),w=this.getPoint(m);e.x=Math.min(e.x,w.x),e.y=Math.min(e.y,w.y),t.x=Math.max(t.x,w.x),t.y=Math.max(t.y,w.y)}})(a,10),{min:e,max:t}}toCommands(){const{start:e,startControl:t,endControl:s,end:r}=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:r.x,y:r.y}]}drawTo(e){const{start:t,startControl:s,endControl:r,end:i}=this;return e.lineTo(t.x,t.y),e.bezierCurveTo(s.x,s.y,r.x,r.y,i.x,i.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 Et=new b,ot=new b,at=new b,_=new u;class ht extends k{constructor(e=new u,t=1,s=1,r=0,i=0,n=Math.PI*2,c=!1){super(),this.center=e,this.radiusX=t,this.radiusY=s,this.rotation=r,this.startAngle=i,this.endAngle=n,this.clockwise=c}isClockwise(){return this.clockwise}getPoint(e,t=new u){const s=Math.PI*2;let r=this.endAngle-this.startAngle;const i=Math.abs(r)<Number.EPSILON;for(;r<0;)r+=s;for(;r>s;)r-=s;r<Number.EPSILON&&(i?r=0:r=s),this.clockwise&&!i&&(r===s?r=-s:r=r-s);const n=this.startAngle+e*r;let c=this.center.x+this.radiusX*Math.cos(n),h=this.center.y+this.radiusY*Math.sin(n);if(this.rotation!==0){const a=Math.cos(this.rotation),l=Math.sin(this.rotation),y=c-this.center.x,f=h-this.center.y;c=y*a-f*l+this.center.x,h=y*l+f*a+this.center.y}return t.set(c,h)}toCommands(){const{center:e,radiusX:t,radiusY:s,startAngle:r,endAngle:i,clockwise:n,rotation:c}=this,{x:h,y:a}=e,l=h+t*Math.cos(r)*Math.cos(c)-s*Math.sin(r)*Math.sin(c),y=a+t*Math.cos(r)*Math.sin(c)+s*Math.sin(r)*Math.cos(c),f=Math.abs(r-i),d=f>Math.PI?1:0,g=n?1:0,x=c*180/Math.PI;if(f>=2*Math.PI){const m=r+Math.PI,w=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:l,y},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:0,sweepFlag:g,x:w,y:E},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:0,sweepFlag:g,x:l,y}]}else{const m=h+t*Math.cos(i)*Math.cos(c)-s*Math.sin(i)*Math.sin(c),w=a+t*Math.cos(i)*Math.sin(c)+s*Math.sin(i)*Math.cos(c);return[{type:"M",x:l,y},{type:"A",rx:t,ry:s,angle:x,largeArcFlag:d,sweepFlag:g,x:m,y:w}]}}drawTo(e){const{center:t,radiusX:s,radiusY:r,rotation:i,startAngle:n,endAngle:c,clockwise:h}=this;return e.ellipse(t.x,t.y,s,r,i,n,c,!h),this}matrix(e){return _.set(this.center.x,this.center.y),_.applyMatrix3(e),this.center.x=_.x,this.center.y=_.y,zt(e)?Lt(this,e):qt(this,e),this}getControlPoints(){return[this.center]}getMinMax(e=u.MAX,t=u.MIN){const{center:s,radiusX:r,radiusY:i,rotation:n}=this,{x:c,y:h}=s,a=Math.cos(n),l=Math.sin(n),y=Math.sqrt(r*r*a*a+i*i*l*l),f=Math.sqrt(r*r*l*l+i*i*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 Lt(o,e){const t=o.radiusX,s=o.radiusY,r=Math.cos(o.rotation),i=Math.sin(o.rotation),n=new u(t*r,t*i),c=new u(-s*i,s*r),h=n.applyMatrix3(e),a=c.applyMatrix3(e),l=Et.set(h.x,a.x,0,h.y,a.y,0,0,0,1),y=ot.copy(l).invert(),g=at.copy(y).transpose().multiply(y).elements,x=Dt(g[0],g[1],g[4]),m=Math.sqrt(x.rt1),w=Math.sqrt(x.rt2);if(o.radiusX=1/m,o.radiusY=1/w,o.rotation=Math.atan2(x.sn,x.cs),!((o.endAngle-o.startAngle)%(2*Math.PI)<Number.EPSILON)){const v=ot.set(m,0,0,0,w,0,0,0,1),S=at.set(x.cs,x.sn,0,-x.sn,x.cs,0,0,0,1),N=v.multiply(S).multiply(l),z=D=>{const{x:U,y:J}=new u(Math.cos(D),Math.sin(D)).applyMatrix3(N);return Math.atan2(J,U)};o.startAngle=z(o.startAngle),o.endAngle=z(o.endAngle),ct(e)&&(o.clockwise=!o.clockwise)}}function qt(o,e){const t=lt(e),s=ut(e);o.radiusX*=t,o.radiusY*=s;const r=t>Number.EPSILON?Math.atan2(e.elements[1],e.elements[0]):Math.atan2(-e.elements[3],e.elements[4]);o.rotation+=r,ct(e)&&(o.startAngle*=-1,o.endAngle*=-1,o.clockwise=!o.clockwise)}function ct(o){const e=o.elements;return e[0]*e[4]-e[1]*e[3]<0}function zt(o){const e=o.elements,t=e[0]*e[3]+e[1]*e[4];if(t===0)return!1;const s=lt(o),r=ut(o);return Math.abs(t/(s*r))>Number.EPSILON}function lt(o){const e=o.elements;return Math.sqrt(e[0]*e[0]+e[1]*e[1])}function ut(o){const e=o.elements;return Math.sqrt(e[3]*e[3]+e[4]*e[4])}function Dt(o,e,t){let s,r,i,n,c;const h=o+t,a=o-t,l=Math.sqrt(a*a+4*e*e);return h>0?(s=.5*(h+l),c=1/s,r=o*c*t-e*c*e):h<0?r=.5*(h-l):(s=.5*l,r=-.5*l),a>0?i=a+l:i=a-l,Math.abs(i)>2*Math.abs(e)?(c=-2*e/i,n=1/Math.sqrt(1+c*c),i=c*n):Math.abs(e)===0?(i=1,n=0):(c=-.5*i/e,i=1/Math.sqrt(1+c*c),n=c*i),a>0&&(c=i,i=-n,n=c),{rt1:s,rt2:r,cs:i,sn:n}}class O extends k{constructor(e=new u,t=new u){super(),this.start=e,this.end=t}getPoint(e,t=new u){return e===1?t.copy(this.end):t.copy(this.end).sub(this.start).scale(e).add(this.start),t}getPointAt(e,t=new u){return this.getPoint(e,t)}getTangent(e,t=new u){return t.subVectors(this.end,this.start).normalize()}getTangentAt(e,t=new u){return this.getTangent(e,t)}getControlPoints(){return[this.start,this.end]}getMinMax(e=u.MAX,t=u.MIN){const{start:s,end:r}=this;return e.x=Math.min(e.x,s.x,r.x),e.y=Math.min(e.y,s.y,r.y),t.x=Math.max(t.x,s.x,r.x),t.y=Math.max(t.y,s.y,r.y),{min:e,max:t}}toCommands(){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{start:t,end:s}=this;return e.lineTo(t.x,t.y),e.lineTo(s.x,s.y),this}copy(e){return super.copy(e),this.start.copy(e.start),this.end.copy(e.end),this}}class Ot extends k{constructor(t,s,r=0,i=1){super();T(this,"curveT",0);this.center=t,this.size=s,this.start=r,this.end=i,this.update()}update(){const{x:t,y:s}=this.center,r=new u(t+.5*this.size,s-.5*this.size),i=new u(t-.5*this.size,s-.5*this.size),n=new u(t,s+.5*this.size),c=new F(r,Math.SQRT1_2*this.size,-.25*Math.PI,.75*Math.PI),h=new F(i,Math.SQRT1_2*this.size,-.75*Math.PI,.25*Math.PI),a=new F(n,.5*Math.SQRT1_2*this.size,.75*Math.PI,1.25*Math.PI),l=new u(t,s+this.size),y=new u(t+this.size,s),f=new u().lerpVectors(y,l,.75),d=new u(t-this.size,s),g=new u().lerpVectors(d,l,.75),x=new O(y,f),m=new O(g,d);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 r;const i=.5*Math.PI;return s<i?(r=0,this.curveT=s/i):s<i+.75?(r=1,this.curveT=(s-i)/.75):s<5*Math.PI/8+.75?(r=2,this.curveT=(s-i-.75)/(Math.PI/8)):s<5*Math.PI/8+1.5?(r=3,this.curveT=(s-5*Math.PI/8-.75)/.75):(r=4,this.curveT=(s-5*Math.PI/8-1.5)/i),this.curves[r]}getTangent(t,s){return this.getCurve(t).getTangent(this.curveT,s)}getNormal(t,s){return this.getCurve(t).getNormal(this.curveT,s)}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(r=>r.getMinMax(t,s)),{min:t,max:s}}toCommands(){return this.curves.flatMap(t=>t.toCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class Xt extends k{constructor(t,s=0,r=0,i=0,n=1){super();T(this,"curves",[]);T(this,"curveT",0);T(this,"points",[]);this.center=t,this.radius=s,this.number=r,this.start=i,this.end=n,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 u(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 O(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 r=s*this.number,i=Math.floor(r);return this.curveT=r-i,this.curves[i]}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)}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(r=>r.getMinMax(t,s)),{min:t,max:s}}toCommands(){return this.curves.flatMap(t=>t.toCommands())}drawTo(t){return this.curves.forEach(s=>s.drawTo(t)),this}}class yt extends k{constructor(e=new u,t=new u,s=new u){super(),this.start=e,this.control=t,this.end=s}getPoint(e,t=new u){const{start:s,control:r,end:i}=this;return t.set(nt(e,s.x,r.x,i.x),nt(e,s.y,r.y,i.y)),t}getControlPoints(){return[this.start,this.control,this.end]}getMinMax(e=u.MAX,t=u.MIN){const{start:s,control:r,end:i}=this,n=.5*(s.x+r.x),c=.5*(s.y+r.y),h=.5*(s.x+i.x),a=.5*(s.y+i.y);return e.x=Math.min(e.x,s.x,i.x,n,h),e.y=Math.min(e.y,s.y,i.y,c,a),t.x=Math.max(t.x,s.x,i.x,n,h),t.y=Math.max(t.y,s.y,i.y,c,a),{min:e,max:t}}toCommands(){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{start:t,control:s,end:r}=this;return e.lineTo(t.x,t.y),e.quadraticCurveTo(s.x,s.y,r.x,r.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 gt extends k{constructor(t,s,r=1,i=0,n=1){super();T(this,"curves",[]);T(this,"curveT",0);this.center=t,this.rx=s,this.aspectRatio=r,this.start=i,this.end=n,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,r=this.rx,i=this.rx/this.aspectRatio,n=[new u(t-r,s-i),new u(t+r,s-i),new u(t+r,s+i),new u(t-r,s+i)];for(let c=0;c<4;c++)this.curves.push(new O(n[c].clone(),n[(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 r;return s<this.aspectRatio?(r=0,this.curveT=s/this.aspectRatio):s<this.aspectRatio+1?(r=1,this.curveT=(s-this.aspectRatio)/1):s<2*this.aspectRatio+1?(r=2,this.curveT=(s-this.aspectRatio-1)/this.aspectRatio):(r=3,this.curveT=(s-2*this.aspectRatio-1)/1),this.curves[r]}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)}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(r=>r.getMinMax(t,s)),{min:t,max:s}}toCommands(){return this.curves.flatMap(t=>t.toCommands())}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 u){const{points:s}=this,r=(s.length-1)*e,i=Math.floor(r),n=r-i,c=s[i===0?i:i-1],h=s[i],a=s[i>s.length-2?s.length-1:i+1],l=s[i>s.length-3?s.length-1:i+2];return t.set(st(n,c.x,h.x,a.x,l.x),st(n,c.y,h.y,a.y,l.y)),t}getControlPoints(){return this.points}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();T(this,"curves",[]);T(this,"startPoint");T(this,"currentPoint",new u);T(this,"autoClose",!1);T(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,r=t.length;s<r;s++){const{x:i,y:n}=t[s];this.lineTo(i,n)}return this}addCommands(t){return Y(t,this),this}addData(t){return this.addCommands(G(t)),this}getPoint(t,s=new u){const r=t*this.getLength(),i=this.getCurveLengths();let n=0;for(;n<i.length;){if(i[n]>=r){const c=i[n]-r,h=this.curves[n],a=h.getLength();return h.getPointAt(a===0?0:1-c/a,s)}n++}return s}getControlPoints(){return this.curves.flatMap(t=>t.getControlPoints())}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 r=0,i=this.curves.length;r<i;r++)s+=this.curves[r].getLength(),t.push(s);return this._cacheLengths=t,t}getSpacedPoints(t=40){const s=[];for(let r=0;r<=t;r++)s.push(this.getPoint(r/t));return this.autoClose&&s.push(s[0]),s}getPoints(t=12){const s=[],r=this.curves;let i;for(let n=0,c=r.length;n<c;n++){const a=r[n].getPoints(t);for(let l=0;l<a.length;l++){const y=a[l];i!=null&&i.equals(y)||(s.push(y),i=y)}}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 O(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 O(this.currentPoint.clone(),new u(t,s))),this._setCurrentPoint({x:t,y:s}),this}bezierCurveTo(t,s,r,i,n,c){return this.currentPoint.equals({x:n,y:c})||this.curves.push(new it(this.currentPoint.clone(),new u(t,s),new u(r,i),new u(n,c))),this._setCurrentPoint({x:n,y:c}),this}quadraticCurveTo(t,s,r,i){return this.currentPoint.equals({x:r,y:i})||this.curves.push(new yt(this.currentPoint.clone(),new u(t,s),new u(r,i))),this._setCurrentPoint({x:r,y:i}),this}arc(t,s,r,i,n,c){return this.ellipse(t,s,r,r,0,i,n,c),this}relativeArc(t,s,r,i,n,c){const h=this.currentPoint;return this.arc(t+h.x,s+h.y,r,i,n,c),this}arcTo(t,s,r,i,n){return console.warn("Method arcTo not supported yet"),this}ellipse(t,s,r,i,n,c,h,a=!0){const l=new ht(new u(t,s),r,i,n,c,h,!a);if(this.curves.length>0){const y=l.getPoint(0);y.equals(this.currentPoint)||this.lineTo(y.x,y.y)}return this.curves.push(l),this._setCurrentPoint(l.getPoint(1)),this}relativeEllipse(t,s,r,i,n,c,h,a){const l=this.currentPoint;return this.ellipse(t+l.x,s+l.y,r,i,n,c,h,a),this}rect(t,s,r,i){return this.curves.push(new gt(new u(t+r/2,s+i/2),r/2,r/i)),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}getMinMax(t=u.MAX,s=u.MIN){return this.curves.forEach(r=>r.getMinMax(t,s)),{min:t,max:s}}getBoundingBox(){const{min:t,max:s}=this.getMinMax();return new L(t.x,t.y,s.x-t.x,s.y-t.y)}toCommands(){return this.curves.flatMap(t=>t.toCommands())}drawTo(t){var r;const s=(r=this.curves[0])==null?void 0:r.getPoint(0);return s&&t.moveTo(s.x,s.y),this.curves.forEach(i=>i.drawTo(t)),this.autoClose&&t.closePath(),this}copy(t){super.copy(t),this.curves=[];for(let s=0,r=t.curves.length;s<r;s++)this.curves.push(t.curves[s].clone());return this.autoClose=t.autoClose,this.currentPoint.copy(t.currentPoint),this}}function Rt(o){return o.replace(/[^a-z0-9]/gi,"-").replace(/\B([A-Z])/g,"-$1").toLowerCase()}function Ft(o,e,t,s){const r=e.clone().sub(o),i=s.clone().sub(t),n=t.clone().sub(o),c=r.cross(i);if(c===0)return new u((o.x+t.x)/2,(o.y+t.y)/2);const h=n.cross(i)/c;return Math.abs(h)>1?new u((o.x+t.x)/2,(o.y+t.y)/2):new u(o.x+h*r.x,o.y+h*r.y)}class I{constructor(e){T(this,"currentPath",new R);T(this,"paths",[this.currentPath]);T(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:r}=this.currentPath;return s.equals({x:e,y:t})||(r.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,r,i,n){return this.currentPath.bezierCurveTo(e,t,s,r,i,n),this}quadraticCurveTo(e,t,s,r){return this.currentPath.quadraticCurveTo(e,t,s,r),this}arc(e,t,s,r,i,n){return this.currentPath.arc(e,t,s,r,i,n),this}arcTo(e,t,s,r,i){return this.currentPath.arcTo(e,t,s,r,i),this}ellipse(e,t,s,r,i,n,c,h){return this.currentPath.ellipse(e,t,s,r,i,n,c,h),this}rect(e,t,s,r){return this.currentPath.rect(e,t,s,r),this}addCommands(e){return Y(e,this),this}addData(e){return this.addCommands(G(e)),this}splineThru(e){return this.currentPath.splineThru(e),this}getControlPoints(){return this.paths.flatMap(e=>e.getControlPoints())}getCurves(){return this.paths.flatMap(e=>e.curves)}scale(e,t=e,s={x:0,y:0}){return this.getControlPoints().forEach(r=>{r.scale(e,t,s)}),this}skew(e,t=0,s={x:0,y:0}){return this.getControlPoints().forEach(r=>{r.skew(e,t,s)}),this}rotate(e,t={x:0,y:0}){return this.getControlPoints().forEach(s=>{s.rotate(e,t)}),this}bold(e){if(e===0)return this;const t=this.getCurves(),s=[],r=[],i=[];t.forEach((c,h)=>{const a=c.getControlPoints(),l=c.isClockwise();i[h]=a,r[h]=l;const y=a[0],f=a[a.length-1]??y;s.push({start:l?f:y,end:l?y:f,index:h})});const n=[];return s.forEach((c,h)=>{n[h]=[],s.forEach((a,l)=>{l!==h&&a.start.equals(c.end)&&n[h].push(a.index)})}),t.forEach((c,h)=>{const a=r[h];i[h].forEach(y=>{const f=c.getTForPoint(y),d=c.getNormal(f).scale(a?e:-e);y.add(d)})}),n.forEach((c,h)=>{const a=i[h];c.forEach(l=>{const y=i[l],f=Ft(a[a.length-1],a[a.length-2]??a[a.length-1],y[0],y[1]??y[0]);f&&(a[a.length-1].copy(f),y[0].copy(f))})}),this}matrix(e){return this.getCurves().forEach(t=>t.matrix(e)),this}getMinMax(e=u.MAX,t=u.MIN,s=!0){const r=this.strokeWidth;return this.getCurves().forEach(i=>{if(i.getMinMax(e,t),s&&r>1){const n=r/2,c=i.isClockwise(),h=[];for(let a=0;a<=1;a+=1/i.arcLengthDivisions){const l=i.getPoint(a),y=i.getNormal(a),f=y.clone().scale(c?n:-n),d=y.clone().scale(c?-n:n);h.push(l.clone().add(f),l.clone().add(d),l.clone().add({x:n,y:0}),l.clone().add({x:-n,y:0}),l.clone().add({x:0,y:n}),l.clone().add({x:0,y:-n}),l.clone().add({x:n,y:n}),l.clone().add({x:-n,y:-n}))}e.min(...h),t.max(...h)}}),{min:e,max:t}}getBoundingBox(e=!0){const{min:t,max:s}=this.getMinMax(void 0,void 0,e);return new L(t.x,t.y,s.x-t.x,s.y-t.y)}drawTo(e,t={}){t={...this.style,...t};const{fill:s="#000",stroke:r="none"}=t;return e.beginPath(),e.save(),q(e,t),this.paths.forEach(i=>{i.drawTo(e)}),s!=="none"&&e.fill(),r!=="none"&&e.stroke(),e.restore(),this}drawControlPointsTo(e,t={}){t={...this.style,...t};const{fill:s="#000",stroke:r="none"}=t;return e.beginPath(),e.save(),q(e,t),this.getControlPoints().forEach(i=>{e.moveTo(i.x,i.y),e.arc(i.x,i.y,4,0,Math.PI*2)}),s!=="none"&&e.fill(),r!=="none"&&e.stroke(),e.restore(),this}toCommands(){return this.paths.flatMap(e=>e.toCommands())}toData(){return this.paths.map(e=>e.toData()).join(" ")}toSvgPathString(){const e={...this.style,fill:this.style.fill??"#000",stroke:this.style.stroke??"none"},t={};for(const r in e)e[r]!==void 0&&(t[Rt(r)]=e[r]);Object.assign(t,{"stroke-width":`${this.strokeWidth}px`});let s="";for(const r in t)t[r]!==void 0&&(s+=`${r}:${t[r]};`);return`<path d="${this.toData()}" style="${s}"></path>`}toSvgString(){const{x:e,y:t,width:s,height:r}=this.getBoundingBox(),i=this.toSvgPathString();return`<svg viewBox="${e} ${t} ${s} ${r}" width="${s}px" height="${r}px" xmlns="http://www.w3.org/2000/svg">${i}</svg>`}toSvgUrl(){return`data:image/svg+xml;base64,${btoa(this.toSvgString())}`}toSvg(){return new DOMParser().parseFromString(this.toSvgString(),"image/svg+xml").documentElement}toCanvas(e={}){const{pixelRatio:t=2,...s}=e,{left:r,top:i,width:n,height:c}=this.getBoundingBox(),h=document.createElement("canvas");h.width=n*t,h.height=c*t,h.style.width=`${n}px`,h.style.height=`${c}px`;const a=h.getContext("2d");return a&&(a.scale(t,t),a.translate(-r,-i),this.drawTo(a,s)),h}copy(e){return this.currentPath=e.currentPath.clone(),this.paths=e.paths.map(t=>t.clone()),this.style={...e.style},this}clone(){return new this.constructor().copy(this)}}const Q="px",pt=90,dt=["mm","cm","in","pt","pc","px"],j={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(o){let e="px";if(typeof o=="string"||o instanceof String)for(let s=0,r=dt.length;s<r;s++){const i=dt[s];if(o.endsWith(i)){e=i,o=o.substring(0,o.length-i.length);break}}let t;return e==="px"&&Q!=="px"?t=j.in[Q]/pt:(t=j[e][Q],t<0&&(t=j[e].in*pt)),t*Number.parseFloat(o)}const _t=new b,B=new b,xt=new b,mt=new b;function Bt(o,e,t){if(!(o.hasAttribute("transform")||o.nodeName==="use"&&(o.hasAttribute("x")||o.hasAttribute("y"))))return null;const s=Ut(o);return t.length>0&&s.premultiply(t[t.length-1]),e.copy(s),t.push(s),s}function Ut(o){const e=new b,t=_t;if(o.nodeName==="use"&&(o.hasAttribute("x")||o.hasAttribute("y"))&&e.translate(M(o.getAttribute("x")),M(o.getAttribute("y"))),o.hasAttribute("transform")){const s=o.getAttribute("transform").split(")");for(let r=s.length-1;r>=0;r--){const i=s[r].trim();if(i==="")continue;const n=i.indexOf("("),c=i.length;if(n>0&&n<c){const h=i.slice(0,n),a=A(i.slice(n+1));switch(t.identity(),h){case"translate":if(a.length>=1){const l=a[0];let y=0;a.length>=2&&(y=a[1]),t.translate(l,y)}break;case"rotate":if(a.length>=1){let l=0,y=0,f=0;l=a[0]*Math.PI/180,a.length>=3&&(y=a[1],f=a[2]),B.makeTranslation(-y,-f),xt.makeRotation(l),mt.multiplyMatrices(xt,B),B.makeTranslation(y,f),t.multiplyMatrices(B,mt)}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(o){return new I().addPath(new R().arc(M(o.getAttribute("cx")||0),M(o.getAttribute("cy")||0),M(o.getAttribute("r")||0),0,Math.PI*2))}function Yt(o,e){if(!(!o.sheet||!o.sheet.cssRules||!o.sheet.cssRules.length))for(let t=0;t<o.sheet.cssRules.length;t++){const s=o.sheet.cssRules[t];if(s.type!==1)continue;const r=s.selectorText.split(/,/g).filter(Boolean).map(i=>i.trim());for(let i=0;i<r.length;i++){const n=Object.fromEntries(Object.entries(s.style).filter(([,c])=>c!==""));e[r[i]]=Object.assign(e[r[i]]||{},n)}}}function Gt(o){return new I().addPath(new R().ellipse(M(o.getAttribute("cx")||0),M(o.getAttribute("cy")||0),M(o.getAttribute("rx")||0),M(o.getAttribute("ry")||0),0,0,Math.PI*2))}function Qt(o){return new I().moveTo(M(o.getAttribute("x1")||0),M(o.getAttribute("y1")||0)).lineTo(M(o.getAttribute("x2")||0),M(o.getAttribute("y2")||0))}function jt(o){const e=new I,t=o.getAttribute("d");return!t||t==="none"?null:(e.addData(t),e)}const Vt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function Ht(o){var s;const e=new I;let t=0;return(s=o.getAttribute("points"))==null||s.replace(Vt,(r,i,n)=>{const c=M(i),h=M(n);return t===0?e.moveTo(c,h):e.lineTo(c,h),t++,r}),e.currentPath.autoClose=!0,e}const Zt=/([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;function Jt(o){var s;const e=new I;let t=0;return(s=o.getAttribute("points"))==null||s.replace(Zt,(r,i,n)=>{const c=M(i),h=M(n);return t===0?e.moveTo(c,h):e.lineTo(c,h),t++,r}),e.currentPath.autoClose=!1,e}function Kt(o){const e=M(o.getAttribute("x")||0),t=M(o.getAttribute("y")||0),s=M(o.getAttribute("rx")||o.getAttribute("ry")||0),r=M(o.getAttribute("ry")||o.getAttribute("rx")||0),i=M(o.getAttribute("width")),n=M(o.getAttribute("height")),c=1-.551915024494,h=new I;return h.moveTo(e+s,t),h.lineTo(e+i-s,t),(s!==0||r!==0)&&h.bezierCurveTo(e+i-s*c,t,e+i,t+r*c,e+i,t+r),h.lineTo(e+i,t+n-r),(s!==0||r!==0)&&h.bezierCurveTo(e+i,t+n-r*c,e+i-s*c,t+n,e+i-s,t+n),h.lineTo(e+s,t+n),(s!==0||r!==0)&&h.bezierCurveTo(e+s*c,t+n,e,t+n-r*c,e,t+n-r),h.lineTo(e,t+r),(s!==0||r!==0)&&h.bezierCurveTo(e,t+r*c,e+s*c,t,e+s,t),h}function $(o,e,t){e=Object.assign({},e);let s={};if(o.hasAttribute("class")){const a=o.getAttribute("class").split(/\s/).filter(Boolean).map(l=>l.trim());for(let l=0;l<a.length;l++)s=Object.assign(s,t[`.${a[l]}`])}o.hasAttribute("id")&&(s=Object.assign(s,t[`#${o.getAttribute("id")}`]));for(let a=o.style.length,l=0;l<a;l++){const y=o.style.item(l),f=o.style.getPropertyValue(y);e[y]=f,s[y]=f}function r(a,l,y=i){o.hasAttribute(a)&&(e[l]=y(o.getAttribute(a))),s[a]&&(e[l]=y(s[a]))}function i(a){return a.startsWith("url")&&console.warn("url access in attributes is not implemented."),a}function n(a){return Math.max(0,Math.min(1,M(a)))}function c(a){return Math.max(0,M(a))}function h(a){return a.split(" ").filter(l=>l!=="").map(l=>M(l))}return r("fill","fill"),r("fill-opacity","fillOpacity",n),r("fill-rule","fillRule"),r("opacity","opacity",n),r("stroke","stroke"),r("stroke-opacity","strokeOpacity",n),r("stroke-width","strokeWidth",c),r("stroke-linecap","strokeLinecap"),r("stroke-linejoin","strokeLinejoin"),r("stroke-miterlimit","strokeMiterlimit",c),r("stroke-dasharray","strokeDasharray",h),r("stroke-dashoffset","strokeDashoffset",M),r("visibility","visibility"),e}function V(o,e,t=[]){var y;if(o.nodeType!==1)return t;let s=!1,r=null,i={...e};const n={};switch(o.nodeName){case"svg":i=$(o,i,n);break;case"style":Yt(o,n);break;case"g":i=$(o,i,n);break;case"path":i=$(o,i,n),o.hasAttribute("d")&&(r=jt(o));break;case"rect":i=$(o,i,n),r=Kt(o);break;case"polygon":i=$(o,i,n),r=Ht(o);break;case"polyline":i=$(o,i,n),r=Jt(o);break;case"circle":i=$(o,i,n),r=Wt(o);break;case"ellipse":i=$(o,i,n),r=Gt(o);break;case"line":i=$(o,i,n),r=Qt(o);break;case"defs":s=!0;break;case"use":{i=$(o,i,n);const d=(o.getAttributeNS("http://www.w3.org/1999/xlink","href")||"").substring(1),g=(y=o.viewportElement)==null?void 0:y.getElementById(d);g?V(g,i,t):console.warn(`'use node' references non-existent node id: ${d}`);break}default:console.warn(o);break}if(i.display==="none")return t;Object.assign(e,i);const c=new b,h=[],a=Bt(o,c,h);r&&(r.matrix(c),t.push(r),r.style=e);const l=o.childNodes;for(let f=0,d=l.length;f<d;f++){const g=l[f];s&&g.nodeName!=="style"&&g.nodeName!=="defs"||V(g,e,t)}return a&&(h.pop(),h.length>0?c.copy(h[h.length-1]):c.identity()),t}const Mt="data:image/svg+xml;",Pt=`${Mt}base64,`,wt=`${Mt}charset=utf8,`;function Tt(o){if(typeof o=="string"){let e;return o.startsWith(Pt)?(o=o.substring(Pt.length,o.length),e=atob(o)):o.startsWith(wt)?(o=o.substring(wt.length,o.length),e=decodeURIComponent(o)):e=o,new DOMParser().parseFromString(e,"image/svg+xml").documentElement}else return o}function te(o){return V(Tt(o),{})}function H(o,e=!0){if(!o.length)return;const t=u.MAX,s=u.MIN;return o.forEach(r=>r.getMinMax(t,s,e)),new L(t.x,t.y,s.x-t.x,s.y-t.y)}function Z(o){const{x:e,y:t,width:s,height:r}=H(o),i=o.map(n=>n.toSvgPathString()).join("");return`<svg viewBox="${e} ${t} ${s} ${r}" width="${s}px" height="${r}px" xmlns="http://www.w3.org/2000/svg">${i}</svg>`}function ee(o){return`data:image/svg+xml;base64,${btoa(Z(o))}`}function se(o){return new DOMParser().parseFromString(Z(o),"image/svg+xml").documentElement}function ne(o,e={}){const{pixelRatio:t=2,...s}=e,{left:r,top:i,width:n,height:c}=H(o),h=document.createElement("canvas");h.width=n*t,h.height=c*t,h.style.width=`${n}px`,h.style.height=`${c}px`;const a=h.getContext("2d");return a&&(a.scale(t,t),a.translate(-r,-i),o.forEach(l=>{l.drawTo(a,s)})),h}p.BoundingBox=L,p.CircleCurve=F,p.CubicBezierCurve=it,p.Curve=k,p.CurvePath=R,p.EllipseCurve=ht,p.HeartCurve=Ot,p.LineCurve=O,p.Matrix3=b,p.Path2D=I,p.PloygonCurve=Xt,p.QuadraticBezierCurve=yt,p.RectangularCurve=gt,p.SplineCurve=ft,p.Vector2=u,p.addPathCommandsToPath2D=Y,p.getPathsBoundingBox=H,p.parseArcCommand=tt,p.parsePathDataArgs=A,p.parseSvg=te,p.parseSvgToDom=Tt,p.pathCommandsToPathData=et,p.pathDataToPathCommands=G,p.pathsToCanvas=ne,p.pathsToSvg=se,p.pathsToSvgString=Z,p.pathsToSvgUrl=ee,p.setCanvasContext=q,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
package/dist/index.mjs CHANGED
@@ -116,6 +116,16 @@ class Vector2 {
116
116
  this.y = target.y + (dy + Math.tan(ay) * dx);
117
117
  return this;
118
118
  }
119
+ min(...vecs) {
120
+ this.x = Math.min(this.x, ...vecs.map((v) => v.x));
121
+ this.y = Math.min(this.y, ...vecs.map((v) => v.y));
122
+ return this;
123
+ }
124
+ max(...vecs) {
125
+ this.x = Math.max(this.x, ...vecs.map((v) => v.x));
126
+ this.y = Math.max(this.y, ...vecs.map((v) => v.y));
127
+ return this;
128
+ }
119
129
  normalize() {
120
130
  return this.scale(1 / (this.length() || 1));
121
131
  }
@@ -783,46 +793,77 @@ function parsePathDataArgs(input, flags, stride = 0) {
783
793
  return result;
784
794
  }
785
795
 
786
- function commandToData(cmd) {
787
- switch (cmd.type) {
788
- case "m":
789
- case "M":
790
- return `${cmd.type} ${cmd.x} ${cmd.y}`;
791
- case "h":
792
- case "H":
793
- return `${cmd.type} ${cmd.x}`;
794
- case "v":
795
- case "V":
796
- return `${cmd.type} ${cmd.y}`;
797
- case "l":
798
- case "L":
799
- return `${cmd.type} ${cmd.x} ${cmd.y}`;
800
- case "c":
801
- case "C":
802
- return `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
803
- case "s":
804
- case "S":
805
- return `${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
806
- case "q":
807
- case "Q":
808
- return `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`;
809
- case "t":
810
- case "T":
811
- return `${cmd.type} ${cmd.x} ${cmd.y}`;
812
- case "a":
813
- case "A":
814
- return `${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`;
815
- case "z":
816
- case "Z":
817
- return cmd.type;
818
- default:
819
- return "";
820
- }
821
- }
822
796
  function pathCommandsToPathData(commands) {
797
+ const first = { x: 0, y: 0 };
798
+ const prev = { x: 0, y: 0 };
823
799
  let data = "";
824
800
  for (let i = 0, len = commands.length; i < len; i++) {
825
- data += `${commandToData(commands[i])} `;
801
+ const cmd = commands[i];
802
+ switch (cmd.type) {
803
+ case "m":
804
+ case "M":
805
+ if (cmd.x === prev.x && cmd.y === prev.y) {
806
+ continue;
807
+ }
808
+ data += `${cmd.type} ${cmd.x} ${cmd.y}`;
809
+ prev.x = cmd.x;
810
+ prev.y = cmd.y;
811
+ first.x = cmd.x;
812
+ first.y = cmd.y;
813
+ break;
814
+ case "h":
815
+ case "H":
816
+ data += `${cmd.type} ${cmd.x}`;
817
+ prev.x = cmd.x;
818
+ break;
819
+ case "v":
820
+ case "V":
821
+ data += `${cmd.type} ${cmd.y}`;
822
+ prev.y = cmd.y;
823
+ break;
824
+ case "l":
825
+ case "L":
826
+ data += `${cmd.type} ${cmd.x} ${cmd.y}`;
827
+ prev.x = cmd.x;
828
+ prev.y = cmd.y;
829
+ break;
830
+ case "c":
831
+ case "C":
832
+ data += `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
833
+ prev.x = cmd.x;
834
+ prev.y = cmd.y;
835
+ break;
836
+ case "s":
837
+ case "S":
838
+ data += `${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
839
+ prev.x = cmd.x;
840
+ prev.y = cmd.y;
841
+ break;
842
+ case "q":
843
+ case "Q":
844
+ data += `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`;
845
+ prev.x = cmd.x;
846
+ prev.y = cmd.y;
847
+ break;
848
+ case "t":
849
+ case "T":
850
+ data += `${cmd.type} ${cmd.x} ${cmd.y}`;
851
+ prev.x = cmd.x;
852
+ prev.y = cmd.y;
853
+ break;
854
+ case "a":
855
+ case "A":
856
+ data += `${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`;
857
+ prev.x = cmd.x;
858
+ prev.y = cmd.y;
859
+ break;
860
+ case "z":
861
+ case "Z":
862
+ data += cmd.type;
863
+ prev.x = first.x;
864
+ prev.y = first.y;
865
+ break;
866
+ }
826
867
  }
827
868
  return data;
828
869
  }
@@ -2449,14 +2490,35 @@ class Path2D {
2449
2490
  return this;
2450
2491
  }
2451
2492
  getMinMax(min = Vector2.MAX, max = Vector2.MIN, withStyle = true) {
2452
- this.getCurves().forEach((curve) => curve.getMinMax(min, max));
2453
- if (withStyle) {
2454
- const strokeHalfWidth = this.strokeWidth / 2;
2455
- min.x -= strokeHalfWidth;
2456
- min.y -= strokeHalfWidth;
2457
- max.x += strokeHalfWidth;
2458
- max.y += strokeHalfWidth;
2459
- }
2493
+ const strokeWidth = this.strokeWidth;
2494
+ this.getCurves().forEach((curve) => {
2495
+ curve.getMinMax(min, max);
2496
+ if (withStyle) {
2497
+ if (strokeWidth > 1) {
2498
+ const halfStrokeWidth = strokeWidth / 2;
2499
+ const isClockwise = curve.isClockwise();
2500
+ const points = [];
2501
+ for (let t = 0; t <= 1; t += 1 / curve.arcLengthDivisions) {
2502
+ const point = curve.getPoint(t);
2503
+ const normal = curve.getNormal(t);
2504
+ const dist1 = normal.clone().scale(isClockwise ? halfStrokeWidth : -halfStrokeWidth);
2505
+ const dist2 = normal.clone().scale(isClockwise ? -halfStrokeWidth : halfStrokeWidth);
2506
+ points.push(
2507
+ point.clone().add(dist1),
2508
+ point.clone().add(dist2),
2509
+ point.clone().add({ x: halfStrokeWidth, y: 0 }),
2510
+ point.clone().add({ x: -halfStrokeWidth, y: 0 }),
2511
+ point.clone().add({ x: 0, y: halfStrokeWidth }),
2512
+ point.clone().add({ x: 0, y: -halfStrokeWidth }),
2513
+ point.clone().add({ x: halfStrokeWidth, y: halfStrokeWidth }),
2514
+ point.clone().add({ x: -halfStrokeWidth, y: -halfStrokeWidth })
2515
+ );
2516
+ }
2517
+ min.min(...points);
2518
+ max.max(...points);
2519
+ }
2520
+ }
2521
+ });
2460
2522
  return { min, max };
2461
2523
  }
2462
2524
  getBoundingBox(withStyle = true) {
@@ -2930,20 +2992,22 @@ function parseStyle(node, style, stylesheets) {
2930
2992
  if (node.hasAttribute("id")) {
2931
2993
  stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`#${node.getAttribute("id")}`]);
2932
2994
  }
2933
- function addStyle(svgName, jsName, adjustFunction) {
2934
- if (adjustFunction === void 0) {
2935
- adjustFunction = function copy(v) {
2936
- if (v.startsWith("url"))
2937
- console.warn("url access in attributes is not implemented.");
2938
- return v;
2939
- };
2940
- }
2995
+ for (let len = node.style.length, i = 0; i < len; i++) {
2996
+ const name = node.style.item(i);
2997
+ const value = node.style.getPropertyValue(name);
2998
+ style[name] = value;
2999
+ stylesheetStyles[name] = value;
3000
+ }
3001
+ function addStyle(svgName, jsName, adjustFunction = copy) {
2941
3002
  if (node.hasAttribute(svgName))
2942
3003
  style[jsName] = adjustFunction(node.getAttribute(svgName));
2943
3004
  if (stylesheetStyles[svgName])
2944
3005
  style[jsName] = adjustFunction(stylesheetStyles[svgName]);
2945
- if (node.style && node.style[svgName] !== "")
2946
- style[jsName] = adjustFunction(node.style[svgName]);
3006
+ }
3007
+ function copy(v) {
3008
+ if (v.startsWith("url"))
3009
+ console.warn("url access in attributes is not implemented.");
3010
+ return v;
2947
3011
  }
2948
3012
  function clamp(v) {
2949
3013
  return Math.max(0, Math.min(1, parseFloatWithUnits(v)));
@@ -2975,56 +3039,57 @@ function parseNode(node, style, paths = []) {
2975
3039
  return paths;
2976
3040
  let isDefsNode = false;
2977
3041
  let path = null;
3042
+ let _style = { ...style };
2978
3043
  const stylesheets = {};
2979
3044
  switch (node.nodeName) {
2980
3045
  case "svg":
2981
- style = parseStyle(node, style, stylesheets);
3046
+ _style = parseStyle(node, _style, stylesheets);
2982
3047
  break;
2983
3048
  case "style":
2984
3049
  parseCSSStylesheet(node, stylesheets);
2985
3050
  break;
2986
3051
  case "g":
2987
- style = parseStyle(node, style, stylesheets);
3052
+ _style = parseStyle(node, _style, stylesheets);
2988
3053
  break;
2989
3054
  case "path":
2990
- style = parseStyle(node, style, stylesheets);
3055
+ _style = parseStyle(node, _style, stylesheets);
2991
3056
  if (node.hasAttribute("d"))
2992
3057
  path = parsePathNode(node);
2993
3058
  break;
2994
3059
  case "rect":
2995
- style = parseStyle(node, style, stylesheets);
3060
+ _style = parseStyle(node, _style, stylesheets);
2996
3061
  path = parseRectNode(node);
2997
3062
  break;
2998
3063
  case "polygon":
2999
- style = parseStyle(node, style, stylesheets);
3064
+ _style = parseStyle(node, _style, stylesheets);
3000
3065
  path = parsePolygonNode(node);
3001
3066
  break;
3002
3067
  case "polyline":
3003
- style = parseStyle(node, style, stylesheets);
3068
+ _style = parseStyle(node, _style, stylesheets);
3004
3069
  path = parsePolylineNode(node);
3005
3070
  break;
3006
3071
  case "circle":
3007
- style = parseStyle(node, style, stylesheets);
3072
+ _style = parseStyle(node, _style, stylesheets);
3008
3073
  path = parseCircleNode(node);
3009
3074
  break;
3010
3075
  case "ellipse":
3011
- style = parseStyle(node, style, stylesheets);
3076
+ _style = parseStyle(node, _style, stylesheets);
3012
3077
  path = parseEllipseNode(node);
3013
3078
  break;
3014
3079
  case "line":
3015
- style = parseStyle(node, style, stylesheets);
3080
+ _style = parseStyle(node, _style, stylesheets);
3016
3081
  path = parseLineNode(node);
3017
3082
  break;
3018
3083
  case "defs":
3019
3084
  isDefsNode = true;
3020
3085
  break;
3021
3086
  case "use": {
3022
- style = parseStyle(node, style, stylesheets);
3087
+ _style = parseStyle(node, _style, stylesheets);
3023
3088
  const href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href") || "";
3024
3089
  const usedNodeId = href.substring(1);
3025
3090
  const usedNode = node.viewportElement?.getElementById(usedNodeId);
3026
3091
  if (usedNode) {
3027
- parseNode(usedNode, style, paths);
3092
+ parseNode(usedNode, _style, paths);
3028
3093
  } else {
3029
3094
  console.warn(`'use node' references non-existent node id: ${usedNodeId}`);
3030
3095
  }
@@ -3034,6 +3099,10 @@ function parseNode(node, style, paths = []) {
3034
3099
  console.warn(node);
3035
3100
  break;
3036
3101
  }
3102
+ if (_style.display === "none") {
3103
+ return paths;
3104
+ }
3105
+ Object.assign(style, _style);
3037
3106
  const currentTransform = new Matrix3();
3038
3107
  const transformStack = [];
3039
3108
  const transform = getNodeTransform(node, currentTransform, transformStack);
@@ -3087,14 +3156,43 @@ function parseSvg(svg) {
3087
3156
  return parseNode(parseSvgToDom(svg), {});
3088
3157
  }
3089
3158
 
3090
- function getPathsBoundingBox(paths) {
3159
+ function getPathsBoundingBox(paths, withStyle = true) {
3091
3160
  if (!paths.length) {
3092
3161
  return void 0;
3093
3162
  }
3094
3163
  const min = Vector2.MAX;
3095
3164
  const max = Vector2.MIN;
3096
- paths.forEach((path) => path.getMinMax(min, max));
3165
+ paths.forEach((path) => path.getMinMax(min, max, withStyle));
3097
3166
  return new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
3098
3167
  }
3168
+ function pathsToSvgString(paths) {
3169
+ const { x, y, width, height } = getPathsBoundingBox(paths);
3170
+ const content = paths.map((path) => path.toSvgPathString()).join("");
3171
+ return `<svg viewBox="${x} ${y} ${width} ${height}" width="${width}px" height="${height}px" xmlns="http://www.w3.org/2000/svg">${content}</svg>`;
3172
+ }
3173
+ function pathsToSvgUrl(paths) {
3174
+ return `data:image/svg+xml;base64,${btoa(pathsToSvgString(paths))}`;
3175
+ }
3176
+ function pathsToSvg(paths) {
3177
+ return new DOMParser().parseFromString(pathsToSvgString(paths), "image/svg+xml").documentElement;
3178
+ }
3179
+ function pathsToCanvas(paths, options = {}) {
3180
+ const { pixelRatio = 2, ...style } = options;
3181
+ const { left, top, width, height } = getPathsBoundingBox(paths);
3182
+ const canvas = document.createElement("canvas");
3183
+ canvas.width = width * pixelRatio;
3184
+ canvas.height = height * pixelRatio;
3185
+ canvas.style.width = `${width}px`;
3186
+ canvas.style.height = `${height}px`;
3187
+ const ctx = canvas.getContext("2d");
3188
+ if (ctx) {
3189
+ ctx.scale(pixelRatio, pixelRatio);
3190
+ ctx.translate(-left, -top);
3191
+ paths.forEach((path) => {
3192
+ path.drawTo(ctx, style);
3193
+ });
3194
+ }
3195
+ return canvas;
3196
+ }
3099
3197
 
3100
- export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, HeartCurve, LineCurve, Matrix3, Path2D, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, Vector2, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, setCanvasContext };
3198
+ export { BoundingBox, CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, HeartCurve, LineCurve, Matrix3, Path2D, PloygonCurve, QuadraticBezierCurve, RectangularCurve, SplineCurve, Vector2, addPathCommandsToPath2D, getPathsBoundingBox, parseArcCommand, parsePathDataArgs, parseSvg, parseSvgToDom, pathCommandsToPathData, pathDataToPathCommands, pathsToCanvas, pathsToSvg, pathsToSvgString, pathsToSvgUrl, setCanvasContext };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-path2d",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.3",
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",