@pixerate/editor 0.93.0 → 0.95.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 (43) hide show
  1. package/THIRD_PARTY_NOTICES.md +3 -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-E2ILRYTJ.js +3695 -0
  5. package/dist/chunk-E2ILRYTJ.js.map +1 -0
  6. package/dist/{chunk-D4ZCU72J.js → chunk-HEW6KDNI.js} +366 -4
  7. package/dist/chunk-HEW6KDNI.js.map +1 -0
  8. package/dist/{chunk-ISDCJHTO.js → chunk-IB53LVGV.js} +238 -285
  9. package/dist/chunk-IB53LVGV.js.map +1 -0
  10. package/dist/chunk-T6H3JDGA.cjs +3695 -0
  11. package/dist/chunk-T6H3JDGA.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 +1252 -588
  15. package/dist/image-editor/index.cjs.map +1 -1
  16. package/dist/image-editor/index.d.cts +164 -34
  17. package/dist/image-editor/index.d.ts +164 -34
  18. package/dist/image-editor/index.js +913 -249
  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 +83 -3
  26. package/dist/raster/index.cjs.map +1 -1
  27. package/dist/raster/index.d.cts +99 -348
  28. package/dist/raster/index.d.ts +99 -348
  29. package/dist/raster/index.js +83 -3
  30. package/dist/{surface-fJhkmNQn.d.cts → surface-CgAiXVI3.d.cts} +23 -11
  31. package/dist/{surface-fJhkmNQn.d.ts → surface-CgAiXVI3.d.ts} +23 -11
  32. package/dist/zlib-B3LIoxF-.d.cts +796 -0
  33. package/dist/zlib-eiTEEj1z.d.ts +796 -0
  34. package/package.json +1 -1
  35. package/skills/pixerate-image-editor/SKILL.md +82 -7
  36. package/dist/chunk-4F3YDIWW.cjs.map +0 -1
  37. package/dist/chunk-D4ZCU72J.js.map +0 -1
  38. package/dist/chunk-H543GD6T.cjs +0 -1696
  39. package/dist/chunk-H543GD6T.cjs.map +0 -1
  40. package/dist/chunk-ISDCJHTO.js.map +0 -1
  41. package/dist/chunk-P5TPUNBZ.js +0 -1696
  42. package/dist/chunk-P5TPUNBZ.js.map +0 -1
  43. package/dist/chunk-ZOOEX3WT.cjs.map +0 -1
@@ -28,7 +28,6 @@ var _chunkVJUVNERTcjs = require('../chunk-VJUVNERT.cjs');
28
28
 
29
29
 
30
30
 
31
- var _chunkH543GD6Tcjs = require('../chunk-H543GD6T.cjs');
32
31
 
33
32
 
34
33
 
@@ -43,6 +42,7 @@ var _chunkH543GD6Tcjs = require('../chunk-H543GD6T.cjs');
43
42
 
44
43
 
45
44
 
45
+ var _chunkT6H3JDGAcjs = require('../chunk-T6H3JDGA.cjs');
46
46
 
47
47
 
48
48
 
@@ -58,7 +58,6 @@ var _chunkH543GD6Tcjs = require('../chunk-H543GD6T.cjs');
58
58
 
59
59
 
60
60
 
61
- var _chunk4F3YDIWWcjs = require('../chunk-4F3YDIWW.cjs');
62
61
 
63
62
 
64
63
 
@@ -71,6 +70,7 @@ var _chunk4F3YDIWWcjs = require('../chunk-4F3YDIWW.cjs');
71
70
 
72
71
 
73
72
 
73
+ var _chunkZZOTHJ4Kcjs = require('../chunk-ZZOTHJ4K.cjs');
74
74
 
75
75
 
76
76
 
@@ -94,7 +94,32 @@ var _chunk4F3YDIWWcjs = require('../chunk-4F3YDIWW.cjs');
94
94
 
95
95
 
96
96
 
97
- var _chunkZOOEX3WTcjs = require('../chunk-ZOOEX3WT.cjs');
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+ var _chunkCRMAXIUVcjs = require('../chunk-CRMAXIUV.cjs');
98
123
 
99
124
  // src/image-editor/color.ts
100
125
  var LEGACY_PROCESS_VERSION = 1;
@@ -1106,7 +1131,7 @@ function smoothCoverage(m, w, h, r) {
1106
1131
  return src;
1107
1132
  }
1108
1133
  function featherCoverage(m, w, h, radius) {
1109
- const out = _chunkH543GD6Tcjs.gaussianBlur.call(void 0, m, w, h, Number.isFinite(radius) ? Math.max(0, radius) : 0, "zero");
1134
+ const out = _chunkT6H3JDGAcjs.gaussianBlur.call(void 0, m, w, h, Number.isFinite(radius) ? Math.max(0, radius) : 0, "zero");
1110
1135
  for (let i = 0; i < out.length; i++) if (Math.abs(out[i]) < 1e-7) out[i] = 0;
1111
1136
  return out;
1112
1137
  }
@@ -1254,7 +1279,7 @@ function layerMaskCoverage(mask) {
1254
1279
  let v = new Float32Array(sel.data.length);
1255
1280
  for (let i = 0; i < v.length; i++) v[i] = sel.data[i] / 255;
1256
1281
  const feather = _nullishCoalesce(mask.feather, () => ( 0));
1257
- if (feather > 0) v = _chunkH543GD6Tcjs.gaussianBlur.call(void 0, v, mask.width, mask.height, feather, "clamp");
1282
+ if (feather > 0) v = _chunkT6H3JDGAcjs.gaussianBlur.call(void 0, v, mask.width, mask.height, feather, "clamp");
1258
1283
  const density = _nullishCoalesce(mask.density, () => ( 1));
1259
1284
  if (density !== 1) for (let i = 0; i < v.length; i++) v[i] = 1 - density * (1 - v[i]);
1260
1285
  return v;
@@ -1475,7 +1500,7 @@ function normalizeAdjustmentLayer(raw) {
1475
1500
  kind: r.kind,
1476
1501
  enabled: r.enabled !== false,
1477
1502
  opacity: clampTo(r.opacity, 0, 1, 1),
1478
- blend: _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, r.blend),
1503
+ blend: _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, r.blend),
1479
1504
  params: normParams(r.kind, r.params)
1480
1505
  };
1481
1506
  if (typeof r.name === "string" && r.name) layer.name = r.name;
@@ -1496,61 +1521,8 @@ function normalizeAdjustmentLayers(raw) {
1496
1521
  }
1497
1522
  return out;
1498
1523
  }
1499
- function curveLut(points, size = ADJUSTMENT_LUT_SIZE) {
1500
- const pts = points.filter((p) => Number.isFinite(p.input) && Number.isFinite(p.output)).map((p) => [p.input, p.output]).sort((a, b) => a[0] - b[0]);
1501
- const dedup = [];
1502
- for (const p of pts) {
1503
- if (dedup.length && Math.abs(dedup[dedup.length - 1][0] - p[0]) < 1e-6) continue;
1504
- dedup.push(p);
1505
- }
1506
- const out = new Float32Array(size);
1507
- const n = dedup.length;
1508
- if (n < 2) {
1509
- for (let k = 0; k < size; k++) out[k] = k / (size - 1);
1510
- return out;
1511
- }
1512
- const x = dedup.map((p) => p[0]);
1513
- const y = dedup.map((p) => p[1]);
1514
- const m2 = new Float64Array(n);
1515
- if (n > 2) {
1516
- const c = new Float64Array(n);
1517
- const d = new Float64Array(n);
1518
- for (let i = 1; i < n - 1; i++) {
1519
- const h0 = x[i] - x[i - 1];
1520
- const h1 = x[i + 1] - x[i];
1521
- const a = h0 / 6;
1522
- const b = (h0 + h1) / 3;
1523
- const cc = h1 / 6;
1524
- const r = (y[i + 1] - y[i]) / h1 - (y[i] - y[i - 1]) / h0;
1525
- const denom = b - a * c[i - 1];
1526
- c[i] = cc / denom;
1527
- d[i] = (r - a * d[i - 1]) / denom;
1528
- }
1529
- for (let i = n - 2; i >= 1; i--) m2[i] = d[i] - c[i] * m2[i + 1];
1530
- }
1531
- let seg = 0;
1532
- for (let k = 0; k < size; k++) {
1533
- const xv = k / (size - 1);
1534
- if (xv <= x[0]) {
1535
- out[k] = clamp01(y[0]);
1536
- continue;
1537
- }
1538
- if (xv >= x[n - 1]) {
1539
- out[k] = clamp01(y[n - 1]);
1540
- continue;
1541
- }
1542
- while (seg < n - 2 && xv > x[seg + 1]) seg++;
1543
- const x0 = x[seg], x1 = x[seg + 1];
1544
- const h = x1 - x0;
1545
- const a = (x1 - xv) / h;
1546
- const b = (xv - x0) / h;
1547
- const v = a * y[seg] + b * y[seg + 1] + ((a * a * a - a) * m2[seg] + (b * b * b - b) * m2[seg + 1]) * (h * h) / 6;
1548
- out[k] = clamp01(v);
1549
- }
1550
- return out;
1551
- }
1552
1524
  function curveLutFromLevels(points) {
1553
- return curveLut(points.map((p) => ({ input: p.input / 255, output: p.output / 255 })));
1525
+ return _chunkT6H3JDGAcjs.curveLut.call(void 0, points.map((p) => ({ input: p.input / 255, output: p.output / 255 })));
1554
1526
  }
1555
1527
  var toUnitLevels = (c) => ({
1556
1528
  inBlack: c.inBlack / 255,
@@ -1873,7 +1845,7 @@ function compileAdjustmentLayer(layer) {
1873
1845
  return (c) => {
1874
1846
  const g = blackWhiteGray(c, weights);
1875
1847
  if (tint) {
1876
- const t = _chunkZOOEX3WTcjs.setLum.call(void 0, tint, g);
1848
+ const t = _chunkCRMAXIUVcjs.setLum.call(void 0, tint, g);
1877
1849
  c[0] = clamp01(t[0]);
1878
1850
  c[1] = clamp01(t[1]);
1879
1851
  c[2] = clamp01(t[2]);
@@ -1892,7 +1864,7 @@ function compileAdjustmentLayer(layer) {
1892
1864
  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])));
1893
1865
  if (preserve) {
1894
1866
  const target = 0.3 * c[0] + 0.59 * c[1] + 0.11 * c[2];
1895
- f = _chunkZOOEX3WTcjs.setLum.call(void 0, f, target);
1867
+ f = _chunkCRMAXIUVcjs.setLum.call(void 0, f, target);
1896
1868
  }
1897
1869
  c[0] = clamp01(f[0]);
1898
1870
  c[1] = clamp01(f[1]);
@@ -1958,7 +1930,11 @@ function applyLayer(c, layer, op, coverage = 1) {
1958
1930
  }
1959
1931
  const cb0 = c[0], cb1 = c[1], cb2 = c[2];
1960
1932
  op(c);
1961
- const b = blend === "normal" ? c : _chunkZOOEX3WTcjs.blendRgb.call(void 0, blend, [cb0, cb1, cb2], c);
1933
+ if (blend === "pigment") {
1934
+ _chunkCRMAXIUVcjs.mixPigmentRgb.call(void 0, [clamp01(cb0), clamp01(cb1), clamp01(cb2)], [clamp01(c[0]), clamp01(c[1]), clamp01(c[2])], alpha, c);
1935
+ return;
1936
+ }
1937
+ const b = blend === "normal" ? c : _chunkCRMAXIUVcjs.blendRgb.call(void 0, blend, [cb0, cb1, cb2], c);
1962
1938
  c[0] = (1 - alpha) * cb0 + alpha * b[0];
1963
1939
  c[1] = (1 - alpha) * cb1 + alpha * b[1];
1964
1940
  c[2] = (1 - alpha) * cb2 + alpha * b[2];
@@ -2372,7 +2348,7 @@ function newLayerId(prefix = "layer") {
2372
2348
  return `${prefix}_${Date.now().toString(36)}_${(++idCounter).toString(36)}`;
2373
2349
  }
2374
2350
  function pixelLayers(layers) {
2375
- return _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
2351
+ return _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "pixel");
2376
2352
  }
2377
2353
  function developFilter(layer) {
2378
2354
  return _optionalChain([layer, 'access', _8 => _8.filters, 'optionalAccess', _9 => _9.find, 'call', _10 => _10((f) => f.kind === "develop")]);
@@ -2493,7 +2469,7 @@ var PHOTO_PROFILE = {
2493
2469
  return v;
2494
2470
  }
2495
2471
  };
2496
- var LayerCompositor = class extends _chunkH543GD6Tcjs.RasterCompositor {
2472
+ var LayerCompositor = class extends _chunkT6H3JDGAcjs.RasterCompositor {
2497
2473
  constructor(options = {}) {
2498
2474
  super(PHOTO_PROFILE, options);
2499
2475
  }
@@ -2535,7 +2511,7 @@ function rasterMaskFromLegacy(mask, width, height) {
2535
2511
  const sel = decodeLayerMask(mask);
2536
2512
  if (!sel) return null;
2537
2513
  const sized = sel.width === width && sel.height === height ? sel : resizeSelection(sel, width, height);
2538
- const surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0);
2514
+ const surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0);
2539
2515
  legacyMaskMemo.set(surface, { width: mask.width, height: mask.height, rle: mask.rle });
2540
2516
  const out = { surface, defaultValue: 0 };
2541
2517
  if (mask.density !== void 0 && mask.density !== 1) out.density = mask.density;
@@ -2554,7 +2530,7 @@ function hasResampledLegacyMask(layers, width, height) {
2554
2530
  function legacyMaskOf(mask, width, height) {
2555
2531
  let memo = legacyMaskMemo.get(mask.surface);
2556
2532
  if (!memo) {
2557
- const data = _chunkZOOEX3WTcjs.readRegion.call(void 0, mask.surface, { x: 0, y: 0, width, height });
2533
+ const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, mask.surface, { x: 0, y: 0, width, height });
2558
2534
  memo = { width, height, rle: encodeSelectionRle(new Uint8Array(data.buffer, data.byteOffset, data.length)) };
2559
2535
  legacyMaskMemo.set(mask.surface, memo);
2560
2536
  }
@@ -2635,7 +2611,7 @@ function backgroundLayer(filters = [], mask) {
2635
2611
  visible: true,
2636
2612
  opacity: 1,
2637
2613
  blend: "normal",
2638
- surface: _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4),
2614
+ surface: _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4),
2639
2615
  offset: { x: 0, y: 0 },
2640
2616
  source: "document",
2641
2617
  filters
@@ -2645,7 +2621,7 @@ function backgroundLayer(filters = [], mask) {
2645
2621
  }
2646
2622
  function depthRasterMask(source) {
2647
2623
  const out = {
2648
- surface: _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, 255),
2624
+ surface: _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, 255),
2649
2625
  defaultValue: 255,
2650
2626
  source: { ...source, depthRange: [...source.depthRange] }
2651
2627
  };
@@ -2700,7 +2676,7 @@ function developTarget(layers, activeLayerId) {
2700
2676
  }
2701
2677
  return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(pixels.find((l) => l.source === "document"), () => ( pixels.find((l) => l.id === BACKGROUND_LAYER_ID))), () => ( pixels[0])), () => ( null));
2702
2678
  }
2703
- var isPlain = (l) => l.visible && l.opacity === 1 && l.blend === "normal" && !l.clipped && !l.mask && !l.locks;
2679
+ var isPlain = (l) => l.visible && l.opacity === 1 && l.blend === "normal" && !l.clipped && !l.mask && !l.locks && !l.effects;
2704
2680
  function legacyView(stack, width, height, activeLayerId = null) {
2705
2681
  const { layers } = stack;
2706
2682
  const target = developTarget(layers, activeLayerId);
@@ -2740,7 +2716,7 @@ function isLegacyShape(stack) {
2740
2716
  const bg = layers[0];
2741
2717
  if (!bg || bg.type !== "pixel" || bg.source !== "document") return false;
2742
2718
  if (bg.id !== BACKGROUND_LAYER_ID || bg.name !== BACKGROUND_LAYER_NAME) return false;
2743
- if (!bg.visible || bg.opacity !== 1 || bg.blend !== "normal" || bg.clipped || bg.locks) return false;
2719
+ if (!bg.visible || bg.opacity !== 1 || bg.blend !== "normal" || bg.clipped || bg.locks || bg.effects) return false;
2744
2720
  if ((_nullishCoalesce(bg.fillOpacity, () => ( 1))) !== 1 || bg.offset.x !== 0 || bg.offset.y !== 0) return false;
2745
2721
  const filters = _nullishCoalesce(bg.filters, () => ( []));
2746
2722
  if (filters.length < 1 || filters.length > 2) return false;
@@ -2756,7 +2732,7 @@ function isLegacyShape(stack) {
2756
2732
  let adjustments = 0;
2757
2733
  for (; i < layers.length && layers[i].type === "adjustment"; i++) {
2758
2734
  const l = layers[i];
2759
- if (l.clipped || l.locks || _optionalChain([l, 'access', _23 => _23.mask, 'optionalAccess', _24 => _24.source])) return false;
2735
+ if (l.clipped || l.locks || _optionalChain([l, 'access', _23 => _23.mask, 'optionalAccess', _24 => _24.source]) || l.effects) return false;
2760
2736
  adjustments++;
2761
2737
  }
2762
2738
  for (; i < layers.length; i++) {
@@ -3262,22 +3238,24 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3262
3238
  return _nullishCoalesce(this.depthMaps.get(`${source.maskSource}|${width}x${height}`), () => ( null));
3263
3239
  },
3264
3240
  rasterizeAnnotation: (annotation, rect) => this.rasterizeAnnotation(annotation, rect),
3265
- version: `${_nullishCoalesce(_optionalChain([host, 'optionalAccess', _52 => _52.version, 'call', _53 => _53()]), () => ( ""))}:${this.assetVersion}`
3241
+ version: `${_nullishCoalesce(_optionalChain([host, 'optionalAccess', _52 => _52.version, 'call', _53 => _53()]), () => ( ""))}:${this.assetVersion}`,
3242
+ globalLight: _optionalChain([host, 'optionalAccess', _54 => _54.globalLight, 'optionalCall', _55 => _55()]),
3243
+ pattern: _optionalChain([host, 'optionalAccess', _56 => _56.pattern]) ? (id) => host.pattern(id) : void 0
3266
3244
  };
3267
3245
  }
3268
3246
  /** Loads what the compositor reads synchronously: depth maps (at canvas size) and annotation images. */
3269
3247
  /** Loads depth maps and annotation images the compositor reads synchronously. */
3270
3248
  async prepareLayerAssets(layers, width, height) {
3271
- for (const l of _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers)) {
3272
- const source = _optionalChain([l, 'access', _54 => _54.mask, 'optionalAccess', _55 => _55.source]);
3273
- if (_optionalChain([source, 'optionalAccess', _56 => _56.enabled]) && source.maskSource) {
3249
+ for (const l of _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers)) {
3250
+ const source = _optionalChain([l, 'access', _57 => _57.mask, 'optionalAccess', _58 => _58.source]);
3251
+ if (_optionalChain([source, 'optionalAccess', _59 => _59.enabled]) && source.maskSource) {
3274
3252
  const key = `${source.maskSource}|${width}x${height}`;
3275
3253
  if (this.depthMaps.has(key)) continue;
3276
3254
  try {
3277
3255
  const maskImg = await this.imageCache.get(source.maskSource);
3278
3256
  const canvas = this.createCanvas(width, height);
3279
3257
  const mctx = canvas.getContext("2d");
3280
- const data = mctx ? (mctx.drawImage(maskImg, 0, 0, width, height), _optionalChain([mctx, 'access', _57 => _57.getImageData, 'optionalCall', _58 => _58(0, 0, width, height)])) : null;
3258
+ const data = mctx ? (mctx.drawImage(maskImg, 0, 0, width, height), _optionalChain([mctx, 'access', _60 => _60.getImageData, 'optionalCall', _61 => _61(0, 0, width, height)])) : null;
3281
3259
  if (data) {
3282
3260
  this.depthMaps.set(key, { width, height, data: data.data });
3283
3261
  this.assetVersion++;
@@ -3322,14 +3300,14 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3322
3300
  }
3323
3301
  }
3324
3302
  putTile(ctx, data, tx, ty, rect) {
3325
- const ox = tx * _chunkZOOEX3WTcjs.TILE - rect.x;
3326
- const oy = ty * _chunkZOOEX3WTcjs.TILE - rect.y;
3303
+ const ox = tx * _chunkCRMAXIUVcjs.TILE - rect.x;
3304
+ const oy = ty * _chunkCRMAXIUVcjs.TILE - rect.y;
3327
3305
  const x0 = Math.max(0, -ox);
3328
3306
  const y0 = Math.max(0, -oy);
3329
- const x1 = Math.min(_chunkZOOEX3WTcjs.TILE, rect.width - ox);
3330
- const y1 = Math.min(_chunkZOOEX3WTcjs.TILE, rect.height - oy);
3307
+ const x1 = Math.min(_chunkCRMAXIUVcjs.TILE, rect.width - ox);
3308
+ const y1 = Math.min(_chunkCRMAXIUVcjs.TILE, rect.height - oy);
3331
3309
  if (x1 <= x0 || y1 <= y0) return;
3332
- const img = ctx.createImageData(_chunkZOOEX3WTcjs.TILE, _chunkZOOEX3WTcjs.TILE);
3310
+ const img = ctx.createImageData(_chunkCRMAXIUVcjs.TILE, _chunkCRMAXIUVcjs.TILE);
3333
3311
  img.data.set(data);
3334
3312
  ctx.putImageData(img, ox, oy, x0, y0, x1 - x0, y1 - y0);
3335
3313
  }
@@ -3350,7 +3328,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3350
3328
  if (!ctx || typeof ctx.createImageData !== "function") return null;
3351
3329
  let changed = false;
3352
3330
  this.compositor.compositeTiles(layers, rect, this.compositorSources(width, height), (tx, ty, data) => {
3353
- const key = _chunkZOOEX3WTcjs.tileKey.call(void 0, tx, ty);
3331
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty);
3354
3332
  if (comp.tiles.get(key) === data) return;
3355
3333
  comp.tiles.set(key, data);
3356
3334
  comp.histograms.delete(key);
@@ -3397,7 +3375,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3397
3375
  const opacity = _nullishCoalesce(state.outputOpacity, () => ( 1));
3398
3376
  const blur = _nullishCoalesce(state.legacyOutputBlur, () => ( 0));
3399
3377
  if (!(opacity < 1) && !(blur > 0)) return null;
3400
- const data = _optionalChain([ctx, 'access', _59 => _59.getImageData, 'optionalCall', _60 => _60(0, 0, w, h)]);
3378
+ const data = _optionalChain([ctx, 'access', _62 => _62.getImageData, 'optionalCall', _63 => _63(0, 0, w, h)]);
3401
3379
  if (!data) return null;
3402
3380
  applyOutputStage(data, opacity, blur);
3403
3381
  ctx.putImageData(data, 0, 0);
@@ -3406,7 +3384,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3406
3384
  publishHistogram(histogram) {
3407
3385
  if (histogram === this.previewHistogram) return;
3408
3386
  this.previewHistogram = histogram;
3409
- _optionalChain([this, 'access', _61 => _61.onPreviewHistogram, 'optionalCall', _62 => _62(histogram)]);
3387
+ _optionalChain([this, 'access', _64 => _64.onPreviewHistogram, 'optionalCall', _65 => _65(histogram)]);
3410
3388
  }
3411
3389
  __init19() {this.quickMaskCache = /* @__PURE__ */ new WeakMap()}
3412
3390
  __init20() {this.outlineCache = /* @__PURE__ */ new WeakMap()}
@@ -3475,12 +3453,12 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3475
3453
  * Draws an individual annotation onto the canvas.
3476
3454
  */
3477
3455
  async drawAnnotation(ctx, ann) {
3478
- const blend = _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, ann.blend);
3456
+ const blend = _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, ann.blend);
3479
3457
  if (blend === "normal") {
3480
3458
  await this.drawAnnotationContent(ctx, ann);
3481
3459
  return;
3482
3460
  }
3483
- const op = _chunkZOOEX3WTcjs.canvasCompositeOperation.call(void 0, blend);
3461
+ const op = _chunkCRMAXIUVcjs.canvasCompositeOperation.call(void 0, blend);
3484
3462
  if (op) {
3485
3463
  ctx.save();
3486
3464
  ctx.globalCompositeOperation = op;
@@ -3513,7 +3491,7 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3513
3491
  const backdrop = ctx.getImageData(0, 0, w, h);
3514
3492
  const source = lctx.getImageData(0, 0, w, h);
3515
3493
  if (!backdrop || !source) return false;
3516
- _chunkZOOEX3WTcjs.blendImageData.call(void 0, backdrop, source, _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, ann.blend));
3494
+ _chunkCRMAXIUVcjs.blendImageData.call(void 0, backdrop, source, _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, ann.blend));
3517
3495
  lctx.setTransform(1, 0, 0, 1, 0, 0);
3518
3496
  lctx.putImageData(backdrop, 0, 0);
3519
3497
  } catch (e10) {
@@ -3819,8 +3797,8 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3819
3797
  if (!ctx) return maskCanvas;
3820
3798
  ctx.fillStyle = MASK_BLACK;
3821
3799
  ctx.fillRect(0, 0, naturalWidth, naturalHeight);
3822
- const useCrop = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.useCrop]), () => ( true));
3823
- const useAnnotations = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _64 => _64.useAnnotations]), () => ( true));
3800
+ const useCrop = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _66 => _66.useCrop]), () => ( true));
3801
+ const useAnnotations = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _67 => _67.useAnnotations]), () => ( true));
3824
3802
  if (useCrop && state.crop) {
3825
3803
  ctx.fillStyle = MASK_WHITE;
3826
3804
  ctx.fillRect(state.crop.x, state.crop.y, state.crop.width, state.crop.height);
@@ -3830,8 +3808,8 @@ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__
3830
3808
  this.drawAnnotationMask(ctx, ann);
3831
3809
  }
3832
3810
  }
3833
- const imageData = _optionalChain([ctx, 'access', _65 => _65.getImageData, 'optionalCall', _66 => _66(0, 0, naturalWidth, naturalHeight)]);
3834
- const selection = (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _67 => _67.useSelection]), () => ( true))) && _optionalChain([state, 'access', _68 => _68.selection, 'optionalAccess', _69 => _69.bounds]) && state.selection.width === naturalWidth && state.selection.height === naturalHeight ? state.selection : null;
3811
+ const imageData = _optionalChain([ctx, 'access', _68 => _68.getImageData, 'optionalCall', _69 => _69(0, 0, naturalWidth, naturalHeight)]);
3812
+ const selection = (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _70 => _70.useSelection]), () => ( true))) && _optionalChain([state, 'access', _71 => _71.selection, 'optionalAccess', _72 => _72.bounds]) && state.selection.width === naturalWidth && state.selection.height === naturalHeight ? state.selection : null;
3835
3813
  if (imageData) {
3836
3814
  const d = imageData.data;
3837
3815
  for (let i = 0; i < d.length; i += 4) {
@@ -3938,12 +3916,12 @@ var CompositeCanvas = (_class3 = class {
3938
3916
  if (!h) {
3939
3917
  const tx = key % 65536 - 32768;
3940
3918
  const ty = Math.floor(key / 65536) - 32768;
3941
- const x0 = Math.max(r.x, tx * _chunkZOOEX3WTcjs.TILE);
3942
- const y0 = Math.max(r.y, ty * _chunkZOOEX3WTcjs.TILE);
3943
- const x1 = Math.min(r.x + r.width, tx * _chunkZOOEX3WTcjs.TILE + _chunkZOOEX3WTcjs.TILE);
3944
- const y1 = Math.min(r.y + r.height, ty * _chunkZOOEX3WTcjs.TILE + _chunkZOOEX3WTcjs.TILE);
3919
+ const x0 = Math.max(r.x, tx * _chunkCRMAXIUVcjs.TILE);
3920
+ const y0 = Math.max(r.y, ty * _chunkCRMAXIUVcjs.TILE);
3921
+ const x1 = Math.min(r.x + r.width, tx * _chunkCRMAXIUVcjs.TILE + _chunkCRMAXIUVcjs.TILE);
3922
+ const y1 = Math.min(r.y + r.height, ty * _chunkCRMAXIUVcjs.TILE + _chunkCRMAXIUVcjs.TILE);
3945
3923
  h = emptyHistogram();
3946
- 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 });
3924
+ 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 });
3947
3925
  this.histograms.set(key, h);
3948
3926
  }
3949
3927
  parts.push(h);
@@ -4451,11 +4429,11 @@ function refineCoverage(guide, m, w, h, params = {}) {
4451
4429
  }
4452
4430
  const ss = smoothSigma(p);
4453
4431
  if (ss >= 0.3) {
4454
- a = _chunkH543GD6Tcjs.gaussianBlur.call(void 0, a, w, h, ss, "clamp");
4432
+ a = _chunkT6H3JDGAcjs.gaussianBlur.call(void 0, a, w, h, ss, "clamp");
4455
4433
  const gain = 1 + ss;
4456
4434
  for (let i = 0; i < a.length; i++) a[i] = Math.min(1, Math.max(0, (a[i] - 0.5) * gain + 0.5));
4457
4435
  }
4458
- a = _chunkH543GD6Tcjs.gaussianBlur.call(void 0, a, w, h, featherSigma(p), "clamp");
4436
+ a = _chunkT6H3JDGAcjs.gaussianBlur.call(void 0, a, w, h, featherSigma(p), "clamp");
4459
4437
  if (p.contrast > 0) {
4460
4438
  const gain = 1 / (1 - 0.99 * p.contrast / 100);
4461
4439
  for (let i = 0; i < a.length; i++) a[i] = Math.min(1, Math.max(0, (a[i] - 0.5) * gain + 0.5));
@@ -4515,11 +4493,11 @@ var LAYERED_SCHEMA_VERSION = 3;
4515
4493
  var encodedCache = /* @__PURE__ */ new WeakMap();
4516
4494
  function encodeSurface(surface) {
4517
4495
  if (encodedCache.has(surface)) return encodedCache.get(surface);
4518
- const b = _chunkZOOEX3WTcjs.contentBounds.call(void 0, surface);
4496
+ const b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, surface);
4519
4497
  let out = null;
4520
4498
  if (b) {
4521
- const data = _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, b);
4522
- out = { url: _chunkH543GD6Tcjs.pngDataUrl.call(void 0, b.width, b.height, data, surface.channels), x: b.x, y: b.y };
4499
+ const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, b);
4500
+ out = { url: _chunkT6H3JDGAcjs.pngDataUrl.call(void 0, b.width, b.height, data, surface.channels), x: b.x, y: b.y };
4523
4501
  }
4524
4502
  encodedCache.set(surface, out);
4525
4503
  return out;
@@ -4535,8 +4513,29 @@ function baseFields(layer, ctx) {
4535
4513
  if (layer.clipped) out.clipped = true;
4536
4514
  if (layer.mask) out.mask = serializeMask(layer.mask, `${layer.id}-mask`, ctx);
4537
4515
  if (layer.locks && Object.values(layer.locks).some(Boolean)) out.locks = { ...layer.locks };
4516
+ if (layer.effects) out.effects = serializeEffects(layer.effects);
4538
4517
  return out;
4539
4518
  }
4519
+ function serializeEffects(effects) {
4520
+ const out = { enabled: effects.enabled, items: JSON.parse(JSON.stringify(effects.items)) };
4521
+ if (effects.scale !== void 0 && effects.scale !== 1) out.scale = effects.scale;
4522
+ if (effects.psd) out.psd = { key: effects.psd.key, data: _chunkT6H3JDGAcjs.bytesToBase64.call(void 0, effects.psd.data) };
4523
+ return out;
4524
+ }
4525
+ function deserializeEffects(raw) {
4526
+ if (!raw || typeof raw !== "object") return void 0;
4527
+ const r = raw;
4528
+ let psd;
4529
+ const p = r.psd;
4530
+ if (p && typeof p.key === "string" && typeof p.data === "string") {
4531
+ try {
4532
+ psd = { key: p.key, data: _chunkT6H3JDGAcjs.base64ToBytes.call(void 0, p.data) };
4533
+ } catch (e12) {
4534
+ psd = void 0;
4535
+ }
4536
+ }
4537
+ return _chunkT6H3JDGAcjs.normalizeLayerEffects.call(void 0, { ...r, psd });
4538
+ }
4540
4539
  function serializeMask(mask, hint, ctx) {
4541
4540
  const out = { defaultValue: mask.defaultValue };
4542
4541
  if (!mask.source) {
@@ -4569,7 +4568,7 @@ function serializeLayer(layer, ctx) {
4569
4568
  }
4570
4569
  }
4571
4570
  if (layer.fillOpacity !== void 0 && layer.fillOpacity !== 1) out.fillOpacity = layer.fillOpacity;
4572
- if (_optionalChain([layer, 'access', _70 => _70.filters, 'optionalAccess', _71 => _71.length])) out.filters = JSON.parse(JSON.stringify(layer.filters));
4571
+ if (_optionalChain([layer, 'access', _73 => _73.filters, 'optionalAccess', _74 => _74.length])) out.filters = JSON.parse(JSON.stringify(layer.filters));
4573
4572
  return out;
4574
4573
  }
