@pixerate/editor 0.259.0 → 0.261.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 (80) hide show
  1. package/dist/agent/index.cjs +2 -2
  2. package/dist/agent/index.js +1 -1
  3. package/dist/animation-editor/index.cjs +61 -59
  4. package/dist/animation-editor/index.js +5 -3
  5. package/dist/brushes/index.cjs +52 -52
  6. package/dist/brushes/index.js +6 -6
  7. package/dist/{brushstrokeRender-JI4W6F2G.js → brushstrokeRender-25Q5BEY6.js} +17 -7
  8. package/dist/{brushstrokeRender-MQ6PSDM5.cjs → brushstrokeRender-N6UPZSQS.cjs} +31 -21
  9. package/dist/canvas/brushTypes.d.cts +5 -0
  10. package/dist/canvas/brushTypes.d.ts +5 -0
  11. package/dist/canvas/drawController.d.cts +15 -1
  12. package/dist/canvas/drawController.d.ts +15 -1
  13. package/dist/canvas/index.cjs +136 -102
  14. package/dist/canvas/index.js +35 -1
  15. package/dist/{chunk-3PPJRMIG.js → chunk-3O47TPGX.js} +197 -18
  16. package/dist/{chunk-5Q5MLXAD.cjs → chunk-3TQW5MPW.cjs} +23 -23
  17. package/dist/{chunk-JBBJE76O.cjs → chunk-3ZRNK3RO.cjs} +1138 -85
  18. package/dist/{chunk-YSGW7VV4.cjs → chunk-43NT242D.cjs} +1401 -228
  19. package/dist/{chunk-SMTUQWGY.js → chunk-5IW65VQ6.js} +1 -1
  20. package/dist/{chunk-YQ4PQTBB.js → chunk-6NZL24W4.js} +9 -1
  21. package/dist/{chunk-O3ZVZSNJ.cjs → chunk-7AUQ2UJ3.cjs} +137 -129
  22. package/dist/{chunk-4M4E3N6X.js → chunk-CQVTGBQI.js} +1 -1
  23. package/dist/{chunk-SSFMWJDK.js → chunk-D4TE5JNW.js} +1192 -19
  24. package/dist/{chunk-AORZ5M5C.js → chunk-EHALWBBD.js} +1 -1
  25. package/dist/{chunk-6WCQ35GI.cjs → chunk-NHA26O5X.cjs} +2 -2
  26. package/dist/{chunk-DPYAO5U6.cjs → chunk-PVJMTLPJ.cjs} +197 -18
  27. package/dist/{chunk-MQGQTKVW.cjs → chunk-PYTJBVW5.cjs} +29 -29
  28. package/dist/{chunk-IXQZHCOF.js → chunk-QAR2N7HZ.js} +1 -1
  29. package/dist/{chunk-5P4JEOIV.js → chunk-TMDDMJCR.js} +2 -2
  30. package/dist/{chunk-RSIKDWOP.cjs → chunk-TZOX7KWV.cjs} +15 -15
  31. package/dist/{chunk-IPUTIUGQ.cjs → chunk-UVZ7RQOE.cjs} +1 -1
  32. package/dist/{chunk-A7GJ6BXI.js → chunk-WJ4WQJCC.js} +1062 -9
  33. package/dist/{chunk-ICTPLVSR.js → chunk-X2EXYY4J.js} +1 -1
  34. package/dist/{chunk-WQCNC4DK.js → chunk-XC6DPRYI.js} +695 -4
  35. package/dist/{chunk-KBYB7OWB.cjs → chunk-YHDHFJUC.cjs} +776 -85
  36. package/dist/{chunk-P3PZ63M3.cjs → chunk-YLUIFXSL.cjs} +35 -35
  37. package/dist/commands/index.cjs +2 -2
  38. package/dist/commands/index.js +1 -1
  39. package/dist/image-editor/index.cjs +1385 -2484
  40. package/dist/image-editor/index.js +139 -1238
  41. package/dist/image-editor/selection-worker.cjs +3 -4
  42. package/dist/image-editor/selection-worker.js +1 -2
  43. package/dist/paint/index.cjs +3 -5
  44. package/dist/paint/index.js +40 -42
  45. package/dist/paint-editor/contract.d.cts +29 -0
  46. package/dist/paint-editor/contract.d.ts +29 -0
  47. package/dist/paint-editor/controller.d.cts +17 -0
  48. package/dist/paint-editor/controller.d.ts +17 -0
  49. package/dist/paint-editor/dab-stroke.d.cts +5 -0
  50. package/dist/paint-editor/dab-stroke.d.ts +5 -0
  51. package/dist/paint-editor/index.cjs +610 -327
  52. package/dist/paint-editor/index.d.cts +2 -0
  53. package/dist/paint-editor/index.d.ts +2 -0
  54. package/dist/paint-editor/index.js +337 -54
  55. package/dist/paint-editor/path-samples.d.cts +19 -0
  56. package/dist/paint-editor/path-samples.d.ts +19 -0
  57. package/dist/paint-editor/stamp-tip.d.cts +17 -0
  58. package/dist/paint-editor/stamp-tip.d.ts +17 -0
  59. package/dist/paint-editor/ui.d.cts +27 -1
  60. package/dist/paint-editor/ui.d.ts +27 -1
  61. package/dist/raster/index.cjs +2 -4
  62. package/dist/raster/index.js +6 -8
  63. package/dist/vector/brushstroke.d.cts +6 -0
  64. package/dist/vector/brushstroke.d.ts +6 -0
  65. package/dist/vector/controller.d.cts +11 -2
  66. package/dist/vector/controller.d.ts +11 -2
  67. package/dist/vector/index.cjs +990 -973
  68. package/dist/vector/index.js +28 -11
  69. package/package.json +1 -1
  70. package/skills/pixerate-brushes/SKILL.md +1 -1
  71. package/skills/pixerate-canvas/SKILL.md +3 -1
  72. package/skills/pixerate-paint-editor/SKILL.md +2 -0
  73. package/skills/pixerate-paint-sketch-to-finish/SKILL.md +5 -1
  74. package/skills/pixerate-vector/SKILL.md +2 -2
  75. package/dist/chunk-2VJAVXLI.js +0 -192
  76. package/dist/chunk-62Z5WLRA.js +0 -700
  77. package/dist/chunk-BOHDJJ2O.cjs +0 -192
  78. package/dist/chunk-NKGB64CW.cjs +0 -700
  79. package/dist/chunk-SS53NNZO.cjs +0 -1066
  80. package/dist/chunk-ZNA3IQZF.js +0 -1066
@@ -11,7 +11,7 @@ var _chunkRVGP2XLFcjs = require('../chunk-RVGP2XLF.cjs');
11
11
 
12
12
 
13
13
 
14
- var _chunkMQGQTKVWcjs = require('../chunk-MQGQTKVW.cjs');
14
+ var _chunkPYTJBVW5cjs = require('../chunk-PYTJBVW5.cjs');
15
15
 
16
16
 
17
17
 
@@ -26,12 +26,10 @@ var _chunkCBVNCWJMcjs = require('../chunk-CBVNCWJM.cjs');
26
26
 
27
27
 
28
28
 
29
- var _chunkYSGW7VV4cjs = require('../chunk-YSGW7VV4.cjs');
30
- require('../chunk-SS53NNZO.cjs');
31
29
 
30
+ var _chunk43NT242Dcjs = require('../chunk-43NT242D.cjs');
31
+ require('../chunk-3ZRNK3RO.cjs');
32
32
 
33
- var _chunkLRTR4ASZcjs = require('../chunk-LRTR4ASZ.cjs');
34
- require('../chunk-A2IS7EHE.cjs');
35
33
 
36
34
 
37
35
 
@@ -47,7 +45,8 @@ require('../chunk-A2IS7EHE.cjs');
47
45
 
48
46
 
49
47
 
50
- var _chunkDPYAO5U6cjs = require('../chunk-DPYAO5U6.cjs');
48
+
49
+ var _chunkPVJMTLPJcjs = require('../chunk-PVJMTLPJ.cjs');
51
50
  require('../chunk-QT26RHKK.cjs');
52
51
  require('../chunk-K6PXS6DO.cjs');
53
52
 
@@ -74,7 +73,8 @@ require('../chunk-K6PXS6DO.cjs');
74
73
 
75
74
 
76
75
 
77
- var _chunkKBYB7OWBcjs = require('../chunk-KBYB7OWB.cjs');
76
+ var _chunkYHDHFJUCcjs = require('../chunk-YHDHFJUC.cjs');
77
+ require('../chunk-BB6TR422.cjs');
78
78
  require('../chunk-BROJYMWU.cjs');
79
79
 
80
80
 
@@ -85,7 +85,7 @@ var _chunkJLWLX52Lcjs = require('../chunk-JLWLX52L.cjs');
85
85
 
86
86
 
87
87
  var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
88
- require('../chunk-O3ZVZSNJ.cjs');
88
+ require('../chunk-7AUQ2UJ3.cjs');
89
89
 
90
90
 
91
91
 
@@ -140,7 +140,7 @@ require('../chunk-O3ZVZSNJ.cjs');
140
140
 
141
141
 
142
142
 
143
- var _chunkRSIKDWOPcjs = require('../chunk-RSIKDWOP.cjs');
143
+ var _chunkTZOX7KWVcjs = require('../chunk-TZOX7KWV.cjs');
144
144
 
145
145
 
146
146
 
@@ -150,10 +150,18 @@ var _chunkRSIKDWOPcjs = require('../chunk-RSIKDWOP.cjs');
150
150
 
151
151
  var _chunkJSDND7DFcjs = require('../chunk-JSDND7DF.cjs');
152
152
  require('../chunk-CVFAAZXE.cjs');
153
- require('../chunk-GF2RBSDM.cjs');
153
+
154
+
155
+
156
+
157
+ var _chunkGF2RBSDMcjs = require('../chunk-GF2RBSDM.cjs');
154
158
  require('../chunk-NM3G4VQT.cjs');
155
159
 
156
160
 
161
+ var _chunkLRTR4ASZcjs = require('../chunk-LRTR4ASZ.cjs');
162
+ require('../chunk-A2IS7EHE.cjs');
163
+
164
+
157
165
  var _chunkU67EN7GGcjs = require('../chunk-U67EN7GG.cjs');
158
166
 
159
167
 
@@ -270,6 +278,7 @@ require('../chunk-UWEQ55MY.cjs');
270
278
 
271
279
 
272
280
 
281
+
273
282
  var _chunkSJ2CPTQCcjs = require('../chunk-SJ2CPTQC.cjs');
274
283
  require('../chunk-2BSBFBOA.cjs');
275
284
  require('../chunk-4ZC5QJE2.cjs');
@@ -653,6 +662,18 @@ function brushStickerRefs(brush) {
653
662
  const refs = brush.engine === "sticker" ? [...brush.sticker.stamps] : brush.engine === "particle" ? [...brush.particle.dotTextures] : brush.engine === "dab" && brush.stamp ? [brush.stamp] : [];
654
663
  return [...new Set(refs.filter((r) => r.includes(":") && !r.startsWith("editor:")))];
655
664
  }
665
+ function sprayDroplets(d, spray, seed) {
666
+ const count = 1 + Math.round(spray.density * 31);
667
+ const key = d.index * 131 + Math.round(d.travel * 8);
668
+ const out = [];
669
+ for (let i = 0; i < count; i++) {
670
+ const n = key * 64 + i;
671
+ const a = _chunk3K6HWEXZcjs.rand01.call(void 0, seed, n, 61) * Math.PI * 2;
672
+ const rr = Math.sqrt(_chunk3K6HWEXZcjs.rand01.call(void 0, seed, n, 67)) * d.radius;
673
+ out.push({ ...d, x: d.x + Math.cos(a) * rr, y: d.y + Math.sin(a) * rr, radius: Math.max(0.5, d.radius * spray.size * (0.6 + 0.8 * _chunk3K6HWEXZcjs.rand01.call(void 0, seed, n, 71))), roundness: 1, angle: _chunk3K6HWEXZcjs.rand01.call(void 0, seed, n, 73) * Math.PI * 2 });
674
+ }
675
+ return out;
676
+ }
656
677
 
657
678
  // src/paint-editor/engine.ts
658
679
  function penOrientation(p) {
@@ -921,14 +942,7 @@ var DryStroke = (_class3 = class {
921
942
  this.mark(d, d, rects);
922
943
  continue;
923
944
  }
924
- const count = 1 + Math.round(spray.density * 31);
925
- const key = d.index * 131 + Math.round(d.travel * 8);
926
- for (let i = 0; i < count; i++) {
927
- const a = _chunk3K6HWEXZcjs.rand01.call(void 0, seed, key * 64 + i, 61) * Math.PI * 2;
928
- const rr = Math.sqrt(_chunk3K6HWEXZcjs.rand01.call(void 0, seed, key * 64 + i, 67)) * d.radius;
929
- const drop = { ...d, x: d.x + Math.cos(a) * rr, y: d.y + Math.sin(a) * rr, radius: Math.max(0.5, d.radius * spray.size * (0.6 + 0.8 * _chunk3K6HWEXZcjs.rand01.call(void 0, seed, key * 64 + i, 71))), roundness: 1, angle: _chunk3K6HWEXZcjs.rand01.call(void 0, seed, key * 64 + i, 73) * Math.PI * 2 };
930
- this.mark(drop, d, rects);
931
- }
945
+ for (const drop of sprayDroplets(d, spray, seed)) this.mark(drop, d, rects);
932
946
  }
933
947
  return rects;
934
948
  }
