@pixerate/editor 0.246.0 → 0.248.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/animation-editor/index.cjs +59 -59
  2. package/dist/animation-editor/index.js +3 -3
  3. package/dist/{brushstrokeRender-ZDHMXJAE.cjs → brushstrokeRender-DTDPFBLC.cjs} +5 -5
  4. package/dist/{brushstrokeRender-AKUI3SEJ.js → brushstrokeRender-QLCXROJK.js} +2 -2
  5. package/dist/canvas/index.cjs +8 -8
  6. package/dist/canvas/index.js +1 -1
  7. package/dist/{chunk-DQWPMGH2.js → chunk-5GLYUSNT.js} +1 -1
  8. package/dist/{chunk-Q2UYUWAZ.cjs → chunk-6G6ZDDDB.cjs} +390 -27
  9. package/dist/chunk-7T7JWTVE.cjs +192 -0
  10. package/dist/{chunk-UVPD55UZ.cjs → chunk-IBDU6EGZ.cjs} +35 -35
  11. package/dist/{chunk-FK5LTDOO.cjs → chunk-L6REDLNB.cjs} +2 -2
  12. package/dist/{chunk-LDPLEZ5T.js → chunk-NZ3O3A5C.js} +1 -1
  13. package/dist/{chunk-N6WUB3Y5.js → chunk-Q2HA52V4.js} +1 -1
  14. package/dist/chunk-SC2RZ5EF.js +192 -0
  15. package/dist/{chunk-5MFDD7SP.cjs → chunk-TPWB4Y6L.cjs} +1 -1
  16. package/dist/{chunk-VDAWA546.js → chunk-VNBUDVD4.js} +388 -25
  17. package/dist/{chunk-XTWXBQD4.cjs → chunk-WVS5KQDH.cjs} +442 -87
  18. package/dist/{chunk-A23PSOBB.js → chunk-XNRBMYNB.js} +1 -1
  19. package/dist/{chunk-CEPKXLBS.cjs → chunk-XWTRATIM.cjs} +23 -23
  20. package/dist/{chunk-4PMCMWQS.js → chunk-ZFSLEOSQ.js} +357 -2
  21. package/dist/image-editor/effect-tools.d.cts +37 -4
  22. package/dist/image-editor/effect-tools.d.ts +37 -4
  23. package/dist/image-editor/index.cjs +1059 -1552
  24. package/dist/image-editor/index.d.cts +1 -1
  25. package/dist/image-editor/index.d.ts +1 -1
  26. package/dist/image-editor/index.js +275 -768
  27. package/dist/paint-editor/controller.d.cts +34 -1
  28. package/dist/paint-editor/controller.d.ts +34 -1
  29. package/dist/paint-editor/index.cjs +426 -257
  30. package/dist/paint-editor/index.js +184 -15
  31. package/dist/paint-editor/procedural.d.cts +82 -5
  32. package/dist/paint-editor/procedural.d.ts +82 -5
  33. package/dist/paint-editor/tools.d.cts +1 -1
  34. package/dist/paint-editor/tools.d.ts +1 -1
  35. package/dist/paint-editor/ui.d.cts +15 -2
  36. package/dist/paint-editor/ui.d.ts +15 -2
  37. package/dist/{image-editor/layers/effects-ui.d.ts → raster/effects/ui.d.cts} +32 -5
  38. package/dist/{image-editor/layers/effects-ui.d.cts → raster/effects/ui.d.ts} +32 -5
  39. package/dist/raster/index.cjs +13 -1
  40. package/dist/raster/index.d.cts +1 -0
  41. package/dist/raster/index.d.ts +1 -0
  42. package/dist/raster/index.js +12 -0
  43. package/dist/vector/index.cjs +962 -962
  44. package/dist/vector/index.js +4 -4
  45. package/package.json +1 -1
  46. package/skills/pixerate-paint-editor/SKILL.md +18 -27
  47. package/skills/pixerate-paint-editor/references/gradient-paint.md +23 -0
  48. package/skills/pixerate-paint-editor/references/layer-effects.md +28 -0
  49. package/skills/pixerate-paint-editor/references/light-paint.md +10 -2
  50. package/skills/pixerate-paint-editor/references/particle-brushes.md +66 -0
