@pixerate/editor 0.267.0 → 0.268.1

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 (83) 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 +198 -72
  4. package/dist/brushes/index.d.cts +4 -3
  5. package/dist/brushes/index.d.ts +4 -3
  6. package/dist/brushes/index.js +136 -10
  7. package/dist/brushes/library.d.cts +27 -1
  8. package/dist/brushes/library.d.ts +27 -1
  9. package/dist/brushes/profiles.d.cts +4 -0
  10. package/dist/brushes/profiles.d.ts +4 -0
  11. package/dist/brushes/schema.d.cts +4 -0
  12. package/dist/brushes/schema.d.ts +4 -0
  13. package/dist/brushes/sources.d.cts +114 -0
  14. package/dist/brushes/sources.d.ts +114 -0
  15. package/dist/brushes/types.d.cts +37 -5
  16. package/dist/brushes/types.d.ts +37 -5
  17. package/dist/brushes/ui.d.cts +40 -4
  18. package/dist/brushes/ui.d.ts +40 -4
  19. package/dist/{brushstrokeRender-NLFPEBGI.js → brushstrokeRender-A727TTNQ.js} +6 -6
  20. package/dist/{brushstrokeRender-L7JYRR2R.cjs → brushstrokeRender-WR2N5HHY.cjs} +22 -22
  21. package/dist/canvas/index.cjs +13 -13
  22. package/dist/canvas/index.js +1 -1
  23. package/dist/{chunk-J2TNIZ55.cjs → chunk-2WOGXEDX.cjs} +1 -1
  24. package/dist/{chunk-JGWVZPT6.js → chunk-3XDSNIGF.js} +72 -5
  25. package/dist/{chunk-EXB2EGBE.cjs → chunk-62MFUHSI.cjs} +16 -16
  26. package/dist/{chunk-GCVFEPJG.js → chunk-ACTHSQOI.js} +182 -0
  27. package/dist/{chunk-EF7LZAXQ.js → chunk-BAZMCFVL.js} +1 -1
  28. package/dist/{chunk-HIO6E7LC.cjs → chunk-BPJSI4NT.cjs} +2 -2
  29. package/dist/{chunk-XVOP3CGQ.cjs → chunk-EU2ZZA6L.cjs} +393 -62
  30. package/dist/{chunk-YIC6MAJ2.js → chunk-HFY5LG5J.js} +1 -1
  31. package/dist/{chunk-7UKFXXWL.js → chunk-HVO6XCI4.js} +1 -1
  32. package/dist/{chunk-LHPEG5AU.cjs → chunk-J4GXP53R.cjs} +140 -91
  33. package/dist/{chunk-OKHKA43L.cjs → chunk-JBB3GDBB.cjs} +330 -216
  34. package/dist/{chunk-AGNUD5BI.js → chunk-KZI3YWKW.js} +351 -20
  35. package/dist/{chunk-FGJHJIMN.js → chunk-LDOD7VCT.js} +59 -10
  36. package/dist/{chunk-EYSHTYLG.js → chunk-LETF75CA.js} +1 -1
  37. package/dist/{chunk-FQPUF2W2.cjs → chunk-NIBFKXMD.cjs} +217 -35
  38. package/dist/{chunk-G7NHE2VD.cjs → chunk-NPWWSCWT.cjs} +35 -35
  39. package/dist/{chunk-OSEXT7JL.js → chunk-QNY7BDFP.js} +1 -1
  40. package/dist/{chunk-PXDIAYB6.cjs → chunk-STLTOISW.cjs} +34 -214
  41. package/dist/{chunk-4IDUYB45.js → chunk-UVTO3D4E.js} +130 -16
  42. package/dist/{chunk-TXFWZ5ZJ.js → chunk-W6JDUXP3.js} +4 -184
  43. package/dist/{chunk-LA5Y4ETA.cjs → chunk-YOVXQHA3.cjs} +23 -23
  44. package/dist/{chunk-DT4YQUGT.cjs → chunk-YXP6X3SY.cjs} +101 -34
  45. package/dist/image-editor/adjustment-layers.d.cts +8 -0
  46. package/dist/image-editor/adjustment-layers.d.ts +8 -0
  47. package/dist/image-editor/index.cjs +857 -853
  48. package/dist/image-editor/index.js +30 -26
  49. package/dist/paint/index.cjs +5 -5
  50. package/dist/paint/index.js +11 -11
  51. package/dist/paint-editor/brush-library-tools.d.cts +12 -2
  52. package/dist/paint-editor/brush-library-tools.d.ts +12 -2
  53. package/dist/paint-editor/brush-model.d.cts +29 -1
  54. package/dist/paint-editor/brush-model.d.ts +29 -1
  55. package/dist/paint-editor/brush-source-art.d.cts +32 -0
  56. package/dist/paint-editor/brush-source-art.d.ts +32 -0
  57. package/dist/paint-editor/controller.d.cts +6 -1
  58. package/dist/paint-editor/controller.d.ts +6 -1
  59. package/dist/paint-editor/dab-stroke.d.cts +2 -0
  60. package/dist/paint-editor/dab-stroke.d.ts +2 -0
  61. package/dist/paint-editor/engine.d.cts +11 -2
  62. package/dist/paint-editor/engine.d.ts +11 -2
  63. package/dist/paint-editor/index.cjs +576 -481
  64. package/dist/paint-editor/index.d.cts +3 -1
  65. package/dist/paint-editor/index.d.ts +3 -1
  66. package/dist/paint-editor/index.js +127 -32
  67. package/dist/paint-editor/stamp-tip.d.cts +8 -5
  68. package/dist/paint-editor/stamp-tip.d.ts +8 -5
  69. package/dist/paint-editor/thumbnails.d.cts +6 -0
  70. package/dist/paint-editor/thumbnails.d.ts +6 -0
  71. package/dist/paint-editor/tip-grain.d.cts +34 -0
  72. package/dist/paint-editor/tip-grain.d.ts +34 -0
  73. package/dist/raster/index.cjs +2 -2
  74. package/dist/raster/index.js +9 -9
  75. package/dist/vector/index.cjs +1002 -1002
  76. package/dist/vector/index.js +7 -7
  77. package/package.json +110 -1
  78. package/skills/pixerate-brushes/SKILL.md +35 -8
  79. package/skills/pixerate-brushes-design/SKILL.md +8 -1
  80. package/skills/pixerate-image-editor/SKILL.md +1 -1
  81. package/skills/pixerate-paint-editor/SKILL.md +6 -0
  82. package/skills/pixerate-paint-editor/references/brush-facets.md +3 -1
  83. package/skills/pixerate-paint-sketch-to-finish/SKILL.md +1 -0
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16;
2
2
 
3
3
 
4
4
  var _chunk3VHH6V67cjs = require('../chunk-3VHH6V67.cjs');
@@ -11,7 +11,7 @@ var _chunk3VHH6V67cjs = require('../chunk-3VHH6V67.cjs');
11
11
 
12
12
 
13
13
 
14
- var _chunkDT4YQUGTcjs = require('../chunk-DT4YQUGT.cjs');
14
+ var _chunkYXP6X3SYcjs = require('../chunk-YXP6X3SY.cjs');
15
15
 
16
16
 
17
17
 
@@ -19,7 +19,7 @@ var _chunkPFHJS4HEcjs = require('../chunk-PFHJS4HE.cjs');
19
19
 
20
20
 
21
21
 
22
- var _chunkHIO6E7LCcjs = require('../chunk-HIO6E7LC.cjs');
22
+ var _chunkBPJSI4NTcjs = require('../chunk-BPJSI4NT.cjs');
23
23
 
24
24
 
25
25
  var _chunkCBVNCWJMcjs = require('../chunk-CBVNCWJM.cjs');
@@ -34,7 +34,7 @@ var _chunk7TD63DZPcjs = require('../chunk-7TD63DZP.cjs');
34
34
 
35
35
 
36
36
 
37
- var _chunkLHPEG5AUcjs = require('../chunk-LHPEG5AU.cjs');
37
+ var _chunkJ4GXP53Rcjs = require('../chunk-J4GXP53R.cjs');
38
38
  require('../chunk-YZWM6ZIP.cjs');
39
39
  require('../chunk-3ZRNK3RO.cjs');
40
40
 
@@ -60,7 +60,7 @@ require('../chunk-K6PXS6DO.cjs');
60
60
 
61
61
 
62
62
 
63
- var _chunkEXB2EGBEcjs = require('../chunk-EXB2EGBE.cjs');
63
+ var _chunk62MFUHSIcjs = require('../chunk-62MFUHSI.cjs');
64
64
  require('../chunk-BB6TR422.cjs');
65
65
  require('../chunk-BROJYMWU.cjs');
66
66
 
@@ -112,8 +112,8 @@ var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
112
112
 
113
113
 
114
114
 
115
- var _chunkOKHKA43Lcjs = require('../chunk-OKHKA43L.cjs');
116
115
 
116
+ var _chunkJBB3GDBBcjs = require('../chunk-JBB3GDBB.cjs');
117
117
 
118
118
 
119
119
 
@@ -167,7 +167,16 @@ var _chunkOKHKA43Lcjs = require('../chunk-OKHKA43L.cjs');
167
167
 
168
168
 
169
169
 
170
- var _chunkXVOP3CGQcjs = require('../chunk-XVOP3CGQ.cjs');
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+ var _chunkEU2ZZA6Lcjs = require('../chunk-EU2ZZA6L.cjs');
171
180
 
172
181
 
173
182
 
@@ -215,13 +224,13 @@ require('../chunk-WOFXZ3XU.cjs');
215
224
 
216
225
 
217
226
  var _chunkJ5VQYK7Tcjs = require('../chunk-J5VQYK7T.cjs');
227
+ require('../chunk-STLTOISW.cjs');
218
228
 
219
229
 
220
230
 
221
231
 
222
232
 
223
233
 
224
- var _chunkPXDIAYB6cjs = require('../chunk-PXDIAYB6.cjs');
225
234
 
226
235
 
227
236
 
@@ -266,8 +275,7 @@ var _chunkPXDIAYB6cjs = require('../chunk-PXDIAYB6.cjs');
266
275
 
267
276
 
268
277
 
269
-
270
- var _chunkFQPUF2W2cjs = require('../chunk-FQPUF2W2.cjs');
278
+ var _chunkNIBFKXMDcjs = require('../chunk-NIBFKXMD.cjs');
271
279
 
272
280
 
273
281
 
@@ -284,8 +292,8 @@ require('../chunk-YQGCPL5X.cjs');
284
292
 
285
293
 
286
294
 
295
+ var _chunk2VX55NFMcjs = require('../chunk-2VX55NFM.cjs');
287
296
 
288
- var _chunkW5M3J7PVcjs = require('../chunk-W5M3J7PV.cjs');
289
297
 
290
298
 
291
299
 
@@ -293,7 +301,7 @@ var _chunkW5M3J7PVcjs = require('../chunk-W5M3J7PV.cjs');
293
301
 
294
302
 
295
303
 
296
- var _chunk2VX55NFMcjs = require('../chunk-2VX55NFM.cjs');
304
+ var _chunkW5M3J7PVcjs = require('../chunk-W5M3J7PV.cjs');
297
305
 
298
306
 
299
307
 