4575
4574
  case "adjustment":
@@ -4607,7 +4606,7 @@ async function serializeLayersExternal(layers, store) {
4607
4606
  for (const [id, url] of Object.entries(inline.assets)) {
4608
4607
  let ref = refs.get(url);
4609
4608
  if (!ref) {
4610
- const parsed = _chunkH543GD6Tcjs.parseDataUrl.call(void 0, url);
4609
+ const parsed = _chunkT6H3JDGAcjs.parseDataUrl.call(void 0, url);
4611
4610
  const png = decodePngHeader(parsed.bytes);
4612
4611
  ref = await store.put(new Blob([parsed.bytes], { type: "image/png" }), { id, width: png.width, height: png.height });
4613
4612
  if (typeof ref !== "string" || !ref) throw new Error(`The asset store returned no reference for "${id}".`);
@@ -4635,7 +4634,7 @@ async function resolveExternalAssets(assets, store, problems) {
4635
4634
  try {
4636
4635
  const blob = await store.get(ref);
4637
4636
  const bytes = new Uint8Array(await blob.arrayBuffer());
4638
- out[id] = `data:image/png;base64,${_chunkH543GD6Tcjs.bytesToBase64.call(void 0, bytes)}`;
4637
+ out[id] = `data:image/png;base64,${_chunkT6H3JDGAcjs.bytesToBase64.call(void 0, bytes)}`;
4639
4638
  } catch (err) {
4640
4639
  problems.push(`Asset "${id}" (${ref}) could not be fetched: ${err.message}`);
4641
4640
  }
@@ -4643,9 +4642,9 @@ async function resolveExternalAssets(assets, store, problems) {
4643
4642
  return out;
4644
4643
  }
4645
4644
  function decodePngDataUrl(url, channels) {
4646
- const parsed = _chunkH543GD6Tcjs.parseDataUrl.call(void 0, url);
4645
+ const parsed = _chunkT6H3JDGAcjs.parseDataUrl.call(void 0, url);
4647
4646
  if (!parsed) throw new Error("Asset is not a data URL.");
4648
- const png = _chunkH543GD6Tcjs.decodePng.call(void 0, parsed.bytes, { keepGray: channels === 1 });
4647
+ const png = _chunkT6H3JDGAcjs.decodePng.call(void 0, parsed.bytes, { keepGray: channels === 1 });
4649
4648
  if (png.channels === channels) return png;
4650
4649
  if (channels === 1) {
4651
4650
  const out2 = new Uint8ClampedArray(png.width * png.height);
@@ -4663,18 +4662,18 @@ function decodePngDataUrl(url, channels) {
4663
4662
  }
4664
4663
  var num = (v, lo, hi, fallback) => typeof v === "number" && Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : fallback;
4665
4664
  function readSurface(ref, x, y, channels, defaultValue, ctx, what) {
4666
- if (typeof ref !== "string" || !ref) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, channels, defaultValue);
4665
+ if (typeof ref !== "string" || !ref) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, channels, defaultValue);
4667
4666
  const url = ctx.assets[ref];
4668
4667
  if (typeof url !== "string") {
4669
4668
  ctx.problems.push(`${what}: asset "${ref}" is missing`);
4670
- return _chunkZOOEX3WTcjs.emptySurface.call(void 0, channels, defaultValue);
4669
+ return _chunkCRMAXIUVcjs.emptySurface.call(void 0, channels, defaultValue);
4671
4670
  }
4672
4671
  try {
4673
4672
  const px = (_nullishCoalesce(ctx.decodeAsset, () => ( decodePngDataUrl)))(url, channels);
4674
- return _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, px, channels, Math.round(num(x, -1e7, 1e7, 0)), Math.round(num(y, -1e7, 1e7, 0)), defaultValue);
4673
+ return _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, px, channels, Math.round(num(x, -1e7, 1e7, 0)), Math.round(num(y, -1e7, 1e7, 0)), defaultValue);
4675
4674
  } catch (err) {
4676
4675
  ctx.problems.push(`${what}: asset "${ref}" could not be decoded (${err.message})`);
4677
- return _chunkZOOEX3WTcjs.emptySurface.call(void 0, channels, defaultValue);
4676
+ return _chunkCRMAXIUVcjs.emptySurface.call(void 0, channels, defaultValue);
4678
4677
  }
4679
4678
  }
4680
4679
  function readMask(raw, ctx, what) {
@@ -4682,7 +4681,7 @@ function readMask(raw, ctx, what) {
4682
4681
  const r = raw;
4683
4682
  const defaultValue = r.defaultValue === 255 ? 255 : 0;
4684
4683
  const mask = {
4685
- surface: r.source ? _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, 255) : readSurface(r.asset, r.x, r.y, 1, defaultValue, ctx, `${what} mask`),
4684
+ surface: r.source ? _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, 255) : readSurface(r.asset, r.x, r.y, 1, defaultValue, ctx, `${what} mask`),
4686
4685
  defaultValue: r.source ? 255 : defaultValue
4687
4686
  };
4688
4687
  if (typeof r.density === "number" && r.density !== 1) mask.density = num(r.density, 0, 1, 1);
@@ -4729,7 +4728,7 @@ function deserializeLayer(raw, ctx) {
4729
4728
  name: typeof r.name === "string" ? r.name : "",
4730
4729
  visible: r.visible !== false,
4731
4730
  opacity: num(r.opacity, 0, 1, 1),
4732
- blend: _chunkZOOEX3WTcjs.normalizeBlendMode.call(void 0, r.blend)
4731
+ blend: _chunkCRMAXIUVcjs.normalizeBlendMode.call(void 0, r.blend)
4733
4732
  };
4734
4733
  if (r.clipped === true) base.clipped = true;
4735
4734
  const mask = readMask(r.mask, ctx, `Layer "${base.name || id}"`);
@@ -4739,13 +4738,15 @@ function deserializeLayer(raw, ctx) {
4739
4738
  for (const k of ["pixels", "transparency", "position", "all"]) if (r.locks[k] === true) locks[k] = true;
4740
4739
  if (Object.keys(locks).length) base.locks = locks;
4741
4740
  }
4741
+ const effects = deserializeEffects(r.effects);
4742
+ if (effects && r.type !== "adjustment") base.effects = effects;
4742
4743
  switch (r.type) {
4743
4744
  case "pixel": {
4744
4745
  const layer = {
4745
4746
  ...base,
4746
4747
  type: "pixel",
4747
- surface: r.source === "document" ? _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4) : readSurface(r.asset, r.x, r.y, 4, 0, ctx, `Layer "${base.name || id}"`),
4748
- offset: { x: Math.round(num(_optionalChain([r, 'access', _72 => _72.offset, 'optionalAccess', _73 => _73.x]), -1e7, 1e7, 0)), y: Math.round(num(_optionalChain([r, 'access', _74 => _74.offset, 'optionalAccess', _75 => _75.y]), -1e7, 1e7, 0)) }
4748
+ surface: r.source === "document" ? _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4) : readSurface(r.asset, r.x, r.y, 4, 0, ctx, `Layer "${base.name || id}"`),
4749
+ 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)) }
4749
4750
  };
4750
4751
  if (r.source === "document") layer.source = "document";
4751
4752
  if (typeof r.fillOpacity === "number" && r.fillOpacity !== 1) layer.fillOpacity = num(r.fillOpacity, 0, 1, 1);
@@ -4763,7 +4764,7 @@ function deserializeLayer(raw, ctx) {
4763
4764
  }
4764
4765
  case "group": {
4765
4766
  const children = Array.isArray(r.children) ? r.children.map((c) => deserializeLayer(c, ctx)).filter(Boolean) : [];
4766
- const blend = r.blend === "pass-through" ? "pass-through" : _chunkZOOEX3WTcjs.isBlendMode.call(void 0, r.blend) ? r.blend : "pass-through";
4767
+ const blend = r.blend === "pass-through" ? "pass-through" : _chunkCRMAXIUVcjs.isBlendMode.call(void 0, r.blend) ? r.blend : "pass-through";
4767
4768
  const group = { ...base, type: "group", blend, children };
4768
4769
  if (r.collapsed === true) group.collapsed = true;
4769
4770
  return group;
@@ -4805,47 +4806,47 @@ var fail = (message) => {
4805
4806
  throw new LayerOperationError(message);
4806
4807
  };
4807
4808
  function requireLayer(layers, id) {
4808
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, layers, id);
4809
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, layers, id);
4809
4810
  if (!loc) {
4810
- const ids = _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers).map((l) => l.id);
4811
+ const ids = _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers).map((l) => l.id);
4811
4812
  fail(`Unknown layer "${id}". ${ids.length ? `Layers: ${ids.join(", ")}.` : "The document has no layers."} Call list_layers for ids.`);
4812
4813
  }
4813
4814
  return loc;
4814
4815
  }
4815
4816
  function requireUnlocked(layer, what, action) {
4816
- if (_chunkH543GD6Tcjs.isLayerLocked.call(void 0, layer, "all")) fail(`Layer "${layer.name || layer.id}" is locked (all); unlock it before you ${action}.`);
4817
- if (what !== "all" && _chunkH543GD6Tcjs.isLayerLocked.call(void 0, layer, what)) fail(`Layer "${layer.name || layer.id}" has its ${what} locked; unlock it before you ${action}.`);
4817
+ if (_chunkT6H3JDGAcjs.isLayerLocked.call(void 0, layer, "all")) fail(`Layer "${layer.name || layer.id}" is locked (all); unlock it before you ${action}.`);
4818
+ if (what !== "all" && _chunkT6H3JDGAcjs.isLayerLocked.call(void 0, layer, what)) fail(`Layer "${layer.name || layer.id}" has its ${what} locked; unlock it before you ${action}.`);
4818
4819
  }
4819
4820
  function placeLayer(layers, layer, placement = {}, defaultIndex) {
4820
4821
  const given = [placement.aboveId, placement.belowId, placement.parentId].filter((v) => v !== void 0).length;
4821
4822
  if (given > 1) fail("Give only one of aboveId, belowId and parentId.");
4822
4823
  if (placement.aboveId || placement.belowId) {
4823
4824
  const ref = requireLayer(layers, _nullishCoalesce(placement.aboveId, () => ( placement.belowId)));
4824
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, layer, _nullishCoalesce(_optionalChain([ref, 'access', _76 => _76.parent, 'optionalAccess', _77 => _77.id]), () => ( null)), ref.index + (placement.aboveId ? 1 : 0));
4825
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, layer, _nullishCoalesce(_optionalChain([ref, 'access', _79 => _79.parent, 'optionalAccess', _80 => _80.id]), () => ( null)), ref.index + (placement.aboveId ? 1 : 0));
4825
4826
  }
4826
4827
  if (placement.parentId) {
4827
4828
  const ref = requireLayer(layers, placement.parentId);
4828
4829
  if (ref.layer.type !== "group") fail(`Layer "${placement.parentId}" is not a group; parentId must be a group id.`);
4829
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, layer, ref.layer.id, placement.index);
4830
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, layer, ref.layer.id, placement.index);
4830
4831
  }
4831
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, layer, null, _nullishCoalesce(placement.index, () => ( defaultIndex)));
4832
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, layer, null, _nullishCoalesce(placement.index, () => ( defaultIndex)));
4832
4833
  }
4833
4834
  function removeLayer(layers, id) {
4834
4835
  const loc = requireLayer(layers, id);
4835
4836
  requireUnlocked(loc.layer, "all", "delete it");
4836
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => null);
4837
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => null);
4837
4838
  }
4838
4839
  function moveLayer(layers, id, placement) {
4839
4840
  const loc = requireLayer(layers, id);
4840
4841
  requireUnlocked(loc.layer, "all", "move it");
4841
4842
  const target = _nullishCoalesce(_nullishCoalesce(placement.aboveId, () => ( placement.belowId)), () => ( placement.parentId));
4842
4843
  if (target === id) fail("A layer cannot be placed relative to itself.");
4843
- if (target && loc.layer.type === "group" && _chunkH543GD6Tcjs.flattenLayers.call(void 0, loc.layer.children).some((l) => l.id === target)) {
4844
+ if (target && loc.layer.type === "group" && _chunkT6H3JDGAcjs.flattenLayers.call(void 0, loc.layer.children).some((l) => l.id === target)) {
4844
4845
  fail(`Group "${id}" cannot be moved into its own child "${target}".`);
4845
4846
  }
4846
4847
  if (target) requireLayer(layers, target);
4847
4848
  if (!target && placement.index === void 0) fail("Give aboveId, belowId, parentId or index.");
4848
- const without = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => null);
4849
+ const without = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => null);
4849
4850
  return placeLayer(without, loc.layer, placement);
4850
4851
  }
4851
4852
  function withNewIds(layer) {
@@ -4859,7 +4860,7 @@ function duplicateLayer(layers, id, name) {
4859
4860
  const copy = withNewIds(loc.layer);
4860
4861
  copy.name = _nullishCoalesce(name, () => ( `${loc.layer.name || "Layer"} copy`));
4861
4862
  delete copy.locks;
4862
- return { layers: _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _78 => _78.parent, 'optionalAccess', _79 => _79.id]), () => ( null)), loc.index + 1), id: copy.id };
4863
+ return { layers: _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _81 => _81.parent, 'optionalAccess', _82 => _82.id]), () => ( null)), loc.index + 1), id: copy.id };
4863
4864
  }
4864
4865
  function setLayerProperties(layers, id, props) {
4865
4866
  const loc = requireLayer(layers, id);
@@ -4886,7 +4887,7 @@ function setLayerProperties(layers, id, props) {
4886
4887
  if (props.blend !== void 0) {
4887
4888
  if (props.blend === "pass-through") {
4888
4889
  if (layer.type !== "group") fail("pass-through is only for groups.");
4889
- } else if (!_chunkZOOEX3WTcjs.isBlendMode.call(void 0, props.blend)) fail(`Unknown blend mode "${props.blend}".`);
4890
+ } else if (!_chunkCRMAXIUVcjs.isBlendMode.call(void 0, props.blend)) fail(`Unknown blend mode "${props.blend}".`);
4890
4891
  next.blend = props.blend;
4891
4892
  }
4892
4893
  if (props.clipped !== void 0) {
@@ -4906,13 +4907,13 @@ function setLayerProperties(layers, id, props) {
4906
4907
  if (props.collapsed) g.collapsed = true;
4907
4908
  else delete g.collapsed;
4908
4909
  }
4909
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => next);
4910
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => next);
4910
4911
  }
4911
4912
  function groupLayers(layers, ids, name = "Group") {
4912
4913
  if (!ids.length) fail("Give at least one layer id to group.");
4913
4914
  const locs = ids.map((id) => requireLayer(layers, id));
4914
- const parent = _nullishCoalesce(_optionalChain([locs, 'access', _80 => _80[0], 'access', _81 => _81.parent, 'optionalAccess', _82 => _82.id]), () => ( null));
4915
- if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _83 => _83.parent, 'optionalAccess', _84 => _84.id]), () => ( null))) !== parent)) fail("Layers to group must share one parent; move them next to each other first.");
4915
+ const parent = _nullishCoalesce(_optionalChain([locs, 'access', _83 => _83[0], 'access', _84 => _84.parent, 'optionalAccess', _85 => _85.id]), () => ( null));
4916
+ if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _86 => _86.parent, 'optionalAccess', _87 => _87.id]), () => ( null))) !== parent)) fail("Layers to group must share one parent; move them next to each other first.");
4916
4917
  for (const l of locs) requireUnlocked(l.layer, "all", "group it");
4917
4918
  const ordered = [...new Set(locs)].sort((a, b) => a.index - b.index);
4918
4919
  const top = ordered[ordered.length - 1].index;
@@ -4929,23 +4930,23 @@ function groupLayers(layers, ids, name = "Group") {
4929
4930
  return c;
4930
4931
  })
4931
4932
  };
4932
- if (_optionalChain([group, 'access', _85 => _85.children, 'access', _86 => _86[0], 'optionalAccess', _87 => _87.clipped])) {
4933
+ if (_optionalChain([group, 'access', _88 => _88.children, 'access', _89 => _89[0], 'optionalAccess', _90 => _90.clipped])) {
4933
4934
  const c = { ...group.children[0] };
4934
4935
  delete c.clipped;
4935
4936
  group.children[0] = c;
4936
4937
  }
4937
4938
  let out = layers;
4938
- for (const l of ordered) out = _chunkH543GD6Tcjs.mapLayer.call(void 0, out, l.layer.id, () => null);
4939
- return { layers: _chunkH543GD6Tcjs.insertLayer.call(void 0, out, group, parent, top - below), id: group.id };
4939
+ for (const l of ordered) out = _chunkT6H3JDGAcjs.mapLayer.call(void 0, out, l.layer.id, () => null);
4940
+ return { layers: _chunkT6H3JDGAcjs.insertLayer.call(void 0, out, group, parent, top - below), id: group.id };
4940
4941
  }
4941
4942
  function ungroupLayer(layers, id) {
4942
4943
  const loc = requireLayer(layers, id);
4943
4944
  if (loc.layer.type !== "group") fail(`Layer "${id}" is not a group.`);
4944
4945
  requireUnlocked(loc.layer, "all", "ungroup it");
4945
4946
  const group = loc.layer;
4946
- let out = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => null);
4947
+ let out = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => null);
4947
4948
  group.children.forEach((c, i) => {
4948
- out = _chunkH543GD6Tcjs.insertLayer.call(void 0, out, c, _nullishCoalesce(_optionalChain([loc, 'access', _88 => _88.parent, 'optionalAccess', _89 => _89.id]), () => ( null)), loc.index + i);
4949
+ out = _chunkT6H3JDGAcjs.insertLayer.call(void 0, out, c, _nullishCoalesce(_optionalChain([loc, 'access', _91 => _91.parent, 'optionalAccess', _92 => _92.id]), () => ( null)), loc.index + i);
4949
4950
  });
4950
4951
  return { layers: out, ids: group.children.map((c) => c.id) };
4951
4952
  }
@@ -4955,12 +4956,12 @@ function offsetLayer(layers, id, offset) {
4955
4956
  requireUnlocked(loc.layer, "position", "move it");
4956
4957
  if (!Number.isFinite(offset.x) || !Number.isFinite(offset.y)) fail("x and y must be numbers.");
4957
4958
  const layer = loc.layer;
4958
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, offset: { x: Math.round(offset.x), y: Math.round(offset.y) } }));
4959
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, offset: { x: Math.round(offset.x), y: Math.round(offset.y) } }));
4959
4960
  }
4960
4961
  function setLayerMask(layers, id, mask) {
4961
4962
  const loc = requireLayer(layers, id);
4962
4963
  requireUnlocked(loc.layer, "all", "change its mask");
4963
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, (l) => {
4964
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, (l) => {
4964
4965
  const next = { ...l };
4965
4966
  if (mask) next.mask = mask;
4966
4967
  else delete next.mask;
@@ -4998,8 +4999,8 @@ function requirePixelLayer(layers, id) {
4998
4999
  }
4999
5000
  function addLayerFilter(layers, id, filter) {
5000
5001
  const layer = requirePixelLayer(layers, id);
5001
- if (_optionalChain([layer, 'access', _90 => _90.filters, 'optionalAccess', _91 => _91.some, 'call', _92 => _92((f) => f.kind === filter.kind)])) fail(`Layer "${id}" already has a ${filter.kind} filter; change it with update_layer_filter.`);
5002
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters: [..._nullishCoalesce(layer.filters, () => ( [])), filter] }));
5002
+ 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.`);
5003
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters: [..._nullishCoalesce(layer.filters, () => ( [])), filter] }));
5003
5004
  }
5004
5005
  function updateLayerFilter(layers, id, filterId, changes) {
5005
5006
  const layer = requirePixelLayer(layers, id);
@@ -5010,7 +5011,7 @@ function updateLayerFilter(layers, id, filterId, changes) {
5010
5011
  const merged = normalizeFilter({ ...current, ...changes, kind: current.kind }, current.id);
5011
5012
  const filters = [...layer.filters];
5012
5013
  filters[i] = merged;
5013
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters }));
5014
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => ({ ...layer, filters }));
5014
5015
  }
5015
5016
  function removeLayerFilter(layers, id, filterId) {
5016
5017
  const layer = requirePixelLayer(layers, id);
@@ -5019,12 +5020,83 @@ function removeLayerFilter(layers, id, filterId) {
5019
5020
  const next = { ...layer };
5020
5021
  if (filters.length) next.filters = filters;
5021
5022
  else delete next.filters;
5022
- return _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => next);
5023
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => next);
5024
+ }
5025
+ function requireEffectLayer(layers, id, action) {
5026
+ const layer = requireLayer(layers, id).layer;
5027
+ if (layer.type === "adjustment") fail(`Layer "${layer.name || id}" is an adjustment layer; effects go on pixel, annotation and group layers.`);
5028
+ requireUnlocked(layer, "all", action);
5029
+ return layer;
5030
+ }
5031
+ function layerEffectsOf(layer) {
5032
+ return _nullishCoalesce(layer.effects, () => ( { enabled: true, items: [] }));
5033
+ }
5034
+ function guard(fn) {
5035
+ try {
5036
+ return fn();
5037
+ } catch (e) {
5038
+ if (e instanceof _chunkT6H3JDGAcjs.LayerEffectError) fail(e.message);
5039
+ throw e;
5040
+ }
5041
+ }
5042
+ function setLayerEffects(layers, id, effects) {
5043
+ const layer = requireEffectLayer(layers, id, "change its effects");
5044
+ const next = { ...layer };
5045
+ if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) {
5046
+ guard(() => _chunkT6H3JDGAcjs.validateLayerEffects.call(void 0, effects));
5047
+ next.effects = effects;
5048
+ } else delete next.effects;
5049
+ return _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => next);
5050
+ }
5051
+ function addLayerEffect(layers, id, kind, params = {}, index) {
5052
+ if (!_chunkT6H3JDGAcjs.isLayerEffectKind.call(void 0, kind)) fail(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkT6H3JDGAcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
5053
+ const layer = requireEffectLayer(layers, id, "add effects");
5054
+ const current = layerEffectsOf(layer);
5055
+ const ids = new Set(current.items.map((e) => e.id));
5056
+ let effectId = _chunkT6H3JDGAcjs.newEffectId.call(void 0, );
5057
+ while (ids.has(effectId)) effectId = _chunkT6H3JDGAcjs.newEffectId.call(void 0, );
5058
+ const { id: _ignored, kind: _kind, ...rest } = params;
5059
+ const effect = guard(() => _chunkT6H3JDGAcjs.mergeLayerEffect.call(void 0, _chunkT6H3JDGAcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
5060
+ const items = [...current.items];
5061
+ const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
5062
+ items.splice(at, 0, effect);
5063
+ return { layers: setLayerEffects(layers, id, { ...current, items }), effect };
5064
+ }
5065
+ function requireEffect(layer, effectId) {
5066
+ const items = _nullishCoalesce(_optionalChain([layer, 'access', _96 => _96.effects, 'optionalAccess', _97 => _97.items]), () => ( []));
5067
+ const i = items.findIndex((e) => e.id === effectId);
5068
+ if (i === -1) fail(`Layer "${layer.name || layer.id}" has no effect "${effectId}". Effects: ${items.map((e) => `${e.id} (${e.kind})`).join(", ") || "none"}; call list_layer_effects.`);
5069
+ return i;
5070
+ }
5071
+ function updateLayerEffect(layers, id, effectId, changes) {
5072
+ const layer = requireEffectLayer(layers, id, "change its effects");
5073
+ const i = requireEffect(layer, effectId);
5074
+ const current = layer.effects;
5075
+ const items = [...current.items];
5076
+ items[i] = guard(() => _chunkT6H3JDGAcjs.mergeLayerEffect.call(void 0, items[i], changes));
5077
+ return setLayerEffects(layers, id, { ...current, items });
5078
+ }
5079
+ function removeLayerEffect(layers, id, effectId) {
5080
+ const layer = requireEffectLayer(layers, id, "change its effects");
5081
+ requireEffect(layer, effectId);
5082
+ const current = layer.effects;
5083
+ return setLayerEffects(layers, id, { ...current, items: current.items.filter((e) => e.id !== effectId) });
5084
+ }
5085
+ function setLayerEffectsEnabled(layers, id, enabled, scale) {
5086
+ const layer = requireEffectLayer(layers, id, "change its effects");
5087
+ if (scale !== void 0 && !(Number.isFinite(scale) && scale >= 0.01 && scale <= 10)) fail(`scale must be from 0.01 to 10 (1 = 100 %), got ${scale}.`);
5088
+ const current = layerEffectsOf(layer);
5089
+ const next = { ...current, enabled };
5090
+ if (scale !== void 0) {
5091
+ if (scale === 1) delete next.scale;
5092
+ else next.scale = scale;
5093
+ }
5094
+ return setLayerEffects(layers, id, next);
5023
5095
  }
5024
5096
  function parseBlend(value, allowPassThrough = false) {
5025
5097
  if (value === void 0) return void 0;
5026
5098
  if (value === "pass-through" && allowPassThrough) return value;
5027
- if (!_chunkZOOEX3WTcjs.isBlendMode.call(void 0, value)) fail(`Unknown blend mode "${String(value)}".`);
5099
+ if (!_chunkCRMAXIUVcjs.isBlendMode.call(void 0, value)) fail(`Unknown blend mode "${String(value)}".`);
5028
5100
  return value;
5029
5101
  }
5030
5102
  function unionRect(a, b) {
@@ -5258,7 +5330,7 @@ var PsdWriter = (_class4 = class {constructor() { _class4.prototype.__init24.cal
5258
5330
  function decodeLegacyName(b) {
5259
5331
  try {
5260
5332
  return new TextDecoder("utf-8", { fatal: true }).decode(b);
5261
- } catch (e12) {
5333
+ } catch (e13) {
5262
5334
  return String.fromCharCode(...b);
5263
5335
  }
5264
5336
  }
@@ -5279,7 +5351,7 @@ function descriptor(classId, items = []) {
5279
5351
  return { name: "", classId, items };
5280
5352
  }
5281
5353
  function descGet(d, key) {
5282
- return _optionalChain([d, 'access', _93 => _93.items, 'access', _94 => _94.find, 'call', _95 => _95(([k]) => k === key), 'optionalAccess', _96 => _96[1]]);
5354
+ return _optionalChain([d, 'access', _98 => _98.items, 'access', _99 => _99.find, 'call', _100 => _100(([k]) => k === key), 'optionalAccess', _101 => _101[1]]);
5283
5355
  }
5284
5356
  function descNumber(d, key) {
5285
5357
  const v = descGet(d, key);
@@ -5289,7 +5361,7 @@ function descNumber(d, key) {
5289
5361
  }
5290
5362
  function descBool(d, key) {
5291
5363
  const v = descGet(d, key);
5292
- return _optionalChain([v, 'optionalAccess', _97 => _97.type]) === "bool" ? v.value : void 0;
5364
+ return _optionalChain([v, 'optionalAccess', _102 => _102.type]) === "bool" ? v.value : void 0;
5293
5365
  }
5294
5366
  function descObject(d, key) {
5295
5367
  const v = descGet(d, key);
@@ -5760,7 +5832,7 @@ function parseAdjustmentBlock(key, data) {
5760
5832
  default:
5761
5833
  return null;
5762
5834
  }
5763
- } catch (e13) {
5835
+ } catch (e14) {
5764
5836
  return null;
5765
5837
  }
5766
5838
  }
@@ -5936,9 +6008,9 @@ function packbitsDecodeInto(src, expected, out, at) {
5936
6008
  function inflateChecked(data, expected) {
5937
6009
  let out;
5938
6010
  try {
5939
- out = _chunkH543GD6Tcjs.inflate.call(void 0, data, { maxOutput: expected + (1 << 20), sizeHint: expected, verify: false });
6011
+ out = _chunkT6H3JDGAcjs.inflate.call(void 0, data, { maxOutput: expected + (1 << 20), sizeHint: expected, verify: false });
5940
6012
  } catch (e) {
5941
- throw new PsdError(`ZIP channel data: ${e instanceof _chunkH543GD6Tcjs.ZlibError || e instanceof Error ? e.message : String(e)}`);
6013
+ throw new PsdError(`ZIP channel data: ${e instanceof _chunkT6H3JDGAcjs.ZlibError || e instanceof Error ? e.message : String(e)}`);
5942
6014
  }
5943
6015
  if (out.length < expected) throw new PsdError(`ZIP stream produced ${out.length} of ${expected} bytes.`);
5944
6016
  return out.length === expected ? out : out.subarray(0, expected);
@@ -6177,7 +6249,7 @@ function parseMask(d) {
6177
6249
  }
6178
6250
  if (!realFirst) m.real = readReal();
6179
6251
  return m;
6180
- } catch (e14) {
6252
+ } catch (e15) {
6181
6253
  return void 0;
6182
6254
  }
6183
6255
  }
@@ -6251,14 +6323,14 @@ function readPsd(bytes) {
6251
6323
  return { header, colorModeData, resources, layers, mergedAlpha, globalBlocks, imageCompression, imageData: r.rest() };
6252
6324
  }
6253
6325
  function layerBlock(rec, key) {
6254
- return _optionalChain([rec, 'access', _98 => _98.blocks, 'access', _99 => _99.find, 'call', _100 => _100((b) => b.key === key), 'optionalAccess', _101 => _101.data]);
6326
+ return _optionalChain([rec, 'access', _103 => _103.blocks, 'access', _104 => _104.find, 'call', _105 => _105((b) => b.key === key), 'optionalAccess', _106 => _106.data]);
6255
6327
  }
6256
6328
  function layerName(rec) {
6257
6329
  const luni = layerBlock(rec, "luni");
6258
6330
  if (luni) {
6259
6331
  try {
6260
6332
  return new PsdReader(luni).unicode();
6261
- } catch (e15) {
6333
+ } catch (e16) {
6262
6334
  }
6263
6335
  }
6264
6336
  return rec.legacyName;
@@ -6282,7 +6354,7 @@ function u8Block(rec, key) {
6282
6354
  function layerTree(file) {
6283
6355
  const stack = [[]];
6284
6356
  file.layers.forEach((rec, index) => {
6285
- const kind = _nullishCoalesce(_optionalChain([sectionDivider, 'call', _102 => _102(rec), 'optionalAccess', _103 => _103.kind]), () => ( SECTION_OTHER));
6357
+ const kind = _nullishCoalesce(_optionalChain([sectionDivider, 'call', _107 => _107(rec), 'optionalAccess', _108 => _108.kind]), () => ( SECTION_OTHER));
6286
6358
  if (kind === SECTION_DIVIDER) {
6287
6359
  stack.push([]);
6288
6360
  } else if (kind === SECTION_OPEN || kind === SECTION_CLOSED) {
@@ -6300,7 +6372,7 @@ function layerTree(file) {
6300
6372
  }
6301
6373
  function channelRect(rec, id) {
6302
6374
  if (id === CHANNEL_USER_MASK && rec.mask) return rec.mask.rect;
6303
- if (id === CHANNEL_REAL_USER_MASK && rec.mask) return _nullishCoalesce(_optionalChain([rec, 'access', _104 => _104.mask, 'access', _105 => _105.real, 'optionalAccess', _106 => _106.rect]), () => ( rec.mask.rect));
6375
+ if (id === CHANNEL_REAL_USER_MASK && rec.mask) return _nullishCoalesce(_optionalChain([rec, 'access', _109 => _109.mask, 'access', _110 => _110.real, 'optionalAccess', _111 => _111.rect]), () => ( rec.mask.rect));
6304
6376
  return rec.rect;
6305
6377
  }
6306
6378
  function decodeLayerChannel(file, rec, id) {
@@ -6318,7 +6390,7 @@ function decodeMergedImage(file) {
6318
6390
  return decodePlanes(file.imageCompression, file.imageData, { planes: channels, width, height, depth, psb });
6319
6391
  }
6320
6392
  function resource(file, id) {
6321
- return _optionalChain([file, 'access', _107 => _107.resources, 'access', _108 => _108.find, 'call', _109 => _109((r) => r.id === id), 'optionalAccess', _110 => _110.data]);
6393
+ return _optionalChain([file, 'access', _112 => _112.resources, 'access', _113 => _113.find, 'call', _114 => _114((r) => r.id === id), 'optionalAccess', _115 => _115.data]);
6322
6394
  }
6323
6395
  function resolution(file) {
6324
6396
  const d = resource(file, 1005);
@@ -6687,11 +6759,11 @@ function safeSize(ctx, rect, name) {
6687
6759
  }
6688
6760
  function recordPixels(ctx, rec, name) {
6689
6761
  const { width, height } = safeSize(ctx, rec.rect, name);
6690
- if (!width || !height || ctx.skipPixels) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
6762
+ if (!width || !height || ctx.skipPixels) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
6691
6763
  const ids = [...Array.from({ length: ctx.colorCount }, (_, i) => i), CHANNEL_ALPHA];
6692
6764
  const planes = ids.map((id) => rec.channels.some((c) => c.id === id) ? _nullishCoalesce(decodeOr(ctx, rec, id, name), () => ( null)) : void 0);
6693
- if (planes.some((p) => p === null)) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
6694
- if (planes.every((p) => p === void 0)) return _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
6765
+ if (planes.some((p) => p === null)) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
6766
+ if (planes.every((p) => p === void 0)) return _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
6695
6767
  const data = toRgba8({
6696
6768
  width,
6697
6769
  height,
@@ -6701,7 +6773,7 @@ function recordPixels(ctx, rec, name) {
6701
6773
  alpha: planes[ctx.colorCount],
6702
6774
  palette: ctx.palette
6703
6775
  });
6704
- return _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, rec.rect.left, rec.rect.top);
6776
+ return _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, rec.rect.left, rec.rect.top);
6705
6777
  }
6706
6778
  function recordMask(ctx, rec, name) {
6707
6779
  const m = rec.mask;
@@ -6712,11 +6784,11 @@ function recordMask(ctx, rec, name) {
6712
6784
  const rect = useReal ? m.real.rect : m.rect;
6713
6785
  const def = (useReal ? m.real.background : m.defaultColor) >= 128 ? 255 : 0;
6714
6786
  const flags = useReal ? m.real.flags : m.flags;
6715
- let surface = _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, def);
6787
+ let surface = _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, def);
6716
6788
  const { width, height } = safeSize(ctx, rect, name);
6717
6789
  if (width && height && !ctx.skipPixels) {
6718
6790
  const plane = decodeOr(ctx, rec, id, name);
6719
- 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);
6791
+ 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);
6720
6792
  }
6721
6793
  const mask = { surface, defaultValue: def };
6722
6794
  if (m.userDensity !== void 0 && m.userDensity < 255) mask.density = percent(m.userDensity);
@@ -6767,7 +6839,7 @@ function importNode(ctx, node, depth) {
6767
6839
  if (node.children) {
6768
6840
  const props2 = baseProps(ctx, rec, name, notes);
6769
6841
  const divider = sectionDivider(rec);
6770
- const key = _nullishCoalesce(_optionalChain([divider, 'optionalAccess', _111 => _111.blendKey]), () => ( rec.blendKey));
6842
+ const key = _nullishCoalesce(_optionalChain([divider, 'optionalAccess', _116 => _116.blendKey]), () => ( rec.blendKey));
6771
6843
  const groupBlend = key === "pass" ? "pass-through" : _nullishCoalesce(PSD_BLEND_KEYS[key], () => ( "normal"));
6772
6844
  const children = [];
6773
6845
  for (const child of node.children) {
@@ -6775,7 +6847,7 @@ function importNode(ctx, node, depth) {
6775
6847
  if (layer2) children.push(layer2);
6776
6848
  }
6777
6849
  const group = { type: "group", id: ctx.newId(name), ...props2, blend: groupBlend, children };
6778
- if (_optionalChain([divider, 'optionalAccess', _112 => _112.kind]) === SECTION_CLOSED) group.collapsed = true;
6850
+ if (_optionalChain([divider, 'optionalAccess', _117 => _117.kind]) === SECTION_CLOSED) group.collapsed = true;
6779
6851
  const mask2 = recordMask(ctx, rec, name);
6780
6852
  if (mask2) group.mask = mask2;
6781
6853
  entry.type = "group";
@@ -6853,7 +6925,7 @@ function mergedLayer(ctx) {
6853
6925
  visible: true,
6854
6926
  opacity: 1,
6855
6927
  blend: "normal",
6856
- surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
6928
+ surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
6857
6929
  offset: { x: 0, y: 0 }
6858
6930
  };
6859
6931
  }
@@ -6939,13 +7011,13 @@ function rleChannel(id, plane, width, height, psb) {
6939
7011
  var emptyChannel = (id) => ({ id, compression: 0, data: new Uint8Array(0) });
6940
7012
  function maskChannel(mask, ox, oy, psb) {
6941
7013
  if (mask.source) throw new PsdError("A parametric mask must be baked before export.");
6942
- const bounds = _chunkZOOEX3WTcjs.contentBounds.call(void 0, mask.surface);
7014
+ const bounds = _chunkCRMAXIUVcjs.contentBounds.call(void 0, mask.surface);
6943
7015
  const def = mask.defaultValue;
6944
7016
  const m = { rect: EMPTY_RECT, defaultColor: def, flags: mask.enabled === false ? MASK_FLAG_DISABLED : 0 };
6945
7017
  if ((_nullishCoalesce(mask.density, () => ( 1))) < 1) m.userDensity = Math.round(Math.max(0, _nullishCoalesce(mask.density, () => ( 1))) * 255);
6946
7018
  if ((_nullishCoalesce(mask.feather, () => ( 0))) > 0) m.userFeather = mask.feather;
6947
7019
  if (!bounds) return { channel: emptyChannel(CHANNEL_USER_MASK), mask: m };
6948
- const plane = _chunkZOOEX3WTcjs.readRegion.call(void 0, mask.surface, bounds);
7020
+ const plane = _chunkCRMAXIUVcjs.readRegion.call(void 0, mask.surface, bounds);
6949
7021
  m.rect = toRect({ ...bounds, x: bounds.x + ox, y: bounds.y + oy });
6950
7022
  return { channel: rleChannel(CHANNEL_USER_MASK, new Uint8Array(plane.buffer, plane.byteOffset, plane.length), bounds.width, bounds.height, psb), mask: m };
6951
7023
  }
@@ -6968,7 +7040,7 @@ function exportPsd(input) {
6968
7040
  return {
6969
7041
  opacity: Math.round(Math.min(1, Math.max(0, layer.opacity)) * 255),
6970
7042
  clipping: layer.clipped ? 1 : 0,
6971
- flags: (layer.visible ? 0 : LAYER_FLAG_HIDDEN) | (_optionalChain([layer, 'access', _113 => _113.locks, 'optionalAccess', _114 => _114.transparency]) ? LAYER_FLAG_TRANSPARENCY_PROTECTED : 0),
7043
+ flags: (layer.visible ? 0 : LAYER_FLAG_HIDDEN) | (_optionalChain([layer, 'access', _118 => _118.locks, 'optionalAccess', _119 => _119.transparency]) ? LAYER_FLAG_TRANSPARENCY_PROTECTED : 0),
6972
7044
  legacyName: name,
6973
7045
  blocks
6974
7046
  };
@@ -7025,16 +7097,16 @@ function exportPsd(input) {
7025
7097
  }
7026
7098
  case "pixel": {
7027
7099
  if (layer.source === "document") throw new PsdError(`Layer "${layer.name}" reads the document image; resolve its pixels before export.`);
7028
- if (_optionalChain([layer, 'access', _115 => _115.filters, 'optionalAccess', _116 => _116.some, 'call', _117 => _117(isActiveFilter)])) throw new PsdError(`Layer "${layer.name}" has live filters; bake them before export.`);
7100
+ 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.`);
7029
7101
  const extra = [];
