@pixerate/editor 0.155.0 → 0.157.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 (73) hide show
  1. package/dist/agent/index.cjs +34 -34
  2. package/dist/agent/index.js +5 -5
  3. package/dist/animation-editor/index.cjs +58 -58
  4. package/dist/animation-editor/index.js +4 -4
  5. package/dist/{brushstrokeRender-YAZVQUXY.cjs → brushstrokeRender-5WANQIG4.cjs} +10 -10
  6. package/dist/{brushstrokeRender-EUDQTDYS.js → brushstrokeRender-Q4LI22QV.js} +3 -3
  7. package/dist/canvas/index.cjs +14 -14
  8. package/dist/canvas/index.js +3 -3
  9. package/dist/chart/index.cjs +90 -88
  10. package/dist/chart/index.js +9 -7
  11. package/dist/chart/spec.d.cts +2 -1
  12. package/dist/chart/spec.d.ts +2 -1
  13. package/dist/chart/types.d.cts +5 -0
  14. package/dist/chart/types.d.ts +5 -0
  15. package/dist/{chunk-AGZ47XY2.js → chunk-2N2QPO3H.js} +6 -2
  16. package/dist/{chunk-NMXPOKF3.js → chunk-45XXVHVG.js} +1 -1
  17. package/dist/{chunk-2WDZI6QD.cjs → chunk-4T44CJ5K.cjs} +15 -15
  18. package/dist/{chunk-XTU6QO2W.cjs → chunk-4YWAEV4W.cjs} +36 -27
  19. package/dist/{chunk-4YQKRHMI.cjs → chunk-57JLBGJ5.cjs} +8 -8
  20. package/dist/{chunk-SVINJIGK.js → chunk-5QBRAIVK.js} +3 -3
  21. package/dist/{chunk-R3PECGTQ.cjs → chunk-6LUYFHHN.cjs} +51 -51
  22. package/dist/{chunk-FLOGD3QB.js → chunk-6UPGM3JB.js} +2 -2
  23. package/dist/{chunk-6FUAHCVI.cjs → chunk-7NW46N7I.cjs} +16 -16
  24. package/dist/{chunk-ORDXMBD4.js → chunk-A5UCR2TO.js} +10 -3
  25. package/dist/{chunk-ML2II3Y3.cjs → chunk-AKDWAWSY.cjs} +58 -46
  26. package/dist/{chunk-PI45JMP7.cjs → chunk-CD7PLU77.cjs} +81 -81
  27. package/dist/{chunk-EQ4SF4X4.js → chunk-DBIVICAO.js} +1 -1
  28. package/dist/{chunk-LRRCMRSL.cjs → chunk-EBDCRTZI.cjs} +20 -16
  29. package/dist/{chunk-OLCYQLFE.js → chunk-EL5PAHNP.js} +1 -1
  30. package/dist/{chunk-PUC43JPT.cjs → chunk-EYVVIZJ3.cjs} +1 -1
  31. package/dist/{chunk-SUVZJ2CP.js → chunk-H5XX4KHB.js} +11 -1
  32. package/dist/{chunk-BXMIBMVG.cjs → chunk-JGKCC5OF.cjs} +65 -58
  33. package/dist/{chunk-LIXLD433.cjs → chunk-MHEXLG3M.cjs} +35 -35
  34. package/dist/{chunk-37RLSNQ3.js → chunk-Q6PA362P.js} +2 -2
  35. package/dist/{chunk-RHXW4TA5.cjs → chunk-QMI5HZWA.cjs} +7 -7
  36. package/dist/{chunk-DSZCDNTM.js → chunk-R3QY7PPL.js} +11 -2
  37. package/dist/{chunk-4RF2H3N3.js → chunk-SSCL7QQ4.js} +15 -3
  38. package/dist/{chunk-TLMRGLQQ.cjs → chunk-TVO6W2Q6.cjs} +20 -17
  39. package/dist/{chunk-EIUTJPEL.js → chunk-UM3RPYC5.js} +5 -2
  40. package/dist/{chunk-UILRJQFD.js → chunk-WNAAWLZ5.js} +1 -1
  41. package/dist/{chunk-I4AHLP7F.cjs → chunk-WPPJH6X4.cjs} +12 -2
  42. package/dist/{chunk-RZJCYJWO.cjs → chunk-XNQ5EFB4.cjs} +16 -16
  43. package/dist/{chunk-R6HNWN7B.js → chunk-YABNLNY7.js} +3 -3
  44. package/dist/{chunk-Y64YPIFT.js → chunk-ZQWLWDZI.js} +1 -1
  45. package/dist/export/index.cjs +4 -4
  46. package/dist/export/index.js +3 -3
  47. package/dist/extensions/index.cjs +7 -7
  48. package/dist/extensions/index.js +6 -6
  49. package/dist/image-editor/index.cjs +686 -686
  50. package/dist/image-editor/index.js +5 -5
  51. package/dist/index.cjs +13 -13
  52. package/dist/index.js +7 -7
  53. package/dist/paint/grain.d.cts +7 -0
  54. package/dist/paint/grain.d.ts +7 -0
  55. package/dist/paint/index.cjs +3 -3
  56. package/dist/paint/index.js +2 -2
  57. package/dist/paint-editor/controller.d.cts +30 -0
  58. package/dist/paint-editor/controller.d.ts +30 -0
  59. package/dist/paint-editor/document.d.cts +8 -0
  60. package/dist/paint-editor/document.d.ts +8 -0
  61. package/dist/paint-editor/index.cjs +403 -256
  62. package/dist/paint-editor/index.js +158 -11
  63. package/dist/paint-editor/paper.d.cts +8 -0
  64. package/dist/paint-editor/paper.d.ts +8 -0
  65. package/dist/paint-editor/stencils.d.cts +2 -0
  66. package/dist/paint-editor/stencils.d.ts +2 -0
  67. package/dist/paint-editor/wet.d.cts +1 -0
  68. package/dist/paint-editor/wet.d.ts +1 -0
  69. package/dist/vector/index.cjs +950 -950
  70. package/dist/vector/index.js +4 -4
  71. package/package.json +1 -1
  72. package/skills/pixerate-chart/SKILL.md +4 -1
  73. package/skills/pixerate-paint-editor/SKILL.md +9 -1