@@ -372,7 +380,7 @@ function normalizeCanvas(raw) {
372
380
  function createPaintDocument(options = {}) {
373
381
  const canvas = normalizeCanvas({ width: _nullishCoalesce(options.width, () => ( 2048)), height: _nullishCoalesce(options.height, () => ( 1536)), dpi: options.dpi });
374
382
  const layer = createPaintLayer("Layer 1");
375
- return { canvas, paper: _chunkOKHKA43Lcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
383
+ return { canvas, paper: _chunkJBB3GDBBcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
376
384
  }
377
385
 
378
386
  // src/paint-editor/thick.ts
@@ -503,19 +511,19 @@ var ThickStrokeDriver = (_class2 = class {
503
511
  constructor(init) {;_class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);
504
512
  this.init = init;
505
513
  const b = init.brush;
506
- this.smoother = new (0, _chunkOKHKA43Lcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
507
- const copies = init.copies.length ? init.copies : [_chunkOKHKA43Lcjs.IDENTITY_COPY];
514
+ this.smoother = new (0, _chunkJBB3GDBBcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
515
+ const copies = init.copies.length ? init.copies : [_chunkJBB3GDBBcjs.IDENTITY_COPY];
508
516
  this.copies = copies;
509
- const rates = _chunkFQPUF2W2cjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
517
+ const rates = _chunkNIBFKXMDcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
510
518
  this.states = copies.map((c, i) => ({
511
- walker: new (0, _chunkOKHKA43Lcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
512
- exchange: new (0, _chunkFQPUF2W2cjs.PaintExchange)(rates, init.load),
513
- smudge: b.impasto.tool === "knife" ? new (0, _chunkFQPUF2W2cjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
519
+ walker: new (0, _chunkJBB3GDBBcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
520
+ exchange: new (0, _chunkNIBFKXMDcjs.PaintExchange)(rates, init.load),
521
+ 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,
514
522
  carried: null,
515
523
  amount: 1
516
524
  }));
517
- this.medium = new (0, _chunkFQPUF2W2cjs.TileMedium)(init.target, {});
518
- this.sampler = init.paint ? new (0, _chunkFQPUF2W2cjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
525
+ this.medium = new (0, _chunkNIBFKXMDcjs.TileMedium)(init.target, {});
526
+ 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;
519
527
  }
520
528
 
521
529
  __init2() {this.dabCount = 0}
@@ -612,7 +620,7 @@ var ThickStrokeDriver = (_class2 = class {
612
620
  }
613
621
  applyDabs(copy, dabs, rects) {
614
622
  for (const d of dabs) {
615
- const rect = _chunkFQPUF2W2cjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
623
+ const rect = _chunkNIBFKXMDcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
616
624
  if (rect.width <= 0 || rect.height <= 0) continue;
617
625
  this.dab(copy, d, rect);
618
626
  rects.push(rect);
@@ -627,7 +635,7 @@ var ThickStrokeDriver = (_class2 = class {
627
635
  const n = rect.width * rect.height;
628
636
  if (this.tip.length < n) this.tip = new Float32Array(n);
629
637
  const tip = this.tip.subarray(0, n);
630
- _chunkFQPUF2W2cjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
638
+ _chunkNIBFKXMDcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
631
639
  const sel = this.init.target.selection;
632
640
  if (sel) {
633
641
  for (let yy = 0, p = 0; yy < rect.height; yy++)
@@ -654,7 +662,7 @@ var ThickStrokeDriver = (_class2 = class {
654
662
  let flow = 1;
655
663
  const effect = this.init.effect;
656
664
  if (effect) {
657
- _chunkOKHKA43Lcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
665
+ _chunkJBB3GDBBcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
658
666
  ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
659
667
  } else if (this.sampler) {
660
668
  const g = this.sampler.dab(d, this.sample);
@@ -671,7 +679,7 @@ var ThickStrokeDriver = (_class2 = class {
671
679
  let field = null;
672
680
  if (effect) {
673
681
  field = new Float32Array(n * 3);
674
- _chunkOKHKA43Lcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
682
+ _chunkJBB3GDBBcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
675
683
  }
676
684
  this.medium.deposit(rect, cov, dep, this.paint, ex.paintPigment, field);
677
685
  }
@@ -848,7 +856,7 @@ function shadowToLight(shadow) {
848
856
  return new (0, _chunk474IQG74cjs.TiledSurface)(1, tiles, 0);
849
857
  }
850
858
  function lightTwinBrush(brush) {
851
- return _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0,
859
+ return _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0,
852
860
  {
853
861
  tip: { ...brush.tip, blend: "normal", pressureOpacity: brush.tip.pressureOpacity || brush.light.pressure },
854
862
  behavior: { ...brush.behavior, mixing: "rgb" },
@@ -1058,18 +1066,18 @@ var MarkStroke = (_class4 = class {
1058
1066
  constructor(brush, options) {;_class4.prototype.__init14.call(this);_class4.prototype.__init15.call(this);_class4.prototype.__init16.call(this);_class4.prototype.__init17.call(this);_class4.prototype.__init18.call(this);_class4.prototype.__init19.call(this);_class4.prototype.__init20.call(this);_class4.prototype.__init21.call(this);
1059
1067
  this.brush = brush;
1060
1068
  this.options = options;
1061
- this.sampler = options.paint ? new (0, _chunkFQPUF2W2cjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
1062
- this.tipTable = _optionalChain([this, 'access', _29 => _29.sampler, 'optionalAccess', _30 => _30.acrossTip]) ? this.sampler.tipTable(_chunkFQPUF2W2cjs.TIP_GRADIENT_STEPS) : null;
1063
- this.smoother = new (0, _chunkOKHKA43Lcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
1064
- this.copies = _optionalChain([options, 'access', _31 => _31.copies, 'optionalAccess', _32 => _32.length]) ? options.copies : [_chunkOKHKA43Lcjs.IDENTITY_COPY];
1069
+ this.sampler = options.paint ? new (0, _chunkNIBFKXMDcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
1070
+ this.tipTable = _optionalChain([this, 'access', _29 => _29.sampler, 'optionalAccess', _30 => _30.acrossTip]) ? this.sampler.tipTable(_chunkNIBFKXMDcjs.TIP_GRADIENT_STEPS) : null;
1071
+ this.smoother = new (0, _chunkJBB3GDBBcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
1072
+ this.copies = _optionalChain([options, 'access', _31 => _31.copies, 'optionalAccess', _32 => _32.length]) ? options.copies : [_chunkJBB3GDBBcjs.IDENTITY_COPY];
1065
1073
  this.seed = _nullishCoalesce(options.seed, () => ( 0));
1066
1074
  const fine = { ...brush, tip: { ...brush.tip, spacing: Math.max(0.01, Math.min(0.25, STEP_PX / Math.max(1, brush.tip.size))) } };
1067
- this.walkers = this.copies.map((c, i) => new (0, _chunkOKHKA43Lcjs.PenDabWalker)(fine, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear));
1075
+ this.walkers = this.copies.map((c, i) => new (0, _chunkJBB3GDBBcjs.PenDabWalker)(fine, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear));
1068
1076
  this.depth = options.grain && !options.grain.flat ? Math.min(1, Math.max(0, options.paperDepth * brush.grain)) : 0;
1069
1077
  }
1070
1078
 
1071
1079
 
1072
- __init14() {this.coverage = new (0, _chunkFQPUF2W2cjs.CoverageMap)()}
1080
+ __init14() {this.coverage = new (0, _chunkNIBFKXMDcjs.CoverageMap)()}
1073
1081
  __init15() {this.dabCount = 0}
1074
1082
 
1075
1083
 
@@ -1130,11 +1138,11 @@ var MarkStroke = (_class4 = class {
1130
1138
  if (!(r > 0.05) || !(alpha > 0)) return;
1131
1139
  const dab = { x, y, radius: Math.max(0.5, r), alpha: Math.min(1, alpha), opacity: Math.min(1, opacity), angle: 0, roundness: 1 };
1132
1140
  const hardness = this.brush.tip.hardness;
1133
- const rect = _chunkFQPUF2W2cjs.dabRect.call(void 0, dab, hardness);
1141
+ const rect = _chunkNIBFKXMDcjs.dabRect.call(void 0, dab, hardness);
1134
1142
  const n = rect.width * rect.height;
1135
1143
  if (n <= 0) return;
1136
1144
  const vals = this.scratch(n);
1137
- _chunkFQPUF2W2cjs.rasterizeDab.call(void 0, dab, hardness, rect, vals);
1145
+ _chunkNIBFKXMDcjs.rasterizeDab.call(void 0, dab, hardness, rect, vals);
1138
1146
  this.lay(rect, vals, dab.opacity, pressure, x, y, rects);
1139
1147
  }
1140
1148
  /**
@@ -1143,7 +1151,7 @@ var MarkStroke = (_class4 = class {
1143
1151
  */
1144
1152
  stamp(x, y, r, kind, rotation, seed, alpha, opacity, pressure, rects) {
1145
1153
  if (!(r > 0.05) || !(alpha > 0)) return;
1146
- const sample = _chunkOKHKA43Lcjs.stampSampler.call(void 0, kind, this.options.stampArt);
1154
+ const sample = _chunkJBB3GDBBcjs.stampSampler.call(void 0, kind, this.options.stampArt);
1147
1155
  if (!sample) return this.mark(x, y, r, alpha, opacity, pressure, rects);
1148
1156
  const reach = Math.max(0.5, r) * Math.SQRT2 + 1;
1149
1157
  const rect = { x: Math.floor(x - reach), y: Math.floor(y - reach), width: 0, height: 0 };
@@ -1188,12 +1196,12 @@ var MarkStroke = (_class4 = class {
1188
1196
  const grain = this.options.grain;
1189
1197
  if (this.depth > 0 && grain) {
1190
1198
  for (let yy = 0, k = 0; yy < rect.height; yy++)
1191
- for (let xx = 0; xx < rect.width; xx++, k++) if (vals[k] > 0) vals[k] *= _chunkPXDIAYB6cjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, pressure);
1199
+ 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);
1192
1200
  }
1193
1201
  if (this.options.effect) {
1194
1202
  if (this.field.length < n * 3) this.field = new Float32Array(n * 3);
1195
1203
  const field = this.field.subarray(0, n * 3);
1196
- _chunkOKHKA43Lcjs.sampleEffectField.call(void 0, this.options.effect, rect, vals, field, this.pen);
1204
+ _chunkJBB3GDBBcjs.sampleEffectField.call(void 0, this.options.effect, rect, vals, field, this.pen);
1197
1205
  this.coverage.accumulate(rect, vals, opacity, null, field);
1198
1206
  } else {
1199
1207
  const color = this.markColor(x, y);
@@ -1872,12 +1880,12 @@ var StickerSpray = (_class7 = class {
1872
1880
  constructor(init) {;_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);
1873
1881
  this.init = init;
1874
1882
  const b = init.brush;
1875
- this.smoother = new (0, _chunkOKHKA43Lcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
1876
- this.copies = init.copies.length ? init.copies : [_chunkOKHKA43Lcjs.IDENTITY_COPY];
1883
+ this.smoother = new (0, _chunkJBB3GDBBcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
1884
+ this.copies = init.copies.length ? init.copies : [_chunkJBB3GDBBcjs.IDENTITY_COPY];
1877
1885
  const spacing = Math.max(0.05, 1 / Math.max(0.05, b.sticker.density * 4));
1878
1886
  const walk = { ...b, tip: { ...b.tip, spacing }, dynamics: { ...b.dynamics, scatter: 0, sizeJitter: 0, angleJitter: 0 } };
1879
- this.walkers = this.copies.map((c, i) => new (0, _chunkOKHKA43Lcjs.PenDabWalker)(walk, init.seed + i * 7919 | 0, c.linear));
1880
- this.medium = new (0, _chunkFQPUF2W2cjs.TileMedium)(init.target, {});
1887
+ this.walkers = this.copies.map((c, i) => new (0, _chunkJBB3GDBBcjs.PenDabWalker)(walk, init.seed + i * 7919 | 0, c.linear));
1888
+ this.medium = new (0, _chunkNIBFKXMDcjs.TileMedium)(init.target, {});
1881
1889
  this.next = init.nextId;
1882
1890
  }
1883
1891
 
@@ -1962,18 +1970,18 @@ var StickerSpray = (_class7 = class {
1962
1970
  const effect = this.init.effect;
1963
1971
  if (effect) {
1964
1972
  const rgb = [0, 0, 0];
1965
- const alpha = _chunkOKHKA43Lcjs.sampleEffectAt.call(void 0, effect, d.x + dx, d.y + dy, rgb, d);
1973
+ const alpha = _chunkJBB3GDBBcjs.sampleEffectAt.call(void 0, effect, d.x + dx, d.y + dy, rgb, d);
1966
1974
  return { color: "#" + rgb.map((c) => Math.round(c * 255).toString(16).padStart(2, "0")).join(""), alpha };
1967
1975
  }
1968
1976
  const g = this.init.paint;
1969
1977
  if (!g) return { color: this.init.color, alpha: 1 };
1970
- this.sampler ??= new (0, _chunkFQPUF2W2cjs.PaintGradientSampler)(g, this.init.seed);
1978
+ this.sampler ??= new (0, _chunkNIBFKXMDcjs.PaintGradientSampler)(g, this.init.seed);
1971
1979
  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);
1972
1980
  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 };
1973
1981
  }
1974
1982
  }, _class7);
1975
1983
  function renderStickers(stickers, target, art) {
1976
- const medium = new (0, _chunkFQPUF2W2cjs.TileMedium)(target, {});
1984
+ const medium = new (0, _chunkNIBFKXMDcjs.TileMedium)(target, {});
1977
1985
  for (const s of stickers) drawSticker(medium, s, art);
1978
1986
  }
1979
1987
  function normalizeStickerUpdate(u) {
@@ -2091,7 +2099,7 @@ var PaintStrokeSession = (_class8 = class _PaintStrokeSession {
2091
2099
  this.layerId = init.layerId;
2092
2100
  this.base = init.surface;
2093
2101
  this.live = new Map(this.base.tiles);
2094
- this.copies = init.copies.length ? init.copies : [_chunkOKHKA43Lcjs.IDENTITY_COPY];
2102
+ this.copies = init.copies.length ? init.copies : [_chunkJBB3GDBBcjs.IDENTITY_COPY];
2095
2103
  const brush = init.brush;
2096
2104
  if (init.wet) this.wetDriver = init.wet.driver;
2097
2105
  if (init.light && !init.wet && !init.sticker) this.lightTwin = this.makeLightTwin(init.light.surface);
@@ -2112,9 +2120,9 @@ var PaintStrokeSession = (_class8 = class _PaintStrokeSession {
2112
2120
  } else if (init.thick) {
2113
2121
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
2114
2122
  this.thickDriver = new ThickStrokeDriver({ brush, target: this.tileTarget(), channels: init.thick.channels, color: rgb(init.color), load: init.mixerLoad, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
2115
- } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkXVOP3CGQcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
2123
+ } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkEU2ZZA6Lcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
2116
2124
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
2117
- this.wet = new (0, _chunkOKHKA43Lcjs.PaintDabStroke)(brush, {
2125
+ this.wet = new (0, _chunkJBB3GDBBcjs.PaintDabStroke)(brush, {
2118
2126
  target: this.tileTarget(),
2119
2127
  color: rgb(init.color),
2120
2128
  secondary: rgb(_nullishCoalesce(init.secondary, () => ( init.background))),
@@ -2129,7 +2137,7 @@ var PaintStrokeSession = (_class8 = class _PaintStrokeSession {
2129
2137
  });
2130
2138
  } else {
2131
2139
  const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect, stampArt: init.stampArt };
2132
- this.dry = brush.engine === "particle" ? new ParticleStroke(brush, opts) : brush.engine === "bristle" ? new BristleStroke(brush, opts) : new (0, _chunkOKHKA43Lcjs.DryStroke)(brush, opts);
2140
+ this.dry = brush.engine === "particle" ? new ParticleStroke(brush, opts) : brush.engine === "bristle" ? new BristleStroke(brush, opts) : new (0, _chunkJBB3GDBBcjs.DryStroke)(brush, opts);
2133
2141
  }
2134
2142
  }
2135
2143
 
@@ -2259,7 +2267,7 @@ var PaintStrokeSession = (_class8 = class _PaintStrokeSession {
2259
2267
  const changed = d.dabCount > 0;
2260
2268
  this.result = { layerId: this.layerId, bounds: changed ? d.bounds : null, dabs: d.dabCount, strokeId: null, wet: true };
2261
2269
  const carried = d.load;
2262
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkFQPUF2W2cjs.cleanMixer.call(void 0, carried);
2270
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkNIBFKXMDcjs.cleanMixer.call(void 0, carried);
2263
2271
  this.host.commit(this, changed ? this.init.wet.surface() : null, false);
2264
2272
  }
2265
2273
  update(rects) {
@@ -2285,7 +2293,7 @@ var PaintStrokeSession = (_class8 = class _PaintStrokeSession {
2285
2293
  const src = _nullishCoalesce(_optionalChain([this, 'access', _70 => _70.base, 'access', _71 => _71.tiles, 'access', _72 => _72.get, 'call', _73 => _73(key), 'optionalAccess', _74 => _74.data]), () => ( defaultTile(this.base)));
2286
2294
  const prev = this.touched.has(key) ? _optionalChain([this, 'access', _75 => _75.live, 'access', _76 => _76.get, 'call', _77 => _77(key), 'optionalAccess', _78 => _78.data]) : void 0;
2287
2295
  this.touched.add(key);
2288
- const data = _chunkFQPUF2W2cjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
2296
+ const data = _chunkNIBFKXMDcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
2289
2297
  this.live.set(key, { data, uniform: null });
2290
2298
  }
2291
2299
  this.host.update(this.layerId, new (0, _chunk474IQG74cjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
@@ -2322,7 +2330,7 @@ var PaintStrokeSession = (_class8 = class _PaintStrokeSession {
2322
2330
  this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };
2323
2331
  if (_optionalChain([this, 'access', _81 => _81.stickerSpray, 'optionalAccess', _82 => _82.skipped, 'access', _83 => _83.size])) this.result.skippedStickers = [...this.stickerSpray.skipped];
2324
2332
  const carried = _nullishCoalesce(_optionalChain([this, 'access', _84 => _84.wet, 'optionalAccess', _85 => _85.load]), () => ( _optionalChain([this, 'access', _86 => _86.thickDriver, 'optionalAccess', _87 => _87.load])));
2325
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkFQPUF2W2cjs.cleanMixer.call(void 0, carried);
2333
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkNIBFKXMDcjs.cleanMixer.call(void 0, carried);
2326
2334
  this.host.commit(this, surface, false);
2327
2335
  return this.result;
2328
2336
  }
@@ -2345,15 +2353,15 @@ function greyPixels(data, grey) {
2345
2353
  }
2346
2354
  function mixerLoadForStroke(brush, current, color) {
2347
2355
  if (!brush.loadsColor) return { reservoir: null, amount: 0, pickup: brush.mixer.cleanEachStroke ? null : current.pickup };
2348
- if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkFQPUF2W2cjs.loadMixer.call(void 0, current, color);
2356
+ if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkNIBFKXMDcjs.loadMixer.call(void 0, current, color);
2349
2357
  return current;
2350
2358
  }
2351
2359
  function brushLoadForStroke(brush, current, color) {
2352
2360
  if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
2353
2361
  if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
2354
- 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 } : _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD;
2355
- if (_chunkXVOP3CGQcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
2356
- return _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD;
2362
+ 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;
2363
+ if (_chunkEU2ZZA6Lcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
2364
+ return _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD;
2357
2365
  }
2358
2366
 
2359
2367
  // src/paint-editor/stencils.ts
@@ -2614,15 +2622,15 @@ function readLoad(raw) {
2614
2622
  function readStrokeBrush(raw) {
2615
2623
  if (raw && typeof raw === "object" && "kind" in raw && !("engine" in raw)) {
2616
2624
  try {
2617
- return _chunkXVOP3CGQcjs.resolveBrush.call(void 0, _chunkXVOP3CGQcjs.normalizeBrushSpec.call(void 0, raw));
2625
+ return _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, _chunkEU2ZZA6Lcjs.normalizeBrushSpec.call(void 0, raw));
2618
2626
  } catch (e3) {
2619
2627
  }
2620
2628
  }
2621
- return _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(raw, () => ( {})));
2629
+ return _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(raw, () => ( {})));
2622
2630
  }
2623
2631
  function strokeToJSON(stroke) {
2624
2632
  const { brush, ...rest } = stroke;
2625
- return { ...JSON.parse(JSON.stringify(rest)), brush: _chunkXVOP3CGQcjs.migrateBrushV1.call(void 0, brush) };
2633
+ return { ...JSON.parse(JSON.stringify(rest)), brush: _chunkEU2ZZA6Lcjs.migrateBrushV1.call(void 0, brush) };
2626
2634
  }
2627
2635
  function normalizeBrushStroke(raw) {
2628
2636
  if (!raw || typeof raw !== "object") return null;
@@ -2652,8 +2660,8 @@ function normalizeBrushStroke(raw) {
2652
2660
  }
2653
2661
  if (st.length) out.stencils = st;
2654
2662
  }
2655
- const effect = _chunkOKHKA43Lcjs.readPaintEffectPaint.call(void 0, r.paint);
2656
- const paint = effect ? null : _chunkFQPUF2W2cjs.readPaintSource.call(void 0, r.paint);
2663
+ const effect = _chunkJBB3GDBBcjs.readPaintEffectPaint.call(void 0, r.paint);
2664
+ const paint = effect ? null : _chunkNIBFKXMDcjs.readPaintSource.call(void 0, r.paint);
2657
2665
  if (effect) out.paint = effect;
2658
2666
  else if (paint && paint.type === "gradient") out.paint = paint;
2659
2667
  if (Array.isArray(r.steps) && r.steps.length === points.length && r.steps.every((v) => Number.isInteger(v) && v >= 0)) out.steps = [...r.steps];
@@ -2692,9 +2700,9 @@ function varyStroke(stroke, m, v) {
2692
2700
  if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
2693
2701
  return q;
2694
2702
  });
2695
- const brush = s !== 1 ? _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
2703
+ const brush = s !== 1 ? _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
2696
2704
  const out = { ...stroke, brush, points };
2697
- if (_optionalChain([stroke, 'access', _107 => _107.paint, 'optionalAccess', _108 => _108.type]) === "gradient" && s !== 1) out.paint = _chunkFQPUF2W2cjs.scalePaintGradient.call(void 0, stroke.paint, s);
2705
+ if (_optionalChain([stroke, 'access', _107 => _107.paint, 'optionalAccess', _108 => _108.type]) === "gradient" && s !== 1) out.paint = _chunkNIBFKXMDcjs.scalePaintGradient.call(void 0, stroke.paint, s);
2698
2706
  if (_optionalChain([stroke, 'access', _109 => _109.paint, 'optionalAccess', _110 => _110.type]) === "effect" && stroke.paint.map && s !== 1) out.paint = { ...stroke.paint, map: { ...stroke.paint.map, length: Math.min(4096, Math.max(16, Math.round(stroke.paint.map.length * s))) } };
2699
2707
  if (_optionalChain([stroke, 'access', _111 => _111.copies, 'optionalAccess', _112 => _112.length])) {
2700
2708
  const inv = invertAffine(m);
@@ -2727,7 +2735,7 @@ function paperGrain(paper) {
2727
2735
  const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry, _nullishCoalesce(paper.offset, () => ( null))]);
2728
2736
  let g = grainCache.get(key);
2729
2737
  if (!g) {
2730
- g = new (0, _chunkPXDIAYB6cjs.PaperGrain)(paper, "dry");
2738
+ g = new (0, _chunkNIBFKXMDcjs.PaperGrain)(paper, "dry");
2731
2739
  if (grainCache.size > 16) grainCache.delete(grainCache.keys().next().value);
2732
2740
  grainCache.set(key, g);
2733
2741
  }
@@ -2737,7 +2745,7 @@ function paperTile(paper, r, light) {
2737
2745
  const key = `${paperKey(paper, light)}|${r.x},${r.y},${r.width},${r.height}`;
2738
2746
  let t = tileCache.get(key);
2739
2747
  if (!t) {
2740
- t = _chunkOKHKA43Lcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
2748
+ t = _chunkJBB3GDBBcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
2741
2749
  if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value);
2742
2750
  tileCache.set(key, t);
2743
2751
  }
@@ -2842,11 +2850,11 @@ function header(state, options) {
2842
2850
  return out;
2843
2851
  }
2844
2852
  function serializePaintDocument(state, options = {}) {
2845
- const { layers, assets } = _chunkLHPEG5AUcjs.serializeLayers.call(void 0, state.layers);
2853
+ const { layers, assets } = _chunkJ4GXP53Rcjs.serializeLayers.call(void 0, state.layers);
2846
2854
  return { ...header(state, options), layers, assets };
2847
2855
  }
2848
2856
  async function serializePaintDocumentExternal(state, store, options = {}) {
2849
- const { layers, assets } = await _chunkLHPEG5AUcjs.serializeLayersExternal.call(void 0, state.layers, store);
2857
+ const { layers, assets } = await _chunkJ4GXP53Rcjs.serializeLayersExternal.call(void 0, state.layers, store);
2850
2858
  return { ...header(state, options), layers, assets };
2851
2859
  }
2852
2860
  function paintLayersOnly(layers, problems) {
@@ -2881,9 +2889,9 @@ function deserializePaintDocument(raw) {
2881
2889
  }
2882
2890
  const problems = [];
2883
2891
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
2884
- const paper = _chunkOKHKA43Lcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2892
+ const paper = _chunkJBB3GDBBcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2885
2893
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
2886
- const layers = paintLayersOnly(_chunkLHPEG5AUcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2894
+ const layers = paintLayersOnly(_chunkJ4GXP53Rcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2887
2895
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
2888
2896
  const activeLayerId = wanted && _chunkPVJMTLPJcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _124 => _124.filter, 'call', _125 => _125((l) => l.type === "pixel"), 'access', _126 => _126.pop, 'call', _127 => _127(), 'optionalAccess', _128 => _128.id]), () => ( null));
2889
2897
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
@@ -2899,7 +2907,7 @@ async function deserializePaintDocumentAsync(raw, store) {
2899
2907
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
2900
2908
  const r = raw;
2901
2909
  const problems = [];
2902
- const assets = await _chunkLHPEG5AUcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2910
+ const assets = await _chunkJ4GXP53Rcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2903
2911
  const loaded = deserializePaintDocument({ ...r, assets });
2904
2912
  return { ...loaded, problems: [...problems, ...loaded.problems] };
2905
2913
  }
@@ -2976,13 +2984,13 @@ function viewPenToDocument(view, p) {
2976
2984
 
2977
2985
  // src/paint-editor/input.ts
2978
2986
  function samplePressure(e) {
2979
- return _chunkEXB2EGBEcjs.pointerPressure.call(void 0, e);
2987
+ return _chunk62MFUHSIcjs.pointerPressure.call(void 0, e);
2980
2988
  }
2981
2989
  function pointerToPenPoint(e, x, y, view) {
2982
2990
  const p = { x, y, pressure: samplePressure(e) };
2983
2991
  if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;
2984
2992
  if (e.pointerType !== "pen") return p;
2985
- const o = _chunkOKHKA43Lcjs.penOrientation.call(void 0, {
2993
+ const o = _chunkJBB3GDBBcjs.penOrientation.call(void 0, {
2986
2994
  x,
2987
2995
  y,
2988
2996
  altitude: typeof e.altitudeAngle === "number" ? e.altitudeAngle : void 0,
@@ -3049,28 +3057,28 @@ var thumbWorld = null;
3049
3057
  function paintWetTestStroke(brush, paper, color, width, height) {
3050
3058
  if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
3051
3059
  _optionalChain([thumbWorld, 'optionalAccess', _131 => _131.destroy, 'call', _132 => _132()]);
3052
- thumbWorld = new (0, _chunkJ5VQYK7Tcjs.WetWorld)(width, height, _chunkOKHKA43Lcjs.wetPaperInput.call(void 0, paper), { kernel: "typescript", threads: 0 });
3053
- } else thumbWorld.setPaper(_chunkOKHKA43Lcjs.wetPaperInput.call(void 0, paper));
3060
+ thumbWorld = new (0, _chunkJ5VQYK7Tcjs.WetWorld)(width, height, _chunkJBB3GDBBcjs.wetPaperInput.call(void 0, paper), { kernel: "typescript", threads: 0 });
3061
+ } else thumbWorld.setPaper(_chunkJBB3GDBBcjs.wetPaperInput.call(void 0, paper));
3054
3062
  const w = thumbWorld;
3055
3063
  if (w.hasLane("thumb")) w.removeLane("thumb");
3056
3064
  w.ensureLane("thumb");
3057
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, color);
3065
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, color);
3058
3066
  if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
3059
3067
  const half = Math.ceil(height / 2);
3060
3068
  w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkJ5VQYK7Tcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
3061
3069
  w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkJ5VQYK7Tcjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
3062
3070
  }
3063
- const driver = new (0, _chunkOKHKA43Lcjs.WetStrokeDriver)({
3071
+ const driver = new (0, _chunkJBB3GDBBcjs.WetStrokeDriver)({
3064
3072
  world: w,
3065
3073
  laneId: "thumb",
3066
3074
  brush,
3067
3075
  color: [r / 255, g / 255, b / 255],
3068
- load: brushLoadForStroke(brush, _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
3076
+ load: brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
3069
3077
  grain: paperGrain(paper),
3070
3078
  paperDepth: paper.depth,
3071
- paperColor: _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, paper.color),
3079
+ paperColor: _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, paper.color),
3072
3080
  seed: 7,
3073
- copies: [_chunkOKHKA43Lcjs.IDENTITY_COPY]
3081
+ copies: [_chunkJBB3GDBBcjs.IDENTITY_COPY]
3074
3082
  });
3075
3083
  driver.push(thumbnailStroke(width, height));
3076
3084
  driver.finish();
@@ -3089,8 +3097,8 @@ function thumbnailStroke(width, height) {
3089
3097
  }
3090
3098
  return pts;
3091
3099
  }
3092
- function paintTestStroke(surface, brush, paper, color, width, height) {
3093
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, color);
3100
+ function paintTestStroke(surface, brush, paper, color, width, height, stampArt) {
3101
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, color);
3094
3102
  let result = surface;
3095
3103
  let thick = null;
3096
3104
  let light = null;
@@ -3111,17 +3119,18 @@ function paintTestStroke(surface, brush, paper, color, width, height) {
3111
3119
  lockTransparency: false,
3112
3120
  brush,
3113
3121
  color: [r, g, b, 255],
3114
- background: [..._chunkOKHKA43Lcjs.hexToRgb8.call(void 0, paper.color), 255],
3122
+ background: [..._chunkJBB3GDBBcjs.hexToRgb8.call(void 0, paper.color), 255],
3115
3123
  grain: paperGrain(paper),
3116
3124
  paperDepth: paper.depth,
3117
3125
  seed: 7,
3118
3126
  colorHex: color,
3119
3127
  affineCopies: [],
3120
- copies: [_chunkOKHKA43Lcjs.IDENTITY_COPY],
3121
- mixerLoad: brushLoadForStroke(brush, _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
3128
+ copies: [_chunkJBB3GDBBcjs.IDENTITY_COPY],
3129
+ mixerLoad: brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
3122
3130
  thick: brush.engine === "impasto" ? { channels: emptyThickChannels() } : void 0,
3123
3131
  sticker: brush.engine === "sticker" ? { nextId: 1 } : void 0,
3124
- light: brush.light.amount > 0 && brush.engine !== "wet" && brush.engine !== "sticker" ? { surface: emptyLight() } : null
3132
+ light: brush.light.amount > 0 && brush.engine !== "wet" && brush.engine !== "sticker" ? { surface: emptyLight() } : null,
3133
+ stampArt
3125
3134
  }
3126
3135
  );
3127
3136
  session.push(thumbnailStroke(width, height));
@@ -3133,8 +3142,8 @@ function renderBrushThumbnail(brush, options) {
3133
3142
  const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
3134
3143
  const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
3135
3144
  const maxSize = height * 0.42;
3136
- const b = brush.tip.size > maxSize ? _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
3137
- const rgba = [..._chunkOKHKA43Lcjs.hexToRgb8.call(void 0, options.color), 255];
3145
+ const b = brush.tip.size > maxSize ? _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
3146
+ const rgba = [..._chunkJBB3GDBBcjs.hexToRgb8.call(void 0, options.color), 255];
3138
3147
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
3139
3148
  if (b.engine === "eraser") {
3140
3149
  surface = _chunk474IQG74cjs.fillRect.call(void 0, surface, { x: 0, y: 0, width, height }, rgba);
@@ -3146,9 +3155,9 @@ function renderBrushThumbnail(brush, options) {
3146
3155
  }
3147
3156
  let light = null;
3148
3157
  if (b.engine === "wet") surface = paintWetTestStroke(b, options.paper, options.color, width, height);
3149
- else ({ surface, light } = paintTestStroke(surface, b, options.paper, options.color, width, height));
3158
+ else ({ surface, light } = paintTestStroke(surface, b, options.paper, options.color, width, height, options.stampArt));
3150
3159
  const layer = { type: "pixel", id: "thumbnail", name: "thumbnail", visible: true, opacity: 1, blend: "normal", surface, offset: { x: 0, y: 0 } };
3151
- const paper = light && _chunkHIO6E7LCcjs.brushPreviewsOnDark.call(void 0, b) ? { ...options.paper, color: _chunkHIO6E7LCcjs.BRUSH_PREVIEW_DARK_PAPER } : options.paper;
3160
+ const paper = light && _chunkBPJSI4NTcjs.brushPreviewsOnDark.call(void 0, b) ? { ...options.paper, color: _chunkBPJSI4NTcjs.BRUSH_PREVIEW_DARK_PAPER } : options.paper;
3152
3161
  const spill = light ? computeSpill(surface, light, { radius: Math.max(4, height / 6), strength: 1 }) : null;
3153
3162
  const layers = [paperNode(paper), layer];
3154
3163
  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 } });
@@ -3392,8 +3401,8 @@ function colorHarmony2(base, kind, options = {}) {
3392
3401
  function readSwatch(raw) {
3393
3402
  if (!raw || typeof raw !== "object") return null;
3394
3403
  const r = raw;
3395
- const g = _chunkFQPUF2W2cjs.readPaintSource.call(void 0, r.paint);
3396
- const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _133 => _133.type]) === "gradient" ? _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, g) : null;
3404
+ const g = _chunkNIBFKXMDcjs.readPaintSource.call(void 0, r.paint);
3405
+ const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _133 => _133.type]) === "gradient" ? _chunkNIBFKXMDcjs.paintSourceColor.call(void 0, g) : null;
3397
3406
  if (!color) return null;
3398
3407
  const out = { color };
3399
3408
  if (typeof r.name === "string" && r.name.trim()) out.name = r.name.trim().slice(0, 80);
@@ -3416,7 +3425,7 @@ var DEFAULT_SWATCHES = [
3416
3425
  // src/paint-editor/mixing-pad.ts
3417
3426
  var MIXING_PAD_WIDTH = 360;
3418
3427
  var MIXING_PAD_HEIGHT = 220;
3419
- var PAD_PAINT = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, {
3428
+ var PAD_PAINT = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, {
3420
3429
  id: "pad-paint",
3421
3430
  name: "Pad paint",
3422
3431
  category: "mixer",
@@ -3424,7 +3433,7 @@ var PAD_PAINT = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, {
3424
3433
  tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
3425
3434
  mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
3426
3435
  });
3427
- var PAD_KNIFE = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, {
3436
+ var PAD_KNIFE = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, {
3428
3437
  id: "pad-knife",
3429
3438
  name: "Palette knife",
3430
3439
  category: "smudge",
@@ -3434,7 +3443,7 @@ var PAD_KNIFE = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, {
3434
3443
  // A knife drags streaks of paint and folds them into each other, mixing them as pigment.
3435
3444
  smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
3436
3445
  });
3437
- var PAD_BLOB = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, {
3446
+ var PAD_BLOB = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, {
3438
3447
  id: "pad-blob",
3439
3448
  name: "Pad blob",
3440
3449
  category: "custom",
@@ -3456,12 +3465,12 @@ var MixingPad = (_class10 = class {constructor() { _class10.prototype.__init52.c
3456
3465
  }
3457
3466
  }
3458
3467
  let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
3459
- if (options.size !== void 0) brush = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
3468
+ if (options.size !== void 0) brush = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
3460
3469
  return this.run(brush, points, options.color);
3461
3470
  }
3462
3471
  /** Paints `points` with `brush` in `color` on the pad. */
3463
3472
  run(brush, points, color) {
3464
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, color);
3473
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, color);
3465
3474
  let result = null;
3466
3475
  const session = new PaintStrokeSession(
3467
3476
  { update: () => {
@@ -3479,8 +3488,8 @@ var MixingPad = (_class10 = class {constructor() { _class10.prototype.__init52.c
3479
3488
  seed: 1,
3480
3489
  colorHex: color,
3481
3490
  affineCopies: [],
3482
- copies: [_chunkOKHKA43Lcjs.IDENTITY_COPY],
3483
- mixerLoad: brushLoadForStroke(brush, _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
3491
+ copies: [_chunkJBB3GDBBcjs.IDENTITY_COPY],
3492
+ mixerLoad: brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
3484
3493
  }
3485
3494
  );
3486
3495
  session.push(points);
@@ -3555,10 +3564,10 @@ var MixingPad = (_class10 = class {constructor() { _class10.prototype.__init52.c
3555
3564
  const off = used.length === 1 ? 0 : 0.45 * R;
3556
3565
  const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
3557
3566
  const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
3558
- const blob = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
3567
+ const blob = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
3559
3568
  this.run(blob, [{ x, y }], p.color.toLowerCase());
3560
3569
  });
3561
- const knife = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
3570
+ const knife = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
3562
3571
  for (let k = 0; k < passes; k++) {
3563
3572
  const stir = [];
3564
3573
  const turns = 1.6;
@@ -3570,10 +3579,10 @@ var MixingPad = (_class10 = class {constructor() { _class10.prototype.__init52.c
3570
3579
  this.run(knife, stir, "#000000");
3571
3580
  }
3572
3581
  const mixed = _chunk2VX55NFMcjs.mixPigments.call(void 0,
3573
- paints2.map((p) => _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
3582
+ paints2.map((p) => _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
3574
3583
  paints2.map((p) => p.parts)
3575
3584
  );
3576
- const core = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
3585
+ const core = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
3577
3586
  const hex2 = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
3578
3587
  this.run(core, [{ x: cx, y: cy }], hex2);
3579
3588
  return { color: this.pick(cx, cy, 2), bounds };
@@ -3613,21 +3622,21 @@ var MixingPad = (_class10 = class {constructor() { _class10.prototype.__init52.c
3613
3622
  var copyJSON = (v) => JSON.parse(JSON.stringify(v));
3614
3623
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
3615
3624
  function libraryBrush(spec, builtin, resolved) {
3616
- const brush = resolved ? _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, resolved, resolved) : _chunkXVOP3CGQcjs.resolveBrush.call(void 0, spec);
3625
+ const brush = resolved ? _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, resolved, resolved) : _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, spec);
3617
3626
  if (builtin) brush.builtin = true;
3618
3627
  else delete brush.builtin;
3619
3628
  return { spec, brush, builtin };
3620
3629
  }
3621
3630
  var builtins = null;
3622
3631
  function builtinLibraryBrushes() {
3623
- return builtins ??= _chunkXVOP3CGQcjs.BRUSH_PRESETS.map((spec) => {
3624
- const resolved = _chunkXVOP3CGQcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id);
3632
+ return builtins ??= _chunkEU2ZZA6Lcjs.BRUSH_PRESETS.map((spec) => {
3633
+ const resolved = _chunkEU2ZZA6Lcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id);
3625
3634
  return libraryBrush(spec, true, resolved);
3626
3635
  });
3627
3636
  }
3628
3637
  function seededStorage(brushes) {
3629
3638
  if (!brushes.length) return void 0;
3630
- let stored = JSON.stringify({ format: "pixerate-brushes", version: 1, brushes: brushes.map(_chunkXVOP3CGQcjs.brushToJSON) });
3639
+ let stored = JSON.stringify({ format: "pixerate-brushes", version: 1, brushes: brushes.map(_chunkEU2ZZA6Lcjs.brushToJSON) });
3631
3640
  return {
3632
3641
  get: async () => stored,
3633
3642
  set: async (_key, value) => {
@@ -3640,7 +3649,7 @@ var paints = (b) => {
3640
3649
  return JSON.stringify(rest);
3641
3650
  };
3642
3651
  function brushSpecOf(next, from) {
3643
- const plain = _chunkXVOP3CGQcjs.migrateBrushV1.call(void 0, next);
3652
+ const plain = _chunkEU2ZZA6Lcjs.migrateBrushV1.call(void 0, next);
3644
3653
  const out = copyJSON(plain);
3645
3654
  if (from.description) out.description = from.description;
3646
3655
  if (_optionalChain([from, 'access', _136 => _136.tags, 'optionalAccess', _137 => _137.length])) out.tags = [...from.tags];
@@ -3660,8 +3669,8 @@ function brushSpecOf(next, from) {
3660
3669
  out.motion = { ..._nullishCoalesce(out.motion, () => ( {})), ...from.motion.live !== void 0 ? { live: from.motion.live } : {}, ...from.motion.fps !== void 0 ? { fps: from.motion.fps } : {} };
3661
3670
  }
3662
3671
  try {
3663
- const hinted = _chunkXVOP3CGQcjs.normalizeBrushSpec.call(void 0, out, []);
3664
- if (paints(_chunkXVOP3CGQcjs.resolveBrush.call(void 0, hinted)) === paints(_chunkXVOP3CGQcjs.resolveBrush.call(void 0, plain))) return hinted;
3672
+ const hinted = _chunkEU2ZZA6Lcjs.normalizeBrushSpec.call(void 0, out, []);
3673
+ if (paints(_chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, hinted)) === paints(_chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, plain))) return hinted;
3665
3674
  } catch (e5) {
3666
3675
  }
3667
3676
  return plain;
@@ -3736,6 +3745,59 @@ function samplePath(d, options = {}) {
3736
3745
  return out;
3737
3746
  }
3738
3747
 
3748
+ // src/paint-editor/brush-source-art.ts
3749
+ var BrushSourceArtCache = (_class11 = class {constructor() { _class11.prototype.__init56.call(this);_class11.prototype.__init57.call(this);_class11.prototype.__init58.call(this); }
3750
+ __init56() {this.sources = /* @__PURE__ */ new Map()}
3751
+ __init57() {this.art = /* @__PURE__ */ new Map()}
3752
+ /** Adds or replaces sources (a replaced image is decoded again). */
3753
+ set(sources) {
3754
+ for (const s of sources) {
3755
+ const was = this.sources.get(s.id);
3756
+ if (was && was.image === s.image) continue;
3757
+ this.sources.set(s.id, s);
3758
+ this.art.delete(s.id);
3759
+ }
3760
+ }
3761
+ /** The source of an id, if known. */
3762
+ source(id) {
3763
+ return this.sources.get(id);
3764
+ }
3765
+ /** Every known source. */
3766
+ all() {
3767
+ return [...this.sources.values()];
3768
+ }
3769
+ /** The art of a `source:<id>` ref (alpha = the mask), or `undefined` when the source is unknown or its image can't be read. */
3770
+ __init58() {this.get = (ref2) => {
3771
+ const id = _chunkEU2ZZA6Lcjs.brushSourceIdOf.call(void 0, ref2);
3772
+ if (id === null) return void 0;
3773
+ if (this.art.has(id)) return _nullishCoalesce(this.art.get(id), () => ( void 0));
3774
+ const source = this.sources.get(id);
3775
+ if (!source) return void 0;
3776
+ let art = null;
3777
+ try {
3778
+ const { width, height, mask } = _chunkEU2ZZA6Lcjs.decodeBrushSource.call(void 0, source);
3779
+ const data = new Uint8ClampedArray(width * height * 4);
3780
+ for (let i = 0; i < mask.length; i++) {
3781
+ data[i * 4] = data[i * 4 + 1] = data[i * 4 + 2] = 255;
3782
+ data[i * 4 + 3] = mask[i];
3783
+ }
3784
+ art = { width, height, data, tintable: true };
3785
+ } catch (e7) {
3786
+ art = null;
3787
+ }
3788
+ this.art.set(id, art);
3789
+ return _nullishCoalesce(art, () => ( void 0));
3790
+ }}
3791
+ /** A lookup that reads sources from here and every other ref from `stickers`. */
3792
+ with(stickers) {
3793
+ return (ref2, variant) => _chunkEU2ZZA6Lcjs.isBrushSourceRef.call(void 0, ref2) ? this.get(ref2) : stickers(ref2, variant);
3794
+ }
3795
+ }, _class11);
3796
+ function engineBrushSourceIds(brush) {
3797
+ const refs = [brush.stamp, _optionalChain([brush, 'access', _150 => _150.tipGrain, 'optionalAccess', _151 => _151.source]), ..._nullishCoalesce(_optionalChain([brush, 'access', _152 => _152.particle, 'optionalAccess', _153 => _153.dotTextures]), () => ( []))];
3798
+ return [...new Set(refs.filter((r) => !!r && _chunkEU2ZZA6Lcjs.isBrushSourceRef.call(void 0, r)).map((r) => _chunkEU2ZZA6Lcjs.brushSourceIdOf.call(void 0, r)))];
3799
+ }
3800
+
3739
3801
  // src/paint-editor/live-strokes.ts
3740
3802
  var LIVE_STROKE_ENGINES = ["dab", "particle", "bristle", "mixer"];
3741
3803
  function liveStrokeRefusal(brush) {
@@ -3803,11 +3865,11 @@ function tilesUnder(surface, rect, offset, out) {
3803
3865
  for (let ty = y0; ty <= y1; ty++) for (let tx = x0; tx <= x1; tx++) out.push(_nullishCoalesce(surface.tiles.get(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty)), () => ( null)));
3804
3866
  }
3805
3867
  var sameRefs = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
3806
- var BacklightCache = (_class11 = class {constructor() { _class11.prototype.__init56.call(this);_class11.prototype.__init57.call(this);_class11.prototype.__init58.call(this);_class11.prototype.__init59.call(this); }
3807
- __init56() {this.tiles = /* @__PURE__ */ new Map()}
3808
- __init57() {this.key = ""}
3809
- __init58() {this.spillOf = null}
3810
- __init59() {this.out = null}
3868
+ var BacklightCache = (_class12 = class {constructor() { _class12.prototype.__init59.call(this);_class12.prototype.__init60.call(this);_class12.prototype.__init61.call(this);_class12.prototype.__init62.call(this); }
3869
+ __init59() {this.tiles = /* @__PURE__ */ new Map()}
3870
+ __init60() {this.key = ""}
3871
+ __init61() {this.spillOf = null}
3872
+ __init62() {this.out = null}
3811
3873
  /**
3812
3874
  * The backlight layer's pixels for `layers` (bottom first) on `paper` over a `width` × `height`
3813
3875
  * canvas, or `null` when the paper has no backlight. `spillFrom` is the committed painting (the
@@ -3833,8 +3895,8 @@ var BacklightCache = (_class11 = class {constructor() { _class11.prototype.__ini
3833
3895
  refs.length = 0;
3834
3896
  for (const l of layers) {
3835
3897
  tilesUnder(l.surface, rect, l.offset, refs);
3836
- tilesUnder(_optionalChain([l, 'access', _150 => _150.thick, 'optionalAccess', _151 => _151.height]), rect, l.offset, refs);
3837
- tilesUnder(_optionalChain([l, 'access', _152 => _152.thick, 'optionalAccess', _153 => _153.material]), rect, l.offset, refs);
3898
+ tilesUnder(_optionalChain([l, 'access', _154 => _154.thick, 'optionalAccess', _155 => _155.height]), rect, l.offset, refs);
3899
+ tilesUnder(_optionalChain([l, 'access', _156 => _156.thick, 'optionalAccess', _157 => _157.material]), rect, l.offset, refs);
3838
3900
  }
3839
3901
  const k = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
3840
3902
  let r = this.tiles.get(k);
@@ -3878,7 +3940,7 @@ var BacklightCache = (_class11 = class {constructor() { _class11.prototype.__ini
3878
3940
  this.out = { parts, surface };
3879
3941
  return surface;
3880
3942
  }
3881
- }, _class11);
3943
+ }, _class12);
3882
3944
  var full4 = (t) => {
3883
3945
  if (t.data.length === _chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4) return t.data;
3884
3946
  const out = new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4);
@@ -3906,10 +3968,10 @@ function addTiles(a, b) {
3906
3968
  }
3907
3969
  function computeTile(paper, grain, amount, rect, layers) {
3908
3970
  const n = rect.width * rect.height;
3909
- const [p0, p1, p2] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, paper.color);
3971
+ const [p0, p1, p2] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, paper.color);
3910
3972
  const pb = [p0, p1, p2];
3911
3973
  const pl = [Math.max(1e-4, LIN[p0]), Math.max(1e-4, LIN[p1]), Math.max(1e-4, LIN[p2])];
3912
- const [c0, c1, c2] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
3974
+ const [c0, c1, c2] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
3913
3975
  const t0 = new Float32Array(n).fill(amount * LIN[c0]);
3914
3976
  const t1 = new Float32Array(n).fill(amount * LIN[c1]);
3915
3977
  const t2 = new Float32Array(n).fill(amount * LIN[c2]);
@@ -3928,8 +3990,8 @@ function computeTile(paper, grain, amount, rect, layers) {
3928
3990
  const lr = { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height };
3929
3991
  if (!l.surface.tiles.size) continue;
3930
3992
  const px = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, lr);
3931
- const h = _optionalChain([l, 'access', _154 => _154.thick, 'optionalAccess', _155 => _155.height, 'access', _156 => _156.tiles, 'access', _157 => _157.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.height, lr) : null;
3932
- const m = h && _optionalChain([l, 'access', _158 => _158.thick, 'optionalAccess', _159 => _159.material, 'access', _160 => _160.tiles, 'access', _161 => _161.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.material, lr) : null;
3993
+ const h = _optionalChain([l, 'access', _158 => _158.thick, 'optionalAccess', _159 => _159.height, 'access', _160 => _160.tiles, 'access', _161 => _161.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.height, lr) : null;
3994
+ const m = h && _optionalChain([l, 'access', _162 => _162.thick, 'optionalAccess', _163 => _163.material, 'access', _164 => _164.tiles, 'access', _165 => _165.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.material, lr) : null;
3933
3995
  const op = l.opacity;
3934
3996
  for (let i = 0; i < n; i++) {
3935
3997
  const a8 = px[i * 4 + 3];
@@ -4005,7 +4067,7 @@ async function replayPainting(source, target, options = {}) {
4005
4067
  const chunk = Math.max(1, _nullishCoalesce(options.wetChunk, () => ( 0))) || Infinity;
4006
4068
  let strokes = 0;
4007
4069
  const scaled = source.strokes.slice(0, maxStrokes).map((st) => s === 1 ? st : varyStroke(st, scaleM, { scale: s }));
4008
- await target.prepareEffectPaints(scaled.flatMap((st) => _optionalChain([st, 'access', _162 => _162.paint, 'optionalAccess', _163 => _163.type]) === "effect" ? [st.paint] : []));
4070
+ await target.prepareEffectPaints(scaled.flatMap((st) => _optionalChain([st, 'access', _166 => _166.paint, 'optionalAccess', _167 => _167.type]) === "effect" ? [st.paint] : []));
4009
4071
  const advanceTo = async (clock) => {
4010
4072
  const now = target.getState().wet.clock;
4011
4073
  let left = clock - now;
@@ -4013,7 +4075,7 @@ async function replayPainting(source, target, options = {}) {
4013
4075
  const n = Math.min(left, chunk);
4014
4076
  await target.advanceWet({ steps: n });
4015
4077
  left -= n;
4016
- if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _164 => _164.onWetSteps, 'optionalCall', _165 => _165(target.getState().wet.clock)]);
4078
+ if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _168 => _168.onWetSteps, 'optionalCall', _169 => _169(target.getState().wet.clock)]);
4017
4079
  }
4018
4080
  };
4019
4081
  const sr = (r) => ({ x: r.x * s, y: r.y * s, width: r.width * s, height: r.height * s });
@@ -4026,14 +4088,14 @@ async function replayPainting(source, target, options = {}) {
4026
4088
  else if (e.kind === "clear") target.clearLayer(e.layerId);
4027
4089
  else if (e.kind === "live-strokes") {
4028
4090
  const d = e.data;
4029
- if (_optionalChain([d, 'optionalAccess', _166 => _166.rasterized])) target.replaceLiveStrokes(e.layerId, null);
4091
+ if (_optionalChain([d, 'optionalAccess', _170 => _170.rasterized])) target.replaceLiveStrokes(e.layerId, null);
4030
4092
  else {
4031
- const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _167 => _167.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
4032
- await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _168 => _168.paint, 'optionalAccess', _169 => _169.type]) === "effect" ? [st2.paint] : []));
4093
+ const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _171 => _171.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
4094
+ await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _172 => _172.paint, 'optionalAccess', _173 => _173.type]) === "effect" ? [st2.paint] : []));
4033
4095
  target.replaceLiveStrokes(e.layerId, list);
4034
4096
  }
4035
4097
  } else if (e.kind === "stickers") {
4036
- const list = (_nullishCoalesce(_optionalChain([e, 'access', _170 => _170.data, 'optionalAccess', _171 => _171.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
4098
+ const list = (_nullishCoalesce(_optionalChain([e, 'access', _174 => _174.data, 'optionalAccess', _175 => _175.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
4037
4099
  target.replaceStickers(e.layerId, list);
4038
4100
  } else target.flattenRelief(e.layerId);
4039
4101
  continue;
@@ -4046,8 +4108,8 @@ async function replayPainting(source, target, options = {}) {
4046
4108
  switch (e.kind) {
4047
4109
  case "dry": {
4048
4110
  const rect = e.data;
4049
- const ids = _optionalChain([e, 'access', _172 => _172.layerId, 'optionalAccess', _173 => _173.split, 'call', _174 => _174(","), 'access', _175 => _175.filter, 'call', _176 => _176(Boolean)]);
4050
- if (_optionalChain([ids, 'optionalAccess', _177 => _177.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
4111
+ const ids = _optionalChain([e, 'access', _176 => _176.layerId, 'optionalAccess', _177 => _177.split, 'call', _178 => _178(","), 'access', _179 => _179.filter, 'call', _180 => _180(Boolean)]);
4112
+ if (_optionalChain([ids, 'optionalAccess', _181 => _181.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
4051
4113
  else target.dryPaint({ rect: rect ? sr(rect) : void 0 });
4052
4114
  break;
4053
4115
  }
@@ -4070,7 +4132,7 @@ async function replayPainting(source, target, options = {}) {
4070
4132
  break;
4071
4133
  }
4072
4134
  }
4073
- } catch (e6) {
4135
+ } catch (e8) {
4074
4136
  }
4075
4137
  continue;
4076
4138
  }
@@ -4078,7 +4140,7 @@ async function replayPainting(source, target, options = {}) {
4078
4140
  strokes++;
4079
4141
  if (!target.getLayer(st.layerId)) continue;
4080
4142
  const init = { layerId: st.layerId, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...st.paint ? { paint: st.paint } : {}, snapToPerspective: false, stencils: false, maskStencils: (_nullishCoalesce(st.stencils, () => ( []))).map((x) => s === 1 ? x : scaleStencil(x, s)) };
4081
- if (st.brush.engine === "wet" && _optionalChain([st, 'access', _178 => _178.steps, 'optionalAccess', _179 => _179.length]) === st.points.length) {
4143
+ if (st.brush.engine === "wet" && _optionalChain([st, 'access', _182 => _182.steps, 'optionalAccess', _183 => _183.length]) === st.points.length) {
4082
4144
  await target.wetIdle();
4083
4145
  await advanceTo(st.steps[0]);
4084
4146
  const session = target.beginStroke({ ...init, start: st.points[0] });
@@ -4098,7 +4160,7 @@ async function replayPainting(source, target, options = {}) {
4098
4160
  await target.wetIdle();
4099
4161
  target.paintStroke({ ...init, points: st.points });
4100
4162
  }
4101
- await _optionalChain([options, 'access', _180 => _180.onStroke, 'optionalCall', _181 => _181(strokes)]);
4163
+ await _optionalChain([options, 'access', _184 => _184.onStroke, 'optionalCall', _185 => _185(strokes)]);
4102
4164
  }
4103
4165
  void IDENTITY_AFFINE;
4104
4166
  }
@@ -4143,7 +4205,7 @@ async function buildTimeLapse(source, target, options = {}) {
4143
4205
  wetChunk: wetEvery > 0 ? wetEvery : 0,
4144
4206
  onStroke: (i) => {
4145
4207
  if (i % perFrame === 0 || i === total) shoot(i);
4146
- _optionalChain([options, 'access', _182 => _182.onProgress, 'optionalCall', _183 => _183(total ? i / total : 1)]);
4208
+ _optionalChain([options, 'access', _186 => _186.onProgress, 'optionalCall', _187 => _187(total ? i / total : 1)]);
4147
4209
  },
4148
4210
  onWetSteps: wetEvery > 0 ? () => shoot(-1) : void 0
4149
4211
  });
@@ -4230,10 +4292,10 @@ function mixPixels(before, after, amount) {
4230
4292
  }
4231
4293
  return out;
4232
4294
  }
4233
- var PaintEffectsRenderer = (_class12 = class {constructor() { _class12.prototype.__init60.call(this);_class12.prototype.__init61.call(this);_class12.prototype.__init62.call(this); }
4234
- __init60() {this.pool = new (0, _chunkPY4GWSE2cjs.EffectRendererPool)({ maxRenderers: 3 })}
4235
- __init61() {this.descriptions = /* @__PURE__ */ new Map()}
4236
- __init62() {this.provider = null}
4295
+ var PaintEffectsRenderer = (_class13 = class {constructor() { _class13.prototype.__init63.call(this);_class13.prototype.__init64.call(this);_class13.prototype.__init65.call(this); }
4296
+ __init63() {this.pool = new (0, _chunkPY4GWSE2cjs.EffectRendererPool)({ maxRenderers: 3 })}
4297
+ __init64() {this.descriptions = /* @__PURE__ */ new Map()}
4298
+ __init65() {this.provider = null}
4237
4299
  /** Forgets cached descriptions and renderers when the provider changes. */
4238
4300
  follow(provider) {
4239
4301
  if (provider === this.provider) return;
@@ -4263,7 +4325,7 @@ var PaintEffectsRenderer = (_class12 = class {constructor() { _class12.prototype
4263
4325
  this.pool.clear();
4264
4326
  this.descriptions.clear();
4265
4327
  }
4266
- }, _class12);
4328
+ }, _class13);
4267
4329
  var sourceOut = (s) => ({
4268
4330
  effect: s.effect,
4269
4331
  ...s.provider ? { provider: s.provider } : {},
@@ -4323,7 +4385,7 @@ async function libraryCall(call) {
4323
4385
  try {
4324
4386
  return await call();
4325
4387
  } catch (e) {
4326
- throw e instanceof _chunkXVOP3CGQcjs.BrushLibraryError ? new PaintEditorError(e.message) : e;
4388
+ throw e instanceof _chunkEU2ZZA6Lcjs.BrushLibraryError ? new PaintEditorError(e.message) : e;
4327
4389
  }
4328
4390
  }
4329
4391
  var HEX2 = /^#[0-9a-f]{6}$/i;
@@ -4333,7 +4395,7 @@ function parseColor(value, what = "color") {
4333
4395
  return value.trim().toLowerCase();
4334
4396
  }
4335
4397
  function rgbaOf(hex2) {
4336
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, hex2);
4398
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, hex2);
4337
4399
  return [r, g, b, 255];
4338
4400
  }
4339
4401
  function rgbToHex(r, g, b) {
@@ -4346,12 +4408,12 @@ function unionRect(a, b) {
4346
4408
  const y = Math.min(a.y, b.y);
4347
4409
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
4348
4410
  }
4349
- var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _184 => _184.type]) === "pixel";
4350
- var PaintEditorController = (_class13 = class _PaintEditorController {
4411
+ var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _188 => _188.type]) === "pixel";
4412
+ var PaintEditorController = (_class14 = class _PaintEditorController {
4351
4413
 
4352
- __init63() {this.extensions = {}}
4353
- __init64() {this.undoStack = []}
4354
- __init65() {this.redoStack = []}
4414
+ __init66() {this.extensions = {}}
4415
+ __init67() {this.undoStack = []}
4416
+ __init68() {this.redoStack = []}
4355
4417
 
4356
4418
  /** The brush library this editor lists, saves into and paints from (shared with other editors when the host passes one). */
4357
4419
 
@@ -4361,107 +4423,111 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4361
4423
  /** The library's brushes as last read, each as stored (facets) and as the engine paints it. */
4362
4424
 
4363
4425
  /** The brush id asked for at construction, while the library had not listed it yet. */
4364
- __init66() {this.pendingBrushId = null}
4365
- __init67() {this.brushesLoaded = Promise.resolve()}
4426
+ __init69() {this.pendingBrushId = null}
4427
+ __init70() {this.brushesLoaded = Promise.resolve()}
4366
4428
 
4367
4429
  /** The library list in the state (the same array until the user brushes change, so thumbnails are not redrawn). */
4368
- __init68() {this.library = null}
4430
+ __init71() {this.library = null}
4369
4431
 
4370
- __init69() {this.secondaryColor = "#ffffff"}
4432
+ __init72() {this.secondaryColor = "#ffffff"}
4371
4433
  /** Gradient paint chosen with `setPaint` (`null`: the paint colour). */
4372
- __init70() {this.gradient = null}
4434
+ __init73() {this.gradient = null}
4373
4435
  /** Effect paint chosen with `setEffectPaint` (rendered), and one still rendering. */
4374
- __init71() {this.effectPaint = null}
4375
- __init72() {this.effectPaintPending = null}
4436
+ __init74() {this.effectPaint = null}
4437
+ __init75() {this.effectPaintPending = null}
4376
4438
  /** Changes whenever the paint is chosen, so an effect paint that finishes rendering late does not take over. */
4377
- __init73() {this.paintEpoch = 0}
4439
+ __init76() {this.paintEpoch = 0}
4378
4440
  /** Rendered effect paints by `effectPaintKey` (most recently used last). */
4379
- __init74() {this.effectPaintPixels = /* @__PURE__ */ new Map()}
4380
- __init75() {this.mixerLoad = _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD}
4381
- __init76() {this.view = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } }}
4441
+ __init77() {this.effectPaintPixels = /* @__PURE__ */ new Map()}
4442
+ __init78() {this.mixerLoad = _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD}
4443
+ __init79() {this.view = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } }}
4382
4444
 
4383
- __init77() {this.selectedStroke = null}
4384
- __init78() {this.selectedSticker = null}
4445
+ __init80() {this.selectedStroke = null}
4446
+ __init81() {this.selectedSticker = null}
4385
4447
  /** A sticker drag in progress (`previewSticker`): the document before it, so the drop undoes in one step, and the one it showed last. */
4386
- __init79() {this.stickerPreview = null}
4448
+ __init82() {this.stickerPreview = null}
4387
4449
 
4388
- __init80() {this.listeners = /* @__PURE__ */ new Set()}
4389
- __init81() {this.commitListeners = /* @__PURE__ */ new Set()}
4390
- __init82() {this.sampleListeners = /* @__PURE__ */ new Set()}
4450
+ __init83() {this.listeners = /* @__PURE__ */ new Set()}
4451
+ __init84() {this.commitListeners = /* @__PURE__ */ new Set()}
4452
+ __init85() {this.sampleListeners = /* @__PURE__ */ new Set()}
4391
4453
  /** Origins set by `withOrigin`, innermost last. */
4392
- __init83() {this.origins = []}
4454
+ __init86() {this.origins = []}
4393
4455
  /** `group` in progress: commits fold into one step, recorded when it ends. */
4394
- __init84() {this.grouping = null}
4456
+ __init87() {this.grouping = null}
4395
4457
  /** `previewPaint` in progress: nothing is emitted or recorded. */
4396
- __init85() {this.previewing = false}
4397
- __init86() {this.version = 0}
4398
- __init87() {this.cached = null}
4399
- __init88() {this.session = null}
4400
- __init89() {this.live = null}
4401
- __init90() {this.liveLayers = null}
4402
- __init91() {this.dirty = "all"}
4403
- __init92() {this.seedCounter = 1}
4404
- __init93() {this.strokeCounter = 1}
4458
+ __init88() {this.previewing = false}
4459
+ __init89() {this.version = 0}
4460
+ __init90() {this.cached = null}
4461
+ __init91() {this.session = null}
4462
+ __init92() {this.live = null}
4463
+ __init93() {this.liveLayers = null}
4464
+ __init94() {this.dirty = "all"}
4465
+ __init95() {this.seedCounter = 1}
4466
+ __init96() {this.strokeCounter = 1}
4405
4467
  /** Light paint: each layer's spill settings (saved with the document, not undo steps; missing = the defaults). */
4406
- __init94() {this.lightSpills = {}}
4407
- __init95() {this.lightCaches = /* @__PURE__ */ new Map()}
4468
+ __init97() {this.lightSpills = {}}
4469
+ __init98() {this.lightCaches = /* @__PURE__ */ new Map()}
4408
4470
  /** Backlit paper: the light through the paint as drawn (live strokes too), and as committed (its spill). */
4409
- __init96() {this.backlightView = new BacklightCache()}
4410
- __init97() {this.backlightCommitted = new BacklightCache()}
4471
+ __init99() {this.backlightView = new BacklightCache()}
4472
+ __init100() {this.backlightCommitted = new BacklightCache()}
4411
4473
  /** Live effect paint: playing and the frame rate cap (editor state), and the time the view shows. */
4412
- __init98() {this.effectPlaybackState = { playing: true, fps: 30 }}
4413
- __init99() {this.effectTime = 0}
4474
+ __init101() {this.effectPlaybackState = { playing: true, fps: 30 }}
4475
+ __init102() {this.effectTime = 0}
4414
4476
  /** While a frame is drawn: the time live effect strokes are drawn at (else their own time). */
4415
- __init100() {this.liveEffectAt = null}
4477
+ __init103() {this.liveEffectAt = null}
4416
4478
  /** The view's stroke layers at `effectTime`, each with the document surface it was drawn from (stale once that changes). */
4417
- __init101() {this.animatedLayers = /* @__PURE__ */ new Map()}
4479
+ __init104() {this.animatedLayers = /* @__PURE__ */ new Map()}
4418
4480
  /** `renderAnimationFrame` / `withEffectTime`: layer surfaces at another time, for one render. */
4419
- __init102() {this.frameOverride = null}
4481
+ __init105() {this.frameOverride = null}
4420
4482
  /** The area each stroke painted (document pixels; `null`: nothing), learnt as it is painted or drawn, so a stroke layer edit redraws only where it changes (see `drawLiveStrokes`). */
4421
- __init103() {this.paintedBounds = /* @__PURE__ */ new WeakMap()}
4483
+ __init106() {this.paintedBounds = /* @__PURE__ */ new WeakMap()}
4422
4484
 
4423
- __init104() {this.swatches = DEFAULT_SWATCHES.map((s) => ({ ...s }))}
4424
- __init105() {this.pad = new MixingPad()}
4425
- __init106() {this.savedPads = []}
4426
- __init107() {this.nextPadId = 1}
4427
- __init108() {this.tracingVersion = 1}
4428
- __init109() {this.tracingCache = null}
4429
- __init110() {this.imagePixels = /* @__PURE__ */ new Map()}
4430
- __init111() {this.nextReferenceId = 1}
4431
- __init112() {this.viewCompositor = createPaintCompositor()}
4432
- __init113() {this.exportCompositor = createPaintCompositor()}
4485
+ __init107() {this.swatches = DEFAULT_SWATCHES.map((s) => ({ ...s }))}
4486
+ __init108() {this.pad = new MixingPad()}
4487
+ __init109() {this.savedPads = []}
4488
+ __init110() {this.nextPadId = 1}
4489
+ __init111() {this.tracingVersion = 1}
4490
+ __init112() {this.tracingCache = null}
4491
+ __init113() {this.imagePixels = /* @__PURE__ */ new Map()}
4492
+ __init114() {this.nextReferenceId = 1}
4493
+ __init115() {this.viewCompositor = createPaintCompositor()}
4494
+ __init116() {this.exportCompositor = createPaintCompositor()}
4433
4495
  /** Wet media: the simulation, its settings and time. */
4434
4496
 
4435
4497
 
4436
4498
  /** Where the light comes from for thick paint (saved with the document, not undo steps). */
4437
- __init114() {this.lighting = { ...DEFAULT_LIGHTING }}
4438
- __init115() {this.litCaches = /* @__PURE__ */ new Map()}
4499
+ __init117() {this.lighting = { ...DEFAULT_LIGHTING }}
4500
+ __init118() {this.litCaches = /* @__PURE__ */ new Map()}
4439
4501
  /** The live impasto stroke's channels. */
4440
- __init116() {this.liveThick = null}
4502
+ __init119() {this.liveThick = null}
4441
4503
  /** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
4442
- __init117() {this.wetOp = null}
4504
+ __init120() {this.wetOp = null}
4443
4505
  /** The effects provider slot (see `setEffectsProvider`). */
4444
- __init118() {this.effects = new (0, _chunkL2JTLW6Bcjs.EffectsSlot)()}
4506
+ __init121() {this.effects = new (0, _chunkL2JTLW6Bcjs.EffectsSlot)()}
4445
4507
  /** The sticker library slot (see `setStickersProvider`). */
4446
- __init119() {this.stickers = new (0, _chunkRDFHWAHLcjs.StickersSlot)(_chunk3VHH6V67cjs.editorStickers.call(void 0, ))}
4447
- __init120() {this.stickerArt = new StickerArtCache()}
4508
+ __init122() {this.stickers = new (0, _chunkRDFHWAHLcjs.StickersSlot)(_chunk3VHH6V67cjs.editorStickers.call(void 0, ))}
4509
+ __init123() {this.stickerArt = new StickerArtCache()}
4510
+ /** Image sources strokes draw with: the brush library's and the open painting's (saved with it). */
4511
+ __init124() {this.brushSources = new BrushSourceArtCache()}
4512
+ /** Art for stamp tips and tip grain: image sources from `brushSources`, stickers from the sticker library. */
4513
+ __init125() {this.stampArt = (ref2, variant) => _chunkEU2ZZA6Lcjs.isBrushSourceRef.call(void 0, ref2) ? this.brushSources.get(ref2) : this.stickerArt.get(ref2, variant)}
4448
4514
 
4449
- __init121() {this.effectsRenderer = new PaintEffectsRenderer()}
4450
- __init122() {this.paperEffectNodeCache = null}
4451
- constructor(options = {}) {;_class13.prototype.__init63.call(this);_class13.prototype.__init64.call(this);_class13.prototype.__init65.call(this);_class13.prototype.__init66.call(this);_class13.prototype.__init67.call(this);_class13.prototype.__init68.call(this);_class13.prototype.__init69.call(this);_class13.prototype.__init70.call(this);_class13.prototype.__init71.call(this);_class13.prototype.__init72.call(this);_class13.prototype.__init73.call(this);_class13.prototype.__init74.call(this);_class13.prototype.__init75.call(this);_class13.prototype.__init76.call(this);_class13.prototype.__init77.call(this);_class13.prototype.__init78.call(this);_class13.prototype.__init79.call(this);_class13.prototype.__init80.call(this);_class13.prototype.__init81.call(this);_class13.prototype.__init82.call(this);_class13.prototype.__init83.call(this);_class13.prototype.__init84.call(this);_class13.prototype.__init85.call(this);_class13.prototype.__init86.call(this);_class13.prototype.__init87.call(this);_class13.prototype.__init88.call(this);_class13.prototype.__init89.call(this);_class13.prototype.__init90.call(this);_class13.prototype.__init91.call(this);_class13.prototype.__init92.call(this);_class13.prototype.__init93.call(this);_class13.prototype.__init94.call(this);_class13.prototype.__init95.call(this);_class13.prototype.__init96.call(this);_class13.prototype.__init97.call(this);_class13.prototype.__init98.call(this);_class13.prototype.__init99.call(this);_class13.prototype.__init100.call(this);_class13.prototype.__init101.call(this);_class13.prototype.__init102.call(this);_class13.prototype.__init103.call(this);_class13.prototype.__init104.call(this);_class13.prototype.__init105.call(this);_class13.prototype.__init106.call(this);_class13.prototype.__init107.call(this);_class13.prototype.__init108.call(this);_class13.prototype.__init109.call(this);_class13.prototype.__init110.call(this);_class13.prototype.__init111.call(this);_class13.prototype.__init112.call(this);_class13.prototype.__init113.call(this);_class13.prototype.__init114.call(this);_class13.prototype.__init115.call(this);_class13.prototype.__init116.call(this);_class13.prototype.__init117.call(this);_class13.prototype.__init118.call(this);_class13.prototype.__init119.call(this);_class13.prototype.__init120.call(this);_class13.prototype.__init121.call(this);_class13.prototype.__init122.call(this);_class13.prototype.__init123.call(this);_class13.prototype.__init124.call(this);_class13.prototype.__init125.call(this);_class13.prototype.__init126.call(this);_class13.prototype.__init127.call(this);_class13.prototype.__init128.call(this);
4515
+ __init126() {this.effectsRenderer = new PaintEffectsRenderer()}
4516
+ __init127() {this.paperEffectNodeCache = null}
4517
+ constructor(options = {}) {;_class14.prototype.__init66.call(this);_class14.prototype.__init67.call(this);_class14.prototype.__init68.call(this);_class14.prototype.__init69.call(this);_class14.prototype.__init70.call(this);_class14.prototype.__init71.call(this);_class14.prototype.__init72.call(this);_class14.prototype.__init73.call(this);_class14.prototype.__init74.call(this);_class14.prototype.__init75.call(this);_class14.prototype.__init76.call(this);_class14.prototype.__init77.call(this);_class14.prototype.__init78.call(this);_class14.prototype.__init79.call(this);_class14.prototype.__init80.call(this);_class14.prototype.__init81.call(this);_class14.prototype.__init82.call(this);_class14.prototype.__init83.call(this);_class14.prototype.__init84.call(this);_class14.prototype.__init85.call(this);_class14.prototype.__init86.call(this);_class14.prototype.__init87.call(this);_class14.prototype.__init88.call(this);_class14.prototype.__init89.call(this);_class14.prototype.__init90.call(this);_class14.prototype.__init91.call(this);_class14.prototype.__init92.call(this);_class14.prototype.__init93.call(this);_class14.prototype.__init94.call(this);_class14.prototype.__init95.call(this);_class14.prototype.__init96.call(this);_class14.prototype.__init97.call(this);_class14.prototype.__init98.call(this);_class14.prototype.__init99.call(this);_class14.prototype.__init100.call(this);_class14.prototype.__init101.call(this);_class14.prototype.__init102.call(this);_class14.prototype.__init103.call(this);_class14.prototype.__init104.call(this);_class14.prototype.__init105.call(this);_class14.prototype.__init106.call(this);_class14.prototype.__init107.call(this);_class14.prototype.__init108.call(this);_class14.prototype.__init109.call(this);_class14.prototype.__init110.call(this);_class14.prototype.__init111.call(this);_class14.prototype.__init112.call(this);_class14.prototype.__init113.call(this);_class14.prototype.__init114.call(this);_class14.prototype.__init115.call(this);_class14.prototype.__init116.call(this);_class14.prototype.__init117.call(this);_class14.prototype.__init118.call(this);_class14.prototype.__init119.call(this);_class14.prototype.__init120.call(this);_class14.prototype.__init121.call(this);_class14.prototype.__init122.call(this);_class14.prototype.__init123.call(this);_class14.prototype.__init124.call(this);_class14.prototype.__init125.call(this);_class14.prototype.__init126.call(this);_class14.prototype.__init127.call(this);_class14.prototype.__init128.call(this);_class14.prototype.__init129.call(this);_class14.prototype.__init130.call(this);_class14.prototype.__init131.call(this);_class14.prototype.__init132.call(this);_class14.prototype.__init133.call(this);
4452
4518
  this.historyLimit = Math.max(1, _nullishCoalesce(options.historyLimit, () => ( 200)));
4453
4519
  this.rasterizeSticker = _nullishCoalesce(options.rasterizeSticker, () => ( defaultStickerRasterizer));
4454
4520
  if (options.stickers) this.stickers.set(options.stickers);
4455
4521
  this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
4456
- const seed = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
4457
- this.brushLibrary = _nullishCoalesce(options.brushLibrary, () => ( _chunkXVOP3CGQcjs.createBrushLibrary.call(void 0, { storage: seededStorage(seed) })));
4458
- this.brushEntries = [...builtinLibraryBrushes(), ...seed.map((b) => libraryBrush(_chunkXVOP3CGQcjs.migrateBrushV1.call(void 0, b), false, b))];
4459
- const wanted = _nullishCoalesce(options.brushId, () => ( _chunkXVOP3CGQcjs.DEFAULT_BRUSH_ID));
4460
- const start = _nullishCoalesce(this.findEntry(wanted), () => ( this.findEntry(_chunkXVOP3CGQcjs.DEFAULT_BRUSH_ID)));
4461
- this.brush = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, start.brush);
4522
+ const seed = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
4523
+ this.brushLibrary = _nullishCoalesce(options.brushLibrary, () => ( _chunkEU2ZZA6Lcjs.createBrushLibrary.call(void 0, { storage: seededStorage(seed) })));
4524
+ this.brushEntries = [...builtinLibraryBrushes(), ...seed.map((b) => libraryBrush(_chunkEU2ZZA6Lcjs.migrateBrushV1.call(void 0, b), false, b))];
4525
+ const wanted = _nullishCoalesce(options.brushId, () => ( _chunkEU2ZZA6Lcjs.DEFAULT_BRUSH_ID));
4526
+ const start = _nullishCoalesce(this.findEntry(wanted), () => ( this.findEntry(_chunkEU2ZZA6Lcjs.DEFAULT_BRUSH_ID)));
4527
+ this.brush = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, start.brush);
4462
4528
  this.brushSpec = copyJSON(start.spec);
4463
4529
  this.unsubscribeLibrary = this.brushLibrary.subscribe(() => void this.refreshBrushes().catch(() => void 0));
4464
- if (options.brushLibrary && seed.length) void this.brushLibrary.importFile(seed.map(_chunkXVOP3CGQcjs.brushToJSON)).catch(() => void 0);
4530
+ if (options.brushLibrary && seed.length) void this.brushLibrary.importFile(seed.map(_chunkEU2ZZA6Lcjs.brushToJSON)).catch(() => void 0);
4465
4531
  void this.refreshBrushes().catch(() => void 0);
4466
4532
  this.pendingBrushId = start.brush.id === wanted ? null : wanted;
4467
4533
  this.color = options.color ? parseColor(options.color) : "#1f2937";
@@ -4470,12 +4536,12 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4470
4536
  this.encodeImage = options.encodeImage;
4471
4537
  this.guides = defaultGuides(this.doc.canvas);
4472
4538
  this.wetOptions = options.wet;
4473
- this.wet = new (0, _chunkOKHKA43Lcjs.PaintWetLayers)(
4539
+ this.wet = new (0, _chunkJBB3GDBBcjs.PaintWetLayers)(
4474
4540
  {
4475
4541
  canvas: () => this.doc.canvas,
4476
4542
  paper: () => this.doc.paper,
4477
4543
  layerSurface: (id) => {
4478
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _185 => _185.layer]);
4544
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _189 => _189.layer]);
4479
4545
  return isPixelLayer(l) ? l.surface : null;
4480
4546
  },
4481
4547
  updateSurfaces: (surfaces, rects) => {
@@ -4484,7 +4550,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4484
4550
  this.doc = { ...this.doc, layers };
4485
4551
  this.emit(rects.length ? rects : "all");
4486
4552
  },
4487
- layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _186 => _186.doc, 'access', _187 => _187.light, 'optionalAccess', _188 => _188[id]]), () => ( null)),
4553
+ layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _190 => _190.doc, 'access', _191 => _191.light, 'optionalAccess', _192 => _192[id]]), () => ( null)),
4488
4554
  updateLights: (lights) => {
4489
4555
  let light = this.doc.light;
4490
4556
  for (const [id, surface] of lights) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
@@ -4495,7 +4561,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4495
4561
  },
4496
4562
  options.wet
4497
4563
  );
4498
- this.wet.onDriverDone = () => _optionalChain([this, 'access', _189 => _189.session, 'optionalAccess', _190 => _190.completeWetEnd, 'call', _191 => _191()]);
4564
+ this.wet.onDriverDone = () => _optionalChain([this, 'access', _193 => _193.session, 'optionalAccess', _194 => _194.completeWetEnd, 'call', _195 => _195()]);
4499
4565
  }
4500
4566
  // --- State and events ----------------------------------------------------------
4501
4567
  subscribe(listener) {
@@ -4665,7 +4731,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4665
4731
  if (placement.bottom) this.moveLayer(layer.id, 0, null);
4666
4732
  fn(layer.id);
4667
4733
  if (this.wetOp || this.pendingWetEvents.length) throw new PaintEditorError("Wet paint can't be previewed; suggest it with a dry brush.");
4668
- const found = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _192 => _192.layer]);
4734
+ const found = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _196 => _196.layer]);
4669
4735
  const surface = found && isPixelLayer(found) ? found.surface : null;
4670
4736
  const bounds = surface ? _chunk474IQG74cjs.contentBounds.call(void 0, surface) : null;
4671
4737
  const box = bounds ? clipToCanvas(bounds, this.doc.canvas) : null;
@@ -4718,8 +4784,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4718
4784
  selectedSticker: this.selectedSticker,
4719
4785
  canUndo: this.undoStack.length > 0 && !this.session,
4720
4786
  canRedo: this.redoStack.length > 0 && !this.session,
4721
- undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _193 => _193.label]), () => ( null)),
4722
- redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _194 => _194.label]), () => ( null)),
4787
+ undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _197 => _197.label]), () => ( null)),
4788
+ redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _198 => _198.label]), () => ( null)),
4723
4789
  guides: this.guides,
4724
4790
  swatches: this.swatches,
4725
4791
  mixingPadVersion: this.pad.version,
@@ -4732,10 +4798,10 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4732
4798
  overlay: this.wet.overlay,
4733
4799
  instantDry: this.wet.instantDry,
4734
4800
  speed: this.wet.speed,
4735
- clock: _nullishCoalesce(_optionalChain([this, 'access', _195 => _195.wet, 'access', _196 => _196.world, 'optionalAccess', _197 => _197.clock]), () => ( 0)),
4801
+ clock: _nullishCoalesce(_optionalChain([this, 'access', _199 => _199.wet, 'access', _200 => _200.world, 'optionalAccess', _201 => _201.clock]), () => ( 0)),
4736
4802
  tilt: { ...this.wet.tilt },
4737
4803
  gpu: this.wet.gpuMode,
4738
- gpuActive: Boolean(_optionalChain([this, 'access', _198 => _198.wet, 'access', _199 => _199.world, 'optionalAccess', _200 => _200.gpuActive]))
4804
+ gpuActive: Boolean(_optionalChain([this, 'access', _202 => _202.wet, 'access', _203 => _203.world, 'optionalAccess', _204 => _204.gpuActive]))
4739
4805
  },
4740
4806
  version: this.version
4741
4807
  };
@@ -4754,7 +4820,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4754
4820
  return d;
4755
4821
  }
4756
4822
  // --- History -------------------------------------------------------------------
4757
- __init123() {this.docRevision = 0}
4823
+ __init128() {this.docRevision = 0}
4758
4824
  /**
4759
4825
  * Bumped on every change to the painting (a committed or amended step, undo, redo, opening a
4760
4826
  * document), not on wet-paint frames or view changes. `createPaintEditorDocument` uses it.
@@ -4765,13 +4831,13 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4765
4831
  /** Why the document cannot be replaced or stepped through right now, or `null`. */
4766
4832
  busyReason() {
4767
4833
  if (this.session) return "A stroke is in progress; end or cancel it first.";
4768
- if (_optionalChain([this, 'access', _201 => _201.grouping, 'optionalAccess', _202 => _202.pending]) && !this.grouping.inside) return `"${this.grouping.label}" is still being painted; wait for it to finish first.`;
4834
+ if (_optionalChain([this, 'access', _205 => _205.grouping, 'optionalAccess', _206 => _206.pending]) && !this.grouping.inside) return `"${this.grouping.label}" is still being painted; wait for it to finish first.`;
4769
4835
  if (this.wet.busy) return "Wet paint is mid-step; wait a moment (wetIdle()) first.";
4770
4836
  return null;
4771
4837
  }
4772
4838
  requireIdle(what) {
4773
4839
  if (this.session) throw new PaintEditorError(`A stroke is in progress; end or cancel it before ${what}.`);
4774
- if (_optionalChain([this, 'access', _203 => _203.grouping, 'optionalAccess', _204 => _204.pending]) && !this.grouping.inside) throw new PaintEditorError(`"${this.grouping.label}" is still being painted (one undo step); wait for it to finish before ${what}.`);
4840
+ if (_optionalChain([this, 'access', _207 => _207.grouping, 'optionalAccess', _208 => _208.pending]) && !this.grouping.inside) throw new PaintEditorError(`"${this.grouping.label}" is still being painted (one undo step); wait for it to finish before ${what}.`);
4775
4841
  }
4776
4842
  commit(label, next, before = this.doc) {
4777
4843
  if (this.grouping) {
@@ -4847,9 +4913,9 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4847
4913
  return wetIds;
4848
4914
  }
4849
4915
  /** Records a wet event (for replays) in the document being built. */
4850
- __init124() {this.pendingWetEvents = []}
4916
+ __init129() {this.pendingWetEvents = []}
4851
4917
  logWet(e) {
4852
- this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _205 => _205.wet, 'access', _206 => _206.world, 'optionalAccess', _207 => _207.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
4918
+ this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _209 => _209.wet, 'access', _210 => _210.world, 'optionalAccess', _211 => _211.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
4853
4919
  }
4854
4920
  /** The document with a paint event appended (for replays). */
4855
4921
  withPaintEvent(doc, e) {
@@ -4912,7 +4978,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4912
4978
  // --- Canvas and paper ----------------------------------------------------------
4913
4979
  resolvePaper(paper) {
4914
4980
  if (typeof paper === "string") {
4915
- const p = _chunkOKHKA43Lcjs.paperPreset.call(void 0, paper);
4981
+ const p = _chunkJBB3GDBBcjs.paperPreset.call(void 0, paper);
4916
4982
  if (!p) throw new PaintEditorError(`Unknown paper "${paper}". Call list_papers for the ids.`);
4917
4983
  return p;
4918
4984
  }
@@ -4995,7 +5061,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
4995
5061
  }
4996
5062
  let next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
4997
5063
  for (const id of keptWet) {
4998
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _208 => _208.layer]);
5064
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _212 => _212.layer]);
4999
5065
  if (isPixelLayer(l)) next = { ...next, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, l.offset.x, l.offset.y), offset: { x: 0, y: 0 } })) };
5000
5066
  }
5001
5067
  if (this.wet.world) {
@@ -5023,23 +5089,23 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5023
5089
  this.requireIdle("changing the paper");
5024
5090
  let base = this.doc.paper;
5025
5091
  if (update.preset !== void 0 && update.preset !== this.doc.paper.preset) {
5026
- const p = _chunkOKHKA43Lcjs.paperPreset.call(void 0, update.preset);
5092
+ const p = _chunkJBB3GDBBcjs.paperPreset.call(void 0, update.preset);
5027
5093
  if (!p) throw new PaintEditorError(`Unknown paper "${update.preset}". Call list_papers for the ids.`);
5028
5094
  base = p;
5029
5095
  }
5030
5096
  const { preset: _p, ...rest } = update;
5031
5097
  if (rest.color !== void 0) parseColor(rest.color, "paper color");
5032
- const paper = _chunkOKHKA43Lcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
5098
+ const paper = _chunkJBB3GDBBcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
5033
5099
  const changedKeys = Object.keys(rest).filter((k) => k !== "name");
5034
5100
  if (changedKeys.length && update.preset === void 0) paper.preset = base.preset;
5035
5101
  if (this.wet.world) this.beginWetOp();
5036
5102
  this.commit("Paper", { ...this.doc, paper });
5037
5103
  this.wet.paperChanged();
5038
- return _chunkOKHKA43Lcjs.clonePaper.call(void 0, paper);
5104
+ return _chunkJBB3GDBBcjs.clonePaper.call(void 0, paper);
5039
5105
  }
5040
5106
  // --- Layers --------------------------------------------------------------------
5041
5107
  getLayer(id) {
5042
- return _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _209 => _209.layer]);
5108
+ return _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _213 => _213.layer]);
5043
5109
  }
5044
5110
  /** The active pixel layer (or `undefined`). */
5045
5111
  getActiveLayer() {
@@ -5058,7 +5124,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5058
5124
  walk(this.doc.layers, null, 0);
5059
5125
  return out;
5060
5126
  }
5061
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _210 => _210.parent, 'optionalAccess', _211 => _211.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _212 => _212.path, 'access', _213 => _213.length]), () => ( 0))) {
5127
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _214 => _214.parent, 'optionalAccess', _215 => _215.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _216 => _216.path, 'access', _217 => _217.length]), () => ( 0))) {
5062
5128
  let bounds = null;
5063
5129
  if (l.type === "pixel") {
5064
5130
  const b = _chunk474IQG74cjs.contentBounds.call(void 0, l.surface);
@@ -5075,8 +5141,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5075
5141
  locks: { ..._nullishCoalesce(l.locks, () => ( {})) },
5076
5142
  active: l.id === this.doc.activeLayerId,
5077
5143
  bounds,
5078
- ..._optionalChain([this, 'access', _214 => _214.doc, 'access', _215 => _215.liveStrokes, 'optionalAccess', _216 => _216[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
5079
- ..._optionalChain([l, 'access', _217 => _217.effects, 'optionalAccess', _218 => _218.items, 'access', _219 => _219.length]) ? { effects: l.effects.items.length } : {},
5144
+ ..._optionalChain([this, 'access', _218 => _218.doc, 'access', _219 => _219.liveStrokes, 'optionalAccess', _220 => _220[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
5145
+ ..._optionalChain([l, 'access', _221 => _221.effects, 'optionalAccess', _222 => _222.items, 'access', _223 => _223.length]) ? { effects: l.effects.items.length } : {},
5080
5146
  parentId,
5081
5147
  depth
5082
5148
  };
@@ -5108,7 +5174,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5108
5174
  this.requireIdle("adding a layer");
5109
5175
  const count = _chunkPVJMTLPJcjs.flattenLayers.call(void 0, this.doc.layers).length;
5110
5176
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
5111
- const name = _optionalChain([options, 'access', _220 => _220.name, 'optionalAccess', _221 => _221.trim, 'call', _222 => _222()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
5177
+ const name = _optionalChain([options, 'access', _224 => _224.name, 'optionalAccess', _225 => _225.trim, 'call', _226 => _226()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
5112
5178
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
5113
5179
  let parentId = null;
5114
5180
  let index;
@@ -5120,7 +5186,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5120
5186
  } else if (above) {
5121
5187
  const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above);
5122
5188
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
5123
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _223 => _223.parent, 'optionalAccess', _224 => _224.id]), () => ( null));
5189
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _227 => _227.parent, 'optionalAccess', _228 => _228.id]), () => ( null));
5124
5190
  index = loc.index + 1;
5125
5191
  }
5126
5192
  const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
@@ -5226,7 +5292,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5226
5292
  }
5227
5293
  requireEffect(id, effectId) {
5228
5294
  const l = this.requireLayer(id);
5229
- const items = _nullishCoalesce(_optionalChain([l, 'access', _225 => _225.effects, 'optionalAccess', _226 => _226.items]), () => ( []));
5295
+ const items = _nullishCoalesce(_optionalChain([l, 'access', _229 => _229.effects, 'optionalAccess', _230 => _230.items]), () => ( []));
5230
5296
  const i = items.findIndex((e) => e.id === effectId);
5231
5297
  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.`);
5232
5298
  return i;
@@ -5249,7 +5315,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5249
5315
  }
5250
5316
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
5251
5317
  let active = this.doc.activeLayerId;
5252
- if (active && !_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _227 => _227.filter, 'call', _228 => _228((x) => x.type === "pixel"), 'access', _229 => _229.pop, 'call', _230 => _230(), 'optionalAccess', _231 => _231.id]), () => ( null));
5318
+ if (active && !_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _231 => _231.filter, 'call', _232 => _232((x) => x.type === "pixel"), 'access', _233 => _233.pop, 'call', _234 => _234(), 'optionalAccess', _235 => _235.id]), () => ( null));
5253
5319
  this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.lightWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
5254
5320
  return { removed: id, activeLayerId: active };
5255
5321
  }
@@ -5275,7 +5341,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5275
5341
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
5276
5342
  };
5277
5343
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
5278
- const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _232 => _232.parent, 'optionalAccess', _233 => _233.id]), () => ( null)), loc.index + 1);
5344
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _236 => _236.parent, 'optionalAccess', _237 => _237.id]), () => ( null)), loc.index + 1);
5279
5345
  this.commit("Duplicate layer", this.withWetEvents({ ...this.doc, layers, activeLayerId: dup.id, ...this.doc.thick ? { thick } : {}, ...this.doc.stickers ? { stickers } : {}, ...this.doc.liveStrokes ? { liveStrokes } : {}, ...this.doc.light ? { light } : {} }));
5280
5346
  return this.describeLayer(dup);
5281
5347
  }
@@ -5284,7 +5350,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5284
5350
  this.requireIdle("moving a layer");
5285
5351
  const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
5286
5352
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
5287
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _234 => _234.parent, 'optionalAccess', _235 => _235.id]), () => ( null)) : parentId;
5353
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _238 => _238.parent, 'optionalAccess', _239 => _239.id]), () => ( null)) : parentId;
5288
5354
  if (target) {
5289
5355
  const g = this.requireLayer(target);
5290
5356
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
@@ -5303,7 +5369,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5303
5369
  const pre = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
5304
5370
  if (pre) {
5305
5371
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
5306
- this.dryLayersFirst([id, _optionalChain([sib, 'access', _236 => _236[pre.index - 1], 'optionalAccess', _237 => _237.id])].filter((x) => Boolean(x)));
5372
+ this.dryLayersFirst([id, _optionalChain([sib, 'access', _240 => _240[pre.index - 1], 'optionalAccess', _241 => _241.id])].filter((x) => Boolean(x)));
5307
5373
  }
5308
5374
  const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
5309
5375
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
@@ -5323,7 +5389,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5323
5389
  const merged = { ...below, surface, offset: { x: 0, y: 0 } };
5324
5390
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
5325
5391
  const toDoc = (t, l) => t ? _chunk474IQG74cjs.translateSurface.call(void 0, t, l.offset.x, l.offset.y) : void 0;
5326
- const mergedLight = _optionalChain([this, 'access', _238 => _238.doc, 'access', _239 => _239.light, 'optionalAccess', _240 => _240[upper.id]]) || _optionalChain([this, 'access', _241 => _241.doc, 'access', _242 => _242.light, 'optionalAccess', _243 => _243[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _244 => _244.doc, 'access', _245 => _245.light, 'optionalAccess', _246 => _246[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _247 => _247.doc, 'access', _248 => _248.light, 'optionalAccess', _249 => _249[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
5392
+ const mergedLight = _optionalChain([this, 'access', _242 => _242.doc, 'access', _243 => _243.light, 'optionalAccess', _244 => _244[upper.id]]) || _optionalChain([this, 'access', _245 => _245.doc, 'access', _246 => _246.light, 'optionalAccess', _247 => _247[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _248 => _248.doc, 'access', _249 => _249.light, 'optionalAccess', _250 => _250[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _251 => _251.doc, 'access', _252 => _252.light, 'optionalAccess', _253 => _253[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
5327
5393
  const lightAfter = _nullishCoalesce(this.lightWithout([upper.id, below.id]).light, () => ( (this.doc.light ? { ...this.doc.light } : void 0)));
5328
5394
  const light = mergedLight ? { ..._nullishCoalesce(lightAfter, () => ( {})), [below.id]: mergedLight } : lightAfter;
5329
5395
  this.commit("Merge down", this.withWetEvents({ ...this.doc, layers, activeLayerId: below.id, ...this.thickWithout([upper.id]), ...this.stickersWithout([upper.id, below.id]), ...this.liveStrokesWithout([upper.id, below.id]), ...light ? { light } : {} }));
@@ -5338,7 +5404,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5338
5404
  this.wet.world.removeLane(l.id);
5339
5405
  }
5340
5406
  const bounds = this.describeLayer(l).bounds;
5341
- this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _250 => _250.doc, 'access', _251 => _251.liveStrokes, 'optionalAccess', _252 => _252[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
5407
+ this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _254 => _254.doc, 'access', _255 => _255.liveStrokes, 'optionalAccess', _256 => _256[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
5342
5408
  return { layerId: l.id, bounds };
5343
5409
  }
5344
5410
  /**
@@ -5348,8 +5414,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5348
5414
  fillLayer(options = {}) {
5349
5415
  this.requireIdle("filling");
5350
5416
  const fillTarget = this.paintTarget(options.layerId, "fill");
5351
- if (_optionalChain([this, 'access', _253 => _253.doc, 'access', _254 => _254.stickers, 'optionalAccess', _255 => _255[fillTarget.id], 'optionalAccess', _256 => _256.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
5352
- if (_optionalChain([this, 'access', _257 => _257.doc, 'access', _258 => _258.liveStrokes, 'optionalAccess', _259 => _259[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).`);
5417
+ if (_optionalChain([this, 'access', _257 => _257.doc, 'access', _258 => _258.stickers, 'optionalAccess', _259 => _259[fillTarget.id], 'optionalAccess', _260 => _260.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
5418
+ if (_optionalChain([this, 'access', _261 => _261.doc, 'access', _262 => _262.liveStrokes, 'optionalAccess', _263 => _263[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).`);
5353
5419
  this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
5354
5420
  const l = this.paintTarget(options.layerId, "fill");
5355
5421
  const color = options.color === void 0 ? this.color : parseColor(options.color);
@@ -5362,13 +5428,13 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5362
5428
  if (!_chunk2VX55NFMcjs.isBlendMode.call(void 0, blend)) throw new PaintEditorError(`Unknown blend mode "${blend}".`);
5363
5429
  const { width, height } = this.doc.canvas;
5364
5430
  const rect = { x: 0, y: 0, width, height };
5365
- const coverage = new (0, _chunkFQPUF2W2cjs.CoverageMap)();
5431
+ const coverage = new (0, _chunkNIBFKXMDcjs.CoverageMap)();
5366
5432
  const depth = grainAmount * this.doc.paper.depth;
5367
5433
  const grain = depth > 0 ? paperGrain(this.doc.paper) : null;
5368
5434
  for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, rect)) {
5369
5435
  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) };
5370
5436
  const vals = new Float32Array(r.width * r.height);
5371
- for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkPXDIAYB6cjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
5437
+ 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;
5372
5438
  coverage.accumulate(r, vals, 1);
5373
5439
  }
5374
5440
  const apply = {
@@ -5382,7 +5448,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5382
5448
  offset: l.offset
5383
5449
  };
5384
5450
  const surface = this.applyCoverage(l, coverage, rect, apply);
5385
- const lit = _optionalChain([this, 'access', _260 => _260.doc, 'access', _261 => _261.light, 'optionalAccess', _262 => _262[l.id]]);
5451
+ const lit = _optionalChain([this, 'access', _264 => _264.doc, 'access', _265 => _265.light, 'optionalAccess', _266 => _266[l.id]]);
5386
5452
  const light = lit ? withLayerLight(this.doc.light, l.id, scaleLight(lit, 1 - opacity)) : void 0;
5387
5453
  this.commit("Fill layer", this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), ...light ? { light } : {} }), { kind: "fill", layerId: l.id, data: { color, opacity, grain: grainAmount, pressure, blend } }));
5388
5454
  return { layerId: l.id, bounds: rect };
@@ -5392,8 +5458,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5392
5458
  const tiles = new Map(base.tiles);
5393
5459
  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 })) {
5394
5460
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
5395
- const src = _nullishCoalesce(_optionalChain([base, 'access', _263 => _263.tiles, 'access', _264 => _264.get, 'call', _265 => _265(key), 'optionalAccess', _266 => _266.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
5396
- const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkFQPUF2W2cjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
5461
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _267 => _267.tiles, 'access', _268 => _268.get, 'call', _269 => _269(key), 'optionalAccess', _270 => _270.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
5462
+ const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkNIBFKXMDcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
5397
5463
  if (tile) tiles.set(key, tile);
5398
5464
  else tiles.delete(key);
5399
5465
  }
@@ -5425,7 +5491,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5425
5491
  }
5426
5492
  /** The effect a layer is drawn from, or `undefined` for other layers. */
5427
5493
  getEffectLayer(layerId) {
5428
- return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _267 => _267.doc, 'access', _268 => _268.effectLayers, 'optionalAccess', _269 => _269[layerId]]) : void 0;
5494
+ return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _271 => _271.doc, 'access', _272 => _272.effectLayers, 'optionalAccess', _273 => _273[layerId]]) : void 0;
5429
5495
  }
5430
5496
  /** The effect paper (without its pixels), or `null`. */
5431
5497
  getPaperEffect() {
@@ -5462,8 +5528,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5462
5528
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
5463
5529
  effectTarget(layerId, what) {
5464
5530
  const l = this.paintTarget(layerId, what);
5465
- if (_optionalChain([this, 'access', _270 => _270.doc, 'access', _271 => _271.stickers, 'optionalAccess', _272 => _272[l.id], 'optionalAccess', _273 => _273.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
5466
- if (_optionalChain([this, 'access', _274 => _274.doc, 'access', _275 => _275.liveStrokes, 'optionalAccess', _276 => _276[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).`);
5531
+ if (_optionalChain([this, 'access', _274 => _274.doc, 'access', _275 => _275.stickers, 'optionalAccess', _276 => _276[l.id], 'optionalAccess', _277 => _277.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
5532
+ if (_optionalChain([this, 'access', _278 => _278.doc, 'access', _279 => _279.liveStrokes, 'optionalAccess', _280 => _280[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).`);
5467
5533
  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.`);
5468
5534
  return l;
5469
5535
  }
@@ -5502,8 +5568,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5502
5568
  const was = this.doc.paperEffect;
5503
5569
  const paperEffect = {
5504
5570
  ...this.sourceOf(d, values, options.time),
5505
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _277 => _277.opacity]))), () => ( 1)),
5506
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _278 => _278.blend]))), () => ( "multiply")),
5571
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _281 => _281.opacity]))), () => ( 1)),
5572
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _282 => _282.blend]))), () => ( "multiply")),
5507
5573
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
5508
5574
  version: nextPaperEffectVersion()
5509
5575
  };
@@ -5556,8 +5622,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5556
5622
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
5557
5623
  const loc = above ? _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above) : null;
5558
5624
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
5559
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _279 => _279.name, 'optionalAccess', _280 => _280.trim, 'call', _281 => _281()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5560
- const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _282 => _282.parent, 'optionalAccess', _283 => _283.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5625
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _283 => _283.name, 'optionalAccess', _284 => _284.trim, 'call', _285 => _285()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5626
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _286 => _286.parent, 'optionalAccess', _287 => _287.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5561
5627
  const source = this.sourceOf(d, values, options.time);
5562
5628
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
5563
5629
  return { layer: this.describeLayer(layer), source };
@@ -5635,7 +5701,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5635
5701
  this.checkTime(source.time);
5636
5702
  let map;
5637
5703
  try {
5638
- map = _chunkOKHKA43Lcjs.readEffectStrokeMap.call(void 0, source.map);
5704
+ map = _chunkJBB3GDBBcjs.readEffectStrokeMap.call(void 0, source.map);
5639
5705
  } catch (e) {
5640
5706
  throw new PaintEditorError(e.message);
5641
5707
  }
@@ -5666,9 +5732,9 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5666
5732
  }
5667
5733
  /** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
5668
5734
  effectPaintImage(p) {
5669
- const key = _chunkOKHKA43Lcjs.effectPaintKey.call(void 0, p);
5735
+ const key = _chunkJBB3GDBBcjs.effectPaintKey.call(void 0, p);
5670
5736
  const img = this.effectPaintPixels.get(key);
5671
- const size = _chunkOKHKA43Lcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5737
+ const size = _chunkJBB3GDBBcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5672
5738
  if (!img || img.width !== size.width || img.height !== size.height) return null;
5673
5739
  this.effectPaintPixels.delete(key);
5674
5740
  this.effectPaintPixels.set(key, img);
@@ -5682,7 +5748,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5682
5748
  const what = `the effect "${p.effect}"${p.provider ? ` from provider "${p.provider}"` : ""}`;
5683
5749
  if (!provider) throw new PaintEditorError(`Effect paint needs ${what}, but no effects provider is registered; register it (setEffectsProvider) and try again.`);
5684
5750
  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.`);
5685
- const { width, height } = _chunkOKHKA43Lcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5751
+ const { width, height } = _chunkJBB3GDBBcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5686
5752
  let pixels;
5687
5753
  try {
5688
5754
  pixels = await this.effectsRenderer.render(provider, p.effect, { width, height }, { time: p.time, values: p.values });
@@ -5690,7 +5756,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5690
5756
  throw new PaintEditorError(`Effect paint could not render ${what}: ${e instanceof Error ? e.message : String(e)}`);
5691
5757
  }
5692
5758
  const img = { width, height, data: new Uint8ClampedArray(pixels.data), ...p.map ? { map: p.map } : {} };
5693
- this.effectPaintPixels.set(_chunkOKHKA43Lcjs.effectPaintKey.call(void 0, p), img);
5759
+ this.effectPaintPixels.set(_chunkJBB3GDBBcjs.effectPaintKey.call(void 0, p), img);
5694
5760
  while (this.effectPaintPixels.size > _PaintEditorController.EFFECT_PAINT_CACHE) this.effectPaintPixels.delete(this.effectPaintPixels.keys().next().value);
5695
5761
  return img;
5696
5762
  }
@@ -5701,7 +5767,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5701
5767
  async prepareEffectPaints(paints2) {
5702
5768
  const seen = /* @__PURE__ */ new Set();
5703
5769
  for (const p of paints2) {
5704
- const key = _chunkOKHKA43Lcjs.effectPaintKey.call(void 0, p);
5770
+ const key = _chunkJBB3GDBBcjs.effectPaintKey.call(void 0, p);
5705
5771
  if (seen.has(key)) continue;
5706
5772
  seen.add(key);
5707
5773
  await this.renderEffectPaint(p);
@@ -5710,7 +5776,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5710
5776
  /** Renders the effect paints of recorded strokes (default all of them) before a replay. */
5711
5777
  async prepareStrokeEffects(strokeIds) {
5712
5778
  const ids = strokeIds ? new Set(strokeIds) : null;
5713
- const paints2 = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _284 => _284.paint, 'optionalAccess', _285 => _285.type]) === "effect").map((s) => s.paint);
5779
+ const paints2 = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _288 => _288.paint, 'optionalAccess', _289 => _289.type]) === "effect").map((s) => s.paint);
5714
5780
  await this.prepareEffectPaints(paints2);