@@ -7,7 +7,8 @@ var _chunkXNZFVYC2cjs = require('../chunk-XNZFVYC2.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunkXTWXBQD4cjs = require('../chunk-XTWXBQD4.cjs');
10
+
11
+ var _chunkWVS5KQDHcjs = require('../chunk-WVS5KQDH.cjs');
11
12
  require('../chunk-A2IS7EHE.cjs');
12
13
  require('../chunk-SS53NNZO.cjs');
13
14
 
@@ -17,6 +18,14 @@ require('../chunk-SS53NNZO.cjs');
17
18
 
18
19
 
19
20
 
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
20
29
  var _chunkHB4ICNNAcjs = require('../chunk-HB4ICNNA.cjs');
21
30
  require('../chunk-QT26RHKK.cjs');
22
31
  require('../chunk-K6PXS6DO.cjs');
@@ -55,7 +64,10 @@ var _chunkJLWLX52Lcjs = require('../chunk-JLWLX52L.cjs');
55
64
 
56
65
 
57
66
  var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
58
- require('../chunk-FK5LTDOO.cjs');
67
+ require('../chunk-L6REDLNB.cjs');
68
+
69
+
70
+
59
71
 
60
72
 
61
73
 
@@ -133,7 +145,9 @@ require('../chunk-FK5LTDOO.cjs');
133
145
 
134
146
 
135
147
 
136
- var _chunkQ2UYUWAZcjs = require('../chunk-Q2UYUWAZ.cjs');
148
+
149
+
150
+ var _chunk6G6ZDDDBcjs = require('../chunk-6G6ZDDDB.cjs');
137
151
  require('../chunk-CVFAAZXE.cjs');
138
152
  require('../chunk-GF2RBSDM.cjs');
139
153
  require('../chunk-NM3G4VQT.cjs');
@@ -295,7 +309,7 @@ function normalizeCanvas(raw) {
295
309
  function createPaintDocument(options = {}) {
296
310
  const canvas = normalizeCanvas({ width: _nullishCoalesce(options.width, () => ( 2048)), height: _nullishCoalesce(options.height, () => ( 1536)), dpi: options.dpi });
297
311
  const layer = createPaintLayer("Layer 1");
298
- return { canvas, paper: _chunkQ2UYUWAZcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
312
+ return { canvas, paper: _chunk6G6ZDDDBcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
299
313
  }
300
314
 
301
315
  // src/paint-editor/dab-stroke.ts
@@ -349,13 +363,13 @@ var PaintDabStroke = (_class = class {
349
363
  constructor(brush, options) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);
350
364
  this.brush = brush;
351
365
  this.options = options;
352
- this.smoother = new (0, _chunkQ2UYUWAZcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
353
- this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunkQ2UYUWAZcjs.IDENTITY_COPY];
366
+ this.smoother = new (0, _chunk6G6ZDDDBcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
367
+ this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
354
368
  const exchanging = brush.engine === "mixer" || brush.engine === "dab";
355
369
  const rates = brush.engine === "mixer" ? _chunkPQ3H2AANcjs.mixerRates.call(void 0, brush.mixer) : _chunkPQ3H2AANcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, 1, brush.behavior.mixing);
356
370
  this.mixing = brush.engine === "mixer" ? brush.mixer.mixing : brush.behavior.mixing;
357
371
  this.states = this.copies.map((c, i) => ({
358
- walker: new (0, _chunkQ2UYUWAZcjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
372
+ walker: new (0, _chunk6G6ZDDDBcjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
359
373
  exchange: exchanging ? new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, options.load) : null,
360
374
  smudge: brush.engine === "smudge" ? new (0, _chunkPQ3H2AANcjs.SmudgeTip)(brush.smudge, brush.tip.size * (1 + brush.dynamics.tiltSize * 1.5)) : null
361
375
  }));
@@ -468,7 +482,7 @@ var PaintDabStroke = (_class = class {
468
482
  let flow = 1;
469
483
  if (this.options.effect) {
470
484
  const rgb = [0, 0, 0];
471
- flow = _chunkQ2UYUWAZcjs.sampleEffectAt.call(void 0, this.options.effect, d.x, d.y, rgb, d);
485
+ flow = _chunk6G6ZDDDBcjs.sampleEffectAt.call(void 0, this.options.effect, d.x, d.y, rgb, d);
472
486
  ex.setReservoirColor(rgb[0], rgb[1], rgb[2]);
473
487
  } else if (this.sampler && !this.gradient) {
474
488
  const g = this.sampler.dab(d, this.sample);
@@ -699,12 +713,12 @@ var ThickStrokeDriver = (_class3 = class {
699
713
  constructor(init) {;_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);_class3.prototype.__init21.call(this);
700
714
  this.init = init;
701
715
  const b = init.brush;
702
- this.smoother = new (0, _chunkQ2UYUWAZcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
703
- const copies = init.copies.length ? init.copies : [_chunkQ2UYUWAZcjs.IDENTITY_COPY];
716
+ this.smoother = new (0, _chunk6G6ZDDDBcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
717
+ const copies = init.copies.length ? init.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
704
718
  this.copies = copies;
705
719
  const rates = _chunkPQ3H2AANcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
706
720
  this.states = copies.map((c, i) => ({
707
- walker: new (0, _chunkQ2UYUWAZcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
721
+ walker: new (0, _chunk6G6ZDDDBcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
708
722
  exchange: new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, init.load),
709
723
  smudge: b.impasto.tool === "knife" ? new (0, _chunkPQ3H2AANcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
710
724
  carried: null,
@@ -850,7 +864,7 @@ var ThickStrokeDriver = (_class3 = class {
850
864
  let flow = 1;
851
865
  const effect = this.init.effect;
852
866
  if (effect) {
853
- _chunkQ2UYUWAZcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
867
+ _chunk6G6ZDDDBcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
854
868
  ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
855
869
  } else if (this.sampler) {
856
870
  const g = this.sampler.dab(d, this.sample);
@@ -867,7 +881,7 @@ var ThickStrokeDriver = (_class3 = class {
867
881
  let field = null;
868
882
  if (effect) {
869
883
  field = new Float32Array(n * 3);
870
- _chunkQ2UYUWAZcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
884
+ _chunk6G6ZDDDBcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
871
885
  }
872
886
  this.medium.deposit(rect, cov, dep, this.paint, ex.paintPigment, field);
873
887
  }
@@ -1044,7 +1058,7 @@ function shadowToLight(shadow) {
1044
1058
  return new (0, _chunk474IQG74cjs.TiledSurface)(1, tiles, 0);
1045
1059
  }
1046
1060
  function lightTwinBrush(brush) {
1047
- return _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0,
1061
+ return _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0,
1048
1062
  {
1049
1063
  tip: { ...brush.tip, blend: "normal", pressureOpacity: brush.tip.pressureOpacity || brush.light.pressure },
1050
1064
  behavior: { ...brush.behavior, mixing: "rgb" },
@@ -1274,7 +1288,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1274
1288
  this.layerId = init.layerId;
1275
1289
  this.base = init.surface;
1276
1290
  this.live = new Map(this.base.tiles);
1277
- this.copies = init.copies.length ? init.copies : [_chunkQ2UYUWAZcjs.IDENTITY_COPY];
1291
+ this.copies = init.copies.length ? init.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
1278
1292
  const brush = init.brush;
1279
1293
  if (init.wet) this.wetDriver = init.wet.driver;
1280
1294
  if (init.light && !init.wet && !init.sticker) this.lightTwin = this.makeLightTwin(init.light.surface);
@@ -1291,11 +1305,11 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1291
1305
  };
1292
1306
  if (this.wetDriver) {
1293
1307
  } else if (init.sticker) {
1294
- this.stickerSpray = new (0, _chunkQ2UYUWAZcjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
1308
+ this.stickerSpray = new (0, _chunk6G6ZDDDBcjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
1295
1309
  } else if (init.thick) {
1296
1310
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
1297
1311
  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 });
1298
- } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkQ2UYUWAZcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
1312
+ } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunk6G6ZDDDBcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
1299
1313
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
1300
1314
  this.wet = new PaintDabStroke(brush, {
1301
1315
  target: this.tileTarget(),
@@ -1311,7 +1325,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1311
1325
  });
1312
1326
  } else {
1313
1327
  const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect };
1314
- this.dry = brush.engine === "particle" ? new (0, _chunkQ2UYUWAZcjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunkQ2UYUWAZcjs.BristleStroke)(brush, opts) : new (0, _chunkQ2UYUWAZcjs.DryStroke)(brush, opts);
1328
+ this.dry = brush.engine === "particle" ? new (0, _chunk6G6ZDDDBcjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunk6G6ZDDDBcjs.BristleStroke)(brush, opts) : new (0, _chunk6G6ZDDDBcjs.DryStroke)(brush, opts);
1315
1329
  }
1316
1330
  }
1317
1331
 
@@ -1532,7 +1546,7 @@ function brushLoadForStroke(brush, current, color) {
1532
1546
  if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
1533
1547
  if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1534
1548
  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 } : _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD;
1535
- if (_chunkQ2UYUWAZcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1549
+ if (_chunk6G6ZDDDBcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1536
1550
  return _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD;
1537
1551
  }
1538
1552
 
@@ -1800,7 +1814,7 @@ function normalizeBrushStroke(raw) {
1800
1814
  const out = {
1801
1815
  id: r.id,
1802
1816
  layerId: r.layerId,
1803
- brush: _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
1817
+ brush: _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
1804
1818
  color: typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : "#000000",
1805
1819
  points,
1806
1820
  seed: finite2(r.seed) ? r.seed | 0 : 0
@@ -1819,7 +1833,7 @@ function normalizeBrushStroke(raw) {
1819
1833
  }
1820
1834
  if (st.length) out.stencils = st;
1821
1835
  }
1822
- const effect = _chunkQ2UYUWAZcjs.readPaintEffectPaint.call(void 0, r.paint);
1836
+ const effect = _chunk6G6ZDDDBcjs.readPaintEffectPaint.call(void 0, r.paint);
1823
1837
  const paint = effect ? null : _chunkPQ3H2AANcjs.readPaintSource.call(void 0, r.paint);
1824
1838
  if (effect) out.paint = effect;
1825
1839
  else if (paint && paint.type === "gradient") out.paint = paint;
@@ -1859,7 +1873,7 @@ function varyStroke(stroke, m, v) {
1859
1873
  if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
1860
1874
  return q;
1861
1875
  });
1862
- const brush = s !== 1 ? _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
1876
+ const brush = s !== 1 ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
1863
1877
  const out = { ...stroke, brush, points };
1864
1878
  if (_optionalChain([stroke, 'access', _87 => _87.paint, 'optionalAccess', _88 => _88.type]) === "gradient" && s !== 1) out.paint = _chunkPQ3H2AANcjs.scalePaintGradient.call(void 0, stroke.paint, s);
1865
1879
  if (_optionalChain([stroke, 'access', _89 => _89.paint, 'optionalAccess', _90 => _90.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))) } };
@@ -1904,7 +1918,7 @@ function paperTile(paper, r, light) {
1904
1918
  const key = `${paperKey(paper, light)}|${r.x},${r.y},${r.width},${r.height}`;
1905
1919
  let t = tileCache.get(key);
1906
1920
  if (!t) {
1907
- t = _chunkQ2UYUWAZcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
1921
+ t = _chunk6G6ZDDDBcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
1908
1922
  if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value);
1909
1923
  tileCache.set(key, t);
1910
1924
  }
@@ -2009,11 +2023,11 @@ function header(state, options) {
2009
2023
  return out;
2010
2024
  }
2011
2025
  function serializePaintDocument(state, options = {}) {
2012
- const { layers, assets } = _chunkXTWXBQD4cjs.serializeLayers.call(void 0, state.layers);
2026
+ const { layers, assets } = _chunkWVS5KQDHcjs.serializeLayers.call(void 0, state.layers);
2013
2027
  return { ...header(state, options), layers, assets };
2014
2028
  }
2015
2029
  async function serializePaintDocumentExternal(state, store, options = {}) {
2016
- const { layers, assets } = await _chunkXTWXBQD4cjs.serializeLayersExternal.call(void 0, state.layers, store);
2030
+ const { layers, assets } = await _chunkWVS5KQDHcjs.serializeLayersExternal.call(void 0, state.layers, store);
2017
2031
  return { ...header(state, options), layers, assets };
2018
2032
  }
2019
2033
  function paintLayersOnly(layers, problems) {
@@ -2048,9 +2062,9 @@ function deserializePaintDocument(raw) {
2048
2062
  }
2049
2063
  const problems = [];
2050
2064
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
2051
- const paper = _chunkQ2UYUWAZcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2065
+ const paper = _chunk6G6ZDDDBcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2052
2066
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
2053
- const layers = paintLayersOnly(_chunkXTWXBQD4cjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2067
+ const layers = paintLayersOnly(_chunkWVS5KQDHcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2054
2068
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
2055
2069
  const activeLayerId = wanted && _chunkHB4ICNNAcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _104 => _104.filter, 'call', _105 => _105((l) => l.type === "pixel"), 'access', _106 => _106.pop, 'call', _107 => _107(), 'optionalAccess', _108 => _108.id]), () => ( null));
2056
2070
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
@@ -2066,7 +2080,7 @@ async function deserializePaintDocumentAsync(raw, store) {
2066
2080
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
2067
2081
  const r = raw;
2068
2082
  const problems = [];
2069
- const assets = await _chunkXTWXBQD4cjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2083
+ const assets = await _chunkWVS5KQDHcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2070
2084
  const loaded = deserializePaintDocument({ ...r, assets });
2071
2085
  return { ...loaded, problems: [...problems, ...loaded.problems] };
2072
2086
  }
@@ -2149,7 +2163,7 @@ function pointerToPenPoint(e, x, y, view) {
2149
2163
  const p = { x, y, pressure: samplePressure(e) };
2150
2164
  if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;
2151
2165
  if (e.pointerType !== "pen") return p;
2152
- const o = _chunkQ2UYUWAZcjs.penOrientation.call(void 0, {
2166
+ const o = _chunk6G6ZDDDBcjs.penOrientation.call(void 0, {
2153
2167
  x,
2154
2168
  y,
2155
2169
  altitude: typeof e.altitudeAngle === "number" ? e.altitudeAngle : void 0,
@@ -2229,7 +2243,7 @@ function wetPaperInput(paper) {
2229
2243
  absorption: paper.absorption,
2230
2244
  permeability: paper.permeability,
2231
2245
  roughness: flat ? 0 : paper.roughness,
2232
- color: _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, paper.color),
2246
+ color: _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color),
2233
2247
  heightAt: flat ? () => 0.5 : (x, y) => grain.at(x, y)
2234
2248
  };
2235
2249
  }
@@ -2237,8 +2251,8 @@ var WetStrokeDriver = (_class6 = class {
2237
2251
  constructor(init) {;_class6.prototype.__init40.call(this);_class6.prototype.__init41.call(this);_class6.prototype.__init42.call(this);_class6.prototype.__init43.call(this);_class6.prototype.__init44.call(this);_class6.prototype.__init45.call(this);_class6.prototype.__init46.call(this);_class6.prototype.__init47.call(this);_class6.prototype.__init48.call(this);_class6.prototype.__init49.call(this);_class6.prototype.__init50.call(this);_class6.prototype.__init51.call(this);_class6.prototype.__init52.call(this);
2238
2252
  this.init = init;
2239
2253
  const brush = init.brush;
2240
- this.smoother = new (0, _chunkQ2UYUWAZcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
2241
- const copies = init.copies.length ? init.copies : [_chunkQ2UYUWAZcjs.IDENTITY_COPY];
2254
+ this.smoother = new (0, _chunk6G6ZDDDBcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
2255
+ const copies = init.copies.length ? init.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
2242
2256
  const wet = brush.wet;
2243
2257
  const spacing = Math.max(0.02, brush.tip.spacing);
2244
2258
  const perDab = Math.min(1, spacing * 1.2);
@@ -2252,7 +2266,7 @@ var WetStrokeDriver = (_class6 = class {
2252
2266
  this.lightBase = wet.tool === "paint" ? STROKE_LIGHT * brush.light.amount * (1 - 0.6 * thin) * perDab : 0;
2253
2267
  const rates = _chunkPQ3H2AANcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
2254
2268
  this.states = copies.map((c, i) => ({
2255
- walker: new (0, _chunkQ2UYUWAZcjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
2269
+ walker: new (0, _chunk6G6ZDDDBcjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
2256
2270
  exchange: wet.tool === "paint" ? new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, init.load) : null,
2257
2271
  last: null
2258
2272
  }));
@@ -2382,7 +2396,7 @@ var WetStrokeDriver = (_class6 = class {
2382
2396
  let flow = 1;
2383
2397
  const effect = this.init.effect;
2384
2398
  if (effect) {
2385
- _chunkQ2UYUWAZcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
2399
+ _chunk6G6ZDDDBcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
2386
2400
  ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
2387
2401
  } else if (this.sampler) {
2388
2402
  const g = this.sampler.dab(d, this.sample);
@@ -2394,7 +2408,7 @@ var WetStrokeDriver = (_class6 = class {
2394
2408
  if (total > 0 && flow > 0 && effect) {
2395
2409
  const ec = cov.slice();
2396
2410
  const field = new Float32Array(ec.length * 3);
2397
- _chunkQ2UYUWAZcjs.effectDabField.call(void 0, effect, rect, ec, this.centre, this.paint, field, COVERAGE_STEPS, d);
2411
+ _chunk6G6ZDDDBcjs.effectDabField.call(void 0, effect, rect, ec, this.centre, this.paint, field, COVERAGE_STEPS, d);
2398
2412
  this.medium.deposit(rect, ec, Math.min(1, total) * k, this.paint, null, field);
2399
2413
  } else if (total > 0 && flow > 0) this.medium.deposit(rect, cov, Math.min(1, total) * k * flow, this.paint, null);
2400
2414
  else world.paint(laneId, rect, cov, this.medium.options.water * k, null);
@@ -2897,7 +2911,7 @@ var PaintWetLayers = (_class7 = class {
2897
2911
  }
2898
2912
  }, _class7);
2899
2913
  function wetPigmentOf(hex, body) {
2900
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, hex);
2914
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, hex);
2901
2915
  return Array.from(_chunkVMROIWLLcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
2902
2916
  }
2903
2917
 
@@ -2911,7 +2925,7 @@ function paintWetTestStroke(brush, paper, color, width, height) {
2911
2925
  const w = thumbWorld;
2912
2926
  if (w.hasLane("thumb")) w.removeLane("thumb");
2913
2927
  w.ensureLane("thumb");
2914
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, color);
2928
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color);
2915
2929
  if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
2916
2930
  const half = Math.ceil(height / 2);
2917
2931
  w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkVMROIWLLcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
@@ -2925,9 +2939,9 @@ function paintWetTestStroke(brush, paper, color, width, height) {
2925
2939
  load: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2926
2940
  grain: paperGrain(paper),
2927
2941
  paperDepth: paper.depth,
2928
- paperColor: _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, paper.color),
2942
+ paperColor: _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color),
2929
2943
  seed: 7,
2930
- copies: [_chunkQ2UYUWAZcjs.IDENTITY_COPY]
2944
+ copies: [_chunk6G6ZDDDBcjs.IDENTITY_COPY]
2931
2945
  });
2932
2946
  driver.push(thumbnailStroke(width, height));
2933
2947
  driver.finish();
@@ -2947,7 +2961,7 @@ function thumbnailStroke(width, height) {
2947
2961
  return pts;
2948
2962
  }
2949
2963
  function paintTestStroke(surface, brush, paper, color, width, height) {
2950
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, color);
2964
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color);
2951
2965
  let result = surface;
2952
2966
  let thick = null;
2953
2967
  let light = null;
@@ -2968,13 +2982,13 @@ function paintTestStroke(surface, brush, paper, color, width, height) {
2968
2982
  lockTransparency: false,
2969
2983
  brush,
2970
2984
  color: [r, g, b, 255],
2971
- background: [..._chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, paper.color), 255],
2985
+ background: [..._chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color), 255],
2972
2986
  grain: paperGrain(paper),
2973
2987
  paperDepth: paper.depth,
2974
2988
  seed: 7,
2975
2989
  colorHex: color,
2976
2990
  affineCopies: [],
2977
- copies: [_chunkQ2UYUWAZcjs.IDENTITY_COPY],
2991
+ copies: [_chunk6G6ZDDDBcjs.IDENTITY_COPY],
2978
2992
  mixerLoad: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2979
2993
  thick: brush.engine === "impasto" ? { channels: emptyThickChannels() } : void 0,
2980
2994
  sticker: brush.engine === "sticker" ? { nextId: 1 } : void 0,
@@ -2990,8 +3004,8 @@ function renderBrushThumbnail(brush, options) {
2990
3004
  const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
2991
3005
  const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
2992
3006
  const maxSize = height * 0.42;
2993
- const b = brush.tip.size > maxSize ? _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
2994
- const rgba = [..._chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, options.color), 255];
3007
+ const b = brush.tip.size > maxSize ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
3008
+ const rgba = [..._chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, options.color), 255];
2995
3009
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
2996
3010
  if (b.engine === "eraser") {
2997
3011
  surface = _chunk474IQG74cjs.fillRect.call(void 0, surface, { x: 0, y: 0, width, height }, rgba);
@@ -3273,7 +3287,7 @@ var DEFAULT_SWATCHES = [
3273
3287
  // src/paint-editor/mixing-pad.ts
3274
3288
  var MIXING_PAD_WIDTH = 360;
3275
3289
  var MIXING_PAD_HEIGHT = 220;
3276
- var PAD_PAINT = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, {
3290
+ var PAD_PAINT = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3277
3291
  id: "pad-paint",
3278
3292
  name: "Pad paint",
3279
3293
  category: "mixer",
@@ -3281,7 +3295,7 @@ var PAD_PAINT = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, {
3281
3295
  tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
3282
3296
  mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
3283
3297
  });
3284
- var PAD_KNIFE = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, {
3298
+ var PAD_KNIFE = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3285
3299
  id: "pad-knife",
3286
3300
  name: "Palette knife",
3287
3301
  category: "smudge",
@@ -3291,7 +3305,7 @@ var PAD_KNIFE = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, {
3291
3305
  // A knife drags streaks of paint and folds them into each other, mixing them as pigment.
3292
3306
  smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
3293
3307
  });
3294
- var PAD_BLOB = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, {
3308
+ var PAD_BLOB = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3295
3309
  id: "pad-blob",
3296
3310
  name: "Pad blob",
3297
3311
  category: "custom",
@@ -3313,12 +3327,12 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3313
3327
  }
3314
3328
  }
3315
3329
  let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
3316
- if (options.size !== void 0) brush = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
3330
+ if (options.size !== void 0) brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
3317
3331
  return this.run(brush, points, options.color);
3318
3332
  }
3319
3333
  /** Paints `points` with `brush` in `color` on the pad. */
3320
3334
  run(brush, points, color) {
3321
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, color);
3335
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color);
3322
3336
  let result = null;
3323
3337
  const session = new PaintStrokeSession(
3324
3338
  { update: () => {
@@ -3336,7 +3350,7 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3336
3350
  seed: 1,
3337
3351
  colorHex: color,
3338
3352
  affineCopies: [],
3339
- copies: [_chunkQ2UYUWAZcjs.IDENTITY_COPY],
3353
+ copies: [_chunk6G6ZDDDBcjs.IDENTITY_COPY],
3340
3354
  mixerLoad: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
3341
3355
  }
3342
3356
  );
@@ -3412,10 +3426,10 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3412
3426
  const off = used.length === 1 ? 0 : 0.45 * R;
3413
3427
  const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
3414
3428
  const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
3415
- const blob = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
3429
+ const blob = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
3416
3430
  this.run(blob, [{ x, y }], p.color.toLowerCase());
3417
3431
  });
3418
- const knife = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
3432
+ const knife = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
3419
3433
  for (let k = 0; k < passes; k++) {
3420
3434
  const stir = [];
3421
3435
  const turns = 1.6;
@@ -3427,10 +3441,10 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3427
3441
  this.run(knife, stir, "#000000");
3428
3442
  }
3429
3443
  const mixed = _chunkOLNIPTB3cjs.mixPigments.call(void 0,
3430
- paints.map((p) => _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
3444
+ paints.map((p) => _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
3431
3445
  paints.map((p) => p.parts)
3432
3446
  );
3433
- const core = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
3447
+ const core = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
3434
3448
  const hex = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
3435
3449
  this.run(core, [{ x: cx, y: cy }], hex);
3436
3450
  return { color: this.pick(cx, cy, 2), bounds };
@@ -3500,7 +3514,9 @@ function liveStrokeBounds(stroke) {
3500
3514
  if (q.y > y1) y1 = q.y;
3501
3515
  }
3502
3516
  }
3503
- const pad = stroke.brush.tip.size * (stroke.brush.engine === "particle" ? 2 : 1) + 2;
3517
+ const particle = stroke.brush.engine === "particle" ? stroke.brush.particle : null;
3518
+ const wave = particle ? Math.max(_nullishCoalesce(particle.waveAmplitude, () => ( 0)), particle.kind === "fuzzy" ? 0.12 : 0) : 0;
3519
+ const pad = stroke.brush.tip.size * (particle ? 2 + wave : 1) + 2;
3504
3520
  return { x: Math.floor(x0 - pad), y: Math.floor(y0 - pad), width: Math.ceil(x1 - x0 + 2 * pad), height: Math.ceil(y1 - y0 + 2 * pad) };
3505
3521
  }
3506
3522
 
@@ -3634,10 +3650,10 @@ function addTiles(a, b) {
3634
3650
  }
3635
3651
  function computeTile(paper, grain, amount, rect, layers) {
3636
3652
  const n = rect.width * rect.height;
3637
- const [p0, p1, p2] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, paper.color);
3653
+ const [p0, p1, p2] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color);
3638
3654
  const pb = [p0, p1, p2];
3639
3655
  const pl = [Math.max(1e-4, LIN[p0]), Math.max(1e-4, LIN[p1]), Math.max(1e-4, LIN[p2])];
3640
- const [c0, c1, c2] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
3656
+ const [c0, c1, c2] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
3641
3657
  const t0 = new Float32Array(n).fill(amount * LIN[c0]);
3642
3658
  const t1 = new Float32Array(n).fill(amount * LIN[c1]);
3643
3659
  const t2 = new Float32Array(n).fill(amount * LIN[c2]);
@@ -4032,6 +4048,14 @@ function effectLayersToJSON(map, keep) {
4032
4048
  }
4033
4049
 
4034
4050
  // src/paint-editor/controller.ts
4051
+ function effectGuard(fn) {
4052
+ try {
4053
+ return fn();
4054
+ } catch (e) {
4055
+ if (e instanceof _chunkHB4ICNNAcjs.LayerEffectError) throw new PaintEditorError(e.message);
4056
+ throw e;
4057
+ }
4058
+ }
4035
4059
  var PaintEditorError = class extends Error {
4036
4060
  constructor(message) {
4037
4061
  super(message);
@@ -4045,7 +4069,7 @@ function parseColor(value, what = "color") {
4045
4069
  return value.trim().toLowerCase();
4046
4070
  }
4047
4071
  function rgbaOf(hex) {
4048
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, hex);
4072
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, hex);
4049
4073
  return [r, g, b, 255];
4050
4074
  }
4051
4075
  function rgbToHex(r, g, b) {
@@ -4142,9 +4166,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4142
4166
  constructor(options = {}) {;_class12.prototype.__init82.call(this);_class12.prototype.__init83.call(this);_class12.prototype.__init84.call(this);_class12.prototype.__init85.call(this);_class12.prototype.__init86.call(this);_class12.prototype.__init87.call(this);_class12.prototype.__init88.call(this);_class12.prototype.__init89.call(this);_class12.prototype.__init90.call(this);_class12.prototype.__init91.call(this);_class12.prototype.__init92.call(this);_class12.prototype.__init93.call(this);_class12.prototype.__init94.call(this);_class12.prototype.__init95.call(this);_class12.prototype.__init96.call(this);_class12.prototype.__init97.call(this);_class12.prototype.__init98.call(this);_class12.prototype.__init99.call(this);_class12.prototype.__init100.call(this);_class12.prototype.__init101.call(this);_class12.prototype.__init102.call(this);_class12.prototype.__init103.call(this);_class12.prototype.__init104.call(this);_class12.prototype.__init105.call(this);_class12.prototype.__init106.call(this);_class12.prototype.__init107.call(this);_class12.prototype.__init108.call(this);_class12.prototype.__init109.call(this);_class12.prototype.__init110.call(this);_class12.prototype.__init111.call(this);_class12.prototype.__init112.call(this);_class12.prototype.__init113.call(this);_class12.prototype.__init114.call(this);_class12.prototype.__init115.call(this);_class12.prototype.__init116.call(this);_class12.prototype.__init117.call(this);_class12.prototype.__init118.call(this);_class12.prototype.__init119.call(this);_class12.prototype.__init120.call(this);_class12.prototype.__init121.call(this);_class12.prototype.__init122.call(this);_class12.prototype.__init123.call(this);_class12.prototype.__init124.call(this);_class12.prototype.__init125.call(this);_class12.prototype.__init126.call(this);_class12.prototype.__init127.call(this);_class12.prototype.__init128.call(this);_class12.prototype.__init129.call(this);_class12.prototype.__init130.call(this);_class12.prototype.__init131.call(this);_class12.prototype.__init132.call(this);_class12.prototype.__init133.call(this);_class12.prototype.__init134.call(this);_class12.prototype.__init135.call(this);_class12.prototype.__init136.call(this);
4143
4167
  this.historyLimit = Math.max(1, _nullishCoalesce(options.historyLimit, () => ( 200)));
4144
4168
  this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
4145
- this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
4146
- const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunkQ2UYUWAZcjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunkQ2UYUWAZcjs.DEFAULT_BRUSH_ID)));
4147
- this.brush = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, start);
4169
+ this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
4170
+ const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunk6G6ZDDDBcjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunk6G6ZDDDBcjs.DEFAULT_BRUSH_ID)));
4171
+ this.brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, start);
4148
4172
  this.color = options.color ? parseColor(options.color) : "#1f2937";
4149
4173
  this.hand = options.hand === "left" ? "left" : "right";
4150
4174
  this.encodeImage = options.encodeImage;
@@ -4197,7 +4221,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4197
4221
  this.cached = {
4198
4222
  document: this.doc,
4199
4223
  brush: this.brush,
4200
- brushes: this.library ??= [..._chunkQ2UYUWAZcjs.BUILTIN_BRUSHES, ...this.userBrushes],
4224
+ brushes: this.library ??= [..._chunk6G6ZDDDBcjs.BUILTIN_BRUSHES, ...this.userBrushes],
4201
4225
  color: this.color,
4202
4226
  secondaryColor: this.secondaryColor,
4203
4227
  paint: _nullishCoalesce(this.gradient, () => ( { type: "color", color: this.color })),
@@ -4393,7 +4417,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4393
4417
  // --- Canvas and paper ----------------------------------------------------------
4394
4418
  resolvePaper(paper) {
4395
4419
  if (typeof paper === "string") {
4396
- const p = _chunkQ2UYUWAZcjs.paperPreset.call(void 0, paper);
4420
+ const p = _chunk6G6ZDDDBcjs.paperPreset.call(void 0, paper);
4397
4421
  if (!p) throw new PaintEditorError(`Unknown paper "${paper}". Call list_papers for the ids.`);
4398
4422
  return p;
4399
4423
  }
@@ -4504,19 +4528,19 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4504
4528
  this.requireIdle("changing the paper");
4505
4529
  let base = this.doc.paper;
4506
4530
  if (update.preset !== void 0 && update.preset !== this.doc.paper.preset) {
4507
- const p = _chunkQ2UYUWAZcjs.paperPreset.call(void 0, update.preset);
4531
+ const p = _chunk6G6ZDDDBcjs.paperPreset.call(void 0, update.preset);
4508
4532
  if (!p) throw new PaintEditorError(`Unknown paper "${update.preset}". Call list_papers for the ids.`);
4509
4533
  base = p;
4510
4534
  }
4511
4535
  const { preset: _p, ...rest } = update;
4512
4536
  if (rest.color !== void 0) parseColor(rest.color, "paper color");
4513
- const paper = _chunkQ2UYUWAZcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
4537
+ const paper = _chunk6G6ZDDDBcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
4514
4538
  const changedKeys = Object.keys(rest).filter((k) => k !== "name");
4515
4539
  if (changedKeys.length && update.preset === void 0) paper.preset = base.preset;
4516
4540
  if (this.wet.world) this.beginWetOp();
4517
4541
  this.commit("Paper", { ...this.doc, paper });
4518
4542
  this.wet.paperChanged();
4519
- return _chunkQ2UYUWAZcjs.clonePaper.call(void 0, paper);
4543
+ return _chunk6G6ZDDDBcjs.clonePaper.call(void 0, paper);
4520
4544
  }
4521
4545
  // --- Layers --------------------------------------------------------------------
4522
4546
  getLayer(id) {
@@ -4557,6 +4581,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4557
4581
  active: l.id === this.doc.activeLayerId,
4558
4582
  bounds,
4559
4583
  ..._optionalChain([this, 'access', _247 => _247.doc, 'access', _248 => _248.liveStrokes, 'optionalAccess', _249 => _249[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
4584
+ ..._optionalChain([l, 'access', _250 => _250.effects, 'optionalAccess', _251 => _251.items, 'access', _252 => _252.length]) ? { effects: l.effects.items.length } : {},
4560
4585
  parentId,
4561
4586
  depth
4562
4587
  };
@@ -4588,7 +4613,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4588
4613
  this.requireIdle("adding a layer");
4589
4614
  const count = _chunkHB4ICNNAcjs.flattenLayers.call(void 0, this.doc.layers).length;
4590
4615
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
4591
- const name = _optionalChain([options, 'access', _250 => _250.name, 'optionalAccess', _251 => _251.trim, 'call', _252 => _252()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
4616
+ const name = _optionalChain([options, 'access', _253 => _253.name, 'optionalAccess', _254 => _254.trim, 'call', _255 => _255()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
4592
4617
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
4593
4618
  let parentId = null;
4594
4619
  let index;
@@ -4600,7 +4625,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4600
4625
  } else if (above) {
4601
4626
  const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, above);
4602
4627
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
4603
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _253 => _253.parent, 'optionalAccess', _254 => _254.id]), () => ( null));
4628
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _256 => _256.parent, 'optionalAccess', _257 => _257.id]), () => ( null));
4604
4629
  index = loc.index + 1;
4605
4630
  }
4606
4631
  const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
@@ -4630,6 +4655,94 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4630
4655
  this.commit("Layer properties", { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
4631
4656
  return this.describeLayer(next);
4632
4657
  }
4658
+ // --- Layer effects (layer styles) ---------------------------------------------
4659
+ /** A layer's live effects (an empty, enabled list when it has none). */
4660
+ getLayerEffects(id) {
4661
+ return _nullishCoalesce(this.requireLayer(id).effects, () => ( { enabled: true, items: [] }));
4662
+ }
4663
+ /**
4664
+ * Adds a live effect of `kind` (outer and inner glow, drop and inner shadow, stroke, bevel &
4665
+ * emboss, satin, colour / gradient / pattern overlay) with Photoshop's defaults and `settings`
4666
+ * applied, at `index` in the layer's list (default the end). The effect is drawn from the
4667
+ * layer's pixels when it is composited, so it follows later painting. One undo step.
4668
+ */
4669
+ addLayerEffect(id, kind, settings = {}, index) {
4670
+ if (!_chunkHB4ICNNAcjs.isLayerEffectKind.call(void 0, kind)) throw new PaintEditorError(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkHB4ICNNAcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
4671
+ const current = _nullishCoalesce(this.effectsLayer(id, "add effects").effects, () => ( { enabled: true, items: [] }));
4672
+ const ids = new Set(current.items.map((e) => e.id));
4673
+ let effectId = _chunkHB4ICNNAcjs.newEffectId.call(void 0, );
4674
+ while (ids.has(effectId)) effectId = _chunkHB4ICNNAcjs.newEffectId.call(void 0, );
4675
+ const { id: _id, kind: _kind, ...rest } = settings;
4676
+ const effect = effectGuard(() => _chunkHB4ICNNAcjs.mergeLayerEffect.call(void 0, _chunkHB4ICNNAcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
4677
+ const items = [...current.items];
4678
+ const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
4679
+ items.splice(at, 0, effect);
4680
+ this.writeLayerEffects(id, { ...current, items }, `Add ${_chunkHB4ICNNAcjs.layerEffectLabel.call(void 0, kind)}`, true);
4681
+ return { effect, effects: this.getLayerEffects(id) };
4682
+ }
4683
+ /**
4684
+ * Changes one effect: only the given settings (nested objects replace whole; `null` removes an
4685
+ * optional contour or texture). One undo step, or with `commitToHistory` false folded into the
4686
+ * last change of this effect (a slider drag). Returns the layer's effects.
4687
+ */
4688
+ updateLayerEffect(id, effectId, changes, commitToHistory = true) {
4689
+ const current = this.effectsLayer(id, "change its effects").effects;
4690
+ const i = this.requireEffect(id, effectId);
4691
+ const items = [...current.items];
4692
+ items[i] = effectGuard(() => _chunkHB4ICNNAcjs.mergeLayerEffect.call(void 0, items[i], changes));
4693
+ this.writeLayerEffects(id, { ...current, items }, `Change ${_chunkHB4ICNNAcjs.layerEffectLabel.call(void 0, items[i].kind)}`, commitToHistory);
4694
+ return this.getLayerEffects(id);
4695
+ }
4696
+ /** Removes one effect (one undo step). Returns the layer's remaining effects. */
4697
+ removeLayerEffect(id, effectId) {
4698
+ const current = this.effectsLayer(id, "change its effects").effects;
4699
+ const i = this.requireEffect(id, effectId);
4700
+ this.writeLayerEffects(id, { ...current, items: current.items.filter((e) => e.id !== effectId) }, `Remove ${_chunkHB4ICNNAcjs.layerEffectLabel.call(void 0, current.items[i].kind)}`, true);
4701
+ return this.getLayerEffects(id);
4702
+ }
4703
+ /** Turns all of a layer's effects on or off and, when given, sets Scale Effects (0.01..10). One undo step. */
4704
+ setLayerEffectsEnabled(id, enabled, scale, commitToHistory = true) {
4705
+ const current = _nullishCoalesce(this.effectsLayer(id, "change its effects").effects, () => ( { enabled: true, items: [] }));
4706
+ if (scale !== void 0 && !(Number.isFinite(scale) && scale >= 0.01 && scale <= 10)) throw new PaintEditorError(`scale must be from 0.01 to 10 (1 = 100 %), got ${scale}.`);
4707
+ const next = { ...current, enabled };
4708
+ if (scale !== void 0) {
4709
+ if (scale === 1) delete next.scale;
4710
+ else next.scale = scale;
4711
+ }
4712
+ this.writeLayerEffects(id, next, "Layer effects", commitToHistory);
4713
+ return this.getLayerEffects(id);
4714
+ }
4715
+ /** Replaces a layer's effects, validated (`null` removes them). One undo step. Returns the effects. */
4716
+ setLayerEffects(id, effects, commitToHistory = true) {
4717
+ this.effectsLayer(id, "change its effects");
4718
+ if (effects) effectGuard(() => _chunkHB4ICNNAcjs.validateLayerEffects.call(void 0, effects));
4719
+ this.writeLayerEffects(id, effects, "Layer effects", commitToHistory);
4720
+ return this.getLayerEffects(id);
4721
+ }
4722
+ /** Document patterns for pattern effects besides the built-in ones: none (paint documents bring none). */
4723
+ getDocumentPatterns() {
4724
+ return [];
4725
+ }
4726
+ effectsLayer(id, action) {
4727
+ this.requireIdle("changing layer effects");
4728
+ const l = this.requireLayer(id);
4729
+ if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked, so it can't ${action}; unlock it first (locks {all: false}).`);
4730
+ return l;
4731
+ }
4732
+ requireEffect(id, effectId) {
4733
+ const l = this.requireLayer(id);
4734
+ const items = _nullishCoalesce(_optionalChain([l, 'access', _258 => _258.effects, 'optionalAccess', _259 => _259.items]), () => ( []));
4735
+ const i = items.findIndex((e) => e.id === effectId);
4736
+ 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.`);
4737
+ return i;
4738
+ }
4739
+ /** Writes a layer's effects (dropped when empty, enabled and unscaled), as an undo step or folded into the last one. */
4740
+ writeLayerEffects(id, effects, label, commitToHistory) {
4741
+ const next = { ...this.requireLayer(id) };
4742
+ if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) next.effects = effects;
4743
+ else delete next.effects;
4744
+ this.commitOrAmend(label, { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) }, commitToHistory);
4745
+ }
4633
4746
  removeLayer(id) {
4634
4747
  this.requireIdle("removing a layer");
4635
4748
  const l = this.requireLayer(id);
@@ -4641,7 +4754,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4641
4754
  }
4642
4755
  const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
4643
4756
  let active = this.doc.activeLayerId;
4644
- if (active && !_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _255 => _255.filter, 'call', _256 => _256((x) => x.type === "pixel"), 'access', _257 => _257.pop, 'call', _258 => _258(), 'optionalAccess', _259 => _259.id]), () => ( null));
4757
+ if (active && !_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _260 => _260.filter, 'call', _261 => _261((x) => x.type === "pixel"), 'access', _262 => _262.pop, 'call', _263 => _263(), 'optionalAccess', _264 => _264.id]), () => ( null));
4645
4758
  this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.lightWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
4646
4759
  return { removed: id, activeLayerId: active };
4647
4760
  }
@@ -4667,7 +4780,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4667
4780
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
4668
4781
  };
4669
4782
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
4670
- const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _260 => _260.parent, 'optionalAccess', _261 => _261.id]), () => ( null)), loc.index + 1);
4783
+ const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _265 => _265.parent, 'optionalAccess', _266 => _266.id]), () => ( null)), loc.index + 1);
4671
4784
  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 } : {} }));
4672
4785
  return this.describeLayer(dup);
4673
4786
  }
@@ -4676,7 +4789,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4676
4789
  this.requireIdle("moving a layer");
4677
4790
  const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4678
4791
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
4679
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _262 => _262.parent, 'optionalAccess', _263 => _263.id]), () => ( null)) : parentId;
4792
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _267 => _267.parent, 'optionalAccess', _268 => _268.id]), () => ( null)) : parentId;
4680
4793
  if (target) {
4681
4794
  const g = this.requireLayer(target);
4682
4795
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
@@ -4695,7 +4808,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4695
4808
  const pre = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4696
4809
  if (pre) {
4697
4810
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
4698
- this.dryLayersFirst([id, _optionalChain([sib, 'access', _264 => _264[pre.index - 1], 'optionalAccess', _265 => _265.id])].filter((x) => Boolean(x)));
4811
+ this.dryLayersFirst([id, _optionalChain([sib, 'access', _269 => _269[pre.index - 1], 'optionalAccess', _270 => _270.id])].filter((x) => Boolean(x)));
4699
4812
  }
4700
4813
  const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4701
4814
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
@@ -4715,7 +4828,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4715
4828
  const merged = { ...below, surface, offset: { x: 0, y: 0 } };
4716
4829
  const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
4717
4830
  const toDoc = (t, l) => t ? _chunk474IQG74cjs.translateSurface.call(void 0, t, l.offset.x, l.offset.y) : void 0;
4718
- const mergedLight = _optionalChain([this, 'access', _266 => _266.doc, 'access', _267 => _267.light, 'optionalAccess', _268 => _268[upper.id]]) || _optionalChain([this, 'access', _269 => _269.doc, 'access', _270 => _270.light, 'optionalAccess', _271 => _271[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _272 => _272.doc, 'access', _273 => _273.light, 'optionalAccess', _274 => _274[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _275 => _275.doc, 'access', _276 => _276.light, 'optionalAccess', _277 => _277[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
4831
+ const mergedLight = _optionalChain([this, 'access', _271 => _271.doc, 'access', _272 => _272.light, 'optionalAccess', _273 => _273[upper.id]]) || _optionalChain([this, 'access', _274 => _274.doc, 'access', _275 => _275.light, 'optionalAccess', _276 => _276[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _277 => _277.doc, 'access', _278 => _278.light, 'optionalAccess', _279 => _279[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _280 => _280.doc, 'access', _281 => _281.light, 'optionalAccess', _282 => _282[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
4719
4832
  const lightAfter = _nullishCoalesce(this.lightWithout([upper.id, below.id]).light, () => ( (this.doc.light ? { ...this.doc.light } : void 0)));
4720
4833
  const light = mergedLight ? { ..._nullishCoalesce(lightAfter, () => ( {})), [below.id]: mergedLight } : lightAfter;
4721
4834
  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 } : {} }));
@@ -4730,7 +4843,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4730
4843
  this.wet.world.removeLane(l.id);
4731
4844
  }
4732
4845
  const bounds = this.describeLayer(l).bounds;
4733
- this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkHB4ICNNAcjs.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', _278 => _278.doc, 'access', _279 => _279.liveStrokes, 'optionalAccess', _280 => _280[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
4846
+ this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkHB4ICNNAcjs.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', _283 => _283.doc, 'access', _284 => _284.liveStrokes, 'optionalAccess', _285 => _285[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
4734
4847
  return { layerId: l.id, bounds };
4735
4848
  }
4736
4849
  /**
@@ -4740,8 +4853,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4740
4853
  fillLayer(options = {}) {
4741
4854
  this.requireIdle("filling");
4742
4855
  const fillTarget = this.paintTarget(options.layerId, "fill");
4743
- if (_optionalChain([this, 'access', _281 => _281.doc, 'access', _282 => _282.stickers, 'optionalAccess', _283 => _283[fillTarget.id], 'optionalAccess', _284 => _284.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
4744
- if (_optionalChain([this, 'access', _285 => _285.doc, 'access', _286 => _286.liveStrokes, 'optionalAccess', _287 => _287[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).`);
4856
+ if (_optionalChain([this, 'access', _286 => _286.doc, 'access', _287 => _287.stickers, 'optionalAccess', _288 => _288[fillTarget.id], 'optionalAccess', _289 => _289.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
4857
+ if (_optionalChain([this, 'access', _290 => _290.doc, 'access', _291 => _291.liveStrokes, 'optionalAccess', _292 => _292[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).`);
4745
4858
  this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
4746
4859
  const l = this.paintTarget(options.layerId, "fill");
4747
4860
  const color = options.color === void 0 ? this.color : parseColor(options.color);
@@ -4774,7 +4887,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4774
4887
  offset: l.offset
4775
4888
  };
4776
4889
  const surface = this.applyCoverage(l, coverage, rect, apply);
4777
- const lit = _optionalChain([this, 'access', _288 => _288.doc, 'access', _289 => _289.light, 'optionalAccess', _290 => _290[l.id]]);
4890
+ const lit = _optionalChain([this, 'access', _293 => _293.doc, 'access', _294 => _294.light, 'optionalAccess', _295 => _295[l.id]]);
4778
4891
  const light = lit ? withLayerLight(this.doc.light, l.id, scaleLight(lit, 1 - opacity)) : void 0;
4779
4892
  this.commit("Fill layer", this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkHB4ICNNAcjs.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 } }));
4780
4893
  return { layerId: l.id, bounds: rect };
@@ -4784,7 +4897,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4784
4897
  const tiles = new Map(base.tiles);
4785
4898
  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 })) {
4786
4899
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
4787
- const src = _nullishCoalesce(_optionalChain([base, 'access', _291 => _291.tiles, 'access', _292 => _292.get, 'call', _293 => _293(key), 'optionalAccess', _294 => _294.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
4900
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _296 => _296.tiles, 'access', _297 => _297.get, 'call', _298 => _298(key), 'optionalAccess', _299 => _299.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
4788
4901
  const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkPQ3H2AANcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
4789
4902
  if (tile) tiles.set(key, tile);
4790
4903
  else tiles.delete(key);
@@ -4817,7 +4930,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4817
4930
  }
4818
4931
  /** The effect a layer is drawn from, or `undefined` for other layers. */
4819
4932
  getEffectLayer(layerId) {
4820
- return _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _295 => _295.doc, 'access', _296 => _296.effectLayers, 'optionalAccess', _297 => _297[layerId]]) : void 0;
4933
+ return _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _300 => _300.doc, 'access', _301 => _301.effectLayers, 'optionalAccess', _302 => _302[layerId]]) : void 0;
4821
4934
  }
4822
4935
  /** The effect paper (without its pixels), or `null`. */
4823
4936
  getPaperEffect() {
@@ -4854,8 +4967,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4854
4967
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
4855
4968
  effectTarget(layerId, what) {
4856
4969
  const l = this.paintTarget(layerId, what);
4857
- if (_optionalChain([this, 'access', _298 => _298.doc, 'access', _299 => _299.stickers, 'optionalAccess', _300 => _300[l.id], 'optionalAccess', _301 => _301.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
4858
- if (_optionalChain([this, 'access', _302 => _302.doc, 'access', _303 => _303.liveStrokes, 'optionalAccess', _304 => _304[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).`);
4970
+ if (_optionalChain([this, 'access', _303 => _303.doc, 'access', _304 => _304.stickers, 'optionalAccess', _305 => _305[l.id], 'optionalAccess', _306 => _306.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
4971
+ if (_optionalChain([this, 'access', _307 => _307.doc, 'access', _308 => _308.liveStrokes, 'optionalAccess', _309 => _309[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).`);
4859
4972
  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.`);
4860
4973
  return l;
4861
4974
  }
@@ -4894,8 +5007,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4894
5007
  const was = this.doc.paperEffect;
4895
5008
  const paperEffect = {
4896
5009
  ...this.sourceOf(d, values, options.time),
4897
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _305 => _305.opacity]))), () => ( 1)),
4898
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _306 => _306.blend]))), () => ( "multiply")),
5010
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _310 => _310.opacity]))), () => ( 1)),
5011
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _311 => _311.blend]))), () => ( "multiply")),
4899
5012
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
4900
5013
  version: nextPaperEffectVersion()
4901
5014
  };
@@ -4948,8 +5061,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4948
5061
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
4949
5062
  const loc = above ? _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, above) : null;
4950
5063
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
4951
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _307 => _307.name, 'optionalAccess', _308 => _308.trim, 'call', _309 => _309()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
4952
- const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _310 => _310.parent, 'optionalAccess', _311 => _311.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5064
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _312 => _312.name, 'optionalAccess', _313 => _313.trim, 'call', _314 => _314()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5065
+ const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _315 => _315.parent, 'optionalAccess', _316 => _316.id]), () => ( null)), loc ? loc.index + 1 : void 0);
4953
5066
  const source = this.sourceOf(d, values, options.time);
4954
5067
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
4955
5068
  return { layer: this.describeLayer(layer), source };
@@ -5027,7 +5140,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5027
5140
  this.checkTime(source.time);
5028
5141
  let map;
5029
5142
  try {
5030
- map = _chunkQ2UYUWAZcjs.readEffectStrokeMap.call(void 0, source.map);
5143
+ map = _chunk6G6ZDDDBcjs.readEffectStrokeMap.call(void 0, source.map);
5031
5144
  } catch (e) {
5032
5145
  throw new PaintEditorError(e.message);
5033
5146
  }
@@ -5058,9 +5171,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5058
5171
  }
5059
5172
  /** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
5060
5173
  effectPaintImage(p) {
5061
- const key = _chunkQ2UYUWAZcjs.effectPaintKey.call(void 0, p);
5174
+ const key = _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p);
5062
5175
  const img = this.effectPaintPixels.get(key);
5063
- const size = _chunkQ2UYUWAZcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5176
+ const size = _chunk6G6ZDDDBcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5064
5177
  if (!img || img.width !== size.width || img.height !== size.height) return null;
5065
5178
  this.effectPaintPixels.delete(key);
5066
5179
  this.effectPaintPixels.set(key, img);
@@ -5074,7 +5187,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5074
5187
  const what = `the effect "${p.effect}"${p.provider ? ` from provider "${p.provider}"` : ""}`;
5075
5188
  if (!provider) throw new PaintEditorError(`Effect paint needs ${what}, but no effects provider is registered; register it (setEffectsProvider) and try again.`);
5076
5189
  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.`);
5077
- const { width, height } = _chunkQ2UYUWAZcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5190
+ const { width, height } = _chunk6G6ZDDDBcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5078
5191
  let pixels;
5079
5192
  try {
5080
5193
  pixels = await this.effectsRenderer.render(provider, p.effect, { width, height }, { time: p.time, values: p.values });
@@ -5082,7 +5195,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5082
5195
  throw new PaintEditorError(`Effect paint could not render ${what}: ${e instanceof Error ? e.message : String(e)}`);
5083
5196
  }
5084
5197
  const img = { width, height, data: new Uint8ClampedArray(pixels.data), ...p.map ? { map: p.map } : {} };
5085
- this.effectPaintPixels.set(_chunkQ2UYUWAZcjs.effectPaintKey.call(void 0, p), img);
5198
+ this.effectPaintPixels.set(_chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p), img);
5086
5199
  while (this.effectPaintPixels.size > _PaintEditorController.EFFECT_PAINT_CACHE) this.effectPaintPixels.delete(this.effectPaintPixels.keys().next().value);
5087
5200
  return img;
5088
5201
  }
@@ -5093,7 +5206,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5093
5206
  async prepareEffectPaints(paints) {
5094
5207
  const seen = /* @__PURE__ */ new Set();
5095
5208
  for (const p of paints) {
5096
- const key = _chunkQ2UYUWAZcjs.effectPaintKey.call(void 0, p);
5209
+ const key = _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p);
5097
5210
  if (seen.has(key)) continue;
5098
5211
  seen.add(key);
5099
5212
  await this.renderEffectPaint(p);
@@ -5102,7 +5215,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5102
5215
  /** Renders the effect paints of recorded strokes (default all of them) before a replay. */
5103
5216
  async prepareStrokeEffects(strokeIds) {
5104
5217
  const ids = strokeIds ? new Set(strokeIds) : null;
5105
- const paints = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _312 => _312.paint, 'optionalAccess', _313 => _313.type]) === "effect").map((s) => s.paint);
5218
+ const paints = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _317 => _317.paint, 'optionalAccess', _318 => _318.type]) === "effect").map((s) => s.paint);
5106
5219
  await this.prepareEffectPaints(paints);
