@pixerate/editor 0.272.1 → 0.273.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.
@@ -31,6 +31,11 @@ var _chunk7TD63DZPcjs = require('../chunk-7TD63DZP.cjs');
31
31
 
32
32
 
33
33
 
34
+ var _chunkYH6SKC7Pcjs = require('../chunk-YH6SKC7P.cjs');
35
+
36
+
37
+
38
+
34
39
 
35
40
 
36
41
 
@@ -231,6 +236,8 @@ require('../chunk-WOFXZ3XU.cjs');
231
236
 
232
237
 
233
238
 
239
+
240
+
234
241
  var _chunkN5IMDAHMcjs = require('../chunk-N5IMDAHM.cjs');
235
242
  require('../chunk-STLTOISW.cjs');
236
243
 
@@ -2927,7 +2934,7 @@ function deserializePaintDocument(raw) {
2927
2934
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
2928
2935
  const state = { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) };
2929
2936
  if (wetEvents.length) state.wetEvents = wetEvents;
2930
- const paintEvents = Array.isArray(r.paintEvents) ? r.paintEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.at) && typeof e.layerId === "string" && ["fill", "clear", "flatten", "stickers"].includes(e.kind)) : [];
2937
+ const paintEvents = Array.isArray(r.paintEvents) ? r.paintEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.at) && typeof e.layerId === "string" && ["fill", "fill-region", "clear", "flatten", "stickers", "live-strokes"].includes(e.kind)) : [];
2931
2938
  if (paintEvents.length) state.paintEvents = paintEvents;
2932
2939
  const o = r.origin;
2933
2940
  if (o && typeof o === "object" && Number.isFinite(o.x) && Number.isFinite(o.y) && (o.x || o.y)) state.origin = { x: Math.round(o.x), y: Math.round(o.y) };
@@ -4115,7 +4122,18 @@ async function replayPainting(source, target, options = {}) {
4115
4122
  const e = item.event;
4116
4123
  if (!target.getLayer(e.layerId)) continue;
4117
4124
  if (e.kind === "fill") target.fillLayer({ layerId: e.layerId, ...e.data });
4118
- else if (e.kind === "clear") target.clearLayer(e.layerId);
4125
+ else if (e.kind === "fill-region") {
4126
+ const d = _nullishCoalesce(e.data, () => ( {}));
4127
+ if (d.wet) await target.wetIdle();
4128
+ const pts = d.points ? d.points.map((p) => ({ x: p.x * s, y: p.y * s })) : d.x !== void 0 && d.y !== void 0 ? [{ x: d.x * s, y: d.y * s }] : [];
4129
+ target.fillRegion({
4130
+ ...d,
4131
+ layerId: e.layerId,
4132
+ points: pts,
4133
+ ...d.closeGap !== void 0 ? { closeGap: Math.min(32, d.closeGap * s) } : {},
4134
+ ...d.expand !== void 0 ? { expand: Math.max(-16, Math.min(16, d.expand * s)) } : {}
4135
+ });
4136
+ } else if (e.kind === "clear") target.clearLayer(e.layerId);
4119
4137
  else if (e.kind === "live-strokes") {
4120
4138
  const d = e.data;
4121
4139
  if (_optionalChain([d, 'optionalAccess', _181 => _181.rasterized])) target.replaceLiveStrokes(e.layerId, null);
@@ -5502,12 +5520,258 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5502
5520
  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 } }));
5503
5521
  return { layerId: l.id, bounds: rect };
5504
5522
  }
5523
+ /**
5524
+ * Flood-fills one or more contiguous regions on a pixel layer (one undo step), sampling boundaries
5525
+ * from the layer itself (`reference: 'layer'`), all visible layers (`'all'` / `'composite'`), or a
5526
+ * specific reference layer id (e.g. an ink line-art layer above a flats layer). Closes line-art gaps
5527
+ * up to `closeGap` px and expands (`> 0`, bleeding under lines) or contracts (`< 0`) by `expand` px.
5528
+ * With `wet: true`, pours a watercolour wash into the region on the layer's wet layer.
5529
+ */
5530
+ fillRegion(options) {
5531
+ this.requireIdle("filling");
5532
+ const fillTarget = this.paintTarget(options.layerId, "fill");
5533
+ if (_optionalChain([this, 'access', _283 => _283.doc, 'access', _284 => _284.stickers, 'optionalAccess', _285 => _285[fillTarget.id], 'optionalAccess', _286 => _286.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
5534
+ if (_optionalChain([this, 'access', _287 => _287.doc, 'access', _288 => _288.liveStrokes, 'optionalAccess', _289 => _289[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
5535
+ const { width, height } = this.doc.canvas;
5536
+ const pts = [];
5537
+ if (options.points !== void 0) {
5538
+ if (!Array.isArray(options.points) || !options.points.length) {
5539
+ throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
5540
+ }
5541
+ for (let i = 0; i < options.points.length; i++) {
5542
+ const p = options.points[i];
5543
+ if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) {
5544
+ throw new PaintEditorError(`points[${i}] needs finite x and y in document pixels.`);
5545
+ }
5546
+ pts.push({ x: p.x, y: p.y });
5547
+ }
5548
+ }
5549
+ if (options.x !== void 0 || options.y !== void 0) {
5550
+ if (!Number.isFinite(options.x) || !Number.isFinite(options.y)) {
5551
+ throw new PaintEditorError("x and y must be finite numbers in document pixels.");
5552
+ }
5553
+ if (!options.points) pts.push({ x: options.x, y: options.y });
5554
+ }
5555
+ if (!pts.length) {
5556
+ throw new PaintEditorError("Pass x and y (or points) in document pixels to fill a region.");
5557
+ }
5558
+ for (const p of pts) {
5559
+ const px = Math.floor(p.x);
5560
+ const py = Math.floor(p.y);
5561
+ if (px < 0 || py < 0 || px >= width || py >= height) {
5562
+ throw new PaintEditorError(`(${p.x}, ${p.y}) is outside the ${width}\xD7${height} canvas.`);
5563
+ }
5564
+ }
5565
+ const refSpec = _nullishCoalesce(options.reference, () => ( "layer"));
5566
+ if (refSpec !== "layer" && refSpec !== "all" && refSpec !== "composite") {
5567
+ this.requireLayer(refSpec);
5568
+ }
5569
+ const color = options.color === void 0 ? this.color : parseColor(options.color);
5570
+ const opacity = _nullishCoalesce(options.opacity, () => ( 1));
5571
+ if (!(Number.isFinite(opacity) && opacity >= 0 && opacity <= 1)) throw new PaintEditorError(`opacity ${opacity} is out of range; use 0..1.`);
5572
+ const blend = _nullishCoalesce(_nullishCoalesce(options.blend, () => ( options.blendMode)), () => ( "normal"));
5573
+ if (!_chunk2VX55NFMcjs.isBlendMode.call(void 0, blend)) throw new PaintEditorError(`Unknown blend mode "${blend}".`);
5574
+ const tolerance = _nullishCoalesce(options.tolerance, () => ( 32));
5575
+ if (!(Number.isFinite(tolerance) && tolerance >= 0 && tolerance <= 255)) throw new PaintEditorError(`tolerance ${tolerance} is out of range; use 0..255.`);
5576
+ const closeGap = _nullishCoalesce(options.closeGap, () => ( 0));
5577
+ if (!(Number.isFinite(closeGap) && closeGap >= 0 && closeGap <= 32)) throw new PaintEditorError(`closeGap ${closeGap} is out of range; use 0..32 px.`);
5578
+ const expand2 = _nullishCoalesce(options.expand, () => ( 0));
5579
+ if (!(Number.isFinite(expand2) && expand2 >= -16 && expand2 <= 16)) throw new PaintEditorError(`expand ${expand2} is out of range; use -16..16 px.`);
5580
+ const antialias = _nullishCoalesce(options.antialias, () => ( true));
5581
+ if (typeof antialias !== "boolean") throw new PaintEditorError("antialias must be true or false.");
5582
+ const grainAmount = _nullishCoalesce(options.grain, () => ( 0));
5583
+ if (!(Number.isFinite(grainAmount) && grainAmount >= 0 && grainAmount <= 1)) throw new PaintEditorError(`grain ${grainAmount} is out of range; use 0..1.`);
5584
+ const pressure = _nullishCoalesce(options.pressure, () => ( 0.5));
5585
+ if (!(Number.isFinite(pressure) && pressure >= 0 && pressure <= 1)) throw new PaintEditorError(`pressure ${pressure} is out of range; use 0..1.`);
5586
+ const wet = options.wet === true;
5587
+ if (wet && this.previewing) throw new PaintEditorError("Wet paint can't be previewed; suggest a dry fill instead.");
5588
+ if (wet && !this.wet.wetLayerIds().includes(fillTarget.id) && this.wet.wetLayerIds().length >= _chunkN5IMDAHMcjs.MAX_WET_LANES) {
5589
+ throw new PaintEditorError(`At most ${_chunkN5IMDAHMcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
5590
+ }
5591
+ const refPixels = refSpec === "layer" ? this.compositePixels({ layerIds: [fillTarget.id], paper: false, wet: "display" }).data : refSpec === "all" || refSpec === "composite" ? this.compositePixels({ paper: false, wet: "display" }).data : this.compositePixels({ layerIds: [refSpec], paper: false, wet: "display" }).data;
5592
+ const filled = _chunkYH6SKC7Pcjs.fillRegionMask.call(void 0, refPixels, width, height, {
5593
+ points: pts,
5594
+ tolerance,
5595
+ closeGap,
5596
+ expand: expand2,
5597
+ antialias
5598
+ });
5599
+ const eventData = {
5600
+ points: pts.map((p) => ({ x: p.x, y: p.y })),
5601
+ reference: refSpec,
5602
+ color,
5603
+ opacity,
5604
+ blend,
5605
+ tolerance,
5606
+ closeGap,
5607
+ expand: expand2,
5608
+ antialias,
5609
+ grain: grainAmount,
5610
+ pressure,
5611
+ ...wet ? { wet: true } : {}
5612
+ };
5613
+ if (!filled.bounds || filled.pixelCount === 0) {
5614
+ return {
5615
+ layerId: fillTarget.id,
5616
+ bounds: null,
5617
+ pixelCount: 0,
5618
+ leaked: false,
5619
+ regions: filled.regions,
5620
+ ...wet ? { wet: this.wet.isWet(fillTarget.id) } : {}
5621
+ };
5622
+ }
5623
+ const rect = filled.bounds;
5624
+ const depth = grainAmount * this.doc.paper.depth;
5625
+ const grain = depth > 0 ? paperGrain(this.doc.paper) : null;
5626
+ if (wet) {
5627
+ this.requireWetIdle("filling");
5628
+ const before = this.doc;
5629
+ let l2 = fillTarget;
5630
+ if (l2.offset.x || l2.offset.y) {
5631
+ const moved = { ...l2, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l2.surface, l2.offset.x, l2.offset.y), offset: { x: 0, y: 0 } };
5632
+ this.doc = { ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l2.id, () => moved) };
5633
+ l2 = moved;
5634
+ }
5635
+ this.beginWetOp();
5636
+ const world = this.wet.ensureLane(l2.id);
5637
+ const [r, g, b] = _chunkSNAFFCAXcjs.hexToRgb8.call(void 0, color);
5638
+ const medium = new (0, _chunkN5IMDAHMcjs.WetMedium)(world, l2.id, {
5639
+ water: 0.9 * Math.max(0.25, opacity),
5640
+ mass: _chunkN5IMDAHMcjs.PIGMENT_UNIT * 2.5 * opacity,
5641
+ body: 0,
5642
+ light: 0
5643
+ });
5644
+ const subCov = new Float32Array(rect.width * rect.height);
5645
+ for (let yy = 0, k = 0; yy < rect.height; yy++) {
5646
+ const py = rect.y + yy;
5647
+ const row = py * width;
5648
+ for (let xx = 0; xx < rect.width; xx++, k++) {
5649
+ const px = rect.x + xx;
5650
+ let v = filled.mask[row + px];
5651
+ if (v > 0 && grain) v *= _chunkNIBFKXMDcjs.grainCatch.call(void 0, grain.at(px + 0.5, py + 0.5), depth, pressure);
5652
+ subCov[k] = Math.round(v * 4096) / 4096;
5653
+ }
5654
+ }
5655
+ medium.deposit(rect, subCov, 1, [r / 255, g / 255, b / 255], null);
5656
+ if (this.wet.instantDry) {
5657
+ this.wet.dry(l2.id);
5658
+ this.logWet({ kind: "dry", layerId: l2.id });
5659
+ } else {
5660
+ this.wet.syncDisplays();
5661
+ }
5662
+ const afterLayer = this.getLayer(l2.id);
5663
+ this.commit(
5664
+ "Fill region",
5665
+ this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l2.id, () => ({ ...afterLayer })) }), {
5666
+ kind: "fill-region",
5667
+ layerId: l2.id,
5668
+ data: eventData
5669
+ }),
5670
+ before
5671
+ );
5672
+ return {
5673
+ layerId: l2.id,
5674
+ bounds: rect,
5675
+ pixelCount: filled.pixelCount,
5676
+ leaked: filled.leaked,
5677
+ regions: filled.regions,
5678
+ wet: this.wet.isWet(l2.id)
5679
+ };
5680
+ }
5681
+ this.dryLayersFirst([fillTarget.id]);
5682
+ const l = this.paintTarget(options.layerId, "fill");
5683
+ const coverage = new (0, _chunkNIBFKXMDcjs.CoverageMap)();
5684
+ const vals = new Float32Array(rect.width * rect.height);
5685
+ for (let yy = 0, k = 0; yy < rect.height; yy++) {
5686
+ const py = rect.y + yy;
5687
+ const row = py * width;
5688
+ for (let xx = 0; xx < rect.width; xx++, k++) {
5689
+ const px = rect.x + xx;
5690
+ let v = filled.mask[row + px];
5691
+ if (v > 0 && grain) v *= _chunkNIBFKXMDcjs.grainCatch.call(void 0, grain.at(px + 0.5, py + 0.5), depth, pressure);
5692
+ vals[k] = v;
5693
+ }
5694
+ }
5695
+ coverage.accumulate(rect, vals, 1);
5696
+ const apply = {
5697
+ mode: "paint",
5698
+ color: rgbaOf(color),
5699
+ background: rgbaOf(this.doc.paper.color),
5700
+ opacity,
5701
+ blend,
5702
+ lockTransparency: _chunkPVJMTLPJcjs.isLayerLocked.call(void 0, l, "transparency"),
5703
+ selection: null,
5704
+ offset: l.offset
5705
+ };
5706
+ const surface = this.applyCoverage(l, coverage, rect, apply);
5707
+ this.commit(
5708
+ "Fill region",
5709
+ this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })) }), {
5710
+ kind: "fill-region",
5711
+ layerId: l.id,
5712
+ data: eventData
5713
+ })
5714
+ );
5715
+ return {
5716
+ layerId: l.id,
5717
+ bounds: rect,
5718
+ pixelCount: filled.pixelCount,
5719
+ leaked: filled.leaked,
5720
+ regions: filled.regions
5721
+ };
5722
+ }
5723
+ /**
5724
+ * Finds enclosed unfilled regions from a reference layer or the visible composite (without paper),
5725
+ * closing line-art gaps up to `closeGap` px and returning each region's interior seed `point`,
5726
+ * `centroid`, `bounds`, `pixelCount`, and `touchesEdge` flag.
5727
+ */
5728
+ findUnfilledRegions(options = {}) {
5729
+ if (options.layerId !== void 0) {
5730
+ const l = this.requireLayer(options.layerId);
5731
+ if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; pass a pixel layer inside it.`);
5732
+ }
5733
+ const refSpec = _nullishCoalesce(options.reference, () => ( "all"));
5734
+ if (refSpec !== "layer" && refSpec !== "all" && refSpec !== "composite") {
5735
+ this.requireLayer(refSpec);
5736
+ }
5737
+ const tolerance = _nullishCoalesce(options.tolerance, () => ( 32));
5738
+ if (!(Number.isFinite(tolerance) && tolerance >= 0 && tolerance <= 255)) throw new PaintEditorError(`tolerance ${tolerance} is out of range; use 0..255.`);
5739
+ const closeGap = _nullishCoalesce(options.closeGap, () => ( 0));
5740
+ if (!(Number.isFinite(closeGap) && closeGap >= 0 && closeGap <= 32)) throw new PaintEditorError(`closeGap ${closeGap} is out of range; use 0..32 px.`);
5741
+ const minArea = _nullishCoalesce(options.minArea, () => ( 16));
5742
+ if (!(Number.isInteger(minArea) && minArea >= 1 && minArea <= 1e7)) throw new PaintEditorError(`minArea ${minArea} is out of range; use a whole number of pixels, 1 or more.`);
5743
+ const maxRegions = _nullishCoalesce(options.maxRegions, () => ( 100));
5744
+ if (!(Number.isInteger(maxRegions) && maxRegions >= 1 && maxRegions <= 1e3)) throw new PaintEditorError(`maxRegions ${maxRegions} is out of range; use 1..1000.`);
5745
+ const includeEdge = _nullishCoalesce(options.includeEdge, () => ( false));
5746
+ if (typeof includeEdge !== "boolean") throw new PaintEditorError("includeEdge must be true or false.");
5747
+ const { width, height } = this.doc.canvas;
5748
+ let refPixels;
5749
+ if (refSpec === "all" || refSpec === "composite") {
5750
+ refPixels = this.compositePixels({ paper: false, wet: "display" }).data;
5751
+ } else if (refSpec === "layer") {
5752
+ const targetId = _nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId));
5753
+ if (!targetId) throw new PaintEditorError("There is no active layer; pass layerId or reference.");
5754
+ refPixels = this.compositePixels({ layerIds: [targetId], paper: false, wet: "display" }).data;
5755
+ } else {
5756
+ refPixels = this.compositePixels({ layerIds: [refSpec], paper: false, wet: "display" }).data;
5757
+ }
5758
+ const targetPixels = options.layerId !== void 0 && options.layerId !== refSpec && refSpec !== "layer" ? this.compositePixels({ layerIds: [options.layerId], paper: false, wet: "display" }).data : void 0;
5759
+ const regions = _chunkYH6SKC7Pcjs.findUnfilledRegionsMask.call(void 0, refPixels, width, height, {
5760
+ target: targetPixels,
5761
+ tolerance,
5762
+ closeGap,
5763
+ minArea,
5764
+ includeEdge,
5765
+ maxRegions
5766
+ });
5767
+ return { regions };
5768
+ }
5505
5769
  applyCoverage(l, coverage, rect, apply) {
5506
5770
  const base = l.surface;
5507
5771
  const tiles = new Map(base.tiles);
5508
5772
  for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {
5509
5773
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
5510
- const src = _nullishCoalesce(_optionalChain([base, 'access', _283 => _283.tiles, 'access', _284 => _284.get, 'call', _285 => _285(key), 'optionalAccess', _286 => _286.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
5774
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _290 => _290.tiles, 'access', _291 => _291.get, 'call', _292 => _292(key), 'optionalAccess', _293 => _293.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
5511
5775
  const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkNIBFKXMDcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
5512
5776
  if (tile) tiles.set(key, tile);
5513
5777
  else tiles.delete(key);
@@ -5542,7 +5806,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5542
5806
  }
5543
5807
  /** The effect a layer is drawn from, or `undefined` for other layers. */
5544
5808
  getEffectLayer(layerId) {
5545
- return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _287 => _287.doc, 'access', _288 => _288.effectLayers, 'optionalAccess', _289 => _289[layerId]]) : void 0;
5809
+ return _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _294 => _294.doc, 'access', _295 => _295.effectLayers, 'optionalAccess', _296 => _296[layerId]]) : void 0;
5546
5810
  }
5547
5811
  /** The effect paper (without its pixels), or `null`. */
5548
5812
  getPaperEffect() {
@@ -5579,8 +5843,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5579
5843
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
5580
5844
  effectTarget(layerId, what) {
5581
5845
  const l = this.paintTarget(layerId, what);
5582
- if (_optionalChain([this, 'access', _290 => _290.doc, 'access', _291 => _291.stickers, 'optionalAccess', _292 => _292[l.id], 'optionalAccess', _293 => _293.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
5583
- if (_optionalChain([this, 'access', _294 => _294.doc, 'access', _295 => _295.liveStrokes, 'optionalAccess', _296 => _296[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
5846
+ if (_optionalChain([this, 'access', _297 => _297.doc, 'access', _298 => _298.stickers, 'optionalAccess', _299 => _299[l.id], 'optionalAccess', _300 => _300.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
5847
+ if (_optionalChain([this, 'access', _301 => _301.doc, 'access', _302 => _302.liveStrokes, 'optionalAccess', _303 => _303[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
5584
5848
  if (this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" holds wet paint; effects go on dried paint, so dry it first (dry_paint) and try again.`);
5585
5849
  return l;
5586
5850
  }
@@ -5619,8 +5883,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5619
5883
  const was = this.doc.paperEffect;
5620
5884
  const paperEffect = {
5621
5885
  ...this.sourceOf(d, values, options.time),
5622
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _297 => _297.opacity]))), () => ( 1)),
5623
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _298 => _298.blend]))), () => ( "multiply")),
5886
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _304 => _304.opacity]))), () => ( 1)),
5887
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _305 => _305.blend]))), () => ( "multiply")),
5624
5888
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
5625
5889
  version: nextPaperEffectVersion()
5626
5890
  };
