@mce/bigesj 0.17.13 → 0.18.0

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.
Files changed (2) hide show
  1. package/dist/index.js +1983 -1662
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1182,10 +1182,19 @@ function convertBackground(el) {
1182
1182
  const style = getStyle(el);
1183
1183
  let background;
1184
1184
  const color = el.backgroundColor ?? el.background?.color;
1185
- if (color) if (isGradient(color ?? "")) background = { image: color };
1186
- else background = { color };
1185
+ if (color) if (isGradient(color ?? "")) background = {
1186
+ enabled: true,
1187
+ image: color
1188
+ };
1189
+ else background = {
1190
+ enabled: true,
1191
+ color
1192
+ };
1187
1193
  const image = el.backgroundImage ?? el.background?.image;
1188
- if (image) background = { image: image.match(/url\((.+)\)/)?.[1] ?? image };
1194
+ if (image) background = {
1195
+ enabled: true,
1196
+ image: image.match(/url\((.+)\)/)?.[1] ?? image
1197
+ };
1189
1198
  let transform = el.backgroundTransform ?? el.background?.transform;
1190
1199
  if (!transform && el.imageTransform) {
1191
1200
  const imageTransform = el.imageTransform;
@@ -1617,7 +1626,7 @@ function signedArea(data, start, end, dim) {
1617
1626
  return sum;
1618
1627
  }
1619
1628
  //#endregion
1620
- //#region ../../node_modules/.pnpm/modern-path2d@1.4.16/node_modules/modern-path2d/dist/index.mjs
1629
+ //#region ../../node_modules/.pnpm/modern-path2d@1.5.6/node_modules/modern-path2d/dist/index.mjs
1621
1630
  function drawPoint(ctx, x, y, options = {}) {
1622
1631
  const { radius = 1 } = options;
1623
1632
  ctx.moveTo(x, y);
@@ -1646,9 +1655,10 @@ function setCanvasContext(ctx, style) {
1646
1655
  ctx.shadowColor = shadowColor;
1647
1656
  }
1648
1657
  var Vector2 = class Vector2 {
1649
- constructor(x = 0, y = 0) {
1650
- this.x = x;
1651
- this.y = y;
1658
+ constructor(_x = 0, _y = 0, _onUpdate) {
1659
+ this._x = _x;
1660
+ this._y = _y;
1661
+ this._onUpdate = _onUpdate;
1652
1662
  }
1653
1663
  static get MAX() {
1654
1664
  return new Vector2(Infinity, Infinity);
@@ -1656,147 +1666,164 @@ var Vector2 = class Vector2 {
1656
1666
  static get MIN() {
1657
1667
  return new Vector2(-Infinity, -Infinity);
1658
1668
  }
1659
- get array() {
1660
- return [this.x, this.y];
1669
+ static lerp(a, b, t) {
1670
+ return new Vector2(b.x, b.y).clone().sub(a).multiply(t).add(a);
1661
1671
  }
1662
- finite() {
1663
- this.x = Number.isFinite(this.x) ? this.x : 0;
1664
- this.y = Number.isFinite(this.y) ? this.y : 0;
1665
- return this;
1672
+ get width() {
1673
+ return this.x;
1666
1674
  }
1667
- set(x, y) {
1668
- this.x = x;
1669
- this.y = y;
1670
- return this;
1675
+ set width(val) {
1676
+ this.x = val;
1671
1677
  }
1672
- add(vec) {
1673
- this.x += vec.x;
1674
- this.y += vec.y;
1675
- return this;
1678
+ get height() {
1679
+ return this.y;
1676
1680
  }
1677
- sub(vec) {
1678
- this.x -= vec.x;
1679
- this.y -= vec.y;
1680
- return this;
1681
+ set height(val) {
1682
+ this.y = val;
1681
1683
  }
1682
- multiply(vec) {
1683
- this.x *= vec.x;
1684
- this.y *= vec.y;
1685
- return this;
1684
+ get left() {
1685
+ return this.x;
1686
+ }
1687
+ set left(val) {
1688
+ this.x = val;
1686
1689
  }
1687
- divide(vec) {
1688
- this.x /= vec.x;
1689
- this.y /= vec.y;
1690
+ get top() {
1691
+ return this.y;
1692
+ }
1693
+ set top(val) {
1694
+ this.y = val;
1695
+ }
1696
+ get x() {
1697
+ return this._x;
1698
+ }
1699
+ set x(value) {
1700
+ if (this._x !== value) {
1701
+ this._x = value;
1702
+ this._onUpdate?.(this);
1703
+ }
1704
+ }
1705
+ get y() {
1706
+ return this._y;
1707
+ }
1708
+ set y(value) {
1709
+ if (this._y !== value) {
1710
+ this._y = value;
1711
+ this._onUpdate?.(this);
1712
+ }
1713
+ }
1714
+ set(x = 0, y = x) {
1715
+ if (this._x !== x || this._y !== y) {
1716
+ this._x = x;
1717
+ this._y = y;
1718
+ this._onUpdate?.(this);
1719
+ }
1690
1720
  return this;
1691
1721
  }
1692
- dot(vec) {
1693
- return this.x * vec.x + this.y * vec.y;
1722
+ add(p) {
1723
+ return this.set(this._x + p.x, this._y + p.y);
1724
+ }
1725
+ sub(p) {
1726
+ return this.set(this._x - p.x, this._y - p.y);
1727
+ }
1728
+ subVectors(a, b) {
1729
+ return this.set(a.x - b.x, a.y - b.y);
1730
+ }
1731
+ multiply(x = 0, y = x) {
1732
+ return this.set(this._x * x, this._y * y);
1733
+ }
1734
+ divide(x = 0, y = x) {
1735
+ return this.set(this._x / x, this._y / y);
1694
1736
  }
1695
- cross(vec) {
1696
- return this.x * vec.y - this.y * vec.x;
1737
+ cross(p) {
1738
+ return this._x * p.y - this._y * p.x;
1697
1739
  }
1698
- rotate(a, target = {
1740
+ dot(p) {
1741
+ return this._x * p.x + this._y * p.y;
1742
+ }
1743
+ rotate(rad, origin = {
1699
1744
  x: 0,
1700
1745
  y: 0
1701
1746
  }) {
1702
- const rotation = -a / 180 * Math.PI;
1703
- const x = this.x - target.x;
1704
- const y = -(this.y - target.y);
1705
- const sin = Math.sin(rotation);
1706
- const cos = Math.cos(rotation);
1707
- this.set(target.x + (x * cos - y * sin), target.y - (x * sin + y * cos));
1747
+ const { x, y } = this;
1748
+ const cos = Math.cos(rad);
1749
+ const sin = Math.sin(rad);
1750
+ return this.set((x - origin.x) * cos - (y - origin.y) * sin + origin.x, (x - origin.x) * sin + (y - origin.y) * cos + origin.y);
1751
+ }
1752
+ getLength() {
1753
+ const { x, y } = this;
1754
+ return Math.sqrt(x * x + y * y);
1755
+ }
1756
+ getAngle() {
1757
+ return Math.atan2(-this.x, -this.y) + Math.PI;
1758
+ }
1759
+ distanceTo(p) {
1760
+ return Math.hypot(p.x - this.x, p.y - this.y);
1761
+ }
1762
+ normalize() {
1763
+ const scalar = 1 / (this.getLength() || 1);
1764
+ this.set(this.x * scalar, this.y * scalar);
1765
+ return this;
1766
+ }
1767
+ copyFrom(p) {
1768
+ if (this._x !== p.x || this._y !== p.y) {
1769
+ this._x = p.x;
1770
+ this._y = p.y;
1771
+ this._onUpdate?.(this);
1772
+ }
1708
1773
  return this;
1709
1774
  }
1710
- distanceTo(vec) {
1711
- return Math.sqrt(this.distanceToSquared(vec));
1775
+ copyTo(p) {
1776
+ p.set(this._x, this._y);
1777
+ return p;
1778
+ }
1779
+ equals(vec) {
1780
+ return this._x === vec.x && this._y === vec.y;
1781
+ }
1782
+ get array() {
1783
+ return [this.x, this.y];
1712
1784
  }
1713
- distanceToSquared(vec) {
1714
- const dx = this.x - vec.x;
1715
- const dy = this.y - vec.y;
1716
- return dx * dx + dy * dy;
1785
+ finite() {
1786
+ return this.set(Number.isFinite(this._x) ? this._x : 0, Number.isFinite(this._y) ? this._y : 0);
1717
1787
  }
1718
1788
  lengthSquared() {
1719
- return this.x * this.x + this.y * this.y;
1789
+ return this._x * this._x + this._y * this._y;
1720
1790
  }
1721
1791
  length() {
1722
1792
  return Math.sqrt(this.lengthSquared());
1723
1793
  }
1724
- scale(sx, sy = sx, target = {
1794
+ scale(sx, sy = sx, origin = {
1725
1795
  x: 0,
1726
1796
  y: 0
1727
1797
  }) {
1728
- const x = sx < 0 ? target.x - this.x + target.x : this.x;
1729
- const y = sy < 0 ? target.y - this.y + target.y : this.y;
1730
- this.x = x * Math.abs(sx);
1731
- this.y = y * Math.abs(sy);
1732
- return this;
1798
+ const x = sx < 0 ? origin.x - this._x + origin.x : this._x;
1799
+ const y = sy < 0 ? origin.y - this._y + origin.y : this._y;
1800
+ return this.set(x * Math.abs(sx), y * Math.abs(sy));
1733
1801
  }
1734
- skew(ax, ay = 0, target = {
1802
+ skew(ax, ay = 0, origin = {
1735
1803
  x: 0,
1736
1804
  y: 0
1737
1805
  }) {
1738
- const dx = this.x - target.x;
1739
- const dy = this.y - target.y;
1740
- this.x = target.x + (dx + Math.tan(ax) * dy);
1741
- this.y = target.y + (dy + Math.tan(ay) * dx);
1742
- return this;
1743
- }
1744
- min(...vecs) {
1745
- this.x = Math.min(this.x, ...vecs.map((v) => v.x));
1746
- this.y = Math.min(this.y, ...vecs.map((v) => v.y));
1747
- return this;
1748
- }
1749
- max(...vecs) {
1750
- this.x = Math.max(this.x, ...vecs.map((v) => v.x));
1751
- this.y = Math.max(this.y, ...vecs.map((v) => v.y));
1752
- return this;
1753
- }
1754
- normalize() {
1755
- return this.scale(1 / (this.length() || 1));
1756
- }
1757
- addVectors(a, b) {
1758
- this.x = a.x + b.x;
1759
- this.y = a.y + b.y;
1760
- return this;
1761
- }
1762
- subVectors(a, b) {
1763
- this.x = a.x - b.x;
1764
- this.y = a.y - b.y;
1765
- return this;
1766
- }
1767
- multiplyVectors(a, b) {
1768
- this.x = a.x * b.x;
1769
- this.y = a.y * b.y;
1770
- return this;
1806
+ const dx = this._x - origin.x;
1807
+ const dy = this._y - origin.y;
1808
+ return this.set(origin.x + (dx + Math.tan(ax) * dy), origin.y + (dy + Math.tan(ay) * dx));
1771
1809
  }
1772
- divideVectors(a, b) {
1773
- this.x = a.x / b.x;
1774
- this.y = a.y / b.y;
1775
- return this;
1810
+ clampMin(...pList) {
1811
+ return this.set(Math.min(this._x, ...pList.map((v) => v.x)), Math.min(this._y, ...pList.map((v) => v.y)));
1776
1812
  }
1777
- lerpVectors(v1, v2, alpha) {
1778
- this.x = v1.x + (v2.x - v1.x) * alpha;
1779
- this.y = v1.y + (v2.y - v1.y) * alpha;
1780
- return this;
1813
+ clampMax(...pList) {
1814
+ return this.set(Math.max(this.x, ...pList.map((v) => v.x)), Math.max(this.y, ...pList.map((v) => v.y)));
1781
1815
  }
1782
- equals(vec) {
1783
- return this.x === vec.x && this.y === vec.y;
1784
- }
1785
- applyMatrix3(m) {
1786
- const x = this.x;
1787
- const y = this.y;
1788
- const e = m.elements;
1789
- this.x = e[0] * x + e[3] * y + e[6];
1790
- this.y = e[1] * x + e[4] * y + e[7];
1791
- return this;
1816
+ clone(_onUpdate) {
1817
+ return new Vector2(this._x, this._y, _onUpdate ?? this._onUpdate);
1792
1818
  }
1793
- copy(vec) {
1794
- this.x = vec.x;
1795
- this.y = vec.y;
1796
- return this;
1819
+ toJSON() {
1820
+ return {
1821
+ x: this._x,
1822
+ y: this._y
1823
+ };
1797
1824
  }
1798
- clone() {
1799
- return new Vector2(this.x, this.y);
1825
+ destroy() {
1826
+ this._onUpdate = void 0;
1800
1827
  }
1801
1828
  };
1802
1829
  var BoundingBox = class BoundingBox {
@@ -1869,1543 +1896,1828 @@ var BoundingBox = class BoundingBox {
1869
1896
  return new BoundingBox(this.left, this.top, this.width, this.height);
1870
1897
  }
1871
1898
  };
1872
- var Matrix3 = class {
1873
- elements = [];
1874
- constructor(n11 = 1, n12 = 0, n13 = 0, n21 = 0, n22 = 1, n23 = 0, n31 = 0, n32 = 0, n33 = 1) {
1875
- this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33);
1876
- }
1877
- set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
1878
- const te = this.elements;
1879
- te[0] = n11;
1880
- te[1] = n21;
1881
- te[2] = n31;
1882
- te[3] = n12;
1883
- te[4] = n22;
1884
- te[5] = n32;
1885
- te[6] = n13;
1886
- te[7] = n23;
1887
- te[8] = n33;
1888
- return this;
1889
- }
1890
- identity() {
1891
- this.set(1, 0, 0, 0, 1, 0, 0, 0, 1);
1892
- return this;
1893
- }
1894
- copy(m) {
1895
- const te = this.elements;
1896
- const me = m.elements;
1897
- te[0] = me[0];
1898
- te[1] = me[1];
1899
- te[2] = me[2];
1900
- te[3] = me[3];
1901
- te[4] = me[4];
1902
- te[5] = me[5];
1903
- te[6] = me[6];
1904
- te[7] = me[7];
1905
- te[8] = me[8];
1906
- return this;
1907
- }
1908
- multiply(m) {
1909
- return this.multiplyMatrices(this, m);
1910
- }
1911
- premultiply(m) {
1912
- return this.multiplyMatrices(m, this);
1913
- }
1914
- multiplyMatrices(a, b) {
1915
- const ae = a.elements;
1916
- const be = b.elements;
1917
- const te = this.elements;
1918
- const a11 = ae[0];
1919
- const a12 = ae[3];
1920
- const a13 = ae[6];
1921
- const a21 = ae[1];
1922
- const a22 = ae[4];
1923
- const a23 = ae[7];
1924
- const a31 = ae[2];
1925
- const a32 = ae[5];
1926
- const a33 = ae[8];
1927
- const b11 = be[0];
1928
- const b12 = be[3];
1929
- const b13 = be[6];
1930
- const b21 = be[1];
1931
- const b22 = be[4];
1932
- const b23 = be[7];
1933
- const b31 = be[2];
1934
- const b32 = be[5];
1935
- const b33 = be[8];
1936
- te[0] = a11 * b11 + a12 * b21 + a13 * b31;
1937
- te[3] = a11 * b12 + a12 * b22 + a13 * b32;
1938
- te[6] = a11 * b13 + a12 * b23 + a13 * b33;
1939
- te[1] = a21 * b11 + a22 * b21 + a23 * b31;
1940
- te[4] = a21 * b12 + a22 * b22 + a23 * b32;
1941
- te[7] = a21 * b13 + a22 * b23 + a23 * b33;
1942
- te[2] = a31 * b11 + a32 * b21 + a33 * b31;
1943
- te[5] = a31 * b12 + a32 * b22 + a33 * b32;
1944
- te[8] = a31 * b13 + a32 * b23 + a33 * b33;
1945
- return this;
1946
- }
1947
- invert() {
1948
- const te = this.elements;
1949
- const n11 = te[0];
1950
- const n21 = te[1];
1951
- const n31 = te[2];
1952
- const n12 = te[3];
1953
- const n22 = te[4];
1954
- const n32 = te[5];
1955
- const n13 = te[6];
1956
- const n23 = te[7];
1957
- const n33 = te[8];
1958
- const t11 = n33 * n22 - n32 * n23;
1959
- const t12 = n32 * n13 - n33 * n12;
1960
- const t13 = n23 * n12 - n22 * n13;
1961
- const det = n11 * t11 + n21 * t12 + n31 * t13;
1962
- if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
1963
- const detInv = 1 / det;
1964
- te[0] = t11 * detInv;
1965
- te[1] = (n31 * n23 - n33 * n21) * detInv;
1966
- te[2] = (n32 * n21 - n31 * n22) * detInv;
1967
- te[3] = t12 * detInv;
1968
- te[4] = (n33 * n11 - n31 * n13) * detInv;
1969
- te[5] = (n31 * n12 - n32 * n11) * detInv;
1970
- te[6] = t13 * detInv;
1971
- te[7] = (n21 * n13 - n23 * n11) * detInv;
1972
- te[8] = (n22 * n11 - n21 * n12) * detInv;
1973
- return this;
1974
- }
1975
- transpose() {
1976
- let tmp;
1977
- const m = this.elements;
1978
- tmp = m[1];
1979
- m[1] = m[3];
1980
- m[3] = tmp;
1981
- tmp = m[2];
1982
- m[2] = m[6];
1983
- m[6] = tmp;
1984
- tmp = m[5];
1985
- m[5] = m[7];
1986
- m[7] = tmp;
1987
- return this;
1988
- }
1989
- scale(sx, sy) {
1990
- this.premultiply(_m3.makeScale(sx, sy));
1991
- return this;
1992
- }
1993
- rotate(theta) {
1994
- this.premultiply(_m3.makeRotation(-theta));
1995
- return this;
1996
- }
1997
- translate(tx, ty) {
1998
- this.premultiply(_m3.makeTranslation(tx, ty));
1999
- return this;
2000
- }
2001
- makeTranslation(x, y) {
2002
- this.set(1, 0, x, 0, 1, y, 0, 0, 1);
2003
- return this;
2004
- }
2005
- makeRotation(theta) {
2006
- const c = Math.cos(theta);
2007
- const s = Math.sin(theta);
2008
- this.set(c, -s, 0, s, c, 0, 0, 0, 1);
2009
- return this;
2010
- }
2011
- makeScale(x, y) {
2012
- this.set(x, 0, 0, 0, y, 0, 0, 0, 1);
2013
- return this;
2014
- }
2015
- fromArray(array, offset = 0) {
2016
- for (let i = 0; i < 9; i++) this.elements[i] = array[i + offset];
2017
- return this;
2018
- }
2019
- clone() {
2020
- return new this.constructor().fromArray(this.elements);
2021
- }
2022
- };
2023
- var _m3 = /* @__PURE__ */ new Matrix3();
2024
- function svgAngle(ux, uy, vx, vy) {
2025
- const dot = ux * vx + uy * vy;
2026
- const len = Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
2027
- let ang = Math.acos(Math.max(-1, Math.min(1, dot / len)));
2028
- if (ux * vy - uy * vx < 0) ang = -ang;
2029
- return ang;
1899
+ function catmullRom(t, p0, p1, p2, p3) {
1900
+ const v0 = (p2 - p0) * .5;
1901
+ const v1 = (p3 - p1) * .5;
1902
+ const t2 = t * t;
1903
+ const t3 = t * t2;
1904
+ return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
2030
1905
  }
2031
- function parseArcCommand(path, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, start, end) {
2032
- if (rx === 0 || ry === 0) {
2033
- path.lineTo(end.x, end.y);
2034
- return;
2035
- }
2036
- xAxisRotation = xAxisRotation * Math.PI / 180;
2037
- rx = Math.abs(rx);
2038
- ry = Math.abs(ry);
2039
- const dx2 = (start.x - end.x) / 2;
2040
- const dy2 = (start.y - end.y) / 2;
2041
- const x1p = Math.cos(xAxisRotation) * dx2 + Math.sin(xAxisRotation) * dy2;
2042
- const y1p = -Math.sin(xAxisRotation) * dx2 + Math.cos(xAxisRotation) * dy2;
2043
- let rxs = rx * rx;
2044
- let rys = ry * ry;
2045
- const x1ps = x1p * x1p;
2046
- const y1ps = y1p * y1p;
2047
- const cr = x1ps / rxs + y1ps / rys;
2048
- if (cr > 1) {
2049
- const s = Math.sqrt(cr);
2050
- rx = s * rx;
2051
- ry = s * ry;
2052
- rxs = rx * rx;
2053
- rys = ry * ry;
1906
+ var PI_2 = Math.PI * 2;
1907
+ function toKebabCase(str) {
1908
+ return str.replace(/[^a-z0-9]/gi, "-").replace(/\B([A-Z])/g, "-$1").toLowerCase();
1909
+ }
1910
+ function getIntersectionPoint(p1, p2, q1, q2) {
1911
+ const r = p2.clone().sub(p1);
1912
+ const s = q2.clone().sub(q1);
1913
+ const q1p1 = q1.clone().sub(p1);
1914
+ const crossRS = r.cross(s);
1915
+ if (crossRS === 0) return new Vector2((p1.x + q1.x) / 2, (p1.y + q1.y) / 2);
1916
+ const t = q1p1.cross(s) / crossRS;
1917
+ if (Math.abs(t) > 1) return new Vector2((p1.x + q1.x) / 2, (p1.y + q1.y) / 2);
1918
+ return new Vector2(p1.x + t * r.x, p1.y + t * r.y);
1919
+ }
1920
+ var FUNCTIONS_RE = /([\w-]+)\((.+?)\)/g;
1921
+ var ARGS_RE = /[^,]+/g;
1922
+ var ARG_RE = /([-e.\d]+)(.*)/;
1923
+ function parseCssFunctions(propertyValue, context = {}) {
1924
+ const functions = [];
1925
+ let match;
1926
+ while ((match = FUNCTIONS_RE.exec(propertyValue)) !== null) {
1927
+ const [, name, value] = match;
1928
+ if (name) functions.push({
1929
+ name,
1930
+ args: parseCssArgs(name, value, context)
1931
+ });
2054
1932
  }
2055
- const dq = rxs * y1ps + rys * x1ps;
2056
- const pq = (rxs * rys - dq) / dq;
2057
- let q = Math.sqrt(Math.max(0, pq));
2058
- if (largeArcFlag === sweepFlag) q = -q;
2059
- const cxp = q * rx * y1p / ry;
2060
- const cyp = -q * ry * x1p / rx;
2061
- const cx = Math.cos(xAxisRotation) * cxp - Math.sin(xAxisRotation) * cyp + (start.x + end.x) / 2;
2062
- const cy = Math.sin(xAxisRotation) * cxp + Math.cos(xAxisRotation) * cyp + (start.y + end.y) / 2;
2063
- const theta = svgAngle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
2064
- const delta = svgAngle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry) % (Math.PI * 2);
2065
- path.ellipse(cx, cy, rx, ry, xAxisRotation, theta, theta + delta, sweepFlag === 0);
1933
+ return functions;
2066
1934
  }
2067
- var RE$3 = {
2068
- WHITESPACE: /[ \t\r\n]/,
2069
- DIGIT: /\d/,
2070
- SIGN: /[-+]/,
2071
- POINT: /\./,
2072
- COMMA: /,/,
2073
- EXP: /e/i,
2074
- FLAGS: /[01]/
2075
- };
2076
- function parsePathDataArgs(input, flags, stride = 0) {
2077
- const SEP = 0;
2078
- const INT = 1;
2079
- const FLOAT = 2;
2080
- const EXP = 3;
2081
- let state = SEP;
2082
- let seenComma = true;
2083
- let number = "";
2084
- let exponent = "";
2085
- const result = [];
2086
- function throwSyntaxError(current2, i, partial) {
2087
- const error = /* @__PURE__ */ new SyntaxError(`Unexpected character "${current2}" at index ${i}.`);
2088
- error.partial = partial;
2089
- throw error;
1935
+ function parseCssArgs(name, value, context = {}) {
1936
+ const values = [];
1937
+ let match;
1938
+ let i = 0;
1939
+ while ((match = ARGS_RE.exec(value)) !== null) values.push(parseCssArg(name, match[0], {
1940
+ ...context,
1941
+ index: i++
1942
+ }));
1943
+ return values;
1944
+ }
1945
+ function parseCssArg(name, value, context = {}) {
1946
+ const { width = 1, height = 1, index = 0 } = context;
1947
+ const matched = value.match(ARG_RE);
1948
+ const result = {
1949
+ unit: matched?.[2] ?? null,
1950
+ value,
1951
+ intValue: Number(matched?.[1]),
1952
+ normalizedIntValue: 0,
1953
+ normalizedDefaultIntValue: 0
1954
+ };
1955
+ switch (name) {
1956
+ case "scale":
1957
+ case "scaleX":
1958
+ case "scaleY":
1959
+ case "scale3d":
1960
+ result.normalizedDefaultIntValue = 1;
1961
+ break;
2090
1962
  }
2091
- function newNumber() {
2092
- if (number !== "") if (exponent === "") result.push(Number(number));
2093
- else result.push(Number(number) * 10 ** Number(exponent));
2094
- number = "";
2095
- exponent = "";
1963
+ switch (result.unit) {
1964
+ case "%":
1965
+ result.normalizedIntValue = result.intValue / 100;
1966
+ break;
1967
+ case "rad":
1968
+ result.normalizedIntValue = result.intValue / PI_2;
1969
+ break;
1970
+ case "deg":
1971
+ result.normalizedIntValue = result.intValue / 360;
1972
+ break;
1973
+ case "px":
1974
+ switch (index) {
1975
+ case 0:
1976
+ result.normalizedIntValue = result.intValue / width;
1977
+ break;
1978
+ case 1:
1979
+ result.normalizedIntValue = result.intValue / height;
1980
+ break;
1981
+ }
1982
+ break;
1983
+ default:
1984
+ result.normalizedIntValue = result.intValue;
1985
+ break;
2096
1986
  }
2097
- let current;
2098
- const length = input.length;
2099
- for (let i = 0; i < length; i++) {
2100
- current = input[i];
2101
- if (Array.isArray(flags) && flags.includes(result.length % stride) && RE$3.FLAGS.test(current)) {
2102
- state = INT;
2103
- number = current;
2104
- newNumber();
2105
- continue;
1987
+ return result;
1988
+ }
1989
+ function cubicBezierP0(t, p) {
1990
+ const k = 1 - t;
1991
+ return k * k * k * p;
1992
+ }
1993
+ function cubicBezierP1(t, p) {
1994
+ const k = 1 - t;
1995
+ return 3 * k * k * t * p;
1996
+ }
1997
+ function cubicBezierP2(t, p) {
1998
+ return 3 * (1 - t) * t * t * p;
1999
+ }
2000
+ function cubicBezierP3(t, p) {
2001
+ return t * t * t * p;
2002
+ }
2003
+ function cubicBezier(t, p0, p1, p2, p3) {
2004
+ return cubicBezierP0(t, p0) + cubicBezierP1(t, p1) + cubicBezierP2(t, p2) + cubicBezierP3(t, p3);
2005
+ }
2006
+ function fillTriangulate(pointArray, options = {}) {
2007
+ let { vertices = [], indices = [], holes = [], verticesStride = 2, verticesOffset = vertices.length / verticesStride, indicesOffset = indices.length } = options;
2008
+ const triangles = earcut(pointArray, holes, 2);
2009
+ if (triangles.length) {
2010
+ for (let i = 0; i < triangles.length; i += 3) {
2011
+ indices[indicesOffset++] = triangles[i] + verticesOffset;
2012
+ indices[indicesOffset++] = triangles[i + 1] + verticesOffset;
2013
+ indices[indicesOffset++] = triangles[i + 2] + verticesOffset;
2106
2014
  }
2107
- if (state === SEP) {
2108
- if (RE$3.WHITESPACE.test(current)) continue;
2109
- if (RE$3.DIGIT.test(current) || RE$3.SIGN.test(current)) {
2110
- state = INT;
2111
- number = current;
2112
- continue;
2113
- }
2114
- if (RE$3.POINT.test(current)) {
2115
- state = FLOAT;
2116
- number = current;
2117
- continue;
2118
- }
2119
- if (RE$3.COMMA.test(current)) {
2120
- if (seenComma) throwSyntaxError(current, i, result);
2121
- seenComma = true;
2122
- }
2123
- }
2124
- if (state === INT) {
2125
- if (RE$3.DIGIT.test(current)) {
2126
- number += current;
2127
- continue;
2128
- }
2129
- if (RE$3.POINT.test(current)) {
2130
- number += current;
2131
- state = FLOAT;
2132
- continue;
2133
- }
2134
- if (RE$3.EXP.test(current)) {
2135
- state = EXP;
2136
- continue;
2137
- }
2138
- if (RE$3.SIGN.test(current) && number.length === 1 && RE$3.SIGN.test(number[0])) throwSyntaxError(current, i, result);
2015
+ let index = verticesOffset * verticesStride;
2016
+ for (let i = 0; i < pointArray.length; i += 2) {
2017
+ vertices[index] = pointArray[i];
2018
+ vertices[index + 1] = pointArray[i + 1];
2019
+ index += verticesStride;
2139
2020
  }
2140
- if (state === FLOAT) {
2141
- if (RE$3.DIGIT.test(current)) {
2142
- number += current;
2143
- continue;
2021
+ }
2022
+ return {
2023
+ vertices,
2024
+ indices
2025
+ };
2026
+ }
2027
+ var RECURSION_LIMIT$1 = 8;
2028
+ var FLT_EPSILON$1 = 1.1920929e-7;
2029
+ var PATH_DISTANCE_EPSILON$1 = 1;
2030
+ function getAdaptiveCubicBezierCurvePoints(sX, sY, x1, y1, x2, y2, x, y, smoothness = .5, points = []) {
2031
+ let distanceTolerance = (PATH_DISTANCE_EPSILON$1 - Math.min(.99, Math.max(0, smoothness))) / 1;
2032
+ distanceTolerance *= distanceTolerance;
2033
+ recursive$1(sX, sY, x1, y1, x2, y2, x, y, points, distanceTolerance, 0);
2034
+ points.push(x, y);
2035
+ return points;
2036
+ }
2037
+ function recursive$1(x1, y1, x2, y2, x3, y3, x4, y4, points, distanceTolerance, level) {
2038
+ if (level > RECURSION_LIMIT$1) return;
2039
+ const x12 = (x1 + x2) / 2;
2040
+ const y12 = (y1 + y2) / 2;
2041
+ const x23 = (x2 + x3) / 2;
2042
+ const y23 = (y2 + y3) / 2;
2043
+ const x34 = (x3 + x4) / 2;
2044
+ const y34 = (y3 + y4) / 2;
2045
+ const x123 = (x12 + x23) / 2;
2046
+ const y123 = (y12 + y23) / 2;
2047
+ const x234 = (x23 + x34) / 2;
2048
+ const y234 = (y23 + y34) / 2;
2049
+ const x1234 = (x123 + x234) / 2;
2050
+ const y1234 = (y123 + y234) / 2;
2051
+ if (level > 0) {
2052
+ let dx = x4 - x1;
2053
+ let dy = y4 - y1;
2054
+ const d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx);
2055
+ const d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx);
2056
+ if (d2 > FLT_EPSILON$1 && d3 > FLT_EPSILON$1) {
2057
+ if ((d2 + d3) * (d2 + d3) <= distanceTolerance * (dx * dx + dy * dy)) {
2058
+ points.push(x1234, y1234);
2059
+ return;
2144
2060
  }
2145
- if (RE$3.EXP.test(current)) {
2146
- state = EXP;
2147
- continue;
2061
+ } else if (d2 > FLT_EPSILON$1) {
2062
+ if (d2 * d2 <= distanceTolerance * (dx * dx + dy * dy)) {
2063
+ points.push(x1234, y1234);
2064
+ return;
2148
2065
  }
2149
- if (RE$3.POINT.test(current) && number[number.length - 1] === ".") throwSyntaxError(current, i, result);
2150
- }
2151
- if (state === EXP) {
2152
- if (RE$3.DIGIT.test(current)) {
2153
- exponent += current;
2154
- continue;
2066
+ } else if (d3 > FLT_EPSILON$1) {
2067
+ if (d3 * d3 <= distanceTolerance * (dx * dx + dy * dy)) {
2068
+ points.push(x1234, y1234);
2069
+ return;
2155
2070
  }
2156
- if (RE$3.SIGN.test(current)) {
2157
- if (exponent === "") {
2158
- exponent += current;
2159
- continue;
2160
- }
2161
- if (exponent.length === 1 && RE$3.SIGN.test(exponent)) throwSyntaxError(current, i, result);
2071
+ } else {
2072
+ dx = x1234 - (x1 + x4) / 2;
2073
+ dy = y1234 - (y1 + y4) / 2;
2074
+ if (dx * dx + dy * dy <= distanceTolerance) {
2075
+ points.push(x1234, y1234);
2076
+ return;
2162
2077
  }
2163
2078
  }
2164
- if (RE$3.WHITESPACE.test(current)) {
2165
- newNumber();
2166
- state = SEP;
2167
- seenComma = false;
2168
- } else if (RE$3.COMMA.test(current)) {
2169
- newNumber();
2170
- state = SEP;
2171
- seenComma = true;
2172
- } else if (RE$3.SIGN.test(current)) {
2173
- newNumber();
2174
- state = INT;
2175
- number = current;
2176
- } else if (RE$3.POINT.test(current)) {
2177
- newNumber();
2178
- state = FLOAT;
2179
- number = current;
2180
- } else throwSyntaxError(current, i, result);
2181
2079
  }
2182
- newNumber();
2183
- return result;
2080
+ recursive$1(x1, y1, x12, y12, x123, y123, x1234, y1234, points, distanceTolerance, level + 1);
2081
+ recursive$1(x1234, y1234, x234, y234, x34, y34, x4, y4, points, distanceTolerance, level + 1);
2184
2082
  }
2185
- function getReflection(a, b) {
2186
- return a - (b - a);
2083
+ var RECURSION_LIMIT = 8;
2084
+ var FLT_EPSILON = 1.1920929e-7;
2085
+ var PATH_DISTANCE_EPSILON = 1;
2086
+ function getAdaptiveQuadraticBezierCurvePoints(sX, sY, x1, y1, x, y, smoothness = .5, points = []) {
2087
+ let distanceTolerance = (PATH_DISTANCE_EPSILON - Math.min(.99, Math.max(0, smoothness))) / 1;
2088
+ distanceTolerance *= distanceTolerance;
2089
+ recursive(points, sX, sY, x1, y1, x, y, distanceTolerance, 0);
2090
+ points.push(x, y);
2091
+ return points;
2187
2092
  }
2188
- function svgPathCommandsAddToPath2D(commands, path) {
2189
- const current = new Vector2();
2190
- const control = new Vector2();
2191
- for (let i = 0, l = commands.length; i < l; i++) {
2192
- const cmd = commands[i];
2193
- if (cmd.type === "m" || cmd.type === "M") {
2194
- if (cmd.type === "m") current.add(cmd);
2195
- else current.copy(cmd);
2196
- path.moveTo(current.x, current.y);
2197
- control.copy(current);
2198
- } else if (cmd.type === "h" || cmd.type === "H") {
2199
- if (cmd.type === "h") current.x += cmd.x;
2200
- else current.x = cmd.x;
2201
- path.lineTo(current.x, current.y);
2202
- control.copy(current);
2203
- } else if (cmd.type === "v" || cmd.type === "V") {
2204
- if (cmd.type === "v") current.y += cmd.y;
2205
- else current.y = cmd.y;
2206
- path.lineTo(current.x, current.y);
2207
- control.copy(current);
2208
- } else if (cmd.type === "l" || cmd.type === "L") {
2209
- if (cmd.type === "l") current.add(cmd);
2210
- else current.copy(cmd);
2211
- path.lineTo(current.x, current.y);
2212
- control.copy(current);
2213
- } else if (cmd.type === "c" || cmd.type === "C") if (cmd.type === "c") {
2214
- path.bezierCurveTo(current.x + cmd.x1, current.y + cmd.y1, current.x + cmd.x2, current.y + cmd.y2, current.x + cmd.x, current.y + cmd.y);
2215
- control.x = current.x + cmd.x2;
2216
- control.y = current.y + cmd.y2;
2217
- current.add(cmd);
2218
- } else {
2219
- path.bezierCurveTo(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
2220
- control.x = cmd.x2;
2221
- control.y = cmd.y2;
2222
- current.copy(cmd);
2223
- }
2224
- else if (cmd.type === "s" || cmd.type === "S") if (cmd.type === "s") {
2225
- path.bezierCurveTo(getReflection(current.x, control.x), getReflection(current.y, control.y), current.x + cmd.x2, current.y + cmd.y2, current.x + cmd.x, current.y + cmd.y);
2226
- control.x = current.x + cmd.x2;
2227
- control.y = current.y + cmd.y2;
2228
- current.add(cmd);
2229
- } else {
2230
- path.bezierCurveTo(getReflection(current.x, control.x), getReflection(current.y, control.y), cmd.x2, cmd.y2, cmd.x, cmd.y);
2231
- control.x = cmd.x2;
2232
- control.y = cmd.y2;
2233
- current.copy(cmd);
2093
+ function recursive(points, x1, y1, x2, y2, x3, y3, distanceTolerance, level) {
2094
+ if (level > RECURSION_LIMIT) return;
2095
+ const x12 = (x1 + x2) / 2;
2096
+ const y12 = (y1 + y2) / 2;
2097
+ const x23 = (x2 + x3) / 2;
2098
+ const y23 = (y2 + y3) / 2;
2099
+ const x123 = (x12 + x23) / 2;
2100
+ const y123 = (y12 + y23) / 2;
2101
+ let dx = x3 - x1;
2102
+ let dy = y3 - y1;
2103
+ const d = Math.abs((x2 - x3) * dy - (y2 - y3) * dx);
2104
+ if (d > FLT_EPSILON) {
2105
+ if (d * d <= distanceTolerance * (dx * dx + dy * dy)) {
2106
+ points.push(x123, y123);
2107
+ return;
2234
2108
  }
2235
- else if (cmd.type === "q" || cmd.type === "Q") if (cmd.type === "q") {
2236
- path.quadraticCurveTo(current.x + cmd.x1, current.y + cmd.y1, current.x + cmd.x, current.y + cmd.y);
2237
- control.x = current.x + cmd.x1;
2238
- control.y = current.y + cmd.y1;
2239
- current.add(cmd);
2240
- } else {
2241
- path.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
2242
- control.x = cmd.x1;
2243
- control.y = cmd.y1;
2244
- current.copy(cmd);
2109
+ } else {
2110
+ dx = x123 - (x1 + x3) / 2;
2111
+ dy = y123 - (y1 + y3) / 2;
2112
+ if (dx * dx + dy * dy <= distanceTolerance) {
2113
+ points.push(x123, y123);
2114
+ return;
2245
2115
  }
2246
- else if (cmd.type === "t" || cmd.type === "T") {
2247
- const rx = getReflection(current.x, control.x);
2248
- const ry = getReflection(current.y, control.y);
2249
- control.x = rx;
2250
- control.y = ry;
2251
- if (cmd.type === "t") {
2252
- path.quadraticCurveTo(rx, ry, current.x + cmd.x, current.y + cmd.y);
2253
- current.add(cmd);
2254
- } else {
2255
- path.quadraticCurveTo(rx, ry, cmd.x, cmd.y);
2256
- current.copy(cmd);
2257
- }
2258
- } else if (cmd.type === "a" || cmd.type === "A") {
2259
- const start = current.clone();
2260
- if (cmd.type === "a") {
2261
- if (cmd.x === 0 && cmd.y === 0) continue;
2262
- current.add(cmd);
2263
- } else {
2264
- if (current.equals(cmd)) continue;
2265
- current.copy(cmd);
2266
- }
2267
- control.copy(current);
2268
- parseArcCommand(path, cmd.rx, cmd.ry, cmd.angle, cmd.largeArcFlag, cmd.sweepFlag, start, current);
2269
- } else if (cmd.type === "z" || cmd.type === "Z") {
2270
- if (path.startPoint) current.copy(path.startPoint);
2271
- path.closePath();
2272
- } else console.warn("Unsupported commands", cmd);
2273
2116
  }
2117
+ recursive(points, x1, y1, x12, y12, x123, y123, distanceTolerance, level + 1);
2118
+ recursive(points, x123, y123, x23, y23, x3, y3, distanceTolerance, level + 1);
2274
2119
  }
2275
- function svgPathCommandsToData(commands) {
2276
- let first;
2277
- let prev;
2278
- const data = [];
2279
- for (let i = 0, len = commands.length; i < len; i++) {
2280
- const cmd = commands[i];
2281
- switch (cmd.type) {
2282
- case "m":
2283
- case "M":
2284
- if (cmd.x.toFixed(4) === prev?.x.toFixed(4) && cmd.y.toFixed(4) === prev?.y.toFixed(4)) continue;
2285
- data.push(`${cmd.type} ${cmd.x} ${cmd.y}`);
2286
- prev = {
2287
- x: cmd.x,
2288
- y: cmd.y
2289
- };
2290
- first = {
2291
- x: cmd.x,
2292
- y: cmd.y
2293
- };
2294
- break;
2295
- case "h":
2296
- case "H":
2297
- data.push(`${cmd.type} ${cmd.x}`);
2298
- prev = {
2299
- x: cmd.x,
2300
- y: prev?.y ?? 0
2301
- };
2302
- break;
2303
- case "v":
2304
- case "V":
2305
- data.push(`${cmd.type} ${cmd.y}`);
2306
- prev = {
2307
- x: prev?.x ?? 0,
2308
- y: cmd.y
2309
- };
2310
- break;
2311
- case "l":
2312
- case "L":
2313
- data.push(`${cmd.type} ${cmd.x} ${cmd.y}`);
2314
- prev = {
2315
- x: cmd.x,
2316
- y: cmd.y
2317
- };
2318
- break;
2319
- case "c":
2320
- case "C":
2321
- data.push(`${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`);
2322
- prev = {
2323
- x: cmd.x,
2324
- y: cmd.y
2325
- };
2326
- break;
2327
- case "s":
2328
- case "S":
2329
- data.push(`${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`);
2330
- prev = {
2331
- x: cmd.x,
2332
- y: cmd.y
2333
- };
2334
- break;
2335
- case "q":
2336
- case "Q":
2337
- data.push(`${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`);
2338
- prev = {
2339
- x: cmd.x,
2340
- y: cmd.y
2341
- };
2342
- break;
2343
- case "t":
2344
- case "T":
2345
- data.push(`${cmd.type} ${cmd.x} ${cmd.y}`);
2346
- prev = {
2347
- x: cmd.x,
2348
- y: cmd.y
2349
- };
2350
- break;
2351
- case "a":
2352
- case "A":
2353
- data.push(`${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`);
2354
- prev = {
2355
- x: cmd.x,
2356
- y: cmd.y
2357
- };
2358
- break;
2359
- case "z":
2360
- case "Z":
2361
- data.push(cmd.type);
2362
- if (first) prev = {
2363
- x: first.x,
2364
- y: first.y
2365
- };
2366
- break;
2120
+ function cross(ax, ay, bx, by, cx, cy) {
2121
+ return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
2122
+ }
2123
+ function windingNumber(px, py, polygon) {
2124
+ const polygonLen = polygon.length;
2125
+ let wn = 0;
2126
+ for (let i = 0, j = polygonLen - 2; i < polygonLen; j = i, i += 2) {
2127
+ const xi = polygon[i];
2128
+ const yi = polygon[i + 1];
2129
+ const xj = polygon[j];
2130
+ const yj = polygon[j + 1];
2131
+ if (yi <= py) {
2132
+ if (yj > py && cross(xj, yj, xi, yi, px, py) > 0) wn++;
2133
+ } else if (yj <= py && cross(xj, yj, xi, yi, px, py) < 0) wn--;
2134
+ }
2135
+ return wn;
2136
+ }
2137
+ function distance(p1, p2) {
2138
+ const dx = p2[0] - p1[0];
2139
+ const dy = p2[1] - p1[1];
2140
+ return Math.sqrt(dx * dx + dy * dy);
2141
+ }
2142
+ function nonzeroFillRule(paths) {
2143
+ const results = paths.map((_, i) => ({ index: i }));
2144
+ const testPointsGroups = paths.map((path) => {
2145
+ const len = path.length;
2146
+ if (!len) return [];
2147
+ let xMinYAuto = [Number.MAX_SAFE_INTEGER, 0];
2148
+ let xAutoYMin = [0, Number.MAX_SAFE_INTEGER];
2149
+ let xMaxYAuto = [Number.MIN_SAFE_INTEGER, 0];
2150
+ let xAutoYMax = [0, Number.MIN_SAFE_INTEGER];
2151
+ for (let i = 0; i < len; i += 2) {
2152
+ const x = path[i];
2153
+ const y = path[i + 1];
2154
+ if (xMinYAuto[0] > x) xMinYAuto = [x, y];
2155
+ if (xAutoYMin[1] > y) xAutoYMin = [x, y];
2156
+ if (xMaxYAuto[0] < x) xMaxYAuto = [x, y];
2157
+ if (xAutoYMax[1] < y) xAutoYMax = [x, y];
2158
+ }
2159
+ const mid = [(xMinYAuto[0] + xMaxYAuto[0]) / 2, (xAutoYMin[1] + xAutoYMax[1]) / 2];
2160
+ let xMidYMinDx;
2161
+ let xMidYMaxDx;
2162
+ let xMidYMin;
2163
+ let xMidYMax;
2164
+ let xMinYMidDy;
2165
+ let xMaxYMidDy;
2166
+ let xMinYMid;
2167
+ let xMaxYMid;
2168
+ for (let i = 0; i < len; i += 2) {
2169
+ const x = path[i];
2170
+ const y = path[i + 1];
2171
+ const _dx = Math.abs(x - mid[0]);
2172
+ const _dy = Math.abs(y - mid[1]);
2173
+ if (y < mid[1] && (!xMidYMinDx || _dx < xMidYMinDx)) {
2174
+ xMidYMinDx = _dx;
2175
+ xMidYMin = [x, y];
2176
+ }
2177
+ if (y > mid[1] && (!xMidYMaxDx || _dx < xMidYMaxDx)) {
2178
+ xMidYMaxDx = _dx;
2179
+ xMidYMax = [x, y];
2180
+ }
2181
+ if (x < mid[0] && (!xMinYMidDy || _dy < xMinYMidDy)) {
2182
+ xMinYMidDy = _dy;
2183
+ xMinYMid = [x, y];
2184
+ }
2185
+ if (x > mid[0] && (!xMaxYMidDy || _dy < xMaxYMidDy)) {
2186
+ xMaxYMidDy = _dy;
2187
+ xMaxYMid = [x, y];
2188
+ }
2189
+ }
2190
+ return [
2191
+ xMinYAuto,
2192
+ xAutoYMin,
2193
+ xMaxYAuto,
2194
+ xAutoYMax,
2195
+ xMidYMin,
2196
+ xMidYMax,
2197
+ xMinYMid,
2198
+ xMaxYMid
2199
+ ].filter(Boolean);
2200
+ });
2201
+ for (let i = 0, len = paths.length; i < len; i++) {
2202
+ const _results = [];
2203
+ const testPoints = testPointsGroups[i];
2204
+ for (let j = 0; j < len; j++) {
2205
+ if (i === j) continue;
2206
+ const wnMap = {};
2207
+ const wnList = [];
2208
+ for (let p = 0, pLen = testPoints.length; p < pLen; p++) {
2209
+ const [x, y] = testPoints[p];
2210
+ const winding = windingNumber(x, y, paths[j]);
2211
+ wnMap[winding] = (wnMap[winding] ?? 0) + 1;
2212
+ wnList.push(winding);
2213
+ }
2214
+ if (wnList.filter((v) => v !== 0).length > wnList.filter((v) => v === 0).length) _results.push({
2215
+ index: i,
2216
+ parentIndex: j,
2217
+ winding: Number(Array.from(Object.entries(wnMap)).sort((a, b) => b[1] - a[1])?.[0]?.[0] ?? 0),
2218
+ dist: distance(testPointsGroups[i][0], testPointsGroups[j][0])
2219
+ });
2220
+ }
2221
+ if (_results.reduce((total, item) => total + item.winding, 0) !== 0) {
2222
+ _results.sort((a, b) => a.dist - b.dist);
2223
+ results[i] = _results[0];
2367
2224
  }
2368
2225
  }
2369
- return data.join(" ");
2226
+ return results;
2370
2227
  }
2371
- var RE$2 = /[a-df-z][^a-df-z]*/gi;
2372
- function svgPathDataToCommands(data) {
2373
- const commands = [];
2374
- const matched = data.match(RE$2);
2375
- if (!matched) return commands;
2376
- for (let i = 0, len = matched.length; i < len; i++) {
2377
- const command = matched[i];
2378
- const type = command.charAt(0);
2379
- const data2 = command.slice(1).trim();
2380
- let args;
2381
- switch (type) {
2382
- case "m":
2383
- case "M":
2384
- args = parsePathDataArgs(data2);
2385
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) if (i2 === 0) commands.push({
2386
- type,
2387
- x: args[i2],
2388
- y: args[i2 + 1]
2389
- });
2390
- else commands.push({
2391
- type: type === "m" ? "l" : "L",
2392
- x: args[i2],
2393
- y: args[i2 + 1]
2394
- });
2395
- break;
2396
- case "h":
2397
- case "H":
2398
- args = parsePathDataArgs(data2);
2399
- for (let i2 = 0, len2 = args.length; i2 < len2; i2++) commands.push({
2400
- type,
2401
- x: args[i2]
2402
- });
2403
- break;
2404
- case "v":
2405
- case "V":
2406
- args = parsePathDataArgs(data2);
2407
- for (let i2 = 0, len2 = args.length; i2 < len2; i2++) commands.push({
2408
- type,
2409
- y: args[i2]
2410
- });
2411
- break;
2412
- case "l":
2413
- case "L":
2414
- args = parsePathDataArgs(data2);
2415
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) commands.push({
2416
- type,
2417
- x: args[i2],
2418
- y: args[i2 + 1]
2419
- });
2420
- break;
2421
- case "c":
2422
- case "C":
2423
- args = parsePathDataArgs(data2);
2424
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 6) commands.push({
2425
- type,
2426
- x1: args[i2],
2427
- y1: args[i2 + 1],
2428
- x2: args[i2 + 2],
2429
- y2: args[i2 + 3],
2430
- x: args[i2 + 4],
2431
- y: args[i2 + 5]
2432
- });
2433
- break;
2434
- case "s":
2435
- case "S":
2436
- args = parsePathDataArgs(data2);
2437
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 4) commands.push({
2438
- type,
2439
- x2: args[i2],
2440
- y2: args[i2 + 1],
2441
- x: args[i2 + 2],
2442
- y: args[i2 + 3]
2443
- });
2444
- break;
2445
- case "q":
2446
- case "Q":
2447
- args = parsePathDataArgs(data2);
2448
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 4) commands.push({
2449
- type,
2450
- x1: args[i2],
2451
- y1: args[i2 + 1],
2452
- x: args[i2 + 2],
2453
- y: args[i2 + 3]
2454
- });
2455
- break;
2456
- case "t":
2457
- case "T":
2458
- args = parsePathDataArgs(data2);
2459
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) commands.push({
2460
- type,
2461
- x: args[i2],
2462
- y: args[i2 + 1]
2463
- });
2464
- break;
2465
- case "a":
2466
- case "A":
2467
- args = parsePathDataArgs(data2, [3, 4], 7);
2468
- for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 7) commands.push({
2469
- type,
2470
- rx: args[i2],
2471
- ry: args[i2 + 1],
2472
- angle: args[i2 + 2],
2473
- largeArcFlag: args[i2 + 3],
2474
- sweepFlag: args[i2 + 4],
2475
- x: args[i2 + 5],
2476
- y: args[i2 + 6]
2477
- });
2478
- break;
2479
- case "z":
2480
- case "Z":
2481
- commands.push({ type });
2482
- break;
2483
- default: console.warn(command);
2228
+ function quadraticBezierP0(t, p) {
2229
+ const k = 1 - t;
2230
+ return k * k * p;
2231
+ }
2232
+ function quadraticBezierP1(t, p) {
2233
+ return 2 * (1 - t) * t * p;
2234
+ }
2235
+ function quadraticBezierP2(t, p) {
2236
+ return t * t * p;
2237
+ }
2238
+ function quadraticBezier(t, p0, p1, p2) {
2239
+ return quadraticBezierP0(t, p0) + quadraticBezierP1(t, p1) + quadraticBezierP2(t, p2);
2240
+ }
2241
+ var closePointEps = 1e-4;
2242
+ var curveEps = 1e-4;
2243
+ function strokeTriangulate(points, options = {}) {
2244
+ const { vertices = [], indices = [], lineStyle = {
2245
+ alignment: .5,
2246
+ cap: "butt",
2247
+ join: "miter",
2248
+ width: 1,
2249
+ miterLimit: 10
2250
+ }, flipAlignment = false, closed = true } = options;
2251
+ const eps = closePointEps;
2252
+ if (points.length === 0) return {
2253
+ vertices,
2254
+ indices
2255
+ };
2256
+ const style = lineStyle;
2257
+ let alignment = style.alignment;
2258
+ if (lineStyle.alignment !== .5) {
2259
+ let orientation = getOrientationOfPoints(points);
2260
+ if (flipAlignment) orientation *= -1;
2261
+ alignment = (alignment - .5) * orientation + .5;
2262
+ }
2263
+ const firstPoint = {
2264
+ x: points[0],
2265
+ y: points[1]
2266
+ };
2267
+ const lastPoint = {
2268
+ x: points[points.length - 2],
2269
+ y: points[points.length - 1]
2270
+ };
2271
+ const closedShape = closed;
2272
+ const closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps && Math.abs(firstPoint.y - lastPoint.y) < eps;
2273
+ if (closedShape) {
2274
+ points = points.slice();
2275
+ if (closedPath) {
2276
+ points.pop();
2277
+ points.pop();
2278
+ lastPoint.x = points[points.length - 2];
2279
+ lastPoint.y = points[points.length - 1];
2280
+ }
2281
+ const midPointX = (firstPoint.x + lastPoint.x) * .5;
2282
+ const midPointY = (lastPoint.y + firstPoint.y) * .5;
2283
+ points.unshift(midPointX, midPointY);
2284
+ points.push(midPointX, midPointY);
2285
+ }
2286
+ const verts = vertices;
2287
+ const length = points.length / 2;
2288
+ let indexCount = points.length;
2289
+ const indexStart = verts.length / 2;
2290
+ const width = style.width / 2;
2291
+ const widthSquared = width * width;
2292
+ const miterLimitSquared = style.miterLimit * style.miterLimit;
2293
+ let x0 = points[0];
2294
+ let y0 = points[1];
2295
+ let x1 = points[2];
2296
+ let y1 = points[3];
2297
+ let x2 = 0;
2298
+ let y2 = 0;
2299
+ let perpX = -(y0 - y1);
2300
+ let perpY = x0 - x1;
2301
+ let perp1x = 0;
2302
+ let perp1y = 0;
2303
+ let dist = Math.sqrt(perpX * perpX + perpY * perpY);
2304
+ perpX /= dist;
2305
+ perpY /= dist;
2306
+ perpX *= width;
2307
+ perpY *= width;
2308
+ const ratio = alignment;
2309
+ const innerWeight = (1 - ratio) * 2;
2310
+ const outerWeight = ratio * 2;
2311
+ if (!closedShape) {
2312
+ if (style.cap === "round") indexCount += round(x0 - perpX * (innerWeight - outerWeight) * .5, y0 - perpY * (innerWeight - outerWeight) * .5, x0 - perpX * innerWeight, y0 - perpY * innerWeight, x0 + perpX * outerWeight, y0 + perpY * outerWeight, verts, true) + 2;
2313
+ else if (style.cap === "square") indexCount += square(x0, y0, perpX, perpY, innerWeight, outerWeight, true, verts);
2314
+ }
2315
+ verts.push(x0 - perpX * innerWeight, y0 - perpY * innerWeight);
2316
+ verts.push(x0 + perpX * outerWeight, y0 + perpY * outerWeight);
2317
+ for (let i = 1; i < length - 1; ++i) {
2318
+ x0 = points[(i - 1) * 2];
2319
+ y0 = points[(i - 1) * 2 + 1];
2320
+ x1 = points[i * 2];
2321
+ y1 = points[i * 2 + 1];
2322
+ x2 = points[(i + 1) * 2];
2323
+ y2 = points[(i + 1) * 2 + 1];
2324
+ perpX = -(y0 - y1);
2325
+ perpY = x0 - x1;
2326
+ dist = Math.sqrt(perpX * perpX + perpY * perpY);
2327
+ perpX /= dist;
2328
+ perpY /= dist;
2329
+ perpX *= width;
2330
+ perpY *= width;
2331
+ perp1x = -(y1 - y2);
2332
+ perp1y = x1 - x2;
2333
+ dist = Math.sqrt(perp1x * perp1x + perp1y * perp1y);
2334
+ perp1x /= dist;
2335
+ perp1y /= dist;
2336
+ perp1x *= width;
2337
+ perp1y *= width;
2338
+ const dx0 = x1 - x0;
2339
+ const dy0 = y0 - y1;
2340
+ const dx1 = x1 - x2;
2341
+ const dy1 = y2 - y1;
2342
+ const dot = dx0 * dx1 + dy0 * dy1;
2343
+ const cross = dy0 * dx1 - dy1 * dx0;
2344
+ const clockwise = cross < 0;
2345
+ if (Math.abs(cross) < .001 * Math.abs(dot)) {
2346
+ verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2347
+ verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2348
+ if (dot >= 0) {
2349
+ if (style.join === "round") indexCount += round(x1, y1, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 - perp1x * innerWeight, y1 - perp1y * innerWeight, verts, false) + 4;
2350
+ else indexCount += 2;
2351
+ verts.push(x1 - perp1x * outerWeight, y1 - perp1y * outerWeight);
2352
+ verts.push(x1 + perp1x * innerWeight, y1 + perp1y * innerWeight);
2353
+ }
2354
+ continue;
2355
+ }
2356
+ const c1 = (-perpX + x0) * (-perpY + y1) - (-perpX + x1) * (-perpY + y0);
2357
+ const c2 = (-perp1x + x2) * (-perp1y + y1) - (-perp1x + x1) * (-perp1y + y2);
2358
+ const px = (dx0 * c2 - dx1 * c1) / cross;
2359
+ const py = (dy1 * c1 - dy0 * c2) / cross;
2360
+ const pDist = (px - x1) * (px - x1) + (py - y1) * (py - y1);
2361
+ const imx = x1 + (px - x1) * innerWeight;
2362
+ const imy = y1 + (py - y1) * innerWeight;
2363
+ const omx = x1 - (px - x1) * outerWeight;
2364
+ const omy = y1 - (py - y1) * outerWeight;
2365
+ const smallerInsideSegmentSq = Math.min(dx0 * dx0 + dy0 * dy0, dx1 * dx1 + dy1 * dy1);
2366
+ const insideWeight = clockwise ? innerWeight : outerWeight;
2367
+ if (pDist <= smallerInsideSegmentSq + insideWeight * insideWeight * widthSquared) if (style.join === "bevel" || pDist / widthSquared > miterLimitSquared) {
2368
+ if (clockwise) {
2369
+ verts.push(imx, imy);
2370
+ verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2371
+ verts.push(imx, imy);
2372
+ verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
2373
+ } else {
2374
+ verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2375
+ verts.push(omx, omy);
2376
+ verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
2377
+ verts.push(omx, omy);
2378
+ }
2379
+ indexCount += 2;
2380
+ } else if (style.join === "round") if (clockwise) {
2381
+ verts.push(imx, imy);
2382
+ verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2383
+ indexCount += round(x1, y1, x1 + perpX * outerWeight, y1 + perpY * outerWeight, x1 + perp1x * outerWeight, y1 + perp1y * outerWeight, verts, true) + 4;
2384
+ verts.push(imx, imy);
2385
+ verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
2386
+ } else {
2387
+ verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2388
+ verts.push(omx, omy);
2389
+ indexCount += round(x1, y1, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 - perp1x * innerWeight, y1 - perp1y * innerWeight, verts, false) + 4;
2390
+ verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
2391
+ verts.push(omx, omy);
2392
+ }
2393
+ else {
2394
+ verts.push(imx, imy);
2395
+ verts.push(omx, omy);
2396
+ }
2397
+ else {
2398
+ verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2399
+ verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2400
+ if (style.join === "round") if (clockwise) indexCount += round(x1, y1, x1 + perpX * outerWeight, y1 + perpY * outerWeight, x1 + perp1x * outerWeight, y1 + perp1y * outerWeight, verts, true) + 2;
2401
+ else indexCount += round(x1, y1, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 - perp1x * innerWeight, y1 - perp1y * innerWeight, verts, false) + 2;
2402
+ else if (style.join === "miter" && pDist / widthSquared <= miterLimitSquared) {
2403
+ if (clockwise) {
2404
+ verts.push(omx, omy);
2405
+ verts.push(omx, omy);
2406
+ } else {
2407
+ verts.push(imx, imy);
2408
+ verts.push(imx, imy);
2409
+ }
2410
+ indexCount += 2;
2411
+ }
2412
+ verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
2413
+ verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
2414
+ indexCount += 2;
2484
2415
  }
2485
2416
  }
2486
- return commands;
2487
- }
2488
- var dataUri = "data:image/svg+xml;";
2489
- var base64DataUri = `${dataUri}base64,`;
2490
- var utf8DataUri = `${dataUri}charset=utf8,`;
2491
- function svgToDom(svg) {
2492
- if (typeof svg === "string") {
2493
- let xml;
2494
- if (svg.startsWith(base64DataUri)) {
2495
- svg = svg.substring(base64DataUri.length, svg.length);
2496
- xml = atob(svg);
2497
- } else if (svg.startsWith(utf8DataUri)) {
2498
- svg = svg.substring(utf8DataUri.length, svg.length);
2499
- xml = decodeURIComponent(svg);
2500
- } else xml = svg;
2501
- const doc = new DOMParser().parseFromString(xml, "text/xml");
2502
- const error = doc.querySelector("parsererror");
2503
- if (error) throw new Error(`${error.textContent ?? "parser error"}
2504
- ${xml}`);
2505
- return doc.documentElement;
2506
- } else return svg;
2417
+ x0 = points[(length - 2) * 2];
2418
+ y0 = points[(length - 2) * 2 + 1];
2419
+ x1 = points[(length - 1) * 2];
2420
+ y1 = points[(length - 1) * 2 + 1];
2421
+ perpX = -(y0 - y1);
2422
+ perpY = x0 - x1;
2423
+ dist = Math.sqrt(perpX * perpX + perpY * perpY);
2424
+ perpX /= dist;
2425
+ perpY /= dist;
2426
+ perpX *= width;
2427
+ perpY *= width;
2428
+ verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2429
+ verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2430
+ if (!closedShape) {
2431
+ if (style.cap === "round") indexCount += round(x1 - perpX * (innerWeight - outerWeight) * .5, y1 - perpY * (innerWeight - outerWeight) * .5, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 + perpX * outerWeight, y1 + perpY * outerWeight, verts, false) + 2;
2432
+ else if (style.cap === "square") indexCount += square(x1, y1, perpX, perpY, innerWeight, outerWeight, false, verts);
2433
+ }
2434
+ const eps2 = curveEps * curveEps;
2435
+ for (let i = indexStart; i < indexCount + indexStart - 2; ++i) {
2436
+ x0 = verts[i * 2];
2437
+ y0 = verts[i * 2 + 1];
2438
+ x1 = verts[(i + 1) * 2];
2439
+ y1 = verts[(i + 1) * 2 + 1];
2440
+ x2 = verts[(i + 2) * 2];
2441
+ y2 = verts[(i + 2) * 2 + 1];
2442
+ if (Math.abs(x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1)) < eps2) continue;
2443
+ indices.push(i, i + 1, i + 2);
2444
+ }
2445
+ return {
2446
+ vertices,
2447
+ indices
2448
+ };
2507
2449
  }
2508
- var defaultUnit = "px";
2509
- var defaultDPI = 90;
2510
- var units = [
2511
- "mm",
2512
- "cm",
2513
- "in",
2514
- "pt",
2515
- "pc",
2516
- "px"
2517
- ];
2518
- var unitConversion = {
2519
- mm: {
2520
- mm: 1,
2521
- cm: .1,
2522
- in: 1 / 25.4,
2523
- pt: 72 / 25.4,
2524
- pc: 6 / 25.4,
2525
- px: -1
2526
- },
2527
- cm: {
2528
- mm: 10,
2529
- cm: 1,
2530
- in: 1 / 2.54,
2531
- pt: 72 / 2.54,
2532
- pc: 6 / 2.54,
2533
- px: -1
2534
- },
2535
- in: {
2536
- mm: 25.4,
2537
- cm: 2.54,
2538
- in: 1,
2539
- pt: 72,
2540
- pc: 6,
2541
- px: -1
2542
- },
2543
- pt: {
2544
- mm: 25.4 / 72,
2545
- cm: 2.54 / 72,
2546
- in: 1 / 72,
2547
- pt: 1,
2548
- pc: 6 / 72,
2549
- px: -1
2550
- },
2551
- pc: {
2552
- mm: 25.4 / 6,
2553
- cm: 2.54 / 6,
2554
- in: 1 / 6,
2555
- pt: 72 / 6,
2556
- pc: 1,
2557
- px: -1
2558
- },
2559
- px: { px: 1 }
2560
- };
2561
- function parseFloatWithUnits(string) {
2562
- let theUnit = "px";
2563
- if (typeof string === "string") for (let i = 0, n = units.length; i < n; i++) {
2564
- const u = units[i];
2565
- if (string.endsWith(u)) {
2566
- theUnit = u;
2567
- string = string.substring(0, string.length - u.length);
2568
- break;
2569
- }
2450
+ function getOrientationOfPoints(points) {
2451
+ const m = points.length;
2452
+ if (m < 6) return 1;
2453
+ let area = 0;
2454
+ for (let i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) {
2455
+ const x2 = points[i];
2456
+ const y2 = points[i + 1];
2457
+ area += (x2 - x1) * (y2 + y1);
2458
+ x1 = x2;
2459
+ y1 = y2;
2570
2460
  }
2571
- let scale;
2572
- scale = unitConversion[theUnit][defaultUnit];
2573
- if (scale < 0) scale = unitConversion[theUnit].in * defaultDPI;
2574
- return scale * Number.parseFloat(string);
2461
+ if (area < 0) return -1;
2462
+ return 1;
2575
2463
  }
2576
- var tempTransform0$1 = new Matrix3();
2577
- var tempTransform1$1 = new Matrix3();
2578
- var tempTransform2$1 = new Matrix3();
2579
- var tempTransform3 = new Matrix3();
2580
- function getNodeTransform(node, currentTransform, transformStack) {
2581
- if (!(node.hasAttribute("transform") || node.nodeName === "use" && (node.hasAttribute("x") || node.hasAttribute("y")))) return null;
2582
- const transform = parseNodeTransform(node);
2583
- if (transformStack.length > 0) transform.premultiply(transformStack[transformStack.length - 1]);
2584
- currentTransform.copy(transform);
2585
- transformStack.push(transform);
2586
- return transform;
2464
+ function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, verts) {
2465
+ const ix = x - nx * innerWeight;
2466
+ const iy = y - ny * innerWeight;
2467
+ const ox = x + nx * outerWeight;
2468
+ const oy = y + ny * outerWeight;
2469
+ let exx;
2470
+ let eyy;
2471
+ if (clockwise) {
2472
+ exx = ny;
2473
+ eyy = -nx;
2474
+ } else {
2475
+ exx = -ny;
2476
+ eyy = nx;
2477
+ }
2478
+ const eix = ix + exx;
2479
+ const eiy = iy + eyy;
2480
+ const eox = ox + exx;
2481
+ const eoy = oy + eyy;
2482
+ verts.push(eix, eiy);
2483
+ verts.push(eox, eoy);
2484
+ return 2;
2587
2485
  }
2588
- function parseNodeTransform(node) {
2589
- const transform = new Matrix3();
2590
- const currentTransform = tempTransform0$1;
2591
- if (node.nodeName === "use" && (node.hasAttribute("x") || node.hasAttribute("y"))) transform.translate(parseFloatWithUnits(node.getAttribute("x")), parseFloatWithUnits(node.getAttribute("y")));
2592
- if (node.hasAttribute("transform")) {
2593
- const transformsTexts = node.getAttribute("transform").split(")");
2594
- for (let tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex--) {
2595
- const transformText = transformsTexts[tIndex].trim();
2596
- if (transformText === "") continue;
2597
- const openParPos = transformText.indexOf("(");
2598
- const closeParPos = transformText.length;
2599
- if (openParPos > 0 && openParPos < closeParPos) {
2600
- const transformType = transformText.slice(0, openParPos);
2601
- const array = parsePathDataArgs(transformText.slice(openParPos + 1));
2602
- currentTransform.identity();
2603
- switch (transformType) {
2604
- case "translate":
2605
- if (array.length >= 1) {
2606
- const tx = array[0];
2607
- let ty = 0;
2608
- if (array.length >= 2) ty = array[1];
2609
- currentTransform.translate(tx, ty);
2610
- }
2611
- break;
2612
- case "rotate":
2613
- if (array.length >= 1) {
2614
- let angle = 0;
2615
- let cx = 0;
2616
- let cy = 0;
2617
- angle = array[0] * Math.PI / 180;
2618
- if (array.length >= 3) {
2619
- cx = array[1];
2620
- cy = array[2];
2621
- }
2622
- tempTransform1$1.makeTranslation(-cx, -cy);
2623
- tempTransform2$1.makeRotation(angle);
2624
- tempTransform3.multiplyMatrices(tempTransform2$1, tempTransform1$1);
2625
- tempTransform1$1.makeTranslation(cx, cy);
2626
- currentTransform.multiplyMatrices(tempTransform1$1, tempTransform3);
2627
- }
2628
- break;
2629
- case "scale":
2630
- if (array.length >= 1) currentTransform.scale(array[0], array[1] ?? array[0]);
2631
- break;
2632
- case "skewX":
2633
- if (array.length === 1) currentTransform.set(1, Math.tan(array[0] * Math.PI / 180), 0, 0, 1, 0, 0, 0, 1);
2634
- break;
2635
- case "skewY":
2636
- if (array.length === 1) currentTransform.set(1, 0, 0, Math.tan(array[0] * Math.PI / 180), 1, 0, 0, 0, 1);
2637
- break;
2638
- case "matrix":
2639
- if (array.length === 6) currentTransform.set(array[0], array[2], array[4], array[1], array[3], array[5], 0, 0, 1);
2640
- break;
2641
- }
2642
- }
2643
- transform.premultiply(currentTransform);
2486
+ function round(cx, cy, sx, sy, ex, ey, verts, clockwise) {
2487
+ const cx2p0x = sx - cx;
2488
+ const cy2p0y = sy - cy;
2489
+ let angle0 = Math.atan2(cx2p0x, cy2p0y);
2490
+ let angle1 = Math.atan2(ex - cx, ey - cy);
2491
+ if (clockwise && angle0 < angle1) angle0 += Math.PI * 2;
2492
+ else if (!clockwise && angle0 > angle1) angle1 += Math.PI * 2;
2493
+ let startAngle = angle0;
2494
+ const angleDiff = angle1 - angle0;
2495
+ const absAngleDiff = Math.abs(angleDiff);
2496
+ const radius = Math.sqrt(cx2p0x * cx2p0x + cy2p0y * cy2p0y);
2497
+ const segCount = (15 * absAngleDiff * Math.sqrt(radius) / Math.PI >> 0) + 1;
2498
+ const angleInc = angleDiff / segCount;
2499
+ startAngle += angleInc;
2500
+ if (clockwise) {
2501
+ verts.push(cx, cy);
2502
+ verts.push(sx, sy);
2503
+ for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
2504
+ verts.push(cx, cy);
2505
+ verts.push(cx + Math.sin(angle) * radius, cy + Math.cos(angle) * radius);
2506
+ }
2507
+ verts.push(cx, cy);
2508
+ verts.push(ex, ey);
2509
+ } else {
2510
+ verts.push(sx, sy);
2511
+ verts.push(cx, cy);
2512
+ for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
2513
+ verts.push(cx + Math.sin(angle) * radius, cy + Math.cos(angle) * radius);
2514
+ verts.push(cx, cy);
2644
2515
  }
2516
+ verts.push(ex, ey);
2517
+ verts.push(cx, cy);
2645
2518
  }
2646
- return transform;
2647
- }
2648
- function parseCircleNode(node) {
2649
- return new Path2D().arc(parseFloatWithUnits(node.getAttribute("cx") || 0), parseFloatWithUnits(node.getAttribute("cy") || 0), parseFloatWithUnits(node.getAttribute("r") || 0), 0, Math.PI * 2);
2519
+ return segCount * 2;
2650
2520
  }
2651
- function parseCSSStylesheet(node, stylesheets) {
2652
- if (!node.sheet || !node.sheet.cssRules || !node.sheet.cssRules.length) return;
2653
- for (let i = 0; i < node.sheet.cssRules.length; i++) {
2654
- const stylesheet = node.sheet.cssRules[i];
2655
- if (stylesheet.type !== 1) continue;
2656
- const selectorList = stylesheet.selectorText.split(/,/g).filter(Boolean).map((i2) => i2.trim());
2657
- const definitions = {};
2658
- for (let len = stylesheet.style.length, i2 = 0; i2 < len; i2++) {
2659
- const name = stylesheet.style.item(i2);
2660
- definitions[name] = stylesheet.style.getPropertyValue(name);
2521
+ var Transform2D = class Transform2D {
2522
+ constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) {
2523
+ this.a = a;
2524
+ this.b = b;
2525
+ this.c = c;
2526
+ this.d = d;
2527
+ this.tx = tx;
2528
+ this.ty = ty;
2529
+ }
2530
+ _array;
2531
+ set(a, b, c, d, tx, ty) {
2532
+ this.a = a;
2533
+ this.b = b;
2534
+ this.c = c;
2535
+ this.d = d;
2536
+ this.tx = tx;
2537
+ this.ty = ty;
2538
+ return this;
2539
+ }
2540
+ append(t2d) {
2541
+ const a1 = this.a;
2542
+ const b1 = this.b;
2543
+ const c1 = this.c;
2544
+ const d1 = this.d;
2545
+ this.a = t2d.a * a1 + t2d.b * c1;
2546
+ this.b = t2d.a * b1 + t2d.b * d1;
2547
+ this.c = t2d.c * a1 + t2d.d * c1;
2548
+ this.d = t2d.c * b1 + t2d.d * d1;
2549
+ this.tx = t2d.tx * a1 + t2d.ty * c1 + this.tx;
2550
+ this.ty = t2d.tx * b1 + t2d.ty * d1 + this.ty;
2551
+ return this;
2552
+ }
2553
+ appendFrom(a, b) {
2554
+ const a1 = a.a;
2555
+ const b1 = a.b;
2556
+ const c1 = a.c;
2557
+ const d1 = a.d;
2558
+ const tx = a.tx;
2559
+ const ty = a.ty;
2560
+ const a2 = b.a;
2561
+ const b2 = b.b;
2562
+ const c2 = b.c;
2563
+ const d2 = b.d;
2564
+ this.a = a1 * a2 + b1 * c2;
2565
+ this.b = a1 * b2 + b1 * d2;
2566
+ this.c = c1 * a2 + d1 * c2;
2567
+ this.d = c1 * b2 + d1 * d2;
2568
+ this.tx = tx * a2 + ty * c2 + b.tx;
2569
+ this.ty = tx * b2 + ty * d2 + b.ty;
2570
+ return this;
2571
+ }
2572
+ setTransform(x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) {
2573
+ this.a = Math.cos(rotation + skewY) * scaleX;
2574
+ this.b = Math.sin(rotation + skewY) * scaleX;
2575
+ this.c = -Math.sin(rotation - skewX) * scaleY;
2576
+ this.d = Math.cos(rotation - skewX) * scaleY;
2577
+ this.tx = x - (pivotX * this.a + pivotY * this.c);
2578
+ this.ty = y - (pivotX * this.b + pivotY * this.d);
2579
+ return this;
2580
+ }
2581
+ prepend(t2d) {
2582
+ const tx1 = this.tx;
2583
+ if (t2d.a !== 1 || t2d.b !== 0 || t2d.c !== 0 || t2d.d !== 1) {
2584
+ const a1 = this.a;
2585
+ const c1 = this.c;
2586
+ this.a = a1 * t2d.a + this.b * t2d.c;
2587
+ this.b = a1 * t2d.b + this.b * t2d.d;
2588
+ this.c = c1 * t2d.a + this.d * t2d.c;
2589
+ this.d = c1 * t2d.b + this.d * t2d.d;
2661
2590
  }
2662
- for (let j = 0; j < selectorList.length; j++) stylesheets[selectorList[j]] = Object.assign(stylesheets[selectorList[j]] || {}, { ...definitions });
2591
+ this.tx = tx1 * t2d.a + this.ty * t2d.c + t2d.tx;
2592
+ this.ty = tx1 * t2d.b + this.ty * t2d.d + t2d.ty;
2593
+ return this;
2663
2594
  }
2664
- }
2665
- function parseEllipseNode(node) {
2666
- return new Path2D().ellipse(parseFloatWithUnits(node.getAttribute("cx") || 0), parseFloatWithUnits(node.getAttribute("cy") || 0), parseFloatWithUnits(node.getAttribute("rx") || 0), parseFloatWithUnits(node.getAttribute("ry") || 0), 0, 0, Math.PI * 2);
2667
- }
2668
- function parseLineNode(node) {
2669
- return new Path2D().moveTo(parseFloatWithUnits(node.getAttribute("x1") || 0), parseFloatWithUnits(node.getAttribute("y1") || 0)).lineTo(parseFloatWithUnits(node.getAttribute("x2") || 0), parseFloatWithUnits(node.getAttribute("y2") || 0));
2670
- }
2671
- function parsePathNode(node) {
2672
- const path = new Path2D();
2673
- const d = node.getAttribute("d");
2674
- if (!d || d === "none") return null;
2675
- path.addData(d);
2676
- return path;
2677
- }
2678
- var RE$1 = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;
2679
- function parsePolygonNode(node) {
2680
- const path = new Path2D();
2681
- let index = 0;
2682
- node.getAttribute("points")?.replace(RE$1, (match, a, b) => {
2683
- const x = parseFloatWithUnits(a);
2684
- const y = parseFloatWithUnits(b);
2685
- if (index === 0) path.moveTo(x, y);
2686
- else path.lineTo(x, y);
2687
- index++;
2688
- return match;
2689
- });
2690
- path.currentCurve.autoClose = true;
2691
- return path;
2692
- }
2693
- var RE = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;
2694
- function parsePolylineNode(node) {
2695
- const path = new Path2D();
2696
- let index = 0;
2697
- node.getAttribute("points")?.replace(RE, (match, a, b) => {
2698
- const x = parseFloatWithUnits(a);
2699
- const y = parseFloatWithUnits(b);
2700
- if (index === 0) path.moveTo(x, y);
2701
- else path.lineTo(x, y);
2702
- index++;
2703
- return match;
2704
- });
2705
- path.currentCurve.autoClose = false;
2706
- return path;
2707
- }
2708
- function parseRectNode(node) {
2709
- const x = parseFloatWithUnits(node.getAttribute("x") || 0);
2710
- const y = parseFloatWithUnits(node.getAttribute("y") || 0);
2711
- const rx = parseFloatWithUnits(node.getAttribute("rx") || node.getAttribute("ry") || 0);
2712
- const ry = parseFloatWithUnits(node.getAttribute("ry") || node.getAttribute("rx") || 0);
2713
- const w = parseFloatWithUnits(node.getAttribute("width"));
2714
- const h = parseFloatWithUnits(node.getAttribute("height"));
2715
- const bci = .448084975506;
2716
- const path = new Path2D();
2717
- path.moveTo(x + rx, y);
2718
- path.lineTo(x + w - rx, y);
2719
- if (rx !== 0 || ry !== 0) path.bezierCurveTo(x + w - rx * bci, y, x + w, y + ry * bci, x + w, y + ry);
2720
- path.lineTo(x + w, y + h - ry);
2721
- if (rx !== 0 || ry !== 0) path.bezierCurveTo(x + w, y + h - ry * bci, x + w - rx * bci, y + h, x + w - rx, y + h);
2722
- path.lineTo(x + rx, y + h);
2723
- if (rx !== 0 || ry !== 0) path.bezierCurveTo(x + rx * bci, y + h, x, y + h - ry * bci, x, y + h - ry);
2724
- path.lineTo(x, y + ry);
2725
- if (rx !== 0 || ry !== 0) path.bezierCurveTo(x, y + ry * bci, x + rx * bci, y, x + rx, y);
2726
- return path;
2727
- }
2728
- function parseStyle(node, style, stylesheets) {
2729
- style = Object.assign({}, style);
2730
- let stylesheetStyles = {};
2731
- if (node.hasAttribute("class")) {
2732
- const classSelectors = node.getAttribute("class").split(/\s/).filter(Boolean).map((i) => i.trim());
2733
- for (let i = 0; i < classSelectors.length; i++) stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`.${classSelectors[i]}`]);
2595
+ skewX(x) {
2596
+ const tan = Math.tan(x);
2597
+ this.a += tan * this.b;
2598
+ this.c += tan * this.d;
2599
+ this.tx += tan * this.ty;
2600
+ return this;
2734
2601
  }
2735
- if (node.hasAttribute("id")) stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`#${node.getAttribute("id")}`]);
2736
- for (let len = node.style.length, i = 0; i < len; i++) {
2737
- const name = node.style.item(i);
2738
- const value = node.style.getPropertyValue(name);
2739
- style[name] = value;
2740
- stylesheetStyles[name] = value;
2602
+ skewY(y) {
2603
+ const tan = Math.tan(y);
2604
+ this.b += tan * this.a;
2605
+ this.d += tan * this.c;
2606
+ this.ty += tan * this.tx;
2607
+ return this;
2741
2608
  }
2742
- function addStyle(svgName, jsName, adjustFunction = copy) {
2743
- if (node.hasAttribute(svgName)) style[jsName] = adjustFunction(node.getAttribute(svgName));
2744
- if (stylesheetStyles[svgName]) style[jsName] = adjustFunction(stylesheetStyles[svgName]);
2609
+ skew(x, y) {
2610
+ const tanX = Math.tan(x);
2611
+ const tanY = Math.tan(y);
2612
+ const a1 = this.a;
2613
+ const b1 = this.b;
2614
+ const c1 = this.c;
2615
+ const d1 = this.d;
2616
+ const tx1 = this.tx;
2617
+ const ty1 = this.ty;
2618
+ this.a = a1 + tanX * b1;
2619
+ this.b = tanY * a1 + b1;
2620
+ this.c = c1 + tanX * d1;
2621
+ this.d = tanY * c1 + d1;
2622
+ this.tx = tx1 + tanX * ty1;
2623
+ this.ty = tanY * tx1 + ty1;
2624
+ return this;
2745
2625
  }
2746
- function copy(v) {
2747
- if (v.startsWith("url")) console.warn("url access in attributes is not implemented.");
2748
- return v;
2626
+ translateX(x) {
2627
+ return this.translate(x, 0);
2749
2628
  }
2750
- function clamp(v) {
2751
- return Math.max(0, Math.min(1, parseFloatWithUnits(v)));
2629
+ translateY(y) {
2630
+ return this.translate(0, y);
2752
2631
  }
2753
- function positive(v) {
2754
- return Math.max(0, parseFloatWithUnits(v));
2632
+ translateZ(z) {
2633
+ return this.translate(0, 0, z);
2755
2634
  }
2756
- function array(v) {
2757
- return v.split(" ").filter((v2) => v2 !== "").map((v2) => parseFloatWithUnits(v2));
2635
+ translate3d(x, y, z) {
2636
+ return this.translate(x, y, z);
2758
2637
  }
2759
- addStyle("fill", "fill");
2760
- addStyle("fill-opacity", "fillOpacity", clamp);
2761
- addStyle("fill-rule", "fillRule");
2762
- addStyle("opacity", "opacity", clamp);
2763
- addStyle("stroke", "stroke");
2764
- addStyle("stroke-opacity", "strokeOpacity", clamp);
2765
- addStyle("stroke-width", "strokeWidth", positive);
2766
- addStyle("stroke-linecap", "strokeLinecap");
2767
- addStyle("stroke-linejoin", "strokeLinejoin");
2768
- addStyle("stroke-miterlimit", "strokeMiterlimit", positive);
2769
- addStyle("stroke-dasharray", "strokeDasharray", array);
2770
- addStyle("stroke-dashoffset", "strokeDashoffset", parseFloatWithUnits);
2771
- addStyle("visibility", "visibility");
2772
- return style;
2773
- }
2774
- function parseNode(node, style, paths = [], stylesheets = {}) {
2775
- if (node.nodeType !== 1) return paths;
2776
- let isDefsNode = false;
2777
- let path = null;
2778
- let _style = { ...style };
2779
- switch (node.nodeName) {
2780
- case "svg":
2781
- _style = parseStyle(node, _style, stylesheets);
2782
- break;
2783
- case "style":
2784
- parseCSSStylesheet(node, stylesheets);
2785
- break;
2786
- case "g":
2787
- _style = parseStyle(node, _style, stylesheets);
2788
- break;
2789
- case "path":
2790
- _style = parseStyle(node, _style, stylesheets);
2791
- if (node.hasAttribute("d")) path = parsePathNode(node);
2792
- break;
2793
- case "rect":
2794
- _style = parseStyle(node, _style, stylesheets);
2795
- path = parseRectNode(node);
2796
- break;
2797
- case "polygon":
2798
- _style = parseStyle(node, _style, stylesheets);
2799
- path = parsePolygonNode(node);
2800
- break;
2801
- case "polyline":
2802
- _style = parseStyle(node, _style, stylesheets);
2803
- path = parsePolylineNode(node);
2804
- break;
2805
- case "circle":
2806
- _style = parseStyle(node, _style, stylesheets);
2807
- path = parseCircleNode(node);
2808
- break;
2809
- case "ellipse":
2810
- _style = parseStyle(node, _style, stylesheets);
2811
- path = parseEllipseNode(node);
2812
- break;
2813
- case "line":
2814
- _style = parseStyle(node, _style, stylesheets);
2815
- path = parseLineNode(node);
2816
- break;
2817
- case "defs":
2818
- isDefsNode = true;
2819
- break;
2820
- case "use": {
2821
- _style = parseStyle(node, _style, stylesheets);
2822
- const usedNodeId = (node.getAttributeNS("http://www.w3.org/1999/xlink", "href") || node.getAttribute("href") || "").substring(1);
2823
- const usedNode = node.viewportElement?.getElementById(usedNodeId);
2824
- if (usedNode) parseNode(usedNode, _style, paths, stylesheets);
2825
- else console.warn(`'use node' references non-existent node id: ${usedNodeId}`);
2826
- break;
2638
+ translate(x, y, _z = 0) {
2639
+ this.tx += x;
2640
+ this.ty += y;
2641
+ return this;
2642
+ }
2643
+ scaleX(x) {
2644
+ return this.scale(x, 1);
2645
+ }
2646
+ scaleY(y) {
2647
+ return this.scale(1, y);
2648
+ }
2649
+ scale3d(x, y, z = 1) {
2650
+ return this.scale(x, y, z);
2651
+ }
2652
+ scale(x, y, _z = 1) {
2653
+ this.a *= x;
2654
+ this.d *= y;
2655
+ this.c *= x;
2656
+ this.b *= y;
2657
+ this.tx *= x;
2658
+ this.ty *= y;
2659
+ return this;
2660
+ }
2661
+ rotateX(x) {
2662
+ return this.scaleY(this._rotateToScale(x));
2663
+ }
2664
+ rotateY(y) {
2665
+ return this.scaleX(this._rotateToScale(y));
2666
+ }
2667
+ rotateZ(z) {
2668
+ return this.rotate(z);
2669
+ }
2670
+ rotate(angle) {
2671
+ const cos = Math.cos(angle);
2672
+ const sin = Math.sin(angle);
2673
+ const a1 = this.a;
2674
+ const c1 = this.c;
2675
+ const tx1 = this.tx;
2676
+ this.a = a1 * cos - this.b * sin;
2677
+ this.b = a1 * sin + this.b * cos;
2678
+ this.c = c1 * cos - this.d * sin;
2679
+ this.d = c1 * sin + this.d * cos;
2680
+ this.tx = tx1 * cos - this.ty * sin;
2681
+ this.ty = tx1 * sin + this.ty * cos;
2682
+ return this;
2683
+ }
2684
+ rotate3d(x, y, z, rad) {
2685
+ const [rx, ry, rz] = this._rotate3d(x, y, z, rad);
2686
+ rx && this.rotateX(rx);
2687
+ ry && this.rotateY(ry);
2688
+ rz && this.rotateZ(rz);
2689
+ return this;
2690
+ }
2691
+ _rotateToScale(rad) {
2692
+ const val = rad / PI_2;
2693
+ return val <= .5 ? val * -4 + 1 : (val - 1) * 4 + 1;
2694
+ }
2695
+ _rotate3d(x, y, z, rad) {
2696
+ if (x === 1 && y === 0 && z === 0) return [
2697
+ rad,
2698
+ 0,
2699
+ 0
2700
+ ];
2701
+ else if (x === 0 && y === 1 && z === 0) return [
2702
+ 0,
2703
+ rad,
2704
+ 0
2705
+ ];
2706
+ else if (x === 0 && y === 0) return [
2707
+ 0,
2708
+ 0,
2709
+ rad
2710
+ ];
2711
+ else {
2712
+ const cos = Math.cos(rad);
2713
+ const sin = Math.sin(rad);
2714
+ const m11 = cos + x * x * (1 - cos);
2715
+ const m12 = x * y * (1 - cos) - z * sin;
2716
+ const m13 = x * z * (1 - cos) + y * sin;
2717
+ const m22 = cos + y * y * (1 - cos);
2718
+ const m23 = y * z * (1 - cos) - x * sin;
2719
+ const m33 = cos + z * z * (1 - cos);
2720
+ return [
2721
+ -Math.atan2(-m23, m22),
2722
+ -Math.atan2(m13, Math.sqrt(m23 * m23 + m33 * m33)),
2723
+ -Math.atan2(-m12, m11)
2724
+ ];
2827
2725
  }
2828
- default:
2829
- console.warn(node);
2830
- break;
2831
2726
  }
2832
- if (_style.display === "none") return paths;
2833
- const currentTransform = new Matrix3();
2834
- const transformStack = [];
2835
- const transform = getNodeTransform(node, currentTransform, transformStack);
2836
- if (path) {
2837
- path.applyTransform(currentTransform);
2838
- paths.push(path);
2839
- path.style = { ..._style };
2727
+ decompose(pivot = {
2728
+ x: 0,
2729
+ y: 0
2730
+ }, output = {
2731
+ position: {
2732
+ x: 0,
2733
+ y: 0
2734
+ },
2735
+ scale: {
2736
+ x: 0,
2737
+ y: 0
2738
+ },
2739
+ skew: {
2740
+ x: 0,
2741
+ y: 0
2742
+ },
2743
+ rotation: 0
2744
+ }) {
2745
+ const { a, b, c, d, tx, ty } = this;
2746
+ const skewX = -Math.atan2(-c, d);
2747
+ const skewY = Math.atan2(b, a);
2748
+ const delta = Math.abs(skewX + skewY);
2749
+ if (delta < 1e-5 || Math.abs(PI_2 - delta) < 1e-5) {
2750
+ output.rotation = skewY;
2751
+ output.skew.x = output.skew.y = 0;
2752
+ } else {
2753
+ output.rotation = 0;
2754
+ output.skew.x = skewX;
2755
+ output.skew.y = skewY;
2756
+ }
2757
+ output.scale.x = Math.sqrt(a * a + b * b);
2758
+ output.scale.y = Math.sqrt(c * c + d * d);
2759
+ output.position.x = tx + (pivot.x * a + pivot.y * c);
2760
+ output.position.y = ty + (pivot.x * b + pivot.y * d);
2761
+ return output;
2762
+ }
2763
+ apply(pos, newPos) {
2764
+ newPos = newPos || new Vector2();
2765
+ const { x, y } = pos;
2766
+ newPos.x = this.a * x + this.c * y + this.tx;
2767
+ newPos.y = this.b * x + this.d * y + this.ty;
2768
+ return newPos;
2769
+ }
2770
+ affineInvert() {
2771
+ const a1 = this.a;
2772
+ const b1 = this.b;
2773
+ const c1 = this.c;
2774
+ const d1 = this.d;
2775
+ const tx1 = this.tx;
2776
+ const n = a1 * d1 - b1 * c1;
2777
+ this.a = d1 / n;
2778
+ this.b = -b1 / n;
2779
+ this.c = -c1 / n;
2780
+ this.d = a1 / n;
2781
+ this.tx = (c1 * this.ty - d1 * tx1) / n;
2782
+ this.ty = -(a1 * this.ty - b1 * tx1) / n;
2783
+ return this;
2784
+ }
2785
+ affineInverse() {
2786
+ return this.clone().affineInvert();
2787
+ }
2788
+ applyAffineInverse(pos, newPos) {
2789
+ newPos = newPos || new Vector2();
2790
+ const { a, b, c, d, tx, ty } = this;
2791
+ const id = 1 / (a * d + c * -b);
2792
+ const x = pos.x;
2793
+ const y = pos.y;
2794
+ newPos.x = d * id * x + -c * id * y + (ty * c - tx * d) * id;
2795
+ newPos.y = a * id * y + -b * id * x + (-ty * a + tx * b) * id;
2796
+ return newPos;
2797
+ }
2798
+ identity() {
2799
+ this.a = 1;
2800
+ this.b = 0;
2801
+ this.c = 0;
2802
+ this.d = 1;
2803
+ this.tx = 0;
2804
+ this.ty = 0;
2805
+ return this;
2806
+ }
2807
+ isIdentity() {
2808
+ const { a, b, c, d, tx, ty } = this;
2809
+ return a === 1 && b === 0 && c === 0 && d === 1 && tx === 0 && ty === 0;
2810
+ }
2811
+ copyTo(t2d) {
2812
+ t2d.a = this.a;
2813
+ t2d.b = this.b;
2814
+ t2d.c = this.c;
2815
+ t2d.d = this.d;
2816
+ t2d.tx = this.tx;
2817
+ t2d.ty = this.ty;
2818
+ return t2d;
2819
+ }
2820
+ copyFrom(t2d) {
2821
+ this.a = t2d.a;
2822
+ this.b = t2d.b;
2823
+ this.c = t2d.c;
2824
+ this.d = t2d.d;
2825
+ this.tx = t2d.tx;
2826
+ this.ty = t2d.ty;
2827
+ return this;
2828
+ }
2829
+ equals(t2d) {
2830
+ return t2d.a === this.a && t2d.b === this.b && t2d.c === this.c && t2d.d === this.d && t2d.tx === this.tx && t2d.ty === this.ty;
2831
+ }
2832
+ prependCssTransform(cssTransform, ctx = {}) {
2833
+ const { width = 1, height = 1 } = ctx;
2834
+ const temp = new Transform2D();
2835
+ parseCssFunctions(cssTransform, {
2836
+ width,
2837
+ height
2838
+ }).reverse().forEach(({ name, args }) => {
2839
+ const values = args.map((arg) => arg.normalizedIntValue);
2840
+ switch (name) {
2841
+ case "translateX":
2842
+ temp.translateX(values[0] * width);
2843
+ break;
2844
+ case "translateY":
2845
+ temp.translateY(values[0] * height);
2846
+ break;
2847
+ case "translateZ":
2848
+ temp.translateZ(values[0]);
2849
+ break;
2850
+ case "translate":
2851
+ temp.translate(values[0] * width, (values[1] ?? values[0]) * height);
2852
+ break;
2853
+ case "translate3d":
2854
+ temp.translate3d(values[0] * width, (values[1] ?? values[0]) * height, values[2] ?? values[1] ?? values[0]);
2855
+ break;
2856
+ case "scaleX":
2857
+ temp.scaleX(values[0]);
2858
+ break;
2859
+ case "scaleY":
2860
+ temp.scaleY(values[0]);
2861
+ break;
2862
+ case "scale":
2863
+ temp.scale(values[0], values[1] ?? values[0]);
2864
+ break;
2865
+ case "scale3d":
2866
+ temp.scale3d(values[0], values[1] ?? values[0], values[2] ?? values[1] ?? values[0]);
2867
+ break;
2868
+ case "rotateX":
2869
+ temp.rotateX(values[0] * PI_2);
2870
+ break;
2871
+ case "rotateY":
2872
+ temp.rotateY(values[0] * PI_2);
2873
+ break;
2874
+ case "rotateZ":
2875
+ temp.rotateZ(values[0] * PI_2);
2876
+ break;
2877
+ case "rotate":
2878
+ temp.rotate(values[0] * PI_2);
2879
+ break;
2880
+ case "rotate3d":
2881
+ temp.rotate3d(values[0] * PI_2, (values[1] ?? values[0]) * PI_2, (values[2] ?? values[1] ?? values[0]) * PI_2, (values[3] ?? values[2] ?? values[1] ?? values[0]) * PI_2);
2882
+ break;
2883
+ case "skewX":
2884
+ temp.skewX(values[0] * PI_2);
2885
+ break;
2886
+ case "skewY":
2887
+ temp.skewY(values[0] * PI_2);
2888
+ break;
2889
+ case "skew":
2890
+ temp.skew(values[0] * PI_2, (values[0] ?? values[1]) * PI_2);
2891
+ break;
2892
+ case "matrix":
2893
+ temp.set(values[0], values[1], values[2], values[3], values[4], values[5]);
2894
+ break;
2895
+ }
2896
+ });
2897
+ this.prepend(temp);
2898
+ return this;
2899
+ }
2900
+ clone() {
2901
+ return new Transform2D(this.a, this.b, this.c, this.d, this.tx, this.ty);
2902
+ }
2903
+ toArray(transpose, out) {
2904
+ if (!this._array) this._array = new Float32Array(9);
2905
+ const array = out || this._array;
2906
+ if (transpose) {
2907
+ array[0] = this.a;
2908
+ array[1] = this.b;
2909
+ array[2] = 0;
2910
+ array[3] = this.c;
2911
+ array[4] = this.d;
2912
+ array[5] = 0;
2913
+ array[6] = this.tx;
2914
+ array[7] = this.ty;
2915
+ array[8] = 1;
2916
+ } else {
2917
+ array[0] = this.a;
2918
+ array[1] = this.c;
2919
+ array[2] = this.tx;
2920
+ array[3] = this.b;
2921
+ array[4] = this.d;
2922
+ array[5] = this.ty;
2923
+ array[6] = 0;
2924
+ array[7] = 0;
2925
+ array[8] = 1;
2926
+ }
2927
+ return array;
2928
+ }
2929
+ toString() {
2930
+ return `[Transform2D a=${this.a} b=${this.b} c=${this.c} d=${this.d} tx=${this.tx} ty=${this.ty}]`;
2840
2931
  }
2841
- const childNodes = node.childNodes;
2842
- for (let i = 0, len = childNodes.length; i < len; i++) {
2843
- const node2 = childNodes[i];
2844
- if (isDefsNode && node2.nodeName !== "style" && node2.nodeName !== "defs") continue;
2845
- parseNode(node2, _style, paths, stylesheets);
2932
+ toJSON() {
2933
+ return {
2934
+ a: this.a,
2935
+ b: this.b,
2936
+ c: this.c,
2937
+ d: this.d,
2938
+ tx: this.tx,
2939
+ ty: this.ty
2940
+ };
2846
2941
  }
2847
- if (transform) {
2848
- transformStack.pop();
2849
- if (transformStack.length > 0) currentTransform.copy(transformStack[transformStack.length - 1]);
2850
- else currentTransform.identity();
2942
+ destroy() {
2943
+ this._array = void 0;
2851
2944
  }
2852
- return paths;
2853
- }
2854
- function svgToPath2DSet(svg) {
2855
- const dom = svgToDom(svg);
2856
- return new Path2DSet(parseNode(dom, {}), dom.getAttribute("viewBox")?.trim().split(" ").map((v) => Number(v)));
2857
- }
2858
- function catmullRom(t, p0, p1, p2, p3) {
2859
- const v0 = (p2 - p0) * .5;
2860
- const v1 = (p3 - p1) * .5;
2861
- const t2 = t * t;
2862
- const t3 = t * t2;
2863
- return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
2864
- }
2865
- function cubicBezierP0(t, p) {
2866
- const k = 1 - t;
2867
- return k * k * k * p;
2868
- }
2869
- function cubicBezierP1(t, p) {
2870
- const k = 1 - t;
2871
- return 3 * k * k * t * p;
2945
+ };
2946
+ function svgAngle(ux, uy, vx, vy) {
2947
+ const dot = ux * vx + uy * vy;
2948
+ const len = Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
2949
+ let ang = Math.acos(Math.max(-1, Math.min(1, dot / len)));
2950
+ if (ux * vy - uy * vx < 0) ang = -ang;
2951
+ return ang;
2872
2952
  }
2873
- function cubicBezierP2(t, p) {
2874
- return 3 * (1 - t) * t * t * p;
2953
+ function parseArcCommand(path, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, start, end) {
2954
+ if (rx === 0 || ry === 0) {
2955
+ path.lineTo(end.x, end.y);
2956
+ return;
2957
+ }
2958
+ xAxisRotation = xAxisRotation * Math.PI / 180;
2959
+ rx = Math.abs(rx);
2960
+ ry = Math.abs(ry);
2961
+ const dx2 = (start.x - end.x) / 2;
2962
+ const dy2 = (start.y - end.y) / 2;
2963
+ const x1p = Math.cos(xAxisRotation) * dx2 + Math.sin(xAxisRotation) * dy2;
2964
+ const y1p = -Math.sin(xAxisRotation) * dx2 + Math.cos(xAxisRotation) * dy2;
2965
+ let rxs = rx * rx;
2966
+ let rys = ry * ry;
2967
+ const x1ps = x1p * x1p;
2968
+ const y1ps = y1p * y1p;
2969
+ const cr = x1ps / rxs + y1ps / rys;
2970
+ if (cr > 1) {
2971
+ const s = Math.sqrt(cr);
2972
+ rx = s * rx;
2973
+ ry = s * ry;
2974
+ rxs = rx * rx;
2975
+ rys = ry * ry;
2976
+ }
2977
+ const dq = rxs * y1ps + rys * x1ps;
2978
+ const pq = (rxs * rys - dq) / dq;
2979
+ let q = Math.sqrt(Math.max(0, pq));
2980
+ if (largeArcFlag === sweepFlag) q = -q;
2981
+ const cxp = q * rx * y1p / ry;
2982
+ const cyp = -q * ry * x1p / rx;
2983
+ const cx = Math.cos(xAxisRotation) * cxp - Math.sin(xAxisRotation) * cyp + (start.x + end.x) / 2;
2984
+ const cy = Math.sin(xAxisRotation) * cxp + Math.cos(xAxisRotation) * cyp + (start.y + end.y) / 2;
2985
+ const theta = svgAngle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
2986
+ const delta = svgAngle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry) % (Math.PI * 2);
2987
+ path.ellipse(cx, cy, rx, ry, xAxisRotation, theta, theta + delta, sweepFlag === 0);
2875
2988
  }
2876
- function cubicBezierP3(t, p) {
2877
- return t * t * t * p;
2989
+ var RE$3 = {
2990
+ WHITESPACE: /[ \t\r\n]/,
2991
+ DIGIT: /\d/,
2992
+ SIGN: /[-+]/,
2993
+ POINT: /\./,
2994
+ COMMA: /,/,
2995
+ EXP: /e/i,
2996
+ FLAGS: /[01]/
2997
+ };
2998
+ function parsePathDataArgs(input, flags, stride = 0) {
2999
+ const SEP = 0;
3000
+ const INT = 1;
3001
+ const FLOAT = 2;
3002
+ const EXP = 3;
3003
+ let state = SEP;
3004
+ let seenComma = true;
3005
+ let number = "";
3006
+ let exponent = "";
3007
+ const result = [];
3008
+ function throwSyntaxError(current2, i, partial) {
3009
+ const error = /* @__PURE__ */ new SyntaxError(`Unexpected character "${current2}" at index ${i}.`);
3010
+ error.partial = partial;
3011
+ throw error;
3012
+ }
3013
+ function newNumber() {
3014
+ if (number !== "") if (exponent === "") result.push(Number(number));
3015
+ else result.push(Number(number) * 10 ** Number(exponent));
3016
+ number = "";
3017
+ exponent = "";
3018
+ }
3019
+ let current;
3020
+ const length = input.length;
3021
+ for (let i = 0; i < length; i++) {
3022
+ current = input[i];
3023
+ if (Array.isArray(flags) && flags.includes(result.length % stride) && RE$3.FLAGS.test(current)) {
3024
+ state = INT;
3025
+ number = current;
3026
+ newNumber();
3027
+ continue;
3028
+ }
3029
+ if (state === SEP) {
3030
+ if (RE$3.WHITESPACE.test(current)) continue;
3031
+ if (RE$3.DIGIT.test(current) || RE$3.SIGN.test(current)) {
3032
+ state = INT;
3033
+ number = current;
3034
+ continue;
3035
+ }
3036
+ if (RE$3.POINT.test(current)) {
3037
+ state = FLOAT;
3038
+ number = current;
3039
+ continue;
3040
+ }
3041
+ if (RE$3.COMMA.test(current)) {
3042
+ if (seenComma) throwSyntaxError(current, i, result);
3043
+ seenComma = true;
3044
+ }
3045
+ }
3046
+ if (state === INT) {
3047
+ if (RE$3.DIGIT.test(current)) {
3048
+ number += current;
3049
+ continue;
3050
+ }
3051
+ if (RE$3.POINT.test(current)) {
3052
+ number += current;
3053
+ state = FLOAT;
3054
+ continue;
3055
+ }
3056
+ if (RE$3.EXP.test(current)) {
3057
+ state = EXP;
3058
+ continue;
3059
+ }
3060
+ if (RE$3.SIGN.test(current) && number.length === 1 && RE$3.SIGN.test(number[0])) throwSyntaxError(current, i, result);
3061
+ }
3062
+ if (state === FLOAT) {
3063
+ if (RE$3.DIGIT.test(current)) {
3064
+ number += current;
3065
+ continue;
3066
+ }
3067
+ if (RE$3.EXP.test(current)) {
3068
+ state = EXP;
3069
+ continue;
3070
+ }
3071
+ if (RE$3.POINT.test(current) && number[number.length - 1] === ".") throwSyntaxError(current, i, result);
3072
+ }
3073
+ if (state === EXP) {
3074
+ if (RE$3.DIGIT.test(current)) {
3075
+ exponent += current;
3076
+ continue;
3077
+ }
3078
+ if (RE$3.SIGN.test(current)) {
3079
+ if (exponent === "") {
3080
+ exponent += current;
3081
+ continue;
3082
+ }
3083
+ if (exponent.length === 1 && RE$3.SIGN.test(exponent)) throwSyntaxError(current, i, result);
3084
+ }
3085
+ }
3086
+ if (RE$3.WHITESPACE.test(current)) {
3087
+ newNumber();
3088
+ state = SEP;
3089
+ seenComma = false;
3090
+ } else if (RE$3.COMMA.test(current)) {
3091
+ newNumber();
3092
+ state = SEP;
3093
+ seenComma = true;
3094
+ } else if (RE$3.SIGN.test(current)) {
3095
+ newNumber();
3096
+ state = INT;
3097
+ number = current;
3098
+ } else if (RE$3.POINT.test(current)) {
3099
+ newNumber();
3100
+ state = FLOAT;
3101
+ number = current;
3102
+ } else throwSyntaxError(current, i, result);
3103
+ }
3104
+ newNumber();
3105
+ return result;
2878
3106
  }
2879
- function cubicBezier(t, p0, p1, p2, p3) {
2880
- return cubicBezierP0(t, p0) + cubicBezierP1(t, p1) + cubicBezierP2(t, p2) + cubicBezierP3(t, p3);
3107
+ function getReflection(a, b) {
3108
+ return a - (b - a);
2881
3109
  }
2882
- function fillTriangulate(pointArray, options = {}) {
2883
- let { vertices = [], indices = [], holes = [], verticesStride = 2, verticesOffset = vertices.length / verticesStride, indicesOffset = indices.length } = options;
2884
- const triangles = earcut(pointArray, holes, 2);
2885
- if (triangles.length) {
2886
- for (let i = 0; i < triangles.length; i += 3) {
2887
- indices[indicesOffset++] = triangles[i] + verticesOffset;
2888
- indices[indicesOffset++] = triangles[i + 1] + verticesOffset;
2889
- indices[indicesOffset++] = triangles[i + 2] + verticesOffset;
3110
+ function svgPathCommandsAddToPath2D(commands, path) {
3111
+ const current = new Vector2();
3112
+ const control = new Vector2();
3113
+ for (let i = 0, l = commands.length; i < l; i++) {
3114
+ const cmd = commands[i];
3115
+ if (cmd.type === "m" || cmd.type === "M") {
3116
+ if (cmd.type === "m") current.add(cmd);
3117
+ else current.copyFrom(cmd);
3118
+ path.moveTo(current.x, current.y);
3119
+ control.copyFrom(current);
3120
+ } else if (cmd.type === "h" || cmd.type === "H") {
3121
+ if (cmd.type === "h") current.x += cmd.x;
3122
+ else current.x = cmd.x;
3123
+ path.lineTo(current.x, current.y);
3124
+ control.copyFrom(current);
3125
+ } else if (cmd.type === "v" || cmd.type === "V") {
3126
+ if (cmd.type === "v") current.y += cmd.y;
3127
+ else current.y = cmd.y;
3128
+ path.lineTo(current.x, current.y);
3129
+ control.copyFrom(current);
3130
+ } else if (cmd.type === "l" || cmd.type === "L") {
3131
+ if (cmd.type === "l") current.add(cmd);
3132
+ else current.copyFrom(cmd);
3133
+ path.lineTo(current.x, current.y);
3134
+ control.copyFrom(current);
3135
+ } else if (cmd.type === "c" || cmd.type === "C") if (cmd.type === "c") {
3136
+ path.bezierCurveTo(current.x + cmd.x1, current.y + cmd.y1, current.x + cmd.x2, current.y + cmd.y2, current.x + cmd.x, current.y + cmd.y);
3137
+ control.x = current.x + cmd.x2;
3138
+ control.y = current.y + cmd.y2;
3139
+ current.add(cmd);
3140
+ } else {
3141
+ path.bezierCurveTo(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
3142
+ control.x = cmd.x2;
3143
+ control.y = cmd.y2;
3144
+ current.copyFrom(cmd);
2890
3145
  }
2891
- let index = verticesOffset * verticesStride;
2892
- for (let i = 0; i < pointArray.length; i += 2) {
2893
- vertices[index] = pointArray[i];
2894
- vertices[index + 1] = pointArray[i + 1];
2895
- index += verticesStride;
3146
+ else if (cmd.type === "s" || cmd.type === "S") if (cmd.type === "s") {
3147
+ path.bezierCurveTo(getReflection(current.x, control.x), getReflection(current.y, control.y), current.x + cmd.x2, current.y + cmd.y2, current.x + cmd.x, current.y + cmd.y);
3148
+ control.x = current.x + cmd.x2;
3149
+ control.y = current.y + cmd.y2;
3150
+ current.add(cmd);
3151
+ } else {
3152
+ path.bezierCurveTo(getReflection(current.x, control.x), getReflection(current.y, control.y), cmd.x2, cmd.y2, cmd.x, cmd.y);
3153
+ control.x = cmd.x2;
3154
+ control.y = cmd.y2;
3155
+ current.copyFrom(cmd);
2896
3156
  }
2897
- }
2898
- return {
2899
- vertices,
2900
- indices
2901
- };
2902
- }
2903
- var RECURSION_LIMIT$1 = 8;
2904
- var FLT_EPSILON$1 = 1.1920929e-7;
2905
- var PATH_DISTANCE_EPSILON$1 = 1;
2906
- function getAdaptiveCubicBezierCurvePoints(sX, sY, x1, y1, x2, y2, x, y, smoothness = .5, points = []) {
2907
- let distanceTolerance = (PATH_DISTANCE_EPSILON$1 - Math.min(.99, Math.max(0, smoothness))) / 1;
2908
- distanceTolerance *= distanceTolerance;
2909
- recursive$1(sX, sY, x1, y1, x2, y2, x, y, points, distanceTolerance, 0);
2910
- points.push(x, y);
2911
- return points;
2912
- }
2913
- function recursive$1(x1, y1, x2, y2, x3, y3, x4, y4, points, distanceTolerance, level) {
2914
- if (level > RECURSION_LIMIT$1) return;
2915
- const x12 = (x1 + x2) / 2;
2916
- const y12 = (y1 + y2) / 2;
2917
- const x23 = (x2 + x3) / 2;
2918
- const y23 = (y2 + y3) / 2;
2919
- const x34 = (x3 + x4) / 2;
2920
- const y34 = (y3 + y4) / 2;
2921
- const x123 = (x12 + x23) / 2;
2922
- const y123 = (y12 + y23) / 2;
2923
- const x234 = (x23 + x34) / 2;
2924
- const y234 = (y23 + y34) / 2;
2925
- const x1234 = (x123 + x234) / 2;
2926
- const y1234 = (y123 + y234) / 2;
2927
- if (level > 0) {
2928
- let dx = x4 - x1;
2929
- let dy = y4 - y1;
2930
- const d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx);
2931
- const d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx);
2932
- if (d2 > FLT_EPSILON$1 && d3 > FLT_EPSILON$1) {
2933
- if ((d2 + d3) * (d2 + d3) <= distanceTolerance * (dx * dx + dy * dy)) {
2934
- points.push(x1234, y1234);
2935
- return;
2936
- }
2937
- } else if (d2 > FLT_EPSILON$1) {
2938
- if (d2 * d2 <= distanceTolerance * (dx * dx + dy * dy)) {
2939
- points.push(x1234, y1234);
2940
- return;
2941
- }
2942
- } else if (d3 > FLT_EPSILON$1) {
2943
- if (d3 * d3 <= distanceTolerance * (dx * dx + dy * dy)) {
2944
- points.push(x1234, y1234);
2945
- return;
2946
- }
3157
+ else if (cmd.type === "q" || cmd.type === "Q") if (cmd.type === "q") {
3158
+ path.quadraticCurveTo(current.x + cmd.x1, current.y + cmd.y1, current.x + cmd.x, current.y + cmd.y);
3159
+ control.x = current.x + cmd.x1;
3160
+ control.y = current.y + cmd.y1;
3161
+ current.add(cmd);
2947
3162
  } else {
2948
- dx = x1234 - (x1 + x4) / 2;
2949
- dy = y1234 - (y1 + y4) / 2;
2950
- if (dx * dx + dy * dy <= distanceTolerance) {
2951
- points.push(x1234, y1234);
2952
- return;
2953
- }
3163
+ path.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
3164
+ control.x = cmd.x1;
3165
+ control.y = cmd.y1;
3166
+ current.copyFrom(cmd);
2954
3167
  }
3168
+ else if (cmd.type === "t" || cmd.type === "T") {
3169
+ const rx = getReflection(current.x, control.x);
3170
+ const ry = getReflection(current.y, control.y);
3171
+ control.x = rx;
3172
+ control.y = ry;
3173
+ if (cmd.type === "t") {
3174
+ path.quadraticCurveTo(rx, ry, current.x + cmd.x, current.y + cmd.y);
3175
+ current.add(cmd);
3176
+ } else {
3177
+ path.quadraticCurveTo(rx, ry, cmd.x, cmd.y);
3178
+ current.copyFrom(cmd);
3179
+ }
3180
+ } else if (cmd.type === "a" || cmd.type === "A") {
3181
+ const start = current.clone();
3182
+ if (cmd.type === "a") {
3183
+ if (cmd.x === 0 && cmd.y === 0) continue;
3184
+ current.add(cmd);
3185
+ } else {
3186
+ if (current.equals(cmd)) continue;
3187
+ current.copyFrom(cmd);
3188
+ }
3189
+ control.copyFrom(current);
3190
+ parseArcCommand(path, cmd.rx, cmd.ry, cmd.angle, cmd.largeArcFlag, cmd.sweepFlag, start, current);
3191
+ } else if (cmd.type === "z" || cmd.type === "Z") {
3192
+ if (path.startPoint) current.copyFrom(path.startPoint);
3193
+ path.closePath();
3194
+ } else console.warn("Unsupported commands", cmd);
2955
3195
  }
2956
- recursive$1(x1, y1, x12, y12, x123, y123, x1234, y1234, points, distanceTolerance, level + 1);
2957
- recursive$1(x1234, y1234, x234, y234, x34, y34, x4, y4, points, distanceTolerance, level + 1);
2958
- }
2959
- var RECURSION_LIMIT = 8;
2960
- var FLT_EPSILON = 1.1920929e-7;
2961
- var PATH_DISTANCE_EPSILON = 1;
2962
- function getAdaptiveQuadraticBezierCurvePoints(sX, sY, x1, y1, x, y, smoothness = .5, points = []) {
2963
- let distanceTolerance = (PATH_DISTANCE_EPSILON - Math.min(.99, Math.max(0, smoothness))) / 1;
2964
- distanceTolerance *= distanceTolerance;
2965
- recursive(points, sX, sY, x1, y1, x, y, distanceTolerance, 0);
2966
- points.push(x, y);
2967
- return points;
2968
3196
  }
2969
- function recursive(points, x1, y1, x2, y2, x3, y3, distanceTolerance, level) {
2970
- if (level > RECURSION_LIMIT) return;
2971
- const x12 = (x1 + x2) / 2;
2972
- const y12 = (y1 + y2) / 2;
2973
- const x23 = (x2 + x3) / 2;
2974
- const y23 = (y2 + y3) / 2;
2975
- const x123 = (x12 + x23) / 2;
2976
- const y123 = (y12 + y23) / 2;
2977
- let dx = x3 - x1;
2978
- let dy = y3 - y1;
2979
- const d = Math.abs((x2 - x3) * dy - (y2 - y3) * dx);
2980
- if (d > FLT_EPSILON) {
2981
- if (d * d <= distanceTolerance * (dx * dx + dy * dy)) {
2982
- points.push(x123, y123);
2983
- return;
3197
+ function svgPathCommandsToData(commands) {
3198
+ let first;
3199
+ let prev;
3200
+ const data = [];
3201
+ for (let i = 0, len = commands.length; i < len; i++) {
3202
+ const cmd = commands[i];
3203
+ switch (cmd.type) {
3204
+ case "m":
3205
+ case "M":
3206
+ if (cmd.x.toFixed(4) === prev?.x.toFixed(4) && cmd.y.toFixed(4) === prev?.y.toFixed(4)) continue;
3207
+ data.push(`${cmd.type} ${cmd.x} ${cmd.y}`);
3208
+ prev = {
3209
+ x: cmd.x,
3210
+ y: cmd.y
3211
+ };
3212
+ first = {
3213
+ x: cmd.x,
3214
+ y: cmd.y
3215
+ };
3216
+ break;
3217
+ case "h":
3218
+ case "H":
3219
+ data.push(`${cmd.type} ${cmd.x}`);
3220
+ prev = {
3221
+ x: cmd.x,
3222
+ y: prev?.y ?? 0
3223
+ };
3224
+ break;
3225
+ case "v":
3226
+ case "V":
3227
+ data.push(`${cmd.type} ${cmd.y}`);
3228
+ prev = {
3229
+ x: prev?.x ?? 0,
3230
+ y: cmd.y
3231
+ };
3232
+ break;
3233
+ case "l":
3234
+ case "L":
3235
+ data.push(`${cmd.type} ${cmd.x} ${cmd.y}`);
3236
+ prev = {
3237
+ x: cmd.x,
3238
+ y: cmd.y
3239
+ };
3240
+ break;
3241
+ case "c":
3242
+ case "C":
3243
+ data.push(`${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`);
3244
+ prev = {
3245
+ x: cmd.x,
3246
+ y: cmd.y
3247
+ };
3248
+ break;
3249
+ case "s":
3250
+ case "S":
3251
+ data.push(`${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`);
3252
+ prev = {
3253
+ x: cmd.x,
3254
+ y: cmd.y
3255
+ };
3256
+ break;
3257
+ case "q":
3258
+ case "Q":
3259
+ data.push(`${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`);
3260
+ prev = {
3261
+ x: cmd.x,
3262
+ y: cmd.y
3263
+ };
3264
+ break;
3265
+ case "t":
3266
+ case "T":
3267
+ data.push(`${cmd.type} ${cmd.x} ${cmd.y}`);
3268
+ prev = {
3269
+ x: cmd.x,
3270
+ y: cmd.y
3271
+ };
3272
+ break;
3273
+ case "a":
3274
+ case "A":
3275
+ data.push(`${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`);
3276
+ prev = {
3277
+ x: cmd.x,
3278
+ y: cmd.y
3279
+ };
3280
+ break;
3281
+ case "z":
3282
+ case "Z":
3283
+ data.push(cmd.type);
3284
+ if (first) prev = {
3285
+ x: first.x,
3286
+ y: first.y
3287
+ };
3288
+ break;
2984
3289
  }
2985
- } else {
2986
- dx = x123 - (x1 + x3) / 2;
2987
- dy = y123 - (y1 + y3) / 2;
2988
- if (dx * dx + dy * dy <= distanceTolerance) {
2989
- points.push(x123, y123);
2990
- return;
3290
+ }
3291
+ return data.join(" ");
3292
+ }
3293
+ var RE$2 = /[a-df-z][^a-df-z]*/gi;
3294
+ function svgPathDataToCommands(data) {
3295
+ const commands = [];
3296
+ const matched = data.match(RE$2);
3297
+ if (!matched) return commands;
3298
+ for (let i = 0, len = matched.length; i < len; i++) {
3299
+ const command = matched[i];
3300
+ const type = command.charAt(0);
3301
+ const data2 = command.slice(1).trim();
3302
+ let args;
3303
+ switch (type) {
3304
+ case "m":
3305
+ case "M":
3306
+ args = parsePathDataArgs(data2);
3307
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) if (i2 === 0) commands.push({
3308
+ type,
3309
+ x: args[i2],
3310
+ y: args[i2 + 1]
3311
+ });
3312
+ else commands.push({
3313
+ type: type === "m" ? "l" : "L",
3314
+ x: args[i2],
3315
+ y: args[i2 + 1]
3316
+ });
3317
+ break;
3318
+ case "h":
3319
+ case "H":
3320
+ args = parsePathDataArgs(data2);
3321
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2++) commands.push({
3322
+ type,
3323
+ x: args[i2]
3324
+ });
3325
+ break;
3326
+ case "v":
3327
+ case "V":
3328
+ args = parsePathDataArgs(data2);
3329
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2++) commands.push({
3330
+ type,
3331
+ y: args[i2]
3332
+ });
3333
+ break;
3334
+ case "l":
3335
+ case "L":
3336
+ args = parsePathDataArgs(data2);
3337
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) commands.push({
3338
+ type,
3339
+ x: args[i2],
3340
+ y: args[i2 + 1]
3341
+ });
3342
+ break;
3343
+ case "c":
3344
+ case "C":
3345
+ args = parsePathDataArgs(data2);
3346
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 6) commands.push({
3347
+ type,
3348
+ x1: args[i2],
3349
+ y1: args[i2 + 1],
3350
+ x2: args[i2 + 2],
3351
+ y2: args[i2 + 3],
3352
+ x: args[i2 + 4],
3353
+ y: args[i2 + 5]
3354
+ });
3355
+ break;
3356
+ case "s":
3357
+ case "S":
3358
+ args = parsePathDataArgs(data2);
3359
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 4) commands.push({
3360
+ type,
3361
+ x2: args[i2],
3362
+ y2: args[i2 + 1],
3363
+ x: args[i2 + 2],
3364
+ y: args[i2 + 3]
3365
+ });
3366
+ break;
3367
+ case "q":
3368
+ case "Q":
3369
+ args = parsePathDataArgs(data2);
3370
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 4) commands.push({
3371
+ type,
3372
+ x1: args[i2],
3373
+ y1: args[i2 + 1],
3374
+ x: args[i2 + 2],
3375
+ y: args[i2 + 3]
3376
+ });
3377
+ break;
3378
+ case "t":
3379
+ case "T":
3380
+ args = parsePathDataArgs(data2);
3381
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) commands.push({
3382
+ type,
3383
+ x: args[i2],
3384
+ y: args[i2 + 1]
3385
+ });
3386
+ break;
3387
+ case "a":
3388
+ case "A":
3389
+ args = parsePathDataArgs(data2, [3, 4], 7);
3390
+ for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 7) commands.push({
3391
+ type,
3392
+ rx: args[i2],
3393
+ ry: args[i2 + 1],
3394
+ angle: args[i2 + 2],
3395
+ largeArcFlag: args[i2 + 3],
3396
+ sweepFlag: args[i2 + 4],
3397
+ x: args[i2 + 5],
3398
+ y: args[i2 + 6]
3399
+ });
3400
+ break;
3401
+ case "z":
3402
+ case "Z":
3403
+ commands.push({ type });
3404
+ break;
3405
+ default: console.warn(command);
2991
3406
  }
2992
3407
  }
2993
- recursive(points, x1, y1, x12, y12, x123, y123, distanceTolerance, level + 1);
2994
- recursive(points, x123, y123, x23, y23, x3, y3, distanceTolerance, level + 1);
2995
- }
2996
- function toKebabCase(str) {
2997
- return str.replace(/[^a-z0-9]/gi, "-").replace(/\B([A-Z])/g, "-$1").toLowerCase();
2998
- }
2999
- function getIntersectionPoint(p1, p2, q1, q2) {
3000
- const r = p2.clone().sub(p1);
3001
- const s = q2.clone().sub(q1);
3002
- const q1p1 = q1.clone().sub(p1);
3003
- const crossRS = r.cross(s);
3004
- if (crossRS === 0) return new Vector2((p1.x + q1.x) / 2, (p1.y + q1.y) / 2);
3005
- const t = q1p1.cross(s) / crossRS;
3006
- if (Math.abs(t) > 1) return new Vector2((p1.x + q1.x) / 2, (p1.y + q1.y) / 2);
3007
- return new Vector2(p1.x + t * r.x, p1.y + t * r.y);
3008
- }
3009
- function cross(ax, ay, bx, by, cx, cy) {
3010
- return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
3011
- }
3012
- function windingNumber(px, py, polygon) {
3013
- const polygonLen = polygon.length;
3014
- let wn = 0;
3015
- for (let i = 0, j = polygonLen - 2; i < polygonLen; j = i, i += 2) {
3016
- const xi = polygon[i];
3017
- const yi = polygon[i + 1];
3018
- const xj = polygon[j];
3019
- const yj = polygon[j + 1];
3020
- if (yi <= py) {
3021
- if (yj > py && cross(xj, yj, xi, yi, px, py) > 0) wn++;
3022
- } else if (yj <= py && cross(xj, yj, xi, yi, px, py) < 0) wn--;
3023
- }
3024
- return wn;
3408
+ return commands;
3025
3409
  }
3026
- function distance(p1, p2) {
3027
- const dx = p2[0] - p1[0];
3028
- const dy = p2[1] - p1[1];
3029
- return Math.sqrt(dx * dx + dy * dy);
3410
+ var dataUri = "data:image/svg+xml;";
3411
+ var base64DataUri = `${dataUri}base64,`;
3412
+ var utf8DataUri = `${dataUri}charset=utf8,`;
3413
+ function svgToDom(svg) {
3414
+ if (typeof svg === "string") {
3415
+ let xml;
3416
+ if (svg.startsWith(base64DataUri)) {
3417
+ svg = svg.substring(base64DataUri.length, svg.length);
3418
+ xml = atob(svg);
3419
+ } else if (svg.startsWith(utf8DataUri)) {
3420
+ svg = svg.substring(utf8DataUri.length, svg.length);
3421
+ xml = decodeURIComponent(svg);
3422
+ } else xml = svg;
3423
+ const doc = new DOMParser().parseFromString(xml, "text/xml");
3424
+ const error = doc.querySelector("parsererror");
3425
+ if (error) throw new Error(`${error.textContent ?? "parser error"}
3426
+ ${xml}`);
3427
+ return doc.documentElement;
3428
+ } else return svg;
3030
3429
  }
3031
- function nonzeroFillRule(paths) {
3032
- const results = paths.map((_, i) => ({ index: i }));
3033
- const testPointsGroups = paths.map((path) => {
3034
- const len = path.length;
3035
- if (!len) return [];
3036
- let xMinYAuto = [Number.MAX_SAFE_INTEGER, 0];
3037
- let xAutoYMin = [0, Number.MAX_SAFE_INTEGER];
3038
- let xMaxYAuto = [Number.MIN_SAFE_INTEGER, 0];
3039
- let xAutoYMax = [0, Number.MIN_SAFE_INTEGER];
3040
- for (let i = 0; i < len; i += 2) {
3041
- const x = path[i];
3042
- const y = path[i + 1];
3043
- if (xMinYAuto[0] > x) xMinYAuto = [x, y];
3044
- if (xAutoYMin[1] > y) xAutoYMin = [x, y];
3045
- if (xMaxYAuto[0] < x) xMaxYAuto = [x, y];
3046
- if (xAutoYMax[1] < y) xAutoYMax = [x, y];
3047
- }
3048
- const mid = [(xMinYAuto[0] + xMaxYAuto[0]) / 2, (xAutoYMin[1] + xAutoYMax[1]) / 2];
3049
- let xMidYMinDx;
3050
- let xMidYMaxDx;
3051
- let xMidYMin;
3052
- let xMidYMax;
3053
- let xMinYMidDy;
3054
- let xMaxYMidDy;
3055
- let xMinYMid;
3056
- let xMaxYMid;
3057
- for (let i = 0; i < len; i += 2) {
3058
- const x = path[i];
3059
- const y = path[i + 1];
3060
- const _dx = Math.abs(x - mid[0]);
3061
- const _dy = Math.abs(y - mid[1]);
3062
- if (y < mid[1] && (!xMidYMinDx || _dx < xMidYMinDx)) {
3063
- xMidYMinDx = _dx;
3064
- xMidYMin = [x, y];
3065
- }
3066
- if (y > mid[1] && (!xMidYMaxDx || _dx < xMidYMaxDx)) {
3067
- xMidYMaxDx = _dx;
3068
- xMidYMax = [x, y];
3069
- }
3070
- if (x < mid[0] && (!xMinYMidDy || _dy < xMinYMidDy)) {
3071
- xMinYMidDy = _dy;
3072
- xMinYMid = [x, y];
3073
- }
3074
- if (x > mid[0] && (!xMaxYMidDy || _dy < xMaxYMidDy)) {
3075
- xMaxYMidDy = _dy;
3076
- xMaxYMid = [x, y];
3077
- }
3078
- }
3079
- return [
3080
- xMinYAuto,
3081
- xAutoYMin,
3082
- xMaxYAuto,
3083
- xAutoYMax,
3084
- xMidYMin,
3085
- xMidYMax,
3086
- xMinYMid,
3087
- xMaxYMid
3088
- ].filter(Boolean);
3089
- });
3090
- for (let i = 0, len = paths.length; i < len; i++) {
3091
- const _results = [];
3092
- const testPoints = testPointsGroups[i];
3093
- for (let j = 0; j < len; j++) {
3094
- if (i === j) continue;
3095
- const wnMap = {};
3096
- const wnList = [];
3097
- for (let p = 0, pLen = testPoints.length; p < pLen; p++) {
3098
- const [x, y] = testPoints[p];
3099
- const winding = windingNumber(x, y, paths[j]);
3100
- wnMap[winding] = (wnMap[winding] ?? 0) + 1;
3101
- wnList.push(winding);
3102
- }
3103
- if (wnList.filter((v) => v !== 0).length > wnList.filter((v) => v === 0).length) _results.push({
3104
- index: i,
3105
- parentIndex: j,
3106
- winding: Number(Array.from(Object.entries(wnMap)).sort((a, b) => b[1] - a[1])?.[0]?.[0] ?? 0),
3107
- dist: distance(testPointsGroups[i][0], testPointsGroups[j][0])
3108
- });
3109
- }
3110
- if (_results.reduce((total, item) => total + item.winding, 0) !== 0) {
3111
- _results.sort((a, b) => a.dist - b.dist);
3112
- results[i] = _results[0];
3430
+ var defaultUnit = "px";
3431
+ var defaultDPI = 90;
3432
+ var units = [
3433
+ "mm",
3434
+ "cm",
3435
+ "in",
3436
+ "pt",
3437
+ "pc",
3438
+ "px"
3439
+ ];
3440
+ var unitConversion = {
3441
+ mm: {
3442
+ mm: 1,
3443
+ cm: .1,
3444
+ in: 1 / 25.4,
3445
+ pt: 72 / 25.4,
3446
+ pc: 6 / 25.4,
3447
+ px: -1
3448
+ },
3449
+ cm: {
3450
+ mm: 10,
3451
+ cm: 1,
3452
+ in: 1 / 2.54,
3453
+ pt: 72 / 2.54,
3454
+ pc: 6 / 2.54,
3455
+ px: -1
3456
+ },
3457
+ in: {
3458
+ mm: 25.4,
3459
+ cm: 2.54,
3460
+ in: 1,
3461
+ pt: 72,
3462
+ pc: 6,
3463
+ px: -1
3464
+ },
3465
+ pt: {
3466
+ mm: 25.4 / 72,
3467
+ cm: 2.54 / 72,
3468
+ in: 1 / 72,
3469
+ pt: 1,
3470
+ pc: 6 / 72,
3471
+ px: -1
3472
+ },
3473
+ pc: {
3474
+ mm: 25.4 / 6,
3475
+ cm: 2.54 / 6,
3476
+ in: 1 / 6,
3477
+ pt: 72 / 6,
3478
+ pc: 1,
3479
+ px: -1
3480
+ },
3481
+ px: { px: 1 }
3482
+ };
3483
+ function parseFloatWithUnits(string) {
3484
+ let theUnit = "px";
3485
+ if (typeof string === "string") for (let i = 0, n = units.length; i < n; i++) {
3486
+ const u = units[i];
3487
+ if (string.endsWith(u)) {
3488
+ theUnit = u;
3489
+ string = string.substring(0, string.length - u.length);
3490
+ break;
3113
3491
  }
3114
3492
  }
3115
- return results;
3116
- }
3117
- function quadraticBezierP0(t, p) {
3118
- const k = 1 - t;
3119
- return k * k * p;
3493
+ let scale;
3494
+ scale = unitConversion[theUnit][defaultUnit];
3495
+ if (scale < 0) scale = unitConversion[theUnit].in * defaultDPI;
3496
+ return scale * Number.parseFloat(string);
3120
3497
  }
3121
- function quadraticBezierP1(t, p) {
3122
- return 2 * (1 - t) * t * p;
3498
+ function getNodeTransform(node, currentTransform, transformStack) {
3499
+ if (!(node.hasAttribute("transform") || node.nodeName === "use" && (node.hasAttribute("x") || node.hasAttribute("y")))) return null;
3500
+ const transform = parseNodeTransform(node);
3501
+ if (transformStack.length > 0) transform.prepend(transformStack[transformStack.length - 1]);
3502
+ currentTransform.copyFrom(transform);
3503
+ transformStack.push(transform);
3504
+ return transform;
3123
3505
  }
3124
- function quadraticBezierP2(t, p) {
3125
- return t * t * p;
3506
+ function parseNodeTransform(node) {
3507
+ const transform = new Transform2D();
3508
+ if (node.nodeName === "use" && (node.hasAttribute("x") || node.hasAttribute("y"))) transform.translate(parseFloatWithUnits(node.getAttribute("x")), parseFloatWithUnits(node.getAttribute("y")));
3509
+ if (node.hasAttribute("transform")) transform.prependCssTransform(node.getAttribute("transform"));
3510
+ return transform;
3126
3511
  }
3127
- function quadraticBezier(t, p0, p1, p2) {
3128
- return quadraticBezierP0(t, p0) + quadraticBezierP1(t, p1) + quadraticBezierP2(t, p2);
3512
+ function parseCircleNode(node) {
3513
+ return new Path2D().arc(parseFloatWithUnits(node.getAttribute("cx") || 0), parseFloatWithUnits(node.getAttribute("cy") || 0), parseFloatWithUnits(node.getAttribute("r") || 0), 0, Math.PI * 2);
3129
3514
  }
3130
- var closePointEps = 1e-4;
3131
- var curveEps = 1e-4;
3132
- function strokeTriangulate(points, options = {}) {
3133
- const { vertices = [], indices = [], lineStyle = {
3134
- alignment: .5,
3135
- cap: "butt",
3136
- join: "miter",
3137
- width: 1,
3138
- miterLimit: 10
3139
- }, flipAlignment = false, closed = true } = options;
3140
- const eps = closePointEps;
3141
- if (points.length === 0) return {
3142
- vertices,
3143
- indices
3144
- };
3145
- const style = lineStyle;
3146
- let alignment = style.alignment;
3147
- if (lineStyle.alignment !== .5) {
3148
- let orientation = getOrientationOfPoints(points);
3149
- if (flipAlignment) orientation *= -1;
3150
- alignment = (alignment - .5) * orientation + .5;
3151
- }
3152
- const firstPoint = {
3153
- x: points[0],
3154
- y: points[1]
3155
- };
3156
- const lastPoint = {
3157
- x: points[points.length - 2],
3158
- y: points[points.length - 1]
3159
- };
3160
- const closedShape = closed;
3161
- const closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps && Math.abs(firstPoint.y - lastPoint.y) < eps;
3162
- if (closedShape) {
3163
- points = points.slice();
3164
- if (closedPath) {
3165
- points.pop();
3166
- points.pop();
3167
- lastPoint.x = points[points.length - 2];
3168
- lastPoint.y = points[points.length - 1];
3515
+ function parseCSSStylesheet(node, stylesheets) {
3516
+ if (!node.sheet || !node.sheet.cssRules || !node.sheet.cssRules.length) return;
3517
+ for (let i = 0; i < node.sheet.cssRules.length; i++) {
3518
+ const stylesheet = node.sheet.cssRules[i];
3519
+ if (stylesheet.type !== 1) continue;
3520
+ const selectorList = stylesheet.selectorText.split(/,/g).filter(Boolean).map((i2) => i2.trim());
3521
+ const definitions = {};
3522
+ for (let len = stylesheet.style.length, i2 = 0; i2 < len; i2++) {
3523
+ const name = stylesheet.style.item(i2);
3524
+ definitions[name] = stylesheet.style.getPropertyValue(name);
3169
3525
  }
3170
- const midPointX = (firstPoint.x + lastPoint.x) * .5;
3171
- const midPointY = (lastPoint.y + firstPoint.y) * .5;
3172
- points.unshift(midPointX, midPointY);
3173
- points.push(midPointX, midPointY);
3174
- }
3175
- const verts = vertices;
3176
- const length = points.length / 2;
3177
- let indexCount = points.length;
3178
- const indexStart = verts.length / 2;
3179
- const width = style.width / 2;
3180
- const widthSquared = width * width;
3181
- const miterLimitSquared = style.miterLimit * style.miterLimit;
3182
- let x0 = points[0];
3183
- let y0 = points[1];
3184
- let x1 = points[2];
3185
- let y1 = points[3];
3186
- let x2 = 0;
3187
- let y2 = 0;
3188
- let perpX = -(y0 - y1);
3189
- let perpY = x0 - x1;
3190
- let perp1x = 0;
3191
- let perp1y = 0;
3192
- let dist = Math.sqrt(perpX * perpX + perpY * perpY);
3193
- perpX /= dist;
3194
- perpY /= dist;
3195
- perpX *= width;
3196
- perpY *= width;
3197
- const ratio = alignment;
3198
- const innerWeight = (1 - ratio) * 2;
3199
- const outerWeight = ratio * 2;
3200
- if (!closedShape) {
3201
- if (style.cap === "round") indexCount += round(x0 - perpX * (innerWeight - outerWeight) * .5, y0 - perpY * (innerWeight - outerWeight) * .5, x0 - perpX * innerWeight, y0 - perpY * innerWeight, x0 + perpX * outerWeight, y0 + perpY * outerWeight, verts, true) + 2;
3202
- else if (style.cap === "square") indexCount += square(x0, y0, perpX, perpY, innerWeight, outerWeight, true, verts);
3526
+ for (let j = 0; j < selectorList.length; j++) stylesheets[selectorList[j]] = Object.assign(stylesheets[selectorList[j]] || {}, { ...definitions });
3203
3527
  }
3204
- verts.push(x0 - perpX * innerWeight, y0 - perpY * innerWeight);
3205
- verts.push(x0 + perpX * outerWeight, y0 + perpY * outerWeight);
3206
- for (let i = 1; i < length - 1; ++i) {
3207
- x0 = points[(i - 1) * 2];
3208
- y0 = points[(i - 1) * 2 + 1];
3209
- x1 = points[i * 2];
3210
- y1 = points[i * 2 + 1];
3211
- x2 = points[(i + 1) * 2];
3212
- y2 = points[(i + 1) * 2 + 1];
3213
- perpX = -(y0 - y1);
3214
- perpY = x0 - x1;
3215
- dist = Math.sqrt(perpX * perpX + perpY * perpY);
3216
- perpX /= dist;
3217
- perpY /= dist;
3218
- perpX *= width;
3219
- perpY *= width;
3220
- perp1x = -(y1 - y2);
3221
- perp1y = x1 - x2;
3222
- dist = Math.sqrt(perp1x * perp1x + perp1y * perp1y);
3223
- perp1x /= dist;
3224
- perp1y /= dist;
3225
- perp1x *= width;
3226
- perp1y *= width;
3227
- const dx0 = x1 - x0;
3228
- const dy0 = y0 - y1;
3229
- const dx1 = x1 - x2;
3230
- const dy1 = y2 - y1;
3231
- const dot = dx0 * dx1 + dy0 * dy1;
3232
- const cross = dy0 * dx1 - dy1 * dx0;
3233
- const clockwise = cross < 0;
3234
- if (Math.abs(cross) < .001 * Math.abs(dot)) {
3235
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
3236
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
3237
- if (dot >= 0) {
3238
- if (style.join === "round") indexCount += round(x1, y1, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 - perp1x * innerWeight, y1 - perp1y * innerWeight, verts, false) + 4;
3239
- else indexCount += 2;
3240
- verts.push(x1 - perp1x * outerWeight, y1 - perp1y * outerWeight);
3241
- verts.push(x1 + perp1x * innerWeight, y1 + perp1y * innerWeight);
3242
- }
3243
- continue;
3244
- }
3245
- const c1 = (-perpX + x0) * (-perpY + y1) - (-perpX + x1) * (-perpY + y0);
3246
- const c2 = (-perp1x + x2) * (-perp1y + y1) - (-perp1x + x1) * (-perp1y + y2);
3247
- const px = (dx0 * c2 - dx1 * c1) / cross;
3248
- const py = (dy1 * c1 - dy0 * c2) / cross;
3249
- const pDist = (px - x1) * (px - x1) + (py - y1) * (py - y1);
3250
- const imx = x1 + (px - x1) * innerWeight;
3251
- const imy = y1 + (py - y1) * innerWeight;
3252
- const omx = x1 - (px - x1) * outerWeight;
3253
- const omy = y1 - (py - y1) * outerWeight;
3254
- const smallerInsideSegmentSq = Math.min(dx0 * dx0 + dy0 * dy0, dx1 * dx1 + dy1 * dy1);
3255
- const insideWeight = clockwise ? innerWeight : outerWeight;
3256
- if (pDist <= smallerInsideSegmentSq + insideWeight * insideWeight * widthSquared) if (style.join === "bevel" || pDist / widthSquared > miterLimitSquared) {
3257
- if (clockwise) {
3258
- verts.push(imx, imy);
3259
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
3260
- verts.push(imx, imy);
3261
- verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
3262
- } else {
3263
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
3264
- verts.push(omx, omy);
3265
- verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
3266
- verts.push(omx, omy);
3267
- }
3268
- indexCount += 2;
3269
- } else if (style.join === "round") if (clockwise) {
3270
- verts.push(imx, imy);
3271
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
3272
- indexCount += round(x1, y1, x1 + perpX * outerWeight, y1 + perpY * outerWeight, x1 + perp1x * outerWeight, y1 + perp1y * outerWeight, verts, true) + 4;
3273
- verts.push(imx, imy);
3274
- verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
3275
- } else {
3276
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
3277
- verts.push(omx, omy);
3278
- indexCount += round(x1, y1, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 - perp1x * innerWeight, y1 - perp1y * innerWeight, verts, false) + 4;
3279
- verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
3280
- verts.push(omx, omy);
3281
- }
3282
- else {
3283
- verts.push(imx, imy);
3284
- verts.push(omx, omy);
3285
- }
3286
- else {
3287
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
3288
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
3289
- if (style.join === "round") if (clockwise) indexCount += round(x1, y1, x1 + perpX * outerWeight, y1 + perpY * outerWeight, x1 + perp1x * outerWeight, y1 + perp1y * outerWeight, verts, true) + 2;
3290
- else indexCount += round(x1, y1, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 - perp1x * innerWeight, y1 - perp1y * innerWeight, verts, false) + 2;
3291
- else if (style.join === "miter" && pDist / widthSquared <= miterLimitSquared) {
3292
- if (clockwise) {
3293
- verts.push(omx, omy);
3294
- verts.push(omx, omy);
3295
- } else {
3296
- verts.push(imx, imy);
3297
- verts.push(imx, imy);
3298
- }
3299
- indexCount += 2;
3300
- }
3301
- verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
3302
- verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
3303
- indexCount += 2;
3304
- }
3528
+ }
3529
+ function parseEllipseNode(node) {
3530
+ return new Path2D().ellipse(parseFloatWithUnits(node.getAttribute("cx") || 0), parseFloatWithUnits(node.getAttribute("cy") || 0), parseFloatWithUnits(node.getAttribute("rx") || 0), parseFloatWithUnits(node.getAttribute("ry") || 0), 0, 0, Math.PI * 2);
3531
+ }
3532
+ function parseLineNode(node) {
3533
+ return new Path2D().moveTo(parseFloatWithUnits(node.getAttribute("x1") || 0), parseFloatWithUnits(node.getAttribute("y1") || 0)).lineTo(parseFloatWithUnits(node.getAttribute("x2") || 0), parseFloatWithUnits(node.getAttribute("y2") || 0));
3534
+ }
3535
+ function parsePathNode(node) {
3536
+ const path = new Path2D();
3537
+ const d = node.getAttribute("d");
3538
+ if (!d || d === "none") return null;
3539
+ path.addData(d);
3540
+ return path;
3541
+ }
3542
+ var RE$1 = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;
3543
+ function parsePolygonNode(node) {
3544
+ const path = new Path2D();
3545
+ let index = 0;
3546
+ node.getAttribute("points")?.replace(RE$1, (match, a, b) => {
3547
+ const x = parseFloatWithUnits(a);
3548
+ const y = parseFloatWithUnits(b);
3549
+ if (index === 0) path.moveTo(x, y);
3550
+ else path.lineTo(x, y);
3551
+ index++;
3552
+ return match;
3553
+ });
3554
+ path.currentCurve.autoClose = true;
3555
+ return path;
3556
+ }
3557
+ var RE = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;
3558
+ function parsePolylineNode(node) {
3559
+ const path = new Path2D();
3560
+ let index = 0;
3561
+ node.getAttribute("points")?.replace(RE, (match, a, b) => {
3562
+ const x = parseFloatWithUnits(a);
3563
+ const y = parseFloatWithUnits(b);
3564
+ if (index === 0) path.moveTo(x, y);
3565
+ else path.lineTo(x, y);
3566
+ index++;
3567
+ return match;
3568
+ });
3569
+ path.currentCurve.autoClose = false;
3570
+ return path;
3571
+ }
3572
+ function parseRectNode(node) {
3573
+ const x = parseFloatWithUnits(node.getAttribute("x") || 0);
3574
+ const y = parseFloatWithUnits(node.getAttribute("y") || 0);
3575
+ const rx = parseFloatWithUnits(node.getAttribute("rx") || node.getAttribute("ry") || 0);
3576
+ const ry = parseFloatWithUnits(node.getAttribute("ry") || node.getAttribute("rx") || 0);
3577
+ const w = parseFloatWithUnits(node.getAttribute("width"));
3578
+ const h = parseFloatWithUnits(node.getAttribute("height"));
3579
+ const bci = .448084975506;
3580
+ const path = new Path2D();
3581
+ path.moveTo(x + rx, y);
3582
+ path.lineTo(x + w - rx, y);
3583
+ if (rx !== 0 || ry !== 0) path.bezierCurveTo(x + w - rx * bci, y, x + w, y + ry * bci, x + w, y + ry);
3584
+ path.lineTo(x + w, y + h - ry);
3585
+ if (rx !== 0 || ry !== 0) path.bezierCurveTo(x + w, y + h - ry * bci, x + w - rx * bci, y + h, x + w - rx, y + h);
3586
+ path.lineTo(x + rx, y + h);
3587
+ if (rx !== 0 || ry !== 0) path.bezierCurveTo(x + rx * bci, y + h, x, y + h - ry * bci, x, y + h - ry);
3588
+ path.lineTo(x, y + ry);
3589
+ if (rx !== 0 || ry !== 0) path.bezierCurveTo(x, y + ry * bci, x + rx * bci, y, x + rx, y);
3590
+ return path;
3591
+ }
3592
+ function parseStyle(node, style, stylesheets) {
3593
+ style = Object.assign({}, style);
3594
+ let stylesheetStyles = {};
3595
+ if (node.hasAttribute("class")) {
3596
+ const classSelectors = node.getAttribute("class").split(/\s/).filter(Boolean).map((i) => i.trim());
3597
+ for (let i = 0; i < classSelectors.length; i++) stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`.${classSelectors[i]}`]);
3305
3598
  }
3306
- x0 = points[(length - 2) * 2];
3307
- y0 = points[(length - 2) * 2 + 1];
3308
- x1 = points[(length - 1) * 2];
3309
- y1 = points[(length - 1) * 2 + 1];
3310
- perpX = -(y0 - y1);
3311
- perpY = x0 - x1;
3312
- dist = Math.sqrt(perpX * perpX + perpY * perpY);
3313
- perpX /= dist;
3314
- perpY /= dist;
3315
- perpX *= width;
3316
- perpY *= width;
3317
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
3318
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
3319
- if (!closedShape) {
3320
- if (style.cap === "round") indexCount += round(x1 - perpX * (innerWeight - outerWeight) * .5, y1 - perpY * (innerWeight - outerWeight) * .5, x1 - perpX * innerWeight, y1 - perpY * innerWeight, x1 + perpX * outerWeight, y1 + perpY * outerWeight, verts, false) + 2;
3321
- else if (style.cap === "square") indexCount += square(x1, y1, perpX, perpY, innerWeight, outerWeight, false, verts);
3599
+ if (node.hasAttribute("id")) stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`#${node.getAttribute("id")}`]);
3600
+ for (let len = node.style.length, i = 0; i < len; i++) {
3601
+ const name = node.style.item(i);
3602
+ const value = node.style.getPropertyValue(name);
3603
+ style[name] = value;
3604
+ stylesheetStyles[name] = value;
3322
3605
  }
3323
- const eps2 = curveEps * curveEps;
3324
- for (let i = indexStart; i < indexCount + indexStart - 2; ++i) {
3325
- x0 = verts[i * 2];
3326
- y0 = verts[i * 2 + 1];
3327
- x1 = verts[(i + 1) * 2];
3328
- y1 = verts[(i + 1) * 2 + 1];
3329
- x2 = verts[(i + 2) * 2];
3330
- y2 = verts[(i + 2) * 2 + 1];
3331
- if (Math.abs(x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1)) < eps2) continue;
3332
- indices.push(i, i + 1, i + 2);
3606
+ function addStyle(svgName, jsName, adjustFunction = copy) {
3607
+ if (node.hasAttribute(svgName)) style[jsName] = adjustFunction(node.getAttribute(svgName));
3608
+ if (stylesheetStyles[svgName]) style[jsName] = adjustFunction(stylesheetStyles[svgName]);
3333
3609
  }
3334
- return {
3335
- vertices,
3336
- indices
3337
- };
3338
- }
3339
- function getOrientationOfPoints(points) {
3340
- const m = points.length;
3341
- if (m < 6) return 1;
3342
- let area = 0;
3343
- for (let i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) {
3344
- const x2 = points[i];
3345
- const y2 = points[i + 1];
3346
- area += (x2 - x1) * (y2 + y1);
3347
- x1 = x2;
3348
- y1 = y2;
3610
+ function copy(v) {
3611
+ if (v.startsWith("url")) console.warn("url access in attributes is not implemented.");
3612
+ return v;
3349
3613
  }
3350
- if (area < 0) return -1;
3351
- return 1;
3352
- }
3353
- function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, verts) {
3354
- const ix = x - nx * innerWeight;
3355
- const iy = y - ny * innerWeight;
3356
- const ox = x + nx * outerWeight;
3357
- const oy = y + ny * outerWeight;
3358
- let exx;
3359
- let eyy;
3360
- if (clockwise) {
3361
- exx = ny;
3362
- eyy = -nx;
3363
- } else {
3364
- exx = -ny;
3365
- eyy = nx;
3614
+ function clamp(v) {
3615
+ return Math.max(0, Math.min(1, parseFloatWithUnits(v)));
3366
3616
  }
3367
- const eix = ix + exx;
3368
- const eiy = iy + eyy;
3369
- const eox = ox + exx;
3370
- const eoy = oy + eyy;
3371
- verts.push(eix, eiy);
3372
- verts.push(eox, eoy);
3373
- return 2;
3617
+ function positive(v) {
3618
+ return Math.max(0, parseFloatWithUnits(v));
3619
+ }
3620
+ function array(v) {
3621
+ return v.split(" ").filter((v2) => v2 !== "").map((v2) => parseFloatWithUnits(v2));
3622
+ }
3623
+ addStyle("fill", "fill");
3624
+ addStyle("fill-opacity", "fillOpacity", clamp);
3625
+ addStyle("fill-rule", "fillRule");
3626
+ addStyle("opacity", "opacity", clamp);
3627
+ addStyle("stroke", "stroke");
3628
+ addStyle("stroke-opacity", "strokeOpacity", clamp);
3629
+ addStyle("stroke-width", "strokeWidth", positive);
3630
+ addStyle("stroke-linecap", "strokeLinecap");
3631
+ addStyle("stroke-linejoin", "strokeLinejoin");
3632
+ addStyle("stroke-miterlimit", "strokeMiterlimit", positive);
3633
+ addStyle("stroke-dasharray", "strokeDasharray", array);
3634
+ addStyle("stroke-dashoffset", "strokeDashoffset", parseFloatWithUnits);
3635
+ addStyle("visibility", "visibility");
3636
+ return style;
3374
3637
  }
3375
- function round(cx, cy, sx, sy, ex, ey, verts, clockwise) {
3376
- const cx2p0x = sx - cx;
3377
- const cy2p0y = sy - cy;
3378
- let angle0 = Math.atan2(cx2p0x, cy2p0y);
3379
- let angle1 = Math.atan2(ex - cx, ey - cy);
3380
- if (clockwise && angle0 < angle1) angle0 += Math.PI * 2;
3381
- else if (!clockwise && angle0 > angle1) angle1 += Math.PI * 2;
3382
- let startAngle = angle0;
3383
- const angleDiff = angle1 - angle0;
3384
- const absAngleDiff = Math.abs(angleDiff);
3385
- const radius = Math.sqrt(cx2p0x * cx2p0x + cy2p0y * cy2p0y);
3386
- const segCount = (15 * absAngleDiff * Math.sqrt(radius) / Math.PI >> 0) + 1;
3387
- const angleInc = angleDiff / segCount;
3388
- startAngle += angleInc;
3389
- if (clockwise) {
3390
- verts.push(cx, cy);
3391
- verts.push(sx, sy);
3392
- for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
3393
- verts.push(cx, cy);
3394
- verts.push(cx + Math.sin(angle) * radius, cy + Math.cos(angle) * radius);
3395
- }
3396
- verts.push(cx, cy);
3397
- verts.push(ex, ey);
3398
- } else {
3399
- verts.push(sx, sy);
3400
- verts.push(cx, cy);
3401
- for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
3402
- verts.push(cx + Math.sin(angle) * radius, cy + Math.cos(angle) * radius);
3403
- verts.push(cx, cy);
3638
+ function parseNode(node, style, paths = [], stylesheets = {}) {
3639
+ if (node.nodeType !== 1) return paths;
3640
+ let isDefsNode = false;
3641
+ let path = null;
3642
+ let _style = { ...style };
3643
+ switch (node.nodeName) {
3644
+ case "svg":
3645
+ _style = parseStyle(node, _style, stylesheets);
3646
+ break;
3647
+ case "style":
3648
+ parseCSSStylesheet(node, stylesheets);
3649
+ break;
3650
+ case "g":
3651
+ _style = parseStyle(node, _style, stylesheets);
3652
+ break;
3653
+ case "path":
3654
+ _style = parseStyle(node, _style, stylesheets);
3655
+ if (node.hasAttribute("d")) path = parsePathNode(node);
3656
+ break;
3657
+ case "rect":
3658
+ _style = parseStyle(node, _style, stylesheets);
3659
+ path = parseRectNode(node);
3660
+ break;
3661
+ case "polygon":
3662
+ _style = parseStyle(node, _style, stylesheets);
3663
+ path = parsePolygonNode(node);
3664
+ break;
3665
+ case "polyline":
3666
+ _style = parseStyle(node, _style, stylesheets);
3667
+ path = parsePolylineNode(node);
3668
+ break;
3669
+ case "circle":
3670
+ _style = parseStyle(node, _style, stylesheets);
3671
+ path = parseCircleNode(node);
3672
+ break;
3673
+ case "ellipse":
3674
+ _style = parseStyle(node, _style, stylesheets);
3675
+ path = parseEllipseNode(node);
3676
+ break;
3677
+ case "line":
3678
+ _style = parseStyle(node, _style, stylesheets);
3679
+ path = parseLineNode(node);
3680
+ break;
3681
+ case "defs":
3682
+ isDefsNode = true;
3683
+ break;
3684
+ case "use": {
3685
+ _style = parseStyle(node, _style, stylesheets);
3686
+ const usedNodeId = (node.getAttributeNS("http://www.w3.org/1999/xlink", "href") || node.getAttribute("href") || "").substring(1);
3687
+ const usedNode = node.viewportElement?.getElementById(usedNodeId);
3688
+ if (usedNode) parseNode(usedNode, _style, paths, stylesheets);
3689
+ else console.warn(`'use node' references non-existent node id: ${usedNodeId}`);
3690
+ break;
3404
3691
  }
3405
- verts.push(ex, ey);
3406
- verts.push(cx, cy);
3692
+ default:
3693
+ console.warn(node);
3694
+ break;
3407
3695
  }
3408
- return segCount * 2;
3696
+ if (_style.display === "none") return paths;
3697
+ const currentTransform = new Transform2D();
3698
+ const transformStack = [];
3699
+ const transform = getNodeTransform(node, currentTransform, transformStack);
3700
+ if (path) {
3701
+ path.applyTransform(currentTransform);
3702
+ paths.push(path);
3703
+ path.style = { ..._style };
3704
+ }
3705
+ const childNodes = node.childNodes;
3706
+ for (let i = 0, len = childNodes.length; i < len; i++) {
3707
+ const node2 = childNodes[i];
3708
+ if (isDefsNode && node2.nodeName !== "style" && node2.nodeName !== "defs") continue;
3709
+ parseNode(node2, _style, paths, stylesheets);
3710
+ }
3711
+ if (transform) {
3712
+ transformStack.pop();
3713
+ if (transformStack.length > 0) currentTransform.copyFrom(transformStack[transformStack.length - 1]);
3714
+ else currentTransform.identity();
3715
+ }
3716
+ return paths;
3717
+ }
3718
+ function svgToPath2DSet(svg) {
3719
+ const dom = svgToDom(svg);
3720
+ return new Path2DSet(parseNode(dom, {}), dom.getAttribute("viewBox")?.trim().split(" ").map((v) => Number(v)));
3409
3721
  }
3410
3722
  var Curve = class {
3411
3723
  arcLengthDivision = 200;
@@ -3423,7 +3735,7 @@ var Curve = class {
3423
3735
  const isFunction = typeof transform === "function";
3424
3736
  this.getControlPointRefs().forEach((p) => {
3425
3737
  if (isFunction) transform(p);
3426
- else p.applyMatrix3(transform);
3738
+ else transform.apply(p, p);
3427
3739
  });
3428
3740
  return this;
3429
3741
  }
@@ -3525,7 +3837,7 @@ var Curve = class {
3525
3837
  const delta = 1e-4;
3526
3838
  const t1 = Math.max(0, t - delta);
3527
3839
  const t2 = Math.min(1, t + delta);
3528
- return output.copy(this.getPoint(t2).sub(this.getPoint(t1)).normalize());
3840
+ return output.copyFrom(this.getPoint(t2).sub(this.getPoint(t1)).normalize());
3529
3841
  }
3530
3842
  getTangentAt(u, output) {
3531
3843
  return this.getTangent(this.getUToTMapping(u), output);
@@ -3554,8 +3866,8 @@ var Curve = class {
3554
3866
  const potins = this.getPoints();
3555
3867
  for (let i = 0, len = potins.length; i < len; i++) {
3556
3868
  const p = potins[i];
3557
- min.min(p);
3558
- max.max(p);
3869
+ min.clampMin(p);
3870
+ max.clampMax(p);
3559
3871
  }
3560
3872
  return {
3561
3873
  min: min.finite(),
@@ -3609,17 +3921,17 @@ var Curve = class {
3609
3921
  });
3610
3922
  return this;
3611
3923
  }
3612
- copy(source) {
3924
+ copyFrom(source) {
3613
3925
  this.arcLengthDivision = source.arcLengthDivision;
3614
3926
  return this;
3615
3927
  }
3616
3928
  clone() {
3617
- return new this.constructor().copy(this);
3929
+ return new this.constructor().copyFrom(this);
3618
3930
  }
3619
3931
  };
3620
- var tempTransform0 = new Matrix3();
3621
- var tempTransform1 = new Matrix3();
3622
- var tempTransform2 = new Matrix3();
3932
+ var tempTransform0 = new Transform2D();
3933
+ var tempTransform1 = new Transform2D();
3934
+ var tempTransform2 = new Transform2D();
3623
3935
  var tempV2 = new Vector2();
3624
3936
  var RoundCurve = class extends Curve {
3625
3937
  constructor(_center = new Vector2(), _radius = new Vector2(), _diff = new Vector2(), rotate = 0, startAngle = 0, endAngle = Math.PI * 2, clockwise = false) {
@@ -3758,13 +4070,13 @@ var RoundCurve = class extends Curve {
3758
4070
  ctx.ellipse(cx, cy, rx, ry, rotate, startAngle, endAngle, !clockwise);
3759
4071
  return this;
3760
4072
  }
3761
- applyTransform(matrix) {
4073
+ applyTransform(transform) {
3762
4074
  tempV2.set(this.cx, this.cy);
3763
- tempV2.applyMatrix3(matrix);
4075
+ transform.apply(tempV2, tempV2);
3764
4076
  this.cx = tempV2.x;
3765
4077
  this.cy = tempV2.y;
3766
- if (isTransformSkewed(matrix)) transfEllipseGeneric(this, matrix);
3767
- else transfEllipseNoSkew(this, matrix);
4078
+ if (isTransformSkewed(transform)) transfEllipseGeneric(this, transform);
4079
+ else transfEllipseNoSkew(this, transform);
3768
4080
  return this;
3769
4081
  }
3770
4082
  getControlPointRefs() {
@@ -3879,8 +4191,8 @@ var RoundCurve = class extends Curve {
3879
4191
  if (this.startAngle === 0 && this.endAngle === Math.PI * 2) return this._getAdaptiveVerticesByCircle(output);
3880
4192
  return this._getAdaptiveVerticesByArc(output);
3881
4193
  }
3882
- copy(source) {
3883
- super.copy(source);
4194
+ copyFrom(source) {
4195
+ super.copyFrom(source);
3884
4196
  this.cx = source.cx;
3885
4197
  this.cy = source.cy;
3886
4198
  this.rx = source.rx;
@@ -3901,23 +4213,27 @@ function transfEllipseGeneric(curve, m) {
3901
4213
  const sinTheta = Math.sin(curve.rotate);
3902
4214
  const v1 = new Vector2(a * cosTheta, a * sinTheta);
3903
4215
  const v2 = new Vector2(-b * sinTheta, b * cosTheta);
3904
- const f1 = v1.applyMatrix3(m);
3905
- const f2 = v2.applyMatrix3(m);
3906
- const mF = tempTransform0.set(f1.x, f2.x, 0, f1.y, f2.y, 0, 0, 0, 1);
3907
- const mFInv = tempTransform1.copy(mF).invert();
3908
- const mQe = tempTransform2.copy(mFInv).transpose().multiply(mFInv).elements;
3909
- const ed = eigenDecomposition(mQe[0], mQe[1], mQe[4]);
4216
+ const f1x = m.a * v1.x + m.c * v1.y;
4217
+ const f1y = m.b * v1.x + m.d * v1.y;
4218
+ const f2x = m.a * v2.x + m.c * v2.y;
4219
+ const f2y = m.b * v2.x + m.d * v2.y;
4220
+ const mF = tempTransform0.set(f1x, f1y, f2x, f2y, 0, 0);
4221
+ const { a: ia, b: ib, c: ic, d: id } = tempTransform1.copyFrom(mF).affineInvert();
4222
+ const ed = eigenDecomposition(ia * ia + ib * ib, ic * ia + id * ib, ic * ic + id * id);
3910
4223
  const rt1sqrt = Math.sqrt(ed.rt1);
3911
4224
  const rt2sqrt = Math.sqrt(ed.rt2);
3912
4225
  curve.rx = 1 / rt1sqrt;
3913
4226
  curve.ry = 1 / rt2sqrt;
3914
4227
  curve.rotate = Math.atan2(ed.sn, ed.cs);
3915
4228
  if (!((curve.endAngle - curve.startAngle) % (2 * Math.PI) < Number.EPSILON)) {
3916
- const mDsqrt = tempTransform1.set(rt1sqrt, 0, 0, 0, rt2sqrt, 0, 0, 0, 1);
3917
- const mRT = tempTransform2.set(ed.cs, ed.sn, 0, -ed.sn, ed.cs, 0, 0, 0, 1);
3918
- const mDRF = mDsqrt.multiply(mRT).multiply(mF);
4229
+ const mDsqrt = tempTransform1.set(rt1sqrt, 0, 0, rt2sqrt, 0, 0);
4230
+ const mRT = tempTransform2.set(ed.cs, ed.sn, -ed.sn, ed.cs, 0, 0);
4231
+ const mDRF = mDsqrt.append(mRT).append(mF);
3919
4232
  const transformAngle = (phi) => {
3920
- const { x: cosR, y: sinR } = new Vector2(Math.cos(phi), Math.sin(phi)).applyMatrix3(mDRF);
4233
+ const { x: cosR, y: sinR } = mDRF.apply({
4234
+ x: Math.cos(phi),
4235
+ y: Math.sin(phi)
4236
+ });
3921
4237
  return Math.atan2(sinR, cosR);
3922
4238
  };
3923
4239
  curve.startAngle = transformAngle(curve.startAngle);
@@ -3926,11 +4242,10 @@ function transfEllipseGeneric(curve, m) {
3926
4242
  }
3927
4243
  }
3928
4244
  function transfEllipseNoSkew(curve, m) {
3929
- const sx = getTransformScaleX(m);
3930
- const sy = getTransformScaleY(m);
3931
- curve.rx *= sx;
3932
- curve.ry *= sy;
3933
- const theta = sx > Number.EPSILON ? Math.atan2(m.elements[1], m.elements[0]) : Math.atan2(-m.elements[3], m.elements[4]);
4245
+ const { scale } = m.decompose();
4246
+ curve.rx *= scale.x;
4247
+ curve.ry *= scale.y;
4248
+ const theta = scale.x > Number.EPSILON ? Math.atan2(m.b, m.a) : Math.atan2(-m.c, m.d);
3934
4249
  curve.rotate += theta;
3935
4250
  if (isTransformFlipped(m)) {
3936
4251
  curve.startAngle *= -1;
@@ -3939,24 +4254,13 @@ function transfEllipseNoSkew(curve, m) {
3939
4254
  }
3940
4255
  }
3941
4256
  function isTransformFlipped(m) {
3942
- const te = m.elements;
3943
- return te[0] * te[4] - te[1] * te[3] < 0;
4257
+ return m.a * m.d - m.c * m.b < 0;
3944
4258
  }
3945
4259
  function isTransformSkewed(m) {
3946
- const te = m.elements;
3947
- const basisDot = te[0] * te[3] + te[1] * te[4];
4260
+ const basisDot = m.a * m.c + m.b * m.d;
3948
4261
  if (basisDot === 0) return false;
3949
- const sx = getTransformScaleX(m);
3950
- const sy = getTransformScaleY(m);
3951
- return Math.abs(basisDot / (sx * sy)) > Number.EPSILON;
3952
- }
3953
- function getTransformScaleX(m) {
3954
- const te = m.elements;
3955
- return Math.sqrt(te[0] * te[0] + te[1] * te[1]);
3956
- }
3957
- function getTransformScaleY(m) {
3958
- const te = m.elements;
3959
- return Math.sqrt(te[3] * te[3] + te[4] * te[4]);
4262
+ const { scale } = m.decompose();
4263
+ return Math.abs(basisDot / (scale.x * scale.y)) > Number.EPSILON;
3960
4264
  }
3961
4265
  function eigenDecomposition(A, B, C) {
3962
4266
  let rt1, rt2, cs, sn, t;
@@ -4018,8 +4322,8 @@ var LineCurve = class LineCurve extends Curve {
4018
4322
  return new LineCurve(new Vector2(p1x, p1y), new Vector2(p2x, p2y));
4019
4323
  }
4020
4324
  getPoint(t, output = new Vector2()) {
4021
- if (t === 1) output.copy(this.p2);
4022
- else output.copy(this.p2).sub(this.p1).scale(t).add(this.p1);
4325
+ if (t === 1) output.copyFrom(this.p2);
4326
+ else output.copyFrom(this.p2).sub(this.p1).scale(t).add(this.p1);
4023
4327
  return output;
4024
4328
  }
4025
4329
  getPointAt(u, output = new Vector2()) {
@@ -4087,10 +4391,10 @@ var LineCurve = class LineCurve extends Curve {
4087
4391
  ctx.lineTo(p2.x, p2.y);
4088
4392
  return this;
4089
4393
  }
4090
- copy(source) {
4091
- super.copy(source);
4092
- this.p1.copy(source.p1);
4093
- this.p2.copy(source.p2);
4394
+ copyFrom(source) {
4395
+ super.copyFrom(source);
4396
+ this.p1.copyFrom(source.p1);
4397
+ this.p2.copyFrom(source.p2);
4094
4398
  return this;
4095
4399
  }
4096
4400
  };
@@ -4207,8 +4511,8 @@ var CompositeCurve = class CompositeCurve extends Curve {
4207
4511
  this.curves.forEach((curve) => curve.drawTo(ctx));
4208
4512
  return this;
4209
4513
  }
4210
- copy(source) {
4211
- super.copy(source);
4514
+ copyFrom(source) {
4515
+ super.copyFrom(source);
4212
4516
  this.curves = source.curves.map((curve) => curve.clone());
4213
4517
  return this;
4214
4518
  }
@@ -4294,12 +4598,12 @@ var CubicBezierCurve = class CubicBezierCurve extends Curve {
4294
4598
  ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, p2.x, p2.y);
4295
4599
  return this;
4296
4600
  }
4297
- copy(source) {
4298
- super.copy(source);
4299
- this.p1.copy(source.p1);
4300
- this.cp1.copy(source.cp1);
4301
- this.cp2.copy(source.cp2);
4302
- this.p2.copy(source.p2);
4601
+ copyFrom(source) {
4602
+ super.copyFrom(source);
4603
+ this.p1.copyFrom(source.p1);
4604
+ this.cp1.copyFrom(source.cp1);
4605
+ this.cp2.copyFrom(source.cp2);
4606
+ this.p2.copyFrom(source.p2);
4303
4607
  return this;
4304
4608
  }
4305
4609
  };
@@ -4373,11 +4677,11 @@ var QuadraticBezierCurve = class QuadraticBezierCurve extends Curve {
4373
4677
  ctx.quadraticCurveTo(cp.x, cp.y, p2.x, p2.y);
4374
4678
  return this;
4375
4679
  }
4376
- copy(source) {
4377
- super.copy(source);
4378
- this.p1.copy(source.p1);
4379
- this.cp.copy(source.cp);
4380
- this.p2.copy(source.p2);
4680
+ copyFrom(source) {
4681
+ super.copyFrom(source);
4682
+ this.p1.copyFrom(source.p1);
4683
+ this.cp.copyFrom(source.cp);
4684
+ this.p2.copyFrom(source.p2);
4381
4685
  return this;
4382
4686
  }
4383
4687
  };
@@ -4423,8 +4727,8 @@ var RectangleCurve = class extends PloygonCurve {
4423
4727
  y + height
4424
4728
  ];
4425
4729
  }
4426
- copy(source) {
4427
- super.copy(source);
4730
+ copyFrom(source) {
4731
+ super.copyFrom(source);
4428
4732
  this.x = source.x;
4429
4733
  this.y = source.y;
4430
4734
  this.width = source.width;
@@ -4461,8 +4765,8 @@ var RoundRectangleCurve = class extends RoundCurve {
4461
4765
  ctx.roundRect(x, y, width, height, radius);
4462
4766
  return this;
4463
4767
  }
4464
- copy(source) {
4465
- super.copy(source);
4768
+ copyFrom(source) {
4769
+ super.copyFrom(source);
4466
4770
  this.x = source.x;
4467
4771
  this.y = source.y;
4468
4772
  this.width = source.width;
@@ -4492,8 +4796,8 @@ var SplineCurve = class extends Curve {
4492
4796
  getControlPointRefs() {
4493
4797
  return this.points;
4494
4798
  }
4495
- copy(source) {
4496
- super.copy(source);
4799
+ copyFrom(source) {
4800
+ super.copyFrom(source);
4497
4801
  this.points = [];
4498
4802
  for (let i = 0, len = source.points.length; i < len; i++) this.points.push(source.points[i].clone());
4499
4803
  return this;
@@ -4557,7 +4861,7 @@ var CurvePath = class extends CompositeCurve {
4557
4861
  const end = this.currentPoint;
4558
4862
  if (end && !start.equals(end)) {
4559
4863
  this.curves.push(new LineCurve(end.clone(), start.clone()));
4560
- end.copy(start);
4864
+ end.copyFrom(start);
4561
4865
  }
4562
4866
  this.startPoint = void 0;
4563
4867
  }
@@ -4667,8 +4971,8 @@ var CurvePath = class extends CompositeCurve {
4667
4971
  if (this.autoClose) ctx.closePath();
4668
4972
  return this;
4669
4973
  }
4670
- copy(source) {
4671
- super.copy(source);
4974
+ copyFrom(source) {
4975
+ super.copyFrom(source);
4672
4976
  this.autoClose = source.autoClose;
4673
4977
  this.currentPoint = source.currentPoint?.clone();
4674
4978
  return this;
@@ -4803,12 +5107,12 @@ var Path2D = class Path2D extends CompositeCurve {
4803
5107
  });
4804
5108
  return this;
4805
5109
  }
4806
- rotate(a, target = {
5110
+ rotate(rad, target = {
4807
5111
  x: 0,
4808
5112
  y: 0
4809
5113
  }) {
4810
5114
  this.getControlPointRefs().forEach((point) => {
4811
- point.rotate(a, target);
5115
+ point.rotate(rad, target);
4812
5116
  });
4813
5117
  return this;
4814
5118
  }
@@ -4850,8 +5154,8 @@ var Path2D = class Path2D extends CompositeCurve {
4850
5154
  const pointsB = _points[indexB];
4851
5155
  const point = getIntersectionPoint(pointsA[pointsA.length - 1], pointsA[pointsA.length - 2] ?? pointsA[pointsA.length - 1], pointsB[0], pointsB[1] ?? pointsB[0]);
4852
5156
  if (point) {
4853
- pointsA[pointsA.length - 1].copy(point);
4854
- pointsB[0].copy(point);
5157
+ pointsA[pointsA.length - 1].copyFrom(point);
5158
+ pointsB[0].copyFrom(point);
4855
5159
  }
4856
5160
  });
4857
5161
  });
@@ -4891,8 +5195,8 @@ var Path2D = class Path2D extends CompositeCurve {
4891
5195
  y: -halfStrokeWidth
4892
5196
  }));
4893
5197
  }
4894
- min.min(...points);
4895
- max.max(...points);
5198
+ min.clampMin(...points);
5199
+ max.clampMax(...points);
4896
5200
  }
4897
5201
  }
4898
5202
  });
@@ -5022,8 +5326,8 @@ var Path2D = class Path2D extends CompositeCurve {
5022
5326
  for (const key in cssStyle) if (cssStyle[key] !== void 0) cssText += `${key}:${cssStyle[key]};`;
5023
5327
  return `<path d="${this.toData()}" style="${cssText}"></path>`;
5024
5328
  }
5025
- copy(source) {
5026
- super.copy(source);
5329
+ copyFrom(source) {
5330
+ super.copyFrom(source);
5027
5331
  this.currentCurve = source.currentCurve.clone();
5028
5332
  this.style = { ...source.style };
5029
5333
  return this;
@@ -5618,6 +5922,7 @@ async function convertElement(el, parent, context) {
5618
5922
  meta.inPptIs = "Picture";
5619
5923
  meta.lockAspectRatio = true;
5620
5924
  element.foreground = {
5925
+ enabled: true,
5621
5926
  image: el.clipUrl || el.url,
5622
5927
  fillWithShape: true
5623
5928
  };
@@ -5631,6 +5936,7 @@ async function convertElement(el, parent, context) {
5631
5936
  meta.inPptIs = "Picture";
5632
5937
  meta.lockAspectRatio = true;
5633
5938
  element.foreground = {
5939
+ enabled: true,
5634
5940
  image: await convertSvgElementToUrl(el),
5635
5941
  fillWithShape: true
5636
5942
  };
@@ -5650,7 +5956,10 @@ async function convertElement(el, parent, context) {
5650
5956
  });
5651
5957
  meta.textEffectsId = el.effectId;
5652
5958
  if (style.color && isGradientFill(style.color)) {
5653
- element.text.fill = normalizeGradientFill(style.color);
5959
+ element.text.fill = {
5960
+ enabled: true,
5961
+ ...normalizeGradientFill(style.color)
5962
+ };
5654
5963
  style.color = "#000000";
5655
5964
  }
5656
5965
  break;
@@ -5674,21 +5983,33 @@ async function convertElement(el, parent, context) {
5674
5983
  if (set.paths.length === 1) {
5675
5984
  const path = set.paths[0];
5676
5985
  element.shape = {
5986
+ enabled: true,
5677
5987
  paths: [{
5678
5988
  ...path.style,
5679
5989
  data: path.toData()
5680
5990
  }],
5681
5991
  viewBox: set.viewBox
5682
5992
  };
5683
- if (path.style.fill !== "none") element.fill = { color: el.fill };
5993
+ if (path.style.fill !== "none") element.fill = {
5994
+ enabled: true,
5995
+ color: el.fill
5996
+ };
5684
5997
  if (path.style.stroke !== "none") element.outline = {
5998
+ enabled: true,
5685
5999
  color: el.stroke,
5686
6000
  width: el.strokeWidth
5687
6001
  };
5688
6002
  } else {
5689
- element.shape = { svg };
5690
- element.fill = { color: el.fill };
6003
+ element.shape = {
6004
+ enabled: true,
6005
+ svg
6006
+ };
6007
+ element.fill = {
6008
+ enabled: true,
6009
+ color: el.fill
6010
+ };
5691
6011
  element.outline = {
6012
+ enabled: true,
5692
6013
  color: el.stroke,
5693
6014
  width: el.strokeWidth
5694
6015
  };
@@ -6175,11 +6496,11 @@ async function setupFonts(editor, api) {
6175
6496
  root.value && preloadNode(root.value);
6176
6497
  }
6177
6498
  onBeforeMount(() => {
6178
- on("setDoc", preload);
6499
+ on("docSet", preload);
6179
6500
  renderEngine.value.on("nodeEnter", preloadNode);
6180
6501
  });
6181
6502
  onScopeDispose(() => {
6182
- off("setDoc", preload);
6503
+ off("docSet", preload);
6183
6504
  renderEngine.value.off("nodeEnter", preloadNode);
6184
6505
  });
6185
6506
  assets.awaitBy(async () => {