5715
5781
  }
5716
5782
  /** A small preview of the effect paint (a PNG data URL `size` px wide), or `null` without a rendered one. */
@@ -5739,11 +5805,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5739
5805
  * its pixels are not rendered.
5740
5806
  */
5741
5807
  strokeEffect(init, brush) {
5742
- if (!_chunkXVOP3CGQcjs.brushTakesPaint.call(void 0, brush)) return null;
5808
+ if (!_chunkEU2ZZA6Lcjs.brushTakesPaint.call(void 0, brush)) return null;
5743
5809
  let source = null;
5744
5810
  if (init.paint !== void 0) {
5745
- if (!_chunkOKHKA43Lcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5746
- source = _chunkOKHKA43Lcjs.readPaintEffectPaint.call(void 0, init.paint);
5811
+ if (!_chunkJBB3GDBBcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5812
+ source = _chunkJBB3GDBBcjs.readPaintEffectPaint.call(void 0, init.paint);
5747
5813
  if (!source) throw new PaintEditorError("The stroke's effect paint needs an effect id and values (getEffectPaint returns one).");
5748
5814
  } else if (init.color === void 0 && !brush.paint) {
5749
5815
  if (this.effectPaintPending) throw new PaintEditorError(`The effect paint "${this.effectPaintPending.effect}" is still rendering; wait for set_effect_paint to finish, then paint.`);
@@ -5773,14 +5839,14 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5773
5839
  const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
5774
5840
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
5775
5841
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
5776
- const relief = _optionalChain([this, 'access', _286 => _286.doc, 'access', _287 => _287.thick, 'optionalAccess', _288 => _288[l.id]]);
5842
+ const relief = _optionalChain([this, 'access', _290 => _290.doc, 'access', _291 => _291.thick, 'optionalAccess', _292 => _292[l.id]]);
5777
5843
  if (heightInput && relief) {
5778
5844
  const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
5779
5845
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
5780
5846
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
5781
5847
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
5782
5848
  }
5783
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _289 => _289.inputs, 'access', _290 => _290.find, 'call', _291 => _291((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _292 => _292.name])), 'optionalAccess', _293 => _293.name]), () => ( "source"));
5849
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _293 => _293.inputs, 'access', _294 => _294.find, 'call', _295 => _295((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _296 => _296.name])), 'optionalAccess', _297 => _297.name]), () => ( "source"));
5784
5850
  if (sourceInput !== "source") {
5785
5851
  inputs[sourceInput] = inputs.source;
5786
5852
  delete inputs.source;
@@ -5796,11 +5862,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5796
5862
  return this.brushEntries.find((e) => e.brush.id === id);
5797
5863
  }