@@ -5673,8 +5937,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5673
5937
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
5674
5938
  const loc = above ? _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, above) : null;
5675
5939
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
5676
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _299 => _299.name, 'optionalAccess', _300 => _300.trim, 'call', _301 => _301()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5677
- const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _302 => _302.parent, 'optionalAccess', _303 => _303.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5940
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _306 => _306.name, 'optionalAccess', _307 => _307.trim, 'call', _308 => _308()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5941
+ const layers = _chunkPVJMTLPJcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _309 => _309.parent, 'optionalAccess', _310 => _310.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5678
5942
  const source = this.sourceOf(d, values, options.time);
5679
5943
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
5680
5944
  return { layer: this.describeLayer(layer), source };
@@ -5766,7 +6030,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5766
6030
  const epoch = ++this.paintEpoch;
5767
6031
  const changed = (name) => new PaintEditorError(`The paint changed while "${name}" rendered (set_color, set_paint or another set_effect_paint); call set_effect_paint again to paint with it.`);
5768
6032
  const d = await this.describeEffect(source.effect, "paint");
5769
- if (_optionalChain([map, 'optionalAccess', _304 => _304.by]) === "path" && !_chunkL2JTLW6Bcjs.pathControlsOf.call(void 0, d).length) {
6033
+ if (_optionalChain([map, 'optionalAccess', _311 => _311.by]) === "path" && !_chunkL2JTLW6Bcjs.pathControlsOf.call(void 0, d).length) {
5770
6034
  throw new PaintEditorError(`Effect "${d.id}" has no path control (format "svg-path"); use by: "stroke" (bent along each stroke) or by: "canvas" (fixed to the canvas).`);
5771
6035
  }
5772
6036
  const values = this.effectValues(d, { ...d.defaults }, source.values);
@@ -5810,7 +6074,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5810
6074
  }
5811
6075
  trimEffectPaints() {
5812
6076
  let live = 0;
5813
- for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) for (const s of list) if (_optionalChain([s, 'access', _305 => _305.paint, 'optionalAccess', _306 => _306.type]) === "effect" && _optionalChain([s, 'access', _307 => _307.paint, 'access', _308 => _308.map, 'optionalAccess', _309 => _309.by]) === "path") live++;
6077
+ for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) for (const s of list) if (_optionalChain([s, 'access', _312 => _312.paint, 'optionalAccess', _313 => _313.type]) === "effect" && _optionalChain([s, 'access', _314 => _314.paint, 'access', _315 => _315.map, 'optionalAccess', _316 => _316.by]) === "path") live++;
5814
6078
  const limit = Math.max(_PaintEditorController.EFFECT_PAINT_CACHE, this.effectPaintBatch, live + 1);
5815
6079
  while (this.effectPaintPixels.size > limit) this.effectPaintPixels.delete(this.effectPaintPixels.keys().next().value);
5816
6080
  }
@@ -5875,7 +6139,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5875
6139
  } else if (init.color === void 0 && !brush.paint && !this.effectPaintPending) {
5876
6140
  source = this.effectPaint;
5877
6141
  }
5878
- if (!source || _optionalChain([source, 'access', _310 => _310.map, 'optionalAccess', _311 => _311.by]) !== "path") return;
6142
+ if (!source || _optionalChain([source, 'access', _317 => _317.map, 'optionalAccess', _318 => _318.by]) !== "path") return;
5879
6143
  if (!this.effectPathControls.has(source.effect)) await this.describeEffect(source.effect);
5880
6144
  const control = this.effectPathControls.get(source.effect);
5881
6145
  const paints2 = pointsList.filter((pts) => pts.length > 0).map((pts) => _chunkSNAFFCAXcjs.withStrokePath.call(void 0, source, pts, control));
@@ -5889,7 +6153,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5889
6153
  async prepareStrokeEdit(id, edit) {
5890
6154
  const p = this.strokeEditPaint(id, edit);
5891
6155
  if (!p) return;
5892
- if (_optionalChain([p, 'access', _312 => _312.map, 'optionalAccess', _313 => _313.by]) === "path" && !this.effectPathControls.has(p.effect)) await this.describeEffect(p.effect);
6156
+ if (_optionalChain([p, 'access', _319 => _319.map, 'optionalAccess', _320 => _320.by]) === "path" && !this.effectPathControls.has(p.effect)) await this.describeEffect(p.effect);
5893
6157
  await this.prepareEffectPaints([_nullishCoalesce(this.strokeEditPaint(id, edit), () => ( p))]);
5894
6158
  }
5895
6159
  /** Whether `prepareStrokeEdit` has to be awaited before this edit can run. */
@@ -5906,11 +6170,11 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5906
6170
  const p = _chunkSNAFFCAXcjs.readPaintEffectPaint.call(void 0, edit.paint);
5907
6171
  return p && _chunkSNAFFCAXcjs.withStrokePath.call(void 0, p, was.points, this.effectPathControls.get(p.effect));
5908
6172
  }
5909
- if (_optionalChain([was, 'access', _314 => _314.paint, 'optionalAccess', _315 => _315.type]) !== "effect" || _optionalChain([was, 'access', _316 => _316.paint, 'access', _317 => _317.map, 'optionalAccess', _318 => _318.by]) !== "path") return null;
6173
+ if (_optionalChain([was, 'access', _321 => _321.paint, 'optionalAccess', _322 => _322.type]) !== "effect" || _optionalChain([was, 'access', _323 => _323.paint, 'access', _324 => _324.map, 'optionalAccess', _325 => _325.by]) !== "path") return null;
5910
6174
  if (edit.points !== void 0) return _chunkSNAFFCAXcjs.withStrokePath.call(void 0, was.paint, this.checkPoints(edit.points), this.effectPathControls.get(was.paint.effect));
5911
6175
  if (!edit.transform) return null;
5912
6176
  const varied = varyStroke(was, this.strokeTransform(was, edit.transform), {}).paint;
5913
- return _optionalChain([varied, 'optionalAccess', _319 => _319.type]) === "effect" ? varied : null;
6177
+ return _optionalChain([varied, 'optionalAccess', _326 => _326.type]) === "effect" ? varied : null;
5914
6178
  } catch (e9) {
5915
6179
  return null;
5916
6180
  }
@@ -5925,7 +6189,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5925
6189
  /** Renders the effect paints of recorded strokes (default all of them) before a replay. */
5926
6190
  async prepareStrokeEffects(strokeIds, variation) {
5927
6191
  const ids = strokeIds ? new Set(strokeIds) : null;
5928
- const strokes = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _320 => _320.paint, 'optionalAccess', _321 => _321.type]) === "effect");
6192
+ const strokes = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _327 => _327.paint, 'optionalAccess', _328 => _328.type]) === "effect");
5929
6193
  const paints2 = strokes.map((s) => s.paint);
5930
6194
  if (variation && strokes.length) {
5931
6195
  const repeat = Math.max(1, Math.min(100, _nullishCoalesce(variation.repeat, () => ( 1))));
@@ -5940,7 +6204,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5940
6204
  m = [step[0] * m[0] + step[1] * m[2], step[0] * m[1] + step[1] * m[3], step[2] * m[0] + step[3] * m[2], step[2] * m[1] + step[3] * m[3], step[0] * m[4] + step[1] * m[5] + step[4], step[2] * m[4] + step[3] * m[5] + step[5]];
5941
6205
  for (const s of strokes) {
5942
6206
  const v = varyStroke(s, m, variation);
5943
- if (_optionalChain([v, 'access', _322 => _322.paint, 'optionalAccess', _323 => _323.type]) === "effect") paints2.push(v.paint);
6207
+ if (_optionalChain([v, 'access', _329 => _329.paint, 'optionalAccess', _330 => _330.type]) === "effect") paints2.push(v.paint);
5944
6208
  }
5945
6209
  }
5946
6210
  }
@@ -5983,8 +6247,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
5983
6247
  source = this.effectPaint;
5984
6248
  }
5985
6249
  if (!source) return null;
5986
- const path = _optionalChain([source, 'access', _324 => _324.map, 'optionalAccess', _325 => _325.by]) === "path";
5987
- if (path && _optionalChain([points, 'optionalAccess', _326 => _326.length])) source = _chunkSNAFFCAXcjs.withStrokePath.call(void 0, source, points, this.effectPathControls.get(source.effect));
6250
+ const path = _optionalChain([source, 'access', _331 => _331.map, 'optionalAccess', _332 => _332.by]) === "path";
6251
+ if (path && _optionalChain([points, 'optionalAccess', _333 => _333.length])) source = _chunkSNAFFCAXcjs.withStrokePath.call(void 0, source, points, this.effectPathControls.get(source.effect));
5988
6252
  const pixels = _nullishCoalesce(this.effectPaintImage(source), () => ( (path ? this.renderEffectPaintSync(source) : null)));
5989
6253
  if (!pixels) throw new PaintEditorError(`The effect paint "${source.effect}"${source.provider ? ` from provider "${source.provider}"` : ""} is not rendered at this canvas size; call ${path ? "prepareStrokePathEffect (the paint_stroke tool does this) or prepareStrokeEdit" : "set_effect_paint (or prepareEffectPaints)"} first.`);
5990
6254
  return { source, pixels };
@@ -6008,14 +6272,14 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6008
6272
  const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
6009
6273
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
6010
6274
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
6011
- const relief = _optionalChain([this, 'access', _327 => _327.doc, 'access', _328 => _328.thick, 'optionalAccess', _329 => _329[l.id]]);
6275
+ const relief = _optionalChain([this, 'access', _334 => _334.doc, 'access', _335 => _335.thick, 'optionalAccess', _336 => _336[l.id]]);
6012
6276
  if (heightInput && relief) {
6013
6277
  const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
6014
6278
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
6015
6279
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
6016
6280
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
6017
6281
  }
6018
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _330 => _330.inputs, 'access', _331 => _331.find, 'call', _332 => _332((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _333 => _333.name])), 'optionalAccess', _334 => _334.name]), () => ( "source"));
6282
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _337 => _337.inputs, 'access', _338 => _338.find, 'call', _339 => _339((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _340 => _340.name])), 'optionalAccess', _341 => _341.name]), () => ( "source"));
6019
6283
  if (sourceInput !== "source") {
6020
6284
  inputs[sourceInput] = inputs.source;
6021
6285
  delete inputs.source;
@@ -6031,7 +6295,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6031
6295
  return this.brushEntries.find((e) => e.brush.id === id);
6032
6296
  }
6033
6297
  findBrush(id) {
6034
- return _optionalChain([this, 'access', _335 => _335.findEntry, 'call', _336 => _336(id), 'optionalAccess', _337 => _337.brush]);
6298
+ return _optionalChain([this, 'access', _342 => _342.findEntry, 'call', _343 => _343(id), 'optionalAccess', _344 => _344.brush]);
6035
6299
  }
6036
6300
  requireEntry(id) {
6037
6301
  const e = this.findEntry(id);
@@ -6068,7 +6332,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6068
6332
  }
6069
6333
  /** A library brush by id as stored (its facets), or without an id the active brush as edited. */
6070
6334
  getBrushSpec(id) {
6071
- const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _338 => _338.findEntry, 'call', _339 => _339(id), 'optionalAccess', _340 => _340.spec]);
6335
+ const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _345 => _345.findEntry, 'call', _346 => _346(id), 'optionalAccess', _347 => _347.spec]);
6072
6336
  return spec ? copyJSON(spec) : void 0;
6073
6337
  }