7030
7102
  if (layer.fillOpacity !== void 0 && layer.fillOpacity < 1) {
7031
7103
  extra.push({ key: "iOpa", data: Uint8Array.from([Math.round(Math.max(0, layer.fillOpacity) * 255), 0, 0, 0]) });
7032
7104
  }
7033
7105
  const rec = { ...common(layer, extra), rect: EMPTY_RECT, channels: [], blendKey: _nullishCoalesce(BLEND_TO_PSD[layer.blend], () => ( "norm")) };
7034
- const bounds = _chunkZOOEX3WTcjs.contentBounds.call(void 0, layer.surface);
7106
+ const bounds = _chunkCRMAXIUVcjs.contentBounds.call(void 0, layer.surface);
7035
7107
  if (bounds) {
7036
7108
  const n2 = bounds.width * bounds.height;
7037
- const [r2, g2, b2, a2] = rgbaToPlanes(_chunkZOOEX3WTcjs.readRegion.call(void 0, layer.surface, bounds), n2);
7109
+ const [r2, g2, b2, a2] = rgbaToPlanes(_chunkCRMAXIUVcjs.readRegion.call(void 0, layer.surface, bounds), n2);
7038
7110
  rec.rect = toRect({ ...bounds, x: bounds.x + layer.offset.x, y: bounds.y + layer.offset.y });
7039
7111
  rec.channels = [
7040
7112
  rleChannel(CHANNEL_ALPHA, a2, bounds.width, bounds.height, psb),
@@ -7105,33 +7177,40 @@ function paintCoverageInto(base, coverage, apply, rects) {
7105
7177
  const tiles = new Map(base.tiles);
7106
7178
  const done = /* @__PURE__ */ new Set();
7107
7179
  for (const r of rects) {
7108
- 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 })) {
7109
- const key = _chunkZOOEX3WTcjs.tileKey.call(void 0, t.tx, t.ty);
7180
+ 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 })) {
7181
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, t.tx, t.ty);
7110
7182
  if (done.has(key)) continue;
7111
7183
  done.add(key);
7112
- const src = _nullishCoalesce(_optionalChain([base, 'access', _118 => _118.tiles, 'access', _119 => _119.get, 'call', _120 => _120(key), 'optionalAccess', _121 => _121.data]), () => ( defaultTile(base)));
7113
- const data = _chunk4F3YDIWWcjs.applyStrokeToTile.call(void 0, coverage, src, base.channels, t.tx, t.ty, apply);
7114
- const tile = _chunkZOOEX3WTcjs.finishTile.call(void 0, data, base.channels, base.defaultValue);
7184
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _123 => _123.tiles, 'access', _124 => _124.get, 'call', _125 => _125(key), 'optionalAccess', _126 => _126.data]), () => ( defaultTile(base)));
7185
+ const data = _chunkZZOTHJ4Kcjs.applyStrokeToTile.call(void 0, coverage, src, base.channels, t.tx, t.ty, apply);
7186
+ const tile = _chunkCRMAXIUVcjs.finishTile.call(void 0, data, base.channels, base.defaultValue);
7115
7187
  if (tile) tiles.set(key, tile);
7116
7188
  else tiles.delete(key);
7117
7189
  }
7118
7190
  }
7119
- return new (0, _chunkZOOEX3WTcjs.TiledSurface)(base.channels, tiles, base.defaultValue);
7191
+ return new (0, _chunkCRMAXIUVcjs.TiledSurface)(base.channels, tiles, base.defaultValue);
7120
7192
  }
7121
7193
  function defaultTile(s) {
7122
- const d = new Uint8ClampedArray(_chunkZOOEX3WTcjs.TILE * _chunkZOOEX3WTcjs.TILE * s.channels);
7194
+ const d = new Uint8ClampedArray(_chunkCRMAXIUVcjs.TILE * _chunkCRMAXIUVcjs.TILE * s.channels);
7123
7195
  if (s.defaultValue) d.fill(s.defaultValue);
7124
7196
  return d;
7125
7197
  }
7126
7198
  var PaintStrokeSession = (_class6 = class {
7127
- constructor(controller, target, stroke, apply) {;_class6.prototype.__init28.call(this);_class6.prototype.__init29.call(this);_class6.prototype.__init30.call(this);
7199
+ 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);
7128
7200
  this.controller = controller;
7129
7201
  this.target = target;
7130
- this.stroke = stroke;
7131
7202
  this.apply = apply;
7132
7203
  this.before = controller._captureForStroke();
7133
7204
  this.base = target.surface;
7134
7205
  this.live = new Map(this.base.tiles);
7206
+ if (stroke instanceof _chunkZZOTHJ4Kcjs.StrokeCoverage) {
7207
+ this.stroke = stroke;
7208
+ this.mixer = null;
7209
+ } else {
7210
+ this.stroke = null;
7211
+ this.mixer = stroke.create(this.mixerPixels());
7212
+ this.mixerInit = stroke;
7213
+ }
7135
7214
  }
7136
7215
 
7137
7216
 
@@ -7139,10 +7218,34 @@ var PaintStrokeSession = (_class6 = class {
7139
7218
 
7140
7219
 
7141
7220
 
7142
-
7143
7221
  __init28() {this.touched = /* @__PURE__ */ new Set()}
7144
- __init29() {this.last = null}
7145
- __init30() {this.closed = false}
7222
+
7223
+
7224
+ __init29() {this.mixerInit = null}
7225
+ /** Mixer tiles written since the last update: they get new tile objects so the compositor sees them change. */
7226
+ __init30() {this.fresh = /* @__PURE__ */ new Set()}
7227
+ __init31() {this.last = null}
7228
+ __init32() {this.closed = false}
7229
+ /** The live pixels a mixer stroke reads and writes; base tiles are copied on first write. */
7230
+ mixerPixels() {
7231
+ const a = this.apply;
7232
+ return {
7233
+ offset: a.offset,
7234
+ lockTransparency: a.lockTransparency,
7235
+ selection: a.selection,
7236
+ readTile: (tx, ty) => _nullishCoalesce(_optionalChain([this, 'access', _127 => _127.live, 'access', _128 => _128.get, 'call', _129 => _129(_chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty)), 'optionalAccess', _130 => _130.data]), () => ( (this.base.defaultValue ? defaultTile(this.base) : null))),
7237
+ writeTile: (tx, ty) => {
7238
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty);
7239
+ if (!this.touched.has(key)) {
7240
+ const src = _nullishCoalesce(_optionalChain([this, 'access', _131 => _131.base, 'access', _132 => _132.tiles, 'access', _133 => _133.get, 'call', _134 => _134(key), 'optionalAccess', _135 => _135.data]), () => ( defaultTile(this.base)));
7241
+ this.live.set(key, { data: new Uint8ClampedArray(src), uniform: null });
7242
+ this.touched.add(key);
7243
+ }
7244
+ this.fresh.add(key);
7245
+ return this.live.get(key).data;
7246
+ }
7247
+ };
7248
+ }
7146
7249
  get layerId() {
7147
7250
  return this.target.id;
7148
7251
  }
@@ -7150,48 +7253,59 @@ var PaintStrokeSession = (_class6 = class {
7150
7253
  push(points) {
7151
7254
  if (this.closed || !points.length) return;
7152
7255
  this.last = points[points.length - 1];
7153
- this.update(this.stroke.push(points));
7256
+ this.update(this.mixer ? this.mixer.push(points) : this.stroke.push(points));
7154
7257
  }
7155
7258
  update(rects) {
7156
7259
  if (!rects.length) return;
7157
7260
  const ch = this.base.channels;
7261
+ if (this.mixer) {
7262
+ for (const key of this.fresh) this.live.set(key, { data: this.live.get(key).data, uniform: null });
7263
+ this.fresh.clear();
7264
+ this.controller._strokeUpdate(this.target.id, this.target.channel, new (0, _chunkCRMAXIUVcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
7265
+ return;
7266
+ }
7267
+ const stroke = this.stroke;
7158
7268
  const regions = /* @__PURE__ */ new Map();
7159
7269
  for (const r of rects) {
7160
- 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 })) {
7161
- const key = _chunkZOOEX3WTcjs.tileKey.call(void 0, t.tx, t.ty);
7270
+ 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 })) {
7271
+ const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, t.tx, t.ty);
7162
7272
  const cur = regions.get(key);
7163
7273
  regions.set(key, { tx: t.tx, ty: t.ty, r: cur ? unionRect(cur.r, r) : r });
7164
7274
  }
7165
7275
  }