5798
5864
  findBrush(id) {
5799
- return _optionalChain([this, 'access', _294 => _294.findEntry, 'call', _295 => _295(id), 'optionalAccess', _296 => _296.brush]);
5865
+ return _optionalChain([this, 'access', _298 => _298.findEntry, 'call', _299 => _299(id), 'optionalAccess', _300 => _300.brush]);
5800
5866
  }
5801
5867
  requireEntry(id) {
5802
5868
  const e = this.findEntry(id);
5803
- if (!e) throw new PaintEditorError(`Unknown brush "${id}". ${_chunkXVOP3CGQcjs.closest.call(void 0, id, this.brushEntries.map((x) => x.brush.id))}Call list_brush_presets for the ids.`);
5869
+ if (!e) throw new PaintEditorError(`Unknown brush "${id}". ${_chunkEU2ZZA6Lcjs.closest.call(void 0, id, this.brushEntries.map((x) => x.brush.id))}Call list_brush_presets for the ids.`);
5804
5870
  return e;
5805
5871
  }
5806
5872
  requireBrush(id) {
@@ -5808,7 +5874,10 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5808
5874
  }
5809
5875
  /** Reads the library again (after a change anywhere it is shared). */
5810
5876
  refreshBrushes() {
5811
- const run = this.brushLibrary.list().then((entries) => {
5877
+ const library = this.brushLibrary;
5878
+ const sources = typeof library.listSources === "function" ? library.listSources().catch(() => []) : Promise.resolve([]);
5879
+ const run = Promise.all([library.list(), sources]).then(([entries, list]) => {
5880
+ this.brushSources.set(list);
5812
5881
  this.brushEntries = entries.map((e) => libraryBrush(e.brush, e.builtin));
5813
5882
  this.library = null;
5814
5883
  const pending = this.pendingBrushId;
@@ -5826,11 +5895,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5826
5895
  /** A library brush by id, as the engine paints it (`undefined` when unknown). */
5827
5896
  getBrush(id) {
5828
5897
  const b = this.findBrush(id);
5829
- return b ? _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
5898
+ return b ? _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
5830
5899
  }
5831
5900
  /** A library brush by id as stored (its facets), or without an id the active brush as edited. */
5832
5901
  getBrushSpec(id) {
5833
- const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _297 => _297.findEntry, 'call', _298 => _298(id), 'optionalAccess', _299 => _299.spec]);
5902
+ const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _301 => _301.findEntry, 'call', _302 => _302(id), 'optionalAccess', _303 => _303.spec]);
5834
5903
  return spec ? copyJSON(spec) : void 0;
5835
5904
  }
5836
5905
  /**
@@ -5844,7 +5913,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5844
5913
  const baseSpec = entry ? entry.spec : this.brushSpec;
5845
5914
  if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
5846
5915
  const unchanged = !Object.keys(changes).length;
5847
- const next = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
5916
+ const next = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
5848
5917
  if (entry) this.takeBrushColour(entry.spec);
5849
5918
  this.useBrush(next, unchanged ? baseSpec : brushSpecOf(next, baseSpec), unchanged && base.builtin === true);
5850
5919
  return this.brush;
@@ -5862,8 +5931,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5862
5931
  const base = copyJSON(entry ? entry.spec : this.brushSpec);
5863
5932
  for (const k of unset) delete base[k];
5864
5933
  const spec = this.readBrushPatch(base, patch, problems);
5865
- if (entry || _optionalChain([patch, 'access', _300 => _300.colour, 'optionalAccess', _301 => _301.default]) !== void 0) this.takeBrushColour(spec);
5866
- this.useBrush(unchanged && entry ? entry.brush : _chunkXVOP3CGQcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _302 => _302.builtin]) === true);
5934
+ if (entry || _optionalChain([patch, 'access', _304 => _304.colour, 'optionalAccess', _305 => _305.default]) !== void 0) this.takeBrushColour(spec);
5935
+ this.useBrush(unchanged && entry ? entry.brush : _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _306 => _306.builtin]) === true);
5867
5936
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
5868
5937
  }
5869
5938
  /**
@@ -5873,15 +5942,15 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5873
5942
  */
5874
5943
  setBrushSpec(spec) {
5875
5944
  const problems = [];
5876
- const paint = _optionalChain([spec, 'access', _303 => _303.colour, 'optionalAccess', _304 => _304.default]);
5945
+ const paint = _optionalChain([spec, 'access', _307 => _307.colour, 'optionalAccess', _308 => _308.default]);
5877
5946
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
5878
5947
  let next;
5879
5948
  try {
5880
- next = _chunkXVOP3CGQcjs.normalizeBrushSpec.call(void 0, { ...spec, id: this.brush.id }, problems);
5949
+ next = _chunkEU2ZZA6Lcjs.normalizeBrushSpec.call(void 0, { ...spec, id: this.brush.id }, problems);
5881
5950
  } catch (e) {
5882
5951
  throw new PaintEditorError(e.message);
5883
5952
  }
5884
- this.useBrush(_chunkXVOP3CGQcjs.resolveBrush.call(void 0, next), next, false);
5953
+ this.useBrush(_chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, next), next, false);
5885
5954
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
5886
5955
  }