6074
6338
  /**
@@ -6100,8 +6364,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6100
6364
  const base = copyJSON(entry ? entry.spec : this.brushSpec);
6101
6365
  for (const k of unset) delete base[k];
6102
6366
  const spec = this.readBrushPatch(base, patch, problems);
6103
- if (entry || _optionalChain([patch, 'access', _341 => _341.colour, 'optionalAccess', _342 => _342.default]) !== void 0) this.takeBrushColour(spec);
6104
- this.useBrush(unchanged && entry ? entry.brush : _chunkGHGBIAWQcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _343 => _343.builtin]) === true);
6367
+ if (entry || _optionalChain([patch, 'access', _348 => _348.colour, 'optionalAccess', _349 => _349.default]) !== void 0) this.takeBrushColour(spec);
6368
+ this.useBrush(unchanged && entry ? entry.brush : _chunkGHGBIAWQcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _350 => _350.builtin]) === true);
6105
6369
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
6106
6370
  }
6107
6371
  /**
@@ -6111,7 +6375,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6111
6375
  */
6112
6376
  setBrushSpec(spec) {
6113
6377
  const problems = [];
6114
- const paint = _optionalChain([spec, 'access', _344 => _344.colour, 'optionalAccess', _345 => _345.default]);
6378
+ const paint = _optionalChain([spec, 'access', _351 => _351.colour, 'optionalAccess', _352 => _352.default]);
6115
6379
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
6116
6380
  let next;
6117
6381
  try {
@@ -6134,7 +6398,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6134
6398
  }
6135
6399
  readBrushPatch(base, patch, problems) {
6136
6400
  const { id: _id, name, ...rest } = patch;
6137
- const paint = _optionalChain([rest, 'access', _346 => _346.colour, 'optionalAccess', _347 => _347.default]);
6401
+ const paint = _optionalChain([rest, 'access', _353 => _353.colour, 'optionalAccess', _354 => _354.default]);
6138
6402
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
6139
6403
  try {
6140
6404
  return _chunkGHGBIAWQcjs.normalizeBrushSpec.call(void 0, _chunk3JKCREEUcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
@@ -6227,7 +6491,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6227
6491
  */
6228
6492
  takeBrushColour(spec) {
6229
6493
  if (this.colorLocked) return;
6230
- const d = _optionalChain([spec, 'access', _348 => _348.colour, 'optionalAccess', _349 => _349.default]);
6494
+ const d = _optionalChain([spec, 'access', _355 => _355.colour, 'optionalAccess', _356 => _356.default]);
6231
6495
  const hex2 = d !== void 0 ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
6232
6496
  if (!hex2) return;
6233
6497
  this.color = hex2;
@@ -6238,8 +6502,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6238
6502
  }
6239
6503
  /** A brush that always paints its own colour (`colour.own`): that colour, resolved for the scheme now; else `null`. */
6240
6504
  ownColour(brushId) {
6241
- const spec = brushId !== void 0 ? _optionalChain([this, 'access', _350 => _350.findEntry, 'call', _351 => _351(brushId), 'optionalAccess', _352 => _352.spec]) : this.brushSpec;
6242
- const d = _optionalChain([spec, 'optionalAccess', _353 => _353.colour, 'optionalAccess', _354 => _354.own]) ? spec.colour.default : void 0;
6505
+ const spec = brushId !== void 0 ? _optionalChain([this, 'access', _357 => _357.findEntry, 'call', _358 => _358(brushId), 'optionalAccess', _359 => _359.spec]) : this.brushSpec;
6506
+ const d = _optionalChain([spec, 'optionalAccess', _360 => _360.colour, 'optionalAccess', _361 => _361.own]) ? spec.colour.default : void 0;
6243
6507
  return d !== void 0 ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
6244
6508
  }
6245
6509
  /** Sets the paint colour (and goes back to one colour from gradient paint). */
@@ -6401,32 +6665,32 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6401
6665
  if (brush.behavior.multicolor.mode !== "off") throw new PaintEditorError(`Ghost paint (${brush.name}) needs a single colour to subtract as it fades, so it can't use multi-colour paint; set behavior.multicolor.mode to "off" (set_brush).`);
6402
6666
  const gCol = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
6403
6667
  if (this.strokeGradient(init, brush, gCol)) throw new PaintEditorError(`Ghost paint (${brush.name}) needs a single colour to subtract as it fades, so it can't paint a gradient; set a solid colour (set_color) or pass color to paint_stroke.`);
6404
- if (Boolean(_optionalChain([doc, 'access', _355 => _355.light, 'optionalAccess', _356 => _356[layer.id], 'optionalAccess', _357 => _357.tiles, 'access', _358 => _358.size])) || Boolean(_optionalChain([this, 'access', _359 => _359.wet, 'access', _360 => _360.world, 'optionalAccess', _361 => _361.hasLane, 'call', _362 => _362(layer.id)]) && this.wet.world.isLit(layer.id))) {
6668
+ if (Boolean(_optionalChain([doc, 'access', _362 => _362.light, 'optionalAccess', _363 => _363[layer.id], 'optionalAccess', _364 => _364.tiles, 'access', _365 => _365.size])) || Boolean(_optionalChain([this, 'access', _366 => _366.wet, 'access', _367 => _367.world, 'optionalAccess', _368 => _368.hasLane, 'call', _369 => _369(layer.id)]) && this.wet.world.isLit(layer.id))) {
6405
6669
  throw new PaintEditorError(`Layer "${layer.name}" holds light paint, and ghost paint shares the wet light channel; paint on another layer (add_layer) or clear the light first (clear_light).`);
6406
6670
  }
6407
6671
  }
6408
6672
  const effect = this.strokeEffect(init, brush, points);
6409
- if (!points && init.paint === void 0 && _optionalChain([effect, 'optionalAccess', _363 => _363.source, 'access', _364 => _364.map, 'optionalAccess', _365 => _365.by]) === "path" && _chunkGHGBIAWQcjs.isWetBrush.call(void 0, brush)) {
6673
+ if (!points && init.paint === void 0 && _optionalChain([effect, 'optionalAccess', _370 => _370.source, 'access', _371 => _371.map, 'optionalAccess', _372 => _372.by]) === "path" && _chunkGHGBIAWQcjs.isWetBrush.call(void 0, brush)) {
6410
6674
  throw new PaintEditorError(`The ${brush.name} brush paints wet media, which can't follow a path that isn't known until the stroke ends; paint with a dry brush, set_effect_paint with by: "stroke", or give the points to paint_stroke.`);
6411
6675
  }
6412
6676
  if (brush.light.amount > 0) {
6413
6677
  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).`);
6414
- if (Boolean(_optionalChain([this, 'access', _366 => _366.wet, 'access', _367 => _367.world, 'optionalAccess', _368 => _368.hasLane, 'call', _369 => _369(layer.id)]) && this.wet.world.getGhost(layer.id)) || Boolean(_optionalChain([this, 'access', _370 => _370.wet, 'access', _371 => _371.settings, 'access', _372 => _372.get, 'call', _373 => _373(layer.id), 'optionalAccess', _374 => _374.ghost]))) {
6678
+ if (Boolean(_optionalChain([this, 'access', _373 => _373.wet, 'access', _374 => _374.world, 'optionalAccess', _375 => _375.hasLane, 'call', _376 => _376(layer.id)]) && this.wet.world.getGhost(layer.id)) || Boolean(_optionalChain([this, 'access', _377 => _377.wet, 'access', _378 => _378.settings, 'access', _379 => _379.get, 'call', _380 => _380(layer.id), 'optionalAccess', _381 => _381.ghost]))) {
6415
6679
  throw new PaintEditorError(`Layer "${layer.name}" has ghost paint fading on it, which uses the wet light channel; paint light on another layer (add_layer), or finish the ghost first (dry_paint).`);
6416
6680
  }
6417
6681
  }
6418
- if (_optionalChain([doc, 'access', _375 => _375.liveStrokes, 'optionalAccess', _376 => _376[layer.id]])) {
6682
+ if (_optionalChain([doc, 'access', _382 => _382.liveStrokes, 'optionalAccess', _383 => _383[layer.id]])) {
6419
6683
  const why = liveStrokeRefusal(brush);
6420
6684
  if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
6421
6685
  }
6422
- if (_optionalChain([doc, 'access', _377 => _377.liveStrokes, 'optionalAccess', _378 => _378[layer.id]]) && _optionalChain([effect, 'optionalAccess', _379 => _379.source, 'access', _380 => _380.live])) {
6686
+ if (_optionalChain([doc, 'access', _384 => _384.liveStrokes, 'optionalAccess', _385 => _385[layer.id]]) && _optionalChain([effect, 'optionalAccess', _386 => _386.source, 'access', _387 => _387.live])) {
6423
6687
  const key = _chunkSNAFFCAXcjs.effectPaintKey.call(void 0, effect.source);
6424
6688
  const { sources } = this.liveEffects(doc);
6425
6689
  if (!sources.some((p) => _chunkSNAFFCAXcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
6426
6690
  throw new PaintEditorError(`The painting already plays ${MAX_LIVE_EFFECT_SOURCES} live effects, the most it can; paint with one of them, or set_effect_paint with live false to bake this one.`);
6427
6691
  }
6428
6692
  }
6429
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _381 => _381.stickers, 'optionalAccess', _382 => _382[layer.id], 'optionalAccess', _383 => _383.length]));
6693
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _388 => _388.stickers, 'optionalAccess', _389 => _389[layer.id], 'optionalAccess', _390 => _390.length]));
6430
6694
  if (brush.engine === "sticker") {
6431
6695
  if (!stickerLayer && _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; spray stickers onto an empty layer (add_layer) so they stay editable.`);
6432
6696
  } else if (stickerLayer) {
@@ -6466,7 +6730,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6466
6730
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
6467
6731
  mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
6468
6732
  paint: effect ? null : wetGradient,
6469
- effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _384 => _384.pixels]), () => ( null)),
6733
+ effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _391 => _391.pixels]), () => ( null)),
6470
6734
  speed: this.wet.speed
6471
6735
  });
6472
6736
  init = { ...init, seed: seedW, load };
@@ -6478,7 +6742,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6478
6742
  }
6479
6743
  let color = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
6480
6744
  const tracing = this.guides.tracing;
6481
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _385 => _385.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
6745
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _392 => _392.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
6482
6746
  const perspective = this.guides.perspective;
6483
6747
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
6484
6748
  const useStencils = init.stencils !== false;
@@ -6511,9 +6775,9 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6511
6775
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
6512
6776
  secondary: rgbaOf(this.secondaryColor),
6513
6777
  wet,
6514
- thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _386 => _386.thick, 'optionalAccess', _387 => _387[layer.id]]), () => ( emptyThickChannels())) } : void 0,
6778
+ thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _393 => _393.thick, 'optionalAccess', _394 => _394[layer.id]]), () => ( emptyThickChannels())) } : void 0,
6515
6779
  // Light paint: a twin of the stroke paints the light channel (laying, dimming, moving light).
6516
- light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _388 => _388.light, 'optionalAccess', _389 => _389[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _390 => _390.light, 'optionalAccess', _391 => _391[layer.id]]), () => ( emptyLight())) } : null,
6780
+ light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _395 => _395.light, 'optionalAccess', _396 => _396[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _397 => _397.light, 'optionalAccess', _398 => _398[layer.id]]), () => ( emptyLight())) } : null,
6517
6781
  sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc), art: this.stickerArt.get, variant: (ref2) => this.stickerArt.variantFor(ref2, this.colorScheme === "dark") } : void 0,
6518
6782
  stampArt: this.stampArt,
6519
6783
  paint: effect ? null : this.strokeGradient(init, brush, color),
@@ -6553,12 +6817,12 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6553
6817
  const before = this.doc;
6554
6818
  const host = {
6555
6819
  update: (layerId, surface, rects) => {
6556
- if (_optionalChain([this, 'access', _392 => _392.session, 'optionalAccess', _393 => _393.init, 'access', _394 => _394.wet])) {
6820
+ if (_optionalChain([this, 'access', _399 => _399.session, 'optionalAccess', _400 => _400.init, 'access', _401 => _401.wet])) {
6557
6821
  this.wet.syncDisplays();
6558
6822
  return;
6559
6823
  }
6560
6824
  this.live = { layerId, surface };
6561
- const ch = _optionalChain([this, 'access', _395 => _395.session, 'optionalAccess', _396 => _396.thickChannels, 'call', _397 => _397()]);
6825
+ const ch = _optionalChain([this, 'access', _402 => _402.session, 'optionalAccess', _403 => _403.thickChannels, 'call', _404 => _404()]);
6562
6826
  this.liveThick = ch ? { layerId, channels: ch } : null;
6563
6827
  this.emit(rects);
6564
6828
  },
@@ -6568,7 +6832,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6568
6832
  },
6569
6833
  commit: (s, surface, cancelled) => {
6570
6834
  this.session = null;
6571
- const preview = _optionalChain([this, 'access', _398 => _398.pathPreview, 'optionalAccess', _399 => _399.session]) === s ? this.pathPreview : null;
6835
+ const preview = _optionalChain([this, 'access', _405 => _405.pathPreview, 'optionalAccess', _406 => _406.session]) === s ? this.pathPreview : null;
6572
6836
  this.pathPreview = null;
6573
6837
  const pathPaint = cancelled ? null : this.pathStrokePaint(s);
6574
6838
  if (pathPaint) {
@@ -6581,7 +6845,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6581
6845
  const wetStroke = Boolean(s.init.wet);
6582
6846
  if (wetStroke) this.wet.driver = null;
6583
6847
  const brush = s.init.brush;
6584
- if (!cancelled && _optionalChain([s, 'access', _400 => _400.result, 'optionalAccess', _401 => _401.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
6848
+ if (!cancelled && _optionalChain([s, 'access', _407 => _407.result, 'optionalAccess', _408 => _408.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
6585
6849
  if (cancelled || !surface) {
6586
6850
  if (this.wetOp) {
6587
6851
  const snap = this.wetOp.before;
@@ -6597,7 +6861,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6597
6861
  }
6598
6862
  const stroke = this.record(s);
6599
6863
  s.result.strokeId = stroke.id;
6600
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _402 => _402.result, 'optionalAccess', _403 => _403.bounds]), () => ( null)));
6864
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _409 => _409.result, 'optionalAccess', _410 => _410.bounds]), () => ( null)));
6601
6865
  if (wetStroke && this.wet.instantDry) {
6602
6866
  this.wet.dry(s.layerId);
6603
6867
  this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
@@ -6608,8 +6872,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6608
6872
  const ch = s.thickChannels();
6609
6873
  const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
6610
6874
  const sprayed = s.stickers();
6611
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _404 => _404.doc, 'access', _405 => _405.stickers, 'optionalAccess', _406 => _406[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
6612
- const wetLight = wetStroke && _optionalChain([this, 'access', _407 => _407.wet, 'access', _408 => _408.world, 'optionalAccess', _409 => _409.hasLane, 'call', _410 => _410(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
6875
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _411 => _411.doc, 'access', _412 => _412.stickers, 'optionalAccess', _413 => _413[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
6876
+ const wetLight = wetStroke && _optionalChain([this, 'access', _414 => _414.wet, 'access', _415 => _415.world, 'optionalAccess', _416 => _416.hasLane, 'call', _417 => _417(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
6613
6877
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
6614
6878
  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);
6615
6879
  this.notifySample("end", s, [], stroke.id);
@@ -6623,7 +6887,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6623
6887
  throw e;
6624
6888
  }
6625
6889
  this.session = session;
6626
- if (_optionalChain([session, 'access', _411 => _411.init, 'access', _412 => _412.effect, 'optionalAccess', _413 => _413.source, 'access', _414 => _414.map, 'optionalAccess', _415 => _415.by]) === "path" && !session.init.wet) this.pathPreview = { session, key: "", pending: null, landed: null };
6890
+ if (_optionalChain([session, 'access', _418 => _418.init, 'access', _419 => _419.effect, 'optionalAccess', _420 => _420.source, 'access', _421 => _421.map, 'optionalAccess', _422 => _422.by]) === "path" && !session.init.wet) this.pathPreview = { session, key: "", pending: null, landed: null };
6627
6891
  this.emit([]);
6628
6892
  this.notifySample("begin", session);
6629
6893
  return session;
@@ -6668,12 +6932,12 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6668
6932
  * the editor is busy, as during a stroke, and shows the stroke as it was painted.
6669
6933
  */
6670
6934
  get strokeRendering() {
6671
- return _nullishCoalesce(_optionalChain([this, 'access', _416 => _416.pathStroke, 'optionalAccess', _417 => _417.done]), () => ( null));
6935
+ return _nullishCoalesce(_optionalChain([this, 'access', _423 => _423.pathStroke, 'optionalAccess', _424 => _424.done]), () => ( null));
6672
6936
  }
6673
6937
  /** The paint a finished hand-painted stroke must be painted again with, or `null` when it already painted with it. */
6674
6938
  pathStrokePaint(s) {
6675
- const source = _optionalChain([s, 'access', _418 => _418.init, 'access', _419 => _419.effect, 'optionalAccess', _420 => _420.source]);
6676
- if (_optionalChain([source, 'optionalAccess', _421 => _421.map, 'optionalAccess', _422 => _422.by]) !== "path" || !s.points.length) return null;
6939
+ const source = _optionalChain([s, 'access', _425 => _425.init, 'access', _426 => _426.effect, 'optionalAccess', _427 => _427.source]);
6940
+ if (_optionalChain([source, 'optionalAccess', _428 => _428.map, 'optionalAccess', _429 => _429.by]) !== "path" || !s.points.length) return null;
6677
6941
  const paint = _chunkSNAFFCAXcjs.withStrokePath.call(void 0, source, s.points, this.effectPathControls.get(source.effect));
6678
6942
  return _chunkSNAFFCAXcjs.effectPaintKey.call(void 0, paint) === _chunkSNAFFCAXcjs.effectPaintKey.call(void 0, source) ? null : paint;
6679
6943
  }
@@ -6696,12 +6960,12 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6696
6960
  this.notifySample("end", s, [], result.strokeId);
6697
6961
  };
6698
6962
  const key = _chunkSNAFFCAXcjs.effectPaintKey.call(void 0, paint);
6699
- if (_optionalChain([preview, 'optionalAccess', _423 => _423.landed, 'optionalAccess', _424 => _424.key]) === key) this.cacheEffectPaintImage(paint, preview.landed.pixels);
6963
+ if (_optionalChain([preview, 'optionalAccess', _430 => _430.landed, 'optionalAccess', _431 => _431.key]) === key) this.cacheEffectPaintImage(paint, preview.landed.pixels);
6700
6964
  if (this.effectPaintImage(paint) || this.renderEffectPaintSync(paint)) {
6701
6965
  finish();
6702
6966
  return;
6703
6967
  }
6704
- const render = _optionalChain([preview, 'optionalAccess', _425 => _425.pending]) && preview.key === key ? preview.pending.then((img) => this.cacheEffectPaintImage(paint, img)) : this.renderEffectPaint(paint);
6968
+ const render = _optionalChain([preview, 'optionalAccess', _432 => _432.pending]) && preview.key === key ? preview.pending.then((img) => this.cacheEffectPaintImage(paint, img)) : this.renderEffectPaint(paint);
6705
6969
  const done = render.then(finish, (e) => {
6706
6970
  this.pathStroke = null;
6707
6971
  this.live = null;
@@ -6726,18 +6990,18 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6726
6990
  if (cancelled || !surface) return;
6727
6991
  const stroke = this.record(s);
6728
6992
  s.result.strokeId = stroke.id;
6729
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _426 => _426.result, 'optionalAccess', _427 => _427.bounds]), () => ( null)));
6993
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _433 => _433.result, 'optionalAccess', _434 => _434.bounds]), () => ( null)));
6730
6994
  const l = _chunkPVJMTLPJcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
6731
6995
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
6732
6996
  const ch = s.thickChannels();
6733
6997
  const sprayed = s.stickers();
6734
- const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _428 => _428.wet, 'access', _429 => _429.world, 'optionalAccess', _430 => _430.hasLane, 'call', _431 => _431(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
6998
+ const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _435 => _435.wet, 'access', _436 => _436.world, 'optionalAccess', _437 => _437.hasLane, 'call', _438 => _438(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
6735
6999
  out = withLiveStroke({
6736
7000
  ...out,
6737
7001
  layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
6738
7002
  strokes: [...out.strokes, stroke],
6739
7003
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
6740
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _432 => _432.stickers, 'optionalAccess', _433 => _433[l.id]]), () => ( [])), ...sprayed] } } : {},
7004
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _439 => _439.stickers, 'optionalAccess', _440 => _440[l.id]]), () => ( [])), ...sprayed] } } : {},
6741
7005
  ...lit ? { light: withLayerLight(out.light, l.id, lit) } : {}
