@pixerate/editor 0.129.0 → 0.131.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 (62) hide show
  1. package/dist/animation-editor/index.cjs +55 -55
  2. package/dist/animation-editor/index.d.cts +5 -5
  3. package/dist/animation-editor/index.d.ts +5 -5
  4. package/dist/animation-editor/index.js +2 -2
  5. package/dist/{bezier-DP4NnJp3.d.ts → bezier-0IHDCvv_.d.ts} +1 -1
  6. package/dist/{bezier-CvgQiYRg.d.cts → bezier-oCBfrGDG.d.cts} +1 -1
  7. package/dist/canvas/index.d.cts +7 -7
  8. package/dist/canvas/index.d.ts +7 -7
  9. package/dist/{chunk-A6KHMKI4.js → chunk-ECVI5QRE.js} +2 -2
  10. package/dist/{chunk-ROZFX4QI.js → chunk-IEYXYMRQ.js} +556 -13
  11. package/dist/chunk-IEYXYMRQ.js.map +1 -0
  12. package/dist/{chunk-BEGEWQHD.cjs → chunk-OYPJGGF3.cjs} +36 -36
  13. package/dist/{chunk-BEGEWQHD.cjs.map → chunk-OYPJGGF3.cjs.map} +1 -1
  14. package/dist/{chunk-XLUYXUBD.cjs → chunk-SUJ4U6V2.cjs} +82 -82
  15. package/dist/{chunk-XLUYXUBD.cjs.map → chunk-SUJ4U6V2.cjs.map} +1 -1
  16. package/dist/{chunk-F7Q2NE2Y.js → chunk-YQJWLB3G.js} +2 -2
  17. package/dist/{chunk-ORE334I6.cjs → chunk-YYJKIESX.cjs} +619 -76
  18. package/dist/chunk-YYJKIESX.cjs.map +1 -0
  19. package/dist/effects/index.d.cts +4 -4
  20. package/dist/effects/index.d.ts +4 -4
  21. package/dist/{export-DRzNhrdx.d.cts → export-BRixPkeT.d.cts} +3 -3
  22. package/dist/{export-Cbr9IqpJ.d.cts → export-CfAogLEr.d.cts} +1 -1
  23. package/dist/{export-DotEEyXj.d.ts → export-CkDz9XuC.d.ts} +3 -3
  24. package/dist/{export-ClPKUB-v.d.ts → export-Crl82sbE.d.ts} +1 -1
  25. package/dist/{helpers-CPWcK504.d.ts → helpers-BCd2-PAR.d.ts} +67 -3
  26. package/dist/{helpers-C5aAd44p.d.cts → helpers-CoIeXQnW.d.cts} +67 -3
  27. package/dist/image-editor/index.cjs +606 -606
  28. package/dist/image-editor/index.d.cts +8 -8
  29. package/dist/image-editor/index.d.ts +8 -8
  30. package/dist/image-editor/index.js +2 -2
  31. package/dist/{opentype-BOewaGQx.d.cts → opentype-BDahNRTe.d.cts} +2 -2
  32. package/dist/{opentype-sQrF3Ry1.d.ts → opentype-BQFEvy-t.d.ts} +2 -2
  33. package/dist/paint-editor/index.cjs +7 -7
  34. package/dist/paint-editor/index.d.cts +5 -5
  35. package/dist/paint-editor/index.d.ts +5 -5
  36. package/dist/paint-editor/index.js +2 -2
  37. package/dist/{pathfinder-CnkW7zLI.d.cts → pathfinder-01ZgAwqV.d.cts} +1 -1
  38. package/dist/{pathfinder-BwJx0_zM.d.ts → pathfinder-DaVdT8jq.d.ts} +1 -1
  39. package/dist/{pool-CTrtciaN.d.ts → pool-D2A3WTt9.d.ts} +1 -1
  40. package/dist/{pool-C7GtrL34.d.cts → pool-D6a45MoE.d.cts} +1 -1
  41. package/dist/{svg-C4LlFnEw.d.cts → svg-CcDz7Zq2.d.cts} +2 -2
  42. package/dist/{svg-CUzZa0EO.d.ts → svg-DELNVerw.d.ts} +2 -2
  43. package/dist/{tools-BpCmUNxb.d.cts → tools-BFvkFnRj.d.cts} +1 -1
  44. package/dist/{tools-AugT22z3.d.ts → tools-D7ws-OKL.d.ts} +1 -1
  45. package/dist/vector/index.cjs +1149 -1017
  46. package/dist/vector/index.cjs.map +1 -1
  47. package/dist/vector/index.d.cts +106 -10
  48. package/dist/vector/index.d.ts +106 -10
  49. package/dist/vector/index.js +142 -10
  50. package/dist/vector/index.js.map +1 -1
  51. package/dist/video-editor/index.d.cts +4 -4
  52. package/dist/video-editor/index.d.ts +4 -4
  53. package/dist/{warp-CIsO617e.d.ts → warp-2N9wkOkL.d.ts} +2 -2
  54. package/dist/{warp-D62N_5VK.d.cts → warp-DErXW5rz.d.cts} +2 -2
  55. package/package.json +2 -2
  56. package/skills/pixerate-image-editor/SKILL.md +1 -1
  57. package/skills/pixerate-vector/SKILL.md +8 -1
  58. package/skills/pixerate-vector/references/commands.md +20 -0
  59. package/dist/chunk-ORE334I6.cjs.map +0 -1
  60. package/dist/chunk-ROZFX4QI.js.map +0 -1
  61. /package/dist/{chunk-A6KHMKI4.js.map → chunk-ECVI5QRE.js.map} +0 -0
  62. /package/dist/{chunk-F7Q2NE2Y.js.map → chunk-YQJWLB3G.js.map} +0 -0