@@ -1019,6 +1033,7 @@ var PaintDabStroke = (_class4 = class {
1019
1033
  constructor(brush, options) {;_class4.prototype.__init18.call(this);_class4.prototype.__init19.call(this);_class4.prototype.__init20.call(this);_class4.prototype.__init21.call(this);_class4.prototype.__init22.call(this);_class4.prototype.__init23.call(this);_class4.prototype.__init24.call(this);_class4.prototype.__init25.call(this);_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);
1020
1034
  this.brush = brush;
1021
1035
  this.options = options;
1036
+ this.stamp = brush.engine === "dab" && brush.stamp ? stampSampler(brush.stamp, options.stampArt) : null;
1022
1037
  this.smoother = new PenSmoother(brush.tip.smoothing, brush.pressureSmoothing);
1023
1038
  this.copies = _optionalChain([options, 'access', _8 => _8.copies, 'optionalAccess', _9 => _9.length]) ? options.copies : [IDENTITY_COPY];
1024
1039
  const exchanging = brush.engine === "mixer" || brush.engine === "dab";
@@ -1062,6 +1077,8 @@ var PaintDabStroke = (_class4 = class {
1062
1077
  __init25() {this.paint = [0, 0, 0]}
1063
1078
  __init26() {this.lastRaw = null}
1064
1079
  __init27() {this.lastFed = null}
1080
+ /** The stamp tip's shape (dab brushes), or `null` for the round computed tip. */
1081
+
1065
1082
  /** What copy 0's brush carries after the dabs so far (mixer and wet-capable dab brushes). */
1066
1083
  get load() {
1067
1084
  return _nullishCoalesce(_optionalChain([this, 'access', _12 => _12.states, 'access', _13 => _13[0], 'access', _14 => _14.exchange, 'optionalAccess', _15 => _15.load]), () => ( null));
@@ -1094,8 +1111,9 @@ var PaintDabStroke = (_class4 = class {
1094
1111
  return rects;
1095
1112
  }
1096
1113
  paintDabs(copy, dabs, rects) {
1097
- for (const d of dabs) {
1098
- const rect = _chunkFQPUF2W2cjs.dabRect.call(void 0, d, this.brush.tip.hardness);
1114
+ const spray = this.brush.engine === "dab" ? this.brush.spray : null;
1115
+ for (const d of spray ? dabs.flatMap((dab) => sprayDroplets(dab, spray, (_nullishCoalesce(this.options.seed, () => ( 0))) + copy * 7919)) : dabs) {
1116
+ const rect = this.stamp ? stampDabRect(d) : _chunkFQPUF2W2cjs.dabRect.call(void 0, d, this.brush.tip.hardness);
1099
1117
  if (rect.width <= 0 || rect.height <= 0) continue;
1100
1118
  this.dab(copy, d, rect);
1101
1119
  rects.push(rect);
@@ -1111,7 +1129,8 @@ var PaintDabStroke = (_class4 = class {
1111
1129
  }
1112
1130
  const tip = this.tip.subarray(0, n);
1113
1131
  tip.fill(0);
1114
- _chunkFQPUF2W2cjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.tip.hardness, rect, tip);
1132
+ if (this.stamp) rasterizeStampDab({ ...d, alpha: 1 }, this.stamp, d.index, rect, tip);
1133
+ else _chunkFQPUF2W2cjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.tip.hardness, rect, tip);
1115
1134
  if (!(this.depth > 0 && this.options.grain)) return { tip, cov: tip };
1116
1135
  const cov = this.cov.subarray(0, n);
1117
1136
  const grain = this.options.grain;
@@ -1306,10 +1325,10 @@ function lightTile(color, height, heightAround, material, light) {
1306
1325
  const nh = Math.max(0, nx * hx + ny * hy + nz * hz);
1307
1326
  const spec = Math.max(0, Math.pow(nh, shininess) - Math.pow(hz, shininess)) * (0.25 + 0.75 * gloss) * light.relief;
1308
1327
  for (let c = 0; c < 3; c++) {
1309
- const a = _chunkKBYB7OWBcjs.SRGB_TO_LINEAR[color[i + c]];
1328
+ const a = _chunkYHDHFJUCcjs.SRGB_TO_LINEAR[color[i + c]];
1310
1329
  const tint = metal * a + (1 - metal);
1311
1330
  const v = a * shade * (1 - 0.35 * metal) + spec * tint * (1 + metal);
1312
- out[i + c] = _chunkKBYB7OWBcjs.linearToSrgb8.call(void 0, v);
1331
+ out[i + c] = _chunkYHDHFJUCcjs.linearToSrgb8.call(void 0, v);
1313
1332
  }
1314
1333
  }
1315
1334
  }
@@ -1714,7 +1733,7 @@ function shadowToLight(shadow) {
1714
1733
  return new (0, _chunk474IQG74cjs.TiledSurface)(1, tiles, 0);
1715
1734
  }
1716
1735
  function lightTwinBrush(brush) {
1717
- return _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0,
1736
+ return _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0,
1718
1737
  {
1719
1738
  tip: { ...brush.tip, blend: "normal", pressureOpacity: brush.tip.pressureOpacity || brush.light.pressure },
1720
1739
  behavior: { ...brush.behavior, mixing: "rgb" },
@@ -2946,7 +2965,7 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
2946
2965
  } else if (init.thick) {
2947
2966
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
2948
2967
  this.thickDriver = new ThickStrokeDriver({ brush, target: this.tileTarget(), channels: init.thick.channels, color: rgb(init.color), load: init.mixerLoad, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
2949
- } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkRSIKDWOPcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
2968
+ } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkTZOX7KWVcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
2950
2969
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
2951
2970
  this.wet = new PaintDabStroke(brush, {
2952
2971
  target: this.tileTarget(),
@@ -2958,7 +2977,8 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
2958
2977
  seed: init.seed,
2959
2978
  copies: this.copies,
2960
2979
  paint: _nullishCoalesce(init.paint, () => ( null)),
2961
- effect
2980
+ effect,
2981
+ stampArt: init.stampArt
2962
2982
  });
2963
2983
  } else {
2964
2984
  const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect, stampArt: init.stampArt };
@@ -3185,7 +3205,7 @@ function brushLoadForStroke(brush, current, color) {
3185
3205
  if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
3186
3206
  if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
3187
3207
  if (brush.engine === "wet") return brush.wet.tool === "paint" ? { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null } : _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD;
3188
- if (_chunkRSIKDWOPcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
3208
+ if (_chunkTZOX7KWVcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
3189
3209
  return _chunkFQPUF2W2cjs.EMPTY_MIXER_LOAD;
3190
3210
  }
3191
3211
 
@@ -3447,15 +3467,15 @@ function readLoad(raw) {
3447
3467
  function readStrokeBrush(raw) {
3448
3468
  if (raw && typeof raw === "object" && "kind" in raw && !("engine" in raw)) {
3449
3469
  try {
3450
- return _chunkRSIKDWOPcjs.resolveBrush.call(void 0, _chunkRSIKDWOPcjs.normalizeBrushSpec.call(void 0, raw));
3470
+ return _chunkTZOX7KWVcjs.resolveBrush.call(void 0, _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, raw));
3451
3471
  } catch (e5) {
3452
3472
  }
3453
3473
  }
3454
- return _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(raw, () => ( {})));
3474
+ return _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(raw, () => ( {})));
3455
3475
  }
3456
3476
  function strokeToJSON(stroke) {
3457
3477
  const { brush, ...rest } = stroke;
3458
- return { ...JSON.parse(JSON.stringify(rest)), brush: _chunkRSIKDWOPcjs.migrateBrushV1.call(void 0, brush) };
3478
+ return { ...JSON.parse(JSON.stringify(rest)), brush: _chunkTZOX7KWVcjs.migrateBrushV1.call(void 0, brush) };
3459
3479
  }
3460
3480
  function normalizeBrushStroke(raw) {
3461
3481
  if (!raw || typeof raw !== "object") return null;
@@ -3525,7 +3545,7 @@ function varyStroke(stroke, m, v) {
3525
3545
  if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
3526
3546
  return q;
3527
3547
  });
3528
- const brush = s !== 1 ? _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
3548
+ const brush = s !== 1 ? _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
3529
3549
  const out = { ...stroke, brush, points };
3530
3550
  if (_optionalChain([stroke, 'access', _112 => _112.paint, 'optionalAccess', _113 => _113.type]) === "gradient" && s !== 1) out.paint = _chunkFQPUF2W2cjs.scalePaintGradient.call(void 0, stroke.paint, s);
3531
3551
  if (_optionalChain([stroke, 'access', _114 => _114.paint, 'optionalAccess', _115 => _115.type]) === "effect" && stroke.paint.map && s !== 1) out.paint = { ...stroke.paint, map: { ...stroke.paint.map, length: Math.min(4096, Math.max(16, Math.round(stroke.paint.map.length * s))) } };
@@ -3599,7 +3619,7 @@ var PROFILE = {
3599
3619
  }
3600
3620
  };
3601
3621
  function createPaintCompositor() {
3602
- return new (0, _chunkDPYAO5U6cjs.RasterCompositor)(PROFILE);
3622
+ return new (0, _chunkPVJMTLPJcjs.RasterCompositor)(PROFILE);
3603
3623
  }
3604
3624
  function downsampleRgba(data, width, height, tw, th) {
3605
3625
  tw = Math.max(1, Math.round(tw));
@@ -3675,11 +3695,11 @@ function header(state, options) {
3675
3695
  return out;
3676
3696
  }
3677
3697
  function serializePaintDocument(state, options = {}) {
3678
- const { layers, assets } = _chunkYSGW7VV4cjs.serializeLayers.call(void 0, state.layers);
3698
+ const { layers, assets } = _chunk43NT242Dcjs.serializeLayers.call(void 0, state.layers);
3679
3699
  return { ...header(state, options), layers, assets };
3680
3700
  }
3681
3701
  async function serializePaintDocumentExternal(state, store, options = {}) {
3682
- const { layers, assets } = await _chunkYSGW7VV4cjs.serializeLayersExternal.call(void 0, state.layers, store);
3702
+ const { layers, assets } = await _chunk43NT242Dcjs.serializeLayersExternal.call(void 0, state.layers, store);
3683
3703
  return { ...header(state, options), layers, assets };
3684
3704
  }
3685
3705
  function paintLayersOnly(layers, problems) {
@@ -3716,9 +3736,9 @@ function deserializePaintDocument(raw) {
3716
3736
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
3717
3737
  const paper = normalizePaper(_nullishCoalesce(r.paper, () => ( {})));
3718
3738
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
3719
- const layers = paintLayersOnly(_chunkYSGW7VV4cjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
3739
+ const layers = paintLayersOnly(_chunk43NT242Dcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
3720
3740
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
3721
- const activeLayerId = wanted && _chunkDPYAO5U6cjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _129 => _129.filter, 'call', _130 => _130((l) => l.type === "pixel"), 'access', _131 => _131.pop, 'call', _132 => _132(), 'optionalAccess', _133 => _133.id]), () => ( null));
3741
+ const activeLayerId = wanted && _chunkPVJMTLPJcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _129 => _129.filter, 'call', _130 => _130((l) => l.type === "pixel"), 'access', _131 => _131.pop, 'call', _132 => _132(), 'optionalAccess', _133 => _133.id]), () => ( null));
3722
3742
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
3723
3743
  const state = { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) };
3724
3744
  if (wetEvents.length) state.wetEvents = wetEvents;
@@ -3732,7 +3752,7 @@ async function deserializePaintDocumentAsync(raw, store) {
3732
3752
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
3733
3753
  const r = raw;
3734
3754
  const problems = [];
3735
- const assets = await _chunkYSGW7VV4cjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
3755
+ const assets = await _chunk43NT242Dcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
3736
3756
  const loaded = deserializePaintDocument({ ...r, assets });
3737
3757
  return { ...loaded, problems: [...problems, ...loaded.problems] };
3738
3758
  }
@@ -3809,7 +3829,7 @@ function viewPenToDocument(view, p) {
3809
3829
 
3810
3830
  // src/paint-editor/input.ts
3811
3831
  function samplePressure(e) {
3812
- return _chunkKBYB7OWBcjs.pointerPressure.call(void 0, e);
3832
+ return _chunkYHDHFJUCcjs.pointerPressure.call(void 0, e);
3813
3833
  }
3814
3834
  function pointerToPenPoint(e, x, y, view) {
3815
3835
  const p = { x, y, pressure: samplePressure(e) };
@@ -3879,7 +3899,7 @@ function downloadBytes(bytes, fileName, mimeType) {
3879
3899
 
3880
3900
  // src/paint-editor/wet.ts
3881
3901
  var STROKE_WATER = 0.9;
3882
- var STROKE_MASS = _chunkKBYB7OWBcjs.PIGMENT_UNIT * 2.5;
3902
+ var STROKE_MASS = _chunkYHDHFJUCcjs.PIGMENT_UNIT * 2.5;
3883
3903
  var STROKE_LIGHT = 1.5;
3884
3904
  var COVERAGE_STEPS = 4096;
3885
3905
  function union2(a, b) {
@@ -3909,7 +3929,7 @@ var WetStrokeDriver = (_class13 = class {
3909
3929
  const spacing = Math.max(0.02, brush.tip.spacing);
3910
3930
  const perDab = Math.min(1, spacing * 1.2);
3911
3931
  const thin = wet.thinner;
3912
- this.medium = new (0, _chunkKBYB7OWBcjs.WetMedium)(init.world, init.laneId, {
3932
+ this.medium = new (0, _chunkYHDHFJUCcjs.WetMedium)(init.world, init.laneId, {
3913
3933
  water: STROKE_WATER * Math.min(1, wet.water * (1 + thin)) * perDab,
3914
3934
  mass: STROKE_MASS * wet.pigment * (1 - 0.6 * thin) * perDab,
3915
3935
  body: wet.body * (1 - thin),
@@ -4115,7 +4135,7 @@ var PaintWetLayers = (_class14 = class {
4115
4135
 
4116
4136
 
4117
4137
  __init88() {this.world = null}
4118
- __init89() {this.tilt = { ..._chunkKBYB7OWBcjs.FLAT }}
4138
+ __init89() {this.tilt = { ..._chunkYHDHFJUCcjs.FLAT }}
4119
4139
  __init90() {this.settings = /* @__PURE__ */ new Map()}
4120
4140
  __init91() {this.paused = false}
4121
4141
  /** Wet strokes dry as soon as they end (one undo step with the stroke). */
@@ -4139,8 +4159,8 @@ var PaintWetLayers = (_class14 = class {
4139
4159
  /** Starts the GPU engine for the world (once; it may turn out unavailable). */
4140
4160
  startGpu() {
4141
4161
  if (this.gpuMode === "off" || this.gpu || this.gpuStarting || this.gpuSupport) return;
4142
- const provider = this.options.gpuProvider === void 0 ? _chunkKBYB7OWBcjs.findWebGpu.call(void 0, ) : this.options.gpuProvider;
4143
- this.gpuStarting = _chunkKBYB7OWBcjs.createWetGpuEngine.call(void 0, provider).then(({ engine, support }) => {
4162
+ const provider = this.options.gpuProvider === void 0 ? _chunkYHDHFJUCcjs.findWebGpu.call(void 0, ) : this.options.gpuProvider;
4163
+ this.gpuStarting = _chunkYHDHFJUCcjs.createWetGpuEngine.call(void 0, provider).then(({ engine, support }) => {
4144
4164
  this.gpuSupport = support;
4145
4165
  if (!engine) return;
4146
4166
  if (this.gpuMode === "off" || !this.world) {
@@ -4199,7 +4219,7 @@ var PaintWetLayers = (_class14 = class {
4199
4219
  return this.world;
4200
4220
  }
4201
4221
  makeWorld(width, height, paper) {
4202
- const world = new (0, _chunkKBYB7OWBcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: this.options.kernel, threads: this.options.threads });
4222
+ const world = new (0, _chunkYHDHFJUCcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: this.options.kernel, threads: this.options.threads });
4203
4223
  world.setTilt(this.tilt);
4204
4224
  world.gpuMinTiles = this.gpuMinTiles;
4205
4225
  if (this.gpu) world.attachGpu(this.gpu);
@@ -4211,7 +4231,7 @@ var PaintWetLayers = (_class14 = class {
4211
4231
  * sides: the shift has to be whole wet tiles (256 px), and no wet stroke may be live.
4212
4232
  */
4213
4233
  canExtend(left, top) {
4214
- return left % _chunkKBYB7OWBcjs.WET_TILE === 0 && top % _chunkKBYB7OWBcjs.WET_TILE === 0 && !this.driver;
4234
+ return left % _chunkYHDHFJUCcjs.WET_TILE === 0 && top % _chunkYHDHFJUCcjs.WET_TILE === 0 && !this.driver;
4215
4235
  }
4216
4236
  /**
4217
4237
  * Keeps the wet paint while the canvas grows to `width`×`height` by `left` / `top` on those
@@ -4229,12 +4249,12 @@ var PaintWetLayers = (_class14 = class {
4229
4249
  this.lastTick = null;
4230
4250
  this.stepsOwed = 0;
4231
4251
  if (!old || !snap) return;
4232
- const moved = _chunkKBYB7OWBcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left, top, (l) => {
4252
+ const moved = _chunkYHDHFJUCcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left, top, (l) => {
4233
4253
  const flow = _optionalChain([this, 'access', _157 => _157.settings, 'access', _158 => _158.get, 'call', _159 => _159(l.id), 'optionalAccess', _160 => _160.flow]);
4234
4254
  return {
4235
4255
  base: _chunk474IQG74cjs.translateSurface.call(void 0, l.base, left, top),
4236
4256
  ...l.light ? { light: _chunk474IQG74cjs.translateSurface.call(void 0, l.light, left, top) } : {},
4237
- flow: l.flow && flow && flow.kind !== "none" ? _chunkKBYB7OWBcjs.flowField.call(void 0, flow, width, height) : l.flow
4257
+ flow: l.flow && flow && flow.kind !== "none" ? _chunkYHDHFJUCcjs.flowField.call(void 0, flow, width, height) : l.flow
4238
4258
  };
4239
4259
  });
4240
4260
  this.world = this.makeWorld(width, height, paper);
@@ -4262,7 +4282,7 @@ var PaintWetLayers = (_class14 = class {
4262
4282
  settingsOf(layerId, medium = "watercolor") {
4263
4283
  let s = this.settings.get(layerId);
4264
4284
  if (!s) {
4265
- s = { params: _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, WET_MEDIUM_PARAMS[medium], _chunkKBYB7OWBcjs.DEFAULT_WET_PARAMS), flow: { ..._chunkKBYB7OWBcjs.DEFAULT_FLOW } };
4285
+ s = { params: _chunkYHDHFJUCcjs.normalizeWetParams.call(void 0, WET_MEDIUM_PARAMS[medium], _chunkYHDHFJUCcjs.DEFAULT_WET_PARAMS), flow: { ..._chunkYHDHFJUCcjs.DEFAULT_FLOW } };
4266
4286
  this.settings.set(layerId, s);
4267
4287
  }
4268
4288
  return s;
@@ -4275,27 +4295,27 @@ var PaintWetLayers = (_class14 = class {
4275
4295
  const s = this.settingsOf(layerId, medium);
4276
4296
  w.ensureLane(layerId, { params: s.params, base, light: this.host.layerLight(layerId) });
4277
4297
  const { width, height } = this.host.canvas();
4278
- if (s.flow.kind !== "none") w.setFlow(layerId, _chunkKBYB7OWBcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4298
+ if (s.flow.kind !== "none") w.setFlow(layerId, _chunkYHDHFJUCcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4279
4299
  }
4280
4300
  return w;
4281
4301
  }
4282
4302
  setParams(layerId, update) {
4283
4303
  const s = this.settingsOf(layerId);
4284
- s.params = _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, update, s.params);
4304
+ s.params = _chunkYHDHFJUCcjs.normalizeWetParams.call(void 0, update, s.params);
4285
4305
  if (_optionalChain([this, 'access', _166 => _166.world, 'optionalAccess', _167 => _167.hasLane, 'call', _168 => _168(layerId)])) this.world.setParams(layerId, s.params);
4286
4306
  return { ...s.params };
4287
4307
  }
4288
4308
  setFlow(layerId, update) {
4289
4309
  const s = this.settingsOf(layerId);
4290
- s.flow = _chunkKBYB7OWBcjs.normalizeFlow.call(void 0, update, s.flow);
4310
+ s.flow = _chunkYHDHFJUCcjs.normalizeFlow.call(void 0, update, s.flow);
4291
4311
  if (_optionalChain([this, 'access', _169 => _169.world, 'optionalAccess', _170 => _170.hasLane, 'call', _171 => _171(layerId)])) {
4292
4312
  const { width, height } = this.host.canvas();
4293
- this.world.setFlow(layerId, _chunkKBYB7OWBcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4313
+ this.world.setFlow(layerId, _chunkYHDHFJUCcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4294
4314
  }
4295
4315
  return { ...s.flow };
4296
4316
  }
4297
4317
  setTilt(update) {
4298
- this.tilt = _chunkKBYB7OWBcjs.normalizeTilt.call(void 0, update, this.tilt);
4318
+ this.tilt = _chunkYHDHFJUCcjs.normalizeTilt.call(void 0, update, this.tilt);
4299
4319
  _optionalChain([this, 'access', _172 => _172.world, 'optionalAccess', _173 => _173.setTilt, 'call', _174 => _174(this.tilt)]);
4300
4320
  return { ...this.tilt };
4301
4321
  }
@@ -4564,7 +4584,7 @@ var PaintWetLayers = (_class14 = class {
4564
4584
  }, _class14);
4565
4585
  function wetPigmentOf(hex2, body) {
4566
4586
  const [r, g, b] = hexToRgb8(hex2);
4567
- return Array.from(_chunkKBYB7OWBcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
4587
+ return Array.from(_chunkYHDHFJUCcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
4568
4588
  }
4569
4589
 
4570
4590
  // src/paint-editor/thumbnails.ts
@@ -4572,7 +4592,7 @@ var thumbWorld = null;
4572
4592
  function paintWetTestStroke(brush, paper, color, width, height) {
4573
4593
  if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
4574
4594
  _optionalChain([thumbWorld, 'optionalAccess', _208 => _208.destroy, 'call', _209 => _209()]);
4575
- thumbWorld = new (0, _chunkKBYB7OWBcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
4595
+ thumbWorld = new (0, _chunkYHDHFJUCcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
4576
4596
  } else thumbWorld.setPaper(wetPaperInput(paper));
4577
4597
  const w = thumbWorld;
4578
4598
  if (w.hasLane("thumb")) w.removeLane("thumb");
@@ -4580,8 +4600,8 @@ function paintWetTestStroke(brush, paper, color, width, height) {
4580
4600
  const [r, g, b] = hexToRgb8(color);
4581
4601
  if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
4582
4602
  const half = Math.ceil(height / 2);
4583
- w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkKBYB7OWBcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
4584
- w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkKBYB7OWBcjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
4603
+ w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkYHDHFJUCcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
4604
+ w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkYHDHFJUCcjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
4585
4605
  }
4586
4606
  const driver = new WetStrokeDriver({
4587
4607
  world: w,
@@ -4656,7 +4676,7 @@ function renderBrushThumbnail(brush, options) {
4656
4676
  const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
4657
4677
  const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
4658
4678
  const maxSize = height * 0.42;
4659
- const b = brush.tip.size > maxSize ? _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
4679
+ const b = brush.tip.size > maxSize ? _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
4660
4680
  const rgba = [...hexToRgb8(options.color), 255];
4661
4681
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
4662
4682
  if (b.engine === "eraser") {
@@ -4939,7 +4959,7 @@ var DEFAULT_SWATCHES = [
4939
4959
  // src/paint-editor/mixing-pad.ts
4940
4960
  var MIXING_PAD_WIDTH = 360;
4941
4961
  var MIXING_PAD_HEIGHT = 220;
4942
- var PAD_PAINT = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, {
4962
+ var PAD_PAINT = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, {
4943
4963
  id: "pad-paint",
4944
4964
  name: "Pad paint",
4945
4965
  category: "mixer",
@@ -4947,7 +4967,7 @@ var PAD_PAINT = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, {
4947
4967
  tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
4948
4968
  mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
4949
4969
  });
4950
- var PAD_KNIFE = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, {
4970
+ var PAD_KNIFE = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, {
4951
4971
  id: "pad-knife",
4952
4972
  name: "Palette knife",
4953
4973
  category: "smudge",
@@ -4957,7 +4977,7 @@ var PAD_KNIFE = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, {
4957
4977
  // A knife drags streaks of paint and folds them into each other, mixing them as pigment.
4958
4978
  smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
4959
4979
  });
4960
- var PAD_BLOB = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, {
4980
+ var PAD_BLOB = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, {
4961
4981
  id: "pad-blob",
4962
4982
  name: "Pad blob",
4963
4983
  category: "custom",
@@ -4979,7 +4999,7 @@ var MixingPad = (_class16 = class {constructor() { _class16.prototype.__init106.
4979
4999
  }
4980
5000
  }
4981
5001
  let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
4982
- if (options.size !== void 0) brush = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
5002
+ if (options.size !== void 0) brush = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
4983
5003
  return this.run(brush, points, options.color);
4984
5004
  }
4985
5005
  /** Paints `points` with `brush` in `color` on the pad. */
@@ -5078,10 +5098,10 @@ var MixingPad = (_class16 = class {constructor() { _class16.prototype.__init106.
5078
5098
  const off = used.length === 1 ? 0 : 0.45 * R;
5079
5099
  const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
5080
5100
  const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
5081
- const blob = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
5101
+ const blob = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
5082
5102
  this.run(blob, [{ x, y }], p.color.toLowerCase());
5083
5103
  });
5084
- const knife = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
5104
+ const knife = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
5085
5105
  for (let k = 0; k < passes; k++) {
5086
5106
  const stir = [];
5087
5107
  const turns = 1.6;
@@ -5096,7 +5116,7 @@ var MixingPad = (_class16 = class {constructor() { _class16.prototype.__init106.
5096
5116
  paints2.map((p) => hexToRgb8(p.color).map((v) => v / 255)),
5097
5117
  paints2.map((p) => p.parts)
5098
5118
  );
5099
- const core = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
5119
+ const core = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
5100
5120
  const hex2 = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
5101
5121
  this.run(core, [{ x: cx, y: cy }], hex2);
5102
5122
  return { color: this.pick(cx, cy, 2), bounds };
@@ -5136,21 +5156,21 @@ var MixingPad = (_class16 = class {constructor() { _class16.prototype.__init106.
5136
5156
  var copyJSON = (v) => JSON.parse(JSON.stringify(v));
5137
5157
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
5138
5158
  function libraryBrush(spec, builtin, resolved) {
5139
- const brush = resolved ? _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, resolved, resolved) : _chunkRSIKDWOPcjs.resolveBrush.call(void 0, spec);
5159
+ const brush = resolved ? _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, resolved, resolved) : _chunkTZOX7KWVcjs.resolveBrush.call(void 0, spec);
5140
5160
  if (builtin) brush.builtin = true;
5141
5161
  else delete brush.builtin;
5142
5162
  return { spec, brush, builtin };
5143
5163
  }
5144
5164
  var builtins = null;
5145
5165
  function builtinLibraryBrushes() {
5146
- return builtins ??= _chunkRSIKDWOPcjs.BRUSH_PRESETS.map((spec) => {
5147
- const resolved = _chunkRSIKDWOPcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id);
5166
+ return builtins ??= _chunkTZOX7KWVcjs.BRUSH_PRESETS.map((spec) => {
5167
+ const resolved = _chunkTZOX7KWVcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id);
5148
5168
  return libraryBrush(spec, true, resolved);
5149
5169
  });
5150
5170
  }
5151
5171
  function seededStorage(brushes) {
5152
5172
  if (!brushes.length) return void 0;
5153
- let stored = JSON.stringify({ format: "pixerate-brushes", version: 1, brushes: brushes.map(_chunkRSIKDWOPcjs.brushToJSON) });
5173
+ let stored = JSON.stringify({ format: "pixerate-brushes", version: 1, brushes: brushes.map(_chunkTZOX7KWVcjs.brushToJSON) });
5154
5174
  return {
5155
5175
  get: async () => stored,
5156
5176
  set: async (_key, value) => {
@@ -5163,7 +5183,7 @@ var paints = (b) => {
5163
5183
  return JSON.stringify(rest);
5164
5184
  };
5165
5185
  function brushSpecOf(next, from) {
5166
- const plain = _chunkRSIKDWOPcjs.migrateBrushV1.call(void 0, next);
5186
+ const plain = _chunkTZOX7KWVcjs.migrateBrushV1.call(void 0, next);
5167
5187
  const out = copyJSON(plain);
5168
5188
  if (from.description) out.description = from.description;
5169
5189
  if (_optionalChain([from, 'access', _213 => _213.tags, 'optionalAccess', _214 => _214.length])) out.tags = [...from.tags];
@@ -5183,8 +5203,8 @@ function brushSpecOf(next, from) {
5183
5203
  out.motion = { ..._nullishCoalesce(out.motion, () => ( {})), ...from.motion.live !== void 0 ? { live: from.motion.live } : {}, ...from.motion.fps !== void 0 ? { fps: from.motion.fps } : {} };
5184
5204
  }
5185
5205
  try {
5186
- const hinted = _chunkRSIKDWOPcjs.normalizeBrushSpec.call(void 0, out, []);
5187
- if (paints(_chunkRSIKDWOPcjs.resolveBrush.call(void 0, hinted)) === paints(_chunkRSIKDWOPcjs.resolveBrush.call(void 0, plain))) return hinted;
5206
+ const hinted = _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, out, []);
5207
+ if (paints(_chunkTZOX7KWVcjs.resolveBrush.call(void 0, hinted)) === paints(_chunkTZOX7KWVcjs.resolveBrush.call(void 0, plain))) return hinted;
5188
5208
  } catch (e7) {
5189
5209
  }
5190
5210
  return plain;
@@ -5205,6 +5225,55 @@ function engineChanges(base, next) {
5205
5225
  return rest;
5206
5226
  }
5207
5227
 
5228
+ // src/paint-editor/path-samples.ts
5229
+ var FLATTEN_TOLERANCE = 0.1;
5230
+ var MAX_PATH_SAMPLES = 2e4;
5231
+ function profileAt(profile, t) {
5232
+ if (profile.length === 1) return profile[0];
5233
+ const at = t * (profile.length - 1);
5234
+ const i = Math.min(profile.length - 2, Math.floor(at));
5235
+ return profile[i] + (profile[i + 1] - profile[i]) * (at - i);
5236
+ }
5237
+ function samplePath(d, options = {}) {
5238
+ const spacing = _nullishCoalesce(options.spacing, () => ( 2));
5239
+ if (!(spacing >= 0.25 && spacing <= 100)) throw new Error(`spacing ${spacing} is out of range; use 0.25..100 document pixels.`);
5240
+ const profile = options.pressure;
5241
+ if (profile && (!profile.length || profile.some((p) => !(p >= 0 && p <= 1)))) throw new Error("pressure needs one or more values from 0 to 1, e.g. [0.2, 1, 0.2] for a taper.");
5242
+ let contours;
5243
+ try {
5244
+ contours = _chunkGF2RBSDMcjs.pathToContours.call(void 0, d);
5245
+ } catch (e) {
5246
+ throw new Error(`path is not SVG path data (${e instanceof Error ? e.message : String(e)}); give e.g. "M 10 10 C 40 0 80 60 120 30".`);
5247
+ }
5248
+ const out = [];
5249
+ for (const contour of contours) {
5250
+ if (!contour.segments.length) continue;
5251
+ const line = _chunkGF2RBSDMcjs.flattenChain.call(void 0, contour.segments, FLATTEN_TOLERANCE);
5252
+ if (contour.closed && line.length) line.push(line[0]);
5253
+ const lengths = [0];
5254
+ for (let i = 1; i < line.length; i++) lengths.push(lengths[i - 1] + Math.hypot(line[i][0] - line[i - 1][0], line[i][1] - line[i - 1][1]));
5255
+ const total = lengths[lengths.length - 1];
5256
+ const n = Math.max(1, Math.ceil(total / spacing));
5257
+ if (n + 1 > MAX_PATH_SAMPLES) throw new Error(`The path is ${Math.round(total)} px long: too many samples at spacing ${spacing}; use a larger spacing (at least ${Math.ceil(total / (MAX_PATH_SAMPLES - 1))}).`);
5258
+ const points = [];
5259
+ let j = 0;
5260
+ for (let k = 0; k <= n; k++) {
5261
+ const at = total * k / n;
5262
+ while (j < line.length - 2 && lengths[j + 1] < at) j++;
5263
+ const span = lengths[j + 1] - lengths[j] || 1;
5264
+ const f = line.length > 1 ? Math.min(1, Math.max(0, (at - lengths[j]) / span)) : 0;
5265
+ const a = line[j];
5266
+ const b = line[Math.min(j + 1, line.length - 1)];
5267
+ const x = Math.round((a[0] + (b[0] - a[0]) * f) * 1e3) / 1e3;
5268
+ const y = Math.round((a[1] + (b[1] - a[1]) * f) * 1e3) / 1e3;
5269
+ points.push(profile ? { x, y, pressure: Math.round(profileAt(profile, k / n) * 1e3) / 1e3 } : { x, y });
5270
+ }
5271
+ out.push(points);
5272
+ }
5273
+ if (!out.length) throw new Error('path has no segments to brush; give SVG path data such as "M 10 10 L 200 80".');
5274
+ return out;
5275
+ }
5276
+
5208
5277
  // src/paint-editor/live-strokes.ts
5209
5278
  var LIVE_STROKE_ENGINES = ["dab", "particle", "bristle", "mixer"];
5210
5279
  function liveStrokeRefusal(brush) {
@@ -5463,7 +5532,7 @@ function replayItems(doc) {
5463
5532
  }
5464
5533
  function emptiedLayers(layers) {
5465
5534
  let out = [...layers];
5466
- for (const l of _chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers)) if (l.type === "pixel") out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4), offset: { x: 0, y: 0 } }));
5535
+ for (const l of _chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers)) if (l.type === "pixel") out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4), offset: { x: 0, y: 0 } }));
5467
5536
  return out;
5468
5537
  }
5469
5538
  async function replayPainting(source, target, options = {}) {
@@ -5777,7 +5846,7 @@ function effectGuard(fn) {
5777
5846
  try {
5778
5847
  return fn();
5779
5848
  } catch (e) {
5780
- if (e instanceof _chunkDPYAO5U6cjs.LayerEffectError) throw new PaintEditorError(e.message);
5849
+ if (e instanceof _chunkPVJMTLPJcjs.LayerEffectError) throw new PaintEditorError(e.message);
5781
5850
  throw e;
5782
5851
  }
5783
5852
  }
@@ -5791,7 +5860,7 @@ async function libraryCall(call) {
5791
5860
  try {
5792
5861
  return await call();
5793
5862
  } catch (e) {
5794
- throw e instanceof _chunkRSIKDWOPcjs.BrushLibraryError ? new PaintEditorError(e.message) : e;
5863
+ throw e instanceof _chunkTZOX7KWVcjs.BrushLibraryError ? new PaintEditorError(e.message) : e;
5795
5864
  }
5796
5865
  }
5797
5866
  var HEX3 = /^#[0-9a-f]{6}$/i;
@@ -5921,15 +5990,15 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
5921
5990
  this.rasterizeSticker = _nullishCoalesce(options.rasterizeSticker, () => ( defaultStickerRasterizer));
5922
5991
  if (options.stickers) this.stickers.set(options.stickers);
5923
5992
  this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
5924
- const seed = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
5925
- this.brushLibrary = _nullishCoalesce(options.brushLibrary, () => ( _chunkRSIKDWOPcjs.createBrushLibrary.call(void 0, { storage: seededStorage(seed) })));
5926
- this.brushEntries = [...builtinLibraryBrushes(), ...seed.map((b) => libraryBrush(_chunkRSIKDWOPcjs.migrateBrushV1.call(void 0, b), false, b))];
5927
- const wanted = _nullishCoalesce(options.brushId, () => ( _chunkRSIKDWOPcjs.DEFAULT_BRUSH_ID));
5928
- const start = _nullishCoalesce(this.findEntry(wanted), () => ( this.findEntry(_chunkRSIKDWOPcjs.DEFAULT_BRUSH_ID)));
5929
- this.brush = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, start.brush);
5993
+ const seed = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
5994
+ this.brushLibrary = _nullishCoalesce(options.brushLibrary, () => ( _chunkTZOX7KWVcjs.createBrushLibrary.call(void 0, { storage: seededStorage(seed) })));
5995
+ this.brushEntries = [...builtinLibraryBrushes(), ...seed.map((b) => libraryBrush(_chunkTZOX7KWVcjs.migrateBrushV1.call(void 0, b), false, b))];
5996
+ const wanted = _nullishCoalesce(options.brushId, () => ( _chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID));
5997
+ const start = _nullishCoalesce(this.findEntry(wanted), () => ( this.findEntry(_chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID)));
5998
+ this.brush = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, start.brush);
5930
5999
  this.brushSpec = copyJSON(start.spec);
5931
6000
  this.unsubscribeLibrary = this.brushLibrary.subscribe(() => void this.refreshBrushes().catch(() => void 0));
5932
- if (options.brushLibrary && seed.length) void this.brushLibrary.importFile(seed.map(_chunkRSIKDWOPcjs.brushToJSON)).catch(() => void 0);
6001
+ if (options.brushLibrary && seed.length) void this.brushLibrary.importFile(seed.map(_chunkTZOX7KWVcjs.brushToJSON)).catch(() => void 0);
5933
6002
  void this.refreshBrushes().catch(() => void 0);
5934
6003
  this.pendingBrushId = start.brush.id === wanted ? null : wanted;
5935
6004
  this.color = options.color ? parseColor(options.color) : "#1f2937";
@@ -5943,19 +6012,19 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
5943
6012
  canvas: () => this.doc.canvas,
5944
6013
  paper: () => this.doc.paper,
5945
6014
  layerSurface: (id) => {
5946
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _262 => _262.layer]);
6015
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _262 => _262.layer]);
5947
6016
  return isPixelLayer(l) ? l.surface : null;
5948
6017
  },
5949
6018
  updateSurfaces: (surfaces, rects) => {
5950
6019
  let layers = this.doc.layers;
5951
- for (const [id, surface] of surfaces) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id)) layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, id, (l) => ({ ...l, surface }));
6020
+ for (const [id, surface] of surfaces) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id)) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, (l) => ({ ...l, surface }));
5952
6021
  this.doc = { ...this.doc, layers };
5953
6022
  this.emit(rects.length ? rects : "all");
5954
6023
  },
5955
6024
  layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _263 => _263.doc, 'access', _264 => _264.light, 'optionalAccess', _265 => _265[id]]), () => ( null)),
5956
6025
  updateLights: (lights) => {
5957
6026
  let light = this.doc.light;
5958
- for (const [id, surface] of lights) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
6027
+ for (const [id, surface] of lights) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
5959
6028
  this.doc = { ...this.doc, ...light ? { light } : {} };
5960
6029
  },
5961
6030
  changed: () => {
@@ -6087,7 +6156,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6087
6156
  if (placement.bottom) this.moveLayer(layer.id, 0, null);
6088
6157
  fn(layer.id);
6089
6158
  if (this.wetOp || this.pendingWetEvents.length) throw new PaintEditorError("Wet paint can't be previewed; suggest it with a dry brush.");
6090
- const found = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _269 => _269.layer]);
6159
+ const found = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _269 => _269.layer]);
6091
6160
  const surface = found && isPixelLayer(found) ? found.surface : null;
6092
6161
  const bounds = surface ? _chunk474IQG74cjs.contentBounds.call(void 0, surface) : null;
6093
6162
  const box = bounds ? clipToCanvas(bounds, this.doc.canvas) : null;
@@ -6415,8 +6484,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6415
6484
  }
6416
6485
  let next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
6417
6486
  for (const id of keptWet) {
6418
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _281 => _281.layer]);
6419
- if (isPixelLayer(l)) next = { ...next, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, l.offset.x, l.offset.y), offset: { x: 0, y: 0 } })) };
6487
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _281 => _281.layer]);
6488
+ if (isPixelLayer(l)) next = { ...next, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, l.offset.x, l.offset.y), offset: { x: 0, y: 0 } })) };
6420
6489
  }
