@pixerate/editor 0.188.0 → 0.190.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 (41) hide show
  1. package/dist/{chunk-IGMNJM2H.js → chunk-7ZWLDVFH.js} +979 -753
  2. package/dist/{chunk-JYV4R62M.cjs → chunk-T4U4O6DS.cjs} +1013 -787
  3. package/dist/image-editor/controller.d.cts +68 -1
  4. package/dist/image-editor/controller.d.ts +68 -1
  5. package/dist/image-editor/free-transform.d.cts +3 -6
  6. package/dist/image-editor/free-transform.d.ts +3 -6
  7. package/dist/image-editor/index.cjs +1867 -1413
  8. package/dist/image-editor/index.d.cts +1 -0
  9. package/dist/image-editor/index.d.ts +1 -0
  10. package/dist/image-editor/index.js +869 -415
  11. package/dist/image-editor/layer-tools.d.cts +1 -1
  12. package/dist/image-editor/layer-tools.d.ts +1 -1
  13. package/dist/image-editor/layers/compositor.d.cts +3 -0
  14. package/dist/image-editor/layers/compositor.d.ts +3 -0
  15. package/dist/image-editor/layers/model.d.cts +23 -0
  16. package/dist/image-editor/layers/model.d.ts +23 -0
  17. package/dist/image-editor/layers/paint-ui.d.cts +2 -1
  18. package/dist/image-editor/layers/paint-ui.d.ts +2 -1
  19. package/dist/image-editor/layers/panel.d.cts +14 -3
  20. package/dist/image-editor/layers/panel.d.ts +14 -3
  21. package/dist/image-editor/layers/serialize.d.cts +11 -0
  22. package/dist/image-editor/layers/serialize.d.ts +11 -0
  23. package/dist/image-editor/layers/shape.d.cts +5 -0
  24. package/dist/image-editor/layers/shape.d.ts +5 -0
  25. package/dist/image-editor/layers/vector-mask.d.cts +51 -0
  26. package/dist/image-editor/layers/vector-mask.d.ts +51 -0
  27. package/dist/image-editor/psd/import.d.cts +0 -7
  28. package/dist/image-editor/psd/import.d.ts +0 -7
  29. package/dist/image-editor/renderer.d.cts +6 -0
  30. package/dist/image-editor/renderer.d.ts +6 -0
  31. package/dist/image-editor/selection/gesture.d.cts +10 -0
  32. package/dist/image-editor/selection/gesture.d.ts +10 -0
  33. package/dist/image-editor/selection/layer-mask.d.cts +6 -0
  34. package/dist/image-editor/selection/layer-mask.d.ts +6 -0
  35. package/dist/image-editor/types.d.cts +8 -0
  36. package/dist/image-editor/types.d.ts +8 -0
  37. package/dist/paint-editor/index.cjs +6 -6
  38. package/dist/paint-editor/index.js +1 -1
  39. package/package.json +1 -1
  40. package/skills/pixerate-image-editor/SKILL.md +7 -0
  41. package/skills/pixerate-image-selection-masking/SKILL.md +10 -3
@@ -1421,6 +1421,13 @@ function modifySelection(mask, op, radius) {
1421
1421
  }
1422
1422
 
1423
1423
  // src/image-editor/selection/layer-mask.ts
1424
+ function layerMaskSelection(layer, width, height) {
1425
+ if (!layer.mask || layer.mask.source) return null;
1426
+ const ox = layer.type === "pixel" ? layer.offset.x : 0;
1427
+ const oy = layer.type === "pixel" ? layer.offset.y : 0;
1428
+ const data = _chunkCWM3CUUXcjs.readRegion.call(void 0, layer.mask.surface, { x: -ox, y: -oy, width, height });
1429
+ return createSelectionMask(width, height, new Uint8Array(data.buffer, data.byteOffset, data.length));
1430
+ }
1424
1431
  var MAX_SIDE2 = 1 << 15;
1425
1432
  function normalizeLayerMask(raw) {
1426
1433
  if (!raw || typeof raw !== "object") return null;
@@ -2582,192 +2589,6 @@ function removeAlpha(imageData) {
2582
2589
  }
2583
2590
  }
2584
2591
 
2585
- // src/text/types.ts
2586
- var TEXT_ALIGNS = ["left", "center", "right", "justify"];
2587
-
2588
- // src/image-editor/layers/model.ts
2589
- var MAX_EFFECT_ANIMATION_MS = 6e4;
2590
- var SHAPE_OPERATIONS = ["combine", "subtract", "intersect", "exclude"];
2591
- var LIVE_SHAPE_KINDS = ["rect", "ellipse", "polygon", "star", "line"];
2592
- var idCounter = 0;
2593
- function newLayerId(prefix = "layer") {
2594
- return `${prefix}_${Date.now().toString(36)}_${(++idCounter).toString(36)}`;
2595
- }
2596
- function pixelLayers(layers) {
2597
- return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
2598
- }
2599
- function developFilter(layer) {
2600
- return _optionalChain([layer, 'access', _14 => _14.filters, 'optionalAccess', _15 => _15.find, 'call', _16 => _16((f) => f.kind === "develop")]);
2601
- }
2602
- function blurFilter(layer) {
2603
- return _optionalChain([layer, 'access', _17 => _17.filters, 'optionalAccess', _18 => _18.find, 'call', _19 => _19((f) => f.kind === "blur")]);
2604
- }
2605
- function isActiveFilter(f) {
2606
- if (!f.enabled) return false;
2607
- if (f.kind === "blur") return Math.min(Math.round(f.radius), 40) >= 1;
2608
- return Boolean(f.brightness || f.contrast || f.saturation || f.exposure || f.temperature || f.tint);
2609
- }
2610
- function isSpatialFilter(f) {
2611
- return f.kind === "blur";
2612
- }
2613
- function pixelLayerBounds(layer, surface = layer.surface) {
2614
- const b = surface.bounds;
2615
- if (!b) return null;
2616
- return { x: b.x + layer.offset.x, y: b.y + layer.offset.y, width: b.width, height: b.height };
2617
- }
2618
- function layerTypeLabel(type) {
2619
- return type === "pixel" ? "Pixel layer" : type === "adjustment" ? "Adjustment layer" : type === "group" ? "Group" : type === "smart" ? "Smart object" : type === "shape" ? "Shape layer" : type === "type" ? "Type layer" : "Annotation";
2620
- }
2621
- function hasSurface(layer) {
2622
- return layer.type === "pixel" || layer.type === "smart" || layer.type === "shape" || layer.type === "type";
2623
- }
2624
- function isRenderedLayer(layer) {
2625
- return layer.type === "smart" || layer.type === "shape" || layer.type === "type";
2626
- }
2627
- function shapeLayers(layers) {
2628
- return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "shape");
2629
- }
2630
- function smartObjectLayers(layers) {
2631
- return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "smart");
2632
- }
2633
-
2634
- // src/image-editor/layers/compositor.ts
2635
- var legacyViewCache = /* @__PURE__ */ new WeakMap();
2636
- function adjustmentNodeAsLayer(node) {
2637
- let view = legacyViewCache.get(node);
2638
- if (!view) {
2639
- view = {
2640
- id: node.id,
2641
- kind: node.kind,
2642
- enabled: node.visible,
2643
- opacity: node.opacity,
2644
- blend: node.blend,
2645
- params: node.params
2646
- };
2647
- legacyViewCache.set(node, view);
2648
- }
2649
- return view;
2650
- }
2651
- function developAdjustments(f) {
2652
- return {
2653
- brightness: f.brightness,
2654
- contrast: f.contrast,
2655
- saturation: f.saturation,
2656
- exposure: f.exposure,
2657
- temperature: f.temperature,
2658
- tint: _nullishCoalesce(f.tint, () => ( 0)),
2659
- blur: 0,
2660
- opacity: 1,
2661
- process: f.process
2662
- };
2663
- }
2664
- function applyPixelFilters(data, filters) {
2665
- for (const f of filters) {
2666
- if (!isActiveFilter(f) || f.kind !== "develop") continue;
2667
- const adj = developAdjustments(f);
2668
- if (normalizeProcessVersion(adj.process) === LATEST_PROCESS_VERSION) applyProcess2Adjustments({ data }, adj);
2669
- else applyLegacyAdjustments({ data }, adj);
2670
- }
2671
- }
2672
- function depthMaskAlpha(depth, options) {
2673
- const { mode, depthRange, softness, invert } = options;
2674
- let v = invert ? 255 - depth : depth;
2675
- const soft = Math.max(1, softness || 10);
2676
- const [lo, hi] = depthRange;
2677
- if (mode === "threshold") {
2678
- if (v >= hi + soft) return 0;
2679
- if (v > hi) return Math.round((hi + soft - v) / soft * 255);
2680
- if (v >= lo) return 255;
2681
- if (v < lo - soft) return 0;
2682
- return Math.round((v - (lo - soft)) / soft * 255);
2683
- }
2684
- v += lo;
2685
- return v < 0 ? 0 : v > 255 ? 255 : v;
2686
- }
2687
- function runLayerFilters(data, width, height, filters) {
2688
- for (const f of filters) {
2689
- if (!isActiveFilter(f)) continue;
2690
- if (f.kind === "develop") applyPixelFilters(data, [f]);
2691
- else if (f.kind === "blur") applyBoxBlur({ width, height, data }, Math.min(Math.round(f.radius), 40));
2692
- }
2693
- }
2694
- function runLayerFiltersFloat(data, width, height, filters, linear) {
2695
- for (const f of filters) {
2696
- if (!isActiveFilter(f)) continue;
2697
- if (f.kind === "blur") applyBoxBlurFloat({ width, height, data }, Math.min(Math.round(f.radius), 40));
2698
- else if (f.kind === "develop") {
2699
- const adj = developAdjustments(f);
2700
- if (normalizeProcessVersion(adj.process) === LATEST_PROCESS_VERSION) applyProcess2Float(data, adj, linear);
2701
- else applyLegacyFloat(data, adj, linear);
2702
- }
2703
- }
2704
- }
2705
- function filterReach(filters) {
2706
- let r = 0;
2707
- for (const f of filters) if (isActiveFilter(f) && f.kind === "blur") r += Math.min(Math.round(f.radius), 40);
2708
- return r;
2709
- }
2710
- var filterSpecCache = /* @__PURE__ */ new WeakMap();
2711
- function pixelFilterSpec(layer) {
2712
- const list2 = layer.filters;
2713
- if (!_optionalChain([list2, 'optionalAccess', _20 => _20.length])) return null;
2714
- if (filterSpecCache.has(list2)) return filterSpecCache.get(list2);
2715
- const filters = list2.filter(isActiveFilter);
2716
- let spec = null;
2717
- if (filters.length) {
2718
- const spatial = filters.some(isSpatialFilter);
2719
- spec = {
2720
- key: JSON.stringify(filters),
2721
- spatial,
2722
- apply: (data, width, height) => runLayerFilters(data, width, height, filters)
2723
- };
2724
- }
2725
- filterSpecCache.set(list2, spec);
2726
- return spec;
2727
- }
2728
- var PHOTO_PROFILE = {
2729
- isFilterLayer: (l) => l.type === "adjustment",
2730
- applyFilterRun: (layers, acc, _r, masks) => {
2731
- const views = layers.map(adjustmentNodeAsLayer);
2732
- applyAdjustmentLayers({ data: acc }, views, masks);
2733
- },
2734
- contentTile: (l, r, sources) => l.type === "annotation" ? _nullishCoalesce(_optionalChain([sources, 'access', _21 => _21.rasterizeAnnotation, 'optionalCall', _22 => _22(l.annotation, r)]), () => ( null)) : null,
2735
- /** Annotation layers draw with their annotation's blend mode unless the layer sets one. */
2736
- contentBlend: (l) => l.type === "annotation" && l.blend === "normal" && l.annotation.blend ? l.annotation.blend : l.blend,
2737
- layerKey: (l) => l.type === "pixel" ? [_nullishCoalesce(l.filters, () => ( null)), _nullishCoalesce(l.source, () => ( null))] : l.type === "adjustment" ? [l.kind, l.params] : l.type === "annotation" ? l.annotation : void 0,
2738
- pixelFilters: (l) => l.type === "pixel" ? pixelFilterSpec(l) : null,
2739
- /**
2740
- * A smart object draws its rendered pixels (contents → placement → smart filters) like a pixel
2741
- * layer, and a shape layer the pixels rendered from its paths.
2742
- */
2743
- isPixelLike: (l) => l.type === "smart" || l.type === "shape" || l.type === "type",
2744
- maskSourcePlane: (source, W, H, sources) => {
2745
- const opts = source;
2746
- const depth = _nullishCoalesce(_optionalChain([sources, 'access', _23 => _23.depthMap, 'optionalCall', _24 => _24(opts)]), () => ( null));
2747
- if (!depth || depth.width !== W || depth.height !== H) return null;
2748
- const v = new Float32Array(W * H);
2749
- for (let i = 0; i < v.length; i++) v[i] = depthMaskAlpha(depth.data[i * 4], opts) / 255;
2750
- return v;
2751
- }
2752
- };
2753
- var LayerCompositor = class extends _chunkHGTDMKNEcjs.RasterCompositor {
2754
- constructor(options = {}) {
2755
- super(PHOTO_PROFILE, options);
2756
- }
2757
- };
2758
- function compositeDeep(layers, rect, sources, depth) {
2759
- const deep = new (0, _chunkHGTDMKNEcjs.DeepCompositor)(new LayerCompositor(), PHOTO_PROFILE, {
2760
- applyFilterRunDeep: (run, acc, _r, masks) => applyAdjustmentLayersFloat(acc, run.map(adjustmentNodeAsLayer), masks),
2761
- pixelFiltersDeep: (l) => {
2762
- if (l.type !== "pixel") return null;
2763
- const filters = (_nullishCoalesce(l.filters, () => ( []))).filter(isActiveFilter);
2764
- if (!filters.length) return null;
2765
- return { reach: filterReach(filters), apply: (data, width, height, linear) => runLayerFiltersFloat(data, width, height, filters, linear) };
2766
- }
2767
- }, depth);
2768
- return deep.composite(layers, rect, sources);
2769
- }
2770
-
2771
2592
  // src/image-editor/layers/vector-raster.ts
2772
2593
  var FLATNESS = 0.01;
2773
2594
  function flattenPath(path, tolerance = FLATNESS) {
@@ -3101,355 +2922,59 @@ function combineCoverage(a, b, op, n) {
3101
2922
  return out;
3102
2923
  }
3103
2924
 
3104
- // src/image-editor/layers/ops.ts
3105
- var LayerOperationError = class extends Error {
3106
-
3107
- constructor(message, userMessage) {
3108
- super(message);
3109
- this.name = "LayerOperationError";
3110
- if (userMessage) this.userMessage = userMessage;
3111
- }
3112
- };
3113
- function userErrorMessage(err) {
3114
- if (err instanceof LayerOperationError && err.userMessage) return err.userMessage;
3115
- return err instanceof Error ? err.message : String(err);
2925
+ // src/text/types.ts
2926
+ var TEXT_ALIGNS = ["left", "center", "right", "justify"];
2927
+
2928
+ // src/image-editor/layers/model.ts
2929
+ var MAX_EFFECT_ANIMATION_MS = 6e4;
2930
+ var SHAPE_OPERATIONS = ["combine", "subtract", "intersect", "exclude"];
2931
+ var LIVE_SHAPE_KINDS = ["rect", "ellipse", "polygon", "star", "line"];
2932
+ var idCounter = 0;
2933
+ function newLayerId(prefix = "layer") {
2934
+ return `${prefix}_${Date.now().toString(36)}_${(++idCounter).toString(36)}`;
3116
2935
  }
3117
- function isPaintableLayer(layer) {
3118
- return layer.type === "pixel" && layer.visible && !_chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, "pixels");
2936
+ function pixelLayers(layers) {
2937
+ return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
3119
2938
  }
3120
- function defaultActiveLayerId(layers) {
3121
- const pixels = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
3122
- for (let i = pixels.length - 1; i >= 0; i--) if (isPaintableLayer(pixels[i])) return pixels[i].id;
3123
- return _nullishCoalesce(_optionalChain([pixels, 'access', _25 => _25[pixels.length - 1], 'optionalAccess', _26 => _26.id]), () => ( null));
2939
+ function developFilter(layer) {
2940
+ return _optionalChain([layer, 'access', _14 => _14.filters, 'optionalAccess', _15 => _15.find, 'call', _16 => _16((f) => f.kind === "develop")]);
3124
2941
  }
3125
- function activeLayerAfterRemoval(prev, next, removedId) {
3126
- const before = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, prev);
3127
- const at = before.findIndex((l) => l.id === removedId);
3128
- for (let i = at - 1; i >= 0; i--) {
3129
- const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, next, before[i].id);
3130
- if (loc && isPaintableLayer(loc.layer)) return loc.layer.id;
3131
- }
3132
- return defaultActiveLayerId(next);
2942
+ function blurFilter(layer) {
2943
+ return _optionalChain([layer, 'access', _17 => _17.filters, 'optionalAccess', _18 => _18.find, 'call', _19 => _19((f) => f.kind === "blur")]);
3133
2944
  }
3134
- var fail = (message) => {
3135
- throw new LayerOperationError(message);
3136
- };
3137
- function requireLayer(layers, id) {
3138
- const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, layers, id);
3139
- if (!loc) {
3140
- const ids = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).map((l) => l.id);
3141
- fail(`Unknown layer "${id}". ${ids.length ? `Layers: ${ids.join(", ")}.` : "The document has no layers."} Call list_layers for ids.`);
3142
- }
3143
- return loc;
2945
+ function isActiveFilter(f) {
2946
+ if (!f.enabled) return false;
2947
+ if (f.kind === "blur") return Math.min(Math.round(f.radius), 40) >= 1;
2948
+ return Boolean(f.brightness || f.contrast || f.saturation || f.exposure || f.temperature || f.tint);
3144
2949
  }
3145
- function requireUnlocked(layer, what, action) {
3146
- if (_chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, "all")) fail(`Layer "${layer.name || layer.id}" is locked (all); unlock it before you ${action}.`);
3147
- if (what !== "all" && _chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, what)) fail(`Layer "${layer.name || layer.id}" has its ${what} locked; unlock it before you ${action}.`);
2950
+ function isSpatialFilter(f) {
2951
+ return f.kind === "blur";
3148
2952
  }
3149
- function placeLayer(layers, layer, placement = {}, defaultIndex) {
3150
- const given = [placement.aboveId, placement.belowId, placement.parentId].filter((v) => v !== void 0).length;
3151
- if (given > 1) fail("Give only one of aboveId, belowId and parentId.");
3152
- if (placement.aboveId || placement.belowId) {
3153
- const ref = requireLayer(layers, _nullishCoalesce(placement.aboveId, () => ( placement.belowId)));
3154
- return _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, layer, _nullishCoalesce(_optionalChain([ref, 'access', _27 => _27.parent, 'optionalAccess', _28 => _28.id]), () => ( null)), ref.index + (placement.aboveId ? 1 : 0));
3155
- }
3156
- if (placement.parentId) {
3157
- const ref = requireLayer(layers, placement.parentId);
3158
- if (ref.layer.type !== "group") fail(`Layer "${placement.parentId}" is not a group; parentId must be a group id.`);
3159
- return _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, layer, ref.layer.id, placement.index);
3160
- }
3161
- return _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, layer, null, _nullishCoalesce(placement.index, () => ( defaultIndex)));
2953
+ function pixelLayerBounds(layer, surface = layer.surface) {
2954
+ const b = surface.bounds;
2955
+ if (!b) return null;
2956
+ return { x: b.x + layer.offset.x, y: b.y + layer.offset.y, width: b.width, height: b.height };
3162
2957
  }