@@ -12,6 +12,7 @@ import {
12
12
  pathBoolean,
13
13
  pathToContours,
14
14
  pointInBezierPath,
15
+ pointInRings,
15
16
  polygonBoolean,
16
17
  segmentBounds,
17
18
  segmentDerivative,
@@ -73,6 +74,7 @@ var VECTOR_BLEND_MODES = [
73
74
  ];
74
75
  var VECTOR_HORIZONTAL_RESIZING = ["left", "right", "leftRight", "center", "scale"];
75
76
  var VECTOR_VERTICAL_RESIZING = ["top", "bottom", "topBottom", "center", "scale"];
77
+ var VECTOR_LENS_TYPES = ["transparency", "magnify", "fisheye", "brighten", "invert", "tintedGrayscale", "colorAdd", "colorLimit", "heatMap", "wireframe"];
76
78
  var VECTOR_CONNECTOR_SIDES = ["auto", "top", "right", "bottom", "left", "center"];
77
79
  var VECTOR_CONNECTOR_ROUTES = ["straight", "elbow", "curved"];
78
80
  var VECTOR_BLEND_SPACINGS = ["steps", "distance", "smoothColor"];
@@ -124,7 +126,7 @@ var VECTOR_TOOLS = [
124
126
  ];
125
127
  var VECTOR_TRANSFORM_HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w", "rotate"];
126
128
  var VECTOR_PATHFINDER_OPERATIONS = ["divide", "trim", "merge", "crop", "outline", "minusBack"];
127
- var VECTOR_EFFECT_TYPES = ["trim", "roundCorners", "puckerBloat", "twist", "zigzag", "wiggle", "offset", "merge", "repeater", "envelope", "contour", "blockShadow"];
129
+ var VECTOR_EFFECT_TYPES = ["trim", "roundCorners", "puckerBloat", "twist", "zigzag", "wiggle", "offset", "merge", "repeater", "envelope", "contour", "blockShadow", "extrude", "bevel"];
128
130
  var VECTOR_MERGE_MODES = ["merge", "add", "subtract", "intersect", "exclude"];
129
131
  var VECTOR_FILTER_TYPES = ["dropShadow", "innerShadow", "outerGlow", "innerGlow", "layerBlur", "feather"];
130
132
 
@@ -5550,6 +5552,458 @@ function vectorInstanceGroup(node, bake) {
5550
5552
  }
5551
5553
  var composeVectorMatrices = (a, b) => multiplyMatrices(a, b);
5552
5554
 
5555
+ // src/vector/extrude.ts
5556
+ function vectorPaintSolid(paint) {
5557
+ if (paint == null || paint === "none") return null;
5558
+ if (typeof paint === "string") return paint;
5559
+ const stops = paint.stops;
5560
+ if (stops?.length) return stops.reduce((a, b) => Math.abs(b.offset - 0.5) < Math.abs(a.offset - 0.5) ? b : a).color;
5561
+ const colors = paint.colors;
5562
+ if (colors?.length) return colors[0];
5563
+ const points = paint.points;
5564
+ return points?.find((p) => typeof p.color === "string")?.color ?? null;
5565
+ }
5566
+ function shadeVectorColor(color2, amount) {
5567
+ const c = parseVectorColor(color2);
5568
+ if (!c) return color2;
5569
+ const a = Math.min(1, Math.max(-1, amount));
5570
+ const target = a >= 0 ? 1 : 0;
5571
+ const h = (v2) => Math.round(Math.min(1, Math.max(0, v2)) * 255).toString(16).padStart(2, "0");
5572
+ const m = [0, 1, 2].map((k) => c[k] + (target - c[k]) * Math.abs(a));
5573
+ return `#${h(m[0])}${h(m[1])}${h(m[2])}`;
5574
+ }
5575
+ function vectorPathRings(path, tolerance = 0.5) {
5576
+ const rings = [];
5577
+ for (const contour of pathToContours(path)) {
5578
+ const ring = flattenChain(closeContour(contour, true), Math.max(1e-3, tolerance));
5579
+ if (ring.length >= 2) rings.push(ring);
5580
+ }
5581
+ return rings;
5582
+ }
5583
+ function vectorExtrudeFaces(path, params) {
5584
+ const box = bezierPathBounds(path);
5585
+ if (!box || !path.length) return [];
5586
+ const perspective = params.mode === "perspective";
5587
+ const rad2 = params.angle * Math.PI / 180;
5588
+ const d = [Math.cos(rad2) * Math.max(0, params.depth), Math.sin(rad2) * Math.max(0, params.depth)];
5589
+ const vp = [(box.minX + box.maxX) / 2 + params.vanishingPoint.x, (box.minY + box.maxY) / 2 + params.vanishingPoint.y];
5590
+ const pull = Math.min(1, Math.max(0, params.toward / 100));
5591
+ const back = (p) => perspective ? [p[0] + (vp[0] - p[0]) * pull, p[1] + (vp[1] - p[1]) * pull] : [p[0] + d[0], p[1] + d[1]];
5592
+ if (perspective ? pull <= 0 : Math.hypot(d[0], d[1]) < 1e-9) return [];
5593
+ const lr = params.lightAngle * Math.PI / 180;
5594
+ const light = [Math.cos(lr), Math.sin(lr)];
5595
+ const strength = Math.min(1, Math.max(0, params.shading / 100));
5596
+ const u = perspective ? [0, 0] : [d[0] / Math.hypot(d[0], d[1]), d[1] / Math.hypot(d[0], d[1])];
5597
+ const centre = [(box.minX + box.maxX) / 2, (box.minY + box.maxY) / 2];
5598
+ const aim = Math.atan2(centre[1] - vp[1], centre[0] - vp[0]);
5599
+ const across = (p) => {
5600
+ if (!perspective) return -p[0] * u[1] + p[1] * u[0];
5601
+ let a = Math.atan2(p[1] - vp[1], p[0] - vp[0]) - aim;
5602
+ while (a > Math.PI) a -= 2 * Math.PI;
5603
+ while (a <= -Math.PI) a += 2 * Math.PI;
5604
+ return a;
5605
+ };
5606
+ const towardBack = (p, q, l) => {
5607
+ const lp = across(p);
5608
+ const lq = across(q);
5609
+ const t = Math.abs(lq - lp) < 1e-12 ? 0.5 : Math.min(1, Math.max(0, (l - lp) / (lq - lp)));
5610
+ const x = [p[0] + (q[0] - p[0]) * t, p[1] + (q[1] - p[1]) * t];
5611
+ return perspective ? -Math.hypot(vp[0] - x[0], vp[1] - x[1]) : x[0] * u[0] + x[1] * u[1];
5612
+ };
5613
+ const faces = [];
5614
+ for (const ring of vectorPathRings(path, 0.25)) {
5615
+ for (let i = 0; i < ring.length; i++) {
5616
+ const p = ring[i];
5617
+ const q = ring[(i + 1) % ring.length];
5618
+ const ex = q[0] - p[0];
5619
+ const ey = q[1] - p[1];
5620
+ const len2 = Math.hypot(ex, ey);
5621
+ if (len2 < 1e-9) continue;
5622
+ const pb = back(p);
5623
+ const qb = back(q);
5624
+ const mid = [(p[0] + q[0]) / 2, (p[1] + q[1]) / 2];
5625
+ const away = perspective ? [vp[0] - mid[0], vp[1] - mid[1]] : d;
5626
+ let n2 = [ey / len2, -ex / len2];
5627
+ if (n2[0] * away[0] + n2[1] * away[1] < 0) n2 = [-n2[0], -n2[1]];
5628
+ const shade = (n2[0] * light[0] + n2[1] * light[1]) * strength;
5629
+ const lp = across(p);
5630
+ const lq = across(q);
5631
+ faces.push({
5632
+ p,
5633
+ q,
5634
+ lo: Math.min(lp, lq),
5635
+ hi: Math.max(lp, lq),
5636
+ key: towardBack(p, q, (lp + lq) / 2),
5637
+ face: {
5638
+ shade,
5639
+ path: [{ type: "M", x: p[0], y: p[1] }, { type: "L", x: q[0], y: q[1] }, { type: "L", x: qb[0], y: qb[1] }, { type: "L", x: pb[0], y: pb[1] }, { type: "Z" }]
5640
+ }
5641
+ });
5642
+ }
5643
+ }
5644
+ faces.sort((a, b) => a.key - b.key);
5645
+ const n = faces.length;
5646
+ const after = faces.map(() => []);
5647
+ const before = new Array(n).fill(0);
5648
+ const eps = 1e-9;
5649
+ for (let i = 0; i < n; i++) {
5650
+ for (let j = i + 1; j < n; j++) {
5651
+ const lo = Math.max(faces[i].lo, faces[j].lo);
5652
+ const hi = Math.min(faces[i].hi, faces[j].hi);
5653
+ if (hi - lo <= eps * Math.max(1, Math.abs(hi))) continue;
5654
+ const l = (lo + hi) / 2;
5655
+ const di = towardBack(faces[i].p, faces[i].q, l);
5656
+ const dj = towardBack(faces[j].p, faces[j].q, l);
5657
+ if (Math.abs(di - dj) < 1e-9) continue;
5658
+ const [back0, front] = di < dj ? [i, j] : [j, i];
5659
+ after[back0].push(front);
5660
+ before[front]++;
5661
+ }
5662
+ }
5663
+ const order = [];
5664
+ const done = new Array(n).fill(false);
5665
+ let next = 0;
5666
+ while (order.length < n) {
5667
+ let pick = -1;
5668
+ for (let i = next; i < n; i++) {
5669
+ if (!done[i] && before[i] === 0) {
5670
+ pick = i;
5671
+ break;
5672
+ }
5673
+ }
5674
+ if (pick < 0) pick = done.indexOf(false);
5675
+ done[pick] = true;
5676
+ order.push(pick);
5677
+ for (const k of after[pick]) before[k]--;
5678
+ while (next < n && done[next]) next++;
5679
+ }
5680
+ return order.map((i) => faces[i].face);
5681
+ }
5682
+
5683
+ // src/vector/bevel.ts
5684
+ var MITER_LIMIT = 4;
5685
+ function crossing2(a, b, c, d) {
5686
+ const rx = b[0] - a[0];
5687
+ const ry = b[1] - a[1];
5688
+ const sx = d[0] - c[0];
5689
+ const sy = d[1] - c[1];
5690
+ const den = rx * sy - ry * sx;
5691
+ if (Math.abs(den) < 1e-12) return null;
5692
+ const t = ((c[0] - a[0]) * sy - (c[1] - a[1]) * sx) / den;
5693
+ const u = ((c[0] - a[0]) * ry - (c[1] - a[1]) * rx) / den;
5694
+ return t > 1e-9 && t <= 1 && u >= 0 && u <= 1 ? t : null;
5695
+ }
5696
+ function vectorBevelFaces(path, params, fillRule = "nonzero") {
5697
+ const width = Math.max(0, params.width);
5698
+ if (!path.length || width <= 0) return [];
5699
+ const rings = vectorPathRings(path, 0.25).filter((r) => r.length >= 3);
5700
+ const lr = params.lightAngle * Math.PI / 180;
5701
+ const light = [Math.cos(lr), Math.sin(lr)];
5702
+ const strength = Math.min(1, Math.max(0, params.shading / 100));
5703
+ const faces = [];
5704
+ for (const ring of rings) {
5705
+ const n = ring.length;
5706
+ let best = 0;
5707
+ let bestLen = -1;
5708
+ for (let i = 0; i < n; i++) {
5709
+ const q = ring[(i + 1) % n];
5710
+ const l = Math.hypot(q[0] - ring[i][0], q[1] - ring[i][1]);
5711
+ if (l > bestLen) [best, bestLen] = [i, l];
5712
+ }
5713
+ if (bestLen < 1e-9) continue;
5714
+ const bp = ring[best];
5715
+ const bq = ring[(best + 1) % n];
5716
+ const left2 = [-(bq[1] - bp[1]) / bestLen, (bq[0] - bp[0]) / bestLen];
5717
+ const probe = Math.min(bestLen / 4, 1e-3 * Math.max(1, bestLen));
5718
+ const sign = pointInRings([(bp[0] + bq[0]) / 2 + left2[0] * probe, (bp[1] + bq[1]) / 2 + left2[1] * probe], rings, fillRule) ? 1 : -1;
5719
+ const normals = ring.map((p, i) => {
5720
+ const q = ring[(i + 1) % n];
5721
+ const l = Math.hypot(q[0] - p[0], q[1] - p[1]);
5722
+ return l < 1e-9 ? null : [-(q[1] - p[1]) / l * sign, (q[0] - p[0]) / l * sign];
5723
+ });
5724
+ const normalAt = (i, step) => {
5725
+ for (let k = 0; k < n; k++) {
5726
+ const v2 = normals[((i + step * k) % n + n) % n];
5727
+ if (v2) return v2;
5728
+ }
5729
+ return [0, 0];
5730
+ };
5731
+ const inset = ring.map((p, i) => {
5732
+ const a = normalAt(i - 1, -1);
5733
+ const b = normalAt(i, 1);
5734
+ let bx = a[0] + b[0];
5735
+ let by = a[1] + b[1];
5736
+ const bl = Math.hypot(bx, by);
5737
+ if (bl < 1e-9) [bx, by] = [b[0], b[1]];
5738
+ else [bx, by] = [bx / bl, by / bl];
5739
+ const cos = bx * b[0] + by * b[1];
5740
+ let len2 = width / Math.max(cos, 1 / MITER_LIMIT);
5741
+ const end = [p[0] + bx * len2, p[1] + by * len2];
5742
+ let t = 1;
5743
+ for (const other of rings) {
5744
+ const m = other.length;
5745
+ for (let j = 0; j < m; j++) {
5746
+ const c = other[j];
5747
+ const d = other[(j + 1) % m];
5748
+ if (c === p || d === p) continue;
5749
+ const hit = crossing2(p, end, c, d);
5750
+ if (hit !== null && hit < t) t = hit;
5751
+ }
5752
+ }
5753
+ if (t < 1) len2 *= t / 2;
5754
+ return [p[0] + bx * len2, p[1] + by * len2];
5755
+ });
5756
+ for (let i = 0; i < n; i++) {
5757
+ const nrm = normals[i];
5758
+ if (!nrm) continue;
5759
+ const j = (i + 1) % n;
5760
+ const shade = (-nrm[0] * light[0] - nrm[1] * light[1]) * strength;
5761
+ faces.push({
5762
+ shade,
5763
+ path: [
5764
+ { type: "M", x: ring[i][0], y: ring[i][1] },
5765
+ { type: "L", x: ring[j][0], y: ring[j][1] },
5766
+ { type: "L", x: inset[j][0], y: inset[j][1] },
5767
+ { type: "L", x: inset[i][0], y: inset[i][1] },
5768
+ { type: "Z" }
5769
+ ]
5770
+ });
5771
+ }
5772
+ }
5773
+ return faces;
5774
+ }
5775
+
5776
+ // src/vector/lens.ts
5777
+ function isVectorLens(node) {
5778
+ return !!node && node.type === "path" && !!node.lens && VECTOR_LENS_TYPES.includes(node.lens.type);
5779
+ }
5780
+ var VECTOR_LENS_LABELS = {
5781
+ transparency: "Transparency",
5782
+ magnify: "Magnify",
5783
+ fisheye: "Fish Eye",
5784
+ brighten: "Brighten",
5785
+ invert: "Invert",
5786
+ tintedGrayscale: "Tinted Grayscale",
5787
+ colorAdd: "Color Add",
5788
+ colorLimit: "Color Limit",
5789
+ heatMap: "Heat Map",
5790
+ wireframe: "Wireframe"
5791
+ };
5792
+ var VECTOR_LENS_SPECS = {
5793
+ transparency: { min: 0, max: 100, amount: 50, color: null, unit: "percent see-through" },
5794
+ magnify: { min: 1, max: 20, amount: 2, color: null, unit: "times" },
5795
+ fisheye: { min: -100, max: 100, amount: 50, color: null, unit: "percent, negative pinches" },
5796
+ brighten: { min: -100, max: 100, amount: 40, color: null, unit: "percent, negative darkens" },
5797
+ invert: { min: 0, max: 100, amount: 100, color: null, unit: "percent strength" },
5798
+ tintedGrayscale: { min: 0, max: 100, amount: 100, color: "#b45309", unit: "percent strength" },
5799
+ colorAdd: { min: 0, max: 100, amount: 50, color: "#ff0000", unit: "percent of the colour added" },
5800
+ colorLimit: { min: 0, max: 100, amount: 100, color: "#22c55e", unit: "percent strength" },
5801
+ heatMap: { min: 0, max: 100, amount: 0, color: null, unit: "percent the palette is turned" },
5802
+ wireframe: { min: 0, max: 100, amount: 100, color: "#0f172a", unit: "percent outline opacity" }
5803
+ };
5804
+ function sanitizeVectorLens(value) {
5805
+ if (!value || typeof value !== "object") return null;
5806
+ const r = value;
5807
+ if (typeof r.type !== "string" || !VECTOR_LENS_TYPES.includes(r.type)) return null;
5808
+ const type = r.type;
5809
+ const spec = VECTOR_LENS_SPECS[type];
5810
+ const amount = typeof r.amount === "number" && Number.isFinite(r.amount) ? Math.min(spec.max, Math.max(spec.min, r.amount)) : spec.amount;
5811
+ const out = { type, amount };
5812
+ if (spec.color !== null) out.color = typeof r.color === "string" && parseVectorColor(r.color) ? r.color : spec.color;
5813
+ return out;
5814
+ }
5815
+ var hex22 = (v2) => Math.round(Math.min(1, Math.max(0, v2)) * 255).toString(16).padStart(2, "0");
5816
+ var formatRgba = (c) => c[3] >= 1 ? `#${hex22(c[0])}${hex22(c[1])}${hex22(c[2])}` : `rgba(${Math.round(c[0] * 255)}, ${Math.round(c[1] * 255)}, ${Math.round(c[2] * 255)}, ${Math.round(c[3] * 1e3) / 1e3})`;
5817
+ var luma = (c) => 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
5818
+ var mix = (a, b, t) => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t, a[3]];
5819
+ var HEAT = [
5820
+ [0, "#1e1b4b"],
5821
+ [0.25, "#2563eb"],
5822
+ [0.5, "#22c55e"],
5823
+ [0.7, "#facc15"],
5824
+ [0.85, "#f97316"],
5825
+ [1, "#dc2626"]
5826
+ ];
5827
+ var heatAt = (t) => {
5828
+ const u = (t % 1 + 1) % 1;
5829
+ for (let i = 1; i < HEAT.length; i++) {
5830
+ if (u <= HEAT[i][0]) {
5831
+ const a = parseVectorColor(HEAT[i - 1][1]);
5832
+ const b = parseVectorColor(HEAT[i][1]);
5833
+ const k = (u - HEAT[i - 1][0]) / (HEAT[i][0] - HEAT[i - 1][0]);
5834
+ return [0, 1, 2].map((c) => a[c] + (b[c] - a[c]) * k);
5835
+ }
5836
+ }
5837
+ return parseVectorColor(HEAT[HEAT.length - 1][1]).slice(0, 3);
5838
+ };
5839
+ function vectorLensColorMap(lens) {
5840
+ const tint = parseVectorColor(lens.color ?? "#000000") ?? [0, 0, 0, 1];
5841
+ const s = Math.min(1, Math.max(0, lens.amount / 100));
5842
+ switch (lens.type) {
5843
+ case "brighten": {
5844
+ const a = Math.min(1, Math.max(-1, lens.amount / 100));
5845
+ return (c) => a >= 0 ? mix(c, [1, 1, 1], a) : mix(c, [0, 0, 0], -a);
5846
+ }
5847
+ case "invert":
5848
+ return (c) => mix(c, [1 - c[0], 1 - c[1], 1 - c[2]], s);
5849
+ case "tintedGrayscale":
5850
+ return (c) => {
5851
+ const l = luma(c);
5852
+ const duo = l < 0.5 ? [tint[0] * 2 * l, tint[1] * 2 * l, tint[2] * 2 * l] : [0, 1, 2].map((k) => tint[k] + (1 - tint[k]) * (2 * l - 1));
5853
+ return mix(c, duo, s);
5854
+ };
5855
+ case "colorAdd":
5856
+ return (c) => [Math.min(1, c[0] + tint[0] * s), Math.min(1, c[1] + tint[1] * s), Math.min(1, c[2] + tint[2] * s), c[3]];
5857
+ case "colorLimit":
5858
+ return (c) => [c[0] * (1 - s + s * tint[0]), c[1] * (1 - s + s * tint[1]), c[2] * (1 - s + s * tint[2]), c[3]];
5859
+ case "heatMap":
5860
+ return (c) => [...heatAt(luma(c) + lens.amount / 100), c[3]];
5861
+ default:
5862
+ return null;
5863
+ }
5864
+ }
5865
+ function mapVectorPaintColors(paint, f) {
5866
+ const one = (color2) => {
5867
+ const c = parseVectorColor(color2);
5868
+ return c ? formatRgba(f(c)) : color2;
5869
+ };
5870
+ if (paint == null || paint === "none") return paint;
5871
+ if (typeof paint === "string") return one(paint);
5872
+ const p = paint;
5873
+ const out = { ...p };
5874
+ if (Array.isArray(p.stops)) out.stops = p.stops.map((s) => ({ ...s, color: one(s.color) }));
5875
+ if (Array.isArray(p.colors)) out.colors = p.colors.map(one);
5876
+ if (Array.isArray(p.points)) out.points = p.points.map((q) => typeof q.color === "string" ? { ...q, color: one(q.color) } : q);
5877
+ return out;
5878
+ }
5879
+ var drawnCache2 = /* @__PURE__ */ new WeakMap();
5880
+ var STYLE_OFF = { effects: void 0, transform: void 0, opacity: void 0, blendMode: void 0, filters: void 0, lens: void 0, lensView: void 0, connector: void 0 };
5881
+ function shapePath(shape, id, path, extra = {}) {
5882
+ const { id: _i, subpaths: _s, booleanOperation: _b, blendStep: _bs, locked: _l, visible: _v, ...style } = shape.source;
5883
+ return { ...style, ...STYLE_OFF, id, type: "path", subpaths: bezierToSubpaths(path), ...shape.opacity < 1 ? { opacity: shape.opacity } : {}, ...extra };
5884
+ }
5885
+ function vectorLensDrawn(node) {
5886
+ const hit = drawnCache2.get(node);
5887
+ if (hit) return hit;
5888
+ const { lens } = node;
5889
+ const own = subpathsToBezier(node.subpaths);
5890
+ const box = bezierPathBounds(own);
5891
+ const children = [];
5892
+ if (box && lens.type !== "transparency") {
5893
+ const c = { x: (box.minX + box.maxX) / 2, y: (box.minY + box.maxY) / 2 };
5894
+ const inv = node.transform && !isIdentityMatrix(node.transform) ? invertMatrix(node.transform) : null;
5895
+ const k = lens.type === "magnify" ? Math.max(1, lens.amount) : 1;
5896
+ const reach = { minX: c.x - (c.x - box.minX) / k, maxX: c.x + (box.maxX - c.x) / k, minY: c.y - (c.y - box.minY) / k, maxY: c.y + (box.maxY - c.y) / k };
5897
+ let map = null;
5898
+ if (lens.type === "magnify") {
5899
+ const m = [k, 0, 0, k, c.x * (1 - k), c.y * (1 - k)];
5900
+ map = (p) => transformBezierPath(p, m);
5901
+ } else if (lens.type === "fisheye") {
5902
+ const a = Math.min(100, Math.max(-100, lens.amount));
5903
+ const gamma = a >= 0 ? 1 / (1 + a / 25) : 1 - a / 25;
5904
+ const rx = Math.max(1e-9, (box.maxX - box.minX) / 2);
5905
+ const ry = Math.max(1e-9, (box.maxY - box.minY) / 2);
5906
+ const warp = (p) => {
5907
+ const dx = (p.x - c.x) / rx;
5908
+ const dy = (p.y - c.y) / ry;
5909
+ const u = Math.hypot(dx, dy);
5910
+ if (u >= 1 || u < 1e-12) return p;
5911
+ const f = u ** gamma / u;
5912
+ return { x: c.x + dx * f * rx, y: c.y + dy * f * ry };
5913
+ };
5914
+ map = (p) => mapBezierPath(p, warp, 0.25);
5915
+ }
5916
+ const recolour = vectorLensColorMap(lens);
5917
+ const wire = lens.type === "wireframe" ? lens.color ?? "#000000" : null;
5918
+ const contents = [];
5919
+ (node.lensView ?? []).forEach((below, i) => {
5920
+ for (const shape of vectorChildAppearanceShapes(below, i)) {
5921
+ const path = inv ? transformBezierPath(shape.path, inv) : shape.path;
5922
+ const b = bezierPathBounds(path);
5923
+ if (!b || b.maxX < reach.minX || b.minX > reach.maxX || b.maxY < reach.minY || b.minY > reach.maxY) continue;
5924
+ const id = `${node.id}~lens${contents.length}`;
5925
+ const changed = map ? map(path) : path;
5926
+ if (wire) {
5927
+ contents.push(shapePath(shape, id, changed, { fill: null, fills: void 0, stroke: wire, strokes: void 0, strokeWidth: 1, strokeAlign: void 0, strokeDasharray: void 0, strokeWidthProfile: void 0, opacity: Math.min(1, Math.max(0, lens.amount / 100)) }));
5928
+ } else if (recolour) {
5929
+ const fills = shape.source.fills?.map((l) => ({ ...l, paint: mapVectorPaintColors(l.paint, recolour) ?? null }));
5930
+ const strokes = shape.source.strokes?.map((l) => ({ ...l, paint: mapVectorPaintColors(l.paint, recolour) ?? null }));
5931
+ contents.push(shapePath(shape, id, changed, { fill: mapVectorPaintColors(shape.source.fill, recolour) ?? null, stroke: mapVectorPaintColors(shape.source.stroke, recolour) ?? null, ...fills ? { fills } : {}, ...strokes ? { strokes } : {} }));
5932
+ } else contents.push(shapePath(shape, id, changed));
5933
+ }
5934
+ });
5935
+ if (contents.length) {
5936
+ const outline = { id: `${node.id}~lens-clip`, type: "path", subpaths: node.subpaths, fill: "#000000", stroke: null, ...node.fillRule ? { fillRule: node.fillRule } : {} };
5937
+ children.push({ id: `${node.id}~lens-view`, type: "group", mask: { type: "clip" }, children: [outline, ...contents] });
5938
+ }
5939
+ }
5940
+ const { lens: _l, lensView: _v, transform: _t, opacity: _o, effects: _e, blendMode: _bm, filters: _f, ...style } = node;
5941
+ const fillOpacity = lens.type === "transparency" ? 1 - Math.min(100, Math.max(0, lens.amount)) / 100 : 0;
5942
+ children.push({ ...style, id: `${node.id}~lens-fill`, stroke: null, strokes: void 0, opacity: fillOpacity });
5943
+ const stroked = (node.strokes?.length ?? 0) > 0 || node.stroke != null && node.stroke !== "none";
5944
+ if (stroked) children.push({ ...style, id: `${node.id}~lens-stroke`, fill: null, fills: void 0 });
5945
+ const out = {
5946
+ id: node.id,
5947
+ type: "group",
5948
+ ...node.name !== void 0 ? { name: node.name } : {},
5949
+ ...node.transform ? { transform: node.transform } : {},
5950
+ ...node.opacity !== void 0 ? { opacity: node.opacity } : {},
5951
+ ...node.blendMode ? { blendMode: node.blendMode } : {},
5952
+ ...node.filters?.length ? { filters: node.filters } : {},
5953
+ children
5954
+ };
5955
+ drawnCache2.set(node, out);
5956
+ return out;
5957
+ }
5958
+ var sameMatrix = (a, b) => !a && !b || !!a && !!b && a.every((v2, i) => Math.abs(v2 - b[i]) < 1e-12);
5959
+ function sameView(a, b) {
5960
+ if (!a || a.length !== b.length) return false;
5961
+ return a.every((n, i) => {
5962
+ const m = b[i];
5963
+ if (n === m) return true;
5964
+ return n.type === "group" && m.type === "group" && n.id === m.id && n.id.endsWith("~below") && sameMatrix(n.transform, m.transform) && sameView(n.children, m.children);
5965
+ });
5966
+ }
5967
+ function hasLens(nodes) {
5968
+ return nodes.some((n) => isVectorLens(n) || n.type === "group" && hasLens(n.children));
5969
+ }
5970
+ function resolveVectorLenses(doc) {
5971
+ if (!hasLens(doc.nodes)) return doc;
5972
+ let changed = false;
5973
+ const walk = (list, outer, depth) => {
5974
+ const below = outer.slice();
5975
+ const out = list.map((n) => {
5976
+ let next = n;
5977
+ if (isVectorLens(n)) {
5978
+ if (!sameView(n.lensView, below)) next = { ...n, lensView: below.slice() };
5979
+ } else if (n.type === "group" && hasLens(n.children)) {
5980
+ const m = n.transform && !isIdentityMatrix(n.transform) ? invertMatrix(n.transform) : null;
5981
+ const inner = below.length ? m ? [{ id: `${n.id}:${depth}~below`, type: "group", transform: m, children: below.slice() }] : below.slice() : [];
5982
+ const children = walk(n.children, inner, depth + 1);
5983
+ if (children !== n.children) next = { ...n, children };
5984
+ }
5985
+ if (next !== n) changed = true;
5986
+ below.push(next);
5987
+ return next;
5988
+ });
5989
+ return out.some((n, i) => n !== list[i]) ? out : list;
5990
+ };
5991
+ const nodes = walk(doc.nodes, [], 0);
5992
+ return changed ? { ...doc, nodes } : doc;
5993
+ }
5994
+ function stripVectorLensViews(doc) {
5995
+ if (!hasLens(doc.nodes)) return doc;
5996
+ const strip2 = (list) => list.map((n) => {
5997
+ if (n.type === "path" && n.lensView) {
5998
+ const { lensView: _v, ...rest } = n;
5999
+ return rest;
6000
+ }
6001
+ if (n.type === "group") return { ...n, children: strip2(n.children) };
6002
+ return n;
6003
+ });
6004
+ return { ...doc, nodes: strip2(doc.nodes) };
6005
+ }
6006
+
5553
6007
  // src/geom/warp.ts