@@ -7,7 +7,7 @@ var _chunkVKF3PWKRcjs = require('../chunk-VKF3PWKR.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunkPI45JMP7cjs = require('../chunk-PI45JMP7.cjs');
10
+ var _chunkCD7PLU77cjs = require('../chunk-CD7PLU77.cjs');
11
11
  require('../chunk-A2IS7EHE.cjs');
12
12
 
13
13
 
@@ -54,7 +54,7 @@ var _chunkJLWLX52Lcjs = require('../chunk-JLWLX52L.cjs');
54
54
 
55
55
 
56
56
  var _chunkSWTUM32Hcjs = require('../chunk-SWTUM32H.cjs');
57
- require('../chunk-RHXW4TA5.cjs');
57
+ require('../chunk-QMI5HZWA.cjs');
58
58
 
59
59
 
60
60
 
@@ -119,7 +119,7 @@ require('../chunk-RHXW4TA5.cjs');
119
119
 
120
120
 
121
121
 
122
- var _chunkBXMIBMVGcjs = require('../chunk-BXMIBMVG.cjs');
122
+ var _chunkJGKCC5OFcjs = require('../chunk-JGKCC5OF.cjs');
123
123
  require('../chunk-CVFAAZXE.cjs');
124
124
  require('../chunk-GF2RBSDM.cjs');
125
125
  require('../chunk-NM3G4VQT.cjs');
@@ -189,7 +189,7 @@ require('../chunk-WOFXZ3XU.cjs');
189
189
 
190
190
 
191
191
 
192
- var _chunkLRRCMRSLcjs = require('../chunk-LRRCMRSL.cjs');
192
+ var _chunkEBDCRTZIcjs = require('../chunk-EBDCRTZI.cjs');
193
193
  require('../chunk-YQGCPL5X.cjs');
194
194
 
195
195
 
@@ -270,7 +270,7 @@ function normalizeCanvas(raw) {
270
270
  function createPaintDocument(options = {}) {
271
271
  const canvas = normalizeCanvas({ width: _nullishCoalesce(options.width, () => ( 2048)), height: _nullishCoalesce(options.height, () => ( 1536)), dpi: options.dpi });
272
272
  const layer = createPaintLayer("Layer 1");
273
- return { canvas, paper: _chunkBXMIBMVGcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
273
+ return { canvas, paper: _chunkJGKCC5OFcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
274
274
  }
275
275
 
276
276
  // src/paint-editor/dab-stroke.ts
@@ -314,7 +314,7 @@ function multiColorForDab(mc, palette, index, seed, mixing) {
314
314
  const n = palette.length;
315
315
  if (mc.order === "random") {
316
316
  const run = Math.floor(index / mc.length);
317
- return [...palette[Math.min(n - 1, Math.floor(_chunkLRRCMRSLcjs.rand01.call(void 0, seed, run, 11) * n))]];
317
+ return [...palette[Math.min(n - 1, Math.floor(_chunkEBDCRTZIcjs.rand01.call(void 0, seed, run, 11) * n))]];
318
318
  }
319
319
  const f = index / mc.length % n;
320
320
  const i = Math.floor(f);
@@ -324,24 +324,24 @@ var PaintDabStroke = (_class = class {
324
324
  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);
325
325
  this.brush = brush;
326
326
  this.options = options;
327
- this.smoother = new (0, _chunkBXMIBMVGcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
328
- this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunkBXMIBMVGcjs.IDENTITY_COPY];
327
+ this.smoother = new (0, _chunkJGKCC5OFcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
328
+ this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunkJGKCC5OFcjs.IDENTITY_COPY];
329
329
  const exchanging = brush.engine === "mixer" || brush.engine === "dab";
330
- const rates = brush.engine === "mixer" ? _chunkLRRCMRSLcjs.mixerRates.call(void 0, brush.mixer) : _chunkLRRCMRSLcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, 1, brush.behavior.mixing);
330
+ const rates = brush.engine === "mixer" ? _chunkEBDCRTZIcjs.mixerRates.call(void 0, brush.mixer) : _chunkEBDCRTZIcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, 1, brush.behavior.mixing);
331
331
  this.mixing = brush.engine === "mixer" ? brush.mixer.mixing : brush.behavior.mixing;
332
332
  this.states = this.copies.map((c, i) => ({
333
- walker: new (0, _chunkBXMIBMVGcjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
334
- exchange: exchanging ? new (0, _chunkLRRCMRSLcjs.PaintExchange)(rates, options.load) : null,
335
- smudge: brush.engine === "smudge" ? new (0, _chunkLRRCMRSLcjs.SmudgeTip)(brush.smudge, brush.tip.size * (1 + brush.dynamics.tiltSize * 1.5)) : null
333
+ walker: new (0, _chunkJGKCC5OFcjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
334
+ exchange: exchanging ? new (0, _chunkEBDCRTZIcjs.PaintExchange)(rates, options.load) : null,
335
+ smudge: brush.engine === "smudge" ? new (0, _chunkEBDCRTZIcjs.SmudgeTip)(brush.smudge, brush.tip.size * (1 + brush.dynamics.tiltSize * 1.5)) : null
336
336
  }));
337
- this.medium = new (0, _chunkLRRCMRSLcjs.TileMedium)(options.target, brush.engine === "dab" ? { blend: brush.tip.blend } : {});
337
+ this.medium = new (0, _chunkEBDCRTZIcjs.TileMedium)(options.target, brush.engine === "dab" ? { blend: brush.tip.blend } : {});
338
338
  this.depth = options.grain && !options.grain.flat ? Math.min(1, Math.max(0, options.paperDepth * brush.grain)) : 0;
339
- this.coverage = brush.engine === "dab" ? new (0, _chunkLRRCMRSLcjs.CoverageMap)() : null;
340
- this.sampler = exchanging && options.paint ? new (0, _chunkLRRCMRSLcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
339
+ this.coverage = brush.engine === "dab" ? new (0, _chunkEBDCRTZIcjs.CoverageMap)() : null;
340
+ this.sampler = exchanging && options.paint ? new (0, _chunkEBDCRTZIcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
341
341
  const table = _optionalChain([this, 'access', _4 => _4.sampler, 'optionalAccess', _5 => _5.acrossTip]) ? this.sampler.tipTable(GRADIENT_STEPS) : null;
342
342
  this.gradient = table ? table.map((e) => e.rgb) : null;
343
343
  this.gradientAlpha = table && table.some((e) => e.alpha < 1) ? table.map((e) => e.alpha) : null;
344
- this.scratch = brush.engine === "blender" ? _chunkLRRCMRSLcjs.createBlenderScratch.call(void 0, ) : null;
344
+ this.scratch = brush.engine === "blender" ? _chunkEBDCRTZIcjs.createBlenderScratch.call(void 0, ) : null;
345
345
  }
346
346
 
347
347
 
@@ -400,7 +400,7 @@ var PaintDabStroke = (_class = class {
400
400
  }
401
401
  paintDabs(copy, dabs, rects) {
402
402
  for (const d of dabs) {
403
- const rect = _chunkLRRCMRSLcjs.dabRect.call(void 0, d, this.brush.tip.hardness);
403
+ const rect = _chunkEBDCRTZIcjs.dabRect.call(void 0, d, this.brush.tip.hardness);
404
404
  if (rect.width <= 0 || rect.height <= 0) continue;
405
405
  this.dab(copy, d, rect);
406
406
  rects.push(rect);
@@ -416,13 +416,13 @@ var PaintDabStroke = (_class = class {
416
416
  }
417
417
  const tip = this.tip.subarray(0, n);
418
418
  tip.fill(0);
419
- _chunkLRRCMRSLcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.tip.hardness, rect, tip);
419
+ _chunkEBDCRTZIcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.tip.hardness, rect, tip);
420
420
  if (!(this.depth > 0 && this.options.grain)) return { tip, cov: tip };
421
421
  const cov = this.cov.subarray(0, n);
422
422
  const grain = this.options.grain;
423
423
  for (let yy = 0, k = 0; yy < rect.height; yy++) {
424
424
  const y = rect.y + yy + 0.5;
425
- for (let xx = 0; xx < rect.width; xx++, k++) cov[k] = tip[k] > 0 ? tip[k] * _chunkLRRCMRSLcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, y), this.depth, d.pressure) : 0;
425
+ for (let xx = 0; xx < rect.width; xx++, k++) cov[k] = tip[k] > 0 ? tip[k] * _chunkEBDCRTZIcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, y), this.depth, d.pressure) : 0;
426
426
  }
427
427
  return { tip, cov };
428
428
  }
@@ -431,7 +431,7 @@ var PaintDabStroke = (_class = class {
431
431
  const { tip, cov } = this.rasterize(d, rect);
432
432
  const st = this.states[copy];
433
433
  if (brush.engine === "blender") {
434
- _chunkLRRCMRSLcjs.blenderDab.call(void 0, this.medium, rect, cov, d.opacity * d.alpha * brush.tip.opacity, d.radius, brush.blender, this.scratch);
434
+ _chunkEBDCRTZIcjs.blenderDab.call(void 0, this.medium, rect, cov, d.opacity * d.alpha * brush.tip.opacity, d.radius, brush.blender, this.scratch);
435
435
  return;
436
436
  }
437
437
  if (brush.engine === "smudge") {
@@ -670,19 +670,19 @@ var ThickStrokeDriver = (_class3 = class {
670
670
  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);
671
671
  this.init = init;
672
672
  const b = init.brush;
673
- this.smoother = new (0, _chunkBXMIBMVGcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
674
- const copies = init.copies.length ? init.copies : [_chunkBXMIBMVGcjs.IDENTITY_COPY];
673
+ this.smoother = new (0, _chunkJGKCC5OFcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
674
+ const copies = init.copies.length ? init.copies : [_chunkJGKCC5OFcjs.IDENTITY_COPY];
675
675
  this.copies = copies;
676
- const rates = _chunkLRRCMRSLcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
676
+ const rates = _chunkEBDCRTZIcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
677
677
  this.states = copies.map((c, i) => ({
678
- walker: new (0, _chunkBXMIBMVGcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
679
- exchange: new (0, _chunkLRRCMRSLcjs.PaintExchange)(rates, init.load),
680
- smudge: b.impasto.tool === "knife" ? new (0, _chunkLRRCMRSLcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
678
+ walker: new (0, _chunkJGKCC5OFcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
679
+ exchange: new (0, _chunkEBDCRTZIcjs.PaintExchange)(rates, init.load),
680
+ smudge: b.impasto.tool === "knife" ? new (0, _chunkEBDCRTZIcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
681
681
  carried: null,
682
682
  amount: 1
683
683
  }));
684
- this.medium = new (0, _chunkLRRCMRSLcjs.TileMedium)(init.target, {});
685
- this.sampler = init.paint ? new (0, _chunkLRRCMRSLcjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
684
+ this.medium = new (0, _chunkEBDCRTZIcjs.TileMedium)(init.target, {});
685
+ this.sampler = init.paint ? new (0, _chunkEBDCRTZIcjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
686
686
  }
687
687
 
688
688
  __init12() {this.dabCount = 0}
@@ -778,7 +778,7 @@ var ThickStrokeDriver = (_class3 = class {
778
778
  }
779
779
  applyDabs(copy, dabs, rects) {
780
780
  for (const d of dabs) {
781
- const rect = _chunkLRRCMRSLcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
781
+ const rect = _chunkEBDCRTZIcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
782
782
  if (rect.width <= 0 || rect.height <= 0) continue;
783
783
  this.dab(copy, d, rect);
784
784
  rects.push(rect);
@@ -793,7 +793,7 @@ var ThickStrokeDriver = (_class3 = class {
793
793
  const n = rect.width * rect.height;
794
794
  if (this.tip.length < n) this.tip = new Float32Array(n);
795
795
  const tip = this.tip.subarray(0, n);
796
- _chunkLRRCMRSLcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
796
+ _chunkEBDCRTZIcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
797
797
  const sel = this.init.target.selection;
798
798
  if (sel) {
799
799
  for (let yy = 0, p = 0; yy < rect.height; yy++)
@@ -847,7 +847,7 @@ var ThickStrokeDriver = (_class3 = class {
847
847
  const full = 255 * thick * k;
848
848
  switch (im.tool) {
849
849
  case "brush": {
850
- const ridge = 0.6 + 0.4 * Math.sin(u * 9 + _chunkLRRCMRSLcjs.hash2.call(void 0, Math.round(u * 6), 3, seed) * 6.28) + 0.15 * (_chunkLRRCMRSLcjs.hash2.call(void 0, lx, ly, seed) - 0.5);
850
+ const ridge = 0.6 + 0.4 * Math.sin(u * 9 + _chunkEBDCRTZIcjs.hash2.call(void 0, Math.round(u * 6), 3, seed) * 6.28) + 0.15 * (_chunkEBDCRTZIcjs.hash2.call(void 0, lx, ly, seed) - 0.5);
851
851
  const target = full * c * ridge;
852
852
  h = Math.max(h0 * (1 - 0.25 * c * im.drag), Math.min(255, h0 * 0.35 + target));
853
853
  break;
@@ -863,7 +863,7 @@ var ThickStrokeDriver = (_class3 = class {
863
863
  break;
864
864
  }
865
865
  case "roller": {
866
- const stipple = 0.75 + 0.5 * _chunkLRRCMRSLcjs.hash2.call(void 0, lx >> 1, ly >> 1, seed);
866
+ const stipple = 0.75 + 0.5 * _chunkEBDCRTZIcjs.hash2.call(void 0, lx >> 1, ly >> 1, seed);
867
867
  h = h0 + (Math.min(255, full * 0.6 * stipple) - h0) * Math.min(1, c * 1.5);
868
868
  break;
869
869
  }
@@ -973,7 +973,7 @@ var PaintStrokeSession = (_class4 = class {
973
973
  this.layerId = init.layerId;
974
974
  this.base = init.surface;
975
975
  this.live = new Map(this.base.tiles);
976
- this.copies = init.copies.length ? init.copies : [_chunkBXMIBMVGcjs.IDENTITY_COPY];
976
+ this.copies = init.copies.length ? init.copies : [_chunkJGKCC5OFcjs.IDENTITY_COPY];
977
977
  const brush = init.brush;
978
978
  if (init.wet) this.wetDriver = init.wet.driver;
979
979
  this.apply = {
@@ -988,11 +988,11 @@ var PaintStrokeSession = (_class4 = class {
988
988
  };
989
989
  if (this.wetDriver) {
990
990
  } else if (init.sticker) {
991
- this.stickerSpray = new (0, _chunkBXMIBMVGcjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)) });
991
+ this.stickerSpray = new (0, _chunkJGKCC5OFcjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)) });
992
992
  } else if (init.thick) {
993
993
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
994
994
  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)) });
995
- } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkBXMIBMVGcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
995
+ } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkJGKCC5OFcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
996
996
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
997
997
  this.wet = new PaintDabStroke(brush, {
998
998
  target: this.tileTarget(),
@@ -1007,7 +1007,7 @@ var PaintStrokeSession = (_class4 = class {
1007
1007
  });
1008
1008
  } else {
1009
1009
  const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)) };
1010
- this.dry = brush.engine === "particle" ? new (0, _chunkBXMIBMVGcjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunkBXMIBMVGcjs.BristleStroke)(brush, opts) : new (0, _chunkBXMIBMVGcjs.DryStroke)(brush, opts);
1010
+ this.dry = brush.engine === "particle" ? new (0, _chunkJGKCC5OFcjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunkJGKCC5OFcjs.BristleStroke)(brush, opts) : new (0, _chunkJGKCC5OFcjs.DryStroke)(brush, opts);
1011
1011
  }
1012
1012
  }
1013
1013
 
@@ -1097,7 +1097,7 @@ var PaintStrokeSession = (_class4 = class {
1097
1097
  const changed = d.dabCount > 0;
1098
1098
  this.result = { layerId: this.layerId, bounds: changed ? d.bounds : null, dabs: d.dabCount, strokeId: null, wet: true };
1099
1099
  const carried = d.load;
1100
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkLRRCMRSLcjs.cleanMixer.call(void 0, carried);
1100
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkEBDCRTZIcjs.cleanMixer.call(void 0, carried);
1101
1101
  this.host.commit(this, changed ? this.init.wet.surface() : null, false);
1102
1102
  }
1103
1103
  update(rects) {
@@ -1123,7 +1123,7 @@ var PaintStrokeSession = (_class4 = class {
1123
1123
  const src = _nullishCoalesce(_optionalChain([this, 'access', _27 => _27.base, 'access', _28 => _28.tiles, 'access', _29 => _29.get, 'call', _30 => _30(key), 'optionalAccess', _31 => _31.data]), () => ( defaultTile(this.base)));
1124
1124
  const prev = this.touched.has(key) ? _optionalChain([this, 'access', _32 => _32.live, 'access', _33 => _33.get, 'call', _34 => _34(key), 'optionalAccess', _35 => _35.data]) : void 0;
1125
1125
  this.touched.add(key);
1126
- const data = _chunkLRRCMRSLcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
1126
+ const data = _chunkEBDCRTZIcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
1127
1127
  this.live.set(key, { data, uniform: null });
1128
1128
  }
1129
1129
  this.host.update(this.layerId, new (0, _chunkCWM3CUUXcjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
@@ -1158,7 +1158,7 @@ var PaintStrokeSession = (_class4 = class {
1158
1158
  const dabs = this.dry ? this.dry.dabCount : this.thickDriver ? this.thickDriver.dabCount : this.stickerSpray ? this.stickerSpray.dabCount : this.wet.dabCount;
1159
1159
  this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };
1160
1160
  const carried = _nullishCoalesce(_optionalChain([this, 'access', _36 => _36.wet, 'optionalAccess', _37 => _37.load]), () => ( _optionalChain([this, 'access', _38 => _38.thickDriver, 'optionalAccess', _39 => _39.load])));
1161
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkLRRCMRSLcjs.cleanMixer.call(void 0, carried);
1161
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkEBDCRTZIcjs.cleanMixer.call(void 0, carried);
1162
1162
  this.host.commit(this, surface, false);
1163
1163
  return this.result;
1164
1164
  }
@@ -1171,15 +1171,15 @@ var PaintStrokeSession = (_class4 = class {
1171
1171
  }, _class4);
1172
1172
  function mixerLoadForStroke(brush, current, color) {
1173
1173
  if (!brush.loadsColor) return { reservoir: null, amount: 0, pickup: brush.mixer.cleanEachStroke ? null : current.pickup };
1174
- if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkLRRCMRSLcjs.loadMixer.call(void 0, current, color);
1174
+ if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkEBDCRTZIcjs.loadMixer.call(void 0, current, color);
1175
1175
  return current;
1176
1176
  }
1177
1177
  function brushLoadForStroke(brush, current, color) {
1178
1178
  if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
1179
1179
  if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1180
- 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 } : _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD;
1181
- if (_chunkBXMIBMVGcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1182
- return _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD;
1180
+ 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 } : _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD;
1181
+ if (_chunkJGKCC5OFcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1182
+ return _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD;
1183
1183
  }
1184
1184
 
1185
1185
  // src/paint-editor/stencils.ts
@@ -1357,6 +1357,17 @@ function stencilMask(stencils, width, height) {
1357
1357
  }
1358
1358
  return { width, height, data };
1359
1359
  }
1360
+ function translateStencil(s, dx, dy) {
1361
+ const p = (q) => q ? { x: q.x + dx, y: q.y + dy } : void 0;
1362
+ return {
1363
+ ...s,
1364
+ ...s.from ? { from: p(s.from) } : {},
1365
+ ...s.to ? { to: p(s.to) } : {},
1366
+ ...s.center ? { center: p(s.center) } : {},
1367
+ ...s.rect ? { rect: { ...s.rect, x: s.rect.x + dx, y: s.rect.y + dy } } : {},
1368
+ ...s.points ? { points: s.points.map((q) => p(q)) } : {}
1369
+ };
1370
+ }
1360
1371
  function scaleStencil(s, k) {
1361
1372
  const p = (q) => q ? { x: q.x * k, y: q.y * k } : void 0;
1362
1373
  return {
@@ -1435,7 +1446,7 @@ function normalizeBrushStroke(raw) {
1435
1446
  const out = {
1436
1447
  id: r.id,
1437
1448
  layerId: r.layerId,
1438
- brush: _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
1449
+ brush: _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
1439
1450
  color: typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : "#000000",
1440
1451
  points,
1441
1452
  seed: finite2(r.seed) ? r.seed | 0 : 0
@@ -1454,7 +1465,7 @@ function normalizeBrushStroke(raw) {
1454
1465
  }
1455
1466
  if (st.length) out.stencils = st;
1456
1467
  }
1457
- const paint = _chunkLRRCMRSLcjs.readPaintSource.call(void 0, r.paint);
1468
+ const paint = _chunkEBDCRTZIcjs.readPaintSource.call(void 0, r.paint);
1458
1469
  if (paint && paint.type === "gradient") out.paint = paint;
1459
1470
  if (Array.isArray(r.steps) && r.steps.length === points.length && r.steps.every((v) => Number.isInteger(v) && v >= 0)) out.steps = [...r.steps];
1460
1471
  return out;
@@ -1491,9 +1502,9 @@ function varyStroke(stroke, m, v) {
1491
1502
  if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
1492
1503
  return q;
1493
1504
  });
1494
- const brush = s !== 1 ? _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
1505
+ const brush = s !== 1 ? _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
1495
1506
  const out = { ...stroke, brush, points };
1496
- if (stroke.paint && s !== 1) out.paint = _chunkLRRCMRSLcjs.scalePaintGradient.call(void 0, stroke.paint, s);
1507
+ if (stroke.paint && s !== 1) out.paint = _chunkEBDCRTZIcjs.scalePaintGradient.call(void 0, stroke.paint, s);
1497
1508
  if (_optionalChain([stroke, 'access', _57 => _57.copies, 'optionalAccess', _58 => _58.length])) {
1498
1509
  const inv = invertAffine(m);
1499
1510
  out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));
@@ -1507,7 +1518,7 @@ var TRACING_NODE_ID = "__tracing";
1507
1518
  var PAPER_EFFECT_NODE_ID = "__paper_effect";
1508
1519
  function paperKey(p, light) {
1509
1520
  const metal = _nullishCoalesce(p.metallic, () => ( 0));
1510
- return JSON.stringify([p.pattern, p.seed, p.color, p.scale, p.tiling, p.shading, p.dry, metal, metal > 0 && light ? [light.azimuth, light.elevation] : null]);
1521
+ return JSON.stringify([p.pattern, p.seed, p.color, p.scale, p.tiling, p.shading, p.dry, _nullishCoalesce(p.offset, () => ( null)), metal, metal > 0 && light ? [light.azimuth, light.elevation] : null]);
1511
1522
  }
1512
1523
  var paperNodes = /* @__PURE__ */ new WeakMap();
1513
1524
  function paperNode(paper, light) {
@@ -1522,10 +1533,10 @@ function paperNode(paper, light) {
1522
1533
  var grainCache = /* @__PURE__ */ new Map();
1523
1534
  var tileCache = /* @__PURE__ */ new Map();
1524
1535
  function paperGrain(paper) {
1525
- const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry]);
1536
+ const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry, _nullishCoalesce(paper.offset, () => ( null))]);
1526
1537
  let g = grainCache.get(key);
1527
1538
  if (!g) {
1528
- g = new (0, _chunkLRRCMRSLcjs.PaperGrain)(paper, "dry");
1539
+ g = new (0, _chunkEBDCRTZIcjs.PaperGrain)(paper, "dry");
1529
1540
  if (grainCache.size > 16) grainCache.delete(grainCache.keys().next().value);
1530
1541
  grainCache.set(key, g);
1531
1542
  }
@@ -1535,7 +1546,7 @@ function paperTile(paper, r, light) {
1535
1546
  const key = `${paperKey(paper, light)}|${r.x},${r.y},${r.width},${r.height}`;
1536
1547
  let t = tileCache.get(key);
1537
1548
  if (!t) {
1538
- t = _chunkBXMIBMVGcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
1549
+ t = _chunkJGKCC5OFcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
1539
1550
  if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value);
1540
1551
  tileCache.set(key, t);
1541
1552
  }
@@ -1612,7 +1623,7 @@ function downsampleRgba(data, width, height, tw, th) {
1612
1623
  // src/paint-editor/serialize.ts
1613
1624
  var PAINT_FORMAT = "pixerate-paint";
1614
1625
  var PAINT_SCHEMA_VERSION = 1;
1615
- var KNOWN = /* @__PURE__ */ new Set(["format", "version", "width", "height", "dpi", "paper", "layers", "assets", "activeLayerId", "strokes", "guides", "swatches", "mixingPad", "wet", "wetEvents", "paintEvents"]);
1626
+ var KNOWN = /* @__PURE__ */ new Set(["format", "version", "width", "height", "dpi", "paper", "layers", "assets", "activeLayerId", "strokes", "guides", "swatches", "mixingPad", "wet", "wetEvents", "paintEvents", "origin"]);
1616
1627
  function documentExtensions(raw) {
1617
1628
  const out = {};
1618
1629
  for (const [k, v] of Object.entries(raw)) if (!KNOWN.has(k)) out[k] = v;
@@ -1636,14 +1647,15 @@ function header(state, options) {
1636
1647
  if (options.wet !== void 0) out.wet = JSON.parse(JSON.stringify(options.wet));
1637
1648
  if (_optionalChain([state, 'access', _65 => _65.wetEvents, 'optionalAccess', _66 => _66.length])) out.wetEvents = JSON.parse(JSON.stringify(state.wetEvents));
1638
1649
  if (_optionalChain([state, 'access', _67 => _67.paintEvents, 'optionalAccess', _68 => _68.length])) out.paintEvents = JSON.parse(JSON.stringify(state.paintEvents));
1650
+ if (state.origin && (state.origin.x || state.origin.y)) out.origin = { ...state.origin };
1639
1651
  return out;
1640
1652
  }
1641
1653
  function serializePaintDocument(state, options = {}) {
1642
- const { layers, assets } = _chunkPI45JMP7cjs.serializeLayers.call(void 0, state.layers);
1654
+ const { layers, assets } = _chunkCD7PLU77cjs.serializeLayers.call(void 0, state.layers);
1643
1655
  return { ...header(state, options), layers, assets };
1644
1656
  }
1645
1657
  async function serializePaintDocumentExternal(state, store, options = {}) {
1646
- const { layers, assets } = await _chunkPI45JMP7cjs.serializeLayersExternal.call(void 0, state.layers, store);
1658
+ const { layers, assets } = await _chunkCD7PLU77cjs.serializeLayersExternal.call(void 0, state.layers, store);
1647
1659
  return { ...header(state, options), layers, assets };
1648
1660
  }
1649
1661
  function paintLayersOnly(layers, problems) {
@@ -1678,9 +1690,9 @@ function deserializePaintDocument(raw) {
1678
1690
  }
1679
1691
  const problems = [];
1680
1692
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
1681
- const paper = _chunkBXMIBMVGcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
1693
+ const paper = _chunkJGKCC5OFcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
1682
1694
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
1683
- const layers = paintLayersOnly(_chunkPI45JMP7cjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1695
+ const layers = paintLayersOnly(_chunkCD7PLU77cjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1684
1696
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
1685
1697
  const activeLayerId = wanted && _chunkHGTDMKNEcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers), 'access', _70 => _70.filter, 'call', _71 => _71((l) => l.type === "pixel"), 'access', _72 => _72.pop, 'call', _73 => _73(), 'optionalAccess', _74 => _74.id]), () => ( null));
1686
1698
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
@@ -1688,13 +1700,15 @@ function deserializePaintDocument(raw) {
1688
1700
  if (wetEvents.length) state.wetEvents = wetEvents;
1689
1701
  const paintEvents = Array.isArray(r.paintEvents) ? r.paintEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.at) && typeof e.layerId === "string" && ["fill", "clear", "flatten", "stickers"].includes(e.kind)) : [];
1690
1702
  if (paintEvents.length) state.paintEvents = paintEvents;
1703
+ const o = r.origin;
1704
+ if (o && typeof o === "object" && Number.isFinite(o.x) && Number.isFinite(o.y) && (o.x || o.y)) state.origin = { x: Math.round(o.x), y: Math.round(o.y) };
1691
1705
  return { state, extensions: documentExtensions(r), guides: r.guides, swatches: r.swatches, mixingPad: r.mixingPad, wet: r.wet, problems };
1692
1706
  }
1693
1707
  async function deserializePaintDocumentAsync(raw, store) {
1694
1708
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
1695
1709
  const r = raw;
1696
1710
  const problems = [];
1697
- const assets = await _chunkPI45JMP7cjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1711
+ const assets = await _chunkCD7PLU77cjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1698
1712
  const loaded = deserializePaintDocument({ ...r, assets });
1699
1713
  return { ...loaded, problems: [...problems, ...loaded.problems] };
1700
1714
  }
@@ -1777,7 +1791,7 @@ function pointerToPenPoint(e, x, y, view) {
1777
1791
  const p = { x, y, pressure: samplePressure(e) };
1778
1792
  if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;
1779
1793
  if (e.pointerType !== "pen") return p;
1780
- const o = _chunkBXMIBMVGcjs.penOrientation.call(void 0, {
1794
+ const o = _chunkJGKCC5OFcjs.penOrientation.call(void 0, {
1781
1795
  x,
1782
1796
  y,
1783
1797
  altitude: typeof e.altitudeAngle === "number" ? e.altitudeAngle : void 0,
@@ -1850,13 +1864,13 @@ function union2(a, b) {
1850
1864
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
1851
1865
  }
1852
1866
  function wetPaperInput(paper) {
1853
- const grain = new (0, _chunkLRRCMRSLcjs.PaperGrain)(paper, "wet");
1867
+ const grain = new (0, _chunkEBDCRTZIcjs.PaperGrain)(paper, "wet");
1854
1868
  const flat = grain.flat;
1855
1869
  return {
1856
1870
  absorption: paper.absorption,
1857
1871
  permeability: paper.permeability,
1858
1872
  roughness: flat ? 0 : paper.roughness,
1859
- color: _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, paper.color),
1873
+ color: _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, paper.color),
1860
1874
  heightAt: flat ? () => 0.5 : (x, y) => grain.at(x, y)
1861
1875
  };
1862
1876
  }
@@ -1864,8 +1878,8 @@ var WetStrokeDriver = (_class5 = class {
1864
1878
  constructor(init) {;_class5.prototype.__init35.call(this);_class5.prototype.__init36.call(this);_class5.prototype.__init37.call(this);_class5.prototype.__init38.call(this);_class5.prototype.__init39.call(this);_class5.prototype.__init40.call(this);_class5.prototype.__init41.call(this);_class5.prototype.__init42.call(this);_class5.prototype.__init43.call(this);_class5.prototype.__init44.call(this);_class5.prototype.__init45.call(this);_class5.prototype.__init46.call(this);
1865
1879
  this.init = init;
1866
1880
  const brush = init.brush;
1867
- this.smoother = new (0, _chunkBXMIBMVGcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
1868
- const copies = init.copies.length ? init.copies : [_chunkBXMIBMVGcjs.IDENTITY_COPY];
1881
+ this.smoother = new (0, _chunkJGKCC5OFcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
1882
+ const copies = init.copies.length ? init.copies : [_chunkJGKCC5OFcjs.IDENTITY_COPY];
1869
1883
  const wet = brush.wet;
1870
1884
  const spacing = Math.max(0.02, brush.tip.spacing);
1871
1885
  const perDab = Math.min(1, spacing * 1.2);
@@ -1875,16 +1889,16 @@ var WetStrokeDriver = (_class5 = class {
1875
1889
  mass: STROKE_MASS * wet.pigment * (1 - 0.6 * thin) * perDab,
1876
1890
  body: wet.body * (1 - thin)
1877
1891
  });
1878
- const rates = _chunkLRRCMRSLcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
1892
+ const rates = _chunkEBDCRTZIcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
1879
1893
  this.states = copies.map((c, i) => ({
1880
- walker: new (0, _chunkBXMIBMVGcjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
1881
- exchange: wet.tool === "paint" ? new (0, _chunkLRRCMRSLcjs.PaintExchange)(rates, init.load) : null,
1894
+ walker: new (0, _chunkJGKCC5OFcjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
1895
+ exchange: wet.tool === "paint" ? new (0, _chunkEBDCRTZIcjs.PaintExchange)(rates, init.load) : null,
1882
1896
  last: null
1883
1897
  }));
1884
1898
  this.copies = copies;
1885
1899
  this.depth = init.grain && !init.grain.flat ? Math.min(1, Math.max(0, init.paperDepth * brush.grain)) : 0;
1886
1900
  const g = _nullishCoalesce(init.paint, () => ( null));
1887
- this.sampler = g ? new (0, _chunkLRRCMRSLcjs.PaintGradientSampler)(g.map.by === "across-tip" ? { ...g, map: { by: "distance", length: 300, repeat: "mirror" } } : g, init.seed) : null;
1901
+ this.sampler = g ? new (0, _chunkEBDCRTZIcjs.PaintGradientSampler)(g.map.by === "across-tip" ? { ...g, map: { by: "distance", length: 300, repeat: "mirror" } } : g, init.seed) : null;
1888
1902
  }
1889
1903
 
1890
1904
  __init35() {this.dabCount = 0}
@@ -1956,7 +1970,7 @@ var WetStrokeDriver = (_class5 = class {
1956
1970
  }
1957
1971
  applyDabs(copy, dabs, rects) {
1958
1972
  for (const d of dabs) {
1959
- const rect = _chunkLRRCMRSLcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
1973
+ const rect = _chunkEBDCRTZIcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
1960
1974
  if (rect.width <= 0 || rect.height <= 0) continue;
1961
1975
  this.dab(copy, d, rect);
1962
1976
  rects.push(rect);
@@ -1973,7 +1987,7 @@ var WetStrokeDriver = (_class5 = class {
1973
1987
  const tip = this.tip.subarray(0, n);
1974
1988
  const cov = this.cov.subarray(0, n);
1975
1989
  tip.fill(0);
1976
- _chunkLRRCMRSLcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.init.brush.tip.hardness, rect, tip);
1990
+ _chunkEBDCRTZIcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.init.brush.tip.hardness, rect, tip);
1977
1991
  const grain = this.depth > 0 ? this.init.grain : null;
1978
1992
  const mask = this.init.mask;
1979
1993
  for (let yy = 0, k = 0; yy < rect.height; yy++) {
@@ -1984,7 +1998,7 @@ var WetStrokeDriver = (_class5 = class {
1984
1998
  tip[k] *= mx >= 0 && my >= 0 && mx < mask.width && my < mask.height ? mask.data[my * mask.width + mx] / 255 : 0;
1985
1999
  }
1986
2000
  let v = tip[k];
1987
- if (v > 0 && grain) v *= _chunkLRRCMRSLcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, d.pressure);
2001
+ if (v > 0 && grain) v *= _chunkEBDCRTZIcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, d.pressure);
1988
2002
  tip[k] = Math.round(tip[k] * COVERAGE_STEPS) / COVERAGE_STEPS;
1989
2003
  cov[k] = Math.round(v * COVERAGE_STEPS) / COVERAGE_STEPS;
1990
2004
  }
@@ -2138,7 +2152,10 @@ var PaintWetLayers = (_class6 = class {
2138
2152
  /** The world (made on first use, at the canvas size). */
2139
2153
  ensureWorld() {
2140
2154
  const { width, height } = this.host.canvas();
2141
- if (this.world && (this.world.width !== width || this.world.height !== height)) throw new Error("The wet world is the wrong size; dry the paint before resizing the canvas.");
2155
+ if (this.world && (this.world.width !== width || this.world.height !== height)) {
2156
+ if (this.world.laneIds().length) throw new Error("The wet world is the wrong size; dry the paint before resizing the canvas.");
2157
+ this.dropWorld();
2158
+ }
2142
2159
  if (!this.world) {
2143
2160
  this.world = new (0, _chunkGNK7SESQcjs.WetWorld)(width, height, wetPaperInput(this.host.paper()), { kernel: this.options.kernel, threads: this.options.threads });
2144
2161
  this.world.setTilt(this.tilt);
@@ -2401,12 +2418,19 @@ var PaintWetLayers = (_class6 = class {
2401
2418
  if (this.world) for (const id of this.world.laneIds()) this.world.removeLane(id);
2402
2419
  return;
2403
2420
  }
2421
+ const { width, height } = this.host.canvas();
2422
+ if (this.world && (this.world.width !== width || this.world.height !== height)) this.dropWorld();
2404
2423
  this.ensureWorld().restore(snap);
2405
2424
  this.syncDisplays();
2406
2425
  }
2426
+ dropWorld() {
2427
+ _optionalChain([this, 'access', _128 => _128.world, 'optionalAccess', _129 => _129.destroy, 'call', _130 => _130()]);
2428
+ this.world = null;
2429
+ this.driver = null;
2430
+ }
2407
2431
  /** Forgets everything wet (a new canvas, a resize, opening a document). */
2408
2432
  reset() {
2409
- _optionalChain([this, 'access', _128 => _128.world, 'optionalAccess', _129 => _129.destroy, 'call', _130 => _130()]);
2433
+ _optionalChain([this, 'access', _131 => _131.world, 'optionalAccess', _132 => _132.destroy, 'call', _133 => _133()]);
2410
2434
  this.world = null;
2411
2435
  this.driver = null;
2412
2436
  this.settings.clear();
@@ -2436,14 +2460,14 @@ var PaintWetLayers = (_class6 = class {
2436
2460
  return out;
2437
2461
  }
2438
2462
  destroy() {
2439
- _optionalChain([this, 'access', _131 => _131.world, 'optionalAccess', _132 => _132.destroy, 'call', _133 => _133()]);
2463
+ _optionalChain([this, 'access', _134 => _134.world, 'optionalAccess', _135 => _135.destroy, 'call', _136 => _136()]);
2440
2464
  this.world = null;
2441
- _optionalChain([this, 'access', _134 => _134.gpu, 'optionalAccess', _135 => _135.destroy, 'call', _136 => _136()]);
2465
+ _optionalChain([this, 'access', _137 => _137.gpu, 'optionalAccess', _138 => _138.destroy, 'call', _139 => _139()]);
2442
2466
  this.gpu = null;
2443
2467
  }
2444
2468
  }, _class6);
2445
2469
  function wetPigmentOf(hex, body) {
2446
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, hex);
2470
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, hex);
2447
2471
  return Array.from(_chunkGNK7SESQcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
2448
2472
  }
2449
2473
 
@@ -2451,13 +2475,13 @@ function wetPigmentOf(hex, body) {
2451
2475
  var thumbWorld = null;
2452
2476
  function paintWetTestStroke(brush, paper, color, width, height) {
2453
2477
  if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
2454
- _optionalChain([thumbWorld, 'optionalAccess', _137 => _137.destroy, 'call', _138 => _138()]);
2478
+ _optionalChain([thumbWorld, 'optionalAccess', _140 => _140.destroy, 'call', _141 => _141()]);
2455
2479
  thumbWorld = new (0, _chunkGNK7SESQcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
2456
2480
  } else thumbWorld.setPaper(wetPaperInput(paper));
2457
2481
  const w = thumbWorld;
2458
2482
  if (w.hasLane("thumb")) w.removeLane("thumb");
2459
2483
  w.ensureLane("thumb");
2460
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, color);
2484
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, color);
2461
2485
  if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
2462
2486
  const half = Math.ceil(height / 2);
2463
2487
  w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkGNK7SESQcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
@@ -2468,12 +2492,12 @@ function paintWetTestStroke(brush, paper, color, width, height) {
2468
2492
  laneId: "thumb",
2469
2493
  brush,
2470
2494
  color: [r / 255, g / 255, b / 255],
2471
- load: brushLoadForStroke(brush, _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2495
+ load: brushLoadForStroke(brush, _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2472
2496
  grain: paperGrain(paper),
2473
2497
  paperDepth: paper.depth,
2474
- paperColor: _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, paper.color),
2498
+ paperColor: _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, paper.color),
2475
2499
  seed: 7,
2476
- copies: [_chunkBXMIBMVGcjs.IDENTITY_COPY]
2500
+ copies: [_chunkJGKCC5OFcjs.IDENTITY_COPY]
2477
2501
  });
2478
2502
  driver.push(thumbnailStroke(width, height));
2479
2503
  driver.finish();
@@ -2493,7 +2517,7 @@ function thumbnailStroke(width, height) {
2493
2517
  return pts;
2494
2518
  }
2495
2519
  function paintTestStroke(surface, brush, paper, color, width, height) {
2496
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, color);
2520
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, color);
2497
2521
  let result = surface;
2498
2522
  let thick = null;
2499
2523
  const session = new PaintStrokeSession(
@@ -2512,14 +2536,14 @@ function paintTestStroke(surface, brush, paper, color, width, height) {
2512
2536
  lockTransparency: false,
2513
2537
  brush,
2514
2538
  color: [r, g, b, 255],
2515
- background: [..._chunkBXMIBMVGcjs.hexToRgb8.call(void 0, paper.color), 255],
2539
+ background: [..._chunkJGKCC5OFcjs.hexToRgb8.call(void 0, paper.color), 255],
2516
2540
  grain: paperGrain(paper),
2517
2541
  paperDepth: paper.depth,
2518
2542
  seed: 7,
2519
2543
  colorHex: color,
2520
2544
  affineCopies: [],
2521
- copies: [_chunkBXMIBMVGcjs.IDENTITY_COPY],
2522
- mixerLoad: brushLoadForStroke(brush, _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2545
+ copies: [_chunkJGKCC5OFcjs.IDENTITY_COPY],
2546
+ mixerLoad: brushLoadForStroke(brush, _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2523
2547
  thick: brush.engine === "impasto" ? { channels: emptyThickChannels() } : void 0,
2524
2548
  sticker: brush.engine === "sticker" ? { nextId: 1 } : void 0
2525
2549
  }
@@ -2532,8 +2556,8 @@ function renderBrushThumbnail(brush, options) {
2532
2556
  const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
2533
2557
  const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
2534
2558
  const maxSize = height * 0.42;
2535
- const b = brush.tip.size > maxSize ? _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
2536
- const rgba = [..._chunkBXMIBMVGcjs.hexToRgb8.call(void 0, options.color), 255];
2559
+ const b = brush.tip.size > maxSize ? _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
2560
+ const rgba = [..._chunkJGKCC5OFcjs.hexToRgb8.call(void 0, options.color), 255];
2537
2561
  let surface = _chunkCWM3CUUXcjs.emptySurface.call(void 0, 4);
2538
2562
  if (b.engine === "eraser") {
2539
2563
  surface = _chunkCWM3CUUXcjs.fillRect.call(void 0, surface, { x: 0, y: 0, width, height }, rgba);
@@ -2785,12 +2809,12 @@ function colorHarmony2(base, kind, options = {}) {
2785
2809
  function readSwatch(raw) {
2786
2810
  if (!raw || typeof raw !== "object") return null;
2787
2811
  const r = raw;
2788
- const g = _chunkLRRCMRSLcjs.readPaintSource.call(void 0, r.paint);
2789
- const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _139 => _139.type]) === "gradient" ? _chunkLRRCMRSLcjs.paintSourceColor.call(void 0, g) : null;
2812
+ const g = _chunkEBDCRTZIcjs.readPaintSource.call(void 0, r.paint);
2813
+ const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _142 => _142.type]) === "gradient" ? _chunkEBDCRTZIcjs.paintSourceColor.call(void 0, g) : null;
2790
2814
  if (!color) return null;
2791
2815
  const out = { color };
2792
2816
  if (typeof r.name === "string" && r.name.trim()) out.name = r.name.trim().slice(0, 80);
2793
- if (_optionalChain([g, 'optionalAccess', _140 => _140.type]) === "gradient") out.paint = g;
2817
+ if (_optionalChain([g, 'optionalAccess', _143 => _143.type]) === "gradient") out.paint = g;
2794
2818
  return out;
2795
2819
  }
2796
2820
  var DEFAULT_SWATCHES = [
@@ -2809,7 +2833,7 @@ var DEFAULT_SWATCHES = [
2809
2833
  // src/paint-editor/mixing-pad.ts
2810
2834
  var MIXING_PAD_WIDTH = 360;
2811
2835
  var MIXING_PAD_HEIGHT = 220;
2812
- var PAD_PAINT = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, {
2836
+ var PAD_PAINT = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, {
2813
2837
  id: "pad-paint",
2814
2838
  name: "Pad paint",
2815
2839
  category: "mixer",
@@ -2817,7 +2841,7 @@ var PAD_PAINT = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, {
2817
2841
  tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
2818
2842
  mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
2819
2843
  });
2820
- var PAD_KNIFE = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, {
2844
+ var PAD_KNIFE = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, {
2821
2845
  id: "pad-knife",
2822
2846
  name: "Palette knife",
2823
2847
  category: "smudge",
@@ -2827,7 +2851,7 @@ var PAD_KNIFE = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, {
2827
2851
  // A knife drags streaks of paint and folds them into each other, mixing them as pigment.
2828
2852
  smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
2829
2853
  });
2830
- var PAD_BLOB = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, {
2854
+ var PAD_BLOB = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, {
2831
2855
  id: "pad-blob",
2832
2856
  name: "Pad blob",
2833
2857
  category: "custom",
@@ -2849,12 +2873,12 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
2849
2873
  }
2850
2874
  }
2851
2875
  let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
2852
- if (options.size !== void 0) brush = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
2876
+ if (options.size !== void 0) brush = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
2853
2877
  return this.run(brush, points, options.color);
2854
2878
  }
2855
2879
  /** Paints `points` with `brush` in `color` on the pad. */
2856
2880
  run(brush, points, color) {
2857
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, color);
2881
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, color);
2858
2882
  let result = null;
2859
2883
  const session = new PaintStrokeSession(
2860
2884
  { update: () => {
@@ -2872,8 +2896,8 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
2872
2896
  seed: 1,
2873
2897
  colorHex: color,
2874
2898
  affineCopies: [],
2875
- copies: [_chunkBXMIBMVGcjs.IDENTITY_COPY],
2876
- mixerLoad: brushLoadForStroke(brush, _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
2899
+ copies: [_chunkJGKCC5OFcjs.IDENTITY_COPY],
2900
+ mixerLoad: brushLoadForStroke(brush, _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
2877
2901
  }
2878
2902
  );
2879
2903
  session.push(points);
@@ -2948,10 +2972,10 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
2948
2972
  const off = used.length === 1 ? 0 : 0.45 * R;
2949
2973
  const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
2950
2974
  const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
2951
- const blob = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
2975
+ const blob = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
2952
2976
  this.run(blob, [{ x, y }], p.color.toLowerCase());
2953
2977
  });
2954
- const knife = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
2978
+ const knife = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
2955
2979
  for (let k = 0; k < passes; k++) {
2956
2980
  const stir = [];
2957
2981
  const turns = 1.6;
@@ -2963,10 +2987,10 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
2963
2987
  this.run(knife, stir, "#000000");
2964
2988
  }
2965
2989
  const mixed = _chunkCWM3CUUXcjs.mixPigments.call(void 0,
2966
- paints.map((p) => _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
2990
+ paints.map((p) => _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
2967
2991
  paints.map((p) => p.parts)
2968
2992
  );
2969
- const core = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
2993
+ const core = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
2970
2994
  const hex = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
2971
2995
  this.run(core, [{ x: cx, y: cy }], hex);
2972
2996
  return { color: this.pick(cx, cy, 2), bounds };
@@ -2977,7 +3001,7 @@ var MixingPad = (_class8 = class {constructor() { _class8.prototype.__init65.cal
2977
3001
  }
2978
3002
  /** Replaces the pad with a PNG (data URL or base64) of the pad's size, as `toPng` writes. */
2979
3003
  fromPng(png) {
2980
- const bytes = png.startsWith("data:") ? _optionalChain([_chunkCWM3CUUXcjs.parseDataUrl.call(void 0, png), 'optionalAccess', _141 => _141.bytes]) : _chunkCWM3CUUXcjs.base64ToBytes.call(void 0, png);
3004
+ const bytes = png.startsWith("data:") ? _optionalChain([_chunkCWM3CUUXcjs.parseDataUrl.call(void 0, png), 'optionalAccess', _144 => _144.bytes]) : _chunkCWM3CUUXcjs.base64ToBytes.call(void 0, png);
2981
3005
  if (!bytes || !_chunkCWM3CUUXcjs.isPng.call(void 0, bytes)) throw new Error("The pad image is not a PNG data URL or base64 PNG.");
2982
3006
  const img = _chunkCWM3CUUXcjs.decodePng.call(void 0, bytes);
2983
3007
  if (img.width !== this.width || img.height !== this.height) throw new Error(`The pad image is ${img.width}\xD7${img.height}; a mixing pad is ${this.width}\xD7${this.height}.`);
@@ -3031,7 +3055,7 @@ async function replayPainting(source, target, options = {}) {
3031
3055
  const n = Math.min(left, chunk);
3032
3056
  await target.advanceWet({ steps: n });
3033
3057
  left -= n;
3034
- if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _142 => _142.onWetSteps, 'optionalCall', _143 => _143(target.getState().wet.clock)]);
3058
+ if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _145 => _145.onWetSteps, 'optionalCall', _146 => _146(target.getState().wet.clock)]);
3035
3059
  }
3036
3060
  };
3037
3061
  const sr = (r) => ({ x: r.x * s, y: r.y * s, width: r.width * s, height: r.height * s });
@@ -3043,7 +3067,7 @@ async function replayPainting(source, target, options = {}) {
3043
3067
  if (e.kind === "fill") target.fillLayer({ layerId: e.layerId, ...e.data });
3044
3068
  else if (e.kind === "clear") target.clearLayer(e.layerId);
3045
3069
  else if (e.kind === "stickers") {
3046
- const list = (_nullishCoalesce(_optionalChain([e, 'access', _144 => _144.data, 'optionalAccess', _145 => _145.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
3070
+ const list = (_nullishCoalesce(_optionalChain([e, 'access', _147 => _147.data, 'optionalAccess', _148 => _148.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
3047
3071
  target.replaceStickers(e.layerId, list);
3048
3072
  } else target.flattenRelief(e.layerId);
3049
3073
  continue;
@@ -3056,8 +3080,8 @@ async function replayPainting(source, target, options = {}) {
3056
3080
  switch (e.kind) {
3057
3081
  case "dry": {
3058
3082
  const rect = e.data;
3059
- const ids = _optionalChain([e, 'access', _146 => _146.layerId, 'optionalAccess', _147 => _147.split, 'call', _148 => _148(","), 'access', _149 => _149.filter, 'call', _150 => _150(Boolean)]);
3060
- if (_optionalChain([ids, 'optionalAccess', _151 => _151.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
3083
+ const ids = _optionalChain([e, 'access', _149 => _149.layerId, 'optionalAccess', _150 => _150.split, 'call', _151 => _151(","), 'access', _152 => _152.filter, 'call', _153 => _153(Boolean)]);
3084
+ if (_optionalChain([ids, 'optionalAccess', _154 => _154.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
3061
3085
  else target.dryPaint({ rect: rect ? sr(rect) : void 0 });
3062
3086
  break;
3063
3087
  }
@@ -3088,7 +3112,7 @@ async function replayPainting(source, target, options = {}) {
3088
3112
  strokes++;
3089
3113
  if (!target.getLayer(st.layerId)) continue;
3090
3114
  const init = { layerId: st.layerId, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...st.paint ? { paint: st.paint } : {}, snapToPerspective: false, stencils: false, maskStencils: (_nullishCoalesce(st.stencils, () => ( []))).map((x) => s === 1 ? x : scaleStencil(x, s)) };
3091
- if (st.brush.engine === "wet" && _optionalChain([st, 'access', _152 => _152.steps, 'optionalAccess', _153 => _153.length]) === st.points.length) {
3115
+ if (st.brush.engine === "wet" && _optionalChain([st, 'access', _155 => _155.steps, 'optionalAccess', _156 => _156.length]) === st.points.length) {
3092
3116
  await target.wetIdle();
3093
3117
  await advanceTo(st.steps[0]);
3094
3118
  const session = target.beginStroke({ ...init, start: st.points[0] });
@@ -3108,7 +3132,7 @@ async function replayPainting(source, target, options = {}) {
3108
3132
  await target.wetIdle();
3109
3133
  target.paintStroke({ ...init, points: st.points });
3110
3134
  }
3111
- await _optionalChain([options, 'access', _154 => _154.onStroke, 'optionalCall', _155 => _155(strokes)]);
3135
+ await _optionalChain([options, 'access', _157 => _157.onStroke, 'optionalCall', _158 => _158(strokes)]);
3112
3136
  }
3113
3137
  void IDENTITY_AFFINE;
3114
3138
  }
@@ -3153,7 +3177,7 @@ async function buildTimeLapse(source, target, options = {}) {
3153
3177
  wetChunk: wetEvery > 0 ? wetEvery : 0,
3154
3178
  onStroke: (i) => {
3155
3179
  if (i % perFrame === 0 || i === total) shoot(i);
3156
- _optionalChain([options, 'access', _156 => _156.onProgress, 'optionalCall', _157 => _157(total ? i / total : 1)]);
3180
+ _optionalChain([options, 'access', _159 => _159.onProgress, 'optionalCall', _160 => _160(total ? i / total : 1)]);
3157
3181
  },
3158
3182
  onWetSteps: wetEvery > 0 ? () => shoot(-1) : void 0
3159
3183
  });
@@ -3323,7 +3347,7 @@ function parseColor(value, what = "color") {
3323
3347
  return value.trim().toLowerCase();
3324
3348
  }
3325
3349
  function rgbaOf(hex) {
3326
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, hex);
3350
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, hex);
3327
3351
  return [r, g, b, 255];
3328
3352
  }
3329
3353
  function rgbToHex(r, g, b) {
@@ -3336,7 +3360,7 @@ function unionRect(a, b) {
3336
3360
  const y = Math.min(a.y, b.y);
3337
3361
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
3338
3362
  }
3339
- var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _158 => _158.type]) === "pixel";
3363
+ var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _161 => _161.type]) === "pixel";
3340
3364
  var PaintEditorController = (_class10 = class _PaintEditorController {
3341
3365
 
3342
3366
  __init72() {this.extensions = {}}
@@ -3351,7 +3375,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3351
3375
  __init76() {this.secondaryColor = "#ffffff"}
3352
3376
  /** Gradient paint chosen with `setPaint` (`null`: the paint colour). */
3353
3377
  __init77() {this.gradient = null}
3354
- __init78() {this.mixerLoad = _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD}
3378
+ __init78() {this.mixerLoad = _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD}
3355
3379
  __init79() {this.view = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } }}
3356
3380
 
3357
3381
 
@@ -3392,9 +3416,9 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3392
3416
  constructor(options = {}) {;_class10.prototype.__init72.call(this);_class10.prototype.__init73.call(this);_class10.prototype.__init74.call(this);_class10.prototype.__init75.call(this);_class10.prototype.__init76.call(this);_class10.prototype.__init77.call(this);_class10.prototype.__init78.call(this);_class10.prototype.__init79.call(this);_class10.prototype.__init80.call(this);_class10.prototype.__init81.call(this);_class10.prototype.__init82.call(this);_class10.prototype.__init83.call(this);_class10.prototype.__init84.call(this);_class10.prototype.__init85.call(this);_class10.prototype.__init86.call(this);_class10.prototype.__init87.call(this);_class10.prototype.__init88.call(this);_class10.prototype.__init89.call(this);_class10.prototype.__init90.call(this);_class10.prototype.__init91.call(this);_class10.prototype.__init92.call(this);_class10.prototype.__init93.call(this);_class10.prototype.__init94.call(this);_class10.prototype.__init95.call(this);_class10.prototype.__init96.call(this);_class10.prototype.__init97.call(this);_class10.prototype.__init98.call(this);_class10.prototype.__init99.call(this);_class10.prototype.__init100.call(this);_class10.prototype.__init101.call(this);_class10.prototype.__init102.call(this);_class10.prototype.__init103.call(this);_class10.prototype.__init104.call(this);_class10.prototype.__init105.call(this);_class10.prototype.__init106.call(this);_class10.prototype.__init107.call(this);_class10.prototype.__init108.call(this);_class10.prototype.__init109.call(this);
3393
3417
  this.historyLimit = Math.max(1, _nullishCoalesce(options.historyLimit, () => ( 200)));
3394
3418
  this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
3395
- this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
3396
- const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunkBXMIBMVGcjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunkBXMIBMVGcjs.DEFAULT_BRUSH_ID)));
3397
- this.brush = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, start);
3419
+ this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
3420
+ const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunkJGKCC5OFcjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunkJGKCC5OFcjs.DEFAULT_BRUSH_ID)));
3421
+ this.brush = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, start);
3398
3422
  this.color = options.color ? parseColor(options.color) : "#1f2937";
3399
3423
  this.hand = options.hand === "left" ? "left" : "right";
3400
3424
  this.encodeImage = options.encodeImage;
@@ -3405,7 +3429,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3405
3429
  canvas: () => this.doc.canvas,
3406
3430
  paper: () => this.doc.paper,
3407
3431
  layerSurface: (id) => {
3408
- const l = _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _159 => _159.layer]);
3432
+ const l = _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _162 => _162.layer]);
3409
3433
  return isPixelLayer(l) ? l.surface : null;
3410
3434
  },
3411
3435
  updateSurfaces: (surfaces, rects) => {
@@ -3419,7 +3443,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3419
3443
  },
3420
3444
  options.wet
3421
3445
  );
3422
- this.wet.onDriverDone = () => _optionalChain([this, 'access', _160 => _160.session, 'optionalAccess', _161 => _161.completeWetEnd, 'call', _162 => _162()]);
3446
+ this.wet.onDriverDone = () => _optionalChain([this, 'access', _163 => _163.session, 'optionalAccess', _164 => _164.completeWetEnd, 'call', _165 => _165()]);
3423
3447
  }
3424
3448
  // --- State and events ----------------------------------------------------------
3425
3449
  subscribe(listener) {
@@ -3441,7 +3465,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3441
3465
  this.cached = {
3442
3466
  document: this.doc,
3443
3467
  brush: this.brush,
3444
- brushes: this.library ??= [..._chunkBXMIBMVGcjs.BUILTIN_BRUSHES, ...this.userBrushes],
3468
+ brushes: this.library ??= [..._chunkJGKCC5OFcjs.BUILTIN_BRUSHES, ...this.userBrushes],
3445
3469
  color: this.color,
3446
3470
  secondaryColor: this.secondaryColor,
3447
3471
  paint: _nullishCoalesce(this.gradient, () => ( { type: "color", color: this.color })),
@@ -3450,8 +3474,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3450
3474
  hand: this.hand,
3451
3475
  canUndo: this.undoStack.length > 0 && !this.session,
3452
3476
  canRedo: this.redoStack.length > 0 && !this.session,
3453
- undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _163 => _163.label]), () => ( null)),
3454
- redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _164 => _164.label]), () => ( null)),
3477
+ undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _166 => _166.label]), () => ( null)),
3478
+ redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _167 => _167.label]), () => ( null)),
3455
3479
  guides: this.guides,
3456
3480
  swatches: this.swatches,
3457
3481
  mixingPadVersion: this.pad.version,
@@ -3464,10 +3488,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3464
3488
  overlay: this.wet.overlay,
3465
3489
  instantDry: this.wet.instantDry,
3466
3490
  speed: this.wet.speed,
3467
- clock: _nullishCoalesce(_optionalChain([this, 'access', _165 => _165.wet, 'access', _166 => _166.world, 'optionalAccess', _167 => _167.clock]), () => ( 0)),
3491
+ clock: _nullishCoalesce(_optionalChain([this, 'access', _168 => _168.wet, 'access', _169 => _169.world, 'optionalAccess', _170 => _170.clock]), () => ( 0)),
3468
3492
  tilt: { ...this.wet.tilt },
3469
3493
  gpu: this.wet.gpuMode,
3470
- gpuActive: Boolean(_optionalChain([this, 'access', _168 => _168.wet, 'access', _169 => _169.world, 'optionalAccess', _170 => _170.gpuActive]))
3494
+ gpuActive: Boolean(_optionalChain([this, 'access', _171 => _171.wet, 'access', _172 => _172.world, 'optionalAccess', _173 => _173.gpuActive]))
3471
3495
  },
3472
3496
  version: this.version
3473
3497
  };
@@ -3571,7 +3595,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3571
3595
  /** Records a wet event (for replays) in the document being built. */
3572
3596
  __init107() {this.pendingWetEvents = []}
3573
3597
  logWet(e) {
3574
- this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _171 => _171.wet, 'access', _172 => _172.world, 'optionalAccess', _173 => _173.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
3598
+ this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _174 => _174.wet, 'access', _175 => _175.world, 'optionalAccess', _176 => _176.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
3575
3599
  }
3576
3600
  /** The document with a paint event appended (for replays). */
3577
3601
  withPaintEvent(doc, e) {
@@ -3594,6 +3618,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3594
3618
  const paper = this.doc.paper;
3595
3619
  this.doc = e.before;
3596
3620
  this.docRevision++;
3621
+ if (e.guides) this.restoreGuides(e.guides.before);
3597
3622
  if (e.wet) {
3598
3623
  if (paper !== this.doc.paper) this.wet.paperChanged();
3599
3624
  this.wet.restore(e.wet.lost ? null : e.wet.before);
@@ -3612,6 +3637,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3612
3637
  const paper = this.doc.paper;
3613
3638
  this.doc = e.after;
3614
3639
  this.docRevision++;
3640
+ if (e.guides) this.restoreGuides(e.guides.after);
3615
3641
  if (e.wet) {
3616
3642
  this.wet.restore(e.wet.lost ? null : e.wet.after);
3617
3643
  if (paper !== this.doc.paper) this.wet.paperChanged();
@@ -3619,6 +3645,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3619
3645
  this.emit();
3620
3646
  return e.label;
3621
3647
  }
3648
+ restoreGuides(guides) {
3649
+ if (guides.tracing !== this.guides.tracing) this.tracingVersion++;
3650
+ this.guides = guides;
3651
+ }
3622
3652
  /** Labels of the undo steps, oldest first. */
3623
3653
  historyLabels() {
3624
3654
  return { undo: this.undoStack.map((e) => e.label), redo: this.redoStack.map((e) => e.label).reverse() };
@@ -3626,7 +3656,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3626
3656
  // --- Canvas and paper ----------------------------------------------------------
3627
3657
  resolvePaper(paper) {
3628
3658
  if (typeof paper === "string") {
3629
- const p = _chunkBXMIBMVGcjs.paperPreset.call(void 0, paper);
3659
+ const p = _chunkJGKCC5OFcjs.paperPreset.call(void 0, paper);
3630
3660
  if (!p) throw new PaintEditorError(`Unknown paper "${paper}". Call list_papers for the ids.`);
3631
3661
  return p;
3632
3662
  }
@@ -3639,7 +3669,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3639
3669
  width: _nullishCoalesce(options.width, () => ( this.doc.canvas.width)),
3640
3670
  height: _nullishCoalesce(options.height, () => ( this.doc.canvas.height)),
3641
3671
  dpi: _nullishCoalesce(options.dpi, () => ( this.doc.canvas.dpi)),
3642
- paper: options.paper === void 0 ? this.doc.paper : this.resolvePaper(options.paper)
3672
+ paper: options.paper === void 0 ? { ...this.doc.paper, offset: void 0 } : this.resolvePaper(options.paper)
3643
3673
  });
3644
3674
  this.extensions = {};
3645
3675
  this.guides = { ...this.guides, symmetry: { ...this.guides.symmetry, center: { x: next.canvas.width / 2, y: next.canvas.height / 2 } }, tracing: null };
@@ -3666,28 +3696,76 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3666
3696
  this.commit("Canvas size", this.withWetEvents({ ...this.doc, canvas }));
3667
3697
  return canvas;
3668
3698
  }
3699
+ /**
3700
+ * Grows the canvas by `left`, `top`, `right` and `bottom` pixels without moving anything
3701
+ * relative to anything else: the layers (with their masks, relief and stickers), the paper grain,
3702
+ * the effect paper, guides, stencils, the tracing image and the recorded strokes and events all
3703
+ * move by (left, top) in document pixels, `document.origin` moves by (−left, −top), and the view
3704
+ * pans so the picture stays still on screen.
3705
+ *
3706
+ * Wet paint dries first (the wet simulation is canvas-sized), as with `setCanvas`; one undo step
3707
+ * (undo brings back the old size, origin and guides, and the wet paint). Returns the new canvas,
3708
+ * where it sits in the previous document's pixels, and the origin.
3709
+ */
3710
+ extendCanvas(by) {
3711
+ this.requireIdle("extending the canvas");
3712
+ const side = (k) => {
3713
+ const v = _nullishCoalesce(by[k], () => ( 0));
3714
+ if (!Number.isInteger(v) || v < 0) throw new PaintEditorError(`${k} is ${JSON.stringify(by[k])}; use a whole number of pixels to add, 0 or more.`);
3715
+ return v;
3716
+ };
3717
+ const left = side("left");
3718
+ const top = side("top");
3719
+ const right = side("right");
3720
+ const bottom = side("bottom");
3721
+ if (!(left || top || right || bottom)) throw new PaintEditorError("Nothing to extend: give left, top, right or bottom (pixels to add on that side) above 0.");
3722
+ const was = this.doc.canvas;
3723
+ const width = was.width + left + right;
3724
+ const height = was.height + top + bottom;
3725
+ if (width > MAX_CANVAS_SIDE || height > MAX_CANVAS_SIDE) {
3726
+ throw new PaintEditorError(`The canvas would be ${width}\xD7${height}; the limit is ${MAX_CANVAS_SIDE} px per side. Extend by less (it is ${was.width}\xD7${was.height} now).`);
3727
+ }
3728
+ if (this.wet.world) {
3729
+ this.requireWetIdle("extending the canvas");
3730
+ this.dryLayersFirst(this.wet.wetLayerIds());
3731
+ const settings = [...this.wet.settings];
3732
+ this.wet.reset();
3733
+ for (const [id, s] of settings) this.wet.settings.set(id, s.flow.center ? { ...s, flow: { ...s.flow, center: { x: s.flow.center.x + left, y: s.flow.center.y + top } } } : s);
3734
+ }
3735
+ const next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
3736
+ const m = viewMatrix(this.view, was, { width: 0, height: 0 });
3737
+ const dx = (right - left) / 2;
3738
+ const dy = (bottom - top) / 2;
3739
+ this.view = { ...this.view, pan: { x: this.view.pan.x + m[0] * dx + m[1] * dy, y: this.view.pan.y + m[2] * dx + m[3] * dy } };
3740
+ const guidesBefore = this.guides;
3741
+ if (left || top) this.restoreGuides(shiftGuides(this.guides, left, top));
3742
+ this.commit("Extend canvas", next);
3743
+ if (this.guides !== guidesBefore) this.undoStack[this.undoStack.length - 1].guides = { before: guidesBefore, after: this.guides };
3744
+ const origin = { ..._nullishCoalesce(next.origin, () => ( { x: 0, y: 0 })) };
3745
+ return { canvas: { ...next.canvas }, rect: { x: 0 - left, y: 0 - top, width, height }, origin };
3746
+ }
3669
3747
  /** Changes the paper: a library preset (`preset`), and / or any of its settings (one undo step). */
3670
3748
  setPaper(update) {
3671
3749
  this.requireIdle("changing the paper");
3672
3750
  let base = this.doc.paper;
3673
3751
  if (update.preset !== void 0 && update.preset !== this.doc.paper.preset) {
3674
- const p = _chunkBXMIBMVGcjs.paperPreset.call(void 0, update.preset);
3752
+ const p = _chunkJGKCC5OFcjs.paperPreset.call(void 0, update.preset);
3675
3753
  if (!p) throw new PaintEditorError(`Unknown paper "${update.preset}". Call list_papers for the ids.`);
3676
3754
  base = p;
3677
3755
  }
3678
3756
  const { preset: _p, ...rest } = update;
3679
3757
  if (rest.color !== void 0) parseColor(rest.color, "paper color");
3680
- const paper = _chunkBXMIBMVGcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset }, base);
3758
+ const paper = _chunkJGKCC5OFcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
3681
3759
  const changedKeys = Object.keys(rest).filter((k) => k !== "name");
3682
3760
  if (changedKeys.length && update.preset === void 0) paper.preset = base.preset;
3683
3761
  if (this.wet.world) this.beginWetOp();
3684
3762
  this.commit("Paper", { ...this.doc, paper });
3685
3763
  this.wet.paperChanged();
3686
- return _chunkBXMIBMVGcjs.clonePaper.call(void 0, paper);
3764
+ return _chunkJGKCC5OFcjs.clonePaper.call(void 0, paper);
3687
3765
  }
3688
3766
  // --- Layers --------------------------------------------------------------------
3689
3767
  getLayer(id) {
3690
- return _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _174 => _174.layer]);
3768
+ return _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _177 => _177.layer]);
3691
3769
  }
3692
3770
  /** The active pixel layer (or `undefined`). */
3693
3771
  getActiveLayer() {
@@ -3706,7 +3784,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3706
3784
  walk(this.doc.layers, null, 0);
3707
3785
  return out;
3708
3786
  }
3709
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _175 => _175.parent, 'optionalAccess', _176 => _176.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _177 => _177.path, 'access', _178 => _178.length]), () => ( 0))) {
3787
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _178 => _178.parent, 'optionalAccess', _179 => _179.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _180 => _180.path, 'access', _181 => _181.length]), () => ( 0))) {
3710
3788
  let bounds = null;
3711
3789
  if (l.type === "pixel") {
3712
3790
  const b = _chunkCWM3CUUXcjs.contentBounds.call(void 0, l.surface);
@@ -3753,7 +3831,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3753
3831
  this.requireIdle("adding a layer");
3754
3832
  const count = _chunkHGTDMKNEcjs.flattenLayers.call(void 0, this.doc.layers).length;
3755
3833
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
3756
- const name = _optionalChain([options, 'access', _179 => _179.name, 'optionalAccess', _180 => _180.trim, 'call', _181 => _181()]) || (type === "group" ? `Group ${count + 1}` : `Layer ${count + 1}`);
3834
+ const name = _optionalChain([options, 'access', _182 => _182.name, 'optionalAccess', _183 => _183.trim, 'call', _184 => _184()]) || (type === "group" ? `Group ${count + 1}` : `Layer ${count + 1}`);
3757
3835
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
3758
3836
  let parentId = null;
3759
3837
  let index;
@@ -3765,7 +3843,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3765
3843
  } else if (above) {
3766
3844
  const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, above);
3767
3845
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
3768
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _182 => _182.parent, 'optionalAccess', _183 => _183.id]), () => ( null));
3846
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _185 => _185.parent, 'optionalAccess', _186 => _186.id]), () => ( null));
3769
3847
  index = loc.index + 1;
3770
3848
  }
3771
3849
  const layers = _chunkHGTDMKNEcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
@@ -3805,7 +3883,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3805
3883
  }
3806
3884
  const layers = _chunkHGTDMKNEcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
3807
3885
  let active = this.doc.activeLayerId;
3808
- if (active && !_chunkHGTDMKNEcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers), 'access', _184 => _184.filter, 'call', _185 => _185((x) => x.type === "pixel"), 'access', _186 => _186.pop, 'call', _187 => _187(), 'optionalAccess', _188 => _188.id]), () => ( null));
3886
+ if (active && !_chunkHGTDMKNEcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers), 'access', _187 => _187.filter, 'call', _188 => _188((x) => x.type === "pixel"), 'access', _189 => _189.pop, 'call', _190 => _190(), 'optionalAccess', _191 => _191.id]), () => ( null));
3809
3887
  this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkHGTDMKNEcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkHGTDMKNEcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