5887
5956
  /**
@@ -5890,29 +5959,29 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5890
5959
  */
5891
5960
  brushChanges(patch, from) {
5892
5961
  const entry = typeof from === "string" ? this.requireEntry(from) : null;
5893
- const base = entry ? entry.brush : typeof from === "object" ? _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, from, from) : this.brush;
5894
- const spec = entry ? entry.spec : typeof from === "object" ? _chunkXVOP3CGQcjs.migrateBrushV1.call(void 0, base) : this.brushSpec;
5895
- return engineChanges(base, _chunkXVOP3CGQcjs.resolveBrush.call(void 0, this.readBrushPatch(spec, patch, [])));
5962
+ const base = entry ? entry.brush : typeof from === "object" ? _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, from, from) : this.brush;
5963
+ const spec = entry ? entry.spec : typeof from === "object" ? _chunkEU2ZZA6Lcjs.migrateBrushV1.call(void 0, base) : this.brushSpec;
5964
+ return engineChanges(base, _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, this.readBrushPatch(spec, patch, [])));
5896
5965
  }
5897
5966
  readBrushPatch(base, patch, problems) {
5898
5967
  const { id: _id, name, ...rest } = patch;
5899
- const paint = _optionalChain([rest, 'access', _305 => _305.colour, 'optionalAccess', _306 => _306.default]);
5968
+ const paint = _optionalChain([rest, 'access', _309 => _309.colour, 'optionalAccess', _310 => _310.default]);
5900
5969
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
5901
5970
  try {
5902
- return _chunkXVOP3CGQcjs.normalizeBrushSpec.call(void 0, _chunkDT4YQUGTcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
5971
+ return _chunkEU2ZZA6Lcjs.normalizeBrushSpec.call(void 0, _chunkYXP6X3SYcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
5903
5972
  } catch (e) {
5904
5973
  throw new PaintEditorError(e.message);
5905
5974
  }
5906
5975
  }
5907
5976
  useBrush(next, spec, builtin) {
5908
- next = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, next, next);
5977
+ next = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, next, next);
5909
5978
  if (builtin) next.builtin = true;
5910
5979
  else delete next.builtin;
5911
5980
  this.brush = next;
5912
5981
  this.brushSpec = { ...copyJSON(spec), id: next.id, name: next.name };
5913
5982
  this.pendingBrushId = null;
5914
5983
  this.emit([]);
5915
- const refs = _chunkOKHKA43Lcjs.brushStickerRefs.call(void 0, next);
5984
+ const refs = _chunkJBB3GDBBcjs.brushStickerRefs.call(void 0, next);
5916
5985
  if (refs.length) void this.prepareStickers(refs).catch(() => this.emit([]));
5917
5986
  }
5918
5987
  /**
@@ -5921,9 +5990,9 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5921
5990
  * saved brush.
5922
5991
  */
5923
5992
  async saveBrush(options) {
5924
- if (!_chunkXVOP3CGQcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
5993
+ if (!_chunkEU2ZZA6Lcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
5925
5994
  if (this.brushLibrary.isBuiltin(options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
5926
- const spec = options.brush ? brushSpecOf(_chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, options.brush, this.brush), this.brushSpec) : this.brushSpec;
5995
+ const spec = options.brush ? brushSpecOf(_chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, options.brush, this.brush), this.brushSpec) : this.brushSpec;
5927
5996
  const { brush } = await libraryCall(() => this.brushLibrary.save({ ...spec, id: options.id, name: _nullishCoalesce(options.name, () => ( spec.name)) }, { overwrite: true }));
5928
5997
  await this.refreshBrushes();
5929
5998
  return this.requireBrush(brush.id);
@@ -5936,7 +6005,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5936
6005
  }
5937
6006
  /** The user's saved brushes, as the engine paints them. */
5938
6007
  getUserBrushes() {
5939
- return this.brushEntries.filter((e) => !e.builtin).map((e) => _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, e.brush, e.brush));
6008
+ return this.brushEntries.filter((e) => !e.builtin).map((e) => _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, e.brush, e.brush));
5940
6009
  }
5941
6010
  /** A brush library file (version 2) of the given brushes (default: the user's brushes). */
