@pixerate/editor 0.275.1 → 0.276.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 (65) hide show
  1. package/dist/animation-editor/index.cjs +62 -62
  2. package/dist/animation-editor/index.js +6 -6
  3. package/dist/brushes/index.cjs +81 -70
  4. package/dist/brushes/index.js +17 -6
  5. package/dist/brushes/patch.d.cts +1 -1
  6. package/dist/brushes/patch.d.ts +1 -1
  7. package/dist/brushes/profiles.d.cts +2 -0
  8. package/dist/brushes/profiles.d.ts +2 -0
  9. package/dist/brushes/schema.d.cts +1 -0
  10. package/dist/brushes/schema.d.ts +1 -0
  11. package/dist/brushes/types.d.cts +22 -1
  12. package/dist/brushes/types.d.ts +22 -1
  13. package/dist/{brushstrokeRender-WGY4DZHF.js → brushstrokeRender-FK3ASUUJ.js} +5 -5
  14. package/dist/{brushstrokeRender-2RQL46WB.cjs → brushstrokeRender-I6MYFCOU.cjs} +21 -21
  15. package/dist/canvas/index.cjs +13 -13
  16. package/dist/canvas/index.js +1 -1
  17. package/dist/{chunk-Y2ISSVPH.js → chunk-4EM5NGCL.js} +167 -9
  18. package/dist/{chunk-Y354ETAE.cjs → chunk-5HR5CSLC.cjs} +49 -49
  19. package/dist/{chunk-LMG57L5A.js → chunk-CTHWXW5M.js} +121 -8
  20. package/dist/{chunk-43XJC3PP.js → chunk-CVBTJVRN.js} +1 -1
  21. package/dist/{chunk-RJGW3RQS.js → chunk-GHYJAMMS.js} +1 -1
  22. package/dist/{chunk-NIBFKXMD.cjs → chunk-IFWLZZCW.cjs} +619 -2
  23. package/dist/{chunk-G5TCMKX5.js → chunk-IJ6NSWKM.js} +2 -2
  24. package/dist/{chunk-C6VB7CPY.cjs → chunk-ISCAJBPQ.cjs} +1 -1
  25. package/dist/{chunk-W6JDUXP3.js → chunk-J23JOHPR.js} +1 -1
  26. package/dist/{chunk-IEEY5RJV.js → chunk-JNMNM3SL.js} +1 -1
  27. package/dist/{chunk-HVO6XCI4.js → chunk-JPB65KQ6.js} +1 -1
  28. package/dist/{chunk-ACTHSQOI.js → chunk-LDZOXESA.js} +618 -1
  29. package/dist/{chunk-DHC4E2DU.cjs → chunk-MITQGHN3.cjs} +121 -8
  30. package/dist/{chunk-STLTOISW.cjs → chunk-NPPMKMCU.cjs} +17 -17
  31. package/dist/{chunk-75SYKUOT.js → chunk-OS6OG7DN.js} +1 -1
  32. package/dist/{chunk-OLZXXAER.cjs → chunk-OY24XRYF.cjs} +408 -250
  33. package/dist/{chunk-6QNDGMK7.cjs → chunk-Q33V5PEF.cjs} +123 -42
  34. package/dist/{chunk-JDXWLCXF.cjs → chunk-QNNZA3V5.cjs} +2 -2
  35. package/dist/{chunk-T6KNJVBP.cjs → chunk-U26LUXCJ.cjs} +35 -35
  36. package/dist/{chunk-62MFUHSI.cjs → chunk-UQXULAMQ.cjs} +16 -16
  37. package/dist/{chunk-RAPNRK4R.cjs → chunk-X7XBEX3O.cjs} +88 -88
  38. package/dist/{chunk-MSWLJI4G.js → chunk-XMSH66VU.js} +2 -2
  39. package/dist/{chunk-ZM7IKQ4X.js → chunk-XVPQNX7O.js} +89 -8
  40. package/dist/{chunk-YYZC2EQO.cjs → chunk-ZIE6EJGR.cjs} +23 -23
  41. package/dist/image-editor/index.cjs +880 -852
  42. package/dist/image-editor/index.js +36 -8
  43. package/dist/paint/index.cjs +33 -5
  44. package/dist/paint/index.d.cts +1 -0
  45. package/dist/paint/index.d.ts +1 -0
  46. package/dist/paint/index.js +32 -4
  47. package/dist/paint/live-patterns.d.cts +149 -0
  48. package/dist/paint/live-patterns.d.ts +149 -0
  49. package/dist/paint/wet/world.d.cts +13 -0
  50. package/dist/paint/wet/world.d.ts +13 -0
  51. package/dist/paint-editor/brush-model.d.cts +7 -1
  52. package/dist/paint-editor/brush-model.d.ts +7 -1
  53. package/dist/paint-editor/controller.d.cts +52 -0
  54. package/dist/paint-editor/controller.d.ts +52 -0
  55. package/dist/paint-editor/index.cjs +850 -510
  56. package/dist/paint-editor/index.js +355 -15
  57. package/dist/paint-editor/ui.d.cts +5 -1
  58. package/dist/paint-editor/ui.d.ts +5 -1
  59. package/dist/paint-editor/wet-tools.d.cts +42 -0
  60. package/dist/paint-editor/wet-tools.d.ts +42 -0
  61. package/dist/paint-editor/wet.d.cts +22 -1
  62. package/dist/paint-editor/wet.d.ts +22 -1
  63. package/dist/vector/index.cjs +1002 -1002
  64. package/dist/vector/index.js +7 -7
  65. package/package.json +1 -1
@@ -14,7 +14,7 @@ var _chunk3VHH6V67cjs = require('../chunk-3VHH6V67.cjs');
14
14
 
15
15
 
16
16
 
17
- var _chunkY354ETAEcjs = require('../chunk-Y354ETAE.cjs');
17
+ var _chunk5HR5CSLCcjs = require('../chunk-5HR5CSLC.cjs');
18
18
 
19
19
 
20
20
 
@@ -22,7 +22,7 @@ var _chunkPFHJS4HEcjs = require('../chunk-PFHJS4HE.cjs');
22
22
 
23
23
 
24
24
 
25
- var _chunkJDXWLCXFcjs = require('../chunk-JDXWLCXF.cjs');
25
+ var _chunkQNNZA3V5cjs = require('../chunk-QNNZA3V5.cjs');
26
26
 
27
27
 
28
28
  var _chunkLBDC5434cjs = require('../chunk-LBDC5434.cjs');
@@ -42,7 +42,7 @@ var _chunkYH6SKC7Pcjs = require('../chunk-YH6SKC7P.cjs');
42
42
 
43
43
 
44
44
 
45
- var _chunkRAPNRK4Rcjs = require('../chunk-RAPNRK4R.cjs');
45
+ var _chunkX7XBEX3Ocjs = require('../chunk-X7XBEX3O.cjs');
46
46
  require('../chunk-YZWM6ZIP.cjs');
47
47
  require('../chunk-3ZRNK3RO.cjs');
48
48
 
@@ -68,7 +68,7 @@ require('../chunk-K6PXS6DO.cjs');
68
68
 
69
69
 
70
70
 
71
- var _chunk62MFUHSIcjs = require('../chunk-62MFUHSI.cjs');
71
+ var _chunkUQXULAMQcjs = require('../chunk-UQXULAMQ.cjs');
72
72
  require('../chunk-BB6TR422.cjs');
73
73
  require('../chunk-BROJYMWU.cjs');
74
74
 
@@ -125,7 +125,7 @@ var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
125
125
 
126
126
 
127
127
 
128
- var _chunkOLZXXAERcjs = require('../chunk-OLZXXAER.cjs');
128
+ var _chunkOY24XRYFcjs = require('../chunk-OY24XRYF.cjs');
129
129
 
130
130
 
131
131
 
@@ -198,7 +198,7 @@ var _chunkOLZXXAERcjs = require('../chunk-OLZXXAER.cjs');
198
198
 
199
199
 
200
200
 
201
- var _chunk6QNDGMK7cjs = require('../chunk-6QNDGMK7.cjs');
201
+ var _chunkQ33V5PEFcjs = require('../chunk-Q33V5PEF.cjs');
202
202
 
203
203
 
204
204
 
@@ -248,8 +248,8 @@ require('../chunk-WOFXZ3XU.cjs');
248
248
 
249
249
 
250
250
 
251
- var _chunkDHC4E2DUcjs = require('../chunk-DHC4E2DU.cjs');
252
- require('../chunk-STLTOISW.cjs');
251
+ var _chunkMITQGHN3cjs = require('../chunk-MITQGHN3.cjs');
252
+ require('../chunk-NPPMKMCU.cjs');
253
253
 
254
254
 
255
255
 
@@ -300,7 +300,11 @@ require('../chunk-STLTOISW.cjs');
300
300
 
301
301
 
302
302
 
303
- var _chunkNIBFKXMDcjs = require('../chunk-NIBFKXMD.cjs');
303
+
304
+
305
+
306
+
307
+ var _chunkIFWLZZCWcjs = require('../chunk-IFWLZZCW.cjs');
304
308
 
305
309
 
306
310
 
@@ -405,7 +409,7 @@ function normalizeCanvas(raw) {
405
409
  function createPaintDocument(options = {}) {
406
410
  const canvas = normalizeCanvas({ width: _nullishCoalesce(options.width, () => ( 2048)), height: _nullishCoalesce(options.height, () => ( 1536)), dpi: options.dpi });
407
411
  const layer = createPaintLayer("Layer 1");
408
- return { canvas, paper: _chunkOLZXXAERcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
412
+ return { canvas, paper: _chunkOY24XRYFcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
409
413
  }
410
414
 
411
415
  // src/paint-editor/thick.ts
@@ -528,17 +532,17 @@ function lightTile(color, height, heightAround, material, light, film = null, vi
528
532
  filmRgb = thinFilmRgb(opd);
529
533
  }
530
534
  for (let c = 0; c < 3; c++) {
531
- const a = _chunkDHC4E2DUcjs.SRGB_TO_LINEAR[color[i + c]];
535
+ const a = _chunkMITQGHN3cjs.SRGB_TO_LINEAR[color[i + c]];
532
536
  const fc = filmRgb ? filmRgb[c] : a;
533
537
  if (hasSlope) {
534
538
  const tint = metal * a + (1 - metal);
535
539
  const diff = fa > 0 ? a * (1 - fa * 0.75) + fc * fa * (0.45 + 0.55 * a) : a;
536
540
  const specTint = fa > 0 ? tint * (1 - fa) + fc * fa : tint;
537
541
  const v = diff * shade * (1 - 0.35 * metal) + spec * specTint * (1 + metal);
538
- out[i + c] = _chunkDHC4E2DUcjs.linearToSrgb8.call(void 0, v);
542
+ out[i + c] = _chunkMITQGHN3cjs.linearToSrgb8.call(void 0, v);
539
543
  } else {
540
544
  const v = a * (1 - fa * 0.75) + fc * fa * (0.45 + 0.55 * a);
541
- out[i + c] = _chunkDHC4E2DUcjs.linearToSrgb8.call(void 0, v);
545
+ out[i + c] = _chunkMITQGHN3cjs.linearToSrgb8.call(void 0, v);
542
546
  }
543
547
  }
544
548
  }
@@ -729,20 +733,20 @@ var ThickStrokeDriver = (_class3 = class {
729
733
  constructor(init) {;_class3.prototype.__init3.call(this);_class3.prototype.__init4.call(this);_class3.prototype.__init5.call(this);_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);_class3.prototype.__init11.call(this);_class3.prototype.__init12.call(this);
730
734
  this.init = init;
731
735
  const b = init.brush;
732
- this.smoother = new (0, _chunkOLZXXAERcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
733
- const copies = init.copies.length ? init.copies : [_chunkOLZXXAERcjs.IDENTITY_COPY];
736
+ this.smoother = new (0, _chunkOY24XRYFcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
737
+ const copies = init.copies.length ? init.copies : [_chunkOY24XRYFcjs.IDENTITY_COPY];
734
738
  this.copies = copies;
735
- const rates = _chunkNIBFKXMDcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
739
+ const rates = _chunkIFWLZZCWcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
736
740
  this.states = copies.map((c, i) => ({
737
- walker: new (0, _chunkOLZXXAERcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
738
- exchange: new (0, _chunkNIBFKXMDcjs.PaintExchange)(rates, init.load),
739
- smudge: b.impasto.tool === "knife" ? new (0, _chunkNIBFKXMDcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
741
+ walker: new (0, _chunkOY24XRYFcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
742
+ exchange: new (0, _chunkIFWLZZCWcjs.PaintExchange)(rates, init.load),
743
+ smudge: b.impasto.tool === "knife" ? new (0, _chunkIFWLZZCWcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
740
744
  carried: null,
741
745
  amount: 1
742
746
  }));
743
- this.medium = new (0, _chunkNIBFKXMDcjs.TileMedium)(init.target, {});
747
+ this.medium = new (0, _chunkIFWLZZCWcjs.TileMedium)(init.target, {});
744
748
  this.film = b.iridescence ? new FilmBuffer(init.channels.film, init.target.offset) : null;
745
- this.sampler = init.paint ? new (0, _chunkNIBFKXMDcjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
749
+ this.sampler = init.paint ? new (0, _chunkIFWLZZCWcjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
746
750
  }
747
751
 
748
752
  __init3() {this.dabCount = 0}
@@ -844,7 +848,7 @@ var ThickStrokeDriver = (_class3 = class {
844
848
  }
845
849
  applyDabs(copy, dabs, rects) {
846
850
  for (const d of dabs) {
847
- const rect = _chunkNIBFKXMDcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
851
+ const rect = _chunkIFWLZZCWcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
848
852
  if (rect.width <= 0 || rect.height <= 0) continue;
849
853
  this.dab(copy, d, rect);
850
854
  rects.push(rect);
@@ -859,7 +863,7 @@ var ThickStrokeDriver = (_class3 = class {
859
863
  const n = rect.width * rect.height;
860
864
  if (this.tip.length < n) this.tip = new Float32Array(n);
861
865
  const tip = this.tip.subarray(0, n);
862
- _chunkNIBFKXMDcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
866
+ _chunkIFWLZZCWcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
863
867
  const sel = this.init.target.selection;
864
868
  if (sel) {
865
869
  for (let yy = 0, p = 0; yy < rect.height; yy++)
@@ -887,7 +891,7 @@ var ThickStrokeDriver = (_class3 = class {
887
891
  let flow = 1;
888
892
  const effect = this.init.effect;
889
893
  if (effect) {
890
- _chunkOLZXXAERcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
894
+ _chunkOY24XRYFcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
891
895
  ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
892
896
  } else if (this.sampler) {
893
897
  const g = this.sampler.dab(d, this.sample);
@@ -904,7 +908,7 @@ var ThickStrokeDriver = (_class3 = class {
904
908
  let field = null;
905
909
  if (effect) {
906
910
  field = new Float32Array(n * 3);
907
- _chunkOLZXXAERcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
911
+ _chunkOY24XRYFcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
908
912
  }
909
913
  this.medium.deposit(rect, cov, dep, this.paint, ex.paintPigment, field);
910
914
  }
@@ -1102,7 +1106,7 @@ function shadowToLight(shadow) {
1102
1106
  return new (0, _chunk474IQG74cjs.TiledSurface)(1, tiles, 0);
1103
1107
  }
1104
1108
  function lightTwinBrush(brush) {
1105
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0,
1109
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0,
1106
1110
  {
1107
1111
  tip: { ...brush.tip, blend: "normal", pressureOpacity: brush.tip.pressureOpacity || brush.light.pressure },
1108
1112
  behavior: { ...brush.behavior, mixing: "rgb" },
@@ -1324,7 +1328,7 @@ function uvPaper(paper, uv) {
1324
1328
  if (!uv.on || uv.ambient >= 1) return paper;
1325
1329
  const cached = uvPapers.get(paper);
1326
1330
  if (cached && cached.ambient === uv.ambient) return cached.paper;
1327
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, paper.color);
1331
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, paper.color);
1328
1332
  const toHex = (v) => Math.round(Math.min(255, Math.max(0, v * uv.ambient))).toString(16).padStart(2, "0");
1329
1333
  const next = { ...paper, color: `#${toHex(r)}${toHex(g)}${toHex(b)}` };
1330
1334
  uvPapers.set(paper, { ambient: uv.ambient, paper: next });
@@ -1350,7 +1354,7 @@ function fluorTwinBrush(brush) {
1350
1354
  if (brush.engine === "eraser" || brush.engine === "smudge" || brush.engine === "blender") return base;
1351
1355
  const move = brush.engine === "impasto" ? brush.impasto.tool === "knife" ? "smudge" : "dab" : brush.engine;
1352
1356
  if (f > 0) {
1353
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0,
1357
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0,
1354
1358
  {
1355
1359
  ...base,
1356
1360
  engine: move,
@@ -1360,9 +1364,9 @@ function fluorTwinBrush(brush) {
1360
1364
  );
1361
1365
  }
1362
1366
  if (brush.engine === "mixer" || brush.behavior.pickup > 0 || brush.engine === "impasto" && brush.impasto.tool === "knife") {
1363
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...base, engine: move }, base);
1367
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...base, engine: move }, base);
1364
1368
  }
1365
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0,
1369
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0,
1366
1370
  {
1367
1371
  ...base,
1368
1372
  engine: "eraser",
@@ -1385,12 +1389,12 @@ function thermoTwinBrush(brush) {
1385
1389
  if (brush.engine === "eraser" || brush.engine === "smudge" || brush.engine === "blender") return base;
1386
1390
  const move = brush.engine === "impasto" ? brush.impasto.tool === "knife" ? "smudge" : "dab" : brush.engine;
1387
1391
  if (active) {
1388
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...base, engine: move, behavior: { ...base.behavior, pickup: 0 } }, base);
1392
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...base, engine: move, behavior: { ...base.behavior, pickup: 0 } }, base);
1389
1393
  }
1390
1394
  if (brush.engine === "mixer" || brush.behavior.pickup > 0 || brush.engine === "impasto" && brush.impasto.tool === "knife") {
1391
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...base, engine: move }, base);
1395
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...base, engine: move }, base);
1392
1396
  }
1393
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...base, engine: "eraser", tip: { ...base.tip, opacity: brush.tip.opacity } }, base);
1397
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...base, engine: "eraser", tip: { ...base.tip, opacity: brush.tip.opacity } }, base);
1394
1398
  }
1395
1399
  function finalizeThermoStroke(twinOut, before, hotRgb, threshold) {
1396
1400
  const thByte = Math.max(1, Math.min(255, Math.round(threshold * 255)));
@@ -1527,9 +1531,9 @@ var UvCache = (_class5 = class {constructor() { _class5.prototype.__init15.call(
1527
1531
  const fGain = fa / 255 * str;
1528
1532
  const fCov = Math.min(1, fGain);
1529
1533
  for (let c = 0; c < 3; c++) {
1530
- const baseLin = ca > 0 ? _chunkDHC4E2DUcjs.SRGB_TO_LINEAR[cd[i + c]] * amb : 0;
1531
- const emLin = fa > 0 ? _chunkDHC4E2DUcjs.SRGB_TO_LINEAR[fd[i + c]] * (1 + 1.15 * fGain) : 0;
1532
- dst[i + c] = _chunkDHC4E2DUcjs.linearToSrgb8.call(void 0, baseLin * (1 - fCov * 0.5) + emLin * fCov);
1534
+ const baseLin = ca > 0 ? _chunkMITQGHN3cjs.SRGB_TO_LINEAR[cd[i + c]] * amb : 0;
1535
+ const emLin = fa > 0 ? _chunkMITQGHN3cjs.SRGB_TO_LINEAR[fd[i + c]] * (1 + 1.15 * fGain) : 0;
1536
+ dst[i + c] = _chunkMITQGHN3cjs.linearToSrgb8.call(void 0, baseLin * (1 - fCov * 0.5) + emLin * fCov);
1533
1537
  }
1534
1538
  dst[i + 3] = Math.min(255, Math.max(ca, Math.round(fa * Math.min(1, str))));
1535
1539
  }
@@ -1873,18 +1877,18 @@ var MarkStroke = (_class7 = class {
1873
1877
  constructor(brush, options) {;_class7.prototype.__init18.call(this);_class7.prototype.__init19.call(this);_class7.prototype.__init20.call(this);_class7.prototype.__init21.call(this);_class7.prototype.__init22.call(this);_class7.prototype.__init23.call(this);_class7.prototype.__init24.call(this);_class7.prototype.__init25.call(this);
1874
1878
  this.brush = brush;
1875
1879
  this.options = options;
1876
- this.sampler = options.paint ? new (0, _chunkNIBFKXMDcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
1877
- this.tipTable = _optionalChain([this, 'access', _44 => _44.sampler, 'optionalAccess', _45 => _45.acrossTip]) ? this.sampler.tipTable(_chunkNIBFKXMDcjs.TIP_GRADIENT_STEPS) : null;
1878
- this.smoother = new (0, _chunkOLZXXAERcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
1879
- this.copies = _optionalChain([options, 'access', _46 => _46.copies, 'optionalAccess', _47 => _47.length]) ? options.copies : [_chunkOLZXXAERcjs.IDENTITY_COPY];
1880
+ this.sampler = options.paint ? new (0, _chunkIFWLZZCWcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
1881
+ this.tipTable = _optionalChain([this, 'access', _44 => _44.sampler, 'optionalAccess', _45 => _45.acrossTip]) ? this.sampler.tipTable(_chunkIFWLZZCWcjs.TIP_GRADIENT_STEPS) : null;
1882
+ this.smoother = new (0, _chunkOY24XRYFcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
1883
+ this.copies = _optionalChain([options, 'access', _46 => _46.copies, 'optionalAccess', _47 => _47.length]) ? options.copies : [_chunkOY24XRYFcjs.IDENTITY_COPY];
1880
1884
  this.seed = _nullishCoalesce(options.seed, () => ( 0));
1881
1885
  const fine = { ...brush, tip: { ...brush.tip, spacing: Math.max(0.01, Math.min(0.25, STEP_PX / Math.max(1, brush.tip.size))) } };
1882
- this.walkers = this.copies.map((c, i) => new (0, _chunkOLZXXAERcjs.PenDabWalker)(fine, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear));
1886
+ this.walkers = this.copies.map((c, i) => new (0, _chunkOY24XRYFcjs.PenDabWalker)(fine, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear));
1883
1887
  this.depth = options.grain && !options.grain.flat ? Math.min(1, Math.max(0, options.paperDepth * brush.grain)) : 0;
1884
1888
  }
1885
1889
 
1886
1890
 
1887
- __init18() {this.coverage = new (0, _chunkNIBFKXMDcjs.CoverageMap)()}
1891
+ __init18() {this.coverage = new (0, _chunkIFWLZZCWcjs.CoverageMap)()}
1888
1892
  __init19() {this.dabCount = 0}
1889
1893
 
1890
1894
 
@@ -1945,11 +1949,11 @@ var MarkStroke = (_class7 = class {
1945
1949
  if (!(r > 0.05) || !(alpha > 0)) return;
1946
1950
  const dab = { x, y, radius: Math.max(0.5, r), alpha: Math.min(1, alpha), opacity: Math.min(1, opacity), angle: 0, roundness: 1 };
1947
1951
  const hardness = this.brush.tip.hardness;
1948
- const rect = _chunkNIBFKXMDcjs.dabRect.call(void 0, dab, hardness);
1952
+ const rect = _chunkIFWLZZCWcjs.dabRect.call(void 0, dab, hardness);
1949
1953
  const n = rect.width * rect.height;
1950
1954
  if (n <= 0) return;
1951
1955
  const vals = this.scratch(n);
1952
- _chunkNIBFKXMDcjs.rasterizeDab.call(void 0, dab, hardness, rect, vals);
1956
+ _chunkIFWLZZCWcjs.rasterizeDab.call(void 0, dab, hardness, rect, vals);
1953
1957
  this.lay(rect, vals, dab.opacity, pressure, x, y, rects);
1954
1958
  }
1955
1959
  /**
@@ -1958,7 +1962,7 @@ var MarkStroke = (_class7 = class {
1958
1962
  */
1959
1963
  stamp(x, y, r, kind, rotation, seed, alpha, opacity, pressure, rects) {
1960
1964
  if (!(r > 0.05) || !(alpha > 0)) return;
1961
- const sample = _chunkOLZXXAERcjs.stampSampler.call(void 0, kind, this.options.stampArt);
1965
+ const sample = _chunkOY24XRYFcjs.stampSampler.call(void 0, kind, this.options.stampArt);
1962
1966
  if (!sample) return this.mark(x, y, r, alpha, opacity, pressure, rects);
1963
1967
  const reach = Math.max(0.5, r) * Math.SQRT2 + 1;
1964
1968
  const rect = { x: Math.floor(x - reach), y: Math.floor(y - reach), width: 0, height: 0 };
@@ -2003,12 +2007,12 @@ var MarkStroke = (_class7 = class {
2003
2007
  const grain = this.options.grain;
2004
2008
  if (this.depth > 0 && grain) {
2005
2009
  for (let yy = 0, k = 0; yy < rect.height; yy++)
2006
- for (let xx = 0; xx < rect.width; xx++, k++) if (vals[k] > 0) vals[k] *= _chunkNIBFKXMDcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, pressure);
2010
+ for (let xx = 0; xx < rect.width; xx++, k++) if (vals[k] > 0) vals[k] *= _chunkIFWLZZCWcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, pressure);
2007
2011
  }
2008
2012
  if (this.options.effect) {
2009
2013
  if (this.field.length < n * 3) this.field = new Float32Array(n * 3);
2010
2014
  const field = this.field.subarray(0, n * 3);
2011
- _chunkOLZXXAERcjs.sampleEffectField.call(void 0, this.options.effect, rect, vals, field, this.pen);
2015
+ _chunkOY24XRYFcjs.sampleEffectField.call(void 0, this.options.effect, rect, vals, field, this.pen);
2012
2016
  this.coverage.accumulate(rect, vals, opacity, null, field);
2013
2017
  } else {
2014
2018
  const color = this.markColor(x, y);
@@ -2688,12 +2692,12 @@ var StickerSpray = (_class10 = class {
2688
2692
  constructor(init) {;_class10.prototype.__init33.call(this);_class10.prototype.__init34.call(this);_class10.prototype.__init35.call(this);_class10.prototype.__init36.call(this);_class10.prototype.__init37.call(this);
2689
2693
  this.init = init;
2690
2694
  const b = init.brush;
2691
- this.smoother = new (0, _chunkOLZXXAERcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
2692
- this.copies = init.copies.length ? init.copies : [_chunkOLZXXAERcjs.IDENTITY_COPY];
2695
+ this.smoother = new (0, _chunkOY24XRYFcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
2696
+ this.copies = init.copies.length ? init.copies : [_chunkOY24XRYFcjs.IDENTITY_COPY];
2693
2697
  const spacing = Math.max(0.05, 1 / Math.max(0.05, b.sticker.density * 4));
2694
2698
  const walk = { ...b, tip: { ...b.tip, spacing }, dynamics: { ...b.dynamics, scatter: 0, sizeJitter: 0, angleJitter: 0 } };
2695
- this.walkers = this.copies.map((c, i) => new (0, _chunkOLZXXAERcjs.PenDabWalker)(walk, init.seed + i * 7919 | 0, c.linear));
2696
- this.medium = new (0, _chunkNIBFKXMDcjs.TileMedium)(init.target, {});
2699
+ this.walkers = this.copies.map((c, i) => new (0, _chunkOY24XRYFcjs.PenDabWalker)(walk, init.seed + i * 7919 | 0, c.linear));
2700
+ this.medium = new (0, _chunkIFWLZZCWcjs.TileMedium)(init.target, {});
2697
2701
  this.next = init.nextId;
2698
2702
  }
2699
2703
 
@@ -2778,18 +2782,18 @@ var StickerSpray = (_class10 = class {
2778
2782
  const effect = this.init.effect;
2779
2783
  if (effect) {
2780
2784
  const rgb = [0, 0, 0];
2781
- const alpha = _chunkOLZXXAERcjs.sampleEffectAt.call(void 0, effect, d.x + dx, d.y + dy, rgb, d);
2785
+ const alpha = _chunkOY24XRYFcjs.sampleEffectAt.call(void 0, effect, d.x + dx, d.y + dy, rgb, d);
2782
2786
  return { color: "#" + rgb.map((c) => Math.round(c * 255).toString(16).padStart(2, "0")).join(""), alpha };
2783
2787
  }
2784
2788
  const g = this.init.paint;
2785
2789
  if (!g) return { color: this.init.color, alpha: 1 };
2786
- this.sampler ??= new (0, _chunkNIBFKXMDcjs.PaintGradientSampler)(g, this.init.seed);
2790
+ this.sampler ??= new (0, _chunkIFWLZZCWcjs.PaintGradientSampler)(g, this.init.seed);
2787
2791
  const s = g.map.by === "across-tip" ? this.sampler.sample(((dx * Math.sin(d.direction) + dy * Math.cos(d.direction)) / Math.max(0.5, d.radius) + 1) / 2) : this.sampler.dab(d);
2788
2792
  return { color: "#" + s.rgb.map((c) => Math.round(Math.min(1, Math.max(0, c)) * 255).toString(16).padStart(2, "0")).join(""), alpha: s.alpha };
2789
2793
  }
2790
2794
  }, _class10);
2791
2795
  function renderStickers(stickers, target, art) {
2792
- const medium = new (0, _chunkNIBFKXMDcjs.TileMedium)(target, {});
2796
+ const medium = new (0, _chunkIFWLZZCWcjs.TileMedium)(target, {});
2793
2797
  for (const s of stickers) drawSticker(medium, s, art);
2794
2798
  }
2795
2799
  function normalizeStickerUpdate(u) {
@@ -2907,7 +2911,7 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
2907
2911
  this.layerId = init.layerId;
2908
2912
  this.base = init.surface;
2909
2913
  this.live = new Map(this.base.tiles);
2910
- this.copies = init.copies.length ? init.copies : [_chunkOLZXXAERcjs.IDENTITY_COPY];
2914
+ this.copies = init.copies.length ? init.copies : [_chunkOY24XRYFcjs.IDENTITY_COPY];
2911
2915
  const brush = init.brush;
2912
2916
  this.invisibleDaylight = brush.fluorescence.amount > 0 && brush.fluorescence.invisible && brush.engine !== "eraser" && brush.engine !== "blender" && brush.engine !== "smudge";
2913
2917
  if (init.wet) this.wetDriver = init.wet.driver;
@@ -2975,9 +2979,9 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
2975
2979
  if (init.thick && (brush.iridescence || brush.engine === "eraser")) {
2976
2980
  this.filmBuffer = new FilmBuffer(init.thick.channels.film, init.offset, _nullishCoalesce(init.selection, () => ( null)));
2977
2981
  }
2978
- if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunk6QNDGMK7cjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
2982
+ if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkQ33V5PEFcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
2979
2983
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
2980
- this.wet = new (0, _chunkOLZXXAERcjs.PaintDabStroke)(brush, {
2984
+ this.wet = new (0, _chunkOY24XRYFcjs.PaintDabStroke)(brush, {
2981
2985
  target: this.tileTarget(),
2982
2986
  color: rgb(init.color),
2983
2987
  secondary: rgb(_nullishCoalesce(init.secondary, () => ( init.background))),
@@ -2993,7 +2997,7 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
2993
2997
  });
2994
2998
  } else {
2995
2999
  const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect, stampArt: init.stampArt, film: this.filmBuffer };
2996
- this.dry = brush.engine === "particle" ? new ParticleStroke(brush, opts) : brush.engine === "bristle" ? new BristleStroke(brush, opts) : new (0, _chunkOLZXXAERcjs.DryStroke)(brush, opts);
3000
+ this.dry = brush.engine === "particle" ? new ParticleStroke(brush, opts) : brush.engine === "bristle" ? new BristleStroke(brush, opts) : new (0, _chunkOY24XRYFcjs.DryStroke)(brush, opts);
2997
3001
  }
2998
3002
  }
2999
3003
  }
@@ -3072,7 +3076,7 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
3072
3076
  makeThermoTwin(thermo) {
3073
3077
  const init = this.init;
3074
3078
  const hotHex = init.brush.thermochromic.hotColor;
3075
- const hotRgb = hotHex ? _chunkOLZXXAERcjs.hexToRgb8.call(void 0, hotHex) : [0, 0, 0];
3079
+ const hotRgb = hotHex ? _chunkOY24XRYFcjs.hexToRgb8.call(void 0, hotHex) : [0, 0, 0];
3076
3080
  const threshold = init.brush.thermochromic.threshold;
3077
3081
  const host = {
3078
3082
  update: (_id, surface) => {
@@ -3187,7 +3191,7 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
3187
3191
  const changed = d.dabCount > 0;
3188
3192
  this.result = { layerId: this.layerId, bounds: changed ? d.bounds : null, dabs: d.dabCount, strokeId: null, wet: true };
3189
3193
  const carried = d.load;
3190
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkNIBFKXMDcjs.cleanMixer.call(void 0, carried);
3194
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkIFWLZZCWcjs.cleanMixer.call(void 0, carried);
3191
3195
  this.host.commit(this, changed ? this.init.wet.surface() : null, false);
3192
3196
  }
3193
3197
  update(rects) {
@@ -3217,7 +3221,7 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
3217
3221
  const src = _nullishCoalesce(_optionalChain([this, 'access', _95 => _95.base, 'access', _96 => _96.tiles, 'access', _97 => _97.get, 'call', _98 => _98(key), 'optionalAccess', _99 => _99.data]), () => ( defaultTile(this.base)));
3218
3222
  const prev = this.touched.has(key) ? _optionalChain([this, 'access', _100 => _100.live, 'access', _101 => _101.get, 'call', _102 => _102(key), 'optionalAccess', _103 => _103.data]) : void 0;
3219
3223
  this.touched.add(key);
3220
- const data = _chunkNIBFKXMDcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
3224
+ const data = _chunkIFWLZZCWcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
3221
3225
  this.live.set(key, { data, uniform: null });
3222
3226
  }
3223
3227
  this.host.update(this.layerId, new (0, _chunk474IQG74cjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
@@ -3260,7 +3264,7 @@ var PaintStrokeSession = (_class11 = class _PaintStrokeSession {
3260
3264
  this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };
3261
3265
  if (_optionalChain([this, 'access', _110 => _110.stickerSpray, 'optionalAccess', _111 => _111.skipped, 'access', _112 => _112.size])) this.result.skippedStickers = [...this.stickerSpray.skipped];
3262
3266
  const carried = _nullishCoalesce(_optionalChain([this, 'access', _113 => _113.wet, 'optionalAccess', _114 => _114.load]), () => ( _optionalChain([this, 'access', _115 => _115.thickDriver, 'optionalAccess', _116 => _116.load])));
3263
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkNIBFKXMDcjs.cleanMixer.call(void 0, carried);
3267
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkIFWLZZCWcjs.cleanMixer.call(void 0, carried);
3264
3268
  this.host.commit(this, surface, false);
3265
3269
  return this.result;
3266
3270
  }
@@ -3287,15 +3291,15 @@ function greyPixels(data, grey) {
3287
3291
  }
3288
3292
  function mixerLoadForStroke(brush, current, color) {
3289
3293
  if (!brush.loadsColor) return { reservoir: null, amount: 0, pickup: brush.mixer.cleanEachStroke ? null : current.pickup };
3290
- if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkNIBFKXMDcjs.loadMixer.call(void 0, current, color);
3294
+ if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkIFWLZZCWcjs.loadMixer.call(void 0, current, color);
3291
3295
  return current;
3292
3296
  }
3293
3297
  function brushLoadForStroke(brush, current, color) {
3294
3298
  if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
3295
3299
  if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
3296
- if (brush.engine === "wet") return brush.wet.tool === "paint" ? { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null } : _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD;
3297
- if (_chunk6QNDGMK7cjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
3298
- return _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD;
3300
+ if (brush.engine === "wet") return brush.wet.tool === "paint" ? { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null } : _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD;
3301
+ if (_chunkQ33V5PEFcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
3302
+ return _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD;
3299
3303
  }
3300
3304
 
3301
3305
  // src/paint-editor/stencils.ts
@@ -3556,15 +3560,15 @@ function readLoad(raw) {
3556
3560
  function readStrokeBrush(raw) {
3557
3561
  if (raw && typeof raw === "object" && "kind" in raw && !("engine" in raw)) {
3558
3562
  try {
3559
- return _chunk6QNDGMK7cjs.resolveBrush.call(void 0, _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, raw));
3563
+ return _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, raw));
3560
3564
  } catch (e3) {
3561
3565
  }
3562
3566
  }
3563
- return _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, _nullishCoalesce(raw, () => ( {})));
3567
+ return _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(raw, () => ( {})));
3564
3568
  }
3565
3569
  function strokeToJSON(stroke) {
3566
3570
  const { brush, ...rest } = stroke;
3567
- return { ...JSON.parse(JSON.stringify(rest)), brush: _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, brush) };
3571
+ return { ...JSON.parse(JSON.stringify(rest)), brush: _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, brush) };
3568
3572
  }
3569
3573
  function normalizeBrushStroke(raw) {
3570
3574
  if (!raw || typeof raw !== "object") return null;
@@ -3594,8 +3598,8 @@ function normalizeBrushStroke(raw) {
3594
3598
  }
3595
3599
  if (st.length) out.stencils = st;
3596
3600
  }
3597
- const effect = _chunkOLZXXAERcjs.readPaintEffectPaint.call(void 0, r.paint);
3598
- const paint = effect ? null : _chunkNIBFKXMDcjs.readPaintSource.call(void 0, r.paint);
3601
+ const effect = _chunkOY24XRYFcjs.readPaintEffectPaint.call(void 0, r.paint);
3602
+ const paint = effect ? null : _chunkIFWLZZCWcjs.readPaintSource.call(void 0, r.paint);
3599
3603
  if (effect) out.paint = effect;
3600
3604
  else if (paint && paint.type === "gradient") out.paint = paint;
3601
3605
  if (Array.isArray(r.steps) && r.steps.length === points.length && r.steps.every((v) => Number.isInteger(v) && v >= 0)) out.steps = [...r.steps];
@@ -3634,11 +3638,11 @@ function varyStroke(stroke, m, v) {
3634
3638
  if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
3635
3639
  return q;
3636
3640
  });
3637
- const brush = s !== 1 ? _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
3641
+ const brush = s !== 1 ? _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
3638
3642
  const out = { ...stroke, brush, points };
3639
- if (_optionalChain([stroke, 'access', _140 => _140.paint, 'optionalAccess', _141 => _141.type]) === "gradient" && s !== 1) out.paint = _chunkNIBFKXMDcjs.scalePaintGradient.call(void 0, stroke.paint, s);
3643
+ if (_optionalChain([stroke, 'access', _140 => _140.paint, 'optionalAccess', _141 => _141.type]) === "gradient" && s !== 1) out.paint = _chunkIFWLZZCWcjs.scalePaintGradient.call(void 0, stroke.paint, s);
3640
3644
  if (_optionalChain([stroke, 'access', _142 => _142.paint, 'optionalAccess', _143 => _143.type]) === "effect" && _optionalChain([stroke, 'access', _144 => _144.paint, 'access', _145 => _145.map, 'optionalAccess', _146 => _146.by]) === "stroke" && s !== 1) out.paint = { ...stroke.paint, map: { ...stroke.paint.map, length: Math.min(4096, Math.max(16, Math.round(stroke.paint.map.length * s))) } };
3641
- if (_optionalChain([stroke, 'access', _147 => _147.paint, 'optionalAccess', _148 => _148.type]) === "effect" && _optionalChain([stroke, 'access', _149 => _149.paint, 'access', _150 => _150.map, 'optionalAccess', _151 => _151.by]) === "path") out.paint = _chunkOLZXXAERcjs.withStrokePath.call(void 0, stroke.paint, points);
3645
+ if (_optionalChain([stroke, 'access', _147 => _147.paint, 'optionalAccess', _148 => _148.type]) === "effect" && _optionalChain([stroke, 'access', _149 => _149.paint, 'access', _150 => _150.map, 'optionalAccess', _151 => _151.by]) === "path") out.paint = _chunkOY24XRYFcjs.withStrokePath.call(void 0, stroke.paint, points);
3642
3646
  if (_optionalChain([stroke, 'access', _152 => _152.copies, 'optionalAccess', _153 => _153.length])) {
3643
3647
  const inv = invertAffine(m);
3644
3648
  out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));
@@ -3670,7 +3674,7 @@ function paperGrain(paper) {
3670
3674
  const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry, _nullishCoalesce(paper.offset, () => ( null))]);
3671
3675
  let g = grainCache.get(key);
3672
3676
  if (!g) {
3673
- g = new (0, _chunkNIBFKXMDcjs.PaperGrain)(paper, "dry");
3677
+ g = new (0, _chunkIFWLZZCWcjs.PaperGrain)(paper, "dry");
3674
3678
  if (grainCache.size > 16) grainCache.delete(grainCache.keys().next().value);
3675
3679
  grainCache.set(key, g);
3676
3680
  }
@@ -3680,7 +3684,7 @@ function paperTile(paper, r, light) {
3680
3684
  const key = `${paperKey(paper, light)}|${r.x},${r.y},${r.width},${r.height}`;
3681
3685
  let t = tileCache.get(key);
3682
3686
  if (!t) {
3683
- t = _chunkOLZXXAERcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
3687
+ t = _chunkOY24XRYFcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
3684
3688
  if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value);
3685
3689
  tileCache.set(key, t);
3686
3690
  }
@@ -3785,11 +3789,11 @@ function header(state, options) {
3785
3789
  return out;
3786
3790
  }
3787
3791
  function serializePaintDocument(state, options = {}) {
3788
- const { layers, assets } = _chunkRAPNRK4Rcjs.serializeLayers.call(void 0, state.layers);
3792
+ const { layers, assets } = _chunkX7XBEX3Ocjs.serializeLayers.call(void 0, state.layers);
3789
3793
  return { ...header(state, options), layers, assets };
3790
3794
  }
3791
3795
  async function serializePaintDocumentExternal(state, store, options = {}) {
3792
- const { layers, assets } = await _chunkRAPNRK4Rcjs.serializeLayersExternal.call(void 0, state.layers, store);
3796
+ const { layers, assets } = await _chunkX7XBEX3Ocjs.serializeLayersExternal.call(void 0, state.layers, store);
3793
3797
  return { ...header(state, options), layers, assets };
3794
3798
  }
3795
3799
  function paintLayersOnly(layers, problems) {
@@ -3824,9 +3828,9 @@ function deserializePaintDocument(raw) {
3824
3828
  }
3825
3829
  const problems = [];
3826
3830
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
3827
- const paper = _chunkOLZXXAERcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
3831
+ const paper = _chunkOY24XRYFcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
3828
3832
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
3829
- const layers = paintLayersOnly(_chunkRAPNRK4Rcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
3833
+ const layers = paintLayersOnly(_chunkX7XBEX3Ocjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
3830
3834
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
3831
3835
  const activeLayerId = wanted && _chunkPVJMTLPJcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _165 => _165.filter, 'call', _166 => _166((l) => l.type === "pixel"), 'access', _167 => _167.pop, 'call', _168 => _168(), 'optionalAccess', _169 => _169.id]), () => ( null));
3832
3836
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
@@ -3842,7 +3846,7 @@ async function deserializePaintDocumentAsync(raw, store) {
3842
3846
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
3843
3847
  const r = raw;
3844
3848
  const problems = [];
3845
- const assets = await _chunkRAPNRK4Rcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
3849
+ const assets = await _chunkX7XBEX3Ocjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
3846
3850
  const loaded = deserializePaintDocument({ ...r, assets });
3847
3851
  return { ...loaded, problems: [...problems, ...loaded.problems] };
3848
3852
  }
@@ -3919,13 +3923,13 @@ function viewPenToDocument(view, p) {
3919
3923
 
3920
3924
  // src/paint-editor/input.ts
3921
3925
  function samplePressure(e) {
3922
- return _chunk62MFUHSIcjs.pointerPressure.call(void 0, e);
3926
+ return _chunkUQXULAMQcjs.pointerPressure.call(void 0, e);
3923
3927
  }
3924
3928
  function pointerToPenPoint(e, x, y, view) {
3925
3929
  const p = { x, y, pressure: samplePressure(e) };
3926
3930
  if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;
3927
3931
  if (e.pointerType !== "pen") return p;
3928
- const o = _chunkOLZXXAERcjs.penOrientation.call(void 0, {
3932
+ const o = _chunkOY24XRYFcjs.penOrientation.call(void 0, {
3929
3933
  x,
3930
3934
  y,
3931
3935
  altitude: typeof e.altitudeAngle === "number" ? e.altitudeAngle : void 0,
@@ -3992,29 +3996,29 @@ var thumbWorld = null;
3992
3996
  function paintWetTestStroke(brush, paper, color, width, height) {
3993
3997
  if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
3994
3998
  _optionalChain([thumbWorld, 'optionalAccess', _172 => _172.destroy, 'call', _173 => _173()]);
3995
- thumbWorld = new (0, _chunkDHC4E2DUcjs.WetWorld)(width, height, _chunkOLZXXAERcjs.wetPaperInput.call(void 0, paper), { kernel: "typescript", threads: 0 });
3996
- } else thumbWorld.setPaper(_chunkOLZXXAERcjs.wetPaperInput.call(void 0, paper));
3999
+ thumbWorld = new (0, _chunkMITQGHN3cjs.WetWorld)(width, height, _chunkOY24XRYFcjs.wetPaperInput.call(void 0, paper), { kernel: "typescript", threads: 0 });
4000
+ } else thumbWorld.setPaper(_chunkOY24XRYFcjs.wetPaperInput.call(void 0, paper));
3997
4001
  const w = thumbWorld;
3998
4002
  if (w.hasLane("thumb")) w.removeLane("thumb");
3999
4003
  w.ensureLane("thumb");
4000
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, color);
4004
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, color);
4001
4005
  if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
4002
4006
  const half = Math.ceil(height / 2);
4003
- w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkDHC4E2DUcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
4004
- w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkDHC4E2DUcjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
4007
+ w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkMITQGHN3cjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
4008
+ w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkMITQGHN3cjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
4005
4009
  }
4006
4010
  const film = brush.iridescence && brush.wet.tool === "paint" ? new FilmBuffer(_chunk474IQG74cjs.emptySurface.call(void 0, 4, 0)) : null;
4007
- const driver = new (0, _chunkOLZXXAERcjs.WetStrokeDriver)({
4011
+ const driver = new (0, _chunkOY24XRYFcjs.WetStrokeDriver)({
4008
4012
  world: w,
4009
4013
  laneId: "thumb",
4010
4014
  brush,
4011
4015
  color: [r / 255, g / 255, b / 255],
4012
- load: brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
4016
+ load: brushLoadForStroke(brush, _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
4013
4017
  grain: paperGrain(paper),
4014
4018
  paperDepth: paper.depth,
4015
- paperColor: _chunkOLZXXAERcjs.hexToRgb8.call(void 0, paper.color),
4019
+ paperColor: _chunkOY24XRYFcjs.hexToRgb8.call(void 0, paper.color),
4016
4020
  seed: 7,
4017
- copies: [_chunkOLZXXAERcjs.IDENTITY_COPY],
4021
+ copies: [_chunkOY24XRYFcjs.IDENTITY_COPY],
4018
4022
  film
4019
4023
  });
4020
4024
  driver.push(thumbnailStroke(width, height));
@@ -4036,7 +4040,7 @@ function thumbnailStroke(width, height) {
4036
4040
  return pts;
4037
4041
  }
4038
4042
  function paintTestStroke(surface, brush, paper, color, width, height, stampArt) {
4039
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, color);
4043
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, color);
4040
4044
  let result = surface;
4041
4045
  let thick = null;
4042
4046
  let light = null;
@@ -4059,14 +4063,14 @@ function paintTestStroke(surface, brush, paper, color, width, height, stampArt)
4059
4063
  lockTransparency: false,
4060
4064
  brush,
4061
4065
  color: [r, g, b, 255],
4062
- background: [..._chunkOLZXXAERcjs.hexToRgb8.call(void 0, paper.color), 255],
4066
+ background: [..._chunkOY24XRYFcjs.hexToRgb8.call(void 0, paper.color), 255],
4063
4067
  grain: paperGrain(paper),
4064
4068
  paperDepth: paper.depth,
4065
4069
  seed: 7,
4066
4070
  colorHex: color,
4067
4071
  affineCopies: [],
4068
- copies: [_chunkOLZXXAERcjs.IDENTITY_COPY],
4069
- mixerLoad: brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
4072
+ copies: [_chunkOY24XRYFcjs.IDENTITY_COPY],
4073
+ mixerLoad: brushLoadForStroke(brush, _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
4070
4074
  thick: brush.engine === "impasto" || brush.iridescence ? { channels: emptyThickChannels() } : void 0,
4071
4075
  sticker: brush.engine === "sticker" ? { nextId: 1 } : void 0,
4072
4076
  light: brush.light.amount > 0 && brush.engine !== "wet" && brush.engine !== "sticker" ? { surface: emptyLight() } : null,
@@ -4085,8 +4089,8 @@ function renderBrushThumbnail(brush, options) {
4085
4089
  const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
4086
4090
  const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
4087
4091
  const maxSize = height * 0.42;
4088
- const b = brush.tip.size > maxSize ? _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
4089
- const rgba = [..._chunkOLZXXAERcjs.hexToRgb8.call(void 0, options.color), 255];
4092
+ const b = brush.tip.size > maxSize ? _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
4093
+ const rgba = [..._chunkOY24XRYFcjs.hexToRgb8.call(void 0, options.color), 255];
4090
4094
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
4091
4095
  if (b.engine === "eraser") {
4092
4096
  surface = _chunk474IQG74cjs.fillRect.call(void 0, surface, { x: 0, y: 0, width, height }, rgba);
@@ -4101,7 +4105,7 @@ function renderBrushThumbnail(brush, options) {
4101
4105
  if (b.engine === "wet") surface = paintWetTestStroke(b, options.paper, options.color, width, height);
4102
4106
  else ({ surface, light, fluor } = paintTestStroke(surface, b, options.paper, options.color, width, height, options.stampArt));
4103
4107
  const layer = { type: "pixel", id: "thumbnail", name: "thumbnail", visible: true, opacity: 1, blend: "normal", surface, offset: { x: 0, y: 0 } };
4104
- const paper = (light || fluor) && _chunkJDXWLCXFcjs.brushPreviewsOnDark.call(void 0, b) ? { ...options.paper, color: _chunkJDXWLCXFcjs.BRUSH_PREVIEW_DARK_PAPER } : options.paper;
4108
+ const paper = (light || fluor) && _chunkQNNZA3V5cjs.brushPreviewsOnDark.call(void 0, b) ? { ...options.paper, color: _chunkQNNZA3V5cjs.BRUSH_PREVIEW_DARK_PAPER } : options.paper;
4105
4109
  const spill = light ? computeSpill(surface, light, { radius: Math.max(4, height / 6), strength: 1 }) : fluor ? computeUvSpill(fluor, 1) : null;
4106
4110
  const layers = [paperNode(paper), layer];
4107
4111
  if (spill) layers.push({ type: "pixel", id: "thumbnail-light", name: "light", visible: true, opacity: 1, blend: "linear-dodge", surface: spill, offset: { x: 0, y: 0 } });
@@ -4345,8 +4349,8 @@ function colorHarmony2(base, kind, options = {}) {
4345
4349
  function readSwatch(raw) {
4346
4350
  if (!raw || typeof raw !== "object") return null;
4347
4351
  const r = raw;
4348
- const g = _chunkNIBFKXMDcjs.readPaintSource.call(void 0, r.paint);
4349
- const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _174 => _174.type]) === "gradient" ? _chunkNIBFKXMDcjs.paintSourceColor.call(void 0, g) : null;
4352
+ const g = _chunkIFWLZZCWcjs.readPaintSource.call(void 0, r.paint);
4353
+ const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _174 => _174.type]) === "gradient" ? _chunkIFWLZZCWcjs.paintSourceColor.call(void 0, g) : null;
4350
4354
  if (!color) return null;
4351
4355
  const out = { color };
4352
4356
  if (typeof r.name === "string" && r.name.trim()) out.name = r.name.trim().slice(0, 80);
@@ -4369,7 +4373,7 @@ var DEFAULT_SWATCHES = [
4369
4373
  // src/paint-editor/mixing-pad.ts
4370
4374
  var MIXING_PAD_WIDTH = 360;
4371
4375
  var MIXING_PAD_HEIGHT = 220;
4372
- var PAD_PAINT = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, {
4376
+ var PAD_PAINT = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, {
4373
4377
  id: "pad-paint",
4374
4378
  name: "Pad paint",
4375
4379
  category: "mixer",
@@ -4377,7 +4381,7 @@ var PAD_PAINT = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, {
4377
4381
  tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
4378
4382
  mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
4379
4383
  });
4380
- var PAD_KNIFE = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, {
4384
+ var PAD_KNIFE = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, {
4381
4385
  id: "pad-knife",
4382
4386
  name: "Palette knife",
4383
4387
  category: "smudge",
@@ -4387,7 +4391,7 @@ var PAD_KNIFE = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, {
4387
4391
  // A knife drags streaks of paint and folds them into each other, mixing them as pigment.
4388
4392
  smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
4389
4393
  });
4390
- var PAD_BLOB = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, {
4394
+ var PAD_BLOB = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, {
4391
4395
  id: "pad-blob",
4392
4396
  name: "Pad blob",
4393
4397
  category: "custom",
@@ -4409,12 +4413,12 @@ var MixingPad = (_class13 = class {constructor() { _class13.prototype.__init61.c
4409
4413
  }
4410
4414
  }
4411
4415
  let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
4412
- if (options.size !== void 0) brush = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
4416
+ if (options.size !== void 0) brush = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
4413
4417
  return this.run(brush, points, options.color);
4414
4418
  }
4415
4419
  /** Paints `points` with `brush` in `color` on the pad. */
4416
4420
  run(brush, points, color) {
4417
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, color);
4421
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, color);
4418
4422
  let result = null;
4419
4423
  const session = new PaintStrokeSession(
4420
4424
  { update: () => {
@@ -4432,8 +4436,8 @@ var MixingPad = (_class13 = class {constructor() { _class13.prototype.__init61.c
4432
4436
  seed: 1,
4433
4437
  colorHex: color,
4434
4438
  affineCopies: [],
4435
- copies: [_chunkOLZXXAERcjs.IDENTITY_COPY],
4436
- mixerLoad: brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
4439
+ copies: [_chunkOY24XRYFcjs.IDENTITY_COPY],
4440
+ mixerLoad: brushLoadForStroke(brush, _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
4437
4441
  }
4438
4442
  );
4439
4443
  session.push(points);
@@ -4508,10 +4512,10 @@ var MixingPad = (_class13 = class {constructor() { _class13.prototype.__init61.c
4508
4512
  const off = used.length === 1 ? 0 : 0.45 * R;
4509
4513
  const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
4510
4514
  const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
4511
- const blob = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
4515
+ const blob = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
4512
4516
  this.run(blob, [{ x, y }], p.color.toLowerCase());
4513
4517
  });
4514
- const knife = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
4518
+ const knife = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
4515
4519
  for (let k = 0; k < passes; k++) {
4516
4520
  const stir = [];
4517
4521
  const turns = 1.6;
@@ -4523,10 +4527,10 @@ var MixingPad = (_class13 = class {constructor() { _class13.prototype.__init61.c
4523
4527
  this.run(knife, stir, "#000000");
4524
4528
  }
4525
4529
  const mixed = _chunk2VX55NFMcjs.mixPigments.call(void 0,
4526
- paints2.map((p) => _chunkOLZXXAERcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
4530
+ paints2.map((p) => _chunkOY24XRYFcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
4527
4531
  paints2.map((p) => p.parts)
4528
4532
  );
4529
- const core = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
4533
+ const core = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
4530
4534
  const hex2 = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
4531
4535
  this.run(core, [{ x: cx, y: cy }], hex2);
4532
4536
  return { color: this.pick(cx, cy, 2), bounds };
@@ -4566,21 +4570,21 @@ var MixingPad = (_class13 = class {constructor() { _class13.prototype.__init61.c
4566
4570
  var copyJSON = (v) => JSON.parse(JSON.stringify(v));
4567
4571
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
4568
4572
  function libraryBrush(spec, builtin, resolved) {
4569
- const brush = resolved ? _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, resolved, resolved) : _chunk6QNDGMK7cjs.resolveBrush.call(void 0, spec);
4573
+ const brush = resolved ? _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, resolved, resolved) : _chunkQ33V5PEFcjs.resolveBrush.call(void 0, spec);
4570
4574
  if (builtin) brush.builtin = true;
4571
4575
  else delete brush.builtin;
4572
4576
  return { spec, brush, builtin };
4573
4577
  }
4574
4578
  var builtins = null;
4575
4579
  function builtinLibraryBrushes() {
4576
- return builtins ??= _chunk6QNDGMK7cjs.BRUSH_PRESETS.map((spec) => {
4577
- const resolved = _chunk6QNDGMK7cjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id);
4580
+ return builtins ??= _chunkQ33V5PEFcjs.BRUSH_PRESETS.map((spec) => {
4581
+ const resolved = _chunkQ33V5PEFcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id);
4578
4582
  return libraryBrush(spec, true, resolved);
4579
4583
  });
4580
4584
  }
4581
4585
  function seededStorage(brushes) {
4582
4586
  if (!brushes.length) return void 0;
4583
- let stored = JSON.stringify({ format: "pixerate-brushes", version: 1, brushes: brushes.map(_chunk6QNDGMK7cjs.brushToJSON) });
4587
+ let stored = JSON.stringify({ format: "pixerate-brushes", version: 1, brushes: brushes.map(_chunkQ33V5PEFcjs.brushToJSON) });
4584
4588
  return {
4585
4589
  get: async () => stored,
4586
4590
  set: async (_key, value) => {
@@ -4593,7 +4597,7 @@ var paints = (b) => {
4593
4597
  return JSON.stringify(rest);
4594
4598
  };
4595
4599
  function brushSpecOf(next, from) {
4596
- const plain = _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, next);
4600
+ const plain = _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, next);
4597
4601
  const out = copyJSON(plain);
4598
4602
  if (from.description) out.description = from.description;
4599
4603
  if (_optionalChain([from, 'access', _177 => _177.tags, 'optionalAccess', _178 => _178.length])) out.tags = [...from.tags];
@@ -4613,8 +4617,8 @@ function brushSpecOf(next, from) {
4613
4617
  out.motion = { ..._nullishCoalesce(out.motion, () => ( {})), ...from.motion.live !== void 0 ? { live: from.motion.live } : {}, ...from.motion.fps !== void 0 ? { fps: from.motion.fps } : {} };
4614
4618
  }
4615
4619
  try {
4616
- const hinted = _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, out, []);
4617
- if (paints(_chunk6QNDGMK7cjs.resolveBrush.call(void 0, hinted)) === paints(_chunk6QNDGMK7cjs.resolveBrush.call(void 0, plain))) return hinted;
4620
+ const hinted = _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, out, []);
4621
+ if (paints(_chunkQ33V5PEFcjs.resolveBrush.call(void 0, hinted)) === paints(_chunkQ33V5PEFcjs.resolveBrush.call(void 0, plain))) return hinted;
4618
4622
  } catch (e5) {
4619
4623
  }
4620
4624
  return plain;
@@ -4714,14 +4718,14 @@ var BrushSourceArtCache = (_class14 = class {constructor() { _class14.prototype.
4714
4718
  }
4715
4719
  /** The art of a `source:<id>` ref (alpha = the mask), or `undefined` when the source is unknown or its image can't be read. */
4716
4720
  __init67() {this.get = (ref2) => {
4717
- const id = _chunk6QNDGMK7cjs.brushSourceIdOf.call(void 0, ref2);
4721
+ const id = _chunkQ33V5PEFcjs.brushSourceIdOf.call(void 0, ref2);
4718
4722
  if (id === null) return void 0;
4719
4723
  if (this.art.has(id)) return _nullishCoalesce(this.art.get(id), () => ( void 0));
4720
4724
  const source = this.sources.get(id);
4721
4725
  if (!source) return void 0;
4722
4726
  let art = null;
4723
4727
  try {
4724
- const { width, height, mask } = _chunk6QNDGMK7cjs.decodeBrushSource.call(void 0, source);
4728
+ const { width, height, mask } = _chunkQ33V5PEFcjs.decodeBrushSource.call(void 0, source);
4725
4729
  const data = new Uint8ClampedArray(width * height * 4);
4726
4730
  for (let i = 0; i < mask.length; i++) {
4727
4731
  data[i * 4] = data[i * 4 + 1] = data[i * 4 + 2] = 255;
@@ -4736,12 +4740,12 @@ var BrushSourceArtCache = (_class14 = class {constructor() { _class14.prototype.
4736
4740
  }}
4737
4741
  /** A lookup that reads sources from here and every other ref from `stickers`. */
4738
4742
  with(stickers) {
4739
- return (ref2, variant) => _chunk6QNDGMK7cjs.isBrushSourceRef.call(void 0, ref2) ? this.get(ref2) : stickers(ref2, variant);
4743
+ return (ref2, variant) => _chunkQ33V5PEFcjs.isBrushSourceRef.call(void 0, ref2) ? this.get(ref2) : stickers(ref2, variant);
4740
4744
  }
4741
4745
  }, _class14);
4742
4746
  function engineBrushSourceIds(brush) {
4743
4747
  const refs = [brush.stamp, _optionalChain([brush, 'access', _191 => _191.tipGrain, 'optionalAccess', _192 => _192.source]), ..._nullishCoalesce(_optionalChain([brush, 'access', _193 => _193.particle, 'optionalAccess', _194 => _194.dotTextures]), () => ( []))];
4744
- return [...new Set(refs.filter((r) => !!r && _chunk6QNDGMK7cjs.isBrushSourceRef.call(void 0, r)).map((r) => _chunk6QNDGMK7cjs.brushSourceIdOf.call(void 0, r)))];
4748
+ return [...new Set(refs.filter((r) => !!r && _chunkQ33V5PEFcjs.isBrushSourceRef.call(void 0, r)).map((r) => _chunkQ33V5PEFcjs.brushSourceIdOf.call(void 0, r)))];
4745
4749
  }
4746
4750
 
4747
4751
  // src/paint-editor/live-strokes.ts
@@ -4917,10 +4921,10 @@ function addTiles(a, b) {
4917
4921
  }
4918
4922
  function computeTile(paper, grain, amount, rect, layers) {
4919
4923
  const n = rect.width * rect.height;
4920
- const [p0, p1, p2] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, paper.color);
4924
+ const [p0, p1, p2] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, paper.color);
4921
4925
  const pb = [p0, p1, p2];
4922
4926
  const pl = [Math.max(1e-4, LIN[p0]), Math.max(1e-4, LIN[p1]), Math.max(1e-4, LIN[p2])];
4923
- const [c0, c1, c2] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
4927
+ const [c0, c1, c2] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
4924
4928
  const t0 = new Float32Array(n).fill(amount * LIN[c0]);
4925
4929
  const t1 = new Float32Array(n).fill(amount * LIN[c1]);
4926
4930
  const t2 = new Float32Array(n).fill(amount * LIN[c2]);
@@ -5091,6 +5095,26 @@ async function replayPainting(source, target, options = {}) {
5091
5095
  if (e.layerId && target.getLayer(e.layerId)) target.wetPaper({ layerId: e.layerId, rect: sr(d.rect), amount: d.amount });
5092
5096
  break;
5093
5097
  }
5098
+ case "live-patterns": {
5099
+ const d = e.data;
5100
+ if (e.layerId && target.getLayer(e.layerId)) {
5101
+ target.setLivePatterns(e.layerId, d ? { ...d, scale: Math.min(4, d.scale * s), enabled: true } : { enabled: false });
5102
+ }
5103
+ break;
5104
+ }
5105
+ case "seed-live-patterns": {
5106
+ const d = e.data;
5107
+ if (e.layerId && target.getLayer(e.layerId) && Array.isArray(d.points)) {
5108
+ target.seedLivePatterns({
5109
+ layerId: e.layerId,
5110
+ points: d.points.map((p) => ({ ...p, x: p.x * s, y: p.y * s })),
5111
+ radius: Math.min(512, d.radius * s),
5112
+ seed: d.seed,
5113
+ ...d.settings ? { ...d.settings, ...d.settings.scale ? { scale: Math.min(4, d.settings.scale * s) } : {} } : {}
5114
+ });
5115
+ }
5116
+ break;
5117
+ }
5094
5118
  case "ghost-release": {
5095
5119
  const d = e.data;
5096
5120
  if (e.layerId && target.getLayer(e.layerId)) target.wet.releaseGhost(e.layerId, _optionalChain([d, 'optionalAccess', _226 => _226.linger]));
@@ -5514,7 +5538,7 @@ function createPaintProposals(options) {
5514
5538
  if (!_optionalChain([s, 'access', _256 => _256.points, 'optionalAccess', _257 => _257.length])) throw new PaintEditorError(`${at}: each stroke needs points in document pixels.`);
5515
5539
  points += s.points.length;
5516
5540
  if (!HEX2.test(_nullishCoalesce(s.color, () => ( "")))) throw new PaintEditorError(`${at}: color "${s.color}" is not #rrggbb.`);
5517
- const brush = "engine" in s.brush ? s.brush : _chunk6QNDGMK7cjs.resolveBrush.call(void 0, _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, s.brush));
5541
+ const brush = "engine" in s.brush ? s.brush : _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, s.brush));
5518
5542
  const refusal = _nullishCoalesce(liveStrokeRefusal(brush), () => ( suggestionBrushRefusal(brush)));
5519
5543
  if (refusal) throw new PaintEditorError(`${at}: ${refusal}`);
5520
5544
  }
@@ -5540,7 +5564,7 @@ function createPaintProposals(options) {
5540
5564
  controller.fillLayer({ layerId, color: op.color, opacity: _nullishCoalesce(op.opacity, () => ( 0.35)), grain: _nullishCoalesce(op.grain, () => ( 0.4)) });
5541
5565
  } else if (op.kind === "strokes") {
5542
5566
  for (const s of op.strokes) {
5543
- const brush = "engine" in s.brush ? s.brush : _chunk6QNDGMK7cjs.resolveBrush.call(void 0, _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, s.brush));
5567
+ const brush = "engine" in s.brush ? s.brush : _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, s.brush));
5544
5568
  controller.paintStroke({
5545
5569
  layerId,
5546
5570
  points: s.points,
@@ -5840,8 +5864,8 @@ function mixColorOklch(hexA, hexB, t) {
5840
5864
  }
5841
5865
  function driftBrushFacets(brush, amount, seed, index = 0) {
5842
5866
  if (!(amount > 0)) return brush;
5843
- const facetSpec = _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, brush);
5844
- const base = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, facetSpec);
5867
+ const facetSpec = _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, brush);
5868
+ const base = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, facetSpec);
5845
5869
  const shape = _nullishCoalesce(_optionalChain([facetSpec, 'access', _265 => _265.tip, 'optionalAccess', _266 => _266.shape]), () => ( "round"));
5846
5870
  const marksKind = _nullishCoalesce(_optionalChain([facetSpec, 'access', _267 => _267.marks, 'optionalAccess', _268 => _268.kind]), () => ( "continuous"));
5847
5871
  for (let fi = 0; fi < EVOLUTION_BRUSH_FACETS.length; fi++) {
@@ -5859,7 +5883,7 @@ function driftBrushFacets(brush, amount, seed, index = 0) {
5859
5883
  setFacetPath(facetSpec, f.facet, next);
5860
5884
  }
5861
5885
  }
5862
- const resolved = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, facetSpec));
5886
+ const resolved = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, facetSpec));
5863
5887
  return { ...resolved, builtin: void 0 };
5864
5888
  }
5865
5889
  function rerollStrokeSeed(strokeSeed, amount, seed, index = 0) {
@@ -5923,12 +5947,12 @@ function resampleStrokePoints(points, count) {
5923
5947
  return out;
5924
5948
  }
5925
5949
  function crossoverBrushes(brushA, brushB, seed, index = 0) {
5926
- const fa = _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, brushA);
5927
- const fb = _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, brushB);
5950
+ const fa = _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, brushA);
5951
+ const fb = _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, brushB);
5928
5952
  const pickB = _chunk3K6HWEXZcjs.rand01.call(void 0, seed, index, 400) >= 0.5;
5929
5953
  const domFacet = JSON.parse(JSON.stringify(pickB ? fb : fa));
5930
- const ra = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, fa);
5931
- const rb = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, fb);
5954
+ const ra = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, fa);
5955
+ const rb = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, fb);
5932
5956
  const rDom = pickB ? rb : ra;
5933
5957
  const shape = _nullishCoalesce(_optionalChain([domFacet, 'access', _269 => _269.tip, 'optionalAccess', _270 => _270.shape]), () => ( "round"));
5934
5958
  const marksKind = _nullishCoalesce(_optionalChain([domFacet, 'access', _271 => _271.marks, 'optionalAccess', _272 => _272.kind]), () => ( "continuous"));
@@ -5946,7 +5970,7 @@ function crossoverBrushes(brushA, brushB, seed, index = 0) {
5946
5970
  setFacetPath(domFacet, f.facet, mixed);
5947
5971
  }
5948
5972
  }
5949
- const resolved = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, domFacet));
5973
+ const resolved = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, domFacet));
5950
5974
  return { ...resolved, builtin: void 0 };
5951
5975
  }
5952
5976
  function crossoverStrokes(a, b, seed, index = 0) {
@@ -5975,7 +5999,7 @@ function crossoverStrokes(a, b, seed, index = 0) {
5975
5999
  const dom = w >= 0.5 ? b : a;
5976
6000
  let paint = dom.paint;
5977
6001
  if (_optionalChain([paint, 'optionalAccess', _273 => _273.type]) === "effect" && _optionalChain([paint, 'access', _274 => _274.map, 'optionalAccess', _275 => _275.by]) === "path") {
5978
- paint = _chunkOLZXXAERcjs.withStrokePath.call(void 0, paint, points);
6002
+ paint = _chunkOY24XRYFcjs.withStrokePath.call(void 0, paint, points);
5979
6003
  }
5980
6004
  let load = dom.load;
5981
6005
  if (_optionalChain([load, 'optionalAccess', _276 => _276.reservoir])) {
@@ -6017,7 +6041,7 @@ function mutateStroke(stroke, rates, seed, index = 0, group) {
6017
6041
  out = {
6018
6042
  ...out,
6019
6043
  points: jittered,
6020
- ..._optionalChain([out, 'access', _279 => _279.paint, 'optionalAccess', _280 => _280.type]) === "effect" && _optionalChain([out, 'access', _281 => _281.paint, 'access', _282 => _282.map, 'optionalAccess', _283 => _283.by]) === "path" ? { paint: _chunkOLZXXAERcjs.withStrokePath.call(void 0, out.paint, jittered) } : {}
6044
+ ..._optionalChain([out, 'access', _279 => _279.paint, 'optionalAccess', _280 => _280.type]) === "effect" && _optionalChain([out, 'access', _281 => _281.paint, 'access', _282 => _282.map, 'optionalAccess', _283 => _283.by]) === "path" ? { paint: _chunkOY24XRYFcjs.withStrokePath.call(void 0, out.paint, jittered) } : {}
6021
6045
  };
6022
6046
  }
6023
6047
  if (r.color > 0) {
@@ -6060,10 +6084,10 @@ function describeGenomeDiff(parents, children, options = {}) {
6060
6084
  const entry = { from: p.color.toLowerCase(), to: c.color.toLowerCase() };
6061
6085
  if (!colors.some((x) => x.from === entry.from && x.to === entry.to)) colors.push(entry);
6062
6086
  }
6063
- const fp = _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, p.brush);
6064
- const fc = _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, c.brush);
6065
- const rp = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, fp);
6066
- const rc = _chunk6QNDGMK7cjs.resolveBrush.call(void 0, fc);
6087
+ const fp = _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, p.brush);
6088
+ const fc = _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, c.brush);
6089
+ const rp = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, fp);
6090
+ const rc = _chunkQ33V5PEFcjs.resolveBrush.call(void 0, fc);
6067
6091
  const shape = _nullishCoalesce(_optionalChain([fc, 'access', _299 => _299.tip, 'optionalAccess', _300 => _300.shape]), () => ( "round"));
6068
6092
  const marksKind = _nullishCoalesce(_optionalChain([fc, 'access', _301 => _301.marks, 'optionalAccess', _302 => _302.kind]), () => ( "continuous"));
6069
6093
  for (const f of EVOLUTION_BRUSH_FACETS) {
@@ -6121,7 +6145,7 @@ function proposalGenomeStrokes(first, second) {
6121
6145
  for (const op of proposal.ops) {
6122
6146
  if (op.kind === "strokes") {
6123
6147
  for (const s of op.strokes) {
6124
- const brush = "engine" in s.brush ? s.brush : _chunk6QNDGMK7cjs.resolveBrush.call(void 0, _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, s.brush));
6148
+ const brush = "engine" in s.brush ? s.brush : _chunkQ33V5PEFcjs.resolveBrush.call(void 0, _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, s.brush));
6125
6149
  out.push({ ...s, brush });
6126
6150
  }
6127
6151
  } else if (op.kind === "stroke" && controller) {
@@ -6211,7 +6235,7 @@ async function libraryCall(call) {
6211
6235
  try {
6212
6236
  return await call();
6213
6237
  } catch (e) {
6214
- throw e instanceof _chunk6QNDGMK7cjs.BrushLibraryError ? new PaintEditorError(e.message) : e;
6238
+ throw e instanceof _chunkQ33V5PEFcjs.BrushLibraryError ? new PaintEditorError(e.message) : e;
6215
6239
  }
6216
6240
  }
6217
6241
  var HEX3 = /^#[0-9a-f]{6}$/i;
@@ -6221,7 +6245,7 @@ function parseColor(value, what = "color") {
6221
6245
  return value.trim().toLowerCase();
6222
6246
  }
6223
6247
  function rgbaOf(hex2) {
6224
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, hex2);
6248
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, hex2);
6225
6249
  return [r, g, b, 255];
6226
6250
  }
6227
6251
  function rgbToHex(r, g, b) {
@@ -6276,7 +6300,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6276
6300
  * (one render at a time; the newest path when it lands), repainted into the stroke as it lands.
6277
6301
  */
6278
6302
  __init90() {this.pathPreview = null}
6279
- __init91() {this.mixerLoad = _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD}
6303
+ __init91() {this.mixerLoad = _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD}
6280
6304
  __init92() {this.view = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } }}
6281
6305
 
6282
6306
  __init93() {this.selectedStroke = null}
@@ -6355,7 +6379,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6355
6379
  /** Image sources strokes draw with: the brush library's and the open painting's (saved with it). */
6356
6380
  __init143() {this.brushSources = new BrushSourceArtCache()}
6357
6381
  /** Art for stamp tips and tip grain: image sources from `brushSources`, stickers from the sticker library. */
6358
- __init144() {this.stampArt = (ref2, variant) => _chunk6QNDGMK7cjs.isBrushSourceRef.call(void 0, ref2) ? this.brushSources.get(ref2) : this.stickerArt.get(ref2, variant)}
6382
+ __init144() {this.stampArt = (ref2, variant) => _chunkQ33V5PEFcjs.isBrushSourceRef.call(void 0, ref2) ? this.brushSources.get(ref2) : this.stickerArt.get(ref2, variant)}
6359
6383
 
6360
6384
  __init145() {this.effectsRenderer = new PaintEffectsRenderer()}
6361
6385
  __init146() {this.paperEffectNodeCache = null}
@@ -6373,15 +6397,15 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6373
6397
  this.rasterizeSticker = _nullishCoalesce(options.rasterizeSticker, () => ( defaultStickerRasterizer));
6374
6398
  if (options.stickers) this.stickers.set(options.stickers);
6375
6399
  this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
6376
- const seed = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
6377
- this.brushLibrary = _nullishCoalesce(options.brushLibrary, () => ( _chunk6QNDGMK7cjs.createBrushLibrary.call(void 0, { storage: seededStorage(seed) })));
6378
- this.brushEntries = [...builtinLibraryBrushes(), ...seed.map((b) => libraryBrush(_chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, b), false, b))];
6379
- const wanted = _nullishCoalesce(options.brushId, () => ( _chunk6QNDGMK7cjs.DEFAULT_BRUSH_ID));
6380
- const start = _nullishCoalesce(this.findEntry(wanted), () => ( this.findEntry(_chunk6QNDGMK7cjs.DEFAULT_BRUSH_ID)));
6381
- this.brush = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, start.brush);
6400
+ const seed = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
6401
+ this.brushLibrary = _nullishCoalesce(options.brushLibrary, () => ( _chunkQ33V5PEFcjs.createBrushLibrary.call(void 0, { storage: seededStorage(seed) })));
6402
+ this.brushEntries = [...builtinLibraryBrushes(), ...seed.map((b) => libraryBrush(_chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, b), false, b))];
6403
+ const wanted = _nullishCoalesce(options.brushId, () => ( _chunkQ33V5PEFcjs.DEFAULT_BRUSH_ID));
6404
+ const start = _nullishCoalesce(this.findEntry(wanted), () => ( this.findEntry(_chunkQ33V5PEFcjs.DEFAULT_BRUSH_ID)));
6405
+ this.brush = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, start.brush);
6382
6406
  this.brushSpec = copyJSON(start.spec);
6383
6407
  this.unsubscribeLibrary = this.brushLibrary.subscribe(() => void this.refreshBrushes().catch(() => void 0));
6384
- if (options.brushLibrary && seed.length) void this.brushLibrary.importFile(seed.map(_chunk6QNDGMK7cjs.brushToJSON)).catch(() => void 0);
6408
+ if (options.brushLibrary && seed.length) void this.brushLibrary.importFile(seed.map(_chunkQ33V5PEFcjs.brushToJSON)).catch(() => void 0);
6385
6409
  void this.refreshBrushes().catch(() => void 0);
6386
6410
  this.pendingBrushId = start.brush.id === wanted ? null : wanted;
6387
6411
  this.color = options.color ? parseColor(options.color) : "#1f2937";
@@ -6390,7 +6414,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6390
6414
  this.encodeImage = options.encodeImage;
6391
6415
  this.guides = defaultGuides(this.doc.canvas);
6392
6416
  this.wetOptions = options.wet;
6393
- this.wet = new (0, _chunkOLZXXAERcjs.PaintWetLayers)(
6417
+ this.wet = new (0, _chunkOY24XRYFcjs.PaintWetLayers)(
6394
6418
  {
6395
6419
  canvas: () => this.doc.canvas,
6396
6420
  paper: () => this.doc.paper,
@@ -6410,12 +6434,22 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6410
6434
  for (const [id, surface] of lights) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
6411
6435
  this.doc = { ...this.doc, ...light ? { light } : {} };
6412
6436
  },
6437
+ layerHeight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _308 => _308.doc, 'access', _309 => _309.thick, 'optionalAccess', _310 => _310[id], 'optionalAccess', _311 => _311.height]), () => ( null)),
6438
+ updateHeights: (heights) => {
6439
+ let thick = this.doc.thick;
6440
+ for (const [id, height] of heights) {
6441
+ if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
6442
+ const prev = _nullishCoalesce(_optionalChain([thick, 'optionalAccess', _312 => _312[id]]), () => ( emptyThickChannels()));
6443
+ thick = { ..._nullishCoalesce(thick, () => ( {})), [id]: { ...prev, height } };
6444
+ }
6445
+ if (thick !== this.doc.thick) this.doc = { ...this.doc, ...thick ? { thick } : {} };
6446
+ },
6413
6447
  changed: () => {
6414
6448
  }
6415
6449
  },
6416
6450
  options.wet
6417
6451
  );
6418
- this.wet.onDriverDone = () => _optionalChain([this, 'access', _308 => _308.session, 'optionalAccess', _309 => _309.completeWetEnd, 'call', _310 => _310()]);
6452
+ this.wet.onDriverDone = () => _optionalChain([this, 'access', _313 => _313.session, 'optionalAccess', _314 => _314.completeWetEnd, 'call', _315 => _315()]);
6419
6453
  }
6420
6454
  // --- State and events ----------------------------------------------------------
6421
6455
  subscribe(listener) {
@@ -6585,7 +6619,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6585
6619
  if (placement.bottom) this.moveLayer(layer.id, 0, null);
6586
6620
  fn(layer.id);
6587
6621
  if (this.wetOp || this.pendingWetEvents.length) throw new PaintEditorError("Wet paint can't be previewed; suggest it with a dry brush.");
6588
- const found = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _311 => _311.layer]);
6622
+ const found = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _316 => _316.layer]);
6589
6623
  const surface = found && isPixelLayer(found) ? found.surface : null;
6590
6624
  const bounds = surface ? _chunk474IQG74cjs.contentBounds.call(void 0, surface) : null;
6591
6625
  const box = bounds ? clipToCanvas(bounds, this.doc.canvas) : null;
@@ -6639,8 +6673,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6639
6673
  selectedSticker: this.selectedSticker,
6640
6674
  canUndo: this.undoStack.length > 0 && !this.session,
6641
6675
  canRedo: this.redoStack.length > 0 && !this.session,
6642
- undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _312 => _312.label]), () => ( null)),
6643
- redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _313 => _313.label]), () => ( null)),
6676
+ undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _317 => _317.label]), () => ( null)),
6677
+ redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _318 => _318.label]), () => ( null)),
6644
6678
  guides: this.guides,
6645
6679
  swatches: this.swatches,
6646
6680
  mixingPadVersion: this.pad.version,
@@ -6653,10 +6687,10 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6653
6687
  overlay: this.wet.overlay,
6654
6688
  instantDry: this.wet.instantDry,
6655
6689
  speed: this.wet.speed,
6656
- clock: _nullishCoalesce(_optionalChain([this, 'access', _314 => _314.wet, 'access', _315 => _315.world, 'optionalAccess', _316 => _316.clock]), () => ( 0)),
6690
+ clock: _nullishCoalesce(_optionalChain([this, 'access', _319 => _319.wet, 'access', _320 => _320.world, 'optionalAccess', _321 => _321.clock]), () => ( 0)),
6657
6691
  tilt: { ...this.wet.tilt },
6658
6692
  gpu: this.wet.gpuMode,
6659
- gpuActive: Boolean(_optionalChain([this, 'access', _317 => _317.wet, 'access', _318 => _318.world, 'optionalAccess', _319 => _319.gpuActive]))
6693
+ gpuActive: Boolean(_optionalChain([this, 'access', _322 => _322.wet, 'access', _323 => _323.world, 'optionalAccess', _324 => _324.gpuActive]))
6660
6694
  },
6661
6695
  uvLight: { ...this.uvLight },
6662
6696
  heat: heatStats(this.doc.heat),
@@ -6690,14 +6724,14 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6690
6724
  /** Why the document cannot be replaced or stepped through right now, or `null`. */
6691
6725
  busyReason() {
6692
6726
  if (this.session) return "A stroke is in progress; end or cancel it first.";
6693
- if (_optionalChain([this, 'access', _320 => _320.grouping, 'optionalAccess', _321 => _321.pending]) && !this.grouping.inside) return `"${this.grouping.label}" is still being painted; wait for it to finish first.`;
6727
+ if (_optionalChain([this, 'access', _325 => _325.grouping, 'optionalAccess', _326 => _326.pending]) && !this.grouping.inside) return `"${this.grouping.label}" is still being painted; wait for it to finish first.`;
6694
6728
  if (this.wet.busy) return "Wet paint is mid-step; wait a moment (wetIdle()) first.";
6695
6729
  return null;
6696
6730
  }
6697
6731
  requireIdle(what) {
6698
6732
  if (this.session) throw new PaintEditorError(`A stroke is in progress; end or cancel it before ${what}.`);
6699
6733
  if (this.pathStroke) throw new PaintEditorError(`The last stroke is still rendering the effect "${this.pathStroke.effect}" along its path; wait for it (strokeRendering) before ${what}.`);
6700
- if (_optionalChain([this, 'access', _322 => _322.grouping, 'optionalAccess', _323 => _323.pending]) && !this.grouping.inside) throw new PaintEditorError(`"${this.grouping.label}" is still being painted (one undo step); wait for it to finish before ${what}.`);
6734
+ if (_optionalChain([this, 'access', _327 => _327.grouping, 'optionalAccess', _328 => _328.pending]) && !this.grouping.inside) throw new PaintEditorError(`"${this.grouping.label}" is still being painted (one undo step); wait for it to finish before ${what}.`);
6701
6735
  }
6702
6736
  commit(label, next, before = this.doc) {
6703
6737
  if (this.grouping) {
@@ -6778,7 +6812,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6778
6812
  /** Records a wet event (for replays) in the document being built. */
6779
6813
  __init157() {this.pendingWetEvents = []}
6780
6814
  logWet(e) {
6781
- this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _324 => _324.wet, 'access', _325 => _325.world, 'optionalAccess', _326 => _326.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
6815
+ this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _329 => _329.wet, 'access', _330 => _330.world, 'optionalAccess', _331 => _331.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
6782
6816
  }
6783
6817
  /** The document with a paint event appended (for replays). */
6784
6818
  withPaintEvent(doc, e) {
@@ -6842,7 +6876,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6842
6876
  // --- Canvas and paper ----------------------------------------------------------
6843
6877
  resolvePaper(paper) {
6844
6878
  if (typeof paper === "string") {
6845
- const p = _chunkOLZXXAERcjs.paperPreset.call(void 0, paper);
6879
+ const p = _chunkOY24XRYFcjs.paperPreset.call(void 0, paper);
6846
6880
  if (!p) throw new PaintEditorError(`Unknown paper "${paper}". Call list_papers for the ids.`);
6847
6881
  return p;
6848
6882
  }
@@ -6860,7 +6894,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6860
6894
  this.extensions = {};
6861
6895
  this.guides = { ...this.guides, symmetry: { ...this.guides.symmetry, center: { x: next.canvas.width / 2, y: next.canvas.height / 2 } }, tracing: null };
6862
6896
  this.tracingVersion++;
6863
- if (this.wet.world) {
6897
+ if (this.wet.world || this.wet.patterns.size) {
6864
6898
  this.beginWetOp();
6865
6899
  this.wet.reset();
6866
6900
  }
@@ -6929,12 +6963,12 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6929
6963
  let next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
6930
6964
  if (next.heat) next = { ...next, heat: shiftHeatField(next.heat, left, top, width, height) };
6931
6965
  for (const id of keptWet) {
6932
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _327 => _327.layer]);
6966
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _332 => _332.layer]);
6933
6967
  if (isPixelLayer(l)) {
6934
6968
  const ox = l.offset.x;
6935
6969
  const oy = l.offset.y;
6936
6970
  next = { ...next, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, ox, oy), offset: { x: 0, y: 0 } })) };
6937
- const tc = _optionalChain([next, 'access', _328 => _328.thick, 'optionalAccess', _329 => _329[id]]);
6971
+ const tc = _optionalChain([next, 'access', _333 => _333.thick, 'optionalAccess', _334 => _334[id]]);
6938
6972
  if (tc && (ox || oy)) {
6939
6973
  next = {
6940
6974
  ...next,
@@ -6948,8 +6982,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6948
6982
  }
6949
6983
  };
6950
6984
  }
6951
- if (_optionalChain([next, 'access', _330 => _330.fluor, 'optionalAccess', _331 => _331[id]]) && (ox || oy)) next = { ...next, fluor: { ...next.fluor, [id]: _chunk474IQG74cjs.translateSurface.call(void 0, next.fluor[id], ox, oy) } };
6952
- if (_optionalChain([next, 'access', _332 => _332.thermo, 'optionalAccess', _333 => _333[id]]) && (ox || oy)) next = { ...next, thermo: { ...next.thermo, [id]: _chunk474IQG74cjs.translateSurface.call(void 0, next.thermo[id], ox, oy) } };
6985
+ if (_optionalChain([next, 'access', _335 => _335.fluor, 'optionalAccess', _336 => _336[id]]) && (ox || oy)) next = { ...next, fluor: { ...next.fluor, [id]: _chunk474IQG74cjs.translateSurface.call(void 0, next.fluor[id], ox, oy) } };
6986
+ if (_optionalChain([next, 'access', _337 => _337.thermo, 'optionalAccess', _338 => _338[id]]) && (ox || oy)) next = { ...next, thermo: { ...next.thermo, [id]: _chunk474IQG74cjs.translateSurface.call(void 0, next.thermo[id], ox, oy) } };
6953
6987
  }
6954
6988
  }
6955
6989
  if (this.wet.world) {
@@ -6977,23 +7011,23 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
6977
7011
  this.requireIdle("changing the paper");
6978
7012
  let base = this.doc.paper;
6979
7013
  if (update.preset !== void 0 && update.preset !== this.doc.paper.preset) {
6980
- const p = _chunkOLZXXAERcjs.paperPreset.call(void 0, update.preset);
7014
+ const p = _chunkOY24XRYFcjs.paperPreset.call(void 0, update.preset);
6981
7015
  if (!p) throw new PaintEditorError(`Unknown paper "${update.preset}". Call list_papers for the ids.`);
6982
7016
  base = p;
6983
7017
  }
6984
7018
  const { preset: _p, ...rest } = update;
6985
7019
  if (rest.color !== void 0) parseColor(rest.color, "paper color");
6986
- const paper = _chunkOLZXXAERcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
7020
+ const paper = _chunkOY24XRYFcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
6987
7021
  const changedKeys = Object.keys(rest).filter((k) => k !== "name");
6988
7022
  if (changedKeys.length && update.preset === void 0) paper.preset = base.preset;
6989
7023
  if (this.wet.world) this.beginWetOp();
6990
7024
  this.commit("Paper", { ...this.doc, paper });
6991
7025
  this.wet.paperChanged();
6992
- return _chunkOLZXXAERcjs.clonePaper.call(void 0, paper);
7026
+ return _chunkOY24XRYFcjs.clonePaper.call(void 0, paper);
6993
7027
  }
6994
7028
  // --- Layers --------------------------------------------------------------------
6995
7029
  getLayer(id) {
6996
- return _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _334 => _334.layer]);
7030
+ return _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _339 => _339.layer]);
6997
7031
  }
6998
7032
  /** The active pixel layer (or `undefined`). */
6999
7033
  getActiveLayer() {
@@ -7012,10 +7046,10 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7012
7046
  walk(this.doc.layers, null, 0);
7013
7047
  return out;
7014
7048
  }
7015
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _335 => _335.parent, 'optionalAccess', _336 => _336.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _337 => _337.path, 'access', _338 => _338.length]), () => ( 0))) {
7049
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _340 => _340.parent, 'optionalAccess', _341 => _341.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _342 => _342.path, 'access', _343 => _343.length]), () => ( 0))) {
7016
7050
  let bounds = null;
7017
7051
  if (l.type === "pixel") {
7018
- const b = unionRect(_chunk474IQG74cjs.contentBounds.call(void 0, l.surface), _optionalChain([this, 'access', _339 => _339.doc, 'access', _340 => _340.fluor, 'optionalAccess', _341 => _341[l.id]]) ? _chunk474IQG74cjs.contentBounds.call(void 0, this.doc.fluor[l.id]) : null);
7052
+ const b = unionRect(_chunk474IQG74cjs.contentBounds.call(void 0, l.surface), _optionalChain([this, 'access', _344 => _344.doc, 'access', _345 => _345.fluor, 'optionalAccess', _346 => _346[l.id]]) ? _chunk474IQG74cjs.contentBounds.call(void 0, this.doc.fluor[l.id]) : null);
7019
7053
  bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;
7020
7054
  } else for (const c of _chunkPVJMTLPJcjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
7021
7055
  return {
@@ -7029,8 +7063,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7029
7063
  locks: { ..._nullishCoalesce(l.locks, () => ( {})) },
7030
7064
  active: l.id === this.doc.activeLayerId,
7031
7065
  bounds,
7032
- ..._optionalChain([this, 'access', _342 => _342.doc, 'access', _343 => _343.liveStrokes, 'optionalAccess', _344 => _344[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
7033
- ..._optionalChain([l, 'access', _345 => _345.effects, 'optionalAccess', _346 => _346.items, 'access', _347 => _347.length]) ? { effects: l.effects.items.length } : {},
7066
+ ..._optionalChain([this, 'access', _347 => _347.doc, 'access', _348 => _348.liveStrokes, 'optionalAccess', _349 => _349[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
7067
+ ..._optionalChain([l, 'access', _350 => _350.effects, 'optionalAccess', _351 => _351.items, 'access', _352 => _352.length]) ? { effects: l.effects.items.length } : {},
7034
7068
  ...l.type === "pixel" && l.temporary ? { temporary: true } : {},
7035
7069
  parentId,
7036
7070
  depth
@@ -7064,7 +7098,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7064
7098
  this.requireIdle("adding a layer");
7065
7099
  const count = _chunkPVJMTLPJcjs.flattenLayers.call(void 0, this.doc.layers).length;
7066
7100
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
7067
- const name = _optionalChain([options, 'access', _348 => _348.name, 'optionalAccess', _349 => _349.trim, 'call', _350 => _350()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
7101
+ const name = _optionalChain([options, 'access', _353 => _353.name, 'optionalAccess', _354 => _354.trim, 'call', _355 => _355()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
7068
7102
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
7069
7103
  let parentId = null;
7070
7104
  let index;
@@ -7076,7 +7110,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7076
7110
  } else if (above) {
7077
7111
  const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above);
7078
7112
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
7079
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _351 => _351.parent, 'optionalAccess', _352 => _352.id]), () => ( null));
7113
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _356 => _356.parent, 'optionalAccess', _357 => _357.id]), () => ( null));
7080
7114
  index = loc.index + 1;
7081
7115
  }
7082
7116
  const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
@@ -7182,7 +7216,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7182
7216
  }
7183
7217
  requireEffect(id, effectId) {
7184
7218
  const l = this.requireLayer(id);
7185
- const items = _nullishCoalesce(_optionalChain([l, 'access', _353 => _353.effects, 'optionalAccess', _354 => _354.items]), () => ( []));
7219
+ const items = _nullishCoalesce(_optionalChain([l, 'access', _358 => _358.effects, 'optionalAccess', _359 => _359.items]), () => ( []));
7186
7220
  const i = items.findIndex((e) => e.id === effectId);
7187
7221
  if (i === -1) throw new PaintEditorError(`Layer "${l.name}" has no effect "${effectId}". Effects: ${items.map((e) => `${e.id} (${e.kind})`).join(", ") || "none"}; call list_layer_effects.`);
7188
7222
  return i;
@@ -7205,7 +7239,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7205
7239
  }
7206
7240
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
7207
7241
  let active = this.doc.activeLayerId;
7208
- if (active && !_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _355 => _355.filter, 'call', _356 => _356((x) => x.type === "pixel"), 'access', _357 => _357.pop, 'call', _358 => _358(), 'optionalAccess', _359 => _359.id]), () => ( null));
7242
+ if (active && !_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _360 => _360.filter, 'call', _361 => _361((x) => x.type === "pixel"), 'access', _362 => _362.pop, 'call', _363 => _363(), 'optionalAccess', _364 => _364.id]), () => ( null));
7209
7243
  const removedIds = _chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id);
7210
7244
  this.commit("Remove layer", {
7211
7245
  ...this.doc,
@@ -7246,7 +7280,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7246
7280
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
7247
7281
  };
7248
7282
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
7249
- const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _360 => _360.parent, 'optionalAccess', _361 => _361.id]), () => ( null)), loc.index + 1);
7283
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _365 => _365.parent, 'optionalAccess', _366 => _366.id]), () => ( null)), loc.index + 1);
7250
7284
  this.commit(
7251
7285
  "Duplicate layer",
7252
7286
  this.withWetEvents({
@@ -7268,7 +7302,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7268
7302
  this.requireIdle("moving a layer");
7269
7303
  const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
7270
7304
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
7271
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _362 => _362.parent, 'optionalAccess', _363 => _363.id]), () => ( null)) : parentId;
7305
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _367 => _367.parent, 'optionalAccess', _368 => _368.id]), () => ( null)) : parentId;
7272
7306
  if (target) {
7273
7307
  const g = this.requireLayer(target);
7274
7308
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
@@ -7287,7 +7321,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7287
7321
  const pre = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
7288
7322
  if (pre) {
7289
7323
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
7290
- this.dryLayersFirst([id, _optionalChain([sib, 'access', _364 => _364[pre.index - 1], 'optionalAccess', _365 => _365.id])].filter((x) => Boolean(x)));
7324
+ this.dryLayersFirst([id, _optionalChain([sib, 'access', _369 => _369[pre.index - 1], 'optionalAccess', _370 => _370.id])].filter((x) => Boolean(x)));
7291
7325
  }
7292
7326
  const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
7293
7327
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
@@ -7308,13 +7342,13 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7308
7342
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
7309
7343
  const toDoc = (t, l) => t ? _chunk474IQG74cjs.translateSurface.call(void 0, t, l.offset.x, l.offset.y) : void 0;
7310
7344
  const upperDoc = _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y);
7311
- const mergedLight = _optionalChain([this, 'access', _366 => _366.doc, 'access', _367 => _367.light, 'optionalAccess', _368 => _368[upper.id]]) || _optionalChain([this, 'access', _369 => _369.doc, 'access', _370 => _370.light, 'optionalAccess', _371 => _371[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _372 => _372.doc, 'access', _373 => _373.light, 'optionalAccess', _374 => _374[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _375 => _375.doc, 'access', _376 => _376.light, 'optionalAccess', _377 => _377[upper.id]]), upper) : void 0, upperDoc) : void 0;
7345
+ const mergedLight = _optionalChain([this, 'access', _371 => _371.doc, 'access', _372 => _372.light, 'optionalAccess', _373 => _373[upper.id]]) || _optionalChain([this, 'access', _374 => _374.doc, 'access', _375 => _375.light, 'optionalAccess', _376 => _376[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _377 => _377.doc, 'access', _378 => _378.light, 'optionalAccess', _379 => _379[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _380 => _380.doc, 'access', _381 => _381.light, 'optionalAccess', _382 => _382[upper.id]]), upper) : void 0, upperDoc) : void 0;
7312
7346
  const lightAfter = _nullishCoalesce(this.lightWithout([upper.id, below.id]).light, () => ( (this.doc.light ? { ...this.doc.light } : void 0)));
7313
7347
  const light = mergedLight ? { ..._nullishCoalesce(lightAfter, () => ( {})), [below.id]: mergedLight } : lightAfter;
7314
- const mergedFluor = _optionalChain([this, 'access', _378 => _378.doc, 'access', _379 => _379.fluor, 'optionalAccess', _380 => _380[upper.id]]) || _optionalChain([this, 'access', _381 => _381.doc, 'access', _382 => _382.fluor, 'optionalAccess', _383 => _383[below.id]]) ? mergeFourChannel(toDoc(_optionalChain([this, 'access', _384 => _384.doc, 'access', _385 => _385.fluor, 'optionalAccess', _386 => _386[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _387 => _387.doc, 'access', _388 => _388.fluor, 'optionalAccess', _389 => _389[upper.id]]), upper) : void 0) : void 0;
7348
+ const mergedFluor = _optionalChain([this, 'access', _383 => _383.doc, 'access', _384 => _384.fluor, 'optionalAccess', _385 => _385[upper.id]]) || _optionalChain([this, 'access', _386 => _386.doc, 'access', _387 => _387.fluor, 'optionalAccess', _388 => _388[below.id]]) ? mergeFourChannel(toDoc(_optionalChain([this, 'access', _389 => _389.doc, 'access', _390 => _390.fluor, 'optionalAccess', _391 => _391[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _392 => _392.doc, 'access', _393 => _393.fluor, 'optionalAccess', _394 => _394[upper.id]]), upper) : void 0) : void 0;
7315
7349
  const fluorAfter = _nullishCoalesce(this.fluorWithout([upper.id, below.id]).fluor, () => ( (this.doc.fluor ? { ...this.doc.fluor } : void 0)));
7316
7350
  const fluor = mergedFluor ? { ..._nullishCoalesce(fluorAfter, () => ( {})), [below.id]: mergedFluor } : fluorAfter;
7317
- const mergedThermo = _optionalChain([this, 'access', _390 => _390.doc, 'access', _391 => _391.thermo, 'optionalAccess', _392 => _392[upper.id]]) || _optionalChain([this, 'access', _393 => _393.doc, 'access', _394 => _394.thermo, 'optionalAccess', _395 => _395[below.id]]) ? mergeFourChannel(toDoc(_optionalChain([this, 'access', _396 => _396.doc, 'access', _397 => _397.thermo, 'optionalAccess', _398 => _398[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _399 => _399.doc, 'access', _400 => _400.thermo, 'optionalAccess', _401 => _401[upper.id]]), upper) : void 0) : void 0;
7351
+ const mergedThermo = _optionalChain([this, 'access', _395 => _395.doc, 'access', _396 => _396.thermo, 'optionalAccess', _397 => _397[upper.id]]) || _optionalChain([this, 'access', _398 => _398.doc, 'access', _399 => _399.thermo, 'optionalAccess', _400 => _400[below.id]]) ? mergeFourChannel(toDoc(_optionalChain([this, 'access', _401 => _401.doc, 'access', _402 => _402.thermo, 'optionalAccess', _403 => _403[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _404 => _404.doc, 'access', _405 => _405.thermo, 'optionalAccess', _406 => _406[upper.id]]), upper) : void 0) : void 0;
7318
7352
  const thermoAfter = _nullishCoalesce(this.thermoWithout([upper.id, below.id]).thermo, () => ( (this.doc.thermo ? { ...this.doc.thermo } : void 0)));
7319
7353
  const thermo = mergedThermo ? { ..._nullishCoalesce(thermoAfter, () => ( {})), [below.id]: mergedThermo } : thermoAfter;
7320
7354
  this.commit(
@@ -7350,7 +7384,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7350
7384
  layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })),
7351
7385
  ...this.thickWithout([l.id]),
7352
7386
  ...this.stickersWithout([l.id]),
7353
- ..._optionalChain([this, 'access', _402 => _402.doc, 'access', _403 => _403.liveStrokes, 'optionalAccess', _404 => _404[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {},
7387
+ ..._optionalChain([this, 'access', _407 => _407.doc, 'access', _408 => _408.liveStrokes, 'optionalAccess', _409 => _409[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {},
7354
7388
  ...this.lightWithout([l.id]),
7355
7389
  ...this.fluorWithout([l.id]),
7356
7390
  ...this.thermoWithout([l.id])
@@ -7367,8 +7401,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7367
7401
  fillLayer(options = {}) {
7368
7402
  this.requireIdle("filling");
7369
7403
  const fillTarget = this.paintTarget(options.layerId, "fill");
7370
- if (_optionalChain([this, 'access', _405 => _405.doc, 'access', _406 => _406.stickers, 'optionalAccess', _407 => _407[fillTarget.id], 'optionalAccess', _408 => _408.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
7371
- if (_optionalChain([this, 'access', _409 => _409.doc, 'access', _410 => _410.liveStrokes, 'optionalAccess', _411 => _411[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
7404
+ if (_optionalChain([this, 'access', _410 => _410.doc, 'access', _411 => _411.stickers, 'optionalAccess', _412 => _412[fillTarget.id], 'optionalAccess', _413 => _413.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
7405
+ if (_optionalChain([this, 'access', _414 => _414.doc, 'access', _415 => _415.liveStrokes, 'optionalAccess', _416 => _416[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
7372
7406
  this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
7373
7407
  const l = this.paintTarget(options.layerId, "fill");
7374
7408
  const color = options.color === void 0 ? this.color : parseColor(options.color);
@@ -7381,13 +7415,13 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7381
7415
  if (!_chunk2VX55NFMcjs.isBlendMode.call(void 0, blend)) throw new PaintEditorError(`Unknown blend mode "${blend}".`);
7382
7416
  const { width, height } = this.doc.canvas;
7383
7417
  const rect = { x: 0, y: 0, width, height };
7384
- const coverage = new (0, _chunkNIBFKXMDcjs.CoverageMap)();
7418
+ const coverage = new (0, _chunkIFWLZZCWcjs.CoverageMap)();
7385
7419
  const depth = grainAmount * this.doc.paper.depth;
7386
7420
  const grain = depth > 0 ? paperGrain(this.doc.paper) : null;
7387
7421
  for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, rect)) {
7388
7422
  const r = { x: tx * _chunk474IQG74cjs.TILE, y: ty * _chunk474IQG74cjs.TILE, width: Math.min(_chunk474IQG74cjs.TILE, width - tx * _chunk474IQG74cjs.TILE), height: Math.min(_chunk474IQG74cjs.TILE, height - ty * _chunk474IQG74cjs.TILE) };
7389
7423
  const vals = new Float32Array(r.width * r.height);
7390
- for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkNIBFKXMDcjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
7424
+ for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkIFWLZZCWcjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
7391
7425
  coverage.accumulate(r, vals, 1);
7392
7426
  }
7393
7427
  const apply = {
@@ -7401,11 +7435,11 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7401
7435
  offset: l.offset
7402
7436
  };
7403
7437
  const surface = this.applyCoverage(l, coverage, rect, apply);
7404
- const lit = _optionalChain([this, 'access', _412 => _412.doc, 'access', _413 => _413.light, 'optionalAccess', _414 => _414[l.id]]);
7438
+ const lit = _optionalChain([this, 'access', _417 => _417.doc, 'access', _418 => _418.light, 'optionalAccess', _419 => _419[l.id]]);
7405
7439
  const light = lit ? withLayerLight(this.doc.light, l.id, scaleLight(lit, 1 - opacity)) : void 0;
7406
- const fl = _optionalChain([this, 'access', _415 => _415.doc, 'access', _416 => _416.fluor, 'optionalAccess', _417 => _417[l.id]]);
7440
+ const fl = _optionalChain([this, 'access', _420 => _420.doc, 'access', _421 => _421.fluor, 'optionalAccess', _422 => _422[l.id]]);
7407
7441
  const fluor = fl ? withLayerLight(this.doc.fluor, l.id, scaleFluor(fl, 1 - opacity)) : void 0;
7408
- const th = _optionalChain([this, 'access', _418 => _418.doc, 'access', _419 => _419.thermo, 'optionalAccess', _420 => _420[l.id]]);
7442
+ const th = _optionalChain([this, 'access', _423 => _423.doc, 'access', _424 => _424.thermo, 'optionalAccess', _425 => _425[l.id]]);
7409
7443
  const thermo = th && opacity >= 0.5 ? this.thermoWithout([l.id]).thermo : void 0;
7410
7444
  this.commit(
7411
7445
  "Fill layer",
@@ -7432,8 +7466,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7432
7466
  fillRegion(options) {
7433
7467
  this.requireIdle("filling");
7434
7468
  const fillTarget = this.paintTarget(options.layerId, "fill");
7435
- if (_optionalChain([this, 'access', _421 => _421.doc, 'access', _422 => _422.stickers, 'optionalAccess', _423 => _423[fillTarget.id], 'optionalAccess', _424 => _424.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
7436
- if (_optionalChain([this, 'access', _425 => _425.doc, 'access', _426 => _426.liveStrokes, 'optionalAccess', _427 => _427[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
7469
+ if (_optionalChain([this, 'access', _426 => _426.doc, 'access', _427 => _427.stickers, 'optionalAccess', _428 => _428[fillTarget.id], 'optionalAccess', _429 => _429.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
7470
+ if (_optionalChain([this, 'access', _430 => _430.doc, 'access', _431 => _431.liveStrokes, 'optionalAccess', _432 => _432[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
7437
7471
  const { width, height } = this.doc.canvas;
7438
7472
  const pts = [];
7439
7473
  if (options.points !== void 0) {
@@ -7487,8 +7521,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7487
7521
  if (!(Number.isFinite(pressure) && pressure >= 0 && pressure <= 1)) throw new PaintEditorError(`pressure ${pressure} is out of range; use 0..1.`);
7488
7522
  const wet = options.wet === true;
7489
7523
  if (wet && this.previewing) throw new PaintEditorError("Wet paint can't be previewed; suggest a dry fill instead.");
7490
- if (wet && !this.wet.wetLayerIds().includes(fillTarget.id) && this.wet.wetLayerIds().length >= _chunkDHC4E2DUcjs.MAX_WET_LANES) {
7491
- throw new PaintEditorError(`At most ${_chunkDHC4E2DUcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
7524
+ if (wet && !this.wet.wetLayerIds().includes(fillTarget.id) && this.wet.wetLayerIds().length >= _chunkMITQGHN3cjs.MAX_WET_LANES) {
7525
+ throw new PaintEditorError(`At most ${_chunkMITQGHN3cjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
7492
7526
  }
7493
7527
  const refPixels = refSpec === "layer" ? this.compositePixels({ layerIds: [fillTarget.id], paper: false, wet: "display" }).data : refSpec === "all" || refSpec === "composite" ? this.compositePixels({ paper: false, wet: "display" }).data : this.compositePixels({ layerIds: [refSpec], paper: false, wet: "display" }).data;
7494
7528
  const filled = _chunkYH6SKC7Pcjs.fillRegionMask.call(void 0, refPixels, width, height, {
@@ -7536,10 +7570,10 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7536
7570
  }
7537
7571
  this.beginWetOp();
7538
7572
  const world = this.wet.ensureLane(l2.id);
7539
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, color);
7540
- const medium = new (0, _chunkDHC4E2DUcjs.WetMedium)(world, l2.id, {
7573
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, color);
7574
+ const medium = new (0, _chunkMITQGHN3cjs.WetMedium)(world, l2.id, {
7541
7575
  water: 0.9 * Math.max(0.25, opacity),
7542
- mass: _chunkDHC4E2DUcjs.PIGMENT_UNIT * 2.5 * opacity,
7576
+ mass: _chunkMITQGHN3cjs.PIGMENT_UNIT * 2.5 * opacity,
7543
7577
  body: 0,
7544
7578
  light: 0
7545
7579
  });
@@ -7550,7 +7584,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7550
7584
  for (let xx = 0; xx < rect.width; xx++, k++) {
7551
7585
  const px = rect.x + xx;
7552
7586
  let v = filled.mask[row + px];
7553
- if (v > 0 && grain) v *= _chunkNIBFKXMDcjs.grainCatch.call(void 0, grain.at(px + 0.5, py + 0.5), depth, pressure);
7587
+ if (v > 0 && grain) v *= _chunkIFWLZZCWcjs.grainCatch.call(void 0, grain.at(px + 0.5, py + 0.5), depth, pressure);
7554
7588
  subCov[k] = Math.round(v * 4096) / 4096;
7555
7589
  }
7556
7590
  }
@@ -7582,7 +7616,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7582
7616
  }
7583
7617
  this.dryLayersFirst([fillTarget.id]);
7584
7618
  const l = this.paintTarget(options.layerId, "fill");
7585
- const coverage = new (0, _chunkNIBFKXMDcjs.CoverageMap)();
7619
+ const coverage = new (0, _chunkIFWLZZCWcjs.CoverageMap)();
7586
7620
  const vals = new Float32Array(rect.width * rect.height);
7587
7621
  for (let yy = 0, k = 0; yy < rect.height; yy++) {
7588
7622
  const py = rect.y + yy;
@@ -7590,7 +7624,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7590
7624
  for (let xx = 0; xx < rect.width; xx++, k++) {
7591
7625
  const px = rect.x + xx;
7592
7626
  let v = filled.mask[row + px];
7593
- if (v > 0 && grain) v *= _chunkNIBFKXMDcjs.grainCatch.call(void 0, grain.at(px + 0.5, py + 0.5), depth, pressure);
7627
+ if (v > 0 && grain) v *= _chunkIFWLZZCWcjs.grainCatch.call(void 0, grain.at(px + 0.5, py + 0.5), depth, pressure);
7594
7628
  vals[k] = v;
7595
7629
  }
7596
7630
  }
@@ -7673,8 +7707,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7673
7707
  const tiles = new Map(base.tiles);
7674
7708
  for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {
7675
7709
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
7676
- const src = _nullishCoalesce(_optionalChain([base, 'access', _428 => _428.tiles, 'access', _429 => _429.get, 'call', _430 => _430(key), 'optionalAccess', _431 => _431.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
7677
- const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkNIBFKXMDcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
7710
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _433 => _433.tiles, 'access', _434 => _434.get, 'call', _435 => _435(key), 'optionalAccess', _436 => _436.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
7711
+ const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkIFWLZZCWcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
7678
7712
  if (tile) tiles.set(key, tile);
7679
7713
  else tiles.delete(key);
7680
7714
  }
@@ -7708,7 +7742,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7708
7742
  }
7709
7743
  /** The effect a layer is drawn from, or `undefined` for other layers. */
7710
7744
  getEffectLayer(layerId) {
7711
- return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _432 => _432.doc, 'access', _433 => _433.effectLayers, 'optionalAccess', _434 => _434[layerId]]) : void 0;
7745
+ return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _437 => _437.doc, 'access', _438 => _438.effectLayers, 'optionalAccess', _439 => _439[layerId]]) : void 0;
7712
7746
  }
7713
7747
  /** The effect paper (without its pixels), or `null`. */
7714
7748
  getPaperEffect() {
@@ -7745,8 +7779,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7745
7779
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
7746
7780
  effectTarget(layerId, what) {
7747
7781
  const l = this.paintTarget(layerId, what);
7748
- if (_optionalChain([this, 'access', _435 => _435.doc, 'access', _436 => _436.stickers, 'optionalAccess', _437 => _437[l.id], 'optionalAccess', _438 => _438.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
7749
- if (_optionalChain([this, 'access', _439 => _439.doc, 'access', _440 => _440.liveStrokes, 'optionalAccess', _441 => _441[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
7782
+ if (_optionalChain([this, 'access', _440 => _440.doc, 'access', _441 => _441.stickers, 'optionalAccess', _442 => _442[l.id], 'optionalAccess', _443 => _443.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
7783
+ if (_optionalChain([this, 'access', _444 => _444.doc, 'access', _445 => _445.liveStrokes, 'optionalAccess', _446 => _446[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
7750
7784
  if (this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" holds wet paint; effects go on dried paint, so dry it first (dry_paint) and try again.`);
7751
7785
  return l;
7752
7786
  }
@@ -7785,8 +7819,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7785
7819
  const was = this.doc.paperEffect;
7786
7820
  const paperEffect = {
7787
7821
  ...this.sourceOf(d, values, options.time),
7788
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _442 => _442.opacity]))), () => ( 1)),
7789
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _443 => _443.blend]))), () => ( "multiply")),
7822
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _447 => _447.opacity]))), () => ( 1)),
7823
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _448 => _448.blend]))), () => ( "multiply")),
7790
7824
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
7791
7825
  version: nextPaperEffectVersion()
7792
7826
  };
@@ -7839,8 +7873,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7839
7873
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
7840
7874
  const loc = above ? _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above) : null;
7841
7875
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
7842
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _444 => _444.name, 'optionalAccess', _445 => _445.trim, 'call', _446 => _446()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
7843
- const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _447 => _447.parent, 'optionalAccess', _448 => _448.id]), () => ( null)), loc ? loc.index + 1 : void 0);
7876
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _449 => _449.name, 'optionalAccess', _450 => _450.trim, 'call', _451 => _451()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
7877
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _452 => _452.parent, 'optionalAccess', _453 => _453.id]), () => ( null)), loc ? loc.index + 1 : void 0);
7844
7878
  const source = this.sourceOf(d, values, options.time);
7845
7879
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
7846
7880
  return { layer: this.describeLayer(layer), source };
@@ -7924,7 +7958,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7924
7958
  this.checkTime(source.time);
7925
7959
  let map;
7926
7960
  try {
7927
- map = _chunkOLZXXAERcjs.readEffectStrokeMap.call(void 0, source.map);
7961
+ map = _chunkOY24XRYFcjs.readEffectStrokeMap.call(void 0, source.map);
7928
7962
  } catch (e) {
7929
7963
  throw new PaintEditorError(e.message);
7930
7964
  }
@@ -7932,7 +7966,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7932
7966
  const epoch = ++this.paintEpoch;
7933
7967
  const changed = (name) => new PaintEditorError(`The paint changed while "${name}" rendered (set_color, set_paint or another set_effect_paint); call set_effect_paint again to paint with it.`);
7934
7968
  const d = await this.describeEffect(source.effect, "paint");
7935
- if (_optionalChain([map, 'optionalAccess', _449 => _449.by]) === "path" && !_chunkL2JTLW6Bcjs.pathControlsOf.call(void 0, d).length) {
7969
+ if (_optionalChain([map, 'optionalAccess', _454 => _454.by]) === "path" && !_chunkL2JTLW6Bcjs.pathControlsOf.call(void 0, d).length) {
7936
7970
  throw new PaintEditorError(`Effect "${d.id}" has no path control (format "svg-path"); use by: "stroke" (bent along each stroke) or by: "canvas" (fixed to the canvas).`);
7937
7971
  }
7938
7972
  const values = this.effectValues(d, { ...d.defaults }, source.values);
@@ -7958,9 +7992,9 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7958
7992
  }
7959
7993
  /** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
7960
7994
  effectPaintImage(p) {
7961
- const key = _chunkOLZXXAERcjs.effectPaintKey.call(void 0, p);
7995
+ const key = _chunkOY24XRYFcjs.effectPaintKey.call(void 0, p);
7962
7996
  const img = this.effectPaintPixels.get(key);
7963
- const size = _chunkOLZXXAERcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
7997
+ const size = _chunkOY24XRYFcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
7964
7998
  if (!img || img.width !== size.width || img.height !== size.height) return null;
7965
7999
  this.effectPaintPixels.delete(key);
7966
8000
  this.effectPaintPixels.set(key, img);
@@ -7970,13 +8004,13 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7970
8004
  return this.cacheEffectPaintImage(p, toEffectPaintPixels(p, pixels));
7971
8005
  }
7972
8006
  cacheEffectPaintImage(p, img) {
7973
- this.effectPaintPixels.set(_chunkOLZXXAERcjs.effectPaintKey.call(void 0, p), img);
8007
+ this.effectPaintPixels.set(_chunkOY24XRYFcjs.effectPaintKey.call(void 0, p), img);
7974
8008
  this.trimEffectPaints();
7975
8009
  return img;
7976
8010
  }
7977
8011
  trimEffectPaints() {
7978
8012
  let live = 0;
7979
- for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) for (const s of list) if (_optionalChain([s, 'access', _450 => _450.paint, 'optionalAccess', _451 => _451.type]) === "effect" && _optionalChain([s, 'access', _452 => _452.paint, 'access', _453 => _453.map, 'optionalAccess', _454 => _454.by]) === "path") live++;
8013
+ for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) for (const s of list) if (_optionalChain([s, 'access', _455 => _455.paint, 'optionalAccess', _456 => _456.type]) === "effect" && _optionalChain([s, 'access', _457 => _457.paint, 'access', _458 => _458.map, 'optionalAccess', _459 => _459.by]) === "path") live++;
7980
8014
  const limit = Math.max(_PaintEditorController.EFFECT_PAINT_CACHE, this.effectPaintBatch, live + 1);
7981
8015
  while (this.effectPaintPixels.size > limit) this.effectPaintPixels.delete(this.effectPaintPixels.keys().next().value);
7982
8016
  }
@@ -7986,7 +8020,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
7986
8020
  if (have) return have;
7987
8021
  const provider = this.effects.provider;
7988
8022
  if (!provider || p.provider && provider.id !== p.provider) return null;
7989
- const size = _chunkOLZXXAERcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
8023
+ const size = _chunkOY24XRYFcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
7990
8024
  const pixels = this.effectsRenderer.renderSync(provider, p.effect, size, { time: p.time, values: p.values });
7991
8025
  return pixels ? this.cacheEffectPaintPixels(p, pixels) : null;
7992
8026
  }
@@ -8002,7 +8036,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8002
8036
  const what = `the effect "${p.effect}"${p.provider ? ` from provider "${p.provider}"` : ""}`;
8003
8037
  if (!provider) throw new PaintEditorError(`Effect paint needs ${what}, but no effects provider is registered; register it (setEffectsProvider) and try again.`);
8004
8038
  if (p.provider && provider.id !== p.provider) throw new PaintEditorError(`Effect paint needs ${what}, but the registered provider is "${provider.id}"; register "${p.provider}" (setEffectsProvider) and try again.`);
8005
- const { width, height } = _chunkOLZXXAERcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
8039
+ const { width, height } = _chunkOY24XRYFcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
8006
8040
  let pixels;
8007
8041
  try {
8008
8042
  pixels = await this.effectsRenderer.render(provider, p.effect, { width, height }, { time: p.time, values: p.values });
@@ -8017,10 +8051,10 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8017
8051
  */
8018
8052
  async prepareEffectPaints(paints2) {
8019
8053
  const list = [...paints2];
8020
- this.effectPaintBatch = new Set(list.map(_chunkOLZXXAERcjs.effectPaintKey)).size;
8054
+ this.effectPaintBatch = new Set(list.map(_chunkOY24XRYFcjs.effectPaintKey)).size;
8021
8055
  const seen = /* @__PURE__ */ new Set();
8022
8056
  for (const p of list) {
8023
- const key = _chunkOLZXXAERcjs.effectPaintKey.call(void 0, p);
8057
+ const key = _chunkOY24XRYFcjs.effectPaintKey.call(void 0, p);
8024
8058
  if (seen.has(key)) continue;
8025
8059
  seen.add(key);
8026
8060
  await this.renderEffectPaint(p);
@@ -8033,18 +8067,18 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8033
8067
  */
8034
8068
  async prepareStrokePathEffect(init, pointsList) {
8035
8069
  const brush = this.strokeBrush(init);
8036
- if (!_chunk6QNDGMK7cjs.brushTakesPaint.call(void 0, brush)) return;
8070
+ if (!_chunkQ33V5PEFcjs.brushTakesPaint.call(void 0, brush)) return;
8037
8071
  let source = null;
8038
8072
  if (init.paint !== void 0) {
8039
- if (!_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, init.paint)) return;
8040
- source = _chunkOLZXXAERcjs.readPaintEffectPaint.call(void 0, init.paint);
8073
+ if (!_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, init.paint)) return;
8074
+ source = _chunkOY24XRYFcjs.readPaintEffectPaint.call(void 0, init.paint);
8041
8075
  } else if (init.color === void 0 && !brush.paint && !this.effectPaintPending) {
8042
8076
  source = this.effectPaint;
8043
8077
  }
8044
- if (!source || _optionalChain([source, 'access', _455 => _455.map, 'optionalAccess', _456 => _456.by]) !== "path") return;
8078
+ if (!source || _optionalChain([source, 'access', _460 => _460.map, 'optionalAccess', _461 => _461.by]) !== "path") return;
8045
8079
  if (!this.effectPathControls.has(source.effect)) await this.describeEffect(source.effect);
8046
8080
  const control = this.effectPathControls.get(source.effect);
8047
- const paints2 = pointsList.filter((pts) => pts.length > 0).map((pts) => _chunkOLZXXAERcjs.withStrokePath.call(void 0, source, pts, control));
8081
+ const paints2 = pointsList.filter((pts) => pts.length > 0).map((pts) => _chunkOY24XRYFcjs.withStrokePath.call(void 0, source, pts, control));
8048
8082
  if (paints2.length) await this.prepareEffectPaints(paints2);
8049
8083
  }
8050
8084
  /**
@@ -8055,7 +8089,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8055
8089
  async prepareStrokeEdit(id, edit) {
8056
8090
  const p = this.strokeEditPaint(id, edit);
8057
8091
  if (!p) return;
8058
- if (_optionalChain([p, 'access', _457 => _457.map, 'optionalAccess', _458 => _458.by]) === "path" && !this.effectPathControls.has(p.effect)) await this.describeEffect(p.effect);
8092
+ if (_optionalChain([p, 'access', _462 => _462.map, 'optionalAccess', _463 => _463.by]) === "path" && !this.effectPathControls.has(p.effect)) await this.describeEffect(p.effect);
8059
8093
  await this.prepareEffectPaints([_nullishCoalesce(this.strokeEditPaint(id, edit), () => ( p))]);
8060
8094
  }
8061
8095
  /** Whether `prepareStrokeEdit` has to be awaited before this edit can run. */
@@ -8068,15 +8102,15 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8068
8102
  if (!was) return null;
8069
8103
  try {
8070
8104
  if (edit.paint !== void 0) {
8071
- if (!_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, edit.paint)) return null;
8072
- const p = _chunkOLZXXAERcjs.readPaintEffectPaint.call(void 0, edit.paint);
8073
- return p && _chunkOLZXXAERcjs.withStrokePath.call(void 0, p, was.points, this.effectPathControls.get(p.effect));
8105
+ if (!_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, edit.paint)) return null;
8106
+ const p = _chunkOY24XRYFcjs.readPaintEffectPaint.call(void 0, edit.paint);
8107
+ return p && _chunkOY24XRYFcjs.withStrokePath.call(void 0, p, was.points, this.effectPathControls.get(p.effect));
8074
8108
  }
8075
- if (_optionalChain([was, 'access', _459 => _459.paint, 'optionalAccess', _460 => _460.type]) !== "effect" || _optionalChain([was, 'access', _461 => _461.paint, 'access', _462 => _462.map, 'optionalAccess', _463 => _463.by]) !== "path") return null;
8076
- if (edit.points !== void 0) return _chunkOLZXXAERcjs.withStrokePath.call(void 0, was.paint, this.checkPoints(edit.points), this.effectPathControls.get(was.paint.effect));
8109
+ if (_optionalChain([was, 'access', _464 => _464.paint, 'optionalAccess', _465 => _465.type]) !== "effect" || _optionalChain([was, 'access', _466 => _466.paint, 'access', _467 => _467.map, 'optionalAccess', _468 => _468.by]) !== "path") return null;
8110
+ if (edit.points !== void 0) return _chunkOY24XRYFcjs.withStrokePath.call(void 0, was.paint, this.checkPoints(edit.points), this.effectPathControls.get(was.paint.effect));
8077
8111
  if (!edit.transform) return null;
8078
8112
  const varied = varyStroke(was, this.strokeTransform(was, edit.transform), {}).paint;
8079
- return _optionalChain([varied, 'optionalAccess', _464 => _464.type]) === "effect" ? varied : null;
8113
+ return _optionalChain([varied, 'optionalAccess', _469 => _469.type]) === "effect" ? varied : null;
8080
8114
  } catch (e9) {
8081
8115
  return null;
8082
8116
  }
@@ -8091,7 +8125,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8091
8125
  /** Renders the effect paints of recorded strokes (default all of them) before a replay. */
8092
8126
  async prepareStrokeEffects(strokeIds, variation) {
8093
8127
  const ids = strokeIds ? new Set(strokeIds) : null;
8094
- const strokes = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _465 => _465.paint, 'optionalAccess', _466 => _466.type]) === "effect");
8128
+ const strokes = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _470 => _470.paint, 'optionalAccess', _471 => _471.type]) === "effect");
8095
8129
  const paints2 = strokes.map((s) => s.paint);
8096
8130
  if (variation && strokes.length) {
8097
8131
  const repeat = Math.max(1, Math.min(100, _nullishCoalesce(variation.repeat, () => ( 1))));
@@ -8106,7 +8140,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8106
8140
  m = [step[0] * m[0] + step[1] * m[2], step[0] * m[1] + step[1] * m[3], step[2] * m[0] + step[3] * m[2], step[2] * m[1] + step[3] * m[3], step[0] * m[4] + step[1] * m[5] + step[4], step[2] * m[4] + step[3] * m[5] + step[5]];
8107
8141
  for (const s of strokes) {
8108
8142
  const v = varyStroke(s, m, variation);
8109
- if (_optionalChain([v, 'access', _467 => _467.paint, 'optionalAccess', _468 => _468.type]) === "effect") paints2.push(v.paint);
8143
+ if (_optionalChain([v, 'access', _472 => _472.paint, 'optionalAccess', _473 => _473.type]) === "effect") paints2.push(v.paint);
8110
8144
  }
8111
8145
  }
8112
8146
  }
@@ -8138,19 +8172,19 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8138
8172
  * its pixels are not rendered.
8139
8173
  */
8140
8174
  strokeEffect(init, brush, points) {
8141
- if (!_chunk6QNDGMK7cjs.brushTakesPaint.call(void 0, brush)) return null;
8175
+ if (!_chunkQ33V5PEFcjs.brushTakesPaint.call(void 0, brush)) return null;
8142
8176
  let source = null;
8143
8177
  if (init.paint !== void 0) {
8144
- if (!_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
8145
- source = _chunkOLZXXAERcjs.readPaintEffectPaint.call(void 0, init.paint);
8178
+ if (!_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
8179
+ source = _chunkOY24XRYFcjs.readPaintEffectPaint.call(void 0, init.paint);
8146
8180
  if (!source) throw new PaintEditorError("The stroke's effect paint needs an effect id and values (getEffectPaint returns one).");
8147
8181
  } else if (init.color === void 0 && !brush.paint) {
8148
8182
  if (this.effectPaintPending) throw new PaintEditorError(`The effect paint "${this.effectPaintPending.effect}" is still rendering; wait for set_effect_paint to finish, then paint.`);
8149
8183
  source = this.effectPaint;
8150
8184
  }
8151
8185
  if (!source) return null;
8152
- const path = _optionalChain([source, 'access', _469 => _469.map, 'optionalAccess', _470 => _470.by]) === "path";
8153
- if (path && _optionalChain([points, 'optionalAccess', _471 => _471.length])) source = _chunkOLZXXAERcjs.withStrokePath.call(void 0, source, points, this.effectPathControls.get(source.effect));
8186
+ const path = _optionalChain([source, 'access', _474 => _474.map, 'optionalAccess', _475 => _475.by]) === "path";
8187
+ if (path && _optionalChain([points, 'optionalAccess', _476 => _476.length])) source = _chunkOY24XRYFcjs.withStrokePath.call(void 0, source, points, this.effectPathControls.get(source.effect));
8154
8188
  const pixels = _nullishCoalesce(this.effectPaintImage(source), () => ( (path ? this.renderEffectPaintSync(source) : null)));
8155
8189
  if (!pixels) throw new PaintEditorError(`The effect paint "${source.effect}"${source.provider ? ` from provider "${source.provider}"` : ""} is not rendered at this canvas size; call ${path ? "prepareStrokePathEffect (the paint_stroke tool does this) or prepareStrokeEdit" : "set_effect_paint (or prepareEffectPaints)"} first.`);
8156
8190
  return { source, pixels };
@@ -8174,14 +8208,14 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8174
8208
  const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
8175
8209
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
8176
8210
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
8177
- const relief = _optionalChain([this, 'access', _472 => _472.doc, 'access', _473 => _473.thick, 'optionalAccess', _474 => _474[l.id]]);
8211
+ const relief = _optionalChain([this, 'access', _477 => _477.doc, 'access', _478 => _478.thick, 'optionalAccess', _479 => _479[l.id]]);
8178
8212
  if (heightInput && relief) {
8179
8213
  const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
8180
8214
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
8181
8215
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
8182
8216
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
8183
8217
  }
8184
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _475 => _475.inputs, 'access', _476 => _476.find, 'call', _477 => _477((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _478 => _478.name])), 'optionalAccess', _479 => _479.name]), () => ( "source"));
8218
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _480 => _480.inputs, 'access', _481 => _481.find, 'call', _482 => _482((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _483 => _483.name])), 'optionalAccess', _484 => _484.name]), () => ( "source"));
8185
8219
  if (sourceInput !== "source") {
8186
8220
  inputs[sourceInput] = inputs.source;
8187
8221
  delete inputs.source;
@@ -8197,11 +8231,11 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8197
8231
  return this.brushEntries.find((e) => e.brush.id === id);
8198
8232
  }
8199
8233
  findBrush(id) {
8200
- return _optionalChain([this, 'access', _480 => _480.findEntry, 'call', _481 => _481(id), 'optionalAccess', _482 => _482.brush]);
8234
+ return _optionalChain([this, 'access', _485 => _485.findEntry, 'call', _486 => _486(id), 'optionalAccess', _487 => _487.brush]);
8201
8235
  }
8202
8236
  requireEntry(id) {
8203
8237
  const e = this.findEntry(id);
8204
- if (!e) throw new PaintEditorError(`Unknown brush "${id}". ${_chunk6QNDGMK7cjs.closest.call(void 0, id, this.brushEntries.map((x) => x.brush.id))}Call list_brush_presets for the ids.`);
8238
+ if (!e) throw new PaintEditorError(`Unknown brush "${id}". ${_chunkQ33V5PEFcjs.closest.call(void 0, id, this.brushEntries.map((x) => x.brush.id))}Call list_brush_presets for the ids.`);
8205
8239
  return e;
8206
8240
  }
8207
8241
  requireBrush(id) {
@@ -8230,11 +8264,11 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8230
8264
  /** A library brush by id, as the engine paints it (`undefined` when unknown). */
8231
8265
  getBrush(id) {
8232
8266
  const b = this.findBrush(id);
8233
- return b ? _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, b, b) : void 0;
8267
+ return b ? _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
8234
8268
  }
8235
8269
  /** A library brush by id as stored (its facets), or without an id the active brush as edited. */
8236
8270
  getBrushSpec(id) {
8237
- const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _483 => _483.findEntry, 'call', _484 => _484(id), 'optionalAccess', _485 => _485.spec]);
8271
+ const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _488 => _488.findEntry, 'call', _489 => _489(id), 'optionalAccess', _490 => _490.spec]);
8238
8272
  return spec ? copyJSON(spec) : void 0;
8239
8273
  }
8240
8274
  /**
@@ -8248,7 +8282,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8248
8282
  const baseSpec = entry ? entry.spec : this.brushSpec;
8249
8283
  if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
8250
8284
  const unchanged = !Object.keys(changes).length;
8251
- const next = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
8285
+ const next = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
8252
8286
  if (entry) this.takeBrushColour(entry.spec);
8253
8287
  this.useBrush(next, unchanged ? baseSpec : brushSpecOf(next, baseSpec), unchanged && base.builtin === true);
8254
8288
  return this.brush;
@@ -8266,8 +8300,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8266
8300
  const base = copyJSON(entry ? entry.spec : this.brushSpec);
8267
8301
  for (const k of unset) delete base[k];
8268
8302
  const spec = this.readBrushPatch(base, patch, problems);
8269
- if (entry || _optionalChain([patch, 'access', _486 => _486.colour, 'optionalAccess', _487 => _487.default]) !== void 0) this.takeBrushColour(spec);
8270
- this.useBrush(unchanged && entry ? entry.brush : _chunk6QNDGMK7cjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _488 => _488.builtin]) === true);
8303
+ if (entry || _optionalChain([patch, 'access', _491 => _491.colour, 'optionalAccess', _492 => _492.default]) !== void 0) this.takeBrushColour(spec);
8304
+ this.useBrush(unchanged && entry ? entry.brush : _chunkQ33V5PEFcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _493 => _493.builtin]) === true);
8271
8305
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
8272
8306
  }
8273
8307
  /**
@@ -8277,15 +8311,15 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8277
8311
  */
8278
8312
  setBrushSpec(spec) {
8279
8313
  const problems = [];
8280
- const paint = _optionalChain([spec, 'access', _489 => _489.colour, 'optionalAccess', _490 => _490.default]);
8314
+ const paint = _optionalChain([spec, 'access', _494 => _494.colour, 'optionalAccess', _495 => _495.default]);
8281
8315
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
8282
8316
  let next;
8283
8317
  try {
8284
- next = _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, { ...spec, id: this.brush.id }, problems);
8318
+ next = _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, { ...spec, id: this.brush.id }, problems);
8285
8319
  } catch (e) {
8286
8320
  throw new PaintEditorError(e.message);
8287
8321
  }
8288
- this.useBrush(_chunk6QNDGMK7cjs.resolveBrush.call(void 0, next), next, false);
8322
+ this.useBrush(_chunkQ33V5PEFcjs.resolveBrush.call(void 0, next), next, false);
8289
8323
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
8290
8324
  }
8291
8325
  /**
@@ -8294,22 +8328,22 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8294
8328
  */
8295
8329
  brushChanges(patch, from) {
8296
8330
  const entry = typeof from === "string" ? this.requireEntry(from) : null;
8297
- const base = entry ? entry.brush : typeof from === "object" ? _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, from, from) : this.brush;
8298
- const spec = entry ? entry.spec : typeof from === "object" ? _chunk6QNDGMK7cjs.migrateBrushV1.call(void 0, base) : this.brushSpec;
8299
- return engineChanges(base, _chunk6QNDGMK7cjs.resolveBrush.call(void 0, this.readBrushPatch(spec, patch, [])));
8331
+ const base = entry ? entry.brush : typeof from === "object" ? _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, from, from) : this.brush;
8332
+ const spec = entry ? entry.spec : typeof from === "object" ? _chunkQ33V5PEFcjs.migrateBrushV1.call(void 0, base) : this.brushSpec;
8333
+ return engineChanges(base, _chunkQ33V5PEFcjs.resolveBrush.call(void 0, this.readBrushPatch(spec, patch, [])));
8300
8334
  }
8301
8335
  readBrushPatch(base, patch, problems) {
8302
8336
  const { id: _id, name, ...rest } = patch;
8303
- const paint = _optionalChain([rest, 'access', _491 => _491.colour, 'optionalAccess', _492 => _492.default]);
8337
+ const paint = _optionalChain([rest, 'access', _496 => _496.colour, 'optionalAccess', _497 => _497.default]);
8304
8338
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
8305
8339
  try {
8306
- return _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, _chunkY354ETAEcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
8340
+ return _chunkQ33V5PEFcjs.normalizeBrushSpec.call(void 0, _chunk5HR5CSLCcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
8307
8341
  } catch (e) {
8308
8342
  throw new PaintEditorError(e.message);
8309
8343
  }
8310
8344
  }
8311
8345
  useBrush(next, spec, builtin) {
8312
- next = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, next, next);
8346
+ next = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, next, next);
8313
8347
  const refusal = mutationBrushRefusal(next);
8314
8348
  if (refusal) throw new PaintEditorError(refusal);
8315
8349
  if (builtin) next.builtin = true;
@@ -8318,7 +8352,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8318
8352
  this.brushSpec = { ...copyJSON(spec), id: next.id, name: next.name };
8319
8353
  this.pendingBrushId = null;
8320
8354
  this.emit([]);
8321
- const refs = _chunkOLZXXAERcjs.brushStickerRefs.call(void 0, next);
8355
+ const refs = _chunkOY24XRYFcjs.brushStickerRefs.call(void 0, next);
8322
8356
  if (refs.length) void this.prepareStickers(refs).catch(() => this.emit([]));
8323
8357
  }
8324
8358
  /**
@@ -8327,9 +8361,9 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8327
8361
  * saved brush.
8328
8362
  */
8329
8363
  async saveBrush(options) {
8330
- if (!_chunk6QNDGMK7cjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
8364
+ if (!_chunkQ33V5PEFcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
8331
8365
  if (this.brushLibrary.isBuiltin(options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
8332
- const spec = options.brush ? brushSpecOf(_chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, options.brush, this.brush), this.brushSpec) : this.brushSpec;
8366
+ const spec = options.brush ? brushSpecOf(_chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, options.brush, this.brush), this.brushSpec) : this.brushSpec;
8333
8367
  const { brush } = await libraryCall(() => this.brushLibrary.save({ ...spec, id: options.id, name: _nullishCoalesce(options.name, () => ( spec.name)) }, { overwrite: true }));
8334
8368
  await this.refreshBrushes();
8335
8369
  return this.requireBrush(brush.id);
@@ -8342,7 +8376,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8342
8376
  }
8343
8377
  /** The user's saved brushes, as the engine paints them. */
8344
8378
  getUserBrushes() {
8345
- return this.brushEntries.filter((e) => !e.builtin).map((e) => _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, e.brush, e.brush));
8379
+ return this.brushEntries.filter((e) => !e.builtin).map((e) => _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, e.brush, e.brush));
8346
8380
  }
8347
8381
  /** A brush library file (version 2) of the given brushes (default: the user's brushes). */
8348
8382
  exportBrushes(ids) {
@@ -8378,7 +8412,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8378
8412
  this.colorScheme = next;
8379
8413
  const hex2 = this.brushColour ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, this.brushColour, next) : null;
8380
8414
  if (hex2) this.color = hex2;
8381
- const refs = _chunkOLZXXAERcjs.brushStickerRefs.call(void 0, this.brush);
8415
+ const refs = _chunkOY24XRYFcjs.brushStickerRefs.call(void 0, this.brush);
8382
8416
  if (refs.some((r) => !_chunkRDFHWAHLcjs.editorStampOf.call(void 0, r))) void this.prepareStickers(refs).catch(() => this.emit([]));
8383
8417
  this.emit([]);
8384
8418
  }
@@ -8395,7 +8429,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8395
8429
  */
8396
8430
  takeBrushColour(spec) {
8397
8431
  if (this.colorLocked) return;
8398
- const d = _optionalChain([spec, 'access', _493 => _493.colour, 'optionalAccess', _494 => _494.default]);
8432
+ const d = _optionalChain([spec, 'access', _498 => _498.colour, 'optionalAccess', _499 => _499.default]);
8399
8433
  const hex2 = d !== void 0 ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
8400
8434
  if (!hex2) return;
8401
8435
  this.color = hex2;
@@ -8406,8 +8440,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8406
8440
  }
8407
8441
  /** A brush that always paints its own colour (`colour.own`): that colour, resolved for the scheme now; else `null`. */
8408
8442
  ownColour(brushId) {
8409
- const spec = brushId !== void 0 ? _optionalChain([this, 'access', _495 => _495.findEntry, 'call', _496 => _496(brushId), 'optionalAccess', _497 => _497.spec]) : this.brushSpec;
8410
- const d = _optionalChain([spec, 'optionalAccess', _498 => _498.colour, 'optionalAccess', _499 => _499.own]) ? spec.colour.default : void 0;
8443
+ const spec = brushId !== void 0 ? _optionalChain([this, 'access', _500 => _500.findEntry, 'call', _501 => _501(brushId), 'optionalAccess', _502 => _502.spec]) : this.brushSpec;
8444
+ const d = _optionalChain([spec, 'optionalAccess', _503 => _503.colour, 'optionalAccess', _504 => _504.own]) ? spec.colour.default : void 0;
8411
8445
  return d !== void 0 ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
8412
8446
  }
8413
8447
  /** Sets the paint colour (and goes back to one colour from gradient paint). */
@@ -8429,9 +8463,9 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8429
8463
  setPaint(paint) {
8430
8464
  let p;
8431
8465
  try {
8432
- p = _chunkNIBFKXMDcjs.parsePaintSource.call(void 0, paint);
8466
+ p = _chunkIFWLZZCWcjs.parsePaintSource.call(void 0, paint);
8433
8467
  } catch (e) {
8434
- if (e instanceof _chunkNIBFKXMDcjs.PaintSourceError) throw new PaintEditorError(e.message);
8468
+ if (e instanceof _chunkIFWLZZCWcjs.PaintSourceError) throw new PaintEditorError(e.message);
8435
8469
  throw e;
8436
8470
  }
8437
8471
  if (p.type === "color") {
@@ -8450,20 +8484,20 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8450
8484
  * brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
8451
8485
  */
8452
8486
  strokeGradient(init, brush, color) {
8453
- if (!_chunk6QNDGMK7cjs.brushTakesPaint.call(void 0, brush)) return null;
8487
+ if (!_chunkQ33V5PEFcjs.brushTakesPaint.call(void 0, brush)) return null;
8454
8488
  let g = null;
8455
8489
  if (init.paint !== void 0) {
8456
- if (_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
8490
+ if (_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
8457
8491
  const p = this.readStrokePaint(init.paint);
8458
8492
  g = p.type === "gradient" ? p : null;
8459
8493
  } else g = _nullishCoalesce(brush.paint, () => ( (init.color === void 0 ? this.gradient : null)));
8460
- return g ? _chunkNIBFKXMDcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
8494
+ return g ? _chunkIFWLZZCWcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
8461
8495
  }
8462
8496
  readStrokePaint(raw) {
8463
8497
  try {
8464
- return _chunkNIBFKXMDcjs.parsePaintSource.call(void 0, raw);
8498
+ return _chunkIFWLZZCWcjs.parsePaintSource.call(void 0, raw);
8465
8499
  } catch (e) {
8466
- if (e instanceof _chunkNIBFKXMDcjs.PaintSourceError) throw new PaintEditorError(e.message);
8500
+ if (e instanceof _chunkIFWLZZCWcjs.PaintSourceError) throw new PaintEditorError(e.message);
8467
8501
  throw e;
8468
8502
  }
8469
8503
  }
@@ -8497,14 +8531,14 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8497
8531
  // --- Mixer Brush ---------------------------------------------------------------
8498
8532
  /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */
8499
8533
  loadMixerBrush(color) {
8500
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
8501
- this.mixerLoad = _chunkNIBFKXMDcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
8534
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
8535
+ this.mixerLoad = _chunkIFWLZZCWcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
8502
8536
  this.emit([]);
8503
8537
  return this.mixerLoad;
8504
8538
  }
8505
8539
  /** Empties the pickup well (and with `emptyReservoir` the loaded paint too). */
8506
8540
  cleanMixerBrush(emptyReservoir = false) {
8507
- this.mixerLoad = emptyReservoir ? _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD : _chunkNIBFKXMDcjs.cleanMixer.call(void 0, this.mixerLoad);
8541
+ this.mixerLoad = emptyReservoir ? _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD : _chunkIFWLZZCWcjs.cleanMixer.call(void 0, this.mixerLoad);
8508
8542
  this.emit([]);
8509
8543
  return this.mixerLoad;
8510
8544
  }
@@ -8527,7 +8561,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8527
8561
  // --- Strokes -------------------------------------------------------------------
8528
8562
  strokeBrush(init) {
8529
8563
  let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
8530
- if (init.brush) brush = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
8564
+ if (init.brush) brush = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
8531
8565
  return brush;
8532
8566
  }
8533
8567
  /**
@@ -8543,7 +8577,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8543
8577
  return symmetryCopies(this.guides.symmetry);
8544
8578
  }
8545
8579
  sessionFor(doc, init, host, points) {
8546
- if (init.paint !== void 0 && !_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, init.paint)) {
8580
+ if (init.paint !== void 0 && !_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, init.paint)) {
8547
8581
  const p = this.readStrokePaint(init.paint);
8548
8582
  if (p.type === "color") init = { ...init, color: p.color, paint: void 0 };
8549
8583
  else init = { ...init, paint: p };
@@ -8562,26 +8596,26 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8562
8596
  const brush = this.strokeBrush(init);
8563
8597
  const mutRefusal = mutationBrushRefusal(brush);
8564
8598
  if (mutRefusal) throw new PaintEditorError(mutRefusal);
8565
- if (this.previewing && _chunk6QNDGMK7cjs.isWetBrush.call(void 0, brush)) throw new PaintEditorError(`Wet paint can't be previewed; the ${brush.name} brush paints wet media. Suggest it with a dry brush.`);
8599
+ if (this.previewing && _chunkQ33V5PEFcjs.isWetBrush.call(void 0, brush)) throw new PaintEditorError(`Wet paint can't be previewed; the ${brush.name} brush paints wet media. Suggest it with a dry brush.`);
8566
8600
  if (brush.ghost) {
8567
8601
  if (brush.light.amount > 0) throw new PaintEditorError(`Ghost paint (${brush.name}) shares the wet light channel and can't emit light; set light.amount to 0 or ghost to null (set_brush).`);
8568
- if (_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, init.paint) || init.paint === void 0 && init.color === void 0 && Boolean(this.effectPaint)) {
8602
+ if (_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, init.paint) || init.paint === void 0 && init.color === void 0 && Boolean(this.effectPaint)) {
8569
8603
  throw new PaintEditorError(`Ghost paint (${brush.name}) needs a single colour to subtract as it fades, so it can't paint with an effect; set a solid colour (set_color) or pass color to paint_stroke.`);
8570
8604
  }
8571
8605
  if (brush.behavior.multicolor.mode !== "off") throw new PaintEditorError(`Ghost paint (${brush.name}) needs a single colour to subtract as it fades, so it can't use multi-colour paint; set behavior.multicolor.mode to "off" (set_brush).`);
8572
8606
  const gCol = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
8573
8607
  if (this.strokeGradient(init, brush, gCol)) throw new PaintEditorError(`Ghost paint (${brush.name}) needs a single colour to subtract as it fades, so it can't paint a gradient; set a solid colour (set_color) or pass color to paint_stroke.`);
8574
- if (Boolean(_optionalChain([doc, 'access', _500 => _500.light, 'optionalAccess', _501 => _501[layer.id], 'optionalAccess', _502 => _502.tiles, 'access', _503 => _503.size])) || Boolean(_optionalChain([this, 'access', _504 => _504.wet, 'access', _505 => _505.world, 'optionalAccess', _506 => _506.hasLane, 'call', _507 => _507(layer.id)]) && this.wet.world.isLit(layer.id))) {
8608
+ if (Boolean(_optionalChain([doc, 'access', _505 => _505.light, 'optionalAccess', _506 => _506[layer.id], 'optionalAccess', _507 => _507.tiles, 'access', _508 => _508.size])) || Boolean(_optionalChain([this, 'access', _509 => _509.wet, 'access', _510 => _510.world, 'optionalAccess', _511 => _511.hasLane, 'call', _512 => _512(layer.id)]) && this.wet.world.isLit(layer.id))) {
8575
8609
  throw new PaintEditorError(`Layer "${layer.name}" holds light paint, and ghost paint shares the wet light channel; paint on another layer (add_layer) or clear the light first (clear_light).`);
8576
8610
  }
8577
8611
  }
8578
8612
  const effect = this.strokeEffect(init, brush, points);
8579
- if (!points && init.paint === void 0 && _optionalChain([effect, 'optionalAccess', _508 => _508.source, 'access', _509 => _509.map, 'optionalAccess', _510 => _510.by]) === "path" && _chunk6QNDGMK7cjs.isWetBrush.call(void 0, brush)) {
8613
+ if (!points && init.paint === void 0 && _optionalChain([effect, 'optionalAccess', _513 => _513.source, 'access', _514 => _514.map, 'optionalAccess', _515 => _515.by]) === "path" && _chunkQ33V5PEFcjs.isWetBrush.call(void 0, brush)) {
8580
8614
  throw new PaintEditorError(`The ${brush.name} brush paints wet media, which can't follow a path that isn't known until the stroke ends; paint with a dry brush, set_effect_paint with by: "stroke", or give the points to paint_stroke.`);
8581
8615
  }
8582
8616
  if (brush.light.amount > 0) {
8583
8617
  if (brush.engine === "sticker") throw new PaintEditorError(`The ${brush.name} brush sprays stickers, which don't take light yet; paint light with a dab or particle light brush (glow-gel, neon-marker; list_brush_presets lists them), or set light.amount to 0 (set_brush).`);
8584
- if (Boolean(_optionalChain([this, 'access', _511 => _511.wet, 'access', _512 => _512.world, 'optionalAccess', _513 => _513.hasLane, 'call', _514 => _514(layer.id)]) && this.wet.world.getGhost(layer.id)) || Boolean(_optionalChain([this, 'access', _515 => _515.wet, 'access', _516 => _516.settings, 'access', _517 => _517.get, 'call', _518 => _518(layer.id), 'optionalAccess', _519 => _519.ghost]))) {
8618
+ if (Boolean(_optionalChain([this, 'access', _516 => _516.wet, 'access', _517 => _517.world, 'optionalAccess', _518 => _518.hasLane, 'call', _519 => _519(layer.id)]) && this.wet.world.getGhost(layer.id)) || Boolean(_optionalChain([this, 'access', _520 => _520.wet, 'access', _521 => _521.settings, 'access', _522 => _522.get, 'call', _523 => _523(layer.id), 'optionalAccess', _524 => _524.ghost]))) {
8585
8619
  throw new PaintEditorError(`Layer "${layer.name}" has ghost paint fading on it, which uses the wet light channel; paint light on another layer (add_layer), or finish the ghost first (dry_paint).`);
8586
8620
  }
8587
8621
  }
@@ -8591,55 +8625,55 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8591
8625
  if (brush.thermochromic.hotColor !== null && brush.engine === "sticker") {
8592
8626
  throw new PaintEditorError(`The ${brush.name} brush sprays stickers, which don't take thermochromic ink; paint thermochromic ink with a dab or particle brush (thermo-ink; list_brush_presets lists them), or set thermochromic.hotColor to null (set_brush).`);
8593
8627
  }
8594
- if (_optionalChain([doc, 'access', _520 => _520.liveStrokes, 'optionalAccess', _521 => _521[layer.id]])) {
8628
+ if (_optionalChain([doc, 'access', _525 => _525.liveStrokes, 'optionalAccess', _526 => _526[layer.id]])) {
8595
8629
  const why = liveStrokeRefusal(brush);
8596
8630
  if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
8597
8631
  }
8598
- if (_optionalChain([doc, 'access', _522 => _522.liveStrokes, 'optionalAccess', _523 => _523[layer.id]]) && _optionalChain([effect, 'optionalAccess', _524 => _524.source, 'access', _525 => _525.live])) {
8599
- const key = _chunkOLZXXAERcjs.effectPaintKey.call(void 0, effect.source);
8632
+ if (_optionalChain([doc, 'access', _527 => _527.liveStrokes, 'optionalAccess', _528 => _528[layer.id]]) && _optionalChain([effect, 'optionalAccess', _529 => _529.source, 'access', _530 => _530.live])) {
8633
+ const key = _chunkOY24XRYFcjs.effectPaintKey.call(void 0, effect.source);
8600
8634
  const { sources } = this.liveEffects(doc);
8601
- if (!sources.some((p) => _chunkOLZXXAERcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
8635
+ if (!sources.some((p) => _chunkOY24XRYFcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
8602
8636
  throw new PaintEditorError(`The painting already plays ${MAX_LIVE_EFFECT_SOURCES} live effects, the most it can; paint with one of them, or set_effect_paint with live false to bake this one.`);
8603
8637
  }
8604
8638
  }
8605
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _526 => _526.stickers, 'optionalAccess', _527 => _527[layer.id], 'optionalAccess', _528 => _528.length]));
8639
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _531 => _531.stickers, 'optionalAccess', _532 => _532[layer.id], 'optionalAccess', _533 => _533.length]));
8606
8640
  if (brush.engine === "sticker") {
8607
8641
  if (!stickerLayer && _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; spray stickers onto an empty layer (add_layer) so they stay editable.`);
8608
8642
  } else if (stickerLayer) {
8609
8643
  throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
8610
8644
  }
8611
8645
  let wet;
8612
- if (_chunk6QNDGMK7cjs.isWetBrush.call(void 0, brush)) {
8646
+ if (_chunkQ33V5PEFcjs.isWetBrush.call(void 0, brush)) {
8613
8647
  this.requireWetIdle("painting");
8614
8648
  if (layer.offset.x || layer.offset.y) {
8615
8649
  const ox = layer.offset.x;
8616
8650
  const oy = layer.offset.y;
8617
8651
  const moved = { ...layer, surface: _chunk474IQG74cjs.translateSurface.call(void 0, layer.surface, ox, oy), offset: { x: 0, y: 0 } };
8618
8652
  const moveThick = (t) => {
8619
- const tc = _optionalChain([t, 'optionalAccess', _529 => _529[layer.id]]);
8653
+ const tc = _optionalChain([t, 'optionalAccess', _534 => _534[layer.id]]);
8620
8654
  if (!tc) return t;
8621
8655
  return { ...t, [layer.id]: { height: _chunk474IQG74cjs.translateSurface.call(void 0, tc.height, ox, oy), material: _chunk474IQG74cjs.translateSurface.call(void 0, tc.material, ox, oy), film: _chunk474IQG74cjs.translateSurface.call(void 0, tc.film, ox, oy) } };
8622
8656
  };
8623
- this.doc = { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => moved), ..._optionalChain([this, 'access', _530 => _530.doc, 'access', _531 => _531.thick, 'optionalAccess', _532 => _532[layer.id]]) ? { thick: moveThick(this.doc.thick) } : {} };
8624
- if (doc !== this.doc) doc = { ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, layer.id, () => moved), ..._optionalChain([doc, 'access', _533 => _533.thick, 'optionalAccess', _534 => _534[layer.id]]) ? { thick: moveThick(doc.thick) } : {} };
8657
+ this.doc = { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => moved), ..._optionalChain([this, 'access', _535 => _535.doc, 'access', _536 => _536.thick, 'optionalAccess', _537 => _537[layer.id]]) ? { thick: moveThick(this.doc.thick) } : {} };
8658
+ if (doc !== this.doc) doc = { ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, layer.id, () => moved), ..._optionalChain([doc, 'access', _538 => _538.thick, 'optionalAccess', _539 => _539[layer.id]]) ? { thick: moveThick(doc.thick) } : {} };
8625
8659
  layer = moved;
8626
8660
  }
8627
- if (!this.wet.wetLayerIds().includes(layer.id) && this.wet.wetLayerIds().length >= _chunkDHC4E2DUcjs.MAX_WET_LANES) {
8628
- throw new PaintEditorError(`At most ${_chunkDHC4E2DUcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
8661
+ if (!this.wet.wetLayerIds().includes(layer.id) && this.wet.wetLayerIds().length >= _chunkMITQGHN3cjs.MAX_WET_LANES) {
8662
+ throw new PaintEditorError(`At most ${_chunkMITQGHN3cjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
8629
8663
  }
8630
8664
  this.beginWetOp();
8631
8665
  const world = this.wet.ensureLane(layer.id, brush.wet.medium);
8632
8666
  const id = layer.id;
8633
8667
  const wetColor = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
8634
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, wetColor);
8668
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, wetColor);
8635
8669
  const wetGradient = this.strokeGradient(init, brush, wetColor);
8636
8670
  const load = _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [r / 255, g / 255, b / 255])));
8637
8671
  const seedW = _nullishCoalesce(init.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
8638
8672
  const copiesW = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
8639
8673
  const wetMask = init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null;
8640
- const needWetFilm = Boolean(brush.wet.tool === "paint" && brush.iridescence || brush.wet.tool === "blot" && _optionalChain([doc, 'access', _535 => _535.thick, 'optionalAccess', _536 => _536[id], 'optionalAccess', _537 => _537.film, 'access', _538 => _538.tiles, 'access', _539 => _539.size]));
8641
- const wetFilm = needWetFilm ? new FilmBuffer((_nullishCoalesce(_optionalChain([doc, 'access', _540 => _540.thick, 'optionalAccess', _541 => _541[id]]), () => ( emptyThickChannels()))).film, layer.offset, wetMask) : null;
8642
- const driver = new (0, _chunkOLZXXAERcjs.WetStrokeDriver)({
8674
+ const needWetFilm = Boolean(brush.wet.tool === "paint" && brush.iridescence || brush.wet.tool === "blot" && _optionalChain([doc, 'access', _540 => _540.thick, 'optionalAccess', _541 => _541[id], 'optionalAccess', _542 => _542.film, 'access', _543 => _543.tiles, 'access', _544 => _544.size]));
8675
+ const wetFilm = needWetFilm ? new FilmBuffer((_nullishCoalesce(_optionalChain([doc, 'access', _545 => _545.thick, 'optionalAccess', _546 => _546[id]]), () => ( emptyThickChannels()))).film, layer.offset, wetMask) : null;
8676
+ const driver = new (0, _chunkOY24XRYFcjs.WetStrokeDriver)({
8643
8677
  world,
8644
8678
  laneId: id,
8645
8679
  brush,
@@ -8647,12 +8681,12 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8647
8681
  load,
8648
8682
  grain: paperGrain(doc.paper),
8649
8683
  paperDepth: doc.paper.depth,
8650
- paperColor: _chunkOLZXXAERcjs.hexToRgb8.call(void 0, doc.paper.color),
8684
+ paperColor: _chunkOY24XRYFcjs.hexToRgb8.call(void 0, doc.paper.color),
8651
8685
  seed: seedW,
8652
8686
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
8653
8687
  mask: wetMask,
8654
8688
  paint: effect ? null : wetGradient,
8655
- effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _542 => _542.pixels]), () => ( null)),
8689
+ effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _547 => _547.pixels]), () => ( null)),
8656
8690
  film: wetFilm,
8657
8691
  speed: this.wet.speed
8658
8692
  });
@@ -8663,10 +8697,10 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8663
8697
  const dried = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id).layer;
8664
8698
  layer = dried;
8665
8699
  }
8666
- if (brush.mutation && !_chunk6QNDGMK7cjs.isWetBrush.call(void 0, brush) && !this.answeringMutation && !this.previewing && !this.getOrigin().startsWith("agent:")) {
8700
+ if (brush.mutation && !_chunkQ33V5PEFcjs.isWetBrush.call(void 0, brush) && !this.answeringMutation && !this.previewing && !this.getOrigin().startsWith("agent:")) {
8667
8701
  const targetLayer = layer;
8668
8702
  const existing = this.mutations.find((m) => m.state === "settling" && m.medium === "dry" && m.layerId === targetLayer.id && m.tempLayerId && _chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, m.tempLayerId));
8669
- if (_optionalChain([existing, 'optionalAccess', _543 => _543.tempLayerId])) {
8703
+ if (_optionalChain([existing, 'optionalAccess', _548 => _548.tempLayerId])) {
8670
8704
  layer = _chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, existing.tempLayerId).layer;
8671
8705
  } else {
8672
8706
  const temp = {
@@ -8682,7 +8716,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8682
8716
  }
8683
8717
  let color = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
8684
8718
  const tracing = this.guides.tracing;
8685
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _544 => _544.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
8719
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _549 => _549.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
8686
8720
  const perspective = this.guides.perspective;
8687
8721
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
8688
8722
  const useStencils = init.stencils !== false;
@@ -8696,8 +8730,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8696
8730
  const rgba = rgbaOf(color);
8697
8731
  const seed = _nullishCoalesce(init.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, this.seedCounter++ * 2654435761 >>> 0) & 2147483647));
8698
8732
  const copies = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
8699
- const hasThick = Boolean(_optionalChain([doc, 'access', _545 => _545.thick, 'optionalAccess', _546 => _546[layer.id]]));
8700
- const needThick = brush.engine === "impasto" || Boolean(brush.iridescence) || brush.engine === "eraser" && hasThick || Boolean(_optionalChain([wet, 'optionalAccess', _547 => _547.driver, 'access', _548 => _548.init, 'access', _549 => _549.film]));
8733
+ const hasThick = Boolean(_optionalChain([doc, 'access', _550 => _550.thick, 'optionalAccess', _551 => _551[layer.id]]));
8734
+ const needThick = brush.engine === "impasto" || Boolean(brush.iridescence) || brush.engine === "eraser" && hasThick || Boolean(_optionalChain([wet, 'optionalAccess', _552 => _552.driver, 'access', _553 => _553.init, 'access', _554 => _554.film]));
8701
8735
  const session = new PaintStrokeSession(host, {
8702
8736
  layerId: layer.id,
8703
8737
  surface: layer.surface,
@@ -8717,11 +8751,11 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8717
8751
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
8718
8752
  secondary: rgbaOf(this.secondaryColor),
8719
8753
  wet,
8720
- thick: needThick ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _550 => _550.thick, 'optionalAccess', _551 => _551[layer.id]]), () => ( emptyThickChannels())) } : void 0,
8754
+ thick: needThick ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _555 => _555.thick, 'optionalAccess', _556 => _556[layer.id]]), () => ( emptyThickChannels())) } : void 0,
8721
8755
  // Light paint: a twin of the stroke paints the light channel (laying, dimming, moving light).
8722
- light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _552 => _552.light, 'optionalAccess', _553 => _553[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _554 => _554.light, 'optionalAccess', _555 => _555[layer.id]]), () => ( emptyLight())) } : null,
8723
- fluor: brush.engine !== "sticker" && (brush.fluorescence.amount > 0 || _optionalChain([doc, 'access', _556 => _556.fluor, 'optionalAccess', _557 => _557[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _558 => _558.fluor, 'optionalAccess', _559 => _559[layer.id]]), () => ( emptyFluor())) } : null,
8724
- thermo: brush.engine !== "sticker" && (brush.thermochromic.hotColor !== null || _optionalChain([doc, 'access', _560 => _560.thermo, 'optionalAccess', _561 => _561[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _562 => _562.thermo, 'optionalAccess', _563 => _563[layer.id]]), () => ( emptyThermo())) } : null,
8756
+ light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _557 => _557.light, 'optionalAccess', _558 => _558[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _559 => _559.light, 'optionalAccess', _560 => _560[layer.id]]), () => ( emptyLight())) } : null,
8757
+ fluor: brush.engine !== "sticker" && (brush.fluorescence.amount > 0 || _optionalChain([doc, 'access', _561 => _561.fluor, 'optionalAccess', _562 => _562[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _563 => _563.fluor, 'optionalAccess', _564 => _564[layer.id]]), () => ( emptyFluor())) } : null,
8758
+ thermo: brush.engine !== "sticker" && (brush.thermochromic.hotColor !== null || _optionalChain([doc, 'access', _565 => _565.thermo, 'optionalAccess', _566 => _566[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _567 => _567.thermo, 'optionalAccess', _568 => _568[layer.id]]), () => ( emptyThermo())) } : null,
8725
8759
  sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc), art: this.stickerArt.get, variant: (ref2) => this.stickerArt.variantFor(ref2, this.colorScheme === "dark") } : void 0,
8726
8760
  stampArt: this.stampArt,
8727
8761
  paint: effect ? null : this.strokeGradient(init, brush, color),
@@ -8736,7 +8770,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8736
8770
  const stroke = {
8737
8771
  id: `s${this.strokeCounter++}`,
8738
8772
  layerId: session.layerId,
8739
- brush: _chunk6QNDGMK7cjs.brushToJSON.call(void 0, init.brush),
8773
+ brush: _chunkQ33V5PEFcjs.brushToJSON.call(void 0, init.brush),
8740
8774
  color: init.colorHex,
8741
8775
  points: session.points.map((p) => ({ ...p })),
8742
8776
  seed: init.seed
@@ -8761,18 +8795,18 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8761
8795
  const before = this.doc;
8762
8796
  const host = {
8763
8797
  update: (layerId, surface, rects) => {
8764
- if (_optionalChain([this, 'access', _564 => _564.session, 'optionalAccess', _565 => _565.init, 'access', _566 => _566.wet])) {
8798
+ if (_optionalChain([this, 'access', _569 => _569.session, 'optionalAccess', _570 => _570.init, 'access', _571 => _571.wet])) {
8765
8799
  const ch2 = this.session.thickChannels();
8766
8800
  this.liveThick = ch2 ? { layerId, channels: ch2 } : null;
8767
8801
  this.wet.syncDisplays();
8768
8802
  return;
8769
8803
  }
8770
8804
  this.live = { layerId, surface };
8771
- const ch = _optionalChain([this, 'access', _567 => _567.session, 'optionalAccess', _568 => _568.thickChannels, 'call', _569 => _569()]);
8805
+ const ch = _optionalChain([this, 'access', _572 => _572.session, 'optionalAccess', _573 => _573.thickChannels, 'call', _574 => _574()]);
8772
8806
  this.liveThick = ch ? { layerId, channels: ch } : null;
8773
- const fl = _optionalChain([this, 'access', _570 => _570.session, 'optionalAccess', _571 => _571.fluorChannel, 'call', _572 => _572()]);
8807
+ const fl = _optionalChain([this, 'access', _575 => _575.session, 'optionalAccess', _576 => _576.fluorChannel, 'call', _577 => _577()]);
8774
8808
  this.liveFluor = fl ? { layerId, surface: fl } : null;
8775
- const th = _optionalChain([this, 'access', _573 => _573.session, 'optionalAccess', _574 => _574.thermoChannel, 'call', _575 => _575()]);
8809
+ const th = _optionalChain([this, 'access', _578 => _578.session, 'optionalAccess', _579 => _579.thermoChannel, 'call', _580 => _580()]);
8776
8810
  this.liveThermo = th ? { layerId, surface: th } : null;
8777
8811
  this.emit(rects);
8778
8812
  },
@@ -8782,7 +8816,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8782
8816
  },
8783
8817
  commit: (s, surface, cancelled) => {
8784
8818
  this.session = null;
8785
- const preview = _optionalChain([this, 'access', _576 => _576.pathPreview, 'optionalAccess', _577 => _577.session]) === s ? this.pathPreview : null;
8819
+ const preview = _optionalChain([this, 'access', _581 => _581.pathPreview, 'optionalAccess', _582 => _582.session]) === s ? this.pathPreview : null;
8786
8820
  this.pathPreview = null;
8787
8821
  const pathPaint = cancelled ? null : this.pathStrokePaint(s);
8788
8822
  if (pathPaint) {
@@ -8797,7 +8831,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8797
8831
  const wetStroke = Boolean(s.init.wet);
8798
8832
  if (wetStroke) this.wet.driver = null;
8799
8833
  const brush = s.init.brush;
8800
- if (!cancelled && _optionalChain([s, 'access', _578 => _578.result, 'optionalAccess', _579 => _579.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
8834
+ if (!cancelled && _optionalChain([s, 'access', _583 => _583.result, 'optionalAccess', _584 => _584.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
8801
8835
  if (cancelled || !surface) {
8802
8836
  if (this.wetOp) {
8803
8837
  const snap = this.wetOp.before;
@@ -8815,7 +8849,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8815
8849
  }
8816
8850
  const stroke = this.record(s);
8817
8851
  s.result.strokeId = stroke.id;
8818
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _580 => _580.result, 'optionalAccess', _581 => _581.bounds]), () => ( null)));
8852
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _585 => _585.result, 'optionalAccess', _586 => _586.bounds]), () => ( null)));
8819
8853
  if (wetStroke && this.wet.instantDry) {
8820
8854
  this.wet.dry(s.layerId);
8821
8855
  this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
@@ -8823,10 +8857,22 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8823
8857
  s.result.wet = this.wet.isWet(s.layerId);
8824
8858
  }
8825
8859
  const l = this.getLayer(s.layerId);
8826
- const thick = withLayerThick(this.doc.thick, l.id, s.thickChannels());
8860
+ let ch = s.thickChannels();
8861
+ if (wetStroke) {
8862
+ const f = this.wet.patterns.get(l.id);
8863
+ if (_optionalChain([f, 'optionalAccess', _587 => _587.enabled])) {
8864
+ this.wet.settingsOf(l.id).livePatterns = { ...f.settings };
8865
+ if (f.settings.relief > 0 && f.tiles.size > 0) {
8866
+ const prevCh = _nullishCoalesce(_nullishCoalesce(ch, () => ( _optionalChain([this, 'access', _588 => _588.doc, 'access', _589 => _589.thick, 'optionalAccess', _590 => _590[l.id]]))), () => ( emptyThickChannels()));
8867
+ const nextHeight = f.applyReliefHeight(prevCh.height);
8868
+ if (nextHeight !== prevCh.height) ch = { ...prevCh, height: nextHeight };
8869
+ }
8870
+ }
8871
+ }
8872
+ const thick = withLayerThick(this.doc.thick, l.id, ch);
8827
8873
  const sprayed = s.stickers();
8828
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _582 => _582.doc, 'access', _583 => _583.stickers, 'optionalAccess', _584 => _584[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
8829
- const wetLight = wetStroke && _optionalChain([this, 'access', _585 => _585.wet, 'access', _586 => _586.world, 'optionalAccess', _587 => _587.hasLane, 'call', _588 => _588(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
8874
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _591 => _591.doc, 'access', _592 => _592.stickers, 'optionalAccess', _593 => _593[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
8875
+ const wetLight = wetStroke && _optionalChain([this, 'access', _594 => _594.wet, 'access', _595 => _595.world, 'optionalAccess', _596 => _596.hasLane, 'call', _597 => _597(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
8830
8876
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
8831
8877
  const fluor = withLayerLight(this.doc.fluor, l.id, s.fluorChannel());
8832
8878
  const thermo = withLayerLight(this.doc.thermo, l.id, s.thermoChannel());
@@ -8849,7 +8895,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8849
8895
  ),
8850
8896
  before
8851
8897
  );
8852
- this.recordMutationStroke(stroke, _nullishCoalesce(_optionalChain([s, 'access', _589 => _589.result, 'optionalAccess', _590 => _590.bounds]), () => ( null)));
8898
+ this.recordMutationStroke(stroke, _nullishCoalesce(_optionalChain([s, 'access', _598 => _598.result, 'optionalAccess', _599 => _599.bounds]), () => ( null)));
8853
8899
  this.notifySample("end", s, [], stroke.id);
8854
8900
  }
8855
8901
  };
@@ -8861,7 +8907,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8861
8907
  throw e;
8862
8908
  }
8863
8909
  this.session = session;
8864
- if (_optionalChain([session, 'access', _591 => _591.init, 'access', _592 => _592.effect, 'optionalAccess', _593 => _593.source, 'access', _594 => _594.map, 'optionalAccess', _595 => _595.by]) === "path" && !session.init.wet) this.pathPreview = { session, key: "", pending: null, landed: null };
8910
+ if (_optionalChain([session, 'access', _600 => _600.init, 'access', _601 => _601.effect, 'optionalAccess', _602 => _602.source, 'access', _603 => _603.map, 'optionalAccess', _604 => _604.by]) === "path" && !session.init.wet) this.pathPreview = { session, key: "", pending: null, landed: null };
8865
8911
  this.emit([]);
8866
8912
  this.notifySample("begin", session);
8867
8913
  return session;
@@ -8877,7 +8923,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8877
8923
  if (!pv || pv.session !== s || pv.pending || !s.open) return;
8878
8924
  const paint = this.pathStrokePaint(s);
8879
8925
  if (!paint) return;
8880
- const key = _chunkOLZXXAERcjs.effectPaintKey.call(void 0, paint);
8926
+ const key = _chunkOY24XRYFcjs.effectPaintKey.call(void 0, paint);
8881
8927
  if (key === pv.key) return;
8882
8928
  pv.key = key;
8883
8929
  const cached = this.effectPaintImage(paint);
@@ -8906,14 +8952,14 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8906
8952
  * the editor is busy, as during a stroke, and shows the stroke as it was painted.
8907
8953
  */
8908
8954
  get strokeRendering() {
8909
- return _nullishCoalesce(_optionalChain([this, 'access', _596 => _596.pathStroke, 'optionalAccess', _597 => _597.done]), () => ( null));
8955
+ return _nullishCoalesce(_optionalChain([this, 'access', _605 => _605.pathStroke, 'optionalAccess', _606 => _606.done]), () => ( null));
8910
8956
  }
8911
8957
  /** The paint a finished hand-painted stroke must be painted again with, or `null` when it already painted with it. */
8912
8958
  pathStrokePaint(s) {
8913
- const source = _optionalChain([s, 'access', _598 => _598.init, 'access', _599 => _599.effect, 'optionalAccess', _600 => _600.source]);
8914
- if (_optionalChain([source, 'optionalAccess', _601 => _601.map, 'optionalAccess', _602 => _602.by]) !== "path" || !s.points.length) return null;
8915
- const paint = _chunkOLZXXAERcjs.withStrokePath.call(void 0, source, s.points, this.effectPathControls.get(source.effect));
8916
- return _chunkOLZXXAERcjs.effectPaintKey.call(void 0, paint) === _chunkOLZXXAERcjs.effectPaintKey.call(void 0, source) ? null : paint;
8959
+ const source = _optionalChain([s, 'access', _607 => _607.init, 'access', _608 => _608.effect, 'optionalAccess', _609 => _609.source]);
8960
+ if (_optionalChain([source, 'optionalAccess', _610 => _610.map, 'optionalAccess', _611 => _611.by]) !== "path" || !s.points.length) return null;
8961
+ const paint = _chunkOY24XRYFcjs.withStrokePath.call(void 0, source, s.points, this.effectPathControls.get(source.effect));
8962
+ return _chunkOY24XRYFcjs.effectPaintKey.call(void 0, paint) === _chunkOY24XRYFcjs.effectPaintKey.call(void 0, source) ? null : paint;
8917
8963
  }
8918
8964
  /**
8919
8965
  * Ends a hand-painted stroke with a path-mapped effect. Its whole path isn't known until now, so
@@ -8931,17 +8977,17 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8931
8977
  this.liveThermo = null;
8932
8978
  const masks = s.init.selection ? (_nullishCoalesce(s.maskStencils, () => ( this.guides.stencils))).filter((x) => x.enabled && x.mode === "mask") : [];
8933
8979
  const load = s.init.mixerLoad;
8934
- const result = this.paintStroke({ layerId: s.layerId, points: s.points, color: s.init.colorHex, brush: _chunk6QNDGMK7cjs.brushToJSON.call(void 0, s.init.brush), seed: s.init.seed, copies: s.init.affineCopies, ...load.reservoir || load.pickup ? { load } : {}, paint, snapToPerspective: false, stencils: false, maskStencils: masks });
8980
+ const result = this.paintStroke({ layerId: s.layerId, points: s.points, color: s.init.colorHex, brush: _chunkQ33V5PEFcjs.brushToJSON.call(void 0, s.init.brush), seed: s.init.seed, copies: s.init.affineCopies, ...load.reservoir || load.pickup ? { load } : {}, paint, snapToPerspective: false, stencils: false, maskStencils: masks });
8935
8981
  Object.assign(s.result, result);
8936
8982
  this.notifySample("end", s, [], result.strokeId);
8937
8983
  };
8938
- const key = _chunkOLZXXAERcjs.effectPaintKey.call(void 0, paint);
8939
- if (_optionalChain([preview, 'optionalAccess', _603 => _603.landed, 'optionalAccess', _604 => _604.key]) === key) this.cacheEffectPaintImage(paint, preview.landed.pixels);
8984
+ const key = _chunkOY24XRYFcjs.effectPaintKey.call(void 0, paint);
8985
+ if (_optionalChain([preview, 'optionalAccess', _612 => _612.landed, 'optionalAccess', _613 => _613.key]) === key) this.cacheEffectPaintImage(paint, preview.landed.pixels);
8940
8986
  if (this.effectPaintImage(paint) || this.renderEffectPaintSync(paint)) {
8941
8987
  finish();
8942
8988
  return;
8943
8989
  }
8944
- const render = _optionalChain([preview, 'optionalAccess', _605 => _605.pending]) && preview.key === key ? preview.pending.then((img) => this.cacheEffectPaintImage(paint, img)) : this.renderEffectPaint(paint);
8990
+ const render = _optionalChain([preview, 'optionalAccess', _614 => _614.pending]) && preview.key === key ? preview.pending.then((img) => this.cacheEffectPaintImage(paint, img)) : this.renderEffectPaint(paint);
8945
8991
  const done = render.then(finish, (e) => {
8946
8992
  this.pathStroke = null;
8947
8993
  this.live = null;
@@ -8968,17 +9014,29 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8968
9014
  if (cancelled || !surface) return;
8969
9015
  const stroke = this.record(s);
8970
9016
  s.result.strokeId = stroke.id;
8971
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _606 => _606.result, 'optionalAccess', _607 => _607.bounds]), () => ( null)));
9017
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _615 => _615.result, 'optionalAccess', _616 => _616.bounds]), () => ( null)));
8972
9018
  const targetId = this.tempLayerTargets.get(s.layerId);
8973
9019
  if (targetId && !_chunkPVJMTLPJcjs.findLayer.call(void 0, out.layers, s.layerId)) {
8974
- const temp = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, s.layerId), 'optionalAccess', _608 => _608.layer]);
9020
+ const temp = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, s.layerId), 'optionalAccess', _617 => _617.layer]);
8975
9021
  if (temp) out = { ...out, layers: insertAfter(out.layers, targetId, temp) };
8976
9022
  }
8977
9023
  const l = _chunkPVJMTLPJcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
8978
9024
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
8979
- const thick = withLayerThick(out.thick, l.id, s.thickChannels());
9025
+ let ch = s.thickChannels();
9026
+ if (s.init.wet) {
9027
+ const f = this.wet.patterns.get(l.id);
9028
+ if (_optionalChain([f, 'optionalAccess', _618 => _618.enabled])) {
9029
+ this.wet.settingsOf(l.id).livePatterns = { ...f.settings };
9030
+ if (f.settings.relief > 0 && f.tiles.size > 0) {
9031
+ const prevCh = _nullishCoalesce(_nullishCoalesce(ch, () => ( _optionalChain([out, 'access', _619 => _619.thick, 'optionalAccess', _620 => _620[l.id]]))), () => ( emptyThickChannels()));
9032
+ const nextHeight = f.applyReliefHeight(prevCh.height);
9033
+ if (nextHeight !== prevCh.height) ch = { ...prevCh, height: nextHeight };
9034
+ }
9035
+ }
9036
+ }
9037
+ const thick = withLayerThick(out.thick, l.id, ch);
8980
9038
  const sprayed = s.stickers();
8981
- const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _609 => _609.wet, 'access', _610 => _610.world, 'optionalAccess', _611 => _611.hasLane, 'call', _612 => _612(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
9039
+ const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _621 => _621.wet, 'access', _622 => _622.world, 'optionalAccess', _623 => _623.hasLane, 'call', _624 => _624(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
8982
9040
  const fl = s.fluorChannel();
8983
9041
  const th = s.thermoChannel();
8984
9042
  out = withLiveStroke({
@@ -8986,7 +9044,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
8986
9044
  layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
8987
9045
  strokes: [...out.strokes, stroke],
8988
9046
  ...thick ? { thick } : {},
8989
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _613 => _613.stickers, 'optionalAccess', _614 => _614[l.id]]), () => ( [])), ...sprayed] } } : {},
9047
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _625 => _625.stickers, 'optionalAccess', _626 => _626[l.id]]), () => ( [])), ...sprayed] } } : {},
8990
9048
  ...lit ? { light: withLayerLight(out.light, l.id, lit) } : {},
8991
9049
  ...fl ? { fluor: withLayerLight(out.fluor, l.id, fl) } : {},
8992
9050
  ...th ? { thermo: withLayerLight(out.thermo, l.id, th) } : {}
@@ -9064,16 +9122,16 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9064
9122
  throw e;
9065
9123
  }
9066
9124
  const run = last;
9067
- if (_optionalChain([run, 'optionalAccess', _615 => _615.result, 'access', _616 => _616.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
9125
+ if (_optionalChain([run, 'optionalAccess', _627 => _627.result, 'access', _628 => _628.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
9068
9126
  if (doc !== before || this.wetOp) {
9069
- this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _617 => _617.brush, 'access', _618 => _618.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
9127
+ this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _629 => _629.brush, 'access', _630 => _630.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
9070
9128
  for (const sid of strokeIds) {
9071
9129
  const recorded = this.doc.strokes.find((s) => s.id === sid);
9072
9130
  if (recorded) this.recordMutationStroke(recorded, _nullishCoalesce(this.paintedBounds.get(recorded), () => ( null)));
9073
9131
  }
9074
9132
  } else this.emit([]);
9075
- const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _619 => _619.result, 'access', _620 => _620.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
9076
- return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _621 => _621.result, 'access', _622 => _622.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _623 => _623.result, 'access', _624 => _624.wet]) !== void 0 ? { wet: run.result.wet } : {} };
9133
+ const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _631 => _631.result, 'access', _632 => _632.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
9134
+ return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _633 => _633.result, 'access', _634 => _634.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _635 => _635.result, 'access', _636 => _636.wet]) !== void 0 ? { wet: run.result.wet } : {} };
9077
9135
  }
9078
9136
  /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
9079
9137
  checkPoints(points) {
@@ -9096,7 +9154,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9096
9154
  */
9097
9155
  replayStrokes(options) {
9098
9156
  this.requireIdle("replaying");
9099
- if (!_optionalChain([options, 'access', _625 => _625.strokeIds, 'optionalAccess', _626 => _626.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
9157
+ if (!_optionalChain([options, 'access', _637 => _637.strokeIds, 'optionalAccess', _638 => _638.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
9100
9158
  const strokes = options.strokeIds.map((id) => {
9101
9159
  const s = this.doc.strokes.find((x) => x.id === id);
9102
9160
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -9110,7 +9168,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9110
9168
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
9111
9169
  if (options.color === void 0) {
9112
9170
  for (const s of strokes) {
9113
- if (_optionalChain([s, 'access', _627 => _627.paint, 'optionalAccess', _628 => _628.type]) === "effect" && !this.effectPaintImage(s.paint)) {
9171
+ if (_optionalChain([s, 'access', _639 => _639.paint, 'optionalAccess', _640 => _640.type]) === "effect" && !this.effectPaintImage(s.paint)) {
9114
9172
  throw new PaintEditorError(`Stroke "${s.id}" paints with the effect "${s.paint.effect}"${s.paint.provider ? ` from provider "${s.paint.provider}"` : ""}, which is not rendered in this editor; render it first (prepareStrokeEffects; the replay_strokes tool does this) or recolour the replay with color.`);
9115
9173
  }
9116
9174
  }
@@ -9133,13 +9191,13 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9133
9191
  let brush = v.brush;
9134
9192
  if (options.brushId !== void 0) {
9135
9193
  const b = this.requireBrush(options.brushId);
9136
- brush = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
9194
+ brush = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
9137
9195
  }
9138
9196
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
9139
9197
  if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
9140
9198
  let load = s.load;
9141
9199
  if (load && options.color !== void 0 && load.reservoir) {
9142
- const [r, g, b] = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, options.color);
9200
+ const [r, g, b] = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, options.color);
9143
9201
  load = { ...load, reservoir: [r / 255, g / 255, b / 255] };
9144
9202
  }
9145
9203
  const paint = v.paint && options.color === void 0 ? { paint: v.paint } : {};
@@ -9170,7 +9228,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9170
9228
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
9171
9229
  lightOf(layerId) {
9172
9230
  const l = this.wetLayer(layerId, "read the light of");
9173
- const info = lightInfo(_optionalChain([this, 'access', _629 => _629.doc, 'access', _630 => _630.light, 'optionalAccess', _631 => _631[l.id]]));
9231
+ const info = lightInfo(_optionalChain([this, 'access', _641 => _641.doc, 'access', _642 => _642.light, 'optionalAccess', _643 => _643[l.id]]));
9174
9232
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
9175
9233
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
9176
9234
  }
@@ -9287,7 +9345,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9287
9345
  advanceHeat(stepsOrOptions = 10) {
9288
9346
  this.requireIdle("advancing heat");
9289
9347
  this.requireWetIdle("advancing heat");
9290
- const rawSteps = typeof stepsOrOptions === "number" ? stepsOrOptions : _optionalChain([stepsOrOptions, 'optionalAccess', _632 => _632.steps]);
9348
+ const rawSteps = typeof stepsOrOptions === "number" ? stepsOrOptions : _optionalChain([stepsOrOptions, 'optionalAccess', _644 => _644.steps]);
9291
9349
  const steps = _nullishCoalesce(rawSteps, () => ( 10));
9292
9350
  if (!(Number.isInteger(steps) && steps >= 1 && steps <= 200)) {
9293
9351
  throw new PaintEditorError(`steps ${rawSteps} is out of range; use a whole number 1..200.`);
@@ -9368,7 +9426,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9368
9426
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
9369
9427
  if (!id) return null;
9370
9428
  this.requireLayer(id);
9371
- const ch = _optionalChain([this, 'access', _633 => _633.doc, 'access', _634 => _634.thick, 'optionalAccess', _635 => _635[id]]);
9429
+ const ch = _optionalChain([this, 'access', _645 => _645.doc, 'access', _646 => _646.thick, 'optionalAccess', _647 => _647[id]]);
9372
9430
  if (!ch || !hasThickChannels(ch)) return null;
9373
9431
  const r = reliefInfo(ch);
9374
9432
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -9481,7 +9539,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9481
9539
  wetState() {
9482
9540
  const st = this.getState().wet;
9483
9541
  const backend = this.wet.backend();
9484
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _636 => _636.message]), () => ( _chunkDHC4E2DUcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
9542
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _648 => _648.message]), () => ( _chunkMITQGHN3cjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
9485
9543
  }
9486
9544
  /**
9487
9545
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -9499,7 +9557,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9499
9557
  */
9500
9558
  async setWetEngine(options) {
9501
9559
  const gpu = _nullishCoalesce(options.gpu, () => ( this.wet.gpuMode));
9502
- if (!_chunkOLZXXAERcjs.WET_GPU_MODES.includes(gpu)) throw new PaintEditorError(`gpu must be ${_chunkOLZXXAERcjs.WET_GPU_MODES.join(" or ")}, not ${JSON.stringify(gpu)}.`);
9560
+ if (!_chunkOY24XRYFcjs.WET_GPU_MODES.includes(gpu)) throw new PaintEditorError(`gpu must be ${_chunkOY24XRYFcjs.WET_GPU_MODES.join(" or ")}, not ${JSON.stringify(gpu)}.`);
9503
9561
  if (options.minTiles !== void 0 && !(Number.isInteger(options.minTiles) && options.minTiles >= 1 && options.minTiles <= 1024)) throw new PaintEditorError(`minTiles ${options.minTiles} is out of range; use 1..1024 tiles of 256 px.`);
9504
9562
  this.wet.setGpu(gpu, options.minTiles);
9505
9563
  this.emit();
@@ -9560,7 +9618,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9560
9618
  const amount = _nullishCoalesce(options.amount, () => ( 1));
9561
9619
  if (!(amount > 0 && amount <= 1)) throw new PaintEditorError(`amount ${amount} is out of range; use above 0 up to 1.`);
9562
9620
  const rect = _nullishCoalesce(this.checkRect(options.rect), () => ( { x: 0, y: 0, width: this.doc.canvas.width, height: this.doc.canvas.height }));
9563
- if (!this.wet.wetLayerIds().includes(l.id) && this.wet.wetLayerIds().length >= _chunkDHC4E2DUcjs.MAX_WET_LANES) throw new PaintEditorError(`At most ${_chunkDHC4E2DUcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
9621
+ if (!this.wet.wetLayerIds().includes(l.id) && this.wet.wetLayerIds().length >= _chunkMITQGHN3cjs.MAX_WET_LANES) throw new PaintEditorError(`At most ${_chunkMITQGHN3cjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
9564
9622
  const before = this.doc;
9565
9623
  this.beginWetOp();
9566
9624
  const world = this.wet.ensureLane(l.id);
@@ -9572,7 +9630,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9572
9630
  }
9573
9631
  /** Records a settings change as a wet event (not an undo step). */
9574
9632
  recordWetSetting(e) {
9575
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _637 => _637.wet, 'access', _638 => _638.world, 'optionalAccess', _639 => _639.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
9633
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _649 => _649.wet, 'access', _650 => _650.world, 'optionalAccess', _651 => _651.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
9576
9634
  }
9577
9635
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
9578
9636
  setWetParams(layerId, update) {
@@ -9580,7 +9638,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9580
9638
  this.requireWetIdle("changing wet settings");
9581
9639
  if (this.heldEvaporation.has(l.id)) {
9582
9640
  const current = this.wet.info(l.id).params;
9583
- const intended = _chunkDHC4E2DUcjs.normalizeWetParams.call(void 0, { ...current, evaporation: this.heldEvaporation.get(l.id), ...update });
9641
+ const intended = _chunkMITQGHN3cjs.normalizeWetParams.call(void 0, { ...current, evaporation: this.heldEvaporation.get(l.id), ...update });
9584
9642
  this.heldEvaporation.set(l.id, intended.evaporation);
9585
9643
  this.wet.setParams(l.id, { ...update, evaporation: 0 });
9586
9644
  this.recordWetSetting({ kind: "params", layerId: l.id, data: intended });
@@ -9640,6 +9698,149 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9640
9698
  if (this.wet.busy) return [];
9641
9699
  return this.wet.waterOverlay(rect);
9642
9700
  }
9701
+ layerLivePatternsInfo(layerId) {
9702
+ const info = this.wet.info(layerId);
9703
+ const stats = this.wet.livePatternStats(layerId);
9704
+ return {
9705
+ layerId,
9706
+ wet: info.wet,
9707
+ wetCells: info.wetCells,
9708
+ wetBounds: info.wetBounds,
9709
+ ...stats
9710
+ };
9711
+ }
9712
+ checkLivePatternsInput(input) {
9713
+ if (!input) return {};
9714
+ const out = {};
9715
+ if (input.pattern !== void 0) {
9716
+ if (!_chunkIFWLZZCWcjs.LIVE_PATTERN_KINDS.includes(input.pattern)) {
9717
+ throw new PaintEditorError(`pattern must be one of ${_chunkIFWLZZCWcjs.LIVE_PATTERN_KINDS.join(", ")}, not ${JSON.stringify(input.pattern)}.`);
9718
+ }
9719
+ out.pattern = input.pattern;
9720
+ }
9721
+ if (input.feed !== void 0) {
9722
+ if (!(Number.isFinite(input.feed) && input.feed >= 5e-3 && input.feed <= 0.1)) {
9723
+ throw new PaintEditorError(`feed ${input.feed} is out of range; use 0.005..0.1.`);
9724
+ }
9725
+ out.feed = input.feed;
9726
+ }
9727
+ if (input.kill !== void 0) {
9728
+ if (!(Number.isFinite(input.kill) && input.kill >= 0.02 && input.kill <= 0.08)) {
9729
+ throw new PaintEditorError(`kill ${input.kill} is out of range; use 0.02..0.08.`);
9730
+ }
9731
+ out.kill = input.kill;
9732
+ }
9733
+ if (input.scale !== void 0) {
9734
+ if (!(Number.isFinite(input.scale) && input.scale >= 0.25 && input.scale <= 4)) {
9735
+ throw new PaintEditorError(`scale ${input.scale} is out of range; use 0.25..4.`);
9736
+ }
9737
+ out.scale = input.scale;
9738
+ }
9739
+ if (input.contrast !== void 0) {
9740
+ if (!(Number.isFinite(input.contrast) && input.contrast >= 0 && input.contrast <= 2)) {
9741
+ throw new PaintEditorError(`contrast ${input.contrast} is out of range; use 0..2.`);
9742
+ }
9743
+ out.contrast = input.contrast;
9744
+ }
9745
+ if (input.secondColor !== void 0) {
9746
+ out.secondColor = input.secondColor === null ? null : parseColor(input.secondColor, "secondColor");
9747
+ }
9748
+ if (input.relief !== void 0) {
9749
+ if (!(Number.isFinite(input.relief) && input.relief >= 0 && input.relief <= 1)) {
9750
+ throw new PaintEditorError(`relief ${input.relief} is out of range; use 0..1.`);
9751
+ }
9752
+ out.relief = input.relief;
9753
+ }
9754
+ return out;
9755
+ }
9756
+ /**
9757
+ * Reads a layer's Gray-Scott reaction-diffusion live patterns (`layerId`, default the active
9758
+ * layer), plus all layers with wet paint or live patterns and the built-in Pearson presets.
9759
+ */
9760
+ getLivePatterns(layerId) {
9761
+ const l = this.wetLayer(layerId, "read the live patterns of");
9762
+ const primary = this.layerLivePatternsInfo(l.id);
9763
+ const ids = /* @__PURE__ */ new Set([l.id, ...this.wet.wetLayerIds()]);
9764
+ for (const [id, f] of this.wet.patterns) {
9765
+ if ((f.enabled || f.tiles.size > 0) && _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) ids.add(id);
9766
+ }
9767
+ for (const [id, s] of this.wet.settings) {
9768
+ if (s.livePatterns && _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) ids.add(id);
9769
+ }
9770
+ const layers = [...ids].map((id) => id === l.id ? primary : this.layerLivePatternsInfo(id));
9771
+ return {
9772
+ ...primary,
9773
+ layers,
9774
+ presets: _chunkIFWLZZCWcjs.LIVE_PATTERN_PRESETS,
9775
+ brushPresets: ["turing-wash", "coral-ink"]
9776
+ };
9777
+ }
9778
+ /**
9779
+ * Configures a layer's Gray-Scott reaction-diffusion live patterns (or clears them with
9780
+ * `enabled: false`). One undo step.
9781
+ */
9782
+ setLivePatterns(layerId, update) {
9783
+ this.requireIdle("changing live patterns");
9784
+ this.requireWetIdle("changing live patterns");
9785
+ const l = this.wetLayer(layerId, "set the live patterns of");
9786
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it first.`);
9787
+ if (update.enabled !== void 0 && typeof update.enabled !== "boolean") {
9788
+ throw new PaintEditorError("enabled must be true or false.");
9789
+ }
9790
+ const checked = this.checkLivePatternsInput(update);
9791
+ const before = this.doc;
9792
+ this.beginWetOp();
9793
+ const next = this.wet.setLivePatterns(l.id, update.enabled === false ? null : checked);
9794
+ this.logWet({ kind: "live-patterns", layerId: l.id, data: next });
9795
+ this.commit("Live patterns", this.withWetEvents(this.doc), before);
9796
+ return this.layerLivePatternsInfo(l.id);
9797
+ }
9798
+ /**
9799
+ * Seeds Gray-Scott reaction-diffusion activator (`V`) discs into a layer's live-pattern field so
9800
+ * patterns grow where the layer holds wet water and freeze where it dries. One undo step.
9801
+ */
9802
+ seedLivePatterns(options) {
9803
+ this.requireIdle("seeding live patterns");
9804
+ this.requireWetIdle("seeding live patterns");
9805
+ const l = this.wetLayer(options.layerId, "seed live patterns on");
9806
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it first.`);
9807
+ if (!Array.isArray(options.points) || !options.points.length) {
9808
+ throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
9809
+ }
9810
+ const { width, height } = this.doc.canvas;
9811
+ const points = options.points.map((p, i) => {
9812
+ if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) {
9813
+ throw new PaintEditorError(`points[${i}] needs finite x and y in document pixels.`);
9814
+ }
9815
+ if (p.x < 0 || p.y < 0 || p.x >= width || p.y >= height) {
9816
+ throw new PaintEditorError(`points[${i}] (${p.x}, ${p.y}) is outside the ${width}\xD7${height} canvas.`);
9817
+ }
9818
+ if (p.strength !== void 0 && !(Number.isFinite(p.strength) && p.strength > 0 && p.strength <= 1)) {
9819
+ throw new PaintEditorError(`points[${i}].strength ${p.strength} is out of range; use above 0 up to 1.`);
9820
+ }
9821
+ return { x: p.x, y: p.y, ...p.strength !== void 0 ? { strength: p.strength } : {} };
9822
+ });
9823
+ const radius = _nullishCoalesce(options.radius, () => ( 16));
9824
+ if (!(Number.isFinite(radius) && radius >= 1 && radius <= 512)) {
9825
+ throw new PaintEditorError(`radius ${radius} is out of range; use 1..512 px.`);
9826
+ }
9827
+ const seed = _nullishCoalesce(options.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, this.seedCounter++ * 2654435761 >>> 0) & 2147483647));
9828
+ if (!Number.isInteger(seed) || seed < 0) {
9829
+ throw new PaintEditorError(`seed ${seed} must be a whole number of 0 or more.`);
9830
+ }
9831
+ const hasSettings = options.pattern !== void 0 || options.feed !== void 0 || options.kill !== void 0 || options.scale !== void 0 || options.contrast !== void 0 || options.secondColor !== void 0 || options.relief !== void 0;
9832
+ const settings = hasSettings ? this.checkLivePatternsInput(options) : void 0;
9833
+ const before = this.doc;
9834
+ this.beginWetOp();
9835
+ const { seededCells } = this.wet.seedLivePatterns(l.id, points, radius, seed, settings);
9836
+ this.logWet({
9837
+ kind: "seed-live-patterns",
9838
+ layerId: l.id,
9839
+ data: { points, radius, seed, ...settings ? { settings } : {} }
9840
+ });
9841
+ this.commit("Seed live patterns", this.withWetEvents(this.doc), before);
9842
+ return { ...this.layerLivePatternsInfo(l.id), seededCells };
9843
+ }
9643
9844
  // --- Rendering -----------------------------------------------------------------
9644
9845
  sources() {
9645
9846
  return { width: this.doc.canvas.width, height: this.doc.canvas.height };
@@ -9650,7 +9851,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9650
9851
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkPVJMTLPJcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
9651
9852
  const live = this.live;
9652
9853
  if (!live) return this.animatedView();
9653
- if (_optionalChain([this, 'access', _640 => _640.liveLayers, 'optionalAccess', _641 => _641.key]) === live.surface) return this.liveLayers.layers;
9854
+ if (_optionalChain([this, 'access', _652 => _652.liveLayers, 'optionalAccess', _653 => _653.key]) === live.surface) return this.liveLayers.layers;
9654
9855
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
9655
9856
  this.liveLayers = { key: live.surface, layers };
9656
9857
  return layers;
@@ -9673,7 +9874,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9673
9874
  tracingNode(t) {
9674
9875
  const { width, height } = this.doc.canvas;
9675
9876
  const key = this.tracingVersion * 100003 + width * 7 + height;
9676
- if (_optionalChain([this, 'access', _642 => _642.tracingCache, 'optionalAccess', _643 => _643.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
9877
+ if (_optionalChain([this, 'access', _654 => _654.tracingCache, 'optionalAccess', _655 => _655.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
9677
9878
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
9678
9879
  const image = resampleInto(src, t.rect, width, height);
9679
9880
  const node = { type: "image", id: TRACING_NODE_ID, name: "Tracing", visible: true, opacity: t.opacity, blend: "normal", image, version: key + Math.round(t.opacity * 1e3) / 1e4 };
@@ -9699,7 +9900,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9699
9900
  if (!thermo || !heat || heat.max === 0) return layers;
9700
9901
  let out = layers;
9701
9902
  for (const [id, th] of Object.entries(thermo)) {
9702
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _644 => _644.layer]);
9903
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _656 => _656.layer]);
9703
9904
  if (!isPixelLayer(l) || !th.tiles.size) continue;
9704
9905
  let cache = this.thermoCaches.get(id);
9705
9906
  if (!cache) this.thermoCaches.set(id, cache = new ThermoCache());
@@ -9749,8 +9950,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9749
9950
  let out = layers;
9750
9951
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
9751
9952
  for (const id of ids) {
9752
- const ch = _optionalChain([live, 'optionalAccess', _645 => _645.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _646 => _646[id]]);
9753
- const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _647 => _647.layer]);
9953
+ const ch = _optionalChain([live, 'optionalAccess', _657 => _657.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _658 => _658[id]]);
9954
+ const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _659 => _659.layer]);
9754
9955
  if (!ch || !isPixelLayer(l)) continue;
9755
9956
  let cache = this.litCaches.get(id);
9756
9957
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -9770,13 +9971,13 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9770
9971
  if (!ids.size) return layers;
9771
9972
  let out = layers;
9772
9973
  for (const id of ids) {
9773
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _648 => _648.layer]);
9974
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _660 => _660.layer]);
9774
9975
  if (!isPixelLayer(l)) continue;
9775
9976
  let cache = this.lightCaches.get(id);
9776
9977
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
9777
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _649 => _649.liveThick, 'optionalAccess', _650 => _650.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _651 => _651.doc, 'access', _652 => _652.thick, 'optionalAccess', _653 => _653[id]]));
9978
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _661 => _661.liveThick, 'optionalAccess', _662 => _662.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _663 => _663.doc, 'access', _664 => _664.thick, 'optionalAccess', _665 => _665[id]]));
9778
9979
  if (glowed !== l.surface) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
9779
- const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _654 => _654.layer]);
9980
+ const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _666 => _666.layer]);
9780
9981
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
9781
9982
  if (spill) out = insertAfter(out, id, { type: "pixel", id: `${id}${SPILL_SUFFIX}`, name: `${l.name} light`, visible: l.visible, opacity: l.opacity, blend: "linear-dodge", surface: spill, offset: { ...l.offset } });
9782
9983
  }
@@ -9788,7 +9989,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9788
9989
  if (!l.visible) continue;
9789
9990
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
9790
9991
  else if (isPixelLayer(l)) {
9791
- const thick = !committed && _optionalChain([this, 'access', _655 => _655.liveThick, 'optionalAccess', _656 => _656.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _657 => _657.doc, 'access', _658 => _658.thick, 'optionalAccess', _659 => _659[l.id]]);
9992
+ const thick = !committed && _optionalChain([this, 'access', _667 => _667.liveThick, 'optionalAccess', _668 => _668.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _669 => _669.doc, 'access', _670 => _670.thick, 'optionalAccess', _671 => _671[l.id]]);
9792
9993
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
9793
9994
  }
9794
9995
  }
@@ -9817,7 +10018,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9817
10018
  if (backlight) layers = [...layers, backlight];
9818
10019
  if (options.layerIds) {
9819
10020
  const picked = [];
9820
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _660 => _660.layer]), () => ( this.requireLayer(id))));
10021
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _672 => _672.layer]), () => ( this.requireLayer(id))));
9821
10022
  layers = picked.map((l) => ({ ...l, visible: true }));
9822
10023
  }
9823
10024
  const under = options.paper === false ? [] : [paperNode(uvPaper(this.doc.paper, this.uvLight), this.lighting)];
@@ -9833,7 +10034,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9833
10034
  */
9834
10035
  compositeTiles(rect, onTile, options = {}) {
9835
10036
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
9836
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _661 => _661.live, 'optionalAccess', _662 => _662.layerId]), () => ( this.doc.activeLayerId)) });
10037
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _673 => _673.live, 'optionalAccess', _674 => _674.layerId]), () => ( this.doc.activeLayerId)) });
9837
10038
  }
9838
10039
  /** The canvas as canvas-sized RGBA (paper included by default). */
9839
10040
  compositePixels(options = {}) {
@@ -9891,11 +10092,16 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9891
10092
  const layers = {};
9892
10093
  for (const [id, set] of this.wet.settings) {
9893
10094
  if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
9894
- const ghost = _optionalChain([this, 'access', _663 => _663.wet, 'access', _664 => _664.world, 'optionalAccess', _665 => _665.hasLane, 'call', _666 => _666(id)]) ? this.wet.world.getGhost(id) : _nullishCoalesce(set.ghost, () => ( null));
9895
- const savedGhost = _optionalChain([ghost, 'optionalAccess', _667 => _667.trigger]) === "agent" ? null : ghost;
10095
+ const ghost = _optionalChain([this, 'access', _675 => _675.wet, 'access', _676 => _676.world, 'optionalAccess', _677 => _677.hasLane, 'call', _678 => _678(id)]) ? this.wet.world.getGhost(id) : _nullishCoalesce(set.ghost, () => ( null));
10096
+ const savedGhost = _optionalChain([ghost, 'optionalAccess', _679 => _679.trigger]) === "agent" ? null : ghost;
9896
10097
  const heldEvap = this.heldEvaporation.get(id);
9897
10098
  const params = heldEvap !== void 0 ? { ...set.params, evaporation: heldEvap } : { ...set.params };
9898
- layers[id] = { params, flow: { ...set.flow }, ...savedGhost ? { ghost: savedGhost } : {} };
10099
+ layers[id] = {
10100
+ params,
10101
+ flow: { ...set.flow },
10102
+ ...savedGhost ? { ghost: savedGhost } : {},
10103
+ ...set.livePatterns ? { livePatterns: { ...set.livePatterns } } : {}
10104
+ };
9899
10105
  }
9900
10106
  const flat = this.wet.tilt.angle === 0;
9901
10107
  if (!Object.keys(layers).length && flat) return void 0;
@@ -9905,7 +10111,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9905
10111
  this.wet.reset();
9906
10112
  if (!raw || typeof raw !== "object") return;
9907
10113
  const r = raw;
9908
- this.wet.setTilt(_chunkDHC4E2DUcjs.normalizeTilt.call(void 0, _nullishCoalesce(r.tilt, () => ( {}))));
10114
+ this.wet.setTilt(_chunkMITQGHN3cjs.normalizeTilt.call(void 0, _nullishCoalesce(r.tilt, () => ( {}))));
9909
10115
  if (r.layers && typeof r.layers === "object") {
9910
10116
  for (const [id, v] of Object.entries(r.layers)) {
9911
10117
  if (!v || typeof v !== "object") {
@@ -9914,7 +10120,14 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9914
10120
  }
9915
10121
  const x = v;
9916
10122
  const ghost = readWetGhost(x.ghost);
9917
- this.wet.settings.set(id, { params: _chunkDHC4E2DUcjs.normalizeWetParams.call(void 0, _nullishCoalesce(x.params, () => ( {}))), flow: _chunkDHC4E2DUcjs.normalizeFlow.call(void 0, _nullishCoalesce(x.flow, () => ( {}))), ...ghost ? { ghost } : {} });
10123
+ const livePatterns = x.livePatterns ? _chunkIFWLZZCWcjs.normalizeLivePatterns.call(void 0, x.livePatterns) : null;
10124
+ this.wet.settings.set(id, {
10125
+ params: _chunkMITQGHN3cjs.normalizeWetParams.call(void 0, _nullishCoalesce(x.params, () => ( {}))),
10126
+ flow: _chunkMITQGHN3cjs.normalizeFlow.call(void 0, _nullishCoalesce(x.flow, () => ( {}))),
10127
+ ...ghost ? { ghost } : {},
10128
+ ...livePatterns ? { livePatterns } : {}
10129
+ });
10130
+ if (livePatterns) this.wet.patternFieldOf(id).configure(livePatterns);
9918
10131
  }
9919
10132
  }
9920
10133
  }
@@ -9953,7 +10166,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9953
10166
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)));
9954
10167
  if (Object.keys(spills).length) ext.lightSpill = spills;
9955
10168
  else delete ext.lightSpill;
9956
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _668 => _668.layer])));
10169
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _680 => _680.layer])));
9957
10170
  if (effectLayers) ext.effectLayers = effectLayers;
9958
10171
  else delete ext.effectLayers;
9959
10172
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -9985,7 +10198,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
9985
10198
  }
9986
10199
  /** Reads `layerChannels` and `lighting` from loaded extensions into the document. */
9987
10200
  readThick(state, ext, problems) {
9988
- if (Array.isArray(ext.brushSources)) this.brushSources.set(ext.brushSources.map((x, i) => _chunk6QNDGMK7cjs.readBrushSource.call(void 0, x, `brushSources[${i}]`, problems)).filter((x) => x !== null));
10201
+ if (Array.isArray(ext.brushSources)) this.brushSources.set(ext.brushSources.map((x, i) => _chunkQ33V5PEFcjs.readBrushSource.call(void 0, x, `brushSources[${i}]`, problems)).filter((x) => x !== null));
9989
10202
  this.lighting = normalizeLighting(_nullishCoalesce(ext.lighting, () => ( {})), DEFAULT_LIGHTING);
9990
10203
  this.uvLight = normalizeUvLight(_nullishCoalesce(ext.uvLight, () => ( {})), DEFAULT_UV_LIGHT);
9991
10204
  this.litCaches.clear();
@@ -10014,7 +10227,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10014
10227
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
10015
10228
  const liveStrokes = {};
10016
10229
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
10017
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _669 => _669.layer])) || !Array.isArray(list)) continue;
10230
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _681 => _681.layer])) || !Array.isArray(list)) continue;
10018
10231
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
10019
10232
  if (ok.length !== list.length) problems.push(`Some strokes of stroke layer "${id}" could not be read; they were dropped (the layer's pixels are kept until a stroke is edited).`);
10020
10233
  liveStrokes[id] = ok;
@@ -10024,7 +10237,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10024
10237
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
10025
10238
  const effectLayers = {};
10026
10239
  for (const [id, v] of Object.entries(ext.effectLayers)) {
10027
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _670 => _670.layer]))) continue;
10240
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _682 => _682.layer]))) continue;
10028
10241
  const source = readPaintEffectSource(v);
10029
10242
  if (source) effectLayers[id] = source;
10030
10243
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -10052,7 +10265,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10052
10265
  if (ext.light && typeof ext.light === "object") {
10053
10266
  const light = {};
10054
10267
  for (const [id, v] of Object.entries(ext.light)) {
10055
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _671 => _671.layer]))) continue;
10268
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _683 => _683.layer]))) continue;
10056
10269
  try {
10057
10270
  light[id] = lightFromJSON(v);
10058
10271
  } catch (e) {
@@ -10064,7 +10277,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10064
10277
  if (ext.fluor && typeof ext.fluor === "object") {
10065
10278
  const fluor = {};
10066
10279
  for (const [id, v] of Object.entries(ext.fluor)) {
10067
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _672 => _672.layer]))) continue;
10280
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _684 => _684.layer]))) continue;
10068
10281
  try {
10069
10282
  fluor[id] = fluorFromJSON(v);
10070
10283
  } catch (e) {
@@ -10076,7 +10289,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10076
10289
  if (ext.thermo && typeof ext.thermo === "object") {
10077
10290
  const thermo = {};
10078
10291
  for (const [id, v] of Object.entries(ext.thermo)) {
10079
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _673 => _673.layer]))) continue;
10292
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _685 => _685.layer]))) continue;
10080
10293
  try {
10081
10294
  thermo[id] = thermoFromJSON(v);
10082
10295
  } catch (e) {
@@ -10117,7 +10330,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10117
10330
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
10118
10331
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
10119
10332
  for (const s of loaded.state.strokes) {
10120
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _674 => _674.exec, 'call', _675 => _675(s.id), 'optionalAccess', _676 => _676[1]]), () => ( 0)));
10333
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _686 => _686.exec, 'call', _687 => _687(s.id), 'optionalAccess', _688 => _688[1]]), () => ( 0)));
10121
10334
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
10122
10335
  }
10123
10336
  this.undoStack = [];
@@ -10126,7 +10339,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10126
10339
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
10127
10340
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
10128
10341
  for (const s of list) {
10129
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _677 => _677.exec, 'call', _678 => _678(s.id), 'optionalAccess', _679 => _679[1]]), () => ( 0)));
10342
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _689 => _689.exec, 'call', _690 => _690(s.id), 'optionalAccess', _691 => _691[1]]), () => ( 0)));
10130
10343
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
10131
10344
  }
10132
10345
  }
@@ -10228,10 +10441,10 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10228
10441
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
10229
10442
  });
10230
10443
  const layers = toStandard(dried);
10231
- const result = _chunkRAPNRK4Rcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
10444
+ const result = _chunkX7XBEX3Ocjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
10232
10445
  for (const [mode, names] of changed) {
10233
- const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _680 => _680.find, 'call', _681 => _681((m) => m.id === mode), 'optionalAccess', _682 => _682.label]), () => ( mode));
10234
- const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _683 => _683.find, 'call', _684 => _684((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _685 => _685.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
10446
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _692 => _692.find, 'call', _693 => _693((m) => m.id === mode), 'optionalAccess', _694 => _694.label]), () => ( mode));
10447
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _695 => _695.find, 'call', _696 => _696((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _697 => _697.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
10235
10448
  const list = names.map((n) => `"${n}"`).join(", ");
10236
10449
  const one = names.length === 1;
10237
10450
  result.warnings.push(`${label} blending has no PSD equivalent; ${list} ${one ? "was" : "were"} written as ${std}, the nearest Photoshop mode, so ${one ? "it looks" : "they look"} different in Photoshop (the merged image is exact).`);
@@ -10353,7 +10566,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10353
10566
  const { src, pixels } = this.importImage(options, "The reference image");
10354
10567
  const ref2 = {
10355
10568
  id: `ref${this.nextReferenceId++}`,
10356
- name: _optionalChain([options, 'access', _686 => _686.name, 'optionalAccess', _687 => _687.trim, 'call', _688 => _688()]) || `Reference ${this.guides.references.length + 1}`,
10569
+ name: _optionalChain([options, 'access', _698 => _698.name, 'optionalAccess', _699 => _699.trim, 'call', _700 => _700()]) || `Reference ${this.guides.references.length + 1}`,
10357
10570
  src,
10358
10571
  width: pixels.width,
10359
10572
  height: pixels.height,
@@ -10432,7 +10645,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10432
10645
  try {
10433
10646
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
10434
10647
  guides.references.push({ id: ref2.id, name: String(_nullishCoalesce(ref2.name, () => ( ref2.id))), src: ref2.src, width: px.width, height: px.height, x: Number(ref2.x) || 0, y: Number(ref2.y) || 0, displayWidth: Number(ref2.displayWidth) || 240, visible: ref2.visible !== false });
10435
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _689 => _689.exec, 'call', _690 => _690(ref2.id), 'optionalAccess', _691 => _691[1]]), () => ( 0)));
10648
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _701 => _701.exec, 'call', _702 => _702(ref2.id), 'optionalAccess', _703 => _703[1]]), () => ( 0)));
10436
10649
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
10437
10650
  } catch (e) {
10438
10651
  problems.push(e.message);
@@ -10443,7 +10656,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10443
10656
  guides.stencils = [];
10444
10657
  r.stencils.forEach((raw2, i) => {
10445
10658
  try {
10446
- const id = typeof _optionalChain([raw2, 'optionalAccess', _692 => _692.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
10659
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _704 => _704.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
10447
10660
  guides.stencils.push(normalizeStencil(raw2, id));
10448
10661
  const n = Number(id.slice(7));
10449
10662
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -10466,12 +10679,12 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10466
10679
  /** The next free sticker number (ids `st<n>` are unique across the document). */
10467
10680
  nextStickerNumber(doc = this.doc) {
10468
10681
  let n = 0;
10469
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _693 => _693.exec, 'call', _694 => _694(st.id), 'optionalAccess', _695 => _695[1]]), () => ( 0))));
10682
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _705 => _705.exec, 'call', _706 => _706(st.id), 'optionalAccess', _707 => _707[1]]), () => ( 0))));
10470
10683
  return n + 1;
10471
10684
  }
10472
10685
  stickerLayer(layerId) {
10473
10686
  const l = this.wetLayer(layerId, "edit the stickers of");
10474
- const stickers = _optionalChain([this, 'access', _696 => _696.doc, 'access', _697 => _697.stickers, 'optionalAccess', _698 => _698[l.id]]);
10687
+ const stickers = _optionalChain([this, 'access', _708 => _708.doc, 'access', _709 => _709.stickers, 'optionalAccess', _710 => _710[l.id]]);
10475
10688
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (sticker-stars; list_brush_presets lists them).`);
10476
10689
  return { layer: l, stickers };
10477
10690
  }
@@ -10547,7 +10760,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10547
10760
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
10548
10761
  if (!id) return [];
10549
10762
  this.requireLayer(id);
10550
- return (_nullishCoalesce(_optionalChain([this, 'access', _699 => _699.doc, 'access', _700 => _700.stickers, 'optionalAccess', _701 => _701[id]]), () => ( []))).map((s) => ({ ...s }));
10763
+ return (_nullishCoalesce(_optionalChain([this, 'access', _711 => _711.doc, 'access', _712 => _712.stickers, 'optionalAccess', _713 => _713[id]]), () => ( []))).map((s) => ({ ...s }));
10551
10764
  }
10552
10765
  /**
10553
10766
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -10568,7 +10781,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10568
10781
  }
10569
10782
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
10570
10783
  previewBase() {
10571
- return _optionalChain([this, 'access', _702 => _702.stickerPreview, 'optionalAccess', _703 => _703.shown]) === this.doc ? this.stickerPreview.base : null;
10784
+ return _optionalChain([this, 'access', _714 => _714.stickerPreview, 'optionalAccess', _715 => _715.shown]) === this.doc ? this.stickerPreview.base : null;
10572
10785
  }
10573
10786
  readStickerUpdate(update) {
10574
10787
  try {
@@ -10583,7 +10796,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10583
10796
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
10584
10797
  if (!id) return null;
10585
10798
  this.requireLayer(id);
10586
- const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _704 => _704.doc, 'access', _705 => _705.stickers, 'optionalAccess', _706 => _706[id]]), () => ( [])), x, y, this.stickerArt.get);
10799
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _716 => _716.doc, 'access', _717 => _717.stickers, 'optionalAccess', _718 => _718[id]]), () => ( [])), x, y, this.stickerArt.get);
10587
10800
  return hit ? { ...hit } : null;
10588
10801
  }
10589
10802
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -10640,8 +10853,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10640
10853
  const layer = this.wetLayer(layerId, "add stickers to");
10641
10854
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
10642
10855
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
10643
- const existing = _optionalChain([this, 'access', _707 => _707.doc, 'access', _708 => _708.stickers, 'optionalAccess', _709 => _709[layer.id]]);
10644
- if (!_optionalChain([existing, 'optionalAccess', _710 => _710.length])) {
10856
+ const existing = _optionalChain([this, 'access', _719 => _719.doc, 'access', _720 => _720.stickers, 'optionalAccess', _721 => _721[layer.id]]);
10857
+ if (!_optionalChain([existing, 'optionalAccess', _722 => _722.length])) {
10645
10858
  if (this.wet.wetLayerIds().includes(layer.id) || _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; add stickers to an empty layer (add_layer) or a sticker layer so they stay editable.`);
10646
10859
  }
10647
10860
  let n = this.nextStickerNumber();
@@ -10658,7 +10871,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10658
10871
  const id = n++;
10659
10872
  return this.withStickerVariant({ id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u });
10660
10873
  });
10661
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _711 => _711.length]) ? added.map(stickerRect) : void 0);
10874
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _723 => _723.length]) ? added.map(stickerRect) : void 0);
10662
10875
  return added.map((s) => ({ ...s }));
10663
10876
  }
10664
10877
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -10697,20 +10910,20 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10697
10910
  }
10698
10911
  liveStrokeLayer(layerId, what) {
10699
10912
  const l = this.wetLayer(layerId, what);
10700
- const strokes = _optionalChain([this, 'access', _712 => _712.doc, 'access', _713 => _713.liveStrokes, 'optionalAccess', _714 => _714[l.id]]);
10913
+ const strokes = _optionalChain([this, 'access', _724 => _724.doc, 'access', _725 => _725.liveStrokes, 'optionalAccess', _726 => _726[l.id]]);
10701
10914
  if (!strokes) throw new PaintEditorError(`Layer "${l.name}" is not a stroke layer; add one with add_layer {type: "strokes"} (or convert_to_stroke_layer on an empty layer), then paint on it.`);
10702
10915
  return { layer: l, strokes };
10703
10916
  }
10704
10917
  /** Whether a layer is a live stroke layer. */
10705
10918
  isLiveStrokeLayer(layerId) {
10706
- return Boolean(_optionalChain([this, 'access', _715 => _715.doc, 'access', _716 => _716.liveStrokes, 'optionalAccess', _717 => _717[layerId]]));
10919
+ return Boolean(_optionalChain([this, 'access', _727 => _727.doc, 'access', _728 => _728.liveStrokes, 'optionalAccess', _729 => _729[layerId]]));
10707
10920
  }
10708
10921
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
10709
10922
  convertToLiveStrokes(layerId) {
10710
10923
  this.requireIdle("converting a layer");
10711
10924
  const l = this.paintTarget(layerId, "convert");
10712
- if (_optionalChain([this, 'access', _718 => _718.doc, 'access', _719 => _719.liveStrokes, 'optionalAccess', _720 => _720[l.id]])) return this.describeLayer(l);
10713
- if (_optionalChain([this, 'access', _721 => _721.doc, 'access', _722 => _722.stickers, 'optionalAccess', _723 => _723[l.id], 'optionalAccess', _724 => _724.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
10925
+ if (_optionalChain([this, 'access', _730 => _730.doc, 'access', _731 => _731.liveStrokes, 'optionalAccess', _732 => _732[l.id]])) return this.describeLayer(l);
10926
+ if (_optionalChain([this, 'access', _733 => _733.doc, 'access', _734 => _734.stickers, 'optionalAccess', _735 => _735[l.id], 'optionalAccess', _736 => _736.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
10714
10927
  if (_chunk474IQG74cjs.contentBounds.call(void 0, l.surface) || this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" already has paint, which isn't kept as strokes; convert an empty layer or add a stroke layer (add_layer {type: "strokes"}).`);
10715
10928
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
10716
10929
  return this.describeLayer(this.getLayer(l.id));
@@ -10723,7 +10936,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10723
10936
  findLiveStroke(id) {
10724
10937
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
10725
10938
  const index = strokes.findIndex((x) => x.id === id);
10726
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _725 => _725.layer]);
10939
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _737 => _737.layer]);
10727
10940
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
10728
10941
  }
10729
10942
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -10743,15 +10956,15 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10743
10956
  let brush = was.brush;
10744
10957
  if (update.brushId !== void 0) {
10745
10958
  const b = this.requireBrush(update.brushId);
10746
- brush = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
10959
+ brush = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
10747
10960
  }
10748
10961
  if (update.brush !== void 0) {
10749
10962
  if (!update.brush || typeof update.brush !== "object") throw new PaintEditorError("brush must be an object of brush settings (as set_brush takes).");
10750
- brush = _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
10963
+ brush = _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
10751
10964
  }
10752
10965
  const why = liveStrokeRefusal(brush);
10753
10966
  if (why) throw new PaintEditorError(why);
10754
- const next = { ...was, brush: _chunk6QNDGMK7cjs.brushToJSON.call(void 0, brush) };
10967
+ const next = { ...was, brush: _chunkQ33V5PEFcjs.brushToJSON.call(void 0, brush) };
10755
10968
  if (update.seed !== void 0) {
10756
10969
  if (!Number.isInteger(update.seed) || update.seed < 0) throw new PaintEditorError(`seed ${update.seed} must be a whole number of 0 or more.`);
10757
10970
  next.seed = update.seed;
@@ -10762,8 +10975,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10762
10975
  }
10763
10976
  if (update.paint !== void 0) {
10764
10977
  if (update.paint === null) delete next.paint;
10765
- else if (_chunkOLZXXAERcjs.isPaintEffectPaint.call(void 0, update.paint)) {
10766
- const ep = _optionalChain([update, 'access', _726 => _726.paint, 'access', _727 => _727.map, 'optionalAccess', _728 => _728.by]) === "path" ? _chunkOLZXXAERcjs.withStrokePath.call(void 0, update.paint, next.points, this.effectPathControls.get(update.paint.effect)) : update.paint;
10978
+ else if (_chunkOY24XRYFcjs.isPaintEffectPaint.call(void 0, update.paint)) {
10979
+ const ep = _optionalChain([update, 'access', _738 => _738.paint, 'access', _739 => _739.map, 'optionalAccess', _740 => _740.by]) === "path" ? _chunkOY24XRYFcjs.withStrokePath.call(void 0, update.paint, next.points, this.effectPathControls.get(update.paint.effect)) : update.paint;
10767
10980
  if (!this.effectPaintImage(ep) && !this.renderEffectPaintSync(ep)) throw new PaintEditorError(`The effect "${update.paint.effect}" is not rendered yet; render it first (prepareEffectPaints; the update_stroke tool does this).`);
10768
10981
  next.paint = JSON.parse(JSON.stringify(ep));
10769
10982
  } else {
@@ -10774,8 +10987,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10774
10987
  } else next.paint = JSON.parse(JSON.stringify(p));
10775
10988
  }
10776
10989
  }
10777
- const rgb = _chunkOLZXXAERcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
10778
- const load = brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, rgb);
10990
+ const rgb = _chunkOY24XRYFcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
10991
+ const load = brushLoadForStroke(brush, _chunkIFWLZZCWcjs.EMPTY_MIXER_LOAD, rgb);
10779
10992
  if (load.reservoir || load.pickup) next.load = load;
10780
10993
  else delete next.load;
10781
10994
  const list = strokes.map((x, i) => i === index ? next : x);
@@ -10796,8 +11009,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10796
11009
  if (edit.points !== void 0) {
10797
11010
  const points = this.checkPoints(edit.points);
10798
11011
  next = { ...was, points: points.map((p) => ({ ...p })) };
10799
- if (_optionalChain([next, 'access', _729 => _729.paint, 'optionalAccess', _730 => _730.type]) === "effect" && _optionalChain([next, 'access', _731 => _731.paint, 'access', _732 => _732.map, 'optionalAccess', _733 => _733.by]) === "path") {
10800
- next.paint = _chunkOLZXXAERcjs.withStrokePath.call(void 0, next.paint, next.points, this.effectPathControls.get(next.paint.effect));
11012
+ if (_optionalChain([next, 'access', _741 => _741.paint, 'optionalAccess', _742 => _742.type]) === "effect" && _optionalChain([next, 'access', _743 => _743.paint, 'access', _744 => _744.map, 'optionalAccess', _745 => _745.by]) === "path") {
11013
+ next.paint = _chunkOY24XRYFcjs.withStrokePath.call(void 0, next.paint, next.points, this.effectPathControls.get(next.paint.effect));
10801
11014
  }
10802
11015
  } else {
10803
11016
  next = varyStroke(was, this.strokeTransform(was, edit.transform), {});
@@ -10817,9 +11030,9 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10817
11030
  const layers = /* @__PURE__ */ new Map();
10818
11031
  for (const f of found) layers.set(f.layer.id, f.layer);
10819
11032
  for (const [layerId, layer] of layers) {
10820
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _734 => _734.liveStrokes, 'optionalAccess', _735 => _735[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
11033
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _746 => _746.liveStrokes, 'optionalAccess', _747 => _747[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
10821
11034
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
10822
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _736 => _736.liveStrokes, 'optionalAccess', _737 => _737[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
11035
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _748 => _748.liveStrokes, 'optionalAccess', _749 => _749[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
10823
11036
  }
10824
11037
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
10825
11038
  return { removed: [...ids], bounds };
@@ -10887,8 +11100,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10887
11100
  }
10888
11101
  withLiveStrokes(doc, layer, list, dirty) {
10889
11102
  if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
10890
- const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _738 => _738.layer]);
10891
- const hasFilm = list.some((s) => Boolean(s.brush.iridescence)) || Boolean(_optionalChain([doc, 'access', _739 => _739.thick, 'optionalAccess', _740 => _740[layer.id]]));
11103
+ const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _750 => _750.layer]);
11104
+ const hasFilm = list.some((s) => Boolean(s.brush.iridescence)) || Boolean(_optionalChain([doc, 'access', _751 => _751.thick, 'optionalAccess', _752 => _752[layer.id]]));
10892
11105
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, hasFilm ? null : dirty);
10893
11106
  let thick = doc.thick;
10894
11107
  if (hasFilm) {
@@ -10985,7 +11198,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10985
11198
  if (!this.animatedLayers.size) return this.doc.layers;
10986
11199
  let layers = this.doc.layers;
10987
11200
  for (const [id, a] of this.animatedLayers) {
10988
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _741 => _741.layer]);
11201
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _753 => _753.layer]);
10989
11202
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
10990
11203
  }
10991
11204
  return layers;
@@ -10995,11 +11208,11 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
10995
11208
  const layers = [];
10996
11209
  const sources = /* @__PURE__ */ new Map();
10997
11210
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
10998
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _742 => _742.layer]);
11211
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _754 => _754.layer]);
10999
11212
  const live = strokes.filter(isLiveEffect);
11000
11213
  if (!isPixelLayer(layer) || !live.length) continue;
11001
11214
  layers.push({ layer, strokes });
11002
- for (const st of live) sources.set(_chunkOLZXXAERcjs.effectPaintKey.call(void 0, st.paint), st.paint);
11215
+ for (const st of live) sources.set(_chunkOY24XRYFcjs.effectPaintKey.call(void 0, st.paint), st.paint);
11003
11216
  }
11004
11217
  return { layers, sources: [...sources.values()] };
11005
11218
  }
@@ -11126,7 +11339,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11126
11339
  stencilSelection(stencils = this.guides.stencils) {
11127
11340
  const { width, height } = this.doc.canvas;
11128
11341
  const size = `${width}x${height}`;
11129
- if (_optionalChain([this, 'access', _743 => _743.stencilCache, 'optionalAccess', _744 => _744.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
11342
+ if (_optionalChain([this, 'access', _755 => _755.stencilCache, 'optionalAccess', _756 => _756.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
11130
11343
  const mask = stencilMask(stencils, width, height);
11131
11344
  this.stencilCache = { key: stencils, size, mask };
11132
11345
  return mask;
@@ -11187,8 +11400,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11187
11400
  }
11188
11401
  makeSwatch(color, name) {
11189
11402
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
11190
- const out = { color: _chunkNIBFKXMDcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
11191
- if (_optionalChain([name, 'optionalAccess', _745 => _745.trim, 'call', _746 => _746()])) out.name = name.trim();
11403
+ const out = { color: _chunkIFWLZZCWcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
11404
+ if (_optionalChain([name, 'optionalAccess', _757 => _757.trim, 'call', _758 => _758()])) out.name = name.trim();
11192
11405
  if (p.type === "gradient") out.paint = p;
11193
11406
  return out;
11194
11407
  }
@@ -11240,7 +11453,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11240
11453
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
11241
11454
  */
11242
11455
  mixOnPad(paints2, options = {}) {
11243
- const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _747 => _747.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _748 => _748.parts]) }));
11456
+ const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _759 => _759.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _760 => _760.parts]) }));
11244
11457
  let r;
11245
11458
  try {
11246
11459
  r = this.pad.mix(parsed, options);
@@ -11449,7 +11662,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11449
11662
  if (m.state === "answered") throw new PaintEditorError(`Mutation "${id}" has already been answered.`);
11450
11663
  if (m.state === "declined") throw new PaintEditorError(`Mutation "${id}" was declined and cannot be answered.`);
11451
11664
  if (m.state !== "claimed") throw new PaintEditorError(`Mutation "${id}" has not been claimed yet; call read_mutation("${id}") first.`);
11452
- if (!Array.isArray(_optionalChain([input, 'optionalAccess', _749 => _749.strokes])) || !input.strokes.length) {
11665
+ if (!Array.isArray(_optionalChain([input, 'optionalAccess', _761 => _761.strokes])) || !input.strokes.length) {
11453
11666
  throw new PaintEditorError("strokes is empty; give at least one stroke with points.");
11454
11667
  }
11455
11668
  const targetLayerId = _nullishCoalesce(input.layerId, () => ( m.layerId));
@@ -11459,7 +11672,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11459
11672
  const layerId = _nullishCoalesce(s.layerId, () => ( targetLayerId));
11460
11673
  this.paintTarget(layerId, "paint on");
11461
11674
  const baseBrush = s.brushId !== void 0 ? this.requireBrush(s.brushId) : this.brush;
11462
- const stripAutoGhost = _optionalChain([baseBrush, 'access', _750 => _750.ghost, 'optionalAccess', _751 => _751.trigger]) === "agent" && !_optionalChain([s, 'access', _752 => _752.brush, 'optionalAccess', _753 => _753.ghost]);
11675
+ const stripAutoGhost = _optionalChain([baseBrush, 'access', _762 => _762.ghost, 'optionalAccess', _763 => _763.trigger]) === "agent" && !_optionalChain([s, 'access', _764 => _764.brush, 'optionalAccess', _765 => _765.ghost]);
11463
11676
  const brushPatch = {
11464
11677
  ..._nullishCoalesce(s.brush, () => ( {})),
11465
11678
  mutation: null,
@@ -11481,7 +11694,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11481
11694
  m.state = "claimed";
11482
11695
  throw e;
11483
11696
  }
11484
- const rawActorId = (_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'access', _754 => _754.actor, 'optionalAccess', _755 => _755.id]), () => ( m.claimedBy)), () => ( "mutation-agent"))).replace(/^agent:/, "") || "mutation-agent";
11697
+ const rawActorId = (_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'access', _766 => _766.actor, 'optionalAccess', _767 => _767.id]), () => ( m.claimedBy)), () => ( "mutation-agent"))).replace(/^agent:/, "") || "mutation-agent";
11485
11698
  const actor = _nullishCoalesce(options.actor, () => ( {
11486
11699
  id: rawActorId,
11487
11700
  name: "Agent",
@@ -11566,7 +11779,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11566
11779
  if (m.state === "answered") throw new PaintEditorError(`Mutation "${id}" has already been answered.`);
11567
11780
  if (m.state === "declined") return this.toMutationInfo(m);
11568
11781
  m.state = "declined";
11569
- if (_optionalChain([reason, 'optionalAccess', _756 => _756.trim, 'call', _757 => _757()])) m.declineReason = reason.trim();
11782
+ if (_optionalChain([reason, 'optionalAccess', _768 => _768.trim, 'call', _769 => _769()])) m.declineReason = reason.trim();
11570
11783
  this.keepMutationPaint(m);
11571
11784
  if (this.mutationDirector && m.claimedBy) {
11572
11785
  this.mutationDirector.presence.remove(m.claimedBy.replace(/^agent:/, "") || "mutation-agent");
@@ -11664,7 +11877,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11664
11877
  recordMutationStroke(stroke, bounds) {
11665
11878
  const mut = stroke.brush.mutation;
11666
11879
  if (!mut || this.answeringMutation || this.previewing || this.getOrigin().startsWith("agent:")) return;
11667
- const medium = _chunk6QNDGMK7cjs.isWetBrush.call(void 0, stroke.brush) ? "wet" : "dry";
11880
+ const medium = _chunkQ33V5PEFcjs.isWetBrush.call(void 0, stroke.brush) ? "wet" : "dry";
11668
11881
  const tempLayerId = medium === "dry" && this.tempLayerTargets.has(stroke.layerId) ? stroke.layerId : void 0;
11669
11882
  const targetLayerId = tempLayerId ? this.tempLayerTargets.get(tempLayerId) : stroke.layerId;
11670
11883
  let entry = this.mutations.find((m) => m.state === "settling" && m.layerId === targetLayerId && m.medium === medium);
@@ -11710,7 +11923,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11710
11923
  }
11711
11924
  holdMutationEvaporation(layerId) {
11712
11925
  if (this.heldEvaporation.has(layerId)) return;
11713
- const currentEvap = (_nullishCoalesce(_optionalChain([this, 'access', _758 => _758.wet, 'access', _759 => _759.settings, 'access', _760 => _760.get, 'call', _761 => _761(layerId), 'optionalAccess', _762 => _762.params]), () => ( this.wet.info(layerId).params))).evaporation;
11926
+ const currentEvap = (_nullishCoalesce(_optionalChain([this, 'access', _770 => _770.wet, 'access', _771 => _771.settings, 'access', _772 => _772.get, 'call', _773 => _773(layerId), 'optionalAccess', _774 => _774.params]), () => ( this.wet.info(layerId).params))).evaporation;
11714
11927
  this.heldEvaporation.set(layerId, currentEvap);
11715
11928
  this.wet.setParams(layerId, { evaporation: 0 });
11716
11929
  }
@@ -11764,8 +11977,8 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11764
11977
  }
11765
11978
  }
11766
11979
  mergeTempLayerIntoTarget(doc, tempLayerId, targetLayerId) {
11767
- const upper = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, tempLayerId), 'optionalAccess', _763 => _763.layer]);
11768
- const below = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, targetLayerId), 'optionalAccess', _764 => _764.layer]);
11980
+ const upper = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, tempLayerId), 'optionalAccess', _775 => _775.layer]);
11981
+ const below = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, targetLayerId), 'optionalAccess', _776 => _776.layer]);
11769
11982
  if (!isPixelLayer(upper)) return doc;
11770
11983
  if (!isPixelLayer(below)) {
11771
11984
  return {
@@ -11819,7 +12032,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11819
12032
  for (const m of this.mutations) {
11820
12033
  m.strokes = m.strokes.filter((s) => remainingIds.has(s.id));
11821
12034
  if (m.strokes.length === 0) {
11822
- _optionalChain([this, 'access', _765 => _765.mutationDirector, 'optionalAccess', _766 => _766.cancel, 'call', _767 => _767(m.id)]);
12035
+ _optionalChain([this, 'access', _777 => _777.mutationDirector, 'optionalAccess', _778 => _778.cancel, 'call', _779 => _779(m.id)]);
11823
12036
  if (m.claimedBy && this.mutationDirector) {
11824
12037
  this.mutationDirector.presence.remove(m.claimedBy.replace(/^agent:/, "") || "mutation-agent");
11825
12038
  }
@@ -11846,7 +12059,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11846
12059
  }
11847
12060
  resetMutations() {
11848
12061
  for (const m of this.mutations) {
11849
- _optionalChain([this, 'access', _768 => _768.mutationDirector, 'optionalAccess', _769 => _769.cancel, 'call', _770 => _770(m.id)]);
12062
+ _optionalChain([this, 'access', _780 => _780.mutationDirector, 'optionalAccess', _781 => _781.cancel, 'call', _782 => _782(m.id)]);
11850
12063
  }
11851
12064
  this.mutations = [];
11852
12065
  this.heldEvaporation.clear();
@@ -11855,7 +12068,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11855
12068
  }
11856
12069
  /** A layer's tile surface (live while stroking), for thumbnails. */
11857
12070
  layerSurface(id) {
11858
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _771 => _771.layer]);
12071
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _783 => _783.layer]);
11859
12072
  return isPixelLayer(l) ? l.surface : null;
11860
12073
  }
11861
12074
  // --- Proposals and evolutionary strokes ------------------------------------------
@@ -11875,7 +12088,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11875
12088
  breedStrokes(options) {
11876
12089
  const { strokeIds } = options;
11877
12090
  if (!Array.isArray(strokeIds) || strokeIds.length < 1 || strokeIds.length > 16) {
11878
- throw new PaintEditorError(`strokeIds must have 1..16 stroke ids (got ${_nullishCoalesce(_optionalChain([strokeIds, 'optionalAccess', _772 => _772.length]), () => ( 0))}); call list_strokes for the ids.`);
12091
+ throw new PaintEditorError(`strokeIds must have 1..16 stroke ids (got ${_nullishCoalesce(_optionalChain([strokeIds, 'optionalAccess', _784 => _784.length]), () => ( 0))}); call list_strokes for the ids.`);
11879
12092
  }
11880
12093
  const count = _nullishCoalesce(options.count, () => ( 4));
11881
12094
  if (!Number.isInteger(count) || count < 2 || count > 12) {
@@ -11931,7 +12144,7 @@ var PaintEditorController = (_class17 = class _PaintEditorController {
11931
12144
  breedProposal(options) {
11932
12145
  const { proposalIds } = options;
11933
12146
  if (!Array.isArray(proposalIds) || proposalIds.length < 1 || proposalIds.length > 2) {
11934
- throw new PaintEditorError(`proposalIds must have 1 or 2 proposal ids (1 to mutate, 2 to cross over; got ${_nullishCoalesce(_optionalChain([proposalIds, 'optionalAccess', _773 => _773.length]), () => ( 0))}); call list_paint_proposals for the ids.`);
12147
+ throw new PaintEditorError(`proposalIds must have 1 or 2 proposal ids (1 to mutate, 2 to cross over; got ${_nullishCoalesce(_optionalChain([proposalIds, 'optionalAccess', _785 => _785.length]), () => ( 0))}); call list_paint_proposals for the ids.`);
11935
12148
  }
11936
12149
  const count = _nullishCoalesce(options.count, () => ( 4));
11937
12150
  if (!Number.isInteger(count) || count < 2 || count > 12) {
@@ -12025,7 +12238,7 @@ function insertAfter(layers, id, node) {
12025
12238
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
12026
12239
  }
12027
12240
  function isLiveEffect(s) {
12028
- return _optionalChain([s, 'access', _774 => _774.paint, 'optionalAccess', _775 => _775.type]) === "effect" && s.paint.live === true;
12241
+ return _optionalChain([s, 'access', _786 => _786.paint, 'optionalAccess', _787 => _787.type]) === "effect" && s.paint.live === true;
12029
12242
  }
12030
12243
  function framePaint(p, t) {
12031
12244
  return { ...p, time: p.time + t };
@@ -12050,7 +12263,7 @@ function clipRect(r, width, height) {
12050
12263
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
12051
12264
  }
12052
12265
  function withLiveStroke(doc, stroke) {
12053
- const list = _optionalChain([doc, 'access', _776 => _776.liveStrokes, 'optionalAccess', _777 => _777[stroke.layerId]]);
12266
+ const list = _optionalChain([doc, 'access', _788 => _788.liveStrokes, 'optionalAccess', _789 => _789[stroke.layerId]]);
12054
12267
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
12055
12268
  }
12056
12269
  function shiftDocument(doc, dx, dy) {
@@ -12077,9 +12290,9 @@ function shiftDocument(doc, dx, dy) {
12077
12290
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
12078
12291
  if (doc.paintEvents) {
12079
12292
  out.paintEvents = doc.paintEvents.map((e) => {
12080
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _778 => _778.data, 'optionalAccess', _779 => _779.stickers]) : void 0;
12293
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _790 => _790.data, 'optionalAccess', _791 => _791.stickers]) : void 0;
12081
12294
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
12082
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _780 => _780.data, 'optionalAccess', _781 => _781.strokes]) : void 0;
12295
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _792 => _792.data, 'optionalAccess', _793 => _793.strokes]) : void 0;
12083
12296
  if (strokes) return { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } };
12084
12297
  if (e.kind === "fill-region" && e.data) {
12085
12298
  const d = e.data;
@@ -12102,6 +12315,9 @@ function shiftDocument(doc, dx, dy) {
12102
12315
  if (e.kind === "dry" && typeof d.x === "number") return { ...e, data: moveRect(d, dx, dy) };
12103
12316
  if (e.kind === "wet-paper" && d.rect) return { ...e, data: { ...d, rect: moveRect(d.rect, dx, dy) } };
12104
12317
  if (e.kind === "flow" && d.center) return { ...e, data: { ...d, center: movePoint(d.center, dx, dy) } };
12318
+ if (e.kind === "seed-live-patterns" && Array.isArray(d.points)) {
12319
+ return { ...e, data: { ...d, points: d.points.map((p) => ({ ...p, x: p.x + dx, y: p.y + dy })) } };
12320
+ }
12105
12321
  return e;
12106
12322
  });
12107
12323
  }
@@ -12163,7 +12379,7 @@ function clipToCanvas(rect, canvas) {
12163
12379
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
12164
12380
  }
12165
12381
  function toEffectPaintPixels(p, pixels) {
12166
- return { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data), ..._optionalChain([p, 'access', _782 => _782.map, 'optionalAccess', _783 => _783.by]) === "stroke" ? { map: p.map } : {} };
12382
+ return { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data), ..._optionalChain([p, 'access', _794 => _794.map, 'optionalAccess', _795 => _795.by]) === "stroke" ? { map: p.map } : {} };
12167
12383
  }
12168
12384
  function readWetGhost(raw) {
12169
12385
  if (!raw || typeof raw !== "object") return null;
@@ -12193,8 +12409,8 @@ function strokeSchedule(points) {
12193
12409
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
12194
12410
  }
12195
12411
  function strokeDuration(points, max = 1800) {
12196
- const t0 = _optionalChain([points, 'access', _784 => _784[0], 'optionalAccess', _785 => _785.t]);
12197
- const t1 = _optionalChain([points, 'access', _786 => _786[points.length - 1], 'optionalAccess', _787 => _787.t]);
12412
+ const t0 = _optionalChain([points, 'access', _796 => _796[0], 'optionalAccess', _797 => _797.t]);
12413
+ const t1 = _optionalChain([points, 'access', _798 => _798[points.length - 1], 'optionalAccess', _799 => _799.t]);
12198
12414
  let ms;
12199
12415
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
12200
12416
  else {
@@ -12234,16 +12450,16 @@ var PaintDirector = (_class18 = class {
12234
12450
  /** Cancels any queued or running performance with `key` (e.g. a mutation that was undone). */
12235
12451
  cancel(key) {
12236
12452
  this.cancelled.add(key);
12237
- if (_optionalChain([this, 'access', _788 => _788.currentRun, 'optionalAccess', _789 => _789.key]) === key) {
12453
+ if (_optionalChain([this, 'access', _800 => _800.currentRun, 'optionalAccess', _801 => _801.key]) === key) {
12238
12454
  const { actorId, cancelSession } = this.currentRun;
12239
12455
  this.currentRun = null;
12240
- _optionalChain([cancelSession, 'optionalCall', _790 => _790()]);
12456
+ _optionalChain([cancelSession, 'optionalCall', _802 => _802()]);
12241
12457
  this.presence.remove(actorId);
12242
12458
  }
12243
12459
  }
12244
12460
  /** Acts out `commands` in order for `actor`. Resolves with one result per command. */
12245
12461
  perform(actor, commands, options) {
12246
- const key = _optionalChain([options, 'optionalAccess', _791 => _791.key]);
12462
+ const key = _optionalChain([options, 'optionalAccess', _803 => _803.key]);
12247
12463
  if (key) this.cancelled.delete(key);
12248
12464
  return this.queue.run(actor, async () => {
12249
12465
  if (key && this.cancelled.has(key)) {
@@ -12264,7 +12480,7 @@ var PaintDirector = (_class18 = class {
12264
12480
  }
12265
12481
  }
12266
12482
  } finally {
12267
- if (_optionalChain([this, 'access', _792 => _792.currentRun, 'optionalAccess', _793 => _793.key]) === key) this.currentRun = null;
12483
+ if (_optionalChain([this, 'access', _804 => _804.currentRun, 'optionalAccess', _805 => _805.key]) === key) this.currentRun = null;
12268
12484
  }
12269
12485
  return results;
12270
12486
  });
@@ -12274,7 +12490,7 @@ var PaintDirector = (_class18 = class {
12274
12490
  }
12275
12491
  where(id) {
12276
12492
  const a = this.presence.get(id);
12277
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _794 => _794.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _795 => _795.y]), () => ( 0)) };
12493
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _806 => _806.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _807 => _807.y]), () => ( 0)) };
12278
12494
  }
12279
12495
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
12280
12496
  async glide(id, to, ms = 380) {
@@ -12324,7 +12540,7 @@ var PaintDirector = (_class18 = class {
12324
12540
  }
12325
12541
  case "fill-region": {
12326
12542
  await this.say(id, command.note, 500);
12327
- const pts = _optionalChain([command, 'access', _796 => _796.fill, 'access', _797 => _797.points, 'optionalAccess', _798 => _798.length]) ? command.fill.points : command.fill.x !== void 0 && command.fill.y !== void 0 ? [{ x: command.fill.x, y: command.fill.y }] : [];
12543
+ const pts = _optionalChain([command, 'access', _808 => _808.fill, 'access', _809 => _809.points, 'optionalAccess', _810 => _810.length]) ? command.fill.points : command.fill.x !== void 0 && command.fill.y !== void 0 ? [{ x: command.fill.x, y: command.fill.y }] : [];
12328
12544
  for (const p of pts) {
12329
12545
  await this.glide(id, p, 240);
12330
12546
  this.presence.set({ id, pressed: true });
@@ -12335,8 +12551,8 @@ var PaintDirector = (_class18 = class {
12335
12551
  }
12336
12552
  case "replay": {
12337
12553
  await this.say(id, command.note, 500);
12338
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _799 => _799.replay, 'access', _800 => _800.strokeIds, 'optionalAccess', _801 => _801.includes, 'call', _802 => _802(s.id)]));
12339
- const first = _optionalChain([source, 'access', _803 => _803[0], 'optionalAccess', _804 => _804.points, 'access', _805 => _805[0]]);
12554
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _811 => _811.replay, 'access', _812 => _812.strokeIds, 'optionalAccess', _813 => _813.includes, 'call', _814 => _814(s.id)]));
12555
+ const first = _optionalChain([source, 'access', _815 => _815[0], 'optionalAccess', _816 => _816.points, 'access', _817 => _817[0]]);
12340
12556
  if (first) await this.glide(id, first);
12341
12557
  const result = c.replayStrokes(command.replay);
12342
12558
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -12350,7 +12566,7 @@ var PaintDirector = (_class18 = class {
12350
12566
  const points = c.checkPoints(init.points);
12351
12567
  const { points: _points, ...rest } = init;
12352
12568
  const session = within(() => c.beginStroke({ snapToPerspective: false, start: points[0], ...rest }));
12353
- if (key && _optionalChain([this, 'access', _806 => _806.currentRun, 'optionalAccess', _807 => _807.key]) === key) {
12569
+ if (key && _optionalChain([this, 'access', _818 => _818.currentRun, 'optionalAccess', _819 => _819.key]) === key) {
12354
12570
  this.currentRun.cancelSession = () => {
12355
12571
  if (c.activeStroke === session) session.cancel();
12356
12572
  };
@@ -12384,7 +12600,7 @@ var PaintDirector = (_class18 = class {
12384
12600
  this.presence.set({ id, pressed: false });
12385
12601
  throw error;
12386
12602
  } finally {
12387
- if (key && _optionalChain([this, 'access', _808 => _808.currentRun, 'optionalAccess', _809 => _809.key]) === key) delete this.currentRun.cancelSession;
12603
+ if (key && _optionalChain([this, 'access', _820 => _820.currentRun, 'optionalAccess', _821 => _821.key]) === key) delete this.currentRun.cancelSession;
12388
12604
  }
12389
12605
  }
12390
12606
  /** Paints several strokes live in turn and commits them as one undo step (e.g. a path's subpaths). */
@@ -12394,7 +12610,7 @@ var PaintDirector = (_class18 = class {
12394
12610
  const checked = inits.map((s) => ({ ...s, points: c.checkPoints(s.points) }));
12395
12611
  const first = checked[0];
12396
12612
  const base = first.brushId ? c.getBrush(first.brushId) : c.getState().brush;
12397
- const stepLabel = _nullishCoalesce(label, () => ( `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _810 => _810.name]), () => ( "Brush"))} path stroke`));
12613
+ const stepLabel = _nullishCoalesce(label, () => ( `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _822 => _822.name]), () => ( "Brush"))} path stroke`));
12398
12614
  return c.group(stepLabel, async (within) => {
12399
12615
  let layerId = _nullishCoalesce(_nullishCoalesce(first.layerId, () => ( c.document.activeLayerId)), () => ( ""));
12400
12616
  let bounds = null;
@@ -12415,8 +12631,8 @@ var PaintDirector = (_class18 = class {
12415
12631
  bounds,
12416
12632
  dabs,
12417
12633
  strokeIds,
12418
- ..._optionalChain([last, 'optionalAccess', _811 => _811.mixerLoad]) ? { mixerLoad: last.mixerLoad } : {},
12419
- ..._optionalChain([last, 'optionalAccess', _812 => _812.wet]) !== void 0 ? { wet: last.wet } : {}
12634
+ ..._optionalChain([last, 'optionalAccess', _823 => _823.mixerLoad]) ? { mixerLoad: last.mixerLoad } : {},
12635
+ ..._optionalChain([last, 'optionalAccess', _824 => _824.wet]) !== void 0 ? { wet: last.wet } : {}
12420
12636
  };
12421
12637
  });
12422
12638
  }
@@ -12920,7 +13136,7 @@ function createPaintGuideTools(c) {
12920
13136
  type: "object",
12921
13137
  properties: {
12922
13138
  color: { ...COLOR2, description: "A colour #rrggbb." },
12923
- paint: { ..._chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
13139
+ paint: { ..._chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
12924
13140
  name: { type: "string", minLength: 1, description: "Optional name." }
12925
13141
  },
12926
13142
  additionalProperties: false
@@ -13139,6 +13355,43 @@ var WET_PARAM_SCHEMA = {
13139
13355
  bloom: UNIT("Blooms: water running into a drying wash pushes its pigment into cauliflower edges (default 0.4)."),
13140
13356
  bleed: UNIT("Colour bleed between touching wet areas (default 0.3).")
13141
13357
  };
13358
+ var LIVE_PATTERN_SCHEMA = {
13359
+ pattern: {
13360
+ type: "string",
13361
+ enum: [..._chunkIFWLZZCWcjs.LIVE_PATTERN_KINDS],
13362
+ description: "Pearson Gray-Scott preset: spots, stripes, coral, maze or worms (default spots). Sets feed and kill unless explicit feed/kill are also passed."
13363
+ },
13364
+ feed: {
13365
+ type: "number",
13366
+ minimum: 5e-3,
13367
+ maximum: 0.1,
13368
+ description: "Gray-Scott feed rate F, 0.005..0.1 (default: the pattern preset\u2019s feed rate)."
13369
+ },
13370
+ kill: {
13371
+ type: "number",
13372
+ minimum: 0.02,
13373
+ maximum: 0.08,
13374
+ description: "Gray-Scott kill rate k, 0.02..0.08 (default: the pattern preset\u2019s kill rate)."
13375
+ },
13376
+ scale: {
13377
+ type: "number",
13378
+ minimum: 0.25,
13379
+ maximum: 4,
13380
+ description: "Diffusion scale 0.25..4 (larger values grow broader pattern features; default 1)."
13381
+ },
13382
+ contrast: {
13383
+ type: "number",
13384
+ minimum: 0,
13385
+ maximum: 2,
13386
+ description: "How strongly V modulates the wet pigment or blends toward secondColor, 0..2 (default 0.85)."
13387
+ },
13388
+ secondColor: {
13389
+ type: ["string", "null"],
13390
+ pattern: "^#[0-9a-fA-F]{6}$",
13391
+ description: "Optional #rrggbb colour that high-V pattern ridges blend toward, or null to modulate pigment contrast (default null)."
13392
+ },
13393
+ relief: UNIT("Impasto ridge height 0..1 written from V into the layer\u2019s thick height map so light catches the pattern (default 0).")
13394
+ };
13142
13395
  function createPaintWetTools(c) {
13143
13396
  const stillWet = () => c.wetState().wet;
13144
13397
  return [
@@ -13216,7 +13469,7 @@ function createPaintWetTools(c) {
13216
13469
  type: "object",
13217
13470
  properties: {
13218
13471
  layerId: LAYER_ID2,
13219
- kind: { type: "string", enum: [..._chunkDHC4E2DUcjs.WET_FLOW_KINDS], description: "none, linear, swirl, radial or turbulent." },
13472
+ kind: { type: "string", enum: [..._chunkMITQGHN3cjs.WET_FLOW_KINDS], description: "none, linear, swirl, radial or turbulent." },
13220
13473
  strength: UNIT("How hard it pushes, 0..1 (1 is about a 25\xB0 tilt; default 0.5)."),
13221
13474
  angle: { type: "number", minimum: -360, maximum: 360, description: "linear: direction in degrees clockwise from canvas down (default 0)." },
13222
13475
  center: {
@@ -13302,6 +13555,73 @@ function createPaintWetTools(c) {
13302
13555
  inputSchema: { type: "object", properties: { visible: { type: "boolean", description: "Show (true) or hide (false) the overlay." } }, required: ["visible"], additionalProperties: false },
13303
13556
  annotations: { title: "Show the water", ...SET2 },
13304
13557
  handler: ({ visible }) => ({ visible: c.setWaterOverlay(visible), stillWet: stillWet() })
13558
+ },
13559
+ {
13560
+ name: "get_live_patterns",
13561
+ title: "Get live patterns",
13562
+ description: "Reads the Gray-Scott reaction-diffusion live patterns on a layer (layerId, default the active layer): whether live patterns are enabled, the active settings (pattern, feed, kill, scale, contrast, secondColor, relief), activeTiles, patternCells, wetPatternCells (pattern cells still holding water where the pattern can grow), meanV, maxV, bounds, wet coverage (wet, wetCells, wetBounds), layers (every layer with wet paint or live patterns), and presets (built-in Pearson feed/kill presets: spots, stripes, coral, maze, worms). Call it before or after advance_wet_paint and dry_paint to inspect pattern growth and freezing.",
13563
+ inputSchema: { type: "object", properties: { layerId: LAYER_ID2 }, additionalProperties: false },
13564
+ annotations: { title: "Get live patterns", ...READ3 },
13565
+ coordinates: { out: ["wetBounds", "bounds", "layers[].wetBounds", "layers[].bounds"] },
13566
+ handler: ({ layerId }) => c.getLivePatterns(layerId)
13567
+ },
13568
+ {
13569
+ name: "set_live_patterns",
13570
+ title: "Set live patterns",
13571
+ description: "Configures a layer\u2019s Gray-Scott reaction-diffusion live patterns (or clears them with enabled: false). Patterns grow inside wet paint during advance_wet_paint and freeze when the paint dries (dry_paint). Choose a Pearson preset (spots, stripes, coral, maze, worms) or explicit feed and kill rates, scale, contrast, secondColor (#rrggbb or null to modulate pigment contrast) and relief (0..1, writes ridge height into thick paint so lighting catches the pattern). One undo step. Returns the layer\u2019s live-pattern stats and stillWet.",
13572
+ inputSchema: {
13573
+ type: "object",
13574
+ properties: {
13575
+ layerId: LAYER_ID2,
13576
+ enabled: { type: "boolean", description: "true (default) configures live patterns on the layer; false clears them." },
13577
+ ...LIVE_PATTERN_SCHEMA
13578
+ },
13579
+ additionalProperties: false
13580
+ },
13581
+ annotations: { title: "Set live patterns", ...SET2 },
13582
+ coordinates: { out: ["wetBounds", "bounds"] },
13583
+ handler: async ({ layerId, ...update }) => {
13584
+ await c.wetIdle();
13585
+ return { ...c.setLivePatterns(layerId, update), stillWet: stillWet() };
13586
+ }
13587
+ },
13588
+ {
13589
+ name: "seed_live_patterns",
13590
+ title: "Seed live patterns",
13591
+ description: 'Seeds Gray-Scott reaction-diffusion activator (V) discs at points on a layer so reaction-diffusion patterns (spots, stripes, coral, maze, worms) grow where the layer holds wet water (advance_wet_paint) and freeze where it dries (dry_paint). Painting with a wet brush that has a livePatterns facet (such as preset "turing-wash" or "coral-ink") also seeds along the stroke automatically. One undo step. Returns seededCells, the layer\u2019s live-pattern stats (patternCells, wetPatternCells, meanV, maxV, bounds) and stillWet.',
13592
+ inputSchema: {
13593
+ type: "object",
13594
+ properties: {
13595
+ layerId: LAYER_ID2,
13596
+ points: {
13597
+ type: "array",
13598
+ minItems: 1,
13599
+ maxItems: 1024,
13600
+ description: "Seed centres in document pixels where reaction-diffusion activator V is nucleated.",
13601
+ items: {
13602
+ type: "object",
13603
+ properties: {
13604
+ x: { type: "number", description: "Document x in pixels." },
13605
+ y: { type: "number", description: "Document y in pixels." },
13606
+ strength: { type: "number", exclusiveMinimum: 0, maximum: 1, description: "Seed strength 0..1 (default 1)." }
13607
+ },
13608
+ required: ["x", "y"],
13609
+ additionalProperties: false
13610
+ }
13611
+ },
13612
+ radius: { type: "number", minimum: 1, maximum: 512, description: "Seed disc radius in document pixels (default 16)." },
13613
+ seed: { type: "integer", minimum: 0, description: "Deterministic noise seed for the nucleated discs (default: next editor seed)." },
13614
+ ...LIVE_PATTERN_SCHEMA
13615
+ },
13616
+ required: ["points"],
13617
+ additionalProperties: false
13618
+ },
13619
+ annotations: { title: "Seed live patterns", ...WRITE3 },
13620
+ coordinates: { in: ["points"], out: ["wetBounds", "bounds"] },
13621
+ handler: async (args) => {
13622
+ await c.wetIdle();
13623
+ return { ...c.seedLivePatterns(args), stillWet: stillWet() };
13624
+ }
13305
13625
  }
13306
13626
  ];
13307
13627
  }
@@ -13657,7 +13977,7 @@ function createMutationTools(c, options = {}) {
13657
13977
  annotations: { title: "Read and claim a mutation", ...WRITE5 },
13658
13978
  coordinates: { out: ["bounds", "strokes[].bounds", "strokes[].points[]", "cropPng.rect"] },
13659
13979
  handler: (a) => c.readMutation(a.id, {
13660
- actor: _optionalChain([options, 'access', _813 => _813.actor, 'optionalAccess', _814 => _814.id]),
13980
+ actor: _optionalChain([options, 'access', _825 => _825.actor, 'optionalAccess', _826 => _826.id]),
13661
13981
  padding: a.padding,
13662
13982
  maxSide: a.maxSide
13663
13983
  })
@@ -13693,7 +14013,7 @@ function createMutationTools(c, options = {}) {
13693
14013
  brush: {
13694
14014
  type: "object",
13695
14015
  description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).",
13696
- properties: _chunkY354ETAEcjs.BRUSH_PATCH_PROPERTIES,
14016
+ properties: _chunk5HR5CSLCcjs.BRUSH_PATCH_PROPERTIES,
13697
14017
  additionalProperties: false
13698
14018
  },
13699
14019
  color: {
@@ -13702,7 +14022,7 @@ function createMutationTools(c, options = {}) {
13702
14022
  description: "Paint colour #rrggbb (default the paint colour)."
13703
14023
  },
13704
14024
  paint: {
13705
- ..._chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA,
14025
+ ..._chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA,
13706
14026
  description: "Colour or gradient paint for this stroke."
13707
14027
  },
13708
14028
  seed: {
@@ -13741,7 +14061,7 @@ function createMutationTools(c, options = {}) {
13741
14061
  const base = s.brushId ? c.getBrush(s.brushId) : c.getState().brush;
13742
14062
  const brush = s.brush ? c.brushChanges(s.brush, s.brushId) : void 0;
13743
14063
  if (base) {
13744
- const refs = _chunkOLZXXAERcjs.brushStickerRefs.call(void 0, _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
14064
+ const refs = _chunkOY24XRYFcjs.brushStickerRefs.call(void 0, _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
13745
14065
  if (refs.length) await c.prepareStickers(refs);
13746
14066
  }
13747
14067
  strokes.push({
@@ -13842,7 +14162,7 @@ function createPaintEvolutionTools(c) {
13842
14162
  annotations: { title: "Breed stroke variants", ...WRITE6 },
13843
14163
  coordinates: { out: ["proposals[].bounds"] },
13844
14164
  handler: ({ strokeIds, count, mutation, seed }, context) => {
13845
- const actor = _optionalChain([context, 'optionalAccess', _815 => _815.actor, 'optionalAccess', _816 => _816.id]);
14165
+ const actor = _optionalChain([context, 'optionalAccess', _827 => _827.actor, 'optionalAccess', _828 => _828.id]);
13846
14166
  return c.breedStrokes({
13847
14167
  strokeIds,
13848
14168
  count,
@@ -13885,7 +14205,7 @@ function createPaintEvolutionTools(c) {
13885
14205
  annotations: { title: "Breed from paint proposals", ...WRITE6 },
13886
14206
  coordinates: { out: ["proposals[].bounds"] },
13887
14207
  handler: ({ proposalIds, count, mutation, seed }, context) => {
13888
- const actor = _optionalChain([context, 'optionalAccess', _817 => _817.actor, 'optionalAccess', _818 => _818.id]);
14208
+ const actor = _optionalChain([context, 'optionalAccess', _829 => _829.actor, 'optionalAccess', _830 => _830.id]);
13889
14209
  return c.breedProposal({
13890
14210
  proposalIds,
13891
14211
  count,
@@ -14063,9 +14383,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
14063
14383
  inputSchema: EMPTY3,
14064
14384
  annotations: { title: "List papers", ...READ8 },
14065
14385
  handler: () => ({
14066
- papers: _chunkOLZXXAERcjs.PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),
14067
- families: [..._chunkOLZXXAERcjs.PAPER_FAMILIES],
14068
- patterns: [..._chunkNIBFKXMDcjs.GRAIN_PATTERNS]
14386
+ papers: _chunkOY24XRYFcjs.PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),
14387
+ families: [..._chunkOY24XRYFcjs.PAPER_FAMILIES],
14388
+ patterns: [..._chunkIFWLZZCWcjs.GRAIN_PATTERNS]
14069
14389
  })
14070
14390
  });
14071
14391
  add({
@@ -14096,7 +14416,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
14096
14416
  depth: { type: "number", minimum: 0, maximum: 1, description: "Grain depth 0..1 (0: brushes ignore the grain)." },
14097
14417
  scale: { type: "number", minimum: 0.25, maximum: 8, description: "Grain scale: 1 natural, 2 twice as coarse." },
14098
14418
  seed: { type: "integer", minimum: 0, description: "Grain seed: another sheet of the same paper." },
14099
- pattern: { type: "string", enum: [..._chunkNIBFKXMDcjs.GRAIN_PATTERNS], description: "Grain pattern." },
14419
+ pattern: { type: "string", enum: [..._chunkIFWLZZCWcjs.GRAIN_PATTERNS], description: "Grain pattern." },
14100
14420
  tiling: { type: "string", enum: ["repeat", "mirror"], description: "How the grain tile repeats (mirror hides seams)." },
14101
14421
  shading: { type: "number", minimum: 0, maximum: 1, description: "How much the grain shades the paper colour." },
14102
14422
  dry: { ...tuning, description: "Height map tuning for dry media." },
@@ -14367,10 +14687,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
14367
14687
  name: "set_brush",
14368
14688
  title: "Set the brush",
14369
14689
  description: "Chooses the active brush (id, from list_brush_presets) and / or changes it with facets laid over it (objects merge, lists and values replace, marks of another kind replace the marks; the brush library's create_brush fields); unset removes whole facets first (unset colour drops a brush's own gradient). Strokes without a brush use it. Editor state, not an undo step: the changes stay on the active brush until the library's create_brush or update_brush stores a brush. Returns the active brush as facets, the engine it paints with, and problems (values clamped or dropped).",
14370
- inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brush_presets to start from (default the active brush)." }, name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." }, ..._chunkY354ETAEcjs.BRUSH_PATCH_PROPERTIES, unset: _chunkY354ETAEcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
14690
+ inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brush_presets to start from (default the active brush)." }, name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." }, ..._chunk5HR5CSLCcjs.BRUSH_PATCH_PROPERTIES, unset: _chunk5HR5CSLCcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
14371
14691
  annotations: { title: "Set the brush", ...SET5 },
14372
14692
  handler: async ({ id, unset, ...patch }) => {
14373
- const stamps = _optionalChain([patch, 'access', _819 => _819.tip, 'optionalAccess', _820 => _820.stamps]);
14693
+ const stamps = _optionalChain([patch, 'access', _831 => _831.tip, 'optionalAccess', _832 => _832.stamps]);
14374
14694
  if (stamps) await c.prepareStickers(stamps);
14375
14695
  const r = c.setBrushFacets(patch, id, unset);
14376
14696
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -14403,7 +14723,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
14403
14723
  name: "set_paint",
14404
14724
  title: "Set the paint (colour or gradient)",
14405
14725
  description: 'Sets what strokes paint with: one colour, or gradient paint that changes colour as the stroke goes. Gradient paint: 2..16 stops sorted by offset (#rrggbb, or "paint" / "secondary" for the two editor colours), space pigment (default: mixes like paint) / oklab / srgb, and map: distance (default: the colour changes as the stroke is dragged out, 300 px then mirrored back), pressure, tilt, velocity, direction, time, across-tip or random. Every stroking brush samples it per dab (dab, mixer, watercolour and gouache, oil and impasto, particle, bristle, sticker); erasers, blenders and smudges ignore it, and a brush with its own gradient (get_brush paint) paints that instead. It also ends effect paint (set_effect_paint); set_color goes back to one colour. Editor state, not an undo step. Returns paint, color and secondaryColor.',
14406
- inputSchema: { type: "object", properties: { paint: _chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
14726
+ inputSchema: { type: "object", properties: { paint: _chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
14407
14727
  annotations: { title: "Set the paint (colour or gradient)", ...SET5 },
14408
14728
  handler: ({ paint }) => {
14409
14729
  const p = c.setPaint(paint);
@@ -14463,9 +14783,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
14463
14783
  points: POINTS2,
14464
14784
  layerId: LAYER_ID4,
14465
14785
  brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
14466
- brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkY354ETAEcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
14786
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunk5HR5CSLCcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
14467
14787
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
14468
- paint: { ..._chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
14788
+ paint: { ..._chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
14469
14789
  seed: { type: "integer", minimum: 0, description: "Jitter seed (default a new one); the same seed and points give the same marks." },
14470
14790
  snapToPerspective: { type: "boolean", description: "Snap the points to the perspective guide, as a pen stroke would (default false)." }
14471
14791
  },
@@ -14479,7 +14799,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
14479
14799
  const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
14480
14800
  const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
14481
14801
  if (base) {
14482
- const refs = _chunkOLZXXAERcjs.brushStickerRefs.call(void 0, _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
14802
+ const refs = _chunkOY24XRYFcjs.brushStickerRefs.call(void 0, _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
14483
14803
  if (refs.length) await c.prepareStickers(refs);
14484
14804
  }
14485
14805
  const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush, color: a.color, paint: a.paint, seed: a.seed, snapToPerspective: a.snapToPerspective };
@@ -14501,9 +14821,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
14501
14821
  speed: { type: "number", minimum: 0.01, maximum: 100, description: "Drawing speed in document pixels per millisecond (optional; gives each sample a time t so playback has a pace and speed-sensitive brushes respond)." },
14502
14822
  layerId: LAYER_ID4,
14503
14823
  brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
14504
- brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkY354ETAEcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
14824
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunk5HR5CSLCcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
14505
14825
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
14506
- paint: { ..._chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What the strokes paint with instead of the editor's paint: a colour, or gradient paint that changes colour as each stroke goes." },
14826
+ paint: { ..._chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What the strokes paint with instead of the editor's paint: a colour, or gradient paint that changes colour as each stroke goes." },
14507
14827
  seed: { type: "integer", minimum: 0, description: "Jitter seed of the first subpath, the next ones take the following seeds (default new ones); the same seed and path give the same marks." }
14508
14828
  },
14509
14829
  required: ["path"],
@@ -14516,7 +14836,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
14516
14836
  const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
14517
14837
  const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
14518
14838
  if (base) {
14519
- const refs = _chunkOLZXXAERcjs.brushStickerRefs.call(void 0, _chunk6QNDGMK7cjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
14839
+ const refs = _chunkOY24XRYFcjs.brushStickerRefs.call(void 0, _chunkQ33V5PEFcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
14520
14840
  if (refs.length) await c.prepareStickers(refs);
14521
14841
  }
14522
14842
  const path = options.origin && typeof a.path === "string" && a.path.trim() ? _chunkGF2RBSDMcjs.bezierPathToSvg.call(void 0, a.path, { offset: { x: -options.origin.x, y: -options.origin.y } }) : a.path;
@@ -14540,7 +14860,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
14540
14860
  const { path: _path, spacing: _spacing, pressure: _pressure, speed: _speed, ...stroke } = init;
14541
14861
  return {
14542
14862
  kind: "strokes",
14543
- label: `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _821 => _821.name]), () => ( "Brush"))} path stroke`,
14863
+ label: `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _833 => _833.name]), () => ( "Brush"))} path stroke`,
14544
14864
  strokes: subpaths.map((points, i) => ({
14545
14865
  ...stroke,
14546
14866
  ...stroke.seed !== void 0 ? { seed: stroke.seed + i } : {},
@@ -14597,7 +14917,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
14597
14917
  if (ids) {
14598
14918
  for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke "${id}". Call list_strokes without ids for the ids.`);
14599
14919
  }
14600
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _822 => _822.document, 'access', _823 => _823.liveStrokes, 'optionalAccess', _824 => _824[s.layerId], 'optionalAccess', _825 => _825.includes, 'call', _826 => _826(s)]) === true)) };
14920
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _834 => _834.document, 'access', _835 => _835.liveStrokes, 'optionalAccess', _836 => _836[s.layerId], 'optionalAccess', _837 => _837.includes, 'call', _838 => _838(s)]) === true)) };
14601
14921
  }
14602
14922
  });
14603
14923
  add({
@@ -14630,9 +14950,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
14630
14950
  properties: {
14631
14951
  id: { type: "string", description: "Stroke id from list_strokes {live: true}." },
14632
14952
  brushId: { type: "string", description: "Brush id from list_brush_presets; the stroke keeps its size." },
14633
- brush: { type: "object", properties: _chunkY354ETAEcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false, description: "Facets to change on top of brushId or the stroke\u2019s brush (as set_brush takes them); missing fields keep their values." },
14953
+ brush: { type: "object", properties: _chunk5HR5CSLCcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false, description: "Facets to change on top of brushId or the stroke\u2019s brush (as set_brush takes them); missing fields keep their values." },
14634
14954
  color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", description: "New colour #rrggbb (replaces gradient paint)." },
14635
- paint: { anyOf: [_chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA, { type: "null", description: "Back to the stroke\u2019s plain colour." }], description: "A colour or gradient paint for the stroke; null drops its gradient." },
14955
+ paint: { anyOf: [_chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA, { type: "null", description: "Back to the stroke\u2019s plain colour." }], description: "A colour or gradient paint for the stroke; null drops its gradient." },
14636
14956
  seed: { type: "integer", minimum: 0, description: "Another jitter seed: particles, scatter and texture fall differently." }
14637
14957
  },
14638
14958
  required: ["id"],
@@ -14881,10 +15201,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
14881
15201
  tools.push(...createPaintEvolutionTools(c));
14882
15202
  tools.push(...createPaintStickerTools(c));
14883
15203
  tools.push(...createMutationTools(c, { director: options.director, actor: options.actor }));
14884
- tools.push(..._chunk62MFUHSIcjs.createPigmentTools.call(void 0, ));
15204
+ tools.push(..._chunkUQXULAMQcjs.createPigmentTools.call(void 0, ));
14885
15205
  tools.push(..._chunkPFHJS4HEcjs.createStickerTools.call(void 0, { provider: () => c.stickersProvider }));
14886
15206
  tools.push(
14887
- ..._chunkRAPNRK4Rcjs.createLayerEffectTools.call(void 0,
15207
+ ..._chunkX7XBEX3Ocjs.createLayerEffectTools.call(void 0,
14888
15208
  {
14889
15209
  requireLayer: (id) => void c.getLayerEffects(id),
14890
15210
  getLayerEffects: (id) => c.getLayerEffects(id),
@@ -14909,16 +15229,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
14909
15229
  }
14910
15230
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
14911
15231
  if (!origin && !onChange) return tool;
14912
- const write = !_optionalChain([tool, 'access', _827 => _827.annotations, 'optionalAccess', _828 => _828.readOnlyHint]);
15232
+ const write = !_optionalChain([tool, 'access', _839 => _839.annotations, 'optionalAccess', _840 => _840.readOnlyHint]);
14913
15233
  const done = (result) => {
14914
- if (write) _optionalChain([onChange, 'optionalCall', _829 => _829({ tool: tool.name })]);
14915
- return origin && _optionalChain([coordinates, 'optionalAccess', _830 => _830.out]) ? fromDocument(result, coordinates.out, origin) : result;
15234
+ if (write) _optionalChain([onChange, 'optionalCall', _841 => _841({ tool: tool.name })]);
15235
+ return origin && _optionalChain([coordinates, 'optionalAccess', _842 => _842.out]) ? fromDocument(result, coordinates.out, origin) : result;
14916
15236
  };
14917
15237
  return {
14918
15238
  ...tool,
14919
15239
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
14920
15240
  handler: (args, context) => {
14921
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _831 => _831.in]) ? toDocument(args, coordinates.in, origin) : args, context);
15241
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _843 => _843.in]) ? toDocument(args, coordinates.in, origin) : args, context);
14922
15242
  return r instanceof Promise ? r.then(done) : done(r);
14923
15243
  }
14924
15244
  };
@@ -14935,23 +15255,23 @@ function strokeSummary(s, withPoints, live) {
14935
15255
  color: s.color,
14936
15256
  points: withPoints ? s.points : s.points.length,
14937
15257
  seed: s.seed,
14938
- copies: _nullishCoalesce(_optionalChain([s, 'access', _832 => _832.copies, 'optionalAccess', _833 => _833.length]), () => ( 0)),
15258
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _844 => _844.copies, 'optionalAccess', _845 => _845.length]), () => ( 0)),
14939
15259
  live,
14940
15260
  bounds: { x: Math.floor(Math.min(...xs) - pad), y: Math.floor(Math.min(...ys) - pad), width: Math.ceil(Math.max(...xs) - Math.min(...xs) + 2 * pad), height: Math.ceil(Math.max(...ys) - Math.min(...ys) + 2 * pad) }
14941
15261
  };
14942
15262
  }
14943
15263
 
14944
15264
  // src/paint-editor/brush-library-tools.ts
14945
- function paintBrushPreviewRenderer(paper = () => _chunkOLZXXAERcjs.DEFAULT_PAPER, options = {}) {
15265
+ function paintBrushPreviewRenderer(paper = () => _chunkOY24XRYFcjs.DEFAULT_PAPER, options = {}) {
14946
15266
  const sources = new BrushSourceArtCache();
14947
15267
  const draw = (brush, { width, height, color }) => {
14948
- const stickers = _optionalChain([options, 'access', _834 => _834.stampArt, 'optionalCall', _835 => _835()]);
15268
+ const stickers = _optionalChain([options, 'access', _846 => _846.stampArt, 'optionalCall', _847 => _847()]);
14949
15269
  const stampArt = sources.with(_nullishCoalesce(stickers, () => ( (() => void 0))));
14950
- const t = renderBrushThumbnail(_chunk6QNDGMK7cjs.resolveBrush.call(void 0, brush), { paper: paper(), width, height, color: color.toLowerCase(), stampArt });
15270
+ const t = renderBrushThumbnail(_chunkQ33V5PEFcjs.resolveBrush.call(void 0, brush), { paper: paper(), width, height, color: color.toLowerCase(), stampArt });
14951
15271
  return { data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" };
14952
15272
  };
14953
15273
  const render = (brush, size) => {
14954
- const ids = _chunk6QNDGMK7cjs.brushSourceIds.call(void 0, brush);
15274
+ const ids = _chunkQ33V5PEFcjs.brushSourceIds.call(void 0, brush);
14955
15275
  if (!ids.length || !options.library) return draw(brush, size);
14956
15276
  const library = options.library;
14957
15277
  return Promise.all(ids.map((id) => library.getSource(id))).then((found) => {
@@ -14962,8 +15282,8 @@ function paintBrushPreviewRenderer(paper = () => _chunkOLZXXAERcjs.DEFAULT_PAPER
14962
15282
  return Object.defineProperty(render, "paper", { get: () => paper().color, enumerable: true });
14963
15283
  }
14964
15284
  function createPaintBrushLibraryToolProvider(controller, options = {}) {
14965
- return _chunkY354ETAEcjs.createBrushLibraryToolProvider.call(void 0, controller.brushLibrary, {
14966
- profile: _chunk6QNDGMK7cjs.PAINT_PROFILE,
15285
+ return _chunk5HR5CSLCcjs.createBrushLibraryToolProvider.call(void 0, controller.brushLibrary, {
15286
+ profile: _chunkQ33V5PEFcjs.PAINT_PROFILE,
14967
15287
  stickers: () => controller.stickers.provider,
14968
15288
  ...options,
14969
15289
  renderPreview: paintBrushPreviewRenderer(() => controller.getState().document.paper, { library: controller.brushLibrary, stampArt: () => controller.stampArt })
@@ -15053,13 +15373,13 @@ var PaintGesture = (_class19 = class {
15053
15373
  const p = this.doc(e);
15054
15374
  const s = this.controller.getState();
15055
15375
  const layerId = s.document.activeLayerId;
15056
- if (!layerId || !_optionalChain([s, 'access', _836 => _836.document, 'access', _837 => _837.liveStrokes, 'optionalAccess', _838 => _838[layerId]])) {
15376
+ if (!layerId || !_optionalChain([s, 'access', _848 => _848.document, 'access', _849 => _849.liveStrokes, 'optionalAccess', _850 => _850[layerId]])) {
15057
15377
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
15058
15378
  return false;
15059
15379
  }
15060
15380
  try {
15061
15381
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
15062
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _839 => _839.id]), () => ( null)));
15382
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _851 => _851.id]), () => ( null)));
15063
15383
  if (!hit) return false;
15064
15384
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
15065
15385
  return true;
@@ -15071,7 +15391,7 @@ var PaintGesture = (_class19 = class {
15071
15391
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
15072
15392
  get strokeDrag() {
15073
15393
  const m = this.mode;
15074
- return _optionalChain([m, 'optionalAccess', _840 => _840.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
15394
+ return _optionalChain([m, 'optionalAccess', _852 => _852.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
15075
15395
  }
15076
15396
  /**
15077
15397
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -15173,8 +15493,8 @@ var PaintGesture = (_class19 = class {
15173
15493
  this.mode = null;
15174
15494
  this.predicted = [];
15175
15495
  if (m.kind === "stroke") {
15176
- _optionalChain([this, 'access', _841 => _841.controller, 'access', _842 => _842.activeStroke, 'optionalAccess', _843 => _843.end, 'call', _844 => _844()]);
15177
- _optionalChain([this, 'access', _845 => _845.controller, 'access', _846 => _846.strokeRendering, 'optionalAccess', _847 => _847.catch, 'call', _848 => _848((err) => {
15496
+ _optionalChain([this, 'access', _853 => _853.controller, 'access', _854 => _854.activeStroke, 'optionalAccess', _855 => _855.end, 'call', _856 => _856()]);
15497
+ _optionalChain([this, 'access', _857 => _857.controller, 'access', _858 => _858.strokeRendering, 'optionalAccess', _859 => _859.catch, 'call', _860 => _860((err) => {
15178
15498
  this.error = err instanceof Error ? err.message : String(err);
15179
15499
  })]);
15180
15500
  }
@@ -15209,9 +15529,9 @@ var PaintGesture = (_class19 = class {
15209
15529
  cancel() {
15210
15530
  this.penDown = false;
15211
15531
  this.predicted = [];
15212
- if (_optionalChain([this, 'access', _849 => _849.mode, 'optionalAccess', _850 => _850.kind]) === "stroke") _optionalChain([this, 'access', _851 => _851.controller, 'access', _852 => _852.activeStroke, 'optionalAccess', _853 => _853.cancel, 'call', _854 => _854()]);
15213
- if (_optionalChain([this, 'access', _855 => _855.mode, 'optionalAccess', _856 => _856.kind]) === "fill" && this.mode.committed) this.controller.undo();
15214
- if (_optionalChain([this, 'access', _857 => _857.mode, 'optionalAccess', _858 => _858.kind]) === "sticker") this.controller.cancelStickerPreview();
15532
+ if (_optionalChain([this, 'access', _861 => _861.mode, 'optionalAccess', _862 => _862.kind]) === "stroke") _optionalChain([this, 'access', _863 => _863.controller, 'access', _864 => _864.activeStroke, 'optionalAccess', _865 => _865.cancel, 'call', _866 => _866()]);
15533
+ if (_optionalChain([this, 'access', _867 => _867.mode, 'optionalAccess', _868 => _868.kind]) === "fill" && this.mode.committed) this.controller.undo();
15534
+ if (_optionalChain([this, 'access', _869 => _869.mode, 'optionalAccess', _870 => _870.kind]) === "sticker") this.controller.cancelStickerPreview();
15215
15535
  this.mode = null;
15216
15536
  }
15217
15537
  get active() {
@@ -15314,7 +15634,7 @@ function guideOverlay(controller, drag) {
15314
15634
  const size = s.document.canvas;
15315
15635
  const out = [];
15316
15636
  const layerId = s.document.activeLayerId;
15317
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _859 => _859.document, 'access', _860 => _860.liveStrokes, 'optionalAccess', _861 => _861[layerId], 'optionalAccess', _862 => _862.some, 'call', _863 => _863((x) => x.id === s.selectedStroke)]) : false;
15637
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _871 => _871.document, 'access', _872 => _872.liveStrokes, 'optionalAccess', _873 => _873[layerId], 'optionalAccess', _874 => _874.some, 'call', _875 => _875((x) => x.id === s.selectedStroke)]) : false;
15318
15638
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
15319
15639
  if (area) {
15320
15640
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -15327,7 +15647,7 @@ function guideOverlay(controller, drag) {
15327
15647
  ];
15328
15648
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
15329
15649
  }
15330
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _864 => _864.document, 'access', _865 => _865.stickers, 'optionalAccess', _866 => _866[layerId], 'optionalAccess', _867 => _867.find, 'call', _868 => _868((x) => x.id === s.selectedSticker)]) : void 0;
15650
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _876 => _876.document, 'access', _877 => _877.stickers, 'optionalAccess', _878 => _878[layerId], 'optionalAccess', _879 => _879.find, 'call', _880 => _880((x) => x.id === s.selectedSticker)]) : void 0;
15331
15651
  if (picked) {
15332
15652
  const r = picked.size / 2 + 2;
15333
15653
  const a = picked.rotation * Math.PI / 180;
@@ -15357,7 +15677,7 @@ var PAPER_SLIDERS = [
15357
15677
  ];
15358
15678
  function readPath(obj, path) {
15359
15679
  let v = obj;
15360
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _869 => _869[k]]);
15680
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _881 => _881[k]]);
15361
15681
  return typeof v === "number" ? v : 0;
15362
15682
  }
15363
15683
  function patchPath(obj, path, value) {
@@ -15435,6 +15755,18 @@ var WET_TILT_SLIDERS = [
15435
15755
  { path: "direction", label: "Downhill", min: 0, max: 359, step: 1 }
15436
15756
  ];
15437
15757
  var WET_SPEED_SLIDER = { path: "speed", label: "Speed", min: 15, max: 480, step: 15 };
15758
+ var LIVE_PATTERN_LABELS = {
15759
+ spots: "Spots",
15760
+ stripes: "Stripes",
15761
+ coral: "Coral",
15762
+ maze: "Maze",
15763
+ worms: "Worms"
15764
+ };
15765
+ var LIVE_PATTERN_SLIDERS = [
15766
+ { path: "scale", label: "Scale", min: 0.25, max: 4, step: 0.05 },
15767
+ { path: "contrast", label: "Contrast", min: 0, max: 2, step: 0.05 },
15768
+ { path: "relief", label: "Relief", min: 0, max: 1, step: 0.01 }
15769
+ ];
15438
15770
  var WET_GPU_OPTIONS = [
15439
15771
  { value: "auto", label: "GPU for large washes" },
15440
15772
  { value: "off", label: "CPU only" }
@@ -15473,7 +15805,7 @@ function startWetClock(controller, frame, cancel) {
15473
15805
  id = raf(loop);
15474
15806
  return () => {
15475
15807
  stopped = true;
15476
- _optionalChain([caf, 'optionalCall', _870 => _870(id)]);
15808
+ _optionalChain([caf, 'optionalCall', _882 => _882(id)]);
15477
15809
  };
15478
15810
  }
15479
15811
  function drawWaterOverlay(controller, ctx) {
@@ -15540,7 +15872,7 @@ function startDeviceTilt(controller) {
15540
15872
  };
15541
15873
  g.addEventListener("deviceorientation", onOrientation);
15542
15874
  return () => {
15543
- _optionalChain([g, 'access', _871 => _871.removeEventListener, 'optionalCall', _872 => _872("deviceorientation", onOrientation)]);
15875
+ _optionalChain([g, 'access', _883 => _883.removeEventListener, 'optionalCall', _884 => _884("deviceorientation", onOrientation)]);
15544
15876
  };
15545
15877
  }
15546
15878
  var PARTICLE_KIND_LABELS = { string: "Strings", spring: "Springs", orbit: "Orbits", flow: "Flow", elastic: "Elastic", fuzzy: "Fuzzy" };
@@ -15551,7 +15883,7 @@ var DOT_ROTATION_LABELS = { follow: "Follow motion", random: "Random", fixed: "T
15551
15883
  var STAMP_LABELS = { dot: "Dot", star: "Star", heart: "Heart", leaf: "Leaf", flower: "Flower", confetti: "Confetti", splat: "Splat", sparkle: "Sparkle", ring: "Ring" };
15552
15884
  function toggleStickerRef(refs, ref2) {
15553
15885
  if (refs.includes(ref2)) return refs.length > 1 ? refs.filter((r) => r !== ref2) : [...refs];
15554
- return refs.length < _chunk6QNDGMK7cjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
15886
+ return refs.length < _chunkQ33V5PEFcjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
15555
15887
  }
15556
15888
  function stickerRefLabel(ref2) {
15557
15889
  const stamp = ref2.startsWith("editor:") ? ref2.slice(7) : null;
@@ -15564,7 +15896,7 @@ function toggleStamp(stamps, stamp) {
15564
15896
  }
15565
15897
  function toggleDotTexture(textures, stamp) {
15566
15898
  if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
15567
- return textures.length < _chunk6QNDGMK7cjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
15899
+ return textures.length < _chunkQ33V5PEFcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
15568
15900
  }
15569
15901
  var PATH_STROKE_TAPERS = [
15570
15902
  { id: "even", label: "Even" },
@@ -15954,7 +16286,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
15954
16286
  },
15955
16287
  annotations: { title: "Propose paint", ...WRITE8 },
15956
16288
  handler: (args, context) => {
15957
- const origin = _optionalChain([context, 'access', _873 => _873.actor, 'optionalAccess', _874 => _874.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
16289
+ const origin = _optionalChain([context, 'access', _885 => _885.actor, 'optionalAccess', _886 => _886.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
15958
16290
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
15959
16291
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
15960
16292
  return { proposalId: proposal.id, ...rest };
@@ -16105,16 +16437,17 @@ function toolList(provider) {
16105
16437
  function uiTables() {
16106
16438
  return {
16107
16439
  tools: PAINT_TOOLS,
16108
- brushOptions: _chunkRAPNRK4Rcjs.BRUSH_OPTION_CONTROLS,
16440
+ brushOptions: _chunkX7XBEX3Ocjs.BRUSH_OPTION_CONTROLS,
16109
16441
  blendMenu: BLEND_MENU_GROUPS,
16110
16442
  layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_MENU.map(({ kind, label }) => ({ kind, label, controls: _chunkPVJMTLPJcjs.layerEffectControls.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, kind)) })),
16111
- sliders: { paper: PAPER_SLIDERS, wet: WET_PARAM_SLIDERS, wetTilt: WET_TILT_SLIDERS, wetSpeed: WET_SPEED_SLIDER, light: LIGHT_SLIDERS, uvLight: UV_LIGHT_SLIDERS, viewTilt: VIEW_TILT_SLIDERS, ghost: _chunkY354ETAEcjs.GHOST_SLIDERS, mutation: _chunkY354ETAEcjs.MUTATION_SLIDERS, stroke: STROKE_SLIDERS, sticker: STICKER_SLIDERS },
16443
+ sliders: { paper: PAPER_SLIDERS, wet: WET_PARAM_SLIDERS, wetTilt: WET_TILT_SLIDERS, wetSpeed: WET_SPEED_SLIDER, light: LIGHT_SLIDERS, uvLight: UV_LIGHT_SLIDERS, viewTilt: VIEW_TILT_SLIDERS, ghost: _chunk5HR5CSLCcjs.GHOST_SLIDERS, mutation: _chunk5HR5CSLCcjs.MUTATION_SLIDERS, livePatterns: LIVE_PATTERN_SLIDERS, stroke: STROKE_SLIDERS, sticker: STICKER_SLIDERS },
16112
16444
  pathStrokeTapers: PATH_STROKE_TAPERS,
16113
16445
  padSampleSizes: PAD_SAMPLE_SIZES,
16114
16446
  wetGpu: WET_GPU_OPTIONS,
16115
16447
  labels: {
16116
16448
  wetTools: WET_TOOL_LABELS,
16117
16449
  wetMedia: WET_MEDIUM_LABELS,
16450
+ livePatterns: LIVE_PATTERN_LABELS,
16118
16451
  impastoTools: IMPASTO_TOOL_LABELS,
16119
16452
  particleKinds: PARTICLE_KIND_LABELS,
16120
16453
  particleRenders: PARTICLE_RENDER_LABELS,
@@ -16629,4 +16962,11 @@ function createPaintConformanceHost(setup, options) {
16629
16962
 
16630
16963
 
16631
16964
 
16632
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunk6QNDGMK7cjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunk6QNDGMK7cjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkY354ETAEcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunk6QNDGMK7cjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.BrushSourceArtCache = BrushSourceArtCache; exports.DAB_FLIPS = _chunk6QNDGMK7cjs.DAB_FLIPS; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunk6QNDGMK7cjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunk6QNDGMK7cjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunk6QNDGMK7cjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunk6QNDGMK7cjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkDHC4E2DUcjs.DEFAULT_FLOW; exports.DEFAULT_FLUORESCENCE = _chunk6QNDGMK7cjs.DEFAULT_FLUORESCENCE; exports.DEFAULT_GHOST = _chunk6QNDGMK7cjs.DEFAULT_GHOST; exports.DEFAULT_IMPASTO = _chunk6QNDGMK7cjs.DEFAULT_IMPASTO; exports.DEFAULT_IRIDESCENCE = _chunk6QNDGMK7cjs.DEFAULT_IRIDESCENCE; exports.DEFAULT_LIGHT = _chunk6QNDGMK7cjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunk6QNDGMK7cjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_MUTATION = _chunk6QNDGMK7cjs.DEFAULT_MUTATION; exports.DEFAULT_MUTATION_RATES = DEFAULT_MUTATION_RATES; exports.DEFAULT_PAINT_GRADIENT = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkOLZXXAERcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunk6QNDGMK7cjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunk6QNDGMK7cjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunk6QNDGMK7cjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_THERMOCHROMIC = _chunk6QNDGMK7cjs.DEFAULT_THERMOCHROMIC; exports.DEFAULT_TIP_GRAIN = _chunk6QNDGMK7cjs.DEFAULT_TIP_GRAIN; exports.DEFAULT_UV_LIGHT = DEFAULT_UV_LIGHT; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_VIEW_TILT = DEFAULT_VIEW_TILT; exports.DEFAULT_WET_BRUSH = _chunk6QNDGMK7cjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkDHC4E2DUcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunk6QNDGMK7cjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunk6QNDGMK7cjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkOLZXXAERcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkOLZXXAERcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkOLZXXAERcjs.EFFECT_STRIP_HEIGHT; exports.EVOLUTION_BRUSH_FACETS = EVOLUTION_BRUSH_FACETS; exports.EVOLUTION_MUTATION_SCHEMA = EVOLUTION_MUTATION_SCHEMA; exports.EVOLUTION_SLIDERS = EVOLUTION_SLIDERS; exports.FilmBuffer = FilmBuffer; exports.GHOST_SLIDERS = _chunkY354ETAEcjs.GHOST_SLIDERS; exports.GHOST_TRIGGERS = _chunk6QNDGMK7cjs.GHOST_TRIGGERS; exports.GPU_LEAD = _chunkOLZXXAERcjs.GPU_LEAD; exports.GRAIN_PATTERNS = _chunkNIBFKXMDcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkNIBFKXMDcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.HEAT_COOLING = HEAT_COOLING; exports.HEAT_DIFFUSION = HEAT_DIFFUSION; exports.HEAT_DRY_THRESHOLD = HEAT_DRY_THRESHOLD; exports.HEAT_SCALE = HEAT_SCALE; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkOLZXXAERcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunk6QNDGMK7cjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.IRIDESCENCE_SLIDERS = _chunkY354ETAEcjs.IRIDESCENCE_SLIDERS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkNIBFKXMDcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunk6QNDGMK7cjs.MAX_DOT_TEXTURES; exports.MAX_EFFECT_PATH_POINTS = _chunkOLZXXAERcjs.MAX_EFFECT_PATH_POINTS; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunk6QNDGMK7cjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunk6QNDGMK7cjs.MULTI_COLOR_MODES; exports.MUTATION_SLIDERS = _chunkY354ETAEcjs.MUTATION_SLIDERS; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunk6QNDGMK7cjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunk6QNDGMK7cjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkNIBFKXMDcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkNIBFKXMDcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkNIBFKXMDcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkOLZXXAERcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkOLZXXAERcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunk6QNDGMK7cjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunk6QNDGMK7cjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = _chunkOLZXXAERcjs.PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkNIBFKXMDcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkNIBFKXMDcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = _chunkOLZXXAERcjs.PaintWetLayers; exports.PaperGrain = _chunkNIBFKXMDcjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = _chunkOLZXXAERcjs.PenDabWalker; exports.PenSmoother = _chunkOLZXXAERcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunk6QNDGMK7cjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkRDFHWAHLcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunk3VHH6V67cjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TIP_GRAIN_MODES = _chunk6QNDGMK7cjs.TIP_GRAIN_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThermoCache = ThermoCache; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.TipGrain = _chunkOLZXXAERcjs.TipGrain; exports.UV_LIGHT_SLIDERS = UV_LIGHT_SLIDERS; exports.UvCache = UvCache; exports.VIEW_TILT_SLIDERS = VIEW_TILT_SLIDERS; exports.WET_FLOW_KINDS = _chunkDHC4E2DUcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = _chunkOLZXXAERcjs.WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunk6QNDGMK7cjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = _chunkOLZXXAERcjs.WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkDHC4E2DUcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunk6QNDGMK7cjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = _chunkOLZXXAERcjs.WetStrokeDriver; exports.addPaintGradientStop = _chunkNIBFKXMDcjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.advanceHeatField = advanceHeatField; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkY354ETAEcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunk6QNDGMK7cjs.brushTakesPaint; exports.brushToJSON = _chunk6QNDGMK7cjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkEvolutionStrokes = checkEvolutionStrokes; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clearHeatField = clearHeatField; exports.cloneHeatField = cloneHeatField; exports.clonePaper = _chunkOLZXXAERcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.computeUvSpill = computeUvSpill; exports.contactSheet = contactSheet; exports.createEvolutionTools = createEvolutionTools; exports.createHeatField = createHeatField; exports.createMutationTools = createMutationTools; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintConformanceHost = createPaintConformanceHost; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintEvolutionToolProvider = createPaintEvolutionToolProvider; exports.createPaintEvolutionTools = createPaintEvolutionTools; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.crossoverBrushes = crossoverBrushes; exports.crossoverGenomes = crossoverGenomes; exports.crossoverStrokes = crossoverStrokes; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.describeGenomeDiff = describeGenomeDiff; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.deviceOrientationToViewTilt = deviceOrientationToViewTilt; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.driftBrushFacets = driftBrushFacets; exports.driftColorOklch = driftColorOklch; exports.effectDabField = _chunkOLZXXAERcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkOLZXXAERcjs.effectPaintKey; exports.effectPaintSize = _chunkOLZXXAERcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyFluor = emptyFluor; exports.emptyThermo = emptyThermo; exports.emptyThickChannels = emptyThickChannels; exports.engineBrushSourceIds = engineBrushSourceIds; exports.exportProposalContactSheetPng = exportProposalContactSheetPng; exports.fillRegionMask = _chunkYH6SKC7Pcjs.fillRegionMask; exports.finalizeThermoStroke = finalizeThermoStroke; exports.findUnfilledRegionsMask = _chunkYH6SKC7Pcjs.findUnfilledRegionsMask; exports.fitZoom = fitZoom; exports.fluorFromJSON = fluorFromJSON; exports.fluorToJSON = fluorToJSON; exports.fluorTwinBrush = fluorTwinBrush; exports.grainCatch = _chunkNIBFKXMDcjs.grainCatch; exports.grainHeights = _chunkNIBFKXMDcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hasThickChannels = hasThickChannels; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.heatFromJSON = heatFromJSON; exports.heatStats = heatStats; exports.heatToJSON = heatToJSON; exports.hexToPaintRgb = _chunkNIBFKXMDcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkOLZXXAERcjs.hexToRgb8; exports.hotCellsBounds = hotCellsBounds; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.inferEffectPathControl = _chunkOLZXXAERcjs.inferEffectPathControl; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkNIBFKXMDcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkOLZXXAERcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunk6QNDGMK7cjs.isWetBrush; exports.isWetCapable = _chunk6QNDGMK7cjs.isWetCapable; exports.jitterStrokePoints = jitterStrokePoints; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mergeFourChannel = mergeFourChannel; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixColorOklch = mixColorOklch; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkOLZXXAERcjs.mixerTip; exports.multiColorForDab = _chunkOLZXXAERcjs.multiColorForDab; exports.multiColorGradient = _chunkOLZXXAERcjs.multiColorGradient; exports.multiColorPalette = _chunkOLZXXAERcjs.multiColorPalette; exports.multiColorSliders = _chunkY354ETAEcjs.multiColorSliders; exports.multiColorToPaint = _chunk6QNDGMK7cjs.multiColorToPaint; exports.mutateGenome = mutateGenome; exports.mutateStroke = mutateStroke; exports.mutationBrushRefusal = mutationBrushRefusal; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunk6QNDGMK7cjs.normalizeBehavior; exports.normalizeBristle = _chunk6QNDGMK7cjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunk6QNDGMK7cjs.normalizeDynamics; exports.normalizeFlow = _chunkDHC4E2DUcjs.normalizeFlow; exports.normalizeFluorescence = _chunk6QNDGMK7cjs.normalizeFluorescence; exports.normalizeGhost = _chunk6QNDGMK7cjs.normalizeGhost; exports.normalizeHexColor = _chunkNIBFKXMDcjs.normalizeHexColor; exports.normalizeImpasto = _chunk6QNDGMK7cjs.normalizeImpasto; exports.normalizeLight = _chunk6QNDGMK7cjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunk6QNDGMK7cjs.normalizeMultiColor; exports.normalizeMutation = _chunk6QNDGMK7cjs.normalizeMutation; exports.normalizeMutationRates = normalizeMutationRates; exports.normalizePaintBrush = _chunk6QNDGMK7cjs.normalizePaintBrush; exports.normalizePaper = _chunkOLZXXAERcjs.normalizePaper; exports.normalizeParticle = _chunk6QNDGMK7cjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunk6QNDGMK7cjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeThermochromic = _chunk6QNDGMK7cjs.normalizeThermochromic; exports.normalizeUvLight = normalizeUvLight; exports.normalizeView = normalizeView; exports.normalizeViewTilt = normalizeViewTilt; exports.normalizeWetBrush = _chunk6QNDGMK7cjs.normalizeWetBrush; exports.normalizeWetParams = _chunkDHC4E2DUcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintBrushPreviewRenderer = paintBrushPreviewRenderer; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkNIBFKXMDcjs.paintGradientMappingFor; exports.paintHeatField = paintHeatField; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkNIBFKXMDcjs.paintSourceColor; exports.paintSourceCss = _chunkNIBFKXMDcjs.paintSourceCss; exports.paintToMultiColor = _chunk6QNDGMK7cjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkOLZXXAERcjs.paperPreset; exports.parseBrushLibrary = _chunk6QNDGMK7cjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkNIBFKXMDcjs.parsePaintSource; exports.patchBrushValue = _chunkY354ETAEcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkOLZXXAERcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.proposalGenomeStrokes = proposalGenomeStrokes; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = _chunkOLZXXAERcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkOLZXXAERcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkNIBFKXMDcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkNIBFKXMDcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkOLZXXAERcjs.renderPaper; exports.renderProposalContactSheet = renderProposalContactSheet; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.requestDeviceTiltPermission = requestDeviceTiltPermission; exports.rerollStrokeSeed = rerollStrokeSeed; exports.resampleStrokePoints = resampleStrokePoints; exports.resolvePaintGradient = _chunkNIBFKXMDcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkNIBFKXMDcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = _chunkOLZXXAERcjs.sampleEffectAt; exports.sampleEffectField = _chunkOLZXXAERcjs.sampleEffectField; exports.sampleHeatAt = sampleHeatAt; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scaleFluor = scaleFluor; exports.scalePaintGradient = _chunkNIBFKXMDcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.seededStrokeVariation = seededStrokeVariation; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.shiftHeatField = shiftHeatField; exports.solidPaint = _chunkNIBFKXMDcjs.solidPaint; exports.squaredDistanceTransform = _chunkYH6SKC7Pcjs.squaredDistanceTransform; exports.stampCoverage = _chunkRDFHWAHLcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startDeviceTilt = startDeviceTilt; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokePathPoints = _chunkOLZXXAERcjs.strokePathPoints; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thermoFromJSON = thermoFromJSON; exports.thermoToJSON = thermoToJSON; exports.thermoTwinBrush = thermoTwinBrush; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thinFilmRgb = thinFilmRgb; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkOLZXXAERcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkOLZXXAERcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkNIBFKXMDcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunk6QNDGMK7cjs.usesPaintExchange; exports.uvLightKey = uvLightKey; exports.uvPaper = uvPaper; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.viewTiltKey = viewTiltKey; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = _chunkOLZXXAERcjs.wetPaperInput; exports.wetPigmentOf = _chunkOLZXXAERcjs.wetPigmentOf; exports.wetSupport = _chunkDHC4E2DUcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback; exports.withStrokePath = _chunkOLZXXAERcjs.withStrokePath;
16965
+
16966
+
16967
+
16968
+
16969
+
16970
+
16971
+
16972
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkQ33V5PEFcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkQ33V5PEFcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunk5HR5CSLCcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkQ33V5PEFcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.BrushSourceArtCache = BrushSourceArtCache; exports.DAB_FLIPS = _chunkQ33V5PEFcjs.DAB_FLIPS; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkQ33V5PEFcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkQ33V5PEFcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkQ33V5PEFcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkQ33V5PEFcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkMITQGHN3cjs.DEFAULT_FLOW; exports.DEFAULT_FLUORESCENCE = _chunkQ33V5PEFcjs.DEFAULT_FLUORESCENCE; exports.DEFAULT_GHOST = _chunkQ33V5PEFcjs.DEFAULT_GHOST; exports.DEFAULT_IMPASTO = _chunkQ33V5PEFcjs.DEFAULT_IMPASTO; exports.DEFAULT_IRIDESCENCE = _chunkQ33V5PEFcjs.DEFAULT_IRIDESCENCE; exports.DEFAULT_LIGHT = _chunkQ33V5PEFcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_LIVE_PATTERNS = _chunkIFWLZZCWcjs.DEFAULT_LIVE_PATTERNS; exports.DEFAULT_MULTI_COLOR = _chunkQ33V5PEFcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_MUTATION = _chunkQ33V5PEFcjs.DEFAULT_MUTATION; exports.DEFAULT_MUTATION_RATES = DEFAULT_MUTATION_RATES; exports.DEFAULT_PAINT_GRADIENT = _chunkIFWLZZCWcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkIFWLZZCWcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkOY24XRYFcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkQ33V5PEFcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkQ33V5PEFcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkQ33V5PEFcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_THERMOCHROMIC = _chunkQ33V5PEFcjs.DEFAULT_THERMOCHROMIC; exports.DEFAULT_TIP_GRAIN = _chunkQ33V5PEFcjs.DEFAULT_TIP_GRAIN; exports.DEFAULT_UV_LIGHT = DEFAULT_UV_LIGHT; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_VIEW_TILT = DEFAULT_VIEW_TILT; exports.DEFAULT_WET_BRUSH = _chunkQ33V5PEFcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkMITQGHN3cjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkQ33V5PEFcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkQ33V5PEFcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkOY24XRYFcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkOY24XRYFcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkOY24XRYFcjs.EFFECT_STRIP_HEIGHT; exports.EVOLUTION_BRUSH_FACETS = EVOLUTION_BRUSH_FACETS; exports.EVOLUTION_MUTATION_SCHEMA = EVOLUTION_MUTATION_SCHEMA; exports.EVOLUTION_SLIDERS = EVOLUTION_SLIDERS; exports.FilmBuffer = FilmBuffer; exports.GHOST_SLIDERS = _chunk5HR5CSLCcjs.GHOST_SLIDERS; exports.GHOST_TRIGGERS = _chunkQ33V5PEFcjs.GHOST_TRIGGERS; exports.GPU_LEAD = _chunkOY24XRYFcjs.GPU_LEAD; exports.GRAIN_PATTERNS = _chunkIFWLZZCWcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkIFWLZZCWcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.HEAT_COOLING = HEAT_COOLING; exports.HEAT_DIFFUSION = HEAT_DIFFUSION; exports.HEAT_DRY_THRESHOLD = HEAT_DRY_THRESHOLD; exports.HEAT_SCALE = HEAT_SCALE; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkOY24XRYFcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkQ33V5PEFcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.IRIDESCENCE_SLIDERS = _chunk5HR5CSLCcjs.IRIDESCENCE_SLIDERS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_PATTERN_KINDS = _chunkIFWLZZCWcjs.LIVE_PATTERN_KINDS; exports.LIVE_PATTERN_LABELS = LIVE_PATTERN_LABELS; exports.LIVE_PATTERN_PRESETS = _chunkIFWLZZCWcjs.LIVE_PATTERN_PRESETS; exports.LIVE_PATTERN_SCHEMA = LIVE_PATTERN_SCHEMA; exports.LIVE_PATTERN_SLIDERS = LIVE_PATTERN_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkIFWLZZCWcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkQ33V5PEFcjs.MAX_DOT_TEXTURES; exports.MAX_EFFECT_PATH_POINTS = _chunkOY24XRYFcjs.MAX_EFFECT_PATH_POINTS; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkQ33V5PEFcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkQ33V5PEFcjs.MULTI_COLOR_MODES; exports.MUTATION_SLIDERS = _chunk5HR5CSLCcjs.MUTATION_SLIDERS; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkQ33V5PEFcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkQ33V5PEFcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkIFWLZZCWcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkIFWLZZCWcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkIFWLZZCWcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkIFWLZZCWcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkIFWLZZCWcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkIFWLZZCWcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkIFWLZZCWcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkIFWLZZCWcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkIFWLZZCWcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkIFWLZZCWcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkIFWLZZCWcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkIFWLZZCWcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkOY24XRYFcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkOY24XRYFcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkQ33V5PEFcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkQ33V5PEFcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = _chunkOY24XRYFcjs.PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkIFWLZZCWcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkIFWLZZCWcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = _chunkOY24XRYFcjs.PaintWetLayers; exports.PaperGrain = _chunkIFWLZZCWcjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = _chunkOY24XRYFcjs.PenDabWalker; exports.PenSmoother = _chunkOY24XRYFcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkQ33V5PEFcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkRDFHWAHLcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunk3VHH6V67cjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TIP_GRAIN_MODES = _chunkQ33V5PEFcjs.TIP_GRAIN_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThermoCache = ThermoCache; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.TipGrain = _chunkOY24XRYFcjs.TipGrain; exports.UV_LIGHT_SLIDERS = UV_LIGHT_SLIDERS; exports.UvCache = UvCache; exports.VIEW_TILT_SLIDERS = VIEW_TILT_SLIDERS; exports.WET_FLOW_KINDS = _chunkMITQGHN3cjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = _chunkOY24XRYFcjs.WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkQ33V5PEFcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = _chunkOY24XRYFcjs.WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkMITQGHN3cjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkQ33V5PEFcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = _chunkOY24XRYFcjs.WetStrokeDriver; exports.addPaintGradientStop = _chunkIFWLZZCWcjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.advanceHeatField = advanceHeatField; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunk5HR5CSLCcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkQ33V5PEFcjs.brushTakesPaint; exports.brushToJSON = _chunkQ33V5PEFcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkEvolutionStrokes = checkEvolutionStrokes; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clearHeatField = clearHeatField; exports.cloneHeatField = cloneHeatField; exports.clonePaper = _chunkOY24XRYFcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.computeUvSpill = computeUvSpill; exports.contactSheet = contactSheet; exports.createEvolutionTools = createEvolutionTools; exports.createHeatField = createHeatField; exports.createMutationTools = createMutationTools; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintConformanceHost = createPaintConformanceHost; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintEvolutionToolProvider = createPaintEvolutionToolProvider; exports.createPaintEvolutionTools = createPaintEvolutionTools; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.crossoverBrushes = crossoverBrushes; exports.crossoverGenomes = crossoverGenomes; exports.crossoverStrokes = crossoverStrokes; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.describeGenomeDiff = describeGenomeDiff; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.deviceOrientationToViewTilt = deviceOrientationToViewTilt; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.driftBrushFacets = driftBrushFacets; exports.driftColorOklch = driftColorOklch; exports.effectDabField = _chunkOY24XRYFcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkOY24XRYFcjs.effectPaintKey; exports.effectPaintSize = _chunkOY24XRYFcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyFluor = emptyFluor; exports.emptyThermo = emptyThermo; exports.emptyThickChannels = emptyThickChannels; exports.engineBrushSourceIds = engineBrushSourceIds; exports.exportProposalContactSheetPng = exportProposalContactSheetPng; exports.fillRegionMask = _chunkYH6SKC7Pcjs.fillRegionMask; exports.finalizeThermoStroke = finalizeThermoStroke; exports.findUnfilledRegionsMask = _chunkYH6SKC7Pcjs.findUnfilledRegionsMask; exports.fitZoom = fitZoom; exports.fluorFromJSON = fluorFromJSON; exports.fluorToJSON = fluorToJSON; exports.fluorTwinBrush = fluorTwinBrush; exports.grainCatch = _chunkIFWLZZCWcjs.grainCatch; exports.grainHeights = _chunkIFWLZZCWcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hasThickChannels = hasThickChannels; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.heatFromJSON = heatFromJSON; exports.heatStats = heatStats; exports.heatToJSON = heatToJSON; exports.hexToPaintRgb = _chunkIFWLZZCWcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkOY24XRYFcjs.hexToRgb8; exports.hotCellsBounds = hotCellsBounds; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.inferEffectPathControl = _chunkOY24XRYFcjs.inferEffectPathControl; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkIFWLZZCWcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkOY24XRYFcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkQ33V5PEFcjs.isWetBrush; exports.isWetCapable = _chunkQ33V5PEFcjs.isWetCapable; exports.jitterStrokePoints = jitterStrokePoints; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mergeFourChannel = mergeFourChannel; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixColorOklch = mixColorOklch; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkOY24XRYFcjs.mixerTip; exports.multiColorForDab = _chunkOY24XRYFcjs.multiColorForDab; exports.multiColorGradient = _chunkOY24XRYFcjs.multiColorGradient; exports.multiColorPalette = _chunkOY24XRYFcjs.multiColorPalette; exports.multiColorSliders = _chunk5HR5CSLCcjs.multiColorSliders; exports.multiColorToPaint = _chunkQ33V5PEFcjs.multiColorToPaint; exports.mutateGenome = mutateGenome; exports.mutateStroke = mutateStroke; exports.mutationBrushRefusal = mutationBrushRefusal; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkQ33V5PEFcjs.normalizeBehavior; exports.normalizeBristle = _chunkQ33V5PEFcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkQ33V5PEFcjs.normalizeDynamics; exports.normalizeFlow = _chunkMITQGHN3cjs.normalizeFlow; exports.normalizeFluorescence = _chunkQ33V5PEFcjs.normalizeFluorescence; exports.normalizeGhost = _chunkQ33V5PEFcjs.normalizeGhost; exports.normalizeHexColor = _chunkIFWLZZCWcjs.normalizeHexColor; exports.normalizeImpasto = _chunkQ33V5PEFcjs.normalizeImpasto; exports.normalizeLight = _chunkQ33V5PEFcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeLivePatterns = _chunkIFWLZZCWcjs.normalizeLivePatterns; exports.normalizeMultiColor = _chunkQ33V5PEFcjs.normalizeMultiColor; exports.normalizeMutation = _chunkQ33V5PEFcjs.normalizeMutation; exports.normalizeMutationRates = normalizeMutationRates; exports.normalizePaintBrush = _chunkQ33V5PEFcjs.normalizePaintBrush; exports.normalizePaper = _chunkOY24XRYFcjs.normalizePaper; exports.normalizeParticle = _chunkQ33V5PEFcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkQ33V5PEFcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeThermochromic = _chunkQ33V5PEFcjs.normalizeThermochromic; exports.normalizeUvLight = normalizeUvLight; exports.normalizeView = normalizeView; exports.normalizeViewTilt = normalizeViewTilt; exports.normalizeWetBrush = _chunkQ33V5PEFcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkMITQGHN3cjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintBrushPreviewRenderer = paintBrushPreviewRenderer; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkIFWLZZCWcjs.paintGradientMappingFor; exports.paintHeatField = paintHeatField; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkIFWLZZCWcjs.paintSourceColor; exports.paintSourceCss = _chunkIFWLZZCWcjs.paintSourceCss; exports.paintToMultiColor = _chunkQ33V5PEFcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkOY24XRYFcjs.paperPreset; exports.parseBrushLibrary = _chunkQ33V5PEFcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkIFWLZZCWcjs.parsePaintSource; exports.patchBrushValue = _chunk5HR5CSLCcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkOY24XRYFcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.proposalGenomeStrokes = proposalGenomeStrokes; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = _chunkOY24XRYFcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkOY24XRYFcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkIFWLZZCWcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkIFWLZZCWcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkOY24XRYFcjs.renderPaper; exports.renderProposalContactSheet = renderProposalContactSheet; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.requestDeviceTiltPermission = requestDeviceTiltPermission; exports.rerollStrokeSeed = rerollStrokeSeed; exports.resampleStrokePoints = resampleStrokePoints; exports.resolvePaintGradient = _chunkIFWLZZCWcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkIFWLZZCWcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = _chunkOY24XRYFcjs.sampleEffectAt; exports.sampleEffectField = _chunkOY24XRYFcjs.sampleEffectField; exports.sampleHeatAt = sampleHeatAt; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scaleFluor = scaleFluor; exports.scalePaintGradient = _chunkIFWLZZCWcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.seededStrokeVariation = seededStrokeVariation; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.shiftHeatField = shiftHeatField; exports.solidPaint = _chunkIFWLZZCWcjs.solidPaint; exports.squaredDistanceTransform = _chunkYH6SKC7Pcjs.squaredDistanceTransform; exports.stampCoverage = _chunkRDFHWAHLcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startDeviceTilt = startDeviceTilt; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokePathPoints = _chunkOY24XRYFcjs.strokePathPoints; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thermoFromJSON = thermoFromJSON; exports.thermoToJSON = thermoToJSON; exports.thermoTwinBrush = thermoTwinBrush; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thinFilmRgb = thinFilmRgb; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkOY24XRYFcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkOY24XRYFcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkIFWLZZCWcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkQ33V5PEFcjs.usesPaintExchange; exports.uvLightKey = uvLightKey; exports.uvPaper = uvPaper; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.viewTiltKey = viewTiltKey; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = _chunkOY24XRYFcjs.wetPaperInput; exports.wetPigmentOf = _chunkOY24XRYFcjs.wetPigmentOf; exports.wetSupport = _chunkMITQGHN3cjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback; exports.withStrokePath = _chunkOY24XRYFcjs.withStrokePath;