@pixerate/editor 0.130.0 → 0.132.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 (72) hide show
  1. package/dist/animation-editor/index.cjs +55 -55
  2. package/dist/animation-editor/index.d.cts +4 -4
  3. package/dist/animation-editor/index.d.ts +4 -4
  4. package/dist/animation-editor/index.js +2 -2
  5. package/dist/{bezier-CigmusV_.d.ts → bezier-0IHDCvv_.d.ts} +1 -1
  6. package/dist/{bezier-CdoGygwG.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-PMHPXCJC.cjs → chunk-55UEZIU4.cjs} +119 -90
  10. package/dist/chunk-55UEZIU4.cjs.map +1 -0
  11. package/dist/{chunk-L5OTIYOO.js → chunk-ECVI5QRE.js} +2 -2
  12. package/dist/{chunk-ERYGCA72.js → chunk-G5FX56KX.js} +39 -10
  13. package/dist/{chunk-ERYGCA72.js.map → chunk-G5FX56KX.js.map} +1 -1
  14. package/dist/{chunk-PRYMC442.js → chunk-IEYXYMRQ.js} +255 -10
  15. package/dist/chunk-IEYXYMRQ.js.map +1 -0
  16. package/dist/{chunk-2PXRKMOH.cjs → chunk-OYPJGGF3.cjs} +36 -36
  17. package/dist/{chunk-2PXRKMOH.cjs.map → chunk-OYPJGGF3.cjs.map} +1 -1
  18. package/dist/{chunk-LXGOYRPE.cjs → chunk-YYJKIESX.cjs} +320 -75
  19. package/dist/chunk-YYJKIESX.cjs.map +1 -0
  20. package/dist/effects/index.d.cts +4 -4
  21. package/dist/effects/index.d.ts +4 -4
  22. package/dist/{export-B4r8b9Ft.d.ts → export-ByJvAvR7.d.ts} +26 -4
  23. package/dist/{export-5WDKJqTy.d.cts → export-CfAogLEr.d.cts} +1 -1
  24. package/dist/{export-CU_ARP3A.d.ts → export-Crl82sbE.d.ts} +1 -1
  25. package/dist/{export-CejjC2iI.d.cts → export-D-gkjBkB.d.cts} +26 -4
  26. package/dist/{helpers-X_rycLNJ.d.ts → helpers-BCd2-PAR.d.ts} +34 -1
  27. package/dist/{helpers-CzZu51eI.d.cts → helpers-CoIeXQnW.d.cts} +34 -1
  28. package/dist/image-editor/index.cjs +775 -723
  29. package/dist/image-editor/index.cjs.map +1 -1
  30. package/dist/image-editor/index.d.cts +8 -8
  31. package/dist/image-editor/index.d.ts +8 -8
  32. package/dist/image-editor/index.js +59 -7
  33. package/dist/image-editor/index.js.map +1 -1
  34. package/dist/index.cjs +11 -4
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.js +11 -4
  37. package/dist/index.js.map +1 -1
  38. package/dist/{opentype-DlRMYcCW.d.cts → opentype-BDahNRTe.d.cts} +1 -1
  39. package/dist/{opentype-CrHAsKh3.d.ts → opentype-BQFEvy-t.d.ts} +1 -1
  40. package/dist/paint-editor/index.cjs +7 -7
  41. package/dist/paint-editor/index.d.cts +5 -5
  42. package/dist/paint-editor/index.d.ts +5 -5
  43. package/dist/paint-editor/index.js +2 -2
  44. package/dist/{pathfinder-CKfKOVP4.d.cts → pathfinder-01ZgAwqV.d.cts} +1 -1
  45. package/dist/{pathfinder-Dlss70hL.d.ts → pathfinder-DaVdT8jq.d.ts} +1 -1
  46. package/dist/{pool-DDOo0xJH.d.ts → pool-D2A3WTt9.d.ts} +1 -1
  47. package/dist/{pool-DKic69LD.d.cts → pool-D6a45MoE.d.cts} +1 -1
  48. package/dist/{svg-BRaii3pI.d.cts → svg-CcDz7Zq2.d.cts} +2 -2
  49. package/dist/{svg-BYVZeVo0.d.ts → svg-DELNVerw.d.ts} +2 -2
  50. package/dist/{tools-CtheDLDr.d.cts → tools-BFvkFnRj.d.cts} +1 -1
  51. package/dist/{tools-D8bZ-7YG.d.ts → tools-D7ws-OKL.d.ts} +1 -1
  52. package/dist/vector/index.cjs +1136 -1014
  53. package/dist/vector/index.cjs.map +1 -1
  54. package/dist/vector/index.d.cts +63 -10
  55. package/dist/vector/index.d.ts +63 -10
  56. package/dist/vector/index.js +129 -7
  57. package/dist/vector/index.js.map +1 -1
  58. package/dist/video-editor/index.d.cts +4 -4
  59. package/dist/video-editor/index.d.ts +4 -4
  60. package/dist/{warp-CZVC8pB5.d.ts → warp-2N9wkOkL.d.ts} +1 -1
  61. package/dist/{warp-BFoYxy_s.d.cts → warp-DErXW5rz.d.cts} +1 -1
  62. package/package.json +2 -2
  63. package/skills/pixerate-image-editor/SKILL.md +6 -2
  64. package/skills/pixerate-image-editor/references/color-management.md +1 -1
  65. package/skills/pixerate-image-editor/references/photoshop-files.md +2 -2
  66. package/skills/pixerate-image-editor/references/retouching.md +9 -1
  67. package/skills/pixerate-vector/SKILL.md +17 -0
  68. package/skills/pixerate-vector/references/commands.md +19 -0
  69. package/dist/chunk-LXGOYRPE.cjs.map +0 -1
  70. package/dist/chunk-PMHPXCJC.cjs.map +0 -1
  71. package/dist/chunk-PRYMC442.js.map +0 -1
  72. /package/dist/{chunk-L5OTIYOO.js.map → chunk-ECVI5QRE.js.map} +0 -0