5942
6011
  exportBrushes(ids) {
@@ -5955,13 +6024,13 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5955
6024
  /** A thumbnail of a brush: a test stroke on the current paper. */
5956
6025
  brushThumbnail(id, options = {}) {
5957
6026
  const b = id === this.brush.id ? this.brush : this.requireBrush(id);
5958
- return renderBrushThumbnail(b, { paper: this.doc.paper, width: options.width, height: options.height, color: options.color ? parseColor(options.color) : this.color });
6027
+ return renderBrushThumbnail(b, { paper: this.doc.paper, width: options.width, height: options.height, color: options.color ? parseColor(options.color) : this.color, stampArt: this.stampArt });
5959
6028
  }
5960
6029
  // --- Colour --------------------------------------------------------------------
5961
6030
 
5962
- __init125() {this.colorLocked = false}
6031
+ __init130() {this.colorLocked = false}
5963
6032
  /** The brush default colour the paint colour came from (resolved again when the scheme changes), or `null`. */
5964
- __init126() {this.brushColour = null}
6033
+ __init131() {this.brushColour = null}
5965
6034
  /**
5966
6035
  * The host's colour scheme: a paint colour that came from a brush's light / dark default
5967
6036
  * resolves to the new side. Editor state, not an undo step.
@@ -5972,7 +6041,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5972
6041
  this.colorScheme = next;
5973
6042
  const hex2 = this.brushColour ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, this.brushColour, next) : null;
5974
6043
  if (hex2) this.color = hex2;
5975
- const refs = _chunkOKHKA43Lcjs.brushStickerRefs.call(void 0, this.brush);
6044
+ const refs = _chunkJBB3GDBBcjs.brushStickerRefs.call(void 0, this.brush);
5976
6045
  if (refs.some((r) => !_chunkRDFHWAHLcjs.editorStampOf.call(void 0, r))) void this.prepareStickers(refs).catch(() => this.emit([]));
5977
6046
  this.emit([]);
5978
6047
  }
@@ -5989,7 +6058,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
5989
6058
  */
5990
6059
  takeBrushColour(spec) {
5991
6060
  if (this.colorLocked) return;
5992
- const d = _optionalChain([spec, 'access', _307 => _307.colour, 'optionalAccess', _308 => _308.default]);
6061
+ const d = _optionalChain([spec, 'access', _311 => _311.colour, 'optionalAccess', _312 => _312.default]);
5993
6062
  const hex2 = d !== void 0 ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
5994
6063
  if (!hex2) return;
5995
6064
  this.color = hex2;
@@ -6000,8 +6069,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6000
6069
  }
6001
6070
  /** A brush that always paints its own colour (`colour.own`): that colour, resolved for the scheme now; else `null`. */
6002
6071
  ownColour(brushId) {
6003
- const spec = brushId !== void 0 ? _optionalChain([this, 'access', _309 => _309.findEntry, 'call', _310 => _310(brushId), 'optionalAccess', _311 => _311.spec]) : this.brushSpec;
6004
- const d = _optionalChain([spec, 'optionalAccess', _312 => _312.colour, 'optionalAccess', _313 => _313.own]) ? spec.colour.default : void 0;
6072
+ const spec = brushId !== void 0 ? _optionalChain([this, 'access', _313 => _313.findEntry, 'call', _314 => _314(brushId), 'optionalAccess', _315 => _315.spec]) : this.brushSpec;
6073
+ const d = _optionalChain([spec, 'optionalAccess', _316 => _316.colour, 'optionalAccess', _317 => _317.own]) ? spec.colour.default : void 0;
6005
6074
  return d !== void 0 ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
6006
6075
  }
6007
6076
  /** Sets the paint colour (and goes back to one colour from gradient paint). */
@@ -6023,9 +6092,9 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6023
6092
  setPaint(paint) {
6024
6093
  let p;
6025
6094
  try {
6026
- p = _chunkFQPUF2W2cjs.parsePaintSource.call(void 0, paint);
6095
+ p = _chunkNIBFKXMDcjs.parsePaintSource.call(void 0, paint);
6027
6096
  } catch (e) {
6028
- if (e instanceof _chunkFQPUF2W2cjs.PaintSourceError) throw new PaintEditorError(e.message);
6097
+ if (e instanceof _chunkNIBFKXMDcjs.PaintSourceError) throw new PaintEditorError(e.message);
6029
6098
  throw e;
6030
6099
  }
6031
6100
  if (p.type === "color") {
@@ -6044,20 +6113,20 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6044
6113
  * brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
6045
6114
  */
6046
6115
  strokeGradient(init, brush, color) {
6047
- if (!_chunkXVOP3CGQcjs.brushTakesPaint.call(void 0, brush)) return null;
6116
+ if (!_chunkEU2ZZA6Lcjs.brushTakesPaint.call(void 0, brush)) return null;
6048
6117
  let g = null;
6049
6118
  if (init.paint !== void 0) {
6050
- if (_chunkOKHKA43Lcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
6119
+ if (_chunkJBB3GDBBcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
6051
6120
  const p = this.readStrokePaint(init.paint);
6052
6121
  g = p.type === "gradient" ? p : null;
6053
6122
  } else g = _nullishCoalesce(brush.paint, () => ( (init.color === void 0 ? this.gradient : null)));
6054
- return g ? _chunkFQPUF2W2cjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
6123
+ return g ? _chunkNIBFKXMDcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
6055
6124
  }
6056
6125
  readStrokePaint(raw) {
6057
6126
  try {
6058
- return _chunkFQPUF2W2cjs.parsePaintSource.call(void 0, raw);
6127
+ return _chunkNIBFKXMDcjs.parsePaintSource.call(void 0, raw);
6059
6128
  } catch (e) {
6060
- if (e instanceof _chunkFQPUF2W2cjs.PaintSourceError) throw new PaintEditorError(e.message);
6129
+ if (e instanceof _chunkNIBFKXMDcjs.PaintSourceError) throw new PaintEditorError(e.message);
6061
6130
  throw e;
6062
6131
  }
6063
6132
  }
@@ -6091,14 +6160,14 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6091
6160
  // --- Mixer Brush ---------------------------------------------------------------
6092
6161
  /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */
6093
6162
  loadMixerBrush(color) {
6094
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
6095
- this.mixerLoad = _chunkFQPUF2W2cjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
6163
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
6164
+ this.mixerLoad = _chunkNIBFKXMDcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
6096
6165
  this.emit([]);
6097
6166
  return this.mixerLoad;
6098
6167
  }
6099
6168
  /** Empties the pickup well (and with `emptyReservoir` the loaded paint too). */
6100
6169
  cleanMixerBrush(emptyReservoir = false) {
6101
- this.mixerLoad = emptyReservoir ? _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD : _chunkFQPUF2W2cjs.cleanMixer.call(void 0, this.mixerLoad);
6170
+ this.mixerLoad = emptyReservoir ? _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD : _chunkNIBFKXMDcjs.cleanMixer.call(void 0, this.mixerLoad);
6102
6171
  this.emit([]);
6103
6172
  return this.mixerLoad;
6104
6173
  }
@@ -6121,7 +6190,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6121
6190
  // --- Strokes -------------------------------------------------------------------
6122
6191
  strokeBrush(init) {
6123
6192
  let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
6124
- if (init.brush) brush = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
6193
+ if (init.brush) brush = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
6125
6194
  return brush;
6126
6195
  }
6127
6196
  /**
@@ -6137,7 +6206,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6137
6206
  return symmetryCopies(this.guides.symmetry);
6138
6207
  }
6139
6208
  sessionFor(doc, init, host) {
6140
- if (init.paint !== void 0 && !_chunkOKHKA43Lcjs.isPaintEffectPaint.call(void 0, init.paint)) {
6209
+ if (init.paint !== void 0 && !_chunkJBB3GDBBcjs.isPaintEffectPaint.call(void 0, init.paint)) {
6141
6210
  const p = this.readStrokePaint(init.paint);
6142
6211
  if (p.type === "color") init = { ...init, color: p.color, paint: void 0 };
6143
6212
  else init = { ...init, paint: p };
@@ -6154,30 +6223,30 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6154
6223
  return l;
6155
6224
  })();
6156
6225
  const brush = this.strokeBrush(init);
6157
- if (this.previewing && _chunkXVOP3CGQcjs.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.`);
6226
+ if (this.previewing && _chunkEU2ZZA6Lcjs.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.`);
6158
6227
  const effect = this.strokeEffect(init, brush);
6159
6228
  if (brush.light.amount > 0) {
6160
6229
  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).`);
6161
6230
  }
6162
- if (_optionalChain([doc, 'access', _314 => _314.liveStrokes, 'optionalAccess', _315 => _315[layer.id]])) {
6231
+ if (_optionalChain([doc, 'access', _318 => _318.liveStrokes, 'optionalAccess', _319 => _319[layer.id]])) {
6163
6232
  const why = liveStrokeRefusal(brush);
6164
6233
  if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
6165
6234
  }
6166
- if (_optionalChain([doc, 'access', _316 => _316.liveStrokes, 'optionalAccess', _317 => _317[layer.id]]) && _optionalChain([effect, 'optionalAccess', _318 => _318.source, 'access', _319 => _319.live])) {
6167
- const key = _chunkOKHKA43Lcjs.effectPaintKey.call(void 0, effect.source);
6235
+ if (_optionalChain([doc, 'access', _320 => _320.liveStrokes, 'optionalAccess', _321 => _321[layer.id]]) && _optionalChain([effect, 'optionalAccess', _322 => _322.source, 'access', _323 => _323.live])) {
6236
+ const key = _chunkJBB3GDBBcjs.effectPaintKey.call(void 0, effect.source);
6168
6237
  const { sources } = this.liveEffects(doc);
6169
- if (!sources.some((p) => _chunkOKHKA43Lcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
6238
+ if (!sources.some((p) => _chunkJBB3GDBBcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
6170
6239
  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.`);
6171
6240
  }
6172
6241
  }
6173
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _320 => _320.stickers, 'optionalAccess', _321 => _321[layer.id], 'optionalAccess', _322 => _322.length]));
6242
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _324 => _324.stickers, 'optionalAccess', _325 => _325[layer.id], 'optionalAccess', _326 => _326.length]));
6174
6243
  if (brush.engine === "sticker") {
6175
6244
  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.`);
6176
6245
  } else if (stickerLayer) {
6177
6246
  throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
6178
6247
  }
6179
6248
  let wet;
6180
- if (_chunkXVOP3CGQcjs.isWetBrush.call(void 0, brush)) {
6249
+ if (_chunkEU2ZZA6Lcjs.isWetBrush.call(void 0, brush)) {
6181
6250
  this.requireWetIdle("painting");
6182
6251
  if (layer.offset.x || layer.offset.y) {
6183
6252
  const moved = { ...layer, surface: _chunk474IQG74cjs.translateSurface.call(void 0, layer.surface, layer.offset.x, layer.offset.y), offset: { x: 0, y: 0 } };
@@ -6192,12 +6261,12 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6192
6261
  const world = this.wet.ensureLane(layer.id, brush.wet.medium);
6193
6262
  const id = layer.id;
6194
6263
  const wetColor = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
6195
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, wetColor);
6264
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, wetColor);
6196
6265
  const wetGradient = this.strokeGradient(init, brush, wetColor);
6197
6266
  const load = _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [r / 255, g / 255, b / 255])));
6198
6267
  const seedW = _nullishCoalesce(init.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
6199
6268
  const copiesW = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
6200
- const driver = new (0, _chunkOKHKA43Lcjs.WetStrokeDriver)({
6269
+ const driver = new (0, _chunkJBB3GDBBcjs.WetStrokeDriver)({
6201
6270
  world,
6202
6271
  laneId: id,
6203
6272
  brush,
@@ -6205,12 +6274,12 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6205
6274
  load,
6206
6275
  grain: paperGrain(doc.paper),
6207
6276
  paperDepth: doc.paper.depth,
6208
- paperColor: _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, doc.paper.color),
6277
+ paperColor: _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, doc.paper.color),
6209
6278
  seed: seedW,
6210
6279
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
6211
6280
  mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
6212
6281
  paint: effect ? null : wetGradient,
6213
- effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _323 => _323.pixels]), () => ( null))
6282
+ effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _327 => _327.pixels]), () => ( null))
6214
6283
  });
6215
6284
  init = { ...init, seed: seedW, load };
6216
6285
  wet = { driver, surface: () => world.display(id).surface };
@@ -6221,7 +6290,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6221
6290
  }
6222
6291
  let color = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
6223
6292
  const tracing = this.guides.tracing;
6224
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _324 => _324.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
6293
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _328 => _328.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
6225
6294
  const perspective = this.guides.perspective;
6226
6295
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
6227
6296
  const useStencils = init.stencils !== false;
@@ -6254,11 +6323,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6254
6323
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
6255
6324
  secondary: rgbaOf(this.secondaryColor),
6256
6325
  wet,
6257
- thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _325 => _325.thick, 'optionalAccess', _326 => _326[layer.id]]), () => ( emptyThickChannels())) } : void 0,
6326
+ thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _329 => _329.thick, 'optionalAccess', _330 => _330[layer.id]]), () => ( emptyThickChannels())) } : void 0,
6258
6327
  // Light paint: a twin of the stroke paints the light channel (laying, dimming, moving light).
6259
- light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _327 => _327.light, 'optionalAccess', _328 => _328[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _329 => _329.light, 'optionalAccess', _330 => _330[layer.id]]), () => ( emptyLight())) } : null,
6328
+ light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _331 => _331.light, 'optionalAccess', _332 => _332[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _333 => _333.light, 'optionalAccess', _334 => _334[layer.id]]), () => ( emptyLight())) } : null,
6260
6329
  sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc), art: this.stickerArt.get, variant: (ref2) => this.stickerArt.variantFor(ref2, this.colorScheme === "dark") } : void 0,
6261
- stampArt: this.stickerArt.get,
6330
+ stampArt: this.stampArt,
6262
6331
  paint: effect ? null : this.strokeGradient(init, brush, color),
6263
6332
  effect
6264
6333
  });
@@ -6271,7 +6340,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6271
6340
  const stroke = {
6272
6341
  id: `s${this.strokeCounter++}`,
6273
6342
  layerId: session.layerId,
6274
- brush: _chunkXVOP3CGQcjs.brushToJSON.call(void 0, init.brush),
6343
+ brush: _chunkEU2ZZA6Lcjs.brushToJSON.call(void 0, init.brush),
6275
6344
  color: init.colorHex,
6276
6345
  points: session.points.map((p) => ({ ...p })),
6277
6346
  seed: init.seed
@@ -6296,12 +6365,12 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6296
6365
  const before = this.doc;
6297
6366
  const host = {
6298
6367
  update: (layerId, surface, rects) => {
6299
- if (_optionalChain([this, 'access', _331 => _331.session, 'optionalAccess', _332 => _332.init, 'access', _333 => _333.wet])) {
6368
+ if (_optionalChain([this, 'access', _335 => _335.session, 'optionalAccess', _336 => _336.init, 'access', _337 => _337.wet])) {
6300
6369
  this.wet.syncDisplays();
6301
6370
  return;
6302
6371
  }
6303
6372
  this.live = { layerId, surface };
6304
- const ch = _optionalChain([this, 'access', _334 => _334.session, 'optionalAccess', _335 => _335.thickChannels, 'call', _336 => _336()]);
6373
+ const ch = _optionalChain([this, 'access', _338 => _338.session, 'optionalAccess', _339 => _339.thickChannels, 'call', _340 => _340()]);
6305
6374
  this.liveThick = ch ? { layerId, channels: ch } : null;
6306
6375
  this.emit(rects);
6307
6376
  },
@@ -6314,7 +6383,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6314
6383
  const wetStroke = Boolean(s.init.wet);
6315
6384
  if (wetStroke) this.wet.driver = null;
6316
6385
  const brush = s.init.brush;
6317
- if (!cancelled && _optionalChain([s, 'access', _337 => _337.result, 'optionalAccess', _338 => _338.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
6386
+ if (!cancelled && _optionalChain([s, 'access', _341 => _341.result, 'optionalAccess', _342 => _342.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
6318
6387
  if (cancelled || !surface) {
6319
6388
  if (this.wetOp) {
6320
6389
  const snap = this.wetOp.before;
@@ -6330,7 +6399,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6330
6399
  }
6331
6400
  const stroke = this.record(s);
6332
6401
  s.result.strokeId = stroke.id;
6333
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _339 => _339.result, 'optionalAccess', _340 => _340.bounds]), () => ( null)));
6402
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _343 => _343.result, 'optionalAccess', _344 => _344.bounds]), () => ( null)));
6334
6403
  if (wetStroke && this.wet.instantDry) {
6335
6404
  this.wet.dry(s.layerId);
6336
6405
  this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
@@ -6341,8 +6410,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6341
6410
  const ch = s.thickChannels();
6342
6411
  const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
6343
6412
  const sprayed = s.stickers();
6344
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _341 => _341.doc, 'access', _342 => _342.stickers, 'optionalAccess', _343 => _343[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
6345
- const wetLight = wetStroke && _optionalChain([this, 'access', _344 => _344.wet, 'access', _345 => _345.world, 'optionalAccess', _346 => _346.hasLane, 'call', _347 => _347(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
6413
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _345 => _345.doc, 'access', _346 => _346.stickers, 'optionalAccess', _347 => _347[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
6414
+ const wetLight = wetStroke && _optionalChain([this, 'access', _348 => _348.wet, 'access', _349 => _349.world, 'optionalAccess', _350 => _350.hasLane, 'call', _351 => _351(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
6346
6415
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
6347
6416
  this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {}, ...light ? { light } : {} }, stroke)), wetStroke ? before : this.doc);
6348
6417
  this.notifySample("end", s, [], stroke.id);
@@ -6374,18 +6443,18 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6374
6443
  if (cancelled || !surface) return;
6375
6444
  const stroke = this.record(s);
6376
6445
  s.result.strokeId = stroke.id;
6377
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _348 => _348.result, 'optionalAccess', _349 => _349.bounds]), () => ( null)));
6446
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _352 => _352.result, 'optionalAccess', _353 => _353.bounds]), () => ( null)));
6378
6447
  const l = _chunkPVJMTLPJcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
6379
6448
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
6380
6449
  const ch = s.thickChannels();
6381
6450
  const sprayed = s.stickers();
6382
- const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _350 => _350.wet, 'access', _351 => _351.world, 'optionalAccess', _352 => _352.hasLane, 'call', _353 => _353(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
6451
+ const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _354 => _354.wet, 'access', _355 => _355.world, 'optionalAccess', _356 => _356.hasLane, 'call', _357 => _357(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
6383
6452
  out = withLiveStroke({
6384
6453
  ...out,
6385
6454
  layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
6386
6455
  strokes: [...out.strokes, stroke],
6387
6456
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
6388
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _354 => _354.stickers, 'optionalAccess', _355 => _355[l.id]]), () => ( [])), ...sprayed] } } : {},
6457
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _358 => _358.stickers, 'optionalAccess', _359 => _359[l.id]]), () => ( [])), ...sprayed] } } : {},
6389
6458
  ...lit ? { light: withLayerLight(out.light, l.id, lit) } : {}
6390
6459
  }, stroke);
6391
6460
  }
@@ -6458,11 +6527,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6458
6527
  throw e;
6459
6528
  }
6460
6529
  const run = last;
6461
- if (_optionalChain([run, 'optionalAccess', _356 => _356.result, 'access', _357 => _357.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
6462
- if (doc !== before || this.wetOp) this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _358 => _358.brush, 'access', _359 => _359.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
6530
+ if (_optionalChain([run, 'optionalAccess', _360 => _360.result, 'access', _361 => _361.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
6531
+ if (doc !== before || this.wetOp) this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _362 => _362.brush, 'access', _363 => _363.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
6463
6532
  else this.emit([]);
6464
- const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _360 => _360.result, 'access', _361 => _361.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
6465
- return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _362 => _362.result, 'access', _363 => _363.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _364 => _364.result, 'access', _365 => _365.wet]) !== void 0 ? { wet: run.result.wet } : {} };
6533
+ const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _364 => _364.result, 'access', _365 => _365.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
6534
+ return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _366 => _366.result, 'access', _367 => _367.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _368 => _368.result, 'access', _369 => _369.wet]) !== void 0 ? { wet: run.result.wet } : {} };
6466
6535
  }
6467
6536
  /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
6468
6537
  checkPoints(points) {
@@ -6485,7 +6554,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6485
6554
  */
6486
6555
  replayStrokes(options) {
6487
6556
  this.requireIdle("replaying");
6488
- if (!_optionalChain([options, 'access', _366 => _366.strokeIds, 'optionalAccess', _367 => _367.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
6557
+ if (!_optionalChain([options, 'access', _370 => _370.strokeIds, 'optionalAccess', _371 => _371.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
6489
6558
  const strokes = options.strokeIds.map((id) => {
6490
6559
  const s = this.doc.strokes.find((x) => x.id === id);
6491
6560
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -6499,7 +6568,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6499
6568
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
6500
6569
  if (options.color === void 0) {
6501
6570
  for (const s of strokes) {
6502
- if (_optionalChain([s, 'access', _368 => _368.paint, 'optionalAccess', _369 => _369.type]) === "effect" && !this.effectPaintImage(s.paint)) {
6571
+ if (_optionalChain([s, 'access', _372 => _372.paint, 'optionalAccess', _373 => _373.type]) === "effect" && !this.effectPaintImage(s.paint)) {
6503
6572
  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.`);
6504
6573
  }
6505
6574
  }
@@ -6522,13 +6591,13 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6522
6591
  let brush = v.brush;
6523
6592
  if (options.brushId !== void 0) {
6524
6593
  const b = this.requireBrush(options.brushId);
6525
- brush = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
6594
+ brush = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
6526
6595
  }
6527
6596
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
6528
6597
  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.`);
6529
6598
  let load = s.load;
6530
6599
  if (load && options.color !== void 0 && load.reservoir) {
6531
- const [r, g, b] = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, options.color);
6600
+ const [r, g, b] = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, options.color);
6532
6601
  load = { ...load, reservoir: [r / 255, g / 255, b / 255] };
6533
6602
  }
6534
6603
  const paint = v.paint && options.color === void 0 ? { paint: v.paint } : {};
@@ -6557,7 +6626,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6557
6626
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
6558
6627
  lightOf(layerId) {
6559
6628
  const l = this.wetLayer(layerId, "read the light of");
6560
- const info = lightInfo(_optionalChain([this, 'access', _370 => _370.doc, 'access', _371 => _371.light, 'optionalAccess', _372 => _372[l.id]]));
6629
+ const info = lightInfo(_optionalChain([this, 'access', _374 => _374.doc, 'access', _375 => _375.light, 'optionalAccess', _376 => _376[l.id]]));
6561
6630
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
6562
6631
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
6563
6632
  }
@@ -6608,7 +6677,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6608
6677
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
6609
6678
  if (!id) return null;
6610
6679
  this.requireLayer(id);
6611
- const ch = _optionalChain([this, 'access', _373 => _373.doc, 'access', _374 => _374.thick, 'optionalAccess', _375 => _375[id]]);
6680
+ const ch = _optionalChain([this, 'access', _377 => _377.doc, 'access', _378 => _378.thick, 'optionalAccess', _379 => _379[id]]);
6612
6681
  if (!ch) return null;
6613
6682
  const r = reliefInfo(ch);
6614
6683
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -6636,6 +6705,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6636
6705
  if (w > 16384 || h > 16384) throw new PaintEditorError(`At scale ${scale} the canvas would be ${w}\xD7${h}; the limit is 16384 px per side. Use a smaller scale.`);
6637
6706
  const target = new _PaintEditorController({ width: w, height: h, dpi: dpi * scale, brushLibrary: this.brushLibrary, wet: this.wetOptions });
6638
6707
  target.brushEntries = this.brushEntries;
6708
+ target.brushSources.set(this.brushSources.all());
6639
6709
  const paper = { ...this.doc.paper, scale: Math.min(8, this.doc.paper.scale * scale) };
6640
6710
  target.adopt({ state: { canvas: target.doc.canvas, paper, layers: emptiedLayers(this.doc.layers), activeLayerId: this.doc.activeLayerId, strokes: [] }, extensions: {}, problems: [] });
6641
6711
  target.lighting = { ...this.lighting };
@@ -6718,7 +6788,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6718
6788
  wetState() {
6719
6789
  const st = this.getState().wet;
6720
6790
  const backend = this.wet.backend();
6721
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _376 => _376.message]), () => ( _chunkJ5VQYK7Tcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
6791
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _380 => _380.message]), () => ( _chunkJ5VQYK7Tcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
6722
6792
  }
6723
6793
  /**
6724
6794
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -6736,7 +6806,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6736
6806
  */
6737
6807
  async setWetEngine(options) {
6738
6808
  const gpu = _nullishCoalesce(options.gpu, () => ( this.wet.gpuMode));
6739
- if (!_chunkOKHKA43Lcjs.WET_GPU_MODES.includes(gpu)) throw new PaintEditorError(`gpu must be ${_chunkOKHKA43Lcjs.WET_GPU_MODES.join(" or ")}, not ${JSON.stringify(gpu)}.`);
6809
+ if (!_chunkJBB3GDBBcjs.WET_GPU_MODES.includes(gpu)) throw new PaintEditorError(`gpu must be ${_chunkJBB3GDBBcjs.WET_GPU_MODES.join(" or ")}, not ${JSON.stringify(gpu)}.`);
6740
6810
  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.`);
6741
6811
  this.wet.setGpu(gpu, options.minTiles);
6742
6812
  this.emit();
@@ -6803,7 +6873,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6803
6873
  }
6804
6874
  /** Records a settings change as a wet event (not an undo step). */
6805
6875
  recordWetSetting(e) {
6806
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _377 => _377.wet, 'access', _378 => _378.world, 'optionalAccess', _379 => _379.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
6876
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _381 => _381.wet, 'access', _382 => _382.world, 'optionalAccess', _383 => _383.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
6807
6877
  }
6808
6878
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
6809
6879
  setWetParams(layerId, update) {
@@ -6872,7 +6942,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6872
6942
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkPVJMTLPJcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
6873
6943
  const live = this.live;
6874
6944
  if (!live) return this.animatedView();
6875
- if (_optionalChain([this, 'access', _380 => _380.liveLayers, 'optionalAccess', _381 => _381.key]) === live.surface) return this.liveLayers.layers;
6945
+ if (_optionalChain([this, 'access', _384 => _384.liveLayers, 'optionalAccess', _385 => _385.key]) === live.surface) return this.liveLayers.layers;
6876
6946
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
6877
6947
  this.liveLayers = { key: live.surface, layers };
6878
6948
  return layers;
@@ -6895,7 +6965,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6895
6965
  tracingNode(t) {
6896
6966
  const { width, height } = this.doc.canvas;
6897
6967
  const key = this.tracingVersion * 100003 + width * 7 + height;
6898
- if (_optionalChain([this, 'access', _382 => _382.tracingCache, 'optionalAccess', _383 => _383.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
6968
+ if (_optionalChain([this, 'access', _386 => _386.tracingCache, 'optionalAccess', _387 => _387.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
6899
6969
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
6900
6970
  const image = resampleInto(src, t.rect, width, height);
6901
6971
  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 };
@@ -6922,8 +6992,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6922
6992
  let out = layers;
6923
6993
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
6924
6994
  for (const id of ids) {
6925
- const ch = _optionalChain([live, 'optionalAccess', _384 => _384.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _385 => _385[id]]);
6926
- const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _386 => _386.layer]);
6995
+ const ch = _optionalChain([live, 'optionalAccess', _388 => _388.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _389 => _389[id]]);
6996
+ const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _390 => _390.layer]);
6927
6997
  if (!ch || !isPixelLayer(l)) continue;
6928
6998
  let cache = this.litCaches.get(id);
6929
6999
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -6943,13 +7013,13 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6943
7013
  if (!ids.size) return layers;
6944
7014
  let out = layers;
6945
7015
  for (const id of ids) {
6946
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _387 => _387.layer]);
7016
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _391 => _391.layer]);
6947
7017
  if (!isPixelLayer(l)) continue;
6948
7018
  let cache = this.lightCaches.get(id);
6949
7019
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
6950
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _388 => _388.liveThick, 'optionalAccess', _389 => _389.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _390 => _390.doc, 'access', _391 => _391.thick, 'optionalAccess', _392 => _392[id]]));
7020
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _392 => _392.liveThick, 'optionalAccess', _393 => _393.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _394 => _394.doc, 'access', _395 => _395.thick, 'optionalAccess', _396 => _396[id]]));
6951
7021
  if (glowed !== l.surface) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
6952
- const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _393 => _393.layer]);
7022
+ const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _397 => _397.layer]);
6953
7023
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
6954
7024
  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 } });
6955
7025
  }
@@ -6961,7 +7031,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6961
7031
  if (!l.visible) continue;
6962
7032
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
6963
7033
  else if (isPixelLayer(l)) {
6964
- const thick = !committed && _optionalChain([this, 'access', _394 => _394.liveThick, 'optionalAccess', _395 => _395.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _396 => _396.doc, 'access', _397 => _397.thick, 'optionalAccess', _398 => _398[l.id]]);
7034
+ const thick = !committed && _optionalChain([this, 'access', _398 => _398.liveThick, 'optionalAccess', _399 => _399.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _400 => _400.doc, 'access', _401 => _401.thick, 'optionalAccess', _402 => _402[l.id]]);
6965
7035
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
6966
7036
  }
6967
7037
  }
@@ -6990,7 +7060,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
6990
7060
  if (backlight) layers = [...layers, backlight];
6991
7061
  if (options.layerIds) {
6992
7062
  const picked = [];
6993
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _399 => _399.layer]), () => ( this.requireLayer(id))));
7063
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _403 => _403.layer]), () => ( this.requireLayer(id))));
6994
7064
  layers = picked.map((l) => ({ ...l, visible: true }));
6995
7065
  }
6996
7066
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -7006,7 +7076,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7006
7076
  */
7007
7077
  compositeTiles(rect, onTile, options = {}) {
7008
7078
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
7009
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _400 => _400.live, 'optionalAccess', _401 => _401.layerId]), () => ( this.doc.activeLayerId)) });
7079
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _404 => _404.live, 'optionalAccess', _405 => _405.layerId]), () => ( this.doc.activeLayerId)) });
7010
7080
  }
7011
7081
  /** The canvas as canvas-sized RGBA (paper included by default). */
7012
7082
  compositePixels(options = {}) {
@@ -7074,6 +7144,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7074
7144
  for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) liveStrokes[id] = list.map(strokeToJSON);
7075
7145
  if (Object.keys(liveStrokes).length) ext.liveStrokes = liveStrokes;
7076
7146
  else delete ext.liveStrokes;
7147
+ const strokes = [...this.doc.strokes, ...Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {}))).flat()];
7148
+ const sourceIds = [...new Set(strokes.flatMap((st) => engineBrushSourceIds(st.brush)))];
7149
+ const sources = sourceIds.map((id) => this.brushSources.source(id)).filter((x) => x !== void 0);
7150
+ if (sources.length) ext.brushSources = sources.map((x) => ({ ...x }));
7151
+ else delete ext.brushSources;
7077
7152
  const light = {};
7078
7153
  for (const [id, t] of Object.entries(_nullishCoalesce(this.doc.light, () => ( {})))) {
7079
7154
  if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
@@ -7085,7 +7160,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7085
7160
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)));
7086
7161
  if (Object.keys(spills).length) ext.lightSpill = spills;
7087
7162
  else delete ext.lightSpill;
7088
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _402 => _402.layer])));
7163
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _406 => _406.layer])));
7089
7164
  if (effectLayers) ext.effectLayers = effectLayers;
7090
7165
  else delete ext.effectLayers;
7091
7166
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -7096,6 +7171,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7096
7171
  }
7097
7172
  /** Reads `layerChannels` and `lighting` from loaded extensions into the document. */
7098
7173
  readThick(state, ext, problems) {
7174
+ if (Array.isArray(ext.brushSources)) this.brushSources.set(ext.brushSources.map((x, i) => _chunkEU2ZZA6Lcjs.readBrushSource.call(void 0, x, `brushSources[${i}]`, problems)).filter((x) => x !== null));
7099
7175
  this.lighting = normalizeLighting(_nullishCoalesce(ext.lighting, () => ( {})), DEFAULT_LIGHTING);
7100
7176
  this.litCaches.clear();
7101
7177
  if (ext.stickers && typeof ext.stickers === "object") {
@@ -7109,7 +7185,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7109
7185
  const stamp = _chunkRDFHWAHLcjs.editorStampOf.call(void 0, ref2);
7110
7186
  const { stamp: _old, variant, ...rest } = x;
7111
7187
  return [{ ...rest, ref: ref2, ...stamp ? { stamp } : {}, ...variant === "dark" && !stamp ? { variant } : {} }];
7112
- } catch (e7) {
7188
+ } catch (e9) {
7113
7189
  return [];
7114
7190
  }
7115
7191
  });
@@ -7121,7 +7197,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7121
7197
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
7122
7198
  const liveStrokes = {};
7123
7199
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
7124
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _403 => _403.layer])) || !Array.isArray(list)) continue;
7200
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _407 => _407.layer])) || !Array.isArray(list)) continue;
7125
7201
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
7126
7202
  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).`);
7127
7203
  liveStrokes[id] = ok;
@@ -7131,7 +7207,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7131
7207
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
7132
7208
  const effectLayers = {};
7133
7209
  for (const [id, v] of Object.entries(ext.effectLayers)) {
7134
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _404 => _404.layer]))) continue;
7210
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _408 => _408.layer]))) continue;
7135
7211
  const source = readPaintEffectSource(v);
7136
7212
  if (source) effectLayers[id] = source;
7137
7213
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -7151,7 +7227,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7151
7227
  for (const [id, v] of Object.entries(ext.lightSpill)) {
7152
7228
  try {
7153
7229
  if (_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id)) this.lightSpills[id] = normalizeLightSpill(_nullishCoalesce(v, () => ( {})));
7154
- } catch (e8) {
7230
+ } catch (e10) {
7155
7231
  problems.push(`The light spill of layer "${id}" could not be read; it takes the defaults.`);
7156
7232
  }
7157
7233
  }
@@ -7159,7 +7235,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7159
7235
  if (ext.light && typeof ext.light === "object") {
7160
7236
  const light = {};
7161
7237
  for (const [id, v] of Object.entries(ext.light)) {
7162
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _405 => _405.layer]))) continue;
7238
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _409 => _409.layer]))) continue;
7163
7239
  try {
7164
7240
  light[id] = lightFromJSON(v);
7165
7241
  } catch (e) {
@@ -7195,7 +7271,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7195
7271
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
7196
7272
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
7197
7273
  for (const s of loaded.state.strokes) {
7198
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _406 => _406.exec, 'call', _407 => _407(s.id), 'optionalAccess', _408 => _408[1]]), () => ( 0)));
7274
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _410 => _410.exec, 'call', _411 => _411(s.id), 'optionalAccess', _412 => _412[1]]), () => ( 0)));
7199
7275
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
7200
7276
  }
7201
7277
  this.undoStack = [];
@@ -7203,7 +7279,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7203
7279
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
7204
7280
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
7205
7281
  for (const s of list) {
7206
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _409 => _409.exec, 'call', _410 => _410(s.id), 'optionalAccess', _411 => _411[1]]), () => ( 0)));
7282
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _413 => _413.exec, 'call', _414 => _414(s.id), 'optionalAccess', _415 => _415[1]]), () => ( 0)));
7207
7283
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
7208
7284
  }
7209
7285
  }
@@ -7214,6 +7290,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7214
7290
  delete this.extensions.lighting;
7215
7291
  delete this.extensions.stickers;
7216
7292
  delete this.extensions.liveStrokes;
7293
+ delete this.extensions.brushSources;
7217
7294
  delete this.extensions.effectLayers;
7218
7295
  delete this.extensions.paperEffect;
7219
7296
  this.viewCompositor.clear();
@@ -7300,10 +7377,10 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7300
7377
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
7301
7378
  });
7302
7379
  const layers = toStandard(dried);
7303
- const result = _chunkLHPEG5AUcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
7380
+ const result = _chunkJ4GXP53Rcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
7304
7381
  for (const [mode, names] of changed) {
7305
- const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _412 => _412.find, 'call', _413 => _413((m) => m.id === mode), 'optionalAccess', _414 => _414.label]), () => ( mode));
7306
- const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _415 => _415.find, 'call', _416 => _416((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _417 => _417.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
7382
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _416 => _416.find, 'call', _417 => _417((m) => m.id === mode), 'optionalAccess', _418 => _418.label]), () => ( mode));
7383
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _419 => _419.find, 'call', _420 => _420((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _421 => _421.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
7307
7384
  const list = names.map((n) => `"${n}"`).join(", ");
7308
7385
  const one = names.length === 1;
7309
7386
  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).`);
@@ -7425,7 +7502,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7425
7502
  const { src, pixels } = this.importImage(options, "The reference image");
7426
7503
  const ref2 = {
7427
7504
  id: `ref${this.nextReferenceId++}`,
7428
- name: _optionalChain([options, 'access', _418 => _418.name, 'optionalAccess', _419 => _419.trim, 'call', _420 => _420()]) || `Reference ${this.guides.references.length + 1}`,
7505
+ name: _optionalChain([options, 'access', _422 => _422.name, 'optionalAccess', _423 => _423.trim, 'call', _424 => _424()]) || `Reference ${this.guides.references.length + 1}`,
7429
7506
  src,
7430
7507
  width: pixels.width,
7431
7508
  height: pixels.height,
@@ -7504,7 +7581,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7504
7581
  try {
7505
7582
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
7506
7583
  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 });
7507
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _421 => _421.exec, 'call', _422 => _422(ref2.id), 'optionalAccess', _423 => _423[1]]), () => ( 0)));
7584
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _425 => _425.exec, 'call', _426 => _426(ref2.id), 'optionalAccess', _427 => _427[1]]), () => ( 0)));
7508
7585
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
7509
7586
  } catch (e) {
7510
7587
  problems.push(e.message);
@@ -7515,7 +7592,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7515
7592
  guides.stencils = [];
7516
7593
  r.stencils.forEach((raw2, i) => {
7517
7594
  try {
7518
- const id = typeof _optionalChain([raw2, 'optionalAccess', _424 => _424.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
7595
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _428 => _428.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
7519
7596
  guides.stencils.push(normalizeStencil(raw2, id));
7520
7597
  const n = Number(id.slice(7));
7521
7598
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -7538,12 +7615,12 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7538
7615
  /** The next free sticker number (ids `st<n>` are unique across the document). */
7539
7616
  nextStickerNumber(doc = this.doc) {
7540
7617
  let n = 0;
7541
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _425 => _425.exec, 'call', _426 => _426(st.id), 'optionalAccess', _427 => _427[1]]), () => ( 0))));
7618
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _429 => _429.exec, 'call', _430 => _430(st.id), 'optionalAccess', _431 => _431[1]]), () => ( 0))));
7542
7619
  return n + 1;
7543
7620
  }
7544
7621
  stickerLayer(layerId) {
7545
7622
  const l = this.wetLayer(layerId, "edit the stickers of");
7546
- const stickers = _optionalChain([this, 'access', _428 => _428.doc, 'access', _429 => _429.stickers, 'optionalAccess', _430 => _430[l.id]]);
7623
+ const stickers = _optionalChain([this, 'access', _432 => _432.doc, 'access', _433 => _433.stickers, 'optionalAccess', _434 => _434[l.id]]);
7547
7624
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (sticker-stars; list_brush_presets lists them).`);
7548
7625
  return { layer: l, stickers };
7549
7626
  }
@@ -7619,7 +7696,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7619
7696
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
7620
7697
  if (!id) return [];
7621
7698
  this.requireLayer(id);
7622
- return (_nullishCoalesce(_optionalChain([this, 'access', _431 => _431.doc, 'access', _432 => _432.stickers, 'optionalAccess', _433 => _433[id]]), () => ( []))).map((s) => ({ ...s }));
7699
+ return (_nullishCoalesce(_optionalChain([this, 'access', _435 => _435.doc, 'access', _436 => _436.stickers, 'optionalAccess', _437 => _437[id]]), () => ( []))).map((s) => ({ ...s }));
7623
7700
  }