6742
7006
  }, stroke);
6743
7007
  }
@@ -6810,11 +7074,11 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6810
7074
  throw e;
6811
7075
  }
6812
7076
  const run = last;
6813
- if (_optionalChain([run, 'optionalAccess', _434 => _434.result, 'access', _435 => _435.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
6814
- if (doc !== before || this.wetOp) this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _436 => _436.brush, 'access', _437 => _437.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
7077
+ if (_optionalChain([run, 'optionalAccess', _441 => _441.result, 'access', _442 => _442.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
7078
+ if (doc !== before || this.wetOp) this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _443 => _443.brush, 'access', _444 => _444.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
6815
7079
  else this.emit([]);
6816
- const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _438 => _438.result, 'access', _439 => _439.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
6817
- return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _440 => _440.result, 'access', _441 => _441.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _442 => _442.result, 'access', _443 => _443.wet]) !== void 0 ? { wet: run.result.wet } : {} };
7080
+ const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _445 => _445.result, 'access', _446 => _446.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
7081
+ return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _447 => _447.result, 'access', _448 => _448.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _449 => _449.result, 'access', _450 => _450.wet]) !== void 0 ? { wet: run.result.wet } : {} };
6818
7082
  }
6819
7083
  /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
6820
7084
  checkPoints(points) {
@@ -6837,7 +7101,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6837
7101
  */
6838
7102
  replayStrokes(options) {
6839
7103
  this.requireIdle("replaying");
6840
- if (!_optionalChain([options, 'access', _444 => _444.strokeIds, 'optionalAccess', _445 => _445.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7104
+ if (!_optionalChain([options, 'access', _451 => _451.strokeIds, 'optionalAccess', _452 => _452.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
6841
7105
  const strokes = options.strokeIds.map((id) => {
6842
7106
  const s = this.doc.strokes.find((x) => x.id === id);
6843
7107
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -6851,7 +7115,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6851
7115
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
6852
7116
  if (options.color === void 0) {
6853
7117
  for (const s of strokes) {
6854
- if (_optionalChain([s, 'access', _446 => _446.paint, 'optionalAccess', _447 => _447.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7118
+ if (_optionalChain([s, 'access', _453 => _453.paint, 'optionalAccess', _454 => _454.type]) === "effect" && !this.effectPaintImage(s.paint)) {
6855
7119
  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.`);
6856
7120
  }
6857
7121
  }
@@ -6911,7 +7175,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6911
7175
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
6912
7176
  lightOf(layerId) {
6913
7177
  const l = this.wetLayer(layerId, "read the light of");
6914
- const info = lightInfo(_optionalChain([this, 'access', _448 => _448.doc, 'access', _449 => _449.light, 'optionalAccess', _450 => _450[l.id]]));
7178
+ const info = lightInfo(_optionalChain([this, 'access', _455 => _455.doc, 'access', _456 => _456.light, 'optionalAccess', _457 => _457[l.id]]));
6915
7179
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
6916
7180
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
6917
7181
  }
@@ -6962,7 +7226,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
6962
7226
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
6963
7227
  if (!id) return null;
6964
7228
  this.requireLayer(id);
6965
- const ch = _optionalChain([this, 'access', _451 => _451.doc, 'access', _452 => _452.thick, 'optionalAccess', _453 => _453[id]]);
7229
+ const ch = _optionalChain([this, 'access', _458 => _458.doc, 'access', _459 => _459.thick, 'optionalAccess', _460 => _460[id]]);
6966
7230
  if (!ch) return null;
6967
7231
  const r = reliefInfo(ch);
6968
7232
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -7073,7 +7337,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7073
7337
  wetState() {
7074
7338
  const st = this.getState().wet;
7075
7339
  const backend = this.wet.backend();
7076
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _454 => _454.message]), () => ( _chunkN5IMDAHMcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
7340
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _461 => _461.message]), () => ( _chunkN5IMDAHMcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
7077
7341
  }
7078
7342
  /**
7079
7343
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -7158,7 +7422,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7158
7422
  }
7159
7423
  /** Records a settings change as a wet event (not an undo step). */
7160
7424
  recordWetSetting(e) {
7161
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _455 => _455.wet, 'access', _456 => _456.world, 'optionalAccess', _457 => _457.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
7425
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _462 => _462.wet, 'access', _463 => _463.world, 'optionalAccess', _464 => _464.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
7162
7426
  }
7163
7427
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
7164
7428
  setWetParams(layerId, update) {
@@ -7227,7 +7491,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7227
7491
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkPVJMTLPJcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
7228
7492
  const live = this.live;
7229
7493
  if (!live) return this.animatedView();
7230
- if (_optionalChain([this, 'access', _458 => _458.liveLayers, 'optionalAccess', _459 => _459.key]) === live.surface) return this.liveLayers.layers;
7494
+ if (_optionalChain([this, 'access', _465 => _465.liveLayers, 'optionalAccess', _466 => _466.key]) === live.surface) return this.liveLayers.layers;
7231
7495
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
7232
7496
  this.liveLayers = { key: live.surface, layers };
7233
7497
  return layers;
@@ -7250,7 +7514,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7250
7514
  tracingNode(t) {
7251
7515
  const { width, height } = this.doc.canvas;
7252
7516
  const key = this.tracingVersion * 100003 + width * 7 + height;
7253
- if (_optionalChain([this, 'access', _460 => _460.tracingCache, 'optionalAccess', _461 => _461.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
7517
+ if (_optionalChain([this, 'access', _467 => _467.tracingCache, 'optionalAccess', _468 => _468.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
7254
7518
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
7255
7519
  const image = resampleInto(src, t.rect, width, height);
7256
7520
  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 };
@@ -7277,8 +7541,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7277
7541
  let out = layers;
7278
7542
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
7279
7543
  for (const id of ids) {
7280
- const ch = _optionalChain([live, 'optionalAccess', _462 => _462.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _463 => _463[id]]);
7281
- const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _464 => _464.layer]);
7544
+ const ch = _optionalChain([live, 'optionalAccess', _469 => _469.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _470 => _470[id]]);
7545
+ const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _471 => _471.layer]);
7282
7546
  if (!ch || !isPixelLayer(l)) continue;
7283
7547
  let cache = this.litCaches.get(id);
7284
7548
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -7298,13 +7562,13 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7298
7562
  if (!ids.size) return layers;
7299
7563
  let out = layers;
7300
7564
  for (const id of ids) {
7301
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _465 => _465.layer]);
7565
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _472 => _472.layer]);
7302
7566
  if (!isPixelLayer(l)) continue;
7303
7567
  let cache = this.lightCaches.get(id);
7304
7568
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
7305
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _466 => _466.liveThick, 'optionalAccess', _467 => _467.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _468 => _468.doc, 'access', _469 => _469.thick, 'optionalAccess', _470 => _470[id]]));
7569
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _473 => _473.liveThick, 'optionalAccess', _474 => _474.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _475 => _475.doc, 'access', _476 => _476.thick, 'optionalAccess', _477 => _477[id]]));
7306
7570
  if (glowed !== l.surface) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
7307
- const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _471 => _471.layer]);
7571
+ const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _478 => _478.layer]);
7308
7572
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
7309
7573
  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 } });
7310
7574
  }
@@ -7316,7 +7580,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7316
7580
  if (!l.visible) continue;
7317
7581
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
7318
7582
  else if (isPixelLayer(l)) {
7319
- const thick = !committed && _optionalChain([this, 'access', _472 => _472.liveThick, 'optionalAccess', _473 => _473.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _474 => _474.doc, 'access', _475 => _475.thick, 'optionalAccess', _476 => _476[l.id]]);
7583
+ const thick = !committed && _optionalChain([this, 'access', _479 => _479.liveThick, 'optionalAccess', _480 => _480.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _481 => _481.doc, 'access', _482 => _482.thick, 'optionalAccess', _483 => _483[l.id]]);
7320
7584
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
7321
7585
  }
7322
7586
  }
@@ -7345,7 +7609,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7345
7609
  if (backlight) layers = [...layers, backlight];
7346
7610
  if (options.layerIds) {
7347
7611
  const picked = [];
7348
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _477 => _477.layer]), () => ( this.requireLayer(id))));
7612
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _484 => _484.layer]), () => ( this.requireLayer(id))));
7349
7613
  layers = picked.map((l) => ({ ...l, visible: true }));
7350
7614
  }
7351
7615
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -7361,7 +7625,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7361
7625
  */
7362
7626
  compositeTiles(rect, onTile, options = {}) {
7363
7627
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
7364
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _478 => _478.live, 'optionalAccess', _479 => _479.layerId]), () => ( this.doc.activeLayerId)) });
7628
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _485 => _485.live, 'optionalAccess', _486 => _486.layerId]), () => ( this.doc.activeLayerId)) });
7365
7629
  }
7366
7630
  /** The canvas as canvas-sized RGBA (paper included by default). */
7367
7631
  compositePixels(options = {}) {
@@ -7391,7 +7655,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7391
7655
  const layers = {};
7392
7656
  for (const [id, set] of this.wet.settings) {
7393
7657
  if (!_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
7394
- const ghost = _optionalChain([this, 'access', _480 => _480.wet, 'access', _481 => _481.world, 'optionalAccess', _482 => _482.hasLane, 'call', _483 => _483(id)]) ? this.wet.world.getGhost(id) : _nullishCoalesce(set.ghost, () => ( null));
7658
+ const ghost = _optionalChain([this, 'access', _487 => _487.wet, 'access', _488 => _488.world, 'optionalAccess', _489 => _489.hasLane, 'call', _490 => _490(id)]) ? this.wet.world.getGhost(id) : _nullishCoalesce(set.ghost, () => ( null));
7395
7659
  layers[id] = { params: { ...set.params }, flow: { ...set.flow }, ...ghost ? { ghost } : {} };
7396
7660
  }
7397
7661
  const flat = this.wet.tilt.angle === 0;
@@ -7450,7 +7714,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7450
7714
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)));
7451
7715
  if (Object.keys(spills).length) ext.lightSpill = spills;
7452
7716
  else delete ext.lightSpill;
7453
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _484 => _484.layer])));
7717
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _491 => _491.layer])));
7454
7718
  if (effectLayers) ext.effectLayers = effectLayers;
7455
7719
  else delete ext.effectLayers;
7456
7720
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -7487,7 +7751,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7487
7751
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
7488
7752
  const liveStrokes = {};
7489
7753
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
7490
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _485 => _485.layer])) || !Array.isArray(list)) continue;
7754
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _492 => _492.layer])) || !Array.isArray(list)) continue;
7491
7755
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
7492
7756
  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).`);
7493
7757
  liveStrokes[id] = ok;
@@ -7497,7 +7761,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7497
7761
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
7498
7762
  const effectLayers = {};
7499
7763
  for (const [id, v] of Object.entries(ext.effectLayers)) {
7500
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _486 => _486.layer]))) continue;
7764
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _493 => _493.layer]))) continue;
7501
7765
  const source = readPaintEffectSource(v);
7502
7766
  if (source) effectLayers[id] = source;
7503
7767
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -7525,7 +7789,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7525
7789
  if (ext.light && typeof ext.light === "object") {
7526
7790
  const light = {};
7527
7791
  for (const [id, v] of Object.entries(ext.light)) {
7528
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _487 => _487.layer]))) continue;
7792
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _494 => _494.layer]))) continue;
7529
7793
  try {
7530
7794
  light[id] = lightFromJSON(v);
7531
7795
  } catch (e) {
@@ -7561,7 +7825,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7561
7825
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
7562
7826
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
7563
7827
  for (const s of loaded.state.strokes) {
7564
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _488 => _488.exec, 'call', _489 => _489(s.id), 'optionalAccess', _490 => _490[1]]), () => ( 0)));
7828
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _495 => _495.exec, 'call', _496 => _496(s.id), 'optionalAccess', _497 => _497[1]]), () => ( 0)));
7565
7829
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
7566
7830
  }
7567
7831
  this.undoStack = [];
@@ -7569,7 +7833,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7569
7833
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
7570
7834
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
7571
7835
  for (const s of list) {
7572
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _491 => _491.exec, 'call', _492 => _492(s.id), 'optionalAccess', _493 => _493[1]]), () => ( 0)));
7836
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _498 => _498.exec, 'call', _499 => _499(s.id), 'optionalAccess', _500 => _500[1]]), () => ( 0)));
7573
7837
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
7574
7838
  }
7575
7839
  }
@@ -7669,8 +7933,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7669
7933
  const layers = toStandard(dried);
7670
7934
  const result = _chunkYJANF2BLcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