3163
- function removeLayer(layers, id) {
3164
- const loc = requireLayer(layers, id);
3165
- requireUnlocked(loc.layer, "all", "delete it");
3166
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => null);
3167
- }
3168
- function moveLayer(layers, id, placement) {
3169
- const loc = requireLayer(layers, id);
3170
- requireUnlocked(loc.layer, "all", "move it");
3171
- const target = _nullishCoalesce(_nullishCoalesce(placement.aboveId, () => ( placement.belowId)), () => ( placement.parentId));
3172
- if (target === id) fail("A layer cannot be placed relative to itself.");
3173
- if (target && loc.layer.type === "group" && _chunkHGTDMKNEcjs.flattenLayers.call(void 0, loc.layer.children).some((l) => l.id === target)) {
3174
- fail(`Group "${id}" cannot be moved into its own child "${target}".`);
3175
- }
3176
- if (target) requireLayer(layers, target);
3177
- if (!target && placement.index === void 0) fail("Give aboveId, belowId, parentId or index.");
3178
- const without = _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => null);
3179
- return placeLayer(without, loc.layer, placement);
3180
- }
3181
- function withNewIds(layer) {
3182
- const next = { ...layer, id: newLayerId(layer.type === "adjustment" ? "adj" : layer.type) };
3183
- if (next.type === "group") next.children = next.children.map(withNewIds);
3184
- if (next.type === "annotation") next.annotation = { ...next.annotation, id: next.id };
3185
- if (next.type === "shape" || next.type === "type") delete next.annotation;
3186
- if (next.type === "smart" && _optionalChain([next, 'access', _29 => _29.psd, 'optionalAccess', _30 => _30.placed])) {
3187
- next.psd = { ...next.psd };
3188
- delete next.psd.placed;
3189
- }
3190
- return next;
3191
- }
3192
- function duplicateLayer(layers, id, name) {
3193
- const loc = requireLayer(layers, id);
3194
- const copy = withNewIds(loc.layer);
3195
- copy.name = _nullishCoalesce(name, () => ( `${loc.layer.name || "Layer"} copy`));
3196
- delete copy.locks;
3197
- return { layers: _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _31 => _31.parent, 'optionalAccess', _32 => _32.id]), () => ( null)), loc.index + 1), id: copy.id };
3198
- }
3199
- function setLayerProperties(layers, id, props) {
3200
- const loc = requireLayer(layers, id);
3201
- const layer = loc.layer;
3202
- const onlyUnlocking = Object.keys(props).every((k) => k === "locks" || k === "visible" || k === "collapsed");
3203
- if (!onlyUnlocking) requireUnlocked(layer, "all", "change its properties");
3204
- const next = { ...layer };
3205
- if (props.name !== void 0) {
3206
- if (typeof props.name !== "string" || !props.name.trim()) fail("name must be a non-empty string.");
3207
- next.name = props.name.trim();
3208
- }
3209
- if (props.visible !== void 0) next.visible = Boolean(props.visible);
3210
- if (props.opacity !== void 0) {
3211
- if (!(typeof props.opacity === "number" && props.opacity >= 0 && props.opacity <= 1)) fail("opacity must be a number from 0 to 1.");
3212
- next.opacity = props.opacity;
3213
- }
3214
- if (props.fillOpacity !== void 0) {
3215
- if (layer.type !== "pixel" && layer.type !== "smart" && layer.type !== "shape" && layer.type !== "type") fail(`fillOpacity applies to pixel, shape, type and smart object layers; "${id}" is a ${layer.type} layer.`);
3216
- if (!(typeof props.fillOpacity === "number" && props.fillOpacity >= 0 && props.fillOpacity <= 1)) fail("fillOpacity must be a number from 0 to 1.");
3217
- const p = next;
3218
- if (props.fillOpacity === 1) delete p.fillOpacity;
3219
- else p.fillOpacity = props.fillOpacity;
3220
- }
3221
- if (props.blend !== void 0) {
3222
- if (props.blend === "pass-through") {
3223
- if (layer.type !== "group") fail("pass-through is only for groups.");
3224
- } else if (!_chunkCWM3CUUXcjs.isBlendMode.call(void 0, props.blend)) fail(`Unknown blend mode "${props.blend}".`);
3225
- next.blend = props.blend;
3226
- }
3227
- if (props.clipped !== void 0) {
3228
- if (props.clipped && loc.index === 0) fail("The bottom layer of a group or the stack has nothing below to clip to.");
3229
- if (props.clipped) next.clipped = true;
3230
- else delete next.clipped;
3231
- }
3232
- if (props.locks !== void 0) {
3233
- const locks = {};
3234
- for (const k of ["pixels", "transparency", "position", "all"]) if (props.locks[k]) locks[k] = true;
3235
- if (Object.keys(locks).length) next.locks = locks;
3236
- else delete next.locks;
3237
- }
3238
- if (props.collapsed !== void 0) {
3239
- if (layer.type !== "group") fail("collapsed applies to groups.");
3240
- const g = next;
3241
- if (props.collapsed) g.collapsed = true;
3242
- else delete g.collapsed;
3243
- }
3244
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
3245
- }
3246
- function groupLayers(layers, ids, name = "Group") {
3247
- if (!ids.length) fail("Give at least one layer id to group.");
3248
- const locs = ids.map((id) => requireLayer(layers, id));
3249
- const parent = _nullishCoalesce(_optionalChain([locs, 'access', _33 => _33[0], 'access', _34 => _34.parent, 'optionalAccess', _35 => _35.id]), () => ( null));
3250
- if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _36 => _36.parent, 'optionalAccess', _37 => _37.id]), () => ( null))) !== parent)) fail("Layers to group must share one parent; move them next to each other first.");
3251
- for (const l of locs) requireUnlocked(l.layer, "all", "group it");
3252
- const ordered = [...new Set(locs)].sort((a, b) => a.index - b.index);
3253
- const top = ordered[ordered.length - 1].index;
3254
- const below = ordered.filter((l) => l.index < top).length;
3255
- const group = {
3256
- type: "group",
3257
- id: newLayerId("group"),
3258
- name,
3259
- visible: true,
3260
- opacity: 1,
3261
- blend: "pass-through",
3262
- children: ordered.map((l) => {
3263
- const c = { ...l.layer };
3264
- return c;
3265
- })
3266
- };
3267
- if (_optionalChain([group, 'access', _38 => _38.children, 'access', _39 => _39[0], 'optionalAccess', _40 => _40.clipped])) {
3268
- const c = { ...group.children[0] };
3269
- delete c.clipped;
3270
- group.children[0] = c;
3271
- }
3272
- let out = layers;
3273
- for (const l of ordered) out = _chunkHGTDMKNEcjs.mapLayer.call(void 0, out, l.layer.id, () => null);
3274
- return { layers: _chunkHGTDMKNEcjs.insertLayer.call(void 0, out, group, parent, top - below), id: group.id };
3275
- }
3276
- function ungroupLayer(layers, id) {
3277
- const loc = requireLayer(layers, id);
3278
- if (loc.layer.type !== "group") fail(`Layer "${id}" is not a group.`);
3279
- requireUnlocked(loc.layer, "all", "ungroup it");
3280
- const group = loc.layer;
3281
- let out = _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => null);
3282
- group.children.forEach((c, i) => {
3283
- out = _chunkHGTDMKNEcjs.insertLayer.call(void 0, out, c, _nullishCoalesce(_optionalChain([loc, 'access', _41 => _41.parent, 'optionalAccess', _42 => _42.id]), () => ( null)), loc.index + i);
3284
- });
3285
- return { layers: out, ids: group.children.map((c) => c.id) };
3286
- }
3287
- function offsetLayer(layers, id, offset) {
3288
- const loc = requireLayer(layers, id);
3289
- if (loc.layer.type !== "pixel") fail(`Only pixel layers move; "${id}" is a ${loc.layer.type} layer.`);
3290
- requireUnlocked(loc.layer, "position", "move it");
3291
- if (!Number.isFinite(offset.x) || !Number.isFinite(offset.y)) fail("x and y must be numbers.");
3292
- const layer = loc.layer;
3293
- const next = { ...layer, offset: { x: Math.round(offset.x), y: Math.round(offset.y) } };
3294
- const mask = layer.mask;
3295
- if (mask && mask.linked === false && !mask.source) {
3296
- next.mask = { ...mask, surface: _chunkCWM3CUUXcjs.translateSurface.call(void 0, mask.surface, layer.offset.x - next.offset.x, layer.offset.y - next.offset.y) };
3297
- }
3298
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
3299
- }
3300
- function setLayerMask(layers, id, mask) {
3301
- const loc = requireLayer(layers, id);
3302
- requireUnlocked(loc.layer, "all", "change its mask");
3303
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, (l) => {
3304
- const next = { ...l };
3305
- if (mask) next.mask = mask;
3306
- else delete next.mask;
3307
- return next;
3308
- });
3309
- }
3310
- var DEVELOP_FIELDS = ["brightness", "contrast", "saturation", "exposure", "temperature", "tint"];
3311
- function normalizeFilter(raw, id = newLayerId("flt")) {
3312
- const enabled = raw.enabled !== false;
3313
- if (raw.kind === "blur") {
3314
- const r = raw.radius;
3315
- if (r !== void 0 && !(typeof r === "number" && r >= 0 && r <= 50)) fail("blur radius must be a number from 0 to 50 px.");
3316
- return { id, kind: "blur", enabled, radius: typeof r === "number" ? r : 2 };
3317
- }
3318
- if (raw.kind !== "develop") fail(`Unknown filter kind "${raw.kind}". Use develop or blur.`);
3319
- const out = { id, kind: "develop", enabled, brightness: 0, contrast: 0, saturation: 0, exposure: 0, temperature: 0, tint: 0, process: 2 };
3320
- for (const k of DEVELOP_FIELDS) {
3321
- const v = raw[k];
3322
- if (v === void 0) continue;
3323
- if (!(typeof v === "number" && v >= -100 && v <= 100)) fail(`${k} must be a number from -100 to 100.`);
3324
- out[k] = v;
3325
- }
3326
- const p = raw.process;
3327
- if (p !== void 0) {
3328
- if (p !== 1 && p !== 2) fail("process must be 1 or 2.");
3329
- out.process = p;
3330
- }
3331
- return out;
3332
- }
3333
- function requirePixelLayer(layers, id) {
3334
- const loc = requireLayer(layers, id);
3335
- if (loc.layer.type !== "pixel") fail(`Filters belong to pixel layers; "${id}" is a ${loc.layer.type} layer.`);
3336
- requireUnlocked(loc.layer, "all", "change its filters");
3337
- return loc.layer;
3338
- }
3339
- function addLayerFilter(layers, id, filter) {
3340
- const layer = requirePixelLayer(layers, id);
3341
- if (_optionalChain([layer, 'access', _43 => _43.filters, 'optionalAccess', _44 => _44.some, 'call', _45 => _45((f) => f.kind === filter.kind)])) fail(`Layer "${id}" already has a ${filter.kind} filter; change it with update_layer_filter.`);
3342
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters: [..._nullishCoalesce(layer.filters, () => ( [])), filter] }));
3343
- }
3344
- function updateLayerFilter(layers, id, filterId, changes) {
3345
- const layer = requirePixelLayer(layers, id);
3346
- const i = (_nullishCoalesce(layer.filters, () => ( []))).findIndex((f) => f.id === filterId);
3347
- if (i === -1) fail(`Layer "${id}" has no filter "${filterId}". Filters: ${(_nullishCoalesce(layer.filters, () => ( []))).map((f) => f.id).join(", ") || "none"}.`);
3348
- const current = layer.filters[i];
3349
- if ("kind" in changes && changes.kind !== current.kind) fail("A filter kind cannot change; remove it and add another.");
3350
- const merged2 = normalizeFilter({ ...current, ...changes, kind: current.kind }, current.id);
3351
- const filters = [...layer.filters];
3352
- filters[i] = merged2;
3353
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters }));
3354
- }
3355
- function removeLayerFilter(layers, id, filterId) {
3356
- const layer = requirePixelLayer(layers, id);
3357
- if (!(_nullishCoalesce(layer.filters, () => ( []))).some((f) => f.id === filterId)) fail(`Layer "${id}" has no filter "${filterId}".`);
3358
- const filters = layer.filters.filter((f) => f.id !== filterId);
3359
- const next = { ...layer };
3360
- if (filters.length) next.filters = filters;
3361
- else delete next.filters;
3362
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
3363
- }
3364
- function requireEffectLayer(layers, id, action) {
3365
- const layer = requireLayer(layers, id).layer;
3366
- if (layer.type === "adjustment") fail(`Layer "${layer.name || id}" is an adjustment layer; effects go on pixel, annotation and group layers.`);
3367
- requireUnlocked(layer, "all", action);
3368
- return layer;
3369
- }
3370
- function layerEffectsOf(layer) {
3371
- return _nullishCoalesce(layer.effects, () => ( { enabled: true, items: [] }));
3372
- }
3373
- function guard(fn) {
3374
- try {
3375
- return fn();
3376
- } catch (e) {
3377
- if (e instanceof _chunkHGTDMKNEcjs.LayerEffectError) fail(e.message);
3378
- throw e;
3379
- }
3380
- }
3381
- function setLayerEffects(layers, id, effects) {
3382
- const layer = requireEffectLayer(layers, id, "change its effects");
3383
- const next = { ...layer };
3384
- if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) {
3385
- guard(() => _chunkHGTDMKNEcjs.validateLayerEffects.call(void 0, effects));
3386
- next.effects = effects;
3387
- } else delete next.effects;
3388
- return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
3389
- }
3390
- function addLayerEffect(layers, id, kind, params = {}, index) {
3391
- if (!_chunkHGTDMKNEcjs.isLayerEffectKind.call(void 0, kind)) fail(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkHGTDMKNEcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
3392
- const layer = requireEffectLayer(layers, id, "add effects");
3393
- const current = layerEffectsOf(layer);
3394
- const ids = new Set(current.items.map((e) => e.id));
3395
- let effectId = _chunkHGTDMKNEcjs.newEffectId.call(void 0, );
3396
- while (ids.has(effectId)) effectId = _chunkHGTDMKNEcjs.newEffectId.call(void 0, );
3397
- const { id: _ignored, kind: _kind, ...rest } = params;
3398
- const effect = guard(() => _chunkHGTDMKNEcjs.mergeLayerEffect.call(void 0, _chunkHGTDMKNEcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
3399
- const items = [...current.items];
3400
- const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
3401
- items.splice(at, 0, effect);
3402
- return { layers: setLayerEffects(layers, id, { ...current, items }), effect };
3403
- }
3404
- function requireEffect(layer, effectId) {
3405
- const items = _nullishCoalesce(_optionalChain([layer, 'access', _46 => _46.effects, 'optionalAccess', _47 => _47.items]), () => ( []));
3406
- const i = items.findIndex((e) => e.id === effectId);
3407
- if (i === -1) fail(`Layer "${layer.name || layer.id}" has no effect "${effectId}". Effects: ${items.map((e) => `${e.id} (${e.kind})`).join(", ") || "none"}; call list_layer_effects.`);
3408
- return i;
3409
- }
3410
- function updateLayerEffect(layers, id, effectId, changes) {
3411
- const layer = requireEffectLayer(layers, id, "change its effects");
3412
- const i = requireEffect(layer, effectId);
3413
- const current = layer.effects;
3414
- const items = [...current.items];
3415
- items[i] = guard(() => _chunkHGTDMKNEcjs.mergeLayerEffect.call(void 0, items[i], changes));
3416
- return setLayerEffects(layers, id, { ...current, items });
2958
+ function layerTypeLabel(type) {
2959
+ return type === "pixel" ? "Pixel layer" : type === "adjustment" ? "Adjustment layer" : type === "group" ? "Group" : type === "smart" ? "Smart object" : type === "shape" ? "Shape layer" : type === "type" ? "Type layer" : "Annotation";
3417
2960
  }
3418
- function removeLayerEffect(layers, id, effectId) {
3419
- const layer = requireEffectLayer(layers, id, "change its effects");
3420
- requireEffect(layer, effectId);
3421
- const current = layer.effects;
3422
- return setLayerEffects(layers, id, { ...current, items: current.items.filter((e) => e.id !== effectId) });
2961
+ function hasSurface(layer) {
2962
+ return layer.type === "pixel" || layer.type === "smart" || layer.type === "shape" || layer.type === "type";
3423
2963
  }
3424
- function setLayerEffectsEnabled(layers, id, enabled, scale) {
3425
- const layer = requireEffectLayer(layers, id, "change its effects");
3426
- if (scale !== void 0 && !(Number.isFinite(scale) && scale >= 0.01 && scale <= 10)) fail(`scale must be from 0.01 to 10 (1 = 100 %), got ${scale}.`);
3427
- const current = layerEffectsOf(layer);
3428
- const next = { ...current, enabled };
3429
- if (scale !== void 0) {
3430
- if (scale === 1) delete next.scale;
3431
- else next.scale = scale;
3432
- }
3433
- return setLayerEffects(layers, id, next);
2964
+ function isRenderedLayer(layer) {
2965
+ return layer.type === "smart" || layer.type === "shape" || layer.type === "type";
3434
2966
  }
3435
- function parseBlend(value, allowPassThrough = false) {
3436
- if (value === void 0) return void 0;
3437
- if (value === "pass-through" && allowPassThrough) return value;
3438
- if (!_chunkCWM3CUUXcjs.isBlendMode.call(void 0, value)) fail(`Unknown blend mode "${String(value)}".`);
3439
- return value;
2967
+ function shapeLayers(layers) {
2968
+ return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "shape");
3440
2969
  }
3441
- function unionRect(a, b) {
3442
- if (!a) return b;
3443
- if (!b) return a;
3444
- const x = Math.min(a.x, b.x);
3445
- const y = Math.min(a.y, b.y);
3446
- return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
2970
+ function smartObjectLayers(layers) {
2971
+ return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "smart");
3447
2972
  }
3448
2973
 
3449
2974
  // src/image-editor/layers/shape.ts
3450
2975
  var SHAPE_RENDER_MARGIN = _chunkHGTDMKNEcjs.MAX_EFFECT_REACH;
3451
2976
  var DEFAULT_MITER_LIMIT = 100;
3452
- var fail2 = (message) => {
2977
+ var fail = (message) => {
3453
2978
  throw new LayerOperationError(message);
3454
2979
  };
3455
2980
  var orientation = (anchors) => {
@@ -3590,7 +3115,7 @@ function closedOutline(path) {
3590
3115
  function strokeArea(path, stroke, double) {
3591
3116
  const w = stroke.width * (double ? 2 : 1);
3592
3117
  if (!(w > 0) || !path.length) return [];
3593
- const dashes = _optionalChain([stroke, 'access', _48 => _48.dashes, 'optionalAccess', _49 => _49.length]) && stroke.dashes.some((d) => d > 0) ? stroke.dashes.map((d) => d * stroke.width) : void 0;
3118
+ const dashes = _optionalChain([stroke, 'access', _20 => _20.dashes, 'optionalAccess', _21 => _21.length]) && stroke.dashes.some((d) => d > 0) ? stroke.dashes.map((d) => d * stroke.width) : void 0;
3594
3119
  const options = {
3595
3120
  width: w,
3596
3121
  cap: _nullishCoalesce(stroke.cap, () => ( "butt")),
@@ -3660,13 +3185,17 @@ function fillCoverage(geo, rect, rule, inverted = false) {
3660
3185
  });
3661
3186
  return acc;
3662
3187
  }
3188
+ function componentsCoverage(components, rect, rule = "nonzero", inverted = false) {
3189
+ const geo = { fills: components.map((c) => ({ op: c.op, flat: flattenPath(componentPath(c)) })) };
3190
+ return _nullishCoalesce(fillCoverage(geo, rect, rule, inverted), () => ( new Float32Array(rect.width * rect.height)));
3191
+ }
3663
3192
  function paintContext(env) {
3664
3193
  const tiles = /* @__PURE__ */ new Map();
3665
3194
  return {
3666
3195
  light: _chunkHGTDMKNEcjs.DEFAULT_GLOBAL_LIGHT,
3667
3196
  pattern: (id) => {
3668
3197
  if (tiles.has(id)) return tiles.get(id);
3669
- const p = _nullishCoalesce(_optionalChain([env, 'access', _50 => _50.pattern, 'optionalCall', _51 => _51(id)]), () => ( _chunkHGTDMKNEcjs.builtinPattern.call(void 0, id)));
3198
+ const p = _nullishCoalesce(_optionalChain([env, 'access', _22 => _22.pattern, 'optionalCall', _23 => _23(id)]), () => ( _chunkHGTDMKNEcjs.builtinPattern.call(void 0, id)));
3670
3199
  const t = p && p.width > 0 && p.height > 0 && p.data.length >= p.width * p.height * 4 ? new (0, _chunkHGTDMKNEcjs.PatternTile)(p) : null;
3671
3200
  tiles.set(id, t);
3672
3201
  return t;
@@ -3699,9 +3228,9 @@ function renderShapeRect(layer, rect, env, ctx = paintContext(env)) {
3699
3228
  const canvas = { x: 0, y: 0, width: env.width, height: env.height };
3700
3229
  const anchor = { x: geo.frame.x, y: geo.frame.y };
3701
3230
  const fc = fCov ? _chunkHGTDMKNEcjs.effectFillColors.call(void 0, layer.fill, rect, geo.frame, canvas, anchor, ctx) : null;
3702
- const fo = _nullishCoalesce(_optionalChain([layer, 'access', _52 => _52.fill, 'optionalAccess', _53 => _53.opacity]), () => ( 1));
3231
+ const fo = _nullishCoalesce(_optionalChain([layer, 'access', _24 => _24.fill, 'optionalAccess', _25 => _25.opacity]), () => ( 1));
3703
3232
  const sc = sCov ? _chunkHGTDMKNEcjs.effectFillColors.call(void 0, layer.stroke.paint, rect, geo.frame, canvas, anchor, ctx) : null;
3704
- const so = _nullishCoalesce(_optionalChain([layer, 'access', _54 => _54.stroke, 'optionalAccess', _55 => _55.paint, 'access', _56 => _56.opacity]), () => ( 1));
3233
+ const so = _nullishCoalesce(_optionalChain([layer, 'access', _26 => _26.stroke, 'optionalAccess', _27 => _27.paint, 'access', _28 => _28.opacity]), () => ( 1));
3705
3234
  const out = new Uint8ClampedArray(n * 4);
3706
3235
  let any = false;
3707
3236
  for (let i = 0; i < n; i++) {
@@ -3759,31 +3288,31 @@ function rerenderShape(layer, env) {
3759
3288
  }
3760
3289
  var isNum = (v) => typeof v === "number" && Number.isFinite(v);
3761
3290
  function requireNum(v, path, min = -Infinity, max = Infinity) {
3762
- if (!isNum(v)) fail2(`${path} must be a finite number.`);
3763
- if (v < min || v > max) fail2(`${path} must be between ${min} and ${max}, got ${v}.`);
3291
+ if (!isNum(v)) fail(`${path} must be a finite number.`);
3292
+ if (v < min || v > max) fail(`${path} must be between ${min} and ${max}, got ${v}.`);
3764
3293
  return v;
3765
3294
  }
3766
3295
  function normalizeShapePaint(v, path = "paint") {
3767
3296
  if (typeof v === "string") {
3768
3297
  const c = _chunkA2IS7EHEcjs.parseCssColor.call(void 0, v);
3769
- if (!c) return fail2(`${path}: "${v}" is not a colour; use #rrggbb (or #rrggbbaa, rgb(), a CSS colour name).`);
3298
+ if (!c) return fail(`${path}: "${v}" is not a colour; use #rrggbb (or #rrggbbaa, rgb(), a CSS colour name).`);
3770
3299
  return c.alpha < 1 ? { type: "color", color: c.hex, opacity: c.alpha } : { type: "color", color: c.hex };
3771
3300
  }
3772
- if (!v || typeof v !== "object") return fail2(`${path} must be a colour string or an object with type color, gradient or pattern.`);
3301
+ if (!v || typeof v !== "object") return fail(`${path} must be a colour string or an object with type color, gradient or pattern.`);
3773
3302
  const o = v;
3774
3303
  const opacity = o.opacity === void 0 ? void 0 : requireNum(o.opacity, `${path}.opacity`, 0, 1);
3775
3304
  const withOpacity = (p) => opacity !== void 0 && opacity !== 1 ? { ...p, opacity } : p;
3776
3305
  if (o.type === "color") {
3777
3306
  const c = _chunkA2IS7EHEcjs.parseCssColor.call(void 0, o.color);
3778
- if (!c) return fail2(`${path}.color must be a colour such as #rrggbb.`);
3307
+ if (!c) return fail(`${path}.color must be a colour such as #rrggbb.`);
3779
3308
  const op = (_nullishCoalesce(opacity, () => ( 1))) * c.alpha;
3780
3309
  return op !== 1 ? { type: "color", color: c.hex, opacity: op } : { type: "color", color: c.hex };
3781
3310
  }
3782
3311
  if (o.type === "gradient") {
3783
3312
  const g = o.gradient;
3784
- if (!g || typeof g !== "object") return fail2(`${path}.gradient is required: { stops: [{ position, color }], style, angle, \u2026 }.`);
3313
+ if (!g || typeof g !== "object") return fail(`${path}.gradient is required: { stops: [{ position, color }], style, angle, \u2026 }.`);
3785
3314
  const gradient = {
3786
- stops: Array.isArray(g.stops) ? g.stops.map((s) => ({ position: s.position, color: _nullishCoalesce(_optionalChain([_chunkA2IS7EHEcjs.parseCssColor.call(void 0, s.color), 'optionalAccess', _57 => _57.hex]), () => ( s.color)) })) : [],
3315
+ stops: Array.isArray(g.stops) ? g.stops.map((s) => ({ position: s.position, color: _nullishCoalesce(_optionalChain([_chunkA2IS7EHEcjs.parseCssColor.call(void 0, s.color), 'optionalAccess', _29 => _29.hex]), () => ( s.color)) })) : [],
3787
3316
  ...g.opacityStops ? { opacityStops: g.opacityStops } : {},
3788
3317
  style: _nullishCoalesce(g.style, () => ( "linear")),
3789
3318
  angle: _nullishCoalesce(g.angle, () => ( 90)),
@@ -3795,52 +3324,52 @@ function normalizeShapePaint(v, path = "paint") {
3795
3324
  try {
3796
3325
  _chunkHGTDMKNEcjs.validateEffectGradient.call(void 0, gradient, `${path}.gradient`);
3797
3326
  } catch (e) {
3798
- if (e instanceof _chunkHGTDMKNEcjs.LayerEffectError) fail2(e.message);
3327
+ if (e instanceof _chunkHGTDMKNEcjs.LayerEffectError) fail(e.message);
3799
3328
  throw e;
3800
3329
  }
3801
- if (gradient.stops.length < 1) fail2(`${path}.gradient.stops needs at least one { position, color }.`);
3330
+ if (gradient.stops.length < 1) fail(`${path}.gradient.stops needs at least one { position, color }.`);
3802
3331
  return withOpacity({ type: "gradient", gradient });
3803
3332
  }
3804
3333
  if (o.type === "pattern") {
3805
- if (typeof o.patternId !== "string" || !o.patternId) fail2(`${path}.patternId is required (a document or built-in pattern id).`);
3334
+ if (typeof o.patternId !== "string" || !o.patternId) fail(`${path}.patternId is required (a document or built-in pattern id).`);
3806
3335
  const p = { type: "pattern", patternId: o.patternId, scale: o.scale === void 0 ? 1 : requireNum(o.scale, `${path}.scale`, 0.01, 10) };
3807
3336
  if (typeof o.name === "string") p.name = o.name;
3808
3337
  if (o.angle !== void 0) p.angle = requireNum(o.angle, `${path}.angle`, -360, 360);
3809
3338
  if (o.link !== void 0) p.link = Boolean(o.link);
3810
3339
  if (o.phase !== void 0) {
3811
3340
  const ph = o.phase;
3812
- p.phase = { x: requireNum(_optionalChain([ph, 'optionalAccess', _58 => _58.x]), `${path}.phase.x`), y: requireNum(_optionalChain([ph, 'optionalAccess', _59 => _59.y]), `${path}.phase.y`) };
3341
+ p.phase = { x: requireNum(_optionalChain([ph, 'optionalAccess', _30 => _30.x]), `${path}.phase.x`), y: requireNum(_optionalChain([ph, 'optionalAccess', _31 => _31.y]), `${path}.phase.y`) };
3813
3342
  }
3814
3343
  return withOpacity(p);
3815
3344
  }
3816
- return fail2(`${path}.type must be color, gradient or pattern, got ${JSON.stringify(o.type)}.`);
3345
+ return fail(`${path}.type must be color, gradient or pattern, got ${JSON.stringify(o.type)}.`);
3817
3346
  }
3818
3347
  function normalizeShapeStroke(v, path = "stroke", base) {
3819
- if (!v || typeof v !== "object") return fail2(`${path} must be an object { width, paint, align?, cap?, join?, miterLimit?, dashes?, dashOffset? } or null.`);
3348
+ if (!v || typeof v !== "object") return fail(`${path} must be an object { width, paint, align?, cap?, join?, miterLimit?, dashes?, dashOffset? } or null.`);
3820
3349
  const o = v;
3821
3350
  const width = o.width === void 0 && base ? base.width : requireNum(o.width, `${path}.width`, 0, 1e4);
3822
3351
  const paint = o.paint === void 0 && base ? base.paint : o.paint === void 0 && o.color !== void 0 ? normalizeShapePaint(o.color, `${path}.color`) : normalizeShapePaint(o.paint, `${path}.paint`);
3823
3352
  const out = { width, paint };
3824
3353
  const pick = (k, allowed) => {
3825
- const value = o[k] === void 0 ? _optionalChain([base, 'optionalAccess', _60 => _60[k]]) : o[k];
3354
+ const value = o[k] === void 0 ? _optionalChain([base, 'optionalAccess', _32 => _32[k]]) : o[k];
3826
3355
  if (value === void 0) return;
3827
- if (!allowed.includes(value)) fail2(`${path}.${k} must be one of ${allowed.join(", ")}, got ${JSON.stringify(value)}.`);
3356
+ if (!allowed.includes(value)) fail(`${path}.${k} must be one of ${allowed.join(", ")}, got ${JSON.stringify(value)}.`);
3828
3357
  if (value !== (k === "align" ? "center" : k === "cap" ? "butt" : "miter")) out[k] = value;
3829
3358
  };
3830
3359
  pick("align", ["inside", "center", "outside"]);
3831
3360
  pick("cap", ["butt", "round", "square"]);
3832
3361
  pick("join", ["miter", "round", "bevel"]);
3833
- const miter = o.miterLimit === void 0 ? _optionalChain([base, 'optionalAccess', _61 => _61.miterLimit]) : requireNum(o.miterLimit, `${path}.miterLimit`, 1, 500);
3362
+ const miter = o.miterLimit === void 0 ? _optionalChain([base, 'optionalAccess', _33 => _33.miterLimit]) : requireNum(o.miterLimit, `${path}.miterLimit`, 1, 500);
3834
3363
  if (miter !== void 0 && miter !== DEFAULT_MITER_LIMIT) out.miterLimit = miter;
3835
- const dashes = o.dashes === void 0 ? _optionalChain([base, 'optionalAccess', _62 => _62.dashes]) : o.dashes;
3364
+ const dashes = o.dashes === void 0 ? _optionalChain([base, 'optionalAccess', _34 => _34.dashes]) : o.dashes;
3836
3365
  if (dashes !== void 0 && dashes !== null) {
3837
- if (!Array.isArray(dashes) || dashes.length > 32 || !dashes.every((d) => isNum(d) && d >= 0 && d <= 1e4)) fail2(`${path}.dashes must be at most 32 lengths 0..10000 (multiples of the width).`);
3366
+ if (!Array.isArray(dashes) || dashes.length > 32 || !dashes.every((d) => isNum(d) && d >= 0 && d <= 1e4)) fail(`${path}.dashes must be at most 32 lengths 0..10000 (multiples of the width).`);
3838
3367
  if (dashes.length) {
3839
- if (dashes.reduce((s, d) => s + d, 0) < 0.01) fail2(`${path}.dashes must add up to at least 0.01 widths.`);
3368
+ if (dashes.reduce((s, d) => s + d, 0) < 0.01) fail(`${path}.dashes must add up to at least 0.01 widths.`);
3840
3369
  out.dashes = [...dashes];
3841
3370
  }
3842
3371
  }
3843
- const offset = o.dashOffset === void 0 ? _optionalChain([base, 'optionalAccess', _63 => _63.dashOffset]) : requireNum(o.dashOffset, `${path}.dashOffset`, -1e6, 1e6);
3372
+ const offset = o.dashOffset === void 0 ? _optionalChain([base, 'optionalAccess', _35 => _35.dashOffset]) : requireNum(o.dashOffset, `${path}.dashOffset`, -1e6, 1e6);
3844
3373
  if (offset) out.dashOffset = offset;
3845
3374
  return out;
3846
3375
  }
@@ -3854,7 +3383,7 @@ function box(o, path) {
3854
3383
  }
3855
3384
  function arrowhead(v, path) {
3856
3385
  if (v === null || v === void 0 || v === false) return null;
3857
- if (typeof v !== "object") return fail2(`${path} must be { width, length, concavity? } in pixels, or null.`);
3386
+ if (typeof v !== "object") return fail(`${path} must be { width, length, concavity? } in pixels, or null.`);
3858
3387
  const o = v;
3859
3388
  const head = { width: requireNum(o.width, `${path}.width`, 0, 1e5), length: requireNum(o.length, `${path}.length`, 0, 1e5) };
3860
3389
  if (o.concavity !== void 0 && o.concavity !== 0) head.concavity = requireNum(o.concavity, `${path}.concavity`, -0.5, 0.5);
@@ -3862,13 +3391,13 @@ function arrowhead(v, path) {
3862
3391
  }
3863
3392
  function matrixArg(v, path) {
3864
3393
  if (v === void 0 || v === null) return void 0;
3865
- if (!Array.isArray(v) || v.length !== 6 || !v.every(isNum)) fail2(`${path} must be six numbers [a, b, c, d, e, f].`);
3394
+ if (!Array.isArray(v) || v.length !== 6 || !v.every(isNum)) fail(`${path} must be six numbers [a, b, c, d, e, f].`);
3866
3395
  const m = v;
3867
- if (Math.abs(m[0] * m[3] - m[1] * m[2]) < 1e-12) fail2(`${path} is singular.`);
3396
+ if (Math.abs(m[0] * m[3] - m[1] * m[2]) < 1e-12) fail(`${path} is singular.`);
3868
3397
  return _chunkEGZM52EOcjs.isIdentityMatrix.call(void 0, m) ? void 0 : [...m];
3869
3398
  }
3870
3399
  function normalizeLiveShape(v, path = "shape") {
3871
- if (!v || typeof v !== "object") return fail2(`${path} must be an object with kind ${LIVE_SHAPE_KINDS.join(", ")}.`);
3400
+ if (!v || typeof v !== "object") return fail(`${path} must be an object with kind ${LIVE_SHAPE_KINDS.join(", ")}.`);
3872
3401
  const o = v;
3873
3402
  const transform = matrixArg(o.transform, `${path}.transform`);
3874
3403
  const t = transform ? { transform } : {};
@@ -3879,7 +3408,7 @@ function normalizeLiveShape(v, path = "shape") {
3879
3408
  if (o.radii !== void 0 || o.radius !== void 0) {
3880
3409
  const r = _nullishCoalesce(o.radii, () => ( o.radius));
3881
3410
  const list2 = typeof r === "number" ? [r, r, r, r] : r;
3882
- if (!Array.isArray(list2) || list2.length !== 4 || !list2.every((x) => isNum(x) && x >= 0)) fail2(`${path}.radii must be four radii \u2265 0 [top-left, top-right, bottom-right, bottom-left] (or radius, one number).`);
3411
+ if (!Array.isArray(list2) || list2.length !== 4 || !list2.every((x) => isNum(x) && x >= 0)) fail(`${path}.radii must be four radii \u2265 0 [top-left, top-right, bottom-right, bottom-left] (or radius, one number).`);
3883
3412
  if (list2.some((x) => x > 0)) radii = [...list2];
3884
3413
  }
3885
3414
  return { kind: "rect", ...b, ...radii ? { radii } : {}, ...t };
@@ -3910,16 +3439,16 @@ function normalizeLiveShape(v, path = "shape") {
3910
3439
  const e = arrowhead(o.endArrow, `${path}.endArrow`);
3911
3440
  if (s) line.startArrow = s;
3912
3441
  if (e) line.endArrow = e;
3913
- if (line.x1 === line.x2 && line.y1 === line.y2) fail2(`${path}: the line's two ends are the same point.`);
3442
+ if (line.x1 === line.x2 && line.y1 === line.y2) fail(`${path}: the line's two ends are the same point.`);
3914
3443
  return line;
3915
3444
  }
3916
3445
  default:
3917
- return fail2(`${path}.kind must be one of ${LIVE_SHAPE_KINDS.join(", ")}, got ${JSON.stringify(o.kind)}.`);
3446
+ return fail(`${path}.kind must be one of ${LIVE_SHAPE_KINDS.join(", ")}, got ${JSON.stringify(o.kind)}.`);
3918
3447
  }
3919
3448
  }
3920
3449
  function point(v, path) {
3921
3450
  const p = v;
3922
- if (!p || typeof p !== "object") return fail2(`${path} must be { x, y } in document pixels.`);
3451
+ if (!p || typeof p !== "object") return fail(`${path} must be { x, y } in document pixels.`);
3923
3452
  return { x: requireNum(p.x, `${path}.x`), y: requireNum(p.y, `${path}.y`) };
3924
3453
  }
3925
3454
  function normalizeSubpaths(v, path = "subpaths") {
@@ -3928,15 +3457,15 @@ function normalizeSubpaths(v, path = "subpaths") {
3928
3457
  try {
3929
3458
  subs = _chunkEGZM52EOcjs.bezierToSubpaths.call(void 0, v);
3930
3459
  } catch (e5) {
3931
- return fail2(`${path}: could not read the SVG path data.`);
3460
+ return fail(`${path}: could not read the SVG path data.`);
3932
3461
  }
3933
- if (!subs.length || !subs.every((s) => s.anchors.every((a) => isNum(a.x) && isNum(a.y)))) fail2(`${path}: the SVG path data holds no drawable subpath.`);
3462
+ if (!subs.length || !subs.every((s) => s.anchors.every((a) => isNum(a.x) && isNum(a.y)))) fail(`${path}: the SVG path data holds no drawable subpath.`);
3934
3463
  return subs;
3935
3464
  }
3936
- if (!Array.isArray(v) || !v.length) return fail2(`${path} must be a non-empty array of { anchors: [{ x, y, in?, out? }], closed } (or SVG path data).`);
3465
+ if (!Array.isArray(v) || !v.length) return fail(`${path} must be a non-empty array of { anchors: [{ x, y, in?, out? }], closed } (or SVG path data).`);
3937
3466
  return v.map((s, i) => {
3938
3467
  const sp = s;
3939
- if (!sp || !Array.isArray(sp.anchors) || sp.anchors.length < 1) fail2(`${path}[${i}].anchors must be a non-empty array.`);
3468
+ if (!sp || !Array.isArray(sp.anchors) || sp.anchors.length < 1) fail(`${path}[${i}].anchors must be a non-empty array.`);
3940
3469
  const anchors = sp.anchors.map((a, j) => {
3941
3470
  const at = `${path}[${i}].anchors[${j}]`;
3942
3471
  const p = point(a, at);
@@ -3956,16 +3485,16 @@ function normalizeSubpaths(v, path = "subpaths") {
3956
3485
  }
3957
3486
  function requireOperation(v, path = "op") {
3958
3487
  if (v === void 0) return "combine";
3959
- if (!SHAPE_OPERATIONS.includes(v)) fail2(`${path} must be one of ${SHAPE_OPERATIONS.join(", ")}, got ${JSON.stringify(v)}.`);
3488
+ if (!SHAPE_OPERATIONS.includes(v)) fail(`${path} must be one of ${SHAPE_OPERATIONS.join(", ")}, got ${JSON.stringify(v)}.`);
3960
3489
  return v;
3961
3490
  }
3962
3491
  function requireShapeLayer(layers, id) {
3963
3492
  const layer = requireLayer(layers, id).layer;
3964
- if (layer.type !== "shape") fail2(`Layer "${layer.name || id}" is a ${layer.type} layer, not a shape layer; list_layers shows each layer's type.`);
3493
+ if (layer.type !== "shape") fail(`Layer "${layer.name || id}" is a ${layer.type} layer, not a shape layer; list_layers shows each layer's type.`);
3965
3494
  return layer;
3966
3495
  }
3967
3496
  function createShapeLayer(init, env, id = newLayerId()) {
3968
- if (!init.components.length) fail2("A shape needs at least one component.");
3497
+ if (!init.components.length) fail("A shape needs at least one component.");
3969
3498
  const layer = {
3970
3499
  type: "shape",
3971
3500
  id,
@@ -3984,7 +3513,7 @@ function createShapeLayer(init, env, id = newLayerId()) {
3984
3513
  return rerenderShape(layer, env);
3985
3514
  }
3986
3515
  function defaultShapeName(c) {
3987
- switch (_optionalChain([c, 'optionalAccess', _64 => _64.live, 'optionalAccess', _65 => _65.kind])) {
3516
+ switch (_optionalChain([c, 'optionalAccess', _36 => _36.live, 'optionalAccess', _37 => _37.kind])) {
3988
3517
  case "rect":
3989
3518
  return "Rectangle";
3990
3519
  case "ellipse":
@@ -4005,7 +3534,7 @@ function updateShapeLayer(layers, id, change, env, action = "edit it") {
4005
3534
  const patch = change(current);
4006
3535
  const next = { ...current, ...patch };
4007
3536
  if (!("annotation" in patch)) delete next.annotation;
4008
- if (!next.components.length) fail2("A shape needs at least one component; delete the layer instead.");
3537
+ if (!next.components.length) fail("A shape needs at least one component; delete the layer instead.");
4009
3538
  const rendered = rerenderShape(next, env);
4010
3539
  return { layers: _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => rendered), layer: rendered };
4011
3540
  }
@@ -4029,7 +3558,7 @@ function mergeShapeComponents(components, fillRule = "nonzero") {
4029
3558
  if (components.length < 2) return [...components];
4030
3559
  const path = shapeOutline(components, fillRule);
4031
3560
  const subpaths = _chunkEGZM52EOcjs.bezierToSubpaths.call(void 0, path);
4032
- if (!subpaths.length) fail2("The components combine to nothing (the operations remove every area), so there is nothing to merge into.");
3561
+ if (!subpaths.length) fail("The components combine to nothing (the operations remove every area), so there is nothing to merge into.");
4033
3562
  return [{ op: "combine", subpaths }];
4034
3563
  }
4035
3564
  function shapeAsPixelLayer(layer) {
@@ -4100,19 +3629,644 @@ function shapeFromAnnotation(a) {
4100
3629
  return null;
4101
3630
  }
4102
3631
  }
4103
- function annotationBlend(a, layerBlend) {
4104
- if (layerBlend !== "normal") return layerBlend;
4105
- return a.blend && _chunkCWM3CUUXcjs.isBlendMode.call(void 0, a.blend) ? a.blend : "normal";
4106
- }
4107
- function annotationOfShape(layer) {
4108
- const a = layer.annotation;
4109
- if (!a) return null;
4110
- const blend = layer.blend;
4111
- if ((_nullishCoalesce(a.blend, () => ( "normal"))) === blend) return a;
4112
- const out = { ...a };
4113
- if (blend === "normal") delete out.blend;
4114
- else out.blend = blend;
4115
- return out;
3632
+ function annotationBlend(a, layerBlend) {
3633
+ if (layerBlend !== "normal") return layerBlend;
3634
+ return a.blend && _chunkCWM3CUUXcjs.isBlendMode.call(void 0, a.blend) ? a.blend : "normal";
3635
+ }
3636
+ function annotationOfShape(layer) {
3637
+ const a = layer.annotation;
3638
+ if (!a) return null;
3639
+ const blend = layer.blend;
3640
+ if ((_nullishCoalesce(a.blend, () => ( "normal"))) === blend) return a;
3641
+ const out = { ...a };
3642
+ if (blend === "normal") delete out.blend;
3643
+ else out.blend = blend;
3644
+ return out;
3645
+ }
3646
+
3647
+ // src/image-editor/layers/vector-mask.ts
3648
+ function isActiveVectorMask(vm) {
3649
+ return Boolean(vm && vm.enabled !== false);
3650
+ }
3651
+ function vectorMaskCoverage(vm, width, height) {
3652
+ let v = componentsCoverage(vm.components, { x: 0, y: 0, width, height }, _nullishCoalesce(vm.fillRule, () => ( "nonzero")), vm.inverted === true);
3653
+ if ((_nullishCoalesce(vm.feather, () => ( 0))) > 0) v = _chunkHGTDMKNEcjs.gaussianBlur.call(void 0, v, width, height, vm.feather, "clamp");
3654
+ const density = _nullishCoalesce(vm.density, () => ( 1));
3655
+ if (density !== 1) for (let i = 0; i < v.length; i++) v[i] = 1 - density * (1 - v[i]);
3656
+ return v;
3657
+ }
3658
+ function outsideValue(vm) {
3659
+ return 1 - (_nullishCoalesce(vm.density, () => ( 1))) * (1 - (vm.inverted ? 1 : 0));
3660
+ }
3661
+ function rasterCoverage(mask, ox, oy, width, height) {
3662
+ const bytes = _chunkCWM3CUUXcjs.readRegion.call(void 0, mask.surface, { x: -ox, y: -oy, width, height });
3663
+ let v = new Float32Array(width * height);
3664
+ for (let i = 0; i < v.length; i++) v[i] = bytes[i] / 255;
3665
+ if ((_nullishCoalesce(mask.feather, () => ( 0))) > 0) v = _chunkHGTDMKNEcjs.gaussianBlur.call(void 0, v, width, height, mask.feather, "clamp");
3666
+ const density = _nullishCoalesce(mask.density, () => ( 1));
3667
+ if (density !== 1) for (let i = 0; i < v.length; i++) v[i] = 1 - density * (1 - v[i]);
3668
+ return v;
3669
+ }
3670
+ var layerOffset = (layer) => layer.type === "pixel" ? layer.offset : { x: 0, y: 0 };
3671
+ function effectiveLayerMask(layer, width, height) {
3672
+ const vm = layer.vectorMask;
3673
+ const raster = layer.mask;
3674
+ if (!isActiveVectorMask(vm) || _optionalChain([raster, 'optionalAccess', _38 => _38.source]) || width < 1 || height < 1) return raster;
3675
+ const { x: ox, y: oy } = layerOffset(layer);
3676
+ const v = vectorMaskCoverage(vm, width, height);
3677
+ let outside = outsideValue(vm);
3678
+ if (raster && raster.enabled !== false) {
3679
+ const r = rasterCoverage(raster, ox, oy, width, height);
3680
+ for (let i = 0; i < v.length; i++) v[i] *= r[i];
3681
+ outside *= 1 - (_nullishCoalesce(raster.density, () => ( 1))) * (1 - raster.defaultValue / 255);
3682
+ }
3683
+ const bytes = new Uint8ClampedArray(v.length);
3684
+ for (let i = 0; i < v.length; i++) bytes[i] = Math.round(v[i] * 255);
3685
+ const defaultValue = outside >= 0.5 ? 255 : 0;
3686
+ return { surface: _chunkCWM3CUUXcjs.writeRegion.call(void 0, _chunkCWM3CUUXcjs.emptySurface.call(void 0, 1, defaultValue), { x: -ox, y: -oy, width, height }, bytes), defaultValue };
3687
+ }
3688
+ var resolved = /* @__PURE__ */ new WeakMap();
3689
+ function hasVectorMask(layers) {
3690
+ for (const l of layers) {
3691
+ if (isActiveVectorMask(l.vectorMask)) return true;
3692
+ if (l.type === "group" && hasVectorMask(l.children)) return true;
3693
+ }
3694
+ return false;
3695
+ }
3696
+ function resolveVectorMasks(layers, width, height) {
3697
+ if (!hasVectorMask(layers)) return layers;
3698
+ return layers.map((l) => resolveLayer(l, width, height));
3699
+ }
3700
+ function resolveLayer(layer, width, height) {
3701
+ let next = layer;
3702
+ if (layer.type === "group" && hasVectorMask(layer.children)) {
3703
+ const key2 = `${width}x${height}`;
3704
+ const hit2 = resolved.get(layer);
3705
+ if (_optionalChain([hit2, 'optionalAccess', _39 => _39.key]) === key2) return hit2.layer;
3706
+ next = { ...layer, children: layer.children.map((c) => resolveLayer(c, width, height)) };
3707
+ if (!isActiveVectorMask(layer.vectorMask)) {
3708
+ resolved.set(layer, { key: key2, layer: next });
3709
+ return next;
3710
+ }
3711
+ }
3712
+ if (!isActiveVectorMask(layer.vectorMask)) return layer;
3713
+ const key = `${width}x${height}:v`;
3714
+ const hit = resolved.get(layer);
3715
+ if (_optionalChain([hit, 'optionalAccess', _40 => _40.key]) === key) return hit.layer;
3716
+ const mask = effectiveLayerMask(layer, width, height);
3717
+ const out = { ...next, mask };
3718
+ delete out.vectorMask;
3719
+ if (!mask) delete out.mask;
3720
+ resolved.set(layer, { key, layer: out });
3721
+ return out;
3722
+ }
3723
+ function offsetVectorMask(vm, dx, dy) {
3724
+ if (!dx && !dy) return vm;
3725
+ return { ...vm, components: vm.components.map((c) => ({ ...c, subpaths: mapSubpaths(c.subpaths, (p) => ({ x: p.x + dx, y: p.y + dy })), ...c.live ? { live: offsetLive(c.live, dx, dy) } : {} })) };
3726
+ }
3727
+ function offsetLive(live, dx, dy) {
3728
+ if (live.kind === "line") return { ...live, x1: live.x1 + dx, y1: live.y1 + dy, x2: live.x2 + dx, y2: live.y2 + dy };
3729
+ return { ...live, x: live.x + dx, y: live.y + dy };
3730
+ }
3731
+ function transformVectorMask(vm, f, affine) {
3732
+ return { ...vm, components: transformShapeComponents(vm.components, f, affine) };
3733
+ }
3734
+ function followLayerMove(layer, dx, dy) {
3735
+ const vm = layer.vectorMask;
3736
+ if (!vm || vm.linked === false || !dx && !dy) return layer;
3737
+ return { ...layer, vectorMask: offsetVectorMask(vm, dx, dy) };
3738
+ }
3739
+ function vectorMaskBounds(vm) {
3740
+ let x0 = Infinity;
3741
+ let y0 = Infinity;
3742
+ let x1 = -Infinity;
3743
+ let y1 = -Infinity;
3744
+ for (const c of vm.components) {
3745
+ for (const sp of c.subpaths) {
3746
+ for (const a of sp.anchors) {
3747
+ for (const p of [a, a.in, a.out]) {
3748
+ if (!p) continue;
3749
+ x0 = Math.min(x0, p.x);
3750
+ y0 = Math.min(y0, p.y);
3751
+ x1 = Math.max(x1, p.x);
3752
+ y1 = Math.max(y1, p.y);
3753
+ }
3754
+ }
3755
+ }
3756
+ }
3757
+ return x0 === Infinity ? null : { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };
3758
+ }
3759
+ var thumbCache = /* @__PURE__ */ new WeakMap();
3760
+ function vectorMaskThumbnail(vm, width, height, maxSide = 64) {
3761
+ const key = `${width}x${height}:${maxSide}`;
3762
+ const hit = thumbCache.get(vm);
3763
+ if (_optionalChain([hit, 'optionalAccess', _41 => _41.key]) === key) return hit.pixels;
3764
+ const k = Math.min(1, maxSide / Math.max(1, width, height));
3765
+ const tw = Math.max(1, Math.round(width * k));
3766
+ const th = Math.max(1, Math.round(height * k));
3767
+ const scaled = transformVectorMask(vm, (p) => ({ x: p.x * k, y: p.y * k }), [k, 0, 0, k, 0, 0]);
3768
+ const cov = componentsCoverage(scaled.components, { x: 0, y: 0, width: tw, height: th }, _nullishCoalesce(vm.fillRule, () => ( "nonzero")), vm.inverted === true);
3769
+ const data = new Uint8ClampedArray(tw * th * 4);
3770
+ for (let i = 0; i < cov.length; i++) {
3771
+ const v = Math.round(Math.min(1, Math.max(0, cov[i])) * 255);
3772
+ data[i * 4] = data[i * 4 + 1] = data[i * 4 + 2] = v;
3773
+ data[i * 4 + 3] = 255;
3774
+ }
3775
+ const pixels = { width: tw, height: th, data };
3776
+ thumbCache.set(vm, { key, pixels });
3777
+ return pixels;
3778
+ }
3779
+
3780
+ // src/image-editor/layers/ops.ts
3781
+ var LayerOperationError = class extends Error {
3782
+
3783
+ constructor(message, userMessage) {
3784
+ super(message);
3785
+ this.name = "LayerOperationError";
3786
+ if (userMessage) this.userMessage = userMessage;
3787
+ }
3788
+ };
3789
+ function userErrorMessage(err) {
3790
+ if (err instanceof LayerOperationError && err.userMessage) return err.userMessage;
3791
+ return err instanceof Error ? err.message : String(err);
3792
+ }
3793
+ function isPaintableLayer(layer) {
3794
+ return layer.type === "pixel" && layer.visible && !_chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, "pixels");
3795
+ }
3796
+ function defaultActiveLayerId(layers) {
3797
+ const pixels = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
3798
+ for (let i = pixels.length - 1; i >= 0; i--) if (isPaintableLayer(pixels[i])) return pixels[i].id;
3799
+ return _nullishCoalesce(_optionalChain([pixels, 'access', _42 => _42[pixels.length - 1], 'optionalAccess', _43 => _43.id]), () => ( null));
3800
+ }
3801
+ function activeLayerAfterRemoval(prev, next, removedId) {
3802
+ const before = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, prev);
3803
+ const at = before.findIndex((l) => l.id === removedId);
3804
+ for (let i = at - 1; i >= 0; i--) {
3805
+ const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, next, before[i].id);
3806
+ if (loc && isPaintableLayer(loc.layer)) return loc.layer.id;
3807
+ }
3808
+ return defaultActiveLayerId(next);
3809
+ }
3810
+ var fail2 = (message) => {
3811
+ throw new LayerOperationError(message);
3812
+ };
3813
+ function requireLayer(layers, id) {
3814
+ const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, layers, id);
3815
+ if (!loc) {
3816
+ const ids = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).map((l) => l.id);
3817
+ fail2(`Unknown layer "${id}". ${ids.length ? `Layers: ${ids.join(", ")}.` : "The document has no layers."} Call list_layers for ids.`);
3818
+ }
3819
+ return loc;
3820
+ }
3821
+ function requireUnlocked(layer, what, action) {
3822
+ if (_chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, "all")) fail2(`Layer "${layer.name || layer.id}" is locked (all); unlock it before you ${action}.`);
3823
+ if (what !== "all" && _chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, what)) fail2(`Layer "${layer.name || layer.id}" has its ${what} locked; unlock it before you ${action}.`);
3824
+ }
3825
+ function placeLayer(layers, layer, placement = {}, defaultIndex) {
3826
+ const given = [placement.aboveId, placement.belowId, placement.parentId].filter((v) => v !== void 0).length;
3827
+ if (given > 1) fail2("Give only one of aboveId, belowId and parentId.");
3828
+ if (placement.aboveId || placement.belowId) {
3829
+ const ref = requireLayer(layers, _nullishCoalesce(placement.aboveId, () => ( placement.belowId)));
3830
+ return _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, layer, _nullishCoalesce(_optionalChain([ref, 'access', _44 => _44.parent, 'optionalAccess', _45 => _45.id]), () => ( null)), ref.index + (placement.aboveId ? 1 : 0));
3831
+ }
3832
+ if (placement.parentId) {
3833
+ const ref = requireLayer(layers, placement.parentId);
3834
+ if (ref.layer.type !== "group") fail2(`Layer "${placement.parentId}" is not a group; parentId must be a group id.`);
3835
+ return _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, layer, ref.layer.id, placement.index);
3836
+ }
3837
+ return _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, layer, null, _nullishCoalesce(placement.index, () => ( defaultIndex)));
3838
+ }
3839
+ function removeLayer(layers, id) {
3840
+ const loc = requireLayer(layers, id);
3841
+ requireUnlocked(loc.layer, "all", "delete it");
3842
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => null);
3843
+ }
3844
+ function moveLayer(layers, id, placement) {
3845
+ const loc = requireLayer(layers, id);
3846
+ requireUnlocked(loc.layer, "all", "move it");
3847
+ const target = _nullishCoalesce(_nullishCoalesce(placement.aboveId, () => ( placement.belowId)), () => ( placement.parentId));
3848
+ if (target === id) fail2("A layer cannot be placed relative to itself.");
3849
+ if (target && loc.layer.type === "group" && _chunkHGTDMKNEcjs.flattenLayers.call(void 0, loc.layer.children).some((l) => l.id === target)) {
3850
+ fail2(`Group "${id}" cannot be moved into its own child "${target}".`);
3851
+ }
3852
+ if (target) requireLayer(layers, target);
3853
+ if (!target && placement.index === void 0) fail2("Give aboveId, belowId, parentId or index.");
3854
+ const without = _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => null);
3855
+ return placeLayer(without, loc.layer, placement);
3856
+ }
3857
+ function withNewIds(layer) {
3858
+ const next = { ...layer, id: newLayerId(layer.type === "adjustment" ? "adj" : layer.type) };
3859
+ if (next.type === "group") next.children = next.children.map(withNewIds);
3860
+ if (next.type === "annotation") next.annotation = { ...next.annotation, id: next.id };
3861
+ if (next.type === "shape" || next.type === "type") delete next.annotation;
3862
+ if (next.type === "smart" && _optionalChain([next, 'access', _46 => _46.psd, 'optionalAccess', _47 => _47.placed])) {
3863
+ next.psd = { ...next.psd };
3864
+ delete next.psd.placed;
3865
+ }
3866
+ return next;
3867
+ }
3868
+ function duplicateLayer(layers, id, name) {
3869
+ const loc = requireLayer(layers, id);
3870
+ const copy = withNewIds(loc.layer);
3871
+ copy.name = _nullishCoalesce(name, () => ( `${loc.layer.name || "Layer"} copy`));
3872
+ delete copy.locks;
3873
+ return { layers: _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _48 => _48.parent, 'optionalAccess', _49 => _49.id]), () => ( null)), loc.index + 1), id: copy.id };
3874
+ }
3875
+ function setLayerProperties(layers, id, props) {
3876
+ const loc = requireLayer(layers, id);
3877
+ const layer = loc.layer;
3878
+ const onlyUnlocking = Object.keys(props).every((k) => k === "locks" || k === "visible" || k === "collapsed");
3879
+ if (!onlyUnlocking) requireUnlocked(layer, "all", "change its properties");
3880
+ const next = { ...layer };
3881
+ if (props.name !== void 0) {
3882
+ if (typeof props.name !== "string" || !props.name.trim()) fail2("name must be a non-empty string.");
3883
+ next.name = props.name.trim();
3884
+ }
3885
+ if (props.visible !== void 0) next.visible = Boolean(props.visible);
3886
+ if (props.opacity !== void 0) {
3887
+ if (!(typeof props.opacity === "number" && props.opacity >= 0 && props.opacity <= 1)) fail2("opacity must be a number from 0 to 1.");
3888
+ next.opacity = props.opacity;
3889
+ }
3890
+ if (props.fillOpacity !== void 0) {
3891
+ if (layer.type !== "pixel" && layer.type !== "smart" && layer.type !== "shape" && layer.type !== "type") fail2(`fillOpacity applies to pixel, shape, type and smart object layers; "${id}" is a ${layer.type} layer.`);
3892
+ if (!(typeof props.fillOpacity === "number" && props.fillOpacity >= 0 && props.fillOpacity <= 1)) fail2("fillOpacity must be a number from 0 to 1.");
3893
+ const p = next;
3894
+ if (props.fillOpacity === 1) delete p.fillOpacity;
3895
+ else p.fillOpacity = props.fillOpacity;
3896
+ }
3897
+ if (props.blend !== void 0) {
3898
+ if (props.blend === "pass-through") {
3899
+ if (layer.type !== "group") fail2("pass-through is only for groups.");
3900
+ } else if (!_chunkCWM3CUUXcjs.isBlendMode.call(void 0, props.blend)) fail2(`Unknown blend mode "${props.blend}".`);
3901
+ next.blend = props.blend;
3902
+ }
3903
+ if (props.clipped !== void 0) {
3904
+ if (props.clipped && loc.index === 0) fail2("The bottom layer of a group or the stack has nothing below to clip to.");
3905
+ if (props.clipped) next.clipped = true;
3906
+ else delete next.clipped;
3907
+ }
3908
+ if (props.locks !== void 0) {
3909
+ const locks = {};
3910
+ for (const k of ["pixels", "transparency", "position", "all"]) if (props.locks[k]) locks[k] = true;
3911
+ if (Object.keys(locks).length) next.locks = locks;
3912
+ else delete next.locks;
3913
+ }
3914
+ if (props.collapsed !== void 0) {
3915
+ if (layer.type !== "group") fail2("collapsed applies to groups.");
3916
+ const g = next;
3917
+ if (props.collapsed) g.collapsed = true;
3918
+ else delete g.collapsed;
3919
+ }
3920
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
3921
+ }
3922
+ function groupLayers(layers, ids, name = "Group") {
3923
+ if (!ids.length) fail2("Give at least one layer id to group.");
3924
+ const locs = ids.map((id) => requireLayer(layers, id));
3925
+ const parent = _nullishCoalesce(_optionalChain([locs, 'access', _50 => _50[0], 'access', _51 => _51.parent, 'optionalAccess', _52 => _52.id]), () => ( null));
3926
+ if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _53 => _53.parent, 'optionalAccess', _54 => _54.id]), () => ( null))) !== parent)) fail2("Layers to group must share one parent; move them next to each other first.");
3927
+ for (const l of locs) requireUnlocked(l.layer, "all", "group it");
3928
+ const ordered = [...new Set(locs)].sort((a, b) => a.index - b.index);
3929
+ const top = ordered[ordered.length - 1].index;
3930
+ const below = ordered.filter((l) => l.index < top).length;
3931
+ const group = {
3932
+ type: "group",
3933
+ id: newLayerId("group"),
3934
+ name,
3935
+ visible: true,
3936
+ opacity: 1,
3937
+ blend: "pass-through",
3938
+ children: ordered.map((l) => {
3939
+ const c = { ...l.layer };
3940
+ return c;
3941
+ })
3942
+ };
3943
+ if (_optionalChain([group, 'access', _55 => _55.children, 'access', _56 => _56[0], 'optionalAccess', _57 => _57.clipped])) {
3944
+ const c = { ...group.children[0] };
3945
+ delete c.clipped;
3946
+ group.children[0] = c;
3947
+ }
3948
+ let out = layers;
3949
+ for (const l of ordered) out = _chunkHGTDMKNEcjs.mapLayer.call(void 0, out, l.layer.id, () => null);
3950
+ return { layers: _chunkHGTDMKNEcjs.insertLayer.call(void 0, out, group, parent, top - below), id: group.id };
3951
+ }
3952
+ function ungroupLayer(layers, id) {
3953
+ const loc = requireLayer(layers, id);
3954
+ if (loc.layer.type !== "group") fail2(`Layer "${id}" is not a group.`);
3955
+ requireUnlocked(loc.layer, "all", "ungroup it");
3956
+ const group = loc.layer;
3957
+ let out = _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => null);
3958
+ group.children.forEach((c, i) => {
3959
+ out = _chunkHGTDMKNEcjs.insertLayer.call(void 0, out, c, _nullishCoalesce(_optionalChain([loc, 'access', _58 => _58.parent, 'optionalAccess', _59 => _59.id]), () => ( null)), loc.index + i);
3960
+ });
3961
+ return { layers: out, ids: group.children.map((c) => c.id) };
3962
+ }
3963
+ function offsetLayer(layers, id, offset) {
3964
+ const loc = requireLayer(layers, id);
3965
+ if (loc.layer.type !== "pixel") fail2(`Only pixel layers move; "${id}" is a ${loc.layer.type} layer.`);
3966
+ requireUnlocked(loc.layer, "position", "move it");
3967
+ if (!Number.isFinite(offset.x) || !Number.isFinite(offset.y)) fail2("x and y must be numbers.");
3968
+ const layer = loc.layer;
3969
+ const next = { ...layer, offset: { x: Math.round(offset.x), y: Math.round(offset.y) } };
3970
+ const mask = layer.mask;
3971
+ if (mask && mask.linked === false && !mask.source) {
3972
+ next.mask = { ...mask, surface: _chunkCWM3CUUXcjs.translateSurface.call(void 0, mask.surface, layer.offset.x - next.offset.x, layer.offset.y - next.offset.y) };
3973
+ }
3974
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => followLayerMove(next, next.offset.x - layer.offset.x, next.offset.y - layer.offset.y));
3975
+ }
3976
+ function setLayerMask(layers, id, mask) {
3977
+ const loc = requireLayer(layers, id);
3978
+ requireUnlocked(loc.layer, "all", "change its mask");
3979
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, (l) => {
3980
+ const next = { ...l };
3981
+ if (mask) next.mask = mask;
3982
+ else delete next.mask;
3983
+ return next;
3984
+ });
3985
+ }
3986
+ var DEVELOP_FIELDS = ["brightness", "contrast", "saturation", "exposure", "temperature", "tint"];
3987
+ function normalizeFilter(raw, id = newLayerId("flt")) {
3988
+ const enabled = raw.enabled !== false;
3989
+ if (raw.kind === "blur") {
3990
+ const r = raw.radius;
3991
+ if (r !== void 0 && !(typeof r === "number" && r >= 0 && r <= 50)) fail2("blur radius must be a number from 0 to 50 px.");
3992
+ return { id, kind: "blur", enabled, radius: typeof r === "number" ? r : 2 };
3993
+ }
3994
+ if (raw.kind !== "develop") fail2(`Unknown filter kind "${raw.kind}". Use develop or blur.`);
3995
+ const out = { id, kind: "develop", enabled, brightness: 0, contrast: 0, saturation: 0, exposure: 0, temperature: 0, tint: 0, process: 2 };
3996
+ for (const k of DEVELOP_FIELDS) {
3997
+ const v = raw[k];
3998
+ if (v === void 0) continue;
3999
+ if (!(typeof v === "number" && v >= -100 && v <= 100)) fail2(`${k} must be a number from -100 to 100.`);
4000
+ out[k] = v;
4001
+ }
4002
+ const p = raw.process;
4003
+ if (p !== void 0) {
4004
+ if (p !== 1 && p !== 2) fail2("process must be 1 or 2.");
4005
+ out.process = p;
4006
+ }
4007
+ return out;
4008
+ }
4009
+ function requirePixelLayer(layers, id) {
4010
+ const loc = requireLayer(layers, id);
4011
+ if (loc.layer.type !== "pixel") fail2(`Filters belong to pixel layers; "${id}" is a ${loc.layer.type} layer.`);
4012
+ requireUnlocked(loc.layer, "all", "change its filters");
4013
+ return loc.layer;
4014
+ }
4015
+ function addLayerFilter(layers, id, filter) {
4016
+ const layer = requirePixelLayer(layers, id);
4017
+ if (_optionalChain([layer, 'access', _60 => _60.filters, 'optionalAccess', _61 => _61.some, 'call', _62 => _62((f) => f.kind === filter.kind)])) fail2(`Layer "${id}" already has a ${filter.kind} filter; change it with update_layer_filter.`);
4018
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters: [..._nullishCoalesce(layer.filters, () => ( [])), filter] }));
4019
+ }
4020
+ function updateLayerFilter(layers, id, filterId, changes) {
4021
+ const layer = requirePixelLayer(layers, id);
4022
+ const i = (_nullishCoalesce(layer.filters, () => ( []))).findIndex((f) => f.id === filterId);
4023
+ if (i === -1) fail2(`Layer "${id}" has no filter "${filterId}". Filters: ${(_nullishCoalesce(layer.filters, () => ( []))).map((f) => f.id).join(", ") || "none"}.`);
4024
+ const current = layer.filters[i];
4025
+ if ("kind" in changes && changes.kind !== current.kind) fail2("A filter kind cannot change; remove it and add another.");
4026
+ const merged2 = normalizeFilter({ ...current, ...changes, kind: current.kind }, current.id);
4027
+ const filters = [...layer.filters];
4028
+ filters[i] = merged2;
4029
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters }));
4030
+ }
4031
+ function removeLayerFilter(layers, id, filterId) {
4032
+ const layer = requirePixelLayer(layers, id);
4033
+ if (!(_nullishCoalesce(layer.filters, () => ( []))).some((f) => f.id === filterId)) fail2(`Layer "${id}" has no filter "${filterId}".`);
4034
+ const filters = layer.filters.filter((f) => f.id !== filterId);
4035
+ const next = { ...layer };
4036
+ if (filters.length) next.filters = filters;
4037
+ else delete next.filters;
4038
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
4039
+ }
4040
+ function requireEffectLayer(layers, id, action) {
4041
+ const layer = requireLayer(layers, id).layer;
4042
+ if (layer.type === "adjustment") fail2(`Layer "${layer.name || id}" is an adjustment layer; effects go on pixel, annotation and group layers.`);
4043
+ requireUnlocked(layer, "all", action);
4044
+ return layer;
4045
+ }
4046
+ function layerEffectsOf(layer) {
4047
+ return _nullishCoalesce(layer.effects, () => ( { enabled: true, items: [] }));
4048
+ }
4049
+ function guard(fn) {
4050
+ try {
4051
+ return fn();
4052
+ } catch (e) {
4053
+ if (e instanceof _chunkHGTDMKNEcjs.LayerEffectError) fail2(e.message);
4054
+ throw e;
4055
+ }
4056
+ }
4057
+ function setLayerEffects(layers, id, effects) {
4058
+ const layer = requireEffectLayer(layers, id, "change its effects");
4059
+ const next = { ...layer };
4060
+ if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) {
4061
+ guard(() => _chunkHGTDMKNEcjs.validateLayerEffects.call(void 0, effects));
4062
+ next.effects = effects;
4063
+ } else delete next.effects;
4064
+ return _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, id, () => next);
4065
+ }
4066
+ function addLayerEffect(layers, id, kind, params = {}, index) {
4067
+ if (!_chunkHGTDMKNEcjs.isLayerEffectKind.call(void 0, kind)) fail2(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkHGTDMKNEcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
4068
+ const layer = requireEffectLayer(layers, id, "add effects");
4069
+ const current = layerEffectsOf(layer);
4070
+ const ids = new Set(current.items.map((e) => e.id));
4071
+ let effectId = _chunkHGTDMKNEcjs.newEffectId.call(void 0, );
4072
+ while (ids.has(effectId)) effectId = _chunkHGTDMKNEcjs.newEffectId.call(void 0, );
4073
+ const { id: _ignored, kind: _kind, ...rest } = params;
4074
+ const effect = guard(() => _chunkHGTDMKNEcjs.mergeLayerEffect.call(void 0, _chunkHGTDMKNEcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
4075
+ const items = [...current.items];
4076
+ const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
4077
+ items.splice(at, 0, effect);
4078
+ return { layers: setLayerEffects(layers, id, { ...current, items }), effect };
4079
+ }
4080
+ function requireEffect(layer, effectId) {
4081
+ const items = _nullishCoalesce(_optionalChain([layer, 'access', _63 => _63.effects, 'optionalAccess', _64 => _64.items]), () => ( []));
4082
+ const i = items.findIndex((e) => e.id === effectId);
4083
+ if (i === -1) fail2(`Layer "${layer.name || layer.id}" has no effect "${effectId}". Effects: ${items.map((e) => `${e.id} (${e.kind})`).join(", ") || "none"}; call list_layer_effects.`);
4084
+ return i;
4085
+ }
4086
+ function updateLayerEffect(layers, id, effectId, changes) {
4087
+ const layer = requireEffectLayer(layers, id, "change its effects");
4088
+ const i = requireEffect(layer, effectId);
4089
+ const current = layer.effects;
4090
+ const items = [...current.items];
4091
+ items[i] = guard(() => _chunkHGTDMKNEcjs.mergeLayerEffect.call(void 0, items[i], changes));
4092
+ return setLayerEffects(layers, id, { ...current, items });
4093
+ }
4094
+ function removeLayerEffect(layers, id, effectId) {
4095
+ const layer = requireEffectLayer(layers, id, "change its effects");
4096
+ requireEffect(layer, effectId);
4097
+ const current = layer.effects;
4098
+ return setLayerEffects(layers, id, { ...current, items: current.items.filter((e) => e.id !== effectId) });
4099
+ }
4100
+ function setLayerEffectsEnabled(layers, id, enabled, scale) {
4101
+ const layer = requireEffectLayer(layers, id, "change its effects");
4102
+ if (scale !== void 0 && !(Number.isFinite(scale) && scale >= 0.01 && scale <= 10)) fail2(`scale must be from 0.01 to 10 (1 = 100 %), got ${scale}.`);
4103
+ const current = layerEffectsOf(layer);
4104
+ const next = { ...current, enabled };
4105
+ if (scale !== void 0) {
4106
+ if (scale === 1) delete next.scale;
4107
+ else next.scale = scale;
4108
+ }
4109
+ return setLayerEffects(layers, id, next);
4110
+ }
4111
+ function parseBlend(value, allowPassThrough = false) {
4112
+ if (value === void 0) return void 0;
4113
+ if (value === "pass-through" && allowPassThrough) return value;
4114
+ if (!_chunkCWM3CUUXcjs.isBlendMode.call(void 0, value)) fail2(`Unknown blend mode "${String(value)}".`);
4115
+ return value;
4116
+ }
4117
+ function unionRect(a, b) {
4118
+ if (!a) return b;
4119
+ if (!b) return a;
4120
+ const x = Math.min(a.x, b.x);
4121
+ const y = Math.min(a.y, b.y);
4122
+ return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
4123
+ }
4124
+
4125
+ // src/image-editor/layers/compositor.ts
4126
+ var legacyViewCache = /* @__PURE__ */ new WeakMap();
4127
+ function adjustmentNodeAsLayer(node) {
4128
+ let view = legacyViewCache.get(node);
4129
+ if (!view) {
4130
+ view = {
4131
+ id: node.id,
4132
+ kind: node.kind,
4133
+ enabled: node.visible,
4134
+ opacity: node.opacity,
4135
+ blend: node.blend,
4136
+ params: node.params
4137
+ };
4138
+ legacyViewCache.set(node, view);
4139
+ }
4140
+ return view;
4141
+ }
4142
+ function developAdjustments(f) {
4143
+ return {
4144
+ brightness: f.brightness,
4145
+ contrast: f.contrast,
4146
+ saturation: f.saturation,
4147
+ exposure: f.exposure,
4148
+ temperature: f.temperature,
4149
+ tint: _nullishCoalesce(f.tint, () => ( 0)),
4150
+ blur: 0,
4151
+ opacity: 1,
4152
+ process: f.process
4153
+ };
4154
+ }
4155
+ function applyPixelFilters(data, filters) {
4156
+ for (const f of filters) {
4157
+ if (!isActiveFilter(f) || f.kind !== "develop") continue;
4158
+ const adj = developAdjustments(f);
4159
+ if (normalizeProcessVersion(adj.process) === LATEST_PROCESS_VERSION) applyProcess2Adjustments({ data }, adj);
4160
+ else applyLegacyAdjustments({ data }, adj);
4161
+ }
4162
+ }
4163
+ function depthMaskAlpha(depth, options) {
4164
+ const { mode, depthRange, softness, invert } = options;
4165
+ let v = invert ? 255 - depth : depth;
4166
+ const soft = Math.max(1, softness || 10);
4167
+ const [lo, hi] = depthRange;
4168
+ if (mode === "threshold") {
4169
+ if (v >= hi + soft) return 0;
4170
+ if (v > hi) return Math.round((hi + soft - v) / soft * 255);
4171
+ if (v >= lo) return 255;
4172
+ if (v < lo - soft) return 0;
4173
+ return Math.round((v - (lo - soft)) / soft * 255);
4174
+ }
4175
+ v += lo;
4176
+ return v < 0 ? 0 : v > 255 ? 255 : v;
4177
+ }
4178
+ function runLayerFilters(data, width, height, filters) {
4179
+ for (const f of filters) {
4180
+ if (!isActiveFilter(f)) continue;
4181
+ if (f.kind === "develop") applyPixelFilters(data, [f]);
4182
+ else if (f.kind === "blur") applyBoxBlur({ width, height, data }, Math.min(Math.round(f.radius), 40));
4183
+ }
4184
+ }
4185
+ function runLayerFiltersFloat(data, width, height, filters, linear) {
4186
+ for (const f of filters) {
4187
+ if (!isActiveFilter(f)) continue;
4188
+ if (f.kind === "blur") applyBoxBlurFloat({ width, height, data }, Math.min(Math.round(f.radius), 40));
4189
+ else if (f.kind === "develop") {
4190
+ const adj = developAdjustments(f);
4191
+ if (normalizeProcessVersion(adj.process) === LATEST_PROCESS_VERSION) applyProcess2Float(data, adj, linear);
4192
+ else applyLegacyFloat(data, adj, linear);
4193
+ }
4194
+ }
4195
+ }
4196
+ function filterReach(filters) {
4197
+ let r = 0;
4198
+ for (const f of filters) if (isActiveFilter(f) && f.kind === "blur") r += Math.min(Math.round(f.radius), 40);
4199
+ return r;
4200
+ }
4201
+ var filterSpecCache = /* @__PURE__ */ new WeakMap();
4202
+ function pixelFilterSpec(layer) {
4203
+ const list2 = layer.filters;
4204
+ if (!_optionalChain([list2, 'optionalAccess', _65 => _65.length])) return null;
4205
+ if (filterSpecCache.has(list2)) return filterSpecCache.get(list2);
4206
+ const filters = list2.filter(isActiveFilter);
4207
+ let spec = null;
4208
+ if (filters.length) {
4209
+ const spatial = filters.some(isSpatialFilter);
4210
+ spec = {
4211
+ key: JSON.stringify(filters),
4212
+ spatial,
4213
+ apply: (data, width, height) => runLayerFilters(data, width, height, filters)
4214
+ };
4215
+ }
4216
+ filterSpecCache.set(list2, spec);
4217
+ return spec;
4218
+ }
4219
+ var PHOTO_PROFILE = {
4220
+ isFilterLayer: (l) => l.type === "adjustment",
4221
+ applyFilterRun: (layers, acc, _r, masks) => {
4222
+ const views = layers.map(adjustmentNodeAsLayer);
4223
+ applyAdjustmentLayers({ data: acc }, views, masks);
4224
+ },
4225
+ contentTile: (l, r, sources) => l.type === "annotation" ? _nullishCoalesce(_optionalChain([sources, 'access', _66 => _66.rasterizeAnnotation, 'optionalCall', _67 => _67(l.annotation, r)]), () => ( null)) : null,
4226
+ /** Annotation layers draw with their annotation's blend mode unless the layer sets one. */
4227
+ contentBlend: (l) => l.type === "annotation" && l.blend === "normal" && l.annotation.blend ? l.annotation.blend : l.blend,
4228
+ layerKey: (l) => l.type === "pixel" ? [_nullishCoalesce(l.filters, () => ( null)), _nullishCoalesce(l.source, () => ( null))] : l.type === "adjustment" ? [l.kind, l.params] : l.type === "annotation" ? l.annotation : void 0,
4229
+ pixelFilters: (l) => l.type === "pixel" ? pixelFilterSpec(l) : null,
4230
+ /**
4231
+ * A smart object draws its rendered pixels (contents → placement → smart filters) like a pixel
4232
+ * layer, and a shape layer the pixels rendered from its paths.
4233
+ */
4234
+ isPixelLike: (l) => l.type === "smart" || l.type === "shape" || l.type === "type",
4235
+ maskSourcePlane: (source, W, H, sources) => {
4236
+ const opts = source;
4237
+ const depth = _nullishCoalesce(_optionalChain([sources, 'access', _68 => _68.depthMap, 'optionalCall', _69 => _69(opts)]), () => ( null));
4238
+ if (!depth || depth.width !== W || depth.height !== H) return null;
4239
+ const v = new Float32Array(W * H);
4240
+ for (let i = 0; i < v.length; i++) v[i] = depthMaskAlpha(depth.data[i * 4], opts) / 255;
4241
+ return v;
4242
+ }
4243
+ };
4244
+ var LayerCompositor = class extends _chunkHGTDMKNEcjs.RasterCompositor {
4245
+ constructor(options = {}) {
4246
+ super(PHOTO_PROFILE, options);
4247
+ }
4248
+ // Vector masks reach the engine as part of each layer's raster mask (see `resolveVectorMasks`).
4249
+ composite(layers, rect, sources, options) {
4250
+ return super.composite(resolveVectorMasks(layers, sources.width, sources.height), rect, sources, options);
4251
+ }
4252
+ compositeTiles(layers, rect, sources, onTile, options) {
4253
+ super.compositeTiles(resolveVectorMasks(layers, sources.width, sources.height), rect, sources, onTile, options);
4254
+ }
4255
+ tile(layers, tx, ty, sources) {
4256
+ return super.tile(resolveVectorMasks(layers, sources.width, sources.height), tx, ty, sources);
4257
+ }
4258
+ };
4259
+ function compositeDeep(layers, rect, sources, depth) {
4260
+ const deep = new (0, _chunkHGTDMKNEcjs.DeepCompositor)(new LayerCompositor(), PHOTO_PROFILE, {
4261
+ applyFilterRunDeep: (run, acc, _r, masks) => applyAdjustmentLayersFloat(acc, run.map(adjustmentNodeAsLayer), masks),
4262
+ pixelFiltersDeep: (l) => {
4263
+ if (l.type !== "pixel") return null;
4264
+ const filters = (_nullishCoalesce(l.filters, () => ( []))).filter(isActiveFilter);
4265
+ if (!filters.length) return null;
4266
+ return { reach: filterReach(filters), apply: (data, width, height, linear) => runLayerFiltersFloat(data, width, height, filters, linear) };
4267
+ }
4268
+ }, depth);
4269
+ return deep.composite(resolveVectorMasks(layers, sources.width, sources.height), rect, sources);
4116
4270
  }
4117
4271
 
4118
4272
  // src/image-editor/layers/text.ts
@@ -4179,7 +4333,7 @@ function textOutlines(layer, shaper) {
4179
4333
  }
4180
4334
  var rgbOf = (hex) => {
4181
4335
  const c = _chunkA2IS7EHEcjs.parseCssColor.call(void 0, hex);
4182
- const h = (_nullishCoalesce(_optionalChain([c, 'optionalAccess', _66 => _66.hex]), () => ( "#000000"))).slice(1);
4336
+ const h = (_nullishCoalesce(_optionalChain([c, 'optionalAccess', _70 => _70.hex]), () => ( "#000000"))).slice(1);
4183
4337
  return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
4184
4338
  };
4185
4339
  function renderOutlines(layer, shaper, region) {
@@ -4395,7 +4549,7 @@ function createTypeLayer(init, env, id = newLayerId(), lenient = false) {
4395
4549
  surface: _chunkCWM3CUUXcjs.emptySurface.call(void 0, 4),
4396
4550
  offset: { x: 0, y: 0 }
4397
4551
  };
4398
- if (!layer.runs.length) layer.runs = [{ length: 0, style: _nullishCoalesce(_optionalChain([init, 'access', _67 => _67.runs, 'access', _68 => _68[0], 'optionalAccess', _69 => _69.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)) }];
4552
+ if (!layer.runs.length) layer.runs = [{ length: 0, style: _nullishCoalesce(_optionalChain([init, 'access', _71 => _71.runs, 'access', _72 => _72[0], 'optionalAccess', _73 => _73.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)) }];
4399
4553
  if (init.transform && !_chunkEGZM52EOcjs.isIdentityMatrix.call(void 0, init.transform)) layer.transform = init.transform;
4400
4554
  if (lenient && !renderText(layer, env)) return { ...layer, rendering: "stored" };
4401
4555
  return rerenderText(layer, env);
@@ -4406,7 +4560,7 @@ function updateTypeLayer(layers, id, change, env, action = "edit it") {
4406
4560
  const patch = change(current);
4407
4561
  const next = { ...current, ...patch };
4408
4562
  if (!("annotation" in patch)) delete next.annotation;
4409
- if ("text" in patch || "runs" in patch) next.runs = _chunkEGZM52EOcjs.fitRuns.call(void 0, next.runs, next.text.length, _nullishCoalesce(_optionalChain([current, 'access', _70 => _70.runs, 'access', _71 => _71[0], 'optionalAccess', _72 => _72.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)));
4563
+ if ("text" in patch || "runs" in patch) next.runs = _chunkEGZM52EOcjs.fitRuns.call(void 0, next.runs, next.text.length, _nullishCoalesce(_optionalChain([current, 'access', _74 => _74.runs, 'access', _75 => _75[0], 'optionalAccess', _76 => _76.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)));
4410
4564
  if (!next.runs.length) next.runs = [{ length: 0, style: _chunkEGZM52EOcjs.styleAt.call(void 0, current.runs, 0, _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE) }];
4411
4565
  if ("text" in patch || "paragraphs" in patch) next.paragraphs = _chunkEGZM52EOcjs.fitParagraphRuns.call(void 0, next.paragraphs, next.text);
4412
4566
  const rendered = rerenderText(next, env);
@@ -4693,7 +4847,7 @@ function legacyView(stack, width, height, activeLayerId = null) {
4693
4847
  const { layers } = stack;
4694
4848
  const target = developTarget(layers, activeLayerId);
4695
4849
  const develop = target ? developFilter(target) : void 0;
4696
- const blur = _nullishCoalesce(_nullishCoalesce(stack.legacyOutputBlur, () => ( (target ? _optionalChain([blurFilter, 'call', _73 => _73(target), 'optionalAccess', _74 => _74.radius]) : void 0))), () => ( 0));
4850
+ const blur = _nullishCoalesce(_nullishCoalesce(stack.legacyOutputBlur, () => ( (target ? _optionalChain([blurFilter, 'call', _77 => _77(target), 'optionalAccess', _78 => _78.radius]) : void 0))), () => ( 0));
4697
4851
  const adjustments = {
4698
4852
  ...DEFAULT_ADJUSTMENTS_VALUES,
4699
4853
  ...develop ? {
@@ -4722,7 +4876,7 @@ function legacyView(stack, width, height, activeLayerId = null) {
4722
4876
  };
4723
4877
  walk(layers);
4724
4878
  if (adjNodes.length) adjustments.layers = adjNodes.map((n) => legacyAdjustmentLayer(n, width, height));
4725
- const depthSource = _optionalChain([target, 'optionalAccess', _75 => _75.mask, 'optionalAccess', _76 => _76.source]);
4879
+ const depthSource = _optionalChain([target, 'optionalAccess', _79 => _79.mask, 'optionalAccess', _80 => _80.source]);
4726
4880
  const depthMask = depthSource ? { ...depthSource, depthRange: [...depthSource.depthRange] } : { ...DEFAULT_DEPTH_MASK_VALUES, depthRange: [...DEFAULT_DEPTH_MASK_VALUES.depthRange] };
4727
4881
  return { adjustments, depthMask, annotations, exact: isLegacyShape(stack) };
4728
4882
  }
@@ -4747,7 +4901,7 @@ function isLegacyShape(stack) {
4747
4901
  let adjustments = 0;
4748
4902
  for (; i < layers.length && layers[i].type === "adjustment"; i++) {
4749
4903
  const l = layers[i];
4750
- if (l.clipped || l.locks || _optionalChain([l, 'access', _77 => _77.mask, 'optionalAccess', _78 => _78.source]) || l.effects) return false;
4904
+ if (l.clipped || l.locks || _optionalChain([l, 'access', _81 => _81.mask, 'optionalAccess', _82 => _82.source]) || l.effects) return false;
4751
4905
  adjustments++;
4752
4906
  }
4753
4907
  for (; i < layers.length; i++) {
@@ -4954,7 +5108,7 @@ function isContentsDecoded(contents) {
4954
5108
  }
4955
5109
  function requireDecoded(layer, action) {
4956
5110
  if (isContentsDecoded(layer.contents)) return;
4957
- const what = _optionalChain([layer, 'access', _79 => _79.contents, 'access', _80 => _80.file, 'optionalAccess', _81 => _81.type]) ? `a ${layer.contents.file.type.toUpperCase()} file` : "a file";
5111
+ const what = _optionalChain([layer, 'access', _83 => _83.contents, 'access', _84 => _84.file, 'optionalAccess', _85 => _85.type]) ? `a ${layer.contents.file.type.toUpperCase()} file` : "a file";
4958
5112
  fail4(
4959
5113
  `The contents of smart object "${layer.name || layer.id}" are ${what} that could not be decoded here, so it cannot ${action}. Run prepareSmartObjects() in a browser first, or rasterize it.`
4960
5114
  );
@@ -4979,7 +5133,7 @@ function contentsSurface(contents) {
4979
5133
  width: W,
4980
5134
  height: H,
4981
5135
  globalLight: doc.globalLight,
4982
- pattern: (id) => _nullishCoalesce(_optionalChain([doc, 'access', _82 => _82.patterns, 'optionalAccess', _83 => _83.find, 'call', _84 => _84((p) => p.id === id)]), () => ( null))
5136
+ pattern: (id) => _nullishCoalesce(_optionalChain([doc, 'access', _86 => _86.patterns, 'optionalAccess', _87 => _87.find, 'call', _88 => _88((p) => p.id === id)]), () => ( null))
4983
5137
  });
4984
5138
  s = _chunkCWM3CUUXcjs.surfaceFromPixels.call(void 0, { width: W, height: H, data }, 4, 0, 0);
4985
5139
  }
@@ -5014,7 +5168,7 @@ function placeContents(layer, canvas, options = {}) {
5014
5168
  const preview = Boolean(options.step && options.step > 1) || Boolean(options.clip);
5015
5169
  const key = placementKey(placement, canvas);
5016
5170
  if (!preview) {
5017
- const hit = _optionalChain([placedCache, 'access', _85 => _85.get, 'call', _86 => _86(contents), 'optionalAccess', _87 => _87.get, 'call', _88 => _88(key)]);
5171
+ const hit = _optionalChain([placedCache, 'access', _89 => _89.get, 'call', _90 => _90(contents), 'optionalAccess', _91 => _91.get, 'call', _92 => _92(key)]);
5018
5172
  if (hit) return hit;
5019
5173
  }
5020
5174
  const src = contentsSurface(contents);
@@ -5041,10 +5195,10 @@ function placeContents(layer, canvas, options = {}) {
5041
5195
  let k = 1;
5042
5196
  if (step > 1) {
5043
5197
  k = step;
5044
- let r = _optionalChain([options, 'access', _89 => _89.reduced, 'optionalAccess', _90 => _90.get, 'call', _91 => _91(k)]);
5198
+ let r = _optionalChain([options, 'access', _93 => _93.reduced, 'optionalAccess', _94 => _94.get, 'call', _95 => _95(k)]);
5045
5199
  if (!r) {
5046
5200
  r = _chunkHGTDMKNEcjs.reduceSurface.call(void 0, src, k);
5047
- _optionalChain([options, 'access', _92 => _92.reduced, 'optionalAccess', _93 => _93.set, 'call', _94 => _94(k, r)]);
5201
+ _optionalChain([options, 'access', _96 => _96.reduced, 'optionalAccess', _97 => _97.set, 'call', _98 => _98(k, r)]);
5048
5202
  }
5049
5203
  source = r;
5050
5204
  }
@@ -5077,15 +5231,15 @@ function placeContents(layer, canvas, options = {}) {
5077
5231
  return out;
5078
5232
  }
5079
5233
  function activeSmartFilters(stack) {
5080
- if (!_optionalChain([stack, 'optionalAccess', _95 => _95.enabled])) return [];
5234
+ if (!_optionalChain([stack, 'optionalAccess', _99 => _99.enabled])) return [];
5081
5235
  return stack.filters.filter((f) => f.kind !== "psd" && f.kind !== "effect" && isActiveFilter(f) && f.opacity > 0);
5082
5236
  }
5083
5237
  function activeEffectSmartFilters(stack) {
5084
- if (!_optionalChain([stack, 'optionalAccess', _96 => _96.enabled])) return [];
5238
+ if (!_optionalChain([stack, 'optionalAccess', _100 => _100.enabled])) return [];
5085
5239
  return stack.filters.filter((f) => f.kind === "effect" && f.enabled && f.opacity > 0);
5086
5240
  }
5087
5241
  function runnableSmartFilters(stack) {
5088
- if (!_optionalChain([stack, 'optionalAccess', _97 => _97.enabled])) return [];
5242
+ if (!_optionalChain([stack, 'optionalAccess', _101 => _101.enabled])) return [];
5089
5243
  return stack.filters.filter((f) => f.opacity > 0 && (f.kind === "effect" ? f.enabled : f.kind !== "psd" && isActiveFilter(f)));
5090
5244
  }
5091
5245
  function filterMaskCoverage(mask, canvas) {
@@ -5111,7 +5265,7 @@ function applySmartFilters(placed, stack, canvas) {
5111
5265
  if (!active.length || !(canvas.width > 0 && canvas.height > 0)) return placed;
5112
5266
  const W = canvas.width;
5113
5267
  const H = canvas.height;
5114
- const token = active.some((f) => f.kind === "effect") ? _nullishCoalesce(_optionalChain([canvas, 'access', _98 => _98.effects, 'optionalAccess', _99 => _99.token]), () => ( -1)) : 0;
5268
+ const token = active.some((f) => f.kind === "effect") ? _nullishCoalesce(_optionalChain([canvas, 'access', _102 => _102.effects, 'optionalAccess', _103 => _103.token]), () => ( -1)) : 0;
5115
5269
  const key = JSON.stringify([W, H, token, active.map((f) => ({ ...f, id: void 0 }))]);
5116
5270
  let entry = filteredCache.get(placed);
5117
5271
  let incomplete = false;
@@ -5123,9 +5277,9 @@ function applySmartFilters(placed, stack, canvas) {
5123
5277
  if (f.kind === "effect") {
5124
5278
  if (incomplete) continue;
5125
5279
  const inputKey = JSON.stringify([surfaceId(placed), W, H, active.slice(0, i + 1).map((x) => ({ ...x, id: void 0, blend: x === f ? void 0 : x.blend, opacity: x === f ? void 0 : x.opacity }))]);
5126
- const r = _optionalChain([canvas, 'access', _100 => _100.effects, 'optionalAccess', _101 => _101.resolve, 'call', _102 => _102(f, acc, W, H, inputKey)]);
5127
- if (!_optionalChain([r, 'optionalAccess', _103 => _103.result])) {
5128
- if (_optionalChain([r, 'optionalAccess', _104 => _104.pending])) incomplete = true;
5280
+ const r = _optionalChain([canvas, 'access', _104 => _104.effects, 'optionalAccess', _105 => _105.resolve, 'call', _106 => _106(f, acc, W, H, inputKey)]);
5281
+ if (!_optionalChain([r, 'optionalAccess', _107 => _107.result])) {
5282
+ if (_optionalChain([r, 'optionalAccess', _108 => _108.pending])) incomplete = true;
5129
5283
  continue;
5130
5284
  }
5131
5285
  out2 = new Uint8ClampedArray(r.result);
@@ -5176,7 +5330,7 @@ function rerender(layer, canvas, action = "change") {
5176
5330
  return { ...layer, surface: renderSmartObject(layer, canvas) };
5177
5331
  }
5178
5332
  function normalizePlacement(raw, contents) {
5179
- const c = _optionalChain([raw, 'optionalAccess', _105 => _105.corners]);
5333
+ const c = _optionalChain([raw, 'optionalAccess', _109 => _109.corners]);
5180
5334
  if (!Array.isArray(c) || c.length !== 4 || !c.every((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y))) {
5181
5335
  fail4("corners must be four finite points [top-left, top-right, bottom-right, bottom-left] in document pixels.");
5182
5336
  }
@@ -5221,7 +5375,7 @@ function setSmartPlacement(layers, id, placement, canvas) {
5221
5375
  masksMoved ||= m !== layer.mask;
5222
5376
  next.mask = m;
5223
5377
  }
5224
- if (_optionalChain([next, 'access', _106 => _106.smartFilters, 'optionalAccess', _107 => _107.mask])) {
5378
+ if (_optionalChain([next, 'access', _110 => _110.smartFilters, 'optionalAccess', _111 => _111.mask])) {
5225
5379
  const m = followMask(next.smartFilters.mask, layer, next);
5226
5380
  masksMoved ||= m !== next.smartFilters.mask;
5227
5381
  next.smartFilters = { ...next.smartFilters, mask: m };
@@ -5239,12 +5393,13 @@ function offsetSmartObject(layers, id, dx, dy, canvas) {
5239
5393
  let next = { ...layer, placement: { ...layer.placement, corners } };
5240
5394
  const moveMask = (m2) => m2 && m2.linked !== false && !m2.source ? { ...m2, surface: _chunkCWM3CUUXcjs.translateSurface.call(void 0, m2.surface, mx, my) } : m2;
5241
5395
  if (layer.mask) next.mask = moveMask(layer.mask);
5242
- if (_optionalChain([layer, 'access', _108 => _108.smartFilters, 'optionalAccess', _109 => _109.mask])) next.smartFilters = { ...layer.smartFilters, mask: moveMask(layer.smartFilters.mask) };
5396
+ if (_optionalChain([layer, 'access', _112 => _112.smartFilters, 'optionalAccess', _113 => _113.mask])) next.smartFilters = { ...layer.smartFilters, mask: moveMask(layer.smartFilters.mask) };
5397
+ next = followLayerMove(next, mx, my);
5243
5398
  const spatial = activeSmartFilters(layer.smartFilters).some((f) => f.kind === "blur") || activeEffectSmartFilters(layer.smartFilters).length > 0;
5244
5399
  const b = _chunkCWM3CUUXcjs.contentBounds.call(void 0, layer.surface);
5245
5400
  const m = SMART_RENDER_MARGIN;
5246
5401
  const cut = b && (b.x <= -m || b.y <= -m || b.x + b.width >= canvas.width + m || b.y + b.height >= canvas.height + m);
5247
- if (!spatial && !cut && !(_optionalChain([next, 'access', _110 => _110.smartFilters, 'optionalAccess', _111 => _111.mask]) && activeSmartFilters(next.smartFilters).length && next.smartFilters.mask.linked === false)) {
5402
+ if (!spatial && !cut && !(_optionalChain([next, 'access', _114 => _114.smartFilters, 'optionalAccess', _115 => _115.mask]) && activeSmartFilters(next.smartFilters).length && next.smartFilters.mask.linked === false)) {
5248
5403
  next = { ...next, surface: _chunkCWM3CUUXcjs.translateSurface.call(void 0, layer.surface, mx, my) };
5249
5404
  } else {
5250
5405
  next = rerender(next, canvas, "move");
@@ -5269,7 +5424,7 @@ function translateLayer(layer, dx, dy) {
5269
5424
  mask: moveMask(layer.mask)
5270
5425
  };
5271
5426
  if (!next.mask) delete next.mask;
5272
- if (_optionalChain([layer, 'access', _112 => _112.smartFilters, 'optionalAccess', _113 => _113.mask])) next.smartFilters = { ...layer.smartFilters, mask: moveMask(layer.smartFilters.mask) };
5427
+ if (_optionalChain([layer, 'access', _116 => _116.smartFilters, 'optionalAccess', _117 => _117.mask])) next.smartFilters = { ...layer.smartFilters, mask: moveMask(layer.smartFilters.mask) };
5273
5428
  return next;
5274
5429
  }
5275
5430
  case "group": {
@@ -5329,14 +5484,14 @@ function union(a, b) {
5329
5484
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
5330
5485
  }
5331
5486
  function asSmartFilters(filters) {
5332
- if (!_optionalChain([filters, 'optionalAccess', _114 => _114.length])) return void 0;
5487
+ if (!_optionalChain([filters, 'optionalAccess', _118 => _118.length])) return void 0;
5333
5488
  return { enabled: true, filters: filters.map((f) => ({ ...f, blend: "normal", opacity: 1 })) };
5334
5489
  }
5335
5490
  function convertToSmartObject(layers, ids, canvas, options) {
5336
5491
  if (!ids.length) fail4("Give at least one layer id to convert.");
5337
5492
  const locs = [...new Set(ids)].map((id) => requireLayer(layers, id));
5338
- const parent = _nullishCoalesce(_optionalChain([locs, 'access', _115 => _115[0], 'access', _116 => _116.parent, 'optionalAccess', _117 => _117.id]), () => ( null));
5339
- if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _118 => _118.parent, 'optionalAccess', _119 => _119.id]), () => ( null))) !== parent)) fail4("Layers to convert must share one parent; move them next to each other first.");
5493
+ const parent = _nullishCoalesce(_optionalChain([locs, 'access', _119 => _119[0], 'access', _120 => _120.parent, 'optionalAccess', _121 => _121.id]), () => ( null));
5494
+ if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _122 => _122.parent, 'optionalAccess', _123 => _123.id]), () => ( null))) !== parent)) fail4("Layers to convert must share one parent; move them next to each other first.");
5340
5495
  for (const l of locs) requireUnlocked(l.layer, "all", "convert it");
5341
5496
  const ordered = locs.sort((a, b) => a.index - b.index);
5342
5497
  const top = ordered[ordered.length - 1];
@@ -5382,9 +5537,9 @@ function convertToSmartObject(layers, ids, canvas, options) {
5382
5537
  const nested = ordered.map((l) => {
5383
5538
  let layer = l.layer;
5384
5539
  if (layer.type === "pixel" && layer.source === "document") {
5385
- const resolved = { ...layer, surface: options.surfaceOf(layer) };
5386
- delete resolved.source;
5387
- layer = resolved;
5540
+ const resolved2 = { ...layer, surface: options.surfaceOf(layer) };
5541
+ delete resolved2.source;
5542
+ layer = resolved2;
5388
5543
  }
5389
5544
  if (_chunkHGTDMKNEcjs.flattenLayers.call(void 0, [layer]).some((x) => x.type === "pixel" && x.source === "document")) fail4(`Layer "${layer.name || layer.id}" holds the document image inside a group; convert the Background on its own.`);
5390
5545
  return translateLayer(layer, -b.x, -b.y);
@@ -5394,7 +5549,7 @@ function convertToSmartObject(layers, ids, canvas, options) {
5394
5549
  delete first.clipped;
5395
5550
  nested[0] = first;
5396
5551
  }
5397
- const name = _optionalChain([options, 'access', _120 => _120.name, 'optionalAccess', _121 => _121.trim, 'call', _122 => _122()]) || top.layer.name || "Smart Object";
5552
+ const name = _optionalChain([options, 'access', _124 => _124.name, 'optionalAccess', _125 => _125.trim, 'call', _126 => _126()]) || top.layer.name || "Smart Object";
5398
5553
  const contents = documentContents({ layers: nested }, b.width, b.height, `${name}.psb`);
5399
5554
  smart = {
5400
5555
  type: "smart",
@@ -5409,7 +5564,7 @@ function convertToSmartObject(layers, ids, canvas, options) {
5409
5564
  offset: { x: 0, y: 0 }
5410
5565
  };
5411
5566
  }
5412
- if (_optionalChain([options, 'access', _123 => _123.name, 'optionalAccess', _124 => _124.trim, 'call', _125 => _125()])) smart.name = options.name.trim();
5567
+ if (_optionalChain([options, 'access', _127 => _127.name, 'optionalAccess', _128 => _128.trim, 'call', _129 => _129()])) smart.name = options.name.trim();
5413
5568
  smart = { ...smart, surface: renderSmartObject(smart, canvas) };
5414
5569
  const below = ordered.filter((l) => l.index < top.index).length;
5415
5570
  let out = layers;
@@ -5439,12 +5594,12 @@ function rasterizeSmartObject(layers, id) {
5439
5594
  function copySmartObject(layers, id, linked, name) {
5440
5595
  const loc = requireLayer(layers, id);
5441
5596
  const layer = requireSmartObject(layers, id);
5442
- const copy = { ...layer, id: newLayerId("smart"), name: _optionalChain([name, 'optionalAccess', _126 => _126.trim, 'call', _127 => _127()]) || `${layer.name || "Smart Object"} copy` };
5597
+ const copy = { ...layer, id: newLayerId("smart"), name: _optionalChain([name, 'optionalAccess', _130 => _130.trim, 'call', _131 => _131()]) || `${layer.name || "Smart Object"} copy` };
5443
5598
  delete copy.locks;
5444
5599
  delete copy.psd;
5445
5600
  if (!linked) copy.contents = { ...layer.contents, id: newContentsId() };
5446
5601
  if (copy.smartFilters) copy.smartFilters = { ...copy.smartFilters, filters: copy.smartFilters.filters.map((f) => ({ ...f, id: newLayerId("flt") })) };
5447
- return { layers: _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _128 => _128.parent, 'optionalAccess', _129 => _129.id]), () => ( null)), loc.index + 1), layer: copy };
5602
+ return { layers: _chunkHGTDMKNEcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _132 => _132.parent, 'optionalAccess', _133 => _133.id]), () => ( null)), loc.index + 1), layer: copy };
5448
5603
  }
5449
5604
  function instancesOf(layers, contentsId) {
5450
5605
  return _chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "smart" && l.contents.id === contentsId).map((l) => l.id);
@@ -5516,7 +5671,7 @@ function stackOf(layer) {
5516
5671
  return _nullishCoalesce(layer.smartFilters, () => ( { enabled: true, filters: [] }));
5517
5672
  }
5518
5673
  function requireFilter(layer, filterId) {
5519
- const list2 = _nullishCoalesce(_optionalChain([layer, 'access', _130 => _130.smartFilters, 'optionalAccess', _131 => _131.filters]), () => ( []));
5674
+ const list2 = _nullishCoalesce(_optionalChain([layer, 'access', _134 => _134.smartFilters, 'optionalAccess', _135 => _135.filters]), () => ( []));
5520
5675
  const i = list2.findIndex((f) => f.id === filterId);
5521
5676
  if (i === -1) fail4(`Smart object "${layer.name || layer.id}" has no smart filter "${filterId}". Filters: ${list2.map((f) => `${f.id} (${f.kind})`).join(", ") || "none"}; call get_smart_object.`);
5522
5677
  return i;
@@ -5583,7 +5738,7 @@ function setSmartFiltersEnabled(layers, id, enabled, canvas) {
5583
5738
  }
5584
5739
  function setSmartFilterMask(layers, id, mask, canvas) {
5585
5740
  const layer = editableSmart(layers, id);
5586
- if (_optionalChain([mask, 'optionalAccess', _132 => _132.source])) fail4("A smart filter mask is painted, not generated; use a raster mask.");
5741
+ if (_optionalChain([mask, 'optionalAccess', _136 => _136.source])) fail4("A smart filter mask is painted, not generated; use a raster mask.");
5587
5742
  const stack = { ...stackOf(layer) };
5588
5743
  if (mask) stack.mask = mask;
5589
5744
  else delete stack.mask;
@@ -5676,6 +5831,7 @@ function baseFields(layer, ctx) {
5676
5831
  };
5677
5832
  if (layer.clipped) out.clipped = true;
5678
5833
  if (layer.mask) out.mask = serializeMask(layer.mask, `${layer.id}-mask`, ctx);
5834
+ if (layer.vectorMask) out.vectorMask = serializeVectorMask(layer.vectorMask);
5679
5835
  if (layer.locks && Object.values(layer.locks).some(Boolean)) out.locks = { ...layer.locks };
5680
5836
  if (layer.effects) out.effects = serializeEffects(layer.effects);
5681
5837
  return out;
@@ -5700,6 +5856,36 @@ function deserializeEffects(raw) {
5700
5856
  }
5701
5857
  return _chunkHGTDMKNEcjs.normalizeLayerEffects.call(void 0, { ...r, psd });
5702
5858
  }
5859
+ function serializeVectorMask(vm) {
5860
+ const out = { components: JSON.parse(JSON.stringify(vm.components)) };
5861
+ if (vm.fillRule === "evenodd") out.fillRule = "evenodd";
5862
+ if (vm.inverted) out.inverted = true;
5863
+ if (vm.enabled === false) out.enabled = false;
5864
+ if (vm.linked === false) out.linked = false;
5865
+ if (vm.density !== void 0 && vm.density !== 1) out.density = vm.density;
5866
+ if (vm.feather) out.feather = vm.feather;
5867
+ return out;
5868
+ }
5869
+ function readVectorMask(r) {
5870
+ if (!Array.isArray(r.components)) throw new Error("its components are missing");
5871
+ const components = r.components.map((raw, i) => {
5872
+ const c = raw;
5873
+ const op = requireOperation(_optionalChain([c, 'optionalAccess', _137 => _137.op]), `components[${i}].op`);
5874
+ if (_optionalChain([c, 'optionalAccess', _138 => _138.live])) {
5875
+ const live = normalizeLiveShape(c.live, `components[${i}].live`);
5876
+ return { op, subpaths: liveShapeSubpaths(live), live };
5877
+ }
5878
+ return { op, subpaths: Array.isArray(_optionalChain([c, 'optionalAccess', _139 => _139.subpaths])) && !c.subpaths.length ? [] : normalizeSubpaths(_optionalChain([c, 'optionalAccess', _140 => _140.subpaths]), `components[${i}].subpaths`) };
5879
+ });
5880
+ const vm = { components };
5881
+ if (r.fillRule === "evenodd") vm.fillRule = "evenodd";
5882
+ if (r.inverted === true) vm.inverted = true;
5883
+ if (r.enabled === false) vm.enabled = false;
5884
+ if (r.linked === false) vm.linked = false;
5885
+ if (typeof r.density === "number" && r.density !== 1) vm.density = num2(r.density, 0, 1, 1);
5886
+ if (typeof r.feather === "number" && r.feather > 0) vm.feather = num2(r.feather, 0, 1e3, 0);
5887
+ return vm;
5888
+ }
5703
5889
  function serializeMask(mask, hint, ctx) {
5704
5890
  const out = { defaultValue: mask.defaultValue };
5705
5891
  if (!mask.source) {
@@ -5735,7 +5921,7 @@ function serializeLayer(layer, ctx) {
5735
5921
  }
5736
5922
  }
5737
5923
  if (layer.fillOpacity !== void 0 && layer.fillOpacity !== 1) out.fillOpacity = layer.fillOpacity;
5738
- if (_optionalChain([layer, 'access', _133 => _133.filters, 'optionalAccess', _134 => _134.length])) out.filters = JSON.parse(JSON.stringify(layer.filters));
5924
+ if (_optionalChain([layer, 'access', _141 => _141.filters, 'optionalAccess', _142 => _142.length])) out.filters = JSON.parse(JSON.stringify(layer.filters));
5739
5925
  if (layer.generator) out.generator = JSON.parse(JSON.stringify(layer.generator));
5740
5926
  if (layer.source !== "document") {
5741
5927
  const deep = encodeDeepSurface(layer.surface);
@@ -5778,12 +5964,12 @@ function serializeType(layer, base, ctx) {
5778
5964
  out.x = enc.x;
5779
5965
  out.y = enc.y;
5780
5966
  }
5781
- if (_optionalChain([layer, 'access', _135 => _135.missingFonts, 'optionalAccess', _136 => _136.length])) out.missingFonts = [...layer.missingFonts];
5967
+ if (_optionalChain([layer, 'access', _143 => _143.missingFonts, 'optionalAccess', _144 => _144.length])) out.missingFonts = [...layer.missingFonts];
5782
5968
  if (layer.annotation) out.annotation = JSON.parse(JSON.stringify(layer.annotation));
5783
- if (_optionalChain([layer, 'access', _137 => _137.psd, 'optionalAccess', _138 => _138.tySh]) || _optionalChain([layer, 'access', _139 => _139.psd, 'optionalAccess', _140 => _140.blocks, 'optionalAccess', _141 => _141.length])) {
5969
+ if (_optionalChain([layer, 'access', _145 => _145.psd, 'optionalAccess', _146 => _146.tySh]) || _optionalChain([layer, 'access', _147 => _147.psd, 'optionalAccess', _148 => _148.blocks, 'optionalAccess', _149 => _149.length])) {
5784
5970
  out.psd = {};
5785
5971
  if (layer.psd.tySh) out.psd.tySh = _chunkCWM3CUUXcjs.bytesToBase64.call(void 0, layer.psd.tySh);
5786
- if (_optionalChain([layer, 'access', _142 => _142.psd, 'access', _143 => _143.blocks, 'optionalAccess', _144 => _144.length])) out.psd.blocks = layer.psd.blocks.map((b) => ({ key: b.key, data: _chunkCWM3CUUXcjs.bytesToBase64.call(void 0, b.data) }));
5972
+ if (_optionalChain([layer, 'access', _150 => _150.psd, 'access', _151 => _151.blocks, 'optionalAccess', _152 => _152.length])) out.psd.blocks = layer.psd.blocks.map((b) => ({ key: b.key, data: _chunkCWM3CUUXcjs.bytesToBase64.call(void 0, b.data) }));
5787
5973
  if (layer.psd.signature) out.psd.signature = layer.psd.signature;
5788
5974
  }
5789
5975
  return out;
@@ -5793,15 +5979,15 @@ function readType(r, base, ctx) {
5793
5979
  try {
5794
5980
  const text3 = normalizeText(_nullishCoalesce(r.text, () => ( "")));
5795
5981
  const runs = (Array.isArray(r.runs) ? r.runs : []).map((run, i) => ({
5796
- length: Math.max(0, Math.floor(num2(_optionalChain([run, 'optionalAccess', _145 => _145.length]), 0, 1e9, 0))),
5797
- style: patchTextStyle(_chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE, _optionalChain([run, 'optionalAccess', _146 => _146.style]) && typeof run.style === "object" ? run.style : {}, `runs[${i}].style`)
5982
+ length: Math.max(0, Math.floor(num2(_optionalChain([run, 'optionalAccess', _153 => _153.length]), 0, 1e9, 0))),
5983
+ style: patchTextStyle(_chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE, _optionalChain([run, 'optionalAccess', _154 => _154.style]) && typeof run.style === "object" ? run.style : {}, `runs[${i}].style`)
5798
5984
  }));
5799
5985
  const paragraphs = (Array.isArray(r.paragraphs) ? r.paragraphs : []).map((p, i) => ({
5800
- length: Math.max(0, Math.floor(num2(_optionalChain([p, 'optionalAccess', _147 => _147.length]), 0, 1e9, 0))),
5801
- style: patchParagraphStyle({}, _optionalChain([p, 'optionalAccess', _148 => _148.style]) && typeof p.style === "object" ? p.style : {}, `paragraphs[${i}].style`)
5986
+ length: Math.max(0, Math.floor(num2(_optionalChain([p, 'optionalAccess', _155 => _155.length]), 0, 1e9, 0))),
5987
+ style: patchParagraphStyle({}, _optionalChain([p, 'optionalAccess', _156 => _156.style]) && typeof p.style === "object" ? p.style : {}, `paragraphs[${i}].style`)
5802
5988
  }));
5803
5989
  const f = r.frame;
5804
- const frame = _optionalChain([f, 'optionalAccess', _149 => _149.kind]) === "box" ? { kind: "box", width: num2(f.width, 1, 1e6, 100), height: num2(f.height, 1, 1e6, 100) } : _optionalChain([f, 'optionalAccess', _150 => _150.origin]) === "top" ? { kind: "point", origin: "top" } : { kind: "point" };
5990
+ const frame = _optionalChain([f, 'optionalAccess', _157 => _157.kind]) === "box" ? { kind: "box", width: num2(f.width, 1, 1e6, 100), height: num2(f.height, 1, 1e6, 100) } : _optionalChain([f, 'optionalAccess', _158 => _158.origin]) === "top" ? { kind: "point", origin: "top" } : { kind: "point" };
5805
5991
  const m = Array.isArray(r.transform) && r.transform.length === 6 && r.transform.every((v) => typeof v === "number" && Number.isFinite(v)) ? r.transform : void 0;
5806
5992
  const layer = {
5807
5993
  ...base,
@@ -5813,7 +5999,7 @@ function readType(r, base, ctx) {
5813
5999
  surface: _chunkCWM3CUUXcjs.emptySurface.call(void 0, 4),
5814
6000
  offset: { x: 0, y: 0 }
5815
6001
  };
5816
- if (!layer.runs.length) layer.runs = [{ length: 0, style: _nullishCoalesce(_optionalChain([runs, 'access', _151 => _151[0], 'optionalAccess', _152 => _152.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)) }];
6002
+ if (!layer.runs.length) layer.runs = [{ length: 0, style: _nullishCoalesce(_optionalChain([runs, 'access', _159 => _159[0], 'optionalAccess', _160 => _160.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)) }];
5817
6003
  if (m) layer.transform = m;
5818
6004
  if (r.antiAlias === false) layer.antiAlias = false;
5819
6005
  if (typeof r.fillOpacity === "number" && r.fillOpacity !== 1) layer.fillOpacity = num2(r.fillOpacity, 0, 1, 1);
@@ -5824,10 +6010,10 @@ function readType(r, base, ctx) {
5824
6010
  if (typeof r.psd.tySh === "string") psd.tySh = _chunkCWM3CUUXcjs.base64ToBytes.call(void 0, r.psd.tySh);
5825
6011
  if (Array.isArray(r.psd.blocks)) psd.blocks = r.psd.blocks.filter((b) => b && typeof b.key === "string" && typeof b.data === "string").map((b) => ({ key: b.key, data: _chunkCWM3CUUXcjs.base64ToBytes.call(void 0, b.data) }));
5826
6012
  if (typeof r.psd.signature === "string") psd.signature = r.psd.signature;
5827
- if (psd.tySh || _optionalChain([psd, 'access', _153 => _153.blocks, 'optionalAccess', _154 => _154.length])) layer.psd = psd;
6013
+ if (psd.tySh || _optionalChain([psd, 'access', _161 => _161.blocks, 'optionalAccess', _162 => _162.length])) layer.psd = psd;
5828
6014
  }
5829
6015
  if (typeof r.asset === "string") return { ...layer, surface: readSurface(r.asset, r.x, r.y, 4, 0, ctx, label), rendering: "stored" };
5830
- const env = { ..._nullishCoalesce(ctx.canvas, () => ( { width: 1, height: 1 })), shaper: _nullishCoalesce(_optionalChain([ctx, 'access', _155 => _155.text, 'optionalAccess', _156 => _156.shaper]), () => ( null)), createCanvas: _optionalChain([ctx, 'access', _157 => _157.text, 'optionalAccess', _158 => _158.createCanvas]) };
6016
+ const env = { ..._nullishCoalesce(ctx.canvas, () => ( { width: 1, height: 1 })), shaper: _nullishCoalesce(_optionalChain([ctx, 'access', _163 => _163.text, 'optionalAccess', _164 => _164.shaper]), () => ( null)), createCanvas: _optionalChain([ctx, 'access', _165 => _165.text, 'optionalAccess', _166 => _166.createCanvas]) };
5831
6017
  try {
5832
6018
  return rerenderText(layer, env);
5833
6019
  } catch (e8) {
@@ -5850,7 +6036,7 @@ function serializeShape(layer, base) {
5850
6036
  if (layer.inverted) out.inverted = true;
5851
6037
  if (layer.fillOpacity !== void 0 && layer.fillOpacity !== 1) out.fillOpacity = layer.fillOpacity;
5852
6038
  if (layer.annotation) out.annotation = JSON.parse(JSON.stringify(layer.annotation));
5853
- if (_optionalChain([layer, 'access', _159 => _159.psd, 'optionalAccess', _160 => _160.blocks, 'optionalAccess', _161 => _161.length])) out.psd = { blocks: layer.psd.blocks.map((b) => ({ key: b.key, data: _chunkCWM3CUUXcjs.bytesToBase64.call(void 0, b.data) })), ...layer.psd.signature ? { signature: layer.psd.signature } : {} };
6039
+ if (_optionalChain([layer, 'access', _167 => _167.psd, 'optionalAccess', _168 => _168.blocks, 'optionalAccess', _169 => _169.length])) out.psd = { blocks: layer.psd.blocks.map((b) => ({ key: b.key, data: _chunkCWM3CUUXcjs.bytesToBase64.call(void 0, b.data) })), ...layer.psd.signature ? { signature: layer.psd.signature } : {} };
5854
6040
  return out;
5855
6041
  }
5856
6042
  function readShape(r, base, ctx) {
@@ -5864,12 +6050,12 @@ function readShape(r, base, ctx) {
5864
6050
  if (!data) {
5865
6051
  if (!Array.isArray(r.components) || !r.components.length) throw new Error("it has no components");
5866
6052
  const components = r.components.map((c, i) => {
5867
- const op = requireOperation(_optionalChain([c, 'optionalAccess', _162 => _162.op]), `components[${i}].op`);
5868
- if (_optionalChain([c, 'optionalAccess', _163 => _163.live])) {
6053
+ const op = requireOperation(_optionalChain([c, 'optionalAccess', _170 => _170.op]), `components[${i}].op`);
6054
+ if (_optionalChain([c, 'optionalAccess', _171 => _171.live])) {
5869
6055
  const live = normalizeLiveShape(c.live, `components[${i}].live`);
5870
6056
  return { op, subpaths: liveShapeSubpaths(live), live };
5871
6057
  }
5872
- return { op, subpaths: Array.isArray(_optionalChain([c, 'optionalAccess', _164 => _164.subpaths])) && !c.subpaths.length ? [] : normalizeSubpaths(_optionalChain([c, 'optionalAccess', _165 => _165.subpaths]), `components[${i}].subpaths`) };
6058
+ return { op, subpaths: Array.isArray(_optionalChain([c, 'optionalAccess', _172 => _172.subpaths])) && !c.subpaths.length ? [] : normalizeSubpaths(_optionalChain([c, 'optionalAccess', _173 => _173.subpaths]), `components[${i}].subpaths`) };
5873
6059
  });
5874
6060
  data = {
5875
6061
  components,
@@ -5940,7 +6126,7 @@ function serializeContents(c, ctx) {
5940
6126
  if (c.kind === "document" && c.document) {
5941
6127
  out.layers = c.document.layers.map((l) => serializeLayer(l, ctx));
5942
6128
  if (c.document.globalLight) out.globalLight = { ...c.document.globalLight };
5943
- if (_optionalChain([c, 'access', _166 => _166.document, 'access', _167 => _167.patterns, 'optionalAccess', _168 => _168.length])) out.patterns = serializePatterns(c.document.patterns);
6129
+ if (_optionalChain([c, 'access', _174 => _174.document, 'access', _175 => _175.patterns, 'optionalAccess', _176 => _176.length])) out.patterns = serializePatterns(c.document.patterns);
5944
6130
  }
5945
6131
  if (c.file) out.file = { type: c.file.type, data: _chunkCWM3CUUXcjs.bytesToBase64.call(void 0, c.file.bytes) };
5946
6132
  if (c.linked) out.linked = { path: c.linked.path };
@@ -6107,6 +6293,13 @@ function deserializeLayer(raw, ctx) {
6107
6293
  if (r.clipped === true) base.clipped = true;
6108
6294
  const mask = readMask(r.mask, ctx, `Layer "${base.name || id}"`);
6109
6295
  if (mask) base.mask = mask;
6296
+ if (r.vectorMask && typeof r.vectorMask === "object" && r.type !== "shape") {
6297
+ try {
6298
+ base.vectorMask = readVectorMask(r.vectorMask);
6299
+ } catch (err) {
6300
+ ctx.problems.push(`The vector mask of layer "${base.name || id}" could not be read (${err instanceof Error ? err.message : String(err)}); it was left out.`);
6301
+ }
6302
+ }
6110
6303
  if (r.locks && typeof r.locks === "object") {
6111
6304
  const locks = {};
6112
6305
  for (const k of ["pixels", "transparency", "position", "all"]) if (r.locks[k] === true) locks[k] = true;
@@ -6120,7 +6313,7 @@ function deserializeLayer(raw, ctx) {
6120
6313
  ...base,
6121
6314
  type: "pixel",
6122
6315
  surface: r.source === "document" ? _chunkCWM3CUUXcjs.emptySurface.call(void 0, 4) : readSurface(r.asset, r.x, r.y, 4, 0, ctx, `Layer "${base.name || id}"`),
6123
- offset: { x: Math.round(num2(_optionalChain([r, 'access', _169 => _169.offset, 'optionalAccess', _170 => _170.x]), -1e7, 1e7, 0)), y: Math.round(num2(_optionalChain([r, 'access', _171 => _171.offset, 'optionalAccess', _172 => _172.y]), -1e7, 1e7, 0)) }
6316
+ offset: { x: Math.round(num2(_optionalChain([r, 'access', _177 => _177.offset, 'optionalAccess', _178 => _178.x]), -1e7, 1e7, 0)), y: Math.round(num2(_optionalChain([r, 'access', _179 => _179.offset, 'optionalAccess', _180 => _180.y]), -1e7, 1e7, 0)) }
6124
6317
  };
6125
6318
  if (r.source === "document") layer.source = "document";
6126
6319
  else if (r.deep) layer.surface = decodeDeepSurface(layer.surface, r.deep, ctx.problems, `Layer "${base.name || id}"`);
@@ -6129,7 +6322,7 @@ function deserializeLayer(raw, ctx) {
6129
6322
  if (filters) layer.filters = filters;
6130
6323
  const generator = readEffectRef(r.generator);
6131
6324
  if (generator) {
6132
- const duration = _optionalChain([r, 'access', _173 => _173.generator, 'access', _174 => _174.animate, 'optionalAccess', _175 => _175.duration]);
6325
+ const duration = _optionalChain([r, 'access', _181 => _181.generator, 'access', _182 => _182.animate, 'optionalAccess', _183 => _183.duration]);
6133
6326
  layer.generator = {
6134
6327
  ...generator,
6135
6328
  ...typeof r.generator.time === "number" && r.generator.time > 0 ? { time: r.generator.time } : {},
@@ -6160,7 +6353,7 @@ function deserializeLayer(raw, ctx) {
6160
6353
  return null;
6161
6354
  }
6162
6355
  const annotation = JSON.parse(JSON.stringify({ ...a, id: typeof a.id === "string" ? a.id : id }));
6163
- const migrated = annotationLayerFor(annotation, { ..._nullishCoalesce(ctx.canvas, () => ( { width: 1, height: 1 })), shaper: _nullishCoalesce(_optionalChain([ctx, 'access', _176 => _176.text, 'optionalAccess', _177 => _177.shaper]), () => ( null)), createCanvas: _optionalChain([ctx, 'access', _178 => _178.text, 'optionalAccess', _179 => _179.createCanvas]) });
6356
+ const migrated = annotationLayerFor(annotation, { ..._nullishCoalesce(ctx.canvas, () => ( { width: 1, height: 1 })), shaper: _nullishCoalesce(_optionalChain([ctx, 'access', _184 => _184.text, 'optionalAccess', _185 => _185.shaper]), () => ( null)), createCanvas: _optionalChain([ctx, 'access', _186 => _186.text, 'optionalAccess', _187 => _187.createCanvas]) });
6164
6357
  if (migrated.type === "shape" || migrated.type === "type") {
6165
6358
  const blend = base.blend === "normal" ? migrated.blend : base.blend;
6166
6359
  return { ...migrated, ...base, blend, id, name: base.name };
@@ -6738,7 +6931,7 @@ function descriptor(classId, items = []) {
6738
6931
  return { name: "", classId, items };
6739
6932
  }
6740
6933
  function descGet(d, key) {
6741
- return _optionalChain([d, 'access', _180 => _180.items, 'access', _181 => _181.find, 'call', _182 => _182(([k]) => k === key), 'optionalAccess', _183 => _183[1]]);
6934
+ return _optionalChain([d, 'access', _188 => _188.items, 'access', _189 => _189.find, 'call', _190 => _190(([k]) => k === key), 'optionalAccess', _191 => _191[1]]);
6742
6935
  }
6743
6936
  function descNumber(d, key) {
6744
6937
  const v = descGet(d, key);
@@ -6748,7 +6941,7 @@ function descNumber(d, key) {
6748
6941
  }
6749
6942
  function descBool(d, key) {
6750
6943
  const v = descGet(d, key);
6751
- return _optionalChain([v, 'optionalAccess', _184 => _184.type]) === "bool" ? v.value : void 0;
6944
+ return _optionalChain([v, 'optionalAccess', _192 => _192.type]) === "bool" ? v.value : void 0;
6752
6945
  }
6753
6946
  function descObject(d, key) {
6754
6947
  const v = descGet(d, key);
@@ -7330,97 +7523,6 @@ function writeAdjustmentBlock(kind, params) {
7330
7523
  throw new Error(`Unknown adjustment kind "${kind}".`);
7331
7524
  }
7332
7525
 
7333
- // src/image-editor/psd/channels.ts
7334
- var hexToRgb2 = (hex) => {
7335
- const v = parseInt(_nullishCoalesce(_optionalChain([/^#?([0-9a-f]{6})$/i, 'access', _185 => _185.exec, 'call', _186 => _186(hex), 'optionalAccess', _187 => _187[1]]), () => ( "ff0000")), 16);
7336
- return [v >> 16 & 255, v >> 8 & 255, v & 255];
7337
- };
7338
- var rgbToHex = (r, g, b) => `#${[r, g, b].map((c) => c.toString(16).padStart(2, "0")).join("")}`;
7339
- function alphaChannelResources(channels) {
7340
- if (!channels.length) return [];
7341
- const names = new PsdWriter();
7342
- for (const c of channels) names.pascal(encodeLegacyName(c.name), 1);
7343
- const unicode = new PsdWriter();
7344
- for (const c of channels) unicode.unicode(c.name);
7345
- const display = new PsdWriter();
7346
- display.u32(1);
7347
- for (const c of channels) {
7348
- const [r, g, b] = hexToRgb2(c.color);
7349
- display.u16(0);
7350
- for (const v of [r, g, b, 0]) display.u16(v * 257);
7351
- display.u16(Math.round(Math.min(1, Math.max(0, c.opacity)) * 100));
7352
- display.u8(c.indicates === "selected" ? 0 : 1);
7353
- display.u8(0);
7354
- }
7355
- return [
7356
- { id: 1006, name: "", data: names.result() },
7357
- { id: 1045, name: "", data: unicode.result() },
7358
- { id: 1077, name: "", data: display.result() }
7359
- ];
7360
- }
7361
- function planeTo8(plane, n, depth) {
7362
- if (depth === 8) return plane.slice(0, n);
7363
- const out = new Uint8Array(n);
7364
- const view = new DataView(plane.buffer, plane.byteOffset, plane.byteLength);
7365
- for (let i = 0; i < n; i++) {
7366
- if (depth === 16) out[i] = plane[2 * i];
7367
- else out[i] = Math.round(Math.min(1, Math.max(0, view.getFloat32(4 * i, false))) * 255);
7368
- }
7369
- return out;
7370
- }
7371
- function readAlphaChannels(planes, header, first, resource2, warn) {
7372
- const count = header.channels - first;
7373
- if (count <= 0 || header.depth === 1) return [];
7374
- const size = rowBytes(header.width, header.depth) * header.height;
7375
- const n = header.width * header.height;
7376
- const names = [];
7377
- const unicode = resource2(1045);
7378
- if (unicode) {
7379
- const r = new PsdReader(unicode);
7380
- while (r.remaining >= 4 && names.length < count) names.push(r.unicode().replace(/\0+$/, ""));
7381
- } else {
7382
- const legacy = resource2(1006);
7383
- if (legacy) {
7384
- const r = new PsdReader(legacy);
7385
- while (r.remaining >= 1 && names.length < count) names.push(new TextDecoder("latin1").decode(r.pascal(1)));
7386
- }
7387
- }
7388
- const display = [];
7389
- const info = resource2(1077);
7390
- if (info && info.length >= 4) {
7391
- const r = new PsdReader(info);
7392
- r.u32();
7393
- while (r.remaining >= 14 && display.length < count) {
7394
- r.u16();
7395
- const [cr, cg, cb] = [r.u16(), r.u16(), r.u16()];
7396
- r.u16();
7397
- const opacity = r.u16();
7398
- const kind = r.u8();
7399
- r.u8();
7400
- display.push({ color: rgbToHex(cr >> 8, cg >> 8, cb >> 8), opacity: Math.min(100, opacity) / 100, kind });
7401
- }
7402
- }
7403
- const out = [];
7404
- for (let i = 0; i < count; i++) {
7405
- const start = (first + i) * size;
7406
- if (start + size > planes.length) break;
7407
- const d = display[i];
7408
- const name = names[i] || `Alpha ${i + 1}`;
7409
- if (_optionalChain([d, 'optionalAccess', _188 => _188.kind]) === 2) {
7410
- warn(`Spot colour channel "${name}" is not supported and was left out.`);
7411
- continue;
7412
- }
7413
- out.push({
7414
- name,
7415
- data: planeTo8(planes.subarray(start, start + size), n, header.depth),
7416
- color: _nullishCoalesce(_optionalChain([d, 'optionalAccess', _189 => _189.color]), () => ( "#ff0000")),
7417
- opacity: _nullishCoalesce(_optionalChain([d, 'optionalAccess', _190 => _190.opacity]), () => ( 0.5)),
7418
- indicates: _optionalChain([d, 'optionalAccess', _191 => _191.kind]) === 0 ? "selected" : "masked"
7419
- });
7420
- }
7421
- return out;
7422
- }
7423
-
7424
7526
  // src/image-editor/psd/paths.ts
7425
7527
  var RECORD = 26;
7426
7528
  var fixed = (v) => v / 16777216;
@@ -7480,6 +7582,8 @@ function writePathRecords(path) {
7480
7582
  return w.result();
7481
7583
  }
7482
7584
  var VMSK_INVERT = 1;
7585
+ var VMSK_NOT_LINKED = 2;
7586
+ var VMSK_DISABLED = 4;
7483
7587
  function readVectorBlock(data) {
7484
7588
  if (data.length < 8) return null;
7485
7589
  const r = new PsdReader(data);
@@ -7550,6 +7654,97 @@ function vectorBlockForComponents(components, inverted, width, height, flags = 0
7550
7654
  return writeVectorBlock({ subpaths, initialFill: subpaths.length === 0 && inverted }, flags & ~VMSK_INVERT | (inverted && subpaths.length ? VMSK_INVERT : 0));
7551
7655
  }
7552
7656
 
7657
+ // src/image-editor/psd/channels.ts
7658
+ var hexToRgb2 = (hex) => {
7659
+ const v = parseInt(_nullishCoalesce(_optionalChain([/^#?([0-9a-f]{6})$/i, 'access', _193 => _193.exec, 'call', _194 => _194(hex), 'optionalAccess', _195 => _195[1]]), () => ( "ff0000")), 16);
7660
+ return [v >> 16 & 255, v >> 8 & 255, v & 255];
7661
+ };
7662
+ var rgbToHex = (r, g, b) => `#${[r, g, b].map((c) => c.toString(16).padStart(2, "0")).join("")}`;
7663
+ function alphaChannelResources(channels) {
7664
+ if (!channels.length) return [];
7665
+ const names = new PsdWriter();
7666
+ for (const c of channels) names.pascal(encodeLegacyName(c.name), 1);
7667
+ const unicode = new PsdWriter();
7668
+ for (const c of channels) unicode.unicode(c.name);
7669
+ const display = new PsdWriter();
7670
+ display.u32(1);
7671
+ for (const c of channels) {
7672
+ const [r, g, b] = hexToRgb2(c.color);
7673
+ display.u16(0);
7674
+ for (const v of [r, g, b, 0]) display.u16(v * 257);
7675
+ display.u16(Math.round(Math.min(1, Math.max(0, c.opacity)) * 100));
7676
+ display.u8(c.indicates === "selected" ? 0 : 1);
7677
+ display.u8(0);
7678
+ }
7679
+ return [
7680
+ { id: 1006, name: "", data: names.result() },
7681
+ { id: 1045, name: "", data: unicode.result() },
7682
+ { id: 1077, name: "", data: display.result() }
7683
+ ];
7684
+ }
7685
+ function planeTo8(plane, n, depth) {
7686
+ if (depth === 8) return plane.slice(0, n);
7687
+ const out = new Uint8Array(n);
7688
+ const view = new DataView(plane.buffer, plane.byteOffset, plane.byteLength);
7689
+ for (let i = 0; i < n; i++) {
7690
+ if (depth === 16) out[i] = plane[2 * i];
7691
+ else out[i] = Math.round(Math.min(1, Math.max(0, view.getFloat32(4 * i, false))) * 255);
7692
+ }
7693
+ return out;
7694
+ }
7695
+ function readAlphaChannels(planes, header, first, resource2, warn) {
7696
+ const count = header.channels - first;
7697
+ if (count <= 0 || header.depth === 1) return [];
7698
+ const size = rowBytes(header.width, header.depth) * header.height;
7699
+ const n = header.width * header.height;
7700
+ const names = [];
7701
+ const unicode = resource2(1045);
7702
+ if (unicode) {
7703
+ const r = new PsdReader(unicode);
7704
+ while (r.remaining >= 4 && names.length < count) names.push(r.unicode().replace(/\0+$/, ""));
7705
+ } else {
7706
+ const legacy = resource2(1006);
7707
+ if (legacy) {
7708
+ const r = new PsdReader(legacy);
7709
+ while (r.remaining >= 1 && names.length < count) names.push(new TextDecoder("latin1").decode(r.pascal(1)));
7710
+ }
7711
+ }
7712
+ const display = [];
7713
+ const info = resource2(1077);
7714
+ if (info && info.length >= 4) {
7715
+ const r = new PsdReader(info);
7716
+ r.u32();
7717
+ while (r.remaining >= 14 && display.length < count) {
7718
+ r.u16();
7719
+ const [cr, cg, cb] = [r.u16(), r.u16(), r.u16()];
7720
+ r.u16();
7721
+ const opacity = r.u16();
7722
+ const kind = r.u8();
7723
+ r.u8();
7724
+ display.push({ color: rgbToHex(cr >> 8, cg >> 8, cb >> 8), opacity: Math.min(100, opacity) / 100, kind });
7725
+ }
7726
+ }
7727
+ const out = [];
7728
+ for (let i = 0; i < count; i++) {
7729
+ const start = (first + i) * size;
7730
+ if (start + size > planes.length) break;
7731
+ const d = display[i];
7732
+ const name = names[i] || `Alpha ${i + 1}`;
7733
+ if (_optionalChain([d, 'optionalAccess', _196 => _196.kind]) === 2) {
7734
+ warn(`Spot colour channel "${name}" is not supported and was left out.`);
7735
+ continue;
7736
+ }
7737
+ out.push({
7738
+ name,
7739
+ data: planeTo8(planes.subarray(start, start + size), n, header.depth),
7740
+ color: _nullishCoalesce(_optionalChain([d, 'optionalAccess', _197 => _197.color]), () => ( "#ff0000")),
7741
+ opacity: _nullishCoalesce(_optionalChain([d, 'optionalAccess', _198 => _198.opacity]), () => ( 0.5)),
7742
+ indicates: _optionalChain([d, 'optionalAccess', _199 => _199.kind]) === 0 ? "selected" : "masked"
7743
+ });
7744
+ }
7745
+ return out;
7746
+ }
7747
+
7553
7748
  // src/image-editor/psd/shapes.ts
7554
7749
  var SHAPE_PSD_KEYS = ["vsms", "vmsk", "vscg", "vstk", "vogk", "SoCo", "GdFl", "PtFl"];
7555
7750
  var unit = (u, value) => ({ type: "UntF", unit: u, value });
@@ -7560,7 +7755,7 @@ var enumV = (typeId, value) => ({ type: "enum", typeId, value });
7560
7755
  var obj = (d) => ({ type: "Objc", value: d });
7561
7756
  var enumOf = (d, key) => {
7562
7757
  const v = descGet(d, key);
7563
- return _optionalChain([v, 'optionalAccess', _192 => _192.type]) === "enum" ? v.value : void 0;
7758
+ return _optionalChain([v, 'optionalAccess', _200 => _200.type]) === "enum" ? v.value : void 0;
7564
7759
  };
7565
7760
  function read(data) {
7566
7761
  try {
@@ -7642,7 +7837,7 @@ function strokeFromVstk(data, dpi, notes) {
7642
7837
  const miter = descNumber(d, "strokeStyleMiterLimit");
7643
7838
  if (miter !== void 0 && miter !== 100) stroke.miterLimit = Math.max(1, Math.min(500, miter));
7644
7839
  const dashes = descGet(d, "strokeStyleLineDashSet");
7645
- if (_optionalChain([dashes, 'optionalAccess', _193 => _193.type]) === "VlLs") {
7840
+ if (_optionalChain([dashes, 'optionalAccess', _201 => _201.type]) === "VlLs") {
7646
7841
  const list2 = dashes.items.map((v) => v.type === "UntF" || v.type === "doub" || v.type === "long" ? v.value : NaN).filter((v) => Number.isFinite(v) && v >= 0);
7647
7842
  if (list2.length && list2.some((v) => v > 0)) stroke.dashes = list2;
7648
7843
  }
@@ -7794,7 +7989,7 @@ function vogkBytes(components, dpi) {
7794
7989
  ["keyOriginLineArrowEnd", boolV(Boolean(live.endArrow))],
7795
7990
  ["keyOriginLineArrWdth", dbl(head ? head.width / w * 100 : 0)],
7796
7991
  ["keyOriginLineArrLngth", dbl(head ? head.length / w * 100 : 0)],
7797
- ["keyOriginLineArrConc", long2(_optionalChain([head, 'optionalAccess', _194 => _194.concavity]) ? head.concavity * 100 : 0)]
7992
+ ["keyOriginLineArrConc", long2(_optionalChain([head, 'optionalAccess', _202 => _202.concavity]) ? head.concavity * 100 : 0)]
7798
7993
  ];
7799
7994
  }
7800
7995
  const m = live.transform;
@@ -7827,7 +8022,7 @@ function shapeSignature(layer) {
7827
8022
  return JSON.stringify([layer.components, layer.fill, layer.stroke, _nullishCoalesce(layer.fillRule, () => ( "nonzero")), Boolean(layer.inverted)]);
7828
8023
  }
7829
8024
  function shapeFromBlocks(blocks, width, height, dpi, notes) {
7830
- const block = (k) => _optionalChain([blocks, 'access', _195 => _195.find, 'call', _196 => _196((b) => b.key === k), 'optionalAccess', _197 => _197.data]);
8025
+ const block = (k) => _optionalChain([blocks, 'access', _203 => _203.find, 'call', _204 => _204((b) => b.key === k), 'optionalAccess', _205 => _205.data]);
7831
8026
  const vector = _nullishCoalesce(block("vsms"), () => ( block("vmsk")));
7832
8027
  const path = vector ? componentsFromVectorBlock(vector, width, height) : null;
7833
8028
  if (!path) return null;
@@ -7882,18 +8077,18 @@ function sameExtent(sub, c) {
7882
8077
  return a.every((v, i) => Math.abs(v - b[i]) < 1);
7883
8078
  }
7884
8079
  function shapeBlocks(layer, width, height, dpi, notes) {
7885
- const kept = _optionalChain([layer, 'access', _198 => _198.psd, 'optionalAccess', _199 => _199.blocks]);
7886
- if (_optionalChain([kept, 'optionalAccess', _200 => _200.length]) && _optionalChain([layer, 'access', _201 => _201.psd, 'optionalAccess', _202 => _202.signature]) === shapeSignature(layer)) return kept.map((b) => ({ key: b.key, data: b.data }));
8080
+ const kept = _optionalChain([layer, 'access', _206 => _206.psd, 'optionalAccess', _207 => _207.blocks]);
8081
+ if (_optionalChain([kept, 'optionalAccess', _208 => _208.length]) && _optionalChain([layer, 'access', _209 => _209.psd, 'optionalAccess', _210 => _210.signature]) === shapeSignature(layer)) return kept.map((b) => ({ key: b.key, data: b.data }));
7887
8082
  const out = [];
7888
8083
  out.push({ key: "vsms", data: vectorBlockForComponents(layer.components, Boolean(layer.inverted), width, height) });
7889
8084
  if (layer.fillRule === "evenodd" && layer.components.some((c) => c.subpaths.length > 1)) notes.add("Even-odd fill rules were written as nonzero (Photoshop fills shapes nonzero)");
7890
8085
  const fill = _nullishCoalesce(layer.fill, () => ( { type: "color", color: "#000000" }));
7891
- if (_optionalChain([layer, 'access', _203 => _203.fill, 'optionalAccess', _204 => _204.opacity]) !== void 0 && layer.fill.opacity < 1) notes.add("Shape fill opacity has no PSD equivalent and was written as 100 % (use the layer fill opacity)");
8086
+ if (_optionalChain([layer, 'access', _211 => _211.fill, 'optionalAccess', _212 => _212.opacity]) !== void 0 && layer.fill.opacity < 1) notes.add("Shape fill opacity has no PSD equivalent and was written as 100 % (use the layer fill opacity)");
7892
8087
  out.push({ key: "vscg", data: vscgBytes(fill) });
7893
8088
  if (layer.stroke || !layer.fill) out.push({ key: "vstk", data: vstkBytes(layer.stroke, Boolean(layer.fill), dpi) });
7894
8089
  const vogk = vogkBytes(layer.components, dpi);
7895
8090
  if (vogk) out.push({ key: "vogk", data: vogk });
7896
- if (layer.components.some((c) => _optionalChain([c, 'access', _205 => _205.live, 'optionalAccess', _206 => _206.kind]) === "line" && (c.live.startArrow && c.live.endArrow && JSON.stringify(c.live.startArrow) !== JSON.stringify(c.live.endArrow) || false))) {
8091
+ if (layer.components.some((c) => _optionalChain([c, 'access', _213 => _213.live, 'optionalAccess', _214 => _214.kind]) === "line" && (c.live.startArrow && c.live.endArrow && JSON.stringify(c.live.startArrow) !== JSON.stringify(c.live.endArrow) || false))) {
7897
8092
  notes.add("Lines with different start and end arrowheads were written with one arrowhead size (Photoshop has one)");
7898
8093
  }
7899
8094
  return out;
@@ -8102,7 +8297,7 @@ var E = {
8102
8297
  bool: (value) => ({ t: "bool", value })
8103
8298
  };
8104
8299
  function eGet(v, key) {
8105
- return _optionalChain([v, 'optionalAccess', _207 => _207.t]) === "dict" ? _optionalChain([v, 'access', _208 => _208.items, 'access', _209 => _209.find, 'call', _210 => _210(([k]) => k === key), 'optionalAccess', _211 => _211[1]]) : void 0;
8300
+ return _optionalChain([v, 'optionalAccess', _215 => _215.t]) === "dict" ? _optionalChain([v, 'access', _216 => _216.items, 'access', _217 => _217.find, 'call', _218 => _218(([k]) => k === key), 'optionalAccess', _219 => _219[1]]) : void 0;
8106
8301
  }
8107
8302
  function ePath(v, keys) {
8108
8303
  return keys.reduce((at, k) => eGet(at, k), v);
@@ -8120,7 +8315,7 @@ function eStr(v) {
8120
8315
  return v && (v.t === "string" || v.t === "name") ? v.value : void 0;
8121
8316
  }
8122
8317
  function eArray(v) {
8123
- return _optionalChain([v, 'optionalAccess', _212 => _212.t]) === "array" ? v.items : [];
8318
+ return _optionalChain([v, 'optionalAccess', _220 => _220.t]) === "array" ? v.items : [];
8124
8319
  }
8125
8320
  function eSet(d, key, value) {
8126
8321
  if (d.t !== "dict") return;
@@ -8222,7 +8417,7 @@ function fontFromPostScript(ps) {
8222
8417
  }
8223
8418
  family += suffix;
8224
8419
  const s = style.toLowerCase();
8225
- const weight = _nullishCoalesce(_optionalChain([WEIGHTS, 'access', _213 => _213.find, 'call', _214 => _214(([re]) => re.test(s)), 'optionalAccess', _215 => _215[1]]), () => ( 400));
8420
+ const weight = _nullishCoalesce(_optionalChain([WEIGHTS, 'access', _221 => _221.find, 'call', _222 => _222(([re]) => re.test(s)), 'optionalAccess', _223 => _223[1]]), () => ( 400));
8226
8421
  return { family: family || ps, weight, italic: /italic|oblique|it$/.test(s) };
8227
8422
  }
8228
8423
  var STYLE_NAMES = [
@@ -8247,7 +8442,7 @@ var hex2 = (v) => Math.round(Math.max(0, Math.min(1, v)) * 255).toString(16).pad
8247
8442
  function merged(levels) {
8248
8443
  const items = [];
8249
8444
  for (const l of levels) {
8250
- if (_optionalChain([l, 'optionalAccess', _216 => _216.t]) !== "dict") continue;
8445
+ if (_optionalChain([l, 'optionalAccess', _224 => _224.t]) !== "dict") continue;
8251
8446
  for (const [k, v] of l.items) if (!items.some(([o]) => o === k)) items.push([k, v]);
8252
8447
  }
8253
8448
  return E.dict(items);
@@ -8318,10 +8513,10 @@ function typeFromTySh(data, notes) {
8318
8513
  const t = parseTySh(data);
8319
8514
  if (!t) return null;
8320
8515
  const txtV = descGet(t.text, "Txt ");
8321
- const txt = _optionalChain([txtV, 'optionalAccess', _217 => _217.type]) === "TEXT" ? txtV.value.replace(/\0+$/, "") : void 0;
8516
+ const txt = _optionalChain([txtV, 'optionalAccess', _225 => _225.type]) === "TEXT" ? txtV.value.replace(/\0+$/, "") : void 0;
8322
8517
  const ed = descGet(t.text, "EngineData");
8323
8518
  let engine = null;
8324
- if (_optionalChain([ed, 'optionalAccess', _218 => _218.type]) === "tdta") {
8519
+ if (_optionalChain([ed, 'optionalAccess', _226 => _226.type]) === "tdta") {
8325
8520
  try {
8326
8521
  engine = parseEngineData(ed.data);
8327
8522
  } catch (e18) {
@@ -8329,12 +8524,12 @@ function typeFromTySh(data, notes) {
8329
8524
  }
8330
8525
  }
8331
8526
  const anti = descGet(t.text, "AntA");
8332
- const antiAlias = !(_optionalChain([anti, 'optionalAccess', _219 => _219.type]) === "enum" && (anti.value === "Anno" || anti.value === "antiAliasNone"));
8527
+ const antiAlias = !(_optionalChain([anti, 'optionalAccess', _227 => _227.type]) === "enum" && (anti.value === "Anno" || anti.value === "antiAliasNone"));
8333
8528
  const ornt = descGet(t.text, "Ornt");
8334
- if (_optionalChain([ornt, 'optionalAccess', _220 => _220.type]) === "enum" && ornt.value === "Vrtc") notes.add("vertical type is laid out horizontally");
8529
+ if (_optionalChain([ornt, 'optionalAccess', _228 => _228.type]) === "enum" && ornt.value === "Vrtc") notes.add("vertical type is laid out horizontally");
8335
8530
  if (t.warp) {
8336
8531
  const style = descGet(t.warp, "warpStyle");
8337
- if (_optionalChain([style, 'optionalAccess', _221 => _221.type]) === "enum" && style.value !== "warpNone") notes.add("warped text is drawn without its warp when edited");
8532
+ if (_optionalChain([style, 'optionalAccess', _229 => _229.type]) === "enum" && style.value !== "warpNone") notes.add("warped text is drawn without its warp when edited");
8338
8533
  }
8339
8534
  const edText = _nullishCoalesce(eStr(ePath(_nullishCoalesce(engine, () => ( void 0)), ["EngineDict", "Editor", "Text"])), () => ( ""));
8340
8535
  const text3 = (_nullishCoalesce(txt, () => ( edText.replace(/\r$/, "")))).replace(/\r\n?/g, "\n");
@@ -8383,7 +8578,7 @@ function typeFromTySh(data, notes) {
8383
8578
  let at = 0;
8384
8579
  runs = ssheets.map((sheet, i) => {
8385
8580
  const own = named(styleSet, sheet);
8386
- const paraDefault = _optionalChain([paraBases, 'access', _222 => _222[paraAt(at)], 'optionalAccess', _223 => _223.charDefault]);
8581
+ const paraDefault = _optionalChain([paraBases, 'access', _230 => _230[paraAt(at)], 'optionalAccess', _231 => _231.charDefault]);
8387
8582
  at += _nullishCoalesce(slens[i], () => ( 0));
8388
8583
  const d = merged([eGet(sheet, "StyleSheetData"), eGet(own, "StyleSheetData"), eGet(paraDefault, "StyleSheetData"), eGet(normalStyle, "StyleSheetData")]);
8389
8584
  return { length: _nullishCoalesce(slens[i], () => ( 0)), style: charStyle(d, fonts, notes) };
@@ -8462,8 +8657,8 @@ var fontEntry = (name) => E.dict([
8462
8657
  ["Synthetic", E.int(0)]
8463
8658
  ]);
8464
8659
  function buildEngineData(layer, template) {
8465
- const e = _optionalChain([template, 'optionalAccess', _224 => _224.t]) === "dict" ? eClone(template) : E.dict([["EngineDict", E.dict()], ["ResourceDict", E.dict()]]);
8466
- if (_optionalChain([eGet, 'call', _225 => _225(e, "EngineDict"), 'optionalAccess', _226 => _226.t]) !== "dict") eSet(e, "EngineDict", E.dict());
8660
+ const e = _optionalChain([template, 'optionalAccess', _232 => _232.t]) === "dict" ? eClone(template) : E.dict([["EngineDict", E.dict()], ["ResourceDict", E.dict()]]);
8661
+ if (_optionalChain([eGet, 'call', _233 => _233(e, "EngineDict"), 'optionalAccess', _234 => _234.t]) !== "dict") eSet(e, "EngineDict", E.dict());
8467
8662
  const dict = eGet(e, "EngineDict");
8468
8663
  const text3 = layer.text.replace(/\n/g, "\r");
8469
8664
  const edText = `${text3}\r`;
@@ -8542,7 +8737,7 @@ function buildEngineData(layer, template) {
8542
8737
  eSet(e, key, rd);
8543
8738
  }
8544
8739
  eSet(rd, "FontSet", fontSet);
8545
- if (!eGet(rd, "StyleSheetSet")) eSet(rd, "StyleSheetSet", E.array([E.dict([["Name", E.str("Normal RGB")], ["StyleSheetData", styleSheetData(_nullishCoalesce(_optionalChain([runs, 'access', _227 => _227[0], 'optionalAccess', _228 => _228.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)), 0)]])]));
8740
+ if (!eGet(rd, "StyleSheetSet")) eSet(rd, "StyleSheetSet", E.array([E.dict([["Name", E.str("Normal RGB")], ["StyleSheetData", styleSheetData(_nullishCoalesce(_optionalChain([runs, 'access', _235 => _235[0], 'optionalAccess', _236 => _236.style]), () => ( _chunkEGZM52EOcjs.DEFAULT_TEXT_STYLE)), 0)]])]));
8546
8741
  if (!eGet(rd, "ParagraphSheetSet")) eSet(rd, "ParagraphSheetSet", E.array([E.dict([["Name", E.str("Normal RGB")], ["DefaultStyleSheet", E.int(0)], ["Properties", paragraphProperties({})]])]));
8547
8742
  if (!eGet(rd, "TheNormalStyleSheet")) eSet(rd, "TheNormalStyleSheet", E.int(0));
8548
8743
  if (!eGet(rd, "TheNormalParagraphSheet")) eSet(rd, "TheNormalParagraphSheet", E.int(0));
@@ -8563,12 +8758,12 @@ function inkBounds2(layer) {
8563
8758
  return [Math.min(...pts.map((p) => p.x)), Math.min(...pts.map((p) => p.y)), Math.max(...pts.map((p) => p.x)), Math.max(...pts.map((p) => p.y))];
8564
8759
  }
8565
8760
  function tyShForLayer(layer) {
8566
- const raw = _optionalChain([layer, 'access', _229 => _229.psd, 'optionalAccess', _230 => _230.tySh]);
8567
- if (raw && _optionalChain([layer, 'access', _231 => _231.psd, 'optionalAccess', _232 => _232.signature]) === typeSignature(layer)) return raw;
8761
+ const raw = _optionalChain([layer, 'access', _237 => _237.psd, 'optionalAccess', _238 => _238.tySh]);
8762
+ if (raw && _optionalChain([layer, 'access', _239 => _239.psd, 'optionalAccess', _240 => _240.signature]) === typeSignature(layer)) return raw;
8568
8763
  const old = raw ? parseTySh(raw) : null;
8569
8764
  const oldEd = old ? descGet(old.text, "EngineData") : void 0;
8570
8765
  let template = null;
8571
- if (_optionalChain([oldEd, 'optionalAccess', _233 => _233.type]) === "tdta") {
8766
+ if (_optionalChain([oldEd, 'optionalAccess', _241 => _241.type]) === "tdta") {
8572
8767
  try {
8573
8768
  template = parseEngineData(oldEd.data);
8574
8769
  } catch (e19) {
@@ -8600,8 +8795,8 @@ function tyShForLayer(layer) {
8600
8795
  set("boundingBox", rect("boundingBox"));
8601
8796
  if (!descGet(text3, "TextIndex")) set("TextIndex", { type: "long", value: 0 });
8602
8797
  set("EngineData", { type: "tdta", data: writeEngineData(engine) });
8603
- const warpStyle = _optionalChain([old, 'optionalAccess', _234 => _234.warp]) ? descGet(old.warp, "warpStyle") : void 0;
8604
- const warp = _optionalChain([old, 'optionalAccess', _235 => _235.warp]) && _optionalChain([warpStyle, 'optionalAccess', _236 => _236.type]) === "enum" && warpStyle.value === "warpNone" ? old.warp : null;
8798
+ const warpStyle = _optionalChain([old, 'optionalAccess', _242 => _242.warp]) ? descGet(old.warp, "warpStyle") : void 0;
8799
+ const warp = _optionalChain([old, 'optionalAccess', _243 => _243.warp]) && _optionalChain([warpStyle, 'optionalAccess', _244 => _244.type]) === "enum" && warpStyle.value === "warpNone" ? old.warp : null;
8605
8800
  return writeTySh({ transform: textMatrix(layer), text: text3, warp, tail: new Uint8Array(16) });
8606
8801
  }
8607
8802
 
@@ -8615,15 +8810,15 @@ var textV = (value) => ({ type: "TEXT", value });
8615
8810
  var obj2 = (d) => ({ type: "Objc", value: d });
8616
8811
  var text = (d, key) => {
8617
8812
  const v = descGet(d, key);
8618
- return _optionalChain([v, 'optionalAccess', _237 => _237.type]) === "TEXT" ? v.value : void 0;
8813
+ return _optionalChain([v, 'optionalAccess', _245 => _245.type]) === "TEXT" ? v.value : void 0;
8619
8814
  };
8620
8815
  var enumOf2 = (d, key) => {
8621
8816
  const v = descGet(d, key);
8622
- return _optionalChain([v, 'optionalAccess', _238 => _238.type]) === "enum" ? v.value : void 0;
8817
+ return _optionalChain([v, 'optionalAccess', _246 => _246.type]) === "enum" ? v.value : void 0;
8623
8818
  };
8624
8819
  var numbers = (d, key) => {
8625
8820
  const v = descGet(d, key);
8626
- if (_optionalChain([v, 'optionalAccess', _239 => _239.type]) !== "VlLs") return null;
8821
+ if (_optionalChain([v, 'optionalAccess', _247 => _247.type]) !== "VlLs") return null;
8627
8822
  const out = [];
8628
8823
  for (const it of v.items) {
8629
8824
  if (it.type === "doub" || it.type === "UntF" || it.type === "long") out.push(it.value);
@@ -8818,8 +9013,8 @@ function filterMaskItem(placed, mask, area) {
8818
9013
  const painted = _chunkCWM3CUUXcjs.contentBounds.call(void 0, mask.surface);
8819
9014
  let b = _nullishCoalesce(painted, () => ( { x: 0, y: 0, width: 1, height: 1 }));
8820
9015
  if (mask.defaultValue !== 255 && area) {
8821
- const x0 = Math.min(area.x, _nullishCoalesce(_optionalChain([painted, 'optionalAccess', _240 => _240.x]), () => ( area.x)));
8822
- const y0 = Math.min(area.y, _nullishCoalesce(_optionalChain([painted, 'optionalAccess', _241 => _241.y]), () => ( area.y)));
9016
+ const x0 = Math.min(area.x, _nullishCoalesce(_optionalChain([painted, 'optionalAccess', _248 => _248.x]), () => ( area.x)));
9017
+ const y0 = Math.min(area.y, _nullishCoalesce(_optionalChain([painted, 'optionalAccess', _249 => _249.y]), () => ( area.y)));
8823
9018
  const x1 = Math.max(area.x + area.width, painted ? painted.x + painted.width : 0);
8824
9019
  const y1 = Math.max(area.y + area.height, painted ? painted.y + painted.height : 0);
8825
9020
  b = { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };
@@ -8839,7 +9034,7 @@ function filterMaskItem(placed, mask, area) {
8839
9034
  }
8840
9035
  var warpStyleOf = (name) => {
8841
9036
  if (!name.startsWith("warp")) return null;
8842
- const s = _optionalChain([name, 'access', _242 => _242[4], 'optionalAccess', _243 => _243.toLowerCase, 'call', _244 => _244()]) + name.slice(5);
9037
+ const s = _optionalChain([name, 'access', _250 => _250[4], 'optionalAccess', _251 => _251.toLowerCase, 'call', _252 => _252()]) + name.slice(5);
8843
9038
  return _chunkEGZM52EOcjs.WARP_STYLES.includes(s) ? s : null;
8844
9039
  };
8845
9040
  function warpFromDescriptor(w, contents) {
@@ -8861,7 +9056,7 @@ function warpFromDescriptor(w, contents) {
8861
9056
  if (!arr || arr.type !== "ObAr") return void 0;
8862
9057
  const xs = descGet(arr.body, "Hrzn");
8863
9058
  const ys = descGet(arr.body, "Vrtc");
8864
- if (_optionalChain([xs, 'optionalAccess', _245 => _245.type]) !== "UnFl" || _optionalChain([ys, 'optionalAccess', _246 => _246.type]) !== "UnFl" || xs.values.length !== 16 || ys.values.length !== 16) return void 0;
9059
+ if (_optionalChain([xs, 'optionalAccess', _253 => _253.type]) !== "UnFl" || _optionalChain([ys, 'optionalAccess', _254 => _254.type]) !== "UnFl" || xs.values.length !== 16 || ys.values.length !== 16) return void 0;
8865
9060
  mesh = { us: [0, 1], vs: [0, 1], points: xs.values.map((x, i) => ({ x, y: ys.values[i] })) };
8866
9061
  const px2 = mesh.points.map((p) => p.x);
8867
9062
  const py = mesh.points.map((p) => p.y);
@@ -9028,13 +9223,13 @@ function blendOptions(f) {
9028
9223
  function smartFiltersFromPsd(fx, newId, notes) {
9029
9224
  const filters = [];
9030
9225
  const list2 = descGet(fx, "filterFXList");
9031
- for (const v of _optionalChain([list2, 'optionalAccess', _247 => _247.type]) === "VlLs" ? list2.items : []) {
9226
+ for (const v of _optionalChain([list2, 'optionalAccess', _255 => _255.type]) === "VlLs" ? list2.items : []) {
9032
9227
  if (v.type !== "Objc" && v.type !== "GlbO") continue;
9033
9228
  const item = v.value;
9034
9229
  const { blend, opacity } = blendOptionsOf(item);
9035
9230
  const enabled = descBool(item, "enab") !== false;
9036
9231
  const fltr = descObject(item, "Fltr");
9037
- const radius = _optionalChain([fltr, 'optionalAccess', _248 => _248.classId]) === BOX_BLUR.classId ? descNumber(fltr, "Rds ") : void 0;
9232
+ const radius = _optionalChain([fltr, 'optionalAccess', _256 => _256.classId]) === BOX_BLUR.classId ? descNumber(fltr, "Rds ") : void 0;
9038
9233
  if (radius !== void 0 && radius >= 0 && radius <= 50) {
9039
9234
  filters.push({ id: newId(), kind: "blur", enabled, radius, blend, opacity });
9040
9235
  continue;
@@ -9387,7 +9582,7 @@ function readPsd(bytes) {
9387
9582
  return { header, colorModeData, resources, layers, mergedAlpha, globalBlocks, imageCompression, imageData: r.rest() };
9388
9583
  }
9389
9584
  function layerBlock(rec, key) {
9390
- return _optionalChain([rec, 'access', _249 => _249.blocks, 'access', _250 => _250.find, 'call', _251 => _251((b) => b.key === key), 'optionalAccess', _252 => _252.data]);
9585
+ return _optionalChain([rec, 'access', _257 => _257.blocks, 'access', _258 => _258.find, 'call', _259 => _259((b) => b.key === key), 'optionalAccess', _260 => _260.data]);
9391
9586
  }
9392
9587
  function layerName(rec) {
9393
9588
  const luni = layerBlock(rec, "luni");
@@ -9418,7 +9613,7 @@ function u8Block(rec, key) {
9418
9613
  function layerTree(file) {
9419
9614
  const stack = [[]];
9420
9615
  file.layers.forEach((rec, index) => {
9421
- const kind = _nullishCoalesce(_optionalChain([sectionDivider, 'call', _253 => _253(rec), 'optionalAccess', _254 => _254.kind]), () => ( SECTION_OTHER));
9616
+ const kind = _nullishCoalesce(_optionalChain([sectionDivider, 'call', _261 => _261(rec), 'optionalAccess', _262 => _262.kind]), () => ( SECTION_OTHER));
9422
9617
  if (kind === SECTION_DIVIDER) {
9423
9618
  stack.push([]);
9424
9619
  } else if (kind === SECTION_OPEN || kind === SECTION_CLOSED) {
@@ -9436,7 +9631,7 @@ function layerTree(file) {
9436
9631
  }
9437
9632
  function channelRect(rec, id) {
9438
9633
  if (id === CHANNEL_USER_MASK && rec.mask) return rec.mask.rect;
9439
- if (id === CHANNEL_REAL_USER_MASK && rec.mask) return _nullishCoalesce(_optionalChain([rec, 'access', _255 => _255.mask, 'access', _256 => _256.real, 'optionalAccess', _257 => _257.rect]), () => ( rec.mask.rect));
9634
+ if (id === CHANNEL_REAL_USER_MASK && rec.mask) return _nullishCoalesce(_optionalChain([rec, 'access', _263 => _263.mask, 'access', _264 => _264.real, 'optionalAccess', _265 => _265.rect]), () => ( rec.mask.rect));
9440
9635
  return rec.rect;
9441
9636
  }
9442
9637
  function decodeLayerChannel(file, rec, id) {
@@ -9454,7 +9649,7 @@ function decodeMergedImage(file) {
9454
9649
  return decodePlanes(file.imageCompression, file.imageData, { planes: channels, width, height, depth, psb });
9455
9650
  }
9456
9651
  function resource(file, id) {
9457
- return _optionalChain([file, 'access', _258 => _258.resources, 'access', _259 => _259.find, 'call', _260 => _260((r) => r.id === id), 'optionalAccess', _261 => _261.data]);
9652
+ return _optionalChain([file, 'access', _266 => _266.resources, 'access', _267 => _267.find, 'call', _268 => _268((r) => r.id === id), 'optionalAccess', _269 => _269.data]);
9458
9653
  }
9459
9654
  function resolution(file) {
9460
9655
  const d = resource(file, 1005);
@@ -10181,9 +10376,22 @@ function baseProps(ctx, rec, name, notes) {
10181
10376
  ctx.warn.add("Artboards are not supported; they came in as plain groups, without their background colour and clipping", name);
10182
10377
  notes.push("artboard imported as a group");
10183
10378
  }
10184
- if (rec.blocks.some((b) => VECTOR_KEYS.includes(b.key)) && psdKind(rec) === "pixel") {
10185
- ctx.warn.add("Vector masks are not supported and were ignored", name);
10186
- notes.push("vector mask ignored");
10379
+ const vectorBlock = psdKind(rec) === "shape" ? void 0 : _nullishCoalesce(rec.blocks.find((b) => b.key === "vsms"), () => ( rec.blocks.find((b) => b.key === "vmsk")));
10380
+ if (vectorBlock) {
10381
+ const read2 = componentsFromVectorBlock(vectorBlock.data, ctx.file.header.width, ctx.file.header.height);
10382
+ if (read2) {
10383
+ const vm = { components: read2.components };
10384
+ if (read2.inverted) vm.inverted = true;
10385
+ if (read2.flags & VMSK_NOT_LINKED) vm.linked = false;
10386
+ if (read2.flags & VMSK_DISABLED) vm.enabled = false;
10387
+ const m = rec.mask;
10388
+ if (_optionalChain([m, 'optionalAccess', _270 => _270.vectorDensity]) !== void 0 && m.vectorDensity < 255) vm.density = percent(m.vectorDensity);
10389
+ if (_optionalChain([m, 'optionalAccess', _271 => _271.vectorFeather]) !== void 0 && m.vectorFeather > 0) vm.feather = Math.min(1e3, m.vectorFeather);
10390
+ props.vectorMask = vm;
10391
+ } else {
10392
+ ctx.warn.add("A vector mask could not be read and was ignored", name);
10393
+ notes.push("vector mask ignored");
10394
+ }
10187
10395
  }
10188
10396
  return props;
10189
10397
  }
@@ -10238,7 +10446,7 @@ function importNode(ctx, node, depth) {
10238
10446
  if (node.children) {
10239
10447
  const props2 = baseProps(ctx, rec, name, notes);
10240
10448
  const divider = sectionDivider(rec);
10241
- const key = _nullishCoalesce(_optionalChain([divider, 'optionalAccess', _262 => _262.blendKey]), () => ( rec.blendKey));
10449
+ const key = _nullishCoalesce(_optionalChain([divider, 'optionalAccess', _272 => _272.blendKey]), () => ( rec.blendKey));
10242
10450
  const groupBlend = key === "pass" ? "pass-through" : _nullishCoalesce(PSD_BLEND_KEYS[key], () => ( "normal"));
10243
10451
  const children = [];
10244
10452
  for (const child of node.children) {
@@ -10248,7 +10456,7 @@ function importNode(ctx, node, depth) {
10248
10456
  const group = { type: "group", id: ctx.newId(name), ...props2, blend: groupBlend, children };
10249
10457
  const effects2 = recordEffects(ctx, rec, name, notes, true);
10250
10458
  if (effects2) group.effects = effects2;
10251
- if (_optionalChain([divider, 'optionalAccess', _263 => _263.kind]) === SECTION_CLOSED) group.collapsed = true;
10459
+ if (_optionalChain([divider, 'optionalAccess', _273 => _273.kind]) === SECTION_CLOSED) group.collapsed = true;
10252
10460
  const mask2 = recordMask(ctx, rec, name);
10253
10461
  if (mask2) group.mask = mask2;
10254
10462
  entry.type = "group";
@@ -10471,7 +10679,7 @@ function importSmart(ctx, rec, name, notes, props) {
10471
10679
  const file = ctx.linked.get(placed.idnt);
10472
10680
  contents = {
10473
10681
  id: placed.idnt || ctx.newId(`${name}-contents`),
10474
- name: _optionalChain([file, 'optionalAccess', _264 => _264.name]) || `${name}.png`,
10682
+ name: _optionalChain([file, 'optionalAccess', _274 => _274.name]) || `${name}.png`,
10475
10683
  width,
10476
10684
  height,
10477
10685
  kind: "raster",
@@ -10628,7 +10836,7 @@ function psdToLayers(file, options = {}) {
10628
10836
  if (mode !== "rgb" && header.depth > 8 && header.colorMode !== MODE_INDEXED && header.colorMode !== MODE_BITMAP) {
10629
10837
  warn.extra.push(`The file is ${header.depth}-bit ${mode}; it was converted to ${header.depth}-bit RGB.`);
10630
10838
  } else if (mode !== "rgb" || header.depth !== 8 && header.depth !== 16 && header.depth !== 32) {
10631
- const how = header.colorMode === MODE_CMYK ? ` through ${_nullishCoalesce(_optionalChain([cmykProfile, 'optionalAccess', _265 => _265.name]), () => ( "its profile"))}` : "";
10839
+ const how = header.colorMode === MODE_CMYK ? ` through ${_nullishCoalesce(_optionalChain([cmykProfile, 'optionalAccess', _275 => _275.name]), () => ( "its profile"))}` : "";
10632
10840
  warn.extra.push(`The file is ${header.depth}-bit ${mode}; it was converted to 8-bit RGB${how}.`);
10633
10841
  }
10634
10842
  let layers = [];
@@ -10745,15 +10953,15 @@ var pct = (d, key, fallback) => num3(d, key, fallback * 100) / 100;
10745
10953
  var bool = (d, key) => descBool(d, key) === true;
10746
10954
  var enumOf3 = (d, key) => {
10747
10955
  const v = descGet(d, key);
10748
- return _optionalChain([v, 'optionalAccess', _266 => _266.type]) === "enum" ? v.value : void 0;
10956
+ return _optionalChain([v, 'optionalAccess', _276 => _276.type]) === "enum" ? v.value : void 0;
10749
10957
  };
10750
10958
  var text2 = (d, key) => {
10751
10959
  const v = d ? descGet(d, key) : void 0;
10752
- return _optionalChain([v, 'optionalAccess', _267 => _267.type]) === "TEXT" ? v.value : "";
10960
+ return _optionalChain([v, 'optionalAccess', _277 => _277.type]) === "TEXT" ? v.value : "";
10753
10961
  };
10754
10962
  var list = (d, key) => {
10755
10963
  const v = descGet(d, key);
10756
- if (_optionalChain([v, 'optionalAccess', _268 => _268.type]) !== "VlLs") return [];
10964
+ if (_optionalChain([v, 'optionalAccess', _278 => _278.type]) !== "VlLs") return [];
10757
10965
  return v.items.flatMap((it) => it.type === "Objc" || it.type === "GlbO" ? [it.value] : []);
10758
10966
  };
10759
10967
  var clamp3 = (v, lo, hi) => Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : lo;
@@ -10823,8 +11031,8 @@ function contourOf(d, key) {
10823
11031
  return { name, points };
10824
11032
  }
10825
11033
  function contourDesc(c) {
10826
- const name = _nullishCoalesce(_optionalChain([c, 'optionalAccess', _269 => _269.name]), () => ( "Linear"));
10827
- const points = _nullishCoalesce(_optionalChain([c, 'optionalAccess', _270 => _270.points]), () => ( [
11034
+ const name = _nullishCoalesce(_optionalChain([c, 'optionalAccess', _279 => _279.name]), () => ( "Linear"));
11035
+ const points = _nullishCoalesce(_optionalChain([c, 'optionalAccess', _280 => _280.points]), () => ( [
10828
11036
  { input: 0, output: 0 },
10829
11037
  { input: 1, output: 1 }
10830
11038
  ]));
@@ -10859,7 +11067,7 @@ function gradientOf(d, notes) {
10859
11067
  { position: 0, color: "#000000" },
10860
11068
  { position: 1, color: "#ffffff" }
10861
11069
  ],
10862
- style: _nullishCoalesce(_optionalChain([GRADIENT_STYLES, 'access', _271 => _271.find, 'call', _272 => _272(([, id]) => id === enumOf3(d, "Type")), 'optionalAccess', _273 => _273[0]]), () => ( "linear")),
11070
+ style: _nullishCoalesce(_optionalChain([GRADIENT_STYLES, 'access', _281 => _281.find, 'call', _282 => _282(([, id]) => id === enumOf3(d, "Type")), 'optionalAccess', _283 => _283[0]]), () => ( "linear")),
10863
11071
  angle: clamp3(num3(d, "Angl", 90), -360, 360),
10864
11072
  scale: clamp3(pct(d, "Scl ", 1), 0.1, 1.5),
10865
11073
  reverse: bool(d, "Rvrs"),
@@ -10913,7 +11121,7 @@ function gradientItems(g) {
10913
11121
  )
10914
11122
  )
10915
11123
  };
10916
- const op = _optionalChain([g, 'access', _274 => _274.opacityStops, 'optionalAccess', _275 => _275.length]) ? g.opacityStops : g.stops.map((s) => ({ position: s.position, opacity: 1 }));
11124
+ const op = _optionalChain([g, 'access', _284 => _284.opacityStops, 'optionalAccess', _285 => _285.length]) ? g.opacityStops : g.stops.map((s) => ({ position: s.position, opacity: 1 }));
10917
11125
  const trns = {
10918
11126
  type: "VlLs",
10919
11127
  items: op.map(
@@ -11410,9 +11618,9 @@ function prepareNestedLayers(layers) {
11410
11618
  if (l.type === "annotation") continue;
11411
11619
  let next = l;
11412
11620
  if (l.type === "group") next = { ...l, children: prepareNestedLayers(l.children) };
11413
- else if (l.type === "pixel" && (_optionalChain([l, 'access', _276 => _276.filters, 'optionalAccess', _277 => _277.length]) || l.source === "document")) {
11621
+ else if (l.type === "pixel" && (_optionalChain([l, 'access', _286 => _286.filters, 'optionalAccess', _287 => _287.length]) || l.source === "document")) {
11414
11622
  const p = { ...l };
11415
- if (_optionalChain([l, 'access', _278 => _278.filters, 'optionalAccess', _279 => _279.some, 'call', _280 => _280(isActiveFilter)])) {
11623
+ if (_optionalChain([l, 'access', _288 => _288.filters, 'optionalAccess', _289 => _289.some, 'call', _290 => _290(isActiveFilter)])) {
11416
11624
  const b = l.surface.bounds;
11417
11625
  if (b) {
11418
11626
  const r = { x: b.x + l.offset.x - 64, y: b.y + l.offset.y - 64, width: b.width + 128, height: b.height + 128 };
@@ -11429,7 +11637,7 @@ function prepareNestedLayers(layers) {
11429
11637
  delete p.source;
11430
11638
  next = p;
11431
11639
  }
11432
- if (_optionalChain([next, 'access', _281 => _281.mask, 'optionalAccess', _282 => _282.source])) {
11640
+ if (_optionalChain([next, 'access', _291 => _291.mask, 'optionalAccess', _292 => _292.source])) {
11433
11641
  next = { ...next };
11434
11642
  delete next.mask;
11435
11643
  }
@@ -11532,10 +11740,17 @@ function exportPsd(input) {
11532
11740
  if (fx) blocks.push(fx);
11533
11741
  const locks = lockBits(layer);
11534
11742
  if (locks) blocks.push({ key: "lspf", data: u32Bytes(locks >>> 0) });
11743
+ const vm = layer.type !== "shape" ? layer.vectorMask : void 0;
11744
+ if (vm) {
11745
+ const flags = (vm.linked === false ? VMSK_NOT_LINKED : 0) | (vm.enabled === false ? VMSK_DISABLED : 0);
11746
+ blocks.push({ key: "vmsk", data: vectorBlockForComponents(vm.components, vm.inverted === true, width, height, flags) });
11747
+ if ((_nullishCoalesce(vm.density, () => ( 1))) !== 1 || (_nullishCoalesce(vm.feather, () => ( 0))) > 0) note("Vector mask density and feather are not written; the paths are", layer.name);
11748
+ if (vm.fillRule === "evenodd") note("Vector masks are written with the nonzero fill rule (Photoshop has no even-odd paths)", layer.name);
11749
+ }
11535
11750
  return {
11536
11751
  opacity: Math.round(Math.min(1, Math.max(0, layer.opacity)) * 255),
11537
11752
  clipping: layer.clipped ? 1 : 0,
11538
- flags: (layer.visible ? 0 : LAYER_FLAG_HIDDEN) | (_optionalChain([layer, 'access', _283 => _283.locks, 'optionalAccess', _284 => _284.transparency]) ? LAYER_FLAG_TRANSPARENCY_PROTECTED : 0),
11753
+ flags: (layer.visible ? 0 : LAYER_FLAG_HIDDEN) | (_optionalChain([layer, 'access', _293 => _293.locks, 'optionalAccess', _294 => _294.transparency]) ? LAYER_FLAG_TRANSPARENCY_PROTECTED : 0),
11539
11754
  legacyName: name,
11540
11755
  blocks
11541
11756
  };
@@ -11592,7 +11807,7 @@ function exportPsd(input) {
11592
11807
  }
11593
11808
  case "pixel": {
11594
11809
  if (layer.source === "document") throw new PsdError(`Layer "${layer.name}" reads the document image; resolve its pixels before export.`);
11595
- if (_optionalChain([layer, 'access', _285 => _285.filters, 'optionalAccess', _286 => _286.some, 'call', _287 => _287(isActiveFilter)])) throw new PsdError(`Layer "${layer.name}" has live filters; bake them before export.`);
11810
+ if (_optionalChain([layer, 'access', _295 => _295.filters, 'optionalAccess', _296 => _296.some, 'call', _297 => _297(isActiveFilter)])) throw new PsdError(`Layer "${layer.name}" has live filters; bake them before export.`);
11596
11811
  const extra = [];
11597
11812
  if (layer.fillOpacity !== void 0 && layer.fillOpacity < 1) {
11598
11813
  extra.push({ key: "iOpa", data: Uint8Array.from([Math.round(Math.max(0, layer.fillOpacity) * 255), 0, 0, 0]) });
@@ -11624,7 +11839,7 @@ function exportPsd(input) {
11624
11839
  if (c.linked) note("Linked smart objects were embedded (their preview is written as the contents)", layer.name);
11625
11840
  linkedFiles.set(idnt, smartContentsFile(c));
11626
11841
  }
11627
- let placedId = _nullishCoalesce(_optionalChain([layer, 'access', _288 => _288.psd, 'optionalAccess', _289 => _289.placed]), () => ( psdUuid(`${layer.id}:placed`)));
11842
+ let placedId = _nullishCoalesce(_optionalChain([layer, 'access', _298 => _298.psd, 'optionalAccess', _299 => _299.placed]), () => ( psdUuid(`${layer.id}:placed`)));
11628
11843
  if (placedIds.has(placedId)) placedId = psdUuid(`${layer.id}:placed:${placedIds.size}`);
11629
11844
  placedIds.add(placedId);
11630
11845
  if (placedUnchanged(layer, idnt, placedId)) {
@@ -11634,12 +11849,12 @@ function exportPsd(input) {
11634
11849
  const filterFX = layer.smartFilters ? filterFXDescriptor(layer.smartFilters, dropped) : void 0;
11635
11850
  if (dropped.length) note("Develop smart filters have no Photoshop filter and were left out of the filter list (the layer\u2019s pixels still show them)", layer.name);
11636
11851
  const raw = layer.psd && layer.psd.key !== "PlLd" ? parsePlaced(layer.psd.key, layer.psd.data) : null;
11637
- const spec = { idnt, placed: placedId, placement: layer.placement, size: { width: c.width, height: c.height }, filterFX, template: _optionalChain([raw, 'optionalAccess', _290 => _290.descriptor]) };
11852
+ const spec = { idnt, placed: placedId, placement: layer.placement, size: { width: c.width, height: c.height }, filterFX, template: _optionalChain([raw, 'optionalAccess', _300 => _300.descriptor]) };
11638
11853
  const wnotes = [];
11639
11854
  extra.push({ key: "PlLd", data: plldBytes(spec) }, { key: "SoLd", data: soldBytes(spec, wnotes) });
11640
11855
  for (const n2 of wnotes) note(`A smart object: ${n2}`, layer.name);
11641
11856
  }
11642
- const fm = _optionalChain([layer, 'access', _291 => _291.smartFilters, 'optionalAccess', _292 => _292.mask]);
11857
+ const fm = _optionalChain([layer, 'access', _301 => _301.smartFilters, 'optionalAccess', _302 => _302.mask]);
11643
11858
  if (fm && !fm.source) filterItems.push(filterMaskItem(placedId, fm, { x: 0, y: 0, width, height }));
11644
11859
  const rec = { ...common2(layer, extra), rect: EMPTY_RECT, channels: [], blendKey: _nullishCoalesce(BLEND_TO_PSD[layer.blend], () => ( "norm")) };
11645
11860
  const bounds = _chunkCWM3CUUXcjs.contentBounds.call(void 0, layer.surface);
@@ -11667,8 +11882,8 @@ function exportPsd(input) {
11667
11882
  const losses = /* @__PURE__ */ new Set();
11668
11883
  for (const b of shapeBlocks(layer, width, height, _nullishCoalesce(input.resolution, () => ( 72)), losses)) extra.push({ key: b.key, data: padEven(b.data) });
11669
11884
  for (const n2 of losses) note(n2, layer.name);
11670
- if (_optionalChain([layer, 'access', _293 => _293.fill, 'optionalAccess', _294 => _294.type]) === "pattern") patternIds2.add(layer.fill.patternId);
11671
- if (_optionalChain([layer, 'access', _295 => _295.stroke, 'optionalAccess', _296 => _296.paint, 'access', _297 => _297.type]) === "pattern") patternIds2.add(layer.stroke.paint.patternId);
11885
+ if (_optionalChain([layer, 'access', _303 => _303.fill, 'optionalAccess', _304 => _304.type]) === "pattern") patternIds2.add(layer.fill.patternId);
11886
+ if (_optionalChain([layer, 'access', _305 => _305.stroke, 'optionalAccess', _306 => _306.paint, 'access', _307 => _307.type]) === "pattern") patternIds2.add(layer.stroke.paint.patternId);
11672
11887
  } else {
11673
11888
  extra.push({ key: "TySh", data: padEven(tyShForLayer(layer)) });
11674
11889
  }
@@ -11736,7 +11951,7 @@ function exportPsd(input) {
11736
11951
  { id: 1005, name: "", data: rw.result() },
11737
11952
  { id: 1057, name: "", data: version.result() }
11738
11953
  ];
11739
- if (_optionalChain([input, 'access', _298 => _298.iccProfile, 'optionalAccess', _299 => _299.length])) resources.push({ id: 1039, name: "", data: input.iccProfile });
11954
+ if (_optionalChain([input, 'access', _308 => _308.iccProfile, 'optionalAccess', _309 => _309.length])) resources.push({ id: 1039, name: "", data: input.iccProfile });
11740
11955
  resources.push(...alphaChannelResources(_nullishCoalesce(input.alphaChannels, () => ( []))));
11741
11956
  if (input.globalLight) {
11742
11957
  const i32 = (v) => {
@@ -12155,4 +12370,15 @@ function exportPsd(input) {
12155
12370
 
12156
12371
 
12157
12372
 
12158
- exports.LEGACY_PROCESS_VERSION = LEGACY_PROCESS_VERSION; exports.LATEST_PROCESS_VERSION = LATEST_PROCESS_VERSION; exports.normalizeProcessVersion = normalizeProcessVersion; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.LUMA_709 = LUMA_709; exports.IDENTITY_MATRIX3 = IDENTITY_MATRIX3; exports.mulMatrix3 = mulMatrix3; exports.applyMatrix3 = applyMatrix3; exports.invertMatrix3 = invertMatrix3; exports.D65 = D65; exports.bradfordAdaptation = bradfordAdaptation; exports.wbMatrix = wbMatrix; exports.linearSrgbToXy = linearSrgbToXy; exports.TINT_SCALE = TINT_SCALE; exports.MIN_KELVIN = MIN_KELVIN; exports.MAX_KELVIN = MAX_KELVIN; exports.xyToUv = xyToUv; exports.uvToXy = uvToXy; exports.tempTintToXy = tempTintToXy; exports.xyToTempTint = xyToTempTint; exports.AS_SHOT_KELVIN = AS_SHOT_KELVIN; exports.MIRED_PER_TEMPERATURE_UNIT = MIRED_PER_TEMPERATURE_UNIT; exports.temperatureToKelvin = temperatureToKelvin; exports.kelvinToTemperature = kelvinToTemperature; exports.whiteBalanceMatrix = whiteBalanceMatrix; exports.whiteBalanceFromSample = whiteBalanceFromSample; exports.TONE_LUT_SIZE = TONE_LUT_SIZE; exports.toneCurve = toneCurve; exports.buildToneLut = buildToneLut; exports.sampleToneLut = sampleToneLut; exports.normalizeAngle = normalizeAngle; exports.isQuarterTurnSwapped = isQuarterTurnSwapped; exports.getRotatedSize = getRotatedSize; exports.projectImagePoint = projectImagePoint; exports.unprojectCanvasPoint = unprojectCanvasPoint; exports.applyImageProjectionToContext = applyImageProjectionToContext; exports.projectImageRect = projectImageRect; exports.clampCropToImage = clampCropToImage; exports.getViewportProjection = getViewportProjection; exports.getViewportMetrics = getViewportMetrics; exports.canvasToImagePoint = canvasToImagePoint; exports.imageToCanvasPoint = imageToCanvasPoint; exports.mapCropHandle = mapCropHandle; exports.hitTestCrop = hitTestCrop; exports.getCropCursor = getCropCursor; exports.calculateCropDrag = calculateCropDrag; exports.getAnnotationBounds = getAnnotationBounds; exports.hitTestAnnotation = hitTestAnnotation; exports.SELECTION_MODES = SELECTION_MODES; exports.isSelectionMode = isSelectionMode; exports.parseSelectionMode = parseSelectionMode; exports.computeSelectionBounds = computeSelectionBounds; exports.selectionFromTiles = selectionFromTiles; exports.createSelectionMask = createSelectionMask; exports.selectionFromRegion = selectionFromRegion; exports.fullSelection = fullSelection; exports.isSelectionEmpty = isSelectionEmpty; exports.selectionValueAt = selectionValueAt; exports.coverageToByte = coverageToByte; exports.selectionFromCoverage = selectionFromCoverage; exports.selectionToCoverage = selectionToCoverage; exports.selectionArea = selectionArea; exports.combineSelections = combineSelections; exports.invertSelection = invertSelection; exports.resizeSelection = resizeSelection; exports.selectionFromPixels = selectionFromPixels; exports.selectionToPixels = selectionToPixels; exports.encodeSelectionRle = encodeSelectionRle; exports.decodeSelectionRle = decodeSelectionRle; exports.serializeSelection = serializeSelection; exports.deserializeSelection = deserializeSelection; exports.hashMaskContent = hashMaskContent; exports.EMPTY_DISTANCE = EMPTY_DISTANCE; exports.distanceTransform = distanceTransform; exports.expandCoverage = expandCoverage; exports.contractCoverage = contractCoverage; exports.borderCoverage = borderCoverage; exports.smoothCoverage = smoothCoverage; exports.featherCoverage = featherCoverage; exports.greyMorphology = greyMorphology; exports.shiftCoverage = shiftCoverage; exports.SELECTION_MODIFY_OPS = SELECTION_MODIFY_OPS; exports.modifySelection = modifySelection; exports.normalizeLayerMask = normalizeLayerMask; exports.layerMaskFromSelection = layerMaskFromSelection; exports.updateLayerMaskProps = updateLayerMaskProps; exports.decodeLayerMask = decodeLayerMask; exports.layerMaskKey = layerMaskKey; exports.layerMaskCoverage = layerMaskCoverage; exports.projectMaskCoverage = projectMaskCoverage; exports.buildLayerMaskPlanes = buildLayerMaskPlanes; exports.ADJUSTMENT_LUT_SIZE = ADJUSTMENT_LUT_SIZE; exports.sampleLut = sampleLut; exports.ADJUSTMENT_KINDS = ADJUSTMENT_KINDS; exports.isAdjustmentKind = isAdjustmentKind; exports.adjustmentKindLabel = adjustmentKindLabel; exports.HUE_RANGE_LABELS = HUE_RANGE_LABELS; exports.neutralHueRange = neutralHueRange; exports.identityCurve = identityCurve; exports.identityLevels = identityLevels; exports.defaultAdjustmentParams = defaultAdjustmentParams; exports.createAdjustmentLayer = createAdjustmentLayer; exports.normalizeAdjustmentLayer = normalizeAdjustmentLayer; exports.normalizeAdjustmentLayers = normalizeAdjustmentLayers; exports.curveLutFromLevels = curveLutFromLevels; exports.levelsValue = levelsValue; exports.rgbToHsl = rgbToHsl; exports.hslToRgb = hslToRgb; exports.hueRangeWeight = hueRangeWeight; exports.hueRangeTables = hueRangeTables; exports.hueSaturation = hueSaturation; exports.rangeLightness = rangeLightness; exports.VIBRANCE_GREY = VIBRANCE_GREY; exports.vibranceLinear = vibranceLinear; exports.vibrancePixel = vibrancePixel; exports.colorBalanceChannel = colorBalanceChannel; exports.blackWhiteGray = blackWhiteGray; exports.D50 = D50; exports.XYZ_D50_TO_SRGB = XYZ_D50_TO_SRGB; exports.photoFilterMatrix = photoFilterMatrix; exports.posterizeValue = posterizeValue; exports.rgbToGray = rgbToGray; exports.hexToRgb = hexToRgb; exports.toneLuts = toneLuts; exports.compileAdjustmentLayer = compileAdjustmentLayer; exports.activeAdjustmentLayers = activeAdjustmentLayers; exports.evaluateAdjustmentLayers = evaluateAdjustmentLayers; exports.applyAdjustmentLayers = applyAdjustmentLayers; exports.applyAdjustmentLayersFloat = applyAdjustmentLayersFloat; exports.adjustmentLayersKey = adjustmentLayersKey; exports.applyAdjustments = applyAdjustments; exports.applyLegacyAdjustments = applyLegacyAdjustments; exports.applyLegacyFloat = applyLegacyFloat; exports.applyProcess2Adjustments = applyProcess2Adjustments; exports.applyProcess2Float = applyProcess2Float; exports.applyBoxBlurFloat = applyBoxBlurFloat; exports.applyBoxBlur = applyBoxBlur; exports.applyDepthMask = applyDepthMask; exports.removeAlpha = removeAlpha; exports.TEXT_ALIGNS = TEXT_ALIGNS; exports.MAX_EFFECT_ANIMATION_MS = MAX_EFFECT_ANIMATION_MS; exports.SHAPE_OPERATIONS = SHAPE_OPERATIONS; exports.LIVE_SHAPE_KINDS = LIVE_SHAPE_KINDS; exports.newLayerId = newLayerId; exports.pixelLayers = pixelLayers; exports.developFilter = developFilter; exports.blurFilter = blurFilter; exports.isActiveFilter = isActiveFilter; exports.isSpatialFilter = isSpatialFilter; exports.pixelLayerBounds = pixelLayerBounds; exports.layerTypeLabel = layerTypeLabel; exports.hasSurface = hasSurface; exports.isRenderedLayer = isRenderedLayer; exports.shapeLayers = shapeLayers; exports.smartObjectLayers = smartObjectLayers; exports.adjustmentNodeAsLayer = adjustmentNodeAsLayer; exports.depthMaskAlpha = depthMaskAlpha; exports.runLayerFilters = runLayerFilters; exports.runLayerFiltersFloat = runLayerFiltersFloat; exports.LayerCompositor = LayerCompositor; exports.compositeDeep = compositeDeep; exports.DEFAULT_ADJUSTMENTS_VALUES = DEFAULT_ADJUSTMENTS_VALUES; exports.DEFAULT_TRANSFORM_VALUES = DEFAULT_TRANSFORM_VALUES; exports.DEFAULT_DEPTH_MASK_VALUES = DEFAULT_DEPTH_MASK_VALUES; exports.flattenPath = flattenPath; exports.rasterizeCoverage = rasterizeCoverage; exports.LayerOperationError = LayerOperationError; exports.userErrorMessage = userErrorMessage; exports.isPaintableLayer = isPaintableLayer; exports.defaultActiveLayerId = defaultActiveLayerId; exports.activeLayerAfterRemoval = activeLayerAfterRemoval; exports.requireLayer = requireLayer; exports.requireUnlocked = requireUnlocked; exports.placeLayer = placeLayer; exports.removeLayer = removeLayer; exports.moveLayer = moveLayer; exports.withNewIds = withNewIds; exports.duplicateLayer = duplicateLayer; exports.setLayerProperties = setLayerProperties; exports.groupLayers = groupLayers; exports.ungroupLayer = ungroupLayer; exports.offsetLayer = offsetLayer; exports.setLayerMask = setLayerMask; exports.normalizeFilter = normalizeFilter; exports.addLayerFilter = addLayerFilter; exports.updateLayerFilter = updateLayerFilter; exports.removeLayerFilter = removeLayerFilter; exports.layerEffectsOf = layerEffectsOf; exports.setLayerEffects = setLayerEffects; exports.addLayerEffect = addLayerEffect; exports.updateLayerEffect = updateLayerEffect; exports.removeLayerEffect = removeLayerEffect; exports.setLayerEffectsEnabled = setLayerEffectsEnabled; exports.parseBlend = parseBlend; exports.unionRect = unionRect; exports.SHAPE_RENDER_MARGIN = SHAPE_RENDER_MARGIN; exports.DEFAULT_MITER_LIMIT = DEFAULT_MITER_LIMIT; exports.mapSubpaths = mapSubpaths; exports.liveShapeSubpaths = liveShapeSubpaths; exports.liveComponent = liveComponent; exports.componentPath = componentPath; exports.shapeOutline = shapeOutline; exports.shapeGeometryBounds = shapeGeometryBounds; exports.shapeRenderClip = shapeRenderClip; exports.renderShapeRect = renderShapeRect; exports.renderShape = renderShape; exports.rerenderShape = rerenderShape; exports.normalizeShapePaint = normalizeShapePaint; exports.normalizeShapeStroke = normalizeShapeStroke; exports.normalizeLiveShape = normalizeLiveShape; exports.normalizeSubpaths = normalizeSubpaths; exports.requireOperation = requireOperation; exports.requireShapeLayer = requireShapeLayer; exports.createShapeLayer = createShapeLayer; exports.defaultShapeName = defaultShapeName; exports.updateShapeLayer = updateShapeLayer; exports.transformShapeComponents = transformShapeComponents; exports.offsetShape = offsetShape; exports.mergeShapeComponents = mergeShapeComponents; exports.shapeAsPixelLayer = shapeAsPixelLayer; exports.shapeFromAnnotation = shapeFromAnnotation; exports.annotationBlend = annotationBlend; exports.annotationOfShape = annotationOfShape; exports.TEXT_RENDER_MARGIN = TEXT_RENDER_MARGIN; exports.textMatrix = textMatrix; exports.textOutlines = textOutlines; exports.renderText = renderText; exports.rerenderText = rerenderText; exports.TEXT_STYLE_FIELDS = TEXT_STYLE_FIELDS; exports.patchTextStyle = patchTextStyle; exports.PARAGRAPH_STYLE_FIELDS = PARAGRAPH_STYLE_FIELDS; exports.patchParagraphStyle = patchParagraphStyle; exports.textRange = textRange; exports.requireTypeLayer = requireTypeLayer; exports.normalizeText = normalizeText; exports.typeLayerName = typeLayerName; exports.createTypeLayer = createTypeLayer; exports.updateTypeLayer = updateTypeLayer; exports.replaceTextRange = replaceTextRange; exports.transformTypeLayer = transformTypeLayer; exports.typeFrame = typeFrame; exports.typeAsPixelLayer = typeAsPixelLayer; exports.toTextSpace = toTextSpace; exports.typeFromAnnotation = typeFromAnnotation; exports.annotationOfType = annotationOfType; exports.BACKGROUND_LAYER_ID = BACKGROUND_LAYER_ID; exports.BACKGROUND_LAYER_NAME = BACKGROUND_LAYER_NAME; exports.DEVELOP_FILTER_ID = DEVELOP_FILTER_ID; exports.BLUR_FILTER_ID = BLUR_FILTER_ID; exports.rasterMaskFromLegacy = rasterMaskFromLegacy; exports.hasResampledLegacyMask = hasResampledLegacyMask; exports.legacyMaskOf = legacyMaskOf; exports.isDefaultDepthMask = isDefaultDepthMask; exports.developFromAdjustments = developFromAdjustments; exports.annotationLayerName = annotationLayerName; exports.annotationLayerFor = annotationLayerFor; exports.annotationOfLayer = annotationOfLayer; exports.adjustmentNodeFromLegacy = adjustmentNodeFromLegacy; exports.backgroundLayer = backgroundLayer; exports.depthRasterMask = depthRasterMask; exports.layersFromLegacy = layersFromLegacy; exports.legacyAdjustmentLayer = legacyAdjustmentLayer; exports.developTarget = developTarget; exports.legacyView = legacyView; exports.isLegacyShape = isLegacyShape; exports.FREE_TRANSFORM_MODES = FREE_TRANSFORM_MODES; exports.TRANSFORM_ANCHORS = TRANSFORM_ANCHORS; exports.ANCHOR_FRACTION = ANCHOR_FRACTION; exports.isTransformAnchor = isTransformAnchor; exports.identityTransform = identityTransform; exports.cornersFromMatrix = cornersFromMatrix; exports.matrixFromCorners = matrixFromCorners; exports.transformHomography = transformHomography; exports.hasWarp = hasWarp; exports.isIdentityTransform = isIdentityTransform; exports.transformMap = transformMap; exports.transformedPoint = transformedPoint; exports.anchorPoint = anchorPoint; exports.transformedBox = transformedBox; exports.referencePoint = referencePoint; exports.matrixFromParams = matrixFromParams; exports.describeTransform = describeTransform; exports.applyParams = applyParams; exports.flipCorners = flipCorners; exports.boxPointOf = boxPointOf; exports.presetWarp = presetWarp; exports.isValidWarp = isValidWarp; exports.geometryHomography = geometryHomography; exports.SMART_RENDER_MARGIN = SMART_RENDER_MARGIN; exports.isSmartSurfaceIncomplete = isSmartSurfaceIncomplete; exports.newContentsId = newContentsId; exports.contentsBox = contentsBox; exports.placementGeometry = placementGeometry; exports.placementAt = placementAt; exports.isContentsDecoded = isContentsDecoded; exports.requireSmartObject = requireSmartObject; exports.contentsSurface = contentsSurface; exports.rasterContents = rasterContents; exports.documentContents = documentContents; exports.placeContents = placeContents; exports.activeSmartFilters = activeSmartFilters; exports.activeEffectSmartFilters = activeEffectSmartFilters; exports.filterMaskCoverage = filterMaskCoverage; exports.applySmartFilters = applySmartFilters; exports.renderSmartObject = renderSmartObject; exports.rerender = rerender; exports.normalizePlacement = normalizePlacement; exports.setSmartPlacement = setSmartPlacement; exports.offsetSmartObject = offsetSmartObject; exports.translateLayer = translateLayer; exports.convertToSmartObject = convertToSmartObject; exports.rasterizeSmartObject = rasterizeSmartObject; exports.copySmartObject = copySmartObject; exports.instancesOf = instancesOf; exports.replaceContents = replaceContents; exports.normalizeSmartFilter = normalizeSmartFilter; exports.addSmartFilter = addSmartFilter; exports.updateSmartFilter = updateSmartFilter; exports.removeSmartFilter = removeSmartFilter; exports.moveSmartFilter = moveSmartFilter; exports.setSmartFiltersEnabled = setSmartFiltersEnabled; exports.setSmartFilterMask = setSmartFilterMask; exports.withFilterMaskSurface = withFilterMaskSurface; exports.placementBounds = placementBounds; exports.LAYERED_SCHEMA_VERSION = LAYERED_SCHEMA_VERSION; exports.serializePatterns = serializePatterns; exports.deserializePatterns = deserializePatterns; exports.encodeSurface = encodeSurface; exports.encodeDeepSurface = encodeDeepSurface; exports.decodeDeepSurface = decodeDeepSurface; exports.serializeEffects = serializeEffects; exports.deserializeEffects = deserializeEffects; exports.serializeLayer = serializeLayer; exports.serializeContents = serializeContents; exports.serializeLayers = serializeLayers; exports.serializeLayersExternal = serializeLayersExternal; exports.resolveExternalAssets = resolveExternalAssets; exports.decodePngDataUrl = decodePngDataUrl; exports.deserializeLayer = deserializeLayer; exports.deserializeLayers = deserializeLayers; exports.PsdError = PsdError; exports.decodePlanes = decodePlanes; exports.encodeRle = encodeRle; exports.parseVersionedDescriptor = parseVersionedDescriptor; exports.versionedDescriptorBytes = versionedDescriptorBytes; exports.ADJUSTMENT_KEYS = ADJUSTMENT_KEYS; exports.SUPPORTED_ADJUSTMENT_KEYS = SUPPORTED_ADJUSTMENT_KEYS; exports.parseAdjustmentBlock = parseAdjustmentBlock; exports.writeAdjustmentBlock = writeAdjustmentBlock; exports.parseLfx2 = parseLfx2; exports.writeLfx2 = writeLfx2; exports.parseLrfx = parseLrfx; exports.BROWSER_IMAGE_TYPES = BROWSER_IMAGE_TYPES; exports.readPsd = readPsd; exports.layerName = layerName; exports.layerTree = layerTree; exports.decodeLayerChannel = decodeLayerChannel; exports.decodeMergedImage = decodeMergedImage; exports.writePsd = writePsd; exports.PATTERN_BLOCK_KEYS = PATTERN_BLOCK_KEYS; exports.parsePatternBlock = parsePatternBlock; exports.psdPatternToEffectPattern = psdPatternToEffectPattern; exports.writePatternBlock = writePatternBlock; exports.PSD_BLEND_KEYS = PSD_BLEND_KEYS; exports.psdToLayers = psdToLayers; exports.importPsd = importPsd; exports.smartContentsFile = smartContentsFile; exports.exportPsd = exportPsd;
12373
+
12374
+
12375
+
12376
+
12377
+
12378
+
12379
+
12380
+
12381
+
12382
+
12383
+
12384
+ exports.LEGACY_PROCESS_VERSION = LEGACY_PROCESS_VERSION; exports.LATEST_PROCESS_VERSION = LATEST_PROCESS_VERSION; exports.normalizeProcessVersion = normalizeProcessVersion; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.LUMA_709 = LUMA_709; exports.IDENTITY_MATRIX3 = IDENTITY_MATRIX3; exports.mulMatrix3 = mulMatrix3; exports.applyMatrix3 = applyMatrix3; exports.invertMatrix3 = invertMatrix3; exports.D65 = D65; exports.bradfordAdaptation = bradfordAdaptation; exports.wbMatrix = wbMatrix; exports.linearSrgbToXy = linearSrgbToXy; exports.TINT_SCALE = TINT_SCALE; exports.MIN_KELVIN = MIN_KELVIN; exports.MAX_KELVIN = MAX_KELVIN; exports.xyToUv = xyToUv; exports.uvToXy = uvToXy; exports.tempTintToXy = tempTintToXy; exports.xyToTempTint = xyToTempTint; exports.AS_SHOT_KELVIN = AS_SHOT_KELVIN; exports.MIRED_PER_TEMPERATURE_UNIT = MIRED_PER_TEMPERATURE_UNIT; exports.temperatureToKelvin = temperatureToKelvin; exports.kelvinToTemperature = kelvinToTemperature; exports.whiteBalanceMatrix = whiteBalanceMatrix; exports.whiteBalanceFromSample = whiteBalanceFromSample; exports.TONE_LUT_SIZE = TONE_LUT_SIZE; exports.toneCurve = toneCurve; exports.buildToneLut = buildToneLut; exports.sampleToneLut = sampleToneLut; exports.normalizeAngle = normalizeAngle; exports.isQuarterTurnSwapped = isQuarterTurnSwapped; exports.getRotatedSize = getRotatedSize; exports.projectImagePoint = projectImagePoint; exports.unprojectCanvasPoint = unprojectCanvasPoint; exports.applyImageProjectionToContext = applyImageProjectionToContext; exports.projectImageRect = projectImageRect; exports.clampCropToImage = clampCropToImage; exports.getViewportProjection = getViewportProjection; exports.getViewportMetrics = getViewportMetrics; exports.canvasToImagePoint = canvasToImagePoint; exports.imageToCanvasPoint = imageToCanvasPoint; exports.mapCropHandle = mapCropHandle; exports.hitTestCrop = hitTestCrop; exports.getCropCursor = getCropCursor; exports.calculateCropDrag = calculateCropDrag; exports.getAnnotationBounds = getAnnotationBounds; exports.hitTestAnnotation = hitTestAnnotation; exports.SELECTION_MODES = SELECTION_MODES; exports.isSelectionMode = isSelectionMode; exports.parseSelectionMode = parseSelectionMode; exports.computeSelectionBounds = computeSelectionBounds; exports.selectionFromTiles = selectionFromTiles; exports.createSelectionMask = createSelectionMask; exports.selectionFromRegion = selectionFromRegion; exports.fullSelection = fullSelection; exports.isSelectionEmpty = isSelectionEmpty; exports.selectionValueAt = selectionValueAt; exports.coverageToByte = coverageToByte; exports.selectionFromCoverage = selectionFromCoverage; exports.selectionToCoverage = selectionToCoverage; exports.selectionArea = selectionArea; exports.combineSelections = combineSelections; exports.invertSelection = invertSelection; exports.resizeSelection = resizeSelection; exports.selectionFromPixels = selectionFromPixels; exports.selectionToPixels = selectionToPixels; exports.encodeSelectionRle = encodeSelectionRle; exports.decodeSelectionRle = decodeSelectionRle; exports.serializeSelection = serializeSelection; exports.deserializeSelection = deserializeSelection; exports.hashMaskContent = hashMaskContent; exports.EMPTY_DISTANCE = EMPTY_DISTANCE; exports.distanceTransform = distanceTransform; exports.expandCoverage = expandCoverage; exports.contractCoverage = contractCoverage; exports.borderCoverage = borderCoverage; exports.smoothCoverage = smoothCoverage; exports.featherCoverage = featherCoverage; exports.greyMorphology = greyMorphology; exports.shiftCoverage = shiftCoverage; exports.SELECTION_MODIFY_OPS = SELECTION_MODIFY_OPS; exports.modifySelection = modifySelection; exports.layerMaskSelection = layerMaskSelection; exports.normalizeLayerMask = normalizeLayerMask; exports.layerMaskFromSelection = layerMaskFromSelection; exports.updateLayerMaskProps = updateLayerMaskProps; exports.decodeLayerMask = decodeLayerMask; exports.layerMaskKey = layerMaskKey; exports.layerMaskCoverage = layerMaskCoverage; exports.projectMaskCoverage = projectMaskCoverage; exports.buildLayerMaskPlanes = buildLayerMaskPlanes; exports.ADJUSTMENT_LUT_SIZE = ADJUSTMENT_LUT_SIZE; exports.sampleLut = sampleLut; exports.ADJUSTMENT_KINDS = ADJUSTMENT_KINDS; exports.isAdjustmentKind = isAdjustmentKind; exports.adjustmentKindLabel = adjustmentKindLabel; exports.HUE_RANGE_LABELS = HUE_RANGE_LABELS; exports.neutralHueRange = neutralHueRange; exports.identityCurve = identityCurve; exports.identityLevels = identityLevels; exports.defaultAdjustmentParams = defaultAdjustmentParams; exports.createAdjustmentLayer = createAdjustmentLayer; exports.normalizeAdjustmentLayer = normalizeAdjustmentLayer; exports.normalizeAdjustmentLayers = normalizeAdjustmentLayers; exports.curveLutFromLevels = curveLutFromLevels; exports.levelsValue = levelsValue; exports.rgbToHsl = rgbToHsl; exports.hslToRgb = hslToRgb; exports.hueRangeWeight = hueRangeWeight; exports.hueRangeTables = hueRangeTables; exports.hueSaturation = hueSaturation; exports.rangeLightness = rangeLightness; exports.VIBRANCE_GREY = VIBRANCE_GREY; exports.vibranceLinear = vibranceLinear; exports.vibrancePixel = vibrancePixel; exports.colorBalanceChannel = colorBalanceChannel; exports.blackWhiteGray = blackWhiteGray; exports.D50 = D50; exports.XYZ_D50_TO_SRGB = XYZ_D50_TO_SRGB; exports.photoFilterMatrix = photoFilterMatrix; exports.posterizeValue = posterizeValue; exports.rgbToGray = rgbToGray; exports.hexToRgb = hexToRgb; exports.toneLuts = toneLuts; exports.compileAdjustmentLayer = compileAdjustmentLayer; exports.activeAdjustmentLayers = activeAdjustmentLayers; exports.evaluateAdjustmentLayers = evaluateAdjustmentLayers; exports.applyAdjustmentLayers = applyAdjustmentLayers; exports.applyAdjustmentLayersFloat = applyAdjustmentLayersFloat; exports.adjustmentLayersKey = adjustmentLayersKey; exports.applyAdjustments = applyAdjustments; exports.applyLegacyAdjustments = applyLegacyAdjustments; exports.applyLegacyFloat = applyLegacyFloat; exports.applyProcess2Adjustments = applyProcess2Adjustments; exports.applyProcess2Float = applyProcess2Float; exports.applyBoxBlurFloat = applyBoxBlurFloat; exports.applyBoxBlur = applyBoxBlur; exports.applyDepthMask = applyDepthMask; exports.removeAlpha = removeAlpha; exports.flattenPath = flattenPath; exports.rasterizeCoverage = rasterizeCoverage; exports.TEXT_ALIGNS = TEXT_ALIGNS; exports.MAX_EFFECT_ANIMATION_MS = MAX_EFFECT_ANIMATION_MS; exports.SHAPE_OPERATIONS = SHAPE_OPERATIONS; exports.LIVE_SHAPE_KINDS = LIVE_SHAPE_KINDS; exports.newLayerId = newLayerId; exports.pixelLayers = pixelLayers; exports.developFilter = developFilter; exports.blurFilter = blurFilter; exports.isActiveFilter = isActiveFilter; exports.isSpatialFilter = isSpatialFilter; exports.pixelLayerBounds = pixelLayerBounds; exports.layerTypeLabel = layerTypeLabel; exports.hasSurface = hasSurface; exports.isRenderedLayer = isRenderedLayer; exports.shapeLayers = shapeLayers; exports.smartObjectLayers = smartObjectLayers; exports.LayerOperationError = LayerOperationError; exports.userErrorMessage = userErrorMessage; exports.isPaintableLayer = isPaintableLayer; exports.defaultActiveLayerId = defaultActiveLayerId; exports.activeLayerAfterRemoval = activeLayerAfterRemoval; exports.requireLayer = requireLayer; exports.requireUnlocked = requireUnlocked; exports.placeLayer = placeLayer; exports.removeLayer = removeLayer; exports.moveLayer = moveLayer; exports.withNewIds = withNewIds; exports.duplicateLayer = duplicateLayer; exports.setLayerProperties = setLayerProperties; exports.groupLayers = groupLayers; exports.ungroupLayer = ungroupLayer; exports.offsetLayer = offsetLayer; exports.setLayerMask = setLayerMask; exports.normalizeFilter = normalizeFilter; exports.addLayerFilter = addLayerFilter; exports.updateLayerFilter = updateLayerFilter; exports.removeLayerFilter = removeLayerFilter; exports.layerEffectsOf = layerEffectsOf; exports.setLayerEffects = setLayerEffects; exports.addLayerEffect = addLayerEffect; exports.updateLayerEffect = updateLayerEffect; exports.removeLayerEffect = removeLayerEffect; exports.setLayerEffectsEnabled = setLayerEffectsEnabled; exports.parseBlend = parseBlend; exports.unionRect = unionRect; exports.SHAPE_RENDER_MARGIN = SHAPE_RENDER_MARGIN; exports.DEFAULT_MITER_LIMIT = DEFAULT_MITER_LIMIT; exports.mapSubpaths = mapSubpaths; exports.liveShapeSubpaths = liveShapeSubpaths; exports.liveComponent = liveComponent; exports.componentPath = componentPath; exports.shapeOutline = shapeOutline; exports.shapeGeometryBounds = shapeGeometryBounds; exports.componentsCoverage = componentsCoverage; exports.shapeRenderClip = shapeRenderClip; exports.renderShapeRect = renderShapeRect; exports.renderShape = renderShape; exports.rerenderShape = rerenderShape; exports.normalizeShapePaint = normalizeShapePaint; exports.normalizeShapeStroke = normalizeShapeStroke; exports.normalizeLiveShape = normalizeLiveShape; exports.normalizeSubpaths = normalizeSubpaths; exports.requireOperation = requireOperation; exports.requireShapeLayer = requireShapeLayer; exports.createShapeLayer = createShapeLayer; exports.defaultShapeName = defaultShapeName; exports.updateShapeLayer = updateShapeLayer; exports.transformShapeComponents = transformShapeComponents; exports.offsetShape = offsetShape; exports.mergeShapeComponents = mergeShapeComponents; exports.shapeAsPixelLayer = shapeAsPixelLayer; exports.shapeFromAnnotation = shapeFromAnnotation; exports.annotationBlend = annotationBlend; exports.annotationOfShape = annotationOfShape; exports.isActiveVectorMask = isActiveVectorMask; exports.vectorMaskCoverage = vectorMaskCoverage; exports.effectiveLayerMask = effectiveLayerMask; exports.resolveVectorMasks = resolveVectorMasks; exports.offsetVectorMask = offsetVectorMask; exports.transformVectorMask = transformVectorMask; exports.followLayerMove = followLayerMove; exports.vectorMaskBounds = vectorMaskBounds; exports.vectorMaskThumbnail = vectorMaskThumbnail; exports.adjustmentNodeAsLayer = adjustmentNodeAsLayer; exports.depthMaskAlpha = depthMaskAlpha; exports.runLayerFilters = runLayerFilters; exports.runLayerFiltersFloat = runLayerFiltersFloat; exports.LayerCompositor = LayerCompositor; exports.compositeDeep = compositeDeep; exports.DEFAULT_ADJUSTMENTS_VALUES = DEFAULT_ADJUSTMENTS_VALUES; exports.DEFAULT_TRANSFORM_VALUES = DEFAULT_TRANSFORM_VALUES; exports.DEFAULT_DEPTH_MASK_VALUES = DEFAULT_DEPTH_MASK_VALUES; exports.TEXT_RENDER_MARGIN = TEXT_RENDER_MARGIN; exports.textMatrix = textMatrix; exports.textOutlines = textOutlines; exports.renderText = renderText; exports.rerenderText = rerenderText; exports.TEXT_STYLE_FIELDS = TEXT_STYLE_FIELDS; exports.patchTextStyle = patchTextStyle; exports.PARAGRAPH_STYLE_FIELDS = PARAGRAPH_STYLE_FIELDS; exports.patchParagraphStyle = patchParagraphStyle; exports.textRange = textRange; exports.requireTypeLayer = requireTypeLayer; exports.normalizeText = normalizeText; exports.typeLayerName = typeLayerName; exports.createTypeLayer = createTypeLayer; exports.updateTypeLayer = updateTypeLayer; exports.replaceTextRange = replaceTextRange; exports.transformTypeLayer = transformTypeLayer; exports.typeFrame = typeFrame; exports.typeAsPixelLayer = typeAsPixelLayer; exports.toTextSpace = toTextSpace; exports.typeFromAnnotation = typeFromAnnotation; exports.annotationOfType = annotationOfType; exports.BACKGROUND_LAYER_ID = BACKGROUND_LAYER_ID; exports.BACKGROUND_LAYER_NAME = BACKGROUND_LAYER_NAME; exports.DEVELOP_FILTER_ID = DEVELOP_FILTER_ID; exports.BLUR_FILTER_ID = BLUR_FILTER_ID; exports.rasterMaskFromLegacy = rasterMaskFromLegacy; exports.hasResampledLegacyMask = hasResampledLegacyMask; exports.legacyMaskOf = legacyMaskOf; exports.isDefaultDepthMask = isDefaultDepthMask; exports.developFromAdjustments = developFromAdjustments; exports.annotationLayerName = annotationLayerName; exports.annotationLayerFor = annotationLayerFor; exports.annotationOfLayer = annotationOfLayer; exports.adjustmentNodeFromLegacy = adjustmentNodeFromLegacy; exports.backgroundLayer = backgroundLayer; exports.depthRasterMask = depthRasterMask; exports.layersFromLegacy = layersFromLegacy; exports.legacyAdjustmentLayer = legacyAdjustmentLayer; exports.developTarget = developTarget; exports.legacyView = legacyView; exports.isLegacyShape = isLegacyShape; exports.FREE_TRANSFORM_MODES = FREE_TRANSFORM_MODES; exports.TRANSFORM_ANCHORS = TRANSFORM_ANCHORS; exports.ANCHOR_FRACTION = ANCHOR_FRACTION; exports.isTransformAnchor = isTransformAnchor; exports.identityTransform = identityTransform; exports.cornersFromMatrix = cornersFromMatrix; exports.matrixFromCorners = matrixFromCorners; exports.transformHomography = transformHomography; exports.hasWarp = hasWarp; exports.isIdentityTransform = isIdentityTransform; exports.transformMap = transformMap; exports.transformedPoint = transformedPoint; exports.anchorPoint = anchorPoint; exports.transformedBox = transformedBox; exports.referencePoint = referencePoint; exports.matrixFromParams = matrixFromParams; exports.describeTransform = describeTransform; exports.applyParams = applyParams; exports.flipCorners = flipCorners; exports.boxPointOf = boxPointOf; exports.presetWarp = presetWarp; exports.isValidWarp = isValidWarp; exports.geometryHomography = geometryHomography; exports.SMART_RENDER_MARGIN = SMART_RENDER_MARGIN; exports.isSmartSurfaceIncomplete = isSmartSurfaceIncomplete; exports.newContentsId = newContentsId; exports.contentsBox = contentsBox; exports.placementGeometry = placementGeometry; exports.placementAt = placementAt; exports.isContentsDecoded = isContentsDecoded; exports.requireSmartObject = requireSmartObject; exports.contentsSurface = contentsSurface; exports.rasterContents = rasterContents; exports.documentContents = documentContents; exports.placeContents = placeContents; exports.activeSmartFilters = activeSmartFilters; exports.activeEffectSmartFilters = activeEffectSmartFilters; exports.filterMaskCoverage = filterMaskCoverage; exports.applySmartFilters = applySmartFilters; exports.renderSmartObject = renderSmartObject; exports.rerender = rerender; exports.normalizePlacement = normalizePlacement; exports.setSmartPlacement = setSmartPlacement; exports.offsetSmartObject = offsetSmartObject; exports.translateLayer = translateLayer; exports.convertToSmartObject = convertToSmartObject; exports.rasterizeSmartObject = rasterizeSmartObject; exports.copySmartObject = copySmartObject; exports.instancesOf = instancesOf; exports.replaceContents = replaceContents; exports.normalizeSmartFilter = normalizeSmartFilter; exports.addSmartFilter = addSmartFilter; exports.updateSmartFilter = updateSmartFilter; exports.removeSmartFilter = removeSmartFilter; exports.moveSmartFilter = moveSmartFilter; exports.setSmartFiltersEnabled = setSmartFiltersEnabled; exports.setSmartFilterMask = setSmartFilterMask; exports.withFilterMaskSurface = withFilterMaskSurface; exports.placementBounds = placementBounds; exports.LAYERED_SCHEMA_VERSION = LAYERED_SCHEMA_VERSION; exports.serializePatterns = serializePatterns; exports.deserializePatterns = deserializePatterns; exports.encodeSurface = encodeSurface; exports.encodeDeepSurface = encodeDeepSurface; exports.decodeDeepSurface = decodeDeepSurface; exports.serializeEffects = serializeEffects; exports.deserializeEffects = deserializeEffects; exports.serializeLayer = serializeLayer; exports.serializeContents = serializeContents; exports.serializeLayers = serializeLayers; exports.serializeLayersExternal = serializeLayersExternal; exports.resolveExternalAssets = resolveExternalAssets; exports.decodePngDataUrl = decodePngDataUrl; exports.deserializeLayer = deserializeLayer; exports.deserializeLayers = deserializeLayers; exports.PsdError = PsdError; exports.decodePlanes = decodePlanes; exports.encodeRle = encodeRle; exports.parseVersionedDescriptor = parseVersionedDescriptor; exports.versionedDescriptorBytes = versionedDescriptorBytes; exports.ADJUSTMENT_KEYS = ADJUSTMENT_KEYS; exports.SUPPORTED_ADJUSTMENT_KEYS = SUPPORTED_ADJUSTMENT_KEYS; exports.parseAdjustmentBlock = parseAdjustmentBlock; exports.writeAdjustmentBlock = writeAdjustmentBlock; exports.parseLfx2 = parseLfx2; exports.writeLfx2 = writeLfx2; exports.parseLrfx = parseLrfx; exports.BROWSER_IMAGE_TYPES = BROWSER_IMAGE_TYPES; exports.readPsd = readPsd; exports.layerName = layerName; exports.layerTree = layerTree; exports.decodeLayerChannel = decodeLayerChannel; exports.decodeMergedImage = decodeMergedImage; exports.writePsd = writePsd; exports.PATTERN_BLOCK_KEYS = PATTERN_BLOCK_KEYS; exports.parsePatternBlock = parsePatternBlock; exports.psdPatternToEffectPattern = psdPatternToEffectPattern; exports.writePatternBlock = writePatternBlock; exports.PSD_BLEND_KEYS = PSD_BLEND_KEYS; exports.psdToLayers = psdToLayers; exports.importPsd = importPsd; exports.smartContentsFile = smartContentsFile; exports.exportPsd = exportPsd;