7624
7701
  /**
7625
7702
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -7640,7 +7717,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7640
7717
  }
7641
7718
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
7642
7719
  previewBase() {
7643
- return _optionalChain([this, 'access', _434 => _434.stickerPreview, 'optionalAccess', _435 => _435.shown]) === this.doc ? this.stickerPreview.base : null;
7720
+ return _optionalChain([this, 'access', _438 => _438.stickerPreview, 'optionalAccess', _439 => _439.shown]) === this.doc ? this.stickerPreview.base : null;
7644
7721
  }
7645
7722
  readStickerUpdate(update) {
7646
7723
  try {
@@ -7655,7 +7732,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7655
7732
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
7656
7733
  if (!id) return null;
7657
7734
  this.requireLayer(id);
7658
- const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _436 => _436.doc, 'access', _437 => _437.stickers, 'optionalAccess', _438 => _438[id]]), () => ( [])), x, y, this.stickerArt.get);
7735
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _440 => _440.doc, 'access', _441 => _441.stickers, 'optionalAccess', _442 => _442[id]]), () => ( [])), x, y, this.stickerArt.get);
7659
7736
  return hit ? { ...hit } : null;
7660
7737
  }
7661
7738
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -7712,8 +7789,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7712
7789
  const layer = this.wetLayer(layerId, "add stickers to");
7713
7790
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
7714
7791
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
7715
- const existing = _optionalChain([this, 'access', _439 => _439.doc, 'access', _440 => _440.stickers, 'optionalAccess', _441 => _441[layer.id]]);
7716
- if (!_optionalChain([existing, 'optionalAccess', _442 => _442.length])) {
7792
+ const existing = _optionalChain([this, 'access', _443 => _443.doc, 'access', _444 => _444.stickers, 'optionalAccess', _445 => _445[layer.id]]);
7793
+ if (!_optionalChain([existing, 'optionalAccess', _446 => _446.length])) {
7717
7794
  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.`);
7718
7795
  }
7719
7796
  let n = this.nextStickerNumber();
@@ -7730,7 +7807,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7730
7807
  const id = n++;
7731
7808
  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 });
7732
7809
  });
7733
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _443 => _443.length]) ? added.map(stickerRect) : void 0);
7810
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _447 => _447.length]) ? added.map(stickerRect) : void 0);
7734
7811
  return added.map((s) => ({ ...s }));
7735
7812
  }
7736
7813
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -7769,20 +7846,20 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7769
7846
  }
7770
7847
  liveStrokeLayer(layerId, what) {
7771
7848
  const l = this.wetLayer(layerId, what);
7772
- const strokes = _optionalChain([this, 'access', _444 => _444.doc, 'access', _445 => _445.liveStrokes, 'optionalAccess', _446 => _446[l.id]]);
7849
+ const strokes = _optionalChain([this, 'access', _448 => _448.doc, 'access', _449 => _449.liveStrokes, 'optionalAccess', _450 => _450[l.id]]);
7773
7850
  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.`);
7774
7851
  return { layer: l, strokes };
7775
7852
  }
7776
7853
  /** Whether a layer is a live stroke layer. */
7777
7854
  isLiveStrokeLayer(layerId) {
7778
- return Boolean(_optionalChain([this, 'access', _447 => _447.doc, 'access', _448 => _448.liveStrokes, 'optionalAccess', _449 => _449[layerId]]));
7855
+ return Boolean(_optionalChain([this, 'access', _451 => _451.doc, 'access', _452 => _452.liveStrokes, 'optionalAccess', _453 => _453[layerId]]));
7779
7856
  }
7780
7857
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
7781
7858
  convertToLiveStrokes(layerId) {
7782
7859
  this.requireIdle("converting a layer");
7783
7860
  const l = this.paintTarget(layerId, "convert");
7784
- if (_optionalChain([this, 'access', _450 => _450.doc, 'access', _451 => _451.liveStrokes, 'optionalAccess', _452 => _452[l.id]])) return this.describeLayer(l);
7785
- if (_optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.stickers, 'optionalAccess', _455 => _455[l.id], 'optionalAccess', _456 => _456.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
7861
+ if (_optionalChain([this, 'access', _454 => _454.doc, 'access', _455 => _455.liveStrokes, 'optionalAccess', _456 => _456[l.id]])) return this.describeLayer(l);
7862
+ if (_optionalChain([this, 'access', _457 => _457.doc, 'access', _458 => _458.stickers, 'optionalAccess', _459 => _459[l.id], 'optionalAccess', _460 => _460.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
7786
7863
  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"}).`);
7787
7864
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
7788
7865
  return this.describeLayer(this.getLayer(l.id));
@@ -7795,7 +7872,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7795
7872
  findLiveStroke(id) {
7796
7873
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
7797
7874
  const index = strokes.findIndex((x) => x.id === id);
7798
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _457 => _457.layer]);
7875
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _461 => _461.layer]);
7799
7876
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
7800
7877
  }
7801
7878
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -7815,15 +7892,15 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7815
7892
  let brush = was.brush;
7816
7893
  if (update.brushId !== void 0) {
7817
7894
  const b = this.requireBrush(update.brushId);
7818
- brush = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
7895
+ brush = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
7819
7896
  }
7820
7897
  if (update.brush !== void 0) {
7821
7898
  if (!update.brush || typeof update.brush !== "object") throw new PaintEditorError("brush must be an object of brush settings (as set_brush takes).");
7822
- brush = _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
7899
+ brush = _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
7823
7900
  }
7824
7901
  const why = liveStrokeRefusal(brush);
7825
7902
  if (why) throw new PaintEditorError(why);
7826
- const next = { ...was, brush: _chunkXVOP3CGQcjs.brushToJSON.call(void 0, brush) };
7903
+ const next = { ...was, brush: _chunkEU2ZZA6Lcjs.brushToJSON.call(void 0, brush) };
7827
7904
  if (update.seed !== void 0) {
7828
7905
  if (!Number.isInteger(update.seed) || update.seed < 0) throw new PaintEditorError(`seed ${update.seed} must be a whole number of 0 or more.`);
7829
7906
  next.seed = update.seed;
@@ -7834,7 +7911,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7834
7911
  }
7835
7912
  if (update.paint !== void 0) {
7836
7913
  if (update.paint === null) delete next.paint;
7837
- else if (_chunkOKHKA43Lcjs.isPaintEffectPaint.call(void 0, update.paint)) {
7914
+ else if (_chunkJBB3GDBBcjs.isPaintEffectPaint.call(void 0, update.paint)) {
7838
7915
  if (!this.effectPaintImage(update.paint)) throw new PaintEditorError(`The effect "${update.paint.effect}" is not rendered yet; render it first (prepareEffectPaints; the update_stroke tool does this).`);
7839
7916
  next.paint = JSON.parse(JSON.stringify(update.paint));
7840
7917
  } else {
@@ -7845,8 +7922,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7845
7922
  } else next.paint = JSON.parse(JSON.stringify(p));
7846
7923
  }
7847
7924
  }
7848
- const rgb = _chunkOKHKA43Lcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
7849
- const load = brushLoadForStroke(brush, _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD, rgb);
7925
+ const rgb = _chunkJBB3GDBBcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
7926
+ const load = brushLoadForStroke(brush, _chunkNIBFKXMDcjs.EMPTY_MIXER_LOAD, rgb);
7850
7927
  if (load.reservoir || load.pickup) next.load = load;
7851
7928
  else delete next.load;
7852
7929
  const list = strokes.map((x, i) => i === index ? next : x);
@@ -7890,9 +7967,9 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7890
7967
  const layers = /* @__PURE__ */ new Map();
7891
7968
  for (const f of found) layers.set(f.layer.id, f.layer);
7892
7969
  for (const [layerId, layer] of layers) {
7893
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _458 => _458.liveStrokes, 'optionalAccess', _459 => _459[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
7970
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _462 => _462.liveStrokes, 'optionalAccess', _463 => _463[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
7894
7971
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
7895
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _460 => _460.liveStrokes, 'optionalAccess', _461 => _461[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
7972
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _464 => _464.liveStrokes, 'optionalAccess', _465 => _465[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
7896
7973
  }
7897
7974
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
7898
7975
  return { removed: [...ids], bounds };
@@ -7960,7 +8037,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
7960
8037
  }
7961
8038
  withLiveStrokes(doc, layer, list, dirty) {
7962
8039
  if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
7963
- const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _462 => _462.layer]);
8040
+ const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _466 => _466.layer]);
7964
8041
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
7965
8042
  const next = { ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
7966
8043
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
@@ -8038,7 +8115,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
8038
8115
  if (!this.animatedLayers.size) return this.doc.layers;
8039
8116
  let layers = this.doc.layers;
8040
8117
  for (const [id, a] of this.animatedLayers) {
8041
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _463 => _463.layer]);
8118
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _467 => _467.layer]);
8042
8119
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
8043
8120
  }
8044
8121
  return layers;
@@ -8048,11 +8125,11 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
8048
8125
  const layers = [];
8049
8126
  const sources = /* @__PURE__ */ new Map();
8050
8127
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
8051
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _464 => _464.layer]);
8128
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _468 => _468.layer]);
8052
8129
  const live = strokes.filter(isLiveEffect);
8053
8130
  if (!isPixelLayer(layer) || !live.length) continue;
8054
8131
  layers.push({ layer, strokes });
8055
- for (const st of live) sources.set(_chunkOKHKA43Lcjs.effectPaintKey.call(void 0, st.paint), st.paint);
8132
+ for (const st of live) sources.set(_chunkJBB3GDBBcjs.effectPaintKey.call(void 0, st.paint), st.paint);
8056
8133
  }
8057
8134
  return { layers, sources: [...sources.values()] };
8058
8135
  }
@@ -8173,13 +8250,13 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
8173
8250
  return this.withEffectTime(time, () => this.compositePixels(options));
8174
8251
  }
8175
8252
  // --- Stencils --------------------------------------------------------------------
8176
- __init127() {this.stencilCache = null}
8177
- __init128() {this.nextStencilId = 1}
8253
+ __init132() {this.stencilCache = null}
8254
+ __init133() {this.nextStencilId = 1}
8178
8255
  /** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
8179
8256
  stencilSelection(stencils = this.guides.stencils) {
8180
8257
  const { width, height } = this.doc.canvas;
8181
8258
  const size = `${width}x${height}`;
8182
- if (_optionalChain([this, 'access', _465 => _465.stencilCache, 'optionalAccess', _466 => _466.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
8259
+ if (_optionalChain([this, 'access', _469 => _469.stencilCache, 'optionalAccess', _470 => _470.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
8183
8260
  const mask = stencilMask(stencils, width, height);
8184
8261
  this.stencilCache = { key: stencils, size, mask };
8185
8262
  return mask;
@@ -8240,8 +8317,8 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
8240
8317
  }
8241
8318
  makeSwatch(color, name) {
8242
8319
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
8243
- const out = { color: _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
8244
- if (_optionalChain([name, 'optionalAccess', _467 => _467.trim, 'call', _468 => _468()])) out.name = name.trim();
8320
+ const out = { color: _chunkNIBFKXMDcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
8321
+ if (_optionalChain([name, 'optionalAccess', _471 => _471.trim, 'call', _472 => _472()])) out.name = name.trim();
8245
8322
  if (p.type === "gradient") out.paint = p;
8246
8323
  return out;
8247
8324
  }
@@ -8293,7 +8370,7 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
8293
8370
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
8294
8371
  */
8295
8372
  mixOnPad(paints2, options = {}) {
8296
- const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _469 => _469.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _470 => _470.parts]) }));
8373
+ const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _473 => _473.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _474 => _474.parts]) }));
8297
8374
  let r;
8298
8375
  try {
8299
8376
  r = this.pad.mix(parsed, options);
@@ -8382,10 +8459,10 @@ var PaintEditorController = (_class13 = class _PaintEditorController {
8382
8459
  }
8383
8460
  /** A layer's tile surface (live while stroking), for thumbnails. */
8384
8461
  layerSurface(id) {
8385
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _471 => _471.layer]);
8462
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _475 => _475.layer]);
8386
8463
  return isPixelLayer(l) ? l.surface : null;
8387
8464
  }
8388
- }, _class13.__initStatic(), _class13);
8465
+ }, _class14.__initStatic(), _class14);
8389
8466
  var MAX_IMAGE_SIDE = 8192;
8390
8467
  var movePoint = (p, dx, dy) => ({ x: p.x + dx, y: p.y + dy });
8391
8468
  var moveRect = (r, dx, dy) => ({ ...r, x: r.x + dx, y: r.y + dy });
@@ -8404,7 +8481,7 @@ function insertAfter(layers, id, node) {
8404
8481
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
8405
8482
  }
8406
8483
  function isLiveEffect(s) {
8407
- return _optionalChain([s, 'access', _472 => _472.paint, 'optionalAccess', _473 => _473.type]) === "effect" && s.paint.live === true;
8484
+ return _optionalChain([s, 'access', _476 => _476.paint, 'optionalAccess', _477 => _477.type]) === "effect" && s.paint.live === true;
8408
8485
  }
8409
8486
  function framePaint(p, t) {
8410
8487
  return { ...p, time: p.time + t };
@@ -8429,7 +8506,7 @@ function clipRect(r, width, height) {
8429
8506
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
8430
8507
  }
8431
8508
  function withLiveStroke(doc, stroke) {
8432
- const list = _optionalChain([doc, 'access', _474 => _474.liveStrokes, 'optionalAccess', _475 => _475[stroke.layerId]]);
8509
+ const list = _optionalChain([doc, 'access', _478 => _478.liveStrokes, 'optionalAccess', _479 => _479[stroke.layerId]]);
8433
8510
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
8434
8511
  }
8435
8512
  function shiftDocument(doc, dx, dy) {
@@ -8456,9 +8533,9 @@ function shiftDocument(doc, dx, dy) {
8456
8533
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
8457
8534
  if (doc.paintEvents) {
8458
8535
  out.paintEvents = doc.paintEvents.map((e) => {
8459
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _476 => _476.data, 'optionalAccess', _477 => _477.stickers]) : void 0;
8536
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _480 => _480.data, 'optionalAccess', _481 => _481.stickers]) : void 0;
8460
8537
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
8461
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _478 => _478.data, 'optionalAccess', _479 => _479.strokes]) : void 0;
8538
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _482 => _482.data, 'optionalAccess', _483 => _483.strokes]) : void 0;
8462
8539
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
8463
8540
  });
8464
8541
  }
@@ -8547,8 +8624,8 @@ function strokeSchedule(points) {
8547
8624
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
8548
8625
  }
8549
8626
  function strokeDuration(points, max = 1800) {
8550
- const t0 = _optionalChain([points, 'access', _480 => _480[0], 'optionalAccess', _481 => _481.t]);
8551
- const t1 = _optionalChain([points, 'access', _482 => _482[points.length - 1], 'optionalAccess', _483 => _483.t]);
8627
+ const t0 = _optionalChain([points, 'access', _484 => _484[0], 'optionalAccess', _485 => _485.t]);
8628
+ const t1 = _optionalChain([points, 'access', _486 => _486[points.length - 1], 'optionalAccess', _487 => _487.t]);
8552
8629
  let ms;
8553
8630
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
8554
8631
  else {
@@ -8602,7 +8679,7 @@ var PaintDirector = class {
8602
8679
  }
8603
8680
  where(id) {
8604
8681
  const a = this.presence.get(id);
8605
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _484 => _484.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _485 => _485.y]), () => ( 0)) };
8682
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _488 => _488.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _489 => _489.y]), () => ( 0)) };
8606
8683
  }
8607
8684
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
8608
8685
  async glide(id, to, ms = 380) {
@@ -8652,8 +8729,8 @@ var PaintDirector = class {
8652
8729
  }
8653
8730
  case "replay": {
8654
8731
  await this.say(id, command.note, 500);
8655
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _486 => _486.replay, 'access', _487 => _487.strokeIds, 'optionalAccess', _488 => _488.includes, 'call', _489 => _489(s.id)]));
8656
- const first = _optionalChain([source, 'access', _490 => _490[0], 'optionalAccess', _491 => _491.points, 'access', _492 => _492[0]]);
8732
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _490 => _490.replay, 'access', _491 => _491.strokeIds, 'optionalAccess', _492 => _492.includes, 'call', _493 => _493(s.id)]));
8733
+ const first = _optionalChain([source, 'access', _494 => _494[0], 'optionalAccess', _495 => _495.points, 'access', _496 => _496[0]]);
8657
8734
  if (first) await this.glide(id, first);
8658
8735
  const result = c.replayStrokes(command.replay);
8659
8736
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -8701,7 +8778,7 @@ var PaintDirector = class {
8701
8778
  const checked = inits.map((s) => ({ ...s, points: c.checkPoints(s.points) }));
8702
8779
  const first = checked[0];
8703
8780
  const base = first.brushId ? c.getBrush(first.brushId) : c.getState().brush;
8704
- const stepLabel = _nullishCoalesce(label, () => ( `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _493 => _493.name]), () => ( "Brush"))} path stroke`));
8781
+ const stepLabel = _nullishCoalesce(label, () => ( `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _497 => _497.name]), () => ( "Brush"))} path stroke`));
8705
8782
  return c.group(stepLabel, async (within) => {
8706
8783
  let layerId = _nullishCoalesce(_nullishCoalesce(first.layerId, () => ( c.document.activeLayerId)), () => ( ""));
8707
8784
  let bounds = null;
@@ -8721,8 +8798,8 @@ var PaintDirector = class {
8721
8798
  bounds,
8722
8799
  dabs,
8723
8800
  strokeIds,
8724
- ..._optionalChain([last, 'optionalAccess', _494 => _494.mixerLoad]) ? { mixerLoad: last.mixerLoad } : {},
8725
- ..._optionalChain([last, 'optionalAccess', _495 => _495.wet]) !== void 0 ? { wet: last.wet } : {}
8801
+ ..._optionalChain([last, 'optionalAccess', _498 => _498.mixerLoad]) ? { mixerLoad: last.mixerLoad } : {},
8802
+ ..._optionalChain([last, 'optionalAccess', _499 => _499.wet]) !== void 0 ? { wet: last.wet } : {}
8726
8803
  };
8727
8804
  });
8728
8805
  }
@@ -9226,7 +9303,7 @@ function createPaintGuideTools(c) {
9226
9303
  type: "object",
9227
9304
  properties: {
9228
9305
  color: { ...COLOR2, description: "A colour #rrggbb." },
9229
- paint: { ..._chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
9306
+ paint: { ..._chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
9230
9307
  name: { type: "string", minLength: 1, description: "Optional name." }
9231
9308
  },
9232
9309
  additionalProperties: false
@@ -9894,9 +9971,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
9894
9971
  inputSchema: EMPTY3,
9895
9972
  annotations: { title: "List papers", ...READ6 },
9896
9973
  handler: () => ({
9897
- papers: _chunkOKHKA43Lcjs.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 })),
9898
- families: [..._chunkOKHKA43Lcjs.PAPER_FAMILIES],
9899
- patterns: [..._chunkPXDIAYB6cjs.GRAIN_PATTERNS]
9974
+ papers: _chunkJBB3GDBBcjs.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 })),
9975
+ families: [..._chunkJBB3GDBBcjs.PAPER_FAMILIES],
9976
+ patterns: [..._chunkNIBFKXMDcjs.GRAIN_PATTERNS]
9900
9977
  })
9901
9978
  });