3810
3888
  return { removed: id, activeLayerId: active };
3811
3889
  }
@@ -3826,7 +3904,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3826
3904
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
3827
3905
  };
3828
3906
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
3829
- const layers = _chunkHGTDMKNEcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _189 => _189.parent, 'optionalAccess', _190 => _190.id]), () => ( null)), loc.index + 1);
3907
+ const layers = _chunkHGTDMKNEcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _192 => _192.parent, 'optionalAccess', _193 => _193.id]), () => ( null)), loc.index + 1);
3830
3908
  this.commit("Duplicate layer", this.withWetEvents({ ...this.doc, layers, activeLayerId: dup.id, ...this.doc.thick ? { thick } : {}, ...this.doc.stickers ? { stickers } : {} }));
3831
3909
  return this.describeLayer(dup);
3832
3910
  }
@@ -3835,7 +3913,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3835
3913
  this.requireIdle("moving a layer");
3836
3914
  const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id);
3837
3915
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
3838
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _191 => _191.parent, 'optionalAccess', _192 => _192.id]), () => ( null)) : parentId;
3916
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _194 => _194.parent, 'optionalAccess', _195 => _195.id]), () => ( null)) : parentId;
3839
3917
  if (target) {
3840
3918
  const g = this.requireLayer(target);
3841
3919
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
@@ -3854,7 +3932,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3854
3932
  const pre = _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id);