7671
7935
  for (const [mode, names] of changed) {
7672
- const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _494 => _494.find, 'call', _495 => _495((m) => m.id === mode), 'optionalAccess', _496 => _496.label]), () => ( mode));
7673
- const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _497 => _497.find, 'call', _498 => _498((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _499 => _499.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
7936
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _501 => _501.find, 'call', _502 => _502((m) => m.id === mode), 'optionalAccess', _503 => _503.label]), () => ( mode));
7937
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _504 => _504.find, 'call', _505 => _505((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _506 => _506.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
7674
7938
  const list = names.map((n) => `"${n}"`).join(", ");
7675
7939
  const one = names.length === 1;
7676
7940
  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).`);
@@ -7792,7 +8056,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7792
8056
  const { src, pixels } = this.importImage(options, "The reference image");
7793
8057
  const ref2 = {
7794
8058
  id: `ref${this.nextReferenceId++}`,
7795
- name: _optionalChain([options, 'access', _500 => _500.name, 'optionalAccess', _501 => _501.trim, 'call', _502 => _502()]) || `Reference ${this.guides.references.length + 1}`,
8059
+ name: _optionalChain([options, 'access', _507 => _507.name, 'optionalAccess', _508 => _508.trim, 'call', _509 => _509()]) || `Reference ${this.guides.references.length + 1}`,
7796
8060
  src,
7797
8061
  width: pixels.width,
7798
8062
  height: pixels.height,
@@ -7871,7 +8135,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7871
8135
  try {
7872
8136
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
7873
8137
  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 });
7874
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _503 => _503.exec, 'call', _504 => _504(ref2.id), 'optionalAccess', _505 => _505[1]]), () => ( 0)));
8138
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _510 => _510.exec, 'call', _511 => _511(ref2.id), 'optionalAccess', _512 => _512[1]]), () => ( 0)));
7875
8139
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
7876
8140
  } catch (e) {
7877
8141
  problems.push(e.message);
@@ -7882,7 +8146,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7882
8146
  guides.stencils = [];
7883
8147
  r.stencils.forEach((raw2, i) => {
7884
8148
  try {
7885
- const id = typeof _optionalChain([raw2, 'optionalAccess', _506 => _506.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
8149
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _513 => _513.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
7886
8150
  guides.stencils.push(normalizeStencil(raw2, id));
7887
8151
  const n = Number(id.slice(7));
7888
8152
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -7905,12 +8169,12 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7905
8169
  /** The next free sticker number (ids `st<n>` are unique across the document). */
7906
8170
  nextStickerNumber(doc = this.doc) {
7907
8171
  let n = 0;
7908
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _507 => _507.exec, 'call', _508 => _508(st.id), 'optionalAccess', _509 => _509[1]]), () => ( 0))));
8172
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _514 => _514.exec, 'call', _515 => _515(st.id), 'optionalAccess', _516 => _516[1]]), () => ( 0))));
7909
8173
  return n + 1;
7910
8174
  }
7911
8175
  stickerLayer(layerId) {
7912
8176
  const l = this.wetLayer(layerId, "edit the stickers of");
7913
- const stickers = _optionalChain([this, 'access', _510 => _510.doc, 'access', _511 => _511.stickers, 'optionalAccess', _512 => _512[l.id]]);
8177
+ const stickers = _optionalChain([this, 'access', _517 => _517.doc, 'access', _518 => _518.stickers, 'optionalAccess', _519 => _519[l.id]]);
7914
8178
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (sticker-stars; list_brush_presets lists them).`);
7915
8179
  return { layer: l, stickers };
7916
8180
  }
@@ -7986,7 +8250,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7986
8250
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
7987
8251
  if (!id) return [];
7988
8252
  this.requireLayer(id);
7989
- return (_nullishCoalesce(_optionalChain([this, 'access', _513 => _513.doc, 'access', _514 => _514.stickers, 'optionalAccess', _515 => _515[id]]), () => ( []))).map((s) => ({ ...s }));
8253
+ return (_nullishCoalesce(_optionalChain([this, 'access', _520 => _520.doc, 'access', _521 => _521.stickers, 'optionalAccess', _522 => _522[id]]), () => ( []))).map((s) => ({ ...s }));
7990
8254
  }
7991
8255
  /**
7992
8256
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -8007,7 +8271,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8007
8271
  }
8008
8272
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
8009
8273
  previewBase() {
8010
- return _optionalChain([this, 'access', _516 => _516.stickerPreview, 'optionalAccess', _517 => _517.shown]) === this.doc ? this.stickerPreview.base : null;
8274
+ return _optionalChain([this, 'access', _523 => _523.stickerPreview, 'optionalAccess', _524 => _524.shown]) === this.doc ? this.stickerPreview.base : null;
8011
8275
  }
8012
8276
  readStickerUpdate(update) {
8013
8277
  try {
@@ -8022,7 +8286,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8022
8286
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8023
8287
  if (!id) return null;
8024
8288
  this.requireLayer(id);
8025
- const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _518 => _518.doc, 'access', _519 => _519.stickers, 'optionalAccess', _520 => _520[id]]), () => ( [])), x, y, this.stickerArt.get);
8289
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _525 => _525.doc, 'access', _526 => _526.stickers, 'optionalAccess', _527 => _527[id]]), () => ( [])), x, y, this.stickerArt.get);
8026
8290
  return hit ? { ...hit } : null;
8027
8291
  }
8028
8292
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -8079,8 +8343,8 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8079
8343
  const layer = this.wetLayer(layerId, "add stickers to");
8080
8344
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
8081
8345
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
8082
- const existing = _optionalChain([this, 'access', _521 => _521.doc, 'access', _522 => _522.stickers, 'optionalAccess', _523 => _523[layer.id]]);
8083
- if (!_optionalChain([existing, 'optionalAccess', _524 => _524.length])) {
8346
+ const existing = _optionalChain([this, 'access', _528 => _528.doc, 'access', _529 => _529.stickers, 'optionalAccess', _530 => _530[layer.id]]);
8347
+ if (!_optionalChain([existing, 'optionalAccess', _531 => _531.length])) {
8084
8348
  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.`);
8085
8349
  }
8086
8350
  let n = this.nextStickerNumber();
@@ -8097,7 +8361,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8097
8361
  const id = n++;
8098
8362
  return this.withStickerVariant({ id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u });
8099
8363
  });
8100
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _525 => _525.length]) ? added.map(stickerRect) : void 0);
8364
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _532 => _532.length]) ? added.map(stickerRect) : void 0);
8101
8365
  return added.map((s) => ({ ...s }));
8102
8366
  }
8103
8367
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -8136,20 +8400,20 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8136
8400
  }
8137
8401
  liveStrokeLayer(layerId, what) {
8138
8402
  const l = this.wetLayer(layerId, what);
8139
- const strokes = _optionalChain([this, 'access', _526 => _526.doc, 'access', _527 => _527.liveStrokes, 'optionalAccess', _528 => _528[l.id]]);
8403
+ const strokes = _optionalChain([this, 'access', _533 => _533.doc, 'access', _534 => _534.liveStrokes, 'optionalAccess', _535 => _535[l.id]]);
8140
8404
  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.`);
8141
8405
  return { layer: l, strokes };
8142
8406
  }
8143
8407
  /** Whether a layer is a live stroke layer. */
8144
8408
  isLiveStrokeLayer(layerId) {
8145
- return Boolean(_optionalChain([this, 'access', _529 => _529.doc, 'access', _530 => _530.liveStrokes, 'optionalAccess', _531 => _531[layerId]]));
8409
+ return Boolean(_optionalChain([this, 'access', _536 => _536.doc, 'access', _537 => _537.liveStrokes, 'optionalAccess', _538 => _538[layerId]]));
8146
8410
  }
8147
8411
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
8148
8412
  convertToLiveStrokes(layerId) {
8149
8413
  this.requireIdle("converting a layer");
8150
8414
  const l = this.paintTarget(layerId, "convert");
8151
- if (_optionalChain([this, 'access', _532 => _532.doc, 'access', _533 => _533.liveStrokes, 'optionalAccess', _534 => _534[l.id]])) return this.describeLayer(l);
8152
- if (_optionalChain([this, 'access', _535 => _535.doc, 'access', _536 => _536.stickers, 'optionalAccess', _537 => _537[l.id], 'optionalAccess', _538 => _538.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
8415
+ if (_optionalChain([this, 'access', _539 => _539.doc, 'access', _540 => _540.liveStrokes, 'optionalAccess', _541 => _541[l.id]])) return this.describeLayer(l);
8416
+ if (_optionalChain([this, 'access', _542 => _542.doc, 'access', _543 => _543.stickers, 'optionalAccess', _544 => _544[l.id], 'optionalAccess', _545 => _545.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
8153
8417
  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"}).`);
8154
8418
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
8155
8419
  return this.describeLayer(this.getLayer(l.id));
@@ -8162,7 +8426,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8162
8426
  findLiveStroke(id) {
8163
8427
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
8164
8428
  const index = strokes.findIndex((x) => x.id === id);
8165
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _539 => _539.layer]);
8429
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _546 => _546.layer]);
8166
8430
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
8167
8431
  }
8168
8432
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -8202,7 +8466,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8202
8466
  if (update.paint !== void 0) {
8203
8467
  if (update.paint === null) delete next.paint;
8204
8468
  else if (_chunkSNAFFCAXcjs.isPaintEffectPaint.call(void 0, update.paint)) {
8205
- const ep = _optionalChain([update, 'access', _540 => _540.paint, 'access', _541 => _541.map, 'optionalAccess', _542 => _542.by]) === "path" ? _chunkSNAFFCAXcjs.withStrokePath.call(void 0, update.paint, next.points, this.effectPathControls.get(update.paint.effect)) : update.paint;
8469
+ const ep = _optionalChain([update, 'access', _547 => _547.paint, 'access', _548 => _548.map, 'optionalAccess', _549 => _549.by]) === "path" ? _chunkSNAFFCAXcjs.withStrokePath.call(void 0, update.paint, next.points, this.effectPathControls.get(update.paint.effect)) : update.paint;
8206
8470
  if (!this.effectPaintImage(ep) && !this.renderEffectPaintSync(ep)) throw new PaintEditorError(`The effect "${update.paint.effect}" is not rendered yet; render it first (prepareEffectPaints; the update_stroke tool does this).`);
8207
8471
  next.paint = JSON.parse(JSON.stringify(ep));
8208
8472
  } else {
@@ -8235,7 +8499,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8235
8499
  if (edit.points !== void 0) {
8236
8500
  const points = this.checkPoints(edit.points);
8237
8501
  next = { ...was, points: points.map((p) => ({ ...p })) };
8238
- if (_optionalChain([next, 'access', _543 => _543.paint, 'optionalAccess', _544 => _544.type]) === "effect" && _optionalChain([next, 'access', _545 => _545.paint, 'access', _546 => _546.map, 'optionalAccess', _547 => _547.by]) === "path") {
8502
+ if (_optionalChain([next, 'access', _550 => _550.paint, 'optionalAccess', _551 => _551.type]) === "effect" && _optionalChain([next, 'access', _552 => _552.paint, 'access', _553 => _553.map, 'optionalAccess', _554 => _554.by]) === "path") {
8239
8503
  next.paint = _chunkSNAFFCAXcjs.withStrokePath.call(void 0, next.paint, next.points, this.effectPathControls.get(next.paint.effect));
8240
8504
  }
8241
8505
  } else {
@@ -8256,9 +8520,9 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8256
8520
  const layers = /* @__PURE__ */ new Map();
8257
8521
  for (const f of found) layers.set(f.layer.id, f.layer);
8258
8522
  for (const [layerId, layer] of layers) {
8259
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _548 => _548.liveStrokes, 'optionalAccess', _549 => _549[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
8523
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _555 => _555.liveStrokes, 'optionalAccess', _556 => _556[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
8260
8524
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
8261
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _550 => _550.liveStrokes, 'optionalAccess', _551 => _551[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
8525
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _557 => _557.liveStrokes, 'optionalAccess', _558 => _558[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
8262
8526
  }
8263
8527
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
8264
8528
  return { removed: [...ids], bounds };
@@ -8326,7 +8590,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8326
8590
  }
8327
8591
  withLiveStrokes(doc, layer, list, dirty) {
8328
8592
  if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
8329
- const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _552 => _552.layer]);
8593
+ const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _559 => _559.layer]);
8330
8594
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
8331
8595
  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] } };
8332
8596
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
@@ -8404,7 +8668,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8404
8668
  if (!this.animatedLayers.size) return this.doc.layers;
8405
8669
  let layers = this.doc.layers;
8406
8670
  for (const [id, a] of this.animatedLayers) {
8407
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _553 => _553.layer]);
8671
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _560 => _560.layer]);
8408
8672
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
8409
8673
  }
8410
8674
  return layers;
@@ -8414,7 +8678,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8414
8678
  const layers = [];
8415
8679
  const sources = /* @__PURE__ */ new Map();
8416
8680
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
8417
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _554 => _554.layer]);
8681
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _561 => _561.layer]);
8418
8682
  const live = strokes.filter(isLiveEffect);
8419
8683
  if (!isPixelLayer(layer) || !live.length) continue;
8420
8684
  layers.push({ layer, strokes });
@@ -8545,7 +8809,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8545
8809
  stencilSelection(stencils = this.guides.stencils) {
8546
8810
  const { width, height } = this.doc.canvas;
8547
8811
  const size = `${width}x${height}`;
8548
- if (_optionalChain([this, 'access', _555 => _555.stencilCache, 'optionalAccess', _556 => _556.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
8812
+ if (_optionalChain([this, 'access', _562 => _562.stencilCache, 'optionalAccess', _563 => _563.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
8549
8813
  const mask = stencilMask(stencils, width, height);
8550
8814
  this.stencilCache = { key: stencils, size, mask };
8551
8815
  return mask;
@@ -8607,7 +8871,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8607
8871
  makeSwatch(color, name) {
8608
8872
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
8609
8873
  const out = { color: _chunkNIBFKXMDcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
8610
- if (_optionalChain([name, 'optionalAccess', _557 => _557.trim, 'call', _558 => _558()])) out.name = name.trim();
8874
+ if (_optionalChain([name, 'optionalAccess', _564 => _564.trim, 'call', _565 => _565()])) out.name = name.trim();
8611
8875
  if (p.type === "gradient") out.paint = p;
8612
8876
  return out;
8613
8877
  }
@@ -8659,7 +8923,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8659
8923
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
8660
8924
  */
8661
8925
  mixOnPad(paints2, options = {}) {
8662
- const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _559 => _559.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _560 => _560.parts]) }));
8926
+ const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _566 => _566.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _567 => _567.parts]) }));
8663
8927
  let r;
8664
8928
  try {
8665
8929
  r = this.pad.mix(parsed, options);
@@ -8748,7 +9012,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
8748
9012
  }
8749
9013
  /** A layer's tile surface (live while stroking), for thumbnails. */
8750
9014
  layerSurface(id) {
8751
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _561 => _561.layer]);
9015
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _568 => _568.layer]);
8752
9016
  return isPixelLayer(l) ? l.surface : null;
8753
9017
  }
8754
9018
  }, _class14.__initStatic(), _class14);
@@ -8770,7 +9034,7 @@ function insertAfter(layers, id, node) {
8770
9034
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
8771
9035
  }
8772
9036
  function isLiveEffect(s) {
8773
- return _optionalChain([s, 'access', _562 => _562.paint, 'optionalAccess', _563 => _563.type]) === "effect" && s.paint.live === true;
9037
+ return _optionalChain([s, 'access', _569 => _569.paint, 'optionalAccess', _570 => _570.type]) === "effect" && s.paint.live === true;
8774
9038
  }
8775
9039
  function framePaint(p, t) {
8776
9040
  return { ...p, time: p.time + t };
@@ -8795,7 +9059,7 @@ function clipRect(r, width, height) {
8795
9059
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
8796
9060
  }
8797
9061
  function withLiveStroke(doc, stroke) {
8798
- const list = _optionalChain([doc, 'access', _564 => _564.liveStrokes, 'optionalAccess', _565 => _565[stroke.layerId]]);
9062
+ const list = _optionalChain([doc, 'access', _571 => _571.liveStrokes, 'optionalAccess', _572 => _572[stroke.layerId]]);
8799
9063
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
8800
9064
  }
8801
9065
  function shiftDocument(doc, dx, dy) {
@@ -8822,10 +9086,22 @@ function shiftDocument(doc, dx, dy) {
8822
9086
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
8823
9087
  if (doc.paintEvents) {
8824
9088
  out.paintEvents = doc.paintEvents.map((e) => {
8825
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _566 => _566.data, 'optionalAccess', _567 => _567.stickers]) : void 0;
9089
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _573 => _573.data, 'optionalAccess', _574 => _574.stickers]) : void 0;
8826
9090
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
8827
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _568 => _568.data, 'optionalAccess', _569 => _569.strokes]) : void 0;
8828
- return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
9091
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _575 => _575.data, 'optionalAccess', _576 => _576.strokes]) : void 0;
9092
+ if (strokes) return { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } };
9093
+ if (e.kind === "fill-region" && e.data) {
9094
+ const d = e.data;
9095
+ return {
9096
+ ...e,
9097
+ data: {
9098
+ ...e.data,
9099
+ ...typeof d.x === "number" && typeof d.y === "number" ? { x: d.x + dx, y: d.y + dy } : {},
9100
+ ...Array.isArray(d.points) ? { points: d.points.map((p) => movePoint(p, dx, dy)) } : {}
9101
+ }
9102
+ };
9103
+ }
9104
+ return e;
8829
9105
  });