5107
5220
  }
5108
5221
  /** A small preview of the effect paint (a PNG data URL `size` px wide), or `null` without a rendered one. */
@@ -5131,11 +5244,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5131
5244
  * its pixels are not rendered.
5132
5245
  */
5133
5246
  strokeEffect(init, brush) {
5134
- if (!_chunkQ2UYUWAZcjs.brushTakesPaint.call(void 0, brush)) return null;
5247
+ if (!_chunk6G6ZDDDBcjs.brushTakesPaint.call(void 0, brush)) return null;
5135
5248
  let source = null;
5136
5249
  if (init.paint !== void 0) {
5137
- if (!_chunkQ2UYUWAZcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5138
- source = _chunkQ2UYUWAZcjs.readPaintEffectPaint.call(void 0, init.paint);
5250
+ if (!_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5251
+ source = _chunk6G6ZDDDBcjs.readPaintEffectPaint.call(void 0, init.paint);
5139
5252
  if (!source) throw new PaintEditorError("The stroke's effect paint needs an effect id and values (getEffectPaint returns one).");
5140
5253
  } else if (init.color === void 0 && !brush.paint) {
5141
5254
  if (this.effectPaintPending) throw new PaintEditorError(`The effect paint "${this.effectPaintPending.effect}" is still rendering; wait for set_effect_paint to finish, then paint.`);
@@ -5165,14 +5278,14 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5165
5278
  const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
5166
5279
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
5167
5280
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
5168
- const relief = _optionalChain([this, 'access', _314 => _314.doc, 'access', _315 => _315.thick, 'optionalAccess', _316 => _316[l.id]]);
5281
+ const relief = _optionalChain([this, 'access', _319 => _319.doc, 'access', _320 => _320.thick, 'optionalAccess', _321 => _321[l.id]]);
5169
5282
  if (heightInput && relief) {
5170
5283
  const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
5171
5284
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
5172
5285
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
5173
5286
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
5174
5287
  }
5175
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _317 => _317.inputs, 'access', _318 => _318.find, 'call', _319 => _319((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _320 => _320.name])), 'optionalAccess', _321 => _321.name]), () => ( "source"));
5288
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _322 => _322.inputs, 'access', _323 => _323.find, 'call', _324 => _324((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _325 => _325.name])), 'optionalAccess', _326 => _326.name]), () => ( "source"));
5176
5289
  if (sourceInput !== "source") {
5177
5290
  inputs[sourceInput] = inputs.source;
5178
5291
  delete inputs.source;
@@ -5185,12 +5298,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5185
5298
  }