3855
3933
  if (pre) {
3856
3934
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
3857
- this.dryLayersFirst([id, _optionalChain([sib, 'access', _193 => _193[pre.index - 1], 'optionalAccess', _194 => _194.id])].filter((x) => Boolean(x)));
3935
+ this.dryLayersFirst([id, _optionalChain([sib, 'access', _196 => _196[pre.index - 1], 'optionalAccess', _197 => _197.id])].filter((x) => Boolean(x)));
3858
3936
  }
3859
3937
  const loc = _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id);
3860
3938
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
@@ -3895,7 +3973,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3895
3973
  fillLayer(options = {}) {
3896
3974
  this.requireIdle("filling");
3897
3975
  const fillTarget = this.paintTarget(options.layerId, "fill");
3898
- if (_optionalChain([this, 'access', _195 => _195.doc, 'access', _196 => _196.stickers, 'optionalAccess', _197 => _197[fillTarget.id], 'optionalAccess', _198 => _198.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
3976
+ if (_optionalChain([this, 'access', _198 => _198.doc, 'access', _199 => _199.stickers, 'optionalAccess', _200 => _200[fillTarget.id], 'optionalAccess', _201 => _201.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
3899
3977
  this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
3900
3978
  const l = this.paintTarget(options.layerId, "fill");
3901
3979
  const color = options.color === void 0 ? this.color : parseColor(options.color);
@@ -3908,13 +3986,13 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3908
3986
  if (!_chunkCWM3CUUXcjs.isBlendMode.call(void 0, blend)) throw new PaintEditorError(`Unknown blend mode "${blend}".`);
3909
3987
  const { width, height } = this.doc.canvas;
3910
3988
  const rect = { x: 0, y: 0, width, height };
3911
- const coverage = new (0, _chunkLRRCMRSLcjs.CoverageMap)();
3989
+ const coverage = new (0, _chunkEBDCRTZIcjs.CoverageMap)();
3912
3990
  const depth = grainAmount * this.doc.paper.depth;
3913
3991
  const grain = depth > 0 ? paperGrain(this.doc.paper) : null;
3914
3992
  for (const { tx, ty } of _chunkCWM3CUUXcjs.tilesInRect.call(void 0, rect)) {
3915
3993
  const r = { x: tx * _chunkCWM3CUUXcjs.TILE, y: ty * _chunkCWM3CUUXcjs.TILE, width: Math.min(_chunkCWM3CUUXcjs.TILE, width - tx * _chunkCWM3CUUXcjs.TILE), height: Math.min(_chunkCWM3CUUXcjs.TILE, height - ty * _chunkCWM3CUUXcjs.TILE) };
3916
3994
  const vals = new Float32Array(r.width * r.height);
3917
- for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkLRRCMRSLcjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
3995
+ for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkEBDCRTZIcjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
3918
3996
  coverage.accumulate(r, vals, 1);
3919
3997
  }
3920
3998
  const apply = {
@@ -3936,8 +4014,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3936
4014
  const tiles = new Map(base.tiles);
3937
4015
  for (const { tx, ty } of _chunkCWM3CUUXcjs.tilesInRect.call(void 0, { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {
3938
4016
  const key = _chunkCWM3CUUXcjs.tileKey.call(void 0, tx, ty);
3939
- const src = _nullishCoalesce(_optionalChain([base, 'access', _199 => _199.tiles, 'access', _200 => _200.get, 'call', _201 => _201(key), 'optionalAccess', _202 => _202.data]), () => ( new Uint8ClampedArray(_chunkCWM3CUUXcjs.TILE * _chunkCWM3CUUXcjs.TILE * 4)));
3940
- const tile = _chunkCWM3CUUXcjs.finishTile.call(void 0, _chunkLRRCMRSLcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
4017
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _202 => _202.tiles, 'access', _203 => _203.get, 'call', _204 => _204(key), 'optionalAccess', _205 => _205.data]), () => ( new Uint8ClampedArray(_chunkCWM3CUUXcjs.TILE * _chunkCWM3CUUXcjs.TILE * 4)));
4018
+ const tile = _chunkCWM3CUUXcjs.finishTile.call(void 0, _chunkEBDCRTZIcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
3941
4019
  if (tile) tiles.set(key, tile);
3942
4020
  else tiles.delete(key);
3943
4021
  }
@@ -3969,7 +4047,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3969
4047
  }
3970
4048
  /** The effect a layer is drawn from, or `undefined` for other layers. */
3971
4049
  getEffectLayer(layerId) {
3972
- return _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _203 => _203.doc, 'access', _204 => _204.effectLayers, 'optionalAccess', _205 => _205[layerId]]) : void 0;
4050
+ return _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _206 => _206.doc, 'access', _207 => _207.effectLayers, 'optionalAccess', _208 => _208[layerId]]) : void 0;
3973
4051
  }
3974
4052
  /** The effect paper (without its pixels), or `null`. */
3975
4053
  getPaperEffect() {
@@ -4006,7 +4084,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4006
4084
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
4007
4085
  effectTarget(layerId, what) {
4008
4086
  const l = this.paintTarget(layerId, what);
4009
- if (_optionalChain([this, 'access', _206 => _206.doc, 'access', _207 => _207.stickers, 'optionalAccess', _208 => _208[l.id], 'optionalAccess', _209 => _209.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
4087
+ if (_optionalChain([this, 'access', _209 => _209.doc, 'access', _210 => _210.stickers, 'optionalAccess', _211 => _211[l.id], 'optionalAccess', _212 => _212.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
4010
4088
  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.`);
4011
4089
  return l;
4012
4090
  }
@@ -4045,8 +4123,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4045
4123
  const was = this.doc.paperEffect;
4046
4124
  const paperEffect = {
4047
4125
  ...this.sourceOf(d, values, options.time),
4048
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _210 => _210.opacity]))), () => ( 1)),
4049
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _211 => _211.blend]))), () => ( "multiply")),
4126
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _213 => _213.opacity]))), () => ( 1)),
4127
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _214 => _214.blend]))), () => ( "multiply")),
4050
4128
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
4051
4129
  version: nextPaperEffectVersion()
4052
4130
  };
@@ -4099,8 +4177,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4099
4177
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
4100
4178
  const loc = above ? _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, above) : null;
4101
4179
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
4102
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _212 => _212.name, 'optionalAccess', _213 => _213.trim, 'call', _214 => _214()]) || d.name), surface: _chunkCWM3CUUXcjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
4103
- const layers = _chunkHGTDMKNEcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _215 => _215.parent, 'optionalAccess', _216 => _216.id]), () => ( null)), loc ? loc.index + 1 : void 0);
4180
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _215 => _215.name, 'optionalAccess', _216 => _216.trim, 'call', _217 => _217()]) || d.name), surface: _chunkCWM3CUUXcjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
4181
+ const layers = _chunkHGTDMKNEcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _218 => _218.parent, 'optionalAccess', _219 => _219.id]), () => ( null)), loc ? loc.index + 1 : void 0);
4104
4182
  const source = this.sourceOf(d, values, options.time);
4105
4183
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
4106
4184
  return { layer: this.describeLayer(layer), source };
@@ -4176,14 +4254,14 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4176
4254
  const before = _chunkCWM3CUUXcjs.readRegion.call(void 0, l.surface, rect);
4177
4255
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
4178
4256
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
4179
- const relief = _optionalChain([this, 'access', _217 => _217.doc, 'access', _218 => _218.thick, 'optionalAccess', _219 => _219[l.id]]);
4257
+ const relief = _optionalChain([this, 'access', _220 => _220.doc, 'access', _221 => _221.thick, 'optionalAccess', _222 => _222[l.id]]);
4180
4258
  if (heightInput && relief) {
4181
4259
  const h = _chunkCWM3CUUXcjs.readRegion.call(void 0, relief.height, rect);
4182
4260
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
4183
4261
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
4184
4262
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
4185
4263
  }
4186
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _220 => _220.inputs, 'access', _221 => _221.find, 'call', _222 => _222((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _223 => _223.name])), 'optionalAccess', _224 => _224.name]), () => ( "source"));
4264
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _223 => _223.inputs, 'access', _224 => _224.find, 'call', _225 => _225((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _226 => _226.name])), 'optionalAccess', _227 => _227.name]), () => ( "source"));
4187
4265
  if (sourceInput !== "source") {
4188
4266
  inputs[sourceInput] = inputs.source;
4189
4267
  delete inputs.source;
@@ -4196,12 +4274,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4196
4274
  }
4197
4275
  // --- Brushes -------------------------------------------------------------------
4198
4276
  findBrush(id) {
4199
- return _nullishCoalesce(_chunkBXMIBMVGcjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
4277
+ return _nullishCoalesce(_chunkJGKCC5OFcjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
4200
4278
  }
4201
4279
  /** A library brush by id (`undefined` when unknown). */
4202
4280
  getBrush(id) {
4203
4281
  const b = this.findBrush(id);
4204
- return b ? _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
4282
+ return b ? _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
4205
4283
  }
4206
4284
  requireBrush(id) {
4207
4285
  const b = this.findBrush(id);
@@ -4216,7 +4294,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4216
4294
  const { id, ...changes } = update;
4217
4295
  const base = id !== void 0 ? this.requireBrush(id) : this.brush;
4218
4296
  if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
4219
- const next = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
4297
+ const next = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
4220
4298
  if (base.builtin && !Object.keys(changes).length) next.builtin = true;
4221
4299
  else delete next.builtin;
4222
4300
  this.brush = next;
@@ -4225,10 +4303,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4225
4303
  }
4226
4304
  /** Saves the active brush (or `brush`) into the user library under `id` / `name`. */
4227
4305
  saveBrush(options) {
4228
- if (!_chunkBXMIBMVGcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
4229
- if (_chunkBXMIBMVGcjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
4230
- const source = options.brush ? _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
4231
- const saved = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
4306
+ if (!_chunkJGKCC5OFcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
4307
+ if (_chunkJGKCC5OFcjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
4308
+ const source = options.brush ? _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
4309
+ const saved = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
4232
4310
  delete saved.builtin;
4233
4311
  const i = this.userBrushes.findIndex((b) => b.id === options.id);
4234
4312
  if (i >= 0) this.userBrushes[i] = saved;
@@ -4238,7 +4316,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4238
4316
  return saved;
4239
4317
  }
4240
4318
  removeBrush(id) {
4241
- if (_chunkBXMIBMVGcjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
4319
+ if (_chunkJGKCC5OFcjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
4242
4320
  const i = this.userBrushes.findIndex((b) => b.id === id);
4243
4321
  if (i < 0) throw new PaintEditorError(`Unknown brush "${id}". Call list_brushes for the ids.`);
4244
4322
  this.userBrushes.splice(i, 1);
@@ -4247,12 +4325,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4247
4325
  }
4248
4326
  /** The user's saved brushes. */
4249
4327
  getUserBrushes() {
4250
- return this.userBrushes.map((b) => _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, b, b));
4328
+ return this.userBrushes.map((b) => _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, b, b));
4251
4329
  }
4252
4330
  /** A brush library file of the given brushes (default: the user's brushes). */
4253
4331
  exportBrushes(ids) {
4254
4332
  const list = ids ? ids.map((id) => this.requireBrush(id)) : this.userBrushes;
4255
- return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunkBXMIBMVGcjs.brushToJSON) };
4333
+ return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunkJGKCC5OFcjs.brushToJSON) };
4256
4334
  }
4257
4335
  /**
4258
4336
  * Adds the brushes of a library file to the user library. A brush whose id is taken is skipped
@@ -4262,14 +4340,14 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4262
4340
  const problems = [];
4263
4341
  let list;
4264
4342
  try {
4265
- list = _chunkBXMIBMVGcjs.parseBrushLibrary.call(void 0, file, problems);
4343
+ list = _chunkJGKCC5OFcjs.parseBrushLibrary.call(void 0, file, problems);
4266
4344
  } catch (e) {
4267
4345
  throw new PaintEditorError(e.message);
4268
4346
  }
4269
4347
  const added = [];
4270
4348
  const skipped = [];
4271
4349
  for (const b of list) {
4272
- if (_chunkBXMIBMVGcjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
4350
+ if (_chunkJGKCC5OFcjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
4273
4351
  skipped.push(b.id);
4274
4352
  problems.push(`"${b.id}" is a built-in brush id; rename it to import it.`);
4275
4353
  continue;
@@ -4311,9 +4389,9 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4311
4389
  setPaint(paint) {
4312
4390
  let p;
4313
4391
  try {
4314
- p = _chunkLRRCMRSLcjs.parsePaintSource.call(void 0, paint);
4392
+ p = _chunkEBDCRTZIcjs.parsePaintSource.call(void 0, paint);
4315
4393
  } catch (e) {
4316
- if (e instanceof _chunkLRRCMRSLcjs.PaintSourceError) throw new PaintEditorError(e.message);
4394
+ if (e instanceof _chunkEBDCRTZIcjs.PaintSourceError) throw new PaintEditorError(e.message);
4317
4395
  throw e;
4318
4396
  }
4319
4397
  if (p.type === "color") {
@@ -4330,19 +4408,19 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4330
4408
  * brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
4331
4409
  */
4332
4410
  strokeGradient(init, brush, color) {
4333
- if (!_chunkBXMIBMVGcjs.brushTakesPaint.call(void 0, brush)) return null;
4411
+ if (!_chunkJGKCC5OFcjs.brushTakesPaint.call(void 0, brush)) return null;
4334
4412
  let g = null;
4335
4413
  if (init.paint !== void 0) {
4336
4414
  const p = this.readStrokePaint(init.paint);
4337
4415
  g = p.type === "gradient" ? p : null;
4338
4416
  } else g = _nullishCoalesce(brush.paint, () => ( (init.color === void 0 ? this.gradient : null)));
4339
- return g ? _chunkLRRCMRSLcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
4417
+ return g ? _chunkEBDCRTZIcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
4340
4418
  }
4341
4419
  readStrokePaint(raw) {
4342
4420
  try {
4343
- return _chunkLRRCMRSLcjs.parsePaintSource.call(void 0, raw);
4421
+ return _chunkEBDCRTZIcjs.parsePaintSource.call(void 0, raw);
4344
4422
  } catch (e) {
4345
- if (e instanceof _chunkLRRCMRSLcjs.PaintSourceError) throw new PaintEditorError(e.message);
4423
+ if (e instanceof _chunkEBDCRTZIcjs.PaintSourceError) throw new PaintEditorError(e.message);
4346
4424
  throw e;
4347
4425
  }
4348
4426
  }
@@ -4376,14 +4454,14 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4376
4454
  // --- Mixer Brush ---------------------------------------------------------------
4377
4455
  /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */
4378
4456
  loadMixerBrush(color) {
4379
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
4380
- this.mixerLoad = _chunkLRRCMRSLcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
4457
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
4458
+ this.mixerLoad = _chunkEBDCRTZIcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
4381
4459
  this.emit([]);
4382
4460
  return this.mixerLoad;
4383
4461
  }
4384
4462
  /** Empties the pickup well (and with `emptyReservoir` the loaded paint too). */
4385
4463
  cleanMixerBrush(emptyReservoir = false) {
4386
- this.mixerLoad = emptyReservoir ? _chunkLRRCMRSLcjs.EMPTY_MIXER_LOAD : _chunkLRRCMRSLcjs.cleanMixer.call(void 0, this.mixerLoad);
4464
+ this.mixerLoad = emptyReservoir ? _chunkEBDCRTZIcjs.EMPTY_MIXER_LOAD : _chunkEBDCRTZIcjs.cleanMixer.call(void 0, this.mixerLoad);
4387
4465
  this.emit([]);
4388
4466
  return this.mixerLoad;
4389
4467
  }
@@ -4406,7 +4484,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4406
4484
  // --- Strokes -------------------------------------------------------------------
4407
4485
  strokeBrush(init) {
4408
4486
  let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
4409
- if (init.brush) brush = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
4487
+ if (init.brush) brush = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
4410
4488
  return brush;
4411
4489
  }
4412
4490
  /**
@@ -4439,14 +4517,14 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4439
4517
  return l;
4440
4518
  })();
4441
4519
  const brush = this.strokeBrush(init);
4442
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _225 => _225.stickers, 'optionalAccess', _226 => _226[layer.id], 'optionalAccess', _227 => _227.length]));
4520
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _228 => _228.stickers, 'optionalAccess', _229 => _229[layer.id], 'optionalAccess', _230 => _230.length]));
4443
4521
  if (brush.engine === "sticker") {
4444
4522
  if (!stickerLayer && _chunkCWM3CUUXcjs.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.`);
4445
4523
  } else if (stickerLayer) {
4446
4524
  throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
4447
4525
  }
4448
4526
  let wet;
4449
- if (_chunkBXMIBMVGcjs.isWetBrush.call(void 0, brush)) {
4527
+ if (_chunkJGKCC5OFcjs.isWetBrush.call(void 0, brush)) {
4450
4528
  this.requireWetIdle("painting");
4451
4529
  if (layer.offset.x || layer.offset.y) {
4452
4530
  const moved = { ...layer, surface: _chunkCWM3CUUXcjs.translateSurface.call(void 0, layer.surface, layer.offset.x, layer.offset.y), offset: { x: 0, y: 0 } };
@@ -4461,10 +4539,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4461
4539
  const world = this.wet.ensureLane(layer.id, brush.wet.medium);
4462
4540
  const id = layer.id;
4463
4541
  const wetColor = init.color === void 0 ? this.color : parseColor(init.color);
4464
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, wetColor);
4542
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, wetColor);
4465
4543
  const wetGradient = this.strokeGradient(init, brush, wetColor);
4466
4544
  const load = _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [r / 255, g / 255, b / 255])));
4467
- const seedW = _nullishCoalesce(init.seed, () => ( _chunkLRRCMRSLcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
4545
+ const seedW = _nullishCoalesce(init.seed, () => ( _chunkEBDCRTZIcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
4468
4546
  const copiesW = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
4469
4547
  const driver = new WetStrokeDriver({
4470
4548
  world,
@@ -4474,7 +4552,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4474
4552
  load,
4475
4553
  grain: paperGrain(doc.paper),
4476
4554
  paperDepth: doc.paper.depth,
4477
- paperColor: _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, doc.paper.color),
4555
+ paperColor: _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, doc.paper.color),
4478
4556
  seed: seedW,
4479
4557
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
4480
4558
  mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
@@ -4489,7 +4567,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4489
4567
  }
4490
4568
  let color = init.color === void 0 ? this.color : parseColor(init.color);
4491
4569
  const tracing = this.guides.tracing;
4492
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _228 => _228.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
4570
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _231 => _231.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
4493
4571
  const perspective = this.guides.perspective;
4494
4572
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
4495
4573
  const useStencils = init.stencils !== false;
@@ -4497,7 +4575,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4497
4575
  const selection = init.maskStencils ? this.stencilSelection(init.maskStencils) : useStencils ? this.stencilSelection() : null;
4498
4576
  const inputFilter = snapper || stencilSnapper ? (p) => stencilSnapper ? stencilSnapper.snap(snapper ? snapper.snap(p) : p) : snapper.snap(p) : void 0;
4499
4577
  const rgba = rgbaOf(color);
4500
- const seed = _nullishCoalesce(init.seed, () => ( _chunkLRRCMRSLcjs.mix32.call(void 0, this.seedCounter++ * 2654435761 >>> 0) & 2147483647));
4578
+ const seed = _nullishCoalesce(init.seed, () => ( _chunkEBDCRTZIcjs.mix32.call(void 0, this.seedCounter++ * 2654435761 >>> 0) & 2147483647));
4501
4579
  const copies = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
4502
4580
  const session = new PaintStrokeSession(host, {
4503
4581
  layerId: layer.id,
@@ -4518,7 +4596,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4518
4596
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
4519
4597
  secondary: rgbaOf(this.secondaryColor),
4520
4598
  wet,
4521
- thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _229 => _229.thick, 'optionalAccess', _230 => _230[layer.id]]), () => ( emptyThickChannels())) } : void 0,
4599
+ thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _232 => _232.thick, 'optionalAccess', _233 => _233[layer.id]]), () => ( emptyThickChannels())) } : void 0,
4522
4600
  sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc) } : void 0,
4523
4601
  paint: this.strokeGradient(init, brush, color)
4524
4602
  });
@@ -4531,7 +4609,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4531
4609
  const stroke = {
4532
4610
  id: `s${this.strokeCounter++}`,
4533
4611
  layerId: session.layerId,
4534
- brush: _chunkBXMIBMVGcjs.brushToJSON.call(void 0, init.brush),
4612
+ brush: _chunkJGKCC5OFcjs.brushToJSON.call(void 0, init.brush),
4535
4613
  color: init.colorHex,
4536
4614
  points: session.points.map((p) => ({ ...p })),
4537
4615
  seed: init.seed
@@ -4555,12 +4633,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4555
4633
  const before = this.doc;
4556
4634
  const host = {
4557
4635
  update: (layerId, surface, rects) => {
4558
- if (_optionalChain([this, 'access', _231 => _231.session, 'optionalAccess', _232 => _232.init, 'access', _233 => _233.wet])) {
4636
+ if (_optionalChain([this, 'access', _234 => _234.session, 'optionalAccess', _235 => _235.init, 'access', _236 => _236.wet])) {
4559
4637
  this.wet.syncDisplays();
4560
4638
  return;
4561
4639
  }
4562
4640
  this.live = { layerId, surface };
4563
- const ch = _optionalChain([this, 'access', _234 => _234.session, 'optionalAccess', _235 => _235.thickChannels, 'call', _236 => _236()]);
4641
+ const ch = _optionalChain([this, 'access', _237 => _237.session, 'optionalAccess', _238 => _238.thickChannels, 'call', _239 => _239()]);
4564
4642
  this.liveThick = ch ? { layerId, channels: ch } : null;
4565
4643
  this.emit(rects);
4566
4644
  },
@@ -4572,7 +4650,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4572
4650
  const wetStroke = Boolean(s.init.wet);
4573
4651
  if (wetStroke) this.wet.driver = null;
4574
4652
  const brush = s.init.brush;
4575
- if (!cancelled && _optionalChain([s, 'access', _237 => _237.result, 'optionalAccess', _238 => _238.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
4653
+ if (!cancelled && _optionalChain([s, 'access', _240 => _240.result, 'optionalAccess', _241 => _241.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
4576
4654
  if (cancelled || !surface) {
4577
4655
  if (this.wetOp) {
4578
4656
  const snap = this.wetOp.before;
@@ -4597,7 +4675,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4597
4675
  const ch = s.thickChannels();
4598
4676
  const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
4599
4677
  const sprayed = s.stickers();
4600
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _239 => _239.doc, 'access', _240 => _240.stickers, 'optionalAccess', _241 => _241[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
4678
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _242 => _242.doc, 'access', _243 => _243.stickers, 'optionalAccess', _244 => _244[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
4601
4679
  this.commit(`${brush.name} stroke`, this.withWetEvents({ ...this.doc, layers: _chunkHGTDMKNEcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {} }), wetStroke ? before : this.doc);
4602
4680
  }
4603
4681
  };
@@ -4635,7 +4713,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4635
4713
  layers: _chunkHGTDMKNEcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
4636
4714
  strokes: [...out.strokes, stroke],
4637
4715
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
4638
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _242 => _242.stickers, 'optionalAccess', _243 => _243[l.id]]), () => ( [])), ...sprayed] } } : {}
4716
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _245 => _245.stickers, 'optionalAccess', _246 => _246[l.id]]), () => ( [])), ...sprayed] } } : {}
4639
4717
  };