9902
9979
  add({
@@ -9927,7 +10004,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9927
10004
  depth: { type: "number", minimum: 0, maximum: 1, description: "Grain depth 0..1 (0: brushes ignore the grain)." },
9928
10005
  scale: { type: "number", minimum: 0.25, maximum: 8, description: "Grain scale: 1 natural, 2 twice as coarse." },
9929
10006
  seed: { type: "integer", minimum: 0, description: "Grain seed: another sheet of the same paper." },
9930
- pattern: { type: "string", enum: [..._chunkPXDIAYB6cjs.GRAIN_PATTERNS], description: "Grain pattern." },
10007
+ pattern: { type: "string", enum: [..._chunkNIBFKXMDcjs.GRAIN_PATTERNS], description: "Grain pattern." },
9931
10008
  tiling: { type: "string", enum: ["repeat", "mirror"], description: "How the grain tile repeats (mirror hides seams)." },
9932
10009
  shading: { type: "number", minimum: 0, maximum: 1, description: "How much the grain shades the paper colour." },
9933
10010
  dry: { ...tuning, description: "Height map tuning for dry media." },
@@ -10127,10 +10204,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
10127
10204
  name: "set_brush",
10128
10205
  title: "Set the brush",
10129
10206
  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).",
10130
- 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." }, ..._chunkDT4YQUGTcjs.BRUSH_PATCH_PROPERTIES, unset: _chunkDT4YQUGTcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
10207
+ 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." }, ..._chunkYXP6X3SYcjs.BRUSH_PATCH_PROPERTIES, unset: _chunkYXP6X3SYcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
10131
10208
  annotations: { title: "Set the brush", ...SET4 },
10132
10209
  handler: async ({ id, unset, ...patch }) => {
10133
- const stamps = _optionalChain([patch, 'access', _496 => _496.tip, 'optionalAccess', _497 => _497.stamps]);
10210
+ const stamps = _optionalChain([patch, 'access', _500 => _500.tip, 'optionalAccess', _501 => _501.stamps]);
10134
10211
  if (stamps) await c.prepareStickers(stamps);
10135
10212
  const r = c.setBrushFacets(patch, id, unset);
10136
10213
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -10163,7 +10240,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10163
10240
  name: "set_paint",
10164
10241
  title: "Set the paint (colour or gradient)",
10165
10242
  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.',
10166
- inputSchema: { type: "object", properties: { paint: _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
10243
+ inputSchema: { type: "object", properties: { paint: _chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
10167
10244
  annotations: { title: "Set the paint (colour or gradient)", ...SET4 },
10168
10245
  handler: ({ paint }) => {
10169
10246
  const p = c.setPaint(paint);
@@ -10223,9 +10300,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
10223
10300
  points: POINTS,
10224
10301
  layerId: LAYER_ID4,
10225
10302
  brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
10226
- brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkDT4YQUGTcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
10303
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkYXP6X3SYcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
10227
10304
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
10228
- paint: { ..._chunkFQPUF2W2cjs.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." },
10305
+ 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." },
10229
10306
  seed: { type: "integer", minimum: 0, description: "Jitter seed (default a new one); the same seed and points give the same marks." },
10230
10307
  snapToPerspective: { type: "boolean", description: "Snap the points to the perspective guide, as a pen stroke would (default false)." }
10231
10308
  },
@@ -10239,7 +10316,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10239
10316
  const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
10240
10317
  const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
10241
10318
  if (base) {
10242
- const refs = _chunkOKHKA43Lcjs.brushStickerRefs.call(void 0, _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
10319
+ const refs = _chunkJBB3GDBBcjs.brushStickerRefs.call(void 0, _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
10243
10320
  if (refs.length) await c.prepareStickers(refs);
10244
10321
  }
10245
10322
  const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush, color: a.color, paint: a.paint, seed: a.seed, snapToPerspective: a.snapToPerspective };
@@ -10260,9 +10337,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
10260
10337
  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)." },
10261
10338
  layerId: LAYER_ID4,
10262
10339
  brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
10263
- brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkDT4YQUGTcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
10340
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkYXP6X3SYcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
10264
10341
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
10265
- paint: { ..._chunkFQPUF2W2cjs.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." },
10342
+ 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." },
10266
10343
  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." }
10267
10344
  },
10268
10345
  required: ["path"],
@@ -10275,7 +10352,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10275
10352
  const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
10276
10353
  const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
10277
10354
  if (base) {
10278
- const refs = _chunkOKHKA43Lcjs.brushStickerRefs.call(void 0, _chunkXVOP3CGQcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
10355
+ const refs = _chunkJBB3GDBBcjs.brushStickerRefs.call(void 0, _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
10279
10356
  if (refs.length) await c.prepareStickers(refs);
10280
10357
  }
10281
10358
  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;
@@ -10292,7 +10369,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10292
10369
  const { path: _path, spacing: _spacing, pressure: _pressure, speed: _speed, ...stroke } = init;
10293
10370
  return {
10294
10371
  kind: "strokes",
10295
- label: `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _498 => _498.name]), () => ( "Brush"))} path stroke`,
10372
+ label: `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _502 => _502.name]), () => ( "Brush"))} path stroke`,
10296
10373
  strokes: subpaths.map((points, i) => ({
10297
10374
  ...stroke,
10298
10375
  ...stroke.seed !== void 0 ? { seed: stroke.seed + i } : {},
@@ -10349,7 +10426,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10349
10426
  if (ids) {
10350
10427
  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.`);
10351
10428
  }
10352
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _499 => _499.document, 'access', _500 => _500.liveStrokes, 'optionalAccess', _501 => _501[s.layerId], 'optionalAccess', _502 => _502.includes, 'call', _503 => _503(s)]) === true)) };
10429
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _503 => _503.document, 'access', _504 => _504.liveStrokes, 'optionalAccess', _505 => _505[s.layerId], 'optionalAccess', _506 => _506.includes, 'call', _507 => _507(s)]) === true)) };
10353
10430
  }
10354
10431
  });
10355
10432
  add({
@@ -10382,9 +10459,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
10382
10459
  properties: {
10383
10460
  id: { type: "string", description: "Stroke id from list_strokes {live: true}." },
10384
10461
  brushId: { type: "string", description: "Brush id from list_brush_presets; the stroke keeps its size." },
10385
- brush: { type: "object", properties: _chunkDT4YQUGTcjs.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." },
10462
+ brush: { type: "object", properties: _chunkYXP6X3SYcjs.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." },
10386
10463
  color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", description: "New colour #rrggbb (replaces gradient paint)." },
10387
- paint: { anyOf: [_chunkFQPUF2W2cjs.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." },
10464
+ 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." },
10388
10465
  seed: { type: "integer", minimum: 0, description: "Another jitter seed: particles, scatter and texture fall differently." }
10389
10466
  },
10390
10467
  required: ["id"],
@@ -10630,10 +10707,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
10630
10707
  tools.push(...createPaintThickTools(c));
10631
10708
  tools.push(...createPaintReplayTools(c));
10632
10709
  tools.push(...createPaintStickerTools(c));
10633
- tools.push(..._chunkEXB2EGBEcjs.createPigmentTools.call(void 0, ));
10710
+ tools.push(..._chunk62MFUHSIcjs.createPigmentTools.call(void 0, ));
10634
10711
  tools.push(..._chunkPFHJS4HEcjs.createStickerTools.call(void 0, { provider: () => c.stickersProvider }));
10635
10712
  tools.push(
10636
- ..._chunkLHPEG5AUcjs.createLayerEffectTools.call(void 0,
10713
+ ..._chunkJ4GXP53Rcjs.createLayerEffectTools.call(void 0,
10637
10714
  {
10638
10715
  requireLayer: (id) => void c.getLayerEffects(id),
10639
10716
  getLayerEffects: (id) => c.getLayerEffects(id),
@@ -10658,16 +10735,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
10658
10735
  }
10659
10736
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
10660
10737
  if (!origin && !onChange) return tool;
10661
- const write = !_optionalChain([tool, 'access', _504 => _504.annotations, 'optionalAccess', _505 => _505.readOnlyHint]);
10738
+ const write = !_optionalChain([tool, 'access', _508 => _508.annotations, 'optionalAccess', _509 => _509.readOnlyHint]);
10662
10739
  const done = (result) => {
10663
- if (write) _optionalChain([onChange, 'optionalCall', _506 => _506({ tool: tool.name })]);
10664
- return origin && _optionalChain([coordinates, 'optionalAccess', _507 => _507.out]) ? fromDocument(result, coordinates.out, origin) : result;
10740
+ if (write) _optionalChain([onChange, 'optionalCall', _510 => _510({ tool: tool.name })]);
10741
+ return origin && _optionalChain([coordinates, 'optionalAccess', _511 => _511.out]) ? fromDocument(result, coordinates.out, origin) : result;
10665
10742
  };
10666
10743
  return {
10667
10744
  ...tool,
10668
10745
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
10669
10746
  handler: (args, context) => {
10670
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _508 => _508.in]) ? toDocument(args, coordinates.in, origin) : args, context);
10747
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _512 => _512.in]) ? toDocument(args, coordinates.in, origin) : args, context);
10671
10748
  return r instanceof Promise ? r.then(done) : done(r);
10672
10749
  }
10673
10750
  };
@@ -10684,26 +10761,38 @@ function strokeSummary(s, withPoints, live) {
10684
10761
  color: s.color,
10685
10762
  points: withPoints ? s.points : s.points.length,
10686
10763
  seed: s.seed,
10687
- copies: _nullishCoalesce(_optionalChain([s, 'access', _509 => _509.copies, 'optionalAccess', _510 => _510.length]), () => ( 0)),
10764
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _513 => _513.copies, 'optionalAccess', _514 => _514.length]), () => ( 0)),
10688
10765
  live,
10689
10766
  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) }
10690
10767
  };
10691
10768
  }
10692
10769
 
10693
10770
  // src/paint-editor/brush-library-tools.ts
10694
- function paintBrushPreviewRenderer(paper = () => _chunkOKHKA43Lcjs.DEFAULT_PAPER) {
10695
- const render = (brush, { width, height, color }) => {
10696
- const t = renderBrushThumbnail(_chunkXVOP3CGQcjs.resolveBrush.call(void 0, brush), { paper: paper(), width, height, color: color.toLowerCase() });
10771
+ function paintBrushPreviewRenderer(paper = () => _chunkJBB3GDBBcjs.DEFAULT_PAPER, options = {}) {
10772
+ const sources = new BrushSourceArtCache();
10773
+ const draw = (brush, { width, height, color }) => {
10774
+ const stickers = _optionalChain([options, 'access', _515 => _515.stampArt, 'optionalCall', _516 => _516()]);
10775
+ const stampArt = sources.with(_nullishCoalesce(stickers, () => ( (() => void 0))));
10776
+ const t = renderBrushThumbnail(_chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, brush), { paper: paper(), width, height, color: color.toLowerCase(), stampArt });
10697
10777
  return { data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" };
10698
10778
  };
10779
+ const render = (brush, size) => {
10780
+ const ids = _chunkEU2ZZA6Lcjs.brushSourceIds.call(void 0, brush);
10781
+ if (!ids.length || !options.library) return draw(brush, size);
10782
+ const library = options.library;
10783
+ return Promise.all(ids.map((id) => library.getSource(id))).then((found) => {
10784
+ sources.set(found.filter((s) => s !== null));
10785
+ return draw(brush, size);
10786
+ });
10787
+ };
10699
10788
  return Object.defineProperty(render, "paper", { get: () => paper().color, enumerable: true });
10700
10789
  }
10701
10790
  function createPaintBrushLibraryToolProvider(controller, options = {}) {
10702
- return _chunkDT4YQUGTcjs.createBrushLibraryToolProvider.call(void 0, controller.brushLibrary, {
10703
- profile: _chunkXVOP3CGQcjs.PAINT_PROFILE,
10791
+ return _chunkYXP6X3SYcjs.createBrushLibraryToolProvider.call(void 0, controller.brushLibrary, {
10792
+ profile: _chunkEU2ZZA6Lcjs.PAINT_PROFILE,
10704
10793
  stickers: () => controller.stickers.provider,
10705
10794
  ...options,
10706
- renderPreview: paintBrushPreviewRenderer(() => controller.getState().document.paper)
10795
+ renderPreview: paintBrushPreviewRenderer(() => controller.getState().document.paper, { library: controller.brushLibrary, stampArt: () => controller.stampArt })
10707
10796
  });
10708
10797
  }
10709
10798
 
@@ -10716,21 +10805,21 @@ var PAINT_TOOLS = [
10716
10805
  { id: "pan", label: "Pan", key: "h" },
10717
10806
  { id: "rotate", label: "Rotate view", key: "r" }
10718
10807
  ];
10719
- var PaintGesture = (_class14 = class {
10720
- constructor(controller, box) {;_class14.prototype.__init129.call(this);_class14.prototype.__init130.call(this);_class14.prototype.__init131.call(this);_class14.prototype.__init132.call(this);_class14.prototype.__init133.call(this);_class14.prototype.__init134.call(this);
10808
+ var PaintGesture = (_class15 = class {
10809
+ constructor(controller, box) {;_class15.prototype.__init134.call(this);_class15.prototype.__init135.call(this);_class15.prototype.__init136.call(this);_class15.prototype.__init137.call(this);_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);
10721
10810
  this.controller = controller;
10722
10811
  this.box = box;
10723
10812
  }
10724
10813
 
10725
10814
 
10726
- __init129() {this.tool = "brush"}
10815
+ __init134() {this.tool = "brush"}
10727
10816
  /** The last refusal (a hidden or locked layer), for the editor to show. */
10728
- __init130() {this.error = null}
10817
+ __init135() {this.error = null}
10729
10818
  /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */
10730
- __init131() {this.predicted = []}
10731
- __init132() {this.mode = null}
10732
- __init133() {this.penAt = null}
10733
- __init134() {this.penDown = false}
10819
+ __init136() {this.predicted = []}
10820
+ __init137() {this.mode = null}
10821
+ __init138() {this.penAt = null}
10822
+ __init139() {this.penDown = false}
10734
10823
  doc(e) {
10735
10824
  const b = this.box();
10736
10825
  const s = this.controller.getState();
@@ -10786,13 +10875,13 @@ var PaintGesture = (_class14 = class {
10786
10875
  const p = this.doc(e);
10787
10876
  const s = this.controller.getState();
10788
10877
  const layerId = s.document.activeLayerId;
10789
- if (!layerId || !_optionalChain([s, 'access', _511 => _511.document, 'access', _512 => _512.liveStrokes, 'optionalAccess', _513 => _513[layerId]])) {
10878
+ if (!layerId || !_optionalChain([s, 'access', _517 => _517.document, 'access', _518 => _518.liveStrokes, 'optionalAccess', _519 => _519[layerId]])) {
10790
10879
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
10791
10880
  return false;
10792
10881
  }
10793
10882
  try {
10794
10883
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
10795
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _514 => _514.id]), () => ( null)));
10884
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _520 => _520.id]), () => ( null)));
10796
10885
  if (!hit) return false;
10797
10886
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
10798
10887
  return true;
@@ -10804,7 +10893,7 @@ var PaintGesture = (_class14 = class {
10804
10893
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
10805
10894
  get strokeDrag() {
10806
10895
  const m = this.mode;
10807
- return _optionalChain([m, 'optionalAccess', _515 => _515.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
10896
+ return _optionalChain([m, 'optionalAccess', _521 => _521.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
10808
10897
  }
10809
10898
  /**
10810
10899
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -10878,7 +10967,7 @@ var PaintGesture = (_class14 = class {
10878
10967
  if (!m || m.pointerId !== e.pointerId) return;
10879
10968
  this.mode = null;
10880
10969
  this.predicted = [];
10881
- if (m.kind === "stroke") _optionalChain([this, 'access', _516 => _516.controller, 'access', _517 => _517.activeStroke, 'optionalAccess', _518 => _518.end, 'call', _519 => _519()]);
10970
+ if (m.kind === "stroke") _optionalChain([this, 'access', _522 => _522.controller, 'access', _523 => _523.activeStroke, 'optionalAccess', _524 => _524.end, 'call', _525 => _525()]);
10882
10971
  if (m.kind === "move-stroke") {
10883
10972
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
10884
10973
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -10902,8 +10991,8 @@ var PaintGesture = (_class14 = class {
10902
10991
  cancel() {
10903
10992
  this.penDown = false;
10904
10993
  this.predicted = [];
10905
- if (_optionalChain([this, 'access', _520 => _520.mode, 'optionalAccess', _521 => _521.kind]) === "stroke") _optionalChain([this, 'access', _522 => _522.controller, 'access', _523 => _523.activeStroke, 'optionalAccess', _524 => _524.cancel, 'call', _525 => _525()]);
10906
- if (_optionalChain([this, 'access', _526 => _526.mode, 'optionalAccess', _527 => _527.kind]) === "sticker") this.controller.cancelStickerPreview();
10994
+ if (_optionalChain([this, 'access', _526 => _526.mode, 'optionalAccess', _527 => _527.kind]) === "stroke") _optionalChain([this, 'access', _528 => _528.controller, 'access', _529 => _529.activeStroke, 'optionalAccess', _530 => _530.cancel, 'call', _531 => _531()]);
10995
+ if (_optionalChain([this, 'access', _532 => _532.mode, 'optionalAccess', _533 => _533.kind]) === "sticker") this.controller.cancelStickerPreview();
10907
10996
  this.mode = null;
10908
10997
  }
10909
10998
  get active() {
@@ -10923,7 +11012,7 @@ var PaintGesture = (_class14 = class {
10923
11012
  const py = e.clientY - b.top - b.height / 2;
10924
11013
  this.controller.setView({ zoom, pan: { x: px - (px - s.view.pan.x) * k, y: py - (py - s.view.pan.y) * k } });
10925
11014
  }
10926
- }, _class14);
11015
+ }, _class15);
10927
11016
  var round2 = (v) => Math.round(v * 100) / 100;
10928
11017
  var PAINT_SHORTCUTS = [
10929
11018
  { id: "undo", label: "Undo", group: "edit", keys: ["Mod+Z"], tool: "undo_paint" },
@@ -10967,14 +11056,14 @@ function handlePaintShortcut(controller, gesture, e) {
10967
11056
  else if (id === "view.reset") controller.resetView();
10968
11057
  return true;
10969
11058
  }
10970
- var PaintCanvasPresenter = (_class15 = class {
10971
- constructor(controller) {;_class15.prototype.__init135.call(this);_class15.prototype.__init136.call(this);_class15.prototype.__init137.call(this);
11059
+ var PaintCanvasPresenter = (_class16 = class {
11060
+ constructor(controller) {;_class16.prototype.__init140.call(this);_class16.prototype.__init141.call(this);_class16.prototype.__init142.call(this);
10972
11061
  this.controller = controller;
10973
11062
  }
10974
11063
 
10975
- __init135() {this.uploaded = /* @__PURE__ */ new Map()}
10976
- __init136() {this.scratch = null}
10977
- __init137() {this.size = ""}
11064
+ __init140() {this.uploaded = /* @__PURE__ */ new Map()}
11065
+ __init141() {this.scratch = null}
11066
+ __init142() {this.size = ""}
10978
11067
  /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
10979
11068
  render(ctx) {
10980
11069
  const { width, height } = this.controller.document.canvas;
@@ -11000,13 +11089,13 @@ var PaintCanvasPresenter = (_class15 = class {
11000
11089
  }, { dirty });
11001
11090
  return drawn;
11002
11091
  }
11003
- }, _class15);
11092
+ }, _class16);
11004
11093
  function guideOverlay(controller, drag) {
11005
11094
  const s = controller.getState();
11006
11095
  const size = s.document.canvas;
11007
11096
  const out = [];
11008
11097
  const layerId = s.document.activeLayerId;
11009
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _528 => _528.document, 'access', _529 => _529.liveStrokes, 'optionalAccess', _530 => _530[layerId], 'optionalAccess', _531 => _531.some, 'call', _532 => _532((x) => x.id === s.selectedStroke)]) : false;
11098
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _534 => _534.document, 'access', _535 => _535.liveStrokes, 'optionalAccess', _536 => _536[layerId], 'optionalAccess', _537 => _537.some, 'call', _538 => _538((x) => x.id === s.selectedStroke)]) : false;
11010
11099
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
11011
11100
  if (area) {
11012
11101
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -11019,7 +11108,7 @@ function guideOverlay(controller, drag) {
11019
11108
  ];
11020
11109
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
11021
11110
  }
11022
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _533 => _533.document, 'access', _534 => _534.stickers, 'optionalAccess', _535 => _535[layerId], 'optionalAccess', _536 => _536.find, 'call', _537 => _537((x) => x.id === s.selectedSticker)]) : void 0;
11111
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _539 => _539.document, 'access', _540 => _540.stickers, 'optionalAccess', _541 => _541[layerId], 'optionalAccess', _542 => _542.find, 'call', _543 => _543((x) => x.id === s.selectedSticker)]) : void 0;
11023
11112
  if (picked) {
11024
11113
  const r = picked.size / 2 + 2;
11025
11114
  const a = picked.rotation * Math.PI / 180;
@@ -11049,7 +11138,7 @@ var PAPER_SLIDERS = [
11049
11138
  ];
11050
11139
  function readPath(obj, path) {
11051
11140
  let v = obj;
11052
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _538 => _538[k]]);
11141
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _544 => _544[k]]);
11053
11142
  return typeof v === "number" ? v : 0;
11054
11143
  }
11055
11144
  function patchPath(obj, path, value) {
@@ -11165,7 +11254,7 @@ function startWetClock(controller, frame, cancel) {
11165
11254
  id = raf(loop);
11166
11255
  return () => {
11167
11256
  stopped = true;
11168
- _optionalChain([caf, 'optionalCall', _539 => _539(id)]);
11257
+ _optionalChain([caf, 'optionalCall', _545 => _545(id)]);
11169
11258
  };
11170
11259
  }
11171
11260
  function drawWaterOverlay(controller, ctx) {
@@ -11196,7 +11285,7 @@ var DOT_ROTATION_LABELS = { follow: "Follow motion", random: "Random", fixed: "T
11196
11285
  var STAMP_LABELS = { dot: "Dot", star: "Star", heart: "Heart", leaf: "Leaf", flower: "Flower", confetti: "Confetti", splat: "Splat", sparkle: "Sparkle", ring: "Ring" };
11197
11286
  function toggleStickerRef(refs, ref2) {
11198
11287
  if (refs.includes(ref2)) return refs.length > 1 ? refs.filter((r) => r !== ref2) : [...refs];
11199
- return refs.length < _chunkXVOP3CGQcjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
11288
+ return refs.length < _chunkEU2ZZA6Lcjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
11200
11289
  }
11201
11290
  function stickerRefLabel(ref2) {
11202
11291
  const stamp = ref2.startsWith("editor:") ? ref2.slice(7) : null;
@@ -11209,7 +11298,7 @@ function toggleStamp(stamps, stamp) {
11209
11298
  }
11210
11299
  function toggleDotTexture(textures, stamp) {
11211
11300
  if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
11212
- return textures.length < _chunkXVOP3CGQcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
11301
+ return textures.length < _chunkEU2ZZA6Lcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
11213
11302
  }
11214
11303
  var PATH_STROKE_TAPERS = [
11215
11304
  { id: "even", label: "Even" },
@@ -11523,7 +11612,7 @@ function createPaintChangeFeed(controller, options = {}) {
11523
11612
  const doc = state.document;
11524
11613
  const layers = /* @__PURE__ */ new Map();
11525
11614
  for (const l of controller.listLayers()) layers.set(l.id, { name: l.name, visible: l.visible, opacity: l.opacity, blend: l.blend });
11526
- return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _540 => _540.paintEvents, 'optionalAccess', _541 => _541.length]), () => ( 0)), layers, stroking: state.stroking };
11615
+ return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _546 => _546.paintEvents, 'optionalAccess', _547 => _547.length]), () => ( 0)), layers, stroking: state.stroking };
11527
11616
  };
11528
11617
  let last = take();
11529
11618
  const check = () => {
@@ -11554,7 +11643,7 @@ function createPaintChangeFeed(controller, options = {}) {
11554
11643
  if (edited) pending = void 0;
11555
11644
  const change = {
11556
11645
  seq: ++seq,
11557
- origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _542 => _542.origin]), () => ( "user")),
11646
+ origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _548 => _548.origin]), () => ( "user")),
11558
11647
  ...commit ? { commit } : {},
11559
11648
  addedStrokes,
11560
11649
  removedStrokes,
@@ -11621,7 +11710,7 @@ function createPaintProposals(options) {
11621
11710
  };
11622
11711
  const strokeIds = () => new Set(controller.getStrokes().map((s) => s.id));
11623
11712
  const validate = (input) => {
11624
- if (!_optionalChain([input, 'access', _543 => _543.title, 'optionalAccess', _544 => _544.trim, 'call', _545 => _545()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
11713
+ if (!_optionalChain([input, 'access', _549 => _549.title, 'optionalAccess', _550 => _550.trim, 'call', _551 => _551()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
11625
11714
  if (!Array.isArray(input.ops) || !input.ops.length) throw new PaintEditorError("A proposal needs at least one op (stroke, wash or echo).");
11626
11715
  const place = _nullishCoalesce(input.place, () => ( "top"));
11627
11716
  if (place === "above") {
@@ -11633,7 +11722,7 @@ function createPaintProposals(options) {
11633
11722
  input.ops.forEach((op, i) => {
11634
11723
  const at = `ops[${i}]`;
11635
11724
  if (op.kind === "stroke") {
11636
- if (!_optionalChain([op, 'access', _546 => _546.points, 'optionalAccess', _547 => _547.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
11725
+ if (!_optionalChain([op, 'access', _552 => _552.points, 'optionalAccess', _553 => _553.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
11637
11726
  points += op.points.length;
11638
11727
  if (op.color !== void 0 && !HEX3.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
11639
11728
  const brush = op.brushId ? controller.getBrush(op.brushId) : controller.getState().brush;
@@ -11645,7 +11734,7 @@ function createPaintProposals(options) {
11645
11734
  if (!HEX3.test(_nullishCoalesce(op.color, () => ( "")))) throw new PaintEditorError(`${at}: a wash needs color as #rrggbb.`);
11646
11735
  if (op.opacity !== void 0 && !(op.opacity > 0 && op.opacity <= 1)) throw new PaintEditorError(`${at}: opacity must be in (0, 1].`);
11647
11736
  } else if (op.kind === "echo") {
11648
- if (!_optionalChain([op, 'access', _548 => _548.strokeIds, 'optionalAccess', _549 => _549.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
11737
+ if (!_optionalChain([op, 'access', _554 => _554.strokeIds, 'optionalAccess', _555 => _555.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
11649
11738
  const unknown = op.strokeIds.filter((id) => !known.has(id));
11650
11739
  if (unknown.length) throw new PaintEditorError(`${at}: unknown stroke ${unknown.map((u) => `"${u}"`).join(", ")}. Call list_strokes for the ids.`);
11651
11740
  if (op.color !== void 0 && !HEX3.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
@@ -11694,7 +11783,7 @@ function createPaintProposals(options) {
11694
11783
  ...input.layerId ? { layerId: input.layerId } : {},
11695
11784
  ...input.layerName ? { layerName: input.layerName } : {}
11696
11785
  });
11697
- const topLayerId = () => _optionalChain([controller, 'access', _550 => _550.listLayers, 'call', _551 => _551(), 'access', _552 => _552.find, 'call', _553 => _553((l) => l.parentId === null), 'optionalAccess', _554 => _554.id]);
11786
+ const topLayerId = () => _optionalChain([controller, 'access', _556 => _556.listLayers, 'call', _557 => _557(), 'access', _558 => _558.find, 'call', _559 => _559((l) => l.parentId === null), 'optionalAccess', _560 => _560.id]);
11698
11787
  return {
11699
11788
  getState: () => state,
11700
11789
  subscribe(listener) {
@@ -11881,7 +11970,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
11881
11970
  },
11882
11971
  annotations: { title: "Propose paint", ...WRITE6 },
11883
11972
  handler: (args, context) => {
11884
- const origin = _optionalChain([context, 'access', _555 => _555.actor, 'optionalAccess', _556 => _556.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
11973
+ const origin = _optionalChain([context, 'access', _561 => _561.actor, 'optionalAccess', _562 => _562.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
11885
11974
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
11886
11975
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
11887
11976
  return { proposalId: proposal.id, ...rest };
@@ -12003,7 +12092,7 @@ function toolList(provider) {
12003
12092
  function uiTables() {
12004
12093
  return {
12005
12094
  tools: PAINT_TOOLS,
12006
- brushOptions: _chunkLHPEG5AUcjs.BRUSH_OPTION_CONTROLS,
12095
+ brushOptions: _chunkJ4GXP53Rcjs.BRUSH_OPTION_CONTROLS,
12007
12096
  blendMenu: BLEND_MENU_GROUPS,
12008
12097
  layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_MENU.map(({ kind, label }) => ({ kind, label, controls: _chunkPVJMTLPJcjs.layerEffectControls.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, kind)) })),
12009
12098
  sliders: { paper: PAPER_SLIDERS, wet: WET_PARAM_SLIDERS, wetTilt: WET_TILT_SLIDERS, wetSpeed: WET_SPEED_SLIDER, light: LIGHT_SLIDERS, stroke: STROKE_SLIDERS, sticker: STICKER_SLIDERS },
@@ -12430,4 +12519,10 @@ function createPaintConformanceHost(setup, options) {
12430
12519
 
12431
12520
 
12432
12521
 
12433
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkXVOP3CGQcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkXVOP3CGQcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkDT4YQUGTcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkXVOP3CGQcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkXVOP3CGQcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkXVOP3CGQcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkXVOP3CGQcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkXVOP3CGQcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkJ5VQYK7Tcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkXVOP3CGQcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkXVOP3CGQcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkXVOP3CGQcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkOKHKA43Lcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkXVOP3CGQcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkXVOP3CGQcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkXVOP3CGQcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkXVOP3CGQcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkJ5VQYK7Tcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkXVOP3CGQcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkXVOP3CGQcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkOKHKA43Lcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkOKHKA43Lcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkOKHKA43Lcjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = _chunkOKHKA43Lcjs.GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkOKHKA43Lcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkXVOP3CGQcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkXVOP3CGQcjs.MAX_DOT_TEXTURES; 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 = _chunkXVOP3CGQcjs.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 = _chunkXVOP3CGQcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkXVOP3CGQcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkXVOP3CGQcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.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 = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.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 = _chunkOKHKA43Lcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkOKHKA43Lcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkXVOP3CGQcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkXVOP3CGQcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = _chunkOKHKA43Lcjs.PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = _chunkOKHKA43Lcjs.PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = _chunkOKHKA43Lcjs.PenDabWalker; exports.PenSmoother = _chunkOKHKA43Lcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkXVOP3CGQcjs.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.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkJ5VQYK7Tcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = _chunkOKHKA43Lcjs.WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkXVOP3CGQcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = _chunkOKHKA43Lcjs.WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkJ5VQYK7Tcjs.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 = _chunkXVOP3CGQcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = _chunkOKHKA43Lcjs.WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkDT4YQUGTcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkXVOP3CGQcjs.brushTakesPaint; exports.brushToJSON = _chunkXVOP3CGQcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkOKHKA43Lcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; 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.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunkOKHKA43Lcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkOKHKA43Lcjs.effectPaintKey; exports.effectPaintSize = _chunkOKHKA43Lcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = _chunkOKHKA43Lcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = _chunkOKHKA43Lcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkXVOP3CGQcjs.isWetBrush; exports.isWetCapable = _chunkXVOP3CGQcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkOKHKA43Lcjs.mixerTip; exports.multiColorForDab = _chunkOKHKA43Lcjs.multiColorForDab; exports.multiColorGradient = _chunkOKHKA43Lcjs.multiColorGradient; exports.multiColorPalette = _chunkOKHKA43Lcjs.multiColorPalette; exports.multiColorSliders = _chunkDT4YQUGTcjs.multiColorSliders; exports.multiColorToPaint = _chunkXVOP3CGQcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkXVOP3CGQcjs.normalizeBehavior; exports.normalizeBristle = _chunkXVOP3CGQcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkXVOP3CGQcjs.normalizeDynamics; exports.normalizeFlow = _chunkJ5VQYK7Tcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkXVOP3CGQcjs.normalizeImpasto; exports.normalizeLight = _chunkXVOP3CGQcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkXVOP3CGQcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkXVOP3CGQcjs.normalizePaintBrush; exports.normalizePaper = _chunkOKHKA43Lcjs.normalizePaper; exports.normalizeParticle = _chunkXVOP3CGQcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkXVOP3CGQcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkXVOP3CGQcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkJ5VQYK7Tcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintBrushPreviewRenderer = paintBrushPreviewRenderer; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkXVOP3CGQcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkOKHKA43Lcjs.paperPreset; exports.parseBrushLibrary = _chunkXVOP3CGQcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkDT4YQUGTcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkOKHKA43Lcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = _chunkOKHKA43Lcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkOKHKA43Lcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkOKHKA43Lcjs.renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = _chunkOKHKA43Lcjs.sampleEffectAt; exports.sampleEffectField = _chunkOKHKA43Lcjs.sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkRDFHWAHLcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; 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.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkOKHKA43Lcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkOKHKA43Lcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkXVOP3CGQcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = _chunkOKHKA43Lcjs.wetPaperInput; exports.wetPigmentOf = _chunkOKHKA43Lcjs.wetPigmentOf; exports.wetSupport = _chunkJ5VQYK7Tcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
12522
+
12523
+
12524
+
12525
+
12526
+
12527
+
12528
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkEU2ZZA6Lcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkEU2ZZA6Lcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkYXP6X3SYcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkEU2ZZA6Lcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.BrushSourceArtCache = BrushSourceArtCache; exports.DAB_FLIPS = _chunkEU2ZZA6Lcjs.DAB_FLIPS; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkEU2ZZA6Lcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkEU2ZZA6Lcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkEU2ZZA6Lcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkEU2ZZA6Lcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkJ5VQYK7Tcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkEU2ZZA6Lcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkEU2ZZA6Lcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkEU2ZZA6Lcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkJBB3GDBBcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkEU2ZZA6Lcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkEU2ZZA6Lcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkEU2ZZA6Lcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_TIP_GRAIN = _chunkEU2ZZA6Lcjs.DEFAULT_TIP_GRAIN; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkEU2ZZA6Lcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkJ5VQYK7Tcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkEU2ZZA6Lcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkEU2ZZA6Lcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkJBB3GDBBcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkJBB3GDBBcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkJBB3GDBBcjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = _chunkJBB3GDBBcjs.GPU_LEAD; exports.GRAIN_PATTERNS = _chunkNIBFKXMDcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkNIBFKXMDcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkJBB3GDBBcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkEU2ZZA6Lcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; 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 = _chunkEU2ZZA6Lcjs.MAX_DOT_TEXTURES; 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 = _chunkEU2ZZA6Lcjs.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 = _chunkEU2ZZA6Lcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkEU2ZZA6Lcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkEU2ZZA6Lcjs.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 = _chunkJBB3GDBBcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkJBB3GDBBcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkEU2ZZA6Lcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkEU2ZZA6Lcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = _chunkJBB3GDBBcjs.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 = _chunkJBB3GDBBcjs.PaintWetLayers; exports.PaperGrain = _chunkNIBFKXMDcjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = _chunkJBB3GDBBcjs.PenDabWalker; exports.PenSmoother = _chunkJBB3GDBBcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkEU2ZZA6Lcjs.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 = _chunkEU2ZZA6Lcjs.TIP_GRAIN_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.TipGrain = _chunkJBB3GDBBcjs.TipGrain; exports.WET_FLOW_KINDS = _chunkJ5VQYK7Tcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = _chunkJBB3GDBBcjs.WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkEU2ZZA6Lcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = _chunkJBB3GDBBcjs.WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkJ5VQYK7Tcjs.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 = _chunkEU2ZZA6Lcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = _chunkJBB3GDBBcjs.WetStrokeDriver; exports.addPaintGradientStop = _chunkNIBFKXMDcjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkYXP6X3SYcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkEU2ZZA6Lcjs.brushTakesPaint; exports.brushToJSON = _chunkEU2ZZA6Lcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkJBB3GDBBcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; 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.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunkJBB3GDBBcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkJBB3GDBBcjs.effectPaintKey; exports.effectPaintSize = _chunkJBB3GDBBcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.engineBrushSourceIds = engineBrushSourceIds; exports.fitZoom = fitZoom; exports.grainCatch = _chunkNIBFKXMDcjs.grainCatch; exports.grainHeights = _chunkNIBFKXMDcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkNIBFKXMDcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkJBB3GDBBcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkNIBFKXMDcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkJBB3GDBBcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkEU2ZZA6Lcjs.isWetBrush; exports.isWetCapable = _chunkEU2ZZA6Lcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkJBB3GDBBcjs.mixerTip; exports.multiColorForDab = _chunkJBB3GDBBcjs.multiColorForDab; exports.multiColorGradient = _chunkJBB3GDBBcjs.multiColorGradient; exports.multiColorPalette = _chunkJBB3GDBBcjs.multiColorPalette; exports.multiColorSliders = _chunkYXP6X3SYcjs.multiColorSliders; exports.multiColorToPaint = _chunkEU2ZZA6Lcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkEU2ZZA6Lcjs.normalizeBehavior; exports.normalizeBristle = _chunkEU2ZZA6Lcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkEU2ZZA6Lcjs.normalizeDynamics; exports.normalizeFlow = _chunkJ5VQYK7Tcjs.normalizeFlow; exports.normalizeHexColor = _chunkNIBFKXMDcjs.normalizeHexColor; exports.normalizeImpasto = _chunkEU2ZZA6Lcjs.normalizeImpasto; exports.normalizeLight = _chunkEU2ZZA6Lcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkEU2ZZA6Lcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkEU2ZZA6Lcjs.normalizePaintBrush; exports.normalizePaper = _chunkJBB3GDBBcjs.normalizePaper; exports.normalizeParticle = _chunkEU2ZZA6Lcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkEU2ZZA6Lcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkEU2ZZA6Lcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkJ5VQYK7Tcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintBrushPreviewRenderer = paintBrushPreviewRenderer; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkNIBFKXMDcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkNIBFKXMDcjs.paintSourceColor; exports.paintSourceCss = _chunkNIBFKXMDcjs.paintSourceCss; exports.paintToMultiColor = _chunkEU2ZZA6Lcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkJBB3GDBBcjs.paperPreset; exports.parseBrushLibrary = _chunkEU2ZZA6Lcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkNIBFKXMDcjs.parsePaintSource; exports.patchBrushValue = _chunkYXP6X3SYcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkJBB3GDBBcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = _chunkJBB3GDBBcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkJBB3GDBBcjs.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 = _chunkJBB3GDBBcjs.renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkNIBFKXMDcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkNIBFKXMDcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = _chunkJBB3GDBBcjs.sampleEffectAt; exports.sampleEffectField = _chunkJBB3GDBBcjs.sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkNIBFKXMDcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkNIBFKXMDcjs.solidPaint; exports.stampCoverage = _chunkRDFHWAHLcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; 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.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkJBB3GDBBcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkJBB3GDBBcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkNIBFKXMDcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkEU2ZZA6Lcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = _chunkJBB3GDBBcjs.wetPaperInput; exports.wetPigmentOf = _chunkJBB3GDBBcjs.wetPigmentOf; exports.wetSupport = _chunkJ5VQYK7Tcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;