5186
5299
  // --- Brushes -------------------------------------------------------------------
5187
5300
  findBrush(id) {
5188
- return _nullishCoalesce(_chunkQ2UYUWAZcjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
5301
+ return _nullishCoalesce(_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
5189
5302
  }
5190
5303
  /** A library brush by id (`undefined` when unknown). */
5191
5304
  getBrush(id) {
5192
5305
  const b = this.findBrush(id);
5193
- return b ? _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
5306
+ return b ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
5194
5307
  }
5195
5308
  requireBrush(id) {
5196
5309
  const b = this.findBrush(id);
@@ -5205,7 +5318,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5205
5318
  const { id, ...changes } = update;
5206
5319
  const base = id !== void 0 ? this.requireBrush(id) : this.brush;
5207
5320
  if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
5208
- const next = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
5321
+ const next = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
5209
5322
  if (base.builtin && !Object.keys(changes).length) next.builtin = true;
5210
5323
  else delete next.builtin;
5211
5324
  this.brush = next;
@@ -5214,10 +5327,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5214
5327
  }
5215
5328
  /** Saves the active brush (or `brush`) into the user library under `id` / `name`. */
5216
5329
  saveBrush(options) {
5217
- if (!_chunkQ2UYUWAZcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
5218
- if (_chunkQ2UYUWAZcjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
5219
- const source = options.brush ? _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
5220
- const saved = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
5330
+ if (!_chunk6G6ZDDDBcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
5331
+ if (_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
5332
+ const source = options.brush ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
5333
+ const saved = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
5221
5334
  delete saved.builtin;
5222
5335
  const i = this.userBrushes.findIndex((b) => b.id === options.id);
5223
5336
  if (i >= 0) this.userBrushes[i] = saved;
@@ -5227,7 +5340,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5227
5340
  return saved;
5228
5341
  }
5229
5342
  removeBrush(id) {
5230
- if (_chunkQ2UYUWAZcjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
5343
+ if (_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
5231
5344
  const i = this.userBrushes.findIndex((b) => b.id === id);
5232
5345
  if (i < 0) throw new PaintEditorError(`Unknown brush "${id}". Call list_brushes for the ids.`);
5233
5346
  this.userBrushes.splice(i, 1);
@@ -5236,12 +5349,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5236
5349
  }
5237
5350
  /** The user's saved brushes. */
5238
5351
  getUserBrushes() {
5239
- return this.userBrushes.map((b) => _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, b, b));
5352
+ return this.userBrushes.map((b) => _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, b, b));
5240
5353
  }
5241
5354
  /** A brush library file of the given brushes (default: the user's brushes). */
5242
5355
  exportBrushes(ids) {
5243
5356
  const list = ids ? ids.map((id) => this.requireBrush(id)) : this.userBrushes;
5244
- return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunkQ2UYUWAZcjs.brushToJSON) };
5357
+ return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunk6G6ZDDDBcjs.brushToJSON) };
5245
5358
  }
5246
5359
  /**
5247
5360
  * Adds the brushes of a library file to the user library. A brush whose id is taken is skipped
@@ -5251,14 +5364,14 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5251
5364
  const problems = [];
5252
5365
  let list;
5253
5366
  try {
5254
- list = _chunkQ2UYUWAZcjs.parseBrushLibrary.call(void 0, file, problems);
5367
+ list = _chunk6G6ZDDDBcjs.parseBrushLibrary.call(void 0, file, problems);
5255
5368
  } catch (e) {
5256
5369
  throw new PaintEditorError(e.message);
5257
5370
  }
5258
5371
  const added = [];
5259
5372
  const skipped = [];
5260
5373
  for (const b of list) {
5261
- if (_chunkQ2UYUWAZcjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
5374
+ if (_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
5262
5375
  skipped.push(b.id);
5263
5376
  problems.push(`"${b.id}" is a built-in brush id; rename it to import it.`);
5264
5377
  continue;
@@ -5323,10 +5436,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5323
5436
  * brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
5324
5437
  */
5325
5438
  strokeGradient(init, brush, color) {
5326
- if (!_chunkQ2UYUWAZcjs.brushTakesPaint.call(void 0, brush)) return null;
5439
+ if (!_chunk6G6ZDDDBcjs.brushTakesPaint.call(void 0, brush)) return null;
5327
5440
  let g = null;
5328
5441
  if (init.paint !== void 0) {
5329
- if (_chunkQ2UYUWAZcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5442
+ if (_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5330
5443
  const p = this.readStrokePaint(init.paint);
5331
5444
  g = p.type === "gradient" ? p : null;
5332
5445
  } else g = _nullishCoalesce(brush.paint, () => ( (init.color === void 0 ? this.gradient : null)));
@@ -5370,7 +5483,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5370
5483
  // --- Mixer Brush ---------------------------------------------------------------
5371
5484
  /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */
5372
5485
  loadMixerBrush(color) {
5373
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
5486
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
5374
5487
  this.mixerLoad = _chunkPQ3H2AANcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
5375
5488
  this.emit([]);
5376
5489
  return this.mixerLoad;
@@ -5400,7 +5513,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5400
5513
  // --- Strokes -------------------------------------------------------------------
5401
5514
  strokeBrush(init) {
5402
5515
  let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
5403
- if (init.brush) brush = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
5516
+ if (init.brush) brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
5404
5517
  return brush;
5405
5518
  }
5406
5519
  /**
@@ -5416,7 +5529,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5416
5529
  return symmetryCopies(this.guides.symmetry);
5417
5530
  }
5418
5531
  sessionFor(doc, init, host) {
5419
- if (init.paint !== void 0 && !_chunkQ2UYUWAZcjs.isPaintEffectPaint.call(void 0, init.paint)) {
5532
+ if (init.paint !== void 0 && !_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, init.paint)) {
5420
5533
  const p = this.readStrokePaint(init.paint);
5421
5534
  if (p.type === "color") init = { ...init, color: p.color, paint: void 0 };
5422
5535
  else init = { ...init, paint: p };
@@ -5437,25 +5550,25 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5437
5550
  if (brush.light.amount > 0) {
5438
5551
  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 (list_brushes category light), or set light.amount to 0 (set_brush).`);
5439
5552
  }
5440
- if (_optionalChain([doc, 'access', _322 => _322.liveStrokes, 'optionalAccess', _323 => _323[layer.id]])) {
5553
+ if (_optionalChain([doc, 'access', _327 => _327.liveStrokes, 'optionalAccess', _328 => _328[layer.id]])) {
5441
5554
  const why = liveStrokeRefusal(brush);
5442
5555
  if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
5443
5556
  }
5444
- if (_optionalChain([doc, 'access', _324 => _324.liveStrokes, 'optionalAccess', _325 => _325[layer.id]]) && _optionalChain([effect, 'optionalAccess', _326 => _326.source, 'access', _327 => _327.live])) {
5445
- const key = _chunkQ2UYUWAZcjs.effectPaintKey.call(void 0, effect.source);
5557
+ if (_optionalChain([doc, 'access', _329 => _329.liveStrokes, 'optionalAccess', _330 => _330[layer.id]]) && _optionalChain([effect, 'optionalAccess', _331 => _331.source, 'access', _332 => _332.live])) {
5558
+ const key = _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, effect.source);
5446
5559
  const { sources } = this.liveEffects(doc);
5447
- if (!sources.some((p) => _chunkQ2UYUWAZcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
5560
+ if (!sources.some((p) => _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
5448
5561
  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.`);
5449
5562
  }
5450
5563
  }
5451
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _328 => _328.stickers, 'optionalAccess', _329 => _329[layer.id], 'optionalAccess', _330 => _330.length]));
5564
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _333 => _333.stickers, 'optionalAccess', _334 => _334[layer.id], 'optionalAccess', _335 => _335.length]));
5452
5565
  if (brush.engine === "sticker") {
5453
5566
  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.`);
5454
5567
  } else if (stickerLayer) {
5455
5568
  throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
5456
5569
  }
5457
5570
  let wet;
5458
- if (_chunkQ2UYUWAZcjs.isWetBrush.call(void 0, brush)) {
5571
+ if (_chunk6G6ZDDDBcjs.isWetBrush.call(void 0, brush)) {
5459
5572
  this.requireWetIdle("painting");
5460
5573
  if (layer.offset.x || layer.offset.y) {
5461
5574
  const moved = { ...layer, surface: _chunk474IQG74cjs.translateSurface.call(void 0, layer.surface, layer.offset.x, layer.offset.y), offset: { x: 0, y: 0 } };
@@ -5470,7 +5583,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5470
5583
  const world = this.wet.ensureLane(layer.id, brush.wet.medium);
5471
5584
  const id = layer.id;
5472
5585
  const wetColor = init.color === void 0 ? this.color : parseColor(init.color);
5473
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, wetColor);
5586
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, wetColor);
5474
5587
  const wetGradient = this.strokeGradient(init, brush, wetColor);
5475
5588
  const load = _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [r / 255, g / 255, b / 255])));
5476
5589
  const seedW = _nullishCoalesce(init.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
@@ -5483,12 +5596,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5483
5596
  load,
5484
5597
  grain: paperGrain(doc.paper),
5485
5598
  paperDepth: doc.paper.depth,
5486
- paperColor: _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, doc.paper.color),
5599
+ paperColor: _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, doc.paper.color),
5487
5600
  seed: seedW,
5488
5601
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
5489
5602
  mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
5490
5603
  paint: effect ? null : wetGradient,
5491
- effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _331 => _331.pixels]), () => ( null))
5604
+ effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _336 => _336.pixels]), () => ( null))
5492
5605
  });
5493
5606
  init = { ...init, seed: seedW, load };
5494
5607
  wet = { driver, surface: () => world.display(id).surface };
@@ -5499,7 +5612,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5499
5612
  }
5500
5613
  let color = init.color === void 0 ? this.color : parseColor(init.color);
5501
5614
  const tracing = this.guides.tracing;
5502
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _332 => _332.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
5615
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _337 => _337.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
5503
5616
  const perspective = this.guides.perspective;
5504
5617
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
5505
5618
  const useStencils = init.stencils !== false;
@@ -5532,9 +5645,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5532
5645
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
5533
5646
  secondary: rgbaOf(this.secondaryColor),
5534
5647
  wet,
5535
- thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _333 => _333.thick, 'optionalAccess', _334 => _334[layer.id]]), () => ( emptyThickChannels())) } : void 0,
5648
+ thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _338 => _338.thick, 'optionalAccess', _339 => _339[layer.id]]), () => ( emptyThickChannels())) } : void 0,
5536
5649
  // Light paint: a twin of the stroke paints the light channel (laying, dimming, moving light).
5537
- light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _335 => _335.light, 'optionalAccess', _336 => _336[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _337 => _337.light, 'optionalAccess', _338 => _338[layer.id]]), () => ( emptyLight())) } : null,
5650
+ light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _340 => _340.light, 'optionalAccess', _341 => _341[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _342 => _342.light, 'optionalAccess', _343 => _343[layer.id]]), () => ( emptyLight())) } : null,
5538
5651
  sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc) } : void 0,
5539
5652
  paint: effect ? null : this.strokeGradient(init, brush, color),
5540
5653
  effect
@@ -5548,7 +5661,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5548
5661
  const stroke = {
5549
5662
  id: `s${this.strokeCounter++}`,
5550
5663
  layerId: session.layerId,
5551
- brush: _chunkQ2UYUWAZcjs.brushToJSON.call(void 0, init.brush),
5664
+ brush: _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, init.brush),
5552
5665
  color: init.colorHex,
5553
5666
  points: session.points.map((p) => ({ ...p })),
5554
5667
  seed: init.seed
@@ -5573,12 +5686,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5573
5686
  const before = this.doc;
5574
5687
  const host = {
5575
5688
  update: (layerId, surface, rects) => {
5576
- if (_optionalChain([this, 'access', _339 => _339.session, 'optionalAccess', _340 => _340.init, 'access', _341 => _341.wet])) {
5689
+ if (_optionalChain([this, 'access', _344 => _344.session, 'optionalAccess', _345 => _345.init, 'access', _346 => _346.wet])) {
5577
5690
  this.wet.syncDisplays();
5578
5691
  return;
5579
5692
  }
5580
5693
  this.live = { layerId, surface };
5581
- const ch = _optionalChain([this, 'access', _342 => _342.session, 'optionalAccess', _343 => _343.thickChannels, 'call', _344 => _344()]);
5694
+ const ch = _optionalChain([this, 'access', _347 => _347.session, 'optionalAccess', _348 => _348.thickChannels, 'call', _349 => _349()]);
5582
5695
  this.liveThick = ch ? { layerId, channels: ch } : null;
5583
5696
  this.emit(rects);
5584
5697
  },
@@ -5590,7 +5703,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5590
5703
  const wetStroke = Boolean(s.init.wet);
5591
5704
  if (wetStroke) this.wet.driver = null;
5592
5705
  const brush = s.init.brush;
5593
- if (!cancelled && _optionalChain([s, 'access', _345 => _345.result, 'optionalAccess', _346 => _346.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
5706
+ if (!cancelled && _optionalChain([s, 'access', _350 => _350.result, 'optionalAccess', _351 => _351.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
5594
5707
  if (cancelled || !surface) {
5595
5708
  if (this.wetOp) {
5596
5709
  const snap = this.wetOp.before;
@@ -5605,7 +5718,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5605
5718
  }
5606
5719
  const stroke = this.record(s);
5607
5720
  s.result.strokeId = stroke.id;
5608
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _347 => _347.result, 'optionalAccess', _348 => _348.bounds]), () => ( null)));
5721
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _352 => _352.result, 'optionalAccess', _353 => _353.bounds]), () => ( null)));
5609
5722
  if (wetStroke && this.wet.instantDry) {
5610
5723
  this.wet.dry(s.layerId);
5611
5724
  this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
@@ -5616,8 +5729,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5616
5729
  const ch = s.thickChannels();
5617
5730
  const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
5618
5731
  const sprayed = s.stickers();
5619
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _349 => _349.doc, 'access', _350 => _350.stickers, 'optionalAccess', _351 => _351[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
5620
- const wetLight = wetStroke && _optionalChain([this, 'access', _352 => _352.wet, 'access', _353 => _353.world, 'optionalAccess', _354 => _354.hasLane, 'call', _355 => _355(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
5732
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _354 => _354.doc, 'access', _355 => _355.stickers, 'optionalAccess', _356 => _356[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
5733
+ const wetLight = wetStroke && _optionalChain([this, 'access', _357 => _357.wet, 'access', _358 => _358.world, 'optionalAccess', _359 => _359.hasLane, 'call', _360 => _360(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
5621
5734
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
5622
5735
  this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkHB4ICNNAcjs.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);
5623
5736
  }
@@ -5647,18 +5760,18 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5647
5760
  if (cancelled || !surface) return;
5648
5761
  const stroke = this.record(s);
5649
5762
  s.result.strokeId = stroke.id;
5650
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _356 => _356.result, 'optionalAccess', _357 => _357.bounds]), () => ( null)));
5763
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _361 => _361.result, 'optionalAccess', _362 => _362.bounds]), () => ( null)));
5651
5764
  const l = _chunkHB4ICNNAcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
5652
5765
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
5653
5766
  const ch = s.thickChannels();
5654
5767
  const sprayed = s.stickers();
5655
- const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _358 => _358.wet, 'access', _359 => _359.world, 'optionalAccess', _360 => _360.hasLane, 'call', _361 => _361(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
5768
+ const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _363 => _363.wet, 'access', _364 => _364.world, 'optionalAccess', _365 => _365.hasLane, 'call', _366 => _366(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
5656
5769
  out = withLiveStroke({
5657
5770
  ...out,
5658
5771
  layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
5659
5772
  strokes: [...out.strokes, stroke],
5660
5773
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
5661
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _362 => _362.stickers, 'optionalAccess', _363 => _363[l.id]]), () => ( [])), ...sprayed] } } : {},
5774
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _367 => _367.stickers, 'optionalAccess', _368 => _368[l.id]]), () => ( [])), ...sprayed] } } : {},
5662
5775
  ...lit ? { light: withLayerLight(out.light, l.id, lit) } : {}
5663
5776
  }, stroke);
5664
5777
  }
@@ -5717,7 +5830,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5717
5830
  */
5718
5831
  replayStrokes(options) {
5719
5832
  this.requireIdle("replaying");
5720
- if (!_optionalChain([options, 'access', _364 => _364.strokeIds, 'optionalAccess', _365 => _365.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
5833
+ if (!_optionalChain([options, 'access', _369 => _369.strokeIds, 'optionalAccess', _370 => _370.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
5721
5834
  const strokes = options.strokeIds.map((id) => {
5722
5835
  const s = this.doc.strokes.find((x) => x.id === id);
5723
5836
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -5731,7 +5844,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5731
5844
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
5732
5845
  if (options.color === void 0) {
5733
5846
  for (const s of strokes) {
5734
- if (_optionalChain([s, 'access', _366 => _366.paint, 'optionalAccess', _367 => _367.type]) === "effect" && !this.effectPaintImage(s.paint)) {
5847
+ if (_optionalChain([s, 'access', _371 => _371.paint, 'optionalAccess', _372 => _372.type]) === "effect" && !this.effectPaintImage(s.paint)) {
5735
5848
  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.`);
5736
5849
  }
5737
5850
  }
@@ -5754,13 +5867,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5754
5867
  let brush = v.brush;
5755
5868
  if (options.brushId !== void 0) {
5756
5869
  const b = this.requireBrush(options.brushId);
5757
- brush = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
5870
+ brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
5758
5871
  }
5759
5872
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
5760
5873
  if (!_chunkHB4ICNNAcjs.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.`);
5761
5874
  let load = s.load;
5762
5875
  if (load && options.color !== void 0 && load.reservoir) {
5763
- const [r, g, b] = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, options.color);
5876
+ const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, options.color);
5764
5877
  load = { ...load, reservoir: [r / 255, g / 255, b / 255] };
5765
5878
  }
5766
5879
  const paint = v.paint && options.color === void 0 ? { paint: v.paint } : {};
@@ -5789,7 +5902,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5789
5902
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
5790
5903
  lightOf(layerId) {
5791
5904
  const l = this.wetLayer(layerId, "read the light of");
5792
- const info = lightInfo(_optionalChain([this, 'access', _368 => _368.doc, 'access', _369 => _369.light, 'optionalAccess', _370 => _370[l.id]]));
5905
+ const info = lightInfo(_optionalChain([this, 'access', _373 => _373.doc, 'access', _374 => _374.light, 'optionalAccess', _375 => _375[l.id]]));
5793
5906
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
5794
5907
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
5795
5908
  }
@@ -5840,7 +5953,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5840
5953
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
5841
5954
  if (!id) return null;
5842
5955
  this.requireLayer(id);
5843
- const ch = _optionalChain([this, 'access', _371 => _371.doc, 'access', _372 => _372.thick, 'optionalAccess', _373 => _373[id]]);
5956
+ const ch = _optionalChain([this, 'access', _376 => _376.doc, 'access', _377 => _377.thick, 'optionalAccess', _378 => _378[id]]);
5844
5957
  if (!ch) return null;
5845
5958
  const r = reliefInfo(ch);
5846
5959
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -5948,7 +6061,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5948
6061
  wetState() {
5949
6062
  const st = this.getState().wet;
5950
6063
  const backend = this.wet.backend();
5951
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _374 => _374.message]), () => ( _chunkVMROIWLLcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
6064
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _379 => _379.message]), () => ( _chunkVMROIWLLcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
5952
6065
  }
5953
6066
  /**
5954
6067
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -6033,7 +6146,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6033
6146
  }
6034
6147
  /** Records a settings change as a wet event (not an undo step). */
6035
6148
  recordWetSetting(e) {
6036
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _375 => _375.wet, 'access', _376 => _376.world, 'optionalAccess', _377 => _377.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
6149
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _380 => _380.wet, 'access', _381 => _381.world, 'optionalAccess', _382 => _382.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
6037
6150
  }
6038
6151
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
6039
6152
  setWetParams(layerId, update) {
@@ -6102,7 +6215,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6102
6215
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkHB4ICNNAcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
6103
6216
  const live = this.live;
6104
6217
  if (!live) return this.animatedView();
6105
- if (_optionalChain([this, 'access', _378 => _378.liveLayers, 'optionalAccess', _379 => _379.key]) === live.surface) return this.liveLayers.layers;
6218
+ if (_optionalChain([this, 'access', _383 => _383.liveLayers, 'optionalAccess', _384 => _384.key]) === live.surface) return this.liveLayers.layers;
6106
6219
  const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
6107
6220
  this.liveLayers = { key: live.surface, layers };
6108
6221
  return layers;
@@ -6125,7 +6238,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6125
6238
  tracingNode(t) {
6126
6239
  const { width, height } = this.doc.canvas;
6127
6240
  const key = this.tracingVersion * 100003 + width * 7 + height;
6128
- if (_optionalChain([this, 'access', _380 => _380.tracingCache, 'optionalAccess', _381 => _381.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
6241
+ if (_optionalChain([this, 'access', _385 => _385.tracingCache, 'optionalAccess', _386 => _386.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
6129
6242
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
6130
6243
  const image = resampleInto(src, t.rect, width, height);
6131
6244
  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 };
@@ -6152,8 +6265,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6152
6265
  let out = layers;
6153
6266
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
6154
6267
  for (const id of ids) {
6155
- const ch = _optionalChain([live, 'optionalAccess', _382 => _382.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _383 => _383[id]]);
6156
- const l = ch && _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _384 => _384.layer]);
6268
+ const ch = _optionalChain([live, 'optionalAccess', _387 => _387.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _388 => _388[id]]);
6269
+ const l = ch && _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _389 => _389.layer]);
6157
6270
  if (!ch || !isPixelLayer(l)) continue;
6158
6271
  let cache = this.litCaches.get(id);
6159
6272
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -6173,13 +6286,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6173
6286
  if (!ids.size) return layers;
6174
6287
  let out = layers;
6175
6288
  for (const id of ids) {
6176
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _385 => _385.layer]);
6289
+ const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _390 => _390.layer]);
6177
6290
  if (!isPixelLayer(l)) continue;
6178
6291
  let cache = this.lightCaches.get(id);
6179
6292
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
6180
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _386 => _386.liveThick, 'optionalAccess', _387 => _387.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _388 => _388.doc, 'access', _389 => _389.thick, 'optionalAccess', _390 => _390[id]]));
6293
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _391 => _391.liveThick, 'optionalAccess', _392 => _392.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _393 => _393.doc, 'access', _394 => _394.thick, 'optionalAccess', _395 => _395[id]]));
6181
6294
  if (glowed !== l.surface) out = _chunkHB4ICNNAcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
6182
- const committed = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _391 => _391.layer]);
6295
+ const committed = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _396 => _396.layer]);
6183
6296
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
6184
6297
  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 } });
6185
6298
  }
@@ -6191,7 +6304,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6191
6304
  if (!l.visible) continue;
6192
6305
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
6193
6306
  else if (isPixelLayer(l)) {
6194
- const thick = !committed && _optionalChain([this, 'access', _392 => _392.liveThick, 'optionalAccess', _393 => _393.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _394 => _394.doc, 'access', _395 => _395.thick, 'optionalAccess', _396 => _396[l.id]]);
6307
+ const thick = !committed && _optionalChain([this, 'access', _397 => _397.liveThick, 'optionalAccess', _398 => _398.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _399 => _399.doc, 'access', _400 => _400.thick, 'optionalAccess', _401 => _401[l.id]]);
6195
6308
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
6196
6309
  }
6197
6310
  }