8830
9106
  }
8831
9107
  if (doc.wetEvents) {
@@ -8896,7 +9172,7 @@ function clipToCanvas(rect, canvas) {
8896
9172
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
8897
9173
  }
8898
9174
  function toEffectPaintPixels(p, pixels) {
8899
- return { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data), ..._optionalChain([p, 'access', _570 => _570.map, 'optionalAccess', _571 => _571.by]) === "stroke" ? { map: p.map } : {} };
9175
+ return { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data), ..._optionalChain([p, 'access', _577 => _577.map, 'optionalAccess', _578 => _578.by]) === "stroke" ? { map: p.map } : {} };
8900
9176
  }
8901
9177
  function readWetGhost(raw) {
8902
9178
  if (!raw || typeof raw !== "object") return null;
@@ -8926,8 +9202,8 @@ function strokeSchedule(points) {
8926
9202
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
8927
9203
  }
8928
9204
  function strokeDuration(points, max = 1800) {
8929
- const t0 = _optionalChain([points, 'access', _572 => _572[0], 'optionalAccess', _573 => _573.t]);
8930
- const t1 = _optionalChain([points, 'access', _574 => _574[points.length - 1], 'optionalAccess', _575 => _575.t]);
9205
+ const t0 = _optionalChain([points, 'access', _579 => _579[0], 'optionalAccess', _580 => _580.t]);
9206
+ const t1 = _optionalChain([points, 'access', _581 => _581[points.length - 1], 'optionalAccess', _582 => _582.t]);
8931
9207
  let ms;
8932
9208
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
8933
9209
  else {
@@ -8981,7 +9257,7 @@ var PaintDirector = class {
8981
9257
  }
8982
9258
  where(id) {
8983
9259
  const a = this.presence.get(id);
8984
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _576 => _576.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _577 => _577.y]), () => ( 0)) };
9260
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _583 => _583.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _584 => _584.y]), () => ( 0)) };
8985
9261
  }
8986
9262
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
8987
9263
  async glide(id, to, ms = 380) {
@@ -9029,10 +9305,21 @@ var PaintDirector = class {
9029
9305
  }
9030
9306
  return c.fillLayer(command.fill);
9031
9307
  }
9308
+ case "fill-region": {
9309
+ await this.say(id, command.note, 500);
9310
+ const pts = _optionalChain([command, 'access', _585 => _585.fill, 'access', _586 => _586.points, 'optionalAccess', _587 => _587.length]) ? command.fill.points : command.fill.x !== void 0 && command.fill.y !== void 0 ? [{ x: command.fill.x, y: command.fill.y }] : [];
9311
+ for (const p of pts) {
9312
+ await this.glide(id, p, 240);
9313
+ this.presence.set({ id, pressed: true });
9314
+ await this.clock.wait(this.ms(90));
9315
+ this.presence.set({ id, pressed: false });
9316
+ }
9317
+ return c.fillRegion(command.fill);
9318
+ }
9032
9319
  case "replay": {
9033
9320
  await this.say(id, command.note, 500);
9034
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _578 => _578.replay, 'access', _579 => _579.strokeIds, 'optionalAccess', _580 => _580.includes, 'call', _581 => _581(s.id)]));
9035
- const first = _optionalChain([source, 'access', _582 => _582[0], 'optionalAccess', _583 => _583.points, 'access', _584 => _584[0]]);
9321
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _588 => _588.replay, 'access', _589 => _589.strokeIds, 'optionalAccess', _590 => _590.includes, 'call', _591 => _591(s.id)]));
9322
+ const first = _optionalChain([source, 'access', _592 => _592[0], 'optionalAccess', _593 => _593.points, 'access', _594 => _594[0]]);
9036
9323
  if (first) await this.glide(id, first);
9037
9324
  const result = c.replayStrokes(command.replay);
9038
9325
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -9080,7 +9367,7 @@ var PaintDirector = class {
9080
9367
  const checked = inits.map((s) => ({ ...s, points: c.checkPoints(s.points) }));
9081
9368
  const first = checked[0];
9082
9369
  const base = first.brushId ? c.getBrush(first.brushId) : c.getState().brush;
9083
- const stepLabel = _nullishCoalesce(label, () => ( `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _585 => _585.name]), () => ( "Brush"))} path stroke`));
9370
+ const stepLabel = _nullishCoalesce(label, () => ( `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _595 => _595.name]), () => ( "Brush"))} path stroke`));
9084
9371
  return c.group(stepLabel, async (within) => {
9085
9372
  let layerId = _nullishCoalesce(_nullishCoalesce(first.layerId, () => ( c.document.activeLayerId)), () => ( ""));
9086
9373
  let bounds = null;
@@ -9100,8 +9387,8 @@ var PaintDirector = class {
9100
9387
  bounds,
9101
9388
  dabs,
9102
9389
  strokeIds,
9103
- ..._optionalChain([last, 'optionalAccess', _586 => _586.mixerLoad]) ? { mixerLoad: last.mixerLoad } : {},
9104
- ..._optionalChain([last, 'optionalAccess', _587 => _587.wet]) !== void 0 ? { wet: last.wet } : {}
9390
+ ..._optionalChain([last, 'optionalAccess', _596 => _596.mixerLoad]) ? { mixerLoad: last.mixerLoad } : {},
9391
+ ..._optionalChain([last, 'optionalAccess', _597 => _597.wet]) !== void 0 ? { wet: last.wet } : {}
9105
9392
  };
9106
9393
  });
9107
9394
  }
@@ -9144,7 +9431,7 @@ function planPaintToolPlayback(tool, _args) {
9144
9431
  if (control) steps.push({ type: "target", ref: control }, { type: "press" }, { type: "release" });
9145
9432
  return steps.length ? steps : null;
9146
9433
  }