4640
4718
  }
4641
4719
  };
@@ -4693,7 +4771,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4693
4771
  */
4694
4772
  replayStrokes(options) {
4695
4773
  this.requireIdle("replaying");
4696
- if (!_optionalChain([options, 'access', _244 => _244.strokeIds, 'optionalAccess', _245 => _245.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
4774
+ if (!_optionalChain([options, 'access', _247 => _247.strokeIds, 'optionalAccess', _248 => _248.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
4697
4775
  const strokes = options.strokeIds.map((id) => {
4698
4776
  const s = this.doc.strokes.find((x) => x.id === id);
4699
4777
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -4723,13 +4801,13 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4723
4801
  let brush = v.brush;
4724
4802
  if (options.brushId !== void 0) {
4725
4803
  const b = this.requireBrush(options.brushId);
4726
- brush = _chunkBXMIBMVGcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
4804
+ brush = _chunkJGKCC5OFcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
4727
4805
  }
4728
4806
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
4729
4807
  if (!_chunkHGTDMKNEcjs.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.`);
4730
4808
  let load = s.load;
4731
4809
  if (load && options.color !== void 0 && load.reservoir) {
4732
- const [r, g, b] = _chunkBXMIBMVGcjs.hexToRgb8.call(void 0, options.color);
4810
+ const [r, g, b] = _chunkJGKCC5OFcjs.hexToRgb8.call(void 0, options.color);
4733
4811
  load = { ...load, reservoir: [r / 255, g / 255, b / 255] };
4734
4812
  }
4735
4813
  const paint = v.paint && options.color === void 0 ? { paint: v.paint } : {};
@@ -4769,7 +4847,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4769
4847
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
4770
4848
  if (!id) return null;
4771
4849
  this.requireLayer(id);
4772
- const ch = _optionalChain([this, 'access', _246 => _246.doc, 'access', _247 => _247.thick, 'optionalAccess', _248 => _248[id]]);
4850
+ const ch = _optionalChain([this, 'access', _249 => _249.doc, 'access', _250 => _250.thick, 'optionalAccess', _251 => _251[id]]);
4773
4851
  if (!ch) return null;
4774
4852
  const r = reliefInfo(ch);
4775
4853
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -4874,7 +4952,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4874
4952
  wetState() {
4875
4953
  const st = this.getState().wet;
4876
4954
  const backend = this.wet.backend();
4877
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _249 => _249.message]), () => ( _chunkGNK7SESQcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
4955
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _252 => _252.message]), () => ( _chunkGNK7SESQcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
4878
4956
  }
4879
4957
  /**
4880
4958
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -4959,7 +5037,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4959
5037
  }
4960
5038
  /** Records a settings change as a wet event (not an undo step). */
4961
5039
  recordWetSetting(e) {
4962
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _250 => _250.wet, 'access', _251 => _251.world, 'optionalAccess', _252 => _252.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
5040
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _253 => _253.wet, 'access', _254 => _254.world, 'optionalAccess', _255 => _255.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
4963
5041
  }
4964
5042
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
4965
5043
  setWetParams(layerId, update) {
@@ -5026,7 +5104,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5026
5104
  currentLayers() {
5027
5105
  const live = this.live;
5028
5106
  if (!live) return this.doc.layers;
5029
- if (_optionalChain([this, 'access', _253 => _253.liveLayers, 'optionalAccess', _254 => _254.key]) === live.surface) return this.liveLayers.layers;
5107
+ if (_optionalChain([this, 'access', _256 => _256.liveLayers, 'optionalAccess', _257 => _257.key]) === live.surface) return this.liveLayers.layers;
5030
5108
  const layers = _chunkHGTDMKNEcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
5031
5109
  this.liveLayers = { key: live.surface, layers };
5032
5110
  return layers;
@@ -5049,7 +5127,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5049
5127
  tracingNode(t) {
5050
5128
  const { width, height } = this.doc.canvas;
5051
5129
  const key = this.tracingVersion * 100003 + width * 7 + height;
5052
- if (_optionalChain([this, 'access', _255 => _255.tracingCache, 'optionalAccess', _256 => _256.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
5130
+ if (_optionalChain([this, 'access', _258 => _258.tracingCache, 'optionalAccess', _259 => _259.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
5053
5131
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
5054
5132
  const image = resampleInto(src, t.rect, width, height);
5055
5133
  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 };
@@ -5076,8 +5154,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5076
5154
  let out = layers;
5077
5155
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
5078
5156
  for (const id of ids) {
5079
- const ch = _optionalChain([live, 'optionalAccess', _257 => _257.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _258 => _258[id]]);
5080
- const l = ch && _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, out, id), 'optionalAccess', _259 => _259.layer]);
5157
+ const ch = _optionalChain([live, 'optionalAccess', _260 => _260.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _261 => _261[id]]);
5158
+ const l = ch && _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, out, id), 'optionalAccess', _262 => _262.layer]);
5081
5159
  if (!ch || !isPixelLayer(l)) continue;
5082
5160
  let cache = this.litCaches.get(id);
5083
5161
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -5090,7 +5168,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5090
5168
  let layers = this.litLayers((_nullishCoalesce(options.wet, () => ( "display"))) === "dried" ? this.driedLayers() : this.currentLayers());
5091
5169
  if (options.layerIds) {
5092
5170
  const picked = [];
5093
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _260 => _260.layer]), () => ( this.requireLayer(id))));
5171
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _263 => _263.layer]), () => ( this.requireLayer(id))));
5094
5172
  layers = picked.map((l) => ({ ...l, visible: true }));
5095
5173
  }
5096
5174
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -5106,7 +5184,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5106
5184
  */
5107
5185
  compositeTiles(rect, onTile, options = {}) {
5108
5186
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
5109
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _261 => _261.live, 'optionalAccess', _262 => _262.layerId]), () => ( this.doc.activeLayerId)) });
5187
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _264 => _264.live, 'optionalAccess', _265 => _265.layerId]), () => ( this.doc.activeLayerId)) });
5110
5188
  }
5111
5189
  /** The canvas as canvas-sized RGBA (paper included by default). */
5112
5190
  compositePixels(options = {}) {
@@ -5170,7 +5248,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5170
5248
  for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.stickers, () => ( {})))) if (list.length && _chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id)) stickers[id] = list.map((x) => ({ ...x }));
5171
5249
  if (Object.keys(stickers).length) ext.stickers = stickers;
5172
5250
  else delete ext.stickers;
5173
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _263 => _263.layer])));
5251
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _266 => _266.layer])));
5174
5252
  if (effectLayers) ext.effectLayers = effectLayers;
5175
5253
  else delete ext.effectLayers;
5176
5254
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -5187,7 +5265,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5187
5265
  const stickers = {};
5188
5266
  for (const [id, list] of Object.entries(ext.stickers)) {
5189
5267
  if (!_chunkHGTDMKNEcjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
5190
- const ok = list.filter((x) => x && typeof x.id === "string" && _chunkBXMIBMVGcjs.STAMP_KINDS.includes(x.stamp) && Number.isFinite(x.x) && Number.isFinite(x.y) && x.size > 0);
5268
+ const ok = list.filter((x) => x && typeof x.id === "string" && _chunkJGKCC5OFcjs.STAMP_KINDS.includes(x.stamp) && Number.isFinite(x.x) && Number.isFinite(x.y) && x.size > 0);
5191
5269
  if (ok.length !== list.length) problems.push(`Some stickers of layer "${id}" could not be read; they were dropped.`);
5192
5270
  stickers[id] = ok.map((x) => ({ ...x }));
5193
5271
  }
@@ -5196,7 +5274,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5196
5274
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
5197
5275
  const effectLayers = {};
5198
5276
  for (const [id, v] of Object.entries(ext.effectLayers)) {
5199
- if (!isPixelLayer(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _264 => _264.layer]))) continue;
5277
+ if (!isPixelLayer(_optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _267 => _267.layer]))) continue;
5200
5278
  const source = readPaintEffectSource(v);
5201
5279
  if (source) effectLayers[id] = source;
5202
5280
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -5237,7 +5315,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5237
5315
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
5238
5316
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
5239
5317
  for (const s of loaded.state.strokes) {
5240
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _265 => _265.exec, 'call', _266 => _266(s.id), 'optionalAccess', _267 => _267[1]]), () => ( 0)));
5318
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _268 => _268.exec, 'call', _269 => _269(s.id), 'optionalAccess', _270 => _270[1]]), () => ( 0)));
5241
5319
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
5242
5320
  }
5243
5321
  this.undoStack = [];
@@ -5329,10 +5407,10 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5329
5407
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
5330
5408
  });
5331
5409
  const layers = toStandard(dried);
5332
- const result = _chunkPI45JMP7cjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
5410
+ const result = _chunkCD7PLU77cjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
5333
5411
  for (const [mode, names] of changed) {
5334
- const label = _nullishCoalesce(_optionalChain([_chunkCWM3CUUXcjs.BLEND_MODES, 'access', _268 => _268.find, 'call', _269 => _269((m) => m.id === mode), 'optionalAccess', _270 => _270.label]), () => ( mode));
5335
- const std = _nullishCoalesce(_optionalChain([_chunkCWM3CUUXcjs.BLEND_MODES, 'access', _271 => _271.find, 'call', _272 => _272((m) => m.id === _chunkCWM3CUUXcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _273 => _273.label]), () => ( _chunkCWM3CUUXcjs.standardBlendMode.call(void 0, mode)));
5412
+ const label = _nullishCoalesce(_optionalChain([_chunkCWM3CUUXcjs.BLEND_MODES, 'access', _271 => _271.find, 'call', _272 => _272((m) => m.id === mode), 'optionalAccess', _273 => _273.label]), () => ( mode));
5413
+ const std = _nullishCoalesce(_optionalChain([_chunkCWM3CUUXcjs.BLEND_MODES, 'access', _274 => _274.find, 'call', _275 => _275((m) => m.id === _chunkCWM3CUUXcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _276 => _276.label]), () => ( _chunkCWM3CUUXcjs.standardBlendMode.call(void 0, mode)));
5336
5414
  const list = names.map((n) => `"${n}"`).join(", ");
5337
5415
  const one = names.length === 1;
5338
5416
  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).`);
@@ -5448,7 +5526,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5448
5526
  const { src, pixels } = this.importImage(options, "The reference image");
5449
5527
  const ref2 = {
5450
5528
  id: `ref${this.nextReferenceId++}`,
5451
- name: _optionalChain([options, 'access', _274 => _274.name, 'optionalAccess', _275 => _275.trim, 'call', _276 => _276()]) || `Reference ${this.guides.references.length + 1}`,
5529
+ name: _optionalChain([options, 'access', _277 => _277.name, 'optionalAccess', _278 => _278.trim, 'call', _279 => _279()]) || `Reference ${this.guides.references.length + 1}`,
5452
5530
  src,
5453
5531
  width: pixels.width,
5454
5532
  height: pixels.height,
@@ -5527,7 +5605,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5527
5605
  try {
5528
5606
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
5529
5607
  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 });
5530
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _277 => _277.exec, 'call', _278 => _278(ref2.id), 'optionalAccess', _279 => _279[1]]), () => ( 0)));
5608
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _280 => _280.exec, 'call', _281 => _281(ref2.id), 'optionalAccess', _282 => _282[1]]), () => ( 0)));
5531
5609
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
5532
5610
  } catch (e) {
5533
5611
  problems.push(e.message);
@@ -5538,7 +5616,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5538
5616
  guides.stencils = [];
5539
5617
  r.stencils.forEach((raw2, i) => {
5540
5618
  try {
5541
- const id = typeof _optionalChain([raw2, 'optionalAccess', _280 => _280.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
5619
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _283 => _283.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
5542
5620
  guides.stencils.push(normalizeStencil(raw2, id));
5543
5621
  const n = Number(id.slice(7));
5544
5622
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -5561,12 +5639,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5561
5639
  /** The next free sticker number (ids `st<n>` are unique across the document). */
5562
5640
  nextStickerNumber(doc = this.doc) {
5563
5641
  let n = 0;
5564
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _281 => _281.exec, 'call', _282 => _282(st.id), 'optionalAccess', _283 => _283[1]]), () => ( 0))));
5642
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _284 => _284.exec, 'call', _285 => _285(st.id), 'optionalAccess', _286 => _286[1]]), () => ( 0))));
5565
5643
  return n + 1;