@@ -6220,7 +6333,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6220
6333
  if (backlight) layers = [...layers, backlight];
6221
6334
  if (options.layerIds) {
6222
6335
  const picked = [];
6223
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _397 => _397.layer]), () => ( this.requireLayer(id))));
6336
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _402 => _402.layer]), () => ( this.requireLayer(id))));
6224
6337
  layers = picked.map((l) => ({ ...l, visible: true }));
6225
6338
  }
6226
6339
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -6236,7 +6349,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6236
6349
  */
6237
6350
  compositeTiles(rect, onTile, options = {}) {
6238
6351
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
6239
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _398 => _398.live, 'optionalAccess', _399 => _399.layerId]), () => ( this.doc.activeLayerId)) });
6352
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _403 => _403.live, 'optionalAccess', _404 => _404.layerId]), () => ( this.doc.activeLayerId)) });
6240
6353
  }
6241
6354
  /** The canvas as canvas-sized RGBA (paper included by default). */
6242
6355
  compositePixels(options = {}) {
@@ -6315,7 +6428,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6315
6428
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)));
6316
6429
  if (Object.keys(spills).length) ext.lightSpill = spills;
6317
6430
  else delete ext.lightSpill;
6318
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _400 => _400.layer])));
6431
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _405 => _405.layer])));
6319
6432
  if (effectLayers) ext.effectLayers = effectLayers;
6320
6433
  else delete ext.effectLayers;
6321
6434
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -6332,7 +6445,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6332
6445
  const stickers = {};
6333
6446
  for (const [id, list] of Object.entries(ext.stickers)) {
6334
6447
  if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
6335
- const ok = list.filter((x) => x && typeof x.id === "string" && _chunkQ2UYUWAZcjs.STAMP_KINDS.includes(x.stamp) && Number.isFinite(x.x) && Number.isFinite(x.y) && x.size > 0);
6448
+ const ok = list.filter((x) => x && typeof x.id === "string" && _chunk6G6ZDDDBcjs.STAMP_KINDS.includes(x.stamp) && Number.isFinite(x.x) && Number.isFinite(x.y) && x.size > 0);
6336
6449
  if (ok.length !== list.length) problems.push(`Some stickers of layer "${id}" could not be read; they were dropped.`);
6337
6450
  stickers[id] = ok.map((x) => ({ ...x }));
6338
6451
  }
@@ -6341,7 +6454,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6341
6454
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
6342
6455
  const liveStrokes = {};
6343
6456
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
6344
- if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _401 => _401.layer])) || !Array.isArray(list)) continue;
6457
+ if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _406 => _406.layer])) || !Array.isArray(list)) continue;
6345
6458
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
6346
6459
  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).`);
6347
6460
  liveStrokes[id] = ok;
@@ -6351,7 +6464,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6351
6464
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
6352
6465
  const effectLayers = {};
6353
6466
  for (const [id, v] of Object.entries(ext.effectLayers)) {
6354
- if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _402 => _402.layer]))) continue;
6467
+ if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _407 => _407.layer]))) continue;
6355
6468
  const source = readPaintEffectSource(v);
6356
6469
  if (source) effectLayers[id] = source;
6357
6470
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -6379,7 +6492,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6379
6492
  if (ext.light && typeof ext.light === "object") {
6380
6493
  const light = {};
6381
6494
  for (const [id, v] of Object.entries(ext.light)) {
6382
- if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _403 => _403.layer]))) continue;
6495
+ if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _408 => _408.layer]))) continue;
6383
6496
  try {
6384
6497
  light[id] = lightFromJSON(v);
6385
6498
  } catch (e) {
@@ -6415,7 +6528,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6415
6528
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
6416
6529
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
6417
6530
  for (const s of loaded.state.strokes) {
6418
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _404 => _404.exec, 'call', _405 => _405(s.id), 'optionalAccess', _406 => _406[1]]), () => ( 0)));
6531
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _409 => _409.exec, 'call', _410 => _410(s.id), 'optionalAccess', _411 => _411[1]]), () => ( 0)));
6419
6532
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
6420
6533
  }
6421
6534
  this.undoStack = [];
@@ -6423,7 +6536,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6423
6536
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
6424
6537
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
6425
6538
  for (const s of list) {
6426
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _407 => _407.exec, 'call', _408 => _408(s.id), 'optionalAccess', _409 => _409[1]]), () => ( 0)));
6539
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _412 => _412.exec, 'call', _413 => _413(s.id), 'optionalAccess', _414 => _414[1]]), () => ( 0)));
6427
6540
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
6428
6541
  }
6429
6542
  }
@@ -6518,10 +6631,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6518
6631
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
6519
6632
  });
6520
6633
  const layers = toStandard(dried);
6521
- const result = _chunkXTWXBQD4cjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
6634
+ const result = _chunkWVS5KQDHcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
6522
6635
  for (const [mode, names] of changed) {
6523
- const label = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _410 => _410.find, 'call', _411 => _411((m) => m.id === mode), 'optionalAccess', _412 => _412.label]), () => ( mode));
6524
- const std = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _413 => _413.find, 'call', _414 => _414((m) => m.id === _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _415 => _415.label]), () => ( _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)));
6636
+ const label = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _415 => _415.find, 'call', _416 => _416((m) => m.id === mode), 'optionalAccess', _417 => _417.label]), () => ( mode));
6637
+ const std = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _418 => _418.find, 'call', _419 => _419((m) => m.id === _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _420 => _420.label]), () => ( _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)));
6525
6638
  const list = names.map((n) => `"${n}"`).join(", ");
6526
6639
  const one = names.length === 1;
6527
6640
  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).`);
@@ -6643,7 +6756,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6643
6756
  const { src, pixels } = this.importImage(options, "The reference image");
6644
6757
  const ref2 = {
6645
6758
  id: `ref${this.nextReferenceId++}`,
6646
- name: _optionalChain([options, 'access', _416 => _416.name, 'optionalAccess', _417 => _417.trim, 'call', _418 => _418()]) || `Reference ${this.guides.references.length + 1}`,
6759
+ name: _optionalChain([options, 'access', _421 => _421.name, 'optionalAccess', _422 => _422.trim, 'call', _423 => _423()]) || `Reference ${this.guides.references.length + 1}`,
6647
6760
  src,
6648
6761
  width: pixels.width,
6649
6762
  height: pixels.height,
@@ -6722,7 +6835,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6722
6835
  try {
6723
6836
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
6724
6837
  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 });
6725
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _419 => _419.exec, 'call', _420 => _420(ref2.id), 'optionalAccess', _421 => _421[1]]), () => ( 0)));
6838
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _424 => _424.exec, 'call', _425 => _425(ref2.id), 'optionalAccess', _426 => _426[1]]), () => ( 0)));
6726
6839
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
6727
6840
  } catch (e) {
6728
6841
  problems.push(e.message);
@@ -6733,7 +6846,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6733
6846
  guides.stencils = [];
6734
6847
  r.stencils.forEach((raw2, i) => {
6735
6848
  try {
6736
- const id = typeof _optionalChain([raw2, 'optionalAccess', _422 => _422.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
6849
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _427 => _427.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
6737
6850
  guides.stencils.push(normalizeStencil(raw2, id));
6738
6851
  const n = Number(id.slice(7));
6739
6852
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -6756,12 +6869,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6756
6869
  /** The next free sticker number (ids `st<n>` are unique across the document). */
6757
6870
  nextStickerNumber(doc = this.doc) {
6758
6871
  let n = 0;
6759
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _423 => _423.exec, 'call', _424 => _424(st.id), 'optionalAccess', _425 => _425[1]]), () => ( 0))));
6872
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _428 => _428.exec, 'call', _429 => _429(st.id), 'optionalAccess', _430 => _430[1]]), () => ( 0))));
6760
6873
  return n + 1;
6761
6874
  }
6762
6875
  stickerLayer(layerId) {
6763
6876
  const l = this.wetLayer(layerId, "edit the stickers of");
6764
- const stickers = _optionalChain([this, 'access', _426 => _426.doc, 'access', _427 => _427.stickers, 'optionalAccess', _428 => _428[l.id]]);
6877
+ const stickers = _optionalChain([this, 'access', _431 => _431.doc, 'access', _432 => _432.stickers, 'optionalAccess', _433 => _433[l.id]]);
6765
6878
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (list_brushes category sticker).`);
6766
6879
  return { layer: l, stickers };
6767
6880
  }
@@ -6770,7 +6883,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6770
6883
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
6771
6884
  if (!id) return [];
6772
6885
  this.requireLayer(id);
6773
- return (_nullishCoalesce(_optionalChain([this, 'access', _429 => _429.doc, 'access', _430 => _430.stickers, 'optionalAccess', _431 => _431[id]]), () => ( []))).map((s) => ({ ...s }));
6886
+ return (_nullishCoalesce(_optionalChain([this, 'access', _434 => _434.doc, 'access', _435 => _435.stickers, 'optionalAccess', _436 => _436[id]]), () => ( []))).map((s) => ({ ...s }));
6774
6887
  }
6775
6888
  /**
6776
6889
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -6786,15 +6899,15 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6786
6899
  }
6787
6900
  redrawStickers(layer, stickers, dirty) {
6788
6901
  const partial = dirty && !layer.offset.x && !layer.offset.y;
6789
- return partial ? _chunkQ2UYUWAZcjs.stickerSurface.call(void 0, stickers, layer.surface, dirty) : _chunkQ2UYUWAZcjs.stickerSurface.call(void 0, stickers);
6902
+ return partial ? _chunk6G6ZDDDBcjs.stickerSurface.call(void 0, stickers, layer.surface, dirty) : _chunk6G6ZDDDBcjs.stickerSurface.call(void 0, stickers);
6790
6903
  }
6791
6904
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
6792
6905
  previewBase() {
6793
- return _optionalChain([this, 'access', _432 => _432.stickerPreview, 'optionalAccess', _433 => _433.shown]) === this.doc ? this.stickerPreview.base : null;
6906
+ return _optionalChain([this, 'access', _437 => _437.stickerPreview, 'optionalAccess', _438 => _438.shown]) === this.doc ? this.stickerPreview.base : null;
6794
6907
  }
6795
6908
  readStickerUpdate(update) {
6796
6909
  try {
6797
- return _chunkQ2UYUWAZcjs.normalizeStickerUpdate.call(void 0, update);
6910
+ return _chunk6G6ZDDDBcjs.normalizeStickerUpdate.call(void 0, update);
6798
6911
  } catch (e) {
6799
6912
  throw new PaintEditorError(e.message);
6800
6913
  }
@@ -6805,7 +6918,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6805
6918
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
6806
6919
  if (!id) return null;
6807
6920
  this.requireLayer(id);
6808
- const hit = _chunkQ2UYUWAZcjs.stickerAt.call(void 0, _nullishCoalesce(_optionalChain([this, 'access', _434 => _434.doc, 'access', _435 => _435.stickers, 'optionalAccess', _436 => _436[id]]), () => ( [])), x, y);
6921
+ const hit = _chunk6G6ZDDDBcjs.stickerAt.call(void 0, _nullishCoalesce(_optionalChain([this, 'access', _439 => _439.doc, 'access', _440 => _440.stickers, 'optionalAccess', _441 => _441[id]]), () => ( [])), x, y);
6809
6922
  return hit ? { ...hit } : null;
6810
6923
  }
6811
6924
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -6826,7 +6939,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6826
6939
  if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
6827
6940
  const next = { ...stickers[i], ...this.readStickerUpdate(update) };
6828
6941
  const list = stickers.map((s, j) => j === i ? next : s);
6829
- const dirty = [_chunkQ2UYUWAZcjs.stickerRect.call(void 0, stickers[i]), _chunkQ2UYUWAZcjs.stickerRect.call(void 0, next)];
6942
+ const dirty = [_chunk6G6ZDDDBcjs.stickerRect.call(void 0, stickers[i]), _chunk6G6ZDDDBcjs.stickerRect.call(void 0, next)];
6830
6943
  const base = _nullishCoalesce(this.previewBase(), () => ( this.doc));
6831
6944
  const surface = this.redrawStickers(layer, list, dirty);
6832
6945
  this.doc = { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: list } };
@@ -6849,7 +6962,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6849
6962
  if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
6850
6963
  const u = this.readStickerUpdate(update);
6851
6964
  const next = { ...stickers[i], ...u };
6852
- this.commitStickers("Edit sticker", layer, stickers.map((s, j) => j === i ? next : s), [_chunkQ2UYUWAZcjs.stickerRect.call(void 0, stickers[i]), _chunkQ2UYUWAZcjs.stickerRect.call(void 0, next)]);
6965
+ this.commitStickers("Edit sticker", layer, stickers.map((s, j) => j === i ? next : s), [_chunk6G6ZDDDBcjs.stickerRect.call(void 0, stickers[i]), _chunk6G6ZDDDBcjs.stickerRect.call(void 0, next)]);
6853
6966
  return { ...next };
6854
6967
  }
6855
6968
  /**
@@ -6861,8 +6974,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6861
6974
  const layer = this.wetLayer(layerId, "add stickers to");
6862
6975
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (stamp, x, y).");
6863
6976
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
6864
- const existing = _optionalChain([this, 'access', _437 => _437.doc, 'access', _438 => _438.stickers, 'optionalAccess', _439 => _439[layer.id]]);
6865
- if (!_optionalChain([existing, 'optionalAccess', _440 => _440.length])) {
6977
+ const existing = _optionalChain([this, 'access', _442 => _442.doc, 'access', _443 => _443.stickers, 'optionalAccess', _444 => _444[layer.id]]);
6978
+ if (!_optionalChain([existing, 'optionalAccess', _445 => _445.length])) {
6866
6979
  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.`);