9147
- var DIRECTED = /* @__PURE__ */ new Set(["paint_stroke", "stroke_path", "fill_layer", "replay_strokes"]);
9434
+ var DIRECTED = /* @__PURE__ */ new Set(["paint_stroke", "stroke_path", "fill_layer", "fill_region", "replay_strokes"]);
9148
9435
  function withPaintPlayback(provider, options) {
9149
9436
  const plan = (tool) => {
9150
9437
  if (tool.plan || tool.playback !== void 0) return tool;
@@ -10479,6 +10766,77 @@ function createPaintEditorToolProvider(controller, options = {}) {
10479
10766
  coordinates: { out: ["bounds"] },
10480
10767
  handler: (a) => act({ kind: "fill", fill: a }, () => c.fillLayer(a))
10481
10768
  });
10769
+ add({
10770
+ name: "fill_region",
10771
+ title: "Fill a region (bucket / flats)",
10772
+ description: 'Flood-fills one or more enclosed regions on a pixel layer from a seed point (x, y) or a batch of seed points (points). Set reference to a line-art layer id from list_layers (or "all" / "composite" for all visible layers, or "layer" for the target layer itself) to drop flat colours onto a flats layer under the ink without touching the line art. closeGap (0..32 px) bridges small gaps in the line art so flats do not leak; expand (-16..16 px, e.g. 1..2 px) bleeds the fill under anti-aliased line edges so no halo shows; wet pours a watercolour wash into the region on the wet layer. One undo step. Returns layerId, bounds, pixelCount, regions, and leaked (true when the fill touched the canvas border).',
10773
+ inputSchema: {
10774
+ type: "object",
10775
+ properties: {
10776
+ x: { type: "number", description: "Seed point x in document pixels (pass x and y, or points)." },
10777
+ y: { type: "number", description: "Seed point y in document pixels (pass x and y, or points)." },
10778
+ points: {
10779
+ type: "array",
10780
+ minItems: 1,
10781
+ maxItems: 500,
10782
+ description: "Multiple seed points in document pixels, filled together as one undo step.",
10783
+ items: {
10784
+ type: "object",
10785
+ properties: {
10786
+ x: { type: "number", description: "Document x in pixels." },
10787
+ y: { type: "number", description: "Document y in pixels." }
10788
+ },
10789
+ required: ["x", "y"],
10790
+ additionalProperties: false
10791
+ }
10792
+ },
10793
+ layerId: LAYER_ID4,
10794
+ reference: {
10795
+ type: "string",
10796
+ description: 'Which pixels stop the fill: "layer" (default, the target layer itself), "all" or "composite" (all visible layers without paper), or a layer id from list_layers (e.g. an ink line-art layer above the flats layer).'
10797
+ },
10798
+ color: { ...COLOR3, description: "Fill colour #rrggbb (default the paint colour)." },
10799
+ opacity: { type: "number", minimum: 0, maximum: 1, description: "Opacity 0..1 (default 1)." },
10800
+ blend: { type: "string", enum: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal; see list_blend_modes)." },
10801
+ blendMode: { type: "string", enum: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id), description: "Alias for blend (default normal; see list_blend_modes)." },
10802
+ tolerance: { type: "number", minimum: 0, maximum: 255, description: "Colour and alpha similarity tolerance 0..255 (default 32)." },
10803
+ closeGap: { type: "number", minimum: 0, maximum: 32, description: "Close gaps in line art up to this width in pixels, 0..32 (default 0)." },
10804
+ expand: { type: "number", minimum: -16, maximum: 16, description: "Expand (> 0, bleed under lines to hide anti-aliased halos) or contract (< 0) the filled region in pixels, -16..16 (default 0)." },
10805
+ antialias: { type: "boolean", description: "Soften boundary edges (default true)." },
10806
+ grain: { type: "number", minimum: 0, maximum: 1, description: "Paper grain response 0..1 (default 0: flat)." },
10807
+ pressure: { type: "number", minimum: 0, maximum: 1, description: "With grain: how far into the valleys, 0..1 (default 0.5)." },
10808
+ wet: { type: "boolean", description: "Pour a wet watercolour wash into the region on the wet layer instead of dry pixels (default false)." }
10809
+ },
10810
+ additionalProperties: false
10811
+ },
10812
+ annotations: { title: "Fill a region (bucket / flats)", ...WRITE5 },
10813
+ coordinates: { in: ["", "points[]"], out: ["bounds", "regions[].point", "regions[].bounds"] },
10814
+ handler: (a) => act({ kind: "fill-region", fill: a }, () => c.fillRegion(a))
10815
+ });
10816
+ add({
10817
+ name: "find_unfilled_regions",
10818
+ title: "Find enclosed unfilled regions",
10819
+ description: 'Finds enclosed unfilled regions from a reference line-art layer (reference: layerId) or the visible composite ("all" / "composite", the default), closing line-art gaps up to closeGap px. When layerId is given, regions already painted on that target layer are excluded. Changes nothing. Returns regions sorted largest first, each with an interior seed point {x, y} ready for fill_region, centroid, bounds, pixelCount (area), and touchesEdge.',
10820
+ inputSchema: {
10821
+ type: "object",
10822
+ properties: {
10823
+ layerId: { type: "string", description: "Target flats layer id from list_layers; regions already painted on it are excluded (optional)." },
10824
+ reference: {
10825
+ type: "string",
10826
+ description: 'Which pixels define the line-art barriers: "all" or "composite" (default, all visible layers without paper), "layer" (the target or active layer), or a layer id from list_layers (e.g. an ink line-art layer).'
10827
+ },
10828
+ tolerance: { type: "number", minimum: 0, maximum: 255, description: "Alpha/colour threshold 0..255 above which a reference pixel counts as line art (default 32)." },
10829
+ closeGap: { type: "number", minimum: 0, maximum: 32, description: "Close small gaps in line art up to this width in pixels, 0..32 (default 0)." },
10830
+ minArea: { type: "integer", minimum: 1, maximum: 1e7, description: "Ignore regions smaller than this many pixels (default 16)." },
10831
+ includeEdge: { type: "boolean", description: "Include regions that touch the canvas border (default false: only enclosed shapes)." },
10832
+ maxRegions: { type: "integer", minimum: 1, maximum: 1e3, description: "Most regions to return, largest first (default 100)." }
10833
+ },
10834
+ additionalProperties: false
10835
+ },
10836
+ annotations: { title: "Find enclosed unfilled regions", ...READ6 },
10837
+ coordinates: { out: ["regions[].point", "regions[].centroid", "regions[].bounds"] },
10838
+ handler: (a) => c.findUnfilledRegions(a)
10839
+ });
10482
10840
  add({
10483
10841
  name: "clear_layer",
10484
10842
  title: "Clear a layer",
@@ -10509,7 +10867,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10509
10867
  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." }, ..._chunk3JKCREEUcjs.BRUSH_PATCH_PROPERTIES, unset: _chunk3JKCREEUcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
10510
10868
  annotations: { title: "Set the brush", ...SET4 },
10511
10869
  handler: async ({ id, unset, ...patch }) => {
10512
- const stamps = _optionalChain([patch, 'access', _588 => _588.tip, 'optionalAccess', _589 => _589.stamps]);
10870
+ const stamps = _optionalChain([patch, 'access', _598 => _598.tip, 'optionalAccess', _599 => _599.stamps]);
10513
10871
  if (stamps) await c.prepareStickers(stamps);
10514
10872
  const r = c.setBrushFacets(patch, id, unset);
10515
10873
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -10679,7 +11037,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10679
11037
  const { path: _path, spacing: _spacing, pressure: _pressure, speed: _speed, ...stroke } = init;
10680
11038
  return {
10681
11039
  kind: "strokes",
10682
- label: `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _590 => _590.name]), () => ( "Brush"))} path stroke`,
11040
+ label: `${_nullishCoalesce(_optionalChain([base, 'optionalAccess', _600 => _600.name]), () => ( "Brush"))} path stroke`,
10683
11041
  strokes: subpaths.map((points, i) => ({
10684
11042
  ...stroke,
10685
11043
  ...stroke.seed !== void 0 ? { seed: stroke.seed + i } : {},
@@ -10736,7 +11094,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10736
11094
  if (ids) {
10737
11095
  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.`);
10738
11096
  }
10739
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _591 => _591.document, 'access', _592 => _592.liveStrokes, 'optionalAccess', _593 => _593[s.layerId], 'optionalAccess', _594 => _594.includes, 'call', _595 => _595(s)]) === true)) };
11097
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _601 => _601.document, 'access', _602 => _602.liveStrokes, 'optionalAccess', _603 => _603[s.layerId], 'optionalAccess', _604 => _604.includes, 'call', _605 => _605(s)]) === true)) };
10740
11098
  }
10741
11099
  });
10742
11100
  add({
@@ -11046,16 +11404,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
11046
11404
  }
11047
11405
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
11048
11406
  if (!origin && !onChange) return tool;
11049
- const write = !_optionalChain([tool, 'access', _596 => _596.annotations, 'optionalAccess', _597 => _597.readOnlyHint]);
11407
+ const write = !_optionalChain([tool, 'access', _606 => _606.annotations, 'optionalAccess', _607 => _607.readOnlyHint]);
11050
11408
  const done = (result) => {
11051
- if (write) _optionalChain([onChange, 'optionalCall', _598 => _598({ tool: tool.name })]);
11052
- return origin && _optionalChain([coordinates, 'optionalAccess', _599 => _599.out]) ? fromDocument(result, coordinates.out, origin) : result;
11409
+ if (write) _optionalChain([onChange, 'optionalCall', _608 => _608({ tool: tool.name })]);
11410
+ return origin && _optionalChain([coordinates, 'optionalAccess', _609 => _609.out]) ? fromDocument(result, coordinates.out, origin) : result;
11053
11411
  };
11054
11412
  return {
11055
11413
  ...tool,
11056
11414
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
11057
11415
  handler: (args, context) => {
11058
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _600 => _600.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11416
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _610 => _610.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11059
11417
  return r instanceof Promise ? r.then(done) : done(r);
11060
11418
  }
11061
11419
  };
@@ -11072,7 +11430,7 @@ function strokeSummary(s, withPoints, live) {
11072
11430
  color: s.color,
11073
11431
  points: withPoints ? s.points : s.points.length,
11074
11432
  seed: s.seed,
11075
- copies: _nullishCoalesce(_optionalChain([s, 'access', _601 => _601.copies, 'optionalAccess', _602 => _602.length]), () => ( 0)),
11433
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _611 => _611.copies, 'optionalAccess', _612 => _612.length]), () => ( 0)),
11076
11434
  live,
11077
11435
  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) }
11078
11436
  };
@@ -11082,7 +11440,7 @@ function strokeSummary(s, withPoints, live) {
11082
11440
  function paintBrushPreviewRenderer(paper = () => _chunkSNAFFCAXcjs.DEFAULT_PAPER, options = {}) {
11083
11441
  const sources = new BrushSourceArtCache();
11084
11442
  const draw = (brush, { width, height, color }) => {
11085
- const stickers = _optionalChain([options, 'access', _603 => _603.stampArt, 'optionalCall', _604 => _604()]);
11443
+ const stickers = _optionalChain([options, 'access', _613 => _613.stampArt, 'optionalCall', _614 => _614()]);
11086
11444
  const stampArt = sources.with(_nullishCoalesce(stickers, () => ( (() => void 0))));
11087
11445
  const t = renderBrushThumbnail(_chunkGHGBIAWQcjs.resolveBrush.call(void 0, brush), { paper: paper(), width, height, color: color.toLowerCase(), stampArt });
11088
11446
  return { data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" };
@@ -11110,6 +11468,7 @@ function createPaintBrushLibraryToolProvider(controller, options = {}) {
11110
11468
  // src/paint-editor/ui.ts
11111
11469
  var PAINT_TOOLS = [
11112
11470
  { id: "brush", label: "Brush", key: "b" },
11471
+ { id: "fill", label: "Fill", key: "g" },
11113
11472
  { id: "eyedropper", label: "Eyedropper", key: "i" },
11114
11473
  { id: "sticker", label: "Stickers", key: "s" },
11115
11474
  { id: "stroke", label: "Select stroke", key: "v" },
@@ -11117,20 +11476,22 @@ var PAINT_TOOLS = [
11117
11476
  { id: "rotate", label: "Rotate view", key: "r" }
11118
11477
  ];
11119
11478
  var PaintGesture = (_class15 = class {
11120
- constructor(controller, box) {;_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);_class15.prototype.__init140.call(this);_class15.prototype.__init141.call(this);_class15.prototype.__init142.call(this);_class15.prototype.__init143.call(this);
11479
+ constructor(controller, box) {;_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);_class15.prototype.__init140.call(this);_class15.prototype.__init141.call(this);_class15.prototype.__init142.call(this);_class15.prototype.__init143.call(this);_class15.prototype.__init144.call(this);
11121
11480
  this.controller = controller;
11122
11481
  this.box = box;
11123
11482
  }
11124
11483
 
11125
11484
 
11126
11485
  __init138() {this.tool = "brush"}
11486
+ /** Options the Fill tool (`tool === 'fill'`) passes to `fillRegion` (click to fill; drag horizontally to adjust tolerance). */
11487
+ __init139() {this.fillOptions = { reference: "all", tolerance: 32, closeGap: 4, expand: 1, antialias: true }}
11127
11488
  /** The last refusal (a hidden or locked layer), for the editor to show. */
11128
- __init139() {this.error = null}
11489
+ __init140() {this.error = null}
11129
11490
  /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */
11130
- __init140() {this.predicted = []}
11131
- __init141() {this.mode = null}
11132
- __init142() {this.penAt = null}
11133
- __init143() {this.penDown = false}
11491
+ __init141() {this.predicted = []}
11492
+ __init142() {this.mode = null}
11493
+ __init143() {this.penAt = null}
11494
+ __init144() {this.penDown = false}
11134
11495
  doc(e) {
11135
11496
  const b = this.box();
11136
11497
  const s = this.controller.getState();
@@ -11166,6 +11527,7 @@ var PaintGesture = (_class15 = class {
11166
11527
  this.pick(e);
11167
11528
  return false;
11168
11529
  }
11530
+ if (tool === "fill") return this.fillDown(e);
11169
11531
  if (tool === "sticker") return this.stickerDown(e);
11170
11532
  try {
11171
11533
  const p = this.pen(e);
@@ -11186,13 +11548,13 @@ var PaintGesture = (_class15 = class {
11186
11548
  const p = this.doc(e);
11187
11549
  const s = this.controller.getState();
11188
11550
  const layerId = s.document.activeLayerId;
11189
- if (!layerId || !_optionalChain([s, 'access', _605 => _605.document, 'access', _606 => _606.liveStrokes, 'optionalAccess', _607 => _607[layerId]])) {
11551
+ if (!layerId || !_optionalChain([s, 'access', _615 => _615.document, 'access', _616 => _616.liveStrokes, 'optionalAccess', _617 => _617[layerId]])) {
11190
11552
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
11191
11553
  return false;
11192
11554
  }
11193
11555
  try {
11194
11556
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
11195
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _608 => _608.id]), () => ( null)));
11557
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _618 => _618.id]), () => ( null)));
11196
11558
  if (!hit) return false;
11197
11559
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
11198
11560
  return true;
@@ -11204,7 +11566,7 @@ var PaintGesture = (_class15 = class {
11204
11566
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
11205
11567
  get strokeDrag() {
11206
11568
  const m = this.mode;
11207
- return _optionalChain([m, 'optionalAccess', _609 => _609.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
11569
+ return _optionalChain([m, 'optionalAccess', _619 => _619.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
11208
11570
  }
11209
11571
  /**
11210
11572
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -11235,6 +11597,18 @@ var PaintGesture = (_class15 = class {
11235
11597
  if (p.x < 0 || p.y < 0 || p.x >= width || p.y >= height) return;
11236
11598
  this.controller.setColor(this.controller.pickColor(p.x, p.y).color);
11237
11599
  }
11600
+ fillDown(e) {
11601
+ const p = this.doc(e);
11602
+ const baseTolerance = _nullishCoalesce(this.fillOptions.tolerance, () => ( 32));
11603
+ try {
11604
+ const filled = this.controller.fillRegion({ ...this.fillOptions, tolerance: baseTolerance, x: p.x, y: p.y });
11605
+ this.mode = { kind: "fill", pointerId: e.pointerId, startX: e.clientX, p, baseTolerance, lastTolerance: baseTolerance, committed: filled.bounds !== null };
11606
+ return true;
11607
+ } catch (err) {
11608
+ this.error = err instanceof Error ? err.message : String(err);
11609
+ return false;
11610
+ }
11611
+ }
11238
11612
  move(e) {
11239
11613
  if (e.pointerType === "pen") this.penAt = { x: e.clientX, y: e.clientY };
11240
11614
  const m = this.mode;
@@ -11255,6 +11629,21 @@ var PaintGesture = (_class15 = class {
11255
11629
  m.to = this.doc(e);
11256
11630
  return;
11257
11631
  }
11632
+ if (m.kind === "fill") {
11633
+ const dx = e.clientX - m.startX;
11634
+ if (Math.abs(dx) < 4) return;
11635
+ const nextTol = Math.max(0, Math.min(255, Math.round(m.baseTolerance + dx * 0.5)));
11636
+ if (nextTol === m.lastTolerance) return;
11637
+ m.lastTolerance = nextTol;
11638
+ try {
11639
+ if (m.committed) this.controller.undo();
11640
+ m.committed = false;
11641
+ m.committed = this.controller.fillRegion({ ...this.fillOptions, tolerance: nextTol, x: m.p.x, y: m.p.y }).bounds !== null;
11642
+ } catch (err) {
11643
+ this.error = err instanceof Error ? err.message : String(err);
11644
+ }
11645
+ return;
11646
+ }
11258
11647
  if (m.kind === "sticker") {
11259
11648
  const p = this.doc(e);
11260
11649
  m.at = { x: round2(p.x + m.dx), y: round2(p.y + m.dy) };
@@ -11279,8 +11668,8 @@ var PaintGesture = (_class15 = class {
11279
11668
  this.mode = null;
11280
11669
  this.predicted = [];
11281
11670
  if (m.kind === "stroke") {
11282
- _optionalChain([this, 'access', _610 => _610.controller, 'access', _611 => _611.activeStroke, 'optionalAccess', _612 => _612.end, 'call', _613 => _613()]);
11283
- _optionalChain([this, 'access', _614 => _614.controller, 'access', _615 => _615.strokeRendering, 'optionalAccess', _616 => _616.catch, 'call', _617 => _617((err) => {
11671
+ _optionalChain([this, 'access', _620 => _620.controller, 'access', _621 => _621.activeStroke, 'optionalAccess', _622 => _622.end, 'call', _623 => _623()]);
11672
+ _optionalChain([this, 'access', _624 => _624.controller, 'access', _625 => _625.strokeRendering, 'optionalAccess', _626 => _626.catch, 'call', _627 => _627((err) => {
11284
11673
  this.error = err instanceof Error ? err.message : String(err);
11285
11674
  })]);
11286
11675
  }
@@ -11315,8 +11704,9 @@ var PaintGesture = (_class15 = class {
11315
11704
  cancel() {
11316
11705
  this.penDown = false;
11317
11706
  this.predicted = [];
11318
- if (_optionalChain([this, 'access', _618 => _618.mode, 'optionalAccess', _619 => _619.kind]) === "stroke") _optionalChain([this, 'access', _620 => _620.controller, 'access', _621 => _621.activeStroke, 'optionalAccess', _622 => _622.cancel, 'call', _623 => _623()]);
11319
- if (_optionalChain([this, 'access', _624 => _624.mode, 'optionalAccess', _625 => _625.kind]) === "sticker") this.controller.cancelStickerPreview();
11707
+ if (_optionalChain([this, 'access', _628 => _628.mode, 'optionalAccess', _629 => _629.kind]) === "stroke") _optionalChain([this, 'access', _630 => _630.controller, 'access', _631 => _631.activeStroke, 'optionalAccess', _632 => _632.cancel, 'call', _633 => _633()]);
11708
+ if (_optionalChain([this, 'access', _634 => _634.mode, 'optionalAccess', _635 => _635.kind]) === "fill" && this.mode.committed) this.controller.undo();
11709
+ if (_optionalChain([this, 'access', _636 => _636.mode, 'optionalAccess', _637 => _637.kind]) === "sticker") this.controller.cancelStickerPreview();
11320
11710
  this.mode = null;
11321
11711
  }
11322
11712
  get active() {
@@ -11381,13 +11771,13 @@ function handlePaintShortcut(controller, gesture, e) {
11381
11771
  return true;
11382
11772
  }
11383
11773
  var PaintCanvasPresenter = (_class16 = class {
11384
- constructor(controller) {;_class16.prototype.__init144.call(this);_class16.prototype.__init145.call(this);_class16.prototype.__init146.call(this);
11774
+ constructor(controller) {;_class16.prototype.__init145.call(this);_class16.prototype.__init146.call(this);_class16.prototype.__init147.call(this);
11385
11775
  this.controller = controller;
11386
11776
  }
11387
11777
 
11388
- __init144() {this.uploaded = /* @__PURE__ */ new Map()}
11389
- __init145() {this.scratch = null}
11390
- __init146() {this.size = ""}
11778
+ __init145() {this.uploaded = /* @__PURE__ */ new Map()}
11779
+ __init146() {this.scratch = null}
11780
+ __init147() {this.size = ""}
11391
11781
  /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
11392
11782
  render(ctx) {
11393
11783
  const { width, height } = this.controller.document.canvas;
@@ -11419,7 +11809,7 @@ function guideOverlay(controller, drag) {
11419
11809
  const size = s.document.canvas;
11420
11810
  const out = [];
11421
11811
  const layerId = s.document.activeLayerId;
11422
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _626 => _626.document, 'access', _627 => _627.liveStrokes, 'optionalAccess', _628 => _628[layerId], 'optionalAccess', _629 => _629.some, 'call', _630 => _630((x) => x.id === s.selectedStroke)]) : false;
11812
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _638 => _638.document, 'access', _639 => _639.liveStrokes, 'optionalAccess', _640 => _640[layerId], 'optionalAccess', _641 => _641.some, 'call', _642 => _642((x) => x.id === s.selectedStroke)]) : false;
11423
11813
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
11424
11814
  if (area) {
11425
11815
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -11432,7 +11822,7 @@ function guideOverlay(controller, drag) {
11432
11822
  ];
11433
11823
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
11434
11824
  }
11435
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _631 => _631.document, 'access', _632 => _632.stickers, 'optionalAccess', _633 => _633[layerId], 'optionalAccess', _634 => _634.find, 'call', _635 => _635((x) => x.id === s.selectedSticker)]) : void 0;
11825
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _643 => _643.document, 'access', _644 => _644.stickers, 'optionalAccess', _645 => _645[layerId], 'optionalAccess', _646 => _646.find, 'call', _647 => _647((x) => x.id === s.selectedSticker)]) : void 0;
11436
11826
  if (picked) {
11437
11827
  const r = picked.size / 2 + 2;
11438
11828
  const a = picked.rotation * Math.PI / 180;
@@ -11462,7 +11852,7 @@ var PAPER_SLIDERS = [
11462
11852
  ];
11463
11853
  function readPath(obj, path) {
11464
11854
  let v = obj;
11465
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _636 => _636[k]]);
11855
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _648 => _648[k]]);
11466
11856
  return typeof v === "number" ? v : 0;
11467
11857
  }
11468
11858
  function patchPath(obj, path, value) {
@@ -11578,7 +11968,7 @@ function startWetClock(controller, frame, cancel) {
11578
11968
  id = raf(loop);
11579
11969
  return () => {
11580
11970
  stopped = true;
11581
- _optionalChain([caf, 'optionalCall', _637 => _637(id)]);
11971
+ _optionalChain([caf, 'optionalCall', _649 => _649(id)]);
11582
11972
  };
11583
11973
  }
11584
11974
  function drawWaterOverlay(controller, ctx) {
@@ -11936,7 +12326,7 @@ function createPaintChangeFeed(controller, options = {}) {
11936
12326
  const doc = state.document;
11937
12327
  const layers = /* @__PURE__ */ new Map();
11938
12328
  for (const l of controller.listLayers()) layers.set(l.id, { name: l.name, visible: l.visible, opacity: l.opacity, blend: l.blend });
11939
- return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _638 => _638.paintEvents, 'optionalAccess', _639 => _639.length]), () => ( 0)), layers, stroking: state.stroking };
12329
+ return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _650 => _650.paintEvents, 'optionalAccess', _651 => _651.length]), () => ( 0)), layers, stroking: state.stroking };
11940
12330
  };
11941
12331
  let last = take();
11942
12332
  const check = () => {
@@ -11967,7 +12357,7 @@ function createPaintChangeFeed(controller, options = {}) {
11967
12357
  if (edited) pending = void 0;
11968
12358
  const change = {
11969
12359
  seq: ++seq,
11970
- origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _640 => _640.origin]), () => ( "user")),
12360
+ origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _652 => _652.origin]), () => ( "user")),
11971
12361
  ...commit ? { commit } : {},
11972
12362
  addedStrokes,
11973
12363
  removedStrokes,
@@ -12034,7 +12424,7 @@ function createPaintProposals(options) {
12034
12424
  };
12035
12425
  const strokeIds = () => new Set(controller.getStrokes().map((s) => s.id));
12036
12426
  const validate = (input) => {
12037
- if (!_optionalChain([input, 'access', _641 => _641.title, 'optionalAccess', _642 => _642.trim, 'call', _643 => _643()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
12427
+ if (!_optionalChain([input, 'access', _653 => _653.title, 'optionalAccess', _654 => _654.trim, 'call', _655 => _655()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
12038
12428
  if (!Array.isArray(input.ops) || !input.ops.length) throw new PaintEditorError("A proposal needs at least one op (stroke, wash or echo).");
12039
12429
  const place = _nullishCoalesce(input.place, () => ( "top"));
12040
12430
  if (place === "above") {
@@ -12046,7 +12436,7 @@ function createPaintProposals(options) {
12046
12436
  input.ops.forEach((op, i) => {
12047
12437
  const at = `ops[${i}]`;
12048
12438
  if (op.kind === "stroke") {
12049
- if (!_optionalChain([op, 'access', _644 => _644.points, 'optionalAccess', _645 => _645.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12439
+ if (!_optionalChain([op, 'access', _656 => _656.points, 'optionalAccess', _657 => _657.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12050
12440
  points += op.points.length;
12051
12441
  if (op.color !== void 0 && !HEX3.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
12052
12442
  const brush = op.brushId ? controller.getBrush(op.brushId) : controller.getState().brush;
@@ -12058,7 +12448,7 @@ function createPaintProposals(options) {
12058
12448
  if (!HEX3.test(_nullishCoalesce(op.color, () => ( "")))) throw new PaintEditorError(`${at}: a wash needs color as #rrggbb.`);
12059
12449
  if (op.opacity !== void 0 && !(op.opacity > 0 && op.opacity <= 1)) throw new PaintEditorError(`${at}: opacity must be in (0, 1].`);
12060
12450
  } else if (op.kind === "echo") {
12061
- if (!_optionalChain([op, 'access', _646 => _646.strokeIds, 'optionalAccess', _647 => _647.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12451
+ if (!_optionalChain([op, 'access', _658 => _658.strokeIds, 'optionalAccess', _659 => _659.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12062
12452
  const unknown = op.strokeIds.filter((id) => !known.has(id));
12063
12453
  if (unknown.length) throw new PaintEditorError(`${at}: unknown stroke ${unknown.map((u) => `"${u}"`).join(", ")}. Call list_strokes for the ids.`);
12064
12454
  if (op.color !== void 0 && !HEX3.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
@@ -12107,7 +12497,7 @@ function createPaintProposals(options) {
12107
12497
  ...input.layerId ? { layerId: input.layerId } : {},
12108
12498
  ...input.layerName ? { layerName: input.layerName } : {}
12109
12499
  });
12110
- const topLayerId = () => _optionalChain([controller, 'access', _648 => _648.listLayers, 'call', _649 => _649(), 'access', _650 => _650.find, 'call', _651 => _651((l) => l.parentId === null), 'optionalAccess', _652 => _652.id]);
12500
+ const topLayerId = () => _optionalChain([controller, 'access', _660 => _660.listLayers, 'call', _661 => _661(), 'access', _662 => _662.find, 'call', _663 => _663((l) => l.parentId === null), 'optionalAccess', _664 => _664.id]);
12111
12501
  return {
12112
12502
  getState: () => state,
12113
12503
  subscribe(listener) {
@@ -12294,7 +12684,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
12294
12684
  },
12295
12685
  annotations: { title: "Propose paint", ...WRITE6 },
12296
12686
  handler: (args, context) => {
12297
- const origin = _optionalChain([context, 'access', _653 => _653.actor, 'optionalAccess', _654 => _654.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
12687
+ const origin = _optionalChain([context, 'access', _665 => _665.actor, 'optionalAccess', _666 => _666.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
12298
12688
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
12299
12689
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
12300
12690
  return { proposalId: proposal.id, ...rest };
@@ -12856,4 +13246,7 @@ function createPaintConformanceHost(setup, options) {
12856
13246
 
12857
13247
 
12858
13248
 
12859
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkGHGBIAWQcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkGHGBIAWQcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunk3JKCREEUcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkGHGBIAWQcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.BrushSourceArtCache = BrushSourceArtCache; exports.DAB_FLIPS = _chunkGHGBIAWQcjs.DAB_FLIPS; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkGHGBIAWQcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkGHGBIAWQcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkGHGBIAWQcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkGHGBIAWQcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkN5IMDAHMcjs.DEFAULT_FLOW; exports.DEFAULT_GHOST = _chunkGHGBIAWQcjs.DEFAULT_GHOST; exports.DEFAULT_IMPASTO = _chunkGHGBIAWQcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkGHGBIAWQcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkGHGBIAWQcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkSNAFFCAXcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkGHGBIAWQcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkGHGBIAWQcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkGHGBIAWQcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_TIP_GRAIN = _chunkGHGBIAWQcjs.DEFAULT_TIP_GRAIN; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkGHGBIAWQcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkN5IMDAHMcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkGHGBIAWQcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkGHGBIAWQcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkSNAFFCAXcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkSNAFFCAXcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkSNAFFCAXcjs.EFFECT_STRIP_HEIGHT; exports.GHOST_SLIDERS = _chunk3JKCREEUcjs.GHOST_SLIDERS; exports.GPU_LEAD = _chunkSNAFFCAXcjs.GPU_LEAD; exports.GRAIN_PATTERNS = _chunkNIBFKXMDcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkNIBFKXMDcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkSNAFFCAXcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkGHGBIAWQcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkNIBFKXMDcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkGHGBIAWQcjs.MAX_DOT_TEXTURES; exports.MAX_EFFECT_PATH_POINTS = _chunkSNAFFCAXcjs.MAX_EFFECT_PATH_POINTS; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkGHGBIAWQcjs.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 = _chunkGHGBIAWQcjs.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 = _chunkGHGBIAWQcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkGHGBIAWQcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkNIBFKXMDcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkNIBFKXMDcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkNIBFKXMDcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkSNAFFCAXcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkSNAFFCAXcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkGHGBIAWQcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkGHGBIAWQcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = _chunkSNAFFCAXcjs.PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkNIBFKXMDcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkNIBFKXMDcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = _chunkSNAFFCAXcjs.PaintWetLayers; exports.PaperGrain = _chunkNIBFKXMDcjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = _chunkSNAFFCAXcjs.PenDabWalker; exports.PenSmoother = _chunkSNAFFCAXcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkGHGBIAWQcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkRDFHWAHLcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunk3VHH6V67cjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TIP_GRAIN_MODES = _chunkGHGBIAWQcjs.TIP_GRAIN_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.TipGrain = _chunkSNAFFCAXcjs.TipGrain; exports.WET_FLOW_KINDS = _chunkN5IMDAHMcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = _chunkSNAFFCAXcjs.WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkGHGBIAWQcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = _chunkSNAFFCAXcjs.WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkN5IMDAHMcjs.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 = _chunkGHGBIAWQcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = _chunkSNAFFCAXcjs.WetStrokeDriver; exports.addPaintGradientStop = _chunkNIBFKXMDcjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunk3JKCREEUcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkGHGBIAWQcjs.brushTakesPaint; exports.brushToJSON = _chunkGHGBIAWQcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkSNAFFCAXcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintConformanceHost = createPaintConformanceHost; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunkSNAFFCAXcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkSNAFFCAXcjs.effectPaintKey; exports.effectPaintSize = _chunkSNAFFCAXcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.engineBrushSourceIds = engineBrushSourceIds; exports.fitZoom = fitZoom; exports.grainCatch = _chunkNIBFKXMDcjs.grainCatch; exports.grainHeights = _chunkNIBFKXMDcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkNIBFKXMDcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkSNAFFCAXcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.inferEffectPathControl = _chunkSNAFFCAXcjs.inferEffectPathControl; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkNIBFKXMDcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkSNAFFCAXcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkGHGBIAWQcjs.isWetBrush; exports.isWetCapable = _chunkGHGBIAWQcjs.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 = _chunkSNAFFCAXcjs.mixerTip; exports.multiColorForDab = _chunkSNAFFCAXcjs.multiColorForDab; exports.multiColorGradient = _chunkSNAFFCAXcjs.multiColorGradient; exports.multiColorPalette = _chunkSNAFFCAXcjs.multiColorPalette; exports.multiColorSliders = _chunk3JKCREEUcjs.multiColorSliders; exports.multiColorToPaint = _chunkGHGBIAWQcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkGHGBIAWQcjs.normalizeBehavior; exports.normalizeBristle = _chunkGHGBIAWQcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkGHGBIAWQcjs.normalizeDynamics; exports.normalizeFlow = _chunkN5IMDAHMcjs.normalizeFlow; exports.normalizeGhost = _chunkGHGBIAWQcjs.normalizeGhost; exports.normalizeHexColor = _chunkNIBFKXMDcjs.normalizeHexColor; exports.normalizeImpasto = _chunkGHGBIAWQcjs.normalizeImpasto; exports.normalizeLight = _chunkGHGBIAWQcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkGHGBIAWQcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkGHGBIAWQcjs.normalizePaintBrush; exports.normalizePaper = _chunkSNAFFCAXcjs.normalizePaper; exports.normalizeParticle = _chunkGHGBIAWQcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkGHGBIAWQcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkGHGBIAWQcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkN5IMDAHMcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintBrushPreviewRenderer = paintBrushPreviewRenderer; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkNIBFKXMDcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkNIBFKXMDcjs.paintSourceColor; exports.paintSourceCss = _chunkNIBFKXMDcjs.paintSourceCss; exports.paintToMultiColor = _chunkGHGBIAWQcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkSNAFFCAXcjs.paperPreset; exports.parseBrushLibrary = _chunkGHGBIAWQcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkNIBFKXMDcjs.parsePaintSource; exports.patchBrushValue = _chunk3JKCREEUcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkSNAFFCAXcjs.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 = _chunkSNAFFCAXcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkSNAFFCAXcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkNIBFKXMDcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkNIBFKXMDcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkSNAFFCAXcjs.renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkNIBFKXMDcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkNIBFKXMDcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = _chunkSNAFFCAXcjs.sampleEffectAt; exports.sampleEffectField = _chunkSNAFFCAXcjs.sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkNIBFKXMDcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkNIBFKXMDcjs.solidPaint; exports.stampCoverage = _chunkRDFHWAHLcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokePathPoints = _chunkSNAFFCAXcjs.strokePathPoints; 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 = _chunkSNAFFCAXcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkSNAFFCAXcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkNIBFKXMDcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkGHGBIAWQcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = _chunkSNAFFCAXcjs.wetPaperInput; exports.wetPigmentOf = _chunkSNAFFCAXcjs.wetPigmentOf; exports.wetSupport = _chunkN5IMDAHMcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback; exports.withStrokePath = _chunkSNAFFCAXcjs.withStrokePath;
13249
+
13250
+
13251
+
13252
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkGHGBIAWQcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkGHGBIAWQcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunk3JKCREEUcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkGHGBIAWQcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.BrushSourceArtCache = BrushSourceArtCache; exports.DAB_FLIPS = _chunkGHGBIAWQcjs.DAB_FLIPS; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkGHGBIAWQcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkGHGBIAWQcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkGHGBIAWQcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkGHGBIAWQcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkN5IMDAHMcjs.DEFAULT_FLOW; exports.DEFAULT_GHOST = _chunkGHGBIAWQcjs.DEFAULT_GHOST; exports.DEFAULT_IMPASTO = _chunkGHGBIAWQcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkGHGBIAWQcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkGHGBIAWQcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkNIBFKXMDcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkSNAFFCAXcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkGHGBIAWQcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkGHGBIAWQcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkGHGBIAWQcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_TIP_GRAIN = _chunkGHGBIAWQcjs.DEFAULT_TIP_GRAIN; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkGHGBIAWQcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkN5IMDAHMcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkGHGBIAWQcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkGHGBIAWQcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkSNAFFCAXcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkSNAFFCAXcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkSNAFFCAXcjs.EFFECT_STRIP_HEIGHT; exports.GHOST_SLIDERS = _chunk3JKCREEUcjs.GHOST_SLIDERS; exports.GPU_LEAD = _chunkSNAFFCAXcjs.GPU_LEAD; exports.GRAIN_PATTERNS = _chunkNIBFKXMDcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkNIBFKXMDcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkSNAFFCAXcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkGHGBIAWQcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkNIBFKXMDcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkGHGBIAWQcjs.MAX_DOT_TEXTURES; exports.MAX_EFFECT_PATH_POINTS = _chunkSNAFFCAXcjs.MAX_EFFECT_PATH_POINTS; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkGHGBIAWQcjs.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 = _chunkGHGBIAWQcjs.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 = _chunkGHGBIAWQcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkGHGBIAWQcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkNIBFKXMDcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkNIBFKXMDcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkNIBFKXMDcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkNIBFKXMDcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkNIBFKXMDcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkSNAFFCAXcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkSNAFFCAXcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkGHGBIAWQcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkGHGBIAWQcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = _chunkSNAFFCAXcjs.PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkNIBFKXMDcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkNIBFKXMDcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = _chunkSNAFFCAXcjs.PaintWetLayers; exports.PaperGrain = _chunkNIBFKXMDcjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = _chunkSNAFFCAXcjs.PenDabWalker; exports.PenSmoother = _chunkSNAFFCAXcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkGHGBIAWQcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkRDFHWAHLcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunk3VHH6V67cjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TIP_GRAIN_MODES = _chunkGHGBIAWQcjs.TIP_GRAIN_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.TipGrain = _chunkSNAFFCAXcjs.TipGrain; exports.WET_FLOW_KINDS = _chunkN5IMDAHMcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = _chunkSNAFFCAXcjs.WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkGHGBIAWQcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = _chunkSNAFFCAXcjs.WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkN5IMDAHMcjs.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 = _chunkGHGBIAWQcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = _chunkSNAFFCAXcjs.WetStrokeDriver; exports.addPaintGradientStop = _chunkNIBFKXMDcjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunk3JKCREEUcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkGHGBIAWQcjs.brushTakesPaint; exports.brushToJSON = _chunkGHGBIAWQcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkSNAFFCAXcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintConformanceHost = createPaintConformanceHost; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunkSNAFFCAXcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkSNAFFCAXcjs.effectPaintKey; exports.effectPaintSize = _chunkSNAFFCAXcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.engineBrushSourceIds = engineBrushSourceIds; exports.fillRegionMask = _chunkYH6SKC7Pcjs.fillRegionMask; exports.findUnfilledRegionsMask = _chunkYH6SKC7Pcjs.findUnfilledRegionsMask; exports.fitZoom = fitZoom; exports.grainCatch = _chunkNIBFKXMDcjs.grainCatch; exports.grainHeights = _chunkNIBFKXMDcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkNIBFKXMDcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkSNAFFCAXcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.inferEffectPathControl = _chunkSNAFFCAXcjs.inferEffectPathControl; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkNIBFKXMDcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkSNAFFCAXcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkGHGBIAWQcjs.isWetBrush; exports.isWetCapable = _chunkGHGBIAWQcjs.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 = _chunkSNAFFCAXcjs.mixerTip; exports.multiColorForDab = _chunkSNAFFCAXcjs.multiColorForDab; exports.multiColorGradient = _chunkSNAFFCAXcjs.multiColorGradient; exports.multiColorPalette = _chunkSNAFFCAXcjs.multiColorPalette; exports.multiColorSliders = _chunk3JKCREEUcjs.multiColorSliders; exports.multiColorToPaint = _chunkGHGBIAWQcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkGHGBIAWQcjs.normalizeBehavior; exports.normalizeBristle = _chunkGHGBIAWQcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkGHGBIAWQcjs.normalizeDynamics; exports.normalizeFlow = _chunkN5IMDAHMcjs.normalizeFlow; exports.normalizeGhost = _chunkGHGBIAWQcjs.normalizeGhost; exports.normalizeHexColor = _chunkNIBFKXMDcjs.normalizeHexColor; exports.normalizeImpasto = _chunkGHGBIAWQcjs.normalizeImpasto; exports.normalizeLight = _chunkGHGBIAWQcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkGHGBIAWQcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkGHGBIAWQcjs.normalizePaintBrush; exports.normalizePaper = _chunkSNAFFCAXcjs.normalizePaper; exports.normalizeParticle = _chunkGHGBIAWQcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkGHGBIAWQcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkGHGBIAWQcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkN5IMDAHMcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintBrushPreviewRenderer = paintBrushPreviewRenderer; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkNIBFKXMDcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkNIBFKXMDcjs.paintSourceColor; exports.paintSourceCss = _chunkNIBFKXMDcjs.paintSourceCss; exports.paintToMultiColor = _chunkGHGBIAWQcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkSNAFFCAXcjs.paperPreset; exports.parseBrushLibrary = _chunkGHGBIAWQcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkNIBFKXMDcjs.parsePaintSource; exports.patchBrushValue = _chunk3JKCREEUcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkSNAFFCAXcjs.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 = _chunkSNAFFCAXcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkSNAFFCAXcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkNIBFKXMDcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkNIBFKXMDcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkSNAFFCAXcjs.renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkNIBFKXMDcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkNIBFKXMDcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = _chunkSNAFFCAXcjs.sampleEffectAt; exports.sampleEffectField = _chunkSNAFFCAXcjs.sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkNIBFKXMDcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkNIBFKXMDcjs.solidPaint; exports.squaredDistanceTransform = _chunkYH6SKC7Pcjs.squaredDistanceTransform; exports.stampCoverage = _chunkRDFHWAHLcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokePathPoints = _chunkSNAFFCAXcjs.strokePathPoints; 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 = _chunkSNAFFCAXcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkSNAFFCAXcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkNIBFKXMDcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkGHGBIAWQcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = _chunkSNAFFCAXcjs.wetPaperInput; exports.wetPigmentOf = _chunkSNAFFCAXcjs.wetPigmentOf; exports.wetSupport = _chunkN5IMDAHMcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback; exports.withStrokePath = _chunkSNAFFCAXcjs.withStrokePath;