6421
6490
  if (this.wet.world) {
6422
6491
  if (keptWet.length) this.wet.extend(width, height, left, top, next.paper);
@@ -6459,7 +6528,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6459
6528
  }
6460
6529
  // --- Layers --------------------------------------------------------------------
6461
6530
  getLayer(id) {
6462
- return _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _282 => _282.layer]);
6531
+ return _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _282 => _282.layer]);
6463
6532
  }
6464
6533
  /** The active pixel layer (or `undefined`). */
6465
6534
  getActiveLayer() {
@@ -6478,12 +6547,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6478
6547
  walk(this.doc.layers, null, 0);
6479
6548
  return out;
6480
6549
  }
6481
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _283 => _283.parent, 'optionalAccess', _284 => _284.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _285 => _285.path, 'access', _286 => _286.length]), () => ( 0))) {
6550
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _283 => _283.parent, 'optionalAccess', _284 => _284.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _285 => _285.path, 'access', _286 => _286.length]), () => ( 0))) {
6482
6551
  let bounds = null;
6483
6552
  if (l.type === "pixel") {
6484
6553
  const b = _chunk474IQG74cjs.contentBounds.call(void 0, l.surface);
6485
6554
  bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;
6486
- } else for (const c of _chunkDPYAO5U6cjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
6555
+ } else for (const c of _chunkPVJMTLPJcjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
6487
6556
  return {
6488
6557
  id: l.id,
6489
6558
  name: l.name,
@@ -6512,7 +6581,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6512
6581
  if (!id) throw new PaintEditorError(`There is no active layer to ${what}; add one with add_layer.`);
6513
6582
  const l = this.requireLayer(id);
6514
6583
  if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; ${what} a pixel layer inside it.`);
6515
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
6584
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
6516
6585
  if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) before you ${what} it.`);
6517
6586
  return l;
6518
6587
  }
@@ -6526,7 +6595,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6526
6595
  /** Adds a layer above the active one: `pixel` (default), `group`, or `strokes`, a live stroke layer whose strokes stay editable. */
6527
6596
  addLayer(options = {}) {
6528
6597
  this.requireIdle("adding a layer");
6529
- const count = _chunkDPYAO5U6cjs.flattenLayers.call(void 0, this.doc.layers).length;
6598
+ const count = _chunkPVJMTLPJcjs.flattenLayers.call(void 0, this.doc.layers).length;
6530
6599
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
6531
6600
  const name = _optionalChain([options, 'access', _293 => _293.name, 'optionalAccess', _294 => _294.trim, 'call', _295 => _295()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
6532
6601
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
@@ -6538,12 +6607,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6538
6607
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
6539
6608
  parentId = g.id;
6540
6609
  } else if (above) {
6541
- const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, above);
6610
+ const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above);
6542
6611
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
6543
6612
  parentId = _nullishCoalesce(_optionalChain([loc, 'access', _296 => _296.parent, 'optionalAccess', _297 => _297.id]), () => ( null));
6544
6613
  index = loc.index + 1;
6545
6614
  }
6546
- const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
6615
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
6547
6616
  const live = type === "strokes" ? { liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [layer.id]: [] } } : {};
6548
6617
  this.commit(type === "group" ? "Add group" : type === "strokes" ? "Add stroke layer" : "Add layer", { ...this.doc, layers, activeLayerId: layer.id, ...live });
6549
6618
  return this.describeLayer(layer);
@@ -6551,7 +6620,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6551
6620
  updateLayer(id, update) {
6552
6621
  this.requireIdle("changing a layer");
6553
6622
  const l = this.requireLayer(id);
6554
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
6623
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
6555
6624
  if (update.opacity !== void 0 && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);
6556
6625
  if (update.blend !== void 0 && !_chunk2VX55NFMcjs.isBlendMode.call(void 0, update.blend) && !(l.type === "group" && update.blend === "pass-through")) {
6557
6626
  throw new PaintEditorError(`Unknown blend mode "${update.blend}". Call get_canvas_info for the blend modes.`);
@@ -6567,7 +6636,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6567
6636
  const locks = { ..._nullishCoalesce(l.locks, () => ( {})), ...update.locks };
6568
6637
  next.locks = Object.values(locks).some(Boolean) ? locks : void 0;
6569
6638
  }
6570
- this.commit("Layer properties", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
6639
+ this.commit("Layer properties", { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
6571
6640
  return this.describeLayer(next);
6572
6641
  }
6573
6642
  // --- Layer effects (layer styles) ---------------------------------------------
@@ -6582,17 +6651,17 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6582
6651
  * layer's pixels when it is composited, so it follows later painting. One undo step.
6583
6652
  */
6584
6653
  addLayerEffect(id, kind, settings = {}, index) {
6585
- if (!_chunkDPYAO5U6cjs.isLayerEffectKind.call(void 0, kind)) throw new PaintEditorError(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkDPYAO5U6cjs.LAYER_EFFECT_KINDS.join(", ")}.`);
6654
+ if (!_chunkPVJMTLPJcjs.isLayerEffectKind.call(void 0, kind)) throw new PaintEditorError(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkPVJMTLPJcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
6586
6655
  const current = _nullishCoalesce(this.effectsLayer(id, "add effects").effects, () => ( { enabled: true, items: [] }));
6587
6656
  const ids = new Set(current.items.map((e) => e.id));
6588
- let effectId = _chunkDPYAO5U6cjs.newEffectId.call(void 0, );
6589
- while (ids.has(effectId)) effectId = _chunkDPYAO5U6cjs.newEffectId.call(void 0, );
6657
+ let effectId = _chunkPVJMTLPJcjs.newEffectId.call(void 0, );
6658
+ while (ids.has(effectId)) effectId = _chunkPVJMTLPJcjs.newEffectId.call(void 0, );
6590
6659
  const { id: _id, kind: _kind, ...rest } = settings;
6591
- const effect = effectGuard(() => _chunkDPYAO5U6cjs.mergeLayerEffect.call(void 0, _chunkDPYAO5U6cjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
6660
+ const effect = effectGuard(() => _chunkPVJMTLPJcjs.mergeLayerEffect.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
6592
6661
  const items = [...current.items];
6593
6662
  const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
6594
6663
  items.splice(at, 0, effect);
6595
- this.writeLayerEffects(id, { ...current, items }, `Add ${_chunkDPYAO5U6cjs.layerEffectLabel.call(void 0, kind)}`, true);
6664
+ this.writeLayerEffects(id, { ...current, items }, `Add ${_chunkPVJMTLPJcjs.layerEffectLabel.call(void 0, kind)}`, true);
6596
6665
  return { effect, effects: this.getLayerEffects(id) };
6597
6666
  }
6598
6667
  /**
@@ -6604,15 +6673,15 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6604
6673
  const current = this.effectsLayer(id, "change its effects").effects;
6605
6674
  const i = this.requireEffect(id, effectId);
6606
6675
  const items = [...current.items];
6607
- items[i] = effectGuard(() => _chunkDPYAO5U6cjs.mergeLayerEffect.call(void 0, items[i], changes));
6608
- this.writeLayerEffects(id, { ...current, items }, `Change ${_chunkDPYAO5U6cjs.layerEffectLabel.call(void 0, items[i].kind)}`, commitToHistory);
6676
+ items[i] = effectGuard(() => _chunkPVJMTLPJcjs.mergeLayerEffect.call(void 0, items[i], changes));
6677
+ this.writeLayerEffects(id, { ...current, items }, `Change ${_chunkPVJMTLPJcjs.layerEffectLabel.call(void 0, items[i].kind)}`, commitToHistory);
6609
6678
  return this.getLayerEffects(id);
6610
6679
  }
6611
6680
  /** Removes one effect (one undo step). Returns the layer's remaining effects. */
6612
6681
  removeLayerEffect(id, effectId) {
6613
6682
  const current = this.effectsLayer(id, "change its effects").effects;
6614
6683
  const i = this.requireEffect(id, effectId);
6615
- this.writeLayerEffects(id, { ...current, items: current.items.filter((e) => e.id !== effectId) }, `Remove ${_chunkDPYAO5U6cjs.layerEffectLabel.call(void 0, current.items[i].kind)}`, true);
6684
+ this.writeLayerEffects(id, { ...current, items: current.items.filter((e) => e.id !== effectId) }, `Remove ${_chunkPVJMTLPJcjs.layerEffectLabel.call(void 0, current.items[i].kind)}`, true);
6616
6685
  return this.getLayerEffects(id);
6617
6686
  }
6618
6687
  /** Turns all of a layer's effects on or off and, when given, sets Scale Effects (0.01..10). One undo step. */
@@ -6630,7 +6699,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6630
6699
  /** Replaces a layer's effects, validated (`null` removes them). One undo step. Returns the effects. */
6631
6700
  setLayerEffects(id, effects, commitToHistory = true) {
6632
6701
  this.effectsLayer(id, "change its effects");
6633
- if (effects) effectGuard(() => _chunkDPYAO5U6cjs.validateLayerEffects.call(void 0, effects));
6702
+ if (effects) effectGuard(() => _chunkPVJMTLPJcjs.validateLayerEffects.call(void 0, effects));
6634
6703
  this.writeLayerEffects(id, effects, "Layer effects", commitToHistory);
6635
6704
  return this.getLayerEffects(id);
6636
6705
  }
@@ -6641,7 +6710,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6641
6710
  effectsLayer(id, action) {
6642
6711
  this.requireIdle("changing layer effects");
6643
6712
  const l = this.requireLayer(id);
6644
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked, so it can't ${action}; unlock it first (locks {all: false}).`);
6713
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked, so it can't ${action}; unlock it first (locks {all: false}).`);
6645
6714
  return l;
6646
6715
  }
6647
6716
  requireEffect(id, effectId) {
@@ -6656,30 +6725,30 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6656
6725
  const next = { ...this.requireLayer(id) };
6657
6726
  if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) next.effects = effects;
6658
6727
  else delete next.effects;
6659
- this.commitOrAmend(label, { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => next) }, commitToHistory);
6728
+ this.commitOrAmend(label, { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) }, commitToHistory);
6660
6729
  }
6661
6730
  removeLayer(id) {
6662
6731
  this.requireIdle("removing a layer");
6663
6732
  const l = this.requireLayer(id);
6664
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
6665
- const wetIds = this.wet.wetLayerIds().filter((x) => x === id || l.type === "group" && _chunkDPYAO5U6cjs.findLayer.call(void 0, l.children, x));
6733
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
6734
+ const wetIds = this.wet.wetLayerIds().filter((x) => x === id || l.type === "group" && _chunkPVJMTLPJcjs.findLayer.call(void 0, l.children, x));
6666
6735
  if (wetIds.length) {
6667
6736
  this.beginWetOp();
6668
6737
  for (const x of wetIds) this.wet.world.removeLane(x);
6669
6738
  }
6670
- const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
6739
+ const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
6671
6740
  let active = this.doc.activeLayerId;
6672
- if (active && !_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _300 => _300.filter, 'call', _301 => _301((x) => x.type === "pixel"), 'access', _302 => _302.pop, 'call', _303 => _303(), 'optionalAccess', _304 => _304.id]), () => ( null));
6673
- this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.lightWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
6741
+ if (active && !_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _300 => _300.filter, 'call', _301 => _301((x) => x.type === "pixel"), 'access', _302 => _302.pop, 'call', _303 => _303(), 'optionalAccess', _304 => _304.id]), () => ( null));
6742
+ this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.lightWithout(_chunkPVJMTLPJcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
6674
6743
  return { removed: id, activeLayerId: active };
6675
6744
  }
6676
6745
  duplicateLayer(id) {
6677
6746
  this.requireIdle("duplicating a layer");
6678
- if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) {
6747
+ if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) {
6679
6748
  const inside = (l) => l.type === "group" ? l.children.flatMap(inside) : [l.id];
6680
- this.dryLayersFirst(inside(_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id).layer));
6749
+ this.dryLayersFirst(inside(_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id).layer));
6681
6750
  }
6682
- const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6751
+ const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
6683
6752
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
6684
6753
  const thick = { ..._nullishCoalesce(this.doc.thick, () => ( {})) };
6685
6754
  const stickers = { ..._nullishCoalesce(this.doc.stickers, () => ( {})) };
@@ -6695,43 +6764,43 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6695
6764
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
6696
6765
  };