6867
6980
  }
6868
6981
  let n = this.nextStickerNumber();
@@ -6878,7 +6991,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6878
6991
  const id = n++;
6879
6992
  return { id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u };
6880
6993
  });
6881
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _441 => _441.length]) ? added.map(_chunkQ2UYUWAZcjs.stickerRect) : void 0);
6994
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _446 => _446.length]) ? added.map(_chunk6G6ZDDDBcjs.stickerRect) : void 0);
6882
6995
  return added.map((s) => ({ ...s }));
6883
6996
  }
6884
6997
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -6888,7 +7001,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6888
7001
  const picked = stickers.filter((s) => ids.includes(s.id));
6889
7002
  const rest = stickers.filter((s) => !ids.includes(s.id));
6890
7003
  const next = to === "front" ? [...rest, ...picked] : [...picked, ...rest];
6891
- this.commitStickers("Arrange stickers", layer, next, picked.map(_chunkQ2UYUWAZcjs.stickerRect));
7004
+ this.commitStickers("Arrange stickers", layer, next, picked.map(_chunk6G6ZDDDBcjs.stickerRect));
6892
7005
  return next.map((s) => s.id);
6893
7006
  }
6894
7007
  /** Deletes stickers (`ids`, or all of them on the layer) (one undo step). Returns the ids removed. */
@@ -6898,7 +7011,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6898
7011
  for (const id of ids) if (!stickers.some((s) => s.id === id)) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
6899
7012
  }
6900
7013
  const removed = ids ? [...ids] : stickers.map((s) => s.id);
6901
- this.commitStickers("Remove stickers", layer, stickers.filter((s) => !removed.includes(s.id)), ids ? stickers.filter((s) => removed.includes(s.id)).map(_chunkQ2UYUWAZcjs.stickerRect) : void 0);
7014
+ this.commitStickers("Remove stickers", layer, stickers.filter((s) => !removed.includes(s.id)), ids ? stickers.filter((s) => removed.includes(s.id)).map(_chunk6G6ZDDDBcjs.stickerRect) : void 0);
6902
7015
  return removed;
6903
7016
  }
6904
7017
  /** Sets a layer's stickers (replays). */
@@ -6917,20 +7030,20 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6917
7030
  }
6918
7031
  liveStrokeLayer(layerId, what) {
6919
7032
  const l = this.wetLayer(layerId, what);
6920
- const strokes = _optionalChain([this, 'access', _442 => _442.doc, 'access', _443 => _443.liveStrokes, 'optionalAccess', _444 => _444[l.id]]);
7033
+ const strokes = _optionalChain([this, 'access', _447 => _447.doc, 'access', _448 => _448.liveStrokes, 'optionalAccess', _449 => _449[l.id]]);
6921
7034
  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.`);
6922
7035
  return { layer: l, strokes };
6923
7036
  }
6924
7037
  /** Whether a layer is a live stroke layer. */
6925
7038
  isLiveStrokeLayer(layerId) {
6926
- return Boolean(_optionalChain([this, 'access', _445 => _445.doc, 'access', _446 => _446.liveStrokes, 'optionalAccess', _447 => _447[layerId]]));
7039
+ return Boolean(_optionalChain([this, 'access', _450 => _450.doc, 'access', _451 => _451.liveStrokes, 'optionalAccess', _452 => _452[layerId]]));
6927
7040
  }
6928
7041
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
6929
7042
  convertToLiveStrokes(layerId) {
6930
7043
  this.requireIdle("converting a layer");
6931
7044
  const l = this.paintTarget(layerId, "convert");
6932
- if (_optionalChain([this, 'access', _448 => _448.doc, 'access', _449 => _449.liveStrokes, 'optionalAccess', _450 => _450[l.id]])) return this.describeLayer(l);
6933
- if (_optionalChain([this, 'access', _451 => _451.doc, 'access', _452 => _452.stickers, 'optionalAccess', _453 => _453[l.id], 'optionalAccess', _454 => _454.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
7045
+ if (_optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.liveStrokes, 'optionalAccess', _455 => _455[l.id]])) return this.describeLayer(l);
7046
+ if (_optionalChain([this, 'access', _456 => _456.doc, 'access', _457 => _457.stickers, 'optionalAccess', _458 => _458[l.id], 'optionalAccess', _459 => _459.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
6934
7047
  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"}).`);
6935
7048
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
6936
7049
  return this.describeLayer(this.getLayer(l.id));
@@ -6943,7 +7056,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6943
7056
  findLiveStroke(id) {
6944
7057
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
6945
7058
  const index = strokes.findIndex((x) => x.id === id);
6946
- const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _455 => _455.layer]);
7059
+ const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _460 => _460.layer]);
6947
7060
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
6948
7061
  }
6949
7062
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -6963,15 +7076,15 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6963
7076
  let brush = was.brush;
6964
7077
  if (update.brushId !== void 0) {
6965
7078
  const b = this.requireBrush(update.brushId);
6966
- brush = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
7079
+ brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
6967
7080
  }
6968
7081
  if (update.brush !== void 0) {
6969
7082
  if (!update.brush || typeof update.brush !== "object") throw new PaintEditorError("brush must be an object of brush settings (as set_brush takes).");
6970
- brush = _chunkQ2UYUWAZcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
7083
+ brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
6971
7084
  }
6972
7085
  const why = liveStrokeRefusal(brush);
6973
7086
  if (why) throw new PaintEditorError(why);
6974
- const next = { ...was, brush: _chunkQ2UYUWAZcjs.brushToJSON.call(void 0, brush) };
7087
+ const next = { ...was, brush: _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, brush) };
6975
7088
  if (update.seed !== void 0) {
6976
7089
  if (!Number.isInteger(update.seed) || update.seed < 0) throw new PaintEditorError(`seed ${update.seed} must be a whole number of 0 or more.`);
6977
7090
  next.seed = update.seed;
@@ -6982,7 +7095,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6982
7095
  }