5554
6008
  var WARP_STYLES = [
5555
6009
  "arc",
@@ -6269,7 +6723,9 @@ var VECTOR_EFFECT_DEFAULTS = {
6269
6723
  },
6270
6724
  envelope: { style: "arc", bend: 50, horizontal: 0, vertical: 0, orientation: "horizontal", rows: 2, columns: 2, mesh: null },
6271
6725
  contour: { direction: "inside", steps: 4, offset: 6, join: "round", miterLimit: 4, fillColor: "#ffffff", strokeColor: null, acceleration: 0 },
6272
- blockShadow: { angle: 45, distance: 20, color: "#1e293b", opacity: 100, endOpacity: 100 }
6726
+ blockShadow: { angle: 45, distance: 20, color: "#1e293b", opacity: 100, endOpacity: 100 },
6727
+ extrude: { mode: "parallel", angle: 45, depth: 30, vanishingPoint: { x: 0, y: -300 }, toward: 30, color: null, lightAngle: -135, shading: 60 },
6728
+ bevel: { width: 8, lightAngle: -135, shading: 60, color: null }
6273
6729
  };
6274
6730
  var VECTOR_EFFECT_LABELS = {
6275
6731
  trim: "Trim Paths",
@@ -6283,7 +6739,9 @@ var VECTOR_EFFECT_LABELS = {
6283
6739
  repeater: "Repeater",
6284
6740
  envelope: "Envelope",
6285
6741
  contour: "Contour",
6286
- blockShadow: "Block Shadow"
6742
+ blockShadow: "Block Shadow",
6743
+ extrude: "Extrude",
6744
+ bevel: "Bevel"
6287
6745
  };
6288
6746
  var VECTOR_EFFECT_PARAM_SPECS = {
6289
6747
  trim: [
@@ -6385,6 +6843,30 @@ var VECTOR_EFFECT_PARAM_SPECS = {
6385
6843
  { key: "opacity", label: "Opacity %", kind: "number", min: 0, max: 100, step: 1, slider: true },
6386
6844
  { key: "endOpacity", label: "End opacity %", kind: "number", min: 0, max: 100, step: 1, slider: true }
6387
6845
  ],
6846
+ extrude: [
6847
+ {
6848
+ key: "mode",
6849
+ label: "Mode",
6850
+ kind: "select",
6851
+ options: [
6852
+ { value: "parallel", label: "Parallel" },
6853
+ { value: "perspective", label: "Perspective" }
6854
+ ]
6855
+ },
6856
+ { key: "angle", label: "Angle \xB0", kind: "number", min: -360, max: 360, step: 1, slider: true },
6857
+ { key: "depth", label: "Depth", kind: "number", min: 0, max: 2e3, step: 1, slider: true },
6858
+ { key: "vanishingPoint", label: "Vanishing point", kind: "vec2", step: 1 },
6859
+ { key: "toward", label: "Toward VP %", kind: "number", min: 0, max: 100, step: 1, slider: true },
6860
+ { key: "color", label: "Colour", kind: "color" },
6861
+ { key: "lightAngle", label: "Light \xB0", kind: "number", min: -360, max: 360, step: 1, slider: true },
6862
+ { key: "shading", label: "Shading %", kind: "number", min: 0, max: 100, step: 1, slider: true }
6863
+ ],
6864
+ bevel: [
6865
+ { key: "width", label: "Width", kind: "number", min: 0, max: 500, step: 0.5, slider: true },
6866
+ { key: "lightAngle", label: "Light \xB0", kind: "number", min: -360, max: 360, step: 1, slider: true },
6867
+ { key: "shading", label: "Shading %", kind: "number", min: 0, max: 100, step: 1, slider: true },
6868
+ { key: "color", label: "Colour", kind: "color" }
6869
+ ],
6388
6870
  repeater: [
6389
6871
  { key: "copies", label: "Copies", kind: "number", min: 0, max: 50, step: 0.1, slider: true },
6390
6872
  { key: "offset", label: "Offset", kind: "number", min: -10, max: 10, step: 0.1, slider: true },
@@ -6500,7 +6982,7 @@ function activeVectorEffects(node) {
6500
6982
  return node.effects?.filter(isEnabled) ?? [];
6501
6983
  }
6502
6984
  function hasOwnVectorAppearance(node) {
6503
- return node.type === "text" || node.type === "instance" || node.type === "group" && !!node.liveBoolean || isVectorFrame(node) || isVectorSymmetryGroup(node) || !!node.effects?.some(isEnabled);
6985
+ return node.type === "text" || node.type === "instance" || node.type === "group" && !!node.liveBoolean || isVectorFrame(node) || isVectorSymmetryGroup(node) || isVectorLens(node) || !!node.effects?.some(isEnabled);
6504
6986
  }
6505
6987
  var liveCache = /* @__PURE__ */ new WeakMap();
6506
6988
  function hasVectorAppearance(node) {
@@ -6701,6 +7183,43 @@ function blockShadowShapes(shapes, b) {
6701
7183
  }
6702
7184
  return [...shadows, ...shapes.map((s) => ({ ...s, order: [1, ...s.order] }))];
6703
7185
  }
7186
+ function extrudeShapes(shapes, x) {
7187
+ const out = [];
7188
+ for (const s of shapes) {
7189
+ const base = x.color ?? vectorPaintSolid(s.source.fill) ?? "#808080";
7190
+ vectorExtrudeFaces(s.path, x).forEach((f, k) => {
7191
+ const color2 = shadeVectorColor(base, f.shade);
7192
+ const source = { ...s.source, fill: color2, stroke: color2, strokeWidth: 0.5, strokeLinejoin: "round", strokeAlign: void 0, fills: void 0, strokes: void 0, fillRule: "nonzero", startArrow: void 0, endArrow: void 0, strokeDasharray: void 0, strokeWidthProfile: void 0, filters: void 0 };
7193
+ out.push({ source, path: f.path, opacity: s.opacity, order: [...s.order, 0, k] });
7194
+ });
7195
+ out.push({ ...s, order: [...s.order, 1] });
7196
+ }
7197
+ return out;
7198
+ }
7199
+ function bevelShapes(shapes, b) {
7200
+ const out = [];
7201
+ for (const s of shapes) {
7202
+ const fillRule = s.source.fillRule === "evenodd" ? "evenodd" : "nonzero";
7203
+ const faces = vectorBevelFaces(s.path, b, fillRule);
7204
+ if (!faces.length) {
7205
+ out.push(s);
7206
+ continue;
7207
+ }
7208
+ const base = b.color ?? vectorPaintSolid(s.source.fill) ?? "#808080";
7209
+ const fillOnly = { ...s.source, stroke: null, strokes: void 0 };
7210
+ out.push({ ...s, source: fillOnly, order: [...s.order, 0] });
7211
+ faces.forEach((f, k) => {
7212
+ const color2 = shadeVectorColor(base, f.shade);
7213
+ const source = { ...s.source, fill: color2, stroke: color2, strokeWidth: 0.5, strokeLinejoin: "round", strokeAlign: void 0, fills: void 0, strokes: void 0, fillRule: "nonzero", startArrow: void 0, endArrow: void 0, strokeDasharray: void 0, strokeWidthProfile: void 0, filters: void 0 };
7214
+ out.push({ source, path: f.path, opacity: s.opacity, order: [...s.order, 1, k] });
7215
+ });
7216
+ const [middle] = offsetPaths([s.path], -b.width, "miter", 4, 1, 0);
7217
+ if (middle?.length) out.push({ ...s, source: fillOnly, path: middle, order: [...s.order, 2] });
7218
+ const hasStroke = s.source.strokes?.length || s.source.stroke != null && s.source.stroke !== "none";
7219
+ if (hasStroke) out.push({ ...s, source: { ...s.source, fill: null, fills: void 0 }, order: [...s.order, 3] });
7220
+ }
7221
+ return out;
7222
+ }
6704
7223
  function applyVectorEffects(shapes, effects) {
6705
7224
  let list = shapes.slice();
6706
7225
  for (const e of effects ?? []) {
@@ -6747,6 +7266,12 @@ function applyVectorEffects(shapes, effects) {
6747
7266
  case "blockShadow":
6748
7267
  list = blockShadowShapes(list, e.params);
6749
7268
  break;
7269
+ case "extrude":
7270
+ list = extrudeShapes(list, e.params);
7271
+ break;
7272
+ case "bevel":
7273
+ list = bevelShapes(list, e.params);
7274
+ break;
6750
7275
  case "repeater": {
6751
7276
  const r = e.params;
6752
7277
  const copies = repeatPaths(
@@ -6903,8 +7428,8 @@ function expandVectorAppearance(node) {
6903
7428
  expandCache.set(node, [vectorTextShaperGeneration(), drawn]);
6904
7429
  return drawn;
6905
7430
  }
6906
- if (isVectorFrame(node) || isVectorSymmetryGroup(node)) {
6907
- const drawn = isVectorFrame(node) ? vectorFrameDrawn(node) : vectorSymmetryDrawn(node);
7431
+ if (isVectorFrame(node) || isVectorSymmetryGroup(node) || isVectorLens(node)) {
7432
+ const drawn = isVectorFrame(node) ? vectorFrameDrawn(node) : isVectorLens(node) ? vectorLensDrawn(node) : vectorSymmetryDrawn(node);
6908
7433
  const out2 = hasVectorAppearance(drawn) ? expandVectorAppearance(drawn) : drawn;
6909
7434
  expandCache.set(node, [vectorTextShaperGeneration(), out2]);
6910
7435
  return out2;
@@ -7619,7 +8144,7 @@ function blendFromAttribute(value, m) {
7619
8144
  return out;
7620
8145
  }
7621
8146
  function vectorDocumentToSvg(doc, options = {}) {
7622
- doc = resolveVectorSymbols(doc);
8147
+ doc = resolveVectorLenses(resolveVectorSymbols(doc));
7623
8148
  const precision = options.precision ?? 3;
7624
8149
  const prefix = options.idPrefix ?? "vg-";
7625
8150
  const pretty = options.pretty !== false;
@@ -7638,6 +8163,7 @@ function vectorDocumentToSvg(doc, options = {}) {
7638
8163
  if (node.resizing) out2 += ` data-vector-resizing="${escapeAttr2(JSON.stringify(node.resizing))}"`;
7639
8164
  if (node.type === "path" && isVectorShadedPaint(node.fill)) out2 += ` data-vector-shading="${escapeAttr2(JSON.stringify(node.fill))}"`;
7640
8165
  if (node.type === "path" && node.connector) out2 += ` data-vector-connector="${escapeAttr2(JSON.stringify(node.connector))}"`;
8166
+ if (node.type === "path" && node.lens) out2 += ` data-vector-lens="${escapeAttr2(JSON.stringify(node.lens))}"`;
7641
8167
  const blend = vectorBlendModeCss(node.blendMode);
7642
8168
  if (blend) out2 += ` style="mix-blend-mode:${blend}"`;
7643
8169
  if (node.filters?.length) {
@@ -7909,11 +8435,11 @@ function vectorDocumentToSvg(doc, options = {}) {
7909
8435
  };
7910
8436
  lines.push(`${indent(depth)}<g${common(node)} data-vector-live="${escapeAttr2(JSON.stringify(live2))}">`);
7911
8437
  lines.push(`${indent(depth + 1)}<g data-vector-part="appearance">`);
7912
- for (const shape of vectorAppearanceNodes(node)) emit2(shape, depth + 2);
8438
+ for (const shape of isVectorLens(node) ? vectorLensDrawn(node).children : vectorAppearanceNodes(node)) emit2(shape, depth + 2);
7913
8439
  lines.push(`${indent(depth + 1)}</g>`);
7914
8440
  lines.push(`${indent(depth + 1)}<g data-vector-part="source" display="none">`);
7915
8441
  if (node.type === "path") {
7916
- const { effects: _e, transform: _t, opacity: _o, visible: _v, booleanOperation: _b, blendStep: _s, blendMode: _bm, filters: _f, ...source } = node;
8442
+ const { effects: _e, transform: _t, opacity: _o, visible: _v, booleanOperation: _b, blendStep: _s, blendMode: _bm, filters: _f, lens: _l, lensView: _lv, ...source } = node;
7917
8443
  emit2({ ...source, id: `${node.id}~src` }, depth + 2);
7918
8444
  } else for (const child of node.children) emit2(child, depth + 2);
7919
8445
  lines.push(`${indent(depth + 1)}</g>`);
@@ -8740,6 +9266,8 @@ function parseVectorSvg(svg, options = {}) {
8740
9266
  if (resizing) meta.resizing = resizing;
8741
9267
  const connector = child.attrs["data-vector-connector"] !== void 0 ? sanitizeVectorConnector(parseJson(child.attrs["data-vector-connector"])) : null;
8742
9268
  if (connector) meta.connector = connector;
9269
+ const lens = child.attrs["data-vector-lens"] !== void 0 ? sanitizeVectorLens(parseJson(child.attrs["data-vector-lens"])) : null;
9270
+ if (lens) meta.lens = lens;
8743
9271
  if (child.name === "g" && child.attrs["data-vector-frame"] !== void 0) {
8744
9272
  const node2 = frameGroup(child, s, m, meta);
8745
9273
  if (node2) out.push(node2);
@@ -9518,14 +10046,14 @@ function renamed(node, k) {
9518
10046
  if (node.type === "group") return { ...node, id, children: node.children.map((c) => renamed(c, k)) };
9519
10047
  return { ...node, id };
9520
10048
  }
9521
- var drawnCache2 = /* @__PURE__ */ new WeakMap();
10049
+ var drawnCache3 = /* @__PURE__ */ new WeakMap();
9522
10050
  function vectorSymmetryDrawn(node) {
9523
- let hit = drawnCache2.get(node);
10051
+ let hit = drawnCache3.get(node);
9524
10052
  if (hit) return hit;
9525
10053
  const { symmetry, ...group } = node;
9526
10054
  const copies = vectorSymmetryMatrices(symmetry).flatMap((m, k) => node.children.map((c) => ({ ...renamed(transformVectorNode(c, m), k + 1), locked: true })));
9527
10055
  hit = { ...group, children: [...node.children, ...copies] };
9528
- drawnCache2.set(node, hit);
10056
+ drawnCache3.set(node, hit);
9529
10057
  return hit;
9530
10058
  }
9531
10059
  function vectorSymmetryAxes(s, box) {
@@ -9614,6 +10142,7 @@ export {
9614
10142
  VECTOR_BLEND_MODES,
9615
10143
  VECTOR_HORIZONTAL_RESIZING,
9616
10144
  VECTOR_VERTICAL_RESIZING,
10145
+ VECTOR_LENS_TYPES,
9617
10146
  VECTOR_CONNECTOR_SIDES,
9618
10147
  VECTOR_CONNECTOR_ROUTES,
9619
10148
  VECTOR_BLEND_SPACINGS,
@@ -9909,6 +10438,20 @@ export {
9909
10438
  prefixVectorIds,
9910
10439
  vectorInstanceGroup,
9911
10440
  composeVectorMatrices,
10441
+ vectorPaintSolid,
10442
+ shadeVectorColor,
10443
+ vectorPathRings,
10444
+ vectorExtrudeFaces,
10445
+ vectorBevelFaces,
10446
+ isVectorLens,
10447
+ VECTOR_LENS_LABELS,
10448
+ VECTOR_LENS_SPECS,
10449
+ sanitizeVectorLens,
10450
+ vectorLensColorMap,
10451
+ mapVectorPaintColors,
10452
+ vectorLensDrawn,
10453
+ resolveVectorLenses,
10454
+ stripVectorLensViews,
9912
10455
  WARP_STYLES,
9913
10456
  WARP_STYLE_LABELS,
9914
10457
  warpPresetGrid,
@@ -10037,4 +10580,4 @@ export {
10037
10580
  lineSubpath,
10038
10581
  roundSubpaths
10039
10582
  };
10040
- //# sourceMappingURL=chunk-ROZFX4QI.js.map
10583
+ //# sourceMappingURL=chunk-IEYXYMRQ.js.map