6697
6766
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
6698
- const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _305 => _305.parent, 'optionalAccess', _306 => _306.id]), () => ( null)), loc.index + 1);
6767
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _305 => _305.parent, 'optionalAccess', _306 => _306.id]), () => ( null)), loc.index + 1);
6699
6768
  this.commit("Duplicate layer", this.withWetEvents({ ...this.doc, layers, activeLayerId: dup.id, ...this.doc.thick ? { thick } : {}, ...this.doc.stickers ? { stickers } : {}, ...this.doc.liveStrokes ? { liveStrokes } : {}, ...this.doc.light ? { light } : {} }));
6700
6769
  return this.describeLayer(dup);
6701
6770
  }
6702
6771
  /** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */
6703
6772
  moveLayer(id, index, parentId) {
6704
6773
  this.requireIdle("moving a layer");
6705
- const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6774
+ const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
6706
6775
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
6707
6776
  const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _307 => _307.parent, 'optionalAccess', _308 => _308.id]), () => ( null)) : parentId;
6708
6777
  if (target) {
6709
6778
  const g = this.requireLayer(target);
6710
6779
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
6711
- if (target === id || loc.layer.type === "group" && _chunkDPYAO5U6cjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
6780
+ if (target === id || loc.layer.type === "group" && _chunkPVJMTLPJcjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
6712
6781
  }
6713
- const without = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
6714
- const siblings = target ? _chunkDPYAO5U6cjs.findLayer.call(void 0, without, target).layer.children : without;
6782
+ const without = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
6783
+ const siblings = target ? _chunkPVJMTLPJcjs.findLayer.call(void 0, without, target).layer.children : without;
6715
6784
  if (!Number.isInteger(index) || index < 0 || index > siblings.length) throw new PaintEditorError(`index ${index} is out of range; use 0..${siblings.length} (0 is the bottom).`);
6716
- const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, without, loc.layer, target, index);
6785
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, without, loc.layer, target, index);
6717
6786
  this.commit("Move layer", { ...this.doc, layers });
6718
6787
  return this.describeLayer(loc.layer);
6719
6788
  }
6720
6789
  /** Merges a pixel layer into the pixel layer below it (keeping the lower one's settings). */
6721
6790
  mergeDown(id) {
6722
6791
  this.requireIdle("merging");
6723
- const pre = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6792
+ const pre = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
6724
6793
  if (pre) {
6725
6794
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
6726
6795
  this.dryLayersFirst([id, _optionalChain([sib, 'access', _309 => _309[pre.index - 1], 'optionalAccess', _310 => _310.id])].filter((x) => Boolean(x)));
6727
6796
  }
6728
- const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6797
+ const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id);
6729
6798
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
6730
6799
  const siblings = loc.parent ? loc.parent.children : this.doc.layers;
6731
6800
  const below = siblings[loc.index - 1];
6732
6801
  const upper = loc.layer;
6733
6802
  if (!isPixelLayer(upper) || !isPixelLayer(below)) throw new PaintEditorError("Merge down needs a pixel layer directly above another pixel layer in the same group.");
6734
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
6803
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
6735
6804
  const rect = unionRect(this.describeLayer(below).bounds, this.describeLayer(upper).bounds);
6736
6805
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
6737
6806
  if (rect) {
@@ -6741,7 +6810,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6741
6810
  surface = _chunk474IQG74cjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data: px }, 4, rect.x, rect.y);
6742
6811
  }
6743
6812
  const merged = { ...below, surface, offset: { x: 0, y: 0 } };
6744
- const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
6813
+ const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
6745
6814
  const toDoc = (t, l) => t ? _chunk474IQG74cjs.translateSurface.call(void 0, t, l.offset.x, l.offset.y) : void 0;
6746
6815
  const mergedLight = _optionalChain([this, 'access', _311 => _311.doc, 'access', _312 => _312.light, 'optionalAccess', _313 => _313[upper.id]]) || _optionalChain([this, 'access', _314 => _314.doc, 'access', _315 => _315.light, 'optionalAccess', _316 => _316[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _317 => _317.doc, 'access', _318 => _318.light, 'optionalAccess', _319 => _319[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _320 => _320.doc, 'access', _321 => _321.light, 'optionalAccess', _322 => _322[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
6747
6816
  const lightAfter = _nullishCoalesce(this.lightWithout([upper.id, below.id]).light, () => ( (this.doc.light ? { ...this.doc.light } : void 0)));
@@ -6758,7 +6827,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6758
6827
  this.wet.world.removeLane(l.id);
6759
6828
  }
6760
6829
  const bounds = this.describeLayer(l).bounds;
6761
- this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _323 => _323.doc, 'access', _324 => _324.liveStrokes, 'optionalAccess', _325 => _325[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
6830
+ this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _323 => _323.doc, 'access', _324 => _324.liveStrokes, 'optionalAccess', _325 => _325[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
6762
6831
  return { layerId: l.id, bounds };
6763
6832
  }
6764
6833
  /**
@@ -6797,14 +6866,14 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6797
6866
  background: rgbaOf(this.doc.paper.color),
6798
6867
  opacity,
6799
6868
  blend,
6800
- lockTransparency: _chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "transparency"),
6869
+ lockTransparency: _chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "transparency"),
6801
6870
  selection: null,
6802
6871
  offset: l.offset
6803
6872
  };
6804
6873
  const surface = this.applyCoverage(l, coverage, rect, apply);
6805
6874
  const lit = _optionalChain([this, 'access', _333 => _333.doc, 'access', _334 => _334.light, 'optionalAccess', _335 => _335[l.id]]);
6806
6875
  const light = lit ? withLayerLight(this.doc.light, l.id, scaleLight(lit, 1 - opacity)) : void 0;
6807
- this.commit("Fill layer", this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), ...light ? { light } : {} }), { kind: "fill", layerId: l.id, data: { color, opacity, grain: grainAmount, pressure, blend } }));
6876
+ this.commit("Fill layer", this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), ...light ? { light } : {} }), { kind: "fill", layerId: l.id, data: { color, opacity, grain: grainAmount, pressure, blend } }));
6808
6877
  return { layerId: l.id, bounds: rect };
6809
6878
  }
6810
6879
  applyCoverage(l, coverage, rect, apply) {
@@ -6845,7 +6914,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6845
6914
  }
6846
6915
  /** The effect a layer is drawn from, or `undefined` for other layers. */
6847
6916
  getEffectLayer(layerId) {
6848
- return _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _340 => _340.doc, 'access', _341 => _341.effectLayers, 'optionalAccess', _342 => _342[layerId]]) : void 0;
6917
+ return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _340 => _340.doc, 'access', _341 => _341.effectLayers, 'optionalAccess', _342 => _342[layerId]]) : void 0;
6849
6918
  }
6850
6919
  /** The effect paper (without its pixels), or `null`. */
6851
6920
  getPaperEffect() {
@@ -6974,10 +7043,10 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6974
7043
  const pixels = await this.renderEffectCanvas(d, values, options.time);
6975
7044
  this.requireIdle("adding a layer");
6976
7045
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
6977
- const loc = above ? _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, above) : null;
7046
+ const loc = above ? _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above) : null;
6978
7047
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
6979
7048
  const layer = { ...createPaintLayer(_optionalChain([options, 'access', _352 => _352.name, 'optionalAccess', _353 => _353.trim, 'call', _354 => _354()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
6980
- const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _355 => _355.parent, 'optionalAccess', _356 => _356.id]), () => ( null)), loc ? loc.index + 1 : void 0);
7049
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _355 => _355.parent, 'optionalAccess', _356 => _356.id]), () => ( null)), loc ? loc.index + 1 : void 0);
6981
7050
  const source = this.sourceOf(d, values, options.time);
6982
7051
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
6983
7052
  return { layer: this.describeLayer(layer), source };
@@ -7001,7 +7070,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7001
7070
  this.requireIdle("changing an effect layer");
7002
7071
  if (!isPixelLayer(now)) throw new PaintEditorError(`Layer "${l.name}" was removed while the effect rendered.`);
7003
7072
  const source = this.sourceOf(d, values, time);
7004
- this.commitOrAmend("Effect layer", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...now, surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), offset: { x: 0, y: 0 } })), effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [l.id]: source } }, commitToHistory);
7073
+ this.commitOrAmend("Effect layer", { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...now, surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), offset: { x: 0, y: 0 } })), effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [l.id]: source } }, commitToHistory);
7005
7074
  return source;
7006
7075
  }
7007
7076
  /** Turns an effect layer into a plain pixel layer, keeping its pixels (one undo step). */
@@ -7029,9 +7098,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7029
7098
  const rect = this.canvasRectOf(now);
7030
7099
  const before = _chunk474IQG74cjs.readRegion.call(void 0, now.surface, rect);
7031
7100
  let after = overPixels(before, pixels.data, _nullishCoalesce(options.opacity, () => ( 1)));
7032
- if (options.lockTransparency || _chunkDPYAO5U6cjs.isLayerLocked.call(void 0, now, "transparency")) after = mixPixels(before, after, 1);
7101
+ if (options.lockTransparency || _chunkPVJMTLPJcjs.isLayerLocked.call(void 0, now, "transparency")) after = mixPixels(before, after, 1);
7033
7102
  const surface = _chunk474IQG74cjs.writeRegion.call(void 0, now.surface, rect, after);
7034
- this.commit("Effect fill", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
7103
+ this.commit("Effect fill", { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
7035
7104
  return { layerId: now.id, source: this.sourceOf(d, values, options.time) };
7036
7105
  }
7037
7106
  // --- Effect paint ----------------------------------------------------------------
@@ -7159,7 +7228,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7159
7228
  * its pixels are not rendered.
7160
7229
  */
7161
7230
  strokeEffect(init, brush) {
7162
- if (!_chunkRSIKDWOPcjs.brushTakesPaint.call(void 0, brush)) return null;
7231
+ if (!_chunkTZOX7KWVcjs.brushTakesPaint.call(void 0, brush)) return null;
7163
7232
  let source = null;
7164
7233
  if (init.paint !== void 0) {
7165
7234
  if (!isPaintEffectPaint(init.paint)) return null;
@@ -7208,7 +7277,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7208
7277
  const out = await this.effectsRenderer.render(this.effects.require(), d.id, { width: rect.width, height: rect.height }, { time: _nullishCoalesce(options.time, () => ( 0)), values, inputs });
7209
7278
  const now = this.sameLayerAfterRender(l);
7210
7279
  const surface = _chunk474IQG74cjs.writeRegion.call(void 0, now.surface, rect, mixPixels(before, out.data, amount));
7211
- this.commit("Light effect", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
7280
+ this.commit("Light effect", { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
7212
7281
  return { layerId: now.id, source: this.sourceOf(d, values, options.time), amount };
7213
7282
  }
7214
7283
  // --- Brushes -------------------------------------------------------------------
@@ -7220,7 +7289,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7220
7289
  }
7221
7290
  requireEntry(id) {
7222
7291
  const e = this.findEntry(id);
7223
- if (!e) throw new PaintEditorError(`Unknown brush "${id}". ${_chunkRSIKDWOPcjs.closest.call(void 0, id, this.brushEntries.map((x) => x.brush.id))}Call list_brush_presets for the ids.`);
7292
+ if (!e) throw new PaintEditorError(`Unknown brush "${id}". ${_chunkTZOX7KWVcjs.closest.call(void 0, id, this.brushEntries.map((x) => x.brush.id))}Call list_brush_presets for the ids.`);
7224
7293
  return e;
7225
7294
  }
7226
7295
  requireBrush(id) {
@@ -7246,7 +7315,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7246
7315
  /** A library brush by id, as the engine paints it (`undefined` when unknown). */
7247
7316
  getBrush(id) {
7248
7317
  const b = this.findBrush(id);
7249
- return b ? _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
7318
+ return b ? _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
7250
7319
  }
7251
7320
  /** A library brush by id as stored (its facets), or without an id the active brush as edited. */
7252
7321
  getBrushSpec(id) {
@@ -7264,7 +7333,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7264
7333
  const baseSpec = entry ? entry.spec : this.brushSpec;
7265
7334
  if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
7266
7335
  const unchanged = !Object.keys(changes).length;
7267
- const next = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
7336
+ const next = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
7268
7337
  if (entry) this.takeBrushColour(entry.spec);
7269
7338
  this.useBrush(next, unchanged ? baseSpec : brushSpecOf(next, baseSpec), unchanged && base.builtin === true);
7270
7339
  return this.brush;
@@ -7283,7 +7352,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7283
7352
  for (const k of unset) delete base[k];
7284
7353
  const spec = this.readBrushPatch(base, patch, problems);
7285
7354
  if (entry || _optionalChain([patch, 'access', _373 => _373.colour, 'optionalAccess', _374 => _374.default]) !== void 0) this.takeBrushColour(spec);
7286
- this.useBrush(unchanged && entry ? entry.brush : _chunkRSIKDWOPcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _375 => _375.builtin]) === true);
7355
+ this.useBrush(unchanged && entry ? entry.brush : _chunkTZOX7KWVcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _375 => _375.builtin]) === true);
7287
7356
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
7288
7357
  }
7289
7358
  /**
@@ -7297,11 +7366,11 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7297
7366
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
7298
7367
  let next;
7299
7368
  try {
7300
- next = _chunkRSIKDWOPcjs.normalizeBrushSpec.call(void 0, { ...spec, id: this.brush.id }, problems);
7369
+ next = _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, { ...spec, id: this.brush.id }, problems);
7301
7370
  } catch (e) {
7302
7371
  throw new PaintEditorError(e.message);
7303
7372
  }
7304
- this.useBrush(_chunkRSIKDWOPcjs.resolveBrush.call(void 0, next), next, false);
7373
+ this.useBrush(_chunkTZOX7KWVcjs.resolveBrush.call(void 0, next), next, false);
7305
7374
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
7306
7375
  }
7307
7376
  /**
@@ -7310,22 +7379,22 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7310
7379
  */
7311
7380
  brushChanges(patch, from) {
7312
7381
  const entry = typeof from === "string" ? this.requireEntry(from) : null;
7313
- const base = entry ? entry.brush : typeof from === "object" ? _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, from, from) : this.brush;
7314
- const spec = entry ? entry.spec : typeof from === "object" ? _chunkRSIKDWOPcjs.migrateBrushV1.call(void 0, base) : this.brushSpec;
7315
- return engineChanges(base, _chunkRSIKDWOPcjs.resolveBrush.call(void 0, this.readBrushPatch(spec, patch, [])));
7382
+ const base = entry ? entry.brush : typeof from === "object" ? _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, from, from) : this.brush;
7383
+ const spec = entry ? entry.spec : typeof from === "object" ? _chunkTZOX7KWVcjs.migrateBrushV1.call(void 0, base) : this.brushSpec;
7384
+ return engineChanges(base, _chunkTZOX7KWVcjs.resolveBrush.call(void 0, this.readBrushPatch(spec, patch, [])));
7316
7385
  }
7317
7386
  readBrushPatch(base, patch, problems) {
7318
7387
  const { id: _id, name, ...rest } = patch;
7319
7388
  const paint = _optionalChain([rest, 'access', _378 => _378.colour, 'optionalAccess', _379 => _379.default]);
7320
7389
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
7321
7390
  try {
7322
- return _chunkRSIKDWOPcjs.normalizeBrushSpec.call(void 0, _chunkMQGQTKVWcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
7391
+ return _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, _chunkPYTJBVW5cjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
7323
7392
  } catch (e) {
7324
7393
  throw new PaintEditorError(e.message);
7325
7394
  }
7326
7395
  }
7327
7396
  useBrush(next, spec, builtin) {
7328
- next = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, next, next);
7397
+ next = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, next, next);
7329
7398
  if (builtin) next.builtin = true;
7330
7399
  else delete next.builtin;
7331
7400
  this.brush = next;
@@ -7341,9 +7410,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7341
7410
  * saved brush.
7342
7411
  */
7343
7412
  async saveBrush(options) {
7344
- if (!_chunkRSIKDWOPcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
7413
+ if (!_chunkTZOX7KWVcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
7345
7414
  if (this.brushLibrary.isBuiltin(options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
7346
- const spec = options.brush ? brushSpecOf(_chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, options.brush, this.brush), this.brushSpec) : this.brushSpec;
7415
+ const spec = options.brush ? brushSpecOf(_chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, options.brush, this.brush), this.brushSpec) : this.brushSpec;
7347
7416
  const { brush } = await libraryCall(() => this.brushLibrary.save({ ...spec, id: options.id, name: _nullishCoalesce(options.name, () => ( spec.name)) }, { overwrite: true }));
7348
7417
  await this.refreshBrushes();
7349
7418
  return this.requireBrush(brush.id);
@@ -7356,7 +7425,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7356
7425
  }
7357
7426
  /** The user's saved brushes, as the engine paints them. */
7358
7427
  getUserBrushes() {
7359
- return this.brushEntries.filter((e) => !e.builtin).map((e) => _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, e.brush, e.brush));
7428
+ return this.brushEntries.filter((e) => !e.builtin).map((e) => _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, e.brush, e.brush));
7360
7429
  }
7361
7430
  /** A brush library file (version 2) of the given brushes (default: the user's brushes). */