6983
7096
  if (update.paint !== void 0) {
6984
7097
  if (update.paint === null) delete next.paint;
6985
- else if (_chunkQ2UYUWAZcjs.isPaintEffectPaint.call(void 0, update.paint)) {
7098
+ else if (_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, update.paint)) {
6986
7099
  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).`);
6987
7100
  next.paint = JSON.parse(JSON.stringify(update.paint));
6988
7101
  } else {
@@ -6993,7 +7106,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6993
7106
  } else next.paint = JSON.parse(JSON.stringify(p));
6994
7107
  }
6995
7108
  }
6996
- const rgb = _chunkQ2UYUWAZcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
7109
+ const rgb = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
6997
7110
  const load = brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, rgb);
6998
7111
  if (load.reservoir || load.pickup) next.load = load;
6999
7112
  else delete next.load;
@@ -7038,9 +7151,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7038
7151
  const layers = /* @__PURE__ */ new Map();
7039
7152
  for (const f of found) layers.set(f.layer.id, f.layer);
7040
7153
  for (const [layerId, layer] of layers) {
7041
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _456 => _456.liveStrokes, 'optionalAccess', _457 => _457[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
7154
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _461 => _461.liveStrokes, 'optionalAccess', _462 => _462[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
7042
7155
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
7043
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _458 => _458.liveStrokes, 'optionalAccess', _459 => _459[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
7156
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _463 => _463.liveStrokes, 'optionalAccess', _464 => _464[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
7044
7157
  }
7045
7158
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
7046
7159
  return { removed: [...ids], bounds };
@@ -7108,7 +7221,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7108
7221
  }
7109
7222
  withLiveStrokes(doc, layer, list, dirty) {
7110
7223
  if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
7111
- const current = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _460 => _460.layer]);
7224
+ const current = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _465 => _465.layer]);
7112
7225
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
7113
7226
  const next = { ...doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
7114
7227
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
@@ -7186,7 +7299,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7186
7299
  if (!this.animatedLayers.size) return this.doc.layers;
7187
7300
  let layers = this.doc.layers;
7188
7301
  for (const [id, a] of this.animatedLayers) {
7189
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _461 => _461.layer]);
7302
+ const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _466 => _466.layer]);
7190
7303
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
7191
7304
  }
7192
7305
  return layers;
@@ -7196,11 +7309,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7196
7309
  const layers = [];
7197
7310
  const sources = /* @__PURE__ */ new Map();
7198
7311
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
7199
- const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _462 => _462.layer]);
7312
+ const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _467 => _467.layer]);
7200
7313
  const live = strokes.filter(isLiveEffect);
7201
7314
  if (!isPixelLayer(layer) || !live.length) continue;
7202
7315
  layers.push({ layer, strokes });
7203
- for (const st of live) sources.set(_chunkQ2UYUWAZcjs.effectPaintKey.call(void 0, st.paint), st.paint);
7316
+ for (const st of live) sources.set(_chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, st.paint), st.paint);
7204
7317
  }
7205
7318
  return { layers, sources: [...sources.values()] };
7206
7319
  }
@@ -7327,7 +7440,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7327
7440
  stencilSelection(stencils = this.guides.stencils) {
7328
7441
  const { width, height } = this.doc.canvas;
7329
7442
  const size = `${width}x${height}`;
7330
- if (_optionalChain([this, 'access', _463 => _463.stencilCache, 'optionalAccess', _464 => _464.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
7443
+ if (_optionalChain([this, 'access', _468 => _468.stencilCache, 'optionalAccess', _469 => _469.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
7331
7444
  const mask = stencilMask(stencils, width, height);
7332
7445
  this.stencilCache = { key: stencils, size, mask };
7333
7446
  return mask;
@@ -7389,7 +7502,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7389
7502
  makeSwatch(color, name) {
7390
7503
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
7391
7504
  const out = { color: _chunkPQ3H2AANcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
7392
- if (_optionalChain([name, 'optionalAccess', _465 => _465.trim, 'call', _466 => _466()])) out.name = name.trim();
7505
+ if (_optionalChain([name, 'optionalAccess', _470 => _470.trim, 'call', _471 => _471()])) out.name = name.trim();
7393
7506
  if (p.type === "gradient") out.paint = p;
7394
7507
  return out;
7395
7508
  }
@@ -7441,7 +7554,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7441
7554
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
7442
7555
  */
7443
7556
  mixOnPad(paints, options = {}) {
7444
- const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _467 => _467.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _468 => _468.parts]) }));
7557
+ const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _472 => _472.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _473 => _473.parts]) }));
7445
7558
  let r;
7446
7559
  try {
7447
7560
  r = this.pad.mix(parsed, options);
@@ -7530,7 +7643,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7530
7643
  }
7531
7644
  /** A layer's tile surface (live while stroking), for thumbnails. */
7532
7645
  layerSurface(id) {
7533
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _469 => _469.layer]);
7646
+ const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _474 => _474.layer]);
7534
7647
  return isPixelLayer(l) ? l.surface : null;
7535
7648
  }
7536
7649
  }, _class12.__initStatic(), _class12);
@@ -7552,7 +7665,7 @@ function insertAfter(layers, id, node) {
7552
7665
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
7553
7666
  }
7554
7667
  function isLiveEffect(s) {
7555
- return _optionalChain([s, 'access', _470 => _470.paint, 'optionalAccess', _471 => _471.type]) === "effect" && s.paint.live === true;
7668
+ return _optionalChain([s, 'access', _475 => _475.paint, 'optionalAccess', _476 => _476.type]) === "effect" && s.paint.live === true;
7556
7669
  }
7557
7670
  function framePaint(p, t) {
7558
7671
  return { ...p, time: p.time + t };
@@ -7577,7 +7690,7 @@ function clipRect(r, width, height) {
7577
7690
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
7578
7691
  }
7579
7692
  function withLiveStroke(doc, stroke) {
7580
- const list = _optionalChain([doc, 'access', _472 => _472.liveStrokes, 'optionalAccess', _473 => _473[stroke.layerId]]);
7693
+ const list = _optionalChain([doc, 'access', _477 => _477.liveStrokes, 'optionalAccess', _478 => _478[stroke.layerId]]);
7581
7694
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
7582
7695
  }
7583
7696
  function shiftDocument(doc, dx, dy) {
@@ -7604,9 +7717,9 @@ function shiftDocument(doc, dx, dy) {
7604
7717
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
7605
7718
  if (doc.paintEvents) {
7606
7719
  out.paintEvents = doc.paintEvents.map((e) => {
7607
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _474 => _474.data, 'optionalAccess', _475 => _475.stickers]) : void 0;
7720
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _479 => _479.data, 'optionalAccess', _480 => _480.stickers]) : void 0;
7608
7721
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
7609
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _476 => _476.data, 'optionalAccess', _477 => _477.strokes]) : void 0;
7722
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _481 => _481.data, 'optionalAccess', _482 => _482.strokes]) : void 0;
7610
7723
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
7611
7724
  });
7612
7725
  }
@@ -7688,8 +7801,8 @@ function strokeSchedule(points) {
7688
7801
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
7689
7802
  }
7690
7803
  function strokeDuration(points, max = 1800) {
7691
- const t0 = _optionalChain([points, 'access', _478 => _478[0], 'optionalAccess', _479 => _479.t]);
7692
- const t1 = _optionalChain([points, 'access', _480 => _480[points.length - 1], 'optionalAccess', _481 => _481.t]);
7804
+ const t0 = _optionalChain([points, 'access', _483 => _483[0], 'optionalAccess', _484 => _484.t]);
7805
+ const t1 = _optionalChain([points, 'access', _485 => _485[points.length - 1], 'optionalAccess', _486 => _486.t]);
7693
7806
  let ms;
7694
7807
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
7695
7808
  else {
@@ -7743,7 +7856,7 @@ var PaintDirector = class {
7743
7856
  }
7744
7857
  where(id) {
7745
7858
  const a = this.presence.get(id);
7746
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _482 => _482.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _483 => _483.y]), () => ( 0)) };
7859
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _487 => _487.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _488 => _488.y]), () => ( 0)) };
7747
7860
  }
7748
7861
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
7749
7862
  async glide(id, to, ms = 380) {
@@ -7790,8 +7903,8 @@ var PaintDirector = class {
7790
7903
  }
7791
7904
  case "replay": {
7792
7905
  await this.say(id, command.note, 500);
7793
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _484 => _484.replay, 'access', _485 => _485.strokeIds, 'optionalAccess', _486 => _486.includes, 'call', _487 => _487(s.id)]));
7794
- const first = _optionalChain([source, 'access', _488 => _488[0], 'optionalAccess', _489 => _489.points, 'access', _490 => _490[0]]);
7906
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _489 => _489.replay, 'access', _490 => _490.strokeIds, 'optionalAccess', _491 => _491.includes, 'call', _492 => _492(s.id)]));
7907
+ const first = _optionalChain([source, 'access', _493 => _493[0], 'optionalAccess', _494 => _494.points, 'access', _495 => _495[0]]);
7795
7908
  if (first) await this.glide(id, first);
7796
7909
  const result = c.replayStrokes(command.replay);
7797
7910
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -7972,7 +8085,7 @@ function createPaintStickerTools(c) {
7972
8085
  items: {
7973
8086
  type: "object",
7974
8087
  properties: {
7975
- stamp: { type: "string", enum: [..._chunkQ2UYUWAZcjs.STAMP_KINDS], description: "The stamp." },
8088
+ stamp: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "The stamp." },
7976
8089
  x: { type: "number", description: "Centre x in document pixels." },
7977
8090
  y: { type: "number", description: "Centre y in document pixels." },
7978
8091
  size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels (default 48)." },
@@ -8002,7 +8115,7 @@ function createPaintStickerTools(c) {
8002
8115
  properties: {
8003
8116
  layerId: LAYER_ID,
8004
8117
  id: { type: "string", description: "Sticker id from list_stickers." },
8005
- stamp: { type: "string", enum: [..._chunkQ2UYUWAZcjs.STAMP_KINDS], description: "Another stamp." },
8118
+ stamp: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "Another stamp." },
8006
8119
  x: { type: "number", description: "Centre x in document pixels." },
8007
8120
  y: { type: "number", description: "Centre y in document pixels." },
8008
8121
  size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels." },
@@ -8913,7 +9026,7 @@ var BEHAVIOR = {
8913
9026
  type: "object",
8914
9027
  description: "Multi-coloured brush (the older form of paint, the brush's own gradient: tip is across-tip, dab is distance in dabs or random). Read back from paint when it has a multi-colour equivalent. Missing fields keep their current values.",
8915
9028
  properties: {
8916
- mode: { type: "string", enum: [..._chunkQ2UYUWAZcjs.MULTI_COLOR_MODES], description: "off; tip: the colours lie side by side across the tip (stripes along the stroke, like a brush loaded with several paints); dab: the colour changes along the stroke." },
9029
+ mode: { type: "string", enum: [..._chunk6G6ZDDDBcjs.MULTI_COLOR_MODES], description: "off; tip: the colours lie side by side across the tip (stripes along the stroke, like a brush loaded with several paints); dab: the colour changes along the stroke." },
8917
9030
  colors: { type: "array", maxItems: 8, items: { ...COLOR3 }, description: "2..8 colours #rrggbb; fewer than 2 uses the paint colour and the secondary colour." },
8918
9031
  order: { type: "string", enum: ["sequence", "random"], description: "dab mode: sequence runs through the colours in order, blending between them; random picks one per run of dabs (seeded)." },
8919
9032
  length: { type: "integer", minimum: 1, maximum: 500, description: "dab mode: dabs per colour (default 12)." },
@@ -8954,10 +9067,10 @@ var WET_BRUSH = {
8954
9067
  properties: {
8955
9068
  tool: {
8956
9069
  type: "string",
8957
- enum: [..._chunkQ2UYUWAZcjs.WET_TOOLS],
9070
+ enum: [..._chunk6G6ZDDDBcjs.WET_TOOLS],
8958
9071
  description: "paint: water and pigment (picks up and mixes wet paint by behavior.pickup / mix); water: clear water (with rewet it lifts dried paint); dry: a hair dryer, takes water; blow: pushes the water along the stroke; blend: evens out wet pigment; smudge: drags wet paint; blot: a tissue, takes wet paint up (erase wet)."
8959
9072
  },
8960
- medium: { type: "string", enum: [..._chunkQ2UYUWAZcjs.WET_MEDIA], description: "The medium: watercolor, gouache or oil. A layer takes the medium's wet settings the first time it holds wet paint (oil: thick, barely flows, stays wet long and blends into the wet paint it meets)." },
9073
+ medium: { type: "string", enum: [..._chunk6G6ZDDDBcjs.WET_MEDIA], description: "The medium: watercolor, gouache or oil. A layer takes the medium's wet settings the first time it holds wet paint (oil: thick, barely flows, stays wet long and blends into the wet paint it meets)." },
8961
9074
  load: { type: "number", minimum: 0, maximum: 1, description: "Paint loading: 1 never runs out; lower, the brush runs dry along a long stroke (each stroke reloads)." },
8962
9075
  thinner: { type: "number", minimum: 0, maximum: 1, description: "Thinner (water or solvent): more transparent, runnier paint." },
8963
9076
  water: { type: "number", minimum: 0, maximum: 1, description: "Wetness: water laid per stroke, 0.2 a damp brush .. 1 a dripping one." },
@@ -8974,7 +9087,7 @@ var IMPASTO_BRUSH = {
8974
9087
  properties: {
8975
9088
  tool: {
8976
9089
  type: "string",
8977
- enum: [..._chunkQ2UYUWAZcjs.IMPASTO_TOOLS],
9090
+ enum: [..._chunk6G6ZDDDBcjs.IMPASTO_TOOLS],
8978
9091
  description: "brush: thick paint with bristle ridges along the stroke; tube: blobs squeezed from the tube; knife: a palette knife that scrapes the relief flat and smears the paint; roller: a flat stippled band; gloop: a thick, glossy, rounded bead."
8979
9092
  },
8980
9093
  thickness: { type: "number", minimum: 0, maximum: 1, description: "How far the paint stands up." },
@@ -9001,17 +9114,39 @@ var PARTICLE_BRUSH = {
9001
9114
  type: "object",
9002
9115
  description: "Particle engine settings (procedural brushes). Missing fields keep their current values.",
9003
9116
  properties: {
9004
- kind: { type: "string", enum: [..._chunkQ2UYUWAZcjs.PARTICLE_KINDS], description: "string: strands of masses on springs dragged behind the pen (hair, fur, wet string); spring: particles on springs to the pen, overshooting and wobbling; orbit: particles circling the pen (curls); flow: particles thrown off the pen into a swirling flow until they fade." },
9005
- render: { type: "string", enum: [..._chunkQ2UYUWAZcjs.PARTICLE_RENDERS], description: "dot: a mark at each step; line: each particle draws a continuous line; sequence: beads spaced along each path." },
9117
+ kind: {
9118
+ type: "string",
9119
+ enum: [..._chunk6G6ZDDDBcjs.PARTICLE_KINDS],
9120
+ description: "string: strands of masses on springs dragged behind the pen (hair, fur, wet string); spring: particles on springs to the pen, overshooting and wobbling; orbit: particles circling the pen (curls); flow: particles thrown off the pen into a swirling flow until they fade; elastic: strands whose links keep a rest length, stretching when the pen is fast and snapping back; fuzzy: winding strings, each strand waving out of step with the others (always waves by at least 0.12 of the tip size)."
9121
+ },
9122
+ render: {
9123
+ type: "string",
9124
+ enum: [..._chunk6G6ZDDDBcjs.PARTICLE_RENDERS],
9125
+ description: "dot: a mark at each step (round, or dotTextures); line: each particle draws a continuous line; sequence: beads spaced along each path (round, or dotTextures); ribbon: the band between neighbouring particles' paths filled (ribbonFill), with the paths drawn as its edges at the mark size (flame, silk, smoke)."
9126
+ },
9006
9127
  count: { type: "integer", minimum: 1, maximum: 64, description: "Particles (flow: how many are thrown per tip of travel)." },
9007
- size: { type: "number", minimum: 0, maximum: 1, description: "Mark size as a fraction of the tip size." },
9008
- spread: { type: "number", minimum: 0, maximum: 1, description: "How far apart the particles start, as a fraction of the tip size." },
9009
- stiffness: { type: "number", minimum: 0, maximum: 1, description: "Spring and string stiffness: stiff follows closely, soft swings wide." },
9128
+ size: { type: "number", minimum: 0, maximum: 1, description: "Mark size as a fraction of the tip size (ribbon: the width of its edges)." },
9129
+ spread: { type: "number", minimum: 0, maximum: 1, description: "How far apart the particles start, as a fraction of the tip size (ribbon: how wide it is)." },
9130
+ stiffness: { type: "number", minimum: 0, maximum: 1, description: "Spring, string and elastic stiffness: stiff follows closely (elastic: snaps back faster), soft swings wide." },
9010
9131
  damping: { type: "number", minimum: 0, maximum: 1, description: "How quickly motion dies down." },
9011
9132
  speed: { type: "number", minimum: 0, maximum: 1, description: "Orbit and flow speed." },
9012
9133
  gravity: { type: "number", minimum: -1, maximum: 1, description: "Pull downwards (negative: upwards)." },
9013
9134
  life: { type: "number", minimum: 0, maximum: 1, description: "Flow particles: how long they live." },
9014
- interval: { type: "number", minimum: 0, maximum: 1, description: "Sequence: spacing of the beads." }
9135
+ interval: { type: "number", minimum: 0, maximum: 1, description: "Sequence: spacing of the beads." },
9136
+ ribbonFill: { type: "number", minimum: 0, maximum: 1, description: "Ribbon: opacity of the fill between the paths, relative to their edges (default 0.5; 0 draws only the edges)." },
9137
+ ribbonPairs: { type: "string", enum: [..._chunk6G6ZDDDBcjs.RIBBON_PAIRS], description: "Ribbon: adjacent (default) joins each particle to its neighbour around the pen; first-last makes one band between the outermost two." },
9138
+ waveAmplitude: { type: "number", minimum: 0, maximum: 1, description: "Wave: how far each particle's drawn place swings sideways to the stroke, as a fraction of the tip size (default 0: no wave). Works with every kind and render." },
9139
+ waveLength: { type: "number", minimum: 4, maximum: 2e3, description: "Wave: wavelength in px of pen travel (default 60)." },
9140
+ waveSpeed: { type: "number", minimum: 0, maximum: 1, description: "Wave: how fast the waves run, by stroke time (0 default: they stand still on the path; 1: about four a second, so slow strokes wave more). Strokes without times run at a nominal 0.5 px/ms." },
9141
+ wavePhaseJitter: { type: "number", minimum: 0, maximum: 1, description: "Wave: how far out of step the particles' waves are (default 0: all in step, a wavy band; 1: random phases, tangled strands)." },
9142
+ dotTextures: {
9143
+ type: "array",
9144
+ maxItems: _chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES,
9145
+ items: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "A stamp." },
9146
+ description: `Dot and sequence renders: up to ${_chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES} sticker stamps (list_stickers) drawn instead of round marks; repeats are allowed (they weight the order). Empty (default): round marks.`
9147
+ },
9148
+ dotTextureOrder: { type: "string", enum: [..._chunk6G6ZDDDBcjs.DOT_TEXTURE_ORDERS], description: "Textured dots: sequence (default) uses the stamps in turn; random picks one per dot (seeded, so replays are exact)." },
9149
+ dotRotation: { type: "string", enum: [..._chunk6G6ZDDDBcjs.DOT_ROTATIONS], description: "Textured dots: follow turns each with its particle's motion; random (default) turns each at random; fixed uses the tip angle." }
9015
9150
  },
9016
9151
  additionalProperties: false
9017
9152
  };
@@ -9032,7 +9167,7 @@ var STICKER_BRUSH = {
9032
9167
  type: "object",
9033
9168
  description: "Sticker engine settings: stamps sprayed along the stroke as editable stickers. Missing fields keep their current values.",
9034
9169
  properties: {
9035
- stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [..._chunkQ2UYUWAZcjs.STAMP_KINDS], description: "A stamp." }, description: "The stamps to spray (one picked at random per sticker)." },
9170
+ stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "A stamp." }, description: "The stamps to spray (one picked at random per sticker)." },
9036
9171
  density: { type: "number", minimum: 0, maximum: 1, description: "How closely stickers follow each other: about density \xD7 4 stickers per tip diameter of travel (0.25 \u2248 one per diameter, 1 \u2248 four). Default 0.4." },
9037
9172
  sizeJitter: { type: "number", minimum: 0, maximum: 1, description: "Random size change." },
9038
9173
  rotationJitter: { type: "number", minimum: 0, maximum: 1, description: "Random turn as a fraction of \xB1180\xB0." },
@@ -9043,16 +9178,16 @@ var STICKER_BRUSH = {
9043
9178
  };
9044
9179
  var BRUSH_FIELDS = {
9045
9180
  name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." },
9046
- category: { type: "string", enum: [..._chunkQ2UYUWAZcjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
9181
+ category: { type: "string", enum: [..._chunk6G6ZDDDBcjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
9047
9182
  engine: {
9048
9183
  type: "string",
9049
- enum: [..._chunkQ2UYUWAZcjs.PAINT_BRUSH_ENGINES],
9184
+ enum: [..._chunk6G6ZDDDBcjs.PAINT_BRUSH_ENGINES],
9050
9185
  description: "dab: paints dabs (with behavior.pickup or gradient paint it paints dab by dab, lifting and mixing paint); eraser: removes paint; mixer: the Mixer Brush (a reservoir plus picked-up paint); blender: mixes the colours under and near the tip; smudge: drags paint along the stroke; wet: watercolour, gouache, oil and the wet tools on a simulated wet layer (see wet); impasto: thick paint with relief (see impasto); particle: procedural particle brushes (see particle); bristle: a tuft of bristles that bend and splay (see bristle); sticker: sprays editable sticker stamps (see sticker)."
9051
9186
  },
9052
9187
  tip: TIP,
9053
9188
  grain: { type: "number", minimum: 0, maximum: 1, description: "Paper grain response: 0 ignores the grain, 1 catches only its peaks at light pressure (pencil, pastel, charcoal). Multiplied by the paper depth." },
9054
9189
  pressureSmoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Pressure smoothing, separate from the tip position smoothing." },
9055
- rotation: { type: "string", enum: [..._chunkQ2UYUWAZcjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
9190
+ rotation: { type: "string", enum: [..._chunk6G6ZDDDBcjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
9056
9191
  dynamics: DYNAMICS,
9057
9192
  mixer: MIXER,
9058
9193
  loadsColor: { type: "boolean", description: "Mixer engine: load the colour each stroke (false for a mixer that only moves paint)." },
@@ -9104,7 +9239,7 @@ function brushSummary(b) {
9104
9239
  size: b.tip.size,
9105
9240
  grain: b.grain,
9106
9241
  rotation: b.rotation,
9107
- wetCapable: _chunkQ2UYUWAZcjs.isWetCapable.call(void 0, b),
9242
+ wetCapable: _chunk6G6ZDDDBcjs.isWetCapable.call(void 0, b),
9108
9243
  pickup: b.behavior.pickup,
9109
9244
  dirty: b.behavior.dirty,
9110
9245
  multicolor: b.behavior.multicolor.mode,
@@ -9213,8 +9348,8 @@ function createPaintEditorToolProvider(controller, options = {}) {
9213
9348
  inputSchema: EMPTY3,
9214
9349
  annotations: { title: "List papers", ...READ6 },
9215
9350
  handler: () => ({
9216
- papers: _chunkQ2UYUWAZcjs.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 })),
9217
- families: [..._chunkQ2UYUWAZcjs.PAPER_FAMILIES],
9351
+ papers: _chunk6G6ZDDDBcjs.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 })),
9352
+ families: [..._chunk6G6ZDDDBcjs.PAPER_FAMILIES],
9218
9353
  patterns: [..._chunkPQ3H2AANcjs.GRAIN_PATTERNS]
9219
9354
  })
9220
9355
  });
@@ -9431,12 +9566,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
9431
9566
  add({
9432
9567
  name: "list_brushes",
9433
9568
  title: "List brushes",
9434
- description: "Lists the brush library: built-in dry media (pencils, pastels, charcoal, airbrush, marker, ink, erasers), paint brushes (dirty round, multi-colour flat, palette dabber), blending tools (blender, smudge, pigment smudge, Mixer Brush), light paint (category light: glow gel, neon marker, light airbrush, spark trail, glow wash, highlighter; light is the amount they lay) and saved user brushes, with id, name, category, engine, size, grain response, rotation mode, whether it can pick up paint (wetCapable), its pick-up ratio, dirty and multi-colour mode, plus the active brush id.",
9569
+ description: "Lists the brush library: built-in dry media (pencils, pastels, charcoal, airbrush, marker, ink, erasers), paint brushes (dirty round, multi-colour flat, palette dabber), blending tools (blender, smudge, pigment smudge, Mixer Brush), light paint (category light: glow gel, neon marker, light airbrush, spark trail, light ribbon, flame ribbon, neon strand, smoke ribbon, bokeh dots, twinkle sparks, glow wash, highlighter; light is the amount they lay) and saved user brushes, with id, name, category, engine, size, grain response, rotation mode, whether it can pick up paint (wetCapable), its pick-up ratio, dirty and multi-colour mode, plus the active brush id.",
9435
9570
  inputSchema: EMPTY3,
9436
9571
  annotations: { title: "List brushes", ...READ6 },
9437
9572
  handler: () => {
9438
9573
  const s = c.getState();
9439
- return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _491 => _491.getBrush, 'call', _492 => _492(s.brush.id), 'optionalAccess', _493 => _493.builtin])), brushes: s.brushes.map(brushSummary) };
9574
+ return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _496 => _496.getBrush, 'call', _497 => _497(s.brush.id), 'optionalAccess', _498 => _498.builtin])), brushes: s.brushes.map(brushSummary) };
9440
9575
  }
9441
9576
  });
9442
9577
  add({
@@ -9447,10 +9582,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
9447
9582
  annotations: { title: "Get a brush", ...READ6 },
9448
9583
  handler: ({ id }) => {
9449
9584
  const st = c.getState();
9450
- if (id === void 0) return { ..._chunkQ2UYUWAZcjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
9585
+ if (id === void 0) return { ..._chunk6G6ZDDDBcjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
9451
9586
  const b = c.getBrush(id);
9452
9587
  if (!b) throw new Error(`Unknown brush "${id}". Call list_brushes for the ids.`);
9453
- return { ..._chunkQ2UYUWAZcjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
9588
+ return { ..._chunk6G6ZDDDBcjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
9454
9589
  }
9455
9590
  });
9456
9591
  add({
@@ -9459,7 +9594,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9459
9594
  description: "Chooses the active brush (id) and / or changes its settings; strokes without a brush use it. Editor state, not an undo step. Changes stay on the active brush until save_brush stores them. Returns the active brush.",
9460
9595
  inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brushes to start from." }, ...BRUSH_FIELDS }, additionalProperties: false },
9461
9596
  annotations: { title: "Set the brush", ...SET4 },
9462
- handler: (a) => _chunkQ2UYUWAZcjs.brushToJSON.call(void 0, c.setBrush(a))
9597
+ handler: (a) => _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, c.setBrush(a))
9463
9598
  });
9464
9599
  add({
9465
9600
  name: "save_brush",
@@ -9475,7 +9610,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9475
9610
  additionalProperties: false
9476
9611
  },
9477
9612
  annotations: { title: "Save a brush", ...SET4 },
9478
- handler: ({ id, name }) => _chunkQ2UYUWAZcjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
9613
+ handler: ({ id, name }) => _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
9479
9614
  });
9480
9615
  add({
9481
9616
  name: "remove_brush",
@@ -9666,7 +9801,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9666
9801
  if (ids) {
9667
9802
  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.`);
9668
9803
  }
9669
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _494 => _494.document, 'access', _495 => _495.liveStrokes, 'optionalAccess', _496 => _496[s.layerId], 'optionalAccess', _497 => _497.includes, 'call', _498 => _498(s)]) === true)) };
9804
+ 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)) };
9670
9805
  }
9671
9806
  });
9672
9807
  add({
@@ -9943,6 +10078,19 @@ function createPaintEditorToolProvider(controller, options = {}) {
9943
10078
  tools.push(...createPaintReplayTools(c));
9944
10079
  tools.push(...createPaintStickerTools(c));
9945
10080
  tools.push(..._chunkVMROIWLLcjs.createPigmentTools.call(void 0, ));
10081
+ tools.push(
10082
+ ..._chunkWVS5KQDHcjs.createLayerEffectTools.call(void 0,
10083
+ {
10084
+ requireLayer: (id) => void c.getLayerEffects(id),
10085
+ getLayerEffects: (id) => c.getLayerEffects(id),
10086
+ addLayerEffect: (id, kind, settings, index) => c.addLayerEffect(id, kind, settings, index),
10087
+ updateLayerEffect: (id, effectId, changes) => c.updateLayerEffect(id, effectId, changes),
10088
+ removeLayerEffect: (id, effectId) => c.removeLayerEffect(id, effectId),
10089
+ setLayerEffectsEnabled: (id, enabled, scale) => c.setLayerEffectsEnabled(id, enabled, scale)
10090
+ },
10091
+ { layers: "a pixel, stroke, sticker or group layer", error: (m) => new PaintEditorError(m) }
10092
+ )
10093
+ );
9946
10094
  const exclude = new Set(_nullishCoalesce(options.exclude, () => ( [])));
9947
10095
  const description = "Natural-media painting: paper and grain, dry and wet brushes, the brush library, strokes as data, pigment mixing, stencils, guides, layers and export.";
9948
10096
  return withPaintPlayback({
@@ -9956,16 +10104,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
9956
10104
  }
9957
10105
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
9958
10106
  if (!origin && !onChange) return tool;
9959
- const write = !_optionalChain([tool, 'access', _499 => _499.annotations, 'optionalAccess', _500 => _500.readOnlyHint]);
10107
+ const write = !_optionalChain([tool, 'access', _504 => _504.annotations, 'optionalAccess', _505 => _505.readOnlyHint]);
9960
10108
  const done = (result) => {
9961
- if (write) _optionalChain([onChange, 'optionalCall', _501 => _501({ tool: tool.name })]);
9962
- return origin && _optionalChain([coordinates, 'optionalAccess', _502 => _502.out]) ? fromDocument(result, coordinates.out, origin) : result;
10109
+ if (write) _optionalChain([onChange, 'optionalCall', _506 => _506({ tool: tool.name })]);
10110
+ return origin && _optionalChain([coordinates, 'optionalAccess', _507 => _507.out]) ? fromDocument(result, coordinates.out, origin) : result;
9963
10111
  };
9964
10112
  return {
9965
10113
  ...tool,
9966
10114
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
9967
10115
  handler: (args, context) => {
9968
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _503 => _503.in]) ? toDocument(args, coordinates.in, origin) : args, context);
10116
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _508 => _508.in]) ? toDocument(args, coordinates.in, origin) : args, context);
9969
10117
  return r instanceof Promise ? r.then(done) : done(r);
9970
10118
  }
9971
10119
  };
@@ -9982,7 +10130,7 @@ function strokeSummary(s, withPoints, live) {
9982
10130
  color: s.color,
9983
10131
  points: withPoints ? s.points : s.points.length,
9984
10132
  seed: s.seed,
9985
- copies: _nullishCoalesce(_optionalChain([s, 'access', _504 => _504.copies, 'optionalAccess', _505 => _505.length]), () => ( 0)),
10133
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _509 => _509.copies, 'optionalAccess', _510 => _510.length]), () => ( 0)),
9986
10134
  live,
9987
10135
  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) }
9988
10136
  };
@@ -10067,13 +10215,13 @@ var PaintGesture = (_class13 = class {
10067
10215
  const p = this.doc(e);
10068
10216
  const s = this.controller.getState();
10069
10217
  const layerId = s.document.activeLayerId;
10070
- if (!layerId || !_optionalChain([s, 'access', _506 => _506.document, 'access', _507 => _507.liveStrokes, 'optionalAccess', _508 => _508[layerId]])) {
10218
+ if (!layerId || !_optionalChain([s, 'access', _511 => _511.document, 'access', _512 => _512.liveStrokes, 'optionalAccess', _513 => _513[layerId]])) {
10071
10219
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
10072
10220
  return false;
10073
10221
  }
10074
10222
  try {
10075
10223
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
10076
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _509 => _509.id]), () => ( null)));
10224
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _514 => _514.id]), () => ( null)));
10077
10225
  if (!hit) return false;
10078
10226
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
10079
10227
  return true;
