@pixerate/editor 0.94.0 → 0.96.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/THIRD_PARTY_NOTICES.md +2 -0
  2. package/dist/{chunk-ZOOEX3WT.cjs → chunk-CRMAXIUV.cjs} +369 -7
  3. package/dist/chunk-CRMAXIUV.cjs.map +1 -0
  4. package/dist/{chunk-D4ZCU72J.js → chunk-HEW6KDNI.js} +366 -4
  5. package/dist/chunk-HEW6KDNI.js.map +1 -0
  6. package/dist/{chunk-ISDCJHTO.js → chunk-IB53LVGV.js} +238 -285
  7. package/dist/chunk-IB53LVGV.js.map +1 -0
  8. package/dist/{chunk-747CGOT2.js → chunk-KFTQ2PKP.js} +29 -2
  9. package/dist/chunk-KFTQ2PKP.js.map +1 -0
  10. package/dist/{chunk-73L6TROJ.cjs → chunk-T422YCHR.cjs} +71 -44
  11. package/dist/chunk-T422YCHR.cjs.map +1 -0
  12. package/dist/{chunk-4F3YDIWW.cjs → chunk-ZZOTHJ4K.cjs} +264 -311
  13. package/dist/chunk-ZZOTHJ4K.cjs.map +1 -0
  14. package/dist/image-editor/index.cjs +1832 -632
  15. package/dist/image-editor/index.cjs.map +1 -1
  16. package/dist/image-editor/index.d.cts +179 -22
  17. package/dist/image-editor/index.d.ts +179 -22
  18. package/dist/image-editor/index.js +1463 -263
  19. package/dist/image-editor/index.js.map +1 -1
  20. package/dist/paint/index.cjs +22 -3
  21. package/dist/paint/index.cjs.map +1 -1
  22. package/dist/paint/index.d.cts +117 -2
  23. package/dist/paint/index.d.ts +117 -2
  24. package/dist/paint/index.js +32 -13
  25. package/dist/raster/index.cjs +7 -3
  26. package/dist/raster/index.cjs.map +1 -1
  27. package/dist/raster/index.d.cts +796 -5
  28. package/dist/raster/index.d.ts +796 -5
  29. package/dist/raster/index.js +6 -2
  30. package/dist/{surface-CuBg2c6k.d.cts → surface-DIA-XatS.d.cts} +23 -11
  31. package/dist/{surface-CuBg2c6k.d.ts → surface-DIA-XatS.d.ts} +23 -11
  32. package/package.json +1 -1
  33. package/skills/pixerate-image-editor/SKILL.md +39 -6
  34. package/dist/chunk-4F3YDIWW.cjs.map +0 -1
  35. package/dist/chunk-73L6TROJ.cjs.map +0 -1
  36. package/dist/chunk-747CGOT2.js.map +0 -1
  37. package/dist/chunk-D4ZCU72J.js.map +0 -1
  38. package/dist/chunk-ISDCJHTO.js.map +0 -1
  39. package/dist/chunk-ZOOEX3WT.cjs.map +0 -1
  40. package/dist/zlib-BJ6U7LuB.d.cts +0 -795
  41. package/dist/zlib-BjQkpMFi.d.ts +0 -795
@@ -42,7 +42,6 @@ var _chunkVJUVNERTcjs = require('../chunk-VJUVNERT.cjs');
42
42
 
43
43
 
44
44
 
45
- var _chunk73L6TROJcjs = require('../chunk-73L6TROJ.cjs');
46
45
 
47
46
 
48
47
 
@@ -59,6 +58,7 @@ var _chunk73L6TROJcjs = require('../chunk-73L6TROJ.cjs');
59
58
 
60
59
 
61
60
 
61
+ var _chunkT422YCHRcjs = require('../chunk-T422YCHR.cjs');
62
62
 
63
63
 
64
64
 
@@ -72,7 +72,6 @@ var _chunk73L6TROJcjs = require('../chunk-73L6TROJ.cjs');
72
72
 
73
73
 
74
74
 
75
- var _chunk4F3YDIWWcjs = require('../chunk-4F3YDIWW.cjs');
76
75
 
77
76
 
78
77
 
@@ -87,6 +86,7 @@ var _chunk4F3YDIWWcjs = require('../chunk-4F3YDIWW.cjs');
87
86
 
88
87
 
89
88
 
89
+ var _chunkZZOTHJ4Kcjs = require('../chunk-ZZOTHJ4K.cjs');
90
90
 
91
91
 
92
92
 
@@ -108,7 +108,34 @@ var _chunk4F3YDIWWcjs = require('../chunk-4F3YDIWW.cjs');
108
108
 
109
109
 
110
110
 
111
- var _chunkZOOEX3WTcjs = require('../chunk-ZOOEX3WT.cjs');
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+ var _chunkCRMAXIUVcjs = require('../chunk-CRMAXIUV.cjs');
112
139
 
113
140
  // src/image-editor/color.ts
114
141
  var LEGACY_PROCESS_VERSION = 1;
@@ -297,8 +324,8 @@ function whiteBalanceFromSample(rgb) {
297
324
  if (lin[0] + lin[1] + lin[2] <= 1e-6) return { temperature: 0, tint: 0 };
298
325
  const src = linearSrgbToXy(applyMatrix3(AS_SHOT_WB_INV, lin));
299
326
  const { kelvin, tint } = xyToTempTint(src);
300
- const clamp3 = (v) => Math.max(-100, Math.min(100, v));
301
- return { temperature: clamp3(kelvinToTemperature(kelvin)), tint: clamp3(tint) };
327
+ const clamp4 = (v) => Math.max(-100, Math.min(100, v));
328
+ return { temperature: clamp4(kelvinToTemperature(kelvin)), tint: clamp4(tint) };
302
329
  }
303
330
  var TONE_LUT_SIZE = 4096;
304
331
  var GREY = 0.18;
@@ -892,21 +919,21 @@ function toBase64(bytes, length) {
892
919
  parts.push(chunk);
893
920
  return parts.join("");
894
921
  }
895
- function fromBase64(text) {
896
- if (text.length % 4 !== 0) throw new Error("Invalid base64 length");
922
+ function fromBase64(text2) {
923
+ if (text2.length % 4 !== 0) throw new Error("Invalid base64 length");
897
924
  let pad = 0;
898
- if (text.endsWith("==")) pad = 2;
899
- else if (text.endsWith("=")) pad = 1;
900
- const out = new Uint8Array(text.length / 4 * 3 - pad);
925
+ if (text2.endsWith("==")) pad = 2;
926
+ else if (text2.endsWith("=")) pad = 1;
927
+ const out = new Uint8Array(text2.length / 4 * 3 - pad);
901
928
  let o = 0;
902
929
  const digit = (i, k) => {
903
- const ch = text.charCodeAt(i + k);
904
- if (ch === 61 && i + 4 === text.length && k >= 4 - pad) return 0;
930
+ const ch = text2.charCodeAt(i + k);
931
+ if (ch === 61 && i + 4 === text2.length && k >= 4 - pad) return 0;
905
932
  const idx = ch < 128 ? B64_INDEX[ch] : -1;
906
933
  if (idx < 0) throw new Error("Invalid base64 character");
907
934
  return idx;
908
935
  };
909
- for (let i = 0; i < text.length; i += 4) {
936
+ for (let i = 0; i < text2.length; i += 4) {
910
937
  const n = digit(i, 0) << 18 | digit(i, 1) << 12 | digit(i, 2) << 6 | digit(i, 3);
911
938
  if (o < out.length) out[o++] = n >> 16 & 255;
912
939
  if (o < out.length) out[o++] = n >> 8 & 255;
@@ -1120,7 +1147,7 @@ function smoothCoverage(m, w, h, r) {
1120
1147
  return src;
1121
1148
  }
1122
1149
  function featherCoverage(m, w, h, radius) {
1123
- const out = _chunk73L6TROJcjs.gaussianBlur.call(void 0, m, w, h, Number.isFinite(radius) ? Math.max(0, radius) : 0, "zero");
1150
+ const out = _chunkT422YCHRcjs.gaussianBlur.call(void 0, m, w, h, Number.isFinite(radius) ? Math.max(0, radius) : 0, "zero");
1124
1151
  for (let i = 0; i < out.length; i++) if (Math.abs(out[i]) < 1e-7) out[i] = 0;
1125
1152
  return out;
1126
1153
  }
@@ -1268,7 +1295,7 @@ function layerMaskCoverage(mask) {
1268
1295
  let v = new Float32Array(sel.data.length);
1269
1296
  for (let i = 0; i < v.length; i++) v[i] = sel.data[i] / 255;
1270
1297
  const feather = _nullishCoalesce(mask.feather, () => ( 0));
1271
- if (feather > 0) v = _chunk73L6TROJcjs.gaussianBlur.call(void 0, v, mask.width, mask.height, feather, "clamp");
1298
+ if (feather > 0) v = _chunkT422YCHRcjs.gaussianBlur.call(void 0, v, mask.width, mask.height, feather, "clamp");
1272
1299
  const density = _nullishCoalesce(mask.density, () => ( 1));
1273
1300
  if (density !== 1) for (let i = 0; i < v.length; i++) v[i] = 1 - density * (1 - v[i]);
1274
1301
  return v;
@@ -1489,7 +1516,7 @@ function normalizeAdjustmentLayer(raw) {
1489
1516
  kind: r.kind,
1490
1517
  enabled: r.enabled !== false,
1491
1518
  opacity: clampTo(r.opacity, 0, 1, 1),
1492
- blend: _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, r.blend),
1519
+ blend: _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, r.blend),
1493
1520
  params: normParams(r.kind, r.params)
1494
1521
  };
1495
1522
  if (typeof r.name === "string" && r.name) layer.name = r.name;
@@ -1511,7 +1538,7 @@ function normalizeAdjustmentLayers(raw) {
1511
1538
  return out;
1512
1539
  }
1513
1540
  function curveLutFromLevels(points) {
1514
- return _chunk73L6TROJcjs.curveLut.call(void 0, points.map((p) => ({ input: p.input / 255, output: p.output / 255 })));
1541
+ return _chunkT422YCHRcjs.curveLut.call(void 0, points.map((p) => ({ input: p.input / 255, output: p.output / 255 })));
1515
1542
  }
1516
1543
  var toUnitLevels = (c) => ({
1517
1544
  inBlack: c.inBlack / 255,
@@ -1834,7 +1861,7 @@ function compileAdjustmentLayer(layer) {
1834
1861
  return (c) => {
1835
1862
  const g = blackWhiteGray(c, weights);
1836
1863
  if (tint) {
1837
- const t = _chunkZOOEX3WTcjs.setLum.call(void 0, tint, g);
1864
+ const t = _chunkCRMAXIUVcjs.setLum.call(void 0, tint, g);
1838
1865
  c[0] = clamp01(t[0]);
1839
1866
  c[1] = clamp01(t[1]);
1840
1867
  c[2] = clamp01(t[2]);
@@ -1853,7 +1880,7 @@ function compileAdjustmentLayer(layer) {
1853
1880
  let f = [0, 1, 2].map((r) => linearToSrgb(Math.max(0, m[r][0] * l[0] + m[r][1] * l[1] + m[r][2] * l[2])));
1854
1881
  if (preserve) {
1855
1882
  const target = 0.3 * c[0] + 0.59 * c[1] + 0.11 * c[2];
1856
- f = _chunkZOOEX3WTcjs.setLum.call(void 0, f, target);
1883
+ f = _chunkCRMAXIUVcjs.setLum.call(void 0, f, target);
1857
1884
  }
1858
1885
  c[0] = clamp01(f[0]);
1859
1886
  c[1] = clamp01(f[1]);
@@ -1919,7 +1946,11 @@ function applyLayer(c, layer, op, coverage = 1) {
1919
1946
  }
1920
1947
  const cb0 = c[0], cb1 = c[1], cb2 = c[2];
1921
1948
  op(c);
1922
- const b = blend === "normal" ? c : _chunkZOOEX3WTcjs.blendRgb.call(void 0, blend, [cb0, cb1, cb2], c);
1949
+ if (blend === "pigment") {
1950
+ _chunkCRMAXIUVcjs.mixPigmentRgb.call(void 0, [clamp01(cb0), clamp01(cb1), clamp01(cb2)], [clamp01(c[0]), clamp01(c[1]), clamp01(c[2])], alpha, c);
1951
+ return;
1952
+ }
1953
+ const b = blend === "normal" ? c : _chunkCRMAXIUVcjs.blendRgb.call(void 0, blend, [cb0, cb1, cb2], c);
1923
1954
  c[0] = (1 - alpha) * cb0 + alpha * b[0];
1924
1955
  c[1] = (1 - alpha) * cb1 + alpha * b[1];
1925
1956
  c[2] = (1 - alpha) * cb2 + alpha * b[2];
@@ -2333,7 +2364,7 @@ function newLayerId(prefix = "layer") {
2333
2364
  return `${prefix}_${Date.now().toString(36)}_${(++idCounter).toString(36)}`;
2334
2365
  }
2335
2366
  function pixelLayers(layers) {
2336
- return _chunk73L6TROJcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
2367
+ return _chunkT422YCHRcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
2337
2368
  }
2338
2369
  function developFilter(layer) {
2339
2370
  return _optionalChain([layer, 'access', _8 => _8.filters, 'optionalAccess', _9 => _9.find, 'call', _10 => _10((f) => f.kind === "develop")]);
@@ -2413,10 +2444,10 @@ function depthMaskAlpha(depth, options) {
2413
2444
  }
2414
2445
  var filterSpecCache = /* @__PURE__ */ new WeakMap();
2415
2446
  function pixelFilterSpec(layer) {
2416
- const list = layer.filters;
2417
- if (!_optionalChain([list, 'optionalAccess', _14 => _14.length])) return null;
2418
- if (filterSpecCache.has(list)) return filterSpecCache.get(list);
2419
- const filters = list.filter(isActiveFilter);
2447
+ const list2 = layer.filters;
2448
+ if (!_optionalChain([list2, 'optionalAccess', _14 => _14.length])) return null;
2449
+ if (filterSpecCache.has(list2)) return filterSpecCache.get(list2);
2450
+ const filters = list2.filter(isActiveFilter);
2420
2451
  let spec = null;
2421
2452
  if (filters.length) {
2422
2453
  const spatial = filters.some(isSpatialFilter);
@@ -2431,7 +2462,7 @@ function pixelFilterSpec(layer) {
2431
2462
  }
2432
2463
  };
2433
2464
  }
2434
- filterSpecCache.set(list, spec);
2465
+ filterSpecCache.set(list2, spec);
2435
2466
  return spec;
2436
2467
  }
2437
2468
  var PHOTO_PROFILE = {
@@ -2454,7 +2485,7 @@ var PHOTO_PROFILE = {
2454
2485
  return v;
2455
2486
  }
2456
2487
  };
2457
- var LayerCompositor = class extends _chunk73L6TROJcjs.RasterCompositor {
2488
+ var LayerCompositor = class extends _chunkT422YCHRcjs.RasterCompositor {
2458
2489
  constructor(options = {}) {
2459
2490
  super(PHOTO_PROFILE, options);
2460
2491
  }
@@ -2496,7 +2527,7 @@ function rasterMaskFromLegacy(mask, width, height) {
2496
2527
  const sel = decodeLayerMask(mask);
2497
2528
  if (!sel) return null;
2498
2529
  const sized = sel.width === width && sel.height === height ? sel : resizeSelection(sel, width, height);
2499
- const surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0);
2530
+ const surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0);
2500
2531
  legacyMaskMemo.set(surface, { width: mask.width, height: mask.height, rle: mask.rle });
2501
2532
  const out = { surface, defaultValue: 0 };
2502
2533
  if (mask.density !== void 0 && mask.density !== 1) out.density = mask.density;
@@ -2515,7 +2546,7 @@ function hasResampledLegacyMask(layers, width, height) {
2515
2546
  function legacyMaskOf(mask, width, height) {
2516
2547
  let memo = legacyMaskMemo.get(mask.surface);
2517
2548
  if (!memo) {
2518
- const data = _chunkZOOEX3WTcjs.readRegion.call(void 0, mask.surface, { x: 0, y: 0, width, height });
2549
+ const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, mask.surface, { x: 0, y: 0, width, height });
2519
2550
  memo = { width, height, rle: encodeSelectionRle(new Uint8Array(data.buffer, data.byteOffset, data.length)) };
2520
2551
  legacyMaskMemo.set(mask.surface, memo);
2521
2552
  }
@@ -2596,7 +2627,7 @@ function backgroundLayer(filters = [], mask) {
2596
2627
  visible: true,
2597
2628
  opacity: 1,
2598
2629
  blend: "normal",
2599
- surface: _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4),
2630
+ surface: _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4),
2600
2631
  offset: { x: 0, y: 0 },
2601
2632
  source: "document",
2602
2633
  filters
@@ -2606,7 +2637,7 @@ function backgroundLayer(filters = [], mask) {
2606
2637
  }
2607
2638
  function depthRasterMask(source) {
2608
2639
  const out = {
2609
- surface: _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, 255),
2640
+ surface: _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, 255),
2610
2641
  defaultValue: 255,
2611
2642
  source: { ...source, depthRange: [...source.depthRange] }
2612
2643
  };
@@ -2648,8 +2679,8 @@ function legacyAdjustmentLayer(node, width, height) {
2648
2679
  }
2649
2680
  function developTarget(layers, activeLayerId) {
2650
2681
  const pixels = [];
2651
- const walk = (list) => {
2652
- for (const l of list) {
2682
+ const walk = (list2) => {
2683
+ for (const l of list2) {
2653
2684
  if (l.type === "pixel") pixels.push(l);
2654
2685
  else if (l.type === "group") walk(l.children);
2655
2686
  }
@@ -2683,8 +2714,8 @@ function legacyView(stack, width, height, activeLayerId = null) {
2683
2714
  };
2684
2715
  const adjNodes = [];
2685
2716
  const annotations = [];
2686
- const walk = (list) => {
2687
- for (const l of list) {
2717
+ const walk = (list2) => {
2718
+ for (const l of list2) {
2688
2719
  if (l.type === "adjustment") adjNodes.push(l);
2689
2720
  else if (l.type === "annotation") annotations.push(l.annotation);
2690
2721
  else if (l.type === "group") walk(l.children);
@@ -3231,7 +3262,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3231
3262
  /** Loads what the compositor reads synchronously: depth maps (at canvas size) and annotation images. */
3232
3263
  /** Loads depth maps and annotation images the compositor reads synchronously. */
3233
3264
  async prepareLayerAssets(layers, width, height) {
3234
- for (const l of _chunk73L6TROJcjs.flattenLayers.call(void 0, layers)) {
3265
+ for (const l of _chunkT422YCHRcjs.flattenLayers.call(void 0, layers)) {
3235
3266
  const source = _optionalChain([l, 'access', _57 => _57.mask, 'optionalAccess', _58 => _58.source]);
3236
3267
  if (_optionalChain([source, 'optionalAccess', _59 => _59.enabled]) && source.maskSource) {
3237
3268
  const key = `${source.maskSource}|${width}x${height}`;
@@ -3285,14 +3316,14 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3285
3316
  }
3286
3317
  }
3287
3318
  putTile(ctx, data, tx, ty, rect) {
3288
- const ox = tx * _chunkZOOEX3WTcjs.TILE - rect.x;
3289
- const oy = ty * _chunkZOOEX3WTcjs.TILE - rect.y;
3319
+ const ox = tx * _chunkCRMAXIUVcjs.TILE - rect.x;
3320
+ const oy = ty * _chunkCRMAXIUVcjs.TILE - rect.y;
3290
3321
  const x0 = Math.max(0, -ox);
3291
3322
  const y0 = Math.max(0, -oy);
3292
- const x1 = Math.min(_chunkZOOEX3WTcjs.TILE, rect.width - ox);
3293
- const y1 = Math.min(_chunkZOOEX3WTcjs.TILE, rect.height - oy);
3323
+ const x1 = Math.min(_chunkCRMAXIUVcjs.TILE, rect.width - ox);
3324
+ const y1 = Math.min(_chunkCRMAXIUVcjs.TILE, rect.height - oy);
3294
3325
  if (x1 <= x0 || y1 <= y0) return;
3295
- const img = ctx.createImageData(_chunkZOOEX3WTcjs.TILE, _chunkZOOEX3WTcjs.TILE);
3326
+ const img = ctx.createImageData(_chunkCRMAXIUVcjs.TILE, _chunkCRMAXIUVcjs.TILE);
3296
3327
  img.data.set(data);
3297
3328
  ctx.putImageData(img, ox, oy, x0, y0, x1 - x0, y1 - y0);
3298
3329
  }
@@ -3313,7 +3344,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3313
3344
  if (!ctx || typeof ctx.createImageData !== "function") return null;
3314
3345
  let changed = false;
3315
3346
  this.compositor.compositeTiles(layers, rect, this.compositorSources(width, height), (tx, ty, data) => {
3316
- const key = _chunkZOOEX3WTcjs.tileKey.call(void 0, tx, ty);
3347
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty);
3317
3348
  if (comp.tiles.get(key) === data) return;
3318
3349
  comp.tiles.set(key, data);
3319
3350
  comp.histograms.delete(key);
@@ -3438,12 +3469,12 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3438
3469
  * Draws an individual annotation onto the canvas.
3439
3470
  */
3440
3471
  async drawAnnotation(ctx, ann) {
3441
- const blend = _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, ann.blend);
3472
+ const blend = _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, ann.blend);
3442
3473
  if (blend === "normal") {
3443
3474
  await this.drawAnnotationContent(ctx, ann);
3444
3475
  return;
3445
3476
  }
3446
- const op = _chunkZOOEX3WTcjs.canvasCompositeOperation.call(void 0, blend);
3477
+ const op = _chunkCRMAXIUVcjs.canvasCompositeOperation.call(void 0, blend);
3447
3478
  if (op) {
3448
3479
  ctx.save();
3449
3480
  ctx.globalCompositeOperation = op;
@@ -3476,7 +3507,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3476
3507
  const backdrop = ctx.getImageData(0, 0, w, h);
3477
3508
  const source = lctx.getImageData(0, 0, w, h);
3478
3509
  if (!backdrop || !source) return false;
3479
- _chunkZOOEX3WTcjs.blendImageData.call(void 0, backdrop, source, _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, ann.blend));
3510
+ _chunkCRMAXIUVcjs.blendImageData.call(void 0, backdrop, source, _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, ann.blend));
3480
3511
  lctx.setTransform(1, 0, 0, 1, 0, 0);
3481
3512
  lctx.putImageData(backdrop, 0, 0);
3482
3513
  } catch (e10) {
@@ -3901,12 +3932,12 @@ var CompositeCanvas = (_class3 = class {
3901
3932
  if (!h) {
3902
3933
  const tx = key % 65536 - 32768;
3903
3934
  const ty = Math.floor(key / 65536) - 32768;
3904
- const x0 = Math.max(r.x, tx * _chunkZOOEX3WTcjs.TILE);
3905
- const y0 = Math.max(r.y, ty * _chunkZOOEX3WTcjs.TILE);
3906
- const x1 = Math.min(r.x + r.width, tx * _chunkZOOEX3WTcjs.TILE + _chunkZOOEX3WTcjs.TILE);
3907
- const y1 = Math.min(r.y + r.height, ty * _chunkZOOEX3WTcjs.TILE + _chunkZOOEX3WTcjs.TILE);
3935
+ const x0 = Math.max(r.x, tx * _chunkCRMAXIUVcjs.TILE);
3936
+ const y0 = Math.max(r.y, ty * _chunkCRMAXIUVcjs.TILE);
3937
+ const x1 = Math.min(r.x + r.width, tx * _chunkCRMAXIUVcjs.TILE + _chunkCRMAXIUVcjs.TILE);
3938
+ const y1 = Math.min(r.y + r.height, ty * _chunkCRMAXIUVcjs.TILE + _chunkCRMAXIUVcjs.TILE);
3908
3939
  h = emptyHistogram();
3909
- if (x1 > x0 && y1 > y0) addToHistogram(h, data, _chunkZOOEX3WTcjs.TILE, { x: x0 - tx * _chunkZOOEX3WTcjs.TILE, y: y0 - ty * _chunkZOOEX3WTcjs.TILE, width: x1 - x0, height: y1 - y0 });
3940
+ if (x1 > x0 && y1 > y0) addToHistogram(h, data, _chunkCRMAXIUVcjs.TILE, { x: x0 - tx * _chunkCRMAXIUVcjs.TILE, y: y0 - ty * _chunkCRMAXIUVcjs.TILE, width: x1 - x0, height: y1 - y0 });
3910
3941
  this.histograms.set(key, h);
3911
3942
  }
3912
3943
  parts.push(h);
@@ -4414,11 +4445,11 @@ function refineCoverage(guide, m, w, h, params = {}) {
4414
4445
  }
4415
4446
  const ss = smoothSigma(p);
4416
4447
  if (ss >= 0.3) {
4417
- a = _chunk73L6TROJcjs.gaussianBlur.call(void 0, a, w, h, ss, "clamp");
4448
+ a = _chunkT422YCHRcjs.gaussianBlur.call(void 0, a, w, h, ss, "clamp");
4418
4449
  const gain = 1 + ss;
4419
4450
  for (let i = 0; i < a.length; i++) a[i] = Math.min(1, Math.max(0, (a[i] - 0.5) * gain + 0.5));
4420
4451
  }
4421
- a = _chunk73L6TROJcjs.gaussianBlur.call(void 0, a, w, h, featherSigma(p), "clamp");
4452
+ a = _chunkT422YCHRcjs.gaussianBlur.call(void 0, a, w, h, featherSigma(p), "clamp");
4422
4453
  if (p.contrast > 0) {
4423
4454
  const gain = 1 / (1 - 0.99 * p.contrast / 100);
4424
4455
  for (let i = 0; i < a.length; i++) a[i] = Math.min(1, Math.max(0, (a[i] - 0.5) * gain + 0.5));
@@ -4475,14 +4506,31 @@ function refineSelection(pixels, mask, params = {}) {
4475
4506
 
4476
4507
  // src/image-editor/layers/serialize.ts
4477
4508
  var LAYERED_SCHEMA_VERSION = 3;
4509
+ function serializePatterns(patterns) {
4510
+ return patterns.map((p) => ({ id: p.id, name: p.name, png: _chunkT422YCHRcjs.pngDataUrl.call(void 0, p.width, p.height, p.data) }));
4511
+ }
4512
+ function deserializePatterns(raw, problems = []) {
4513
+ if (!Array.isArray(raw)) return [];
4514
+ const out = [];
4515
+ for (const p of raw) {
4516
+ if (!p || typeof p !== "object" || typeof p.id !== "string" || typeof p.png !== "string") continue;
4517
+ try {
4518
+ const png = decodePngDataUrl(p.png, 4);
4519
+ out.push({ id: p.id, name: typeof p.name === "string" ? p.name : p.id, width: png.width, height: png.height, data: png.data });
4520
+ } catch (e) {
4521
+ problems.push(`Pattern "${_nullishCoalesce(p.name, () => ( p.id))}" could not be decoded (${e instanceof Error ? e.message : String(e)}).`);
4522
+ }
4523
+ }
4524
+ return out;
4525
+ }
4478
4526
  var encodedCache = /* @__PURE__ */ new WeakMap();
4479
4527
  function encodeSurface(surface) {
4480
4528
  if (encodedCache.has(surface)) return encodedCache.get(surface);
4481
- const b = _chunkZOOEX3WTcjs.contentBounds.call(void 0, surface);
4529
+ const b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, surface);
4482
4530
  let out = null;
4483
4531
  if (b) {
4484
- const data = _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, b);
4485
- out = { url: _chunk73L6TROJcjs.pngDataUrl.call(void 0, b.width, b.height, data, surface.channels), x: b.x, y: b.y };
4532
+ const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, b);
4533
+ out = { url: _chunkT422YCHRcjs.pngDataUrl.call(void 0, b.width, b.height, data, surface.channels), x: b.x, y: b.y };
4486
4534
  }
4487
4535
  encodedCache.set(surface, out);
4488
4536
  return out;
@@ -4504,7 +4552,7 @@ function baseFields(layer, ctx) {
4504
4552
  function serializeEffects(effects) {
4505
4553
  const out = { enabled: effects.enabled, items: JSON.parse(JSON.stringify(effects.items)) };
4506
4554
  if (effects.scale !== void 0 && effects.scale !== 1) out.scale = effects.scale;
4507
- if (effects.psd) out.psd = { key: effects.psd.key, data: _chunk73L6TROJcjs.bytesToBase64.call(void 0, effects.psd.data) };
4555
+ if (effects.psd) out.psd = { key: effects.psd.key, data: _chunkT422YCHRcjs.bytesToBase64.call(void 0, effects.psd.data) };
4508
4556
  return out;
4509
4557
  }
4510
4558
  function deserializeEffects(raw) {
@@ -4514,12 +4562,12 @@ function deserializeEffects(raw) {
4514
4562
  const p = r.psd;
4515
4563
  if (p && typeof p.key === "string" && typeof p.data === "string") {
4516
4564
  try {
4517
- psd = { key: p.key, data: _chunk73L6TROJcjs.base64ToBytes.call(void 0, p.data) };
4565
+ psd = { key: p.key, data: _chunkT422YCHRcjs.base64ToBytes.call(void 0, p.data) };
4518
4566
  } catch (e12) {
4519
4567
  psd = void 0;
4520
4568
  }
4521
4569
  }
4522
- return _chunk73L6TROJcjs.normalizeLayerEffects.call(void 0, { ...r, psd });
4570
+ return _chunkT422YCHRcjs.normalizeLayerEffects.call(void 0, { ...r, psd });
4523
4571
  }
4524
4572
  function serializeMask(mask, hint, ctx) {
4525
4573
  const out = { defaultValue: mask.defaultValue };
@@ -4591,7 +4639,7 @@ async function serializeLayersExternal(layers, store) {
4591
4639
  for (const [id, url] of Object.entries(inline.assets)) {
4592
4640
  let ref = refs.get(url);
4593
4641
  if (!ref) {
4594
- const parsed = _chunk73L6TROJcjs.parseDataUrl.call(void 0, url);
4642
+ const parsed = _chunkT422YCHRcjs.parseDataUrl.call(void 0, url);
4595
4643
  const png = decodePngHeader(parsed.bytes);
4596
4644
  ref = await store.put(new Blob([parsed.bytes], { type: "image/png" }), { id, width: png.width, height: png.height });
4597
4645
  if (typeof ref !== "string" || !ref) throw new Error(`The asset store returned no reference for "${id}".`);
@@ -4619,7 +4667,7 @@ async function resolveExternalAssets(assets, store, problems) {
4619
4667
  try {
4620
4668
  const blob = await store.get(ref);
4621
4669
  const bytes = new Uint8Array(await blob.arrayBuffer());
4622
- out[id] = `data:image/png;base64,${_chunk73L6TROJcjs.bytesToBase64.call(void 0, bytes)}`;
4670
+ out[id] = `data:image/png;base64,${_chunkT422YCHRcjs.bytesToBase64.call(void 0, bytes)}`;
4623
4671
  } catch (err) {
4624
4672
  problems.push(`Asset "${id}" (${ref}) could not be fetched: ${err.message}`);
4625
4673
  }
@@ -4627,9 +4675,9 @@ async function resolveExternalAssets(assets, store, problems) {
4627
4675
  return out;
4628
4676
  }
4629
4677
  function decodePngDataUrl(url, channels) {
4630
- const parsed = _chunk73L6TROJcjs.parseDataUrl.call(void 0, url);
4678
+ const parsed = _chunkT422YCHRcjs.parseDataUrl.call(void 0, url);
4631
4679
  if (!parsed) throw new Error("Asset is not a data URL.");
4632
- const png = _chunk73L6TROJcjs.decodePng.call(void 0, parsed.bytes, { keepGray: channels === 1 });
4680
+ const png = _chunkT422YCHRcjs.decodePng.call(void 0, parsed.bytes, { keepGray: channels === 1 });
4633
4681
  if (png.channels === channels) return png;
4634
4682
  if (channels === 1) {
4635
4683
  const out2 = new Uint8ClampedArray(png.width * png.height);
@@ -4647,18 +4695,18 @@ function decodePngDataUrl(url, channels) {
4647
4695
  }
4648
4696
  var num = (v, lo, hi, fallback) => typeof v === "number" && Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : fallback;
4649
4697
  function readSurface(ref, x, y, channels, defaultValue, ctx, what) {
4650
- if (typeof ref !== "string" || !ref) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, channels, defaultValue);
4698
+ if (typeof ref !== "string" || !ref) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, channels, defaultValue);
4651
4699
  const url = ctx.assets[ref];
4652
4700
  if (typeof url !== "string") {
4653
4701
  ctx.problems.push(`${what}: asset "${ref}" is missing`);
4654
- return _chunkZOOEX3WTcjs.emptySurface.call(void 0, channels, defaultValue);
4702
+ return _chunkCRMAXIUVcjs.emptySurface.call(void 0, channels, defaultValue);
4655
4703
  }
4656
4704
  try {
4657
4705
  const px = (_nullishCoalesce(ctx.decodeAsset, () => ( decodePngDataUrl)))(url, channels);
4658
- return _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, px, channels, Math.round(num(x, -1e7, 1e7, 0)), Math.round(num(y, -1e7, 1e7, 0)), defaultValue);
4706
+ return _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, px, channels, Math.round(num(x, -1e7, 1e7, 0)), Math.round(num(y, -1e7, 1e7, 0)), defaultValue);
4659
4707
  } catch (err) {
4660
4708
  ctx.problems.push(`${what}: asset "${ref}" could not be decoded (${err.message})`);
4661
- return _chunkZOOEX3WTcjs.emptySurface.call(void 0, channels, defaultValue);
4709
+ return _chunkCRMAXIUVcjs.emptySurface.call(void 0, channels, defaultValue);
4662
4710
  }
4663
4711
  }
4664
4712
  function readMask(raw, ctx, what) {
@@ -4666,7 +4714,7 @@ function readMask(raw, ctx, what) {
4666
4714
  const r = raw;
4667
4715
  const defaultValue = r.defaultValue === 255 ? 255 : 0;
4668
4716
  const mask = {
4669
- surface: r.source ? _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, 255) : readSurface(r.asset, r.x, r.y, 1, defaultValue, ctx, `${what} mask`),
4717
+ surface: r.source ? _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, 255) : readSurface(r.asset, r.x, r.y, 1, defaultValue, ctx, `${what} mask`),
4670
4718
  defaultValue: r.source ? 255 : defaultValue
4671
4719
  };
4672
4720
  if (typeof r.density === "number" && r.density !== 1) mask.density = num(r.density, 0, 1, 1);
@@ -4713,7 +4761,7 @@ function deserializeLayer(raw, ctx) {
4713
4761
  name: typeof r.name === "string" ? r.name : "",
4714
4762
  visible: r.visible !== false,
4715
4763
  opacity: num(r.opacity, 0, 1, 1),
4716
- blend: _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, r.blend)
4764
+ blend: _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, r.blend)
4717
4765
  };
4718
4766
  if (r.clipped === true) base.clipped = true;
4719
4767
  const mask = readMask(r.mask, ctx, `Layer "${base.name || id}"`);
@@ -4730,7 +4778,7 @@ function deserializeLayer(raw, ctx) {
4730
4778
  const layer = {
4731
4779
  ...base,
4732
4780
  type: "pixel",
4733
- surface: r.source === "document" ? _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4) : readSurface(r.asset, r.x, r.y, 4, 0, ctx, `Layer "${base.name || id}"`),
4781
+ surface: r.source === "document" ? _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4) : readSurface(r.asset, r.x, r.y, 4, 0, ctx, `Layer "${base.name || id}"`),
4734
4782
  offset: { x: Math.round(num(_optionalChain([r, 'access', _75 => _75.offset, 'optionalAccess', _76 => _76.x]), -1e7, 1e7, 0)), y: Math.round(num(_optionalChain([r, 'access', _77 => _77.offset, 'optionalAccess', _78 => _78.y]), -1e7, 1e7, 0)) }
4735
4783
  };
4736
4784
  if (r.source === "document") layer.source = "document";
@@ -4749,7 +4797,7 @@ function deserializeLayer(raw, ctx) {
4749
4797
  }
4750
4798
  case "group": {
4751
4799
  const children = Array.isArray(r.children) ? r.children.map((c) => deserializeLayer(c, ctx)).filter(Boolean) : [];
4752
- const blend = r.blend === "pass-through" ? "pass-through" : _chunkZOOEX3WTcjs.isBlendMode.call(void 0, r.blend) ? r.blend : "pass-through";
4800
+ const blend = r.blend === "pass-through" ? "pass-through" : _chunkCRMAXIUVcjs.isBlendMode.call(void 0, r.blend) ? r.blend : "pass-through";
4753
4801
  const group = { ...base, type: "group", blend, children };
4754
4802
  if (r.collapsed === true) group.collapsed = true;
4755
4803
  return group;
@@ -4770,7 +4818,7 @@ function deserializeLayer(raw, ctx) {
4770
4818
  function deserializeLayers(raw, ctx) {
4771
4819
  if (!Array.isArray(raw)) return [];
4772
4820
  const seen = /* @__PURE__ */ new Set();
4773
- const dedupe = (list) => list.map((l) => {
4821
+ const dedupe = (list2) => list2.map((l) => {
4774
4822
  let next = l;
4775
4823
  if (seen.has(l.id)) next = { ...l, id: newLayerId() };
4776
4824
  seen.add(next.id);
@@ -4791,47 +4839,47 @@ var fail = (message) => {
4791
4839
  throw new LayerOperationError(message);
4792
4840
  };
4793
4841
  function requireLayer(layers, id) {
4794
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, layers, id);
4842
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, layers, id);
4795
4843
  if (!loc) {
4796
- const ids = _chunk73L6TROJcjs.flattenLayers.call(void 0, layers).map((l) => l.id);
4844
+ const ids = _chunkT422YCHRcjs.flattenLayers.call(void 0, layers).map((l) => l.id);
4797
4845
  fail(`Unknown layer "${id}". ${ids.length ? `Layers: ${ids.join(", ")}.` : "The document has no layers."} Call list_layers for ids.`);
4798
4846
  }
4799
4847
  return loc;
4800
4848
  }
4801
4849
  function requireUnlocked(layer, what, action) {
4802
- if (_chunk73L6TROJcjs.isLayerLocked.call(void 0, layer, "all")) fail(`Layer "${layer.name || layer.id}" is locked (all); unlock it before you ${action}.`);
4803
- if (what !== "all" && _chunk73L6TROJcjs.isLayerLocked.call(void 0, layer, what)) fail(`Layer "${layer.name || layer.id}" has its ${what} locked; unlock it before you ${action}.`);
4850
+ if (_chunkT422YCHRcjs.isLayerLocked.call(void 0, layer, "all")) fail(`Layer "${layer.name || layer.id}" is locked (all); unlock it before you ${action}.`);
4851
+ if (what !== "all" && _chunkT422YCHRcjs.isLayerLocked.call(void 0, layer, what)) fail(`Layer "${layer.name || layer.id}" has its ${what} locked; unlock it before you ${action}.`);
4804
4852
  }
4805
4853
  function placeLayer(layers, layer, placement = {}, defaultIndex) {
4806
4854
  const given = [placement.aboveId, placement.belowId, placement.parentId].filter((v) => v !== void 0).length;
4807
4855
  if (given > 1) fail("Give only one of aboveId, belowId and parentId.");
4808
4856
  if (placement.aboveId || placement.belowId) {
4809
4857
  const ref = requireLayer(layers, _nullishCoalesce(placement.aboveId, () => ( placement.belowId)));
4810
- return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, layer, _nullishCoalesce(_optionalChain([ref, 'access', _79 => _79.parent, 'optionalAccess', _80 => _80.id]), () => ( null)), ref.index + (placement.aboveId ? 1 : 0));
4858
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, layer, _nullishCoalesce(_optionalChain([ref, 'access', _79 => _79.parent, 'optionalAccess', _80 => _80.id]), () => ( null)), ref.index + (placement.aboveId ? 1 : 0));
4811
4859
  }
4812
4860
  if (placement.parentId) {
4813
4861
  const ref = requireLayer(layers, placement.parentId);
4814
4862
  if (ref.layer.type !== "group") fail(`Layer "${placement.parentId}" is not a group; parentId must be a group id.`);
4815
- return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, layer, ref.layer.id, placement.index);
4863
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, layer, ref.layer.id, placement.index);
4816
4864
  }
4817
- return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, layer, null, _nullishCoalesce(placement.index, () => ( defaultIndex)));
4865
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, layer, null, _nullishCoalesce(placement.index, () => ( defaultIndex)));
4818
4866
  }
4819
4867
  function removeLayer(layers, id) {
4820
4868
  const loc = requireLayer(layers, id);
4821
4869
  requireUnlocked(loc.layer, "all", "delete it");
4822
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => null);
4870
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => null);
4823
4871
  }
4824
4872
  function moveLayer(layers, id, placement) {
4825
4873
  const loc = requireLayer(layers, id);
4826
4874
  requireUnlocked(loc.layer, "all", "move it");
4827
4875
  const target = _nullishCoalesce(_nullishCoalesce(placement.aboveId, () => ( placement.belowId)), () => ( placement.parentId));
4828
4876
  if (target === id) fail("A layer cannot be placed relative to itself.");
4829
- if (target && loc.layer.type === "group" && _chunk73L6TROJcjs.flattenLayers.call(void 0, loc.layer.children).some((l) => l.id === target)) {
4877
+ if (target && loc.layer.type === "group" && _chunkT422YCHRcjs.flattenLayers.call(void 0, loc.layer.children).some((l) => l.id === target)) {
4830
4878
  fail(`Group "${id}" cannot be moved into its own child "${target}".`);
4831
4879
  }
4832
4880
  if (target) requireLayer(layers, target);
4833
4881
  if (!target && placement.index === void 0) fail("Give aboveId, belowId, parentId or index.");
4834
- const without = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => null);
4882
+ const without = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => null);
4835
4883
  return placeLayer(without, loc.layer, placement);
4836
4884
  }
4837
4885
  function withNewIds(layer) {
@@ -4845,7 +4893,7 @@ function duplicateLayer(layers, id, name) {
4845
4893
  const copy = withNewIds(loc.layer);
4846
4894
  copy.name = _nullishCoalesce(name, () => ( `${loc.layer.name || "Layer"} copy`));
4847
4895
  delete copy.locks;
4848
- return { layers: _chunk73L6TROJcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _81 => _81.parent, 'optionalAccess', _82 => _82.id]), () => ( null)), loc.index + 1), id: copy.id };
4896
+ return { layers: _chunkT422YCHRcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _81 => _81.parent, 'optionalAccess', _82 => _82.id]), () => ( null)), loc.index + 1), id: copy.id };
4849
4897
  }
4850
4898
  function setLayerProperties(layers, id, props) {
4851
4899
  const loc = requireLayer(layers, id);
@@ -4872,7 +4920,7 @@ function setLayerProperties(layers, id, props) {
4872
4920
  if (props.blend !== void 0) {
4873
4921
  if (props.blend === "pass-through") {
4874
4922
  if (layer.type !== "group") fail("pass-through is only for groups.");
4875
- } else if (!_chunkZOOEX3WTcjs.isBlendMode.call(void 0, props.blend)) fail(`Unknown blend mode "${props.blend}".`);
4923
+ } else if (!_chunkCRMAXIUVcjs.isBlendMode.call(void 0, props.blend)) fail(`Unknown blend mode "${props.blend}".`);
4876
4924
  next.blend = props.blend;
4877
4925
  }
4878
4926
  if (props.clipped !== void 0) {
@@ -4892,7 +4940,7 @@ function setLayerProperties(layers, id, props) {
4892
4940
  if (props.collapsed) g.collapsed = true;
4893
4941
  else delete g.collapsed;
4894
4942
  }
4895
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => next);
4943
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => next);
4896
4944
  }
4897
4945
  function groupLayers(layers, ids, name = "Group") {
4898
4946
  if (!ids.length) fail("Give at least one layer id to group.");
@@ -4921,17 +4969,17 @@ function groupLayers(layers, ids, name = "Group") {
4921
4969
  group.children[0] = c;
4922
4970
  }
4923
4971
  let out = layers;
4924
- for (const l of ordered) out = _chunk73L6TROJcjs.mapLayer.call(void 0, out, l.layer.id, () => null);
4925
- return { layers: _chunk73L6TROJcjs.insertLayer.call(void 0, out, group, parent, top - below), id: group.id };
4972
+ for (const l of ordered) out = _chunkT422YCHRcjs.mapLayer.call(void 0, out, l.layer.id, () => null);
4973
+ return { layers: _chunkT422YCHRcjs.insertLayer.call(void 0, out, group, parent, top - below), id: group.id };
4926
4974
  }
4927
4975
  function ungroupLayer(layers, id) {
4928
4976
  const loc = requireLayer(layers, id);
4929
4977
  if (loc.layer.type !== "group") fail(`Layer "${id}" is not a group.`);
4930
4978
  requireUnlocked(loc.layer, "all", "ungroup it");
4931
4979
  const group = loc.layer;
4932
- let out = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => null);
4980
+ let out = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => null);
4933
4981
  group.children.forEach((c, i) => {
4934
- out = _chunk73L6TROJcjs.insertLayer.call(void 0, out, c, _nullishCoalesce(_optionalChain([loc, 'access', _91 => _91.parent, 'optionalAccess', _92 => _92.id]), () => ( null)), loc.index + i);
4982
+ out = _chunkT422YCHRcjs.insertLayer.call(void 0, out, c, _nullishCoalesce(_optionalChain([loc, 'access', _91 => _91.parent, 'optionalAccess', _92 => _92.id]), () => ( null)), loc.index + i);
4935
4983
  });
4936
4984
  return { layers: out, ids: group.children.map((c) => c.id) };
4937
4985
  }
@@ -4941,12 +4989,12 @@ function offsetLayer(layers, id, offset) {
4941
4989
  requireUnlocked(loc.layer, "position", "move it");
4942
4990
  if (!Number.isFinite(offset.x) || !Number.isFinite(offset.y)) fail("x and y must be numbers.");
4943
4991
  const layer = loc.layer;
4944
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, offset: { x: Math.round(offset.x), y: Math.round(offset.y) } }));
4992
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, offset: { x: Math.round(offset.x), y: Math.round(offset.y) } }));
4945
4993
  }
4946
4994
  function setLayerMask(layers, id, mask) {
4947
4995
  const loc = requireLayer(layers, id);
4948
4996
  requireUnlocked(loc.layer, "all", "change its mask");
4949
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, (l) => {
4997
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, (l) => {
4950
4998
  const next = { ...l };
4951
4999
  if (mask) next.mask = mask;
4952
5000
  else delete next.mask;
@@ -4985,7 +5033,7 @@ function requirePixelLayer(layers, id) {
4985
5033
  function addLayerFilter(layers, id, filter) {
4986
5034
  const layer = requirePixelLayer(layers, id);
4987
5035
  if (_optionalChain([layer, 'access', _93 => _93.filters, 'optionalAccess', _94 => _94.some, 'call', _95 => _95((f) => f.kind === filter.kind)])) fail(`Layer "${id}" already has a ${filter.kind} filter; change it with update_layer_filter.`);
4988
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters: [..._nullishCoalesce(layer.filters, () => ( [])), filter] }));
5036
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters: [..._nullishCoalesce(layer.filters, () => ( [])), filter] }));
4989
5037
  }
4990
5038
  function updateLayerFilter(layers, id, filterId, changes) {
4991
5039
  const layer = requirePixelLayer(layers, id);
@@ -4996,7 +5044,7 @@ function updateLayerFilter(layers, id, filterId, changes) {
4996
5044
  const merged = normalizeFilter({ ...current, ...changes, kind: current.kind }, current.id);
4997
5045
  const filters = [...layer.filters];
4998
5046
  filters[i] = merged;
4999
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters }));
5047
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters }));
5000
5048
  }
5001
5049
  function removeLayerFilter(layers, id, filterId) {
5002
5050
  const layer = requirePixelLayer(layers, id);
@@ -5005,7 +5053,7 @@ function removeLayerFilter(layers, id, filterId) {
5005
5053
  const next = { ...layer };
5006
5054
  if (filters.length) next.filters = filters;
5007
5055
  else delete next.filters;
5008
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => next);
5056
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => next);
5009
5057
  }
5010
5058
  function requireEffectLayer(layers, id, action) {
5011
5059
  const layer = requireLayer(layers, id).layer;
@@ -5020,7 +5068,7 @@ function guard(fn) {
5020
5068
  try {
5021
5069
  return fn();
5022
5070
  } catch (e) {
5023
- if (e instanceof _chunk73L6TROJcjs.LayerEffectError) fail(e.message);
5071
+ if (e instanceof _chunkT422YCHRcjs.LayerEffectError) fail(e.message);
5024
5072
  throw e;
5025
5073
  }
5026
5074
  }
@@ -5028,20 +5076,20 @@ function setLayerEffects(layers, id, effects) {
5028
5076
  const layer = requireEffectLayer(layers, id, "change its effects");
5029
5077
  const next = { ...layer };
5030
5078
  if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) {
5031
- guard(() => _chunk73L6TROJcjs.validateLayerEffects.call(void 0, effects));
5079
+ guard(() => _chunkT422YCHRcjs.validateLayerEffects.call(void 0, effects));
5032
5080
  next.effects = effects;
5033
5081
  } else delete next.effects;
5034
- return _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => next);
5082
+ return _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => next);
5035
5083
  }
5036
5084
  function addLayerEffect(layers, id, kind, params = {}, index) {
5037
- if (!_chunk73L6TROJcjs.isLayerEffectKind.call(void 0, kind)) fail(`Unknown effect kind "${String(kind)}". Kinds: ${_chunk73L6TROJcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
5085
+ if (!_chunkT422YCHRcjs.isLayerEffectKind.call(void 0, kind)) fail(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkT422YCHRcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
5038
5086
  const layer = requireEffectLayer(layers, id, "add effects");
5039
5087
  const current = layerEffectsOf(layer);
5040
5088
  const ids = new Set(current.items.map((e) => e.id));
5041
- let effectId = _chunk73L6TROJcjs.newEffectId.call(void 0, );
5042
- while (ids.has(effectId)) effectId = _chunk73L6TROJcjs.newEffectId.call(void 0, );
5089
+ let effectId = _chunkT422YCHRcjs.newEffectId.call(void 0, );
5090
+ while (ids.has(effectId)) effectId = _chunkT422YCHRcjs.newEffectId.call(void 0, );
5043
5091
  const { id: _ignored, kind: _kind, ...rest } = params;
5044
- const effect = guard(() => _chunk73L6TROJcjs.mergeLayerEffect.call(void 0, _chunk73L6TROJcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
5092
+ const effect = guard(() => _chunkT422YCHRcjs.mergeLayerEffect.call(void 0, _chunkT422YCHRcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
5045
5093
  const items = [...current.items];
5046
5094
  const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
5047
5095
  items.splice(at, 0, effect);
@@ -5058,7 +5106,7 @@ function updateLayerEffect(layers, id, effectId, changes) {
5058
5106
  const i = requireEffect(layer, effectId);
5059
5107
  const current = layer.effects;
5060
5108
  const items = [...current.items];
5061
- items[i] = guard(() => _chunk73L6TROJcjs.mergeLayerEffect.call(void 0, items[i], changes));
5109
+ items[i] = guard(() => _chunkT422YCHRcjs.mergeLayerEffect.call(void 0, items[i], changes));
5062
5110
  return setLayerEffects(layers, id, { ...current, items });
5063
5111
  }
5064
5112
  function removeLayerEffect(layers, id, effectId) {
@@ -5081,7 +5129,7 @@ function setLayerEffectsEnabled(layers, id, enabled, scale) {
5081
5129
  function parseBlend(value, allowPassThrough = false) {
5082
5130
  if (value === void 0) return void 0;
5083
5131
  if (value === "pass-through" && allowPassThrough) return value;
5084
- if (!_chunkZOOEX3WTcjs.isBlendMode.call(void 0, value)) fail(`Unknown blend mode "${String(value)}".`);
5132
+ if (!_chunkCRMAXIUVcjs.isBlendMode.call(void 0, value)) fail(`Unknown blend mode "${String(value)}".`);
5085
5133
  return value;
5086
5134
  }
5087
5135
  function unionRect(a, b) {
@@ -5172,8 +5220,8 @@ var PsdReader = class _PsdReader {
5172
5220
  return v;
5173
5221
  }
5174
5222
  /** A length field: 8 bytes in PSB where the format says so, else 4. */
5175
- len(long2) {
5176
- return long2 ? this.u64() : this.u32();
5223
+ len(long3) {
5224
+ return long3 ? this.u64() : this.u32();
5177
5225
  }
5178
5226
  bytes(n) {
5179
5227
  this.need(n, `${n} bytes`);
@@ -5280,11 +5328,11 @@ var PsdWriter = (_class4 = class {constructor() { _class4.prototype.__init24.cal
5280
5328
  this.length += n;
5281
5329
  }
5282
5330
  /** Reserves a length field; `endLen` fills it with the bytes written since. */
5283
- beginLen(long2) {
5331
+ beginLen(long3) {
5284
5332
  const at = this.length;
5285
- if (long2) this.u64(0);
5333
+ if (long3) this.u64(0);
5286
5334
  else this.u32(0);
5287
- return { at, long: long2 };
5335
+ return { at, long: long3 };
5288
5336
  }
5289
5337
  endLen(mark) {
5290
5338
  const n = this.length - mark.at - (mark.long ? 8 : 4);
@@ -5444,12 +5492,12 @@ function readValue(r, depth) {
5444
5492
  case "UntF":
5445
5493
  return { type, unit: r.ascii(4), value: r.f64() };
5446
5494
  case "UnFl": {
5447
- const unit = r.ascii(4);
5495
+ const unit2 = r.ascii(4);
5448
5496
  const n = r.u32();
5449
5497
  r.checkCount(n, 8, "Unit float list");
5450
5498
  const values = [];
5451
5499
  for (let i = 0; i < n; i++) values.push(r.f64());
5452
- return { type, unit, values };
5500
+ return { type, unit: unit2, values };
5453
5501
  }
5454
5502
  case "TEXT":
5455
5503
  return { type, value: r.unicode() };
@@ -5902,11 +5950,11 @@ function writeAdjustmentBlock(kind, params) {
5902
5950
  case "blackWhite": {
5903
5951
  const p = params;
5904
5952
  const tint = p.tint ? hexToRgb(p.tint) : BW_TINT;
5905
- const dbl = (v) => ({ type: "doub", value: clamp2(v, 0, 1) * 255 });
5953
+ const dbl2 = (v) => ({ type: "doub", value: clamp2(v, 0, 1) * 255 });
5906
5954
  const items = BW_KEYS.map(([field, key]) => [key, long(clamp2(p[field], -200, 300))]);
5907
5955
  items.push(
5908
5956
  ["useTint", { type: "bool", value: p.tint !== null }],
5909
- ["tintColor", { type: "Objc", value: descriptor("RGBC", [["Rd ", dbl(tint[0])], ["Grn ", dbl(tint[1])], ["Bl ", dbl(tint[2])]]) }],
5957
+ ["tintColor", { type: "Objc", value: descriptor("RGBC", [["Rd ", dbl2(tint[0])], ["Grn ", dbl2(tint[1])], ["Bl ", dbl2(tint[2])]]) }],
5910
5958
  ["bwPresetKind", { type: "long", value: 1 }],
5911
5959
  ["blackAndWhitePresetFileName", { type: "TEXT", value: "" }]
5912
5960
  );
@@ -5993,9 +6041,9 @@ function packbitsDecodeInto(src, expected, out, at) {
5993
6041
  function inflateChecked(data, expected) {
5994
6042
  let out;
5995
6043
  try {
5996
- out = _chunk73L6TROJcjs.inflate.call(void 0, data, { maxOutput: expected + (1 << 20), sizeHint: expected, verify: false });
6044
+ out = _chunkT422YCHRcjs.inflate.call(void 0, data, { maxOutput: expected + (1 << 20), sizeHint: expected, verify: false });
5997
6045
  } catch (e) {
5998
- throw new PsdError(`ZIP channel data: ${e instanceof _chunk73L6TROJcjs.ZlibError || e instanceof Error ? e.message : String(e)}`);
6046
+ throw new PsdError(`ZIP channel data: ${e instanceof _chunkT422YCHRcjs.ZlibError || e instanceof Error ? e.message : String(e)}`);
5999
6047
  }
6000
6048
  if (out.length < expected) throw new PsdError(`ZIP stream produced ${out.length} of ${expected} bytes.`);
6001
6049
  return out.length === expected ? out : out.subarray(0, expected);
@@ -6390,11 +6438,11 @@ function writeRect(w, r) {
6390
6438
  }
6391
6439
  function writeBlocks(w, blocks, psb, alignment) {
6392
6440
  for (const b of blocks) {
6393
- const long2 = psb && PSB_LONG_KEYS.has(b.key);
6394
- w.ascii(long2 ? "8B64" : "8BIM");
6441
+ const long3 = psb && PSB_LONG_KEYS.has(b.key);
6442
+ w.ascii(long3 ? "8B64" : "8BIM");
6395
6443
  w.ascii(b.key);
6396
6444
  const pad = (alignment - b.data.length % alignment) % alignment;
6397
- if (long2) w.u64(b.data.length + pad);
6445
+ if (long3) w.u64(b.data.length + pad);
6398
6446
  else w.u32(b.data.length + pad);
6399
6447
  w.bytes(b.data);
6400
6448
  w.zeros(pad);
@@ -6648,6 +6696,784 @@ function matteWhite(data) {
6648
6696
  return out;
6649
6697
  }
6650
6698
 
6699
+ // src/image-editor/psd/effects.ts
6700
+ var BLEND_CODES = [
6701
+ ["normal", "Nrml"],
6702
+ ["darken", "Drkn"],
6703
+ ["multiply", "Mltp"],
6704
+ ["color-burn", "CBrn"],
6705
+ ["linear-burn", "linearBurn"],
6706
+ ["darker-color", "darkerColor"],
6707
+ ["lighten", "Lghn"],
6708
+ ["screen", "Scrn"],
6709
+ ["color-dodge", "CDdg"],
6710
+ ["linear-dodge", "linearDodge"],
6711
+ ["lighter-color", "lighterColor"],
6712
+ ["overlay", "Ovrl"],
6713
+ ["soft-light", "SftL"],
6714
+ ["hard-light", "HrdL"],
6715
+ ["vivid-light", "vividLight"],
6716
+ ["linear-light", "linearLight"],
6717
+ ["pin-light", "pinLight"],
6718
+ ["hard-mix", "hardMix"],
6719
+ ["difference", "Dfrn"],
6720
+ ["exclusion", "Xclu"],
6721
+ ["subtract", "blendSubtraction"],
6722
+ ["divide", "blendDivide"],
6723
+ ["hue", "H "],
6724
+ ["saturation", "Strt"],
6725
+ ["color", "Clr "],
6726
+ ["luminosity", "Lmns"]
6727
+ ];
6728
+ var BLEND_LONG = [
6729
+ ["normal", "normal"],
6730
+ ["darken", "darken"],
6731
+ ["multiply", "multiply"],
6732
+ ["color-burn", "colorBurn"],
6733
+ ["lighten", "lighten"],
6734
+ ["screen", "screen"],
6735
+ ["color-dodge", "colorDodge"],
6736
+ ["overlay", "overlay"],
6737
+ ["soft-light", "softLight"],
6738
+ ["hard-light", "hardLight"],
6739
+ ["difference", "difference"],
6740
+ ["exclusion", "exclusion"],
6741
+ ["hue", "hue"],
6742
+ ["saturation", "saturation"],
6743
+ ["color", "color"],
6744
+ ["luminosity", "luminosity"]
6745
+ ];
6746
+ var BLEND_OF = new Map([...BLEND_CODES, ...BLEND_LONG].map(([m, id]) => [id, m]));
6747
+ var BLEND_ID = new Map(BLEND_CODES);
6748
+ var num2 = (d, key, fallback) => _nullishCoalesce(descNumber(d, key), () => ( fallback));
6749
+ var pct = (d, key, fallback) => num2(d, key, fallback * 100) / 100;
6750
+ var bool = (d, key) => descBool(d, key) === true;
6751
+ var enumOf = (d, key) => {
6752
+ const v = descGet(d, key);
6753
+ return _optionalChain([v, 'optionalAccess', _116 => _116.type]) === "enum" ? v.value : void 0;
6754
+ };
6755
+ var text = (d, key) => {
6756
+ const v = d ? descGet(d, key) : void 0;
6757
+ return _optionalChain([v, 'optionalAccess', _117 => _117.type]) === "TEXT" ? v.value : "";
6758
+ };
6759
+ var list = (d, key) => {
6760
+ const v = descGet(d, key);
6761
+ if (_optionalChain([v, 'optionalAccess', _118 => _118.type]) !== "VlLs") return [];
6762
+ return v.items.flatMap((it) => it.type === "Objc" || it.type === "GlbO" ? [it.value] : []);
6763
+ };
6764
+ var clamp3 = (v, lo, hi) => Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : lo;
6765
+ var unit = (u, value) => ({ type: "UntF", unit: u, value });
6766
+ var dbl = (value) => ({ type: "doub", value });
6767
+ var long2 = (value) => ({ type: "long", value: Math.round(value) });
6768
+ var boolV = (value) => ({ type: "bool", value });
6769
+ var enumV = (typeId, value) => ({ type: "enum", typeId, value });
6770
+ var textV = (value) => ({ type: "TEXT", value });
6771
+ var obj = (d) => ({ type: "Objc", value: d });
6772
+ function blendOf(d, key, fallback, notes) {
6773
+ const id = enumOf(d, key);
6774
+ if (id === void 0) return fallback;
6775
+ const m = BLEND_OF.get(id);
6776
+ if (m) return m;
6777
+ notes.add(id === "Dslv" || id === "dissolve" ? "Dissolve became Normal" : `an unknown blend mode "${id}" became Normal`);
6778
+ return "normal";
6779
+ }
6780
+ function colorOf(d, fallback = "#000000") {
6781
+ if (!d) return fallback;
6782
+ const g = (k) => descNumber(d, k);
6783
+ if (g("redFloat") !== void 0) return _chunkT422YCHRcjs.effectColorHex.call(void 0, [g("redFloat"), _nullishCoalesce(g("greenFloat"), () => ( 0)), _nullishCoalesce(g("blueFloat"), () => ( 0))]);
6784
+ switch (d.classId) {
6785
+ case "HSBC": {
6786
+ const rgb = decodePsdColor(1, [(_nullishCoalesce(g("H "), () => ( 0))) / 360 * 65535, (_nullishCoalesce(g("Strt"), () => ( 0))) / 100 * 65535, (_nullishCoalesce(g("Brgh"), () => ( 0))) / 100 * 65535]);
6787
+ return rgb ? _chunkT422YCHRcjs.effectColorHex.call(void 0, rgb) : fallback;
6788
+ }
6789
+ case "CMYC": {
6790
+ const inv = (k) => (1 - (_nullishCoalesce(g(k), () => ( 0))) / 100) * 65535;
6791
+ const rgb = decodePsdColor(2, [inv("Cyn "), inv("Mgnt"), inv("Ylw "), inv("Blck")]);
6792
+ return rgb ? _chunkT422YCHRcjs.effectColorHex.call(void 0, rgb) : fallback;
6793
+ }
6794
+ case "LbCl": {
6795
+ const rgb = decodePsdColor(7, [(_nullishCoalesce(g("Lmnc"), () => ( 0))) * 100, Math.round((_nullishCoalesce(g("A "), () => ( 0))) * 100) & 65535, Math.round((_nullishCoalesce(g("B "), () => ( 0))) * 100) & 65535]);
6796
+ return rgb ? _chunkT422YCHRcjs.effectColorHex.call(void 0, rgb) : fallback;
6797
+ }
6798
+ case "Grsc": {
6799
+ const v = 1 - (_nullishCoalesce(g("Gry "), () => ( 0))) / 100;
6800
+ return _chunkT422YCHRcjs.effectColorHex.call(void 0, [v, v, v]);
6801
+ }
6802
+ }
6803
+ const r = g("Rd ");
6804
+ const gr = g("Grn ");
6805
+ const b = g("Bl ");
6806
+ if (r === void 0 || gr === void 0 || b === void 0) return fallback;
6807
+ return _chunkT422YCHRcjs.effectColorHex.call(void 0, [r / 255, gr / 255, b / 255]);
6808
+ }
6809
+ function colorDesc(hex) {
6810
+ const [r, g, b] = _nullishCoalesce(_chunkT422YCHRcjs.parseEffectColor.call(void 0, hex), () => ( [0, 0, 0]));
6811
+ return descriptor("RGBC", [
6812
+ ["Rd ", dbl(r * 255)],
6813
+ ["Grn ", dbl(g * 255)],
6814
+ ["Bl ", dbl(b * 255)]
6815
+ ]);
6816
+ }
6817
+ function contourOf(d, key) {
6818
+ const c = descObject(d, key);
6819
+ if (!c) return void 0;
6820
+ const name = text(c, "Nm ");
6821
+ const points = list(c, "Crv ").map((p) => {
6822
+ const out = { input: clamp3(num2(p, "Hrzn", 0) / 255, 0, 1), output: clamp3(num2(p, "Vrtc", 0) / 255, 0, 1) };
6823
+ if (descBool(p, "Cnty") === false) out.corner = true;
6824
+ return out;
6825
+ });
6826
+ const linear = points.length === 2 && points[0].input === 0 && points[0].output === 0 && points[1].input === 1 && points[1].output === 1 && !points.some((p) => p.corner);
6827
+ if (points.length < 2 || linear && (!name || name === "Linear")) return void 0;
6828
+ return { name, points };
6829
+ }
6830
+ function contourDesc(c) {
6831
+ const name = _nullishCoalesce(_optionalChain([c, 'optionalAccess', _119 => _119.name]), () => ( "Linear"));
6832
+ const points = _nullishCoalesce(_optionalChain([c, 'optionalAccess', _120 => _120.points]), () => ( [
6833
+ { input: 0, output: 0 },
6834
+ { input: 1, output: 1 }
6835
+ ]));
6836
+ const pts = {
6837
+ type: "VlLs",
6838
+ items: points.map((p) => {
6839
+ const items = [
6840
+ ["Hrzn", dbl(p.input * 255)],
6841
+ ["Vrtc", dbl(p.output * 255)]
6842
+ ];
6843
+ if (p.corner) items.push(["Cnty", boolV(false)]);
6844
+ return obj(descriptor("CrPt", items));
6845
+ })
6846
+ };
6847
+ return obj(
6848
+ descriptor("ShpC", [
6849
+ ["Nm ", textV(name)],
6850
+ ["Crv ", pts]
6851
+ ])
6852
+ );
6853
+ }
6854
+ var GRADIENT_STYLES = [
6855
+ ["linear", "Lnr "],
6856
+ ["radial", "Rdl "],
6857
+ ["angle", "Angl"],
6858
+ ["reflected", "Rflc"],
6859
+ ["diamond", "Dmnd"]
6860
+ ];
6861
+ function gradientOf(d, notes) {
6862
+ const g = {
6863
+ stops: [
6864
+ { position: 0, color: "#000000" },
6865
+ { position: 1, color: "#ffffff" }
6866
+ ],
6867
+ style: _nullishCoalesce(_optionalChain([GRADIENT_STYLES, 'access', _121 => _121.find, 'call', _122 => _122(([, id]) => id === enumOf(d, "Type")), 'optionalAccess', _123 => _123[0]]), () => ( "linear")),
6868
+ angle: clamp3(num2(d, "Angl", 90), -360, 360),
6869
+ scale: clamp3(pct(d, "Scl ", 1), 0.1, 1.5),
6870
+ reverse: bool(d, "Rvrs"),
6871
+ align: descBool(d, "Algn") !== false,
6872
+ offset: { x: 0, y: 0 }
6873
+ };
6874
+ const off = descObject(d, "Ofst");
6875
+ if (off) g.offset = { x: clamp3(pct(off, "Hrzn", 0), -1, 1), y: clamp3(pct(off, "Vrtc", 0), -1, 1) };
6876
+ const grad = descObject(d, "Grad");
6877
+ if (!grad) return g;
6878
+ if (enumOf(grad, "GrdF") === "ClNs") {
6879
+ notes.add("noise gradients became black to white");
6880
+ return g;
6881
+ }
6882
+ const raw = list(grad, "Clrs").map((s) => {
6883
+ const type = enumOf(s, "Type");
6884
+ if (type === "FrgC" || type === "BckC") notes.add("foreground / background gradient stops became black / white");
6885
+ const color = type === "BckC" ? "#ffffff" : colorOf(descObject(s, "Clr "));
6886
+ return { position: clamp3(num2(s, "Lctn", 0) / 4096, 0, 1), color, mid: clamp3(num2(s, "Mdpn", 50) / 100, 0.05, 0.95) };
6887
+ }).sort((a, b) => a.position - b.position);
6888
+ if (raw.length) {
6889
+ const stops = [];
6890
+ raw.forEach((s, i) => {
6891
+ if (i > 0 && Math.abs(s.mid - 0.5) > 1e-3) {
6892
+ const a = raw[i - 1];
6893
+ const ca = _chunkT422YCHRcjs.parseEffectColor.call(void 0, a.color);
6894
+ const cb = _chunkT422YCHRcjs.parseEffectColor.call(void 0, s.color);
6895
+ stops.push({ position: a.position + (s.position - a.position) * s.mid, color: _chunkT422YCHRcjs.effectColorHex.call(void 0, ca.map((v, k) => (v + cb[k]) / 2)) });
6896
+ notes.add("gradient midpoints are drawn as straight segments");
6897
+ }
6898
+ stops.push({ position: s.position, color: s.color });
6899
+ });
6900
+ g.stops = stops;
6901
+ }
6902
+ const opacity = list(grad, "Trns").map((s) => ({ position: clamp3(num2(s, "Lctn", 0) / 4096, 0, 1), opacity: clamp3(num2(s, "Opct", 100) / 100, 0, 1) })).sort((a, b) => a.position - b.position);
6903
+ if (opacity.some((o) => o.opacity < 1)) g.opacityStops = opacity;
6904
+ if (num2(grad, "Intr", 0) > 0) notes.add("gradient smoothness is drawn as straight segments");
6905
+ return g;
6906
+ }
6907
+ function gradientItems(g) {
6908
+ const clrs = {
6909
+ type: "VlLs",
6910
+ items: g.stops.map(
6911
+ (s) => obj(
6912
+ descriptor("Clrt", [
6913
+ ["Clr ", obj(colorDesc(s.color))],
6914
+ ["Type", enumV("Clry", "UsrS")],
6915
+ ["Lctn", long2(s.position * 4096)],
6916
+ ["Mdpn", long2(50)]
6917
+ ])
6918
+ )
6919
+ )
6920
+ };
6921
+ const op = _optionalChain([g, 'access', _124 => _124.opacityStops, 'optionalAccess', _125 => _125.length]) ? g.opacityStops : g.stops.map((s) => ({ position: s.position, opacity: 1 }));
6922
+ const trns = {
6923
+ type: "VlLs",
6924
+ items: op.map(
6925
+ (s) => obj(
6926
+ descriptor("TrnS", [
6927
+ ["Opct", unit("#Prc", s.opacity * 100)],
6928
+ ["Lctn", long2(s.position * 4096)],
6929
+ ["Mdpn", long2(50)]
6930
+ ])
6931
+ )
6932
+ )
6933
+ };
6934
+ const grad = descriptor("Grdn", [
6935
+ ["Nm ", textV("Custom")],
6936
+ ["GrdF", enumV("GrdF", "CstS")],
6937
+ ["Intr", dbl(0)],
6938
+ ["Clrs", clrs],
6939
+ ["Trns", trns]
6940
+ ]);
6941
+ return [
6942
+ ["Grad", obj(grad)],
6943
+ ["Angl", unit("#Ang", g.angle)],
6944
+ ["Type", enumV("GrdT", GRADIENT_STYLES.find(([s]) => s === g.style)[1])],
6945
+ ["Rvrs", boolV(g.reverse)],
6946
+ ["Algn", boolV(g.align)],
6947
+ ["Scl ", unit("#Prc", g.scale * 100)],
6948
+ [
6949
+ "Ofst",
6950
+ obj(
6951
+ descriptor("Pnt ", [
6952
+ ["Hrzn", unit("#Prc", g.offset.x * 100)],
6953
+ ["Vrtc", unit("#Prc", g.offset.y * 100)]
6954
+ ])
6955
+ )
6956
+ ]
6957
+ ];
6958
+ }
6959
+ function patternRefOf(d) {
6960
+ const p = descObject(d, "Ptrn");
6961
+ return { patternId: text(p, "Idnt") || text(p, "Nm "), name: text(p, "Nm ") };
6962
+ }
6963
+ function patternRefDesc(patternId, name) {
6964
+ return obj(
6965
+ descriptor("Ptrn", [
6966
+ ["Nm ", textV(_nullishCoalesce(name, () => ( patternId)))],
6967
+ ["Idnt", textV(patternId)]
6968
+ ])
6969
+ );
6970
+ }
6971
+ function placementOf(d) {
6972
+ const phase = descObject(d, "phase");
6973
+ return {
6974
+ angle: clamp3(num2(d, "Angl", 0), -360, 360),
6975
+ link: descBool(d, "Algn") !== false,
6976
+ phase: phase ? { x: num2(phase, "Hrzn", 0), y: num2(phase, "Vrtc", 0) } : { x: 0, y: 0 }
6977
+ };
6978
+ }
6979
+ function placementItems(angle, link, phase) {
6980
+ const out = [];
6981
+ if (angle) out.push(["Angl", unit("#Ang", angle)]);
6982
+ out.push(["Algn", boolV(link)]);
6983
+ out.push([
6984
+ "phase",
6985
+ obj(
6986
+ descriptor("Pnt ", [
6987
+ ["Hrzn", dbl(phase.x)],
6988
+ ["Vrtc", dbl(phase.y)]
6989
+ ])
6990
+ )
6991
+ ]);
6992
+ return out;
6993
+ }
6994
+ var KINDS = [
6995
+ ["DrSh", "dropShadowMulti", "drop-shadow"],
6996
+ ["IrSh", "innerShadowMulti", "inner-shadow"],
6997
+ ["OrGl", "", "outer-glow"],
6998
+ ["IrGl", "", "inner-glow"],
6999
+ ["ebbl", "", "bevel-emboss"],
7000
+ ["ChFX", "", "satin"],
7001
+ ["SoFi", "solidFillMulti", "color-overlay"],
7002
+ ["GrFl", "gradientFillMulti", "gradient-overlay"],
7003
+ ["patternFill", "", "pattern-overlay"],
7004
+ ["FrFX", "frameFXMulti", "stroke"]
7005
+ ];
7006
+ function common(d, kind, notes) {
7007
+ const def = _chunkT422YCHRcjs.defaultLayerEffect.call(void 0, kind, "x");
7008
+ return { id: _chunkT422YCHRcjs.newEffectId.call(void 0, ), enabled: descBool(d, "enab") !== false, blend: blendOf(d, "Md ", def.blend, notes), opacity: clamp3(pct(d, "Opct", def.opacity), 0, 1) };
7009
+ }
7010
+ function readOne(kind, d, notes) {
7011
+ const size = (key, fallback) => clamp3(num2(d, key, fallback), 0, 250);
7012
+ switch (kind) {
7013
+ case "drop-shadow":
7014
+ case "inner-shadow": {
7015
+ const base = {
7016
+ ...common(d, kind, notes),
7017
+ color: colorOf(descObject(d, "Clr ")),
7018
+ angle: clamp3(num2(d, "lagl", 120), -360, 360),
7019
+ useGlobalLight: descBool(d, "uglg") !== false,
7020
+ distance: clamp3(num2(d, "Dstn", 5), 0, 3e4),
7021
+ size: size("blur", 5),
7022
+ contour: contourOf(d, "TrnS"),
7023
+ antiAlias: bool(d, "AntA"),
7024
+ noise: clamp3(pct(d, "Nose", 0), 0, 1)
7025
+ };
7026
+ const spread = clamp3(pct(d, "Ckmt", 0), 0, 1);
7027
+ return kind === "drop-shadow" ? { ...base, kind, spread, knocksOut: descBool(d, "layerConceals") !== false } : { ...base, kind, choke: spread };
7028
+ }
7029
+ case "outer-glow":
7030
+ case "inner-glow": {
7031
+ const fill = descGet(d, "Grad") ? { type: "gradient", gradient: gradientOf(d, notes) } : { type: "color", color: colorOf(descObject(d, "Clr "), "#ffffbe") };
7032
+ const jitter = clamp3(pct(d, "ShdN", 0), 0, 1);
7033
+ if (jitter > 0) notes.add("glow jitter is not drawn");
7034
+ const base = {
7035
+ ...common(d, kind, notes),
7036
+ fill,
7037
+ technique: enumOf(d, "GlwT") === "PrBL" ? "precise" : "softer",
7038
+ size: size("blur", 5),
7039
+ contour: contourOf(d, "TrnS"),
7040
+ antiAlias: bool(d, "AntA"),
7041
+ range: clamp3(pct(d, "Inpr", 0.5), 0.01, 1),
7042
+ jitter,
7043
+ noise: clamp3(pct(d, "Nose", 0), 0, 1)
7044
+ };
7045
+ const spread = clamp3(pct(d, "Ckmt", 0), 0, 1);
7046
+ return kind === "outer-glow" ? { ...base, kind, spread } : { ...base, kind, choke: spread, source: enumOf(d, "glwS") === "SrcC" ? "center" : "edge" };
7047
+ }
7048
+ case "bevel-emboss": {
7049
+ const styles = { OtrB: "outer-bevel", InrB: "inner-bevel", Embs: "emboss", PlEb: "pillow-emboss", strokeEmboss: "stroke-emboss" };
7050
+ const out = {
7051
+ id: _chunkT422YCHRcjs.newEffectId.call(void 0, ),
7052
+ enabled: descBool(d, "enab") !== false,
7053
+ kind,
7054
+ style: _nullishCoalesce(styles[_nullishCoalesce(enumOf(d, "bvlS"), () => ( ""))], () => ( "inner-bevel")),
7055
+ technique: enumOf(d, "bvlT") === "PrBL" ? "chisel-hard" : enumOf(d, "bvlT") === "Slmt" ? "chisel-soft" : "smooth",
7056
+ depth: clamp3(pct(d, "srgR", 1), 0, 10),
7057
+ direction: enumOf(d, "bvlD") === "Out " ? "down" : "up",
7058
+ size: size("blur", 5),
7059
+ soften: clamp3(num2(d, "Sftn", 0), 0, 16),
7060
+ angle: clamp3(num2(d, "lagl", 120), -360, 360),
7061
+ altitude: clamp3(num2(d, "Lald", 30), 0, 90),
7062
+ useGlobalLight: descBool(d, "uglg") !== false,
7063
+ glossContour: contourOf(d, "TrnS"),
7064
+ highlightColor: colorOf(descObject(d, "hglC"), "#ffffff"),
7065
+ highlightBlend: blendOf(d, "hglM", "screen", notes),
7066
+ highlightOpacity: clamp3(pct(d, "hglO", 0.75), 0, 1),
7067
+ shadowColor: colorOf(descObject(d, "sdwC")),
7068
+ shadowBlend: blendOf(d, "sdwM", "multiply", notes),
7069
+ shadowOpacity: clamp3(pct(d, "sdwO", 0.75), 0, 1)
7070
+ };
7071
+ if (bool(d, "useShape")) out.contourElement = { contour: _nullishCoalesce(contourOf(d, "MpgS"), () => ( { name: "Linear", points: [{ input: 0, output: 0 }, { input: 1, output: 1 }] })), range: clamp3(pct(d, "Inpr", 0.5), 0, 1), antiAlias: bool(d, "AntA") };
7072
+ if (bool(d, "useTexture")) {
7073
+ const ref = patternRefOf(d);
7074
+ const place = placementOf(d);
7075
+ out.texture = { patternId: ref.patternId, name: ref.name, scale: clamp3(pct(d, "Scl ", 1), 0.01, 10), depth: clamp3(pct(d, "textureDepth", 1), -10, 10), invert: bool(d, "InvT"), link: place.link, phase: place.phase };
7076
+ }
7077
+ return out;
7078
+ }
7079
+ case "satin":
7080
+ return {
7081
+ ...common(d, kind, notes),
7082
+ kind,
7083
+ color: colorOf(descObject(d, "Clr ")),
7084
+ angle: clamp3(num2(d, "lagl", 19), -360, 360),
7085
+ distance: size("Dstn", 11),
7086
+ size: size("blur", 14),
7087
+ contour: contourOf(d, "MpgS"),
7088
+ antiAlias: bool(d, "AntA"),
7089
+ invert: bool(d, "Invr")
7090
+ };
7091
+ case "color-overlay":
7092
+ return { ...common(d, kind, notes), kind, color: colorOf(descObject(d, "Clr ")) };
7093
+ case "gradient-overlay":
7094
+ return { ...common(d, kind, notes), kind, gradient: gradientOf(d, notes), dither: bool(d, "Dthr") };
7095
+ case "pattern-overlay": {
7096
+ const ref = patternRefOf(d);
7097
+ const place = placementOf(d);
7098
+ return { ...common(d, kind, notes), kind, patternId: ref.patternId, name: ref.name, scale: clamp3(pct(d, "Scl ", 1), 0.01, 10), angle: place.angle, link: place.link, phase: place.phase };
7099
+ }
7100
+ case "stroke": {
7101
+ const paint = enumOf(d, "PntT");
7102
+ let fill;
7103
+ if (paint === "GrFl") fill = { type: "gradient", gradient: gradientOf(d, notes) };
7104
+ else if (paint === "Ptrn") {
7105
+ const ref = patternRefOf(d);
7106
+ fill = { type: "pattern", patternId: ref.patternId, name: ref.name, scale: clamp3(pct(d, "Scl ", 1), 0.01, 10) };
7107
+ } else fill = { type: "color", color: colorOf(descObject(d, "Clr ")) };
7108
+ const pos = enumOf(d, "Styl");
7109
+ return { ...common(d, kind, notes), kind, size: size("Sz ", 3), position: pos === "InsF" ? "inside" : pos === "CtrF" ? "center" : "outside", fill };
7110
+ }
7111
+ }
7112
+ }
7113
+ function parseLfx2(data) {
7114
+ let d;
7115
+ try {
7116
+ d = parseVersionedDescriptor(data.subarray(4));
7117
+ } catch (e17) {
7118
+ return null;
7119
+ }
7120
+ const notes = /* @__PURE__ */ new Set();
7121
+ const items = [];
7122
+ for (const [single, multi, kind] of KINDS) {
7123
+ const many = multi ? list(d, multi) : [];
7124
+ const one = descObject(d, single);
7125
+ for (const x of many.length ? many : one ? [one] : []) {
7126
+ if (descBool(x, "present") === false) continue;
7127
+ items.push(readOne(kind, x, notes));
7128
+ }
7129
+ }
7130
+ const effects = { enabled: descBool(d, "masterFXSwitch") !== false, items };
7131
+ return { effects, notes: [...notes] };
7132
+ }
7133
+ function commonItems(e) {
7134
+ return [
7135
+ ["enab", boolV(e.enabled)],
7136
+ ["present", boolV(true)],
7137
+ ["showInDialog", boolV(true)],
7138
+ ["Md ", enumV("BlnM", _nullishCoalesce(BLEND_ID.get(e.blend), () => ( "Nrml")))],
7139
+ ["Opct", unit("#Prc", e.opacity * 100)]
7140
+ ];
7141
+ }
7142
+ function writeOne(e) {
7143
+ switch (e.kind) {
7144
+ case "drop-shadow":
7145
+ case "inner-shadow": {
7146
+ const inner = e.kind === "inner-shadow";
7147
+ const items = [
7148
+ ...commonItems(e),
7149
+ ["Clr ", obj(colorDesc(e.color))],
7150
+ ["uglg", boolV(e.useGlobalLight)],
7151
+ ["lagl", unit("#Ang", e.angle)],
7152
+ ["Dstn", unit("#Pxl", e.distance)],
7153
+ ["Ckmt", unit("#Pxl", (inner ? e.choke : e.spread) * 100)],
7154
+ ["blur", unit("#Pxl", e.size)],
7155
+ ["Nose", unit("#Prc", e.noise * 100)],
7156
+ ["AntA", boolV(e.antiAlias)],
7157
+ ["TrnS", contourDesc(e.contour)]
7158
+ ];
7159
+ if (e.kind === "drop-shadow") items.push(["layerConceals", boolV(e.knocksOut)]);
7160
+ return descriptor(inner ? "IrSh" : "DrSh", items);
7161
+ }
7162
+ case "outer-glow":
7163
+ case "inner-glow": {
7164
+ const inner = e.kind === "inner-glow";
7165
+ const items = [...commonItems(e)];
7166
+ if (e.fill.type === "gradient") items.push(...gradientItems(e.fill.gradient));
7167
+ else items.push(["Clr ", obj(colorDesc(e.fill.color))]);
7168
+ items.push(
7169
+ ["GlwT", enumV("BETE", e.technique === "precise" ? "PrBL" : "SfBL")],
7170
+ ["Ckmt", unit("#Pxl", (inner ? e.choke : e.spread) * 100)],
7171
+ ["blur", unit("#Pxl", e.size)],
7172
+ ["Nose", unit("#Prc", e.noise * 100)],
7173
+ ["ShdN", unit("#Prc", e.jitter * 100)],
7174
+ ["AntA", boolV(e.antiAlias)],
7175
+ ["TrnS", contourDesc(e.contour)],
7176
+ ["Inpr", unit("#Prc", e.range * 100)]
7177
+ );
7178
+ if (e.kind === "inner-glow") items.push(["glwS", enumV("IGSr", e.source === "center" ? "SrcC" : "SrcE")]);
7179
+ return descriptor(inner ? "IrGl" : "OrGl", items);
7180
+ }
7181
+ case "bevel-emboss": {
7182
+ const style = { "outer-bevel": "OtrB", "inner-bevel": "InrB", emboss: "Embs", "pillow-emboss": "PlEb", "stroke-emboss": "strokeEmboss" }[e.style];
7183
+ const tech = { smooth: "SfBL", "chisel-hard": "PrBL", "chisel-soft": "Slmt" }[e.technique];
7184
+ const items = [
7185
+ ["enab", boolV(e.enabled)],
7186
+ ["present", boolV(true)],
7187
+ ["showInDialog", boolV(true)],
7188
+ ["hglM", enumV("BlnM", _nullishCoalesce(BLEND_ID.get(e.highlightBlend), () => ( "Scrn")))],
7189
+ ["hglC", obj(colorDesc(e.highlightColor))],
7190
+ ["hglO", unit("#Prc", e.highlightOpacity * 100)],
7191
+ ["sdwM", enumV("BlnM", _nullishCoalesce(BLEND_ID.get(e.shadowBlend), () => ( "Mltp")))],
7192
+ ["sdwC", obj(colorDesc(e.shadowColor))],
7193
+ ["sdwO", unit("#Prc", e.shadowOpacity * 100)],
7194
+ ["bvlT", enumV("bvlT", tech)],
7195
+ ["bvlS", enumV("BESl", style)],
7196
+ ["uglg", boolV(e.useGlobalLight)],
7197
+ ["lagl", unit("#Ang", e.angle)],
7198
+ ["Lald", unit("#Ang", e.altitude)],
7199
+ ["srgR", unit("#Prc", e.depth * 100)],
7200
+ ["blur", unit("#Pxl", e.size)],
7201
+ ["bvlD", enumV("BESs", e.direction === "up" ? "In " : "Out ")],
7202
+ ["TrnS", contourDesc(e.glossContour)],
7203
+ ["Sftn", unit("#Pxl", e.soften)]
7204
+ ];
7205
+ if (e.contourElement) {
7206
+ items.push(["useShape", boolV(true)], ["MpgS", contourDesc(e.contourElement.contour)], ["AntA", boolV(e.contourElement.antiAlias)], ["Inpr", unit("#Prc", e.contourElement.range * 100)]);
7207
+ } else items.push(["useShape", boolV(false)]);
7208
+ if (e.texture) {
7209
+ const t = e.texture;
7210
+ items.push(
7211
+ ["useTexture", boolV(true)],
7212
+ ["InvT", boolV(t.invert)],
7213
+ ["Scl ", unit("#Prc", t.scale * 100)],
7214
+ ["textureDepth", unit("#Prc", t.depth * 100)],
7215
+ ["Ptrn", patternRefDesc(t.patternId, t.name)],
7216
+ ...placementItems(0, _nullishCoalesce(t.link, () => ( true)), _nullishCoalesce(t.phase, () => ( { x: 0, y: 0 })))
7217
+ );
7218
+ } else items.push(["useTexture", boolV(false)]);
7219
+ return descriptor("ebbl", items);
7220
+ }
7221
+ case "satin":
7222
+ return descriptor("ChFX", [
7223
+ ...commonItems(e),
7224
+ ["Clr ", obj(colorDesc(e.color))],
7225
+ ["AntA", boolV(e.antiAlias)],
7226
+ ["Invr", boolV(e.invert)],
7227
+ ["lagl", unit("#Ang", e.angle)],
7228
+ ["Dstn", unit("#Pxl", e.distance)],
7229
+ ["blur", unit("#Pxl", e.size)],
7230
+ ["MpgS", contourDesc(e.contour)]
7231
+ ]);
7232
+ case "color-overlay":
7233
+ return descriptor("SoFi", [...commonItems(e), ["Clr ", obj(colorDesc(e.color))]]);
7234
+ case "gradient-overlay":
7235
+ return descriptor("GrFl", [...commonItems(e), ...gradientItems(e.gradient), ["Dthr", boolV(e.dither)]]);
7236
+ case "pattern-overlay":
7237
+ return descriptor("patternFill", [
7238
+ ...commonItems(e),
7239
+ ["Ptrn", patternRefDesc(e.patternId, e.name)],
7240
+ ["Scl ", unit("#Prc", e.scale * 100)],
7241
+ ...placementItems(_nullishCoalesce(e.angle, () => ( 0)), _nullishCoalesce(e.link, () => ( true)), _nullishCoalesce(e.phase, () => ( { x: 0, y: 0 })))
7242
+ ]);
7243
+ case "stroke": {
7244
+ const items = [
7245
+ ...commonItems(e),
7246
+ ["Styl", enumV("FStl", e.position === "inside" ? "InsF" : e.position === "center" ? "CtrF" : "OutF")],
7247
+ ["Sz ", unit("#Pxl", e.size)]
7248
+ ];
7249
+ const f = e.fill;
7250
+ if (f.type === "color") items.push(["PntT", enumV("FrFl", "SClr")], ["Clr ", obj(colorDesc(f.color))]);
7251
+ else if (f.type === "gradient") items.push(["PntT", enumV("FrFl", "GrFl")], ...gradientItems(f.gradient));
7252
+ else items.push(["PntT", enumV("FrFl", "Ptrn")], ["Ptrn", patternRefDesc(f.patternId, f.name)], ["Scl ", unit("#Prc", f.scale * 100)]);
7253
+ return descriptor("FrFX", items);
7254
+ }
7255
+ }
7256
+ }
7257
+ function writeLfx2(effects) {
7258
+ const items = [
7259
+ ["Scl ", unit("#Prc", 100)],
7260
+ ["masterFXSwitch", boolV(effects.enabled)]
7261
+ ];
7262
+ const scale = _chunkT422YCHRcjs.effectsScale.call(void 0, effects);
7263
+ let dropped = 0;
7264
+ for (const [single, multi, kind] of KINDS) {
7265
+ const of = effects.items.filter((e) => e.kind === kind).map((e) => writeOne(_chunkT422YCHRcjs.scaleLayerEffect.call(void 0, e, scale)));
7266
+ if (!of.length) continue;
7267
+ if (of.length === 1) items.push([single, obj(of[0])]);
7268
+ else if (multi) items.push([multi, { type: "VlLs", items: of.map(obj) }]);
7269
+ else {
7270
+ items.push([single, obj(of[0])]);
7271
+ dropped += of.length - 1;
7272
+ }
7273
+ }
7274
+ const body = versionedDescriptorBytes(descriptor("null", items));
7275
+ const w = new PsdWriter();
7276
+ w.u32(0);
7277
+ w.bytes(body);
7278
+ if (w.length % 2) w.u8(0);
7279
+ return { data: w.result(), dropped };
7280
+ }
7281
+ function parseLrfx(data) {
7282
+ try {
7283
+ const r = new PsdReader(data);
7284
+ r.u16();
7285
+ const count = r.u16();
7286
+ const items = [];
7287
+ const notes = /* @__PURE__ */ new Set();
7288
+ const fixed = (v) => (v | 0) / 65536;
7289
+ for (let i = 0; i < count; i++) {
7290
+ if (new TextDecoder().decode(r.bytes(4)) !== "8BIM") return null;
7291
+ const key = new TextDecoder().decode(r.bytes(4));
7292
+ const size = r.u32();
7293
+ const b = new PsdReader(r.bytes(size));
7294
+ const colorAt = (rd) => {
7295
+ rd.u16();
7296
+ const c = [rd.u16(), rd.u16(), rd.u16(), rd.u16()];
7297
+ return _chunkT422YCHRcjs.effectColorHex.call(void 0, [c[0] >> 8, c[1] >> 8, c[2] >> 8].map((v) => v / 255));
7298
+ };
7299
+ const blendAt = (rd) => {
7300
+ rd.skip(4);
7301
+ const k = new TextDecoder().decode(rd.bytes(4));
7302
+ const m = PSD_BLEND_KEYS[k];
7303
+ return m && m !== "pass-through" ? m : "normal";
7304
+ };
7305
+ if (key === "dsdw" || key === "isdw") {
7306
+ b.u32();
7307
+ const blur = fixed(b.u32());
7308
+ b.u32();
7309
+ const angle = fixed(b.u32());
7310
+ const distance = fixed(b.u32());
7311
+ const color = colorAt(b);
7312
+ const blend = blendAt(b);
7313
+ const enabled = b.u8() !== 0;
7314
+ const useGlobalLight = b.u8() !== 0;
7315
+ const opacity = b.u8() / 255;
7316
+ const base = { id: _chunkT422YCHRcjs.newEffectId.call(void 0, ), enabled, blend, opacity, color, angle, useGlobalLight, distance: clamp3(distance, 0, 3e4), size: clamp3(blur, 0, 250), antiAlias: false, noise: 0 };
7317
+ items.push(key === "dsdw" ? { ...base, kind: "drop-shadow", spread: 0, knocksOut: true } : { ...base, kind: "inner-shadow", choke: 0 });
7318
+ } else if (key === "oglw" || key === "iglw") {
7319
+ b.u32();
7320
+ const blur = fixed(b.u32());
7321
+ b.u32();
7322
+ const color = colorAt(b);
7323
+ const blend = blendAt(b);
7324
+ const enabled = b.u8() !== 0;
7325
+ const opacity = b.u8() / 255;
7326
+ const base = { id: _chunkT422YCHRcjs.newEffectId.call(void 0, ), enabled, blend, opacity, fill: { type: "color", color }, technique: "softer", size: clamp3(blur, 0, 250), antiAlias: false, range: 0.5, jitter: 0, noise: 0 };
7327
+ items.push(key === "oglw" ? { ...base, kind: "outer-glow", spread: 0 } : { ...base, kind: "inner-glow", choke: 0, source: "edge" });
7328
+ } else if (key === "sofi") {
7329
+ b.u32();
7330
+ const blend = blendAt(b);
7331
+ const color = colorAt(b);
7332
+ const opacity = b.u8() / 255;
7333
+ const enabled = b.u8() !== 0;
7334
+ items.push({ id: _chunkT422YCHRcjs.newEffectId.call(void 0, ), kind: "color-overlay", enabled, blend, opacity, color });
7335
+ } else if (key === "bevl") notes.add("legacy bevels are not read");
7336
+ }
7337
+ return { effects: { enabled: true, items }, notes: [...notes] };
7338
+ } catch (e18) {
7339
+ return null;
7340
+ }
7341
+ }
7342
+
7343
+ // src/image-editor/psd/patterns.ts
7344
+ var MAX_EDGE = 3e4;
7345
+ var PATTERN_BLOCK_KEYS = ["Patt", "Pat2", "Pat3"];
7346
+ function modeChannels(mode) {
7347
+ return mode === MODE_RGB || mode === MODE_LAB ? 3 : mode === MODE_CMYK ? 4 : 1;
7348
+ }
7349
+ var rowBytes2 = (width, depth) => depth === 1 ? Math.ceil(width / 8) : width * (depth / 8);
7350
+ function readPattern(r) {
7351
+ const version = r.u32();
7352
+ if (version !== 1) throw new PsdError(`Pattern version ${version}, expected 1.`);
7353
+ const mode = r.u32();
7354
+ r.u16();
7355
+ r.u16();
7356
+ const name = r.unicode();
7357
+ const idLength = r.u8();
7358
+ const id = new TextDecoder().decode(r.bytes(idLength));
7359
+ let palette;
7360
+ if (mode === MODE_INDEXED) {
7361
+ palette = r.bytes(768).slice();
7362
+ const next = r.peek(4);
7363
+ if (next.length === 4 && !(next[0] === 0 && next[1] === 0 && next[2] === 0 && next[3] === 3)) r.skip(4);
7364
+ }
7365
+ const vmaVersion = r.u32();
7366
+ if (vmaVersion !== 3) throw new PsdError(`Pattern virtual memory array list version ${vmaVersion}, expected 3.`);
7367
+ const length = r.u32();
7368
+ const body = new PsdReader(r.bytes(length));
7369
+ const [top, left, bottom, right] = [body.i32(), body.i32(), body.i32(), body.i32()];
7370
+ const width = right - left;
7371
+ const height = bottom - top;
7372
+ if (!(width > 0 && height > 0 && width <= MAX_EDGE && height <= MAX_EDGE)) throw new PsdError(`Pattern "${name}" has an invalid size ${width} \xD7 ${height}.`);
7373
+ const count = body.u32();
7374
+ if (count > 64) throw new PsdError(`Pattern "${name}" has ${count} channels.`);
7375
+ const planes = [];
7376
+ let depth = 8;
7377
+ for (let i = 0; i < count + 2 && body.remaining > 0; i++) {
7378
+ if (body.u32() === 0) continue;
7379
+ const arrayLength = body.u32();
7380
+ if (arrayLength === 0) continue;
7381
+ if (arrayLength < 23) throw new PsdError(`Pattern "${name}" has a short channel.`);
7382
+ const d32 = body.u32();
7383
+ const [ct, cl, cb, cr] = [body.i32(), body.i32(), body.i32(), body.i32()];
7384
+ const d16 = body.u16();
7385
+ const compression = body.u8();
7386
+ const data = body.bytes(arrayLength - 23);
7387
+ const d = [1, 8, 16, 32].includes(d16) ? d16 : d32;
7388
+ if (![1, 8, 16, 32].includes(d)) throw new PsdError(`Pattern "${name}" has depth ${d}.`);
7389
+ if (ct < top || cl < left || cb > bottom || cr > right || cb < ct || cr < cl) throw new PsdError(`Pattern "${name}" has a channel outside its rectangle.`);
7390
+ if (compression > 1) throw new PsdError(`Pattern "${name}" uses compression ${compression}.`);
7391
+ depth = d;
7392
+ const cw = cr - cl;
7393
+ const ch = cb - ct;
7394
+ const plane = decodePlanes(compression, data, { planes: 1, width: cw, height: ch, depth: d, psb: false });
7395
+ if (cw === width && ch === height) {
7396
+ planes.push(plane);
7397
+ continue;
7398
+ }
7399
+ if (d === 1) throw new PsdError(`Pattern "${name}" has a cropped bitmap channel.`);
7400
+ const bps = d / 8;
7401
+ const out = new Uint8Array(rowBytes2(width, d) * height);
7402
+ for (let y = 0; y < ch; y++) {
7403
+ out.set(plane.subarray(y * cw * bps, (y + 1) * cw * bps), ((ct - top + y) * width + (cl - left)) * bps);
7404
+ }
7405
+ planes.push(out);
7406
+ }
7407
+ const nc = modeChannels(mode);
7408
+ if (planes.length < nc) throw new PsdError(`Pattern "${name}" has fewer channels than its colour mode.`);
7409
+ return { mode, width, height, name, id, palette, depth, channels: planes.slice(0, nc), alpha: planes[nc] };
7410
+ }
7411
+ function parsePatternBlock(data) {
7412
+ const r = new PsdReader(data);
7413
+ const out = [];
7414
+ while (r.remaining >= 4) {
7415
+ const length = r.u32();
7416
+ if (length === 0) break;
7417
+ out.push(readPattern(new PsdReader(r.bytes(length))));
7418
+ r.skip(Math.min((4 - length % 4) % 4, r.remaining));
7419
+ }
7420
+ return out;
7421
+ }
7422
+ function psdPatternToEffectPattern(p) {
7423
+ const data = toRgba8({ width: p.width, height: p.height, depth: p.depth, mode: p.mode, color: p.channels, alpha: p.alpha, palette: p.palette });
7424
+ return { id: p.id, name: p.name, width: p.width, height: p.height, data };
7425
+ }
7426
+ function writePatternBlock(patterns) {
7427
+ const out = new PsdWriter();
7428
+ for (const p of patterns) {
7429
+ if (!(p.width > 0 && p.height > 0) || p.width > 32767 || p.height > 32767) throw new PsdError(`Pattern "${p.name}" is ${p.width} \xD7 ${p.height}; patterns are 1 to 32767 px.`);
7430
+ const one = new PsdWriter();
7431
+ one.u32(1);
7432
+ one.u32(MODE_RGB);
7433
+ one.u16(p.height);
7434
+ one.u16(p.width);
7435
+ one.unicode(p.name, true);
7436
+ const id = new TextEncoder().encode(p.id).subarray(0, 255);
7437
+ one.u8(id.length);
7438
+ one.bytes(id);
7439
+ const n = p.width * p.height;
7440
+ const plane = (c) => {
7441
+ const v = new Uint8Array(n);
7442
+ for (let i = 0; i < n; i++) v[i] = p.data[i * 4 + c];
7443
+ return v;
7444
+ };
7445
+ const alpha = plane(3);
7446
+ const opaque = alpha.every((v) => v === 255);
7447
+ const body = new PsdWriter();
7448
+ for (const v of [0, 0, p.height, p.width]) body.i32(v);
7449
+ body.u32(24);
7450
+ const array = (v) => {
7451
+ const data = encodeRle(v, { planes: 1, width: p.width, height: p.height, depth: 8, psb: false });
7452
+ body.u32(1);
7453
+ body.u32(23 + data.length);
7454
+ body.u32(8);
7455
+ for (const x of [0, 0, p.height, p.width]) body.i32(x);
7456
+ body.u16(8);
7457
+ body.u8(1);
7458
+ body.bytes(data);
7459
+ };
7460
+ for (let c = 0; c < 3; c++) array(plane(c));
7461
+ for (let c = 3; c < 24; c++) body.u32(0);
7462
+ if (opaque) body.u32(0);
7463
+ else array(alpha);
7464
+ body.u32(0);
7465
+ const b = body.result();
7466
+ one.u32(3);
7467
+ one.u32(b.length);
7468
+ one.bytes(b);
7469
+ const bytes = one.result();
7470
+ out.u32(bytes.length);
7471
+ out.bytes(bytes);
7472
+ for (let k = 0; k < (4 - bytes.length % 4) % 4; k++) out.u8(0);
7473
+ }
7474
+ return out.result();
7475
+ }
7476
+
6651
7477
  // src/image-editor/psd/import.ts
6652
7478
  var PSD_BLEND_KEYS = {
6653
7479
  pass: "pass-through",
@@ -6685,15 +7511,14 @@ var FILL_KEYS = ["SoCo", "GdFl", "PtFl"];
6685
7511
  var TYPE_KEYS = ["TySh", "tySh"];
6686
7512
  var SMART_KEYS = ["SoLd", "SoLE", "PlLd"];
6687
7513
  var VECTOR_KEYS = ["vmsk", "vsms"];
6688
- var EFFECT_KEYS = ["lfx2", "lfxs", "lmfx"];
6689
7514
  var percent = (v) => Math.round(v / 255 * 100) / 100;
6690
7515
  var Warnings = (_class5 = class {constructor() { _class5.prototype.__init26.call(this);_class5.prototype.__init27.call(this); }
6691
7516
  __init26() {this.groups = /* @__PURE__ */ new Map()}
6692
7517
  __init27() {this.extra = []}
6693
7518
  add(message, layer) {
6694
- const list = _nullishCoalesce(this.groups.get(message), () => ( []));
6695
- if (!list.includes(layer)) list.push(layer);
6696
- this.groups.set(message, list);
7519
+ const list2 = _nullishCoalesce(this.groups.get(message), () => ( []));
7520
+ if (!list2.includes(layer)) list2.push(layer);
7521
+ this.groups.set(message, list2);
6697
7522
  }
6698
7523
  list() {
6699
7524
  const out = [...this.extra];
@@ -6744,11 +7569,11 @@ function safeSize(ctx, rect, name) {
6744
7569
  }
6745
7570
  function recordPixels(ctx, rec, name) {
6746
7571
  const { width, height } = safeSize(ctx, rec.rect, name);
6747
- if (!width || !height || ctx.skipPixels) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
7572
+ if (!width || !height || ctx.skipPixels) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
6748
7573
  const ids = [...Array.from({ length: ctx.colorCount }, (_, i) => i), CHANNEL_ALPHA];
6749
7574
  const planes = ids.map((id) => rec.channels.some((c) => c.id === id) ? _nullishCoalesce(decodeOr(ctx, rec, id, name), () => ( null)) : void 0);
6750
- if (planes.some((p) => p === null)) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
6751
- if (planes.every((p) => p === void 0)) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
7575
+ if (planes.some((p) => p === null)) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
7576
+ if (planes.every((p) => p === void 0)) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
6752
7577
  const data = toRgba8({
6753
7578
  width,
6754
7579
  height,
@@ -6758,7 +7583,7 @@ function recordPixels(ctx, rec, name) {
6758
7583
  alpha: planes[ctx.colorCount],
6759
7584
  palette: ctx.palette
6760
7585
  });
6761
- return _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, rec.rect.left, rec.rect.top);
7586
+ return _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, rec.rect.left, rec.rect.top);
6762
7587
  }
6763
7588
  function recordMask(ctx, rec, name) {
6764
7589
  const m = rec.mask;
@@ -6769,11 +7594,11 @@ function recordMask(ctx, rec, name) {
6769
7594
  const rect = useReal ? m.real.rect : m.rect;
6770
7595
  const def = (useReal ? m.real.background : m.defaultColor) >= 128 ? 255 : 0;
6771
7596
  const flags = useReal ? m.real.flags : m.flags;
6772
- let surface = _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, def);
7597
+ let surface = _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, def);
6773
7598
  const { width, height } = safeSize(ctx, rect, name);
6774
7599
  if (width && height && !ctx.skipPixels) {
6775
7600
  const plane = decodeOr(ctx, rec, id, name);
6776
- if (plane) surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: toMask8(plane, width, height, ctx.file.header.depth) }, 1, rect.left, rect.top, def);
7601
+ if (plane) surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: toMask8(plane, width, height, ctx.file.header.depth) }, 1, rect.left, rect.top, def);
6777
7602
  }
6778
7603
  const mask = { surface, defaultValue: def };
6779
7604
  if (m.userDensity !== void 0 && m.userDensity < 255) mask.density = percent(m.userDensity);
@@ -6800,10 +7625,6 @@ function baseProps(ctx, rec, name, notes) {
6800
7625
  if (rec.clipping) props.clipped = true;
6801
7626
  const locks = locksOf(rec);
6802
7627
  if (locks) props.locks = locks;
6803
- if (rec.blocks.some((b) => EFFECT_KEYS.includes(b.key))) {
6804
- ctx.warn.add("Layer effects (lfx2) are not rendered", name);
6805
- notes.push("layer effects are not rendered");
6806
- }
6807
7628
  if (rec.blocks.some((b) => b.key === "artb" || b.key === "artd" || b.key === "abdd")) {
6808
7629
  ctx.warn.add("Artboards are not supported; they came in as plain groups, without their background colour and clipping", name);
6809
7630
  notes.push("artboard imported as a group");
@@ -6814,6 +7635,47 @@ function baseProps(ctx, rec, name, notes) {
6814
7635
  }
6815
7636
  return props;
6816
7637
  }
7638
+ function patternIds(e) {
7639
+ if (e.kind === "pattern-overlay") return [e.patternId];
7640
+ if (e.kind === "stroke" && e.fill.type === "pattern") return [e.fill.patternId];
7641
+ if (e.kind === "bevel-emboss" && e.texture) return [e.texture.patternId];
7642
+ return [];
7643
+ }
7644
+ function recordEffects(ctx, rec, name, notes, group) {
7645
+ const key = ["lmfx", "lfx2", "lfxs"].find((k) => layerBlock(rec, k));
7646
+ if (key) {
7647
+ const data = layerBlock(rec, key);
7648
+ const parsed = parseLfx2(data);
7649
+ if (!parsed) {
7650
+ ctx.warn.add("Layer effects could not be read; they are kept for export but not drawn", name);
7651
+ notes.push("layer effects could not be read");
7652
+ return { enabled: true, items: [], psd: { key, data: data.slice() } };
7653
+ }
7654
+ for (const n of parsed.notes) {
7655
+ ctx.warn.add(`Layer effects were approximated: ${n}`, name);
7656
+ notes.push(`effects: ${n}`);
7657
+ }
7658
+ for (const e of parsed.effects.items) {
7659
+ for (const id of patternIds(e)) {
7660
+ if (ctx.patterns.has(id) || _chunkT422YCHRcjs.builtinPattern.call(void 0, id)) continue;
7661
+ ctx.warn.add("A pattern effect uses a pattern the file does not contain, and paints nothing", name);
7662
+ notes.push(`pattern "${id}" is not in the file`);
7663
+ }
7664
+ }
7665
+ return { ...parsed.effects, psd: { key, data: data.slice() } };
7666
+ }
7667
+ const legacy = layerBlock(rec, "lrFX");
7668
+ if (legacy && !group) {
7669
+ const parsed = parseLrfx(legacy);
7670
+ if (!parsed) return void 0;
7671
+ for (const n of parsed.notes) {
7672
+ ctx.warn.add(`Layer effects were approximated: ${n}`, name);
7673
+ notes.push(`effects: ${n}`);
7674
+ }
7675
+ return parsed.effects.items.length ? parsed.effects : void 0;
7676
+ }
7677
+ return void 0;
7678
+ }
6817
7679
  function importNode(ctx, node, depth) {
6818
7680
  const rec = ctx.file.layers[node.index];
6819
7681
  const name = layerName(rec);
@@ -6824,7 +7686,7 @@ function importNode(ctx, node, depth) {
6824
7686
  if (node.children) {
6825
7687
  const props2 = baseProps(ctx, rec, name, notes);
6826
7688
  const divider = sectionDivider(rec);
6827
- const key = _nullishCoalesce(_optionalChain([divider, 'optionalAccess', _116 => _116.blendKey]), () => ( rec.blendKey));
7689
+ const key = _nullishCoalesce(_optionalChain([divider, 'optionalAccess', _126 => _126.blendKey]), () => ( rec.blendKey));
6828
7690
  const groupBlend = key === "pass" ? "pass-through" : _nullishCoalesce(PSD_BLEND_KEYS[key], () => ( "normal"));
6829
7691
  const children = [];
6830
7692
  for (const child of node.children) {
@@ -6832,7 +7694,9 @@ function importNode(ctx, node, depth) {
6832
7694
  if (layer2) children.push(layer2);
6833
7695
  }
6834
7696
  const group = { type: "group", id: ctx.newId(name), ...props2, blend: groupBlend, children };
6835
- if (_optionalChain([divider, 'optionalAccess', _117 => _117.kind]) === SECTION_CLOSED) group.collapsed = true;
7697
+ const effects2 = recordEffects(ctx, rec, name, notes, true);
7698
+ if (effects2) group.effects = effects2;
7699
+ if (_optionalChain([divider, 'optionalAccess', _127 => _127.kind]) === SECTION_CLOSED) group.collapsed = true;
6836
7700
  const mask2 = recordMask(ctx, rec, name);
6837
7701
  if (mask2) group.mask = mask2;
6838
7702
  entry.type = "group";
@@ -6872,6 +7736,8 @@ function importNode(ctx, node, depth) {
6872
7736
  const layer = { type: "pixel", id: ctx.newId(name), ...props, surface: recordPixels(ctx, rec, name), offset: { x: 0, y: 0 } };
6873
7737
  const fill = u8Block(rec, "iOpa");
6874
7738
  if (fill !== void 0 && fill < 255) layer.fillOpacity = percent(fill);
7739
+ const effects = recordEffects(ctx, rec, name, notes, false);
7740
+ if (effects) layer.effects = effects;
6875
7741
  const mask = recordMask(ctx, rec, name);
6876
7742
  if (mask) layer.mask = mask;
6877
7743
  entry.type = "pixel";
@@ -6910,7 +7776,7 @@ function mergedLayer(ctx) {
6910
7776
  visible: true,
6911
7777
  opacity: 1,
6912
7778
  blend: "normal",
6913
- surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
7779
+ surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
6914
7780
  offset: { x: 0, y: 0 }
6915
7781
  };
6916
7782
  }
@@ -6925,8 +7791,17 @@ function psdToLayers(file, options = {}) {
6925
7791
  skipPixels: _nullishCoalesce(options.skipPixels, () => ( false)),
6926
7792
  summary: [],
6927
7793
  colorCount: colorChannelCount(header.colorMode, header.channels),
6928
- palette: header.colorMode === MODE_INDEXED ? file.colorModeData : void 0
7794
+ palette: header.colorMode === MODE_INDEXED ? file.colorModeData : void 0,
7795
+ patterns: /* @__PURE__ */ new Map()
6929
7796
  };
7797
+ for (const block of file.globalBlocks) {
7798
+ if (!PATTERN_BLOCK_KEYS.includes(block.key)) continue;
7799
+ try {
7800
+ for (const p of parsePatternBlock(block.data)) ctx.patterns.set(p.id, psdPatternToEffectPattern(p));
7801
+ } catch (e) {
7802
+ warn.extra.push(`The file's patterns could not be read (${e instanceof Error ? e.message : String(e)}); pattern effects paint nothing.`);
7803
+ }
7804
+ }
6930
7805
  const mode = _nullishCoalesce(COLOR_MODES[header.colorMode], () => ( `mode ${header.colorMode}`));
6931
7806
  if (mode !== "rgb" || header.depth !== 8) {
6932
7807
  warn.extra.push(`The file is ${header.depth}-bit ${mode}; it was converted to 8-bit RGB.`);
@@ -6952,6 +7827,9 @@ function psdToLayers(file, options = {}) {
6952
7827
  const bg = mergedLayer(ctx);
6953
7828
  if (bg) layers = [bg];
6954
7829
  }
7830
+ const i32 = (b) => b && b.length >= 4 ? new DataView(b.buffer, b.byteOffset, 4).getInt32(0) : void 0;
7831
+ const angle = i32(resource(file, 1037));
7832
+ const altitude = i32(resource(file, 1049));
6955
7833
  return {
6956
7834
  width: header.width,
6957
7835
  height: header.height,
@@ -6959,6 +7837,8 @@ function psdToLayers(file, options = {}) {
6959
7837
  warnings: warn.list(),
6960
7838
  summary: ctx.summary,
6961
7839
  resolution: resolution(file),
7840
+ patterns: [...ctx.patterns.values()],
7841
+ ...angle !== void 0 || altitude !== void 0 ? { globalLight: { angle: Math.max(-360, Math.min(360, _nullishCoalesce(angle, () => ( 120)))), altitude: Math.max(0, Math.min(90, _nullishCoalesce(altitude, () => ( 30)))) } } : {},
6962
7842
  info: { psb: header.psb, depth: header.depth, colorMode: mode, channels: header.channels }
6963
7843
  };
6964
7844
  }
@@ -6968,6 +7848,18 @@ function importPsd(bytes, options = {}) {
6968
7848
  }
6969
7849
 
6970
7850
  // src/image-editor/psd/export.ts
7851
+ function usedPatterns(e) {
7852
+ if (e.kind === "pattern-overlay") return [e.patternId];
7853
+ if (e.kind === "stroke" && e.fill.type === "pattern") return [e.fill.patternId];
7854
+ if (e.kind === "bevel-emboss" && e.texture) return [e.texture.patternId];
7855
+ return [];
7856
+ }
7857
+ var padEven = (d) => {
7858
+ if (d.length % 2 === 0) return d;
7859
+ const out = new Uint8Array(d.length + 1);
7860
+ out.set(d);
7861
+ return out;
7862
+ };
6971
7863
  var FLAG_PIXELS_IRRELEVANT = 8 | 16;
6972
7864
  var EMPTY_RECT = { top: 0, left: 0, bottom: 0, right: 0 };
6973
7865
  function unicodeBlock(s) {
@@ -6996,13 +7888,13 @@ function rleChannel(id, plane, width, height, psb) {
6996
7888
  var emptyChannel = (id) => ({ id, compression: 0, data: new Uint8Array(0) });
6997
7889
  function maskChannel(mask, ox, oy, psb) {
6998
7890
  if (mask.source) throw new PsdError("A parametric mask must be baked before export.");
6999
- const bounds = _chunkZOOEX3WTcjs.contentBounds.call(void 0, mask.surface);
7891
+ const bounds = _chunkCRMAXIUVcjs.contentBounds.call(void 0, mask.surface);
7000
7892
  const def = mask.defaultValue;
7001
7893
  const m = { rect: EMPTY_RECT, defaultColor: def, flags: mask.enabled === false ? MASK_FLAG_DISABLED : 0 };
7002
7894
  if ((_nullishCoalesce(mask.density, () => ( 1))) < 1) m.userDensity = Math.round(Math.max(0, _nullishCoalesce(mask.density, () => ( 1))) * 255);
7003
7895
  if ((_nullishCoalesce(mask.feather, () => ( 0))) > 0) m.userFeather = mask.feather;
7004
7896
  if (!bounds) return { channel: emptyChannel(CHANNEL_USER_MASK), mask: m };
7005
- const plane = _chunkZOOEX3WTcjs.readRegion.call(void 0, mask.surface, bounds);
7897
+ const plane = _chunkCRMAXIUVcjs.readRegion.call(void 0, mask.surface, bounds);
7006
7898
  m.rect = toRect({ ...bounds, x: bounds.x + ox, y: bounds.y + oy });
7007
7899
  return { channel: rleChannel(CHANNEL_USER_MASK, new Uint8Array(plane.buffer, plane.byteOffset, plane.length), bounds.width, bounds.height, psb), mask: m };
7008
7900
  }
@@ -7017,15 +7909,34 @@ function exportPsd(input) {
7017
7909
  const psb = width > PSD_MAX_DIMENSION || height > PSD_MAX_DIMENSION;
7018
7910
  const records = [];
7019
7911
  let nextId = 0;
7020
- const common = (layer, extra = []) => {
7912
+ const notes = /* @__PURE__ */ new Map();
7913
+ const note = (msg, name) => notes.set(msg, [..._nullishCoalesce(notes.get(msg), () => ( [])), name]);
7914
+ const patternIds2 = /* @__PURE__ */ new Set();
7915
+ const effectsBlock = (layer) => {
7916
+ const fx = layer.effects;
7917
+ if (!fx) return null;
7918
+ for (const e of fx.items) for (const id of usedPatterns(e)) patternIds2.add(id);
7919
+ const key = layer.type === "group" ? "lfxs" : "lfx2";
7920
+ if (fx.psd) {
7921
+ const original = parseLfx2(fx.psd.data);
7922
+ if (original ? _chunkT422YCHRcjs.effectsFingerprint.call(void 0, original.effects) === _chunkT422YCHRcjs.effectsFingerprint.call(void 0, fx) : !fx.items.length) return { key, data: padEven(fx.psd.data) };
7923
+ }
7924
+ if (!fx.items.length && fx.enabled && (_nullishCoalesce(fx.scale, () => ( 1))) === 1) return null;
7925
+ const { data, dropped } = writeLfx2(fx);
7926
+ if (dropped) note("Only the first outer glow, inner glow, bevel, satin and pattern overlay of a layer can be written; the others were left out", layer.name);
7927
+ return { key, data };
7928
+ };
7929
+ const common2 = (layer, extra = []) => {
7021
7930
  const name = layer.name || (layer.type === "adjustment" ? adjustmentKindLabel(layer.kind) : "");
7022
7931
  const blocks = [{ key: "luni", data: unicodeBlock(name) }, { key: "lyid", data: u32Bytes(++nextId) }, ...extra];
7932
+ const fx = effectsBlock(layer);
7933
+ if (fx) blocks.push(fx);
7023
7934
  const locks = lockBits(layer);
7024
7935
  if (locks) blocks.push({ key: "lspf", data: u32Bytes(locks >>> 0) });
7025
7936
  return {
7026
7937
  opacity: Math.round(Math.min(1, Math.max(0, layer.opacity)) * 255),
7027
7938
  clipping: layer.clipped ? 1 : 0,
7028
- flags: (layer.visible ? 0 : LAYER_FLAG_HIDDEN) | (_optionalChain([layer, 'access', _118 => _118.locks, 'optionalAccess', _119 => _119.transparency]) ? LAYER_FLAG_TRANSPARENCY_PROTECTED : 0),
7939
+ flags: (layer.visible ? 0 : LAYER_FLAG_HIDDEN) | (_optionalChain([layer, 'access', _128 => _128.locks, 'optionalAccess', _129 => _129.transparency]) ? LAYER_FLAG_TRANSPARENCY_PROTECTED : 0),
7029
7940
  legacyName: name,
7030
7941
  blocks
7031
7942
  };
@@ -7048,7 +7959,7 @@ function exportPsd(input) {
7048
7959
  });
7049
7960
  for (const child of layer.children) write(child);
7050
7961
  const blendKey = _nullishCoalesce(BLEND_TO_PSD[layer.blend], () => ( "norm"));
7051
- const base = common(layer, [{ key: "lsct", data: sectionBlock(layer.collapsed ? SECTION_CLOSED : SECTION_OPEN, blendKey) }]);
7962
+ const base = common2(layer, [{ key: "lsct", data: sectionBlock(layer.collapsed ? SECTION_CLOSED : SECTION_OPEN, blendKey) }]);
7052
7963
  const rec = {
7053
7964
  ...base,
7054
7965
  rect: EMPTY_RECT,
@@ -7067,7 +7978,7 @@ function exportPsd(input) {
7067
7978
  case "adjustment": {
7068
7979
  const block = writeAdjustmentBlock(layer.kind, layer.params);
7069
7980
  const rec = {
7070
- ...common(layer, [{ key: block.key, data: block.data }]),
7981
+ ...common2(layer, [{ key: block.key, data: block.data }]),
7071
7982
  rect: EMPTY_RECT,
7072
7983
  channels: [CHANNEL_ALPHA, 0, 1, 2].map(emptyChannel),
7073
7984
  blendKey: _nullishCoalesce(BLEND_TO_PSD[layer.blend], () => ( "norm"))
@@ -7082,16 +7993,16 @@ function exportPsd(input) {
7082
7993
  }
7083
7994
  case "pixel": {
7084
7995
  if (layer.source === "document") throw new PsdError(`Layer "${layer.name}" reads the document image; resolve its pixels before export.`);
7085
- if (_optionalChain([layer, 'access', _120 => _120.filters, 'optionalAccess', _121 => _121.some, 'call', _122 => _122(isActiveFilter)])) throw new PsdError(`Layer "${layer.name}" has live filters; bake them before export.`);
7996
+ if (_optionalChain([layer, 'access', _130 => _130.filters, 'optionalAccess', _131 => _131.some, 'call', _132 => _132(isActiveFilter)])) throw new PsdError(`Layer "${layer.name}" has live filters; bake them before export.`);
7086
7997
  const extra = [];
7087
7998
  if (layer.fillOpacity !== void 0 && layer.fillOpacity < 1) {
7088
7999
  extra.push({ key: "iOpa", data: Uint8Array.from([Math.round(Math.max(0, layer.fillOpacity) * 255), 0, 0, 0]) });
7089
8000
  }
7090
- const rec = { ...common(layer, extra), rect: EMPTY_RECT, channels: [], blendKey: _nullishCoalesce(BLEND_TO_PSD[layer.blend], () => ( "norm")) };
7091
- const bounds = _chunkZOOEX3WTcjs.contentBounds.call(void 0, layer.surface);
8001
+ const rec = { ...common2(layer, extra), rect: EMPTY_RECT, channels: [], blendKey: _nullishCoalesce(BLEND_TO_PSD[layer.blend], () => ( "norm")) };
8002
+ const bounds = _chunkCRMAXIUVcjs.contentBounds.call(void 0, layer.surface);
7092
8003
  if (bounds) {
7093
8004
  const n2 = bounds.width * bounds.height;
7094
- const [r2, g2, b2, a2] = rgbaToPlanes(_chunkZOOEX3WTcjs.readRegion.call(void 0, layer.surface, bounds), n2);
8005
+ const [r2, g2, b2, a2] = rgbaToPlanes(_chunkCRMAXIUVcjs.readRegion.call(void 0, layer.surface, bounds), n2);
7095
8006
  rec.rect = toRect({ ...bounds, x: bounds.x + layer.offset.x, y: bounds.y + layer.offset.y });
7096
8007
  rec.channels = [
7097
8008
  rleChannel(CHANNEL_ALPHA, a2, bounds.width, bounds.height, psb),
@@ -7140,6 +8051,25 @@ function exportPsd(input) {
7140
8051
  { id: 1005, name: "", data: rw.result() },
7141
8052
  { id: 1057, name: "", data: version.result() }
7142
8053
  ];
8054
+ if (input.globalLight) {
8055
+ const i32 = (v) => {
8056
+ const w = new PsdWriter();
8057
+ w.i32(Math.round(v));
8058
+ return w.result();
8059
+ };
8060
+ resources.push({ id: 1037, name: "", data: i32(input.globalLight.angle) }, { id: 1049, name: "", data: i32(input.globalLight.altitude) });
8061
+ }
8062
+ const globalBlocks = [];
8063
+ if (patternIds2.size) {
8064
+ const byId = new Map((_nullishCoalesce(input.patterns, () => ( []))).map((p) => [p.id, p]));
8065
+ const embed = [];
8066
+ for (const id of patternIds2) {
8067
+ const p = _nullishCoalesce(byId.get(id), () => ( _chunkT422YCHRcjs.builtinPattern.call(void 0, id)));
8068
+ if (p) embed.push(p);
8069
+ else note(`Pattern "${id}" is not in the document and was not embedded`, id);
8070
+ }
8071
+ if (embed.length) globalBlocks.push({ key: "Patt", data: writePatternBlock(embed) });
8072
+ }
7143
8073
  const bytes = writePsd(
7144
8074
  {
7145
8075
  header: { psb, channels: planes.length, width, height, depth: 8, colorMode: 3 },
@@ -7147,13 +8077,14 @@ function exportPsd(input) {
7147
8077
  resources,
7148
8078
  layers: records,
7149
8079
  mergedAlpha: transparent && records.length > 0,
7150
- globalBlocks: [],
8080
+ globalBlocks,
7151
8081
  imageCompression: 1,
7152
8082
  imageData: encodeRle(merged, { planes: planes.length, width, height, depth: 8, psb })
7153
8083
  },
7154
8084
  encodeLegacyName
7155
8085
  );
7156
- return { bytes, psb, records: records.length };
8086
+ const warnings = [...notes].map(([msg, names]) => `${msg} (${names.map((n2) => `"${n2}"`).join(", ")}).`);
8087
+ return { bytes, psb, records: records.length, warnings };
7157
8088
  }
7158
8089
 
7159
8090
  // src/image-editor/controller.ts
@@ -7162,33 +8093,40 @@ function paintCoverageInto(base, coverage, apply, rects) {
7162
8093
  const tiles = new Map(base.tiles);
7163
8094
  const done = /* @__PURE__ */ new Set();
7164
8095
  for (const r of rects) {
7165
- for (const t of _chunkZOOEX3WTcjs.tilesInRect.call(void 0, { x: r.x - apply.offset.x, y: r.y - apply.offset.y, width: r.width, height: r.height })) {
7166
- const key = _chunkZOOEX3WTcjs.tileKey.call(void 0, t.tx, t.ty);
8096
+ for (const t of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, { x: r.x - apply.offset.x, y: r.y - apply.offset.y, width: r.width, height: r.height })) {
8097
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, t.tx, t.ty);
7167
8098
  if (done.has(key)) continue;
7168
8099
  done.add(key);
7169
- const src = _nullishCoalesce(_optionalChain([base, 'access', _123 => _123.tiles, 'access', _124 => _124.get, 'call', _125 => _125(key), 'optionalAccess', _126 => _126.data]), () => ( defaultTile(base)));
7170
- const data = _chunk4F3YDIWWcjs.applyStrokeToTile.call(void 0, coverage, src, base.channels, t.tx, t.ty, apply);
7171
- const tile = _chunkZOOEX3WTcjs.finishTile.call(void 0, data, base.channels, base.defaultValue);
8100
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _133 => _133.tiles, 'access', _134 => _134.get, 'call', _135 => _135(key), 'optionalAccess', _136 => _136.data]), () => ( defaultTile(base)));
8101
+ const data = _chunkZZOTHJ4Kcjs.applyStrokeToTile.call(void 0, coverage, src, base.channels, t.tx, t.ty, apply);
8102
+ const tile = _chunkCRMAXIUVcjs.finishTile.call(void 0, data, base.channels, base.defaultValue);
7172
8103
  if (tile) tiles.set(key, tile);
7173
8104
  else tiles.delete(key);
7174
8105
  }
7175
8106
  }
7176
- return new (0, _chunkZOOEX3WTcjs.TiledSurface)(base.channels, tiles, base.defaultValue);
8107
+ return new (0, _chunkCRMAXIUVcjs.TiledSurface)(base.channels, tiles, base.defaultValue);
7177
8108
  }
7178
8109
  function defaultTile(s) {
7179
- const d = new Uint8ClampedArray(_chunkZOOEX3WTcjs.TILE * _chunkZOOEX3WTcjs.TILE * s.channels);
8110
+ const d = new Uint8ClampedArray(_chunkCRMAXIUVcjs.TILE * _chunkCRMAXIUVcjs.TILE * s.channels);
7180
8111
  if (s.defaultValue) d.fill(s.defaultValue);
7181
8112
  return d;
7182
8113
  }
7183
8114
  var PaintStrokeSession = (_class6 = class {
7184
- constructor(controller, target, stroke, apply) {;_class6.prototype.__init28.call(this);_class6.prototype.__init29.call(this);_class6.prototype.__init30.call(this);
8115
+ constructor(controller, target, stroke, apply) {;_class6.prototype.__init28.call(this);_class6.prototype.__init29.call(this);_class6.prototype.__init30.call(this);_class6.prototype.__init31.call(this);_class6.prototype.__init32.call(this);
7185
8116
  this.controller = controller;
7186
8117
  this.target = target;
7187
- this.stroke = stroke;
7188
8118
  this.apply = apply;
7189
8119
  this.before = controller._captureForStroke();
7190
8120
  this.base = target.surface;
7191
8121
  this.live = new Map(this.base.tiles);
8122
+ if (stroke instanceof _chunkZZOTHJ4Kcjs.StrokeCoverage) {
8123
+ this.stroke = stroke;
8124
+ this.mixer = null;
8125
+ } else {
8126
+ this.stroke = null;
8127
+ this.mixer = stroke.create(this.mixerPixels());
8128
+ this.mixerInit = stroke;
8129
+ }
7192
8130
  }
7193
8131
 
7194
8132
 
@@ -7196,10 +8134,34 @@ var PaintStrokeSession = (_class6 = class {
7196
8134
 
7197
8135
 
7198
8136
 
7199
-
7200
8137
  __init28() {this.touched = /* @__PURE__ */ new Set()}
7201
- __init29() {this.last = null}
7202
- __init30() {this.closed = false}
8138
+
8139
+
8140
+ __init29() {this.mixerInit = null}
8141
+ /** Mixer tiles written since the last update: they get new tile objects so the compositor sees them change. */
8142
+ __init30() {this.fresh = /* @__PURE__ */ new Set()}
8143
+ __init31() {this.last = null}
8144
+ __init32() {this.closed = false}
8145
+ /** The live pixels a mixer stroke reads and writes; base tiles are copied on first write. */
8146
+ mixerPixels() {
8147
+ const a = this.apply;
8148
+ return {
8149
+ offset: a.offset,
8150
+ lockTransparency: a.lockTransparency,
8151
+ selection: a.selection,
8152
+ readTile: (tx, ty) => _nullishCoalesce(_optionalChain([this, 'access', _137 => _137.live, 'access', _138 => _138.get, 'call', _139 => _139(_chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty)), 'optionalAccess', _140 => _140.data]), () => ( (this.base.defaultValue ? defaultTile(this.base) : null))),
8153
+ writeTile: (tx, ty) => {
8154
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty);
8155
+ if (!this.touched.has(key)) {
8156
+ const src = _nullishCoalesce(_optionalChain([this, 'access', _141 => _141.base, 'access', _142 => _142.tiles, 'access', _143 => _143.get, 'call', _144 => _144(key), 'optionalAccess', _145 => _145.data]), () => ( defaultTile(this.base)));
8157
+ this.live.set(key, { data: new Uint8ClampedArray(src), uniform: null });
8158
+ this.touched.add(key);
8159
+ }
8160
+ this.fresh.add(key);
8161
+ return this.live.get(key).data;
8162
+ }
8163
+ };
8164
+ }
7203
8165
  get layerId() {
7204
8166
  return this.target.id;
7205
8167
  }
@@ -7207,48 +8169,59 @@ var PaintStrokeSession = (_class6 = class {
7207
8169
  push(points) {
7208
8170
  if (this.closed || !points.length) return;
7209
8171
  this.last = points[points.length - 1];
7210
- this.update(this.stroke.push(points));
8172
+ this.update(this.mixer ? this.mixer.push(points) : this.stroke.push(points));
7211
8173
  }
7212
8174
  update(rects) {
7213
8175
  if (!rects.length) return;
7214
8176
  const ch = this.base.channels;
8177
+ if (this.mixer) {
8178
+ for (const key of this.fresh) this.live.set(key, { data: this.live.get(key).data, uniform: null });
8179
+ this.fresh.clear();
8180
+ this.controller._strokeUpdate(this.target.id, this.target.channel, new (0, _chunkCRMAXIUVcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
8181
+ return;
8182
+ }
8183
+ const stroke = this.stroke;
7215
8184
  const regions = /* @__PURE__ */ new Map();
7216
8185
  for (const r of rects) {
7217
- for (const t of _chunkZOOEX3WTcjs.tilesInRect.call(void 0, { x: r.x - this.apply.offset.x, y: r.y - this.apply.offset.y, width: r.width, height: r.height })) {
7218
- const key = _chunkZOOEX3WTcjs.tileKey.call(void 0, t.tx, t.ty);
8186
+ for (const t of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, { x: r.x - this.apply.offset.x, y: r.y - this.apply.offset.y, width: r.width, height: r.height })) {
8187
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, t.tx, t.ty);
7219
8188
  const cur = regions.get(key);
7220
8189
  regions.set(key, { tx: t.tx, ty: t.ty, r: cur ? unionRect(cur.r, r) : r });
7221
8190
  }
7222
8191
  }
7223
8192
  for (const [key, { tx, ty, r }] of regions) {
7224
- const src = _nullishCoalesce(_optionalChain([this, 'access', _127 => _127.base, 'access', _128 => _128.tiles, 'access', _129 => _129.get, 'call', _130 => _130(key), 'optionalAccess', _131 => _131.data]), () => ( defaultTile(this.base)));
7225
- const prev = this.touched.has(key) ? _optionalChain([this, 'access', _132 => _132.live, 'access', _133 => _133.get, 'call', _134 => _134(key), 'optionalAccess', _135 => _135.data]) : void 0;
8193
+ const src = _nullishCoalesce(_optionalChain([this, 'access', _146 => _146.base, 'access', _147 => _147.tiles, 'access', _148 => _148.get, 'call', _149 => _149(key), 'optionalAccess', _150 => _150.data]), () => ( defaultTile(this.base)));
8194
+ const prev = this.touched.has(key) ? _optionalChain([this, 'access', _151 => _151.live, 'access', _152 => _152.get, 'call', _153 => _153(key), 'optionalAccess', _154 => _154.data]) : void 0;
7226
8195
  this.touched.add(key);
7227
- const data = _chunk4F3YDIWWcjs.applyStrokeToTile.call(void 0, this.stroke.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
8196
+ const data = _chunkZZOTHJ4Kcjs.applyStrokeToTile.call(void 0, stroke.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
7228
8197
  this.live.set(key, { data, uniform: null });
7229
8198
  }
7230
- this.controller._strokeUpdate(this.target.id, this.target.channel, new (0, _chunkZOOEX3WTcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
8199
+ this.controller._strokeUpdate(this.target.id, this.target.channel, new (0, _chunkCRMAXIUVcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
7231
8200
  }
7232
8201
  /** Finishes the stroke (one undo step) and returns what changed. */
7233
8202
  end() {
7234
8203
  if (this.closed) throw new LayerOperationError("This stroke has already ended.");
7235
- this.update(this.stroke.finish(_nullishCoalesce(this.last, () => ( void 0))));
8204
+ const last = _nullishCoalesce(this.last, () => ( void 0));
8205
+ this.update(this.mixer ? this.mixer.finish(last) : this.stroke.finish(last));
7236
8206
  this.closed = true;
7237
8207
  const ch = this.base.channels;
7238
8208
  const tiles = new Map(this.base.tiles);
7239
8209
  let changed = false;
7240
8210
  for (const key of this.touched) {
7241
8211
  const live = this.live.get(key);
7242
- const tile = _chunkZOOEX3WTcjs.finishTile.call(void 0, live.data, ch, this.base.defaultValue);
8212
+ const tile = _chunkCRMAXIUVcjs.finishTile.call(void 0, live.data, ch, this.base.defaultValue);
7243
8213
  const prev = this.base.tiles.get(key);
7244
8214
  if (tile) tiles.set(key, tile);
7245
8215
  else tiles.delete(key);
7246
8216
  if (!sameTile(prev, tile)) changed = true;
7247
8217
  }
7248
- const surface = changed ? new (0, _chunkZOOEX3WTcjs.TiledSurface)(ch, tiles, this.base.defaultValue) : null;
8218
+ const surface = changed ? new (0, _chunkCRMAXIUVcjs.TiledSurface)(ch, tiles, this.base.defaultValue) : null;
8219
+ const mixerLoad = this.mixer ? this.mixerInit.end(this.mixer.load) : void 0;
7249
8220
  this.controller._strokeCommit(this.before, this.target.id, this.target.channel, surface);
7250
- const b = this.stroke.coverage.bounds;
7251
- return { layerId: this.target.id, channel: this.target.channel, bounds: changed ? b : null, dabs: this.stroke.dabCount };
8221
+ const b = this.mixer ? this.mixer.bounds : this.stroke.coverage.bounds;
8222
+ const result = { layerId: this.target.id, channel: this.target.channel, bounds: changed ? b : null, dabs: (_nullishCoalesce(this.mixer, () => ( this.stroke))).dabCount };
8223
+ if (mixerLoad) result.mixerLoad = mixerLoad;
8224
+ return result;
7252
8225
  }
7253
8226
  /** Abandons the stroke and restores the layer. */
7254
8227
  cancel() {
@@ -7293,14 +8266,14 @@ function migrateSerializedImageEditorState(data) {
7293
8266
  const legacy = data;
7294
8267
  const adjustments = normalizeStoredAdjustments(legacy.adjustments);
7295
8268
  return {
7296
- version: _optionalChain([adjustments, 'access', _136 => _136.layers, 'optionalAccess', _137 => _137.length]) ? 2 : 1,
8269
+ version: _optionalChain([adjustments, 'access', _155 => _155.layers, 'optionalAccess', _156 => _156.length]) ? 2 : 1,
7297
8270
  crop: legacy.crop ? { ...legacy.crop } : null,
7298
8271
  transform: { ...DEFAULT_TRANSFORM, ...legacy.transform },
7299
8272
  adjustments: serializeAdjustments(adjustments),
7300
8273
  depthMask: {
7301
8274
  ...DEFAULT_DEPTH_MASK,
7302
8275
  ...legacy.depthMask,
7303
- depthRange: [..._nullishCoalesce(_optionalChain([legacy, 'access', _138 => _138.depthMask, 'optionalAccess', _139 => _139.depthRange]), () => ( DEFAULT_DEPTH_MASK.depthRange))]
8276
+ depthRange: [..._nullishCoalesce(_optionalChain([legacy, 'access', _157 => _157.depthMask, 'optionalAccess', _158 => _158.depthRange]), () => ( DEFAULT_DEPTH_MASK.depthRange))]
7304
8277
  },
7305
8278
  annotations: JSON.parse(JSON.stringify(_nullishCoalesce(legacy.annotations, () => ( [])))),
7306
8279
  ...legacy.selection ? { selection: { ...legacy.selection } } : {}
@@ -7332,26 +8305,26 @@ var DEVELOP_KEYS = ["brightness", "contrast", "saturation", "exposure", "tempera
7332
8305
  var ImageEditorController = (_class7 = class {
7333
8306
 
7334
8307
 
7335
- __init31() {this.imageElement = null}
7336
- __init32() {this.listeners = /* @__PURE__ */ new Set()}
7337
- __init33() {this.histogramListeners = /* @__PURE__ */ new Set()}
8308
+ __init33() {this.imageElement = null}
8309
+ __init34() {this.listeners = /* @__PURE__ */ new Set()}
8310
+ __init35() {this.histogramListeners = /* @__PURE__ */ new Set()}
7338
8311
 
7339
8312
  // History stacks
7340
- __init34() {this.undoStack = []}
7341
- __init35() {this.redoStack = []}
8313
+ __init36() {this.undoStack = []}
8314
+ __init37() {this.redoStack = []}
7342
8315
 
7343
8316
 
7344
- __init36() {this.isApplyingHistory = false}
8317
+ __init38() {this.isApplyingHistory = false}
7345
8318
 
7346
8319
  /** Pixels the selection tools sample (host-provided or read back from the source). */
7347
- __init37() {this.samplePixels = null}
7348
- __init38() {this.samplePixelsOverride = false}
8320
+ __init39() {this.samplePixels = null}
8321
+ __init40() {this.samplePixelsOverride = false}
7349
8322
  /** Decoded source pixels (the Background's surface), by the buffer or element they came from. */
7350
- __init39() {this.sourceSurfaces = /* @__PURE__ */ new WeakMap()}
7351
- __init40() {this.viewKey = []}
8323
+ __init41() {this.sourceSurfaces = /* @__PURE__ */ new WeakMap()}
8324
+ __init42() {this.viewKey = []}
7352
8325
  /** For `compositePixels` and mask evaluation (the renderer keeps its own for the viewport). */
7353
- __init41() {this.compositor = new LayerCompositor()}
7354
- constructor(options = {}) {;_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);
8326
+ __init43() {this.compositor = new LayerCompositor()}
8327
+ constructor(options = {}) {;_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);
7355
8328
  this.maxHistoryDepth = _nullishCoalesce(options.maxHistoryDepth, () => ( 50));
7356
8329
  this.maxHistoryBytes = _nullishCoalesce(options.maxHistoryBytes, () => ( 512 * 1024 * 1024));
7357
8330
  this.onStateChange = options.onStateChange;
@@ -7362,8 +8335,9 @@ var ImageEditorController = (_class7 = class {
7362
8335
  this.renderer.layerSources = {
7363
8336
  surfaceOf: (layer) => this.surfaceOf(layer),
7364
8337
  sourceIsOpaque: () => this.sourceIsOpaque(),
7365
- version: () => this.sourceVersion(),
7366
- globalLight: () => this.state.globalLight
8338
+ version: () => `${this.sourceVersion()}:${this.patternsVersion()}`,
8339
+ globalLight: () => this.state.globalLight,
8340
+ pattern: (id) => _nullishCoalesce(_optionalChain([this, 'access', _159 => _159.state, 'access', _160 => _160.patterns, 'optionalAccess', _161 => _161.find, 'call', _162 => _162((p) => p.id === id)]), () => ( null))
7367
8341
  };
7368
8342
  this.state = {
7369
8343
  sourceUrl: typeof options.image === "string" ? options.image : null,
@@ -7384,7 +8358,7 @@ var ImageEditorController = (_class7 = class {
7384
8358
  activeLayerId: null,
7385
8359
  activeTarget: "pixels",
7386
8360
  outputOpacity: 1,
7387
- paint: { brush: { ..._chunk4F3YDIWWcjs.DEFAULT_BRUSH }, foreground: "#000000", background: "#ffffff" },
8361
+ paint: { brush: { ..._chunkZZOTHJ4Kcjs.DEFAULT_BRUSH }, foreground: "#000000", background: "#ffffff", mixer: { ..._chunkZZOTHJ4Kcjs.DEFAULT_MIXER }, mixerLoad: _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD },
7388
8362
  fit: _nullishCoalesce(options.fit, () => ( "margin"))
7389
8363
  };
7390
8364
  if (options.image instanceof Object && "width" in options.image) {
@@ -7396,10 +8370,10 @@ var ImageEditorController = (_class7 = class {
7396
8370
  };
7397
8371
  }
7398
8372
  this.applyStored(_nullishCoalesce(options.initialState, () => ( {})));
7399
- if (_optionalChain([options, 'access', _140 => _140.initialState, 'optionalAccess', _141 => _141.selection])) {
8373
+ if (_optionalChain([options, 'access', _163 => _163.initialState, 'optionalAccess', _164 => _164.selection])) {
7400
8374
  try {
7401
8375
  this.state.selection = normalizeSelection(deserializeSelection(options.initialState.selection));
7402
- } catch (e17) {
8376
+ } catch (e19) {
7403
8377
  }
7404
8378
  }
7405
8379
  this.initialSnapshot = this.captureHistoryEntry();
@@ -7440,7 +8414,7 @@ var ImageEditorController = (_class7 = class {
7440
8414
  height: img.naturalHeight || img.height || 600
7441
8415
  }
7442
8416
  };
7443
- } catch (e18) {
8417
+ } catch (e20) {
7444
8418
  return { sourceUrl: src, element: null, dimensions: { ...this.state.imageDimensions } };
7445
8419
  }
7446
8420
  }
@@ -7473,13 +8447,13 @@ var ImageEditorController = (_class7 = class {
7473
8447
  * Where layer pixels changed since the last viewport render, when only strokes changed them
7474
8448
  * (the renderer then recomposites just those rectangles); `'all'` after any other change.
7475
8449
  */
7476
- __init42() {this.pendingDirty = "all"}
8450
+ __init44() {this.pendingDirty = "all"}
7477
8451
  notify(strokeRects) {
7478
8452
  if (strokeRects && this.pendingDirty !== "all") this.pendingDirty.push(...strokeRects);
7479
8453
  else if (!strokeRects) this.pendingDirty = "all";
7480
8454
  this.syncViews();
7481
8455
  const currentState = { ...this.state };
7482
- _optionalChain([this, 'access', _142 => _142.onStateChange, 'optionalCall', _143 => _143(currentState)]);
8456
+ _optionalChain([this, 'access', _165 => _165.onStateChange, 'optionalCall', _166 => _166(currentState)]);
7483
8457
  this.listeners.forEach((l) => l(currentState));
7484
8458
  }
7485
8459
  /** Recomputes the compatibility views (`adjustments`, `depthMask`, `annotations`) when the stack changed. */
@@ -7518,6 +8492,7 @@ var ImageEditorController = (_class7 = class {
7518
8492
  };
7519
8493
  if (s.legacyOutputBlur !== void 0) entry.legacyOutputBlur = s.legacyOutputBlur;
7520
8494
  if (s.globalLight) entry.globalLight = { ...s.globalLight };
8495
+ if (s.patterns) entry.patterns = s.patterns;
7521
8496
  return entry;
7522
8497
  }
7523
8498
  restoreHistoryEntry(entry) {
@@ -7532,6 +8507,8 @@ var ImageEditorController = (_class7 = class {
7532
8507
  else delete s.legacyOutputBlur;
7533
8508
  if (entry.globalLight) s.globalLight = { ...entry.globalLight };
7534
8509
  else delete s.globalLight;
8510
+ if (entry.patterns) s.patterns = entry.patterns;
8511
+ else delete s.patterns;
7535
8512
  s.selection = entry.selection;
7536
8513
  if (this.imageElement !== entry.source.element && !this.samplePixelsOverride) this.samplePixels = null;
7537
8514
  this.imageElement = entry.source.element;
@@ -7687,7 +8664,7 @@ var ImageEditorController = (_class7 = class {
7687
8664
  return this.state.layers;
7688
8665
  }
7689
8666
  getLayer(id) {
7690
- return _optionalChain([_chunk73L6TROJcjs.findLayer.call(void 0, this.state.layers, id), 'optionalAccess', _144 => _144.layer]);
8667
+ return _optionalChain([_chunkT422YCHRcjs.findLayer.call(void 0, this.state.layers, id), 'optionalAccess', _167 => _167.layer]);
7691
8668
  }
7692
8669
  /** The active layer, or `undefined`. */
7693
8670
  getActiveLayer() {
@@ -7700,7 +8677,7 @@ var ImageEditorController = (_class7 = class {
7700
8677
  setActiveLayer(id, target = "pixels") {
7701
8678
  if (id !== null && !this.getLayer(id)) return false;
7702
8679
  const layer = id ? this.getLayer(id) : void 0;
7703
- const t = target === "mask" && _optionalChain([layer, 'optionalAccess', _145 => _145.mask]) ? "mask" : "pixels";
8680
+ const t = target === "mask" && _optionalChain([layer, 'optionalAccess', _168 => _168.mask]) ? "mask" : "pixels";
7704
8681
  if (this.state.activeLayerId === id && this.state.activeTarget === t) return true;
7705
8682
  this.state.activeLayerId = id;
7706
8683
  this.state.activeTarget = t;
@@ -7715,11 +8692,11 @@ var ImageEditorController = (_class7 = class {
7715
8692
  const layer = this.getLayer(id);
7716
8693
  if (!layer || layer.type !== "pixel") return null;
7717
8694
  const surface = this.surfaceOf(layer);
7718
- const b = _chunkZOOEX3WTcjs.contentBounds.call(void 0, surface);
8695
+ const b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, surface);
7719
8696
  if (!b) return null;
7720
- return { x: b.x + layer.offset.x, y: b.y + layer.offset.y, width: b.width, height: b.height, data: _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, b) };
8697
+ return { x: b.x + layer.offset.x, y: b.y + layer.offset.y, width: b.width, height: b.height, data: _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, b) };
7721
8698
  }
7722
- __init43() {this.boundsCache = /* @__PURE__ */ new WeakMap()}
8699
+ __init45() {this.boundsCache = /* @__PURE__ */ new WeakMap()}
7723
8700
  /**
7724
8701
  * Document bounds of a layer's non-transparent pixels (pixel layers; the Background's source
7725
8702
  * included), or `null` for an empty or non-pixel layer.
@@ -7730,7 +8707,7 @@ var ImageEditorController = (_class7 = class {
7730
8707
  const surface = this.surfaceOf(layer);
7731
8708
  let b = this.boundsCache.get(surface);
7732
8709
  if (b === void 0) {
7733
- b = _chunkZOOEX3WTcjs.contentBounds.call(void 0, surface);
8710
+ b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, surface);
7734
8711
  this.boundsCache.set(surface, b);
7735
8712
  }
7736
8713
  return b ? { x: b.x + layer.offset.x, y: b.y + layer.offset.y, width: b.width, height: b.height } : null;
@@ -7746,17 +8723,24 @@ var ImageEditorController = (_class7 = class {
7746
8723
  let layers = this.state.layers;
7747
8724
  if (options.layerIds) {
7748
8725
  const keep = new Set(options.layerIds);
7749
- layers = _chunk73L6TROJcjs.flattenLayers.call(void 0, layers).filter((l) => keep.has(l.id) && l.type !== "group");
8726
+ layers = _chunkT422YCHRcjs.flattenLayers.call(void 0, layers).filter((l) => keep.has(l.id) && l.type !== "group");
7750
8727
  }
7751
8728
  const data = this.compositor.composite(layers, r, this.compositorSources());
7752
8729
  return { width: r.width, height: r.height, data };
7753
8730
  }
7754
8731
  compositorSources() {
7755
8732
  const { width, height } = this.naturalSize;
7756
- return { width, height, surfaceOf: (l) => this.surfaceOf(l), version: this.sourceVersion(), globalLight: this.state.globalLight };
8733
+ return {
8734
+ width,
8735
+ height,
8736
+ surfaceOf: (l) => this.surfaceOf(l),
8737
+ version: `${this.sourceVersion()}:${this.patternsVersion()}`,
8738
+ globalLight: this.state.globalLight,
8739
+ pattern: (id) => _nullishCoalesce(_optionalChain([this, 'access', _169 => _169.state, 'access', _170 => _170.patterns, 'optionalAccess', _171 => _171.find, 'call', _172 => _172((p) => p.id === id)]), () => ( null))
8740
+ };
7757
8741
  }
7758
- __init44() {this.sourceIds = /* @__PURE__ */ new WeakMap()}
7759
- __init45() {this.nextSourceId = 1}
8742
+ __init46() {this.sourceIds = /* @__PURE__ */ new WeakMap()}
8743
+ __init47() {this.nextSourceId = 1}
7760
8744
  /** Changes whenever the Background's source pixels can have changed. */
7761
8745
  sourceVersion() {
7762
8746
  const key = this.samplePixelsOverride ? this.samplePixels : _nullishCoalesce(this.imageElement, () => ( this.samplePixels));
@@ -7782,7 +8766,7 @@ var ImageEditorController = (_class7 = class {
7782
8766
  const fromPixels = (px2) => {
7783
8767
  let s = this.sourceSurfaces.get(px2);
7784
8768
  if (!s) {
7785
- s = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, px2, 4);
8769
+ s = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, px2, 4);
7786
8770
  this.sourceSurfaces.set(px2, s);
7787
8771
  }
7788
8772
  return s;
@@ -7797,7 +8781,7 @@ var ImageEditorController = (_class7 = class {
7797
8781
  const decoded2 = this.decodeSource();
7798
8782
  if (decoded2) {
7799
8783
  if (!this.samplePixelsOverride) this.samplePixels = decoded2;
7800
- const s = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, decoded2, 4);
8784
+ const s = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, decoded2, 4);
7801
8785
  this.sourceSurfaces.set(el, s);
7802
8786
  this.sourceSurfaces.set(decoded2, s);
7803
8787
  return s;
@@ -7805,7 +8789,7 @@ var ImageEditorController = (_class7 = class {
7805
8789
  }
7806
8790
  return fits ? fromPixels(px) : null;
7807
8791
  }
7808
- __init46() {this.opaqueCache = /* @__PURE__ */ new WeakMap()}
8792
+ __init48() {this.opaqueCache = /* @__PURE__ */ new WeakMap()}
7809
8793
  /** Whether every source pixel is opaque (some legacy renders depend on it). */
7810
8794
  sourceIsOpaque() {
7811
8795
  const s = this.sourceSurface();
@@ -7829,9 +8813,9 @@ var ImageEditorController = (_class7 = class {
7829
8813
  if (!ctx || typeof ctx.getImageData !== "function") return null;
7830
8814
  ctx.drawImage(el, 0, 0, width, height);
7831
8815
  const data = ctx.getImageData(0, 0, width, height);
7832
- if (!_optionalChain([data, 'optionalAccess', _146 => _146.data]) || data.data.length < width * height * 4) return null;
8816
+ if (!_optionalChain([data, 'optionalAccess', _173 => _173.data]) || data.data.length < width * height * 4) return null;
7833
8817
  return { width, height, data: data.data };
7834
- } catch (e19) {
8818
+ } catch (e21) {
7835
8819
  return null;
7836
8820
  }
7837
8821
  }
@@ -7840,8 +8824,8 @@ var ImageEditorController = (_class7 = class {
7840
8824
  commitLayers(next, extra, commitToHistory = true) {
7841
8825
  if (commitToHistory) this.recordHistory();
7842
8826
  this.state.layers = next;
7843
- _optionalChain([extra, 'optionalCall', _147 => _147()]);
7844
- if (this.state.activeLayerId && !_chunk73L6TROJcjs.findLayer.call(void 0, next, this.state.activeLayerId)) {
8827
+ _optionalChain([extra, 'optionalCall', _174 => _174()]);
8828
+ if (this.state.activeLayerId && !_chunkT422YCHRcjs.findLayer.call(void 0, next, this.state.activeLayerId)) {
7845
8829
  this.state.activeLayerId = null;
7846
8830
  this.state.activeTarget = "pixels";
7847
8831
  }
@@ -7850,7 +8834,7 @@ var ImageEditorController = (_class7 = class {
7850
8834
  /** The default position of a new layer: above the active layer, else the top of the stack. */
7851
8835
  newLayerPlacement(placement) {
7852
8836
  if (placement.aboveId || placement.belowId || placement.parentId || placement.index !== void 0) return placement;
7853
- const active = this.state.activeLayerId ? _chunk73L6TROJcjs.findLayer.call(void 0, this.state.layers, this.state.activeLayerId) : null;
8837
+ const active = this.state.activeLayerId ? _chunkT422YCHRcjs.findLayer.call(void 0, this.state.layers, this.state.activeLayerId) : null;
7854
8838
  return active ? { aboveId: active.layer.id } : {};
7855
8839
  }
7856
8840
  /**
@@ -7860,24 +8844,24 @@ var ImageEditorController = (_class7 = class {
7860
8844
  */
7861
8845
  addPixelLayer(init = {}) {
7862
8846
  const { width, height } = this.naturalSize;
7863
- let surface = _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
8847
+ let surface = _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
7864
8848
  if (init.pixels) {
7865
8849
  const px = init.pixels;
7866
8850
  if (!(px.width > 0 && px.height > 0) || px.data.length < px.width * px.height * 4) {
7867
8851
  throw new LayerOperationError("pixels must be RGBA with width \xD7 height \xD7 4 bytes.");
7868
8852
  }
7869
- surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, px, 4);
8853
+ surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, px, 4);
7870
8854
  } else if (init.color !== void 0) {
7871
8855
  const c = parseColor(init.color);
7872
- surface = _chunkZOOEX3WTcjs.solidSurface.call(void 0, 4, { x: 0, y: 0, width, height }, _chunkZOOEX3WTcjs.packRgba.call(void 0, c[0], c[1], c[2], c[3]));
8856
+ surface = _chunkCRMAXIUVcjs.solidSurface.call(void 0, 4, { x: 0, y: 0, width, height }, _chunkCRMAXIUVcjs.packRgba.call(void 0, c[0], c[1], c[2], c[3]));
7873
8857
  }
7874
8858
  const blend = parseBlend(init.blend);
7875
8859
  if (init.opacity !== void 0 && !(init.opacity >= 0 && init.opacity <= 1)) throw new LayerOperationError("opacity must be from 0 to 1.");
7876
- const ids = new Set(_chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
8860
+ const ids = new Set(_chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
7877
8861
  const layer = {
7878
8862
  type: "pixel",
7879
8863
  id: init.id && !ids.has(init.id) ? init.id : newLayerId(),
7880
- name: _optionalChain([init, 'access', _148 => _148.name, 'optionalAccess', _149 => _149.trim, 'call', _150 => _150()]) || this.nextLayerName(),
8864
+ name: _optionalChain([init, 'access', _175 => _175.name, 'optionalAccess', _176 => _176.trim, 'call', _177 => _177()]) || this.nextLayerName(),
7881
8865
  visible: _nullishCoalesce(init.visible, () => ( true)),
7882
8866
  opacity: _nullishCoalesce(init.opacity, () => ( 1)),
7883
8867
  blend: _nullishCoalesce(blend, () => ( "normal")),
@@ -7904,27 +8888,27 @@ var ImageEditorController = (_class7 = class {
7904
8888
  async decodeImage(image) {
7905
8889
  const trimmed = image.trim();
7906
8890
  let png = null;
7907
- if (/^data:image\/png/i.test(trimmed)) png = _nullishCoalesce(_optionalChain([_chunk73L6TROJcjs.parseDataUrl.call(void 0, trimmed), 'optionalAccess', _151 => _151.bytes]), () => ( null));
8891
+ if (/^data:image\/png/i.test(trimmed)) png = _nullishCoalesce(_optionalChain([_chunkT422YCHRcjs.parseDataUrl.call(void 0, trimmed), 'optionalAccess', _178 => _178.bytes]), () => ( null));
7908
8892
  else if (/^[A-Za-z0-9+/=\s]+$/.test(trimmed) && trimmed.length > 16) {
7909
8893
  try {
7910
- const bytes = _chunk73L6TROJcjs.base64ToBytes.call(void 0, trimmed);
7911
- if (_chunk73L6TROJcjs.isPng.call(void 0, bytes)) png = bytes;
7912
- } catch (e20) {
8894
+ const bytes = _chunkT422YCHRcjs.base64ToBytes.call(void 0, trimmed);
8895
+ if (_chunkT422YCHRcjs.isPng.call(void 0, bytes)) png = bytes;
8896
+ } catch (e22) {
7913
8897
  png = null;
7914
8898
  }
7915
8899
  }
7916
8900
  if (png) {
7917
8901
  try {
7918
- const d = _chunk73L6TROJcjs.decodePng.call(void 0, png);
8902
+ const d = _chunkT422YCHRcjs.decodePng.call(void 0, png);
7919
8903
  return { width: d.width, height: d.height, data: d.data };
7920
- } catch (e21) {
8904
+ } catch (e23) {
7921
8905
  }
7922
8906
  }
7923
- const src = png ? `data:image/png;base64,${_chunk73L6TROJcjs.bytesToBase64.call(void 0, png)}` : trimmed;
8907
+ const src = png ? `data:image/png;base64,${_chunkT422YCHRcjs.bytesToBase64.call(void 0, png)}` : trimmed;
7924
8908
  let img;
7925
8909
  try {
7926
8910
  img = await this.renderer.imageCache.get(src);
7927
- } catch (e22) {
8911
+ } catch (e24) {
7928
8912
  throw new LayerOperationError("The image could not be decoded here. Pass a PNG (data URL or base64), or run in a browser for other formats and URLs.");
7929
8913
  }
7930
8914
  const w = img.naturalWidth || img.width;
@@ -7936,7 +8920,7 @@ var ImageEditorController = (_class7 = class {
7936
8920
  return { width: w, height: h, data: data.data };
7937
8921
  }
7938
8922
  nextLayerName() {
7939
- const names = new Set(_chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.name));
8923
+ const names = new Set(_chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.name));
7940
8924
  let n = 1;
7941
8925
  while (names.has(`Layer ${n}`)) n++;
7942
8926
  return `Layer ${n}`;
@@ -7953,7 +8937,7 @@ var ImageEditorController = (_class7 = class {
7953
8937
  removeLayer(id) {
7954
8938
  const next = removeLayer(this.state.layers, id);
7955
8939
  this.commitLayers(next, () => {
7956
- if (this.state.selectedAnnotationId && !_chunk73L6TROJcjs.flattenLayers.call(void 0, next).some((l) => l.type === "annotation" && l.annotation.id === this.state.selectedAnnotationId)) {
8940
+ if (this.state.selectedAnnotationId && !_chunkT422YCHRcjs.flattenLayers.call(void 0, next).some((l) => l.type === "annotation" && l.annotation.id === this.state.selectedAnnotationId)) {
7957
8941
  this.state.selectedAnnotationId = null;
7958
8942
  }
7959
8943
  });
@@ -7961,10 +8945,10 @@ var ImageEditorController = (_class7 = class {
7961
8945
  /** Moves a layer above / below another, or into a group, as one undo step. Returns its new parent and index. */
7962
8946
  moveLayer(id, placement) {
7963
8947
  const next = moveLayer(this.state.layers, id, placement);
7964
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, next, id);
7965
- if (next === this.state.layers) return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _152 => _152.parent, 'optionalAccess', _153 => _153.id]), () => ( null)), index: loc.index };
8948
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, next, id);
8949
+ if (next === this.state.layers) return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _179 => _179.parent, 'optionalAccess', _180 => _180.id]), () => ( null)), index: loc.index };
7966
8950
  this.commitLayers(next);
7967
- return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _154 => _154.parent, 'optionalAccess', _155 => _155.id]), () => ( null)), index: loc.index };
8951
+ return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _181 => _181.parent, 'optionalAccess', _182 => _182.id]), () => ( null)), index: loc.index };
7968
8952
  }
7969
8953
  /**
7970
8954
  * Changes name, visibility, opacity, fill, blend, clipping, locks or (groups) collapsed state, as
@@ -7973,7 +8957,7 @@ var ImageEditorController = (_class7 = class {
7973
8957
  setLayerProperties(id, props, commitToHistory = true) {
7974
8958
  const next = setLayerProperties(this.state.layers, id, props);
7975
8959
  this.commitLayers(next, void 0, commitToHistory);
7976
- return _chunk73L6TROJcjs.findLayer.call(void 0, next, id).layer;
8960
+ return _chunkT422YCHRcjs.findLayer.call(void 0, next, id).layer;
7977
8961
  }
7978
8962
  /** Adds an empty pass-through group above the active layer (or at `placement`) and makes it active. Returns its id. */
7979
8963
  addGroup(init = {}) {
@@ -7981,7 +8965,7 @@ var ImageEditorController = (_class7 = class {
7981
8965
  const group = {
7982
8966
  type: "group",
7983
8967
  id: newLayerId("group"),
7984
- name: _optionalChain([init, 'access', _156 => _156.name, 'optionalAccess', _157 => _157.trim, 'call', _158 => _158()]) || "Group",
8968
+ name: _optionalChain([init, 'access', _183 => _183.name, 'optionalAccess', _184 => _184.trim, 'call', _185 => _185()]) || "Group",
7985
8969
  visible: true,
7986
8970
  opacity: 1,
7987
8971
  blend,
@@ -8031,14 +9015,14 @@ var ImageEditorController = (_class7 = class {
8031
9015
  let mask;
8032
9016
  if (from === "selection") {
8033
9017
  const sel = this.state.selection;
8034
- if (!_optionalChain([sel, 'optionalAccess', _159 => _159.bounds])) throw new LayerOperationError("Nothing is selected; select first, or use reveal-all / hide-all.");
9018
+ if (!_optionalChain([sel, 'optionalAccess', _186 => _186.bounds])) throw new LayerOperationError("Nothing is selected; select first, or use reveal-all / hide-all.");
8035
9019
  mask = this.maskFromSelection(sel, props);
8036
9020
  if (layer.type === "pixel" && (layer.offset.x || layer.offset.y)) {
8037
- mask = { ...mask, surface: _chunkZOOEX3WTcjs.translateSurface.call(void 0, mask.surface, -layer.offset.x, -layer.offset.y) };
9021
+ mask = { ...mask, surface: _chunkCRMAXIUVcjs.translateSurface.call(void 0, mask.surface, -layer.offset.x, -layer.offset.y) };
8038
9022
  }
8039
9023
  } else {
8040
9024
  const v = from === "reveal-all" ? 255 : 0;
8041
- mask = withMaskProps({ surface: _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, v), defaultValue: v }, props);
9025
+ mask = withMaskProps({ surface: _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, v), defaultValue: v }, props);
8042
9026
  }
8043
9027
  const next = setLayerMask(this.state.layers, id, mask);
8044
9028
  this.commitLayers(next, () => {
@@ -8079,11 +9063,11 @@ var ImageEditorController = (_class7 = class {
8079
9063
  let out = surface;
8080
9064
  const b = surface.bounds;
8081
9065
  if (b) {
8082
- const draft = new (0, _chunkZOOEX3WTcjs.SurfaceDraft)(surface);
8083
- for (const t of _chunkZOOEX3WTcjs.tilesInRect.call(void 0, b)) {
9066
+ const draft = new (0, _chunkCRMAXIUVcjs.SurfaceDraft)(surface);
9067
+ for (const t of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, b)) {
8084
9068
  const data = draft.peek(t.tx, t.ty);
8085
9069
  if (!data) continue;
8086
- const r = { x: t.tx * _chunkZOOEX3WTcjs.TILE + layer.offset.x, y: t.ty * _chunkZOOEX3WTcjs.TILE + layer.offset.y, width: _chunkZOOEX3WTcjs.TILE, height: _chunkZOOEX3WTcjs.TILE };
9070
+ const r = { x: t.tx * _chunkCRMAXIUVcjs.TILE + layer.offset.x, y: t.ty * _chunkCRMAXIUVcjs.TILE + layer.offset.y, width: _chunkCRMAXIUVcjs.TILE, height: _chunkCRMAXIUVcjs.TILE };
8087
9071
  const cov = this.compositor.maskCoverage(layer, r, sources);
8088
9072
  if (!cov) continue;
8089
9073
  const d = draft.tile(t.tx, t.ty);
@@ -8094,7 +9078,7 @@ var ImageEditorController = (_class7 = class {
8094
9078
  const next = { ...layer, surface: out };
8095
9079
  delete next.mask;
8096
9080
  delete next.source;
8097
- this.commitLayers(_chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, id, () => next), () => {
9081
+ this.commitLayers(_chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, id, () => next), () => {
8098
9082
  if (this.state.activeLayerId === id) this.state.activeTarget = "pixels";
8099
9083
  });
8100
9084
  }
@@ -8109,12 +9093,12 @@ var ImageEditorController = (_class7 = class {
8109
9093
  const layer = loc.layer;
8110
9094
  if (layer.type !== "pixel") throw new LayerOperationError(`Layer via copy needs a pixel layer; "${id}" is a ${layer.type} layer.`);
8111
9095
  const sel = this.state.selection;
8112
- if (!_optionalChain([sel, 'optionalAccess', _160 => _160.bounds])) throw new LayerOperationError("Nothing is selected; select the pixels to copy first.");
9096
+ if (!_optionalChain([sel, 'optionalAccess', _187 => _187.bounds])) throw new LayerOperationError("Nothing is selected; select the pixels to copy first.");
8113
9097
  if (options.cut) requireUnlocked(layer, "pixels", "cut from it");
8114
9098
  const surface = this.surfaceOf(layer);
8115
9099
  const sb = sel.bounds;
8116
9100
  const src = { x: sb.x - layer.offset.x, y: sb.y - layer.offset.y, width: sb.width, height: sb.height };
8117
- const px = _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, src);
9101
+ const px = _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, src);
8118
9102
  const kept = options.cut ? new Uint8ClampedArray(px) : null;
8119
9103
  for (let y = 0; y < sb.height; y++) {
8120
9104
  for (let x = 0; x < sb.width; x++) {
@@ -8127,18 +9111,18 @@ var ImageEditorController = (_class7 = class {
8127
9111
  const copy = {
8128
9112
  type: "pixel",
8129
9113
  id: newLayerId(),
8130
- name: _optionalChain([options, 'access', _161 => _161.name, 'optionalAccess', _162 => _162.trim, 'call', _163 => _163()]) || `${layer.name || "Layer"} ${options.cut ? "cut" : "copy"}`,
9114
+ name: _optionalChain([options, 'access', _188 => _188.name, 'optionalAccess', _189 => _189.trim, 'call', _190 => _190()]) || `${layer.name || "Layer"} ${options.cut ? "cut" : "copy"}`,
8131
9115
  visible: true,
8132
9116
  opacity: 1,
8133
9117
  blend: "normal",
8134
- surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width: src.width, height: src.height, data: px }, 4, src.x, src.y),
9118
+ surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width: src.width, height: src.height, data: px }, 4, src.x, src.y),
8135
9119
  offset: { ...layer.offset }
8136
9120
  };
8137
- let next = _chunk73L6TROJcjs.insertLayer.call(void 0, this.state.layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _164 => _164.parent, 'optionalAccess', _165 => _165.id]), () => ( null)), loc.index + 1);
9121
+ let next = _chunkT422YCHRcjs.insertLayer.call(void 0, this.state.layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _191 => _191.parent, 'optionalAccess', _192 => _192.id]), () => ( null)), loc.index + 1);
8138
9122
  if (kept) {
8139
- const cutLayer = { ...layer, surface: _chunkZOOEX3WTcjs.writeRegion.call(void 0, surface, src, kept) };
9123
+ const cutLayer = { ...layer, surface: _chunkCRMAXIUVcjs.writeRegion.call(void 0, surface, src, kept) };
8140
9124
  delete cutLayer.source;
8141
- next = _chunk73L6TROJcjs.mapLayer.call(void 0, next, id, () => cutLayer);
9125
+ next = _chunkT422YCHRcjs.mapLayer.call(void 0, next, id, () => cutLayer);
8142
9126
  }
8143
9127
  this.commitLayers(next, () => {
8144
9128
  this.state.activeLayerId = copy.id;
@@ -8151,19 +9135,19 @@ var ImageEditorController = (_class7 = class {
8151
9135
  const f = normalizeFilter(filter);
8152
9136
  const next = addLayerFilter(this.state.layers, id, f);
8153
9137
  this.commitLayers(next);
8154
- return _nullishCoalesce(_chunk73L6TROJcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
9138
+ return _nullishCoalesce(_chunkT422YCHRcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8155
9139
  }
8156
9140
  /** Changes one filter (one undo step, or none with `commitToHistory = false` during a drag). Returns the filters. */
8157
9141
  updateLayerFilter(id, filterId, changes, commitToHistory = true) {
8158
9142
  const next = updateLayerFilter(this.state.layers, id, filterId, changes);
8159
9143
  this.commitLayers(next, void 0, commitToHistory);
8160
- return _nullishCoalesce(_chunk73L6TROJcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
9144
+ return _nullishCoalesce(_chunkT422YCHRcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8161
9145
  }
8162
9146
  /** Removes one filter (one undo step). Returns the remaining filters. */
8163
9147
  removeLayerFilter(id, filterId) {
8164
9148
  const next = removeLayerFilter(this.state.layers, id, filterId);
8165
9149
  this.commitLayers(next);
8166
- return _nullishCoalesce(_chunk73L6TROJcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
9150
+ return _nullishCoalesce(_chunkT422YCHRcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8167
9151
  }
8168
9152
  // --- Layer effects ---
8169
9153
  /** A layer's effects (an empty, enabled list when it has none). */
@@ -8199,9 +9183,25 @@ var ImageEditorController = (_class7 = class {
8199
9183
  this.commitLayers(setLayerEffects(this.state.layers, id, effects), void 0, commitToHistory);
8200
9184
  return this.getLayerEffects(id);
8201
9185
  }
9186
+ __init49() {this.patternIds = /* @__PURE__ */ new WeakMap()}
9187
+ /** Changes whenever the document's pattern list is replaced (the compositor then drops its caches). */
9188
+ patternsVersion() {
9189
+ const list2 = this.state.patterns;
9190
+ if (!list2) return 0;
9191
+ let id = this.patternIds.get(list2);
9192
+ if (id === void 0) {
9193
+ id = this.nextSourceId++;
9194
+ this.patternIds.set(list2, id);
9195
+ }
9196
+ return id;
9197
+ }
9198
+ /** The document's patterns (from an opened PSD), besides the built-in ones. */
9199
+ getDocumentPatterns() {
9200
+ return _nullishCoalesce(this.state.patterns, () => ( []));
9201
+ }
8202
9202
  /** The light effects with "use global light" follow. */
8203
9203
  getGlobalLight() {
8204
- return { ..._nullishCoalesce(this.state.globalLight, () => ( _chunk73L6TROJcjs.DEFAULT_GLOBAL_LIGHT)) };
9204
+ return { ..._nullishCoalesce(this.state.globalLight, () => ( _chunkT422YCHRcjs.DEFAULT_GLOBAL_LIGHT)) };
8205
9205
  }
8206
9206
  /** Sets the global light (one undo step). `angle` -360..360°, `altitude` 0..90°. Returns it. */
8207
9207
  setGlobalLight(light, commitToHistory = true) {
@@ -8209,7 +9209,7 @@ var ImageEditorController = (_class7 = class {
8209
9209
  if (!(Number.isFinite(next.angle) && next.angle >= -360 && next.angle <= 360)) throw new LayerOperationError(`angle must be from -360 to 360 degrees, got ${next.angle}.`);
8210
9210
  if (!(Number.isFinite(next.altitude) && next.altitude >= 0 && next.altitude <= 90)) throw new LayerOperationError(`altitude must be from 0 to 90 degrees, got ${next.altitude}.`);
8211
9211
  if (commitToHistory) this.recordHistory();
8212
- if (next.angle === _chunk73L6TROJcjs.DEFAULT_GLOBAL_LIGHT.angle && next.altitude === _chunk73L6TROJcjs.DEFAULT_GLOBAL_LIGHT.altitude) delete this.state.globalLight;
9212
+ if (next.angle === _chunkT422YCHRcjs.DEFAULT_GLOBAL_LIGHT.angle && next.altitude === _chunkT422YCHRcjs.DEFAULT_GLOBAL_LIGHT.altitude) delete this.state.globalLight;
8213
9213
  else this.state.globalLight = next;
8214
9214
  this.notify();
8215
9215
  return this.getGlobalLight();
@@ -8217,12 +9217,12 @@ var ImageEditorController = (_class7 = class {
8217
9217
  /** Composites `layers` (in isolation) over `rect` into a surface, loading depth maps first. */
8218
9218
  async compositeToSurface(layers, rect) {
8219
9219
  const { width, height } = this.naturalSize;
8220
- if (_chunk73L6TROJcjs.flattenLayers.call(void 0, layers).some((l) => l.type === "annotation" && l.visible) && !this.renderer.canRasterize()) {
9220
+ if (_chunkT422YCHRcjs.flattenLayers.call(void 0, layers).some((l) => l.type === "annotation" && l.visible) && !this.renderer.canRasterize()) {
8221
9221
  throw new LayerOperationError("Merging annotation layers needs a canvas (a browser); hide or delete them first, or merge in the browser.");
8222
9222
  }
8223
9223
  await this.renderer.prepareLayerAssets(layers, width, height);
8224
9224
  const data = new LayerCompositor().composite(layers, rect, this.renderer.compositorSources(width, height));
8225
- return _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data }, 4, rect.x, rect.y);
9225
+ return _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data }, 4, rect.x, rect.y);
8226
9226
  }
8227
9227
  /** Document bounds a layer can paint into (pixel content, annotations, or the canvas for the rest). */
8228
9228
  paintBounds(layer) {
@@ -8257,7 +9257,7 @@ var ImageEditorController = (_class7 = class {
8257
9257
  requireUnlocked(upper, "all", "merge it");
8258
9258
  requireUnlocked(lower, "pixels", "merge into it");
8259
9259
  let rect = _nullishCoalesce(unionRect(this.paintBounds(lower), upper.type === "adjustment" ? null : this.paintBounds(upper)), () => ( { x: 0, y: 0, width: 1, height: 1 }));
8260
- const reach = Math.max(_chunk73L6TROJcjs.effectsMargin.call(void 0, lower.effects), upper.type === "adjustment" ? 0 : _chunk73L6TROJcjs.effectsMargin.call(void 0, upper.effects));
9260
+ const reach = Math.max(_chunkT422YCHRcjs.effectsMargin.call(void 0, lower.effects), upper.type === "adjustment" ? 0 : _chunkT422YCHRcjs.effectsMargin.call(void 0, upper.effects));
8261
9261
  if (reach) rect = { x: rect.x - reach, y: rect.y - reach, width: rect.width + 2 * reach, height: rect.height + 2 * reach };
8262
9262
  const base = { ...lower, blend: "normal", opacity: 1 };
8263
9263
  delete base.clipped;
@@ -8268,8 +9268,8 @@ var ImageEditorController = (_class7 = class {
8268
9268
  delete merged.filters;
8269
9269
  delete merged.source;
8270
9270
  delete merged.effects;
8271
- let next = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
8272
- next = _chunk73L6TROJcjs.mapLayer.call(void 0, next, lower.id, () => merged);
9271
+ let next = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
9272
+ next = _chunkT422YCHRcjs.mapLayer.call(void 0, next, lower.id, () => merged);
8273
9273
  this.commitLayers(next, () => {
8274
9274
  this.state.activeLayerId = merged.id;
8275
9275
  this.state.activeTarget = "pixels";
@@ -8326,7 +9326,7 @@ var ImageEditorController = (_class7 = class {
8326
9326
  });
8327
9327
  return bg.id;
8328
9328
  }
8329
- __init47() {this.thumbCache = /* @__PURE__ */ new WeakMap()}
9329
+ __init50() {this.thumbCache = /* @__PURE__ */ new WeakMap()}
8330
9330
  /**
8331
9331
  * A small RGBA preview of a pixel layer over the canvas (or of its mask with `mask: true`),
8332
9332
  * longest side `maxSide` px, point-sampled; `null` for layers without pixels.
@@ -8345,14 +9345,14 @@ var ImageEditorController = (_class7 = class {
8345
9345
  const oy = layer.type === "pixel" ? layer.offset.y : 0;
8346
9346
  const key = `${tw}x${th}:${ox},${oy}`;
8347
9347
  let byKey = this.thumbCache.get(surface);
8348
- const hit = _optionalChain([byKey, 'optionalAccess', _166 => _166.get, 'call', _167 => _167(key)]);
9348
+ const hit = _optionalChain([byKey, 'optionalAccess', _193 => _193.get, 'call', _194 => _194(key)]);
8349
9349
  if (hit) return hit;
8350
9350
  const out = new Uint8ClampedArray(tw * th * 4);
8351
9351
  for (let y = 0; y < th; y++) {
8352
9352
  const dy = Math.min(height - 1, Math.floor((y + 0.5) * height / th)) - oy;
8353
9353
  for (let x = 0; x < tw; x++) {
8354
9354
  const dx = Math.min(width - 1, Math.floor((x + 0.5) * width / tw)) - ox;
8355
- const v = _chunkZOOEX3WTcjs.readPixel.call(void 0, surface, dx, dy);
9355
+ const v = _chunkCRMAXIUVcjs.readPixel.call(void 0, surface, dx, dy);
8356
9356
  const i = (y * tw + x) * 4;
8357
9357
  if (surface.channels === 1) {
8358
9358
  out[i] = out[i + 1] = out[i + 2] = v[0];
@@ -8373,14 +9373,40 @@ var ImageEditorController = (_class7 = class {
8373
9373
  setPaintOptions(options) {
8374
9374
  const cur = this.state.paint;
8375
9375
  const next = {
8376
- brush: options.brush ? _chunk4F3YDIWWcjs.normalizeBrush.call(void 0, { ...cur.brush, ...options.brush }) : cur.brush,
9376
+ brush: options.brush ? _chunkZZOTHJ4Kcjs.normalizeBrush.call(void 0, { ...cur.brush, ...options.brush }) : cur.brush,
8377
9377
  foreground: options.foreground !== void 0 ? toHex2(parseColor(options.foreground)) : cur.foreground,
8378
- background: options.background !== void 0 ? toHex2(parseColor(options.background)) : cur.background
9378
+ background: options.background !== void 0 ? toHex2(parseColor(options.background)) : cur.background,
9379
+ mixer: options.mixer ? _chunkZZOTHJ4Kcjs.normalizeMixer.call(void 0, { ...cur.mixer, ...options.mixer }) : cur.mixer,
9380
+ mixerLoad: cur.mixerLoad
8379
9381
  };
8380
9382
  this.state.paint = next;
8381
9383
  this.notify();
8382
9384
  return next;
8383
9385
  }
9386
+ /**
9387
+ * Loads the Mixer Brush's reservoir full with `color` (default the foreground); the picked-up
9388
+ * colour is kept. View state, no undo. Returns the brush load.
9389
+ */
9390
+ loadMixerBrush(color) {
9391
+ const c = parseColor(_nullishCoalesce(color, () => ( this.state.paint.foreground)));
9392
+ const load = _chunkZZOTHJ4Kcjs.loadMixer.call(void 0, this.state.paint.mixerLoad, [c[0] / 255, c[1] / 255, c[2] / 255]);
9393
+ this.state.paint = { ...this.state.paint, mixerLoad: load };
9394
+ this.notify();
9395
+ return load;
9396
+ }
9397
+ /** Cleans the Mixer Brush: empties the pickup well (the reservoir is kept). Returns the brush load. */
9398
+ cleanMixerBrush() {
9399
+ const load = _chunkZZOTHJ4Kcjs.cleanMixer.call(void 0, this.state.paint.mixerLoad);
9400
+ this.state.paint = { ...this.state.paint, mixerLoad: load };
9401
+ this.notify();
9402
+ return load;
9403
+ }
9404
+ /** Empties the Mixer Brush entirely (no reservoir, nothing picked up). Returns the brush load. */
9405
+ emptyMixerBrush() {
9406
+ this.state.paint = { ...this.state.paint, mixerLoad: _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD };
9407
+ this.notify();
9408
+ return _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD;
9409
+ }
8384
9410
  /** D: black foreground, white background. */
8385
9411
  resetPaintColors() {
8386
9412
  this.setPaintOptions({ foreground: "#000000", background: "#ffffff" });
@@ -8407,7 +9433,7 @@ var ImageEditorController = (_class7 = class {
8407
9433
  if (!layer.visible) throw new LayerOperationError(`Layer "${layer.name || id}" is hidden; show it before you ${action}.`);
8408
9434
  const offset = layer.type === "pixel" ? layer.offset : { x: 0, y: 0 };
8409
9435
  const surface = ch === "mask" ? layer.mask.surface : this.surfaceOf(layer);
8410
- const lockTransparency = ch === "pixels" && Boolean(_optionalChain([layer, 'access', _168 => _168.locks, 'optionalAccess', _169 => _169.transparency]));
9436
+ const lockTransparency = ch === "pixels" && Boolean(_optionalChain([layer, 'access', _195 => _195.locks, 'optionalAccess', _196 => _196.transparency]));
8411
9437
  return { id, layer, channel: ch, offset, surface, lockTransparency };
8412
9438
  }
8413
9439
  /** The layer with its pixels (or mask) replaced by `surface`. */
@@ -8425,8 +9451,12 @@ var ImageEditorController = (_class7 = class {
8425
9451
  */
8426
9452
  beginStroke(init = {}) {
8427
9453
  const tool = _nullishCoalesce(init.tool, () => ( "brush"));
9454
+ if (tool !== "brush" && tool !== "eraser" && tool !== "mixer") throw new LayerOperationError(`Unknown paint tool "${String(tool)}"; use brush, eraser or mixer.`);
8428
9455
  const target = this.paintTarget(init.layerId, init.channel, tool === "eraser" ? "erase" : "paint");
8429
- const brush = _chunk4F3YDIWWcjs.normalizeBrush.call(void 0, { ...this.state.paint.brush, ..._nullishCoalesce(init.brush, () => ( {})) });
9456
+ if (tool === "mixer" && target.channel === "mask") {
9457
+ throw new LayerOperationError("The Mixer Brush paints colour on pixels, not on masks; target pixels (channel pixels), or paint the mask with the brush.");
9458
+ }
9459
+ const brush = _chunkZZOTHJ4Kcjs.normalizeBrush.call(void 0, { ...this.state.paint.brush, ..._nullishCoalesce(init.brush, () => ( {})) });
8430
9460
  const color = parseColor(_nullishCoalesce(init.color, () => ( this.state.paint.foreground)));
8431
9461
  const background = parseColor(_nullishCoalesce(init.background, () => ( this.state.paint.background)));
8432
9462
  const toMaskGrey = (c) => {
@@ -8440,19 +9470,37 @@ var ImageEditorController = (_class7 = class {
8440
9470
  opacity: brush.opacity,
8441
9471
  blend: target.channel === "mask" ? "normal" : brush.blend,
8442
9472
  lockTransparency: target.lockTransparency,
8443
- selection: _optionalChain([this, 'access', _170 => _170.state, 'access', _171 => _171.selection, 'optionalAccess', _172 => _172.bounds]) ? this.state.selection : null,
9473
+ selection: _optionalChain([this, 'access', _197 => _197.state, 'access', _198 => _198.selection, 'optionalAccess', _199 => _199.bounds]) ? this.state.selection : null,
8444
9474
  offset: target.offset
8445
9475
  };
8446
- return new PaintStrokeSession(this, target, new (0, _chunk4F3YDIWWcjs.StrokeCoverage)(brush), apply);
9476
+ if (tool === "mixer") return new PaintStrokeSession(this, target, this.mixerStroke(init, brush), apply);
9477
+ return new PaintStrokeSession(this, target, new (0, _chunkZZOTHJ4Kcjs.StrokeCoverage)(brush), apply);
9478
+ }
9479
+ /** A Mixer Brush stroke's start: the settings, and the load (refilled when asked or set to). */
9480
+ mixerStroke(init, brush) {
9481
+ const settings = _chunkZZOTHJ4Kcjs.normalizeMixer.call(void 0, { ...this.state.paint.mixer, ..._nullishCoalesce(init.mixer, () => ( {})) });
9482
+ let load = this.state.paint.mixerLoad;
9483
+ if (init.color !== void 0 || settings.loadEachStroke) {
9484
+ const c = parseColor(_nullishCoalesce(init.color, () => ( this.state.paint.foreground)));
9485
+ load = _chunkZZOTHJ4Kcjs.loadMixer.call(void 0, load, [c[0] / 255, c[1] / 255, c[2] / 255]);
9486
+ }
9487
+ return {
9488
+ create: (pixels) => new (0, _chunkZZOTHJ4Kcjs.MixerStroke)(brush, settings, load, pixels),
9489
+ end: (after) => {
9490
+ const next = settings.cleanEachStroke ? _chunkZZOTHJ4Kcjs.cleanMixer.call(void 0, after) : after;
9491
+ this.state.paint = { ...this.state.paint, mixerLoad: next };
9492
+ return next;
9493
+ }
9494
+ };
8447
9495
  }
8448
9496
  /** @internal Shows a stroke's live surface (no history). */
8449
9497
  _strokeUpdate(layerId, channel, surface, rects) {
8450
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
9498
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
8451
9499
  this.notify(rects);
8452
9500
  }
8453
9501
  /** @internal Commits a finished stroke as one undo step (`before` is the pre-stroke state). */
8454
9502
  _strokeCommit(before, layerId, channel, surface) {
8455
- if (surface) this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
9503
+ if (surface) this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
8456
9504
  else this.state.layers = before.layers;
8457
9505
  if (surface && !this.isApplyingHistory) {
8458
9506
  this.undoStack.push(before);
@@ -8468,13 +9516,13 @@ var ImageEditorController = (_class7 = class {
8468
9516
  }
8469
9517
  /**
8470
9518
  * Paints a whole stroke in one call (agents, replays): `points` in document pixels with optional
8471
- * pressure, through the brush or eraser. One undo step. Returns the layer, channel, the changed
9519
+ * pressure, through the brush, eraser or Mixer Brush. One undo step. Returns the layer, channel, the changed
8472
9520
  * document bounds and the number of dabs.
8473
9521
  */
8474
9522
  paintStroke(init) {
8475
9523
  if (!Array.isArray(init.points) || !init.points.length) throw new LayerOperationError("points must hold at least one { x, y } point.");
8476
9524
  for (const p of init.points) {
8477
- if (!Number.isFinite(_optionalChain([p, 'optionalAccess', _173 => _173.x])) || !Number.isFinite(_optionalChain([p, 'optionalAccess', _174 => _174.y]))) throw new LayerOperationError("Every point needs finite x and y (document pixels).");
9525
+ if (!Number.isFinite(_optionalChain([p, 'optionalAccess', _200 => _200.x])) || !Number.isFinite(_optionalChain([p, 'optionalAccess', _201 => _201.y]))) throw new LayerOperationError("Every point needs finite x and y (document pixels).");
8478
9526
  }
8479
9527
  const session = this.beginStroke(init);
8480
9528
  session.push(init.points);
@@ -8502,9 +9550,9 @@ var ImageEditorController = (_class7 = class {
8502
9550
  const opacity = _nullishCoalesce(options.opacity, () => ( 1));
8503
9551
  if (!(opacity >= 0 && opacity <= 1)) throw new LayerOperationError("opacity must be from 0 to 1.");
8504
9552
  const blend = _nullishCoalesce(parseBlend(options.blend), () => ( "normal"));
8505
- const sel = options.useSelection !== false && _optionalChain([this, 'access', _175 => _175.state, 'access', _176 => _176.selection, 'optionalAccess', _177 => _177.bounds]) ? this.state.selection : null;
8506
- const region = _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _178 => _178.bounds]), () => ( { x: 0, y: 0, width, height }));
8507
- const coverage = new (0, _chunk4F3YDIWWcjs.CoverageMap)();
9553
+ const sel = options.useSelection !== false && _optionalChain([this, 'access', _202 => _202.state, 'access', _203 => _203.selection, 'optionalAccess', _204 => _204.bounds]) ? this.state.selection : null;
9554
+ const region = _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _205 => _205.bounds]), () => ( { x: 0, y: 0, width, height }));
9555
+ const coverage = new (0, _chunkZZOTHJ4Kcjs.CoverageMap)();
8508
9556
  const ones = new Float32Array(region.width * region.height);
8509
9557
  if (sel) {
8510
9558
  for (let y = 0; y < region.height; y++) {
@@ -8529,7 +9577,7 @@ var ImageEditorController = (_class7 = class {
8529
9577
  offset: target.offset
8530
9578
  };
8531
9579
  const surface = paintCoverageInto(target.surface, coverage, apply, [region]);
8532
- const next = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => this.withSurface(l, target.channel, surface));
9580
+ const next = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => this.withSurface(l, target.channel, surface));
8533
9581
  this.commitLayers(next);
8534
9582
  return { layerId: target.id, channel: target.channel, bounds: region, dabs: 0 };
8535
9583
  }
@@ -8551,12 +9599,12 @@ var ImageEditorController = (_class7 = class {
8551
9599
  const target = this.developLayer();
8552
9600
  let layers = this.state.layers;
8553
9601
  if (target && (DEVELOP_KEYS.some((k) => k in partial) || "process" in partial)) {
8554
- layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, target.id, (l) => withDevelop(l, partial));
9602
+ layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, target.id, (l) => withDevelop(l, partial));
8555
9603
  }
8556
9604
  if ("blur" in partial && typeof partial.blur === "number") {
8557
9605
  const blur = Math.max(0, partial.blur);
8558
9606
  if (this.state.legacyOutputBlur !== void 0) this.state.legacyOutputBlur = blur;
8559
- else if (target) layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, target.id, (l) => withBlur(l, blur));
9607
+ else if (target) layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, target.id, (l) => withBlur(l, blur));
8560
9608
  }
8561
9609
  if ("opacity" in partial && typeof partial.opacity === "number") {
8562
9610
  this.state.outputOpacity = Math.min(1, Math.max(0, partial.opacity));
@@ -8586,7 +9634,7 @@ var ImageEditorController = (_class7 = class {
8586
9634
  this.recordHistory();
8587
9635
  const target = this.developLayer();
8588
9636
  if (target) {
8589
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0,
9637
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0,
8590
9638
  this.state.layers,
8591
9639
  target.id,
8592
9640
  (l) => withBlur(withDevelop(l, { ...DEFAULT_ADJUSTMENTS, process: LATEST_PROCESS_VERSION }), 0)
@@ -8606,7 +9654,7 @@ var ImageEditorController = (_class7 = class {
8606
9654
  return this.getAdjustmentLayers().find((l) => l.id === id);
8607
9655
  }
8608
9656
  adjustmentNodes(layers = this.state.layers) {
8609
- return _chunk73L6TROJcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "adjustment");
9657
+ return _chunkT422YCHRcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "adjustment");
8610
9658
  }
8611
9659
  /**
8612
9660
  * Where a new layer goes when no position is given: directly above the topmost layer that is
@@ -8620,26 +9668,26 @@ var ImageEditorController = (_class7 = class {
8620
9668
  /** Inserts `node` by `aboveId` / `parentId` / adjustment index / default position. */
8621
9669
  placeLayer(layers, node, where) {
8622
9670
  if (where.aboveId) {
8623
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, layers, where.aboveId);
8624
- if (loc) return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _179 => _179.parent, 'optionalAccess', _180 => _180.id]), () => ( null)), loc.index + 1);
9671
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, layers, where.aboveId);
9672
+ if (loc) return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _206 => _206.parent, 'optionalAccess', _207 => _207.id]), () => ( null)), loc.index + 1);
8625
9673
  }
8626
9674
  if (where.parentId) {
8627
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, layers, where.parentId);
8628
- if (loc && loc.layer.type === "group") return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, node, loc.layer.id);
9675
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, layers, where.parentId);
9676
+ if (loc && loc.layer.type === "group") return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, node, loc.layer.id);
8629
9677
  }
8630
9678
  if (where.adjustmentIndex !== void 0) {
8631
9679
  const nodes = this.adjustmentNodes(layers);
8632
9680
  const at = Math.max(0, Math.min(nodes.length, Math.round(where.adjustmentIndex)));
8633
9681
  if (at < nodes.length) {
8634
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, layers, nodes[at].id);
8635
- return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _181 => _181.parent, 'optionalAccess', _182 => _182.id]), () => ( null)), loc.index);
9682
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, layers, nodes[at].id);
9683
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _208 => _208.parent, 'optionalAccess', _209 => _209.id]), () => ( null)), loc.index);
8636
9684
  }
8637
9685
  if (nodes.length) {
8638
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, layers, nodes[nodes.length - 1].id);
8639
- return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _183 => _183.parent, 'optionalAccess', _184 => _184.id]), () => ( null)), loc.index + 1);
9686
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, layers, nodes[nodes.length - 1].id);
9687
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _210 => _210.parent, 'optionalAccess', _211 => _211.id]), () => ( null)), loc.index + 1);
8640
9688
  }
8641
9689
  }
8642
- return _chunk73L6TROJcjs.insertLayer.call(void 0, layers, node, null, this.defaultInsertIndex(layers));
9690
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, layers, node, null, this.defaultInsertIndex(layers));
8643
9691
  }
8644
9692
  /** `setAdjustments({ layers })`: updates nodes by id in place, removes missing ones, adds new ones. */
8645
9693
  replaceAdjustmentNodes(layers, next) {
@@ -8648,7 +9696,7 @@ var ImageEditorController = (_class7 = class {
8648
9696
  let out = layers;
8649
9697
  for (const node of this.adjustmentNodes(layers)) {
8650
9698
  const update = byId.get(node.id);
8651
- out = _chunk73L6TROJcjs.mapLayer.call(void 0, out, node.id, () => update ? mergeAdjustmentNode(node, update, width, height) : null);
9699
+ out = _chunkT422YCHRcjs.mapLayer.call(void 0, out, node.id, () => update ? mergeAdjustmentNode(node, update, width, height) : null);
8652
9700
  }
8653
9701
  const existing = new Set(this.adjustmentNodes(out).map((n) => n.id));
8654
9702
  for (const l of next) {
@@ -8667,7 +9715,7 @@ var ImageEditorController = (_class7 = class {
8667
9715
  */
8668
9716
  addAdjustmentLayer(init, index) {
8669
9717
  const spec = typeof init === "string" ? { kind: init } : init;
8670
- const ids = new Set(_chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
9718
+ const ids = new Set(_chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
8671
9719
  const layer = createAdjustmentLayer(spec.kind, {
8672
9720
  id: spec.id && !ids.has(spec.id) ? spec.id : void 0,
8673
9721
  name: spec.name,
@@ -8696,7 +9744,7 @@ var ImageEditorController = (_class7 = class {
8696
9744
  * Returns false for an unknown id.
8697
9745
  */
8698
9746
  updateAdjustmentLayer(id, update, commitToHistory = true) {
8699
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, this.state.layers, id);
9747
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, this.state.layers, id);
8700
9748
  if (!loc || loc.layer.type !== "adjustment") return false;
8701
9749
  const { width, height } = this.naturalSize;
8702
9750
  const node = loc.layer;
@@ -8724,16 +9772,16 @@ var ImageEditorController = (_class7 = class {
8724
9772
  if (mask) next.mask = mask;
8725
9773
  else delete next.mask;
8726
9774
  }
8727
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, id, () => next);
9775
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, id, () => next);
8728
9776
  this.notify();
8729
9777
  return true;
8730
9778
  }
8731
9779
  /** Removes a layer as one undo step. Returns false for an unknown id. */
8732
9780
  removeAdjustmentLayer(id) {
8733
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, this.state.layers, id);
9781
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, this.state.layers, id);
8734
9782
  if (!loc || loc.layer.type !== "adjustment") return false;
8735
9783
  this.recordHistory();
8736
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
9784
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
8737
9785
  if (this.state.activeLayerId === id) this.state.activeLayerId = null;
8738
9786
  this.notify();
8739
9787
  return true;
@@ -8746,9 +9794,9 @@ var ImageEditorController = (_class7 = class {
8746
9794
  if (to === from) return layers;
8747
9795
  const node = nodes[from];
8748
9796
  const anchor = nodes[to];
8749
- const without = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, id, () => null);
8750
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, without, anchor.id);
8751
- return _chunk73L6TROJcjs.insertLayer.call(void 0, without, node, _nullishCoalesce(_optionalChain([loc, 'access', _185 => _185.parent, 'optionalAccess', _186 => _186.id]), () => ( null)), to > from ? loc.index + 1 : loc.index);
9797
+ const without = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, id, () => null);
9798
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, without, anchor.id);
9799
+ return _chunkT422YCHRcjs.insertLayer.call(void 0, without, node, _nullishCoalesce(_optionalChain([loc, 'access', _212 => _212.parent, 'optionalAccess', _213 => _213.id]), () => ( null)), to > from ? loc.index + 1 : loc.index);
8752
9800
  }
8753
9801
  /** Moves a layer to `toIndex` among the adjustment layers (0 = bottom) as one undo step. Returns false if nothing moved. */
8754
9802
  moveAdjustmentLayer(id, toIndex) {
@@ -8773,7 +9821,7 @@ var ImageEditorController = (_class7 = class {
8773
9821
  if (!nodes.length) return;
8774
9822
  this.recordHistory();
8775
9823
  let layers = this.state.layers;
8776
- for (const n of nodes) layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, n.id, () => null);
9824
+ for (const n of nodes) layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, n.id, () => null);
8777
9825
  this.state.layers = layers;
8778
9826
  if (nodes.some((n) => n.id === this.state.activeLayerId)) this.state.activeLayerId = null;
8779
9827
  this.notify();
@@ -8784,7 +9832,7 @@ var ImageEditorController = (_class7 = class {
8784
9832
  return _nullishCoalesce(this.state.selection, () => ( null));
8785
9833
  }
8786
9834
  get hasSelection() {
8787
- return Boolean(_optionalChain([this, 'access', _187 => _187.state, 'access', _188 => _188.selection, 'optionalAccess', _189 => _189.bounds]));
9835
+ return Boolean(_optionalChain([this, 'access', _214 => _214.state, 'access', _215 => _215.selection, 'optionalAccess', _216 => _216.bounds]));
8788
9836
  }
8789
9837
  get naturalSize() {
8790
9838
  return {
@@ -8874,13 +9922,13 @@ var ImageEditorController = (_class7 = class {
8874
9922
  try {
8875
9923
  const canvas = await this.renderSource();
8876
9924
  const ctx = canvas.getContext("2d");
8877
- const data2 = _optionalChain([ctx, 'optionalAccess', _190 => _190.getImageData, 'optionalCall', _191 => _191(0, 0, width, height)]);
9925
+ const data2 = _optionalChain([ctx, 'optionalAccess', _217 => _217.getImageData, 'optionalCall', _218 => _218(0, 0, width, height)]);
8878
9926
  if (data2 && data2.data && data2.data.length >= width * height * 4) {
8879
9927
  base = { width, height, data: data2.data };
8880
9928
  this.samplePixels = base;
8881
9929
  this.samplePixelsOverride = false;
8882
9930
  }
8883
- } catch (e23) {
9931
+ } catch (e25) {
8884
9932
  base = null;
8885
9933
  }
8886
9934
  }
@@ -8895,8 +9943,8 @@ var ImageEditorController = (_class7 = class {
8895
9943
  if (!layer || layer.type !== "pixel") {
8896
9944
  throw new LayerOperationError("Sampling the active layer needs an active pixel layer; select one, or sample the composite.");
8897
9945
  }
8898
- const surface = layer.source === "document" && options.pixels ? _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, options.pixels, 4) : this.surfaceOf(layer);
8899
- return { width, height, data: _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, { x: -layer.offset.x, y: -layer.offset.y, width, height }) };
9946
+ const surface = layer.source === "document" && options.pixels ? _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, options.pixels, 4) : this.surfaceOf(layer);
9947
+ return { width, height, data: _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, { x: -layer.offset.x, y: -layer.offset.y, width, height }) };
8900
9948
  }
8901
9949
  if (legacy && !options.sampleMerged) return base;
8902
9950
  this.syncViews();
@@ -8909,7 +9957,7 @@ var ImageEditorController = (_class7 = class {
8909
9957
  const sources = {
8910
9958
  width,
8911
9959
  height,
8912
- surfaceOf: (l) => l.source === "document" && pixels ? _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, pixels, 4) : this.surfaceOf(l),
9960
+ surfaceOf: (l) => l.source === "document" && pixels ? _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, pixels, 4) : this.surfaceOf(l),
8913
9961
  version: pixels ? "pixels" : this.sourceVersion()
8914
9962
  };
8915
9963
  const stack = withoutAnnotations(this.state.layers);
@@ -8940,7 +9988,7 @@ var ImageEditorController = (_class7 = class {
8940
9988
  /** Select › Modify: grow, shrink, feather, border or smooth by `radius` pixels (one undo step). */
8941
9989
  modifySelection(op, radius) {
8942
9990
  const sel = this.state.selection;
8943
- if (!_optionalChain([sel, 'optionalAccess', _192 => _192.bounds])) return false;
9991
+ if (!_optionalChain([sel, 'optionalAccess', _219 => _219.bounds])) return false;
8944
9992
  return this.setSelection(modifySelection(sel, op, radius));
8945
9993
  }
8946
9994
  /**
@@ -8949,7 +9997,7 @@ var ImageEditorController = (_class7 = class {
8949
9997
  */
8950
9998
  async refineSelection(params, options = {}) {
8951
9999
  const sel = this.state.selection;
8952
- if (!_optionalChain([sel, 'optionalAccess', _193 => _193.bounds])) return false;
10000
+ if (!_optionalChain([sel, 'optionalAccess', _220 => _220.bounds])) return false;
8953
10001
  const pixels = (_nullishCoalesce(params.radius, () => ( 0))) > 0 ? await this.requirePixels(options) : null;
8954
10002
  return this.setSelection(refineSelection(pixels, sel, params));
8955
10003
  }
@@ -8966,7 +10014,7 @@ var ImageEditorController = (_class7 = class {
8966
10014
  const canvas = this.renderer.createCanvas(w, h);
8967
10015
  const ctx = canvas.getContext("2d");
8968
10016
  if (ctx) ctx.drawImage(img, 0, 0, w, h);
8969
- const data = _optionalChain([ctx, 'optionalAccess', _194 => _194.getImageData, 'optionalCall', _195 => _195(0, 0, w, h)]);
10017
+ const data = _optionalChain([ctx, 'optionalAccess', _221 => _221.getImageData, 'optionalCall', _222 => _222(0, 0, w, h)]);
8970
10018
  if (!data) throw new Error("The mask image pixels are not available (no canvas access); pass pixels.");
8971
10019
  pixels = { width: w, height: h, data: data.data };
8972
10020
  } else {
@@ -8985,7 +10033,7 @@ var ImageEditorController = (_class7 = class {
8985
10033
  maskFromSelection(sel, props = {}) {
8986
10034
  const { width, height } = this.naturalSize;
8987
10035
  const sized = sel.width === width && sel.height === height ? sel : resizeSelection(sel, width, height);
8988
- const mask = { surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0), defaultValue: 0 };
10036
+ const mask = { surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0), defaultValue: 0 };
8989
10037
  return withMaskProps(mask, props);
8990
10038
  }
8991
10039
  /**
@@ -8994,14 +10042,14 @@ var ImageEditorController = (_class7 = class {
8994
10042
  */
8995
10043
  applySelectionAsLayerMask(layerId, props = {}) {
8996
10044
  const sel = this.state.selection;
8997
- if (!_optionalChain([sel, 'optionalAccess', _196 => _196.bounds]) || !this.getAdjustmentLayer(layerId)) return false;
10045
+ if (!_optionalChain([sel, 'optionalAccess', _223 => _223.bounds]) || !this.getAdjustmentLayer(layerId)) return false;
8998
10046
  return this.setLayerMask(layerId, this.maskFromSelection(sel, props));
8999
10047
  }
9000
10048
  setLayerMask(layerId, mask, commitToHistory = true) {
9001
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, this.state.layers, layerId);
10049
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, this.state.layers, layerId);
9002
10050
  if (!loc) return false;
9003
10051
  if (commitToHistory) this.recordHistory();
9004
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => {
10052
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => {
9005
10053
  const next = { ...l };
9006
10054
  if (mask) next.mask = mask;
9007
10055
  else delete next.mask;
@@ -9025,11 +10073,11 @@ var ImageEditorController = (_class7 = class {
9025
10073
  /** Load Selection from a layer mask (its pixels; density and feather are not applied). */
9026
10074
  selectionFromLayerMask(layerId, mode = "replace") {
9027
10075
  const layer = this.getLayer(layerId);
9028
- if (!_optionalChain([layer, 'optionalAccess', _197 => _197.mask]) || layer.mask.source) return false;
10076
+ if (!_optionalChain([layer, 'optionalAccess', _224 => _224.mask]) || layer.mask.source) return false;
9029
10077
  const { width, height } = this.naturalSize;
9030
10078
  const ox = layer.type === "pixel" ? layer.offset.x : 0;
9031
10079
  const oy = layer.type === "pixel" ? layer.offset.y : 0;
9032
- const data = _chunkZOOEX3WTcjs.readRegion.call(void 0, layer.mask.surface, { x: -ox, y: -oy, width, height });
10080
+ const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, layer.mask.surface, { x: -ox, y: -oy, width, height });
9033
10081
  const sel = createSelectionMask(width, height, new Uint8Array(data.buffer, data.byteOffset, data.length));
9034
10082
  return this.setSelection(sel, mode);
9035
10083
  }
@@ -9058,10 +10106,10 @@ var ImageEditorController = (_class7 = class {
9058
10106
  if (target) {
9059
10107
  const merged = { ...this.state.depthMask, ...partial };
9060
10108
  merged.depthRange = [...merged.depthRange];
9061
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
10109
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
9062
10110
  const next = { ...l };
9063
10111
  if (isDefaultDepthMask(merged)) {
9064
- if (_optionalChain([next, 'access', _198 => _198.mask, 'optionalAccess', _199 => _199.source])) delete next.mask;
10112
+ if (_optionalChain([next, 'access', _225 => _225.mask, 'optionalAccess', _226 => _226.source])) delete next.mask;
9065
10113
  } else next.mask = depthRasterMask(merged);
9066
10114
  return next;
9067
10115
  });
@@ -9071,8 +10119,8 @@ var ImageEditorController = (_class7 = class {
9071
10119
  resetDepthMask() {
9072
10120
  this.recordHistory();
9073
10121
  const target = this.developLayer();
9074
- if (_optionalChain([target, 'optionalAccess', _200 => _200.mask, 'optionalAccess', _201 => _201.source])) {
9075
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
10122
+ if (_optionalChain([target, 'optionalAccess', _227 => _227.mask, 'optionalAccess', _228 => _228.source])) {
10123
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
9076
10124
  const next = { ...l };
9077
10125
  delete next.mask;
9078
10126
  return next;
@@ -9082,7 +10130,7 @@ var ImageEditorController = (_class7 = class {
9082
10130
  }
9083
10131
  // --- Annotations & Layers ---
9084
10132
  annotationLayer(id) {
9085
- return _chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).find(
10133
+ return _chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).find(
9086
10134
  (l) => l.type === "annotation" && l.annotation.id === id
9087
10135
  );
9088
10136
  }
@@ -9092,8 +10140,8 @@ var ImageEditorController = (_class7 = class {
9092
10140
  const id = `ann_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
9093
10141
  const fullAnnotation = { ...annotation, id };
9094
10142
  const layer = annotationLayerFor(fullAnnotation);
9095
- const loc = placement.aboveId ? _chunk73L6TROJcjs.findLayer.call(void 0, this.state.layers, placement.aboveId) : null;
9096
- this.state.layers = loc ? _chunk73L6TROJcjs.insertLayer.call(void 0, this.state.layers, layer, _nullishCoalesce(_optionalChain([loc, 'access', _202 => _202.parent, 'optionalAccess', _203 => _203.id]), () => ( null)), loc.index + 1) : _chunk73L6TROJcjs.insertLayer.call(void 0, this.state.layers, layer, null);
10143
+ const loc = placement.aboveId ? _chunkT422YCHRcjs.findLayer.call(void 0, this.state.layers, placement.aboveId) : null;
10144
+ this.state.layers = loc ? _chunkT422YCHRcjs.insertLayer.call(void 0, this.state.layers, layer, _nullishCoalesce(_optionalChain([loc, 'access', _229 => _229.parent, 'optionalAccess', _230 => _230.id]), () => ( null)), loc.index + 1) : _chunkT422YCHRcjs.insertLayer.call(void 0, this.state.layers, layer, null);
9097
10145
  this.state.selectedAnnotationId = id;
9098
10146
  this.notify();
9099
10147
  return id;
@@ -9106,14 +10154,14 @@ var ImageEditorController = (_class7 = class {
9106
10154
  if (layer) {
9107
10155
  const annotation = { ...layer.annotation, ...partial, id };
9108
10156
  const name = layer.name === annotationLayerName(layer.annotation) ? annotationLayerName(annotation) : layer.name;
9109
- this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => ({ ...layer, annotation, name }));
10157
+ this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => ({ ...layer, annotation, name }));
9110
10158
  }
9111
10159
  this.notify();
9112
10160
  }
9113
10161
  removeAnnotation(id) {
9114
10162
  this.recordHistory();
9115
10163
  const layer = this.annotationLayer(id);
9116
- if (layer) this.state.layers = _chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => null);
10164
+ if (layer) this.state.layers = _chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => null);
9117
10165
  if (this.state.selectedAnnotationId === id) {
9118
10166
  this.state.selectedAnnotationId = null;
9119
10167
  }
@@ -9122,7 +10170,7 @@ var ImageEditorController = (_class7 = class {
9122
10170
  clearAnnotations() {
9123
10171
  this.recordHistory();
9124
10172
  let layers = this.state.layers;
9125
- for (const l of _chunk73L6TROJcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, l.id, () => null);
10173
+ for (const l of _chunkT422YCHRcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, l.id, () => null);
9126
10174
  this.state.layers = layers;
9127
10175
  this.state.selectedAnnotationId = null;
9128
10176
  this.notify();
@@ -9162,7 +10210,7 @@ var ImageEditorController = (_class7 = class {
9162
10210
  this.notify();
9163
10211
  }
9164
10212
  // --- Rendering & Export ---
9165
- __init48() {this.blankSource = null}
10213
+ __init51() {this.blankSource = null}
9166
10214
  /**
9167
10215
  * What the renderer draws from: the source image, or, for a document without one (an opened
9168
10216
  * PSD, a v3 document loaded on its own), a transparent canvas of the document size, since every
@@ -9190,7 +10238,7 @@ var ImageEditorController = (_class7 = class {
9190
10238
  dirty: dirty === "all" ? void 0 : dirty,
9191
10239
  checkpointLayerId: this.state.activeLayerId
9192
10240
  });
9193
- } catch (e24) {
10241
+ } catch (e26) {
9194
10242
  }
9195
10243
  }
9196
10244
  async renderExport(options) {
@@ -9199,9 +10247,9 @@ var ImageEditorController = (_class7 = class {
9199
10247
  return this.renderer.createCanvas(1, 1);
9200
10248
  }
9201
10249
  this.syncViews();
9202
- if (_optionalChain([options, 'optionalAccess', _204 => _204.layerIds])) {
10250
+ if (_optionalChain([options, 'optionalAccess', _231 => _231.layerIds])) {
9203
10251
  const keep = new Set(options.layerIds);
9204
- const layers = _chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => keep.has(l.id));
10252
+ const layers = _chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => keep.has(l.id));
9205
10253
  return this.renderer.renderExport(source, { ...this.state, layers }, options);
9206
10254
  }
9207
10255
  return this.renderer.renderExport(source, this.state, options);
@@ -9311,10 +10359,10 @@ var ImageEditorController = (_class7 = class {
9311
10359
  /** No source image, and no layer reading one (an opened PSD): the layers are the whole document. */
9312
10360
  isSourceless() {
9313
10361
  if (this.imageElement || this.state.sourceUrl || !this.state.layers.length) return false;
9314
- return !_chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).some((l) => l.type === "pixel" && l.source === "document");
10362
+ return !_chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).some((l) => l.type === "pixel" && l.source === "document");
9315
10363
  }
9316
10364
  get isMultiLayer() {
9317
- return _chunk73L6TROJcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => l.type === "pixel" || l.type === "group").length > 1;
10365
+ return _chunkT422YCHRcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => l.type === "pixel" || l.type === "group").length > 1;
9318
10366
  }
9319
10367
  /**
9320
10368
  * Applies an inpainted result (natural image space, see `toSourceDataURL`) as ONE undoable step.
@@ -9332,7 +10380,7 @@ var ImageEditorController = (_class7 = class {
9332
10380
  let px = await this.decodeImage(newDataUrl);
9333
10381
  if (px.width !== width || px.height !== height) px = resizePixels(px, width, height);
9334
10382
  const data = new Uint8ClampedArray(px.data);
9335
- const sel = _optionalChain([this, 'access', _205 => _205.state, 'access', _206 => _206.selection, 'optionalAccess', _207 => _207.bounds]) ? this.state.selection : null;
10383
+ const sel = _optionalChain([this, 'access', _232 => _232.state, 'access', _233 => _233.selection, 'optionalAccess', _234 => _234.bounds]) ? this.state.selection : null;
9336
10384
  if (sel) for (let p = 0, i = 3; p < width * height; p++, i += 4) data[i] = Math.round(data[i] * sel.data[p] / 255);
9337
10385
  return this.addPixelLayer({ name: "Inpaint", pixels: { width, height, data } });
9338
10386
  }
@@ -9356,8 +10404,8 @@ var ImageEditorController = (_class7 = class {
9356
10404
  if (px.width !== width || px.height !== height) px = resizePixels(px, width, height);
9357
10405
  const alpha = new Uint8ClampedArray(width * height);
9358
10406
  for (let p = 0; p < alpha.length; p++) alpha[p] = px.data[p * 4 + 3];
9359
- let surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: alpha }, 1, 0, 0, 0);
9360
- if (target.offset.x || target.offset.y) surface = _chunkZOOEX3WTcjs.translateSurface.call(void 0, surface, -target.offset.x, -target.offset.y);
10407
+ let surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: alpha }, 1, 0, 0, 0);
10408
+ if (target.offset.x || target.offset.y) surface = _chunkCRMAXIUVcjs.translateSurface.call(void 0, surface, -target.offset.x, -target.offset.y);
9361
10409
  this.commitLayers(setLayerMask(this.state.layers, target.id, { surface, defaultValue: 0 }));
9362
10410
  return target.id;
9363
10411
  }
@@ -9384,7 +10432,7 @@ var ImageEditorController = (_class7 = class {
9384
10432
  if (layer.locks) next.locks = layer.locks;
9385
10433
  if (this.state.selectedAnnotationId === layer.annotation.id) this.state.selectedAnnotationId = null;
9386
10434
  } else if (layer.type === "pixel") {
9387
- if (!_optionalChain([layer, 'access', _208 => _208.filters, 'optionalAccess', _209 => _209.length])) throw new LayerOperationError(`Layer "${layer.name || id}" is already pixels with no filters to bake.`);
10435
+ if (!_optionalChain([layer, 'access', _235 => _235.filters, 'optionalAccess', _236 => _236.length])) throw new LayerOperationError(`Layer "${layer.name || id}" is already pixels with no filters to bake.`);
9388
10436
  requireUnlocked(layer, "pixels", "rasterize it");
9389
10437
  const spatial = layer.filters.some((f) => f.enabled && f.kind === "blur");
9390
10438
  const content = { ...layer, visible: true, opacity: 1, blend: "normal" };
@@ -9397,12 +10445,12 @@ var ImageEditorController = (_class7 = class {
9397
10445
  delete next.filters;
9398
10446
  delete next.source;
9399
10447
  if (layer.mask && (layer.offset.x || layer.offset.y)) {
9400
- next.mask = { ...layer.mask, surface: _chunkZOOEX3WTcjs.translateSurface.call(void 0, layer.mask.surface, layer.offset.x, layer.offset.y) };
10448
+ next.mask = { ...layer.mask, surface: _chunkCRMAXIUVcjs.translateSurface.call(void 0, layer.mask.surface, layer.offset.x, layer.offset.y) };
9401
10449
  }
9402
10450
  } else {
9403
10451
  throw new LayerOperationError(`Only annotation layers and pixel layers with filters rasterize; "${layer.name || id}" is a ${layer.type} layer. Merge it down or flatten instead.`);
9404
10452
  }
9405
- this.commitLayers(_chunk73L6TROJcjs.mapLayer.call(void 0, this.state.layers, id, () => next));
10453
+ this.commitLayers(_chunkT422YCHRcjs.mapLayer.call(void 0, this.state.layers, id, () => next));
9406
10454
  return id;
9407
10455
  }
9408
10456
  // --- PSD ---
@@ -9429,14 +10477,18 @@ var ImageEditorController = (_class7 = class {
9429
10477
  delete s.legacyOutputBlur;
9430
10478
  s.selection = null;
9431
10479
  s.selectedAnnotationId = null;
9432
- const pixels = _chunk73L6TROJcjs.flattenLayers.call(void 0, result.layers).filter((l) => l.type === "pixel");
10480
+ const pixels = _chunkT422YCHRcjs.flattenLayers.call(void 0, result.layers).filter((l) => l.type === "pixel");
9433
10481
  s.activeLayerId = pixels.length ? pixels[pixels.length - 1].id : null;
9434
10482
  s.activeTarget = "pixels";
9435
10483
  this.psdResolution = result.resolution;
10484
+ if (result.patterns.length) s.patterns = result.patterns;
10485
+ else delete s.patterns;
10486
+ if (result.globalLight) s.globalLight = result.globalLight;
10487
+ else delete s.globalLight;
9436
10488
  this.lastLoadProblems = result.warnings;
9437
10489
  this.notify();
9438
10490
  return {
9439
- layerIds: _chunk73L6TROJcjs.flattenLayers.call(void 0, result.layers).map((l) => l.id),
10491
+ layerIds: _chunkT422YCHRcjs.flattenLayers.call(void 0, result.layers).map((l) => l.id),
9440
10492
  warnings: result.warnings,
9441
10493
  width: result.width,
9442
10494
  height: result.height,
@@ -9461,7 +10513,7 @@ var ImageEditorController = (_class7 = class {
9461
10513
  const compositor = new LayerCompositor();
9462
10514
  const bakeMask = (layer) => {
9463
10515
  const mask = layer.mask;
9464
- if (!_optionalChain([mask, 'optionalAccess', _210 => _210.source])) return mask;
10516
+ if (!_optionalChain([mask, 'optionalAccess', _237 => _237.source])) return mask;
9465
10517
  add("Parametric (depth) masks were baked into pixel masks", layer.name);
9466
10518
  const plain3 = { ...layer, mask: { ...mask, density: 1, feather: 0, enabled: true } };
9467
10519
  const ox = layer.type === "pixel" ? layer.offset.x : 0;
@@ -9470,13 +10522,18 @@ var ImageEditorController = (_class7 = class {
9470
10522
  const bytes = new Uint8ClampedArray(width * height);
9471
10523
  if (coverage) for (let i = 0; i < bytes.length; i++) bytes[i] = Math.round(coverage[i] * 255);
9472
10524
  else bytes.fill(255);
9473
- const baked = { surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: bytes }, 1, -ox, -oy), defaultValue: 0 };
10525
+ const baked = { surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: bytes }, 1, -ox, -oy), defaultValue: 0 };
9474
10526
  if (mask.density !== void 0 && mask.density < 1) baked.density = mask.density;
9475
10527
  if (mask.feather) baked.feather = mask.feather;
9476
10528
  if (mask.enabled === false) baked.enabled = false;
9477
10529
  return baked;
9478
10530
  };
9479
10531
  const prepare = async (layer) => {
10532
+ const p = await prepareLayer(layer);
10533
+ if (_optionalChain([p, 'optionalAccess', _238 => _238.blend]) === "pigment") add("The Pigment blend mode has no PSD equivalent and was written as Normal", layer.name);
10534
+ return p;
10535
+ };
10536
+ const prepareLayer = async (layer) => {
9480
10537
  if (layer.type === "group") {
9481
10538
  const children = [];
9482
10539
  for (const c of layer.children) {
@@ -9496,6 +10553,7 @@ var ImageEditorController = (_class7 = class {
9496
10553
  const content = { ...layer, visible: true, opacity: 1, blend: "normal", annotation: { ...layer.annotation, blend: void 0 } };
9497
10554
  delete content.mask;
9498
10555
  delete content.clipped;
10556
+ delete content.effects;
9499
10557
  const data = compositor.composite([content], canvas, sources);
9500
10558
  const out2 = {
9501
10559
  type: "pixel",
@@ -9504,11 +10562,12 @@ var ImageEditorController = (_class7 = class {
9504
10562
  visible: layer.visible,
9505
10563
  opacity: layer.opacity,
9506
10564
  blend,
9507
- surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
10565
+ surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
9508
10566
  offset: { x: 0, y: 0 }
9509
10567
  };
9510
10568
  if (layer.clipped) out2.clipped = true;
9511
10569
  if (layer.locks) out2.locks = layer.locks;
10570
+ if (layer.effects) out2.effects = layer.effects;
9512
10571
  const mask2 = bakeMask(layer);
9513
10572
  if (mask2) out2.mask = mask2;
9514
10573
  return out2;
@@ -9518,17 +10577,18 @@ var ImageEditorController = (_class7 = class {
9518
10577
  out.surface = this.surfaceOf(layer);
9519
10578
  delete out.source;
9520
10579
  }
9521
- const active = _nullishCoalesce(_optionalChain([layer, 'access', _211 => _211.filters, 'optionalAccess', _212 => _212.filter, 'call', _213 => _213(isActiveFilter)]), () => ( []));
10580
+ const active = _nullishCoalesce(_optionalChain([layer, 'access', _239 => _239.filters, 'optionalAccess', _240 => _240.filter, 'call', _241 => _241(isActiveFilter)]), () => ( []));
9522
10581
  if (active.length) {
9523
10582
  add("Layer filters (develop, blur) were baked into the pixels", layer.name);
9524
10583
  const content = { ...out, visible: true, opacity: 1, blend: "normal" };
9525
10584
  delete content.mask;
9526
10585
  delete content.clipped;
9527
10586
  delete content.fillOpacity;
10587
+ delete content.effects;
9528
10588
  const data = compositor.composite([content], canvas, sources);
9529
- out = { ...out, surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, -layer.offset.x, -layer.offset.y) };
10589
+ out = { ...out, surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, -layer.offset.x, -layer.offset.y) };
9530
10590
  }
9531
- if (_optionalChain([layer, 'access', _214 => _214.filters, 'optionalAccess', _215 => _215.some, 'call', _216 => _216((f) => !f.enabled)])) add("Disabled layer filters were left out", layer.name);
10591
+ if (_optionalChain([layer, 'access', _242 => _242.filters, 'optionalAccess', _243 => _243.some, 'call', _244 => _244((f) => !f.enabled)])) add("Disabled layer filters were left out", layer.name);
9532
10592
  delete out.filters;
9533
10593
  const mask = bakeMask(layer);
9534
10594
  if (mask) out.mask = mask;
@@ -9547,7 +10607,8 @@ var ImageEditorController = (_class7 = class {
9547
10607
  if (s.legacyOutputBlur) warnings.push("The document-level blur of an old document is not written.");
9548
10608
  for (const [msg, names] of note) warnings.push(`${msg} (${names.length === 1 ? "layer" : "layers"} ${names.map((n) => `"${n}"`).join(", ")}).`);
9549
10609
  const merged = compositor.composite(prepared, canvas, { ...sources, version: `psd:${Date.now()}` });
9550
- const result = exportPsd({ width, height, layers: prepared, merged, resolution: this.psdResolution });
10610
+ const result = exportPsd({ width, height, layers: prepared, merged, resolution: this.psdResolution, patterns: this.state.patterns, globalLight: this.state.globalLight });
10611
+ warnings.push(...result.warnings);
9551
10612
  return { bytes: result.bytes, warnings, psb: result.psb, width, height };
9552
10613
  }
9553
10614
  async replaceSource(src, clearAnnotations) {
@@ -9580,16 +10641,16 @@ var ImageEditorController = (_class7 = class {
9580
10641
  );
9581
10642
  }
9582
10643
  layers = resizeLegacyMasks(layers, prev, next.dimensions);
9583
- for (const l of _chunk73L6TROJcjs.flattenLayers.call(void 0, layers)) {
10644
+ for (const l of _chunkT422YCHRcjs.flattenLayers.call(void 0, layers)) {
9584
10645
  if (l.type === "annotation") {
9585
- layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, annotation: scaleAnnotation(l.annotation, sx, sy) }));
10646
+ layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, annotation: scaleAnnotation(l.annotation, sx, sy) }));
9586
10647
  }
9587
10648
  }
9588
10649
  }
9589
10650
  const bg = developTarget(layers, null);
9590
- if (bg && bg.source !== "document") layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, bg.id, () => ({ ...bg, source: "document" }));
10651
+ if (bg && bg.source !== "document") layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, bg.id, () => ({ ...bg, source: "document" }));
9591
10652
  if (clearAnnotations) {
9592
- for (const l of _chunk73L6TROJcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunk73L6TROJcjs.mapLayer.call(void 0, layers, l.id, () => null);
10653
+ for (const l of _chunkT422YCHRcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunkT422YCHRcjs.mapLayer.call(void 0, layers, l.id, () => null);
9593
10654
  this.state.selectedAnnotationId = null;
9594
10655
  }
9595
10656
  this.state.layers = layers;
@@ -9597,7 +10658,7 @@ var ImageEditorController = (_class7 = class {
9597
10658
  }
9598
10659
  toJSON(options) {
9599
10660
  const out = this.serializeState();
9600
- if (_optionalChain([this, 'access', _217 => _217.state, 'access', _218 => _218.selection, 'optionalAccess', _219 => _219.bounds])) out.selection = serializeSelection(this.state.selection);
10661
+ if (_optionalChain([this, 'access', _245 => _245.state, 'access', _246 => _246.selection, 'optionalAccess', _247 => _247.bounds])) out.selection = serializeSelection(this.state.selection);
9601
10662
  if (!options || out.version !== LAYERED_SCHEMA_VERSION) return options ? Promise.resolve(out) : out;
9602
10663
  return serializeLayersExternal(this.state.layers, options.store).then(({ layers, assets }) => ({ ...out, layers, assets }));
9603
10664
  }
@@ -9624,7 +10685,7 @@ var ImageEditorController = (_class7 = class {
9624
10685
  if (data.selection) {
9625
10686
  try {
9626
10687
  selection = normalizeSelection(deserializeSelection(data.selection));
9627
- } catch (e25) {
10688
+ } catch (e27) {
9628
10689
  selection = null;
9629
10690
  }
9630
10691
  }
@@ -9633,7 +10694,7 @@ var ImageEditorController = (_class7 = class {
9633
10694
  this.notify();
9634
10695
  }
9635
10696
  /** Problems found by the last `loadJSON` / `initialState` of a v3 document (unreadable layers or assets). */
9636
- __init49() {this.lastLoadProblems = []}
10697
+ __init52() {this.lastLoadProblems = []}
9637
10698
  applyStored(raw) {
9638
10699
  const s = this.state;
9639
10700
  const data = migrateSerializedImageEditorState(raw);
@@ -9647,10 +10708,13 @@ var ImageEditorController = (_class7 = class {
9647
10708
  s.outputOpacity = data.opacity;
9648
10709
  if (typeof data.legacyOutputBlur === "number" && data.legacyOutputBlur >= 0) s.legacyOutputBlur = data.legacyOutputBlur;
9649
10710
  else delete s.legacyOutputBlur;
9650
- s.activeLayerId = data.activeLayerId && _chunk73L6TROJcjs.findLayer.call(void 0, s.layers, data.activeLayerId) ? data.activeLayerId : null;
10711
+ s.activeLayerId = data.activeLayerId && _chunkT422YCHRcjs.findLayer.call(void 0, s.layers, data.activeLayerId) ? data.activeLayerId : null;
9651
10712
  const light = data.globalLight;
9652
10713
  if (light && Number.isFinite(light.angle) && Number.isFinite(light.altitude)) s.globalLight = { angle: light.angle, altitude: Math.min(90, Math.max(0, light.altitude)) };
9653
10714
  else delete s.globalLight;
10715
+ const patterns = deserializePatterns(data.patterns, problems);
10716
+ if (patterns.length) s.patterns = patterns;
10717
+ else delete s.patterns;
9654
10718
  if (!this.imageElement && typeof data.width === "number" && typeof data.height === "number" && data.width > 0 && data.height > 0) {
9655
10719
  s.imageDimensions = { width: data.width, height: data.height };
9656
10720
  }
@@ -9665,6 +10729,7 @@ var ImageEditorController = (_class7 = class {
9665
10729
  s.transform = { ...data.transform };
9666
10730
  s.activeLayerId = null;
9667
10731
  delete s.globalLight;
10732
+ delete s.patterns;
9668
10733
  }
9669
10734
  s.activeTarget = "pixels";
9670
10735
  this.viewKey = [];
@@ -9674,10 +10739,10 @@ var ImageEditorController = (_class7 = class {
9674
10739
  serializeState() {
9675
10740
  const { width, height } = this.naturalSize;
9676
10741
  const view = legacyView(this.stack(), width, height, null);
9677
- if (view.exact && !this.state.globalLight) {
10742
+ if (view.exact && !this.state.globalLight && !_optionalChain([this, 'access', _248 => _248.state, 'access', _249 => _249.patterns, 'optionalAccess', _250 => _250.length])) {
9678
10743
  return {
9679
10744
  // States without adjustment layers keep schema 1, so they round-trip unchanged.
9680
- version: _optionalChain([view, 'access', _220 => _220.adjustments, 'access', _221 => _221.layers, 'optionalAccess', _222 => _222.length]) ? 2 : 1,
10745
+ version: _optionalChain([view, 'access', _251 => _251.adjustments, 'access', _252 => _252.layers, 'optionalAccess', _253 => _253.length]) ? 2 : 1,
9681
10746
  crop: this.state.crop ? { ...this.state.crop } : null,
9682
10747
  transform: { ...this.state.transform },
9683
10748
  adjustments: serializeAdjustments(view.adjustments),
@@ -9702,12 +10767,13 @@ var ImageEditorController = (_class7 = class {
9702
10767
  };
9703
10768
  if (this.state.legacyOutputBlur !== void 0) out.legacyOutputBlur = this.state.legacyOutputBlur;
9704
10769
  if (this.state.globalLight) out.globalLight = { ...this.state.globalLight };
10770
+ if (_optionalChain([this, 'access', _254 => _254.state, 'access', _255 => _255.patterns, 'optionalAccess', _256 => _256.length])) out.patterns = serializePatterns(this.state.patterns);
9705
10771
  return out;
9706
10772
  }
9707
10773
  }, _class7);
9708
10774
  function serializeAdjustments(adjustments) {
9709
10775
  const out = { ...adjustments };
9710
- if (_optionalChain([out, 'access', _223 => _223.layers, 'optionalAccess', _224 => _224.length])) out.layers = JSON.parse(JSON.stringify(out.layers));
10776
+ if (_optionalChain([out, 'access', _257 => _257.layers, 'optionalAccess', _258 => _258.length])) out.layers = JSON.parse(JSON.stringify(out.layers));
9711
10777
  else delete out.layers;
9712
10778
  if (normalizeProcessVersion(out.process) === LEGACY_PROCESS_VERSION) {
9713
10779
  delete out.process;
@@ -9743,11 +10809,11 @@ function withDevelop(layer, partial) {
9743
10809
  return { ...layer, filters };
9744
10810
  }
9745
10811
  function withBlur(layer, radius) {
9746
- const existing = _optionalChain([layer, 'access', _225 => _225.filters, 'optionalAccess', _226 => _226.find, 'call', _227 => _227((f) => f.kind === "blur")]);
10812
+ const existing = _optionalChain([layer, 'access', _259 => _259.filters, 'optionalAccess', _260 => _260.find, 'call', _261 => _261((f) => f.kind === "blur")]);
9747
10813
  const filters = (_nullishCoalesce(layer.filters, () => ( []))).filter((f) => f.kind !== "blur");
9748
10814
  if (radius > 0) {
9749
10815
  filters.push({
9750
- id: _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _228 => _228.id]), () => ( (layer.source === "document" ? BLUR_FILTER_ID : newLayerId("flt")))),
10816
+ id: _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _262 => _262.id]), () => ( (layer.source === "document" ? BLUR_FILTER_ID : newLayerId("flt")))),
9751
10817
  kind: "blur",
9752
10818
  enabled: true,
9753
10819
  radius
@@ -9811,27 +10877,27 @@ function resizeLegacyMasks(layers, from, to) {
9811
10877
  const th = Math.max(1, Math.round(to.height));
9812
10878
  if (fw === tw && fh === th) return layers;
9813
10879
  let out = layers;
9814
- for (const l of _chunk73L6TROJcjs.flattenLayers.call(void 0, layers)) {
10880
+ for (const l of _chunkT422YCHRcjs.flattenLayers.call(void 0, layers)) {
9815
10881
  if (l.type !== "adjustment" || !l.mask || l.mask.source) continue;
9816
10882
  const old = l.mask;
9817
10883
  const mask = rasterMaskFromLegacy(legacyMaskOf(old, fw, fh), tw, th);
9818
10884
  if (!mask) continue;
9819
- out = _chunk73L6TROJcjs.mapLayer.call(void 0, out, l.id, (n) => ({ ...n, mask: { ...mask, density: old.density, feather: old.feather, enabled: old.enabled } }));
10885
+ out = _chunkT422YCHRcjs.mapLayer.call(void 0, out, l.id, (n) => ({ ...n, mask: { ...mask, density: old.density, feather: old.feather, enabled: old.enabled } }));
9820
10886
  }
9821
10887
  return out;
9822
10888
  }
9823
10889
  function isOpaqueInside(surface, width, height) {
9824
10890
  const row = new Uint8ClampedArray(width * 4);
9825
10891
  for (let y = 0; y < height; y++) {
9826
- _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, { x: 0, y, width, height: 1 }, row);
10892
+ _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, { x: 0, y, width, height: 1 }, row);
9827
10893
  for (let i = 3; i < row.length; i += 4) if (row[i] !== 255) return false;
9828
10894
  }
9829
10895
  return true;
9830
10896
  }
9831
10897
  function collectStateTiles(layers, into) {
9832
- for (const l of _chunk73L6TROJcjs.flattenLayers.call(void 0, layers)) {
9833
- if (l.type === "pixel" && l.source !== "document") _chunkZOOEX3WTcjs.collectTiles.call(void 0, l.surface, into);
9834
- if (l.mask && !l.mask.source) _chunkZOOEX3WTcjs.collectTiles.call(void 0, l.mask.surface, into);
10898
+ for (const l of _chunkT422YCHRcjs.flattenLayers.call(void 0, layers)) {
10899
+ if (l.type === "pixel" && l.source !== "document") _chunkCRMAXIUVcjs.collectTiles.call(void 0, l.surface, into);
10900
+ if (l.mask && !l.mask.source) _chunkCRMAXIUVcjs.collectTiles.call(void 0, l.mask.surface, into);
9835
10901
  }
9836
10902
  }
9837
10903
  function pixelsOnly(layers) {
@@ -9839,7 +10905,7 @@ function pixelsOnly(layers) {
9839
10905
  for (const l of layers) {
9840
10906
  if (l.type === "adjustment") continue;
9841
10907
  if (l.type === "group") out.push({ ...l, children: pixelsOnly(l.children) });
9842
- else if (l.type === "pixel" && _optionalChain([l, 'access', _229 => _229.filters, 'optionalAccess', _230 => _230.length])) {
10908
+ else if (l.type === "pixel" && _optionalChain([l, 'access', _263 => _263.filters, 'optionalAccess', _264 => _264.length])) {
9843
10909
  const p = { ...l };
9844
10910
  delete p.filters;
9845
10911
  out.push(p);
@@ -9897,7 +10963,7 @@ function toHex2(c) {
9897
10963
  return "#" + [c[0], c[1], c[2]].map((v) => Math.round(v).toString(16).padStart(2, "0")).join("");
9898
10964
  }
9899
10965
  function normalizeSelection(mask) {
9900
- return _optionalChain([mask, 'optionalAccess', _231 => _231.bounds]) ? mask : null;
10966
+ return _optionalChain([mask, 'optionalAccess', _265 => _265.bounds]) ? mask : null;
9901
10967
  }
9902
10968
  function sameSelection(a, b) {
9903
10969
  if (a.width !== b.width || a.height !== b.height) return false;
@@ -10002,7 +11068,7 @@ function loadImageEditorDocument(input) {
10002
11068
  if (typeof input === "string") {
10003
11069
  try {
10004
11070
  parsed = JSON.parse(input);
10005
- } catch (e26) {
11071
+ } catch (e28) {
10006
11072
  parsed = input;
10007
11073
  }
10008
11074
  }
@@ -10058,7 +11124,7 @@ function loadImageEditorDocument(input) {
10058
11124
  }
10059
11125
  const state = { version: 1, ...result.value };
10060
11126
  if (isV2) {
10061
- if (_optionalChain([state, 'access', _232 => _232.adjustments, 'access', _233 => _233.layers, 'optionalAccess', _234 => _234.length])) state.version = 2;
11127
+ if (_optionalChain([state, 'access', _266 => _266.adjustments, 'access', _267 => _267.layers, 'optionalAccess', _268 => _268.length])) state.version = 2;
10062
11128
  result.report.version = 2;
10063
11129
  }
10064
11130
  if (state.selection === void 0) delete state.selection;
@@ -10258,7 +11324,7 @@ function findAdjustmentControl(id) {
10258
11324
  }
10259
11325
  function findLayerControl(kind, id) {
10260
11326
  if (id === "opacity") return ADJUSTMENT_LAYER_OPACITY_CONTROL;
10261
- return _optionalChain([ADJUSTMENT_LAYER_CONTROLS, 'access', _235 => _235[kind], 'optionalAccess', _236 => _236.find, 'call', _237 => _237((c) => c.id === id)]);
11327
+ return _optionalChain([ADJUSTMENT_LAYER_CONTROLS, 'access', _269 => _269[kind], 'optionalAccess', _270 => _270.find, 'call', _271 => _271((c) => c.id === id)]);
10262
11328
  }
10263
11329
  function clampControlValue(spec, v) {
10264
11330
  if (typeof v !== "number" || !Number.isFinite(v)) return spec.default;
@@ -10291,17 +11357,17 @@ function controlTrackBackground(spec) {
10291
11357
  return void 0;
10292
11358
  }
10293
11359
  }
10294
- function getControlPath(obj, path) {
10295
- let cur = obj;
11360
+ function getControlPath(obj2, path) {
11361
+ let cur = obj2;
10296
11362
  for (const part of path.split(".")) {
10297
11363
  if (cur === null || cur === void 0) return void 0;
10298
11364
  cur = cur[part];
10299
11365
  }
10300
11366
  return cur;
10301
11367
  }
10302
- function setControlPath(obj, path, value) {
11368
+ function setControlPath(obj2, path, value) {
10303
11369
  const parts = path.split(".");
10304
- const root = Array.isArray(obj) ? [...obj] : { ...obj };
11370
+ const root = Array.isArray(obj2) ? [...obj2] : { ...obj2 };
10305
11371
  let cur = root;
10306
11372
  for (let i = 0; i < parts.length - 1; i++) {
10307
11373
  const next = cur[parts[i]];
@@ -10359,8 +11425,8 @@ function describeSelection(mask) {
10359
11425
  if (!mask || !mask.bounds) return "No selection";
10360
11426
  let sum = 0;
10361
11427
  for (let i = 0; i < mask.data.length; i++) sum += mask.data[i];
10362
- const pct = sum / 255 / mask.data.length * 100;
10363
- const shown = pct >= 10 ? Math.round(pct) : Math.round(pct * 10) / 10;
11428
+ const pct2 = sum / 255 / mask.data.length * 100;
11429
+ const shown = pct2 >= 10 ? Math.round(pct2) : Math.round(pct2 * 10) / 10;
10364
11430
  return `${mask.bounds.width} \xD7 ${mask.bounds.height} px selected (${shown}% of the image)`;
10365
11431
  }
10366
11432
 
@@ -10370,14 +11436,14 @@ var modeSchema = {
10370
11436
  enum: [...SELECTION_MODES],
10371
11437
  description: "How the result combines with the current selection (default replace)."
10372
11438
  };
10373
- var num2 = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : d;
11439
+ var num3 = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : d;
10374
11440
  function summary(controller) {
10375
11441
  const sel = controller.getSelection();
10376
11442
  const { width, height } = controller.getState().imageDimensions;
10377
11443
  const area = selectionArea(sel);
10378
11444
  return {
10379
11445
  empty: !sel,
10380
- bounds: _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _238 => _238.bounds]), () => ( null)),
11446
+ bounds: _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _272 => _272.bounds]), () => ( null)),
10381
11447
  /** Σ coverage in pixels. */
10382
11448
  area: Math.round(area),
10383
11449
  percent: Math.round(area / Math.max(1, width * height) * 1e4) / 100,
@@ -10420,7 +11486,7 @@ function createImageSelectionTools(controller) {
10420
11486
  },
10421
11487
  annotations: writeAnnotations("Select a region", true),
10422
11488
  handler: ({ shape, x, y, width, height, mode, feather }) => {
10423
- const opts = { mode: parseSelectionMode(mode), feather: num2(feather, 0) };
11489
+ const opts = { mode: parseSelectionMode(mode), feather: num3(feather, 0) };
10424
11490
  switch (shape) {
10425
11491
  case "all":
10426
11492
  controller.selectAll();
@@ -10433,7 +11499,7 @@ function createImageSelectionTools(controller) {
10433
11499
  break;
10434
11500
  case "rect":
10435
11501
  case "ellipse": {
10436
- const rect = { x: num2(x, NaN), y: num2(y, NaN), width: num2(width, NaN), height: num2(height, NaN) };
11502
+ const rect = { x: num3(x, NaN), y: num3(y, NaN), width: num3(width, NaN), height: num3(height, NaN) };
10437
11503
  if (![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite)) {
10438
11504
  throw new Error("rect and ellipse need numeric x, y, width and height.");
10439
11505
  }
@@ -10472,15 +11538,15 @@ function createImageSelectionTools(controller) {
10472
11538
  },
10473
11539
  annotations: writeAnnotations("Select by colour", true),
10474
11540
  handler: async ({ x, y, color, tolerance, contiguous, fuzziness, sampleMerged, sample, mode }) => {
10475
- const common = {
11541
+ const common2 = {
10476
11542
  mode: parseSelectionMode(mode),
10477
11543
  sampleMerged: sampleMerged === true,
10478
11544
  sample: _nullishCoalesce(sample, () => ( "composite"))
10479
11545
  };
10480
11546
  if (typeof color === "string") {
10481
- await controller.selectColorRange([{ color }], { ...common, fuzziness: num2(fuzziness, 40) });
11547
+ await controller.selectColorRange([{ color }], { ...common2, fuzziness: num3(fuzziness, 40) });
10482
11548
  } else if (typeof x === "number" && typeof y === "number") {
10483
- await controller.magicWand({ x, y }, { ...common, tolerance: num2(tolerance, 32), contiguous: contiguous !== false });
11549
+ await controller.magicWand({ x, y }, { ...common2, tolerance: num3(tolerance, 32), contiguous: contiguous !== false });
10484
11550
  } else {
10485
11551
  throw new Error("Pass x and y (magic wand) or color (#rrggbb).");
10486
11552
  }
@@ -10504,7 +11570,7 @@ function createImageSelectionTools(controller) {
10504
11570
  handler: ({ op, radius }) => {
10505
11571
  if (!SELECTION_MODIFY_OPS.includes(op)) throw new Error(`Unknown op "${String(op)}".`);
10506
11572
  if (!controller.getSelection()) throw new Error("Nothing is selected.");
10507
- controller.modifySelection(op, Math.min(500, Math.max(0, num2(radius, 0))));
11573
+ controller.modifySelection(op, Math.min(500, Math.max(0, num3(radius, 0))));
10508
11574
  return summary(controller);
10509
11575
  }
10510
11576
  };
@@ -10528,12 +11594,12 @@ function createImageSelectionTools(controller) {
10528
11594
  handler: async (params) => {
10529
11595
  if (!controller.getSelection()) throw new Error("Nothing is selected.");
10530
11596
  await controller.refineSelection({
10531
- radius: num2(params.radius, 8),
11597
+ radius: num3(params.radius, 8),
10532
11598
  smartRadius: params.smartRadius === true,
10533
- smooth: num2(params.smooth, 0),
10534
- feather: num2(params.feather, 0),
10535
- contrast: num2(params.contrast, 0),
10536
- shiftEdge: num2(params.shiftEdge, 0)
11599
+ smooth: num3(params.smooth, 0),
11600
+ feather: num3(params.feather, 0),
11601
+ contrast: num3(params.contrast, 0),
11602
+ shiftEdge: num3(params.shiftEdge, 0)
10537
11603
  });
10538
11604
  return summary(controller);
10539
11605
  }
@@ -10621,7 +11687,7 @@ async function renderImageRegion(controller, request) {
10621
11687
  if (request.includeOverlays) {
10622
11688
  const s = request.scale;
10623
11689
  const selection = state.selection;
10624
- if (_optionalChain([selection, 'optionalAccess', _239 => _239.bounds]) && selection.width === state.imageDimensions.width && selection.height === state.imageDimensions.height) {
11690
+ if (_optionalChain([selection, 'optionalAccess', _273 => _273.bounds]) && selection.width === state.imageDimensions.width && selection.height === state.imageDimensions.height) {
10625
11691
  const shade = selectionShade(selection, document);
10626
11692
  if (shade) context.drawImage(shade, rect.x, rect.y, rect.width, rect.height, 0, 0, out.width, out.height);
10627
11693
  }
@@ -10646,7 +11712,7 @@ function createImageCaptureSurface(controller) {
10646
11712
  return {
10647
11713
  units: "image pixels",
10648
11714
  content: whole,
10649
- selection: () => ({ rect: _nullishCoalesce(_optionalChain([controller, 'access', _240 => _240.getState, 'call', _241 => _241(), 'access', _242 => _242.selection, 'optionalAccess', _243 => _243.bounds]), () => ( null)) }),
11715
+ selection: () => ({ rect: _nullishCoalesce(_optionalChain([controller, 'access', _274 => _274.getState, 'call', _275 => _275(), 'access', _276 => _276.selection, 'optionalAccess', _277 => _277.bounds]), () => ( null)) }),
10650
11716
  overlays: "a shade over unselected pixels and the crop box outline",
10651
11717
  maxScale: 8,
10652
11718
  render: (request) => renderImageRegion(controller, request)
@@ -10680,14 +11746,14 @@ function rebin(bins, count) {
10680
11746
  return out;
10681
11747
  }
10682
11748
  function histogramSummary(h, bins) {
10683
- const pct = (n) => h.samples ? round(n / h.samples * 100) : 0;
11749
+ const pct2 = (n) => h.samples ? round(n / h.samples * 100) : 0;
10684
11750
  const channels = { red: h.red, green: h.green, blue: h.blue, luminance: h.luminance };
10685
11751
  return {
10686
11752
  samples: h.samples,
10687
11753
  transparent: h.transparent,
10688
11754
  clipping: {
10689
- shadowsPercent: { red: pct(h.shadows[0]), green: pct(h.shadows[1]), blue: pct(h.shadows[2]) },
10690
- highlightsPercent: { red: pct(h.highlights[0]), green: pct(h.highlights[1]), blue: pct(h.highlights[2]) }
11755
+ shadowsPercent: { red: pct2(h.shadows[0]), green: pct2(h.shadows[1]), blue: pct2(h.shadows[2]) },
11756
+ highlightsPercent: { red: pct2(h.highlights[0]), green: pct2(h.highlights[1]), blue: pct2(h.highlights[2]) }
10691
11757
  },
10692
11758
  stats: Object.fromEntries(Object.entries(channels).map(([k, v]) => [k, binStats(v, h.samples)])),
10693
11759
  ...bins ? { bins: Object.fromEntries(Object.entries(channels).map(([k, v]) => [k, rebin(v, bins)])) } : {}
@@ -10758,7 +11824,7 @@ function createImageEditTools(controller) {
10758
11824
  properties: {
10759
11825
  layer: LAYER_ID,
10760
11826
  enabled: { type: "boolean", description: "false hides the layer without deleting it." },
10761
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (see list_controls)." },
11827
+ blend: { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (see list_controls)." },
10762
11828
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0-1." },
10763
11829
  name: { type: "string", description: "Layer name shown in the layers panel." }
10764
11830
  },
@@ -10771,7 +11837,7 @@ function createImageEditTools(controller) {
10771
11837
  if (enabled === void 0 && blend === void 0 && opacity === void 0 && name === void 0) {
10772
11838
  throw new Error("Nothing to change. Pass enabled, blend, opacity or name.");
10773
11839
  }
10774
- if (blend !== void 0 && !_chunkZOOEX3WTcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
11840
+ if (blend !== void 0 && !_chunkCRMAXIUVcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
10775
11841
  controller.updateAdjustmentLayer(layer, { enabled, blend, opacity, name });
10776
11842
  return { layer: layerJson(layer) };
10777
11843
  }
@@ -10924,7 +11990,7 @@ function maskSummary(mask) {
10924
11990
  };
10925
11991
  if (!mask.source) {
10926
11992
  out.defaultValue = mask.defaultValue;
10927
- out.paintedBounds = _chunkZOOEX3WTcjs.contentBounds.call(void 0, mask.surface);
11993
+ out.paintedBounds = _chunkCRMAXIUVcjs.contentBounds.call(void 0, mask.surface);
10928
11994
  }
10929
11995
  return out;
10930
11996
  }
@@ -10971,7 +12037,7 @@ var PLACEMENT = {
10971
12037
  parentId: { type: "string", description: "Put the layer inside this group (at index, default its top)." },
10972
12038
  index: { type: "integer", minimum: 0, description: "Position among the siblings, 0 = bottom (with parentId, or at the top level)." }
10973
12039
  };
10974
- var BLEND = { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." };
12040
+ var BLEND = { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." };
10975
12041
  function placementFrom(args) {
10976
12042
  const p = {};
10977
12043
  if (typeof args.aboveId === "string") p.aboveId = args.aboveId;
@@ -10983,11 +12049,11 @@ function placementFrom(args) {
10983
12049
  function createImageLayerTools(controller) {
10984
12050
  const describe = (id) => {
10985
12051
  const s = controller.getState();
10986
- const loc = _chunk73L6TROJcjs.findLayer.call(void 0, s.layers, id);
12052
+ const loc = _chunkT422YCHRcjs.findLayer.call(void 0, s.layers, id);
10987
12053
  if (!loc) return null;
10988
12054
  return {
10989
12055
  ...describeLayer(loc.layer, s.activeLayerId, (x) => controller.getLayerBounds(x.id)),
10990
- parentId: _nullishCoalesce(_optionalChain([loc, 'access', _244 => _244.parent, 'optionalAccess', _245 => _245.id]), () => ( null)),
12056
+ parentId: _nullishCoalesce(_optionalChain([loc, 'access', _278 => _278.parent, 'optionalAccess', _279 => _279.id]), () => ( null)),
10991
12057
  index: loc.index
10992
12058
  };
10993
12059
  };
@@ -11121,7 +12187,7 @@ function createImageLayerTools(controller) {
11121
12187
  visible: { type: "boolean", description: "Show (true) or hide (false)." },
11122
12188
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0..1." },
11123
12189
  fillOpacity: { type: "number", minimum: 0, maximum: 1, description: "Fill 0..1 (pixel layers)." },
11124
- blend: { type: "string", enum: [..._chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode; pass-through for groups only." },
12190
+ blend: { type: "string", enum: [..._chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode; pass-through for groups only." },
11125
12191
  clipped: { type: "boolean", description: "Clip to the nearest unclipped layer below." },
11126
12192
  locks: {
11127
12193
  type: "object",
@@ -11176,7 +12242,7 @@ function createImageLayerTools(controller) {
11176
12242
  type: "object",
11177
12243
  properties: {
11178
12244
  name: { type: "string", description: 'Group name (default "Group").' },
11179
- blend: { type: "string", enum: [..._chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode (default pass-through)." },
12245
+ blend: { type: "string", enum: [..._chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode (default pass-through)." },
11180
12246
  ...PLACEMENT
11181
12247
  },
11182
12248
  additionalProperties: false
@@ -11442,7 +12508,7 @@ var WRITE_IDEMPOTENT3 = { readOnlyHint: false, destructiveHint: false, idempoten
11442
12508
  var DESTRUCTIVE2 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
11443
12509
  var LAYER_ID3 = { type: "string", description: "Layer id from list_layers (a pixel, annotation or group layer)." };
11444
12510
  var EFFECT_ID = { type: "string", description: "Effect id from list_layer_effects or add_layer_effect." };
11445
- var BLEND_IDS = _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id);
12511
+ var BLEND_IDS = _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id).filter((id) => id !== "pigment");
11446
12512
  var DEFS = {
11447
12513
  color: { type: "string", pattern: "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", description: "Colour as #rrggbb." },
11448
12514
  contour: {
@@ -11633,19 +12699,21 @@ function settingsSchema(forUpdate) {
11633
12699
  additionalProperties: false
11634
12700
  };
11635
12701
  }
11636
- function patternList() {
11637
- return _chunk73L6TROJcjs.builtinPatternIds.call(void 0, ).map((id) => {
11638
- const p = _chunk73L6TROJcjs.builtinPattern.call(void 0, id);
12702
+ function patternList(controller) {
12703
+ const doc = controller.getDocumentPatterns().map((p) => ({ id: p.id, name: p.name, width: p.width, height: p.height, builtin: false }));
12704
+ const builtins = _chunkT422YCHRcjs.builtinPatternIds.call(void 0, ).map((id) => {
12705
+ const p = _chunkT422YCHRcjs.builtinPattern.call(void 0, id);
11639
12706
  return { id, name: p.name, width: p.width, height: p.height, builtin: true };
11640
12707
  });
12708
+ return [...doc, ...builtins];
11641
12709
  }
11642
12710
  function describeLayerEffects(effects) {
11643
12711
  return {
11644
12712
  enabled: effects.enabled,
11645
12713
  scale: _nullishCoalesce(effects.scale, () => ( 1)),
11646
- margin: _chunk73L6TROJcjs.effectsMargin.call(void 0, effects),
12714
+ margin: _chunkT422YCHRcjs.effectsMargin.call(void 0, effects),
11647
12715
  fromPsd: Boolean(effects.psd),
11648
- effects: effects.items.map((e) => ({ ...JSON.parse(JSON.stringify(e)), label: _chunk73L6TROJcjs.layerEffectLabel.call(void 0, e.kind) }))
12716
+ effects: effects.items.map((e) => ({ ...JSON.parse(JSON.stringify(e)), label: _chunkT422YCHRcjs.layerEffectLabel.call(void 0, e.kind) }))
11649
12717
  };
11650
12718
  }
11651
12719
  function createImageEffectTools(controller) {
@@ -11655,13 +12723,13 @@ function createImageEffectTools(controller) {
11655
12723
  return id;
11656
12724
  };
11657
12725
  const result = (layerId, extra = {}) => ({ layerId, ...extra, ...describeLayerEffects(controller.getLayerEffects(layerId)) });
11658
- const list = {
12726
+ const list2 = {
11659
12727
  name: "list_layer_effects",
11660
12728
  title: "List layer effects",
11661
12729
  description: "Returns a layer's effects: the master switch (enabled), Scale Effects (scale, 1 = 100 %), margin (px the effects reach beyond the shape), whether they came from a PSD, and every effect with its id, kind, label and all settings. Also returns the document global light and the pattern ids pattern effects can use.",
11662
12730
  inputSchema: { type: "object", properties: { layerId: LAYER_ID3 }, required: ["layerId"], additionalProperties: false },
11663
12731
  annotations: { title: "List layer effects", ...READ3 },
11664
- handler: ({ layerId }) => result(layerArg(layerId), { globalLight: controller.getGlobalLight(), patterns: patternList(), kinds: [..._chunk73L6TROJcjs.LAYER_EFFECT_KINDS] })
12732
+ handler: ({ layerId }) => result(layerArg(layerId), { globalLight: controller.getGlobalLight(), patterns: patternList(controller), kinds: [..._chunkT422YCHRcjs.LAYER_EFFECT_KINDS] })
11665
12733
  };
11666
12734
  const add = {
11667
12735
  name: "add_layer_effect",
@@ -11672,7 +12740,7 @@ function createImageEffectTools(controller) {
11672
12740
  $defs: DEFS,
11673
12741
  properties: {
11674
12742
  layerId: LAYER_ID3,
11675
- kind: { type: "string", enum: [..._chunk73L6TROJcjs.LAYER_EFFECT_KINDS], description: "Effect kind." },
12743
+ kind: { type: "string", enum: [..._chunkT422YCHRcjs.LAYER_EFFECT_KINDS], description: "Effect kind." },
11676
12744
  settings: settingsSchema(false),
11677
12745
  index: { type: "integer", minimum: 0, description: "Position in the layer's effect list (default the end)." }
11678
12746
  },
@@ -11682,7 +12750,7 @@ function createImageEffectTools(controller) {
11682
12750
  annotations: { title: "Add a layer effect", ...WRITE3 },
11683
12751
  handler: ({ layerId, kind, settings, index }) => {
11684
12752
  const id = layerArg(layerId);
11685
- if (!_chunk73L6TROJcjs.isLayerEffectKind.call(void 0, kind)) throw new LayerOperationError(`kind must be one of ${_chunk73L6TROJcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
12753
+ if (!_chunkT422YCHRcjs.isLayerEffectKind.call(void 0, kind)) throw new LayerOperationError(`kind must be one of ${_chunkT422YCHRcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
11686
12754
  const { effect } = controller.addLayerEffect(id, kind, _nullishCoalesce(settings, () => ( {})), index);
11687
12755
  return result(id, { effectId: effect.id });
11688
12756
  }
@@ -11761,49 +12829,222 @@ function createImageEffectTools(controller) {
11761
12829
  return { globalLight: controller.setGlobalLight(next) };
11762
12830
  }
11763
12831
  };
11764
- return [list, add, update, remove, setEnabled, light];
12832
+ return [list2, add, update, remove, setEnabled, light];
11765
12833
  }
11766
12834
 
11767
- // src/image-editor/paint-tools.ts
11768
- var WRITE4 = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
11769
- var DESTRUCTIVE3 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
11770
- var TARGET = {
11771
- layerId: { type: "string", description: "Layer to paint (default the active layer; see list_layers)." },
11772
- channel: { type: "string", enum: ["pixels", "mask"], description: "pixels (default for a pixel layer) or the layer's mask: black hides, white reveals." }
11773
- };
11774
- var BRUSH = {
11775
- type: "object",
11776
- description: "Brush settings; missing fields use the current paint options (default round, hard, 20 px).",
11777
- properties: {
11778
- size: { type: "number", minimum: 1, maximum: _chunk4F3YDIWWcjs.MAX_BRUSH_SIZE, description: "Diameter in px (default 20)." },
11779
- hardness: { type: "number", minimum: 0, maximum: 1, description: "Edge hardness 0 (soft) .. 1 (hard, default)." },
11780
- spacing: { type: "number", minimum: 0.01, maximum: 10, description: "Dab spacing as a fraction of the diameter (default 0.1)." },
11781
- angle: { type: "number", minimum: -360, maximum: 360, description: "Tip angle in degrees (default 0)." },
11782
- roundness: { type: "number", minimum: 0.01, maximum: 1, description: "Tip roundness (default 1)." },
11783
- opacity: { type: "number", minimum: 0, maximum: 1, description: "Stroke opacity: overlapping dabs never exceed it (default 1)." },
11784
- flow: { type: "number", minimum: 0, maximum: 1, description: "Build-up per dab towards the opacity (default 1)." },
11785
- smoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Point smoothing 0..0.95 (default 0)." },
11786
- pressureSize: { type: "boolean", description: "Point pressure scales the size (default true)." },
11787
- pressureOpacity: { type: "boolean", description: "Point pressure scales the opacity (default false)." },
11788
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "How paint combines with the layer (default normal)." }
11789
- },
11790
- additionalProperties: false
11791
- };
11792
- function readTarget(args) {
11793
- return { layerId: args.layerId, channel: args.channel };
12835
+ // src/image-editor/layers/paint-ui.ts
12836
+ var plain2 = { kind: "plain" };
12837
+ var BRUSH_OPTION_CONTROLS = [
12838
+ { id: "size", label: "Size", section: "layer", min: 1, max: 500, step: 1, default: 20, decimals: 0, track: plain2, unit: "px" },
12839
+ { id: "hardness", label: "Hardness", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12840
+ { id: "opacity", label: "Opacity", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12841
+ { id: "flow", label: "Flow", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12842
+ { id: "smoothing", label: "Smoothing", section: "layer", min: 0, max: 0.95, step: 0.01, default: 0, decimals: 0, track: plain2, displayScale: 100, unit: "%" }
12843
+ ];
12844
+ var MIXER_OPTION_CONTROLS = [
12845
+ { id: "wet", label: "Wet", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12846
+ { id: "load", label: "Load", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12847
+ { id: "mix", label: "Mix", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%" }
12848
+ ];
12849
+ var MIXER_MIXING_OPTIONS = [
12850
+ { id: "rgb", label: "RGB", title: "Mix colours as RGB averages" },
12851
+ { id: "pigment", label: "Pigment", title: "Mix colours like paint: blue and yellow make green" }
12852
+ ];
12853
+ var PAINT_TOOLS = [
12854
+ { id: "move", label: "Move", shortcut: "V" },
12855
+ { id: "brush", label: "Brush", shortcut: "B" },
12856
+ { id: "mixer", label: "Mixer", shortcut: "Shift+B" },
12857
+ { id: "eraser", label: "Eraser", shortcut: "E" }
12858
+ ];
12859
+ var isPaintTool = (tool) => tool === "move" || tool === "brush" || tool === "mixer" || tool === "eraser";
12860
+ function rgbUnitToHex(c) {
12861
+ return `#${c.map((v) => Math.round(Math.min(1, Math.max(0, v)) * 255).toString(16).padStart(2, "0")).join("")}`;
11794
12862
  }
11795
- function createImagePaintTools(controller) {
11796
- const paintStroke = {
11797
- name: "paint_stroke",
11798
- title: "Paint a brush stroke",
11799
- description: "Paints one stroke with the brush (or removes pixels with the eraser) through points in document pixels (optional pressure 0..1 each) on a pixel layer or a layer mask. The selection limits the paint; a transparency-locked layer keeps its alpha (the eraser then paints the background colour). One undo step. Returns the layerId, channel, changed bounds and dab count.",
11800
- inputSchema: {
11801
- type: "object",
11802
- properties: {
11803
- tool: { type: "string", enum: ["brush", "eraser"], description: "brush (default) or eraser." },
11804
- points: {
11805
- type: "array",
11806
- minItems: 1,
12863
+ function sizeStep(size) {
12864
+ return size < 10 ? 1 : size < 50 ? 5 : size < 100 ? 10 : size < 200 ? 25 : size < 500 ? 50 : 100;
12865
+ }
12866
+ var isTyping = (t) => {
12867
+ const el = t;
12868
+ return Boolean(el && (el.isContentEditable || el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT"));
12869
+ };
12870
+ function handlePaintShortcut(controller, e) {
12871
+ if (e.ctrlKey || e.metaKey || e.altKey || isTyping(e.target)) return false;
12872
+ const brush = controller.getState().paint.brush;
12873
+ const set = (b) => controller.setPaintOptions({ brush: b });
12874
+ const key = e.key;
12875
+ switch (key.toLowerCase()) {
12876
+ case "b":
12877
+ controller.setTool(e.shiftKey || key === "B" ? "mixer" : "brush");
12878
+ return true;
12879
+ case "e":
12880
+ controller.setTool("eraser");
12881
+ return true;
12882
+ case "v":
12883
+ controller.setTool("move");
12884
+ return true;
12885
+ case "d":
12886
+ controller.resetPaintColors();
12887
+ return true;
12888
+ case "x":
12889
+ controller.swapPaintColors();
12890
+ return true;
12891
+ }
12892
+ if (key === "[" || key === "{") {
12893
+ if (e.shiftKey || key === "{") set({ hardness: Math.max(0, Math.round((brush.hardness - 0.25) * 4) / 4) });
12894
+ else set({ size: Math.max(1, brush.size - sizeStep(brush.size - 1)) });
12895
+ return true;
12896
+ }
12897
+ if (key === "]" || key === "}") {
12898
+ if (e.shiftKey || key === "}") set({ hardness: Math.min(1, Math.round((brush.hardness + 0.25) * 4) / 4) });
12899
+ else set({ size: Math.min(_chunkZZOTHJ4Kcjs.MAX_BRUSH_SIZE, brush.size + sizeStep(brush.size)) });
12900
+ return true;
12901
+ }
12902
+ if (/^[0-9]$/.test(key) && isPaintTool(controller.getState().activeTool)) {
12903
+ set({ opacity: key === "0" ? 1 : Number(key) / 10 });
12904
+ return true;
12905
+ }
12906
+ return false;
12907
+ }
12908
+ function pointerPressure(e) {
12909
+ if (e.pointerType === "pen" && typeof e.pressure === "number" && e.pressure > 0) return Math.min(1, e.pressure);
12910
+ return 1;
12911
+ }
12912
+ var PaintGesture = (_class8 = class {
12913
+ constructor(controller) {;_class8.prototype.__init53.call(this);_class8.prototype.__init54.call(this);_class8.prototype.__init55.call(this);
12914
+ this.controller = controller;
12915
+ }
12916
+
12917
+ __init53() {this.stroke = null}
12918
+ __init54() {this.move = null}
12919
+ /** The last refusal (e.g. "layer is locked"), for the editor to show. */
12920
+ __init55() {this.error = null}
12921
+ get active() {
12922
+ return Boolean(this.stroke || this.move);
12923
+ }
12924
+ down(sample) {
12925
+ this.error = null;
12926
+ const tool = this.controller.getState().activeTool;
12927
+ try {
12928
+ if (tool === "move") {
12929
+ const layer = this.controller.getActiveLayer();
12930
+ if (!layer) throw new Error("Select a layer to move in the Layers panel.");
12931
+ if (layer.type !== "pixel") throw new Error(`Only pixel layers move; "${layer.name}" is a ${layer.type} layer.`);
12932
+ if (_optionalChain([layer, 'access', _280 => _280.locks, 'optionalAccess', _281 => _281.all]) || _optionalChain([layer, 'access', _282 => _282.locks, 'optionalAccess', _283 => _283.position])) throw new Error(`Layer "${layer.name}" has its position locked.`);
12933
+ this.move = { id: layer.id, start: { x: sample.x, y: sample.y }, origin: { ...layer.offset }, moved: false };
12934
+ return null;
12935
+ }
12936
+ if (tool === "brush" || tool === "eraser" || tool === "mixer") {
12937
+ this.stroke = this.controller.beginStroke({ tool });
12938
+ this.stroke.push([sample]);
12939
+ return null;
12940
+ }
12941
+ } catch (err) {
12942
+ this.error = err instanceof Error ? err.message : String(err);
12943
+ this.stroke = null;
12944
+ this.move = null;
12945
+ }
12946
+ return this.error;
12947
+ }
12948
+ /** Feeds pointer samples (all coalesced events of one move, in order). */
12949
+ moveTo(samples) {
12950
+ if (!samples.length) return;
12951
+ if (this.stroke) {
12952
+ this.stroke.push(samples);
12953
+ return;
12954
+ }
12955
+ const m = this.move;
12956
+ if (m) {
12957
+ const last = samples[samples.length - 1];
12958
+ const x = m.origin.x + Math.round(last.x - m.start.x);
12959
+ const y = m.origin.y + Math.round(last.y - m.start.y);
12960
+ try {
12961
+ this.controller.offsetLayer(m.id, { x, y }, !m.moved);
12962
+ m.moved = true;
12963
+ } catch (err) {
12964
+ this.error = err instanceof Error ? err.message : String(err);
12965
+ this.move = null;
12966
+ }
12967
+ }
12968
+ }
12969
+ up() {
12970
+ if (this.stroke) {
12971
+ try {
12972
+ this.stroke.end();
12973
+ } catch (err) {
12974
+ this.error = err instanceof Error ? err.message : String(err);
12975
+ }
12976
+ }
12977
+ this.stroke = null;
12978
+ this.move = null;
12979
+ }
12980
+ cancel() {
12981
+ _optionalChain([this, 'access', _284 => _284.stroke, 'optionalAccess', _285 => _285.cancel, 'call', _286 => _286()]);
12982
+ this.stroke = null;
12983
+ this.move = null;
12984
+ }
12985
+ }, _class8);
12986
+
12987
+ // src/image-editor/paint-tools.ts
12988
+ var READ4 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
12989
+ var WRITE4 = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
12990
+ var DESTRUCTIVE3 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
12991
+ var TARGET = {
12992
+ layerId: { type: "string", description: "Layer to paint (default the active layer; see list_layers)." },
12993
+ channel: { type: "string", enum: ["pixels", "mask"], description: "pixels (default for a pixel layer) or the layer's mask: black hides, white reveals." }
12994
+ };
12995
+ var BRUSH = {
12996
+ type: "object",
12997
+ description: "Brush settings; missing fields use the current paint options (default round, hard, 20 px).",
12998
+ properties: {
12999
+ size: { type: "number", minimum: 1, maximum: _chunkZZOTHJ4Kcjs.MAX_BRUSH_SIZE, description: "Diameter in px (default 20)." },
13000
+ hardness: { type: "number", minimum: 0, maximum: 1, description: "Edge hardness 0 (soft) .. 1 (hard, default)." },
13001
+ spacing: { type: "number", minimum: 0.01, maximum: 10, description: "Dab spacing as a fraction of the diameter (default 0.1)." },
13002
+ angle: { type: "number", minimum: -360, maximum: 360, description: "Tip angle in degrees (default 0)." },
13003
+ roundness: { type: "number", minimum: 0.01, maximum: 1, description: "Tip roundness (default 1)." },
13004
+ opacity: { type: "number", minimum: 0, maximum: 1, description: "Stroke opacity: overlapping dabs never exceed it (default 1)." },
13005
+ flow: { type: "number", minimum: 0, maximum: 1, description: "Build-up per dab towards the opacity (default 1)." },
13006
+ smoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Point smoothing 0..0.95 (default 0)." },
13007
+ pressureSize: { type: "boolean", description: "Point pressure scales the size (default true)." },
13008
+ pressureOpacity: { type: "boolean", description: "Point pressure scales the opacity (default false)." },
13009
+ blend: { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "How paint combines with the layer (default normal). pigment mixes it in like real paint (blue into yellow gives green) instead of laying it over." }
13010
+ },
13011
+ additionalProperties: false
13012
+ };
13013
+ var MIXER = {
13014
+ type: "object",
13015
+ description: "Mixer Brush settings (tool mixer only); missing fields use the current mixer options (wet 0.5, load 0.5, mix 0.5, loadEachStroke true, cleanEachStroke true, mixing rgb).",
13016
+ properties: {
13017
+ wet: { type: "number", minimum: 0, maximum: 1, description: "How much canvas colour each dab picks up, 0 (dry: paints only the reservoir) .. 1 (default 0.5)." },
13018
+ load: { type: "number", minimum: 0, maximum: 1, description: "How much paint the reservoir holds, 0 .. 1 (default 0.5); below 1 it drains per dab, so long strokes run dry." },
13019
+ mix: { type: "number", minimum: 0, maximum: 1, description: "How far each dab's paint moves from the reservoir towards the picked-up colour, 0 .. 1 (default 0.5)." },
13020
+ loadEachStroke: { type: "boolean", description: "Refill the reservoir with `color` (or the foreground) before the stroke (default true). Off, the brush keeps what is left of its last load." },
13021
+ cleanEachStroke: { type: "boolean", description: "Empty the pickup well after the stroke (default true). Off, the next stroke starts with the colour this one picked up." },
13022
+ mixing: { type: "string", enum: [..._chunkZZOTHJ4Kcjs.MIXING_MODELS], description: "rgb (default): RGB averages. pigment: mixes like paint (Kubelka-Munk), so blue dragged through yellow makes green." }
13023
+ },
13024
+ additionalProperties: false
13025
+ };
13026
+ function mixerLoadResult(load) {
13027
+ return {
13028
+ reservoir: load.reservoir ? rgbUnitToHex(load.reservoir) : null,
13029
+ amount: Math.round(load.amount * 1e3) / 1e3,
13030
+ pickup: load.pickup ? rgbUnitToHex(load.pickup) : null
13031
+ };
13032
+ }
13033
+ function readTarget(args) {
13034
+ return { layerId: args.layerId, channel: args.channel };
13035
+ }
13036
+ function createImagePaintTools(controller) {
13037
+ const paintStroke = {
13038
+ name: "paint_stroke",
13039
+ title: "Paint a brush stroke",
13040
+ description: "Paints one stroke with the brush, smears and blends paint with the Mixer Brush (tool mixer: its reservoir mixes with colour picked up from the layer under each dab, in RGB or pigment mixing), or removes pixels with the eraser, through points in document pixels (optional pressure 0..1 each) on a pixel layer or a layer mask (the mixer paints pixels only). The selection limits the paint; a transparency-locked layer keeps its alpha (the eraser then paints the background colour). One undo step. Returns the layerId, channel, changed bounds and dab count, and for the mixer its mixerLoad after the stroke ({reservoir, amount, pickup}).",
13041
+ inputSchema: {
13042
+ type: "object",
13043
+ properties: {
13044
+ tool: { type: "string", enum: ["brush", "eraser", "mixer"], description: "brush (default), eraser, or mixer (the Mixer Brush: picks up and blends the layer colour under each dab)." },
13045
+ points: {
13046
+ type: "array",
13047
+ minItems: 1,
11807
13048
  maxItems: 1e4,
11808
13049
  description: "The path in document pixels; one point paints one dab.",
11809
13050
  items: {
@@ -11817,21 +13058,66 @@ function createImagePaintTools(controller) {
11817
13058
  additionalProperties: false
11818
13059
  }
11819
13060
  },
11820
- color: { type: "string", description: "Paint colour #rrggbb (default the foreground). On a mask its grey value: #000000 hides, #ffffff reveals." },
13061
+ color: {
13062
+ type: "string",
13063
+ description: "Paint colour #rrggbb (default the foreground). On a mask its grey value: #000000 hides, #ffffff reveals. For the mixer, the colour its reservoir is loaded with before the stroke (given, it loads even with loadEachStroke false)."
13064
+ },
11821
13065
  brush: BRUSH,
13066
+ mixer: MIXER,
11822
13067
  ...TARGET
11823
13068
  },
11824
13069
  required: ["points"],
11825
13070
  additionalProperties: false
11826
13071
  },
11827
13072
  annotations: { title: "Paint a brush stroke", ...WRITE4 },
11828
- handler: (args) => controller.paintStroke({
11829
- tool: args.tool,
11830
- points: args.points,
11831
- color: args.color,
11832
- brush: args.brush,
11833
- ...readTarget(args)
11834
- })
13073
+ handler: (args) => {
13074
+ const tool = args.tool;
13075
+ if (args.mixer !== void 0 && tool !== "mixer") throw new LayerOperationError('mixer settings apply to the Mixer Brush only; pass tool "mixer", or drop mixer.');
13076
+ const result = controller.paintStroke({
13077
+ tool,
13078
+ points: args.points,
13079
+ color: args.color,
13080
+ brush: args.brush,
13081
+ mixer: args.mixer,
13082
+ ...readTarget(args)
13083
+ });
13084
+ return result.mixerLoad ? { ...result, mixerLoad: mixerLoadResult(result.mixerLoad) } : result;
13085
+ }
13086
+ };
13087
+ const getMixer = {
13088
+ name: "get_mixer_brush",
13089
+ title: "Get the Mixer Brush",
13090
+ description: "Reads the Mixer Brush: its settings (wet, load, mix, loadEachStroke, cleanEachStroke, mixing) and what it carries now (reservoir #rrggbb or null, amount 0..1 left, pickup #rrggbb or null). Call it before a paint_stroke with tool mixer and loadEachStroke false, to know the brush's starting paint.",
13091
+ inputSchema: { type: "object", properties: {}, additionalProperties: false },
13092
+ annotations: { title: "Get the Mixer Brush", ...READ4 },
13093
+ handler: () => {
13094
+ const { mixer, mixerLoad } = controller.getState().paint;
13095
+ return { settings: { ...mixer }, load: mixerLoadResult(mixerLoad) };
13096
+ }
13097
+ };
13098
+ const loadMixerTool = {
13099
+ name: "load_mixer_brush",
13100
+ title: "Load the Mixer Brush",
13101
+ description: "Fills the Mixer Brush reservoir with a colour (amount 1); the picked-up colour is kept. View state, not an undo step. Use it with loadEachStroke false to carry one load across several paint_stroke calls. Returns the load {reservoir, amount, pickup}.",
13102
+ inputSchema: {
13103
+ type: "object",
13104
+ properties: { color: { type: "string", description: "Paint colour #rrggbb (default the foreground)." } },
13105
+ additionalProperties: false
13106
+ },
13107
+ annotations: { title: "Load the Mixer Brush", ...WRITE4, idempotentHint: true },
13108
+ handler: (args) => mixerLoadResult(controller.loadMixerBrush(args.color))
13109
+ };
13110
+ const cleanMixerTool = {
13111
+ name: "clean_mixer_brush",
13112
+ title: "Clean the Mixer Brush",
13113
+ description: "Cleans the Mixer Brush: empties the pickup well so the next stroke starts without canvas colour; with emptyReservoir also drops the loaded paint (the brush then only smears). View state, not an undo step. Returns the load {reservoir, amount, pickup}.",
13114
+ inputSchema: {
13115
+ type: "object",
13116
+ properties: { emptyReservoir: { type: "boolean", description: "Also drop the reservoir (default false)." } },
13117
+ additionalProperties: false
13118
+ },
13119
+ annotations: { title: "Clean the Mixer Brush", ...WRITE4, idempotentHint: true },
13120
+ handler: (args) => mixerLoadResult(args.emptyReservoir === true ? controller.emptyMixerBrush() : controller.cleanMixerBrush())
11835
13121
  };
11836
13122
  const fill = {
11837
13123
  name: "fill_pixels",
@@ -11842,7 +13128,7 @@ function createImagePaintTools(controller) {
11842
13128
  properties: {
11843
13129
  color: { type: "string", description: "Fill colour #rrggbb or #rrggbbaa (default the foreground)." },
11844
13130
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Fill opacity 0..1 (default 1)." },
11845
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
13131
+ blend: { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal). pigment mixes the colour into the pixels like paint, opacity being the share of new paint." },
11846
13132
  useSelection: { type: "boolean", description: "Limit to the selection when there is one (default true)." },
11847
13133
  ...TARGET
11848
13134
  },
@@ -11873,11 +13159,11 @@ function createImagePaintTools(controller) {
11873
13159
  annotations: { title: "Clear pixels", ...DESTRUCTIVE3 },
11874
13160
  handler: (args) => controller.clearPixels({ opacity: args.opacity, useSelection: args.useSelection, ...readTarget(args) })
11875
13161
  };
11876
- return [paintStroke, fill, clear];
13162
+ return [paintStroke, fill, clear, getMixer, loadMixerTool, cleanMixerTool];
11877
13163
  }
11878
13164
 
11879
13165
  // src/image-editor/psd-tools.ts
11880
- var READ4 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
13166
+ var READ5 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
11881
13167
  var DESTRUCTIVE4 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
11882
13168
  var DATA = {
11883
13169
  type: "string",
@@ -11888,7 +13174,7 @@ function psdBytesFromBase64(data) {
11888
13174
  if (typeof data !== "string" || !data.trim()) throw new PsdError("data is required: the PSD file as base64.");
11889
13175
  const body = data.trim().replace(/^data:[^,]*;base64,/i, "");
11890
13176
  if (!/^[A-Za-z0-9+/=_\s-]+$/.test(body)) throw new PsdError("data is not base64; send the PSD file bytes base64-encoded.");
11891
- const bytes = _chunk73L6TROJcjs.base64ToBytes.call(void 0, body);
13177
+ const bytes = _chunkT422YCHRcjs.base64ToBytes.call(void 0, body);
11892
13178
  if (bytes.length < 26) throw new PsdError(`data decodes to ${bytes.length} bytes, too short for a PSD (at least 26).`);
11893
13179
  return bytes;
11894
13180
  }
@@ -11898,7 +13184,7 @@ function createImagePsdTools(controller) {
11898
13184
  title: "Inspect a PSD",
11899
13185
  description: "Reads a PSD / PSB without opening it: size, bit depth, colour mode, resolution, and every layer (bottom first, a group before its children) with its PSD kind, the layer type it would become and its status (mapped, approximated or dropped, with notes), plus the import warnings. Changes nothing. Call before import_psd to see what would be lost.",
11900
13186
  inputSchema: { type: "object", properties: { data: DATA }, required: ["data"], additionalProperties: false },
11901
- annotations: { title: "Inspect a PSD", ...READ4 },
13187
+ annotations: { title: "Inspect a PSD", ...READ5 },
11902
13188
  handler: ({ data }) => {
11903
13189
  const res = importPsd(psdBytesFromBase64(data), { skipPixels: true });
11904
13190
  return {
@@ -11914,7 +13200,7 @@ function createImagePsdTools(controller) {
11914
13200
  const open = {
11915
13201
  name: "import_psd",
11916
13202
  title: "Open a PSD as the document",
11917
- description: "Opens a PSD / PSB as the document, replacing the current layers, crop and rotation (one undo step; undo brings the previous document back). Pixel, group and adjustment layers, masks, blend modes, opacity, fill, clipping, visibility and locks map directly; type, smart-object, fill and shape layers come in as their pixels; unsupported adjustments are left out. Returns the new layer tree with ids, the size and the warnings (each names the affected layers).",
13203
+ description: "Opens a PSD / PSB as the document, replacing the current layers, crop and rotation (one undo step; undo brings the previous document back). Pixel, group and adjustment layers, masks, blend modes, opacity, fill, clipping, visibility, locks, layer effects (with the patterns and global light of the file) map directly; type, smart-object, fill and shape layers come in as their pixels; unsupported adjustments are left out. Returns the new layer tree with ids, the size and the warnings (each names the affected layers).",
11918
13204
  inputSchema: { type: "object", properties: { data: DATA }, required: ["data"], additionalProperties: false },
11919
13205
  annotations: { title: "Open a PSD as the document", ...DESTRUCTIVE4 },
11920
13206
  handler: ({ data }) => {
@@ -11933,13 +13219,13 @@ function createImagePsdTools(controller) {
11933
13219
  const save = {
11934
13220
  name: "export_psd",
11935
13221
  title: "Export the document as a PSD",
11936
- description: "Writes the document as an 8-bit RGB PSD (a PSB above 30000 px) with real layers, groups, adjustment layers and masks, in the source frame (crop and rotation are not applied). Layer filters and depth masks are baked, annotation layers are rasterized (in a browser; elsewhere left out), and the merged image is the editor's composite. Changes nothing. Returns the file as base64, its size in bytes, whether it is a PSB, and warnings for everything that was changed or left out.",
13222
+ description: "Writes the document as an 8-bit RGB PSD (a PSB above 30000 px) with real layers, groups, adjustment layers, masks and layer effects (an effects block opened from a PSD is written back unchanged while its effects are; the patterns effects use are embedded), in the source frame (crop and rotation are not applied). Layer filters and depth masks are baked, annotation layers are rasterized (in a browser; elsewhere left out), and the merged image is the editor's composite. Changes nothing. Returns the file as base64, its size in bytes, whether it is a PSB, and warnings for everything that was changed or left out.",
11937
13223
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
11938
- annotations: { title: "Export the document as a PSD", ...READ4 },
13224
+ annotations: { title: "Export the document as a PSD", ...READ5 },
11939
13225
  handler: async () => {
11940
13226
  const res = await controller.toPsd();
11941
13227
  return {
11942
- data: _chunk73L6TROJcjs.bytesToBase64.call(void 0, res.bytes),
13228
+ data: _chunkT422YCHRcjs.bytesToBase64.call(void 0, res.bytes),
11943
13229
  mimeType: "image/vnd.adobe.photoshop",
11944
13230
  size: res.bytes.length,
11945
13231
  psb: res.psb,
@@ -12011,7 +13297,7 @@ function createImageEditorToolProvider(controller, options = {}) {
12011
13297
  default: def
12012
13298
  }))
12013
13299
  })),
12014
- blendModes: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id),
13300
+ blendModes: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id),
12015
13301
  layerPathFormat: "layers.<layerId>.<controlId>"
12016
13302
  })
12017
13303
  };
@@ -12102,7 +13388,7 @@ function createImageEditorToolProvider(controller, options = {}) {
12102
13388
  kind: { type: "string", enum: ADJUSTMENT_KINDS.map((k) => k.kind), description: "Adjustment kind." },
12103
13389
  params: { type: "object", description: "Initial parameters (see list_controls); merged with neutral defaults." },
12104
13390
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0-1 (default 1)." },
12105
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
13391
+ blend: { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
12106
13392
  name: { type: "string", description: "Layer name shown in the layers panel." },
12107
13393
  aboveId: { type: "string", description: "Put the layer directly above this layer (from list_layers). Default: above the other adjustment layers, below annotations." },
12108
13394
  parentId: { type: "string", description: "Put the layer at the top of this group (from list_layers)." }
@@ -12119,12 +13405,12 @@ function createImageEditorToolProvider(controller, options = {}) {
12119
13405
  },
12120
13406
  handler: ({ kind, params, opacity, blend, name, aboveId, parentId }) => {
12121
13407
  if (!isAdjustmentKind(kind)) throw new Error(`Unknown adjustment kind "${kind}".`);
12122
- if (blend !== void 0 && !_chunkZOOEX3WTcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
13408
+ if (blend !== void 0 && !_chunkCRMAXIUVcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
12123
13409
  if (aboveId !== void 0 && parentId !== void 0) throw new Error("Give aboveId or parentId, not both.");
12124
13410
  for (const ref of [aboveId, parentId]) {
12125
13411
  if (ref !== void 0 && !controller.getLayer(ref)) throw new Error(`Unknown layer "${ref}". Call list_layers for ids.`);
12126
13412
  }
12127
- if (parentId !== void 0 && _optionalChain([controller, 'access', _246 => _246.getLayer, 'call', _247 => _247(parentId), 'optionalAccess', _248 => _248.type]) !== "group") throw new Error(`Layer "${parentId}" is not a group.`);
13413
+ if (parentId !== void 0 && _optionalChain([controller, 'access', _287 => _287.getLayer, 'call', _288 => _288(parentId), 'optionalAccess', _289 => _289.type]) !== "group") throw new Error(`Layer "${parentId}" is not a group.`);
12128
13414
  const id = controller.addAdjustmentLayer({ kind, params, opacity, blend, name, aboveId, parentId });
12129
13415
  const layer = controller.getAdjustmentLayer(id);
12130
13416
  return { layer: JSON.parse(JSON.stringify(layer)), index: controller.getAdjustmentLayers().findIndex((l) => l.id === id) };
@@ -12191,7 +13477,7 @@ function createImageEditorToolProvider(controller, options = {}) {
12191
13477
  ...createImageLayerTools(controller),
12192
13478
  ...createImageEffectTools(controller),
12193
13479
  ...createImagePaintTools(controller),
12194
- ..._chunk4F3YDIWWcjs.createPigmentTools.call(void 0, ),
13480
+ ..._chunkZZOTHJ4Kcjs.createPigmentTools.call(void 0, ),
12195
13481
  ...createImagePsdTools(controller)
12196
13482
  ]
12197
13483
  };
@@ -12252,19 +13538,19 @@ function removeCurvePoint(points, index) {
12252
13538
  var round22 = (v) => Math.round(v * 100) / 100;
12253
13539
 
12254
13540
  // src/image-editor/selection/gesture.ts
12255
- var SelectionGesture = (_class8 = class {
12256
- constructor(controller, getOptions) {;_class8.prototype.__init50.call(this);_class8.prototype.__init51.call(this);_class8.prototype.__init52.call(this);_class8.prototype.__init53.call(this);_class8.prototype.__init54.call(this);
13541
+ var SelectionGesture = (_class9 = class {
13542
+ constructor(controller, getOptions) {;_class9.prototype.__init56.call(this);_class9.prototype.__init57.call(this);_class9.prototype.__init58.call(this);_class9.prototype.__init59.call(this);_class9.prototype.__init60.call(this);
12257
13543
  this.controller = controller;
12258
13544
  this.getOptions = getOptions;
12259
13545
  }
12260
13546
 
12261
13547
 
12262
- __init50() {this.start = null}
12263
- __init51() {this.points = []}
12264
- __init52() {this.current = null}
12265
- __init53() {this.modifiers = {}}
13548
+ __init56() {this.start = null}
13549
+ __init57() {this.points = []}
13550
+ __init58() {this.current = null}
13551
+ __init59() {this.modifiers = {}}
12266
13552
  /** The last error (e.g. pixels unavailable for the wand), for the UI to show. */
12267
- __init54() {this.error = null}
13553
+ __init60() {this.error = null}
12268
13554
  get active() {
12269
13555
  return this.start !== null;
12270
13556
  }
@@ -12352,7 +13638,7 @@ var SelectionGesture = (_class8 = class {
12352
13638
  this.current = null;
12353
13639
  this.points = [];
12354
13640
  }
12355
- }, _class8);
13641
+ }, _class9);
12356
13642
 
12357
13643
  // src/image-editor/mosaic-filter.ts
12358
13644
  function resolveMosaicRegionBounds(region, imgWidth, imgHeight) {
@@ -12494,9 +13780,9 @@ function applyRegionBlur(imageData, regions, radius = 10) {
12494
13780
  // src/image-editor/layers/panel.ts
12495
13781
  function layerPanelRows(layers, activeId) {
12496
13782
  const rows = [];
12497
- const walk = (list, depth, parentId) => {
12498
- for (let i = list.length - 1; i >= 0; i--) {
12499
- const layer = list[i];
13783
+ const walk = (list2, depth, parentId) => {
13784
+ for (let i = list2.length - 1; i >= 0; i--) {
13785
+ const layer = list2[i];
12500
13786
  rows.push({
12501
13787
  layer,
12502
13788
  depth,
@@ -12535,7 +13821,7 @@ function dropZone(fraction, isGroup) {
12535
13821
  }
12536
13822
  function dropPlacement(layers, dragId, targetId, zone) {
12537
13823
  if (dragId === targetId) return null;
12538
- const target = _chunk73L6TROJcjs.findLayer.call(void 0, layers, targetId);
13824
+ const target = _chunkT422YCHRcjs.findLayer.call(void 0, layers, targetId);
12539
13825
  if (!target) return null;
12540
13826
  if (zone === "inside" && target.layer.type === "group") return { parentId: targetId };
12541
13827
  return zone === "above" ? { aboveId: targetId } : { belowId: targetId };
@@ -12543,35 +13829,35 @@ function dropPlacement(layers, dragId, targetId, zone) {
12543
13829
  function layerMenu(controller) {
12544
13830
  const s = controller.getState();
12545
13831
  const active = controller.getActiveLayer();
12546
- const loc = active ? _chunk73L6TROJcjs.findLayer.call(void 0, s.layers, active.id) : null;
13832
+ const loc = active ? _chunkT422YCHRcjs.findLayer.call(void 0, s.layers, active.id) : null;
12547
13833
  const siblings = loc ? loc.parent ? loc.parent.children : s.layers : [];
12548
13834
  const below = loc ? siblings[loc.index - 1] : void 0;
12549
13835
  const hasSel = controller.hasSelection;
12550
- const isPixel = _optionalChain([active, 'optionalAccess', _249 => _249.type]) === "pixel";
13836
+ const isPixel = _optionalChain([active, 'optionalAccess', _290 => _290.type]) === "pixel";
12551
13837
  return [
12552
13838
  { action: "new-layer", label: "New Layer", enabled: true },
12553
13839
  { action: "new-group", label: "New Group", enabled: true },
12554
13840
  { action: "duplicate", label: "Duplicate Layer", enabled: Boolean(active) },
12555
13841
  { action: "delete", label: "Delete Layer", enabled: Boolean(active) },
12556
13842
  { action: "group-selected", label: "Group Layer", enabled: Boolean(active) },
12557
- { action: "ungroup", label: "Ungroup", enabled: _optionalChain([active, 'optionalAccess', _250 => _250.type]) === "group" },
12558
- { action: "merge-down", label: "Merge Down", enabled: Boolean(_optionalChain([active, 'optionalAccess', _251 => _251.visible]) && _optionalChain([below, 'optionalAccess', _252 => _252.type]) === "pixel") },
13843
+ { action: "ungroup", label: "Ungroup", enabled: _optionalChain([active, 'optionalAccess', _291 => _291.type]) === "group" },
13844
+ { action: "merge-down", label: "Merge Down", enabled: Boolean(_optionalChain([active, 'optionalAccess', _292 => _292.visible]) && _optionalChain([below, 'optionalAccess', _293 => _293.type]) === "pixel") },
12559
13845
  { action: "merge-visible", label: "Merge Visible", enabled: s.layers.some((l) => l.visible) },
12560
13846
  { action: "flatten", label: "Flatten Image", enabled: s.layers.length > 0 },
12561
13847
  { action: "via-copy", label: "Layer via Copy", enabled: isPixel && hasSel },
12562
13848
  { action: "via-cut", label: "Layer via Cut", enabled: isPixel && hasSel },
12563
13849
  { action: "add-mask", label: "Add Layer Mask", enabled: Boolean(active) },
12564
13850
  { action: "add-mask-selection", label: "Add Mask from Selection", enabled: Boolean(active) && hasSel },
12565
- { action: "apply-mask", label: "Apply Layer Mask", enabled: isPixel && Boolean(_optionalChain([active, 'optionalAccess', _253 => _253.mask])) },
12566
- { action: "delete-mask", label: "Delete Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _254 => _254.mask])) },
12567
- { action: "toggle-mask", label: _optionalChain([active, 'optionalAccess', _255 => _255.mask, 'optionalAccess', _256 => _256.enabled]) === false ? "Enable Layer Mask" : "Disable Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _257 => _257.mask])) },
12568
- { action: "rasterize", label: "Rasterize Layer", enabled: _optionalChain([active, 'optionalAccess', _258 => _258.type]) === "annotation" || isPixel && Boolean(_optionalChain([active, 'optionalAccess', _259 => _259.type]) === "pixel" && _optionalChain([active, 'access', _260 => _260.filters, 'optionalAccess', _261 => _261.length])) },
12569
- { action: "toggle-clip", label: _optionalChain([active, 'optionalAccess', _262 => _262.clipped]) ? "Release Clipping Mask" : "Create Clipping Mask", enabled: Boolean(loc && loc.index > 0) }
13851
+ { action: "apply-mask", label: "Apply Layer Mask", enabled: isPixel && Boolean(_optionalChain([active, 'optionalAccess', _294 => _294.mask])) },
13852
+ { action: "delete-mask", label: "Delete Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _295 => _295.mask])) },
13853
+ { action: "toggle-mask", label: _optionalChain([active, 'optionalAccess', _296 => _296.mask, 'optionalAccess', _297 => _297.enabled]) === false ? "Enable Layer Mask" : "Disable Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _298 => _298.mask])) },
13854
+ { action: "rasterize", label: "Rasterize Layer", enabled: _optionalChain([active, 'optionalAccess', _299 => _299.type]) === "annotation" || isPixel && Boolean(_optionalChain([active, 'optionalAccess', _300 => _300.type]) === "pixel" && _optionalChain([active, 'access', _301 => _301.filters, 'optionalAccess', _302 => _302.length])) },
13855
+ { action: "toggle-clip", label: _optionalChain([active, 'optionalAccess', _303 => _303.clipped]) ? "Release Clipping Mask" : "Create Clipping Mask", enabled: Boolean(loc && loc.index > 0) }
12570
13856
  ];
12571
13857
  }
12572
13858
  async function runLayerMenuAction(controller, action) {
12573
13859
  const active = controller.getActiveLayer();
12574
- const id = _optionalChain([active, 'optionalAccess', _263 => _263.id]);
13860
+ const id = _optionalChain([active, 'optionalAccess', _304 => _304.id]);
12575
13861
  try {
12576
13862
  switch (action) {
12577
13863
  case "new-layer":
@@ -12618,13 +13904,13 @@ async function runLayerMenuAction(controller, action) {
12618
13904
  if (id) controller.removeLayerMask(id);
12619
13905
  break;
12620
13906
  case "toggle-mask":
12621
- if (id && _optionalChain([active, 'optionalAccess', _264 => _264.mask])) controller.setLayerMaskProps(id, { enabled: active.mask.enabled === false });
13907
+ if (id && _optionalChain([active, 'optionalAccess', _305 => _305.mask])) controller.setLayerMaskProps(id, { enabled: active.mask.enabled === false });
12622
13908
  break;
12623
13909
  case "rasterize":
12624
13910
  if (id) await controller.rasterizeLayer(id);
12625
13911
  break;
12626
13912
  case "toggle-clip":
12627
- if (id) controller.setLayerProperties(id, { clipped: !_optionalChain([active, 'optionalAccess', _265 => _265.clipped]) });
13913
+ if (id) controller.setLayerProperties(id, { clipped: !_optionalChain([active, 'optionalAccess', _306 => _306.clipped]) });
12628
13914
  break;
12629
13915
  }
12630
13916
  return null;
@@ -12633,145 +13919,6 @@ async function runLayerMenuAction(controller, action) {
12633
13919
  }
12634
13920
  }
12635
13921
 
12636
- // src/image-editor/layers/paint-ui.ts
12637
- var plain2 = { kind: "plain" };
12638
- var BRUSH_OPTION_CONTROLS = [
12639
- { id: "size", label: "Size", section: "layer", min: 1, max: 500, step: 1, default: 20, decimals: 0, track: plain2, unit: "px" },
12640
- { id: "hardness", label: "Hardness", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12641
- { id: "opacity", label: "Opacity", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12642
- { id: "flow", label: "Flow", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12643
- { id: "smoothing", label: "Smoothing", section: "layer", min: 0, max: 0.95, step: 0.01, default: 0, decimals: 0, track: plain2, displayScale: 100, unit: "%" }
12644
- ];
12645
- var PAINT_TOOLS = [
12646
- { id: "move", label: "Move", shortcut: "V" },
12647
- { id: "brush", label: "Brush", shortcut: "B" },
12648
- { id: "eraser", label: "Eraser", shortcut: "E" }
12649
- ];
12650
- var isPaintTool = (tool) => tool === "move" || tool === "brush" || tool === "eraser";
12651
- function sizeStep(size) {
12652
- return size < 10 ? 1 : size < 50 ? 5 : size < 100 ? 10 : size < 200 ? 25 : size < 500 ? 50 : 100;
12653
- }
12654
- var isTyping = (t) => {
12655
- const el = t;
12656
- return Boolean(el && (el.isContentEditable || el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT"));
12657
- };
12658
- function handlePaintShortcut(controller, e) {
12659
- if (e.ctrlKey || e.metaKey || e.altKey || isTyping(e.target)) return false;
12660
- const brush = controller.getState().paint.brush;
12661
- const set = (b) => controller.setPaintOptions({ brush: b });
12662
- const key = e.key;
12663
- switch (key.toLowerCase()) {
12664
- case "b":
12665
- controller.setTool("brush");
12666
- return true;
12667
- case "e":
12668
- controller.setTool("eraser");
12669
- return true;
12670
- case "v":
12671
- controller.setTool("move");
12672
- return true;
12673
- case "d":
12674
- controller.resetPaintColors();
12675
- return true;
12676
- case "x":
12677
- controller.swapPaintColors();
12678
- return true;
12679
- }
12680
- if (key === "[" || key === "{") {
12681
- if (e.shiftKey || key === "{") set({ hardness: Math.max(0, Math.round((brush.hardness - 0.25) * 4) / 4) });
12682
- else set({ size: Math.max(1, brush.size - sizeStep(brush.size - 1)) });
12683
- return true;
12684
- }
12685
- if (key === "]" || key === "}") {
12686
- if (e.shiftKey || key === "}") set({ hardness: Math.min(1, Math.round((brush.hardness + 0.25) * 4) / 4) });
12687
- else set({ size: Math.min(_chunk4F3YDIWWcjs.MAX_BRUSH_SIZE, brush.size + sizeStep(brush.size)) });
12688
- return true;
12689
- }
12690
- if (/^[0-9]$/.test(key) && isPaintTool(controller.getState().activeTool)) {
12691
- set({ opacity: key === "0" ? 1 : Number(key) / 10 });
12692
- return true;
12693
- }
12694
- return false;
12695
- }
12696
- function pointerPressure(e) {
12697
- if (e.pointerType === "pen" && typeof e.pressure === "number" && e.pressure > 0) return Math.min(1, e.pressure);
12698
- return 1;
12699
- }
12700
- var PaintGesture = (_class9 = class {
12701
- constructor(controller) {;_class9.prototype.__init55.call(this);_class9.prototype.__init56.call(this);_class9.prototype.__init57.call(this);
12702
- this.controller = controller;
12703
- }
12704
-
12705
- __init55() {this.stroke = null}
12706
- __init56() {this.move = null}
12707
- /** The last refusal (e.g. "layer is locked"), for the editor to show. */
12708
- __init57() {this.error = null}
12709
- get active() {
12710
- return Boolean(this.stroke || this.move);
12711
- }
12712
- down(sample) {
12713
- this.error = null;
12714
- const tool = this.controller.getState().activeTool;
12715
- try {
12716
- if (tool === "move") {
12717
- const layer = this.controller.getActiveLayer();
12718
- if (!layer) throw new Error("Select a layer to move in the Layers panel.");
12719
- if (layer.type !== "pixel") throw new Error(`Only pixel layers move; "${layer.name}" is a ${layer.type} layer.`);
12720
- if (_optionalChain([layer, 'access', _266 => _266.locks, 'optionalAccess', _267 => _267.all]) || _optionalChain([layer, 'access', _268 => _268.locks, 'optionalAccess', _269 => _269.position])) throw new Error(`Layer "${layer.name}" has its position locked.`);
12721
- this.move = { id: layer.id, start: { x: sample.x, y: sample.y }, origin: { ...layer.offset }, moved: false };
12722
- return null;
12723
- }
12724
- if (tool === "brush" || tool === "eraser") {
12725
- this.stroke = this.controller.beginStroke({ tool });
12726
- this.stroke.push([sample]);
12727
- return null;
12728
- }
12729
- } catch (err) {
12730
- this.error = err instanceof Error ? err.message : String(err);
12731
- this.stroke = null;
12732
- this.move = null;
12733
- }
12734
- return this.error;
12735
- }
12736
- /** Feeds pointer samples (all coalesced events of one move, in order). */
12737
- moveTo(samples) {
12738
- if (!samples.length) return;
12739
- if (this.stroke) {
12740
- this.stroke.push(samples);
12741
- return;
12742
- }
12743
- const m = this.move;
12744
- if (m) {
12745
- const last = samples[samples.length - 1];
12746
- const x = m.origin.x + Math.round(last.x - m.start.x);
12747
- const y = m.origin.y + Math.round(last.y - m.start.y);
12748
- try {
12749
- this.controller.offsetLayer(m.id, { x, y }, !m.moved);
12750
- m.moved = true;
12751
- } catch (err) {
12752
- this.error = err instanceof Error ? err.message : String(err);
12753
- this.move = null;
12754
- }
12755
- }
12756
- }
12757
- up() {
12758
- if (this.stroke) {
12759
- try {
12760
- this.stroke.end();
12761
- } catch (err) {
12762
- this.error = err instanceof Error ? err.message : String(err);
12763
- }
12764
- }
12765
- this.stroke = null;
12766
- this.move = null;
12767
- }
12768
- cancel() {
12769
- _optionalChain([this, 'access', _270 => _270.stroke, 'optionalAccess', _271 => _271.cancel, 'call', _272 => _272()]);
12770
- this.stroke = null;
12771
- this.move = null;
12772
- }
12773
- }, _class9);
12774
-
12775
13922
  // src/image-editor/psd/ui.ts
12776
13923
  var PSD_FILE_ACCEPT = ".psd,.psb,image/vnd.adobe.photoshop,application/x-photoshop";
12777
13924
  function blobBytes(file) {
@@ -13222,5 +14369,58 @@ async function downloadPsd(controller, name = "image") {
13222
14369
 
13223
14370
 
13224
14371
 
13225
- exports.ADJUSTMENT_KEYS = ADJUSTMENT_KEYS; exports.ADJUSTMENT_KINDS = ADJUSTMENT_KINDS; exports.ADJUSTMENT_LAYER_CONTROLS = ADJUSTMENT_LAYER_CONTROLS; exports.ADJUSTMENT_LAYER_OPACITY_CONTROL = ADJUSTMENT_LAYER_OPACITY_CONTROL; exports.ADJUSTMENT_LUT_SIZE = ADJUSTMENT_LUT_SIZE; exports.AS_SHOT_KELVIN = AS_SHOT_KELVIN; exports.BACKGROUND_LAYER_ID = BACKGROUND_LAYER_ID; exports.BACKGROUND_LAYER_NAME = BACKGROUND_LAYER_NAME; exports.BLEND_MODES = _chunkZOOEX3WTcjs.BLEND_MODES; exports.BLUR_FILTER_ID = BLUR_FILTER_ID; exports.BRUSH_OPTION_CONTROLS = BRUSH_OPTION_CONTROLS; exports.CoverageMap = _chunk4F3YDIWWcjs.CoverageMap; exports.D50 = D50; exports.D65 = D65; exports.DEFAULT_ADJUSTMENTS = DEFAULT_ADJUSTMENTS; exports.DEFAULT_BRUSH = _chunk4F3YDIWWcjs.DEFAULT_BRUSH; exports.DEFAULT_DEPTH_MASK = DEFAULT_DEPTH_MASK; exports.DEFAULT_REFINE_EDGE_PARAMS = DEFAULT_REFINE_EDGE_PARAMS; exports.DEFAULT_SELECTION_TOOL_OPTIONS = DEFAULT_SELECTION_TOOL_OPTIONS; exports.DEFAULT_TRANSFORM = DEFAULT_TRANSFORM; exports.DEVELOP_FILTER_ID = DEVELOP_FILTER_ID; exports.DIRECT_GAUSSIAN_MAX_SIGMA = _chunk73L6TROJcjs.DIRECT_GAUSSIAN_MAX_SIGMA; exports.DabWalker = _chunk4F3YDIWWcjs.DabWalker; exports.EMPTY_DISTANCE = EMPTY_DISTANCE; exports.GUIDED_FILTER_EPS = GUIDED_FILTER_EPS; exports.HISTOGRAM_BINS = HISTOGRAM_BINS; exports.HUE_RANGE_LABELS = HUE_RANGE_LABELS; exports.IDENTITY_MATRIX3 = IDENTITY_MATRIX3; exports.IMAGE_ADJUSTMENT_CONTROLS = IMAGE_ADJUSTMENT_CONTROLS; exports.IMAGE_EDITOR_SCHEMA_VERSION = IMAGE_EDITOR_SCHEMA_VERSION; exports.IMAGE_EDITOR_STATE_VERSION = IMAGE_EDITOR_STATE_VERSION; exports.ImageEditorController = ImageEditorController; exports.ImageEditorRenderer = ImageEditorRenderer; exports.LATEST_PROCESS_VERSION = LATEST_PROCESS_VERSION; exports.LAYERED_SCHEMA_VERSION = LAYERED_SCHEMA_VERSION; exports.LEGACY_PROCESS_VERSION = LEGACY_PROCESS_VERSION; exports.LUMA_709 = LUMA_709; exports.LayerCompositor = LayerCompositor; exports.LayerOperationError = LayerOperationError; exports.MAX_BRUSH_SIZE = _chunk4F3YDIWWcjs.MAX_BRUSH_SIZE; exports.MAX_KELVIN = MAX_KELVIN; exports.MIN_KELVIN = MIN_KELVIN; exports.MIRED_PER_TEMPERATURE_UNIT = MIRED_PER_TEMPERATURE_UNIT; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PIGMENT_BANDS = _chunk4F3YDIWWcjs.PIGMENT_BANDS; exports.PIGMENT_LAMBDA_MIN = _chunk4F3YDIWWcjs.PIGMENT_LAMBDA_MIN; exports.PIGMENT_LAMBDA_STEP = _chunk4F3YDIWWcjs.PIGMENT_LAMBDA_STEP; exports.PIGMENT_WAVELENGTHS = _chunk4F3YDIWWcjs.PIGMENT_WAVELENGTHS; exports.PSD_BLEND_KEYS = PSD_BLEND_KEYS; exports.PSD_FILE_ACCEPT = PSD_FILE_ACCEPT; exports.PaintGesture = PaintGesture; exports.PaintStrokeSession = PaintStrokeSession; exports.PsdError = PsdError; exports.REFINE_EDGE_CONTROLS = REFINE_EDGE_CONTROLS; exports.SELECTION_MODES = SELECTION_MODES; exports.SELECTION_MODE_LABELS = SELECTION_MODE_LABELS; exports.SELECTION_MODIFY_OPS = SELECTION_MODIFY_OPS; exports.SELECTION_TOOLS = SELECTION_TOOLS; exports.SUPPORTED_ADJUSTMENT_KEYS = SUPPORTED_ADJUSTMENT_KEYS; exports.SelectionGesture = SelectionGesture; exports.StrokeCoverage = _chunk4F3YDIWWcjs.StrokeCoverage; exports.SurfaceDraft = _chunkZOOEX3WTcjs.SurfaceDraft; exports.TILE = _chunkZOOEX3WTcjs.TILE; exports.TILE_SHIFT = _chunkZOOEX3WTcjs.TILE_SHIFT; exports.TINT_SCALE = TINT_SCALE; exports.TONE_LUT_SIZE = TONE_LUT_SIZE; exports.TONE_RANGE_PRESETS = TONE_RANGE_PRESETS; exports.TiledSurface = _chunkZOOEX3WTcjs.TiledSurface; exports.VIBRANCE_GREY = VIBRANCE_GREY; exports.XYZ_D50_TO_SRGB = XYZ_D50_TO_SRGB; exports.ZlibError = _chunk73L6TROJcjs.ZlibError; exports.activeAdjustmentLayers = activeAdjustmentLayers; exports.addLayerEffect = addLayerEffect; exports.addLayerFilter = addLayerFilter; exports.addToHistogram = addToHistogram; exports.adjustmentKindLabel = adjustmentKindLabel; exports.adjustmentLayersKey = adjustmentLayersKey; exports.adjustmentNodeAsLayer = adjustmentNodeAsLayer; exports.adjustmentNodeFromLegacy = adjustmentNodeFromLegacy; exports.adler32 = _chunk73L6TROJcjs.adler32; exports.annotationLayerFor = annotationLayerFor; exports.annotationLayerName = annotationLayerName; exports.applyAdjustmentLayers = applyAdjustmentLayers; exports.applyAdjustments = applyAdjustments; exports.applyBoxBlur = applyBoxBlur; exports.applyDepthMask = applyDepthMask; exports.applyImageProjectionToContext = applyImageProjectionToContext; exports.applyLegacyAdjustments = applyLegacyAdjustments; exports.applyMatrix3 = applyMatrix3; exports.applyOutputStage = applyOutputStage; exports.applyProcess2Adjustments = applyProcess2Adjustments; exports.applyRegionBlur = applyRegionBlur; exports.applyRegionMosaic = applyRegionMosaic; exports.applyStrokeToTile = _chunk4F3YDIWWcjs.applyStrokeToTile; exports.backgroundLayer = backgroundLayer; exports.base64ToBytes = _chunk73L6TROJcjs.base64ToBytes; exports.baseProjection = baseProjection; exports.blackWhiteGray = blackWhiteGray; exports.blendChannel = _chunkZOOEX3WTcjs.blendChannel; exports.blendImageData = _chunkZOOEX3WTcjs.blendImageData; exports.blendLum = _chunkZOOEX3WTcjs.blendLum; exports.blendPixel = _chunkZOOEX3WTcjs.blendPixel; exports.blendRgb = _chunkZOOEX3WTcjs.blendRgb; exports.blendTile = _chunk73L6TROJcjs.blendTile; exports.blurFilter = blurFilter; exports.borderCoverage = borderCoverage; exports.boxMean = boxMean; exports.boxToCurvePoint = boxToCurvePoint; exports.bradfordAdaptation = bradfordAdaptation; exports.buildLayerMaskPlanes = buildLayerMaskPlanes; exports.buildToneLut = buildToneLut; exports.bytesToBase64 = _chunk73L6TROJcjs.bytesToBase64; exports.calculateCropDrag = calculateCropDrag; exports.canvasCompositeOperation = _chunkZOOEX3WTcjs.canvasCompositeOperation; exports.canvasToImagePoint = canvasToImagePoint; exports.changedTiles = _chunk73L6TROJcjs.changedTiles; exports.clampControlValue = clampControlValue; exports.clampCropToImage = clampCropToImage; exports.collectTiles = _chunkZOOEX3WTcjs.collectTiles; exports.colorBalanceChannel = colorBalanceChannel; exports.colorRange = colorRange; exports.combineSelections = combineSelections; exports.compileAdjustmentLayer = compileAdjustmentLayer; exports.computeHistogram = computeHistogram; exports.computeSelectionBounds = computeSelectionBounds; exports.contentBounds = _chunkZOOEX3WTcjs.contentBounds; exports.contractCoverage = contractCoverage; exports.controlPosition = controlPosition; exports.controlTrackBackground = controlTrackBackground; exports.coverageTileCoord = _chunk4F3YDIWWcjs.coverageTileCoord; exports.coverageToByte = coverageToByte; exports.coveringRect = coveringRect; exports.createAdjustmentLayer = createAdjustmentLayer; exports.createImageCaptureSurface = createImageCaptureSurface; exports.createImageEditTools = createImageEditTools; exports.createImageEditorToolProvider = createImageEditorToolProvider; exports.createImageEffectTools = createImageEffectTools; exports.createImageLayerTools = createImageLayerTools; exports.createImagePaintTools = createImagePaintTools; exports.createImagePsdTools = createImagePsdTools; exports.createImageSelectionTools = createImageSelectionTools; exports.createPigment = _chunk4F3YDIWWcjs.createPigment; exports.createPigmentTools = _chunk4F3YDIWWcjs.createPigmentTools; exports.createSelectionMask = createSelectionMask; exports.curveLut = _chunk73L6TROJcjs.curveLut; exports.curveLutFromLevels = curveLutFromLevels; exports.curvePointToBox = curvePointToBox; exports.curveSvgPath = curveSvgPath; exports.dabCoverage = _chunk4F3YDIWWcjs.dabCoverage; exports.dabRect = _chunk4F3YDIWWcjs.dabRect; exports.decodeLayerChannel = decodeLayerChannel; exports.decodeLayerMask = decodeLayerMask; exports.decodeMergedImage = decodeMergedImage; exports.decodePlanes = decodePlanes; exports.decodePng = _chunk73L6TROJcjs.decodePng; exports.decodePngDataUrl = decodePngDataUrl; exports.decodeSelectionRle = decodeSelectionRle; exports.defaultAdjustmentParams = defaultAdjustmentParams; exports.deflate = _chunk73L6TROJcjs.deflate; exports.deflateRaw = _chunk73L6TROJcjs.deflateRaw; exports.depthMaskAlpha = depthMaskAlpha; exports.depthRasterMask = depthRasterMask; exports.describeLayer = describeLayer; exports.describeLayerEffects = describeLayerEffects; exports.describeSelection = describeSelection; exports.deserializeEffects = deserializeEffects; exports.deserializeLayer = deserializeLayer; exports.deserializeLayers = deserializeLayers; exports.deserializeSelection = deserializeSelection; exports.developFilter = developFilter; exports.developFromAdjustments = developFromAdjustments; exports.developTarget = developTarget; exports.distanceTransform = distanceTransform; exports.downloadPsd = downloadPsd; exports.dropPlacement = dropPlacement; exports.dropZone = dropZone; exports.duplicateLayer = duplicateLayer; exports.edgeWidth = edgeWidth; exports.ellipsePoints = ellipsePoints; exports.ellipseSelection = ellipseSelection; exports.emptyHistogram = emptyHistogram; exports.emptySurface = _chunkZOOEX3WTcjs.emptySurface; exports.encodePng = _chunk73L6TROJcjs.encodePng; exports.encodeRle = encodeRle; exports.encodeSelectionRle = encodeSelectionRle; exports.encodeSurface = encodeSurface; exports.evaluateAdjustmentLayers = evaluateAdjustmentLayers; exports.expandCoverage = expandCoverage; exports.exportPsd = exportPsd; exports.featherCoverage = featherCoverage; exports.fillRect = _chunkZOOEX3WTcjs.fillRect; exports.findAdjustmentControl = findAdjustmentControl; exports.findLayer = _chunk73L6TROJcjs.findLayer; exports.findLayerControl = findLayerControl; exports.finishTile = _chunkZOOEX3WTcjs.finishTile; exports.flattenLayers = _chunk73L6TROJcjs.flattenLayers; exports.formatControlValue = formatControlValue; exports.fullSelection = fullSelection; exports.gaussianBlur = _chunk73L6TROJcjs.gaussianBlur; exports.getAnnotationBounds = getAnnotationBounds; exports.getControlPath = getControlPath; exports.getCropCursor = getCropCursor; exports.getRotatedSize = getRotatedSize; exports.getViewportMetrics = getViewportMetrics; exports.getViewportProjection = getViewportProjection; exports.globalImageCache = globalImageCache; exports.greyMorphology = greyMorphology; exports.groupLayers = groupLayers; exports.guidePlanes = guidePlanes; exports.guidedFilterColor = guidedFilterColor; exports.handlePaintShortcut = handlePaintShortcut; exports.hasResampledLegacyMask = hasResampledLegacyMask; exports.hashMaskContent = hashMaskContent; exports.hexToRgb = hexToRgb; exports.histogramPath = histogramPath; exports.hitTestAnnotation = hitTestAnnotation; exports.hitTestCrop = hitTestCrop; exports.hitTestCurvePoint = hitTestCurvePoint; exports.hslToRgb = hslToRgb; exports.hueRange = hueRange; exports.hueRangeTables = hueRangeTables; exports.hueRangeWeight = hueRangeWeight; exports.hueSaturation = hueSaturation; exports.identityCurve = identityCurve; exports.identityLevels = identityLevels; exports.imageEditorStateMigrations = imageEditorStateMigrations; exports.imageToCanvasPoint = imageToCanvasPoint; exports.importPsd = importPsd; exports.inflate = _chunk73L6TROJcjs.inflate; exports.inflateRaw = _chunk73L6TROJcjs.inflateRaw; exports.insertCurvePoint = insertCurvePoint; exports.insertLayer = _chunk73L6TROJcjs.insertLayer; exports.invertMatrix3 = invertMatrix3; exports.invertSelection = invertSelection; exports.isActiveFilter = isActiveFilter; exports.isAdjustmentKind = isAdjustmentKind; exports.isBlendMode = _chunkZOOEX3WTcjs.isBlendMode; exports.isDefaultDepthMask = isDefaultDepthMask; exports.isLayerLocked = _chunk73L6TROJcjs.isLayerLocked; exports.isLegacyShape = isLegacyShape; exports.isPaintTool = isPaintTool; exports.isPng = _chunk73L6TROJcjs.isPng; exports.isQuarterTurn = isQuarterTurn; exports.isQuarterTurnSwapped = isQuarterTurnSwapped; exports.isSelectionEmpty = isSelectionEmpty; exports.isSelectionMode = isSelectionMode; exports.isSeparableBlendMode = _chunkZOOEX3WTcjs.isSeparableBlendMode; exports.isSpatialFilter = isSpatialFilter; exports.kelvinToTemperature = kelvinToTemperature; exports.layerBadge = layerBadge; exports.layerEffectsOf = layerEffectsOf; exports.layerLabel = layerLabel; exports.layerMaskCoverage = layerMaskCoverage; exports.layerMaskFromSelection = layerMaskFromSelection; exports.layerMaskKey = layerMaskKey; exports.layerMenu = layerMenu; exports.layerName = layerName; exports.layerPanelRows = layerPanelRows; exports.layerTree = layerTree; exports.layerTypeLabel = layerTypeLabel; exports.layersFromLegacy = layersFromLegacy; exports.legacyAdjustmentLayer = legacyAdjustmentLayer; exports.legacyMaskOf = legacyMaskOf; exports.legacyView = legacyView; exports.lerpPigment = _chunk4F3YDIWWcjs.lerpPigment; exports.lerpPigmentInto = _chunk4F3YDIWWcjs.lerpPigmentInto; exports.levelsValue = levelsValue; exports.linearSrgbToXy = linearSrgbToXy; exports.linearToSrgb = linearToSrgb; exports.loadImageEditorDocument = loadImageEditorDocument; exports.magicWand = magicWand; exports.mapCropHandle = mapCropHandle; exports.mapLayer = _chunk73L6TROJcjs.mapLayer; exports.maskSummary = maskSummary; exports.migrateSerializedImageEditorState = migrateSerializedImageEditorState; exports.migrateToLayeredState = migrateToLayeredState; exports.mixPigments = _chunk4F3YDIWWcjs.mixPigments; exports.modifySelection = modifySelection; exports.moveCurvePoint = moveCurvePoint; exports.moveLayer = moveLayer; exports.mulMatrix3 = mulMatrix3; exports.needsLegacyBase = needsLegacyBase; exports.neutralHueRange = neutralHueRange; exports.newLayerId = newLayerId; exports.normalizeAdjustmentLayer = normalizeAdjustmentLayer; exports.normalizeAdjustmentLayers = normalizeAdjustmentLayers; exports.normalizeAngle = normalizeAngle; exports.normalizeBlendMode = _chunkZOOEX3WTcjs.normalizeBlendMode; exports.normalizeBrush = _chunk4F3YDIWWcjs.normalizeBrush; exports.normalizeFilter = normalizeFilter; exports.normalizeLayerMask = normalizeLayerMask; exports.normalizeProcessVersion = normalizeProcessVersion; exports.normalizeRect = normalizeRect; exports.normalizeRefineEdgeParams = normalizeRefineEdgeParams; exports.normalizeStoredAdjustments = normalizeStoredAdjustments; exports.offsetLayer = offsetLayer; exports.openPsdFile = openPsdFile; exports.packRgba = _chunkZOOEX3WTcjs.packRgba; exports.parseAdjustmentBlock = parseAdjustmentBlock; exports.parseBlend = parseBlend; exports.parseColor = parseColor; exports.parseDataUrl = _chunk73L6TROJcjs.parseDataUrl; exports.parseSelectionMode = parseSelectionMode; exports.parseVersionedDescriptor = parseVersionedDescriptor; exports.photoFilterMatrix = photoFilterMatrix; exports.pixelLayerBounds = pixelLayerBounds; exports.pixelLayers = pixelLayers; exports.placeLayer = placeLayer; exports.pngDataUrl = _chunk73L6TROJcjs.pngDataUrl; exports.pointerPressure = pointerPressure; exports.polygonCoverage = polygonCoverage; exports.polygonSelection = polygonSelection; exports.posterizeValue = posterizeValue; exports.projectImagePoint = projectImagePoint; exports.projectImageRect = projectImageRect; exports.projectMaskCoverage = projectMaskCoverage; exports.projectQuarterTurn = projectQuarterTurn; exports.psdBytesFromBase64 = psdBytesFromBase64; exports.psdFileName = psdFileName; exports.psdToLayers = psdToLayers; exports.quickMaskPixels = quickMaskPixels; exports.rangeLightness = rangeLightness; exports.rasterMaskFromLegacy = rasterMaskFromLegacy; exports.rasterizeDab = _chunk4F3YDIWWcjs.rasterizeDab; exports.readAdjustmentControls = readAdjustmentControls; exports.readPixel = _chunkZOOEX3WTcjs.readPixel; exports.readPsd = readPsd; exports.readRegion = _chunkZOOEX3WTcjs.readRegion; exports.rectSelection = rectSelection; exports.refineCoverage = refineCoverage; exports.refineEdgeHalo = refineEdgeHalo; exports.refineSelection = refineSelection; exports.reflectanceToRgb = _chunk4F3YDIWWcjs.reflectanceToRgb; exports.removeAlpha = removeAlpha; exports.removeCurvePoint = removeCurvePoint; exports.removeLayer = removeLayer; exports.removeLayerEffect = removeLayerEffect; exports.removeLayerFilter = removeLayerFilter; exports.renderLayeredBase = renderLayeredBase; exports.requireLayer = requireLayer; exports.requireUnlocked = requireUnlocked; exports.resizePixels = resizePixels; exports.resizeSelection = resizeSelection; exports.resolveExternalAssets = resolveExternalAssets; exports.resolveMosaicRegionBounds = resolveMosaicRegionBounds; exports.rgbToGray = rgbToGray; exports.rgbToHsl = rgbToHsl; exports.rgbToReflectance = _chunk4F3YDIWWcjs.rgbToReflectance; exports.runLayerMenuAction = runLayerMenuAction; exports.sampleLut = sampleLut; exports.sampleToneLut = sampleToneLut; exports.selectionArea = selectionArea; exports.selectionFromCoverage = selectionFromCoverage; exports.selectionFromPixels = selectionFromPixels; exports.selectionModeFromModifiers = selectionModeFromModifiers; exports.selectionOutline = selectionOutline; exports.selectionToCoverage = selectionToCoverage; exports.selectionToPixels = selectionToPixels; exports.selectionValueAt = selectionValueAt; exports.serializeEffects = serializeEffects; exports.serializeLayer = serializeLayer; exports.serializeLayers = serializeLayers; exports.serializeLayersExternal = serializeLayersExternal; exports.serializeSelection = serializeSelection; exports.setControlPath = setControlPath; exports.setLayerEffects = setLayerEffects; exports.setLayerEffectsEnabled = setLayerEffectsEnabled; exports.setLayerMask = setLayerMask; exports.setLayerProperties = setLayerProperties; exports.setLum = _chunkZOOEX3WTcjs.setLum; exports.setPigmentColor = _chunk4F3YDIWWcjs.setPigmentColor; exports.shiftCoverage = shiftCoverage; exports.smoothCoverage = smoothCoverage; exports.smoothPoints = _chunk4F3YDIWWcjs.smoothPoints; exports.solidSurface = _chunkZOOEX3WTcjs.solidSurface; exports.splitOverlayAnnotations = splitOverlayAnnotations; exports.srgb8ToLab = srgb8ToLab; exports.srgbToLinear = srgbToLinear; exports.sumHistograms = sumHistograms; exports.surfaceBytes = _chunkZOOEX3WTcjs.surfaceBytes; exports.surfaceFromPixels = _chunkZOOEX3WTcjs.surfaceFromPixels; exports.surfacesEqual = _chunkZOOEX3WTcjs.surfacesEqual; exports.tempTintToXy = tempTintToXy; exports.temperatureToKelvin = temperatureToKelvin; exports.tileCoord = _chunkZOOEX3WTcjs.tileCoord; exports.tileKey = _chunkZOOEX3WTcjs.tileKey; exports.tileRect = _chunkZOOEX3WTcjs.tileRect; exports.tilesInRect = _chunkZOOEX3WTcjs.tilesInRect; exports.tipFalloff = _chunk4F3YDIWWcjs.tipFalloff; exports.tipReach = _chunk4F3YDIWWcjs.tipReach; exports.tipShape = _chunk4F3YDIWWcjs.tipShape; exports.toHex = toHex2; exports.toneCurve = toneCurve; exports.toneLuts = toneLuts; exports.toneRange = toneRange; exports.translateSurface = _chunkZOOEX3WTcjs.translateSurface; exports.ungroupLayer = ungroupLayer; exports.uniformTile = _chunkZOOEX3WTcjs.uniformTile; exports.unionRect = unionRect; exports.unprojectCanvasPoint = unprojectCanvasPoint; exports.updateLayerEffect = updateLayerEffect; exports.updateLayerFilter = updateLayerFilter; exports.updateLayerMaskProps = updateLayerMaskProps; exports.uvToXy = uvToXy; exports.versionedDescriptorBytes = versionedDescriptorBytes; exports.vibranceLinear = vibranceLinear; exports.vibrancePixel = vibrancePixel; exports.walkDabs = _chunk4F3YDIWWcjs.walkDabs; exports.wbMatrix = wbMatrix; exports.whiteBalanceFromSample = whiteBalanceFromSample; exports.whiteBalanceMatrix = whiteBalanceMatrix; exports.withNewIds = withNewIds; exports.writeAdjustmentBlock = writeAdjustmentBlock; exports.writePsd = writePsd; exports.writeRegion = _chunkZOOEX3WTcjs.writeRegion; exports.xyToTempTint = xyToTempTint; exports.xyToUv = xyToUv;
14372
+
14373
+
14374
+
14375
+
14376
+
14377
+
14378
+
14379
+
14380
+
14381
+
14382
+
14383
+
14384
+
14385
+
14386
+
14387
+
14388
+
14389
+
14390
+
14391
+
14392
+
14393
+
14394
+
14395
+
14396
+
14397
+
14398
+
14399
+
14400
+
14401
+
14402
+
14403
+
14404
+
14405
+
14406
+
14407
+
14408
+
14409
+
14410
+
14411
+
14412
+
14413
+
14414
+
14415
+
14416
+
14417
+
14418
+
14419
+
14420
+
14421
+
14422
+
14423
+
14424
+
14425
+ exports.ADJUSTMENT_KEYS = ADJUSTMENT_KEYS; exports.ADJUSTMENT_KINDS = ADJUSTMENT_KINDS; exports.ADJUSTMENT_LAYER_CONTROLS = ADJUSTMENT_LAYER_CONTROLS; exports.ADJUSTMENT_LAYER_OPACITY_CONTROL = ADJUSTMENT_LAYER_OPACITY_CONTROL; exports.ADJUSTMENT_LUT_SIZE = ADJUSTMENT_LUT_SIZE; exports.AS_SHOT_KELVIN = AS_SHOT_KELVIN; exports.BACKGROUND_LAYER_ID = BACKGROUND_LAYER_ID; exports.BACKGROUND_LAYER_NAME = BACKGROUND_LAYER_NAME; exports.BLEND_MODES = _chunkCRMAXIUVcjs.BLEND_MODES; exports.BLUR_FILTER_ID = BLUR_FILTER_ID; exports.BRUSH_OPTION_CONTROLS = BRUSH_OPTION_CONTROLS; exports.CoverageMap = _chunkZZOTHJ4Kcjs.CoverageMap; exports.D50 = D50; exports.D65 = D65; exports.DEFAULT_ADJUSTMENTS = DEFAULT_ADJUSTMENTS; exports.DEFAULT_BRUSH = _chunkZZOTHJ4Kcjs.DEFAULT_BRUSH; exports.DEFAULT_DEPTH_MASK = DEFAULT_DEPTH_MASK; exports.DEFAULT_GLOBAL_LIGHT = _chunkT422YCHRcjs.DEFAULT_GLOBAL_LIGHT; exports.DEFAULT_MIXER = _chunkZZOTHJ4Kcjs.DEFAULT_MIXER; exports.DEFAULT_REFINE_EDGE_PARAMS = DEFAULT_REFINE_EDGE_PARAMS; exports.DEFAULT_SELECTION_TOOL_OPTIONS = DEFAULT_SELECTION_TOOL_OPTIONS; exports.DEFAULT_TRANSFORM = DEFAULT_TRANSFORM; exports.DEVELOP_FILTER_ID = DEVELOP_FILTER_ID; exports.DIRECT_GAUSSIAN_MAX_SIGMA = _chunkT422YCHRcjs.DIRECT_GAUSSIAN_MAX_SIGMA; exports.DabWalker = _chunkZZOTHJ4Kcjs.DabWalker; exports.EMPTY_DISTANCE = EMPTY_DISTANCE; exports.EMPTY_MIXER_LOAD = _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD; exports.GUIDED_FILTER_EPS = GUIDED_FILTER_EPS; exports.HISTOGRAM_BINS = HISTOGRAM_BINS; exports.HUE_RANGE_LABELS = HUE_RANGE_LABELS; exports.IDENTITY_MATRIX3 = IDENTITY_MATRIX3; exports.IMAGE_ADJUSTMENT_CONTROLS = IMAGE_ADJUSTMENT_CONTROLS; exports.IMAGE_EDITOR_SCHEMA_VERSION = IMAGE_EDITOR_SCHEMA_VERSION; exports.IMAGE_EDITOR_STATE_VERSION = IMAGE_EDITOR_STATE_VERSION; exports.ImageEditorController = ImageEditorController; exports.ImageEditorRenderer = ImageEditorRenderer; exports.LATEST_PROCESS_VERSION = LATEST_PROCESS_VERSION; exports.LAYERED_SCHEMA_VERSION = LAYERED_SCHEMA_VERSION; exports.LAYER_EFFECT_KINDS = _chunkT422YCHRcjs.LAYER_EFFECT_KINDS; exports.LEGACY_PROCESS_VERSION = LEGACY_PROCESS_VERSION; exports.LUMA_709 = LUMA_709; exports.LayerCompositor = LayerCompositor; exports.LayerEffectError = _chunkT422YCHRcjs.LayerEffectError; exports.LayerOperationError = LayerOperationError; exports.MAX_BRUSH_SIZE = _chunkZZOTHJ4Kcjs.MAX_BRUSH_SIZE; exports.MAX_EFFECT_REACH = _chunkT422YCHRcjs.MAX_EFFECT_REACH; exports.MAX_KELVIN = MAX_KELVIN; exports.MIN_KELVIN = MIN_KELVIN; exports.MIRED_PER_TEMPERATURE_UNIT = MIRED_PER_TEMPERATURE_UNIT; exports.MIXER_DRAIN = _chunkZZOTHJ4Kcjs.MIXER_DRAIN; exports.MIXER_MIXING_OPTIONS = MIXER_MIXING_OPTIONS; exports.MIXER_OPTION_CONTROLS = MIXER_OPTION_CONTROLS; exports.MIXER_PICKUP_RATE = _chunkZZOTHJ4Kcjs.MIXER_PICKUP_RATE; exports.MIXING_MODELS = _chunkZZOTHJ4Kcjs.MIXING_MODELS; exports.MixerStroke = _chunkZZOTHJ4Kcjs.MixerStroke; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PATTERN_BLOCK_KEYS = PATTERN_BLOCK_KEYS; exports.PIGMENT_BANDS = _chunkCRMAXIUVcjs.PIGMENT_BANDS; exports.PIGMENT_LAMBDA_MIN = _chunkCRMAXIUVcjs.PIGMENT_LAMBDA_MIN; exports.PIGMENT_LAMBDA_STEP = _chunkCRMAXIUVcjs.PIGMENT_LAMBDA_STEP; exports.PIGMENT_WAVELENGTHS = _chunkCRMAXIUVcjs.PIGMENT_WAVELENGTHS; exports.PSD_BLEND_KEYS = PSD_BLEND_KEYS; exports.PSD_FILE_ACCEPT = PSD_FILE_ACCEPT; exports.PaintGesture = PaintGesture; exports.PaintStrokeSession = PaintStrokeSession; exports.PatternPlacement = _chunkT422YCHRcjs.PatternPlacement; exports.PatternTile = _chunkT422YCHRcjs.PatternTile; exports.PsdError = PsdError; exports.REFINE_EDGE_CONTROLS = REFINE_EDGE_CONTROLS; exports.SELECTION_MODES = SELECTION_MODES; exports.SELECTION_MODE_LABELS = SELECTION_MODE_LABELS; exports.SELECTION_MODIFY_OPS = SELECTION_MODIFY_OPS; exports.SELECTION_TOOLS = SELECTION_TOOLS; exports.SUPPORTED_ADJUSTMENT_KEYS = SUPPORTED_ADJUSTMENT_KEYS; exports.SelectionGesture = SelectionGesture; exports.StrokeCoverage = _chunkZZOTHJ4Kcjs.StrokeCoverage; exports.SurfaceDraft = _chunkCRMAXIUVcjs.SurfaceDraft; exports.TILE = _chunkCRMAXIUVcjs.TILE; exports.TILE_SHIFT = _chunkCRMAXIUVcjs.TILE_SHIFT; exports.TINT_SCALE = TINT_SCALE; exports.TONE_LUT_SIZE = TONE_LUT_SIZE; exports.TONE_RANGE_PRESETS = TONE_RANGE_PRESETS; exports.TiledSurface = _chunkCRMAXIUVcjs.TiledSurface; exports.VIBRANCE_GREY = VIBRANCE_GREY; exports.XYZ_D50_TO_SRGB = XYZ_D50_TO_SRGB; exports.ZlibError = _chunkT422YCHRcjs.ZlibError; exports.activeAdjustmentLayers = activeAdjustmentLayers; exports.addLayerEffect = addLayerEffect; exports.addLayerFilter = addLayerFilter; exports.addToHistogram = addToHistogram; exports.adjustmentKindLabel = adjustmentKindLabel; exports.adjustmentLayersKey = adjustmentLayersKey; exports.adjustmentNodeAsLayer = adjustmentNodeAsLayer; exports.adjustmentNodeFromLegacy = adjustmentNodeFromLegacy; exports.adler32 = _chunkT422YCHRcjs.adler32; exports.annotationLayerFor = annotationLayerFor; exports.annotationLayerName = annotationLayerName; exports.applyAdjustmentLayers = applyAdjustmentLayers; exports.applyAdjustments = applyAdjustments; exports.applyBoxBlur = applyBoxBlur; exports.applyDepthMask = applyDepthMask; exports.applyImageProjectionToContext = applyImageProjectionToContext; exports.applyLegacyAdjustments = applyLegacyAdjustments; exports.applyMatrix3 = applyMatrix3; exports.applyOutputStage = applyOutputStage; exports.applyProcess2Adjustments = applyProcess2Adjustments; exports.applyRegionBlur = applyRegionBlur; exports.applyRegionMosaic = applyRegionMosaic; exports.applyStrokeToTile = _chunkZZOTHJ4Kcjs.applyStrokeToTile; exports.backgroundLayer = backgroundLayer; exports.base64ToBytes = _chunkT422YCHRcjs.base64ToBytes; exports.baseProjection = baseProjection; exports.blackWhiteGray = blackWhiteGray; exports.blendChannel = _chunkCRMAXIUVcjs.blendChannel; exports.blendImageData = _chunkCRMAXIUVcjs.blendImageData; exports.blendLum = _chunkCRMAXIUVcjs.blendLum; exports.blendPixel = _chunkCRMAXIUVcjs.blendPixel; exports.blendRgb = _chunkCRMAXIUVcjs.blendRgb; exports.blendTile = _chunkT422YCHRcjs.blendTile; exports.blurFilter = blurFilter; exports.borderCoverage = borderCoverage; exports.boxMean = boxMean; exports.boxToCurvePoint = boxToCurvePoint; exports.bradfordAdaptation = bradfordAdaptation; exports.buildLayerMaskPlanes = buildLayerMaskPlanes; exports.buildToneLut = buildToneLut; exports.builtinPattern = _chunkT422YCHRcjs.builtinPattern; exports.builtinPatternIds = _chunkT422YCHRcjs.builtinPatternIds; exports.bytesToBase64 = _chunkT422YCHRcjs.bytesToBase64; exports.calculateCropDrag = calculateCropDrag; exports.canvasCompositeOperation = _chunkCRMAXIUVcjs.canvasCompositeOperation; exports.canvasToImagePoint = canvasToImagePoint; exports.changedTiles = _chunkT422YCHRcjs.changedTiles; exports.clampControlValue = clampControlValue; exports.clampCropToImage = clampCropToImage; exports.cleanMixer = _chunkZZOTHJ4Kcjs.cleanMixer; exports.collectTiles = _chunkCRMAXIUVcjs.collectTiles; exports.colorBalanceChannel = colorBalanceChannel; exports.colorRange = colorRange; exports.combineSelections = combineSelections; exports.compileAdjustmentLayer = compileAdjustmentLayer; exports.computeHistogram = computeHistogram; exports.computeSelectionBounds = computeSelectionBounds; exports.contentBounds = _chunkCRMAXIUVcjs.contentBounds; exports.contractCoverage = contractCoverage; exports.controlPosition = controlPosition; exports.controlTrackBackground = controlTrackBackground; exports.coverageTileCoord = _chunkZZOTHJ4Kcjs.coverageTileCoord; exports.coverageToByte = coverageToByte; exports.coveringRect = coveringRect; exports.createAdjustmentLayer = createAdjustmentLayer; exports.createImageCaptureSurface = createImageCaptureSurface; exports.createImageEditTools = createImageEditTools; exports.createImageEditorToolProvider = createImageEditorToolProvider; exports.createImageEffectTools = createImageEffectTools; exports.createImageLayerTools = createImageLayerTools; exports.createImagePaintTools = createImagePaintTools; exports.createImagePsdTools = createImagePsdTools; exports.createImageSelectionTools = createImageSelectionTools; exports.createPigment = _chunkCRMAXIUVcjs.createPigment; exports.createPigmentTools = _chunkZZOTHJ4Kcjs.createPigmentTools; exports.createSelectionMask = createSelectionMask; exports.curveLut = _chunkT422YCHRcjs.curveLut; exports.curveLutFromLevels = curveLutFromLevels; exports.curvePointToBox = curvePointToBox; exports.curveSvgPath = curveSvgPath; exports.dabCoverage = _chunkZZOTHJ4Kcjs.dabCoverage; exports.dabRect = _chunkZZOTHJ4Kcjs.dabRect; exports.decodeLayerChannel = decodeLayerChannel; exports.decodeLayerMask = decodeLayerMask; exports.decodeMergedImage = decodeMergedImage; exports.decodePlanes = decodePlanes; exports.decodePng = _chunkT422YCHRcjs.decodePng; exports.decodePngDataUrl = decodePngDataUrl; exports.decodeSelectionRle = decodeSelectionRle; exports.defaultAdjustmentParams = defaultAdjustmentParams; exports.defaultEffectGradient = _chunkT422YCHRcjs.defaultEffectGradient; exports.defaultLayerEffect = _chunkT422YCHRcjs.defaultLayerEffect; exports.deflate = _chunkT422YCHRcjs.deflate; exports.deflateRaw = _chunkT422YCHRcjs.deflateRaw; exports.depthMaskAlpha = depthMaskAlpha; exports.depthRasterMask = depthRasterMask; exports.describeLayer = describeLayer; exports.describeLayerEffects = describeLayerEffects; exports.describeSelection = describeSelection; exports.deserializeEffects = deserializeEffects; exports.deserializeLayer = deserializeLayer; exports.deserializeLayers = deserializeLayers; exports.deserializePatterns = deserializePatterns; exports.deserializeSelection = deserializeSelection; exports.developFilter = developFilter; exports.developFromAdjustments = developFromAdjustments; exports.developTarget = developTarget; exports.distanceTransform = distanceTransform; exports.downloadPsd = downloadPsd; exports.dropPlacement = dropPlacement; exports.dropZone = dropZone; exports.duplicateLayer = duplicateLayer; exports.edgeWidth = edgeWidth; exports.effectColorHex = _chunkT422YCHRcjs.effectColorHex; exports.effectReach = _chunkT422YCHRcjs.effectReach; exports.effectsFingerprint = _chunkT422YCHRcjs.effectsFingerprint; exports.effectsMargin = _chunkT422YCHRcjs.effectsMargin; exports.effectsScale = _chunkT422YCHRcjs.effectsScale; exports.ellipsePoints = ellipsePoints; exports.ellipseSelection = ellipseSelection; exports.emptyHistogram = emptyHistogram; exports.emptySurface = _chunkCRMAXIUVcjs.emptySurface; exports.encodePng = _chunkT422YCHRcjs.encodePng; exports.encodeRle = encodeRle; exports.encodeSelectionRle = encodeSelectionRle; exports.encodeSurface = encodeSurface; exports.evaluateAdjustmentLayers = evaluateAdjustmentLayers; exports.expandCoverage = expandCoverage; exports.exportPsd = exportPsd; exports.featherCoverage = featherCoverage; exports.fillRect = _chunkCRMAXIUVcjs.fillRect; exports.findAdjustmentControl = findAdjustmentControl; exports.findLayer = _chunkT422YCHRcjs.findLayer; exports.findLayerControl = findLayerControl; exports.finishTile = _chunkCRMAXIUVcjs.finishTile; exports.flattenLayers = _chunkT422YCHRcjs.flattenLayers; exports.formatControlValue = formatControlValue; exports.fullSelection = fullSelection; exports.gaussianBlur = _chunkT422YCHRcjs.gaussianBlur; exports.getAnnotationBounds = getAnnotationBounds; exports.getControlPath = getControlPath; exports.getCropCursor = getCropCursor; exports.getRotatedSize = getRotatedSize; exports.getViewportMetrics = getViewportMetrics; exports.getViewportProjection = getViewportProjection; exports.globalImageCache = globalImageCache; exports.greyMorphology = greyMorphology; exports.groupLayers = groupLayers; exports.guidePlanes = guidePlanes; exports.guidedFilterColor = guidedFilterColor; exports.handlePaintShortcut = handlePaintShortcut; exports.hasActiveEffects = _chunkT422YCHRcjs.hasActiveEffects; exports.hasResampledLegacyMask = hasResampledLegacyMask; exports.hashMaskContent = hashMaskContent; exports.hashNoise = _chunkT422YCHRcjs.hashNoise; exports.hexToRgb = hexToRgb; exports.histogramPath = histogramPath; exports.hitTestAnnotation = hitTestAnnotation; exports.hitTestCrop = hitTestCrop; exports.hitTestCurvePoint = hitTestCurvePoint; exports.hslToRgb = hslToRgb; exports.hueRange = hueRange; exports.hueRangeTables = hueRangeTables; exports.hueRangeWeight = hueRangeWeight; exports.hueSaturation = hueSaturation; exports.identityCurve = identityCurve; exports.identityLevels = identityLevels; exports.imageEditorStateMigrations = imageEditorStateMigrations; exports.imageToCanvasPoint = imageToCanvasPoint; exports.importPsd = importPsd; exports.inflate = _chunkT422YCHRcjs.inflate; exports.inflateRaw = _chunkT422YCHRcjs.inflateRaw; exports.insertCurvePoint = insertCurvePoint; exports.insertLayer = _chunkT422YCHRcjs.insertLayer; exports.invertMatrix3 = invertMatrix3; exports.invertSelection = invertSelection; exports.isActiveFilter = isActiveFilter; exports.isAdjustmentKind = isAdjustmentKind; exports.isBlendMode = _chunkCRMAXIUVcjs.isBlendMode; exports.isDefaultDepthMask = isDefaultDepthMask; exports.isLayerEffectKind = _chunkT422YCHRcjs.isLayerEffectKind; exports.isLayerLocked = _chunkT422YCHRcjs.isLayerLocked; exports.isLegacyShape = isLegacyShape; exports.isPaintTool = isPaintTool; exports.isPng = _chunkT422YCHRcjs.isPng; exports.isQuarterTurn = isQuarterTurn; exports.isQuarterTurnSwapped = isQuarterTurnSwapped; exports.isSelectionEmpty = isSelectionEmpty; exports.isSelectionMode = isSelectionMode; exports.isSeparableBlendMode = _chunkCRMAXIUVcjs.isSeparableBlendMode; exports.isSpatialFilter = isSpatialFilter; exports.kelvinToTemperature = kelvinToTemperature; exports.layerBadge = layerBadge; exports.layerEffectFields = _chunkT422YCHRcjs.layerEffectFields; exports.layerEffectLabel = _chunkT422YCHRcjs.layerEffectLabel; exports.layerEffectsOf = layerEffectsOf; exports.layerLabel = layerLabel; exports.layerMaskCoverage = layerMaskCoverage; exports.layerMaskFromSelection = layerMaskFromSelection; exports.layerMaskKey = layerMaskKey; exports.layerMenu = layerMenu; exports.layerName = layerName; exports.layerPanelRows = layerPanelRows; exports.layerTree = layerTree; exports.layerTypeLabel = layerTypeLabel; exports.layersFromLegacy = layersFromLegacy; exports.legacyAdjustmentLayer = legacyAdjustmentLayer; exports.legacyMaskOf = legacyMaskOf; exports.legacyView = legacyView; exports.lerpPigment = _chunkCRMAXIUVcjs.lerpPigment; exports.lerpPigmentInto = _chunkCRMAXIUVcjs.lerpPigmentInto; exports.levelsValue = levelsValue; exports.linearSrgbToXy = linearSrgbToXy; exports.linearToSrgb = linearToSrgb; exports.loadImageEditorDocument = loadImageEditorDocument; exports.loadMixer = _chunkZZOTHJ4Kcjs.loadMixer; exports.magicWand = magicWand; exports.mapCropHandle = mapCropHandle; exports.mapLayer = _chunkT422YCHRcjs.mapLayer; exports.maskSummary = maskSummary; exports.mergeLayerEffect = _chunkT422YCHRcjs.mergeLayerEffect; exports.migrateSerializedImageEditorState = migrateSerializedImageEditorState; exports.migrateToLayeredState = migrateToLayeredState; exports.mixPigment8 = _chunkCRMAXIUVcjs.mixPigment8; exports.mixPigmentRgb = _chunkCRMAXIUVcjs.mixPigmentRgb; exports.mixPigments = _chunkCRMAXIUVcjs.mixPigments; exports.mixerLoadResult = mixerLoadResult; exports.modifySelection = modifySelection; exports.moveCurvePoint = moveCurvePoint; exports.moveLayer = moveLayer; exports.mulMatrix3 = mulMatrix3; exports.needsLegacyBase = needsLegacyBase; exports.neutralHueRange = neutralHueRange; exports.newEffectId = _chunkT422YCHRcjs.newEffectId; exports.newLayerId = newLayerId; exports.normalizeAdjustmentLayer = normalizeAdjustmentLayer; exports.normalizeAdjustmentLayers = normalizeAdjustmentLayers; exports.normalizeAngle = normalizeAngle; exports.normalizeBlendMode = _chunkCRMAXIUVcjs.normalizeBlendMode; exports.normalizeBrush = _chunkZZOTHJ4Kcjs.normalizeBrush; exports.normalizeFilter = normalizeFilter; exports.normalizeLayerEffects = _chunkT422YCHRcjs.normalizeLayerEffects; exports.normalizeLayerMask = normalizeLayerMask; exports.normalizeMixer = _chunkZZOTHJ4Kcjs.normalizeMixer; exports.normalizeProcessVersion = normalizeProcessVersion; exports.normalizeRect = normalizeRect; exports.normalizeRefineEdgeParams = normalizeRefineEdgeParams; exports.normalizeStoredAdjustments = normalizeStoredAdjustments; exports.offsetLayer = offsetLayer; exports.openPsdFile = openPsdFile; exports.packRgba = _chunkCRMAXIUVcjs.packRgba; exports.parseAdjustmentBlock = parseAdjustmentBlock; exports.parseBlend = parseBlend; exports.parseColor = parseColor; exports.parseDataUrl = _chunkT422YCHRcjs.parseDataUrl; exports.parseEffectColor = _chunkT422YCHRcjs.parseEffectColor; exports.parseLfx2 = parseLfx2; exports.parseLrfx = parseLrfx; exports.parsePatternBlock = parsePatternBlock; exports.parseSelectionMode = parseSelectionMode; exports.parseVersionedDescriptor = parseVersionedDescriptor; exports.photoFilterMatrix = photoFilterMatrix; exports.pixelLayerBounds = pixelLayerBounds; exports.pixelLayers = pixelLayers; exports.placeLayer = placeLayer; exports.pngDataUrl = _chunkT422YCHRcjs.pngDataUrl; exports.pointerPressure = pointerPressure; exports.polygonCoverage = polygonCoverage; exports.polygonSelection = polygonSelection; exports.posterizeValue = posterizeValue; exports.projectImagePoint = projectImagePoint; exports.projectImageRect = projectImageRect; exports.projectMaskCoverage = projectMaskCoverage; exports.projectQuarterTurn = projectQuarterTurn; exports.psdBytesFromBase64 = psdBytesFromBase64; exports.psdFileName = psdFileName; exports.psdPatternToEffectPattern = psdPatternToEffectPattern; exports.psdToLayers = psdToLayers; exports.quickMaskPixels = quickMaskPixels; exports.rangeLightness = rangeLightness; exports.rasterMaskFromLegacy = rasterMaskFromLegacy; exports.rasterizeDab = _chunkZZOTHJ4Kcjs.rasterizeDab; exports.readAdjustmentControls = readAdjustmentControls; exports.readPixel = _chunkCRMAXIUVcjs.readPixel; exports.readPsd = readPsd; exports.readRegion = _chunkCRMAXIUVcjs.readRegion; exports.rectSelection = rectSelection; exports.refineCoverage = refineCoverage; exports.refineEdgeHalo = refineEdgeHalo; exports.refineSelection = refineSelection; exports.reflectanceToRgb = _chunkCRMAXIUVcjs.reflectanceToRgb; exports.removeAlpha = removeAlpha; exports.removeCurvePoint = removeCurvePoint; exports.removeLayer = removeLayer; exports.removeLayerEffect = removeLayerEffect; exports.removeLayerFilter = removeLayerFilter; exports.renderLayerEffects = _chunkT422YCHRcjs.renderLayerEffects; exports.renderLayeredBase = renderLayeredBase; exports.requireLayer = requireLayer; exports.requireUnlocked = requireUnlocked; exports.resizePixels = resizePixels; exports.resizeSelection = resizeSelection; exports.resolveExternalAssets = resolveExternalAssets; exports.resolveMosaicRegionBounds = resolveMosaicRegionBounds; exports.rgbToGray = rgbToGray; exports.rgbToHsl = rgbToHsl; exports.rgbToReflectance = _chunkCRMAXIUVcjs.rgbToReflectance; exports.rgbUnitToHex = rgbUnitToHex; exports.runLayerMenuAction = runLayerMenuAction; exports.sampleLut = sampleLut; exports.sampleToneLut = sampleToneLut; exports.scaleLayerEffect = _chunkT422YCHRcjs.scaleLayerEffect; exports.selectionArea = selectionArea; exports.selectionFromCoverage = selectionFromCoverage; exports.selectionFromPixels = selectionFromPixels; exports.selectionModeFromModifiers = selectionModeFromModifiers; exports.selectionOutline = selectionOutline; exports.selectionToCoverage = selectionToCoverage; exports.selectionToPixels = selectionToPixels; exports.selectionValueAt = selectionValueAt; exports.serializeEffects = serializeEffects; exports.serializeLayer = serializeLayer; exports.serializeLayers = serializeLayers; exports.serializeLayersExternal = serializeLayersExternal; exports.serializePatterns = serializePatterns; exports.serializeSelection = serializeSelection; exports.setControlPath = setControlPath; exports.setLayerEffects = setLayerEffects; exports.setLayerEffectsEnabled = setLayerEffectsEnabled; exports.setLayerMask = setLayerMask; exports.setLayerProperties = setLayerProperties; exports.setLum = _chunkCRMAXIUVcjs.setLum; exports.setPigmentColor = _chunkCRMAXIUVcjs.setPigmentColor; exports.shiftCoverage = shiftCoverage; exports.smoothCoverage = smoothCoverage; exports.smoothPoints = _chunkZZOTHJ4Kcjs.smoothPoints; exports.solidSurface = _chunkCRMAXIUVcjs.solidSurface; exports.splitOverlayAnnotations = splitOverlayAnnotations; exports.srgb8ToLab = srgb8ToLab; exports.srgbToLinear = srgbToLinear; exports.sumHistograms = sumHistograms; exports.surfaceBytes = _chunkCRMAXIUVcjs.surfaceBytes; exports.surfaceFromPixels = _chunkCRMAXIUVcjs.surfaceFromPixels; exports.surfacesEqual = _chunkCRMAXIUVcjs.surfacesEqual; exports.tempTintToXy = tempTintToXy; exports.temperatureToKelvin = temperatureToKelvin; exports.tileCoord = _chunkCRMAXIUVcjs.tileCoord; exports.tileKey = _chunkCRMAXIUVcjs.tileKey; exports.tileRect = _chunkCRMAXIUVcjs.tileRect; exports.tilesInRect = _chunkCRMAXIUVcjs.tilesInRect; exports.tipFalloff = _chunkZZOTHJ4Kcjs.tipFalloff; exports.tipReach = _chunkZZOTHJ4Kcjs.tipReach; exports.tipShape = _chunkZZOTHJ4Kcjs.tipShape; exports.toHex = toHex2; exports.toneCurve = toneCurve; exports.toneLuts = toneLuts; exports.toneRange = toneRange; exports.translateSurface = _chunkCRMAXIUVcjs.translateSurface; exports.ungroupLayer = ungroupLayer; exports.uniformTile = _chunkCRMAXIUVcjs.uniformTile; exports.unionRect = unionRect; exports.unprojectCanvasPoint = unprojectCanvasPoint; exports.updateLayerEffect = updateLayerEffect; exports.updateLayerFilter = updateLayerFilter; exports.updateLayerMaskProps = updateLayerMaskProps; exports.uvToXy = uvToXy; exports.validateEffectGradient = _chunkT422YCHRcjs.validateEffectGradient; exports.validateLayerEffect = _chunkT422YCHRcjs.validateLayerEffect; exports.validateLayerEffects = _chunkT422YCHRcjs.validateLayerEffects; exports.versionedDescriptorBytes = versionedDescriptorBytes; exports.vibranceLinear = vibranceLinear; exports.vibrancePixel = vibrancePixel; exports.walkDabs = _chunkZZOTHJ4Kcjs.walkDabs; exports.wbMatrix = wbMatrix; exports.whiteBalanceFromSample = whiteBalanceFromSample; exports.whiteBalanceMatrix = whiteBalanceMatrix; exports.withNewIds = withNewIds; exports.writeAdjustmentBlock = writeAdjustmentBlock; exports.writeLfx2 = writeLfx2; exports.writePatternBlock = writePatternBlock; exports.writePsd = writePsd; exports.writeRegion = _chunkCRMAXIUVcjs.writeRegion; exports.xyToTempTint = xyToTempTint; exports.xyToUv = xyToUv;
13226
14426
  //# sourceMappingURL=index.cjs.map