7362
7431
  exportBrushes(ids) {
@@ -7462,7 +7531,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7462
7531
  * brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
7463
7532
  */
7464
7533
  strokeGradient(init, brush, color) {
7465
- if (!_chunkRSIKDWOPcjs.brushTakesPaint.call(void 0, brush)) return null;
7534
+ if (!_chunkTZOX7KWVcjs.brushTakesPaint.call(void 0, brush)) return null;
7466
7535
  let g = null;
7467
7536
  if (init.paint !== void 0) {
7468
7537
  if (isPaintEffectPaint(init.paint)) return null;
@@ -7539,7 +7608,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7539
7608
  // --- Strokes -------------------------------------------------------------------
7540
7609
  strokeBrush(init) {
7541
7610
  let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
7542
- if (init.brush) brush = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
7611
+ if (init.brush) brush = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
7543
7612
  return brush;
7544
7613
  }
7545
7614
  /**
@@ -7563,16 +7632,16 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7563
7632
  let layer = (() => {
7564
7633
  const id = _nullishCoalesce(init.layerId, () => ( doc.activeLayerId));
7565
7634
  if (!id) throw new PaintEditorError("There is no active layer to paint on; add one with add_layer.");
7566
- const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, id);
7635
+ const loc = _chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id);
7567
7636
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
7568
7637
  const l = loc.layer;
7569
7638
  if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; paint on a pixel layer inside it.`);
7570
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
7639
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
7571
7640
  if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) to paint on it.`);
7572
7641
  return l;
7573
7642
  })();
7574
7643
  const brush = this.strokeBrush(init);
7575
- if (this.previewing && _chunkRSIKDWOPcjs.isWetBrush.call(void 0, brush)) throw new PaintEditorError(`Wet paint can't be previewed; the ${brush.name} brush paints wet media. Suggest it with a dry brush.`);
7644
+ if (this.previewing && _chunkTZOX7KWVcjs.isWetBrush.call(void 0, brush)) throw new PaintEditorError(`Wet paint can't be previewed; the ${brush.name} brush paints wet media. Suggest it with a dry brush.`);
7576
7645
  const effect = this.strokeEffect(init, brush);
7577
7646
  if (brush.light.amount > 0) {
7578
7647
  if (brush.engine === "sticker") throw new PaintEditorError(`The ${brush.name} brush sprays stickers, which don't take light yet; paint light with a dab or particle light brush (glow-gel, neon-marker; list_brush_presets lists them), or set light.amount to 0 (set_brush).`);
@@ -7595,16 +7664,16 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7595
7664
  throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
7596
7665
  }
7597
7666
  let wet;
7598
- if (_chunkRSIKDWOPcjs.isWetBrush.call(void 0, brush)) {
7667
+ if (_chunkTZOX7KWVcjs.isWetBrush.call(void 0, brush)) {
7599
7668
  this.requireWetIdle("painting");
7600
7669
  if (layer.offset.x || layer.offset.y) {
7601
7670
  const moved = { ...layer, surface: _chunk474IQG74cjs.translateSurface.call(void 0, layer.surface, layer.offset.x, layer.offset.y), offset: { x: 0, y: 0 } };
7602
- this.doc = { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => moved) };
7603
- if (doc !== this.doc) doc = { ...doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, doc.layers, layer.id, () => moved) };
7671
+ this.doc = { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => moved) };
7672
+ if (doc !== this.doc) doc = { ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, layer.id, () => moved) };
7604
7673
  layer = moved;
7605
7674
  }
7606
- if (!this.wet.wetLayerIds().includes(layer.id) && this.wet.wetLayerIds().length >= _chunkKBYB7OWBcjs.MAX_WET_LANES) {
7607
- throw new PaintEditorError(`At most ${_chunkKBYB7OWBcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
7675
+ if (!this.wet.wetLayerIds().includes(layer.id) && this.wet.wetLayerIds().length >= _chunkYHDHFJUCcjs.MAX_WET_LANES) {
7676
+ throw new PaintEditorError(`At most ${_chunkYHDHFJUCcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
7608
7677
  }
7609
7678
  this.beginWetOp();
7610
7679
  const world = this.wet.ensureLane(layer.id, brush.wet.medium);
@@ -7634,7 +7703,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7634
7703
  wet = { driver, surface: () => world.display(id).surface };
7635
7704
  } else if (this.wet.wetLayerIds().includes(layer.id)) {
7636
7705
  this.dryLayersFirst([layer.id]);
7637
- const dried = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layer.id).layer;
7706
+ const dried = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layer.id).layer;
7638
7707
  layer = dried;
7639
7708
  }
7640
7709
  let color = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
@@ -7657,7 +7726,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7657
7726
  layerId: layer.id,
7658
7727
  surface: layer.surface,
7659
7728
  offset: layer.offset,
7660
- lockTransparency: _chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "transparency"),
7729
+ lockTransparency: _chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "transparency"),
7661
7730
  brush,
7662
7731
  color: rgba,
7663
7732
  background: rgbaOf(doc.paper.color),
@@ -7689,7 +7758,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7689
7758
  const stroke = {
7690
7759
  id: `s${this.strokeCounter++}`,
7691
7760
  layerId: session.layerId,
7692
- brush: _chunkRSIKDWOPcjs.brushToJSON.call(void 0, init.brush),
7761
+ brush: _chunkTZOX7KWVcjs.brushToJSON.call(void 0, init.brush),
7693
7762
  color: init.colorHex,
7694
7763
  points: session.points.map((p) => ({ ...p })),
7695
7764
  seed: init.seed
@@ -7762,7 +7831,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7762
7831
  const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _414 => _414.doc, 'access', _415 => _415.stickers, 'optionalAccess', _416 => _416[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
7763
7832
  const wetLight = wetStroke && _optionalChain([this, 'access', _417 => _417.wet, 'access', _418 => _418.world, 'optionalAccess', _419 => _419.hasLane, 'call', _420 => _420(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
7764
7833
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
7765
- this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {}, ...light ? { light } : {} }, stroke)), wetStroke ? before : this.doc);
7834
+ this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {}, ...light ? { light } : {} }, stroke)), wetStroke ? before : this.doc);
7766
7835
  this.notifySample("end", s, [], stroke.id);
7767
7836
  }
7768
7837
  };
@@ -7793,14 +7862,14 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7793
7862
  const stroke = this.record(s);
7794
7863
  s.result.strokeId = stroke.id;
7795
7864
  this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _421 => _421.result, 'optionalAccess', _422 => _422.bounds]), () => ( null)));
7796
- const l = _chunkDPYAO5U6cjs.findLayer.call(void 0, out.layers, s.layerId).layer;
7865
+ const l = _chunkPVJMTLPJcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
7797
7866
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
7798
7867
  const ch = s.thickChannels();
7799
7868
  const sprayed = s.stickers();
7800
7869
  const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _423 => _423.wet, 'access', _424 => _424.world, 'optionalAccess', _425 => _425.hasLane, 'call', _426 => _426(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
7801
7870
  out = withLiveStroke({
7802
7871
  ...out,
7803
- layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
7872
+ layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
7804
7873
  strokes: [...out.strokes, stroke],
7805
7874
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
7806
7875
  ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _427 => _427.stickers, 'optionalAccess', _428 => _428[l.id]]), () => ( [])), ...sprayed] } } : {},
@@ -7816,8 +7885,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7816
7885
  if (this.wet.instantDry && result.strokeId) {
7817
7886
  this.wet.dry(session.layerId);
7818
7887
  this.logWet({ kind: "dry", layerId: session.layerId, at: out.strokes.length });
7819
- const dried = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, session.layerId).layer.surface;
7820
- out = { ...out, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, out.layers, session.layerId, (l) => ({ ...l, surface: dried })) };
7888
+ const dried = _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, session.layerId).layer.surface;
7889
+ out = { ...out, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, out.layers, session.layerId, (l) => ({ ...l, surface: dried })) };
7821
7890
  }
7822
7891
  result.wet = this.wet.isWet(session.layerId);
7823
7892
  }
@@ -7841,6 +7910,47 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7841
7910
  else this.emit([]);
7842
7911
  return result;
7843
7912
  }
7913
+ /**
7914
+ * Brushes vector path data (SVG `d`, document pixels) with the active brush, or `brushId` /
7915
+ * `brush`, as if drawn by hand: one recorded stroke per subpath, sampled every `spacing` px
7916
+ * with an optional `pressure` profile along each. All of it is one undo step. A given `seed`
7917
+ * seeds the first subpath; the next ones take the following seeds.
7918
+ */
7919
+ strokePath(init) {
7920
+ this.requireIdle("painting");
7921
+ if (typeof init.path !== "string" || !init.path.trim()) throw new PaintEditorError('path is empty; give SVG path data in document pixels, e.g. "M 10 10 C 40 0 80 60 120 30".');
7922
+ let subpaths;
7923
+ try {
7924
+ subpaths = samplePath(init.path, init);
7925
+ } catch (e) {
7926
+ throw new PaintEditorError(e instanceof Error ? e.message : String(e));
7927
+ }
7928
+ const { path: _path, spacing: _spacing, pressure: _pressure, ...stroke } = init;
7929
+ const before = this.doc;
7930
+ let doc = this.doc;
7931
+ let bounds = null;
7932
+ let dabs = 0;
7933
+ const strokeIds = [];
7934
+ let last = null;
7935
+ try {
7936
+ subpaths.forEach((points, i) => {
7937
+ last = this.runStroke(doc, { ...stroke, ...stroke.seed !== void 0 ? { seed: stroke.seed + i } : {}, start: points[0] }, points);
7938
+ doc = last.doc;
7939
+ bounds = unionRect(bounds, last.result.bounds);
7940
+ dabs += last.result.dabs;
7941
+ if (last.result.strokeId) strokeIds.push(last.result.strokeId);
7942
+ });
7943
+ } catch (e) {
7944
+ this.wetOp = null;
7945
+ throw e;
7946
+ }
7947
+ const run = last;
7948
+ if (_optionalChain([run, 'optionalAccess', _429 => _429.result, 'access', _430 => _430.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
7949
+ if (doc !== before || this.wetOp) this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _431 => _431.brush, 'access', _432 => _432.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
7950
+ else this.emit([]);
7951
+ const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _433 => _433.result, 'access', _434 => _434.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
7952
+ return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _435 => _435.result, 'access', _436 => _436.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _437 => _437.result, 'access', _438 => _438.wet]) !== void 0 ? { wet: run.result.wet } : {} };
7953
+ }
7844
7954
  /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
7845
7955
  checkPoints(points) {
7846
7956
  if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
@@ -7862,7 +7972,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7862
7972
  */
7863
7973
  replayStrokes(options) {
7864
7974
  this.requireIdle("replaying");
7865
- if (!_optionalChain([options, 'access', _429 => _429.strokeIds, 'optionalAccess', _430 => _430.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7975
+ if (!_optionalChain([options, 'access', _439 => _439.strokeIds, 'optionalAccess', _440 => _440.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7866
7976
  const strokes = options.strokeIds.map((id) => {
7867
7977
  const s = this.doc.strokes.find((x) => x.id === id);
7868
7978
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -7876,7 +7986,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7876
7986
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
7877
7987
  if (options.color === void 0) {
7878
7988
  for (const s of strokes) {
7879
- if (_optionalChain([s, 'access', _431 => _431.paint, 'optionalAccess', _432 => _432.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7989
+ if (_optionalChain([s, 'access', _441 => _441.paint, 'optionalAccess', _442 => _442.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7880
7990
  throw new PaintEditorError(`Stroke "${s.id}" paints with the effect "${s.paint.effect}"${s.paint.provider ? ` from provider "${s.paint.provider}"` : ""}, which is not rendered in this editor; render it first (prepareStrokeEffects; the replay_strokes tool does this) or recolour the replay with color.`);
7881
7991
  }
7882
7992
  }
@@ -7899,10 +8009,10 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7899
8009
  let brush = v.brush;
7900
8010
  if (options.brushId !== void 0) {
7901
8011
  const b = this.requireBrush(options.brushId);
7902
- brush = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
8012
+ brush = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
7903
8013
  }
7904
8014
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
7905
- if (!_chunkDPYAO5U6cjs.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.`);
8015
+ if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
7906
8016
  let load = s.load;
7907
8017
  if (load && options.color !== void 0 && load.reservoir) {
7908
8018
  const [r, g, b] = hexToRgb8(options.color);
@@ -7934,7 +8044,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7934
8044
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
7935
8045
  lightOf(layerId) {
7936
8046
  const l = this.wetLayer(layerId, "read the light of");
7937
- const info = lightInfo(_optionalChain([this, 'access', _433 => _433.doc, 'access', _434 => _434.light, 'optionalAccess', _435 => _435[l.id]]));
8047
+ const info = lightInfo(_optionalChain([this, 'access', _443 => _443.doc, 'access', _444 => _444.light, 'optionalAccess', _445 => _445[l.id]]));
7938
8048
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
7939
8049
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
7940
8050
  }
@@ -7985,7 +8095,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7985
8095
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
7986
8096
  if (!id) return null;
7987
8097
  this.requireLayer(id);
7988
- const ch = _optionalChain([this, 'access', _436 => _436.doc, 'access', _437 => _437.thick, 'optionalAccess', _438 => _438[id]]);
8098
+ const ch = _optionalChain([this, 'access', _446 => _446.doc, 'access', _447 => _447.thick, 'optionalAccess', _448 => _448[id]]);
7989
8099
  if (!ch) return null;
7990
8100
  const r = reliefInfo(ch);
7991
8101
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -8095,7 +8205,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8095
8205
  wetState() {
8096
8206
  const st = this.getState().wet;
8097
8207
  const backend = this.wet.backend();
8098
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _439 => _439.message]), () => ( _chunkKBYB7OWBcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
8208
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _449 => _449.message]), () => ( _chunkYHDHFJUCcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
8099
8209
  }
8100
8210
  /**
8101
8211
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -8164,11 +8274,11 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8164
8274
  wetPaper(options = {}) {
8165
8275
  this.requireIdle("wetting the paper");
8166
8276
  const l = this.wetLayer(options.layerId, "wet the paper of");
8167
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it first.`);
8277
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it first.`);
8168
8278
  const amount = _nullishCoalesce(options.amount, () => ( 1));
8169
8279
  if (!(amount > 0 && amount <= 1)) throw new PaintEditorError(`amount ${amount} is out of range; use above 0 up to 1.`);
8170
8280
  const rect = _nullishCoalesce(this.checkRect(options.rect), () => ( { x: 0, y: 0, width: this.doc.canvas.width, height: this.doc.canvas.height }));
8171
- if (!this.wet.wetLayerIds().includes(l.id) && this.wet.wetLayerIds().length >= _chunkKBYB7OWBcjs.MAX_WET_LANES) throw new PaintEditorError(`At most ${_chunkKBYB7OWBcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
8281
+ if (!this.wet.wetLayerIds().includes(l.id) && this.wet.wetLayerIds().length >= _chunkYHDHFJUCcjs.MAX_WET_LANES) throw new PaintEditorError(`At most ${_chunkYHDHFJUCcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
8172
8282
  const before = this.doc;
8173
8283
  this.beginWetOp();
8174
8284
  const world = this.wet.ensureLane(l.id);
@@ -8180,7 +8290,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8180
8290
  }
8181
8291
  /** Records a settings change as a wet event (not an undo step). */
8182
8292
  recordWetSetting(e) {
8183
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _440 => _440.wet, 'access', _441 => _441.world, 'optionalAccess', _442 => _442.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
8293
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _450 => _450.wet, 'access', _451 => _451.world, 'optionalAccess', _452 => _452.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
8184
8294
  }
8185
8295
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
8186
8296
  setWetParams(layerId, update) {
@@ -8246,11 +8356,11 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8246
8356
  /** The layers with the live stroke's surface in place. */
8247
8357
  currentLayers() {
8248
8358
  const override = this.frameOverride;
8249
- if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkDPYAO5U6cjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
8359
+ if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkPVJMTLPJcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
8250
8360
  const live = this.live;
8251
8361
  if (!live) return this.animatedView();
8252
- if (_optionalChain([this, 'access', _443 => _443.liveLayers, 'optionalAccess', _444 => _444.key]) === live.surface) return this.liveLayers.layers;
8253
- const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
8362
+ if (_optionalChain([this, 'access', _453 => _453.liveLayers, 'optionalAccess', _454 => _454.key]) === live.surface) return this.liveLayers.layers;
8363
+ const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
8254
8364
  this.liveLayers = { key: live.surface, layers };
8255
8365
  return layers;
8256
8366
  }
@@ -8272,7 +8382,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8272
8382
  tracingNode(t) {
8273
8383
  const { width, height } = this.doc.canvas;
8274
8384
  const key = this.tracingVersion * 100003 + width * 7 + height;
8275
- if (_optionalChain([this, 'access', _445 => _445.tracingCache, 'optionalAccess', _446 => _446.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8385
+ if (_optionalChain([this, 'access', _455 => _455.tracingCache, 'optionalAccess', _456 => _456.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8276
8386
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
8277
8387
  const image = resampleInto(src, t.rect, width, height);
8278
8388
  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 };
@@ -8287,7 +8397,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8287
8397
  let out = layers;
8288
8398
  for (const id of ids) {
8289
8399
  const baked = this.wet.bakedSurface(id);
8290
- if (baked && _chunkDPYAO5U6cjs.findLayer.call(void 0, out, id)) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, (l) => ({ ...l, surface: baked }));
8400
+ if (baked && _chunkPVJMTLPJcjs.findLayer.call(void 0, out, id)) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, (l) => ({ ...l, surface: baked }));
8291
8401
  }
8292
8402
  return out;
8293
8403
  }
@@ -8299,13 +8409,13 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8299
8409
  let out = layers;
8300
8410
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
8301
8411
  for (const id of ids) {
8302
- const ch = _optionalChain([live, 'optionalAccess', _447 => _447.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _448 => _448[id]]);
8303
- const l = ch && _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _449 => _449.layer]);
8412
+ const ch = _optionalChain([live, 'optionalAccess', _457 => _457.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _458 => _458[id]]);
8413
+ const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _459 => _459.layer]);
8304
8414
  if (!ch || !isPixelLayer(l)) continue;
8305
8415
  let cache = this.litCaches.get(id);
8306
8416
  if (!cache) this.litCaches.set(id, cache = new LitCache());
8307
8417
  const lit = cache.lit(l.surface, ch, this.lighting);
8308
- if (lit !== l.surface) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: lit }));
8418
+ if (lit !== l.surface) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: lit }));
8309
8419
  }
8310
8420
  return out;
8311
8421
  }
@@ -8320,13 +8430,13 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8320
8430
  if (!ids.size) return layers;
8321
8431
  let out = layers;
8322
8432
  for (const id of ids) {
8323
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _450 => _450.layer]);
8433
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _460 => _460.layer]);
8324
8434
  if (!isPixelLayer(l)) continue;
8325
8435
  let cache = this.lightCaches.get(id);
8326
8436
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
8327
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _451 => _451.liveThick, 'optionalAccess', _452 => _452.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.thick, 'optionalAccess', _455 => _455[id]]));
8328
- if (glowed !== l.surface) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
8329
- const committed = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _456 => _456.layer]);
8437
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _461 => _461.liveThick, 'optionalAccess', _462 => _462.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _463 => _463.doc, 'access', _464 => _464.thick, 'optionalAccess', _465 => _465[id]]));
8438
+ if (glowed !== l.surface) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
8439
+ const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _466 => _466.layer]);
8330
8440
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
8331
8441
  if (spill) out = insertAfter(out, id, { type: "pixel", id: `${id}${SPILL_SUFFIX}`, name: `${l.name} light`, visible: l.visible, opacity: l.opacity, blend: "linear-dodge", surface: spill, offset: { ...l.offset } });
8332
8442
  }
@@ -8338,7 +8448,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8338
8448
  if (!l.visible) continue;
8339
8449
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
8340
8450
  else if (isPixelLayer(l)) {
8341
- const thick = !committed && _optionalChain([this, 'access', _457 => _457.liveThick, 'optionalAccess', _458 => _458.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _459 => _459.doc, 'access', _460 => _460.thick, 'optionalAccess', _461 => _461[l.id]]);
8451
+ const thick = !committed && _optionalChain([this, 'access', _467 => _467.liveThick, 'optionalAccess', _468 => _468.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _469 => _469.doc, 'access', _470 => _470.thick, 'optionalAccess', _471 => _471[l.id]]);
8342
8452
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
8343
8453
  }
8344
8454
  }
@@ -8367,7 +8477,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8367
8477
  if (backlight) layers = [...layers, backlight];
8368
8478
  if (options.layerIds) {
8369
8479
  const picked = [];
8370
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _462 => _462.layer]), () => ( this.requireLayer(id))));
8480
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _472 => _472.layer]), () => ( this.requireLayer(id))));
8371
8481
  layers = picked.map((l) => ({ ...l, visible: true }));
8372
8482
  }
8373
8483
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -8383,7 +8493,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8383
8493
  */
8384
8494
  compositeTiles(rect, onTile, options = {}) {
8385
8495
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
8386
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _463 => _463.live, 'optionalAccess', _464 => _464.layerId]), () => ( this.doc.activeLayerId)) });
8496
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _473 => _473.live, 'optionalAccess', _474 => _474.layerId]), () => ( this.doc.activeLayerId)) });
8387
8497
  }
8388
8498
  /** The canvas as canvas-sized RGBA (paper included by default). */
8389
8499
  compositePixels(options = {}) {
@@ -8411,7 +8521,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8411
8521
  /** Wet settings saved with the document (`null` when they are all defaults). */
8412
8522
  wetJSON() {
8413
8523
  const layers = {};
8414
- for (const [id, set] of this.wet.settings) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) layers[id] = { params: { ...set.params }, flow: { ...set.flow } };
8524
+ for (const [id, set] of this.wet.settings) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) layers[id] = { params: { ...set.params }, flow: { ...set.flow } };
8415
8525
  const flat = this.wet.tilt.angle === 0;
8416
8526
  if (!Object.keys(layers).length && flat) return void 0;
8417
8527
  return { tilt: { ...this.wet.tilt }, layers };
@@ -8420,7 +8530,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8420
8530
  this.wet.reset();
8421
8531
  if (!raw || typeof raw !== "object") return;
8422
8532
  const r = raw;
8423
- this.wet.setTilt(_chunkKBYB7OWBcjs.normalizeTilt.call(void 0, _nullishCoalesce(r.tilt, () => ( {}))));
8533
+ this.wet.setTilt(_chunkYHDHFJUCcjs.normalizeTilt.call(void 0, _nullishCoalesce(r.tilt, () => ( {}))));
8424
8534
  if (r.layers && typeof r.layers === "object") {
8425
8535
  for (const [id, v] of Object.entries(r.layers)) {
8426
8536
  if (!v || typeof v !== "object") {
@@ -8428,7 +8538,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8428
8538
  continue;
8429
8539
  }
8430
8540
  const x = v;
8431
- this.wet.settings.set(id, { params: _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, _nullishCoalesce(x.params, () => ( {}))), flow: _chunkKBYB7OWBcjs.normalizeFlow.call(void 0, _nullishCoalesce(x.flow, () => ( {}))) });
8541
+ this.wet.settings.set(id, { params: _chunkYHDHFJUCcjs.normalizeWetParams.call(void 0, _nullishCoalesce(x.params, () => ( {}))), flow: _chunkYHDHFJUCcjs.normalizeFlow.call(void 0, _nullishCoalesce(x.flow, () => ( {}))) });
8432
8542
  }
8433
8543
  }
8434
8544
  }
@@ -8437,32 +8547,32 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8437
8547
  const ext = { ...this.extensions };
8438
8548
  const channels = {};
8439
8549
  for (const [id, ch] of Object.entries(_nullishCoalesce(this.doc.thick, () => ( {})))) {
8440
- if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) continue;
8550
+ if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
8441
8551
  const saved = thickToJSON(ch);
8442
8552
  if (saved) channels[id] = saved;
8443
8553
  }
8444
8554
  if (Object.keys(channels).length) ext.layerChannels = channels;
8445
8555
  else delete ext.layerChannels;
8446
8556
  const stickers = {};
8447
- for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.stickers, () => ( {})))) if (list.length && _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) stickers[id] = list.map((x) => ({ ...x }));
8557
+ for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.stickers, () => ( {})))) if (list.length && _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) stickers[id] = list.map((x) => ({ ...x }));
8448
8558
  if (Object.keys(stickers).length) ext.stickers = stickers;
8449
8559
  else delete ext.stickers;
8450
8560
  const liveStrokes = {};
8451
- for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) liveStrokes[id] = list.map(strokeToJSON);
8561
+ for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) if (_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) liveStrokes[id] = list.map(strokeToJSON);
8452
8562
  if (Object.keys(liveStrokes).length) ext.liveStrokes = liveStrokes;
8453
8563
  else delete ext.liveStrokes;
8454
8564
  const light = {};
8455
8565
  for (const [id, t] of Object.entries(_nullishCoalesce(this.doc.light, () => ( {})))) {
8456
- if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) continue;
8566
+ if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
8457
8567
  const saved = lightToJSON(_nullishCoalesce(this.wet.bakedLight(id), () => ( t)));
8458
8568
  if (saved) light[id] = saved;
8459
8569
  }
8460
8570
  if (Object.keys(light).length) ext.light = light;
8461
8571
  else delete ext.light;
8462
- const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)));
8572
+ const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)));
8463
8573
  if (Object.keys(spills).length) ext.lightSpill = spills;
8464
8574
  else delete ext.lightSpill;
8465
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _465 => _465.layer])));
8575
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _475 => _475.layer])));
8466
8576
  if (effectLayers) ext.effectLayers = effectLayers;
8467
8577
  else delete ext.effectLayers;
8468
8578
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -8478,7 +8588,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8478
8588
  if (ext.stickers && typeof ext.stickers === "object") {
8479
8589
  const stickers = {};
8480
8590
  for (const [id, list] of Object.entries(ext.stickers)) {
8481
- if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
8591
+ if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
8482
8592
  const ok = list.flatMap((x) => {
8483
8593
  if (!x || typeof x.id !== "string" || !Number.isFinite(x.x) || !Number.isFinite(x.y) || !(x.size > 0)) return [];
8484
8594
  try {
@@ -8498,7 +8608,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8498
8608
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
8499
8609
  const liveStrokes = {};
8500
8610
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
8501
- if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _466 => _466.layer])) || !Array.isArray(list)) continue;
8611
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _476 => _476.layer])) || !Array.isArray(list)) continue;
8502
8612
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
8503
8613
  if (ok.length !== list.length) problems.push(`Some strokes of stroke layer "${id}" could not be read; they were dropped (the layer's pixels are kept until a stroke is edited).`);
8504
8614
  liveStrokes[id] = ok;
@@ -8508,7 +8618,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8508
8618
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
8509
8619
  const effectLayers = {};
8510
8620
  for (const [id, v] of Object.entries(ext.effectLayers)) {
8511
- if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _467 => _467.layer]))) continue;
8621
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _477 => _477.layer]))) continue;
8512
8622
  const source = readPaintEffectSource(v);
8513
8623
  if (source) effectLayers[id] = source;
8514
8624
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -8527,7 +8637,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8527
8637
  if (ext.lightSpill && typeof ext.lightSpill === "object") {
8528
8638
  for (const [id, v] of Object.entries(ext.lightSpill)) {
8529
8639
  try {
8530
- if (_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id)) this.lightSpills[id] = normalizeLightSpill(_nullishCoalesce(v, () => ( {})));
8640
+ if (_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id)) this.lightSpills[id] = normalizeLightSpill(_nullishCoalesce(v, () => ( {})));
8531
8641
  } catch (e10) {
8532
8642
  problems.push(`The light spill of layer "${id}" could not be read; it takes the defaults.`);
8533
8643
  }
@@ -8536,7 +8646,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8536
8646
  if (ext.light && typeof ext.light === "object") {
8537
8647
  const light = {};
8538
8648
  for (const [id, v] of Object.entries(ext.light)) {
8539
- if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _468 => _468.layer]))) continue;
8649
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _478 => _478.layer]))) continue;
8540
8650
  try {
8541
8651
  light[id] = lightFromJSON(v);
8542
8652
  } catch (e) {
@@ -8549,7 +8659,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8549
8659
  if (!raw || typeof raw !== "object") return state;
8550
8660
  const thick = {};
8551
8661
  for (const [id, v] of Object.entries(raw)) {
8552
- if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id)) continue;
8662
+ if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id)) continue;
8553
8663
  try {
8554
8664
  thick[id] = thickFromJSON(v);
8555
8665
  } catch (e) {
@@ -8572,7 +8682,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8572
8682
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
8573
8683
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
8574
8684
  for (const s of loaded.state.strokes) {
8575
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _469 => _469.exec, 'call', _470 => _470(s.id), 'optionalAccess', _471 => _471[1]]), () => ( 0)));
8685
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _479 => _479.exec, 'call', _480 => _480(s.id), 'optionalAccess', _481 => _481[1]]), () => ( 0)));
8576
8686
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8577
8687
  }