@@ -10085,7 +10233,7 @@ var PaintGesture = (_class13 = class {
10085
10233
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
10086
10234
  get strokeDrag() {
10087
10235
  const m = this.mode;
10088
- return _optionalChain([m, 'optionalAccess', _510 => _510.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
10236
+ 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;
10089
10237
  }
10090
10238
  /**
10091
10239
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -10159,7 +10307,7 @@ var PaintGesture = (_class13 = class {
10159
10307
  if (!m || m.pointerId !== e.pointerId) return;
10160
10308
  this.mode = null;
10161
10309
  this.predicted = [];
10162
- if (m.kind === "stroke") _optionalChain([this, 'access', _511 => _511.controller, 'access', _512 => _512.activeStroke, 'optionalAccess', _513 => _513.end, 'call', _514 => _514()]);
10310
+ if (m.kind === "stroke") _optionalChain([this, 'access', _516 => _516.controller, 'access', _517 => _517.activeStroke, 'optionalAccess', _518 => _518.end, 'call', _519 => _519()]);
10163
10311
  if (m.kind === "move-stroke") {
10164
10312
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
10165
10313
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -10183,8 +10331,8 @@ var PaintGesture = (_class13 = class {
10183
10331
  cancel() {
10184
10332
  this.penDown = false;
10185
10333
  this.predicted = [];
10186
- if (_optionalChain([this, 'access', _515 => _515.mode, 'optionalAccess', _516 => _516.kind]) === "stroke") _optionalChain([this, 'access', _517 => _517.controller, 'access', _518 => _518.activeStroke, 'optionalAccess', _519 => _519.cancel, 'call', _520 => _520()]);
10187
- if (_optionalChain([this, 'access', _521 => _521.mode, 'optionalAccess', _522 => _522.kind]) === "sticker") this.controller.cancelStickerPreview();
10334
+ 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()]);
10335
+ if (_optionalChain([this, 'access', _526 => _526.mode, 'optionalAccess', _527 => _527.kind]) === "sticker") this.controller.cancelStickerPreview();
10188
10336
  this.mode = null;
10189
10337
  }
10190
10338
  get active() {
@@ -10284,7 +10432,7 @@ function guideOverlay(controller, drag) {
10284
10432
  const size = s.document.canvas;
10285
10433
  const out = [];
10286
10434
  const layerId = s.document.activeLayerId;
10287
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _523 => _523.document, 'access', _524 => _524.liveStrokes, 'optionalAccess', _525 => _525[layerId], 'optionalAccess', _526 => _526.some, 'call', _527 => _527((x) => x.id === s.selectedStroke)]) : false;
10435
+ 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;
10288
10436
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
10289
10437
  if (area) {
10290
10438
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -10297,7 +10445,7 @@ function guideOverlay(controller, drag) {
10297
10445
  ];
10298
10446
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
10299
10447
  }
10300
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _528 => _528.document, 'access', _529 => _529.stickers, 'optionalAccess', _530 => _530[layerId], 'optionalAccess', _531 => _531.find, 'call', _532 => _532((x) => x.id === s.selectedSticker)]) : void 0;
10448
+ 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;
10301
10449
  if (picked) {
10302
10450
  const r = picked.size / 2 + 2;
10303
10451
  const a = picked.rotation * Math.PI / 180;
@@ -10342,7 +10490,7 @@ var PAPER_SLIDERS = [
10342
10490
  ];
10343
10491
  function readPath(obj, path) {
10344
10492
  let v = obj;
10345
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _533 => _533[k]]);
10493
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _538 => _538[k]]);
10346
10494
  return typeof v === "number" ? v : 0;
10347
10495
  }
10348
10496
  function patchPath(obj, path, value) {
@@ -10394,7 +10542,7 @@ var PICKUP_SLIDERS = [
10394
10542
  ];
10395
10543
  function brushEngineControls(brush) {
10396
10544
  const c = engineControls(brush);
10397
- const wetPaint = brush.engine === "wet" && _optionalChain([brush, 'access', _534 => _534.wet, 'optionalAccess', _535 => _535.tool]) === "paint";
10545
+ const wetPaint = brush.engine === "wet" && _optionalChain([brush, 'access', _539 => _539.wet, 'optionalAccess', _540 => _540.tool]) === "paint";
10398
10546
  if (!c || !(wetPaint || ["dab", "mixer", "particle", "bristle", "impasto"].includes(brush.engine))) return c;
10399
10547
  const extra = brush.engine === "impasto" ? [{ path: "impasto.rim", label: "Rim", min: 0, max: 1, step: 0.01 }, { path: "impasto.clarity", label: "Clarity", min: 0, max: 1, step: 0.01 }] : [];
10400
10548
  return { ...c, sliders: [...c.sliders, LIGHT_SLIDER, ...extra], light: true };
@@ -10413,7 +10561,12 @@ function engineControls(brush) {
10413
10561
  { path: "particle.speed", label: "Speed", min: 0, max: 1, step: 0.01 },
10414
10562
  { path: "particle.gravity", label: "Gravity", min: -1, max: 1, step: 0.01 },
10415
10563
  { path: "particle.life", label: "Life", min: 0, max: 1, step: 0.01 },
10416
- { path: "particle.interval", label: "Bead spacing", min: 0, max: 1, step: 0.01 }
10564
+ { path: "particle.interval", label: "Bead spacing", min: 0, max: 1, step: 0.01 },
10565
+ { path: "particle.ribbonFill", label: "Ribbon fill", min: 0, max: 1, step: 0.01 },
10566
+ { path: "particle.waveAmplitude", label: "Wave", min: 0, max: 1, step: 0.01 },
10567
+ { path: "particle.waveLength", label: "Wavelength", min: 4, max: 400, step: 1 },
10568
+ { path: "particle.waveSpeed", label: "Wave speed", min: 0, max: 1, step: 0.01 },
10569
+ { path: "particle.wavePhaseJitter", label: "Wave scatter", min: 0, max: 1, step: 0.01 }
10417
10570
  ],
10418
10571
  mixingPath: null,
10419
10572
  dirty: false,
@@ -10472,7 +10625,7 @@ function engineControls(brush) {
10472
10625
  impastoTool: true
10473
10626
  };
10474
10627
  case "wet": {
10475
- const tool = _nullishCoalesce(_optionalChain([brush, 'access', _536 => _536.wet, 'optionalAccess', _537 => _537.tool]), () => ( "paint"));
10628
+ const tool = _nullishCoalesce(_optionalChain([brush, 'access', _541 => _541.wet, 'optionalAccess', _542 => _542.tool]), () => ( "paint"));
10476
10629
  const sliders = tool === "paint" ? [
10477
10630
  { path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
10478
10631
  { path: "wet.pigment", label: "Pigment", min: 0, max: 1, step: 0.01 },
@@ -10605,7 +10758,7 @@ function startWetClock(controller, frame, cancel) {
10605
10758
  id = raf(loop);
10606
10759
  return () => {
10607
10760
  stopped = true;
10608
- _optionalChain([caf, 'optionalCall', _538 => _538(id)]);
10761
+ _optionalChain([caf, 'optionalCall', _543 => _543(id)]);
10609
10762
  };
10610
10763
  }
10611
10764
  function drawWaterOverlay(controller, ctx) {
@@ -10628,13 +10781,20 @@ var LIGHT_SLIDERS = [
10628
10781
  { path: "elevation", label: "Light height", min: 5, max: 90, step: 1 },
10629
10782
  { path: "relief", label: "Relief", min: 0, max: 1, step: 0.01 }
10630
10783
  ];
10631
- var PARTICLE_KIND_LABELS = { string: "Strings", spring: "Springs", orbit: "Orbits", flow: "Flow" };
10632
- var PARTICLE_RENDER_LABELS = { dot: "Dots", line: "Lines", sequence: "Beads" };
10784
+ var PARTICLE_KIND_LABELS = { string: "Strings", spring: "Springs", orbit: "Orbits", flow: "Flow", elastic: "Elastic", fuzzy: "Fuzzy" };
10785
+ var PARTICLE_RENDER_LABELS = { dot: "Dots", line: "Lines", sequence: "Beads", ribbon: "Ribbon" };
10786
+ var RIBBON_PAIR_LABELS = { adjacent: "Neighbours", "first-last": "Outermost" };
10787
+ var DOT_TEXTURE_ORDER_LABELS = { sequence: "In turn", random: "Random" };
10788
+ var DOT_ROTATION_LABELS = { follow: "Follow motion", random: "Random", fixed: "Tip angle" };
10633
10789
  var STAMP_LABELS = { dot: "Dot", star: "Star", heart: "Heart", leaf: "Leaf", flower: "Flower", confetti: "Confetti", splat: "Splat", sparkle: "Sparkle", ring: "Ring" };
10634
10790
  function toggleStamp(stamps, stamp) {
10635
10791
  const next = stamps.includes(stamp) ? stamps.filter((s) => s !== stamp) : [...stamps, stamp];
10636
10792
  return next.length ? next : [stamp];
10637
10793
  }
10794
+ function toggleDotTexture(textures, stamp) {
10795
+ if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
10796
+ return textures.length < _chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
10797
+ }
10638
10798
  var STROKE_SLIDERS = [
10639
10799
  { path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
10640
10800
  { path: "tip.opacity", label: "Opacity", min: 0, max: 1, step: 0.01 },
@@ -11256,4 +11416,13 @@ function createPaintEditorDocument(controller, options = {}) {
11256
11416
 
11257
11417
 
11258
11418
 
11259
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.BRUSH_ID = _chunkQ2UYUWAZcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkQ2UYUWAZcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkQ2UYUWAZcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunkQ2UYUWAZcjs.BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkQ2UYUWAZcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkQ2UYUWAZcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkQ2UYUWAZcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkQ2UYUWAZcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkVMROIWLLcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkQ2UYUWAZcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkQ2UYUWAZcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkQ2UYUWAZcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkQ2UYUWAZcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkQ2UYUWAZcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunkQ2UYUWAZcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkQ2UYUWAZcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkVMROIWLLcjs.DEFAULT_WET_PARAMS; exports.DryStroke = _chunkQ2UYUWAZcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkQ2UYUWAZcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkQ2UYUWAZcjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPQ3H2AANcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPQ3H2AANcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunk7PT4RJL5cjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkQ2UYUWAZcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkQ2UYUWAZcjs.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 = _chunkPQ3H2AANcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; 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 = _chunkQ2UYUWAZcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkQ2UYUWAZcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkQ2UYUWAZcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkPQ3H2AANcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkPQ3H2AANcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkPQ3H2AANcjs.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 = _chunkQ2UYUWAZcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkQ2UYUWAZcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkQ2UYUWAZcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkQ2UYUWAZcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkPQ3H2AANcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkPQ3H2AANcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPQ3H2AANcjs.PaperGrain; exports.ParticleStroke = _chunkQ2UYUWAZcjs.ParticleStroke; exports.PenDabWalker = _chunkQ2UYUWAZcjs.PenDabWalker; exports.PenSmoother = _chunkQ2UYUWAZcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkQ2UYUWAZcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunkQ2UYUWAZcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkPQ3H2AANcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkVMROIWLLcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkQ2UYUWAZcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkVMROIWLLcjs.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 = _chunkQ2UYUWAZcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkPQ3H2AANcjs.addPaintGradientStop; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkQ2UYUWAZcjs.brushTakesPaint; exports.brushToJSON = _chunkQ2UYUWAZcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkQ2UYUWAZcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = _chunkQ2UYUWAZcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunkQ2UYUWAZcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkQ2UYUWAZcjs.effectPaintKey; exports.effectPaintSize = _chunkQ2UYUWAZcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPQ3H2AANcjs.grainCatch; exports.grainHeights = _chunkPQ3H2AANcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkPQ3H2AANcjs.hash2; exports.hexToPaintRgb = _chunkPQ3H2AANcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkQ2UYUWAZcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunk7PT4RJL5cjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isGradientPaint = _chunkPQ3H2AANcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkQ2UYUWAZcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkQ2UYUWAZcjs.isWetBrush; exports.isWetCapable = _chunkQ2UYUWAZcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkPQ3H2AANcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkQ2UYUWAZcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunkQ2UYUWAZcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkQ2UYUWAZcjs.normalizeBehavior; exports.normalizeBristle = _chunkQ2UYUWAZcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkQ2UYUWAZcjs.normalizeDynamics; exports.normalizeFlow = _chunkVMROIWLLcjs.normalizeFlow; exports.normalizeHexColor = _chunkPQ3H2AANcjs.normalizeHexColor; exports.normalizeImpasto = _chunkQ2UYUWAZcjs.normalizeImpasto; exports.normalizeLight = _chunkQ2UYUWAZcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkQ2UYUWAZcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkQ2UYUWAZcjs.normalizePaintBrush; exports.normalizePaper = _chunkQ2UYUWAZcjs.normalizePaper; exports.normalizeParticle = _chunkQ2UYUWAZcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkQ2UYUWAZcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunkQ2UYUWAZcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkQ2UYUWAZcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkVMROIWLLcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkPQ3H2AANcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkPQ3H2AANcjs.paintSourceColor; exports.paintSourceCss = _chunkPQ3H2AANcjs.paintSourceCss; exports.paintToMultiColor = _chunkQ2UYUWAZcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkQ2UYUWAZcjs.paperPreset; exports.parseBrushLibrary = _chunkQ2UYUWAZcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkPQ3H2AANcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkQ2UYUWAZcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkPQ3H2AANcjs.rand01; exports.randSigned = _chunkPQ3H2AANcjs.randSigned; exports.readEffectStrokeMap = _chunkQ2UYUWAZcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkQ2UYUWAZcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkPQ3H2AANcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkPQ3H2AANcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkQ2UYUWAZcjs.renderPaper; exports.renderStickers = _chunkQ2UYUWAZcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkPQ3H2AANcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkPQ3H2AANcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleEffectAt = _chunkQ2UYUWAZcjs.sampleEffectAt; exports.sampleEffectField = _chunkQ2UYUWAZcjs.sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkPQ3H2AANcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkPQ3H2AANcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkPQ3H2AANcjs.solidPaint; exports.stampCoverage = _chunkQ2UYUWAZcjs.stampCoverage; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = _chunkQ2UYUWAZcjs.stickerAt; exports.stickerRect = _chunkQ2UYUWAZcjs.stickerRect; exports.stickerSurface = _chunkQ2UYUWAZcjs.stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkQ2UYUWAZcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkQ2UYUWAZcjs.toStrokePoint; exports.toggleStamp = toggleStamp; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkPQ3H2AANcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkQ2UYUWAZcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkVMROIWLLcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunk7PT4RJL5cjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
11419
+
11420
+
11421
+
11422
+
11423
+
11424
+
11425
+
11426
+
11427
+
11428
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.BRUSH_ID = _chunk6G6ZDDDBcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunk6G6ZDDDBcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunk6G6ZDDDBcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunk6G6ZDDDBcjs.BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunk6G6ZDDDBcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunk6G6ZDDDBcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunk6G6ZDDDBcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunk6G6ZDDDBcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkVMROIWLLcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunk6G6ZDDDBcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunk6G6ZDDDBcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunk6G6ZDDDBcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunk6G6ZDDDBcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunk6G6ZDDDBcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunk6G6ZDDDBcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunk6G6ZDDDBcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkVMROIWLLcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunk6G6ZDDDBcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunk6G6ZDDDBcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunk6G6ZDDDBcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunk6G6ZDDDBcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunk6G6ZDDDBcjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPQ3H2AANcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPQ3H2AANcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunk7PT4RJL5cjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunk6G6ZDDDBcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunk6G6ZDDDBcjs.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 = _chunkPQ3H2AANcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; 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 = _chunk6G6ZDDDBcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunk6G6ZDDDBcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunk6G6ZDDDBcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkPQ3H2AANcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkPQ3H2AANcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkPQ3H2AANcjs.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 = _chunk6G6ZDDDBcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunk6G6ZDDDBcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunk6G6ZDDDBcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunk6G6ZDDDBcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkPQ3H2AANcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkPQ3H2AANcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPQ3H2AANcjs.PaperGrain; exports.ParticleStroke = _chunk6G6ZDDDBcjs.ParticleStroke; exports.PenDabWalker = _chunk6G6ZDDDBcjs.PenDabWalker; exports.PenSmoother = _chunk6G6ZDDDBcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunk6G6ZDDDBcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunk6G6ZDDDBcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunk6G6ZDDDBcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkPQ3H2AANcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkVMROIWLLcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunk6G6ZDDDBcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkVMROIWLLcjs.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 = _chunk6G6ZDDDBcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkPQ3H2AANcjs.addPaintGradientStop; exports.addPolygonArea = _chunk6G6ZDDDBcjs.addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunk6G6ZDDDBcjs.brushTakesPaint; exports.brushToJSON = _chunk6G6ZDDDBcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunk6G6ZDDDBcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = _chunk6G6ZDDDBcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunk6G6ZDDDBcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunk6G6ZDDDBcjs.effectPaintKey; exports.effectPaintSize = _chunk6G6ZDDDBcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPQ3H2AANcjs.grainCatch; exports.grainHeights = _chunkPQ3H2AANcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkPQ3H2AANcjs.hash2; exports.hexToPaintRgb = _chunkPQ3H2AANcjs.hexToPaintRgb; exports.hexToRgb8 = _chunk6G6ZDDDBcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunk7PT4RJL5cjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isGradientPaint = _chunkPQ3H2AANcjs.isGradientPaint; exports.isPaintEffectPaint = _chunk6G6ZDDDBcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunk6G6ZDDDBcjs.isWetBrush; exports.isWetCapable = _chunk6G6ZDDDBcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkPQ3H2AANcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunk6G6ZDDDBcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunk6G6ZDDDBcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunk6G6ZDDDBcjs.normalizeBehavior; exports.normalizeBristle = _chunk6G6ZDDDBcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunk6G6ZDDDBcjs.normalizeDynamics; exports.normalizeFlow = _chunkVMROIWLLcjs.normalizeFlow; exports.normalizeHexColor = _chunkPQ3H2AANcjs.normalizeHexColor; exports.normalizeImpasto = _chunk6G6ZDDDBcjs.normalizeImpasto; exports.normalizeLight = _chunk6G6ZDDDBcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunk6G6ZDDDBcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunk6G6ZDDDBcjs.normalizePaintBrush; exports.normalizePaper = _chunk6G6ZDDDBcjs.normalizePaper; exports.normalizeParticle = _chunk6G6ZDDDBcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunk6G6ZDDDBcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunk6G6ZDDDBcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunk6G6ZDDDBcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkVMROIWLLcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkPQ3H2AANcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkPQ3H2AANcjs.paintSourceColor; exports.paintSourceCss = _chunkPQ3H2AANcjs.paintSourceCss; exports.paintToMultiColor = _chunk6G6ZDDDBcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunk6G6ZDDDBcjs.paperPreset; exports.parseBrushLibrary = _chunk6G6ZDDDBcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkPQ3H2AANcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunk6G6ZDDDBcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkPQ3H2AANcjs.rand01; exports.randSigned = _chunkPQ3H2AANcjs.randSigned; exports.readEffectStrokeMap = _chunk6G6ZDDDBcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunk6G6ZDDDBcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkPQ3H2AANcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkPQ3H2AANcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunk6G6ZDDDBcjs.renderPaper; exports.renderStickers = _chunk6G6ZDDDBcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkPQ3H2AANcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkPQ3H2AANcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleEffectAt = _chunk6G6ZDDDBcjs.sampleEffectAt; exports.sampleEffectField = _chunk6G6ZDDDBcjs.sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkPQ3H2AANcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkPQ3H2AANcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkPQ3H2AANcjs.solidPaint; exports.stampCoverage = _chunk6G6ZDDDBcjs.stampCoverage; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = _chunk6G6ZDDDBcjs.stickerAt; exports.stickerRect = _chunk6G6ZDDDBcjs.stickerRect; exports.stickerSurface = _chunk6G6ZDDDBcjs.stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunk6G6ZDDDBcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunk6G6ZDDDBcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkPQ3H2AANcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunk6G6ZDDDBcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkVMROIWLLcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunk7PT4RJL5cjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;