@@ -74,6 +74,7 @@ var VECTOR_BLEND_MODES = [
74
74
  ];
75
75
  var VECTOR_HORIZONTAL_RESIZING = ["left", "right", "leftRight", "center", "scale"];
76
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"];
77
78
  var VECTOR_CONNECTOR_SIDES = ["auto", "top", "right", "bottom", "left", "center"];
78
79
  var VECTOR_CONNECTOR_ROUTES = ["straight", "elbow", "curved"];
79
80
  var VECTOR_BLEND_SPACINGS = ["steps", "distance", "smoothColor"];
@@ -5772,6 +5773,237 @@ function vectorBevelFaces(path, params, fillRule = "nonzero") {
5772
5773
  return faces;
5773
5774
  }
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
+
5775
6007
  // src/geom/warp.ts
5776
6008
  var WARP_STYLES = [
5777
6009
  "arc",
@@ -6750,7 +6982,7 @@ function activeVectorEffects(node) {
6750
6982
  return node.effects?.filter(isEnabled) ?? [];
6751
6983
  }
6752
6984
  function hasOwnVectorAppearance(node) {
6753
- 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);
6754
6986
  }
6755
6987
  var liveCache = /* @__PURE__ */ new WeakMap();
6756
6988
  function hasVectorAppearance(node) {
@@ -7196,8 +7428,8 @@ function expandVectorAppearance(node) {
7196
7428
  expandCache.set(node, [vectorTextShaperGeneration(), drawn]);
7197
7429
  return drawn;
7198
7430
  }
7199
- if (isVectorFrame(node) || isVectorSymmetryGroup(node)) {
7200
- 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);
7201
7433
  const out2 = hasVectorAppearance(drawn) ? expandVectorAppearance(drawn) : drawn;
7202
7434
  expandCache.set(node, [vectorTextShaperGeneration(), out2]);
7203
7435
  return out2;
@@ -7912,7 +8144,7 @@ function blendFromAttribute(value, m) {
7912
8144
  return out;
7913
8145
  }
7914
8146
  function vectorDocumentToSvg(doc, options = {}) {
7915
- doc = resolveVectorSymbols(doc);
8147
+ doc = resolveVectorLenses(resolveVectorSymbols(doc));
7916
8148
  const precision = options.precision ?? 3;
7917
8149
  const prefix = options.idPrefix ?? "vg-";
7918
8150
  const pretty = options.pretty !== false;
@@ -7931,6 +8163,7 @@ function vectorDocumentToSvg(doc, options = {}) {
7931
8163
  if (node.resizing) out2 += ` data-vector-resizing="${escapeAttr2(JSON.stringify(node.resizing))}"`;
7932
8164
  if (node.type === "path" && isVectorShadedPaint(node.fill)) out2 += ` data-vector-shading="${escapeAttr2(JSON.stringify(node.fill))}"`;
7933
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))}"`;
7934
8167
  const blend = vectorBlendModeCss(node.blendMode);