8578
8688
  this.undoStack = [];
@@ -8580,7 +8690,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8580
8690
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
8581
8691
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
8582
8692
  for (const s of list) {
8583
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _472 => _472.exec, 'call', _473 => _473(s.id), 'optionalAccess', _474 => _474[1]]), () => ( 0)));
8693
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _482 => _482.exec, 'call', _483 => _483(s.id), 'optionalAccess', _484 => _484[1]]), () => ( 0)));
8584
8694
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8585
8695
  }
8586
8696
  }
@@ -8677,10 +8787,10 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8677
8787
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
8678
8788
  });
8679
8789
  const layers = toStandard(dried);
8680
- const result = _chunkYSGW7VV4cjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
8790
+ const result = _chunk43NT242Dcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
8681
8791
  for (const [mode, names] of changed) {
8682
- const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _475 => _475.find, 'call', _476 => _476((m) => m.id === mode), 'optionalAccess', _477 => _477.label]), () => ( mode));
8683
- const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _478 => _478.find, 'call', _479 => _479((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _480 => _480.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
8792
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _485 => _485.find, 'call', _486 => _486((m) => m.id === mode), 'optionalAccess', _487 => _487.label]), () => ( mode));
8793
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _488 => _488.find, 'call', _489 => _489((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _490 => _490.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
8684
8794
  const list = names.map((n) => `"${n}"`).join(", ");
8685
8795
  const one = names.length === 1;
8686
8796
  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).`);
@@ -8802,7 +8912,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8802
8912
  const { src, pixels } = this.importImage(options, "The reference image");
8803
8913
  const ref2 = {
8804
8914
  id: `ref${this.nextReferenceId++}`,
8805
- name: _optionalChain([options, 'access', _481 => _481.name, 'optionalAccess', _482 => _482.trim, 'call', _483 => _483()]) || `Reference ${this.guides.references.length + 1}`,
8915
+ name: _optionalChain([options, 'access', _491 => _491.name, 'optionalAccess', _492 => _492.trim, 'call', _493 => _493()]) || `Reference ${this.guides.references.length + 1}`,
8806
8916
  src,
8807
8917
  width: pixels.width,
8808
8918
  height: pixels.height,
@@ -8881,7 +8991,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8881
8991
  try {
8882
8992
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
8883
8993
  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 });
8884
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _484 => _484.exec, 'call', _485 => _485(ref2.id), 'optionalAccess', _486 => _486[1]]), () => ( 0)));
8994
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _494 => _494.exec, 'call', _495 => _495(ref2.id), 'optionalAccess', _496 => _496[1]]), () => ( 0)));
8885
8995
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
8886
8996
  } catch (e) {
8887
8997
  problems.push(e.message);
@@ -8892,7 +9002,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8892
9002
  guides.stencils = [];
8893
9003
  r.stencils.forEach((raw2, i) => {
8894
9004
  try {
8895
- const id = typeof _optionalChain([raw2, 'optionalAccess', _487 => _487.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
9005
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _497 => _497.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
8896
9006
  guides.stencils.push(normalizeStencil(raw2, id));
8897
9007
  const n = Number(id.slice(7));
8898
9008
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -8915,12 +9025,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8915
9025
  /** The next free sticker number (ids `st<n>` are unique across the document). */
8916
9026
  nextStickerNumber(doc = this.doc) {
8917
9027
  let n = 0;
8918
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _488 => _488.exec, 'call', _489 => _489(st.id), 'optionalAccess', _490 => _490[1]]), () => ( 0))));
9028
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _498 => _498.exec, 'call', _499 => _499(st.id), 'optionalAccess', _500 => _500[1]]), () => ( 0))));
8919
9029
  return n + 1;
8920
9030
  }
8921
9031
  stickerLayer(layerId) {
8922
9032
  const l = this.wetLayer(layerId, "edit the stickers of");
8923
- const stickers = _optionalChain([this, 'access', _491 => _491.doc, 'access', _492 => _492.stickers, 'optionalAccess', _493 => _493[l.id]]);
9033
+ const stickers = _optionalChain([this, 'access', _501 => _501.doc, 'access', _502 => _502.stickers, 'optionalAccess', _503 => _503[l.id]]);
8924
9034
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (sticker-stars; list_brush_presets lists them).`);
8925
9035
  return { layer: l, stickers };
8926
9036
  }
@@ -8979,19 +9089,19 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8979
9089
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8980
9090
  if (!id) return [];
8981
9091
  this.requireLayer(id);
8982
- return (_nullishCoalesce(_optionalChain([this, 'access', _494 => _494.doc, 'access', _495 => _495.stickers, 'optionalAccess', _496 => _496[id]]), () => ( []))).map((s) => ({ ...s }));
9092
+ return (_nullishCoalesce(_optionalChain([this, 'access', _504 => _504.doc, 'access', _505 => _505.stickers, 'optionalAccess', _506 => _506[id]]), () => ( []))).map((s) => ({ ...s }));
8983
9093
  }
8984
9094
  /**
8985
9095
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
8986
9096
  * only the tiles under those rects are redrawn.
8987
9097
  */
8988
9098
  commitStickers(label, layer, stickers, dirty) {
8989
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
9099
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
8990
9100
  this.requireStickerArt(stickers);
8991
9101
  const before = _nullishCoalesce(this.previewBase(), () => ( this.doc));
8992
9102
  this.stickerPreview = null;
8993
9103
  const surface = this.redrawStickers(layer, stickers, dirty);
8994
- const doc = { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: stickers } };
9104
+ const doc = { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: stickers } };
8995
9105
  this.commit(label, this.withPaintEvent(doc, { kind: "stickers", layerId: layer.id, data: { stickers: stickers.map((s) => ({ ...s })) } }), before);
8996
9106
  }
8997
9107
  redrawStickers(layer, stickers, dirty) {
@@ -9000,7 +9110,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9000
9110
  }
9001
9111
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
9002
9112
  previewBase() {
9003
- return _optionalChain([this, 'access', _497 => _497.stickerPreview, 'optionalAccess', _498 => _498.shown]) === this.doc ? this.stickerPreview.base : null;
9113
+ return _optionalChain([this, 'access', _507 => _507.stickerPreview, 'optionalAccess', _508 => _508.shown]) === this.doc ? this.stickerPreview.base : null;
9004
9114
  }
9005
9115
  readStickerUpdate(update) {
9006
9116
  try {
@@ -9015,7 +9125,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9015
9125
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
9016
9126
  if (!id) return null;
9017
9127
  this.requireLayer(id);
9018
- const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _499 => _499.doc, 'access', _500 => _500.stickers, 'optionalAccess', _501 => _501[id]]), () => ( [])), x, y, this.stickerArt.get);
9128
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _509 => _509.doc, 'access', _510 => _510.stickers, 'optionalAccess', _511 => _511[id]]), () => ( [])), x, y, this.stickerArt.get);
9019
9129
  return hit ? { ...hit } : null;
9020
9130
  }
9021
9131
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -9031,7 +9141,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9031
9141
  */
9032
9142
  previewSticker(layerId, id, update) {
9033
9143
  const { layer, stickers } = this.stickerLayer(layerId);
9034
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
9144
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
9035
9145
  const i = stickers.findIndex((s) => s.id === id);
9036
9146
  if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
9037
9147
  const next = { ...stickers[i], ...this.readStickerUpdate(update) };
@@ -9039,7 +9149,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9039
9149
  const dirty = [stickerRect(stickers[i]), stickerRect(next)];
9040
9150
  const base = _nullishCoalesce(this.previewBase(), () => ( this.doc));
9041
9151
  const surface = this.redrawStickers(layer, list, dirty);
9042
- this.doc = { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: list } };
9152
+ this.doc = { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: list } };
9043
9153
  this.stickerPreview = { base, shown: this.doc };
9044
9154
  this.emit(dirty);
9045
9155
  return { ...next };
@@ -9071,8 +9181,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9071
9181
  const layer = this.wetLayer(layerId, "add stickers to");
9072
9182
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
9073
9183
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
9074
- const existing = _optionalChain([this, 'access', _502 => _502.doc, 'access', _503 => _503.stickers, 'optionalAccess', _504 => _504[layer.id]]);
9075
- if (!_optionalChain([existing, 'optionalAccess', _505 => _505.length])) {
9184
+ const existing = _optionalChain([this, 'access', _512 => _512.doc, 'access', _513 => _513.stickers, 'optionalAccess', _514 => _514[layer.id]]);
9185
+ if (!_optionalChain([existing, 'optionalAccess', _515 => _515.length])) {
9076
9186
  if (this.wet.wetLayerIds().includes(layer.id) || _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; add stickers to an empty layer (add_layer) or a sticker layer so they stay editable.`);
9077
9187
  }
9078
9188
  let n = this.nextStickerNumber();
@@ -9089,7 +9199,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9089
9199
  const id = n++;
9090
9200
  return { id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u };
9091
9201
  });
9092
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _506 => _506.length]) ? added.map(stickerRect) : void 0);
9202
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _516 => _516.length]) ? added.map(stickerRect) : void 0);
9093
9203
  return added.map((s) => ({ ...s }));
9094
9204
  }
9095
9205
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -9128,20 +9238,20 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9128
9238
  }
9129
9239
  liveStrokeLayer(layerId, what) {
9130
9240
  const l = this.wetLayer(layerId, what);
9131
- const strokes = _optionalChain([this, 'access', _507 => _507.doc, 'access', _508 => _508.liveStrokes, 'optionalAccess', _509 => _509[l.id]]);
9241
+ const strokes = _optionalChain([this, 'access', _517 => _517.doc, 'access', _518 => _518.liveStrokes, 'optionalAccess', _519 => _519[l.id]]);
9132
9242
  if (!strokes) throw new PaintEditorError(`Layer "${l.name}" is not a stroke layer; add one with add_layer {type: "strokes"} (or convert_to_stroke_layer on an empty layer), then paint on it.`);
9133
9243
  return { layer: l, strokes };
9134
9244
  }
9135
9245
  /** Whether a layer is a live stroke layer. */
9136
9246
  isLiveStrokeLayer(layerId) {
9137
- return Boolean(_optionalChain([this, 'access', _510 => _510.doc, 'access', _511 => _511.liveStrokes, 'optionalAccess', _512 => _512[layerId]]));
9247
+ return Boolean(_optionalChain([this, 'access', _520 => _520.doc, 'access', _521 => _521.liveStrokes, 'optionalAccess', _522 => _522[layerId]]));
9138
9248
  }
9139
9249
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
9140
9250
  convertToLiveStrokes(layerId) {
9141
9251
  this.requireIdle("converting a layer");
9142
9252
  const l = this.paintTarget(layerId, "convert");
9143
- if (_optionalChain([this, 'access', _513 => _513.doc, 'access', _514 => _514.liveStrokes, 'optionalAccess', _515 => _515[l.id]])) return this.describeLayer(l);
9144
- if (_optionalChain([this, 'access', _516 => _516.doc, 'access', _517 => _517.stickers, 'optionalAccess', _518 => _518[l.id], 'optionalAccess', _519 => _519.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
9253
+ if (_optionalChain([this, 'access', _523 => _523.doc, 'access', _524 => _524.liveStrokes, 'optionalAccess', _525 => _525[l.id]])) return this.describeLayer(l);
9254
+ if (_optionalChain([this, 'access', _526 => _526.doc, 'access', _527 => _527.stickers, 'optionalAccess', _528 => _528[l.id], 'optionalAccess', _529 => _529.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
9145
9255
  if (_chunk474IQG74cjs.contentBounds.call(void 0, l.surface) || this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" already has paint, which isn't kept as strokes; convert an empty layer or add a stroke layer (add_layer {type: "strokes"}).`);
9146
9256
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
9147
9257
  return this.describeLayer(this.getLayer(l.id));
@@ -9154,7 +9264,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9154
9264
  findLiveStroke(id) {
9155
9265
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
9156
9266
  const index = strokes.findIndex((x) => x.id === id);
9157
- const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _520 => _520.layer]);
9267
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _530 => _530.layer]);
9158
9268
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
9159
9269
  }
9160
9270
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -9174,15 +9284,15 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9174
9284
  let brush = was.brush;
9175
9285
  if (update.brushId !== void 0) {
9176
9286
  const b = this.requireBrush(update.brushId);
9177
- brush = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
9287
+ brush = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
9178
9288
  }
9179
9289
  if (update.brush !== void 0) {
9180
9290
  if (!update.brush || typeof update.brush !== "object") throw new PaintEditorError("brush must be an object of brush settings (as set_brush takes).");
9181
- brush = _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
9291
+ brush = _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
9182
9292
  }
9183
9293
  const why = liveStrokeRefusal(brush);
9184
9294
  if (why) throw new PaintEditorError(why);
9185
- const next = { ...was, brush: _chunkRSIKDWOPcjs.brushToJSON.call(void 0, brush) };
9295
+ const next = { ...was, brush: _chunkTZOX7KWVcjs.brushToJSON.call(void 0, brush) };
9186
9296
  if (update.seed !== void 0) {
9187
9297
  if (!Number.isInteger(update.seed) || update.seed < 0) throw new PaintEditorError(`seed ${update.seed} must be a whole number of 0 or more.`);
9188
9298
  next.seed = update.seed;
@@ -9249,9 +9359,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9249
9359
  const layers = /* @__PURE__ */ new Map();
9250
9360
  for (const f of found) layers.set(f.layer.id, f.layer);
9251
9361
  for (const [layerId, layer] of layers) {
9252
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _521 => _521.liveStrokes, 'optionalAccess', _522 => _522[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9362
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _531 => _531.liveStrokes, 'optionalAccess', _532 => _532[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9253
9363
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
9254
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _523 => _523.liveStrokes, 'optionalAccess', _524 => _524[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
9364
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _533 => _533.liveStrokes, 'optionalAccess', _534 => _534[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
9255
9365
  }
9256
9366
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
9257
9367
  return { removed: [...ids], bounds };
@@ -9318,10 +9428,10 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9318
9428
  this.commit(label, this.withLiveStrokes(this.doc, layer, list, dirty));
9319
9429
  }
9320
9430
  withLiveStrokes(doc, layer, list, dirty) {
9321
- if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
9322
- const current = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _525 => _525.layer]);
9431
+ if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
9432
+ const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _535 => _535.layer]);
9323
9433
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
9324
- const next = { ...doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
9434
+ const next = { ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
9325
9435
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
9326
9436
  }
9327
9437
  /** Where a stroke painted (document pixels): as learnt when it was painted or drawn, else an estimate from its points and brush. */
@@ -9350,7 +9460,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9350
9460
  };
9351
9461
  const paint = st.paint && this.liveEffectAt !== null && isLiveEffect(st) ? framePaint(st.paint, this.liveEffectAt) : st.paint;
9352
9462
  const init = { layerId: plain.id, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...paint ? { paint } : {}, snapToPerspective: false, stencils: false, maskStencils: _nullishCoalesce(st.stencils, () => ( [])) };
9353
- const session = this.sessionFor({ ...doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, doc.layers, plain.id, () => ({ ...plain, surface })) }, init, host);
9463
+ const session = this.sessionFor({ ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, plain.id, () => ({ ...plain, surface })) }, init, host);
9354
9464
  session.push(st.points);
9355
9465
  const result = session.end();
9356
9466
  const had = this.paintedBounds.get(st);
@@ -9397,8 +9507,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9397
9507
  if (!this.animatedLayers.size) return this.doc.layers;
9398
9508
  let layers = this.doc.layers;
9399
9509
  for (const [id, a] of this.animatedLayers) {
9400
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _526 => _526.layer]);
9401
- if (isPixelLayer(l) && l.surface === a.base) layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
9510
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _536 => _536.layer]);
9511
+ if (isPixelLayer(l) && l.surface === a.base) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
9402
9512
  }
9403
9513
  return layers;
9404
9514
  }
@@ -9407,7 +9517,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9407
9517
  const layers = [];
9408
9518
  const sources = /* @__PURE__ */ new Map();
9409
9519
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
9410
- const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _527 => _527.layer]);
9520
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _537 => _537.layer]);
9411
9521
  const live = strokes.filter(isLiveEffect);
9412
9522
  if (!isPixelLayer(layer) || !live.length) continue;
9413
9523
  layers.push({ layer, strokes });
@@ -9538,7 +9648,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9538
9648
  stencilSelection(stencils = this.guides.stencils) {
9539
9649
  const { width, height } = this.doc.canvas;
9540
9650
  const size = `${width}x${height}`;
9541
- if (_optionalChain([this, 'access', _528 => _528.stencilCache, 'optionalAccess', _529 => _529.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9651
+ if (_optionalChain([this, 'access', _538 => _538.stencilCache, 'optionalAccess', _539 => _539.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9542
9652
  const mask = stencilMask(stencils, width, height);
9543
9653
  this.stencilCache = { key: stencils, size, mask };
9544
9654
  return mask;
@@ -9600,7 +9710,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9600
9710
  makeSwatch(color, name) {
9601
9711
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
9602
9712
  const out = { color: _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
9603
- if (_optionalChain([name, 'optionalAccess', _530 => _530.trim, 'call', _531 => _531()])) out.name = name.trim();
9713
+ if (_optionalChain([name, 'optionalAccess', _540 => _540.trim, 'call', _541 => _541()])) out.name = name.trim();
9604
9714
  if (p.type === "gradient") out.paint = p;
9605
9715
  return out;
9606
9716
  }
@@ -9652,7 +9762,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9652
9762
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
9653
9763
  */
9654
9764
  mixOnPad(paints2, options = {}) {
9655
- const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _532 => _532.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _533 => _533.parts]) }));
9765
+ const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _542 => _542.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _543 => _543.parts]) }));
9656
9766
  let r;
9657
9767
  try {
9658
9768
  r = this.pad.mix(parsed, options);
@@ -9741,7 +9851,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9741
9851
  }
9742
9852
  /** A layer's tile surface (live while stroking), for thumbnails. */
9743
9853
  layerSurface(id) {
9744
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _534 => _534.layer]);
9854
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _544 => _544.layer]);
9745
9855
  return isPixelLayer(l) ? l.surface : null;
9746
9856
  }
9747
9857
  }, _class19.__initStatic(), _class19);
@@ -9763,7 +9873,7 @@ function insertAfter(layers, id, node) {
9763
9873
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
9764
9874
  }
9765
9875
  function isLiveEffect(s) {
9766
- return _optionalChain([s, 'access', _535 => _535.paint, 'optionalAccess', _536 => _536.type]) === "effect" && s.paint.live === true;
9876
+ return _optionalChain([s, 'access', _545 => _545.paint, 'optionalAccess', _546 => _546.type]) === "effect" && s.paint.live === true;
9767
9877
  }
9768
9878
  function framePaint(p, t) {
9769
9879
  return { ...p, time: p.time + t };
@@ -9788,13 +9898,13 @@ function clipRect(r, width, height) {
9788
9898
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
9789
9899
  }
9790
9900
  function withLiveStroke(doc, stroke) {
9791
- const list = _optionalChain([doc, 'access', _537 => _537.liveStrokes, 'optionalAccess', _538 => _538[stroke.layerId]]);
9901
+ const list = _optionalChain([doc, 'access', _547 => _547.liveStrokes, 'optionalAccess', _548 => _548[stroke.layerId]]);
9792
9902
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
9793
9903
  }
9794
9904
  function shiftDocument(doc, dx, dy) {
9795
9905
  if (!dx && !dy) return doc;
9796
9906
  let layers = doc.layers;
9797
- for (const l of _chunkDPYAO5U6cjs.flattenLayers.call(void 0, doc.layers)) if (l.type === "pixel") layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, offset: movePoint(l.offset, dx, dy) }));
9907
+ for (const l of _chunkPVJMTLPJcjs.flattenLayers.call(void 0, doc.layers)) if (l.type === "pixel") layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, offset: movePoint(l.offset, dx, dy) }));
9798
9908
  const m = [1, 0, 0, 1, dx, dy];
9799
9909
  const moveStickers = (list) => list.map((s) => ({ ...s, x: Math.round((s.x + dx) * 100) / 100, y: Math.round((s.y + dy) * 100) / 100 }));