5566
5644
  }
5567
5645
  stickerLayer(layerId) {
5568
5646
  const l = this.wetLayer(layerId, "edit the stickers of");
5569
- const stickers = _optionalChain([this, 'access', _284 => _284.doc, 'access', _285 => _285.stickers, 'optionalAccess', _286 => _286[l.id]]);
5647
+ const stickers = _optionalChain([this, 'access', _287 => _287.doc, 'access', _288 => _288.stickers, 'optionalAccess', _289 => _289[l.id]]);
5570
5648
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (list_brushes category sticker).`);
5571
5649
  return { layer: l, stickers };
5572
5650
  }
@@ -5575,12 +5653,12 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5575
5653
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
5576
5654
  if (!id) return [];
5577
5655
  this.requireLayer(id);
5578
- return (_nullishCoalesce(_optionalChain([this, 'access', _287 => _287.doc, 'access', _288 => _288.stickers, 'optionalAccess', _289 => _289[id]]), () => ( []))).map((s) => ({ ...s }));
5656
+ return (_nullishCoalesce(_optionalChain([this, 'access', _290 => _290.doc, 'access', _291 => _291.stickers, 'optionalAccess', _292 => _292[id]]), () => ( []))).map((s) => ({ ...s }));
5579
5657
  }
5580
5658
  /** Replaces a layer's stickers and redraws its pixels from them (one undo step). */
5581
5659
  commitStickers(label, layer, stickers) {
5582
5660
  if (_chunkHGTDMKNEcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
5583
- const surface = _chunkBXMIBMVGcjs.stickerSurface.call(void 0, stickers);
5661
+ const surface = _chunkJGKCC5OFcjs.stickerSurface.call(void 0, stickers);
5584
5662
  const doc = { ...this.doc, layers: _chunkHGTDMKNEcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: stickers } };
5585
5663
  this.commit(label, this.withPaintEvent(doc, { kind: "stickers", layerId: layer.id, data: { stickers: stickers.map((s) => ({ ...s })) } }));
5586
5664
  }
@@ -5591,7 +5669,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5591
5669
  if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
5592
5670
  let u;
5593
5671
  try {
5594
- u = _chunkBXMIBMVGcjs.normalizeStickerUpdate.call(void 0, update);
5672
+ u = _chunkJGKCC5OFcjs.normalizeStickerUpdate.call(void 0, update);
5595
5673
  } catch (e) {
5596
5674
  throw new PaintEditorError(e.message);
5597
5675
  }
@@ -5631,7 +5709,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5631
5709
  stencilSelection(stencils = this.guides.stencils) {
5632
5710
  const { width, height } = this.doc.canvas;
5633
5711
  const size = `${width}x${height}`;
5634
- if (_optionalChain([this, 'access', _290 => _290.stencilCache, 'optionalAccess', _291 => _291.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
5712
+ if (_optionalChain([this, 'access', _293 => _293.stencilCache, 'optionalAccess', _294 => _294.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
5635
5713
  const mask = stencilMask(stencils, width, height);
5636
5714
  this.stencilCache = { key: stencils, size, mask };
5637
5715
  return mask;
@@ -5692,8 +5770,8 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5692
5770
  }
5693
5771
  makeSwatch(color, name) {
5694
5772
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
5695
- const out = { color: _chunkLRRCMRSLcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
5696
- if (_optionalChain([name, 'optionalAccess', _292 => _292.trim, 'call', _293 => _293()])) out.name = name.trim();
5773
+ const out = { color: _chunkEBDCRTZIcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
5774
+ if (_optionalChain([name, 'optionalAccess', _295 => _295.trim, 'call', _296 => _296()])) out.name = name.trim();
5697
5775
  if (p.type === "gradient") out.paint = p;
5698
5776
  return out;
5699
5777
  }
@@ -5745,7 +5823,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5745
5823
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
5746
5824
  */
5747
5825
  mixOnPad(paints, options = {}) {
5748
- const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _294 => _294.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _295 => _295.parts]) }));
5826
+ const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _297 => _297.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _298 => _298.parts]) }));
5749
5827
  let r;
5750
5828
  try {
5751
5829
  r = this.pad.mix(parsed, options);
@@ -5834,11 +5912,65 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5834
5912
  }
5835
5913
  /** A layer's tile surface (live while stroking), for thumbnails. */
5836
5914
  layerSurface(id) {
5837
- const l = _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _296 => _296.layer]);
5915
+ const l = _optionalChain([_chunkHGTDMKNEcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _299 => _299.layer]);
5838
5916
  return isPixelLayer(l) ? l.surface : null;
5839
5917
  }
5840
5918
  }, _class10);
5841
5919
  var MAX_IMAGE_SIDE = 8192;
5920
+ var movePoint = (p, dx, dy) => ({ x: p.x + dx, y: p.y + dy });
5921
+ var moveRect = (r, dx, dy) => ({ ...r, x: r.x + dx, y: r.y + dy });
5922
+ function shiftDocument(doc, dx, dy) {
5923
+ if (!dx && !dy) return doc;
5924
+ let layers = doc.layers;
5925
+ for (const l of _chunkHGTDMKNEcjs.flattenLayers.call(void 0, doc.layers)) if (l.type === "pixel") layers = _chunkHGTDMKNEcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, offset: movePoint(l.offset, dx, dy) }));
5926
+ const m = [1, 0, 0, 1, dx, dy];
5927
+ const moveStickers = (list) => list.map((s) => ({ ...s, x: Math.round((s.x + dx) * 100) / 100, y: Math.round((s.y + dy) * 100) / 100 }));
5928
+ const out = {
5929
+ ...doc,
5930
+ layers,
5931
+ paper: { ...doc.paper, offset: movePoint(_nullishCoalesce(doc.paper.offset, () => ( { x: 0, y: 0 })), dx, dy) },
5932
+ origin: movePoint(_nullishCoalesce(doc.origin, () => ( { x: 0, y: 0 })), -dx, -dy),
5933
+ strokes: doc.strokes.map((s) => {
5934
+ const moved = varyStroke(s, m, {});
5935
+ return s.stencils ? { ...moved, stencils: s.stencils.map((x) => translateStencil(x, dx, dy)) } : moved;
5936
+ })
5937
+ };
5938
+ if (doc.stickers) out.stickers = Object.fromEntries(Object.entries(doc.stickers).map(([id, list]) => [id, moveStickers(list)]));
5939
+ if (doc.paintEvents) {
5940
+ out.paintEvents = doc.paintEvents.map((e) => {
5941
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _300 => _300.data, 'optionalAccess', _301 => _301.stickers]) : void 0;
5942
+ return list ? { ...e, data: { ...e.data, stickers: moveStickers(list) } } : e;
5943
+ });
5944
+ }
5945
+ if (doc.wetEvents) {
5946
+ out.wetEvents = doc.wetEvents.map((e) => {
5947
+ const d = e.data;
5948
+ if (!d) return e;
5949
+ if (e.kind === "dry" && typeof d.x === "number") return { ...e, data: moveRect(d, dx, dy) };
5950
+ if (e.kind === "wet-paper" && d.rect) return { ...e, data: { ...d, rect: moveRect(d.rect, dx, dy) } };
5951
+ if (e.kind === "flow" && d.center) return { ...e, data: { ...d, center: movePoint(d.center, dx, dy) } };
5952
+ return e;
5953
+ });
5954
+ }
5955
+ if (doc.paperEffect) {
5956
+ const src = doc.paperEffect.image;
5957
+ const width = src.width + dx;
5958
+ const height = src.height + dy;
5959
+ const data = new Uint8ClampedArray(width * height * 4);
5960
+ for (let y = 0; y < src.height; y++) data.set(src.data.subarray(y * src.width * 4, (y + 1) * src.width * 4), ((y + dy) * width + dx) * 4);
5961
+ out.paperEffect = { ...doc.paperEffect, image: { width, height, data }, version: nextPaperEffectVersion() };
5962
+ }
5963
+ return out;
5964
+ }
5965
+ function shiftGuides(g, dx, dy) {
5966
+ return {
5967
+ ...g,
5968
+ symmetry: { ...g.symmetry, center: movePoint(g.symmetry.center, dx, dy) },
5969
+ perspective: { ...g.perspective, points: g.perspective.points.map((p) => movePoint(p, dx, dy)) },
5970
+ tracing: g.tracing ? { ...g.tracing, rect: moveRect(g.tracing.rect, dx, dy) } : null,
5971
+ stencils: g.stencils.map((s) => translateStencil(s, dx, dy))
5972
+ };
5973
+ }
5842
5974
  function resampleInto(src, rect, width, height) {
5843
5975
  const out = new Uint8ClampedArray(width * height * 4);
5844
5976
  const x0 = Math.max(0, Math.floor(rect.x));
@@ -5888,8 +6020,8 @@ function strokeSchedule(points) {
5888
6020
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
5889
6021
  }
5890
6022
  function strokeDuration(points, max = 1800) {
5891
- const t0 = _optionalChain([points, 'access', _297 => _297[0], 'optionalAccess', _298 => _298.t]);
5892
- const t1 = _optionalChain([points, 'access', _299 => _299[points.length - 1], 'optionalAccess', _300 => _300.t]);
6023
+ const t0 = _optionalChain([points, 'access', _302 => _302[0], 'optionalAccess', _303 => _303.t]);
6024
+ const t1 = _optionalChain([points, 'access', _304 => _304[points.length - 1], 'optionalAccess', _305 => _305.t]);
5893
6025
  let ms;
5894
6026
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
5895
6027
  else {
@@ -5943,7 +6075,7 @@ var PaintDirector = class {
5943
6075
  }
5944
6076
  where(id) {
5945
6077
  const a = this.presence.get(id);
5946
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _301 => _301.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _302 => _302.y]), () => ( 0)) };
6078
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _306 => _306.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _307 => _307.y]), () => ( 0)) };
5947
6079
  }
5948
6080
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
5949
6081
  async glide(id, to, ms = 380) {
@@ -5990,8 +6122,8 @@ var PaintDirector = class {
5990
6122
  }
5991
6123
  case "replay": {
5992
6124
  await this.say(id, command.note, 500);
5993
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _303 => _303.replay, 'access', _304 => _304.strokeIds, 'optionalAccess', _305 => _305.includes, 'call', _306 => _306(s.id)]));
5994
- const first = _optionalChain([source, 'access', _307 => _307[0], 'optionalAccess', _308 => _308.points, 'access', _309 => _309[0]]);
6125
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _308 => _308.replay, 'access', _309 => _309.strokeIds, 'optionalAccess', _310 => _310.includes, 'call', _311 => _311(s.id)]));
6126
+ const first = _optionalChain([source, 'access', _312 => _312[0], 'optionalAccess', _313 => _313.points, 'access', _314 => _314[0]]);
5995
6127
  if (first) await this.glide(id, first);
5996
6128
  const result = c.replayStrokes(command.replay);
5997
6129
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -6103,7 +6235,7 @@ function createPaintStickerTools(c) {
6103
6235
  properties: {
6104
6236
  layerId: LAYER_ID,
6105
6237
  id: { type: "string", description: "Sticker id from list_stickers." },
6106
- stamp: { type: "string", enum: [..._chunkBXMIBMVGcjs.STAMP_KINDS], description: "Another stamp." },
6238
+ stamp: { type: "string", enum: [..._chunkJGKCC5OFcjs.STAMP_KINDS], description: "Another stamp." },
6107
6239
  x: { type: "number", description: "Centre x in document pixels." },
6108
6240
  y: { type: "number", description: "Centre y in document pixels." },
6109
6241
  size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels." },
@@ -6400,7 +6532,7 @@ function createPaintGuideTools(c) {
6400
6532
  type: "object",
6401
6533
  properties: {
6402
6534
  color: { ...COLOR2, description: "A colour #rrggbb." },
6403
- paint: { ..._chunkLRRCMRSLcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
6535
+ paint: { ..._chunkEBDCRTZIcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
6404
6536
  name: { type: "string", minLength: 1, description: "Optional name." }
6405
6537
  },
6406
6538
  additionalProperties: false
@@ -6905,7 +7037,7 @@ var TIP = {
6905
7037
  type: "object",
6906
7038
  description: "The tip (the shared brush engine). Missing fields keep their current values.",
6907
7039
  properties: {
6908
- size: { type: "number", minimum: 1, maximum: _chunkLRRCMRSLcjs.MAX_BRUSH_SIZE, description: "Diameter in document pixels." },
7040
+ size: { type: "number", minimum: 1, maximum: _chunkEBDCRTZIcjs.MAX_BRUSH_SIZE, description: "Diameter in document pixels." },
6909
7041
  hardness: { type: "number", minimum: 0, maximum: 1, description: "Edge hardness, 0 (soft) .. 1 (hard)." },
6910
7042
  spacing: { type: "number", minimum: 0.01, maximum: 10, description: "Dab spacing as a fraction of the diameter (0.05 is smooth, 1 is dotted)." },
6911
7043
  angle: { type: "number", minimum: -360, maximum: 360, description: "Tip angle in degrees, counter-clockwise; with rotation stroke or barrel it is added to the stroke direction or pen rotation." },
@@ -6950,11 +7082,11 @@ var MIXER = {
6950
7082
  mix: { type: "number", minimum: 0, maximum: 1, description: "Mix ratio: how far each dab's paint moves from the reservoir towards the picked-up colour." },
6951
7083
  loadEachStroke: { type: "boolean", description: "Refill the reservoir with the colour before each stroke." },
6952
7084
  cleanEachStroke: { type: "boolean", description: "Empty the pickup well after each stroke." },
6953
- mixing: { type: "string", enum: [..._chunkLRRCMRSLcjs.MIXING_MODELS], description: "rgb: RGB averages. pigment: mixes like paint (Kubelka-Munk)." }
7085
+ mixing: { type: "string", enum: [..._chunkEBDCRTZIcjs.MIXING_MODELS], description: "rgb: RGB averages. pigment: mixes like paint (Kubelka-Munk)." }
6954
7086
  },
6955
7087
  additionalProperties: false
6956
7088
  };
6957
- var MIXING = { type: "string", enum: [..._chunkLRRCMRSLcjs.MIXING_MODELS], description: "pigment: mixes like paint (Kubelka-Munk, blue and yellow make green); rgb: straight RGB averages." };
7089
+ var MIXING = { type: "string", enum: [..._chunkEBDCRTZIcjs.MIXING_MODELS], description: "pigment: mixes like paint (Kubelka-Munk, blue and yellow make green); rgb: straight RGB averages." };
6958
7090
  var BEHAVIOR = {
6959
7091
  type: "object",
6960
7092
  description: "How the brush handles paint on the canvas (dab and mixer engines; on a mixer brush pickup, mix, dirty and mixing are its mixer wet, mix, !cleanEachStroke and mixing). Missing fields keep their current values.",
@@ -6967,7 +7099,7 @@ var BEHAVIOR = {
6967
7099
  type: "object",
6968
7100
  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.",
6969
7101
  properties: {
6970
- mode: { type: "string", enum: [..._chunkBXMIBMVGcjs.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." },
7102
+ mode: { type: "string", enum: [..._chunkJGKCC5OFcjs.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." },
6971
7103
  colors: { type: "array", maxItems: 8, items: { ...COLOR3 }, description: "2..8 colours #rrggbb; fewer than 2 uses the paint colour and the secondary colour." },
6972
7104
  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)." },
6973
7105
  length: { type: "integer", minimum: 1, maximum: 500, description: "dab mode: dabs per colour (default 12)." },
@@ -6980,7 +7112,7 @@ var BEHAVIOR = {
6980
7112
  };
6981
7113
  var BRUSH_PAINT = {
6982
7114
  description: `The brush's own gradient paint, used instead of the editor's paint (null: the editor's paint). It is what the multi-colour settings became; stops may be "paint" / "secondary" for the editor's two colours.`,
6983
- anyOf: [_chunkLRRCMRSLcjs.PAINT_GRADIENT_JSON_SCHEMA, { type: "null", description: "No gradient of its own: the editor's paint." }]
7115
+ anyOf: [_chunkEBDCRTZIcjs.PAINT_GRADIENT_JSON_SCHEMA, { type: "null", description: "No gradient of its own: the editor's paint." }]
6984
7116
  };
6985
7117
  var BLENDER = {
6986
7118
  type: "object",
@@ -7008,10 +7140,10 @@ var WET_BRUSH = {
7008
7140
  properties: {
7009
7141
  tool: {
7010
7142
  type: "string",
7011
- enum: [..._chunkBXMIBMVGcjs.WET_TOOLS],
7143
+ enum: [..._chunkJGKCC5OFcjs.WET_TOOLS],
7012
7144
  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)."
7013
7145
  },
7014
- medium: { type: "string", enum: [..._chunkBXMIBMVGcjs.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)." },
7146
+ medium: { type: "string", enum: [..._chunkJGKCC5OFcjs.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)." },
7015
7147
  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)." },
7016
7148
  thinner: { type: "number", minimum: 0, maximum: 1, description: "Thinner (water or solvent): more transparent, runnier paint." },
7017
7149
  water: { type: "number", minimum: 0, maximum: 1, description: "Wetness: water laid per stroke, 0.2 a damp brush .. 1 a dripping one." },
@@ -7028,7 +7160,7 @@ var IMPASTO_BRUSH = {
7028
7160
  properties: {
7029
7161
  tool: {
7030
7162
  type: "string",
7031
- enum: [..._chunkBXMIBMVGcjs.IMPASTO_TOOLS],
7163
+ enum: [..._chunkJGKCC5OFcjs.IMPASTO_TOOLS],
7032
7164
  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."
7033
7165
  },
7034
7166
  thickness: { type: "number", minimum: 0, maximum: 1, description: "How far the paint stands up." },
@@ -7044,8 +7176,8 @@ var PARTICLE_BRUSH = {
7044
7176
  type: "object",
7045
7177
  description: "Particle engine settings (procedural brushes). Missing fields keep their current values.",
7046
7178
  properties: {
7047
- kind: { type: "string", enum: [..._chunkBXMIBMVGcjs.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." },
7048
- render: { type: "string", enum: [..._chunkBXMIBMVGcjs.PARTICLE_RENDERS], description: "dot: a mark at each step; line: each particle draws a continuous line; sequence: beads spaced along each path." },
7179
+ kind: { type: "string", enum: [..._chunkJGKCC5OFcjs.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." },
7180
+ render: { type: "string", enum: [..._chunkJGKCC5OFcjs.PARTICLE_RENDERS], description: "dot: a mark at each step; line: each particle draws a continuous line; sequence: beads spaced along each path." },
7049
7181
  count: { type: "integer", minimum: 1, maximum: 64, description: "Particles (flow: how many are thrown per tip of travel)." },
7050
7182
  size: { type: "number", minimum: 0, maximum: 1, description: "Mark size as a fraction of the tip size." },
7051
7183
  spread: { type: "number", minimum: 0, maximum: 1, description: "How far apart the particles start, as a fraction of the tip size." },
@@ -7075,7 +7207,7 @@ var STICKER_BRUSH = {
7075
7207
  type: "object",
7076
7208
  description: "Sticker engine settings: stamps sprayed along the stroke as editable stickers. Missing fields keep their current values.",
7077
7209
  properties: {
7078
- stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [..._chunkBXMIBMVGcjs.STAMP_KINDS], description: "A stamp." }, description: "The stamps to spray (one picked at random per sticker)." },
7210
+ stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [..._chunkJGKCC5OFcjs.STAMP_KINDS], description: "A stamp." }, description: "The stamps to spray (one picked at random per sticker)." },
7079
7211
  density: { type: "number", minimum: 0, maximum: 1, description: "Stickers per distance travelled." },
7080
7212
  sizeJitter: { type: "number", minimum: 0, maximum: 1, description: "Random size change." },
7081
7213
  rotationJitter: { type: "number", minimum: 0, maximum: 1, description: "Random turn as a fraction of \xB1180\xB0." },
@@ -7086,16 +7218,16 @@ var STICKER_BRUSH = {
7086
7218
  };
7087
7219
  var BRUSH_FIELDS = {
7088
7220
  name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." },
7089
- category: { type: "string", enum: [..._chunkBXMIBMVGcjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
7221
+ category: { type: "string", enum: [..._chunkJGKCC5OFcjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
7090
7222
  engine: {
7091
7223
  type: "string",
7092
- enum: [..._chunkBXMIBMVGcjs.PAINT_BRUSH_ENGINES],
7224
+ enum: [..._chunkJGKCC5OFcjs.PAINT_BRUSH_ENGINES],
7093
7225
  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)."
7094
7226
  },
7095
7227
  tip: TIP,
7096
7228
  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." },
7097
7229
  pressureSmoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Pressure smoothing, separate from the tip position smoothing." },
7098
- rotation: { type: "string", enum: [..._chunkBXMIBMVGcjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
7230
+ rotation: { type: "string", enum: [..._chunkJGKCC5OFcjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
7099
7231
  dynamics: DYNAMICS,
7100
7232
  mixer: MIXER,
7101
7233
  loadsColor: { type: "boolean", description: "Mixer engine: load the colour each stroke (false for a mixer that only moves paint)." },
@@ -7145,7 +7277,7 @@ function brushSummary(b) {
7145
7277
  size: b.tip.size,
7146
7278
  grain: b.grain,
7147
7279
  rotation: b.rotation,
7148
- wetCapable: _chunkBXMIBMVGcjs.isWetCapable.call(void 0, b),
7280
+ wetCapable: _chunkJGKCC5OFcjs.isWetCapable.call(void 0, b),
7149
7281
  pickup: b.behavior.pickup,
7150
7282
  dirty: b.behavior.dirty,
7151
7283
  multicolor: b.behavior.multicolor.mode,
@@ -7167,7 +7299,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7167
7299
  add({
7168
7300
  name: "get_canvas_info",
7169
7301
  title: "Get the canvas",
7170
- description: "Reads the canvas: size in pixels and dpi, the paper (preset, colour, grain depth), the active layer, the active brush id, the paint colour, the view (zoom, rotation, mirror), the hand, how many strokes are recorded, the undo / redo labels, and the blend modes. Call it first.",
7302
+ description: "Reads the canvas: size in pixels and dpi, its origin (where (0, 0) is relative to the canvas it was extended from), the paper (preset, colour, grain depth), the active layer, the active brush id, the paint colour, the view (zoom, rotation, mirror), the hand, how many strokes are recorded, the undo / redo labels, and the blend modes. Call it first.",
7171
7303
  inputSchema: EMPTY3,
7172
7304
  annotations: { title: "Get the canvas", ...READ6 },
7173
7305
  handler: () => {
@@ -7177,6 +7309,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7177
7309
  width: d.canvas.width,
7178
7310
  height: d.canvas.height,
7179
7311
  dpi: d.canvas.dpi,
7312
+ origin: { ..._nullishCoalesce(d.origin, () => ( { x: 0, y: 0 })) },
7180
7313
  paper: { preset: d.paper.preset, name: d.paper.name, color: d.paper.color, depth: d.paper.depth },
7181
7314
  activeLayerId: d.activeLayerId,
7182
7315
  layerCount: c.listLayers().length,
@@ -7230,6 +7363,19 @@ function createPaintEditorToolProvider(controller, options = {}) {
7230
7363
  annotations: { title: "Resize the canvas", ...SET4 },
7231
7364
  handler: (a) => c.setCanvas({ width: a.width, height: a.height, dpi: a.dpi })
7232
7365
  });
7366
+ const EXTEND_SIDE = (side) => ({ type: "integer", minimum: 0, maximum: MAX_CANVAS_SIDE - 1, description: `Pixels to add on the ${side} (default 0).` });
7367
+ add({
7368
+ name: "extend_canvas",
7369
+ title: "Extend the canvas",
7370
+ description: "Grows the canvas by adding pixels on any side, keeping everything painted. Adding on the left or top moves the whole picture (layers, paper grain, guides, stencils, recorded strokes) right or down by that much in document pixels, so coordinates you read before change by (+left, +top). Wet paint dries first. One undo step. Returns the canvas, rect (the new canvas in the previous coordinates: x -left, y -top) and origin.",
7371
+ inputSchema: {
7372
+ type: "object",
7373
+ properties: { left: EXTEND_SIDE("left"), top: EXTEND_SIDE("top"), right: EXTEND_SIDE("right"), bottom: EXTEND_SIDE("bottom") },
7374
+ additionalProperties: false
7375
+ },
7376
+ annotations: { title: "Extend the canvas", ...WRITE5 },
7377
+ handler: (a) => c.extendCanvas({ left: a.left, top: a.top, right: a.right, bottom: a.bottom })
7378
+ });
7233
7379
  add({
7234
7380
  name: "list_papers",
7235
7381
  title: "List papers",
@@ -7237,9 +7383,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
7237
7383
  inputSchema: EMPTY3,
7238
7384
  annotations: { title: "List papers", ...READ6 },
7239
7385
  handler: () => ({
7240
- papers: _chunkBXMIBMVGcjs.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 })),
7241
- families: [..._chunkBXMIBMVGcjs.PAPER_FAMILIES],
7242
- patterns: [..._chunkLRRCMRSLcjs.GRAIN_PATTERNS]
7386
+ papers: _chunkJGKCC5OFcjs.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 })),
7387
+ families: [..._chunkJGKCC5OFcjs.PAPER_FAMILIES],
7388
+ patterns: [..._chunkEBDCRTZIcjs.GRAIN_PATTERNS]
7243
7389
  })
7244
7390
  });
7245
7391
  add({
@@ -7270,7 +7416,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7270
7416
  depth: { type: "number", minimum: 0, maximum: 1, description: "Grain depth 0..1 (0: brushes ignore the grain)." },
7271
7417
  scale: { type: "number", minimum: 0.25, maximum: 8, description: "Grain scale: 1 natural, 2 twice as coarse." },
7272
7418
  seed: { type: "integer", minimum: 0, description: "Grain seed: another sheet of the same paper." },
7273
- pattern: { type: "string", enum: [..._chunkLRRCMRSLcjs.GRAIN_PATTERNS], description: "Grain pattern." },
7419
+ pattern: { type: "string", enum: [..._chunkEBDCRTZIcjs.GRAIN_PATTERNS], description: "Grain pattern." },
7274
7420
  tiling: { type: "string", enum: ["repeat", "mirror"], description: "How the grain tile repeats (mirror hides seams)." },
7275
7421
  shading: { type: "number", minimum: 0, maximum: 1, description: "How much the grain shades the paper colour." },
7276
7422
  dry: { ...tuning, description: "Height map tuning for dry media." },
@@ -7449,7 +7595,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7449
7595
  annotations: { title: "List brushes", ...READ6 },
7450
7596
  handler: () => {
7451
7597
  const s = c.getState();
7452
- return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _310 => _310.getBrush, 'call', _311 => _311(s.brush.id), 'optionalAccess', _312 => _312.builtin])), brushes: s.brushes.map(brushSummary) };
7598
+ return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _315 => _315.getBrush, 'call', _316 => _316(s.brush.id), 'optionalAccess', _317 => _317.builtin])), brushes: s.brushes.map(brushSummary) };
7453
7599
  }
7454
7600
  });
7455
7601
  add({
@@ -7460,10 +7606,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
7460
7606
  annotations: { title: "Get a brush", ...READ6 },
7461
7607
  handler: ({ id }) => {
7462
7608
  const st = c.getState();
7463
- if (id === void 0) return { ..._chunkBXMIBMVGcjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
7609
+ if (id === void 0) return { ..._chunkJGKCC5OFcjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
7464
7610
  const b = c.getBrush(id);
7465
7611
  if (!b) throw new Error(`Unknown brush "${id}". Call list_brushes for the ids.`);
7466
- return { ..._chunkBXMIBMVGcjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
7612
+ return { ..._chunkJGKCC5OFcjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
7467
7613
  }
7468
7614
  });
7469
7615
  add({
@@ -7472,7 +7618,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7472
7618
  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.",
7473
7619
  inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brushes to start from." }, ...BRUSH_FIELDS }, additionalProperties: false },
7474
7620
  annotations: { title: "Set the brush", ...SET4 },
7475
- handler: (a) => _chunkBXMIBMVGcjs.brushToJSON.call(void 0, c.setBrush(a))
7621
+ handler: (a) => _chunkJGKCC5OFcjs.brushToJSON.call(void 0, c.setBrush(a))
7476
7622
  });
7477
7623
  add({
7478
7624
  name: "save_brush",
@@ -7488,7 +7634,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7488
7634
  additionalProperties: false
7489
7635
  },
7490
7636
  annotations: { title: "Save a brush", ...SET4 },
7491
- handler: ({ id, name }) => _chunkBXMIBMVGcjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
7637
+ handler: ({ id, name }) => _chunkJGKCC5OFcjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
7492
7638
  });
7493
7639
  add({
7494
7640
  name: "remove_brush",
@@ -7575,7 +7721,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7575
7721
  name: "set_paint",
7576
7722
  title: "Set the paint (colour or gradient)",
7577
7723
  description: 'Sets what strokes paint with: one colour, or gradient paint that changes colour as the stroke goes. Gradient paint: 2..16 stops sorted by offset (#rrggbb, or "paint" / "secondary" for the two editor colours), space pigment (default: mixes like paint) / oklab / srgb, and map: distance (default: the colour changes as the stroke is dragged out, 300 px then mirrored back), pressure, tilt, velocity, direction, time, across-tip or random. Every stroking brush samples it per dab (dab, mixer, watercolour and gouache, oil and impasto, particle, bristle, sticker); erasers, blenders and smudges ignore it, and a brush with its own gradient (get_brush paint) paints that instead. set_color goes back to one colour. Editor state, not an undo step. Returns paint, color and secondaryColor.',
7578
- inputSchema: { type: "object", properties: { paint: _chunkLRRCMRSLcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
7724
+ inputSchema: { type: "object", properties: { paint: _chunkEBDCRTZIcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
7579
7725
  annotations: { title: "Set the paint (colour or gradient)", ...SET4 },
7580
7726
  handler: ({ paint }) => {
7581
7727
  const p = c.setPaint(paint);
@@ -7636,7 +7782,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7636
7782
  brushId: { type: "string", description: "Brush id from list_brushes (default the active brush)." },
7637
7783
  brush: { type: "object", description: "Brush changes for this stroke only.", properties: BRUSH_FIELDS, additionalProperties: false },
7638
7784
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
7639
- paint: { ..._chunkLRRCMRSLcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
7785
+ paint: { ..._chunkEBDCRTZIcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
7640
7786
  seed: { type: "integer", minimum: 0, description: "Jitter seed (default a new one); the same seed and points give the same marks." },
7641
7787
  snapToPerspective: { type: "boolean", description: "Snap the points to the perspective guide, as a pen stroke would (default false)." }
7642
7788
  },
@@ -7684,7 +7830,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
7684
7830
  color: s.color,
7685
7831
  points: ids ? s.points : s.points.length,
7686
7832
  seed: s.seed,
7687
- copies: _nullishCoalesce(_optionalChain([s, 'access', _313 => _313.copies, 'optionalAccess', _314 => _314.length]), () => ( 0)),
7833
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _318 => _318.copies, 'optionalAccess', _319 => _319.length]), () => ( 0)),
7688
7834
  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) }
7689
7835
  };
7690
7836
  })
@@ -7969,12 +8115,12 @@ var PaintGesture = (_class11 = class {
7969
8115
  if (!m || m.pointerId !== e.pointerId) return;
7970
8116
  this.mode = null;
7971
8117
  this.predicted = [];
7972
- if (m.kind === "stroke") _optionalChain([this, 'access', _315 => _315.controller, 'access', _316 => _316.activeStroke, 'optionalAccess', _317 => _317.end, 'call', _318 => _318()]);
8118
+ if (m.kind === "stroke") _optionalChain([this, 'access', _320 => _320.controller, 'access', _321 => _321.activeStroke, 'optionalAccess', _322 => _322.end, 'call', _323 => _323()]);
7973
8119
  }
7974
8120
  cancel() {
7975
8121
  this.penDown = false;
7976
8122
  this.predicted = [];
7977
- if (_optionalChain([this, 'access', _319 => _319.mode, 'optionalAccess', _320 => _320.kind]) === "stroke") _optionalChain([this, 'access', _321 => _321.controller, 'access', _322 => _322.activeStroke, 'optionalAccess', _323 => _323.cancel, 'call', _324 => _324()]);
8123
+ if (_optionalChain([this, 'access', _324 => _324.mode, 'optionalAccess', _325 => _325.kind]) === "stroke") _optionalChain([this, 'access', _326 => _326.controller, 'access', _327 => _327.activeStroke, 'optionalAccess', _328 => _328.cancel, 'call', _329 => _329()]);
7978
8124
  this.mode = null;
7979
8125
  }
7980
8126
  get active() {
@@ -8108,7 +8254,7 @@ var PAPER_SLIDERS = [
8108
8254
  ];
8109
8255
  function readPath(obj, path) {
8110
8256
  let v = obj;
8111
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _325 => _325[k]]);
8257
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _330 => _330[k]]);
8112
8258
  return typeof v === "number" ? v : 0;
8113
8259
  }
8114
8260
  function patchPath(obj, path, value) {
@@ -8230,7 +8376,7 @@ function brushEngineControls(brush) {
8230
8376
  impastoTool: true
8231
8377
  };
8232
8378
  case "wet": {
8233
- const tool = _nullishCoalesce(_optionalChain([brush, 'access', _326 => _326.wet, 'optionalAccess', _327 => _327.tool]), () => ( "paint"));
8379
+ const tool = _nullishCoalesce(_optionalChain([brush, 'access', _331 => _331.wet, 'optionalAccess', _332 => _332.tool]), () => ( "paint"));
8234
8380
  const sliders = tool === "paint" ? [
8235
8381
  { path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
8236
8382
  { path: "wet.pigment", label: "Pigment", min: 0, max: 1, step: 0.01 },
@@ -8363,7 +8509,7 @@ function startWetClock(controller, frame, cancel) {
8363
8509
  id = raf(loop);
8364
8510
  return () => {
8365
8511
  stopped = true;
8366
- _optionalChain([caf, 'optionalCall', _328 => _328(id)]);
8512
+ _optionalChain([caf, 'optionalCall', _333 => _333(id)]);
8367
8513
  };
8368
8514
  }
8369
8515
  function drawWaterOverlay(controller, ctx) {
@@ -8920,4 +9066,5 @@ function createPaintEditorDocument(controller, options = {}) {
8920
9066
 
8921
9067
 
8922
9068
 
8923
- exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkCWM3CUUXcjs.BLEND_MODES; exports.BRUSH_ID = _chunkBXMIBMVGcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkBXMIBMVGcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkBXMIBMVGcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunkBXMIBMVGcjs.BristleStroke; exports.DEFAULT_BEHAVIOR = _chunkBXMIBMVGcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkBXMIBMVGcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkBXMIBMVGcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkBXMIBMVGcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkGNK7SESQcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkBXMIBMVGcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkBXMIBMVGcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkLRRCMRSLcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkLRRCMRSLcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkBXMIBMVGcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkBXMIBMVGcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunkBXMIBMVGcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkBXMIBMVGcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkGNK7SESQcjs.DEFAULT_WET_PARAMS; exports.DryStroke = _chunkBXMIBMVGcjs.DryStroke; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkLRRCMRSLcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkLRRCMRSLcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkUKCJ43YLcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkBXMIBMVGcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkBXMIBMVGcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkLRRCMRSLcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; 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 = _chunkBXMIBMVGcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkCWM3CUUXcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkBXMIBMVGcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkBXMIBMVGcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkLRRCMRSLcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkLRRCMRSLcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkLRRCMRSLcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkLRRCMRSLcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkLRRCMRSLcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkLRRCMRSLcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkLRRCMRSLcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkLRRCMRSLcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkLRRCMRSLcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkLRRCMRSLcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkLRRCMRSLcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkLRRCMRSLcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkBXMIBMVGcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkBXMIBMVGcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkBXMIBMVGcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkBXMIBMVGcjs.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 = _chunkLRRCMRSLcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkLRRCMRSLcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkLRRCMRSLcjs.PaperGrain; exports.ParticleStroke = _chunkBXMIBMVGcjs.ParticleStroke; exports.PenDabWalker = _chunkBXMIBMVGcjs.PenDabWalker; exports.PenSmoother = _chunkBXMIBMVGcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkBXMIBMVGcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunkBXMIBMVGcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkLRRCMRSLcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkGNK7SESQcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkBXMIBMVGcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkGNK7SESQcjs.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 = _chunkBXMIBMVGcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkLRRCMRSLcjs.addPaintGradientStop; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkBXMIBMVGcjs.brushTakesPaint; exports.brushToJSON = _chunkBXMIBMVGcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkBXMIBMVGcjs.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 = _chunkBXMIBMVGcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectLayersToJSON = effectLayersToJSON; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkLRRCMRSLcjs.grainCatch; exports.grainHeights = _chunkLRRCMRSLcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkLRRCMRSLcjs.hash2; exports.hexToPaintRgb = _chunkLRRCMRSLcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkBXMIBMVGcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkUKCJ43YLcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkCWM3CUUXcjs.isBlendMode; exports.isGradientPaint = _chunkLRRCMRSLcjs.isGradientPaint; exports.isPainterlyBlendMode = _chunkCWM3CUUXcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkBXMIBMVGcjs.isWetBrush; exports.isWetCapable = _chunkBXMIBMVGcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkLRRCMRSLcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkBXMIBMVGcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunkBXMIBMVGcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkBXMIBMVGcjs.normalizeBehavior; exports.normalizeBristle = _chunkBXMIBMVGcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkBXMIBMVGcjs.normalizeDynamics; exports.normalizeFlow = _chunkGNK7SESQcjs.normalizeFlow; exports.normalizeHexColor = _chunkLRRCMRSLcjs.normalizeHexColor; exports.normalizeImpasto = _chunkBXMIBMVGcjs.normalizeImpasto; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkBXMIBMVGcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkBXMIBMVGcjs.normalizePaintBrush; exports.normalizePaper = _chunkBXMIBMVGcjs.normalizePaper; exports.normalizeParticle = _chunkBXMIBMVGcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkBXMIBMVGcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunkBXMIBMVGcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkBXMIBMVGcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkGNK7SESQcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkLRRCMRSLcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkLRRCMRSLcjs.paintSourceColor; exports.paintSourceCss = _chunkLRRCMRSLcjs.paintSourceCss; exports.paintToMultiColor = _chunkBXMIBMVGcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkBXMIBMVGcjs.paperPreset; exports.parseBrushLibrary = _chunkBXMIBMVGcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkLRRCMRSLcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkBXMIBMVGcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkLRRCMRSLcjs.rand01; exports.randSigned = _chunkLRRCMRSLcjs.randSigned; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkLRRCMRSLcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkLRRCMRSLcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkBXMIBMVGcjs.renderPaper; exports.renderStickers = _chunkBXMIBMVGcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkLRRCMRSLcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkLRRCMRSLcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkLRRCMRSLcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkLRRCMRSLcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkLRRCMRSLcjs.solidPaint; exports.stampCoverage = _chunkBXMIBMVGcjs.stampCoverage; exports.standardBlendMode = _chunkCWM3CUUXcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerRect = _chunkBXMIBMVGcjs.stickerRect; exports.stickerSurface = _chunkBXMIBMVGcjs.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 = _chunkBXMIBMVGcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkBXMIBMVGcjs.toStrokePoint; exports.toggleStamp = toggleStamp; exports.updatePaintGradientStop = _chunkLRRCMRSLcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkBXMIBMVGcjs.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 = _chunkGNK7SESQcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkUKCJ43YLcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
9069
+
9070
+ exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkCWM3CUUXcjs.BLEND_MODES; exports.BRUSH_ID = _chunkJGKCC5OFcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkJGKCC5OFcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkJGKCC5OFcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunkJGKCC5OFcjs.BristleStroke; exports.DEFAULT_BEHAVIOR = _chunkJGKCC5OFcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkJGKCC5OFcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkJGKCC5OFcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkJGKCC5OFcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkGNK7SESQcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkJGKCC5OFcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkJGKCC5OFcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkEBDCRTZIcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkEBDCRTZIcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkJGKCC5OFcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkJGKCC5OFcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunkJGKCC5OFcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkJGKCC5OFcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkGNK7SESQcjs.DEFAULT_WET_PARAMS; exports.DryStroke = _chunkJGKCC5OFcjs.DryStroke; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkEBDCRTZIcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkEBDCRTZIcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkUKCJ43YLcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkJGKCC5OFcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkJGKCC5OFcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkEBDCRTZIcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; 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 = _chunkJGKCC5OFcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkCWM3CUUXcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkJGKCC5OFcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkJGKCC5OFcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkEBDCRTZIcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkEBDCRTZIcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkEBDCRTZIcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkEBDCRTZIcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkEBDCRTZIcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkEBDCRTZIcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkEBDCRTZIcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkEBDCRTZIcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkEBDCRTZIcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkEBDCRTZIcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkEBDCRTZIcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkEBDCRTZIcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkJGKCC5OFcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkJGKCC5OFcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkJGKCC5OFcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkJGKCC5OFcjs.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 = _chunkEBDCRTZIcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkEBDCRTZIcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkEBDCRTZIcjs.PaperGrain; exports.ParticleStroke = _chunkJGKCC5OFcjs.ParticleStroke; exports.PenDabWalker = _chunkJGKCC5OFcjs.PenDabWalker; exports.PenSmoother = _chunkJGKCC5OFcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJGKCC5OFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunkJGKCC5OFcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkEBDCRTZIcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkGNK7SESQcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkJGKCC5OFcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkGNK7SESQcjs.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 = _chunkJGKCC5OFcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkEBDCRTZIcjs.addPaintGradientStop; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkJGKCC5OFcjs.brushTakesPaint; exports.brushToJSON = _chunkJGKCC5OFcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkJGKCC5OFcjs.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 = _chunkJGKCC5OFcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectLayersToJSON = effectLayersToJSON; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkEBDCRTZIcjs.grainCatch; exports.grainHeights = _chunkEBDCRTZIcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkEBDCRTZIcjs.hash2; exports.hexToPaintRgb = _chunkEBDCRTZIcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkJGKCC5OFcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkUKCJ43YLcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkCWM3CUUXcjs.isBlendMode; exports.isGradientPaint = _chunkEBDCRTZIcjs.isGradientPaint; exports.isPainterlyBlendMode = _chunkCWM3CUUXcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkJGKCC5OFcjs.isWetBrush; exports.isWetCapable = _chunkJGKCC5OFcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkEBDCRTZIcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkJGKCC5OFcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunkJGKCC5OFcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkJGKCC5OFcjs.normalizeBehavior; exports.normalizeBristle = _chunkJGKCC5OFcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkJGKCC5OFcjs.normalizeDynamics; exports.normalizeFlow = _chunkGNK7SESQcjs.normalizeFlow; exports.normalizeHexColor = _chunkEBDCRTZIcjs.normalizeHexColor; exports.normalizeImpasto = _chunkJGKCC5OFcjs.normalizeImpasto; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkJGKCC5OFcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkJGKCC5OFcjs.normalizePaintBrush; exports.normalizePaper = _chunkJGKCC5OFcjs.normalizePaper; exports.normalizeParticle = _chunkJGKCC5OFcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkJGKCC5OFcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunkJGKCC5OFcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkJGKCC5OFcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkGNK7SESQcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkEBDCRTZIcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkEBDCRTZIcjs.paintSourceColor; exports.paintSourceCss = _chunkEBDCRTZIcjs.paintSourceCss; exports.paintToMultiColor = _chunkJGKCC5OFcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkJGKCC5OFcjs.paperPreset; exports.parseBrushLibrary = _chunkJGKCC5OFcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkEBDCRTZIcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkJGKCC5OFcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkEBDCRTZIcjs.rand01; exports.randSigned = _chunkEBDCRTZIcjs.randSigned; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkEBDCRTZIcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkEBDCRTZIcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkJGKCC5OFcjs.renderPaper; exports.renderStickers = _chunkJGKCC5OFcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkEBDCRTZIcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkEBDCRTZIcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkEBDCRTZIcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkEBDCRTZIcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkEBDCRTZIcjs.solidPaint; exports.stampCoverage = _chunkJGKCC5OFcjs.stampCoverage; exports.standardBlendMode = _chunkCWM3CUUXcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerRect = _chunkJGKCC5OFcjs.stickerRect; exports.stickerSurface = _chunkJGKCC5OFcjs.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 = _chunkJGKCC5OFcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkJGKCC5OFcjs.toStrokePoint; exports.toggleStamp = toggleStamp; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkEBDCRTZIcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkJGKCC5OFcjs.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 = _chunkGNK7SESQcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkUKCJ43YLcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;