7166
7276
  for (const [key, { tx, ty, r }] of regions) {
7167
- const src = _nullishCoalesce(_optionalChain([this, 'access', _122 => _122.base, 'access', _123 => _123.tiles, 'access', _124 => _124.get, 'call', _125 => _125(key), 'optionalAccess', _126 => _126.data]), () => ( defaultTile(this.base)));
7168
- const prev = this.touched.has(key) ? _optionalChain([this, 'access', _127 => _127.live, 'access', _128 => _128.get, 'call', _129 => _129(key), 'optionalAccess', _130 => _130.data]) : void 0;
7277
+ const src = _nullishCoalesce(_optionalChain([this, 'access', _136 => _136.base, 'access', _137 => _137.tiles, 'access', _138 => _138.get, 'call', _139 => _139(key), 'optionalAccess', _140 => _140.data]), () => ( defaultTile(this.base)));
7278
+ const prev = this.touched.has(key) ? _optionalChain([this, 'access', _141 => _141.live, 'access', _142 => _142.get, 'call', _143 => _143(key), 'optionalAccess', _144 => _144.data]) : void 0;
7169
7279
  this.touched.add(key);
7170
- const data = _chunk4F3YDIWWcjs.applyStrokeToTile.call(void 0, this.stroke.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
7280
+ const data = _chunkZZOTHJ4Kcjs.applyStrokeToTile.call(void 0, stroke.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
7171
7281
  this.live.set(key, { data, uniform: null });
7172
7282
  }
7173
- this.controller._strokeUpdate(this.target.id, this.target.channel, new (0, _chunkZOOEX3WTcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
7283
+ this.controller._strokeUpdate(this.target.id, this.target.channel, new (0, _chunkCRMAXIUVcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
7174
7284
  }
7175
7285
  /** Finishes the stroke (one undo step) and returns what changed. */
7176
7286
  end() {
7177
7287
  if (this.closed) throw new LayerOperationError("This stroke has already ended.");
7178
- this.update(this.stroke.finish(_nullishCoalesce(this.last, () => ( void 0))));
7288
+ const last = _nullishCoalesce(this.last, () => ( void 0));
7289
+ this.update(this.mixer ? this.mixer.finish(last) : this.stroke.finish(last));
7179
7290
  this.closed = true;
7180
7291
  const ch = this.base.channels;
7181
7292
  const tiles = new Map(this.base.tiles);
7182
7293
  let changed = false;
7183
7294
  for (const key of this.touched) {
7184
7295
  const live = this.live.get(key);
7185
- const tile = _chunkZOOEX3WTcjs.finishTile.call(void 0, live.data, ch, this.base.defaultValue);
7296
+ const tile = _chunkCRMAXIUVcjs.finishTile.call(void 0, live.data, ch, this.base.defaultValue);
7186
7297
  const prev = this.base.tiles.get(key);
7187
7298
  if (tile) tiles.set(key, tile);
7188
7299
  else tiles.delete(key);
7189
7300
  if (!sameTile(prev, tile)) changed = true;
7190
7301
  }
7191
- const surface = changed ? new (0, _chunkZOOEX3WTcjs.TiledSurface)(ch, tiles, this.base.defaultValue) : null;
7302
+ const surface = changed ? new (0, _chunkCRMAXIUVcjs.TiledSurface)(ch, tiles, this.base.defaultValue) : null;
7303
+ const mixerLoad = this.mixer ? this.mixerInit.end(this.mixer.load) : void 0;
7192
7304
  this.controller._strokeCommit(this.before, this.target.id, this.target.channel, surface);
7193
- const b = this.stroke.coverage.bounds;
7194
- return { layerId: this.target.id, channel: this.target.channel, bounds: changed ? b : null, dabs: this.stroke.dabCount };
7305
+ const b = this.mixer ? this.mixer.bounds : this.stroke.coverage.bounds;
7306
+ const result = { layerId: this.target.id, channel: this.target.channel, bounds: changed ? b : null, dabs: (_nullishCoalesce(this.mixer, () => ( this.stroke))).dabCount };
7307
+ if (mixerLoad) result.mixerLoad = mixerLoad;
7308
+ return result;
7195
7309
  }
7196
7310
  /** Abandons the stroke and restores the layer. */
7197
7311
  cancel() {
@@ -7236,14 +7350,14 @@ function migrateSerializedImageEditorState(data) {
7236
7350
  const legacy = data;
7237
7351
  const adjustments = normalizeStoredAdjustments(legacy.adjustments);
7238
7352
  return {
7239
- version: _optionalChain([adjustments, 'access', _131 => _131.layers, 'optionalAccess', _132 => _132.length]) ? 2 : 1,
7353
+ version: _optionalChain([adjustments, 'access', _145 => _145.layers, 'optionalAccess', _146 => _146.length]) ? 2 : 1,
7240
7354
  crop: legacy.crop ? { ...legacy.crop } : null,
7241
7355
  transform: { ...DEFAULT_TRANSFORM, ...legacy.transform },
7242
7356
  adjustments: serializeAdjustments(adjustments),
7243
7357
  depthMask: {
7244
7358
  ...DEFAULT_DEPTH_MASK,
7245
7359
  ...legacy.depthMask,
7246
- depthRange: [..._nullishCoalesce(_optionalChain([legacy, 'access', _133 => _133.depthMask, 'optionalAccess', _134 => _134.depthRange]), () => ( DEFAULT_DEPTH_MASK.depthRange))]
7360
+ depthRange: [..._nullishCoalesce(_optionalChain([legacy, 'access', _147 => _147.depthMask, 'optionalAccess', _148 => _148.depthRange]), () => ( DEFAULT_DEPTH_MASK.depthRange))]
7247
7361
  },
7248
7362
  annotations: JSON.parse(JSON.stringify(_nullishCoalesce(legacy.annotations, () => ( [])))),
7249
7363
  ...legacy.selection ? { selection: { ...legacy.selection } } : {}
@@ -7275,26 +7389,26 @@ var DEVELOP_KEYS = ["brightness", "contrast", "saturation", "exposure", "tempera
7275
7389
  var ImageEditorController = (_class7 = class {
7276
7390
 
7277
7391
 
7278
- __init31() {this.imageElement = null}
7279
- __init32() {this.listeners = /* @__PURE__ */ new Set()}
7280
- __init33() {this.histogramListeners = /* @__PURE__ */ new Set()}
7392
+ __init33() {this.imageElement = null}
7393
+ __init34() {this.listeners = /* @__PURE__ */ new Set()}
7394
+ __init35() {this.histogramListeners = /* @__PURE__ */ new Set()}
7281
7395
 
7282
7396
  // History stacks
7283
- __init34() {this.undoStack = []}
7284
- __init35() {this.redoStack = []}
7397
+ __init36() {this.undoStack = []}
7398
+ __init37() {this.redoStack = []}
7285
7399
 
7286
7400
 
7287
- __init36() {this.isApplyingHistory = false}
7401
+ __init38() {this.isApplyingHistory = false}
7288
7402
 
7289
7403
  /** Pixels the selection tools sample (host-provided or read back from the source). */
7290
- __init37() {this.samplePixels = null}
7291
- __init38() {this.samplePixelsOverride = false}
7404
+ __init39() {this.samplePixels = null}
7405
+ __init40() {this.samplePixelsOverride = false}
7292
7406
  /** Decoded source pixels (the Background's surface), by the buffer or element they came from. */
7293
- __init39() {this.sourceSurfaces = /* @__PURE__ */ new WeakMap()}
7294
- __init40() {this.viewKey = []}
7407
+ __init41() {this.sourceSurfaces = /* @__PURE__ */ new WeakMap()}
7408
+ __init42() {this.viewKey = []}
7295
7409
  /** For `compositePixels` and mask evaluation (the renderer keeps its own for the viewport). */
7296
- __init41() {this.compositor = new LayerCompositor()}
7297
- 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);
7410
+ __init43() {this.compositor = new LayerCompositor()}
7411
+ 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);
7298
7412
  this.maxHistoryDepth = _nullishCoalesce(options.maxHistoryDepth, () => ( 50));
7299
7413
  this.maxHistoryBytes = _nullishCoalesce(options.maxHistoryBytes, () => ( 512 * 1024 * 1024));
7300
7414
  this.onStateChange = options.onStateChange;
@@ -7305,7 +7419,8 @@ var ImageEditorController = (_class7 = class {
7305
7419
  this.renderer.layerSources = {
7306
7420
  surfaceOf: (layer) => this.surfaceOf(layer),
7307
7421
  sourceIsOpaque: () => this.sourceIsOpaque(),
7308
- version: () => this.sourceVersion()
7422
+ version: () => this.sourceVersion(),
7423
+ globalLight: () => this.state.globalLight
7309
7424
  };
7310
7425
  this.state = {
7311
7426
  sourceUrl: typeof options.image === "string" ? options.image : null,
@@ -7326,7 +7441,7 @@ var ImageEditorController = (_class7 = class {
7326
7441
  activeLayerId: null,
7327
7442
  activeTarget: "pixels",
7328
7443
  outputOpacity: 1,
7329
- paint: { brush: { ..._chunk4F3YDIWWcjs.DEFAULT_BRUSH }, foreground: "#000000", background: "#ffffff" },
7444
+ paint: { brush: { ..._chunkZZOTHJ4Kcjs.DEFAULT_BRUSH }, foreground: "#000000", background: "#ffffff", mixer: { ..._chunkZZOTHJ4Kcjs.DEFAULT_MIXER }, mixerLoad: _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD },
7330
7445
  fit: _nullishCoalesce(options.fit, () => ( "margin"))
7331
7446
  };
7332
7447
  if (options.image instanceof Object && "width" in options.image) {
@@ -7338,10 +7453,10 @@ var ImageEditorController = (_class7 = class {
7338
7453
  };
7339
7454
  }
7340
7455
  this.applyStored(_nullishCoalesce(options.initialState, () => ( {})));
7341
- if (_optionalChain([options, 'access', _135 => _135.initialState, 'optionalAccess', _136 => _136.selection])) {
7456
+ if (_optionalChain([options, 'access', _149 => _149.initialState, 'optionalAccess', _150 => _150.selection])) {
7342
7457
  try {
7343
7458
  this.state.selection = normalizeSelection(deserializeSelection(options.initialState.selection));
7344
- } catch (e16) {
7459
+ } catch (e17) {
7345
7460
  }
7346
7461
  }
7347
7462
  this.initialSnapshot = this.captureHistoryEntry();
@@ -7382,7 +7497,7 @@ var ImageEditorController = (_class7 = class {
7382
7497
  height: img.naturalHeight || img.height || 600
7383
7498
  }
7384
7499
  };
7385
- } catch (e17) {
7500
+ } catch (e18) {
7386
7501
  return { sourceUrl: src, element: null, dimensions: { ...this.state.imageDimensions } };
7387
7502
  }
7388
7503
  }
@@ -7415,13 +7530,13 @@ var ImageEditorController = (_class7 = class {
7415
7530
  * Where layer pixels changed since the last viewport render, when only strokes changed them
7416
7531
  * (the renderer then recomposites just those rectangles); `'all'` after any other change.
7417
7532
  */
7418
- __init42() {this.pendingDirty = "all"}
7533
+ __init44() {this.pendingDirty = "all"}
7419
7534
  notify(strokeRects) {
7420
7535
  if (strokeRects && this.pendingDirty !== "all") this.pendingDirty.push(...strokeRects);
7421
7536
  else if (!strokeRects) this.pendingDirty = "all";
7422
7537
  this.syncViews();
7423
7538
  const currentState = { ...this.state };
7424
- _optionalChain([this, 'access', _137 => _137.onStateChange, 'optionalCall', _138 => _138(currentState)]);
7539
+ _optionalChain([this, 'access', _151 => _151.onStateChange, 'optionalCall', _152 => _152(currentState)]);
7425
7540
  this.listeners.forEach((l) => l(currentState));
7426
7541
  }
7427
7542
  /** Recomputes the compatibility views (`adjustments`, `depthMask`, `annotations`) when the stack changed. */
@@ -7459,6 +7574,7 @@ var ImageEditorController = (_class7 = class {
7459
7574
  }
7460
7575
  };
7461
7576
  if (s.legacyOutputBlur !== void 0) entry.legacyOutputBlur = s.legacyOutputBlur;
7577
+ if (s.globalLight) entry.globalLight = { ...s.globalLight };
7462
7578
  return entry;
7463
7579
  }
7464
7580
  restoreHistoryEntry(entry) {
@@ -7471,6 +7587,8 @@ var ImageEditorController = (_class7 = class {
7471
7587
  s.outputOpacity = entry.outputOpacity;
7472
7588
  if (entry.legacyOutputBlur !== void 0) s.legacyOutputBlur = entry.legacyOutputBlur;
7473
7589
  else delete s.legacyOutputBlur;
7590
+ if (entry.globalLight) s.globalLight = { ...entry.globalLight };
7591
+ else delete s.globalLight;
7474
7592
  s.selection = entry.selection;
7475
7593
  if (this.imageElement !== entry.source.element && !this.samplePixelsOverride) this.samplePixels = null;
7476
7594
  this.imageElement = entry.source.element;
@@ -7626,7 +7744,7 @@ var ImageEditorController = (_class7 = class {
7626
7744
  return this.state.layers;
7627
7745
  }
7628
7746
  getLayer(id) {
7629
- return _optionalChain([_chunkH543GD6Tcjs.findLayer.call(void 0, this.state.layers, id), 'optionalAccess', _139 => _139.layer]);
7747
+ return _optionalChain([_chunkT6H3JDGAcjs.findLayer.call(void 0, this.state.layers, id), 'optionalAccess', _153 => _153.layer]);
7630
7748
  }
7631
7749
  /** The active layer, or `undefined`. */
7632
7750
  getActiveLayer() {
@@ -7639,7 +7757,7 @@ var ImageEditorController = (_class7 = class {
7639
7757
  setActiveLayer(id, target = "pixels") {
7640
7758
  if (id !== null && !this.getLayer(id)) return false;
7641
7759
  const layer = id ? this.getLayer(id) : void 0;
7642
- const t = target === "mask" && _optionalChain([layer, 'optionalAccess', _140 => _140.mask]) ? "mask" : "pixels";
7760
+ const t = target === "mask" && _optionalChain([layer, 'optionalAccess', _154 => _154.mask]) ? "mask" : "pixels";
7643
7761
  if (this.state.activeLayerId === id && this.state.activeTarget === t) return true;
7644
7762
  this.state.activeLayerId = id;
7645
7763
  this.state.activeTarget = t;
@@ -7654,11 +7772,11 @@ var ImageEditorController = (_class7 = class {
7654
7772
  const layer = this.getLayer(id);
7655
7773
  if (!layer || layer.type !== "pixel") return null;
7656
7774
  const surface = this.surfaceOf(layer);
7657
- const b = _chunkZOOEX3WTcjs.contentBounds.call(void 0, surface);
7775
+ const b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, surface);
7658
7776
  if (!b) return null;
7659
- 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) };
7777
+ 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) };
7660
7778
  }
7661
- __init43() {this.boundsCache = /* @__PURE__ */ new WeakMap()}
7779
+ __init45() {this.boundsCache = /* @__PURE__ */ new WeakMap()}
7662
7780
  /**
7663
7781
  * Document bounds of a layer's non-transparent pixels (pixel layers; the Background's source
7664
7782
  * included), or `null` for an empty or non-pixel layer.
@@ -7669,7 +7787,7 @@ var ImageEditorController = (_class7 = class {
7669
7787
  const surface = this.surfaceOf(layer);
7670
7788
  let b = this.boundsCache.get(surface);
7671
7789
  if (b === void 0) {
7672
- b = _chunkZOOEX3WTcjs.contentBounds.call(void 0, surface);
7790
+ b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, surface);
7673
7791
  this.boundsCache.set(surface, b);
7674
7792
  }
7675
7793
  return b ? { x: b.x + layer.offset.x, y: b.y + layer.offset.y, width: b.width, height: b.height } : null;
@@ -7685,17 +7803,17 @@ var ImageEditorController = (_class7 = class {
7685
7803
  let layers = this.state.layers;
7686
7804
  if (options.layerIds) {
7687
7805
  const keep = new Set(options.layerIds);
7688
- layers = _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers).filter((l) => keep.has(l.id) && l.type !== "group");
7806
+ layers = _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers).filter((l) => keep.has(l.id) && l.type !== "group");
7689
7807
  }
7690
7808
  const data = this.compositor.composite(layers, r, this.compositorSources());
7691
7809
  return { width: r.width, height: r.height, data };
7692
7810
  }
7693
7811
  compositorSources() {
7694
7812
  const { width, height } = this.naturalSize;
7695
- return { width, height, surfaceOf: (l) => this.surfaceOf(l), version: this.sourceVersion() };
7813
+ return { width, height, surfaceOf: (l) => this.surfaceOf(l), version: this.sourceVersion(), globalLight: this.state.globalLight };
7696
7814
  }
7697
- __init44() {this.sourceIds = /* @__PURE__ */ new WeakMap()}
7698
- __init45() {this.nextSourceId = 1}
7815
+ __init46() {this.sourceIds = /* @__PURE__ */ new WeakMap()}
7816
+ __init47() {this.nextSourceId = 1}
7699
7817
  /** Changes whenever the Background's source pixels can have changed. */
7700
7818
  sourceVersion() {
7701
7819
  const key = this.samplePixelsOverride ? this.samplePixels : _nullishCoalesce(this.imageElement, () => ( this.samplePixels));
@@ -7721,7 +7839,7 @@ var ImageEditorController = (_class7 = class {
7721
7839
  const fromPixels = (px2) => {
7722
7840
  let s = this.sourceSurfaces.get(px2);
7723
7841
  if (!s) {
7724
- s = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, px2, 4);
7842
+ s = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, px2, 4);
7725
7843
  this.sourceSurfaces.set(px2, s);
7726
7844
  }
7727
7845
  return s;
@@ -7736,7 +7854,7 @@ var ImageEditorController = (_class7 = class {
7736
7854
  const decoded2 = this.decodeSource();
7737
7855
  if (decoded2) {
7738
7856
  if (!this.samplePixelsOverride) this.samplePixels = decoded2;
7739
- const s = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, decoded2, 4);
7857
+ const s = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, decoded2, 4);
7740
7858
  this.sourceSurfaces.set(el, s);
7741
7859
  this.sourceSurfaces.set(decoded2, s);
7742
7860
  return s;
@@ -7744,7 +7862,7 @@ var ImageEditorController = (_class7 = class {
7744
7862
  }
7745
7863
  return fits ? fromPixels(px) : null;
7746
7864
  }
7747
- __init46() {this.opaqueCache = /* @__PURE__ */ new WeakMap()}
7865
+ __init48() {this.opaqueCache = /* @__PURE__ */ new WeakMap()}
7748
7866
  /** Whether every source pixel is opaque (some legacy renders depend on it). */
7749
7867
  sourceIsOpaque() {
7750
7868
  const s = this.sourceSurface();
@@ -7768,9 +7886,9 @@ var ImageEditorController = (_class7 = class {
7768
7886
  if (!ctx || typeof ctx.getImageData !== "function") return null;
7769
7887
  ctx.drawImage(el, 0, 0, width, height);
7770
7888
  const data = ctx.getImageData(0, 0, width, height);
7771
- if (!_optionalChain([data, 'optionalAccess', _141 => _141.data]) || data.data.length < width * height * 4) return null;
7889
+ if (!_optionalChain([data, 'optionalAccess', _155 => _155.data]) || data.data.length < width * height * 4) return null;
7772
7890
  return { width, height, data: data.data };
7773
- } catch (e18) {
7891
+ } catch (e19) {
7774
7892
  return null;
7775
7893
  }
7776
7894
  }
@@ -7779,8 +7897,8 @@ var ImageEditorController = (_class7 = class {
7779
7897
  commitLayers(next, extra, commitToHistory = true) {
7780
7898
  if (commitToHistory) this.recordHistory();
7781
7899
  this.state.layers = next;
7782
- _optionalChain([extra, 'optionalCall', _142 => _142()]);
7783
- if (this.state.activeLayerId && !_chunkH543GD6Tcjs.findLayer.call(void 0, next, this.state.activeLayerId)) {
7900
+ _optionalChain([extra, 'optionalCall', _156 => _156()]);
7901
+ if (this.state.activeLayerId && !_chunkT6H3JDGAcjs.findLayer.call(void 0, next, this.state.activeLayerId)) {
7784
7902
  this.state.activeLayerId = null;
7785
7903
  this.state.activeTarget = "pixels";
7786
7904
  }
@@ -7789,7 +7907,7 @@ var ImageEditorController = (_class7 = class {
7789
7907
  /** The default position of a new layer: above the active layer, else the top of the stack. */
7790
7908
  newLayerPlacement(placement) {
7791
7909
  if (placement.aboveId || placement.belowId || placement.parentId || placement.index !== void 0) return placement;
7792
- const active = this.state.activeLayerId ? _chunkH543GD6Tcjs.findLayer.call(void 0, this.state.layers, this.state.activeLayerId) : null;
7910
+ const active = this.state.activeLayerId ? _chunkT6H3JDGAcjs.findLayer.call(void 0, this.state.layers, this.state.activeLayerId) : null;
7793
7911
  return active ? { aboveId: active.layer.id } : {};
7794
7912
  }
7795
7913
  /**
@@ -7799,24 +7917,24 @@ var ImageEditorController = (_class7 = class {
7799
7917
  */
7800
7918
  addPixelLayer(init = {}) {
7801
7919
  const { width, height } = this.naturalSize;
7802
- let surface = _chunkZOOEX3WTcjs.emptySurface.call(void 0, 4);
7920
+ let surface = _chunkCRMAXIUVcjs.emptySurface.call(void 0, 4);
7803
7921
  if (init.pixels) {
7804
7922
  const px = init.pixels;
7805
7923
  if (!(px.width > 0 && px.height > 0) || px.data.length < px.width * px.height * 4) {
7806
7924
  throw new LayerOperationError("pixels must be RGBA with width \xD7 height \xD7 4 bytes.");
7807
7925
  }
7808
- surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, px, 4);
7926
+ surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, px, 4);
7809
7927
  } else if (init.color !== void 0) {
7810
7928
  const c = parseColor(init.color);
7811
- 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]));
7929
+ 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]));
7812
7930
  }
7813
7931
  const blend = parseBlend(init.blend);
7814
7932
  if (init.opacity !== void 0 && !(init.opacity >= 0 && init.opacity <= 1)) throw new LayerOperationError("opacity must be from 0 to 1.");
7815
- const ids = new Set(_chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
7933
+ const ids = new Set(_chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
7816
7934
  const layer = {
7817
7935
  type: "pixel",
7818
7936
  id: init.id && !ids.has(init.id) ? init.id : newLayerId(),
7819
- name: _optionalChain([init, 'access', _143 => _143.name, 'optionalAccess', _144 => _144.trim, 'call', _145 => _145()]) || this.nextLayerName(),
7937
+ name: _optionalChain([init, 'access', _157 => _157.name, 'optionalAccess', _158 => _158.trim, 'call', _159 => _159()]) || this.nextLayerName(),
7820
7938
  visible: _nullishCoalesce(init.visible, () => ( true)),
7821
7939
  opacity: _nullishCoalesce(init.opacity, () => ( 1)),
7822
7940
  blend: _nullishCoalesce(blend, () => ( "normal")),
@@ -7843,27 +7961,27 @@ var ImageEditorController = (_class7 = class {
7843
7961
  async decodeImage(image) {
7844
7962
  const trimmed = image.trim();
7845
7963
  let png = null;
7846
- if (/^data:image\/png/i.test(trimmed)) png = _nullishCoalesce(_optionalChain([_chunkH543GD6Tcjs.parseDataUrl.call(void 0, trimmed), 'optionalAccess', _146 => _146.bytes]), () => ( null));
7964
+ if (/^data:image\/png/i.test(trimmed)) png = _nullishCoalesce(_optionalChain([_chunkT6H3JDGAcjs.parseDataUrl.call(void 0, trimmed), 'optionalAccess', _160 => _160.bytes]), () => ( null));
7847
7965
  else if (/^[A-Za-z0-9+/=\s]+$/.test(trimmed) && trimmed.length > 16) {
7848
7966
  try {
7849
- const bytes = _chunkH543GD6Tcjs.base64ToBytes.call(void 0, trimmed);
7850
- if (_chunkH543GD6Tcjs.isPng.call(void 0, bytes)) png = bytes;
7851
- } catch (e19) {
7967
+ const bytes = _chunkT6H3JDGAcjs.base64ToBytes.call(void 0, trimmed);
7968
+ if (_chunkT6H3JDGAcjs.isPng.call(void 0, bytes)) png = bytes;
7969
+ } catch (e20) {
7852
7970
  png = null;
7853
7971
  }
7854
7972
  }
7855
7973
  if (png) {
7856
7974
  try {
7857
- const d = _chunkH543GD6Tcjs.decodePng.call(void 0, png);
7975
+ const d = _chunkT6H3JDGAcjs.decodePng.call(void 0, png);
7858
7976
  return { width: d.width, height: d.height, data: d.data };
7859
- } catch (e20) {
7977
+ } catch (e21) {
7860
7978
  }
7861
7979
  }
7862
- const src = png ? `data:image/png;base64,${_chunkH543GD6Tcjs.bytesToBase64.call(void 0, png)}` : trimmed;
7980
+ const src = png ? `data:image/png;base64,${_chunkT6H3JDGAcjs.bytesToBase64.call(void 0, png)}` : trimmed;
7863
7981
  let img;
7864
7982
  try {
7865
7983
  img = await this.renderer.imageCache.get(src);
7866
- } catch (e21) {
7984
+ } catch (e22) {
7867
7985
  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.");
7868
7986
  }
7869
7987
  const w = img.naturalWidth || img.width;
@@ -7875,7 +7993,7 @@ var ImageEditorController = (_class7 = class {
7875
7993
  return { width: w, height: h, data: data.data };
7876
7994
  }
7877
7995
  nextLayerName() {
7878
- const names = new Set(_chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.name));
7996
+ const names = new Set(_chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.name));
7879
7997
  let n = 1;
7880
7998
  while (names.has(`Layer ${n}`)) n++;
7881
7999
  return `Layer ${n}`;
@@ -7892,7 +8010,7 @@ var ImageEditorController = (_class7 = class {
7892
8010
  removeLayer(id) {
7893
8011
  const next = removeLayer(this.state.layers, id);
7894
8012
  this.commitLayers(next, () => {
7895
- if (this.state.selectedAnnotationId && !_chunkH543GD6Tcjs.flattenLayers.call(void 0, next).some((l) => l.type === "annotation" && l.annotation.id === this.state.selectedAnnotationId)) {
8013
+ if (this.state.selectedAnnotationId && !_chunkT6H3JDGAcjs.flattenLayers.call(void 0, next).some((l) => l.type === "annotation" && l.annotation.id === this.state.selectedAnnotationId)) {
7896
8014
  this.state.selectedAnnotationId = null;
7897
8015
  }
7898
8016
  });
@@ -7900,10 +8018,10 @@ var ImageEditorController = (_class7 = class {
7900
8018
  /** Moves a layer above / below another, or into a group, as one undo step. Returns its new parent and index. */
7901
8019
  moveLayer(id, placement) {
7902
8020
  const next = moveLayer(this.state.layers, id, placement);
7903
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, next, id);
7904
- if (next === this.state.layers) return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _147 => _147.parent, 'optionalAccess', _148 => _148.id]), () => ( null)), index: loc.index };
8021
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, next, id);
8022
+ if (next === this.state.layers) return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _161 => _161.parent, 'optionalAccess', _162 => _162.id]), () => ( null)), index: loc.index };
7905
8023
  this.commitLayers(next);
7906
- return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _149 => _149.parent, 'optionalAccess', _150 => _150.id]), () => ( null)), index: loc.index };
8024
+ return { parentId: _nullishCoalesce(_optionalChain([loc, 'access', _163 => _163.parent, 'optionalAccess', _164 => _164.id]), () => ( null)), index: loc.index };
7907
8025
  }
7908
8026
  /**
7909
8027
  * Changes name, visibility, opacity, fill, blend, clipping, locks or (groups) collapsed state, as
@@ -7912,7 +8030,7 @@ var ImageEditorController = (_class7 = class {
7912
8030
  setLayerProperties(id, props, commitToHistory = true) {
7913
8031
  const next = setLayerProperties(this.state.layers, id, props);
7914
8032
  this.commitLayers(next, void 0, commitToHistory);
7915
- return _chunkH543GD6Tcjs.findLayer.call(void 0, next, id).layer;
8033
+ return _chunkT6H3JDGAcjs.findLayer.call(void 0, next, id).layer;
7916
8034
  }
7917
8035
  /** Adds an empty pass-through group above the active layer (or at `placement`) and makes it active. Returns its id. */
7918
8036
  addGroup(init = {}) {
@@ -7920,7 +8038,7 @@ var ImageEditorController = (_class7 = class {
7920
8038
  const group = {
7921
8039
  type: "group",
7922
8040
  id: newLayerId("group"),
7923
- name: _optionalChain([init, 'access', _151 => _151.name, 'optionalAccess', _152 => _152.trim, 'call', _153 => _153()]) || "Group",
8041
+ name: _optionalChain([init, 'access', _165 => _165.name, 'optionalAccess', _166 => _166.trim, 'call', _167 => _167()]) || "Group",
7924
8042
  visible: true,
7925
8043
  opacity: 1,
7926
8044
  blend,
@@ -7970,14 +8088,14 @@ var ImageEditorController = (_class7 = class {
7970
8088
  let mask;
7971
8089
  if (from === "selection") {
7972
8090
  const sel = this.state.selection;
7973
- if (!_optionalChain([sel, 'optionalAccess', _154 => _154.bounds])) throw new LayerOperationError("Nothing is selected; select first, or use reveal-all / hide-all.");
8091
+ if (!_optionalChain([sel, 'optionalAccess', _168 => _168.bounds])) throw new LayerOperationError("Nothing is selected; select first, or use reveal-all / hide-all.");
7974
8092
  mask = this.maskFromSelection(sel, props);
7975
8093
  if (layer.type === "pixel" && (layer.offset.x || layer.offset.y)) {
7976
- mask = { ...mask, surface: _chunkZOOEX3WTcjs.translateSurface.call(void 0, mask.surface, -layer.offset.x, -layer.offset.y) };
8094
+ mask = { ...mask, surface: _chunkCRMAXIUVcjs.translateSurface.call(void 0, mask.surface, -layer.offset.x, -layer.offset.y) };
7977
8095
  }
7978
8096
  } else {
7979
8097
  const v = from === "reveal-all" ? 255 : 0;
7980
- mask = withMaskProps({ surface: _chunkZOOEX3WTcjs.emptySurface.call(void 0, 1, v), defaultValue: v }, props);
8098
+ mask = withMaskProps({ surface: _chunkCRMAXIUVcjs.emptySurface.call(void 0, 1, v), defaultValue: v }, props);
7981
8099
  }
7982
8100
  const next = setLayerMask(this.state.layers, id, mask);
7983
8101
  this.commitLayers(next, () => {
@@ -8018,11 +8136,11 @@ var ImageEditorController = (_class7 = class {
8018
8136
  let out = surface;
8019
8137
  const b = surface.bounds;
8020
8138
  if (b) {
8021
- const draft = new (0, _chunkZOOEX3WTcjs.SurfaceDraft)(surface);
8022
- for (const t of _chunkZOOEX3WTcjs.tilesInRect.call(void 0, b)) {
8139
+ const draft = new (0, _chunkCRMAXIUVcjs.SurfaceDraft)(surface);
8140
+ for (const t of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, b)) {
8023
8141
  const data = draft.peek(t.tx, t.ty);
8024
8142
  if (!data) continue;
8025
- const r = { x: t.tx * _chunkZOOEX3WTcjs.TILE + layer.offset.x, y: t.ty * _chunkZOOEX3WTcjs.TILE + layer.offset.y, width: _chunkZOOEX3WTcjs.TILE, height: _chunkZOOEX3WTcjs.TILE };
8143
+ const r = { x: t.tx * _chunkCRMAXIUVcjs.TILE + layer.offset.x, y: t.ty * _chunkCRMAXIUVcjs.TILE + layer.offset.y, width: _chunkCRMAXIUVcjs.TILE, height: _chunkCRMAXIUVcjs.TILE };
8026
8144
  const cov = this.compositor.maskCoverage(layer, r, sources);
8027
8145
  if (!cov) continue;
8028
8146
  const d = draft.tile(t.tx, t.ty);
@@ -8033,7 +8151,7 @@ var ImageEditorController = (_class7 = class {
8033
8151
  const next = { ...layer, surface: out };
8034
8152
  delete next.mask;
8035
8153
  delete next.source;
8036
- this.commitLayers(_chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, id, () => next), () => {
8154
+ this.commitLayers(_chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, id, () => next), () => {
8037
8155
  if (this.state.activeLayerId === id) this.state.activeTarget = "pixels";
8038
8156
  });
8039
8157
  }
@@ -8048,12 +8166,12 @@ var ImageEditorController = (_class7 = class {
8048
8166
  const layer = loc.layer;
8049
8167
  if (layer.type !== "pixel") throw new LayerOperationError(`Layer via copy needs a pixel layer; "${id}" is a ${layer.type} layer.`);
8050
8168
  const sel = this.state.selection;
8051
- if (!_optionalChain([sel, 'optionalAccess', _155 => _155.bounds])) throw new LayerOperationError("Nothing is selected; select the pixels to copy first.");
8169
+ if (!_optionalChain([sel, 'optionalAccess', _169 => _169.bounds])) throw new LayerOperationError("Nothing is selected; select the pixels to copy first.");
8052
8170
  if (options.cut) requireUnlocked(layer, "pixels", "cut from it");
8053
8171
  const surface = this.surfaceOf(layer);
8054
8172
  const sb = sel.bounds;
8055
8173
  const src = { x: sb.x - layer.offset.x, y: sb.y - layer.offset.y, width: sb.width, height: sb.height };
8056
- const px = _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, src);
8174
+ const px = _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, src);
8057
8175
  const kept = options.cut ? new Uint8ClampedArray(px) : null;
8058
8176
  for (let y = 0; y < sb.height; y++) {
8059
8177
  for (let x = 0; x < sb.width; x++) {
@@ -8066,18 +8184,18 @@ var ImageEditorController = (_class7 = class {
8066
8184
  const copy = {
8067
8185
  type: "pixel",
8068
8186
  id: newLayerId(),
8069
- name: _optionalChain([options, 'access', _156 => _156.name, 'optionalAccess', _157 => _157.trim, 'call', _158 => _158()]) || `${layer.name || "Layer"} ${options.cut ? "cut" : "copy"}`,
8187
+ name: _optionalChain([options, 'access', _170 => _170.name, 'optionalAccess', _171 => _171.trim, 'call', _172 => _172()]) || `${layer.name || "Layer"} ${options.cut ? "cut" : "copy"}`,
8070
8188
  visible: true,
8071
8189
  opacity: 1,
8072
8190
  blend: "normal",
8073
- surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width: src.width, height: src.height, data: px }, 4, src.x, src.y),
8191
+ surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width: src.width, height: src.height, data: px }, 4, src.x, src.y),
8074
8192
  offset: { ...layer.offset }
8075
8193
  };
8076
- let next = _chunkH543GD6Tcjs.insertLayer.call(void 0, this.state.layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _159 => _159.parent, 'optionalAccess', _160 => _160.id]), () => ( null)), loc.index + 1);
8194
+ let next = _chunkT6H3JDGAcjs.insertLayer.call(void 0, this.state.layers, copy, _nullishCoalesce(_optionalChain([loc, 'access', _173 => _173.parent, 'optionalAccess', _174 => _174.id]), () => ( null)), loc.index + 1);
8077
8195
  if (kept) {
8078
- const cutLayer = { ...layer, surface: _chunkZOOEX3WTcjs.writeRegion.call(void 0, surface, src, kept) };
8196
+ const cutLayer = { ...layer, surface: _chunkCRMAXIUVcjs.writeRegion.call(void 0, surface, src, kept) };
8079
8197
  delete cutLayer.source;
8080
- next = _chunkH543GD6Tcjs.mapLayer.call(void 0, next, id, () => cutLayer);
8198
+ next = _chunkT6H3JDGAcjs.mapLayer.call(void 0, next, id, () => cutLayer);
8081
8199
  }
8082
8200
  this.commitLayers(next, () => {
8083
8201
  this.state.activeLayerId = copy.id;
@@ -8090,29 +8208,78 @@ var ImageEditorController = (_class7 = class {
8090
8208
  const f = normalizeFilter(filter);
8091
8209
  const next = addLayerFilter(this.state.layers, id, f);
8092
8210
  this.commitLayers(next);
8093
- return _nullishCoalesce(_chunkH543GD6Tcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8211
+ return _nullishCoalesce(_chunkT6H3JDGAcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8094
8212
  }
8095
8213
  /** Changes one filter (one undo step, or none with `commitToHistory = false` during a drag). Returns the filters. */
8096
8214
  updateLayerFilter(id, filterId, changes, commitToHistory = true) {
8097
8215
  const next = updateLayerFilter(this.state.layers, id, filterId, changes);
8098
8216
  this.commitLayers(next, void 0, commitToHistory);
8099
- return _nullishCoalesce(_chunkH543GD6Tcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8217
+ return _nullishCoalesce(_chunkT6H3JDGAcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8100
8218
  }
8101
8219
  /** Removes one filter (one undo step). Returns the remaining filters. */
8102
8220
  removeLayerFilter(id, filterId) {
8103
8221
  const next = removeLayerFilter(this.state.layers, id, filterId);
8104
8222
  this.commitLayers(next);
8105
- return _nullishCoalesce(_chunkH543GD6Tcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8223
+ return _nullishCoalesce(_chunkT6H3JDGAcjs.findLayer.call(void 0, next, id).layer.filters, () => ( []));
8224
+ }
8225
+ // --- Layer effects ---
8226
+ /** A layer's effects (an empty, enabled list when it has none). */
8227
+ getLayerEffects(id) {
8228
+ return layerEffectsOf(requireLayer(this.state.layers, id).layer);
8229
+ }
8230
+ /**
8231
+ * Adds an effect of `kind` with Photoshop's defaults and `params` applied (one undo step), at
8232
+ * `index` in the layer's effect list (default the end). Returns the new effect and the effects.
8233
+ */
8234
+ addLayerEffect(id, kind, params = {}, index) {
8235
+ const res = addLayerEffect(this.state.layers, id, kind, params, index);
8236
+ this.commitLayers(res.layers);
8237
+ return { effect: res.effect, effects: this.getLayerEffects(id) };
8238
+ }
8239
+ /** Changes one effect (one undo step, or none with `commitToHistory = false` during a drag). Returns the effects. */
8240
+ updateLayerEffect(id, effectId, changes, commitToHistory = true) {
8241
+ this.commitLayers(updateLayerEffect(this.state.layers, id, effectId, changes), void 0, commitToHistory);
8242
+ return this.getLayerEffects(id);
8243
+ }
8244
+ /** Removes one effect (one undo step). Returns the remaining effects. */
8245
+ removeLayerEffect(id, effectId) {
8246
+ this.commitLayers(removeLayerEffect(this.state.layers, id, effectId));
8247
+ return this.getLayerEffects(id);
8248
+ }
8249
+ /** Turns a layer's effects on or off as a whole and, when given, sets Scale Effects (one undo step). */
8250
+ setLayerEffectsEnabled(id, enabled, scale, commitToHistory = true) {
8251
+ this.commitLayers(setLayerEffectsEnabled(this.state.layers, id, enabled, scale), void 0, commitToHistory);
8252
+ return this.getLayerEffects(id);
8253
+ }
8254
+ /** Replaces a layer's effects (one undo step; `null` removes them). Returns the effects. */
8255
+ setLayerEffects(id, effects, commitToHistory = true) {
8256
+ this.commitLayers(setLayerEffects(this.state.layers, id, effects), void 0, commitToHistory);
8257
+ return this.getLayerEffects(id);
8258
+ }
8259
+ /** The light effects with "use global light" follow. */
8260
+ getGlobalLight() {
8261
+ return { ..._nullishCoalesce(this.state.globalLight, () => ( _chunkT6H3JDGAcjs.DEFAULT_GLOBAL_LIGHT)) };
8262
+ }
8263
+ /** Sets the global light (one undo step). `angle` -360..360°, `altitude` 0..90°. Returns it. */
8264
+ setGlobalLight(light, commitToHistory = true) {
8265
+ const next = { ...this.getGlobalLight(), ...light };
8266
+ 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}.`);
8267
+ 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}.`);
8268
+ if (commitToHistory) this.recordHistory();
8269
+ if (next.angle === _chunkT6H3JDGAcjs.DEFAULT_GLOBAL_LIGHT.angle && next.altitude === _chunkT6H3JDGAcjs.DEFAULT_GLOBAL_LIGHT.altitude) delete this.state.globalLight;
8270
+ else this.state.globalLight = next;
8271
+ this.notify();
8272
+ return this.getGlobalLight();
8106
8273
  }
8107
8274
  /** Composites `layers` (in isolation) over `rect` into a surface, loading depth maps first. */
8108
8275
  async compositeToSurface(layers, rect) {
8109
8276
  const { width, height } = this.naturalSize;
8110
- if (_chunkH543GD6Tcjs.flattenLayers.call(void 0, layers).some((l) => l.type === "annotation" && l.visible) && !this.renderer.canRasterize()) {
8277
+ if (_chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers).some((l) => l.type === "annotation" && l.visible) && !this.renderer.canRasterize()) {
8111
8278
  throw new LayerOperationError("Merging annotation layers needs a canvas (a browser); hide or delete them first, or merge in the browser.");
8112
8279
  }
8113
8280
  await this.renderer.prepareLayerAssets(layers, width, height);
8114
8281
  const data = new LayerCompositor().composite(layers, rect, this.renderer.compositorSources(width, height));
8115
- return _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data }, 4, rect.x, rect.y);
8282
+ return _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data }, 4, rect.x, rect.y);
8116
8283
  }
8117
8284
  /** Document bounds a layer can paint into (pixel content, annotations, or the canvas for the rest). */
8118
8285
  paintBounds(layer) {
@@ -8133,7 +8300,8 @@ var ImageEditorController = (_class7 = class {
8133
8300
  }
8134
8301
  /**
8135
8302
  * Merge Down: composites a layer onto the pixel layer directly below it (which keeps its name,
8136
- * opacity and blend; masks, fill and filters are baked), as one undo step. Returns the merged id.
8303
+ * opacity and blend; masks, fill, filters and both layers' effects are baked), as one undo step.
8304
+ * Returns the merged id.
8137
8305
  */
8138
8306
  async mergeDown(id) {
8139
8307
  const loc = requireLayer(this.state.layers, id);
@@ -8145,7 +8313,9 @@ var ImageEditorController = (_class7 = class {
8145
8313
  if (!upper.visible) throw new LayerOperationError(`Layer "${upper.name || id}" is hidden; show it or delete it instead of merging.`);
8146
8314
  requireUnlocked(upper, "all", "merge it");
8147
8315
  requireUnlocked(lower, "pixels", "merge into it");
8148
- const rect = _nullishCoalesce(unionRect(this.paintBounds(lower), upper.type === "adjustment" ? null : this.paintBounds(upper)), () => ( { x: 0, y: 0, width: 1, height: 1 }));
8316
+ let rect = _nullishCoalesce(unionRect(this.paintBounds(lower), upper.type === "adjustment" ? null : this.paintBounds(upper)), () => ( { x: 0, y: 0, width: 1, height: 1 }));
8317
+ const reach = Math.max(_chunkT6H3JDGAcjs.effectsMargin.call(void 0, lower.effects), upper.type === "adjustment" ? 0 : _chunkT6H3JDGAcjs.effectsMargin.call(void 0, upper.effects));
8318
+ if (reach) rect = { x: rect.x - reach, y: rect.y - reach, width: rect.width + 2 * reach, height: rect.height + 2 * reach };
8149
8319
  const base = { ...lower, blend: "normal", opacity: 1 };
8150
8320
  delete base.clipped;
8151
8321
  const surface = await this.compositeToSurface([base, upper], rect);
@@ -8154,8 +8324,9 @@ var ImageEditorController = (_class7 = class {
8154
8324
  delete merged.fillOpacity;
8155
8325
  delete merged.filters;
8156
8326
  delete merged.source;
8157
- let next = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
8158
- next = _chunkH543GD6Tcjs.mapLayer.call(void 0, next, lower.id, () => merged);
8327
+ delete merged.effects;
8328
+ let next = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
8329
+ next = _chunkT6H3JDGAcjs.mapLayer.call(void 0, next, lower.id, () => merged);
8159
8330
  this.commitLayers(next, () => {
8160
8331
  this.state.activeLayerId = merged.id;
8161
8332
  this.state.activeTarget = "pixels";
@@ -8212,7 +8383,7 @@ var ImageEditorController = (_class7 = class {
8212
8383
  });
8213
8384
  return bg.id;
8214
8385
  }
8215
- __init47() {this.thumbCache = /* @__PURE__ */ new WeakMap()}
8386
+ __init49() {this.thumbCache = /* @__PURE__ */ new WeakMap()}
8216
8387
  /**
8217
8388
  * A small RGBA preview of a pixel layer over the canvas (or of its mask with `mask: true`),
8218
8389
  * longest side `maxSide` px, point-sampled; `null` for layers without pixels.
@@ -8231,14 +8402,14 @@ var ImageEditorController = (_class7 = class {
8231
8402
  const oy = layer.type === "pixel" ? layer.offset.y : 0;
8232
8403
  const key = `${tw}x${th}:${ox},${oy}`;
8233
8404
  let byKey = this.thumbCache.get(surface);
8234
- const hit = _optionalChain([byKey, 'optionalAccess', _161 => _161.get, 'call', _162 => _162(key)]);
8405
+ const hit = _optionalChain([byKey, 'optionalAccess', _175 => _175.get, 'call', _176 => _176(key)]);
8235
8406
  if (hit) return hit;
8236
8407
  const out = new Uint8ClampedArray(tw * th * 4);
8237
8408
  for (let y = 0; y < th; y++) {
8238
8409
  const dy = Math.min(height - 1, Math.floor((y + 0.5) * height / th)) - oy;
8239
8410
  for (let x = 0; x < tw; x++) {
8240
8411
  const dx = Math.min(width - 1, Math.floor((x + 0.5) * width / tw)) - ox;
8241
- const v = _chunkZOOEX3WTcjs.readPixel.call(void 0, surface, dx, dy);
8412
+ const v = _chunkCRMAXIUVcjs.readPixel.call(void 0, surface, dx, dy);
8242
8413
  const i = (y * tw + x) * 4;
8243
8414
  if (surface.channels === 1) {
8244
8415
  out[i] = out[i + 1] = out[i + 2] = v[0];
@@ -8259,14 +8430,40 @@ var ImageEditorController = (_class7 = class {
8259
8430
  setPaintOptions(options) {
8260
8431
  const cur = this.state.paint;
8261
8432
  const next = {
8262
- brush: options.brush ? _chunk4F3YDIWWcjs.normalizeBrush.call(void 0, { ...cur.brush, ...options.brush }) : cur.brush,
8433
+ brush: options.brush ? _chunkZZOTHJ4Kcjs.normalizeBrush.call(void 0, { ...cur.brush, ...options.brush }) : cur.brush,
8263
8434
  foreground: options.foreground !== void 0 ? toHex2(parseColor(options.foreground)) : cur.foreground,
8264
- background: options.background !== void 0 ? toHex2(parseColor(options.background)) : cur.background
8435
+ background: options.background !== void 0 ? toHex2(parseColor(options.background)) : cur.background,
8436
+ mixer: options.mixer ? _chunkZZOTHJ4Kcjs.normalizeMixer.call(void 0, { ...cur.mixer, ...options.mixer }) : cur.mixer,
8437
+ mixerLoad: cur.mixerLoad
8265
8438
  };
8266
8439
  this.state.paint = next;
8267
8440
  this.notify();
8268
8441
  return next;
8269
8442
  }
8443
+ /**
8444
+ * Loads the Mixer Brush's reservoir full with `color` (default the foreground); the picked-up
8445
+ * colour is kept. View state, no undo. Returns the brush load.
8446
+ */
8447
+ loadMixerBrush(color) {
8448
+ const c = parseColor(_nullishCoalesce(color, () => ( this.state.paint.foreground)));
8449
+ const load = _chunkZZOTHJ4Kcjs.loadMixer.call(void 0, this.state.paint.mixerLoad, [c[0] / 255, c[1] / 255, c[2] / 255]);
8450
+ this.state.paint = { ...this.state.paint, mixerLoad: load };
8451
+ this.notify();
8452
+ return load;
8453
+ }
8454
+ /** Cleans the Mixer Brush: empties the pickup well (the reservoir is kept). Returns the brush load. */
8455
+ cleanMixerBrush() {
8456
+ const load = _chunkZZOTHJ4Kcjs.cleanMixer.call(void 0, this.state.paint.mixerLoad);
8457
+ this.state.paint = { ...this.state.paint, mixerLoad: load };
8458
+ this.notify();
8459
+ return load;
8460
+ }
8461
+ /** Empties the Mixer Brush entirely (no reservoir, nothing picked up). Returns the brush load. */
8462
+ emptyMixerBrush() {
8463
+ this.state.paint = { ...this.state.paint, mixerLoad: _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD };
8464
+ this.notify();
8465
+ return _chunkZZOTHJ4Kcjs.EMPTY_MIXER_LOAD;
8466
+ }
8270
8467
  /** D: black foreground, white background. */
8271
8468
  resetPaintColors() {
8272
8469
  this.setPaintOptions({ foreground: "#000000", background: "#ffffff" });
@@ -8293,7 +8490,7 @@ var ImageEditorController = (_class7 = class {
8293
8490
  if (!layer.visible) throw new LayerOperationError(`Layer "${layer.name || id}" is hidden; show it before you ${action}.`);
8294
8491
  const offset = layer.type === "pixel" ? layer.offset : { x: 0, y: 0 };
8295
8492
  const surface = ch === "mask" ? layer.mask.surface : this.surfaceOf(layer);
8296
- const lockTransparency = ch === "pixels" && Boolean(_optionalChain([layer, 'access', _163 => _163.locks, 'optionalAccess', _164 => _164.transparency]));
8493
+ const lockTransparency = ch === "pixels" && Boolean(_optionalChain([layer, 'access', _177 => _177.locks, 'optionalAccess', _178 => _178.transparency]));
8297
8494
  return { id, layer, channel: ch, offset, surface, lockTransparency };
8298
8495
  }
8299
8496
  /** The layer with its pixels (or mask) replaced by `surface`. */
@@ -8311,8 +8508,12 @@ var ImageEditorController = (_class7 = class {
8311
8508
  */
8312
8509
  beginStroke(init = {}) {
8313
8510
  const tool = _nullishCoalesce(init.tool, () => ( "brush"));
8511
+ if (tool !== "brush" && tool !== "eraser" && tool !== "mixer") throw new LayerOperationError(`Unknown paint tool "${String(tool)}"; use brush, eraser or mixer.`);
8314
8512
  const target = this.paintTarget(init.layerId, init.channel, tool === "eraser" ? "erase" : "paint");
8315
- const brush = _chunk4F3YDIWWcjs.normalizeBrush.call(void 0, { ...this.state.paint.brush, ..._nullishCoalesce(init.brush, () => ( {})) });
8513
+ if (tool === "mixer" && target.channel === "mask") {
8514
+ throw new LayerOperationError("The Mixer Brush paints colour on pixels, not on masks; target pixels (channel pixels), or paint the mask with the brush.");
8515
+ }
8516
+ const brush = _chunkZZOTHJ4Kcjs.normalizeBrush.call(void 0, { ...this.state.paint.brush, ..._nullishCoalesce(init.brush, () => ( {})) });
8316
8517
  const color = parseColor(_nullishCoalesce(init.color, () => ( this.state.paint.foreground)));
8317
8518
  const background = parseColor(_nullishCoalesce(init.background, () => ( this.state.paint.background)));
8318
8519
  const toMaskGrey = (c) => {
@@ -8326,19 +8527,37 @@ var ImageEditorController = (_class7 = class {
8326
8527
  opacity: brush.opacity,
8327
8528
  blend: target.channel === "mask" ? "normal" : brush.blend,
8328
8529
  lockTransparency: target.lockTransparency,
8329
- selection: _optionalChain([this, 'access', _165 => _165.state, 'access', _166 => _166.selection, 'optionalAccess', _167 => _167.bounds]) ? this.state.selection : null,
8530
+ selection: _optionalChain([this, 'access', _179 => _179.state, 'access', _180 => _180.selection, 'optionalAccess', _181 => _181.bounds]) ? this.state.selection : null,
8330
8531
  offset: target.offset
8331
8532
  };
8332
- return new PaintStrokeSession(this, target, new (0, _chunk4F3YDIWWcjs.StrokeCoverage)(brush), apply);
8533
+ if (tool === "mixer") return new PaintStrokeSession(this, target, this.mixerStroke(init, brush), apply);
8534
+ return new PaintStrokeSession(this, target, new (0, _chunkZZOTHJ4Kcjs.StrokeCoverage)(brush), apply);
8535
+ }
8536
+ /** A Mixer Brush stroke's start: the settings, and the load (refilled when asked or set to). */
8537
+ mixerStroke(init, brush) {
8538
+ const settings = _chunkZZOTHJ4Kcjs.normalizeMixer.call(void 0, { ...this.state.paint.mixer, ..._nullishCoalesce(init.mixer, () => ( {})) });
8539
+ let load = this.state.paint.mixerLoad;
8540
+ if (init.color !== void 0 || settings.loadEachStroke) {
8541
+ const c = parseColor(_nullishCoalesce(init.color, () => ( this.state.paint.foreground)));
8542
+ load = _chunkZZOTHJ4Kcjs.loadMixer.call(void 0, load, [c[0] / 255, c[1] / 255, c[2] / 255]);
8543
+ }
8544
+ return {
8545
+ create: (pixels) => new (0, _chunkZZOTHJ4Kcjs.MixerStroke)(brush, settings, load, pixels),
8546
+ end: (after) => {
8547
+ const next = settings.cleanEachStroke ? _chunkZZOTHJ4Kcjs.cleanMixer.call(void 0, after) : after;
8548
+ this.state.paint = { ...this.state.paint, mixerLoad: next };
8549
+ return next;
8550
+ }
8551
+ };
8333
8552
  }
8334
8553
  /** @internal Shows a stroke's live surface (no history). */
8335
8554
  _strokeUpdate(layerId, channel, surface, rects) {
8336
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
8555
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
8337
8556
  this.notify(rects);
8338
8557
  }
8339
8558
  /** @internal Commits a finished stroke as one undo step (`before` is the pre-stroke state). */
8340
8559
  _strokeCommit(before, layerId, channel, surface) {
8341
- if (surface) this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
8560
+ if (surface) this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => this.withSurface(l, channel, surface));
8342
8561
  else this.state.layers = before.layers;
8343
8562
  if (surface && !this.isApplyingHistory) {
8344
8563
  this.undoStack.push(before);
@@ -8354,13 +8573,13 @@ var ImageEditorController = (_class7 = class {
8354
8573
  }
8355
8574
  /**
8356
8575
  * Paints a whole stroke in one call (agents, replays): `points` in document pixels with optional
8357
- * pressure, through the brush or eraser. One undo step. Returns the layer, channel, the changed
8576
+ * pressure, through the brush, eraser or Mixer Brush. One undo step. Returns the layer, channel, the changed
8358
8577
  * document bounds and the number of dabs.
8359
8578
  */
8360
8579
  paintStroke(init) {
8361
8580
  if (!Array.isArray(init.points) || !init.points.length) throw new LayerOperationError("points must hold at least one { x, y } point.");
8362
8581
  for (const p of init.points) {
8363
- if (!Number.isFinite(_optionalChain([p, 'optionalAccess', _168 => _168.x])) || !Number.isFinite(_optionalChain([p, 'optionalAccess', _169 => _169.y]))) throw new LayerOperationError("Every point needs finite x and y (document pixels).");
8582
+ if (!Number.isFinite(_optionalChain([p, 'optionalAccess', _182 => _182.x])) || !Number.isFinite(_optionalChain([p, 'optionalAccess', _183 => _183.y]))) throw new LayerOperationError("Every point needs finite x and y (document pixels).");
8364
8583
  }
8365
8584
  const session = this.beginStroke(init);
8366
8585
  session.push(init.points);
@@ -8388,9 +8607,9 @@ var ImageEditorController = (_class7 = class {
8388
8607
  const opacity = _nullishCoalesce(options.opacity, () => ( 1));
8389
8608
  if (!(opacity >= 0 && opacity <= 1)) throw new LayerOperationError("opacity must be from 0 to 1.");
8390
8609
  const blend = _nullishCoalesce(parseBlend(options.blend), () => ( "normal"));
8391
- const sel = options.useSelection !== false && _optionalChain([this, 'access', _170 => _170.state, 'access', _171 => _171.selection, 'optionalAccess', _172 => _172.bounds]) ? this.state.selection : null;
8392
- const region = _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _173 => _173.bounds]), () => ( { x: 0, y: 0, width, height }));
8393
- const coverage = new (0, _chunk4F3YDIWWcjs.CoverageMap)();
8610
+ const sel = options.useSelection !== false && _optionalChain([this, 'access', _184 => _184.state, 'access', _185 => _185.selection, 'optionalAccess', _186 => _186.bounds]) ? this.state.selection : null;
8611
+ const region = _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _187 => _187.bounds]), () => ( { x: 0, y: 0, width, height }));
8612
+ const coverage = new (0, _chunkZZOTHJ4Kcjs.CoverageMap)();
8394
8613
  const ones = new Float32Array(region.width * region.height);
8395
8614
  if (sel) {
8396
8615
  for (let y = 0; y < region.height; y++) {
@@ -8415,7 +8634,7 @@ var ImageEditorController = (_class7 = class {
8415
8634
  offset: target.offset
8416
8635
  };
8417
8636
  const surface = paintCoverageInto(target.surface, coverage, apply, [region]);
8418
- const next = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => this.withSurface(l, target.channel, surface));
8637
+ const next = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => this.withSurface(l, target.channel, surface));
8419
8638
  this.commitLayers(next);
8420
8639
  return { layerId: target.id, channel: target.channel, bounds: region, dabs: 0 };
8421
8640
  }
@@ -8437,12 +8656,12 @@ var ImageEditorController = (_class7 = class {
8437
8656
  const target = this.developLayer();
8438
8657
  let layers = this.state.layers;
8439
8658
  if (target && (DEVELOP_KEYS.some((k) => k in partial) || "process" in partial)) {
8440
- layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, target.id, (l) => withDevelop(l, partial));
8659
+ layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, target.id, (l) => withDevelop(l, partial));
8441
8660
  }
8442
8661
  if ("blur" in partial && typeof partial.blur === "number") {
8443
8662
  const blur = Math.max(0, partial.blur);
8444
8663
  if (this.state.legacyOutputBlur !== void 0) this.state.legacyOutputBlur = blur;
8445
- else if (target) layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, target.id, (l) => withBlur(l, blur));
8664
+ else if (target) layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, target.id, (l) => withBlur(l, blur));
8446
8665
  }
8447
8666
  if ("opacity" in partial && typeof partial.opacity === "number") {
8448
8667
  this.state.outputOpacity = Math.min(1, Math.max(0, partial.opacity));
@@ -8472,7 +8691,7 @@ var ImageEditorController = (_class7 = class {
8472
8691
  this.recordHistory();
8473
8692
  const target = this.developLayer();
8474
8693
  if (target) {
8475
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0,
8694
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0,
8476
8695
  this.state.layers,
8477
8696
  target.id,
8478
8697
  (l) => withBlur(withDevelop(l, { ...DEFAULT_ADJUSTMENTS, process: LATEST_PROCESS_VERSION }), 0)
@@ -8492,7 +8711,7 @@ var ImageEditorController = (_class7 = class {
8492
8711
  return this.getAdjustmentLayers().find((l) => l.id === id);
8493
8712
  }
8494
8713
  adjustmentNodes(layers = this.state.layers) {
8495
- return _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "adjustment");
8714
+ return _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers).filter((l) => l.type === "adjustment");
8496
8715
  }
8497
8716
  /**
8498
8717
  * Where a new layer goes when no position is given: directly above the topmost layer that is
@@ -8506,26 +8725,26 @@ var ImageEditorController = (_class7 = class {
8506
8725
  /** Inserts `node` by `aboveId` / `parentId` / adjustment index / default position. */
8507
8726
  placeLayer(layers, node, where) {
8508
8727
  if (where.aboveId) {
8509
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, layers, where.aboveId);
8510
- if (loc) return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _174 => _174.parent, 'optionalAccess', _175 => _175.id]), () => ( null)), loc.index + 1);
8728
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, layers, where.aboveId);
8729
+ if (loc) return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _188 => _188.parent, 'optionalAccess', _189 => _189.id]), () => ( null)), loc.index + 1);
8511
8730
  }
8512
8731
  if (where.parentId) {
8513
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, layers, where.parentId);
8514
- if (loc && loc.layer.type === "group") return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, node, loc.layer.id);
8732
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, layers, where.parentId);
8733
+ if (loc && loc.layer.type === "group") return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, node, loc.layer.id);
8515
8734
  }
8516
8735
  if (where.adjustmentIndex !== void 0) {
8517
8736
  const nodes = this.adjustmentNodes(layers);
8518
8737
  const at = Math.max(0, Math.min(nodes.length, Math.round(where.adjustmentIndex)));
8519
8738
  if (at < nodes.length) {
8520
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, layers, nodes[at].id);
8521
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _176 => _176.parent, 'optionalAccess', _177 => _177.id]), () => ( null)), loc.index);
8739
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, layers, nodes[at].id);
8740
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _190 => _190.parent, 'optionalAccess', _191 => _191.id]), () => ( null)), loc.index);
8522
8741
  }
8523
8742
  if (nodes.length) {
8524
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, layers, nodes[nodes.length - 1].id);
8525
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _178 => _178.parent, 'optionalAccess', _179 => _179.id]), () => ( null)), loc.index + 1);
8743
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, layers, nodes[nodes.length - 1].id);
8744
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, node, _nullishCoalesce(_optionalChain([loc, 'access', _192 => _192.parent, 'optionalAccess', _193 => _193.id]), () => ( null)), loc.index + 1);
8526
8745
  }
8527
8746
  }
8528
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, layers, node, null, this.defaultInsertIndex(layers));
8747
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, layers, node, null, this.defaultInsertIndex(layers));
8529
8748
  }
8530
8749
  /** `setAdjustments({ layers })`: updates nodes by id in place, removes missing ones, adds new ones. */
8531
8750
  replaceAdjustmentNodes(layers, next) {
@@ -8534,7 +8753,7 @@ var ImageEditorController = (_class7 = class {
8534
8753
  let out = layers;
8535
8754
  for (const node of this.adjustmentNodes(layers)) {
8536
8755
  const update = byId.get(node.id);
8537
- out = _chunkH543GD6Tcjs.mapLayer.call(void 0, out, node.id, () => update ? mergeAdjustmentNode(node, update, width, height) : null);
8756
+ out = _chunkT6H3JDGAcjs.mapLayer.call(void 0, out, node.id, () => update ? mergeAdjustmentNode(node, update, width, height) : null);
8538
8757
  }
8539
8758
  const existing = new Set(this.adjustmentNodes(out).map((n) => n.id));
8540
8759
  for (const l of next) {
@@ -8553,7 +8772,7 @@ var ImageEditorController = (_class7 = class {
8553
8772
  */
8554
8773
  addAdjustmentLayer(init, index) {
8555
8774
  const spec = typeof init === "string" ? { kind: init } : init;
8556
- const ids = new Set(_chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
8775
+ const ids = new Set(_chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
8557
8776
  const layer = createAdjustmentLayer(spec.kind, {
8558
8777
  id: spec.id && !ids.has(spec.id) ? spec.id : void 0,
8559
8778
  name: spec.name,
@@ -8582,7 +8801,7 @@ var ImageEditorController = (_class7 = class {
8582
8801
  * Returns false for an unknown id.
8583
8802
  */
8584
8803
  updateAdjustmentLayer(id, update, commitToHistory = true) {
8585
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, this.state.layers, id);
8804
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, this.state.layers, id);
8586
8805
  if (!loc || loc.layer.type !== "adjustment") return false;
8587
8806
  const { width, height } = this.naturalSize;
8588
8807
  const node = loc.layer;
@@ -8610,16 +8829,16 @@ var ImageEditorController = (_class7 = class {
8610
8829
  if (mask) next.mask = mask;
8611
8830
  else delete next.mask;
8612
8831
  }
8613
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, id, () => next);
8832
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, id, () => next);
8614
8833
  this.notify();
8615
8834
  return true;
8616
8835
  }
8617
8836
  /** Removes a layer as one undo step. Returns false for an unknown id. */
8618
8837
  removeAdjustmentLayer(id) {
8619
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, this.state.layers, id);
8838
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, this.state.layers, id);
8620
8839
  if (!loc || loc.layer.type !== "adjustment") return false;
8621
8840
  this.recordHistory();
8622
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
8841
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, id, () => null);
8623
8842
  if (this.state.activeLayerId === id) this.state.activeLayerId = null;
8624
8843
  this.notify();
8625
8844
  return true;
@@ -8632,9 +8851,9 @@ var ImageEditorController = (_class7 = class {
8632
8851
  if (to === from) return layers;
8633
8852
  const node = nodes[from];
8634
8853
  const anchor = nodes[to];
8635
- const without = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, id, () => null);
8636
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, without, anchor.id);
8637
- return _chunkH543GD6Tcjs.insertLayer.call(void 0, without, node, _nullishCoalesce(_optionalChain([loc, 'access', _180 => _180.parent, 'optionalAccess', _181 => _181.id]), () => ( null)), to > from ? loc.index + 1 : loc.index);
8854
+ const without = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, id, () => null);
8855
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, without, anchor.id);
8856
+ return _chunkT6H3JDGAcjs.insertLayer.call(void 0, without, node, _nullishCoalesce(_optionalChain([loc, 'access', _194 => _194.parent, 'optionalAccess', _195 => _195.id]), () => ( null)), to > from ? loc.index + 1 : loc.index);
8638
8857
  }
8639
8858
  /** Moves a layer to `toIndex` among the adjustment layers (0 = bottom) as one undo step. Returns false if nothing moved. */
8640
8859
  moveAdjustmentLayer(id, toIndex) {
@@ -8659,7 +8878,7 @@ var ImageEditorController = (_class7 = class {
8659
8878
  if (!nodes.length) return;
8660
8879
  this.recordHistory();
8661
8880
  let layers = this.state.layers;
8662
- for (const n of nodes) layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, n.id, () => null);
8881
+ for (const n of nodes) layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, n.id, () => null);
8663
8882
  this.state.layers = layers;
8664
8883
  if (nodes.some((n) => n.id === this.state.activeLayerId)) this.state.activeLayerId = null;
8665
8884
  this.notify();
@@ -8670,7 +8889,7 @@ var ImageEditorController = (_class7 = class {
8670
8889
  return _nullishCoalesce(this.state.selection, () => ( null));
8671
8890
  }
8672
8891
  get hasSelection() {
8673
- return Boolean(_optionalChain([this, 'access', _182 => _182.state, 'access', _183 => _183.selection, 'optionalAccess', _184 => _184.bounds]));
8892
+ return Boolean(_optionalChain([this, 'access', _196 => _196.state, 'access', _197 => _197.selection, 'optionalAccess', _198 => _198.bounds]));
8674
8893
  }
8675
8894
  get naturalSize() {
8676
8895
  return {
@@ -8760,13 +8979,13 @@ var ImageEditorController = (_class7 = class {
8760
8979
  try {
8761
8980
  const canvas = await this.renderSource();
8762
8981
  const ctx = canvas.getContext("2d");
8763
- const data2 = _optionalChain([ctx, 'optionalAccess', _185 => _185.getImageData, 'optionalCall', _186 => _186(0, 0, width, height)]);
8982
+ const data2 = _optionalChain([ctx, 'optionalAccess', _199 => _199.getImageData, 'optionalCall', _200 => _200(0, 0, width, height)]);
8764
8983
  if (data2 && data2.data && data2.data.length >= width * height * 4) {
8765
8984
  base = { width, height, data: data2.data };
8766
8985
  this.samplePixels = base;
8767
8986
  this.samplePixelsOverride = false;
8768
8987
  }
8769
- } catch (e22) {
8988
+ } catch (e23) {
8770
8989
  base = null;
8771
8990
  }
8772
8991
  }
@@ -8781,8 +9000,8 @@ var ImageEditorController = (_class7 = class {
8781
9000
  if (!layer || layer.type !== "pixel") {
8782
9001
  throw new LayerOperationError("Sampling the active layer needs an active pixel layer; select one, or sample the composite.");
8783
9002
  }
8784
- const surface = layer.source === "document" && options.pixels ? _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, options.pixels, 4) : this.surfaceOf(layer);
8785
- return { width, height, data: _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, { x: -layer.offset.x, y: -layer.offset.y, width, height }) };
9003
+ const surface = layer.source === "document" && options.pixels ? _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, options.pixels, 4) : this.surfaceOf(layer);
9004
+ return { width, height, data: _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, { x: -layer.offset.x, y: -layer.offset.y, width, height }) };
8786
9005
  }
8787
9006
  if (legacy && !options.sampleMerged) return base;
8788
9007
  this.syncViews();
@@ -8795,7 +9014,7 @@ var ImageEditorController = (_class7 = class {
8795
9014
  const sources = {
8796
9015
  width,
8797
9016
  height,
8798
- surfaceOf: (l) => l.source === "document" && pixels ? _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, pixels, 4) : this.surfaceOf(l),
9017
+ surfaceOf: (l) => l.source === "document" && pixels ? _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, pixels, 4) : this.surfaceOf(l),
8799
9018
  version: pixels ? "pixels" : this.sourceVersion()
8800
9019
  };
8801
9020
  const stack = withoutAnnotations(this.state.layers);
@@ -8826,7 +9045,7 @@ var ImageEditorController = (_class7 = class {
8826
9045
  /** Select › Modify: grow, shrink, feather, border or smooth by `radius` pixels (one undo step). */
8827
9046
  modifySelection(op, radius) {
8828
9047
  const sel = this.state.selection;
8829
- if (!_optionalChain([sel, 'optionalAccess', _187 => _187.bounds])) return false;
9048
+ if (!_optionalChain([sel, 'optionalAccess', _201 => _201.bounds])) return false;
8830
9049
  return this.setSelection(modifySelection(sel, op, radius));
8831
9050
  }
8832
9051
  /**
@@ -8835,7 +9054,7 @@ var ImageEditorController = (_class7 = class {
8835
9054
  */
8836
9055
  async refineSelection(params, options = {}) {
8837
9056
  const sel = this.state.selection;
8838
- if (!_optionalChain([sel, 'optionalAccess', _188 => _188.bounds])) return false;
9057
+ if (!_optionalChain([sel, 'optionalAccess', _202 => _202.bounds])) return false;
8839
9058
  const pixels = (_nullishCoalesce(params.radius, () => ( 0))) > 0 ? await this.requirePixels(options) : null;
8840
9059
  return this.setSelection(refineSelection(pixels, sel, params));
8841
9060
  }
@@ -8852,7 +9071,7 @@ var ImageEditorController = (_class7 = class {
8852
9071
  const canvas = this.renderer.createCanvas(w, h);
8853
9072
  const ctx = canvas.getContext("2d");
8854
9073
  if (ctx) ctx.drawImage(img, 0, 0, w, h);
8855
- const data = _optionalChain([ctx, 'optionalAccess', _189 => _189.getImageData, 'optionalCall', _190 => _190(0, 0, w, h)]);
9074
+ const data = _optionalChain([ctx, 'optionalAccess', _203 => _203.getImageData, 'optionalCall', _204 => _204(0, 0, w, h)]);
8856
9075
  if (!data) throw new Error("The mask image pixels are not available (no canvas access); pass pixels.");
8857
9076
  pixels = { width: w, height: h, data: data.data };
8858
9077
  } else {
@@ -8871,7 +9090,7 @@ var ImageEditorController = (_class7 = class {
8871
9090
  maskFromSelection(sel, props = {}) {
8872
9091
  const { width, height } = this.naturalSize;
8873
9092
  const sized = sel.width === width && sel.height === height ? sel : resizeSelection(sel, width, height);
8874
- const mask = { surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0), defaultValue: 0 };
9093
+ const mask = { surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: sized.data }, 1, 0, 0, 0), defaultValue: 0 };
8875
9094
  return withMaskProps(mask, props);
8876
9095
  }
8877
9096
  /**
@@ -8880,14 +9099,14 @@ var ImageEditorController = (_class7 = class {
8880
9099
  */
8881
9100
  applySelectionAsLayerMask(layerId, props = {}) {
8882
9101
  const sel = this.state.selection;
8883
- if (!_optionalChain([sel, 'optionalAccess', _191 => _191.bounds]) || !this.getAdjustmentLayer(layerId)) return false;
9102
+ if (!_optionalChain([sel, 'optionalAccess', _205 => _205.bounds]) || !this.getAdjustmentLayer(layerId)) return false;
8884
9103
  return this.setLayerMask(layerId, this.maskFromSelection(sel, props));
8885
9104
  }
8886
9105
  setLayerMask(layerId, mask, commitToHistory = true) {
8887
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, this.state.layers, layerId);
9106
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, this.state.layers, layerId);
8888
9107
  if (!loc) return false;
8889
9108
  if (commitToHistory) this.recordHistory();
8890
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => {
9109
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, layerId, (l) => {
8891
9110
  const next = { ...l };
8892
9111
  if (mask) next.mask = mask;
8893
9112
  else delete next.mask;
@@ -8911,11 +9130,11 @@ var ImageEditorController = (_class7 = class {
8911
9130
  /** Load Selection from a layer mask (its pixels; density and feather are not applied). */
8912
9131
  selectionFromLayerMask(layerId, mode = "replace") {
8913
9132
  const layer = this.getLayer(layerId);
8914
- if (!_optionalChain([layer, 'optionalAccess', _192 => _192.mask]) || layer.mask.source) return false;
9133
+ if (!_optionalChain([layer, 'optionalAccess', _206 => _206.mask]) || layer.mask.source) return false;
8915
9134
  const { width, height } = this.naturalSize;
8916
9135
  const ox = layer.type === "pixel" ? layer.offset.x : 0;
8917
9136
  const oy = layer.type === "pixel" ? layer.offset.y : 0;
8918
- const data = _chunkZOOEX3WTcjs.readRegion.call(void 0, layer.mask.surface, { x: -ox, y: -oy, width, height });
9137
+ const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, layer.mask.surface, { x: -ox, y: -oy, width, height });
8919
9138
  const sel = createSelectionMask(width, height, new Uint8Array(data.buffer, data.byteOffset, data.length));
8920
9139
  return this.setSelection(sel, mode);
8921
9140
  }
@@ -8944,10 +9163,10 @@ var ImageEditorController = (_class7 = class {
8944
9163
  if (target) {
8945
9164
  const merged = { ...this.state.depthMask, ...partial };
8946
9165
  merged.depthRange = [...merged.depthRange];
8947
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
9166
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
8948
9167
  const next = { ...l };
8949
9168
  if (isDefaultDepthMask(merged)) {
8950
- if (_optionalChain([next, 'access', _193 => _193.mask, 'optionalAccess', _194 => _194.source])) delete next.mask;
9169
+ if (_optionalChain([next, 'access', _207 => _207.mask, 'optionalAccess', _208 => _208.source])) delete next.mask;
8951
9170
  } else next.mask = depthRasterMask(merged);
8952
9171
  return next;
8953
9172
  });
@@ -8957,8 +9176,8 @@ var ImageEditorController = (_class7 = class {
8957
9176
  resetDepthMask() {
8958
9177
  this.recordHistory();
8959
9178
  const target = this.developLayer();
8960
- if (_optionalChain([target, 'optionalAccess', _195 => _195.mask, 'optionalAccess', _196 => _196.source])) {
8961
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
9179
+ if (_optionalChain([target, 'optionalAccess', _209 => _209.mask, 'optionalAccess', _210 => _210.source])) {
9180
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, target.id, (l) => {
8962
9181
  const next = { ...l };
8963
9182
  delete next.mask;
8964
9183
  return next;
@@ -8968,7 +9187,7 @@ var ImageEditorController = (_class7 = class {
8968
9187
  }
8969
9188
  // --- Annotations & Layers ---
8970
9189
  annotationLayer(id) {
8971
- return _chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).find(
9190
+ return _chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).find(
8972
9191
  (l) => l.type === "annotation" && l.annotation.id === id
8973
9192
  );
8974
9193
  }
@@ -8978,8 +9197,8 @@ var ImageEditorController = (_class7 = class {
8978
9197
  const id = `ann_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
8979
9198
  const fullAnnotation = { ...annotation, id };
8980
9199
  const layer = annotationLayerFor(fullAnnotation);
8981
- const loc = placement.aboveId ? _chunkH543GD6Tcjs.findLayer.call(void 0, this.state.layers, placement.aboveId) : null;
8982
- this.state.layers = loc ? _chunkH543GD6Tcjs.insertLayer.call(void 0, this.state.layers, layer, _nullishCoalesce(_optionalChain([loc, 'access', _197 => _197.parent, 'optionalAccess', _198 => _198.id]), () => ( null)), loc.index + 1) : _chunkH543GD6Tcjs.insertLayer.call(void 0, this.state.layers, layer, null);
9200
+ const loc = placement.aboveId ? _chunkT6H3JDGAcjs.findLayer.call(void 0, this.state.layers, placement.aboveId) : null;
9201
+ this.state.layers = loc ? _chunkT6H3JDGAcjs.insertLayer.call(void 0, this.state.layers, layer, _nullishCoalesce(_optionalChain([loc, 'access', _211 => _211.parent, 'optionalAccess', _212 => _212.id]), () => ( null)), loc.index + 1) : _chunkT6H3JDGAcjs.insertLayer.call(void 0, this.state.layers, layer, null);
8983
9202
  this.state.selectedAnnotationId = id;
8984
9203
  this.notify();
8985
9204
  return id;
@@ -8992,14 +9211,14 @@ var ImageEditorController = (_class7 = class {
8992
9211
  if (layer) {
8993
9212
  const annotation = { ...layer.annotation, ...partial, id };
8994
9213
  const name = layer.name === annotationLayerName(layer.annotation) ? annotationLayerName(annotation) : layer.name;
8995
- this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => ({ ...layer, annotation, name }));
9214
+ this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => ({ ...layer, annotation, name }));
8996
9215
  }
8997
9216
  this.notify();
8998
9217
  }
8999
9218
  removeAnnotation(id) {
9000
9219
  this.recordHistory();
9001
9220
  const layer = this.annotationLayer(id);
9002
- if (layer) this.state.layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => null);
9221
+ if (layer) this.state.layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, layer.id, () => null);
9003
9222
  if (this.state.selectedAnnotationId === id) {
9004
9223
  this.state.selectedAnnotationId = null;
9005
9224
  }
@@ -9008,7 +9227,7 @@ var ImageEditorController = (_class7 = class {
9008
9227
  clearAnnotations() {
9009
9228
  this.recordHistory();
9010
9229
  let layers = this.state.layers;
9011
- for (const l of _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, l.id, () => null);
9230
+ for (const l of _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, l.id, () => null);
9012
9231
  this.state.layers = layers;
9013
9232
  this.state.selectedAnnotationId = null;
9014
9233
  this.notify();
@@ -9048,7 +9267,7 @@ var ImageEditorController = (_class7 = class {
9048
9267
  this.notify();
9049
9268
  }
9050
9269
  // --- Rendering & Export ---
9051
- __init48() {this.blankSource = null}
9270
+ __init50() {this.blankSource = null}
9052
9271
  /**
9053
9272
  * What the renderer draws from: the source image, or, for a document without one (an opened
9054
9273
  * PSD, a v3 document loaded on its own), a transparent canvas of the document size, since every
@@ -9076,7 +9295,7 @@ var ImageEditorController = (_class7 = class {
9076
9295
  dirty: dirty === "all" ? void 0 : dirty,
9077
9296
  checkpointLayerId: this.state.activeLayerId
9078
9297
  });
9079
- } catch (e23) {
9298
+ } catch (e24) {
9080
9299
  }
9081
9300
  }
9082
9301
  async renderExport(options) {
@@ -9085,9 +9304,9 @@ var ImageEditorController = (_class7 = class {
9085
9304
  return this.renderer.createCanvas(1, 1);
9086
9305
  }
9087
9306
  this.syncViews();
9088
- if (_optionalChain([options, 'optionalAccess', _199 => _199.layerIds])) {
9307
+ if (_optionalChain([options, 'optionalAccess', _213 => _213.layerIds])) {
9089
9308
  const keep = new Set(options.layerIds);
9090
- const layers = _chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => keep.has(l.id));
9309
+ const layers = _chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => keep.has(l.id));
9091
9310
  return this.renderer.renderExport(source, { ...this.state, layers }, options);
9092
9311
  }
9093
9312
  return this.renderer.renderExport(source, this.state, options);
@@ -9197,10 +9416,10 @@ var ImageEditorController = (_class7 = class {
9197
9416
  /** No source image, and no layer reading one (an opened PSD): the layers are the whole document. */
9198
9417
  isSourceless() {
9199
9418
  if (this.imageElement || this.state.sourceUrl || !this.state.layers.length) return false;
9200
- return !_chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).some((l) => l.type === "pixel" && l.source === "document");
9419
+ return !_chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).some((l) => l.type === "pixel" && l.source === "document");
9201
9420
  }
9202
9421
  get isMultiLayer() {
9203
- return _chunkH543GD6Tcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => l.type === "pixel" || l.type === "group").length > 1;
9422
+ return _chunkT6H3JDGAcjs.flattenLayers.call(void 0, this.state.layers).filter((l) => l.type === "pixel" || l.type === "group").length > 1;
9204
9423
  }
9205
9424
  /**
9206
9425
  * Applies an inpainted result (natural image space, see `toSourceDataURL`) as ONE undoable step.
@@ -9218,7 +9437,7 @@ var ImageEditorController = (_class7 = class {
9218
9437
  let px = await this.decodeImage(newDataUrl);
9219
9438
  if (px.width !== width || px.height !== height) px = resizePixels(px, width, height);
9220
9439
  const data = new Uint8ClampedArray(px.data);
9221
- const sel = _optionalChain([this, 'access', _200 => _200.state, 'access', _201 => _201.selection, 'optionalAccess', _202 => _202.bounds]) ? this.state.selection : null;
9440
+ const sel = _optionalChain([this, 'access', _214 => _214.state, 'access', _215 => _215.selection, 'optionalAccess', _216 => _216.bounds]) ? this.state.selection : null;
9222
9441
  if (sel) for (let p = 0, i = 3; p < width * height; p++, i += 4) data[i] = Math.round(data[i] * sel.data[p] / 255);
9223
9442
  return this.addPixelLayer({ name: "Inpaint", pixels: { width, height, data } });
9224
9443
  }
@@ -9242,8 +9461,8 @@ var ImageEditorController = (_class7 = class {
9242
9461
  if (px.width !== width || px.height !== height) px = resizePixels(px, width, height);
9243
9462
  const alpha = new Uint8ClampedArray(width * height);
9244
9463
  for (let p = 0; p < alpha.length; p++) alpha[p] = px.data[p * 4 + 3];
9245
- let surface = _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: alpha }, 1, 0, 0, 0);
9246
- if (target.offset.x || target.offset.y) surface = _chunkZOOEX3WTcjs.translateSurface.call(void 0, surface, -target.offset.x, -target.offset.y);
9464
+ let surface = _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: alpha }, 1, 0, 0, 0);
9465
+ if (target.offset.x || target.offset.y) surface = _chunkCRMAXIUVcjs.translateSurface.call(void 0, surface, -target.offset.x, -target.offset.y);
9247
9466
  this.commitLayers(setLayerMask(this.state.layers, target.id, { surface, defaultValue: 0 }));
9248
9467
  return target.id;
9249
9468
  }
@@ -9270,7 +9489,7 @@ var ImageEditorController = (_class7 = class {
9270
9489
  if (layer.locks) next.locks = layer.locks;
9271
9490
  if (this.state.selectedAnnotationId === layer.annotation.id) this.state.selectedAnnotationId = null;
9272
9491
  } else if (layer.type === "pixel") {
9273
- if (!_optionalChain([layer, 'access', _203 => _203.filters, 'optionalAccess', _204 => _204.length])) throw new LayerOperationError(`Layer "${layer.name || id}" is already pixels with no filters to bake.`);
9492
+ if (!_optionalChain([layer, 'access', _217 => _217.filters, 'optionalAccess', _218 => _218.length])) throw new LayerOperationError(`Layer "${layer.name || id}" is already pixels with no filters to bake.`);
9274
9493
  requireUnlocked(layer, "pixels", "rasterize it");
9275
9494
  const spatial = layer.filters.some((f) => f.enabled && f.kind === "blur");
9276
9495
  const content = { ...layer, visible: true, opacity: 1, blend: "normal" };
@@ -9283,12 +9502,12 @@ var ImageEditorController = (_class7 = class {
9283
9502
  delete next.filters;
9284
9503
  delete next.source;
9285
9504
  if (layer.mask && (layer.offset.x || layer.offset.y)) {
9286
- next.mask = { ...layer.mask, surface: _chunkZOOEX3WTcjs.translateSurface.call(void 0, layer.mask.surface, layer.offset.x, layer.offset.y) };
9505
+ next.mask = { ...layer.mask, surface: _chunkCRMAXIUVcjs.translateSurface.call(void 0, layer.mask.surface, layer.offset.x, layer.offset.y) };
9287
9506
  }
9288
9507
  } else {
9289
9508
  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.`);
9290
9509
  }
9291
- this.commitLayers(_chunkH543GD6Tcjs.mapLayer.call(void 0, this.state.layers, id, () => next));
9510
+ this.commitLayers(_chunkT6H3JDGAcjs.mapLayer.call(void 0, this.state.layers, id, () => next));
9292
9511
  return id;
9293
9512
  }
9294
9513
  // --- PSD ---
@@ -9315,14 +9534,14 @@ var ImageEditorController = (_class7 = class {
9315
9534
  delete s.legacyOutputBlur;
9316
9535
  s.selection = null;
9317
9536
  s.selectedAnnotationId = null;
9318
- const pixels = _chunkH543GD6Tcjs.flattenLayers.call(void 0, result.layers).filter((l) => l.type === "pixel");
9537
+ const pixels = _chunkT6H3JDGAcjs.flattenLayers.call(void 0, result.layers).filter((l) => l.type === "pixel");
9319
9538
  s.activeLayerId = pixels.length ? pixels[pixels.length - 1].id : null;
9320
9539
  s.activeTarget = "pixels";
9321
9540
  this.psdResolution = result.resolution;
9322
9541
  this.lastLoadProblems = result.warnings;
9323
9542
  this.notify();
9324
9543
  return {
9325
- layerIds: _chunkH543GD6Tcjs.flattenLayers.call(void 0, result.layers).map((l) => l.id),
9544
+ layerIds: _chunkT6H3JDGAcjs.flattenLayers.call(void 0, result.layers).map((l) => l.id),
9326
9545
  warnings: result.warnings,
9327
9546
  width: result.width,
9328
9547
  height: result.height,
@@ -9347,7 +9566,7 @@ var ImageEditorController = (_class7 = class {
9347
9566
  const compositor = new LayerCompositor();
9348
9567
  const bakeMask = (layer) => {
9349
9568
  const mask = layer.mask;
9350
- if (!_optionalChain([mask, 'optionalAccess', _205 => _205.source])) return mask;
9569
+ if (!_optionalChain([mask, 'optionalAccess', _219 => _219.source])) return mask;
9351
9570
  add("Parametric (depth) masks were baked into pixel masks", layer.name);
9352
9571
  const plain3 = { ...layer, mask: { ...mask, density: 1, feather: 0, enabled: true } };
9353
9572
  const ox = layer.type === "pixel" ? layer.offset.x : 0;
@@ -9356,13 +9575,18 @@ var ImageEditorController = (_class7 = class {
9356
9575
  const bytes = new Uint8ClampedArray(width * height);
9357
9576
  if (coverage) for (let i = 0; i < bytes.length; i++) bytes[i] = Math.round(coverage[i] * 255);
9358
9577
  else bytes.fill(255);
9359
- const baked = { surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data: bytes }, 1, -ox, -oy), defaultValue: 0 };
9578
+ const baked = { surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data: bytes }, 1, -ox, -oy), defaultValue: 0 };
9360
9579
  if (mask.density !== void 0 && mask.density < 1) baked.density = mask.density;
9361
9580
  if (mask.feather) baked.feather = mask.feather;
9362
9581
  if (mask.enabled === false) baked.enabled = false;
9363
9582
  return baked;
9364
9583
  };
9365
9584
  const prepare = async (layer) => {
9585
+ const p = await prepareLayer(layer);
9586
+ if (_optionalChain([p, 'optionalAccess', _220 => _220.blend]) === "pigment") add("The Pigment blend mode has no PSD equivalent and was written as Normal", layer.name);
9587
+ return p;
9588
+ };
9589
+ const prepareLayer = async (layer) => {
9366
9590
  if (layer.type === "group") {
9367
9591
  const children = [];
9368
9592
  for (const c of layer.children) {
@@ -9390,7 +9614,7 @@ var ImageEditorController = (_class7 = class {
9390
9614
  visible: layer.visible,
9391
9615
  opacity: layer.opacity,
9392
9616
  blend,
9393
- surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
9617
+ surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4),
9394
9618
  offset: { x: 0, y: 0 }
9395
9619
  };
9396
9620
  if (layer.clipped) out2.clipped = true;
@@ -9404,7 +9628,7 @@ var ImageEditorController = (_class7 = class {
9404
9628
  out.surface = this.surfaceOf(layer);
9405
9629
  delete out.source;
9406
9630
  }
9407
- const active = _nullishCoalesce(_optionalChain([layer, 'access', _206 => _206.filters, 'optionalAccess', _207 => _207.filter, 'call', _208 => _208(isActiveFilter)]), () => ( []));
9631
+ const active = _nullishCoalesce(_optionalChain([layer, 'access', _221 => _221.filters, 'optionalAccess', _222 => _222.filter, 'call', _223 => _223(isActiveFilter)]), () => ( []));
9408
9632
  if (active.length) {
9409
9633
  add("Layer filters (develop, blur) were baked into the pixels", layer.name);
9410
9634
  const content = { ...out, visible: true, opacity: 1, blend: "normal" };
@@ -9412,9 +9636,9 @@ var ImageEditorController = (_class7 = class {
9412
9636
  delete content.clipped;
9413
9637
  delete content.fillOpacity;
9414
9638
  const data = compositor.composite([content], canvas, sources);
9415
- out = { ...out, surface: _chunkZOOEX3WTcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, -layer.offset.x, -layer.offset.y) };
9639
+ out = { ...out, surface: _chunkCRMAXIUVcjs.surfaceFromPixels.call(void 0, { width, height, data }, 4, -layer.offset.x, -layer.offset.y) };
9416
9640
  }
9417
- if (_optionalChain([layer, 'access', _209 => _209.filters, 'optionalAccess', _210 => _210.some, 'call', _211 => _211((f) => !f.enabled)])) add("Disabled layer filters were left out", layer.name);
9641
+ if (_optionalChain([layer, 'access', _224 => _224.filters, 'optionalAccess', _225 => _225.some, 'call', _226 => _226((f) => !f.enabled)])) add("Disabled layer filters were left out", layer.name);
9418
9642
  delete out.filters;
9419
9643
  const mask = bakeMask(layer);
9420
9644
  if (mask) out.mask = mask;
@@ -9466,16 +9690,16 @@ var ImageEditorController = (_class7 = class {
9466
9690
  );
9467
9691
  }
9468
9692
  layers = resizeLegacyMasks(layers, prev, next.dimensions);
9469
- for (const l of _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers)) {
9693
+ for (const l of _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers)) {
9470
9694
  if (l.type === "annotation") {
9471
- layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, annotation: scaleAnnotation(l.annotation, sx, sy) }));
9695
+ layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, annotation: scaleAnnotation(l.annotation, sx, sy) }));
9472
9696
  }
9473
9697
  }
9474
9698
  }
9475
9699
  const bg = developTarget(layers, null);
9476
- if (bg && bg.source !== "document") layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, bg.id, () => ({ ...bg, source: "document" }));
9700
+ if (bg && bg.source !== "document") layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, bg.id, () => ({ ...bg, source: "document" }));
9477
9701
  if (clearAnnotations) {
9478
- for (const l of _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunkH543GD6Tcjs.mapLayer.call(void 0, layers, l.id, () => null);
9702
+ for (const l of _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers)) if (l.type === "annotation") layers = _chunkT6H3JDGAcjs.mapLayer.call(void 0, layers, l.id, () => null);
9479
9703
  this.state.selectedAnnotationId = null;
9480
9704
  }
9481
9705
  this.state.layers = layers;
@@ -9483,7 +9707,7 @@ var ImageEditorController = (_class7 = class {
9483
9707
  }
9484
9708
  toJSON(options) {
9485
9709
  const out = this.serializeState();
9486
- if (_optionalChain([this, 'access', _212 => _212.state, 'access', _213 => _213.selection, 'optionalAccess', _214 => _214.bounds])) out.selection = serializeSelection(this.state.selection);
9710
+ if (_optionalChain([this, 'access', _227 => _227.state, 'access', _228 => _228.selection, 'optionalAccess', _229 => _229.bounds])) out.selection = serializeSelection(this.state.selection);
9487
9711
  if (!options || out.version !== LAYERED_SCHEMA_VERSION) return options ? Promise.resolve(out) : out;
9488
9712
  return serializeLayersExternal(this.state.layers, options.store).then(({ layers, assets }) => ({ ...out, layers, assets }));
9489
9713
  }
@@ -9510,7 +9734,7 @@ var ImageEditorController = (_class7 = class {
9510
9734
  if (data.selection) {
9511
9735
  try {
9512
9736
  selection = normalizeSelection(deserializeSelection(data.selection));
9513
- } catch (e24) {
9737
+ } catch (e25) {
9514
9738
  selection = null;
9515
9739
  }
9516
9740
  }
@@ -9519,7 +9743,7 @@ var ImageEditorController = (_class7 = class {
9519
9743
  this.notify();
9520
9744
  }
9521
9745
  /** Problems found by the last `loadJSON` / `initialState` of a v3 document (unreadable layers or assets). */
9522
- __init49() {this.lastLoadProblems = []}
9746
+ __init51() {this.lastLoadProblems = []}
9523
9747
  applyStored(raw) {
9524
9748
  const s = this.state;
9525
9749
  const data = migrateSerializedImageEditorState(raw);
@@ -9533,7 +9757,10 @@ var ImageEditorController = (_class7 = class {
9533
9757
  s.outputOpacity = data.opacity;
9534
9758
  if (typeof data.legacyOutputBlur === "number" && data.legacyOutputBlur >= 0) s.legacyOutputBlur = data.legacyOutputBlur;
9535
9759
  else delete s.legacyOutputBlur;
9536
- s.activeLayerId = data.activeLayerId && _chunkH543GD6Tcjs.findLayer.call(void 0, s.layers, data.activeLayerId) ? data.activeLayerId : null;
9760
+ s.activeLayerId = data.activeLayerId && _chunkT6H3JDGAcjs.findLayer.call(void 0, s.layers, data.activeLayerId) ? data.activeLayerId : null;
9761
+ const light = data.globalLight;
9762
+ if (light && Number.isFinite(light.angle) && Number.isFinite(light.altitude)) s.globalLight = { angle: light.angle, altitude: Math.min(90, Math.max(0, light.altitude)) };
9763
+ else delete s.globalLight;
9537
9764
  if (!this.imageElement && typeof data.width === "number" && typeof data.height === "number" && data.width > 0 && data.height > 0) {
9538
9765
  s.imageDimensions = { width: data.width, height: data.height };
9539
9766
  }
@@ -9547,6 +9774,7 @@ var ImageEditorController = (_class7 = class {
9547
9774
  s.crop = data.crop ? { ...data.crop } : null;
9548
9775
  s.transform = { ...data.transform };
9549
9776
  s.activeLayerId = null;
9777
+ delete s.globalLight;
9550
9778
  }
9551
9779
  s.activeTarget = "pixels";
9552
9780
  this.viewKey = [];
@@ -9556,10 +9784,10 @@ var ImageEditorController = (_class7 = class {
9556
9784
  serializeState() {
9557
9785
  const { width, height } = this.naturalSize;
9558
9786
  const view = legacyView(this.stack(), width, height, null);
9559
- if (view.exact) {
9787
+ if (view.exact && !this.state.globalLight) {
9560
9788
  return {
9561
9789
  // States without adjustment layers keep schema 1, so they round-trip unchanged.
9562
- version: _optionalChain([view, 'access', _215 => _215.adjustments, 'access', _216 => _216.layers, 'optionalAccess', _217 => _217.length]) ? 2 : 1,
9790
+ version: _optionalChain([view, 'access', _230 => _230.adjustments, 'access', _231 => _231.layers, 'optionalAccess', _232 => _232.length]) ? 2 : 1,
9563
9791
  crop: this.state.crop ? { ...this.state.crop } : null,
9564
9792
  transform: { ...this.state.transform },
9565
9793
  adjustments: serializeAdjustments(view.adjustments),
@@ -9583,12 +9811,13 @@ var ImageEditorController = (_class7 = class {
9583
9811
  opacity: this.state.outputOpacity
9584
9812
  };
9585
9813
  if (this.state.legacyOutputBlur !== void 0) out.legacyOutputBlur = this.state.legacyOutputBlur;
9814
+ if (this.state.globalLight) out.globalLight = { ...this.state.globalLight };
9586
9815
  return out;
9587
9816
  }
9588
9817
  }, _class7);
9589
9818
  function serializeAdjustments(adjustments) {
9590
9819
  const out = { ...adjustments };
9591
- if (_optionalChain([out, 'access', _218 => _218.layers, 'optionalAccess', _219 => _219.length])) out.layers = JSON.parse(JSON.stringify(out.layers));
9820
+ if (_optionalChain([out, 'access', _233 => _233.layers, 'optionalAccess', _234 => _234.length])) out.layers = JSON.parse(JSON.stringify(out.layers));
9592
9821
  else delete out.layers;
9593
9822
  if (normalizeProcessVersion(out.process) === LEGACY_PROCESS_VERSION) {
9594
9823
  delete out.process;
@@ -9624,11 +9853,11 @@ function withDevelop(layer, partial) {
9624
9853
  return { ...layer, filters };
9625
9854
  }
9626
9855
  function withBlur(layer, radius) {
9627
- const existing = _optionalChain([layer, 'access', _220 => _220.filters, 'optionalAccess', _221 => _221.find, 'call', _222 => _222((f) => f.kind === "blur")]);
9856
+ const existing = _optionalChain([layer, 'access', _235 => _235.filters, 'optionalAccess', _236 => _236.find, 'call', _237 => _237((f) => f.kind === "blur")]);
9628
9857
  const filters = (_nullishCoalesce(layer.filters, () => ( []))).filter((f) => f.kind !== "blur");
9629
9858
  if (radius > 0) {
9630
9859
  filters.push({
9631
- id: _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _223 => _223.id]), () => ( (layer.source === "document" ? BLUR_FILTER_ID : newLayerId("flt")))),
9860
+ id: _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _238 => _238.id]), () => ( (layer.source === "document" ? BLUR_FILTER_ID : newLayerId("flt")))),
9632
9861
  kind: "blur",
9633
9862
  enabled: true,
9634
9863
  radius
@@ -9692,27 +9921,27 @@ function resizeLegacyMasks(layers, from, to) {
9692
9921
  const th = Math.max(1, Math.round(to.height));
9693
9922
  if (fw === tw && fh === th) return layers;
9694
9923
  let out = layers;
9695
- for (const l of _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers)) {
9924
+ for (const l of _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers)) {
9696
9925
  if (l.type !== "adjustment" || !l.mask || l.mask.source) continue;
9697
9926
  const old = l.mask;
9698
9927
  const mask = rasterMaskFromLegacy(legacyMaskOf(old, fw, fh), tw, th);
9699
9928
  if (!mask) continue;
9700
- out = _chunkH543GD6Tcjs.mapLayer.call(void 0, out, l.id, (n) => ({ ...n, mask: { ...mask, density: old.density, feather: old.feather, enabled: old.enabled } }));
9929
+ out = _chunkT6H3JDGAcjs.mapLayer.call(void 0, out, l.id, (n) => ({ ...n, mask: { ...mask, density: old.density, feather: old.feather, enabled: old.enabled } }));
9701
9930
  }
9702
9931
  return out;
9703
9932
  }
9704
9933
  function isOpaqueInside(surface, width, height) {
9705
9934
  const row = new Uint8ClampedArray(width * 4);
9706
9935
  for (let y = 0; y < height; y++) {
9707
- _chunkZOOEX3WTcjs.readRegion.call(void 0, surface, { x: 0, y, width, height: 1 }, row);
9936
+ _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, { x: 0, y, width, height: 1 }, row);
9708
9937
  for (let i = 3; i < row.length; i += 4) if (row[i] !== 255) return false;
9709
9938
  }
9710
9939
  return true;
9711
9940
  }
9712
9941
  function collectStateTiles(layers, into) {
9713
- for (const l of _chunkH543GD6Tcjs.flattenLayers.call(void 0, layers)) {
9714
- if (l.type === "pixel" && l.source !== "document") _chunkZOOEX3WTcjs.collectTiles.call(void 0, l.surface, into);
9715
- if (l.mask && !l.mask.source) _chunkZOOEX3WTcjs.collectTiles.call(void 0, l.mask.surface, into);
9942
+ for (const l of _chunkT6H3JDGAcjs.flattenLayers.call(void 0, layers)) {
9943
+ if (l.type === "pixel" && l.source !== "document") _chunkCRMAXIUVcjs.collectTiles.call(void 0, l.surface, into);
9944
+ if (l.mask && !l.mask.source) _chunkCRMAXIUVcjs.collectTiles.call(void 0, l.mask.surface, into);
9716
9945
  }
9717
9946
  }
9718
9947
  function pixelsOnly(layers) {
@@ -9720,7 +9949,7 @@ function pixelsOnly(layers) {
9720
9949
  for (const l of layers) {
9721
9950
  if (l.type === "adjustment") continue;
9722
9951
  if (l.type === "group") out.push({ ...l, children: pixelsOnly(l.children) });
9723
- else if (l.type === "pixel" && _optionalChain([l, 'access', _224 => _224.filters, 'optionalAccess', _225 => _225.length])) {
9952
+ else if (l.type === "pixel" && _optionalChain([l, 'access', _239 => _239.filters, 'optionalAccess', _240 => _240.length])) {
9724
9953
  const p = { ...l };
9725
9954
  delete p.filters;
9726
9955
  out.push(p);
@@ -9778,7 +10007,7 @@ function toHex2(c) {
9778
10007
  return "#" + [c[0], c[1], c[2]].map((v) => Math.round(v).toString(16).padStart(2, "0")).join("");
9779
10008
  }
9780
10009
  function normalizeSelection(mask) {
9781
- return _optionalChain([mask, 'optionalAccess', _226 => _226.bounds]) ? mask : null;
10010
+ return _optionalChain([mask, 'optionalAccess', _241 => _241.bounds]) ? mask : null;
9782
10011
  }
9783
10012
  function sameSelection(a, b) {
9784
10013
  if (a.width !== b.width || a.height !== b.height) return false;
@@ -9883,7 +10112,7 @@ function loadImageEditorDocument(input) {
9883
10112
  if (typeof input === "string") {
9884
10113
  try {
9885
10114
  parsed = JSON.parse(input);
9886
- } catch (e25) {
10115
+ } catch (e26) {
9887
10116
  parsed = input;
9888
10117
  }
9889
10118
  }
@@ -9939,7 +10168,7 @@ function loadImageEditorDocument(input) {
9939
10168
  }
9940
10169
  const state = { version: 1, ...result.value };
9941
10170
  if (isV2) {
9942
- if (_optionalChain([state, 'access', _227 => _227.adjustments, 'access', _228 => _228.layers, 'optionalAccess', _229 => _229.length])) state.version = 2;
10171
+ if (_optionalChain([state, 'access', _242 => _242.adjustments, 'access', _243 => _243.layers, 'optionalAccess', _244 => _244.length])) state.version = 2;
9943
10172
  result.report.version = 2;
9944
10173
  }
9945
10174
  if (state.selection === void 0) delete state.selection;
@@ -10139,7 +10368,7 @@ function findAdjustmentControl(id) {
10139
10368
  }
10140
10369
  function findLayerControl(kind, id) {
10141
10370
  if (id === "opacity") return ADJUSTMENT_LAYER_OPACITY_CONTROL;
10142
- return _optionalChain([ADJUSTMENT_LAYER_CONTROLS, 'access', _230 => _230[kind], 'optionalAccess', _231 => _231.find, 'call', _232 => _232((c) => c.id === id)]);
10371
+ return _optionalChain([ADJUSTMENT_LAYER_CONTROLS, 'access', _245 => _245[kind], 'optionalAccess', _246 => _246.find, 'call', _247 => _247((c) => c.id === id)]);
10143
10372
  }
10144
10373
  function clampControlValue(spec, v) {
10145
10374
  if (typeof v !== "number" || !Number.isFinite(v)) return spec.default;
@@ -10258,7 +10487,7 @@ function summary(controller) {
10258
10487
  const area = selectionArea(sel);
10259
10488
  return {
10260
10489
  empty: !sel,
10261
- bounds: _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _233 => _233.bounds]), () => ( null)),
10490
+ bounds: _nullishCoalesce(_optionalChain([sel, 'optionalAccess', _248 => _248.bounds]), () => ( null)),
10262
10491
  /** Σ coverage in pixels. */
10263
10492
  area: Math.round(area),
10264
10493
  percent: Math.round(area / Math.max(1, width * height) * 1e4) / 100,
@@ -10502,7 +10731,7 @@ async function renderImageRegion(controller, request) {
10502
10731
  if (request.includeOverlays) {
10503
10732
  const s = request.scale;
10504
10733
  const selection = state.selection;
10505
- if (_optionalChain([selection, 'optionalAccess', _234 => _234.bounds]) && selection.width === state.imageDimensions.width && selection.height === state.imageDimensions.height) {
10734
+ if (_optionalChain([selection, 'optionalAccess', _249 => _249.bounds]) && selection.width === state.imageDimensions.width && selection.height === state.imageDimensions.height) {
10506
10735
  const shade = selectionShade(selection, document);
10507
10736
  if (shade) context.drawImage(shade, rect.x, rect.y, rect.width, rect.height, 0, 0, out.width, out.height);
10508
10737
  }
@@ -10527,7 +10756,7 @@ function createImageCaptureSurface(controller) {
10527
10756
  return {
10528
10757
  units: "image pixels",
10529
10758
  content: whole,
10530
- selection: () => ({ rect: _nullishCoalesce(_optionalChain([controller, 'access', _235 => _235.getState, 'call', _236 => _236(), 'access', _237 => _237.selection, 'optionalAccess', _238 => _238.bounds]), () => ( null)) }),
10759
+ selection: () => ({ rect: _nullishCoalesce(_optionalChain([controller, 'access', _250 => _250.getState, 'call', _251 => _251(), 'access', _252 => _252.selection, 'optionalAccess', _253 => _253.bounds]), () => ( null)) }),
10531
10760
  overlays: "a shade over unselected pixels and the crop box outline",
10532
10761
  maxScale: 8,
10533
10762
  render: (request) => renderImageRegion(controller, request)
@@ -10639,7 +10868,7 @@ function createImageEditTools(controller) {
10639
10868
  properties: {
10640
10869
  layer: LAYER_ID,
10641
10870
  enabled: { type: "boolean", description: "false hides the layer without deleting it." },
10642
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (see list_controls)." },
10871
+ blend: { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (see list_controls)." },
10643
10872
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0-1." },
10644
10873
  name: { type: "string", description: "Layer name shown in the layers panel." }
10645
10874
  },
@@ -10652,7 +10881,7 @@ function createImageEditTools(controller) {
10652
10881
  if (enabled === void 0 && blend === void 0 && opacity === void 0 && name === void 0) {
10653
10882
  throw new Error("Nothing to change. Pass enabled, blend, opacity or name.");
10654
10883
  }
10655
- if (blend !== void 0 && !_chunkZOOEX3WTcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
10884
+ if (blend !== void 0 && !_chunkCRMAXIUVcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
10656
10885
  controller.updateAdjustmentLayer(layer, { enabled, blend, opacity, name });
10657
10886
  return { layer: layerJson(layer) };
10658
10887
  }
@@ -10805,7 +11034,7 @@ function maskSummary(mask) {
10805
11034
  };
10806
11035
  if (!mask.source) {
10807
11036
  out.defaultValue = mask.defaultValue;
10808
- out.paintedBounds = _chunkZOOEX3WTcjs.contentBounds.call(void 0, mask.surface);
11037
+ out.paintedBounds = _chunkCRMAXIUVcjs.contentBounds.call(void 0, mask.surface);
10809
11038
  }
10810
11039
  return out;
10811
11040
  }
@@ -10820,6 +11049,7 @@ function describeLayer(layer, activeId, boundsOf) {
10820
11049
  clipped: Boolean(layer.clipped),
10821
11050
  locks: layer.locks ? { ...layer.locks } : {},
10822
11051
  mask: maskSummary(layer.mask),
11052
+ effects: layer.effects ? { enabled: layer.effects.enabled, scale: _nullishCoalesce(layer.effects.scale, () => ( 1)), items: layer.effects.items.map((e) => ({ id: e.id, kind: e.kind, enabled: e.enabled })) } : null,
10823
11053
  active: layer.id === activeId
10824
11054
  };
10825
11055
  switch (layer.type) {
@@ -10851,7 +11081,7 @@ var PLACEMENT = {
10851
11081
  parentId: { type: "string", description: "Put the layer inside this group (at index, default its top)." },
10852
11082
  index: { type: "integer", minimum: 0, description: "Position among the siblings, 0 = bottom (with parentId, or at the top level)." }
10853
11083
  };
10854
- var BLEND = { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." };
11084
+ var BLEND = { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." };
10855
11085
  function placementFrom(args) {
10856
11086
  const p = {};
10857
11087
  if (typeof args.aboveId === "string") p.aboveId = args.aboveId;
@@ -10863,11 +11093,11 @@ function placementFrom(args) {
10863
11093
  function createImageLayerTools(controller) {
10864
11094
  const describe = (id) => {
10865
11095
  const s = controller.getState();
10866
- const loc = _chunkH543GD6Tcjs.findLayer.call(void 0, s.layers, id);
11096
+ const loc = _chunkT6H3JDGAcjs.findLayer.call(void 0, s.layers, id);
10867
11097
  if (!loc) return null;
10868
11098
  return {
10869
11099
  ...describeLayer(loc.layer, s.activeLayerId, (x) => controller.getLayerBounds(x.id)),
10870
- parentId: _nullishCoalesce(_optionalChain([loc, 'access', _239 => _239.parent, 'optionalAccess', _240 => _240.id]), () => ( null)),
11100
+ parentId: _nullishCoalesce(_optionalChain([loc, 'access', _254 => _254.parent, 'optionalAccess', _255 => _255.id]), () => ( null)),
10871
11101
  index: loc.index
10872
11102
  };
10873
11103
  };
@@ -10879,7 +11109,7 @@ function createImageLayerTools(controller) {
10879
11109
  const listLayers = {
10880
11110
  name: "list_layers",
10881
11111
  title: "List image layers",
10882
- description: "Returns the layer stack bottom to top as a tree: id, type (pixel, adjustment, group, annotation), name, document bounds (pixel layers), visible, opacity, fillOpacity, blend, clipped, locks, a mask summary, filters (pixel layers), kind and params (adjustment layers), children (groups) and which layer is active. Also returns the active layer id and target (pixels or mask) and the canvas size.",
11112
+ description: "Returns the layer stack bottom to top as a tree: id, type (pixel, adjustment, group, annotation), name, document bounds (pixel layers), visible, opacity, fillOpacity, blend, clipped, locks, a mask summary, an effects summary (master switch, scale, effect ids and kinds; details from list_layer_effects), filters (pixel layers), kind and params (adjustment layers), children (groups) and which layer is active. Also returns the active layer id and target (pixels or mask) and the canvas size.",
10883
11113
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
10884
11114
  annotations: { title: "List image layers", ...READ2 },
10885
11115
  handler: () => {
@@ -11001,7 +11231,7 @@ function createImageLayerTools(controller) {
11001
11231
  visible: { type: "boolean", description: "Show (true) or hide (false)." },
11002
11232
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0..1." },
11003
11233
  fillOpacity: { type: "number", minimum: 0, maximum: 1, description: "Fill 0..1 (pixel layers)." },
11004
- blend: { type: "string", enum: [..._chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode; pass-through for groups only." },
11234
+ blend: { type: "string", enum: [..._chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode; pass-through for groups only." },
11005
11235
  clipped: { type: "boolean", description: "Clip to the nearest unclipped layer below." },
11006
11236
  locks: {
11007
11237
  type: "object",
@@ -11056,7 +11286,7 @@ function createImageLayerTools(controller) {
11056
11286
  type: "object",
11057
11287
  properties: {
11058
11288
  name: { type: "string", description: 'Group name (default "Group").' },
11059
- blend: { type: "string", enum: [..._chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode (default pass-through)." },
11289
+ blend: { type: "string", enum: [..._chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), "pass-through"], description: "Blend mode (default pass-through)." },
11060
11290
  ...PLACEMENT
11061
11291
  },
11062
11292
  additionalProperties: false
@@ -11315,9 +11545,491 @@ function createImageLayerTools(controller) {
11315
11545
  ];
11316
11546
  }
11317
11547
 
11318
- // src/image-editor/paint-tools.ts
11548
+ // src/image-editor/effect-tools.ts
11549
+ var READ3 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
11319
11550
  var WRITE3 = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
11551
+ var WRITE_IDEMPOTENT3 = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false };
11320
11552
  var DESTRUCTIVE2 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
11553
+ var LAYER_ID3 = { type: "string", description: "Layer id from list_layers (a pixel, annotation or group layer)." };
11554
+ var EFFECT_ID = { type: "string", description: "Effect id from list_layer_effects or add_layer_effect." };
11555
+ var BLEND_IDS = _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id);
11556
+ var DEFS = {
11557
+ color: { type: "string", pattern: "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", description: "Colour as #rrggbb." },
11558
+ contour: {
11559
+ type: "object",
11560
+ description: "A transfer curve over the effect coverage: points { input, output } from 0 to 1 (at least 2), sorted by input. Linear is [{0,0},{1,1}].",
11561
+ properties: {
11562
+ name: { type: "string", description: 'Display name (e.g. "Cone", "Gaussian").' },
11563
+ points: {
11564
+ type: "array",
11565
+ minItems: 2,
11566
+ description: "Curve points.",
11567
+ items: {
11568
+ type: "object",
11569
+ properties: {
11570
+ input: { type: "number", minimum: 0, maximum: 1, description: "Coverage in (0..1)." },
11571
+ output: { type: "number", minimum: 0, maximum: 1, description: "Coverage out (0..1)." },
11572
+ corner: { type: "boolean", description: "Sharp corner instead of a smooth point (default false)." }
11573
+ },
11574
+ required: ["input", "output"],
11575
+ additionalProperties: false
11576
+ }
11577
+ }
11578
+ },
11579
+ required: ["name", "points"],
11580
+ additionalProperties: false
11581
+ },
11582
+ gradient: {
11583
+ type: "object",
11584
+ description: "A gradient: colour stops, optional opacity stops and its layout.",
11585
+ properties: {
11586
+ stops: {
11587
+ type: "array",
11588
+ minItems: 1,
11589
+ description: "Colour stops { position 0..1, color #rrggbb }.",
11590
+ items: {
11591
+ type: "object",
11592
+ properties: { position: { type: "number", minimum: 0, maximum: 1, description: "0..1 along the gradient." }, color: { $ref: "#/$defs/color" } },
11593
+ required: ["position", "color"],
11594
+ additionalProperties: false
11595
+ }
11596
+ },
11597
+ opacityStops: {
11598
+ type: "array",
11599
+ description: "Opacity stops { position 0..1, opacity 0..1 } (default opaque).",
11600
+ items: {
11601
+ type: "object",
11602
+ properties: {
11603
+ position: { type: "number", minimum: 0, maximum: 1, description: "0..1 along the gradient." },
11604
+ opacity: { type: "number", minimum: 0, maximum: 1, description: "0..1." }
11605
+ },
11606
+ required: ["position", "opacity"],
11607
+ additionalProperties: false
11608
+ }
11609
+ },
11610
+ style: { type: "string", enum: ["linear", "radial", "angle", "reflected", "diamond"], description: "Geometry." },
11611
+ angle: { type: "number", minimum: -360, maximum: 360, description: "Degrees, 90 = bottom to top." },
11612
+ scale: { type: "number", minimum: 0.1, maximum: 1.5, description: "1 = 100 %." },
11613
+ reverse: { type: "boolean", description: "Swap the ends." },
11614
+ align: { type: "boolean", description: "Lay out over the layer bounds (true) or the canvas." },
11615
+ offset: {
11616
+ type: "object",
11617
+ description: "Centre offset as fractions of the bounds.",
11618
+ properties: { x: { type: "number", minimum: -1, maximum: 1, description: "Fraction of the width." }, y: { type: "number", minimum: -1, maximum: 1, description: "Fraction of the height." } },
11619
+ required: ["x", "y"],
11620
+ additionalProperties: false
11621
+ }
11622
+ },
11623
+ required: ["stops", "style", "angle", "scale", "reverse", "align", "offset"],
11624
+ additionalProperties: false
11625
+ },
11626
+ phase: {
11627
+ type: "object",
11628
+ description: "Pattern origin offset in px.",
11629
+ properties: { x: { type: "number", description: "px." }, y: { type: "number", description: "px." } },
11630
+ required: ["x", "y"],
11631
+ additionalProperties: false
11632
+ },
11633
+ fill: {
11634
+ description: "What a stroke or glow paints with. Glows take color or gradient only.",
11635
+ anyOf: [
11636
+ {
11637
+ type: "object",
11638
+ properties: { type: { const: "color", description: "Solid colour." }, color: { $ref: "#/$defs/color" } },
11639
+ required: ["type", "color"],
11640
+ additionalProperties: false
11641
+ },
11642
+ {
11643
+ type: "object",
11644
+ properties: { type: { const: "gradient", description: "Gradient." }, gradient: { $ref: "#/$defs/gradient" } },
11645
+ required: ["type", "gradient"],
11646
+ additionalProperties: false
11647
+ },
11648
+ {
11649
+ type: "object",
11650
+ properties: {
11651
+ type: { const: "pattern", description: "Pattern (strokes only)." },
11652
+ patternId: { type: "string", description: "Pattern id from list_layer_effects.patterns." },
11653
+ name: { type: "string", description: "Display name." },
11654
+ scale: { type: "number", minimum: 0.01, maximum: 10, description: "1 = 100 %." },
11655
+ angle: { type: "number", minimum: -360, maximum: 360, description: "Rotation in degrees (default 0)." },
11656
+ link: { type: "boolean", description: "Tile from the layer (default true) or the canvas origin." },
11657
+ phase: { $ref: "#/$defs/phase" }
11658
+ },
11659
+ required: ["type", "patternId", "scale"],
11660
+ additionalProperties: false
11661
+ }
11662
+ ]
11663
+ }
11664
+ };
11665
+ var nullable = (schema, description) => ({ anyOf: [schema, { type: "null" }], description });
11666
+ function settingsSchema(forUpdate) {
11667
+ const opt = (schema, description) => forUpdate ? nullable(schema, `${description} null removes it.`) : { ...schema, description };
11668
+ return {
11669
+ type: "object",
11670
+ description: forUpdate ? "Settings to change (only these; nested objects are replaced whole). Which settings a kind takes: see add_layer_effect." : "Settings to change from Photoshop's defaults (all optional). Unknown settings for the kind are refused with the list of its settings.",
11671
+ properties: {
11672
+ enabled: { type: "boolean", description: "All kinds: false keeps the effect but hides it (default true)." },
11673
+ blend: { type: "string", enum: BLEND_IDS, description: "All but bevel-emboss: blend mode (shadows multiply, glows screen, others normal)." },
11674
+ opacity: { type: "number", minimum: 0, maximum: 1, description: "All but bevel-emboss: 0..1 (shadows / glows 0.75, satin 0.5, others 1)." },
11675
+ color: { $ref: "#/$defs/color", description: "drop-shadow, inner-shadow, satin, color-overlay: #rrggbb." },
11676
+ angle: { type: "number", minimum: -360, maximum: 360, description: "Shadows, satin, bevel-emboss: light direction in degrees, counter-clockwise from 3 o'clock (default 120; satin 19)." },
11677
+ useGlobalLight: { type: "boolean", description: "Shadows, bevel-emboss: follow the document global light instead of angle (default true)." },
11678
+ distance: { type: "number", minimum: 0, maximum: 3e4, description: "Shadows, satin: offset in px (default 5; satin 11)." },
11679
+ spread: { type: "number", minimum: 0, maximum: 1, description: "drop-shadow, outer-glow: 0..1 of the size made solid (default 0)." },
11680
+ choke: { type: "number", minimum: 0, maximum: 1, description: "inner-shadow, inner-glow: 0..1 of the size made solid (default 0)." },
11681
+ size: { type: "number", minimum: 0, maximum: 250, description: "Shadows, glows, satin, bevel-emboss: blur / size in px (default 5; satin 14); stroke: width in px (default 3)." },
11682
+ contour: opt({ $ref: "#/$defs/contour" }, "Shadows, glows, satin: coverage contour (default linear)."),
11683
+ antiAlias: { type: "boolean", description: "Shadows, glows, satin: smooth the contour (default false; satin true)." },
11684
+ noise: { type: "number", minimum: 0, maximum: 1, description: "Shadows, glows: speckle 0..1 (default 0)." },
11685
+ knocksOut: { type: "boolean", description: "drop-shadow: the layer hides the shadow beneath its see-through fill (default true)." },
11686
+ fill: { $ref: "#/$defs/fill", description: "outer-glow, inner-glow (color or gradient), stroke (color, gradient or pattern)." },
11687
+ technique: { type: "string", enum: ["softer", "precise", "smooth", "chisel-hard", "chisel-soft"], description: "Glows: softer | precise (default softer); bevel-emboss: smooth | chisel-hard | chisel-soft (default smooth)." },
11688
+ range: { type: "number", minimum: 0.01, maximum: 1, description: "Glows: the part of the glow the contour spans (default 0.5)." },
11689
+ jitter: { type: "number", minimum: 0, maximum: 1, description: "Glows: gradient jitter 0..1 (stored, not rendered; default 0)." },
11690
+ source: { type: "string", enum: ["edge", "center"], description: "inner-glow: glow from the edge (default) or the centre." },
11691
+ style: { type: "string", enum: ["inner-bevel", "outer-bevel", "emboss", "pillow-emboss", "stroke-emboss"], description: "bevel-emboss: style (default inner-bevel)." },
11692
+ depth: { type: "number", minimum: 0, maximum: 10, description: "bevel-emboss: depth, 1 = 100 % (default 1)." },
11693
+ direction: { type: "string", enum: ["up", "down"], description: "bevel-emboss: raised (up, default) or sunk (down)." },
11694
+ soften: { type: "number", minimum: 0, maximum: 16, description: "bevel-emboss: blur of the height in px (default 0)." },
11695
+ altitude: { type: "number", minimum: 0, maximum: 90, description: "bevel-emboss: light altitude in degrees (default 30)." },
11696
+ glossContour: opt({ $ref: "#/$defs/contour" }, "bevel-emboss: gloss contour over the shading (default linear)."),
11697
+ highlightColor: { $ref: "#/$defs/color", description: "bevel-emboss: highlight colour (default #ffffff)." },
11698
+ highlightBlend: { type: "string", enum: BLEND_IDS, description: "bevel-emboss: highlight mode (default screen)." },
11699
+ highlightOpacity: { type: "number", minimum: 0, maximum: 1, description: "bevel-emboss: highlight opacity (default 0.75)." },
11700
+ shadowColor: { $ref: "#/$defs/color", description: "bevel-emboss: shadow colour (default #000000)." },
11701
+ shadowBlend: { type: "string", enum: BLEND_IDS, description: "bevel-emboss: shadow mode (default multiply)." },
11702
+ shadowOpacity: { type: "number", minimum: 0, maximum: 1, description: "bevel-emboss: shadow opacity (default 0.75)." },
11703
+ contourElement: opt(
11704
+ {
11705
+ type: "object",
11706
+ properties: {
11707
+ contour: { $ref: "#/$defs/contour" },
11708
+ range: { type: "number", minimum: 0, maximum: 1, description: "Stored range (default 0.5)." },
11709
+ antiAlias: { type: "boolean", description: "Smooth the contour." }
11710
+ },
11711
+ required: ["contour", "range", "antiAlias"],
11712
+ additionalProperties: false
11713
+ },
11714
+ "bevel-emboss: the Contour element, shaping the bevel's height profile (default off)."
11715
+ ),
11716
+ texture: opt(
11717
+ {
11718
+ type: "object",
11719
+ properties: {
11720
+ patternId: { type: "string", description: "Pattern id from list_layer_effects.patterns." },
11721
+ name: { type: "string", description: "Display name." },
11722
+ scale: { type: "number", minimum: 0.01, maximum: 10, description: "1 = 100 %." },
11723
+ depth: { type: "number", minimum: -10, maximum: 10, description: "1 = +100 %; negative carves the pattern in." },
11724
+ invert: { type: "boolean", description: "Invert the pattern." },
11725
+ link: { type: "boolean", description: "Tile from the layer (default true)." },
11726
+ phase: { $ref: "#/$defs/phase" }
11727
+ },
11728
+ required: ["patternId", "scale", "depth", "invert"],
11729
+ additionalProperties: false
11730
+ },
11731
+ "bevel-emboss: the Texture element, a pattern's luminance as extra height (default off)."
11732
+ ),
11733
+ invert: { type: "boolean", description: "satin: invert (default true)." },
11734
+ gradient: { $ref: "#/$defs/gradient", description: "gradient-overlay: the gradient (default black to white, 90\xB0)." },
11735
+ dither: { type: "boolean", description: "gradient-overlay: dither (stored; default false)." },
11736
+ patternId: { type: "string", description: "pattern-overlay: pattern id from list_layer_effects.patterns (default checker)." },
11737
+ name: { type: "string", description: "pattern-overlay: pattern display name." },
11738
+ scale: { type: "number", minimum: 0.01, maximum: 10, description: "pattern-overlay: 1 = 100 % (default 1)." },
11739
+ link: { type: "boolean", description: "pattern-overlay: tile from the layer (default true) or the canvas origin." },
11740
+ phase: { $ref: "#/$defs/phase", description: "pattern-overlay: origin offset in px (default 0, 0)." },
11741
+ position: { type: "string", enum: ["outside", "inside", "center"], description: "stroke: where the stroke sits on the edge (default outside)." }
11742
+ },
11743
+ additionalProperties: false
11744
+ };
11745
+ }
11746
+ function patternList() {
11747
+ return _chunkT6H3JDGAcjs.builtinPatternIds.call(void 0, ).map((id) => {
11748
+ const p = _chunkT6H3JDGAcjs.builtinPattern.call(void 0, id);
11749
+ return { id, name: p.name, width: p.width, height: p.height, builtin: true };
11750
+ });
11751
+ }
11752
+ function describeLayerEffects(effects) {
11753
+ return {
11754
+ enabled: effects.enabled,
11755
+ scale: _nullishCoalesce(effects.scale, () => ( 1)),
11756
+ margin: _chunkT6H3JDGAcjs.effectsMargin.call(void 0, effects),
11757
+ fromPsd: Boolean(effects.psd),
11758
+ effects: effects.items.map((e) => ({ ...JSON.parse(JSON.stringify(e)), label: _chunkT6H3JDGAcjs.layerEffectLabel.call(void 0, e.kind) }))
11759
+ };
11760
+ }
11761
+ function createImageEffectTools(controller) {
11762
+ const layerArg = (id) => {
11763
+ if (typeof id !== "string" || !id) throw new LayerOperationError("layerId is required (a layer id from list_layers).");
11764
+ requireLayer(controller.getLayers(), id);
11765
+ return id;
11766
+ };
11767
+ const result = (layerId, extra = {}) => ({ layerId, ...extra, ...describeLayerEffects(controller.getLayerEffects(layerId)) });
11768
+ const list = {
11769
+ name: "list_layer_effects",
11770
+ title: "List layer effects",
11771
+ 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.",
11772
+ inputSchema: { type: "object", properties: { layerId: LAYER_ID3 }, required: ["layerId"], additionalProperties: false },
11773
+ annotations: { title: "List layer effects", ...READ3 },
11774
+ handler: ({ layerId }) => result(layerArg(layerId), { globalLight: controller.getGlobalLight(), patterns: patternList(), kinds: [..._chunkT6H3JDGAcjs.LAYER_EFFECT_KINDS] })
11775
+ };
11776
+ const add = {
11777
+ name: "add_layer_effect",
11778
+ title: "Add a layer effect",
11779
+ description: "Adds a live effect to a pixel, annotation or group layer with Photoshop's defaults, changed by settings: drop-shadow, inner-shadow, outer-glow, inner-glow, bevel-emboss, satin, color-overlay, gradient-overlay, pattern-overlay or stroke. Several of one kind are allowed (the first listed is on top). One undo step. Returns the new effect's id and the layer's effects.",
11780
+ inputSchema: {
11781
+ type: "object",
11782
+ $defs: DEFS,
11783
+ properties: {
11784
+ layerId: LAYER_ID3,
11785
+ kind: { type: "string", enum: [..._chunkT6H3JDGAcjs.LAYER_EFFECT_KINDS], description: "Effect kind." },
11786
+ settings: settingsSchema(false),
11787
+ index: { type: "integer", minimum: 0, description: "Position in the layer's effect list (default the end)." }
11788
+ },
11789
+ required: ["layerId", "kind"],
11790
+ additionalProperties: false
11791
+ },
11792
+ annotations: { title: "Add a layer effect", ...WRITE3 },
11793
+ handler: ({ layerId, kind, settings, index }) => {
11794
+ const id = layerArg(layerId);
11795
+ if (!_chunkT6H3JDGAcjs.isLayerEffectKind.call(void 0, kind)) throw new LayerOperationError(`kind must be one of ${_chunkT6H3JDGAcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
11796
+ const { effect } = controller.addLayerEffect(id, kind, _nullishCoalesce(settings, () => ( {})), index);
11797
+ return result(id, { effectId: effect.id });
11798
+ }
11799
+ };
11800
+ const update = {
11801
+ name: "update_layer_effect",
11802
+ title: "Change a layer effect",
11803
+ description: "Changes settings of one effect (only the given ones; fill, gradient, contour and texture objects are replaced whole, null removes an optional contour or texture). The kind cannot change. Validates everything before changing anything. One undo step. Returns the layer's effects.",
11804
+ inputSchema: {
11805
+ type: "object",
11806
+ $defs: DEFS,
11807
+ properties: { layerId: LAYER_ID3, effectId: EFFECT_ID, settings: settingsSchema(true) },
11808
+ required: ["layerId", "effectId", "settings"],
11809
+ additionalProperties: false
11810
+ },
11811
+ annotations: { title: "Change a layer effect", ...WRITE_IDEMPOTENT3 },
11812
+ handler: ({ layerId, effectId, settings }) => {
11813
+ const id = layerArg(layerId);
11814
+ const changes = _nullishCoalesce(settings, () => ( {}));
11815
+ if (!Object.keys(changes).length) throw new LayerOperationError("Give at least one setting to change.");
11816
+ controller.updateLayerEffect(id, effectId, changes);
11817
+ return result(id);
11818
+ }
11819
+ };
11820
+ const remove = {
11821
+ name: "remove_layer_effect",
11822
+ title: "Remove a layer effect",
11823
+ description: "Removes one effect from a layer (to hide it but keep its settings, set enabled false with update_layer_effect instead). One undo step. Returns the layer's remaining effects.",
11824
+ inputSchema: { type: "object", properties: { layerId: LAYER_ID3, effectId: EFFECT_ID }, required: ["layerId", "effectId"], additionalProperties: false },
11825
+ annotations: { title: "Remove a layer effect", ...DESTRUCTIVE2 },
11826
+ handler: ({ layerId, effectId }) => {
11827
+ const id = layerArg(layerId);
11828
+ controller.removeLayerEffect(id, effectId);
11829
+ return result(id);
11830
+ }
11831
+ };
11832
+ const setEnabled = {
11833
+ name: "set_layer_effects_enabled",
11834
+ title: "Switch layer effects on or off",
11835
+ description: "Turns all of a layer's effects on or off at once (the master switch; each effect keeps its own enabled flag) and optionally sets Scale Effects, which multiplies every size, distance and pattern scale. One undo step. Returns the layer's effects.",
11836
+ inputSchema: {
11837
+ type: "object",
11838
+ properties: {
11839
+ layerId: LAYER_ID3,
11840
+ enabled: { type: "boolean", description: "true renders the enabled effects; false hides them all." },
11841
+ scale: { type: "number", minimum: 0.01, maximum: 10, description: "Scale Effects, 1 = 100 % (unchanged when left out)." }
11842
+ },
11843
+ required: ["layerId", "enabled"],
11844
+ additionalProperties: false
11845
+ },
11846
+ annotations: { title: "Switch layer effects on or off", ...WRITE_IDEMPOTENT3 },
11847
+ handler: ({ layerId, enabled, scale }) => {
11848
+ const id = layerArg(layerId);
11849
+ controller.setLayerEffectsEnabled(id, enabled, scale);
11850
+ return result(id);
11851
+ }
11852
+ };
11853
+ const light = {
11854
+ name: "set_global_light",
11855
+ title: "Set the global light",
11856
+ description: "Sets the document global light that shadows and bevels with useGlobalLight follow (Photoshop default: angle 120\xB0, altitude 30\xB0). One undo step. Returns the light.",
11857
+ inputSchema: {
11858
+ type: "object",
11859
+ properties: {
11860
+ angle: { type: "number", minimum: -360, maximum: 360, description: "Degrees, counter-clockwise from 3 o'clock: where the light comes from (unchanged when left out)." },
11861
+ altitude: { type: "number", minimum: 0, maximum: 90, description: "Degrees above the canvas, for bevels (unchanged when left out)." }
11862
+ },
11863
+ additionalProperties: false
11864
+ },
11865
+ annotations: { title: "Set the global light", ...WRITE_IDEMPOTENT3 },
11866
+ handler: ({ angle, altitude }) => {
11867
+ if (angle === void 0 && altitude === void 0) throw new LayerOperationError("Give angle, altitude or both.");
11868
+ const next = {};
11869
+ if (angle !== void 0) next.angle = angle;
11870
+ if (altitude !== void 0) next.altitude = altitude;
11871
+ return { globalLight: controller.setGlobalLight(next) };
11872
+ }
11873
+ };
11874
+ return [list, add, update, remove, setEnabled, light];
11875
+ }
11876
+
11877
+ // src/image-editor/layers/paint-ui.ts
11878
+ var plain2 = { kind: "plain" };
11879
+ var BRUSH_OPTION_CONTROLS = [
11880
+ { id: "size", label: "Size", section: "layer", min: 1, max: 500, step: 1, default: 20, decimals: 0, track: plain2, unit: "px" },
11881
+ { id: "hardness", label: "Hardness", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
11882
+ { id: "opacity", label: "Opacity", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
11883
+ { id: "flow", label: "Flow", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
11884
+ { id: "smoothing", label: "Smoothing", section: "layer", min: 0, max: 0.95, step: 0.01, default: 0, decimals: 0, track: plain2, displayScale: 100, unit: "%" }
11885
+ ];
11886
+ var MIXER_OPTION_CONTROLS = [
11887
+ { id: "wet", label: "Wet", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
11888
+ { id: "load", label: "Load", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
11889
+ { id: "mix", label: "Mix", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%" }
11890
+ ];
11891
+ var MIXER_MIXING_OPTIONS = [
11892
+ { id: "rgb", label: "RGB", title: "Mix colours as RGB averages" },
11893
+ { id: "pigment", label: "Pigment", title: "Mix colours like paint: blue and yellow make green" }
11894
+ ];
11895
+ var PAINT_TOOLS = [
11896
+ { id: "move", label: "Move", shortcut: "V" },
11897
+ { id: "brush", label: "Brush", shortcut: "B" },
11898
+ { id: "mixer", label: "Mixer", shortcut: "Shift+B" },
11899
+ { id: "eraser", label: "Eraser", shortcut: "E" }
11900
+ ];
11901
+ var isPaintTool = (tool) => tool === "move" || tool === "brush" || tool === "mixer" || tool === "eraser";
11902
+ function rgbUnitToHex(c) {
11903
+ return `#${c.map((v) => Math.round(Math.min(1, Math.max(0, v)) * 255).toString(16).padStart(2, "0")).join("")}`;
11904
+ }
11905
+ function sizeStep(size) {
11906
+ return size < 10 ? 1 : size < 50 ? 5 : size < 100 ? 10 : size < 200 ? 25 : size < 500 ? 50 : 100;
11907
+ }
11908
+ var isTyping = (t) => {
11909
+ const el = t;
11910
+ return Boolean(el && (el.isContentEditable || el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT"));
11911
+ };
11912
+ function handlePaintShortcut(controller, e) {
11913
+ if (e.ctrlKey || e.metaKey || e.altKey || isTyping(e.target)) return false;
11914
+ const brush = controller.getState().paint.brush;
11915
+ const set = (b) => controller.setPaintOptions({ brush: b });
11916
+ const key = e.key;
11917
+ switch (key.toLowerCase()) {
11918
+ case "b":
11919
+ controller.setTool(e.shiftKey || key === "B" ? "mixer" : "brush");
11920
+ return true;
11921
+ case "e":
11922
+ controller.setTool("eraser");
11923
+ return true;
11924
+ case "v":
11925
+ controller.setTool("move");
11926
+ return true;
11927
+ case "d":
11928
+ controller.resetPaintColors();
11929
+ return true;
11930
+ case "x":
11931
+ controller.swapPaintColors();
11932
+ return true;
11933
+ }
11934
+ if (key === "[" || key === "{") {
11935
+ if (e.shiftKey || key === "{") set({ hardness: Math.max(0, Math.round((brush.hardness - 0.25) * 4) / 4) });
11936
+ else set({ size: Math.max(1, brush.size - sizeStep(brush.size - 1)) });
11937
+ return true;
11938
+ }
11939
+ if (key === "]" || key === "}") {
11940
+ if (e.shiftKey || key === "}") set({ hardness: Math.min(1, Math.round((brush.hardness + 0.25) * 4) / 4) });
11941
+ else set({ size: Math.min(_chunkZZOTHJ4Kcjs.MAX_BRUSH_SIZE, brush.size + sizeStep(brush.size)) });
11942
+ return true;
11943
+ }
11944
+ if (/^[0-9]$/.test(key) && isPaintTool(controller.getState().activeTool)) {
11945
+ set({ opacity: key === "0" ? 1 : Number(key) / 10 });
11946
+ return true;
11947
+ }
11948
+ return false;
11949
+ }
11950
+ function pointerPressure(e) {
11951
+ if (e.pointerType === "pen" && typeof e.pressure === "number" && e.pressure > 0) return Math.min(1, e.pressure);
11952
+ return 1;
11953
+ }
11954
+ var PaintGesture = (_class8 = class {
11955
+ constructor(controller) {;_class8.prototype.__init52.call(this);_class8.prototype.__init53.call(this);_class8.prototype.__init54.call(this);
11956
+ this.controller = controller;
11957
+ }
11958
+
11959
+ __init52() {this.stroke = null}
11960
+ __init53() {this.move = null}
11961
+ /** The last refusal (e.g. "layer is locked"), for the editor to show. */
11962
+ __init54() {this.error = null}
11963
+ get active() {
11964
+ return Boolean(this.stroke || this.move);
11965
+ }
11966
+ down(sample) {
11967
+ this.error = null;
11968
+ const tool = this.controller.getState().activeTool;
11969
+ try {
11970
+ if (tool === "move") {
11971
+ const layer = this.controller.getActiveLayer();
11972
+ if (!layer) throw new Error("Select a layer to move in the Layers panel.");
11973
+ if (layer.type !== "pixel") throw new Error(`Only pixel layers move; "${layer.name}" is a ${layer.type} layer.`);
11974
+ if (_optionalChain([layer, 'access', _256 => _256.locks, 'optionalAccess', _257 => _257.all]) || _optionalChain([layer, 'access', _258 => _258.locks, 'optionalAccess', _259 => _259.position])) throw new Error(`Layer "${layer.name}" has its position locked.`);
11975
+ this.move = { id: layer.id, start: { x: sample.x, y: sample.y }, origin: { ...layer.offset }, moved: false };
11976
+ return null;
11977
+ }
11978
+ if (tool === "brush" || tool === "eraser" || tool === "mixer") {
11979
+ this.stroke = this.controller.beginStroke({ tool });
11980
+ this.stroke.push([sample]);
11981
+ return null;
11982
+ }
11983
+ } catch (err) {
11984
+ this.error = err instanceof Error ? err.message : String(err);
11985
+ this.stroke = null;
11986
+ this.move = null;
11987
+ }
11988
+ return this.error;
11989
+ }
11990
+ /** Feeds pointer samples (all coalesced events of one move, in order). */
11991
+ moveTo(samples) {
11992
+ if (!samples.length) return;
11993
+ if (this.stroke) {
11994
+ this.stroke.push(samples);
11995
+ return;
11996
+ }
11997
+ const m = this.move;
11998
+ if (m) {
11999
+ const last = samples[samples.length - 1];
12000
+ const x = m.origin.x + Math.round(last.x - m.start.x);
12001
+ const y = m.origin.y + Math.round(last.y - m.start.y);
12002
+ try {
12003
+ this.controller.offsetLayer(m.id, { x, y }, !m.moved);
12004
+ m.moved = true;
12005
+ } catch (err) {
12006
+ this.error = err instanceof Error ? err.message : String(err);
12007
+ this.move = null;
12008
+ }
12009
+ }
12010
+ }
12011
+ up() {
12012
+ if (this.stroke) {
12013
+ try {
12014
+ this.stroke.end();
12015
+ } catch (err) {
12016
+ this.error = err instanceof Error ? err.message : String(err);
12017
+ }
12018
+ }
12019
+ this.stroke = null;
12020
+ this.move = null;
12021
+ }
12022
+ cancel() {
12023
+ _optionalChain([this, 'access', _260 => _260.stroke, 'optionalAccess', _261 => _261.cancel, 'call', _262 => _262()]);
12024
+ this.stroke = null;
12025
+ this.move = null;
12026
+ }
12027
+ }, _class8);
12028
+
12029
+ // src/image-editor/paint-tools.ts
12030
+ var READ4 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
12031
+ var WRITE4 = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
12032
+ var DESTRUCTIVE3 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
11321
12033
  var TARGET = {
11322
12034
  layerId: { type: "string", description: "Layer to paint (default the active layer; see list_layers)." },
11323
12035
  channel: { type: "string", enum: ["pixels", "mask"], description: "pixels (default for a pixel layer) or the layer's mask: black hides, white reveals." }
@@ -11326,7 +12038,7 @@ var BRUSH = {
11326
12038
  type: "object",
11327
12039
  description: "Brush settings; missing fields use the current paint options (default round, hard, 20 px).",
11328
12040
  properties: {
11329
- size: { type: "number", minimum: 1, maximum: _chunk4F3YDIWWcjs.MAX_BRUSH_SIZE, description: "Diameter in px (default 20)." },
12041
+ size: { type: "number", minimum: 1, maximum: _chunkZZOTHJ4Kcjs.MAX_BRUSH_SIZE, description: "Diameter in px (default 20)." },
11330
12042
  hardness: { type: "number", minimum: 0, maximum: 1, description: "Edge hardness 0 (soft) .. 1 (hard, default)." },
11331
12043
  spacing: { type: "number", minimum: 0.01, maximum: 10, description: "Dab spacing as a fraction of the diameter (default 0.1)." },
11332
12044
  angle: { type: "number", minimum: -360, maximum: 360, description: "Tip angle in degrees (default 0)." },
@@ -11336,10 +12048,30 @@ var BRUSH = {
11336
12048
  smoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Point smoothing 0..0.95 (default 0)." },
11337
12049
  pressureSize: { type: "boolean", description: "Point pressure scales the size (default true)." },
11338
12050
  pressureOpacity: { type: "boolean", description: "Point pressure scales the opacity (default false)." },
11339
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "How paint combines with the layer (default normal)." }
12051
+ 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." }
12052
+ },
12053
+ additionalProperties: false
12054
+ };
12055
+ var MIXER = {
12056
+ type: "object",
12057
+ 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).",
12058
+ properties: {
12059
+ 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)." },
12060
+ 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." },
12061
+ 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)." },
12062
+ 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." },
12063
+ 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." },
12064
+ 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." }
11340
12065
  },
11341
12066
  additionalProperties: false
11342
12067
  };
12068
+ function mixerLoadResult(load) {
12069
+ return {
12070
+ reservoir: load.reservoir ? rgbUnitToHex(load.reservoir) : null,
12071
+ amount: Math.round(load.amount * 1e3) / 1e3,
12072
+ pickup: load.pickup ? rgbUnitToHex(load.pickup) : null
12073
+ };
12074
+ }
11343
12075
  function readTarget(args) {
11344
12076
  return { layerId: args.layerId, channel: args.channel };
11345
12077
  }
@@ -11347,11 +12079,11 @@ function createImagePaintTools(controller) {
11347
12079
  const paintStroke = {
11348
12080
  name: "paint_stroke",
11349
12081
  title: "Paint a brush stroke",
11350
- 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.",
12082
+ 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}).",
11351
12083
  inputSchema: {
11352
12084
  type: "object",
11353
12085
  properties: {
11354
- tool: { type: "string", enum: ["brush", "eraser"], description: "brush (default) or eraser." },
12086
+ 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)." },
11355
12087
  points: {
11356
12088
  type: "array",
11357
12089
  minItems: 1,
@@ -11368,21 +12100,66 @@ function createImagePaintTools(controller) {
11368
12100
  additionalProperties: false
11369
12101
  }
11370
12102
  },
11371
- color: { type: "string", description: "Paint colour #rrggbb (default the foreground). On a mask its grey value: #000000 hides, #ffffff reveals." },
12103
+ color: {
12104
+ type: "string",
12105
+ 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)."
12106
+ },
11372
12107
  brush: BRUSH,
12108
+ mixer: MIXER,
11373
12109
  ...TARGET
11374
12110
  },
11375
12111
  required: ["points"],
11376
12112
  additionalProperties: false
11377
12113
  },
11378
- annotations: { title: "Paint a brush stroke", ...WRITE3 },
11379
- handler: (args) => controller.paintStroke({
11380
- tool: args.tool,
11381
- points: args.points,
11382
- color: args.color,
11383
- brush: args.brush,
11384
- ...readTarget(args)
11385
- })
12114
+ annotations: { title: "Paint a brush stroke", ...WRITE4 },
12115
+ handler: (args) => {
12116
+ const tool = args.tool;
12117
+ if (args.mixer !== void 0 && tool !== "mixer") throw new LayerOperationError('mixer settings apply to the Mixer Brush only; pass tool "mixer", or drop mixer.');
12118
+ const result = controller.paintStroke({
12119
+ tool,
12120
+ points: args.points,
12121
+ color: args.color,
12122
+ brush: args.brush,
12123
+ mixer: args.mixer,
12124
+ ...readTarget(args)
12125
+ });
12126
+ return result.mixerLoad ? { ...result, mixerLoad: mixerLoadResult(result.mixerLoad) } : result;
12127
+ }
12128
+ };
12129
+ const getMixer = {
12130
+ name: "get_mixer_brush",
12131
+ title: "Get the Mixer Brush",
12132
+ 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.",
12133
+ inputSchema: { type: "object", properties: {}, additionalProperties: false },
12134
+ annotations: { title: "Get the Mixer Brush", ...READ4 },
12135
+ handler: () => {
12136
+ const { mixer, mixerLoad } = controller.getState().paint;
12137
+ return { settings: { ...mixer }, load: mixerLoadResult(mixerLoad) };
12138
+ }
12139
+ };
12140
+ const loadMixerTool = {
12141
+ name: "load_mixer_brush",
12142
+ title: "Load the Mixer Brush",
12143
+ 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}.",
12144
+ inputSchema: {
12145
+ type: "object",
12146
+ properties: { color: { type: "string", description: "Paint colour #rrggbb (default the foreground)." } },
12147
+ additionalProperties: false
12148
+ },
12149
+ annotations: { title: "Load the Mixer Brush", ...WRITE4, idempotentHint: true },
12150
+ handler: (args) => mixerLoadResult(controller.loadMixerBrush(args.color))
12151
+ };
12152
+ const cleanMixerTool = {
12153
+ name: "clean_mixer_brush",
12154
+ title: "Clean the Mixer Brush",
12155
+ 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}.",
12156
+ inputSchema: {
12157
+ type: "object",
12158
+ properties: { emptyReservoir: { type: "boolean", description: "Also drop the reservoir (default false)." } },
12159
+ additionalProperties: false
12160
+ },
12161
+ annotations: { title: "Clean the Mixer Brush", ...WRITE4, idempotentHint: true },
12162
+ handler: (args) => mixerLoadResult(args.emptyReservoir === true ? controller.emptyMixerBrush() : controller.cleanMixerBrush())
11386
12163
  };
11387
12164
  const fill = {
11388
12165
  name: "fill_pixels",
@@ -11393,13 +12170,13 @@ function createImagePaintTools(controller) {
11393
12170
  properties: {
11394
12171
  color: { type: "string", description: "Fill colour #rrggbb or #rrggbbaa (default the foreground)." },
11395
12172
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Fill opacity 0..1 (default 1)." },
11396
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
12173
+ 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." },
11397
12174
  useSelection: { type: "boolean", description: "Limit to the selection when there is one (default true)." },
11398
12175
  ...TARGET
11399
12176
  },
11400
12177
  additionalProperties: false
11401
12178
  },
11402
- annotations: { title: "Fill pixels", ...WRITE3 },
12179
+ annotations: { title: "Fill pixels", ...WRITE4 },
11403
12180
  handler: (args) => controller.fillPixels({
11404
12181
  color: args.color,
11405
12182
  opacity: args.opacity,
@@ -11421,15 +12198,15 @@ function createImagePaintTools(controller) {
11421
12198
  },
11422
12199
  additionalProperties: false
11423
12200
  },
11424
- annotations: { title: "Clear pixels", ...DESTRUCTIVE2 },
12201
+ annotations: { title: "Clear pixels", ...DESTRUCTIVE3 },
11425
12202
  handler: (args) => controller.clearPixels({ opacity: args.opacity, useSelection: args.useSelection, ...readTarget(args) })
11426
12203
  };
11427
- return [paintStroke, fill, clear];
12204
+ return [paintStroke, fill, clear, getMixer, loadMixerTool, cleanMixerTool];
11428
12205
  }
11429
12206
 
11430
12207
  // src/image-editor/psd-tools.ts
11431
- var READ3 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
11432
- var DESTRUCTIVE3 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
12208
+ var READ5 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
12209
+ var DESTRUCTIVE4 = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
11433
12210
  var DATA = {
11434
12211
  type: "string",
11435
12212
  minLength: 1,
@@ -11439,7 +12216,7 @@ function psdBytesFromBase64(data) {
11439
12216
  if (typeof data !== "string" || !data.trim()) throw new PsdError("data is required: the PSD file as base64.");
11440
12217
  const body = data.trim().replace(/^data:[^,]*;base64,/i, "");
11441
12218
  if (!/^[A-Za-z0-9+/=_\s-]+$/.test(body)) throw new PsdError("data is not base64; send the PSD file bytes base64-encoded.");
11442
- const bytes = _chunkH543GD6Tcjs.base64ToBytes.call(void 0, body);
12219
+ const bytes = _chunkT6H3JDGAcjs.base64ToBytes.call(void 0, body);
11443
12220
  if (bytes.length < 26) throw new PsdError(`data decodes to ${bytes.length} bytes, too short for a PSD (at least 26).`);
11444
12221
  return bytes;
11445
12222
  }
@@ -11449,7 +12226,7 @@ function createImagePsdTools(controller) {
11449
12226
  title: "Inspect a PSD",
11450
12227
  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.",
11451
12228
  inputSchema: { type: "object", properties: { data: DATA }, required: ["data"], additionalProperties: false },
11452
- annotations: { title: "Inspect a PSD", ...READ3 },
12229
+ annotations: { title: "Inspect a PSD", ...READ5 },
11453
12230
  handler: ({ data }) => {
11454
12231
  const res = importPsd(psdBytesFromBase64(data), { skipPixels: true });
11455
12232
  return {
@@ -11467,7 +12244,7 @@ function createImagePsdTools(controller) {
11467
12244
  title: "Open a PSD as the document",
11468
12245
  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).",
11469
12246
  inputSchema: { type: "object", properties: { data: DATA }, required: ["data"], additionalProperties: false },
11470
- annotations: { title: "Open a PSD as the document", ...DESTRUCTIVE3 },
12247
+ annotations: { title: "Open a PSD as the document", ...DESTRUCTIVE4 },
11471
12248
  handler: ({ data }) => {
11472
12249
  const res = controller.loadPsd(psdBytesFromBase64(data));
11473
12250
  const s = controller.getState();
@@ -11486,11 +12263,11 @@ function createImagePsdTools(controller) {
11486
12263
  title: "Export the document as a PSD",
11487
12264
  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.",
11488
12265
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
11489
- annotations: { title: "Export the document as a PSD", ...READ3 },
12266
+ annotations: { title: "Export the document as a PSD", ...READ5 },
11490
12267
  handler: async () => {
11491
12268
  const res = await controller.toPsd();
11492
12269
  return {
11493
- data: _chunkH543GD6Tcjs.bytesToBase64.call(void 0, res.bytes),
12270
+ data: _chunkT6H3JDGAcjs.bytesToBase64.call(void 0, res.bytes),
11494
12271
  mimeType: "image/vnd.adobe.photoshop",
11495
12272
  size: res.bytes.length,
11496
12273
  psb: res.psb,
@@ -11562,7 +12339,7 @@ function createImageEditorToolProvider(controller, options = {}) {
11562
12339
  default: def
11563
12340
  }))
11564
12341
  })),
11565
- blendModes: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id),
12342
+ blendModes: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id),
11566
12343
  layerPathFormat: "layers.<layerId>.<controlId>"
11567
12344
  })
11568
12345
  };
@@ -11653,7 +12430,7 @@ function createImageEditorToolProvider(controller, options = {}) {
11653
12430
  kind: { type: "string", enum: ADJUSTMENT_KINDS.map((k) => k.kind), description: "Adjustment kind." },
11654
12431
  params: { type: "object", description: "Initial parameters (see list_controls); merged with neutral defaults." },
11655
12432
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0-1 (default 1)." },
11656
- blend: { type: "string", enum: _chunkZOOEX3WTcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
12433
+ blend: { type: "string", enum: _chunkCRMAXIUVcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
11657
12434
  name: { type: "string", description: "Layer name shown in the layers panel." },
11658
12435
  aboveId: { type: "string", description: "Put the layer directly above this layer (from list_layers). Default: above the other adjustment layers, below annotations." },
11659
12436
  parentId: { type: "string", description: "Put the layer at the top of this group (from list_layers)." }
@@ -11670,12 +12447,12 @@ function createImageEditorToolProvider(controller, options = {}) {
11670
12447
  },
11671
12448
  handler: ({ kind, params, opacity, blend, name, aboveId, parentId }) => {
11672
12449
  if (!isAdjustmentKind(kind)) throw new Error(`Unknown adjustment kind "${kind}".`);
11673
- if (blend !== void 0 && !_chunkZOOEX3WTcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
12450
+ if (blend !== void 0 && !_chunkCRMAXIUVcjs.isBlendMode.call(void 0, blend)) throw new Error(`Unknown blend mode "${blend}".`);
11674
12451
  if (aboveId !== void 0 && parentId !== void 0) throw new Error("Give aboveId or parentId, not both.");
11675
12452
  for (const ref of [aboveId, parentId]) {
11676
12453
  if (ref !== void 0 && !controller.getLayer(ref)) throw new Error(`Unknown layer "${ref}". Call list_layers for ids.`);
11677
12454
  }
11678
- if (parentId !== void 0 && _optionalChain([controller, 'access', _241 => _241.getLayer, 'call', _242 => _242(parentId), 'optionalAccess', _243 => _243.type]) !== "group") throw new Error(`Layer "${parentId}" is not a group.`);
12455
+ if (parentId !== void 0 && _optionalChain([controller, 'access', _263 => _263.getLayer, 'call', _264 => _264(parentId), 'optionalAccess', _265 => _265.type]) !== "group") throw new Error(`Layer "${parentId}" is not a group.`);
11679
12456
  const id = controller.addAdjustmentLayer({ kind, params, opacity, blend, name, aboveId, parentId });
11680
12457
  const layer = controller.getAdjustmentLayer(id);
11681
12458
  return { layer: JSON.parse(JSON.stringify(layer)), index: controller.getAdjustmentLayers().findIndex((l) => l.id === id) };
@@ -11740,8 +12517,9 @@ function createImageEditorToolProvider(controller, options = {}) {
11740
12517
  ...createImageSelectionTools(controller),
11741
12518
  ...createImageEditTools(controller),
11742
12519
  ...createImageLayerTools(controller),
12520
+ ...createImageEffectTools(controller),
11743
12521
  ...createImagePaintTools(controller),
11744
- ..._chunk4F3YDIWWcjs.createPigmentTools.call(void 0, ),
12522
+ ..._chunkZZOTHJ4Kcjs.createPigmentTools.call(void 0, ),
11745
12523
  ...createImagePsdTools(controller)
11746
12524
  ]
11747
12525
  };
@@ -11802,19 +12580,19 @@ function removeCurvePoint(points, index) {
11802
12580
  var round22 = (v) => Math.round(v * 100) / 100;
11803
12581
 
11804
12582
  // src/image-editor/selection/gesture.ts
11805
- var SelectionGesture = (_class8 = class {
11806
- 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);
12583
+ var SelectionGesture = (_class9 = class {
12584
+ constructor(controller, getOptions) {;_class9.prototype.__init55.call(this);_class9.prototype.__init56.call(this);_class9.prototype.__init57.call(this);_class9.prototype.__init58.call(this);_class9.prototype.__init59.call(this);
11807
12585
  this.controller = controller;
11808
12586
  this.getOptions = getOptions;
11809
12587
  }
11810
12588
 
11811
12589
 
11812
- __init50() {this.start = null}
11813
- __init51() {this.points = []}
11814
- __init52() {this.current = null}
11815
- __init53() {this.modifiers = {}}
12590
+ __init55() {this.start = null}
12591
+ __init56() {this.points = []}
12592
+ __init57() {this.current = null}
12593
+ __init58() {this.modifiers = {}}
11816
12594
  /** The last error (e.g. pixels unavailable for the wand), for the UI to show. */
11817
- __init54() {this.error = null}
12595
+ __init59() {this.error = null}
11818
12596
  get active() {
11819
12597
  return this.start !== null;
11820
12598
  }
@@ -11902,7 +12680,7 @@ var SelectionGesture = (_class8 = class {
11902
12680
  this.current = null;
11903
12681
  this.points = [];
11904
12682
  }
11905
- }, _class8);
12683
+ }, _class9);
11906
12684
 
11907
12685
  // src/image-editor/mosaic-filter.ts
11908
12686
  function resolveMosaicRegionBounds(region, imgWidth, imgHeight) {
@@ -12085,7 +12863,7 @@ function dropZone(fraction, isGroup) {
12085
12863
  }
12086
12864
  function dropPlacement(layers, dragId, targetId, zone) {
12087
12865
  if (dragId === targetId) return null;
12088
- const target = _chunkH543GD6Tcjs.findLayer.call(void 0, layers, targetId);
12866
+ const target = _chunkT6H3JDGAcjs.findLayer.call(void 0, layers, targetId);
12089
12867
  if (!target) return null;
12090
12868
  if (zone === "inside" && target.layer.type === "group") return { parentId: targetId };
12091
12869
  return zone === "above" ? { aboveId: targetId } : { belowId: targetId };
@@ -12093,35 +12871,35 @@ function dropPlacement(layers, dragId, targetId, zone) {
12093
12871
  function layerMenu(controller) {
12094
12872
  const s = controller.getState();
12095
12873
  const active = controller.getActiveLayer();
12096
- const loc = active ? _chunkH543GD6Tcjs.findLayer.call(void 0, s.layers, active.id) : null;
12874
+ const loc = active ? _chunkT6H3JDGAcjs.findLayer.call(void 0, s.layers, active.id) : null;
12097
12875
  const siblings = loc ? loc.parent ? loc.parent.children : s.layers : [];
12098
12876
  const below = loc ? siblings[loc.index - 1] : void 0;
12099
12877
  const hasSel = controller.hasSelection;
12100
- const isPixel = _optionalChain([active, 'optionalAccess', _244 => _244.type]) === "pixel";
12878
+ const isPixel = _optionalChain([active, 'optionalAccess', _266 => _266.type]) === "pixel";
12101
12879
  return [
12102
12880
  { action: "new-layer", label: "New Layer", enabled: true },
12103
12881
  { action: "new-group", label: "New Group", enabled: true },
12104
12882
  { action: "duplicate", label: "Duplicate Layer", enabled: Boolean(active) },
12105
12883
  { action: "delete", label: "Delete Layer", enabled: Boolean(active) },
12106
12884
  { action: "group-selected", label: "Group Layer", enabled: Boolean(active) },
12107
- { action: "ungroup", label: "Ungroup", enabled: _optionalChain([active, 'optionalAccess', _245 => _245.type]) === "group" },
12108
- { action: "merge-down", label: "Merge Down", enabled: Boolean(_optionalChain([active, 'optionalAccess', _246 => _246.visible]) && _optionalChain([below, 'optionalAccess', _247 => _247.type]) === "pixel") },
12885
+ { action: "ungroup", label: "Ungroup", enabled: _optionalChain([active, 'optionalAccess', _267 => _267.type]) === "group" },
12886
+ { action: "merge-down", label: "Merge Down", enabled: Boolean(_optionalChain([active, 'optionalAccess', _268 => _268.visible]) && _optionalChain([below, 'optionalAccess', _269 => _269.type]) === "pixel") },
12109
12887
  { action: "merge-visible", label: "Merge Visible", enabled: s.layers.some((l) => l.visible) },
12110
12888
  { action: "flatten", label: "Flatten Image", enabled: s.layers.length > 0 },
12111
12889
  { action: "via-copy", label: "Layer via Copy", enabled: isPixel && hasSel },
12112
12890
  { action: "via-cut", label: "Layer via Cut", enabled: isPixel && hasSel },
12113
12891
  { action: "add-mask", label: "Add Layer Mask", enabled: Boolean(active) },
12114
12892
  { action: "add-mask-selection", label: "Add Mask from Selection", enabled: Boolean(active) && hasSel },
12115
- { action: "apply-mask", label: "Apply Layer Mask", enabled: isPixel && Boolean(_optionalChain([active, 'optionalAccess', _248 => _248.mask])) },
12116
- { action: "delete-mask", label: "Delete Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _249 => _249.mask])) },
12117
- { action: "toggle-mask", label: _optionalChain([active, 'optionalAccess', _250 => _250.mask, 'optionalAccess', _251 => _251.enabled]) === false ? "Enable Layer Mask" : "Disable Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _252 => _252.mask])) },
12118
- { action: "rasterize", label: "Rasterize Layer", enabled: _optionalChain([active, 'optionalAccess', _253 => _253.type]) === "annotation" || isPixel && Boolean(_optionalChain([active, 'optionalAccess', _254 => _254.type]) === "pixel" && _optionalChain([active, 'access', _255 => _255.filters, 'optionalAccess', _256 => _256.length])) },
12119
- { action: "toggle-clip", label: _optionalChain([active, 'optionalAccess', _257 => _257.clipped]) ? "Release Clipping Mask" : "Create Clipping Mask", enabled: Boolean(loc && loc.index > 0) }
12893
+ { action: "apply-mask", label: "Apply Layer Mask", enabled: isPixel && Boolean(_optionalChain([active, 'optionalAccess', _270 => _270.mask])) },
12894
+ { action: "delete-mask", label: "Delete Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _271 => _271.mask])) },
12895
+ { action: "toggle-mask", label: _optionalChain([active, 'optionalAccess', _272 => _272.mask, 'optionalAccess', _273 => _273.enabled]) === false ? "Enable Layer Mask" : "Disable Layer Mask", enabled: Boolean(_optionalChain([active, 'optionalAccess', _274 => _274.mask])) },
12896
+ { action: "rasterize", label: "Rasterize Layer", enabled: _optionalChain([active, 'optionalAccess', _275 => _275.type]) === "annotation" || isPixel && Boolean(_optionalChain([active, 'optionalAccess', _276 => _276.type]) === "pixel" && _optionalChain([active, 'access', _277 => _277.filters, 'optionalAccess', _278 => _278.length])) },
12897
+ { action: "toggle-clip", label: _optionalChain([active, 'optionalAccess', _279 => _279.clipped]) ? "Release Clipping Mask" : "Create Clipping Mask", enabled: Boolean(loc && loc.index > 0) }
12120
12898
  ];
12121
12899
  }
12122
12900
  async function runLayerMenuAction(controller, action) {
12123
12901
  const active = controller.getActiveLayer();
12124
- const id = _optionalChain([active, 'optionalAccess', _258 => _258.id]);
12902
+ const id = _optionalChain([active, 'optionalAccess', _280 => _280.id]);
12125
12903
  try {
12126
12904
  switch (action) {
12127
12905
  case "new-layer":
@@ -12168,13 +12946,13 @@ async function runLayerMenuAction(controller, action) {
12168
12946
  if (id) controller.removeLayerMask(id);
12169
12947
  break;
12170
12948
  case "toggle-mask":
12171
- if (id && _optionalChain([active, 'optionalAccess', _259 => _259.mask])) controller.setLayerMaskProps(id, { enabled: active.mask.enabled === false });
12949
+ if (id && _optionalChain([active, 'optionalAccess', _281 => _281.mask])) controller.setLayerMaskProps(id, { enabled: active.mask.enabled === false });
12172
12950
  break;
12173
12951
  case "rasterize":
12174
12952
  if (id) await controller.rasterizeLayer(id);
12175
12953
  break;
12176
12954
  case "toggle-clip":
12177
- if (id) controller.setLayerProperties(id, { clipped: !_optionalChain([active, 'optionalAccess', _260 => _260.clipped]) });
12955
+ if (id) controller.setLayerProperties(id, { clipped: !_optionalChain([active, 'optionalAccess', _282 => _282.clipped]) });
12178
12956
  break;
12179
12957
  }
12180
12958
  return null;
@@ -12183,145 +12961,6 @@ async function runLayerMenuAction(controller, action) {
12183
12961
  }
12184
12962
  }
12185
12963
 
12186
- // src/image-editor/layers/paint-ui.ts
12187
- var plain2 = { kind: "plain" };
12188
- var BRUSH_OPTION_CONTROLS = [
12189
- { id: "size", label: "Size", section: "layer", min: 1, max: 500, step: 1, default: 20, decimals: 0, track: plain2, unit: "px" },
12190
- { id: "hardness", label: "Hardness", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12191
- { id: "opacity", label: "Opacity", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12192
- { id: "flow", label: "Flow", section: "layer", min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain2, displayScale: 100, unit: "%" },
12193
- { id: "smoothing", label: "Smoothing", section: "layer", min: 0, max: 0.95, step: 0.01, default: 0, decimals: 0, track: plain2, displayScale: 100, unit: "%" }
12194
- ];
12195
- var PAINT_TOOLS = [
12196
- { id: "move", label: "Move", shortcut: "V" },
12197
- { id: "brush", label: "Brush", shortcut: "B" },
12198
- { id: "eraser", label: "Eraser", shortcut: "E" }
12199
- ];
12200
- var isPaintTool = (tool) => tool === "move" || tool === "brush" || tool === "eraser";
12201
- function sizeStep(size) {
12202
- return size < 10 ? 1 : size < 50 ? 5 : size < 100 ? 10 : size < 200 ? 25 : size < 500 ? 50 : 100;
12203
- }
12204
- var isTyping = (t) => {
12205
- const el = t;
12206
- return Boolean(el && (el.isContentEditable || el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT"));
12207
- };
12208
- function handlePaintShortcut(controller, e) {
12209
- if (e.ctrlKey || e.metaKey || e.altKey || isTyping(e.target)) return false;
12210
- const brush = controller.getState().paint.brush;
12211
- const set = (b) => controller.setPaintOptions({ brush: b });
12212
- const key = e.key;
12213
- switch (key.toLowerCase()) {
12214
- case "b":
12215
- controller.setTool("brush");
12216
- return true;
12217
- case "e":
12218
- controller.setTool("eraser");
12219
- return true;
12220
- case "v":
12221
- controller.setTool("move");
12222
- return true;
12223
- case "d":
12224
- controller.resetPaintColors();
12225
- return true;
12226
- case "x":
12227
- controller.swapPaintColors();
12228
- return true;
12229
- }
12230
- if (key === "[" || key === "{") {
12231
- if (e.shiftKey || key === "{") set({ hardness: Math.max(0, Math.round((brush.hardness - 0.25) * 4) / 4) });
12232
- else set({ size: Math.max(1, brush.size - sizeStep(brush.size - 1)) });
12233
- return true;
12234
- }
12235
- if (key === "]" || key === "}") {
12236
- if (e.shiftKey || key === "}") set({ hardness: Math.min(1, Math.round((brush.hardness + 0.25) * 4) / 4) });
12237
- else set({ size: Math.min(_chunk4F3YDIWWcjs.MAX_BRUSH_SIZE, brush.size + sizeStep(brush.size)) });
12238
- return true;
12239
- }
12240
- if (/^[0-9]$/.test(key) && isPaintTool(controller.getState().activeTool)) {
12241
- set({ opacity: key === "0" ? 1 : Number(key) / 10 });
12242
- return true;
12243
- }
12244
- return false;
12245
- }
12246
- function pointerPressure(e) {
12247
- if (e.pointerType === "pen" && typeof e.pressure === "number" && e.pressure > 0) return Math.min(1, e.pressure);
12248
- return 1;
12249
- }
12250
- var PaintGesture = (_class9 = class {
12251
- constructor(controller) {;_class9.prototype.__init55.call(this);_class9.prototype.__init56.call(this);_class9.prototype.__init57.call(this);
12252
- this.controller = controller;
12253
- }
12254
-
12255
- __init55() {this.stroke = null}
12256
- __init56() {this.move = null}
12257
- /** The last refusal (e.g. "layer is locked"), for the editor to show. */
12258
- __init57() {this.error = null}
12259
- get active() {
12260
- return Boolean(this.stroke || this.move);
12261
- }
12262
- down(sample) {
12263
- this.error = null;
12264
- const tool = this.controller.getState().activeTool;
12265
- try {
12266
- if (tool === "move") {
12267
- const layer = this.controller.getActiveLayer();
12268
- if (!layer) throw new Error("Select a layer to move in the Layers panel.");
12269
- if (layer.type !== "pixel") throw new Error(`Only pixel layers move; "${layer.name}" is a ${layer.type} layer.`);
12270
- if (_optionalChain([layer, 'access', _261 => _261.locks, 'optionalAccess', _262 => _262.all]) || _optionalChain([layer, 'access', _263 => _263.locks, 'optionalAccess', _264 => _264.position])) throw new Error(`Layer "${layer.name}" has its position locked.`);
12271
- this.move = { id: layer.id, start: { x: sample.x, y: sample.y }, origin: { ...layer.offset }, moved: false };
12272
- return null;
12273
- }
12274
- if (tool === "brush" || tool === "eraser") {
12275
- this.stroke = this.controller.beginStroke({ tool });
12276
- this.stroke.push([sample]);
12277
- return null;
12278
- }
12279
- } catch (err) {
12280
- this.error = err instanceof Error ? err.message : String(err);
12281
- this.stroke = null;
12282
- this.move = null;
12283
- }
12284
- return this.error;
12285
- }
12286
- /** Feeds pointer samples (all coalesced events of one move, in order). */
12287
- moveTo(samples) {
12288
- if (!samples.length) return;
12289
- if (this.stroke) {
12290
- this.stroke.push(samples);
12291
- return;
12292
- }
12293
- const m = this.move;
12294
- if (m) {
12295
- const last = samples[samples.length - 1];
12296
- const x = m.origin.x + Math.round(last.x - m.start.x);
12297
- const y = m.origin.y + Math.round(last.y - m.start.y);
12298
- try {
12299
- this.controller.offsetLayer(m.id, { x, y }, !m.moved);
12300
- m.moved = true;
12301
- } catch (err) {
12302
- this.error = err instanceof Error ? err.message : String(err);
12303
- this.move = null;
12304
- }
12305
- }
12306
- }
12307
- up() {
12308
- if (this.stroke) {
12309
- try {
12310
- this.stroke.end();
12311
- } catch (err) {
12312
- this.error = err instanceof Error ? err.message : String(err);
12313
- }
12314
- }
12315
- this.stroke = null;
12316
- this.move = null;
12317
- }
12318
- cancel() {
12319
- _optionalChain([this, 'access', _265 => _265.stroke, 'optionalAccess', _266 => _266.cancel, 'call', _267 => _267()]);
12320
- this.stroke = null;
12321
- this.move = null;
12322
- }
12323
- }, _class9);
12324
-
12325
12964
  // src/image-editor/psd/ui.ts
12326
12965
  var PSD_FILE_ACCEPT = ".psd,.psb,image/vnd.adobe.photoshop,application/x-photoshop";
12327
12966
  function blobBytes(file) {
@@ -12762,5 +13401,30 @@ async function downloadPsd(controller, name = "image") {
12762
13401
 
12763
13402
 
12764
13403
 
12765
- 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 = _chunkH543GD6Tcjs.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 = _chunkH543GD6Tcjs.ZlibError; exports.activeAdjustmentLayers = activeAdjustmentLayers; exports.addLayerFilter = addLayerFilter; exports.addToHistogram = addToHistogram; exports.adjustmentKindLabel = adjustmentKindLabel; exports.adjustmentLayersKey = adjustmentLayersKey; exports.adjustmentNodeAsLayer = adjustmentNodeAsLayer; exports.adjustmentNodeFromLegacy = adjustmentNodeFromLegacy; exports.adler32 = _chunkH543GD6Tcjs.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 = _chunkH543GD6Tcjs.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 = _chunkH543GD6Tcjs.blendTile; exports.blurFilter = blurFilter; exports.borderCoverage = borderCoverage; exports.boxMean = boxMean; exports.boxToCurvePoint = boxToCurvePoint; exports.bradfordAdaptation = bradfordAdaptation; exports.buildLayerMaskPlanes = buildLayerMaskPlanes; exports.buildToneLut = buildToneLut; exports.bytesToBase64 = _chunkH543GD6Tcjs.bytesToBase64; exports.calculateCropDrag = calculateCropDrag; exports.canvasCompositeOperation = _chunkZOOEX3WTcjs.canvasCompositeOperation; exports.canvasToImagePoint = canvasToImagePoint; exports.changedTiles = _chunkH543GD6Tcjs.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.createImageLayerTools = createImageLayerTools; exports.createImagePaintTools = createImagePaintTools; exports.createImagePsdTools = createImagePsdTools; exports.createImageSelectionTools = createImageSelectionTools; exports.createPigment = _chunk4F3YDIWWcjs.createPigment; exports.createPigmentTools = _chunk4F3YDIWWcjs.createPigmentTools; exports.createSelectionMask = createSelectionMask; exports.curveLut = 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 = _chunkH543GD6Tcjs.decodePng; exports.decodePngDataUrl = decodePngDataUrl; exports.decodeSelectionRle = decodeSelectionRle; exports.defaultAdjustmentParams = defaultAdjustmentParams; exports.deflate = _chunkH543GD6Tcjs.deflate; exports.deflateRaw = _chunkH543GD6Tcjs.deflateRaw; exports.depthMaskAlpha = depthMaskAlpha; exports.depthRasterMask = depthRasterMask; exports.describeLayer = describeLayer; exports.describeSelection = describeSelection; 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 = _chunkH543GD6Tcjs.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 = _chunkH543GD6Tcjs.findLayer; exports.findLayerControl = findLayerControl; exports.finishTile = _chunkZOOEX3WTcjs.finishTile; exports.flattenLayers = _chunkH543GD6Tcjs.flattenLayers; exports.formatControlValue = formatControlValue; exports.fullSelection = fullSelection; exports.gaussianBlur = _chunkH543GD6Tcjs.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 = _chunkH543GD6Tcjs.inflate; exports.inflateRaw = _chunkH543GD6Tcjs.inflateRaw; exports.insertCurvePoint = insertCurvePoint; exports.insertLayer = _chunkH543GD6Tcjs.insertLayer; exports.invertMatrix3 = invertMatrix3; exports.invertSelection = invertSelection; exports.isActiveFilter = isActiveFilter; exports.isAdjustmentKind = isAdjustmentKind; exports.isBlendMode = _chunkZOOEX3WTcjs.isBlendMode; exports.isDefaultDepthMask = isDefaultDepthMask; exports.isLayerLocked = _chunkH543GD6Tcjs.isLayerLocked; exports.isLegacyShape = isLegacyShape; exports.isPaintTool = isPaintTool; exports.isPng = _chunkH543GD6Tcjs.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.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 = _chunkH543GD6Tcjs.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 = _chunkH543GD6Tcjs.parseDataUrl; exports.parseSelectionMode = parseSelectionMode; exports.parseVersionedDescriptor = parseVersionedDescriptor; exports.photoFilterMatrix = photoFilterMatrix; exports.pixelLayerBounds = pixelLayerBounds; exports.pixelLayers = pixelLayers; exports.placeLayer = placeLayer; exports.pngDataUrl = _chunkH543GD6Tcjs.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.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.serializeLayer = serializeLayer; exports.serializeLayers = serializeLayers; exports.serializeLayersExternal = serializeLayersExternal; exports.serializeSelection = serializeSelection; exports.setControlPath = setControlPath; 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.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;
13404
+
13405
+
13406
+
13407
+
13408
+
13409
+
13410
+
13411
+
13412
+
13413
+
13414
+
13415
+
13416
+
13417
+
13418
+
13419
+
13420
+
13421
+
13422
+
13423
+
13424
+
13425
+
13426
+
13427
+
13428
+
13429
+ 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_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 = _chunkT6H3JDGAcjs.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.LEGACY_PROCESS_VERSION = LEGACY_PROCESS_VERSION; exports.LUMA_709 = LUMA_709; exports.LayerCompositor = LayerCompositor; exports.LayerOperationError = LayerOperationError; exports.MAX_BRUSH_SIZE = _chunkZZOTHJ4Kcjs.MAX_BRUSH_SIZE; 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.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.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 = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.blendTile; exports.blurFilter = blurFilter; exports.borderCoverage = borderCoverage; exports.boxMean = boxMean; exports.boxToCurvePoint = boxToCurvePoint; exports.bradfordAdaptation = bradfordAdaptation; exports.buildLayerMaskPlanes = buildLayerMaskPlanes; exports.buildToneLut = buildToneLut; exports.bytesToBase64 = _chunkT6H3JDGAcjs.bytesToBase64; exports.calculateCropDrag = calculateCropDrag; exports.canvasCompositeOperation = _chunkCRMAXIUVcjs.canvasCompositeOperation; exports.canvasToImagePoint = canvasToImagePoint; exports.changedTiles = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.decodePng; exports.decodePngDataUrl = decodePngDataUrl; exports.decodeSelectionRle = decodeSelectionRle; exports.defaultAdjustmentParams = defaultAdjustmentParams; exports.deflate = _chunkT6H3JDGAcjs.deflate; exports.deflateRaw = _chunkT6H3JDGAcjs.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 = _chunkCRMAXIUVcjs.emptySurface; exports.encodePng = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.findLayer; exports.findLayerControl = findLayerControl; exports.finishTile = _chunkCRMAXIUVcjs.finishTile; exports.flattenLayers = _chunkT6H3JDGAcjs.flattenLayers; exports.formatControlValue = formatControlValue; exports.fullSelection = fullSelection; exports.gaussianBlur = _chunkT6H3JDGAcjs.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 = _chunkT6H3JDGAcjs.inflate; exports.inflateRaw = _chunkT6H3JDGAcjs.inflateRaw; exports.insertCurvePoint = insertCurvePoint; exports.insertLayer = _chunkT6H3JDGAcjs.insertLayer; exports.invertMatrix3 = invertMatrix3; exports.invertSelection = invertSelection; exports.isActiveFilter = isActiveFilter; exports.isAdjustmentKind = isAdjustmentKind; exports.isBlendMode = _chunkCRMAXIUVcjs.isBlendMode; exports.isDefaultDepthMask = isDefaultDepthMask; exports.isLayerLocked = _chunkT6H3JDGAcjs.isLayerLocked; exports.isLegacyShape = isLegacyShape; exports.isPaintTool = isPaintTool; exports.isPng = _chunkT6H3JDGAcjs.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.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 = _chunkT6H3JDGAcjs.mapLayer; exports.maskSummary = maskSummary; 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.newLayerId = newLayerId; exports.normalizeAdjustmentLayer = normalizeAdjustmentLayer; exports.normalizeAdjustmentLayers = normalizeAdjustmentLayers; exports.normalizeAngle = normalizeAngle; exports.normalizeBlendMode = _chunkCRMAXIUVcjs.normalizeBlendMode; exports.normalizeBrush = _chunkZZOTHJ4Kcjs.normalizeBrush; exports.normalizeFilter = normalizeFilter; 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 = _chunkT6H3JDGAcjs.parseDataUrl; exports.parseSelectionMode = parseSelectionMode; exports.parseVersionedDescriptor = parseVersionedDescriptor; exports.photoFilterMatrix = photoFilterMatrix; exports.pixelLayerBounds = pixelLayerBounds; exports.pixelLayers = pixelLayers; exports.placeLayer = placeLayer; exports.pngDataUrl = _chunkT6H3JDGAcjs.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 = _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.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.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 = _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.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.writePsd = writePsd; exports.writeRegion = _chunkCRMAXIUVcjs.writeRegion; exports.xyToTempTint = xyToTempTint; exports.xyToUv = xyToUv;
12766
13430
  //# sourceMappingURL=index.cjs.map