9800
9910
  const out = {
@@ -9815,9 +9925,9 @@ function shiftDocument(doc, dx, dy) {
9815
9925
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
9816
9926
  if (doc.paintEvents) {
9817
9927
  out.paintEvents = doc.paintEvents.map((e) => {
9818
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _539 => _539.data, 'optionalAccess', _540 => _540.stickers]) : void 0;
9928
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _549 => _549.data, 'optionalAccess', _550 => _550.stickers]) : void 0;
9819
9929
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
9820
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _541 => _541.data, 'optionalAccess', _542 => _542.strokes]) : void 0;
9930
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _551 => _551.data, 'optionalAccess', _552 => _552.strokes]) : void 0;
9821
9931
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
9822
9932
  });
9823
9933
  }
@@ -9906,8 +10016,8 @@ function strokeSchedule(points) {
9906
10016
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
9907
10017
  }
9908
10018
  function strokeDuration(points, max = 1800) {
9909
- const t0 = _optionalChain([points, 'access', _543 => _543[0], 'optionalAccess', _544 => _544.t]);
9910
- const t1 = _optionalChain([points, 'access', _545 => _545[points.length - 1], 'optionalAccess', _546 => _546.t]);
10019
+ const t0 = _optionalChain([points, 'access', _553 => _553[0], 'optionalAccess', _554 => _554.t]);
10020
+ const t1 = _optionalChain([points, 'access', _555 => _555[points.length - 1], 'optionalAccess', _556 => _556.t]);
9911
10021
  let ms;
9912
10022
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
9913
10023
  else {
@@ -9961,7 +10071,7 @@ var PaintDirector = class {
9961
10071
  }
9962
10072
  where(id) {
9963
10073
  const a = this.presence.get(id);
9964
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _547 => _547.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _548 => _548.y]), () => ( 0)) };
10074
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _557 => _557.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _558 => _558.y]), () => ( 0)) };
9965
10075
  }
9966
10076
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
9967
10077
  async glide(id, to, ms = 380) {
@@ -10008,8 +10118,8 @@ var PaintDirector = class {
10008
10118
  }
10009
10119
  case "replay": {
10010
10120
  await this.say(id, command.note, 500);
10011
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _549 => _549.replay, 'access', _550 => _550.strokeIds, 'optionalAccess', _551 => _551.includes, 'call', _552 => _552(s.id)]));
10012
- const first = _optionalChain([source, 'access', _553 => _553[0], 'optionalAccess', _554 => _554.points, 'access', _555 => _555[0]]);
10121
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _559 => _559.replay, 'access', _560 => _560.strokeIds, 'optionalAccess', _561 => _561.includes, 'call', _562 => _562(s.id)]));
10122
+ const first = _optionalChain([source, 'access', _563 => _563[0], 'optionalAccess', _564 => _564.points, 'access', _565 => _565[0]]);
10013
10123
  if (first) await this.glide(id, first);
10014
10124
  const result = c.replayStrokes(command.replay);