7935
8168
  if (blend) out2 += ` style="mix-blend-mode:${blend}"`;
7936
8169
  if (node.filters?.length) {
@@ -8202,11 +8435,11 @@ function vectorDocumentToSvg(doc, options = {}) {
8202
8435
  };
8203
8436
  lines.push(`${indent(depth)}<g${common(node)} data-vector-live="${escapeAttr2(JSON.stringify(live2))}">`);
8204
8437
  lines.push(`${indent(depth + 1)}<g data-vector-part="appearance">`);
8205
- 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);
8206
8439
  lines.push(`${indent(depth + 1)}</g>`);
8207
8440
  lines.push(`${indent(depth + 1)}<g data-vector-part="source" display="none">`);
8208
8441
  if (node.type === "path") {
8209
- 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;
8210
8443
  emit2({ ...source, id: `${node.id}~src` }, depth + 2);
8211
8444
  } else for (const child of node.children) emit2(child, depth + 2);
8212
8445
  lines.push(`${indent(depth + 1)}</g>`);
@@ -9033,6 +9266,8 @@ function parseVectorSvg(svg, options = {}) {
9033
9266
  if (resizing) meta.resizing = resizing;
9034
9267
  const connector = child.attrs["data-vector-connector"] !== void 0 ? sanitizeVectorConnector(parseJson(child.attrs["data-vector-connector"])) : null;
9035
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;
9036
9271
  if (child.name === "g" && child.attrs["data-vector-frame"] !== void 0) {
9037
9272
  const node2 = frameGroup(child, s, m, meta);
9038
9273
  if (node2) out.push(node2);
@@ -9811,14 +10046,14 @@ function renamed(node, k) {
9811
10046
  if (node.type === "group") return { ...node, id, children: node.children.map((c) => renamed(c, k)) };
9812
10047
  return { ...node, id };
9813
10048
  }
9814
- var drawnCache2 = /* @__PURE__ */ new WeakMap();
10049
+ var drawnCache3 = /* @__PURE__ */ new WeakMap();
9815
10050
  function vectorSymmetryDrawn(node) {
9816
- let hit = drawnCache2.get(node);
10051
+ let hit = drawnCache3.get(node);
9817
10052
  if (hit) return hit;
9818
10053
  const { symmetry, ...group } = node;
9819
10054
  const copies = vectorSymmetryMatrices(symmetry).flatMap((m, k) => node.children.map((c) => ({ ...renamed(transformVectorNode(c, m), k + 1), locked: true })));
9820
10055
  hit = { ...group, children: [...node.children, ...copies] };
9821
- drawnCache2.set(node, hit);
10056
+ drawnCache3.set(node, hit);
9822
10057
  return hit;
9823
10058
  }
9824
10059
  function vectorSymmetryAxes(s, box) {
@@ -9907,6 +10142,7 @@ export {
9907
10142
  VECTOR_BLEND_MODES,
9908
10143
  VECTOR_HORIZONTAL_RESIZING,
9909
10144
  VECTOR_VERTICAL_RESIZING,
10145
+ VECTOR_LENS_TYPES,
9910
10146
  VECTOR_CONNECTOR_SIDES,
9911
10147
  VECTOR_CONNECTOR_ROUTES,
9912
10148
  VECTOR_BLEND_SPACINGS,
@@ -10207,6 +10443,15 @@ export {
10207
10443
  vectorPathRings,
10208
10444
  vectorExtrudeFaces,
10209
10445
  vectorBevelFaces,
10446
+ isVectorLens,
10447
+ VECTOR_LENS_LABELS,
10448
+ VECTOR_LENS_SPECS,
10449
+ sanitizeVectorLens,
10450
+ vectorLensColorMap,
10451
+ mapVectorPaintColors,
10452
+ vectorLensDrawn,
10453
+ resolveVectorLenses,
10454
+ stripVectorLensViews,
10210
10455
  WARP_STYLES,
10211
10456
  WARP_STYLE_LABELS,
10212
10457
  warpPresetGrid,
@@ -10335,4 +10580,4 @@ export {
10335
10580
  lineSubpath,
10336
10581
  roundSubpaths
10337
10582
  };
10338
- //# sourceMappingURL=chunk-PRYMC442.js.map
10583
+ //# sourceMappingURL=chunk-IEYXYMRQ.js.map