10015
10125
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -10839,7 +10949,7 @@ function createPaintWetTools(c) {
10839
10949
  type: "object",
10840
10950
  properties: {
10841
10951
  layerId: LAYER_ID2,
10842
- kind: { type: "string", enum: [..._chunkKBYB7OWBcjs.WET_FLOW_KINDS], description: "none, linear, swirl, radial or turbulent." },
10952
+ kind: { type: "string", enum: [..._chunkYHDHFJUCcjs.WET_FLOW_KINDS], description: "none, linear, swirl, radial or turbulent." },
10843
10953
  strength: UNIT("How hard it pushes, 0..1 (1 is about a 25\xB0 tilt; default 0.5)."),
10844
10954
  angle: { type: "number", minimum: -360, maximum: 360, description: "linear: direction in degrees clockwise from canvas down (default 0)." },
10845
10955
  center: {
@@ -11443,10 +11553,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
11443
11553
  name: "set_brush",
11444
11554
  title: "Set the brush",
11445
11555
  description: "Chooses the active brush (id, from list_brush_presets) and / or changes it with facets laid over it (objects merge, lists and values replace, marks of another kind replace the marks; the brush library's create_brush fields); unset removes whole facets first (unset colour drops a brush's own gradient). Strokes without a brush use it. Editor state, not an undo step: the changes stay on the active brush until the library's create_brush or update_brush stores a brush. Returns the active brush as facets, the engine it paints with, and problems (values clamped or dropped).",
11446
- inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brush_presets to start from (default the active brush)." }, name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." }, ..._chunkMQGQTKVWcjs.BRUSH_PATCH_PROPERTIES, unset: _chunkMQGQTKVWcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
11556
+ inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brush_presets to start from (default the active brush)." }, name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." }, ..._chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES, unset: _chunkPYTJBVW5cjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
11447
11557
  annotations: { title: "Set the brush", ...SET4 },
11448
11558
  handler: async ({ id, unset, ...patch }) => {
11449
- const stamps = _optionalChain([patch, 'access', _556 => _556.tip, 'optionalAccess', _557 => _557.stamps]);
11559
+ const stamps = _optionalChain([patch, 'access', _566 => _566.tip, 'optionalAccess', _567 => _567.stamps]);
11450
11560
  if (stamps) await c.prepareStickers(stamps);
11451
11561
  const r = c.setBrushFacets(patch, id, unset);
11452
11562
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -11539,7 +11649,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11539
11649
  points: POINTS,
11540
11650
  layerId: LAYER_ID4,
11541
11651
  brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
11542
- brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkMQGQTKVWcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
11652
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
11543
11653
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
11544
11654
  paint: { ..._chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
11545
11655
  seed: { type: "integer", minimum: 0, description: "Jitter seed (default a new one); the same seed and points give the same marks." },
@@ -11555,7 +11665,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11555
11665
  const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
11556
11666
  const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
11557
11667
  if (base) {
11558
- const refs = brushStickerRefs(_chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
11668
+ const refs = brushStickerRefs(_chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
11559
11669
  if (refs.length) await c.prepareStickers(refs);
11560
11670
  }
11561
11671
  const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush, color: a.color, paint: a.paint, seed: a.seed, snapToPerspective: a.snapToPerspective };
@@ -11563,6 +11673,41 @@ function createPaintEditorToolProvider(controller, options = {}) {
11563
11673
  return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11564
11674
  }
11565
11675
  });
11676
+ add({
11677
+ name: "stroke_path",
11678
+ title: "Brush along a path",
11679
+ description: "Brushes vector path data (SVG path d in document pixels: M, L, H, V, C, S, Q, T, A and Z) on a pixel layer with a library brush or the active one, as if drawn by hand along it: the outline of a shape, a lettering guide, a curve from a vector tool. Each subpath becomes one recorded stroke, sampled every spacing px, with an optional pressure profile spread along each subpath (a taper such as [0.2, 1, 0.2]); closed subpaths end where they start. Brushes behave as in paint_stroke (grain, pick-up, wet and thick paint, guides off). One undo step for the whole path. Returns the layer id, changed bounds, dab count and the recorded strokeIds (for replay_strokes, update_stroke).",
11680
+ inputSchema: {
11681
+ type: "object",
11682
+ properties: {
11683
+ path: { type: "string", minLength: 1, description: 'SVG path data in document pixels, e.g. "M 40 200 C 120 40 280 40 360 200". Several subpaths paint several strokes.' },
11684
+ spacing: { type: "number", minimum: 0.25, maximum: 100, description: "Distance between samples along the path in document pixels (default 2); the brush spaces its own dabs, so this only sets how closely curves are followed." },
11685
+ pressure: { type: "array", minItems: 1, maxItems: 64, items: { type: "number", minimum: 0, maximum: 1 }, description: "Pen pressure along each subpath, spread evenly from start to end (default full pressure); [0.2, 1, 0.2] tapers both ends." },
11686
+ layerId: LAYER_ID4,
11687
+ brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
11688
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
11689
+ color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
11690
+ paint: { ..._chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA, description: "What the strokes paint with instead of the editor's paint: a colour, or gradient paint that changes colour as each stroke goes." },
11691
+ seed: { type: "integer", minimum: 0, description: "Jitter seed of the first subpath, the next ones take the following seeds (default new ones); the same seed and path give the same marks." }
11692
+ },
11693
+ required: ["path"],
11694
+ additionalProperties: false
11695
+ },
11696
+ annotations: { title: "Brush along a path", ...WRITE5 },
11697
+ coordinates: { out: ["bounds"] },
11698
+ handler: async (a) => {
11699
+ await c.wetIdle();
11700
+ const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
11701
+ const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
11702
+ if (base) {
11703
+ const refs = brushStickerRefs(_chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
11704
+ if (refs.length) await c.prepareStickers(refs);
11705
+ }
11706
+ const path = options.origin && typeof a.path === "string" && a.path.trim() ? _chunkGF2RBSDMcjs.bezierPathToSvg.call(void 0, a.path, { offset: { x: -options.origin.x, y: -options.origin.y } }) : a.path;
11707
+ const r = c.strokePath({ path, spacing: a.spacing, pressure: a.pressure, layerId: a.layerId, brushId: a.brushId, brush, color: a.color, paint: a.paint, seed: a.seed });
11708
+ return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11709
+ }
11710
+ });
11566
11711
  add({
11567
11712
  name: "get_live_stroke",
11568
11713
  title: "Get the stroke being painted",
@@ -11606,7 +11751,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11606
11751
  if (ids) {
11607
11752
  for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke "${id}". Call list_strokes without ids for the ids.`);
11608
11753
  }
11609
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _558 => _558.document, 'access', _559 => _559.liveStrokes, 'optionalAccess', _560 => _560[s.layerId], 'optionalAccess', _561 => _561.includes, 'call', _562 => _562(s)]) === true)) };
11754
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _568 => _568.document, 'access', _569 => _569.liveStrokes, 'optionalAccess', _570 => _570[s.layerId], 'optionalAccess', _571 => _571.includes, 'call', _572 => _572(s)]) === true)) };
11610
11755
  }
11611
11756
  });
11612
11757
  add({
@@ -11639,7 +11784,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11639
11784
  properties: {
11640
11785
  id: { type: "string", description: "Stroke id from list_strokes {live: true}." },
11641
11786
  brushId: { type: "string", description: "Brush id from list_brush_presets; the stroke keeps its size." },
11642
- brush: { type: "object", properties: _chunkMQGQTKVWcjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false, description: "Facets to change on top of brushId or the stroke\u2019s brush (as set_brush takes them); missing fields keep their values." },
11787
+ brush: { type: "object", properties: _chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false, description: "Facets to change on top of brushId or the stroke\u2019s brush (as set_brush takes them); missing fields keep their values." },
11643
11788
  color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", description: "New colour #rrggbb (replaces gradient paint)." },
11644
11789
  paint: { anyOf: [_chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA, { type: "null", description: "Back to the stroke\u2019s plain colour." }], description: "A colour or gradient paint for the stroke; null drops its gradient." },
11645
11790
  seed: { type: "integer", minimum: 0, description: "Another jitter seed: particles, scatter and texture fall differently." }
@@ -11887,10 +12032,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
11887
12032
  tools.push(...createPaintThickTools(c));
11888
12033
  tools.push(...createPaintReplayTools(c));
11889
12034
  tools.push(...createPaintStickerTools(c));
11890
- tools.push(..._chunkKBYB7OWBcjs.createPigmentTools.call(void 0, ));
12035
+ tools.push(..._chunkYHDHFJUCcjs.createPigmentTools.call(void 0, ));
11891
12036
  tools.push(..._chunkAVTPZO4Zcjs.createStickerTools.call(void 0, { provider: () => c.stickersProvider }));
11892
12037
  tools.push(
11893
- ..._chunkYSGW7VV4cjs.createLayerEffectTools.call(void 0,
12038
+ ..._chunk43NT242Dcjs.createLayerEffectTools.call(void 0,
11894
12039
  {
11895
12040
  requireLayer: (id) => void c.getLayerEffects(id),
11896
12041
  getLayerEffects: (id) => c.getLayerEffects(id),
@@ -11915,16 +12060,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
11915
12060
  }
11916
12061
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
11917
12062
  if (!origin && !onChange) return tool;
11918
- const write = !_optionalChain([tool, 'access', _563 => _563.annotations, 'optionalAccess', _564 => _564.readOnlyHint]);
12063
+ const write = !_optionalChain([tool, 'access', _573 => _573.annotations, 'optionalAccess', _574 => _574.readOnlyHint]);
11919
12064
  const done = (result) => {
11920
- if (write) _optionalChain([onChange, 'optionalCall', _565 => _565({ tool: tool.name })]);
11921
- return origin && _optionalChain([coordinates, 'optionalAccess', _566 => _566.out]) ? fromDocument(result, coordinates.out, origin) : result;
12065
+ if (write) _optionalChain([onChange, 'optionalCall', _575 => _575({ tool: tool.name })]);
12066
+ return origin && _optionalChain([coordinates, 'optionalAccess', _576 => _576.out]) ? fromDocument(result, coordinates.out, origin) : result;
11922
12067
  };
11923
12068
  return {
11924
12069
  ...tool,
11925
12070
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
11926
12071
  handler: (args, context) => {
11927
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _567 => _567.in]) ? toDocument(args, coordinates.in, origin) : args, context);
12072
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _577 => _577.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11928
12073
  return r instanceof Promise ? r.then(done) : done(r);
11929
12074
  }
11930
12075
  };
@@ -11941,7 +12086,7 @@ function strokeSummary(s, withPoints, live) {
11941
12086
  color: s.color,
11942
12087
  points: withPoints ? s.points : s.points.length,
11943
12088
  seed: s.seed,
11944
- copies: _nullishCoalesce(_optionalChain([s, 'access', _568 => _568.copies, 'optionalAccess', _569 => _569.length]), () => ( 0)),
12089
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _578 => _578.copies, 'optionalAccess', _579 => _579.length]), () => ( 0)),
11945
12090
  live,
11946
12091
  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) }
11947
12092
  };
@@ -11949,12 +12094,12 @@ function strokeSummary(s, withPoints, live) {
11949
12094
 
11950
12095
  // src/paint-editor/brush-library-tools.ts
11951
12096
  function createPaintBrushLibraryToolProvider(controller, options = {}) {
11952
- return _chunkMQGQTKVWcjs.createBrushLibraryToolProvider.call(void 0, controller.brushLibrary, {
11953
- profile: _chunkRSIKDWOPcjs.PAINT_PROFILE,
12097
+ return _chunkPYTJBVW5cjs.createBrushLibraryToolProvider.call(void 0, controller.brushLibrary, {
12098
+ profile: _chunkTZOX7KWVcjs.PAINT_PROFILE,
11954
12099
  stickers: () => controller.stickers.provider,
11955
12100
  ...options,
11956
12101
  renderPreview: (brush, { width, height, color }) => {
11957
- const t = renderBrushThumbnail(_chunkRSIKDWOPcjs.resolveBrush.call(void 0, brush), { paper: controller.getState().document.paper, width, height, color: color.toLowerCase() });
12102
+ const t = renderBrushThumbnail(_chunkTZOX7KWVcjs.resolveBrush.call(void 0, brush), { paper: controller.getState().document.paper, width, height, color: color.toLowerCase() });
11958
12103
  return { data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" };
11959
12104
  }
11960
12105
  });
@@ -12039,13 +12184,13 @@ var PaintGesture = (_class20 = class {
12039
12184
  const p = this.doc(e);
12040
12185
  const s = this.controller.getState();
12041
12186
  const layerId = s.document.activeLayerId;
12042
- if (!layerId || !_optionalChain([s, 'access', _570 => _570.document, 'access', _571 => _571.liveStrokes, 'optionalAccess', _572 => _572[layerId]])) {
12187
+ if (!layerId || !_optionalChain([s, 'access', _580 => _580.document, 'access', _581 => _581.liveStrokes, 'optionalAccess', _582 => _582[layerId]])) {
12043
12188
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
12044
12189
  return false;
12045
12190
  }
12046
12191
  try {
12047
12192
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
12048
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _573 => _573.id]), () => ( null)));
12193
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _583 => _583.id]), () => ( null)));
12049
12194
  if (!hit) return false;
12050
12195
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
12051
12196
  return true;
@@ -12057,7 +12202,7 @@ var PaintGesture = (_class20 = class {
12057
12202
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
12058
12203
  get strokeDrag() {
12059
12204
  const m = this.mode;
12060
- return _optionalChain([m, 'optionalAccess', _574 => _574.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
12205
+ return _optionalChain([m, 'optionalAccess', _584 => _584.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
12061
12206
  }
12062
12207
  /**
12063
12208
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -12131,7 +12276,7 @@ var PaintGesture = (_class20 = class {
12131
12276
  if (!m || m.pointerId !== e.pointerId) return;
12132
12277
  this.mode = null;
12133
12278
  this.predicted = [];
12134
- if (m.kind === "stroke") _optionalChain([this, 'access', _575 => _575.controller, 'access', _576 => _576.activeStroke, 'optionalAccess', _577 => _577.end, 'call', _578 => _578()]);
12279
+ if (m.kind === "stroke") _optionalChain([this, 'access', _585 => _585.controller, 'access', _586 => _586.activeStroke, 'optionalAccess', _587 => _587.end, 'call', _588 => _588()]);
12135
12280
  if (m.kind === "move-stroke") {
12136
12281
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
12137
12282
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -12155,8 +12300,8 @@ var PaintGesture = (_class20 = class {
12155
12300
  cancel() {
12156
12301
  this.penDown = false;
12157
12302
  this.predicted = [];
12158
- if (_optionalChain([this, 'access', _579 => _579.mode, 'optionalAccess', _580 => _580.kind]) === "stroke") _optionalChain([this, 'access', _581 => _581.controller, 'access', _582 => _582.activeStroke, 'optionalAccess', _583 => _583.cancel, 'call', _584 => _584()]);
12159
- if (_optionalChain([this, 'access', _585 => _585.mode, 'optionalAccess', _586 => _586.kind]) === "sticker") this.controller.cancelStickerPreview();
12303
+ if (_optionalChain([this, 'access', _589 => _589.mode, 'optionalAccess', _590 => _590.kind]) === "stroke") _optionalChain([this, 'access', _591 => _591.controller, 'access', _592 => _592.activeStroke, 'optionalAccess', _593 => _593.cancel, 'call', _594 => _594()]);
12304
+ if (_optionalChain([this, 'access', _595 => _595.mode, 'optionalAccess', _596 => _596.kind]) === "sticker") this.controller.cancelStickerPreview();
12160
12305
  this.mode = null;
12161
12306
  }
12162
12307
  get active() {
@@ -12178,44 +12323,47 @@ var PaintGesture = (_class20 = class {
12178
12323
  }
12179
12324
  }, _class20);
12180
12325
  var round2 = (v) => Math.round(v * 100) / 100;
12326
+ var PAINT_SHORTCUTS = [
12327
+ { id: "undo", label: "Undo", group: "edit", keys: ["Mod+Z"], tool: "undo_paint" },
12328
+ { id: "redo", label: "Redo", group: "edit", keys: ["Mod+Shift+Z", "Mod+Y"], tool: "redo_paint" },
12329
+ ...PAINT_TOOLS.map((t) => ({ id: `tool.${t.id}`, label: t.label, group: "tools", keys: [t.key.toUpperCase()] })),
12330
+ { id: "brush.smaller", label: "Smaller brush", group: "brush", keys: ["["], tool: "set_brush" },
12331
+ { id: "brush.larger", label: "Larger brush", group: "brush", keys: ["]"], tool: "set_brush" },
12332
+ { id: "colour.swap", label: "Swap colours", group: "colour", keys: ["X"] },
12333
+ { id: "view.mirror", label: "Mirror the view", group: "view", keys: ["M"], tool: "set_view" },
12334
+ { id: "view.reset", label: "Reset the view", group: "view", keys: ["Escape"], tool: "set_view" }
12335
+ ];
12336
+ function paintShortcutFor(e) {
12337
+ if (!e.key) return null;
12338
+ const parts = [...e.ctrlKey || e.metaKey ? ["Mod"] : [], ...e.shiftKey && (e.ctrlKey || e.metaKey) ? ["Shift"] : []];
12339
+ const key = e.key.length === 1 ? e.key.toUpperCase() : e.key[0].toUpperCase() + e.key.slice(1).toLowerCase();
12340
+ const combo = [...parts, key].join("+");
12341
+ return _nullishCoalesce(PAINT_SHORTCUTS.find((s) => s.keys.includes(combo)), () => ( null));
12342
+ }
12181
12343
  function handlePaintShortcut(controller, gesture, e) {
12182
- const mod = e.ctrlKey || e.metaKey;
12183
- const key = e.key.toLowerCase();
12184
- if (mod && key === "z") {
12185
- if (controller.getState().stroking) return true;
12186
- if (e.shiftKey) controller.redo();
12187
- else controller.undo();
12344
+ const shortcut = paintShortcutFor(e);
12345
+ if (!shortcut) return false;
12346
+ const id = shortcut.id;
12347
+ if (id === "undo" || id === "redo") {
12348
+ if (controller.getState().stroking && !(id === "redo" && e.key.toLowerCase() === "y")) return true;
12349
+ if (id === "undo") controller.undo();
12350
+ else controller.redo();
12188
12351
  return true;
12189
12352
  }
12190
- if (mod && key === "y") {
12191
- controller.redo();
12353
+ if (id.startsWith("tool.")) {
12354
+ gesture.tool = id.slice(5);
12192
12355
  return true;
12193
12356
  }
12194
- if (mod) return false;
12195
- const tool = PAINT_TOOLS.find((t) => t.key === key);
12196
- if (tool) {
12197
- gesture.tool = tool.id;
12198
- return true;
12199
- }
12200
- const brush = controller.getState().brush;
12201
- if (key === "[" || key === "]") {
12357
+ if (id === "brush.smaller" || id === "brush.larger") {
12358
+ const brush = controller.getState().brush;
12202
12359
  const step = Math.max(1, Math.round(brush.tip.size * 0.15));
12203
- controller.setBrush({ tip: { size: Math.max(1, brush.tip.size + (key === "]" ? step : -step)) } });
12204
- return true;
12205
- }
12206
- if (key === "x") {
12207
- controller.swapColors();
12360
+ controller.setBrush({ tip: { size: Math.max(1, brush.tip.size + (id === "brush.larger" ? step : -step)) } });
12208
12361
  return true;
12209
12362
  }
12210
- if (key === "m") {
12211
- controller.setView({ mirror: !controller.getState().view.mirror });
12212
- return true;
12213
- }
12214
- if (key === "escape") {
12215
- controller.resetView();
12216
- return true;
12217
- }
12218
- return false;
12363
+ if (id === "colour.swap") controller.swapColors();
12364
+ else if (id === "view.mirror") controller.setView({ mirror: !controller.getState().view.mirror });
12365
+ else if (id === "view.reset") controller.resetView();
12366
+ return true;
12219
12367
  }
12220
12368
  var PaintCanvasPresenter = (_class21 = class {
12221
12369
  constructor(controller) {;_class21.prototype.__init189.call(this);_class21.prototype.__init190.call(this);_class21.prototype.__init191.call(this);
@@ -12256,7 +12404,7 @@ function guideOverlay(controller, drag) {
12256
12404
  const size = s.document.canvas;
12257
12405
  const out = [];
12258
12406
  const layerId = s.document.activeLayerId;
12259
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _587 => _587.document, 'access', _588 => _588.liveStrokes, 'optionalAccess', _589 => _589[layerId], 'optionalAccess', _590 => _590.some, 'call', _591 => _591((x) => x.id === s.selectedStroke)]) : false;
12407
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _597 => _597.document, 'access', _598 => _598.liveStrokes, 'optionalAccess', _599 => _599[layerId], 'optionalAccess', _600 => _600.some, 'call', _601 => _601((x) => x.id === s.selectedStroke)]) : false;
12260
12408
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
12261
12409
  if (area) {
12262
12410
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -12269,7 +12417,7 @@ function guideOverlay(controller, drag) {
12269
12417
  ];
12270
12418
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
12271
12419
  }
12272
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _592 => _592.document, 'access', _593 => _593.stickers, 'optionalAccess', _594 => _594[layerId], 'optionalAccess', _595 => _595.find, 'call', _596 => _596((x) => x.id === s.selectedSticker)]) : void 0;
12420
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _602 => _602.document, 'access', _603 => _603.stickers, 'optionalAccess', _604 => _604[layerId], 'optionalAccess', _605 => _605.find, 'call', _606 => _606((x) => x.id === s.selectedSticker)]) : void 0;
12273
12421
  if (picked) {
12274
12422
  const r = picked.size / 2 + 2;
12275
12423
  const a = picked.rotation * Math.PI / 180;
@@ -12299,7 +12447,7 @@ var PAPER_SLIDERS = [
12299
12447
  ];
12300
12448
  function readPath(obj, path) {
12301
12449
  let v = obj;
12302
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _597 => _597[k]]);
12450
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _607 => _607[k]]);
12303
12451
  return typeof v === "number" ? v : 0;
12304
12452
  }
12305
12453
  function patchPath(obj, path, value) {
@@ -12415,7 +12563,7 @@ function startWetClock(controller, frame, cancel) {
12415
12563
  id = raf(loop);
12416
12564
  return () => {
12417
12565
  stopped = true;
12418
- _optionalChain([caf, 'optionalCall', _598 => _598(id)]);
12566
+ _optionalChain([caf, 'optionalCall', _608 => _608(id)]);
12419
12567
  };
12420
12568
  }
12421
12569
  function drawWaterOverlay(controller, ctx) {
@@ -12446,7 +12594,7 @@ var DOT_ROTATION_LABELS = { follow: "Follow motion", random: "Random", fixed: "T
12446
12594
  var STAMP_LABELS = { dot: "Dot", star: "Star", heart: "Heart", leaf: "Leaf", flower: "Flower", confetti: "Confetti", splat: "Splat", sparkle: "Sparkle", ring: "Ring" };
12447
12595
  function toggleStickerRef(refs, ref2) {
12448
12596
  if (refs.includes(ref2)) return refs.length > 1 ? refs.filter((r) => r !== ref2) : [...refs];
12449
- return refs.length < _chunkRSIKDWOPcjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
12597
+ return refs.length < _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
12450
12598
  }
12451
12599
  function stickerRefLabel(ref2) {
12452
12600
  const stamp = ref2.startsWith("editor:") ? ref2.slice(7) : null;
@@ -12459,8 +12607,14 @@ function toggleStamp(stamps, stamp) {
12459
12607
  }
12460
12608
  function toggleDotTexture(textures, stamp) {
12461
12609
  if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
12462
- return textures.length < _chunkRSIKDWOPcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
12610
+ return textures.length < _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
12463
12611
  }
12612
+ var PATH_STROKE_TAPERS = [
12613
+ { id: "even", label: "Even" },
12614
+ { id: "both", label: "Taper both ends", pressure: [0.2, 1, 0.2] },
12615
+ { id: "in", label: "Fade in", pressure: [0.2, 1] },
12616
+ { id: "out", label: "Fade out", pressure: [1, 0.2] }
12617
+ ];
12464
12618
  var STROKE_SLIDERS = [
12465
12619
  { path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
12466
12620
  { path: "tip.opacity", label: "Opacity", min: 0, max: 1, step: 0.01 },
@@ -12767,7 +12921,7 @@ function createPaintChangeFeed(controller, options = {}) {
12767
12921
  const doc = state.document;
12768
12922
  const layers = /* @__PURE__ */ new Map();
12769
12923
  for (const l of controller.listLayers()) layers.set(l.id, { name: l.name, visible: l.visible, opacity: l.opacity, blend: l.blend });
12770
- return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _599 => _599.paintEvents, 'optionalAccess', _600 => _600.length]), () => ( 0)), layers, stroking: state.stroking };
12924
+ return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _609 => _609.paintEvents, 'optionalAccess', _610 => _610.length]), () => ( 0)), layers, stroking: state.stroking };
12771
12925
  };
12772
12926
  let last = take();
12773
12927
  const check = () => {
@@ -12798,7 +12952,7 @@ function createPaintChangeFeed(controller, options = {}) {
12798
12952
  if (edited) pending = void 0;
12799
12953
  const change = {
12800
12954
  seq: ++seq,
12801
- origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _601 => _601.origin]), () => ( "user")),
12955
+ origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _611 => _611.origin]), () => ( "user")),
12802
12956
  ...commit ? { commit } : {},
12803
12957
  addedStrokes,
12804
12958
  removedStrokes,
@@ -12865,7 +13019,7 @@ function createPaintProposals(options) {
12865
13019
  };
12866
13020
  const strokeIds = () => new Set(controller.getStrokes().map((s) => s.id));
12867
13021
  const validate = (input) => {
12868
- if (!_optionalChain([input, 'access', _602 => _602.title, 'optionalAccess', _603 => _603.trim, 'call', _604 => _604()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
13022
+ if (!_optionalChain([input, 'access', _612 => _612.title, 'optionalAccess', _613 => _613.trim, 'call', _614 => _614()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
12869
13023
  if (!Array.isArray(input.ops) || !input.ops.length) throw new PaintEditorError("A proposal needs at least one op (stroke, wash or echo).");
12870
13024
  const place = _nullishCoalesce(input.place, () => ( "top"));
12871
13025
  if (place === "above") {
@@ -12877,7 +13031,7 @@ function createPaintProposals(options) {
12877
13031
  input.ops.forEach((op, i) => {
12878
13032
  const at = `ops[${i}]`;
12879
13033
  if (op.kind === "stroke") {
12880
- if (!_optionalChain([op, 'access', _605 => _605.points, 'optionalAccess', _606 => _606.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
13034
+ if (!_optionalChain([op, 'access', _615 => _615.points, 'optionalAccess', _616 => _616.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12881
13035
  points += op.points.length;
12882
13036
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
12883
13037
  const brush = op.brushId ? controller.getBrush(op.brushId) : controller.getState().brush;
@@ -12889,7 +13043,7 @@ function createPaintProposals(options) {
12889
13043
  if (!HEX4.test(_nullishCoalesce(op.color, () => ( "")))) throw new PaintEditorError(`${at}: a wash needs color as #rrggbb.`);
12890
13044
  if (op.opacity !== void 0 && !(op.opacity > 0 && op.opacity <= 1)) throw new PaintEditorError(`${at}: opacity must be in (0, 1].`);
12891
13045
  } else if (op.kind === "echo") {
12892
- if (!_optionalChain([op, 'access', _607 => _607.strokeIds, 'optionalAccess', _608 => _608.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
13046
+ if (!_optionalChain([op, 'access', _617 => _617.strokeIds, 'optionalAccess', _618 => _618.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12893
13047
  const unknown = op.strokeIds.filter((id) => !known.has(id));
12894
13048
  if (unknown.length) throw new PaintEditorError(`${at}: unknown stroke ${unknown.map((u) => `"${u}"`).join(", ")}. Call list_strokes for the ids.`);
12895
13049
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
@@ -12938,7 +13092,7 @@ function createPaintProposals(options) {
12938
13092
  ...input.layerId ? { layerId: input.layerId } : {},
12939
13093
  ...input.layerName ? { layerName: input.layerName } : {}
12940
13094
  });
12941
- const topLayerId = () => _optionalChain([controller, 'access', _609 => _609.listLayers, 'call', _610 => _610(), 'access', _611 => _611.find, 'call', _612 => _612((l) => l.parentId === null), 'optionalAccess', _613 => _613.id]);
13095
+ const topLayerId = () => _optionalChain([controller, 'access', _619 => _619.listLayers, 'call', _620 => _620(), 'access', _621 => _621.find, 'call', _622 => _622((l) => l.parentId === null), 'optionalAccess', _623 => _623.id]);
12942
13096
  return {
12943
13097
  getState: () => state,
12944
13098
  subscribe(listener) {
@@ -13125,7 +13279,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13125
13279
  },
13126
13280
  annotations: { title: "Propose paint", ...WRITE6 },
13127
13281
  handler: (args, context) => {
13128
- const origin = _optionalChain([context, 'access', _614 => _614.actor, 'optionalAccess', _615 => _615.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13282
+ const origin = _optionalChain([context, 'access', _624 => _624.actor, 'optionalAccess', _625 => _625.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13129
13283
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
13130
13284
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
13131
13285
  return { proposalId: proposal.id, ...rest };
@@ -13172,6 +13326,135 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13172
13326
  };
13173
13327
  }
13174
13328
 
13329
+ // src/paint-editor/contract.ts
13330
+ var PAINT_CONTRACT_FORMAT_VERSION = 1;
13331
+ var POINT2 = { type: "object", properties: { x: { type: "number", description: "Document x in pixels." }, y: { type: "number", description: "Document y in pixels." } }, required: ["x", "y"] };
13332
+ var PAINT_DOCUMENT_JSON_SCHEMA = {
13333
+ type: "object",
13334
+ description: "A saved painting, as the paint editor's save tools and autosave write it.",
13335
+ properties: {
13336
+ format: { type: "string", const: _chunkSJ2CPTQCcjs.EDITOR_DOCUMENT_FORMAT, description: `Always "${_chunkSJ2CPTQCcjs.EDITOR_DOCUMENT_FORMAT}".` },
13337
+ kind: { type: "string", const: "paint", description: 'Always "paint".' },
13338
+ formatVersion: { type: "integer", minimum: 1, description: "Version of the envelope for this kind; readers migrate older ones." },
13339
+ name: { type: "string", description: "Display name, when it has one." },
13340
+ document: {
13341
+ type: "object",
13342
+ description: "The painting (`SerializedPaintDocument`).",
13343
+ properties: {
13344
+ format: { type: "string", const: PAINT_FORMAT, description: `Always "${PAINT_FORMAT}".` },
13345
+ version: { type: "integer", minimum: 1, maximum: PAINT_SCHEMA_VERSION, description: `Painting version (${PAINT_SCHEMA_VERSION}; version 1 strokes hold flat engine brushes and are migrated).` },
13346
+ width: { type: "integer", minimum: 1, description: "Canvas width in pixels." },
13347
+ height: { type: "integer", minimum: 1, description: "Canvas height in pixels." },
13348
+ dpi: { type: "number", exclusiveMinimum: 0, description: "Pixels per inch." },
13349
+ paper: {
13350
+ type: "object",
13351
+ description: "The paper settings; the paper is regenerated from them, never stored as pixels.",
13352
+ properties: {
13353
+ preset: { type: "string", description: "The paper preset it started from (custom when none)." },
13354
+ name: { type: "string", description: "Display name." },
13355
+ pattern: { type: "string", description: "Grain pattern id." },
13356
+ seed: { type: "number", description: "Grain seed." },
13357
+ color: { type: "string", description: "Paper colour #rrggbb." },
13358
+ scale: { type: "number", description: "Grain scale (0.25 to 8)." },
13359
+ depth: { type: "number", minimum: 0, maximum: 1, description: "Grain depth for dry media." }
13360
+ },
13361
+ required: ["preset", "pattern", "seed", "color"]
13362
+ },
13363
+ layers: {
13364
+ type: "array",
13365
+ description: "Bottom to top: the image editor's serialized layers (pixel layers keep their pixels in `assets`).",
13366
+ items: { type: "object", properties: { id: { type: "string", description: "Layer id." }, name: { type: "string", description: "Layer name." }, type: { type: "string", description: "pixel, group, \u2026" } }, required: ["id", "type"] }
13367
+ },
13368
+ assets: { type: "object", additionalProperties: { type: "string" }, description: "Asset id \u2192 PNG data URL or an external reference." },
13369
+ activeLayerId: { type: ["string", "null"], description: "The active layer." },
13370
+ strokes: {
13371
+ type: "array",
13372
+ description: "Recorded strokes, oldest first (missing when saved without them).",
13373
+ items: {
13374
+ type: "object",
13375
+ properties: {
13376
+ id: { type: "string", description: "Stroke id." },
13377
+ layerId: { type: "string", description: "The layer it painted on." },
13378
+ color: { type: "string", description: "The paint colour as recorded at stroke start." },
13379
+ seed: { type: "number", description: "Seed of its jitter and grain, so a replay is exact." },
13380
+ points: { type: "array", items: POINT2, description: "The samples, with pressure, tilt and time when recorded." },
13381
+ brush: { $ref: "../brushes/brush.schema.json", description: "The facet brush it painted with." }
13382
+ },
13383
+ required: ["id", "layerId", "points", "brush"]
13384
+ }
13385
+ }
13386
+ },
13387
+ required: ["format", "version", "width", "height", "dpi", "paper", "layers", "assets", "activeLayerId"]
13388
+ }
13389
+ },
13390
+ required: ["format", "kind", "formatVersion", "document"]
13391
+ };
13392
+ function toolList(provider) {
13393
+ const tools = typeof provider.tools === "function" ? provider.tools() : provider.tools;
13394
+ return {
13395
+ id: provider.id,
13396
+ title: provider.title,
13397
+ ...provider.skill ? { skill: provider.skill } : {},
13398
+ tools: tools.map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations }))
13399
+ };
13400
+ }
13401
+ function uiTables() {
13402
+ return {
13403
+ tools: PAINT_TOOLS,
13404
+ brushOptions: _chunk43NT242Dcjs.BRUSH_OPTION_CONTROLS,
13405
+ blendMenu: BLEND_MENU_GROUPS,
13406
+ layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_MENU.map(({ kind, label }) => ({ kind, label, controls: _chunkPVJMTLPJcjs.layerEffectControls.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, kind)) })),
13407
+ sliders: { paper: PAPER_SLIDERS, wet: WET_PARAM_SLIDERS, wetTilt: WET_TILT_SLIDERS, wetSpeed: WET_SPEED_SLIDER, light: LIGHT_SLIDERS, stroke: STROKE_SLIDERS, sticker: STICKER_SLIDERS },
13408
+ pathStrokeTapers: PATH_STROKE_TAPERS,
13409
+ padSampleSizes: PAD_SAMPLE_SIZES,
13410
+ wetGpu: WET_GPU_OPTIONS,
13411
+ labels: {
13412
+ wetTools: WET_TOOL_LABELS,
13413
+ wetMedia: WET_MEDIUM_LABELS,
13414
+ impastoTools: IMPASTO_TOOL_LABELS,
13415
+ particleKinds: PARTICLE_KIND_LABELS,
13416
+ particleRenders: PARTICLE_RENDER_LABELS,
13417
+ ribbonPairs: RIBBON_PAIR_LABELS,
13418
+ dotTextureOrders: DOT_TEXTURE_ORDER_LABELS,
13419
+ dotRotations: DOT_ROTATION_LABELS,
13420
+ stamps: STAMP_LABELS
13421
+ }
13422
+ };
13423
+ }
13424
+ function paintContracts(options) {
13425
+ const controller = new PaintEditorController({ width: 64, height: 64 });
13426
+ controller.setEffectsProvider(options.effects);
13427
+ const providers = [
13428
+ createPaintEditorToolProvider(controller),
13429
+ createPaintEffectsToolProvider(controller),
13430
+ createPaintBrushLibraryToolProvider(controller),
13431
+ createPaintProposalToolProvider(createPaintProposals({ controller }))
13432
+ ].map(toolList);
13433
+ const document = createPaintEditorDocument(controller);
13434
+ const files = {
13435
+ "document.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "document.schema.json", ...PAINT_DOCUMENT_JSON_SCHEMA },
13436
+ "tools.json": { providers },
13437
+ "commands.json": PAINT_SHORTCUTS.map((s) => ({ ...s, params: { type: "object", properties: {}, additionalProperties: false } })),
13438
+ "ui.json": uiTables()
13439
+ };
13440
+ files["manifest.json"] = {
13441
+ domain: "paint",
13442
+ formatVersion: PAINT_CONTRACT_FORMAT_VERSION,
13443
+ document: { kind: document.kind, formatVersion: document.formatVersion, format: PAINT_FORMAT, version: PAINT_SCHEMA_VERSION },
13444
+ counts: { providers: providers.length, tools: providers.reduce((n, p) => n + p.tools.length, 0), commands: PAINT_SHORTCUTS.length, layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_KINDS.length },
13445
+ files: Object.keys(files).sort()
13446
+ };
13447
+ return files;
13448
+ }
13449
+
13450
+
13451
+
13452
+
13453
+
13454
+
13455
+
13456
+
13457
+
13175
13458
 
13176
13459
 
13177
13460
 
@@ -13526,4 +13809,4 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13526
13809
 
13527
13810
 
13528
13811
 
13529
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkRSIKDWOPcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkRSIKDWOPcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkMQGQTKVWcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkRSIKDWOPcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkRSIKDWOPcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkRSIKDWOPcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkRSIKDWOPcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkRSIKDWOPcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkKBYB7OWBcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkRSIKDWOPcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkRSIKDWOPcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkRSIKDWOPcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkRSIKDWOPcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkRSIKDWOPcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkRSIKDWOPcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkRSIKDWOPcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkKBYB7OWBcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkRSIKDWOPcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkRSIKDWOPcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkRSIKDWOPcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkRSIKDWOPcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_STICKER_STAMPS = _chunkRSIKDWOPcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkRSIKDWOPcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkRSIKDWOPcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkRSIKDWOPcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkRSIKDWOPcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkRSIKDWOPcjs.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 = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkRSIKDWOPcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkKBYB7OWBcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkRSIKDWOPcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkKBYB7OWBcjs.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 = _chunkRSIKDWOPcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkMQGQTKVWcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkRSIKDWOPcjs.brushTakesPaint; exports.brushToJSON = _chunkRSIKDWOPcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkRSIKDWOPcjs.isWetBrush; exports.isWetCapable = _chunkRSIKDWOPcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkMQGQTKVWcjs.multiColorSliders; exports.multiColorToPaint = _chunkRSIKDWOPcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkRSIKDWOPcjs.normalizeBehavior; exports.normalizeBristle = _chunkRSIKDWOPcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkRSIKDWOPcjs.normalizeDynamics; exports.normalizeFlow = _chunkKBYB7OWBcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkRSIKDWOPcjs.normalizeImpasto; exports.normalizeLight = _chunkRSIKDWOPcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkRSIKDWOPcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkRSIKDWOPcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkRSIKDWOPcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkRSIKDWOPcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkRSIKDWOPcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkKBYB7OWBcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkRSIKDWOPcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkRSIKDWOPcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkMQGQTKVWcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkRSIKDWOPcjs.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 = _chunkKBYB7OWBcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
13812
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkTZOX7KWVcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkTZOX7KWVcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkPYTJBVW5cjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkTZOX7KWVcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkTZOX7KWVcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkTZOX7KWVcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkTZOX7KWVcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkYHDHFJUCcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkTZOX7KWVcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkTZOX7KWVcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkTZOX7KWVcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkTZOX7KWVcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkTZOX7KWVcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkTZOX7KWVcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkTZOX7KWVcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkYHDHFJUCcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkTZOX7KWVcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkTZOX7KWVcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkTZOX7KWVcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkTZOX7KWVcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkTZOX7KWVcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkTZOX7KWVcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkTZOX7KWVcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkTZOX7KWVcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; 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 = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkTZOX7KWVcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkYHDHFJUCcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkTZOX7KWVcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkYHDHFJUCcjs.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 = _chunkTZOX7KWVcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkPYTJBVW5cjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkTZOX7KWVcjs.brushTakesPaint; exports.brushToJSON = _chunkTZOX7KWVcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkTZOX7KWVcjs.isWetBrush; exports.isWetCapable = _chunkTZOX7KWVcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkPYTJBVW5cjs.multiColorSliders; exports.multiColorToPaint = _chunkTZOX7KWVcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkTZOX7KWVcjs.normalizeBehavior; exports.normalizeBristle = _chunkTZOX7KWVcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkTZOX7KWVcjs.normalizeDynamics; exports.normalizeFlow = _chunkYHDHFJUCcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkTZOX7KWVcjs.normalizeImpasto; exports.normalizeLight = _chunkTZOX7KWVcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkTZOX7KWVcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkTZOX7KWVcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkTZOX7KWVcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkTZOX7KWVcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkTZOX7KWVcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkYHDHFJUCcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkTZOX7KWVcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkTZOX7KWVcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkPYTJBVW5cjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkTZOX7KWVcjs.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 = _chunkYHDHFJUCcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;