@pixerate/editor 0.260.0 → 0.261.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -150,7 +150,11 @@ var _chunkTZOX7KWVcjs = require('../chunk-TZOX7KWV.cjs');
150
150
 
151
151
  var _chunkJSDND7DFcjs = require('../chunk-JSDND7DF.cjs');
152
152
  require('../chunk-CVFAAZXE.cjs');
153
- require('../chunk-GF2RBSDM.cjs');
153
+
154
+
155
+
156
+
157
+ var _chunkGF2RBSDMcjs = require('../chunk-GF2RBSDM.cjs');
154
158
  require('../chunk-NM3G4VQT.cjs');
155
159
 
156
160
 
@@ -5221,6 +5225,55 @@ function engineChanges(base, next) {
5221
5225
  return rest;
5222
5226
  }
5223
5227
 
5228
+ // src/paint-editor/path-samples.ts
5229
+ var FLATTEN_TOLERANCE = 0.1;
5230
+ var MAX_PATH_SAMPLES = 2e4;
5231
+ function profileAt(profile, t) {
5232
+ if (profile.length === 1) return profile[0];
5233
+ const at = t * (profile.length - 1);
5234
+ const i = Math.min(profile.length - 2, Math.floor(at));
5235
+ return profile[i] + (profile[i + 1] - profile[i]) * (at - i);
5236
+ }
5237
+ function samplePath(d, options = {}) {
5238
+ const spacing = _nullishCoalesce(options.spacing, () => ( 2));
5239
+ if (!(spacing >= 0.25 && spacing <= 100)) throw new Error(`spacing ${spacing} is out of range; use 0.25..100 document pixels.`);
5240
+ const profile = options.pressure;
5241
+ if (profile && (!profile.length || profile.some((p) => !(p >= 0 && p <= 1)))) throw new Error("pressure needs one or more values from 0 to 1, e.g. [0.2, 1, 0.2] for a taper.");
5242
+ let contours;
5243
+ try {
5244
+ contours = _chunkGF2RBSDMcjs.pathToContours.call(void 0, d);
5245
+ } catch (e) {
5246
+ throw new Error(`path is not SVG path data (${e instanceof Error ? e.message : String(e)}); give e.g. "M 10 10 C 40 0 80 60 120 30".`);
5247
+ }
5248
+ const out = [];
5249
+ for (const contour of contours) {
5250
+ if (!contour.segments.length) continue;
5251
+ const line = _chunkGF2RBSDMcjs.flattenChain.call(void 0, contour.segments, FLATTEN_TOLERANCE);
5252
+ if (contour.closed && line.length) line.push(line[0]);
5253
+ const lengths = [0];
5254
+ for (let i = 1; i < line.length; i++) lengths.push(lengths[i - 1] + Math.hypot(line[i][0] - line[i - 1][0], line[i][1] - line[i - 1][1]));
5255
+ const total = lengths[lengths.length - 1];
5256
+ const n = Math.max(1, Math.ceil(total / spacing));
5257
+ if (n + 1 > MAX_PATH_SAMPLES) throw new Error(`The path is ${Math.round(total)} px long: too many samples at spacing ${spacing}; use a larger spacing (at least ${Math.ceil(total / (MAX_PATH_SAMPLES - 1))}).`);
5258
+ const points = [];
5259
+ let j = 0;
5260
+ for (let k = 0; k <= n; k++) {
5261
+ const at = total * k / n;
5262
+ while (j < line.length - 2 && lengths[j + 1] < at) j++;
5263
+ const span = lengths[j + 1] - lengths[j] || 1;
5264
+ const f = line.length > 1 ? Math.min(1, Math.max(0, (at - lengths[j]) / span)) : 0;
5265
+ const a = line[j];
5266
+ const b = line[Math.min(j + 1, line.length - 1)];
5267
+ const x = Math.round((a[0] + (b[0] - a[0]) * f) * 1e3) / 1e3;
5268
+ const y = Math.round((a[1] + (b[1] - a[1]) * f) * 1e3) / 1e3;
5269
+ points.push(profile ? { x, y, pressure: Math.round(profileAt(profile, k / n) * 1e3) / 1e3 } : { x, y });
5270
+ }
5271
+ out.push(points);
5272
+ }
5273
+ if (!out.length) throw new Error('path has no segments to brush; give SVG path data such as "M 10 10 L 200 80".');
5274
+ return out;
5275
+ }
5276
+
5224
5277
  // src/paint-editor/live-strokes.ts
5225
5278
  var LIVE_STROKE_ENGINES = ["dab", "particle", "bristle", "mixer"];
5226
5279
  function liveStrokeRefusal(brush) {
@@ -7857,6 +7910,47 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7857
7910
  else this.emit([]);
7858
7911
  return result;
7859
7912
  }
7913
+ /**
7914
+ * Brushes vector path data (SVG `d`, document pixels) with the active brush, or `brushId` /
7915
+ * `brush`, as if drawn by hand: one recorded stroke per subpath, sampled every `spacing` px
7916
+ * with an optional `pressure` profile along each. All of it is one undo step. A given `seed`
7917
+ * seeds the first subpath; the next ones take the following seeds.
7918
+ */
7919
+ strokePath(init) {
7920
+ this.requireIdle("painting");
7921
+ if (typeof init.path !== "string" || !init.path.trim()) throw new PaintEditorError('path is empty; give SVG path data in document pixels, e.g. "M 10 10 C 40 0 80 60 120 30".');
7922
+ let subpaths;
7923
+ try {
7924
+ subpaths = samplePath(init.path, init);
7925
+ } catch (e) {
7926
+ throw new PaintEditorError(e instanceof Error ? e.message : String(e));
7927
+ }
7928
+ const { path: _path, spacing: _spacing, pressure: _pressure, ...stroke } = init;
7929
+ const before = this.doc;
7930
+ let doc = this.doc;
7931
+ let bounds = null;
7932
+ let dabs = 0;
7933
+ const strokeIds = [];
7934
+ let last = null;
7935
+ try {
7936
+ subpaths.forEach((points, i) => {
7937
+ last = this.runStroke(doc, { ...stroke, ...stroke.seed !== void 0 ? { seed: stroke.seed + i } : {}, start: points[0] }, points);
7938
+ doc = last.doc;
7939
+ bounds = unionRect(bounds, last.result.bounds);
7940
+ dabs += last.result.dabs;
7941
+ if (last.result.strokeId) strokeIds.push(last.result.strokeId);
7942
+ });
7943
+ } catch (e) {
7944
+ this.wetOp = null;
7945
+ throw e;
7946
+ }
7947
+ const run = last;
7948
+ if (_optionalChain([run, 'optionalAccess', _429 => _429.result, 'access', _430 => _430.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
7949
+ if (doc !== before || this.wetOp) this.commit(`${_nullishCoalesce(_optionalChain([run, 'optionalAccess', _431 => _431.brush, 'access', _432 => _432.name]), () => ( "Brush"))} path stroke`, this.withWetEvents(doc), before);
7950
+ else this.emit([]);
7951
+ const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _433 => _433.result, 'access', _434 => _434.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
7952
+ return { layerId, bounds, dabs, strokeIds, ..._optionalChain([run, 'optionalAccess', _435 => _435.result, 'access', _436 => _436.mixerLoad]) ? { mixerLoad: run.result.mixerLoad } : {}, ..._optionalChain([run, 'optionalAccess', _437 => _437.result, 'access', _438 => _438.wet]) !== void 0 ? { wet: run.result.wet } : {} };
7953
+ }
7860
7954
  /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
7861
7955
  checkPoints(points) {
7862
7956
  if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
@@ -7878,7 +7972,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7878
7972
  */
7879
7973
  replayStrokes(options) {
7880
7974
  this.requireIdle("replaying");
7881
- if (!_optionalChain([options, 'access', _429 => _429.strokeIds, 'optionalAccess', _430 => _430.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7975
+ if (!_optionalChain([options, 'access', _439 => _439.strokeIds, 'optionalAccess', _440 => _440.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7882
7976
  const strokes = options.strokeIds.map((id) => {
7883
7977
  const s = this.doc.strokes.find((x) => x.id === id);
7884
7978
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -7892,7 +7986,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7892
7986
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
7893
7987
  if (options.color === void 0) {
7894
7988
  for (const s of strokes) {
7895
- if (_optionalChain([s, 'access', _431 => _431.paint, 'optionalAccess', _432 => _432.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7989
+ if (_optionalChain([s, 'access', _441 => _441.paint, 'optionalAccess', _442 => _442.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7896
7990
  throw new PaintEditorError(`Stroke "${s.id}" paints with the effect "${s.paint.effect}"${s.paint.provider ? ` from provider "${s.paint.provider}"` : ""}, which is not rendered in this editor; render it first (prepareStrokeEffects; the replay_strokes tool does this) or recolour the replay with color.`);
7897
7991
  }
7898
7992
  }
@@ -7950,7 +8044,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7950
8044
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
7951
8045
  lightOf(layerId) {
7952
8046
  const l = this.wetLayer(layerId, "read the light of");
7953
- const info = lightInfo(_optionalChain([this, 'access', _433 => _433.doc, 'access', _434 => _434.light, 'optionalAccess', _435 => _435[l.id]]));
8047
+ const info = lightInfo(_optionalChain([this, 'access', _443 => _443.doc, 'access', _444 => _444.light, 'optionalAccess', _445 => _445[l.id]]));
7954
8048
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
7955
8049
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
7956
8050
  }
@@ -8001,7 +8095,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8001
8095
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8002
8096
  if (!id) return null;
8003
8097
  this.requireLayer(id);
8004
- const ch = _optionalChain([this, 'access', _436 => _436.doc, 'access', _437 => _437.thick, 'optionalAccess', _438 => _438[id]]);
8098
+ const ch = _optionalChain([this, 'access', _446 => _446.doc, 'access', _447 => _447.thick, 'optionalAccess', _448 => _448[id]]);
8005
8099
  if (!ch) return null;
8006
8100
  const r = reliefInfo(ch);
8007
8101
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -8111,7 +8205,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8111
8205
  wetState() {
8112
8206
  const st = this.getState().wet;
8113
8207
  const backend = this.wet.backend();
8114
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _439 => _439.message]), () => ( _chunkYHDHFJUCcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
8208
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _449 => _449.message]), () => ( _chunkYHDHFJUCcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
8115
8209
  }
8116
8210
  /**
8117
8211
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -8196,7 +8290,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8196
8290
  }
8197
8291
  /** Records a settings change as a wet event (not an undo step). */
8198
8292
  recordWetSetting(e) {
8199
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _440 => _440.wet, 'access', _441 => _441.world, 'optionalAccess', _442 => _442.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
8293
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _450 => _450.wet, 'access', _451 => _451.world, 'optionalAccess', _452 => _452.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
8200
8294
  }
8201
8295
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
8202
8296
  setWetParams(layerId, update) {
@@ -8265,7 +8359,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8265
8359
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkPVJMTLPJcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
8266
8360
  const live = this.live;
8267
8361
  if (!live) return this.animatedView();
8268
- if (_optionalChain([this, 'access', _443 => _443.liveLayers, 'optionalAccess', _444 => _444.key]) === live.surface) return this.liveLayers.layers;
8362
+ if (_optionalChain([this, 'access', _453 => _453.liveLayers, 'optionalAccess', _454 => _454.key]) === live.surface) return this.liveLayers.layers;
8269
8363
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
8270
8364
  this.liveLayers = { key: live.surface, layers };
8271
8365
  return layers;
@@ -8288,7 +8382,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8288
8382
  tracingNode(t) {
8289
8383
  const { width, height } = this.doc.canvas;
8290
8384
  const key = this.tracingVersion * 100003 + width * 7 + height;
8291
- if (_optionalChain([this, 'access', _445 => _445.tracingCache, 'optionalAccess', _446 => _446.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8385
+ if (_optionalChain([this, 'access', _455 => _455.tracingCache, 'optionalAccess', _456 => _456.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8292
8386
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
8293
8387
  const image = resampleInto(src, t.rect, width, height);
8294
8388
  const node = { type: "image", id: TRACING_NODE_ID, name: "Tracing", visible: true, opacity: t.opacity, blend: "normal", image, version: key + Math.round(t.opacity * 1e3) / 1e4 };
@@ -8315,8 +8409,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8315
8409
  let out = layers;
8316
8410
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
8317
8411
  for (const id of ids) {
8318
- const ch = _optionalChain([live, 'optionalAccess', _447 => _447.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _448 => _448[id]]);
8319
- const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _449 => _449.layer]);
8412
+ const ch = _optionalChain([live, 'optionalAccess', _457 => _457.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _458 => _458[id]]);
8413
+ const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _459 => _459.layer]);
8320
8414
  if (!ch || !isPixelLayer(l)) continue;
8321
8415
  let cache = this.litCaches.get(id);
8322
8416
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -8336,13 +8430,13 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8336
8430
  if (!ids.size) return layers;
8337
8431
  let out = layers;
8338
8432
  for (const id of ids) {
8339
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _450 => _450.layer]);
8433
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _460 => _460.layer]);
8340
8434
  if (!isPixelLayer(l)) continue;
8341
8435
  let cache = this.lightCaches.get(id);
8342
8436
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
8343
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _451 => _451.liveThick, 'optionalAccess', _452 => _452.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.thick, 'optionalAccess', _455 => _455[id]]));
8437
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _461 => _461.liveThick, 'optionalAccess', _462 => _462.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _463 => _463.doc, 'access', _464 => _464.thick, 'optionalAccess', _465 => _465[id]]));
8344
8438
  if (glowed !== l.surface) out = _chunkPVJMTLPJcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
8345
- const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _456 => _456.layer]);
8439
+ const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _466 => _466.layer]);
8346
8440
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
8347
8441
  if (spill) out = insertAfter(out, id, { type: "pixel", id: `${id}${SPILL_SUFFIX}`, name: `${l.name} light`, visible: l.visible, opacity: l.opacity, blend: "linear-dodge", surface: spill, offset: { ...l.offset } });
8348
8442
  }
@@ -8354,7 +8448,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8354
8448
  if (!l.visible) continue;
8355
8449
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
8356
8450
  else if (isPixelLayer(l)) {
8357
- const thick = !committed && _optionalChain([this, 'access', _457 => _457.liveThick, 'optionalAccess', _458 => _458.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _459 => _459.doc, 'access', _460 => _460.thick, 'optionalAccess', _461 => _461[l.id]]);
8451
+ const thick = !committed && _optionalChain([this, 'access', _467 => _467.liveThick, 'optionalAccess', _468 => _468.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _469 => _469.doc, 'access', _470 => _470.thick, 'optionalAccess', _471 => _471[l.id]]);
8358
8452
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
8359
8453
  }
8360
8454
  }
@@ -8383,7 +8477,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8383
8477
  if (backlight) layers = [...layers, backlight];
8384
8478
  if (options.layerIds) {
8385
8479
  const picked = [];
8386
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _462 => _462.layer]), () => ( this.requireLayer(id))));
8480
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _472 => _472.layer]), () => ( this.requireLayer(id))));
8387
8481
  layers = picked.map((l) => ({ ...l, visible: true }));
8388
8482
  }
8389
8483
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -8399,7 +8493,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8399
8493
  */
8400
8494
  compositeTiles(rect, onTile, options = {}) {
8401
8495
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
8402
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _463 => _463.live, 'optionalAccess', _464 => _464.layerId]), () => ( this.doc.activeLayerId)) });
8496
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _473 => _473.live, 'optionalAccess', _474 => _474.layerId]), () => ( this.doc.activeLayerId)) });
8403
8497
  }
8404
8498
  /** The canvas as canvas-sized RGBA (paper included by default). */
8405
8499
  compositePixels(options = {}) {
@@ -8478,7 +8572,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8478
8572
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)));
8479
8573
  if (Object.keys(spills).length) ext.lightSpill = spills;
8480
8574
  else delete ext.lightSpill;
8481
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _465 => _465.layer])));
8575
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _475 => _475.layer])));
8482
8576
  if (effectLayers) ext.effectLayers = effectLayers;
8483
8577
  else delete ext.effectLayers;
8484
8578
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -8514,7 +8608,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8514
8608
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
8515
8609
  const liveStrokes = {};
8516
8610
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
8517
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _466 => _466.layer])) || !Array.isArray(list)) continue;
8611
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _476 => _476.layer])) || !Array.isArray(list)) continue;
8518
8612
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
8519
8613
  if (ok.length !== list.length) problems.push(`Some strokes of stroke layer "${id}" could not be read; they were dropped (the layer's pixels are kept until a stroke is edited).`);
8520
8614
  liveStrokes[id] = ok;
@@ -8524,7 +8618,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8524
8618
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
8525
8619
  const effectLayers = {};
8526
8620
  for (const [id, v] of Object.entries(ext.effectLayers)) {
8527
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _467 => _467.layer]))) continue;
8621
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _477 => _477.layer]))) continue;
8528
8622
  const source = readPaintEffectSource(v);
8529
8623
  if (source) effectLayers[id] = source;
8530
8624
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -8552,7 +8646,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8552
8646
  if (ext.light && typeof ext.light === "object") {
8553
8647
  const light = {};
8554
8648
  for (const [id, v] of Object.entries(ext.light)) {
8555
- if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _468 => _468.layer]))) continue;
8649
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _478 => _478.layer]))) continue;
8556
8650
  try {
8557
8651
  light[id] = lightFromJSON(v);
8558
8652
  } catch (e) {
@@ -8588,7 +8682,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8588
8682
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
8589
8683
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
8590
8684
  for (const s of loaded.state.strokes) {
8591
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _469 => _469.exec, 'call', _470 => _470(s.id), 'optionalAccess', _471 => _471[1]]), () => ( 0)));
8685
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _479 => _479.exec, 'call', _480 => _480(s.id), 'optionalAccess', _481 => _481[1]]), () => ( 0)));
8592
8686
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8593
8687
  }
8594
8688
  this.undoStack = [];
@@ -8596,7 +8690,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8596
8690
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
8597
8691
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
8598
8692
  for (const s of list) {
8599
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _472 => _472.exec, 'call', _473 => _473(s.id), 'optionalAccess', _474 => _474[1]]), () => ( 0)));
8693
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _482 => _482.exec, 'call', _483 => _483(s.id), 'optionalAccess', _484 => _484[1]]), () => ( 0)));
8600
8694
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8601
8695
  }
8602
8696
  }
@@ -8695,8 +8789,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8695
8789
  const layers = toStandard(dried);
8696
8790
  const result = _chunk43NT242Dcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
8697
8791
  for (const [mode, names] of changed) {
8698
- const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _475 => _475.find, 'call', _476 => _476((m) => m.id === mode), 'optionalAccess', _477 => _477.label]), () => ( mode));
8699
- const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _478 => _478.find, 'call', _479 => _479((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _480 => _480.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
8792
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _485 => _485.find, 'call', _486 => _486((m) => m.id === mode), 'optionalAccess', _487 => _487.label]), () => ( mode));
8793
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _488 => _488.find, 'call', _489 => _489((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _490 => _490.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
8700
8794
  const list = names.map((n) => `"${n}"`).join(", ");
8701
8795
  const one = names.length === 1;
8702
8796
  result.warnings.push(`${label} blending has no PSD equivalent; ${list} ${one ? "was" : "were"} written as ${std}, the nearest Photoshop mode, so ${one ? "it looks" : "they look"} different in Photoshop (the merged image is exact).`);
@@ -8818,7 +8912,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8818
8912
  const { src, pixels } = this.importImage(options, "The reference image");
8819
8913
  const ref2 = {
8820
8914
  id: `ref${this.nextReferenceId++}`,
8821
- name: _optionalChain([options, 'access', _481 => _481.name, 'optionalAccess', _482 => _482.trim, 'call', _483 => _483()]) || `Reference ${this.guides.references.length + 1}`,
8915
+ name: _optionalChain([options, 'access', _491 => _491.name, 'optionalAccess', _492 => _492.trim, 'call', _493 => _493()]) || `Reference ${this.guides.references.length + 1}`,
8822
8916
  src,
8823
8917
  width: pixels.width,
8824
8918
  height: pixels.height,
@@ -8897,7 +8991,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8897
8991
  try {
8898
8992
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
8899
8993
  guides.references.push({ id: ref2.id, name: String(_nullishCoalesce(ref2.name, () => ( ref2.id))), src: ref2.src, width: px.width, height: px.height, x: Number(ref2.x) || 0, y: Number(ref2.y) || 0, displayWidth: Number(ref2.displayWidth) || 240, visible: ref2.visible !== false });
8900
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _484 => _484.exec, 'call', _485 => _485(ref2.id), 'optionalAccess', _486 => _486[1]]), () => ( 0)));
8994
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _494 => _494.exec, 'call', _495 => _495(ref2.id), 'optionalAccess', _496 => _496[1]]), () => ( 0)));
8901
8995
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
8902
8996
  } catch (e) {
8903
8997
  problems.push(e.message);
@@ -8908,7 +9002,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8908
9002
  guides.stencils = [];
8909
9003
  r.stencils.forEach((raw2, i) => {
8910
9004
  try {
8911
- const id = typeof _optionalChain([raw2, 'optionalAccess', _487 => _487.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
9005
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _497 => _497.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
8912
9006
  guides.stencils.push(normalizeStencil(raw2, id));
8913
9007
  const n = Number(id.slice(7));
8914
9008
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -8931,12 +9025,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8931
9025
  /** The next free sticker number (ids `st<n>` are unique across the document). */
8932
9026
  nextStickerNumber(doc = this.doc) {
8933
9027
  let n = 0;
8934
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _488 => _488.exec, 'call', _489 => _489(st.id), 'optionalAccess', _490 => _490[1]]), () => ( 0))));
9028
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _498 => _498.exec, 'call', _499 => _499(st.id), 'optionalAccess', _500 => _500[1]]), () => ( 0))));
8935
9029
  return n + 1;
8936
9030
  }
8937
9031
  stickerLayer(layerId) {
8938
9032
  const l = this.wetLayer(layerId, "edit the stickers of");
8939
- const stickers = _optionalChain([this, 'access', _491 => _491.doc, 'access', _492 => _492.stickers, 'optionalAccess', _493 => _493[l.id]]);
9033
+ const stickers = _optionalChain([this, 'access', _501 => _501.doc, 'access', _502 => _502.stickers, 'optionalAccess', _503 => _503[l.id]]);
8940
9034
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (sticker-stars; list_brush_presets lists them).`);
8941
9035
  return { layer: l, stickers };
8942
9036
  }
@@ -8995,7 +9089,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8995
9089
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8996
9090
  if (!id) return [];
8997
9091
  this.requireLayer(id);
8998
- return (_nullishCoalesce(_optionalChain([this, 'access', _494 => _494.doc, 'access', _495 => _495.stickers, 'optionalAccess', _496 => _496[id]]), () => ( []))).map((s) => ({ ...s }));
9092
+ return (_nullishCoalesce(_optionalChain([this, 'access', _504 => _504.doc, 'access', _505 => _505.stickers, 'optionalAccess', _506 => _506[id]]), () => ( []))).map((s) => ({ ...s }));
8999
9093
  }
9000
9094
  /**
9001
9095
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -9016,7 +9110,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9016
9110
  }
9017
9111
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
9018
9112
  previewBase() {
9019
- return _optionalChain([this, 'access', _497 => _497.stickerPreview, 'optionalAccess', _498 => _498.shown]) === this.doc ? this.stickerPreview.base : null;
9113
+ return _optionalChain([this, 'access', _507 => _507.stickerPreview, 'optionalAccess', _508 => _508.shown]) === this.doc ? this.stickerPreview.base : null;
9020
9114
  }
9021
9115
  readStickerUpdate(update) {
9022
9116
  try {
@@ -9031,7 +9125,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9031
9125
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
9032
9126
  if (!id) return null;
9033
9127
  this.requireLayer(id);
9034
- const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _499 => _499.doc, 'access', _500 => _500.stickers, 'optionalAccess', _501 => _501[id]]), () => ( [])), x, y, this.stickerArt.get);
9128
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _509 => _509.doc, 'access', _510 => _510.stickers, 'optionalAccess', _511 => _511[id]]), () => ( [])), x, y, this.stickerArt.get);
9035
9129
  return hit ? { ...hit } : null;
9036
9130
  }
9037
9131
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -9087,8 +9181,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9087
9181
  const layer = this.wetLayer(layerId, "add stickers to");
9088
9182
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
9089
9183
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
9090
- const existing = _optionalChain([this, 'access', _502 => _502.doc, 'access', _503 => _503.stickers, 'optionalAccess', _504 => _504[layer.id]]);
9091
- if (!_optionalChain([existing, 'optionalAccess', _505 => _505.length])) {
9184
+ const existing = _optionalChain([this, 'access', _512 => _512.doc, 'access', _513 => _513.stickers, 'optionalAccess', _514 => _514[layer.id]]);
9185
+ if (!_optionalChain([existing, 'optionalAccess', _515 => _515.length])) {
9092
9186
  if (this.wet.wetLayerIds().includes(layer.id) || _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; add stickers to an empty layer (add_layer) or a sticker layer so they stay editable.`);
9093
9187
  }
9094
9188
  let n = this.nextStickerNumber();
@@ -9105,7 +9199,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9105
9199
  const id = n++;
9106
9200
  return { id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u };
9107
9201
  });
9108
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _506 => _506.length]) ? added.map(stickerRect) : void 0);
9202
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _516 => _516.length]) ? added.map(stickerRect) : void 0);
9109
9203
  return added.map((s) => ({ ...s }));
9110
9204
  }
9111
9205
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -9144,20 +9238,20 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9144
9238
  }
9145
9239
  liveStrokeLayer(layerId, what) {
9146
9240
  const l = this.wetLayer(layerId, what);
9147
- const strokes = _optionalChain([this, 'access', _507 => _507.doc, 'access', _508 => _508.liveStrokes, 'optionalAccess', _509 => _509[l.id]]);
9241
+ const strokes = _optionalChain([this, 'access', _517 => _517.doc, 'access', _518 => _518.liveStrokes, 'optionalAccess', _519 => _519[l.id]]);
9148
9242
  if (!strokes) throw new PaintEditorError(`Layer "${l.name}" is not a stroke layer; add one with add_layer {type: "strokes"} (or convert_to_stroke_layer on an empty layer), then paint on it.`);
9149
9243
  return { layer: l, strokes };
9150
9244
  }
9151
9245
  /** Whether a layer is a live stroke layer. */
9152
9246
  isLiveStrokeLayer(layerId) {
9153
- return Boolean(_optionalChain([this, 'access', _510 => _510.doc, 'access', _511 => _511.liveStrokes, 'optionalAccess', _512 => _512[layerId]]));
9247
+ return Boolean(_optionalChain([this, 'access', _520 => _520.doc, 'access', _521 => _521.liveStrokes, 'optionalAccess', _522 => _522[layerId]]));
9154
9248
  }
9155
9249
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
9156
9250
  convertToLiveStrokes(layerId) {
9157
9251
  this.requireIdle("converting a layer");
9158
9252
  const l = this.paintTarget(layerId, "convert");
9159
- if (_optionalChain([this, 'access', _513 => _513.doc, 'access', _514 => _514.liveStrokes, 'optionalAccess', _515 => _515[l.id]])) return this.describeLayer(l);
9160
- if (_optionalChain([this, 'access', _516 => _516.doc, 'access', _517 => _517.stickers, 'optionalAccess', _518 => _518[l.id], 'optionalAccess', _519 => _519.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
9253
+ if (_optionalChain([this, 'access', _523 => _523.doc, 'access', _524 => _524.liveStrokes, 'optionalAccess', _525 => _525[l.id]])) return this.describeLayer(l);
9254
+ if (_optionalChain([this, 'access', _526 => _526.doc, 'access', _527 => _527.stickers, 'optionalAccess', _528 => _528[l.id], 'optionalAccess', _529 => _529.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
9161
9255
  if (_chunk474IQG74cjs.contentBounds.call(void 0, l.surface) || this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" already has paint, which isn't kept as strokes; convert an empty layer or add a stroke layer (add_layer {type: "strokes"}).`);
9162
9256
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
9163
9257
  return this.describeLayer(this.getLayer(l.id));
@@ -9170,7 +9264,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9170
9264
  findLiveStroke(id) {
9171
9265
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
9172
9266
  const index = strokes.findIndex((x) => x.id === id);
9173
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _520 => _520.layer]);
9267
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _530 => _530.layer]);
9174
9268
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
9175
9269
  }
9176
9270
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -9265,9 +9359,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9265
9359
  const layers = /* @__PURE__ */ new Map();
9266
9360
  for (const f of found) layers.set(f.layer.id, f.layer);
9267
9361
  for (const [layerId, layer] of layers) {
9268
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _521 => _521.liveStrokes, 'optionalAccess', _522 => _522[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9362
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _531 => _531.liveStrokes, 'optionalAccess', _532 => _532[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9269
9363
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
9270
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _523 => _523.liveStrokes, 'optionalAccess', _524 => _524[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
9364
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _533 => _533.liveStrokes, 'optionalAccess', _534 => _534[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
9271
9365
  }
9272
9366
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
9273
9367
  return { removed: [...ids], bounds };
@@ -9335,7 +9429,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9335
9429
  }
9336
9430
  withLiveStrokes(doc, layer, list, dirty) {
9337
9431
  if (_chunkPVJMTLPJcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
9338
- const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _525 => _525.layer]);
9432
+ const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _535 => _535.layer]);
9339
9433
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
9340
9434
  const next = { ...doc, layers: _chunkPVJMTLPJcjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
9341
9435
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
@@ -9413,7 +9507,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9413
9507
  if (!this.animatedLayers.size) return this.doc.layers;
9414
9508
  let layers = this.doc.layers;
9415
9509
  for (const [id, a] of this.animatedLayers) {
9416
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _526 => _526.layer]);
9510
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _536 => _536.layer]);
9417
9511
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
9418
9512
  }
9419
9513
  return layers;
@@ -9423,7 +9517,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9423
9517
  const layers = [];
9424
9518
  const sources = /* @__PURE__ */ new Map();
9425
9519
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
9426
- const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _527 => _527.layer]);
9520
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _537 => _537.layer]);
9427
9521
  const live = strokes.filter(isLiveEffect);
9428
9522
  if (!isPixelLayer(layer) || !live.length) continue;
9429
9523
  layers.push({ layer, strokes });
@@ -9554,7 +9648,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9554
9648
  stencilSelection(stencils = this.guides.stencils) {
9555
9649
  const { width, height } = this.doc.canvas;
9556
9650
  const size = `${width}x${height}`;
9557
- if (_optionalChain([this, 'access', _528 => _528.stencilCache, 'optionalAccess', _529 => _529.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9651
+ if (_optionalChain([this, 'access', _538 => _538.stencilCache, 'optionalAccess', _539 => _539.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9558
9652
  const mask = stencilMask(stencils, width, height);
9559
9653
  this.stencilCache = { key: stencils, size, mask };
9560
9654
  return mask;
@@ -9616,7 +9710,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9616
9710
  makeSwatch(color, name) {
9617
9711
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
9618
9712
  const out = { color: _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
9619
- if (_optionalChain([name, 'optionalAccess', _530 => _530.trim, 'call', _531 => _531()])) out.name = name.trim();
9713
+ if (_optionalChain([name, 'optionalAccess', _540 => _540.trim, 'call', _541 => _541()])) out.name = name.trim();
9620
9714
  if (p.type === "gradient") out.paint = p;
9621
9715
  return out;
9622
9716
  }
@@ -9668,7 +9762,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9668
9762
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
9669
9763
  */
9670
9764
  mixOnPad(paints2, options = {}) {
9671
- const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _532 => _532.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _533 => _533.parts]) }));
9765
+ const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _542 => _542.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _543 => _543.parts]) }));
9672
9766
  let r;
9673
9767
  try {
9674
9768
  r = this.pad.mix(parsed, options);
@@ -9757,7 +9851,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9757
9851
  }
9758
9852
  /** A layer's tile surface (live while stroking), for thumbnails. */
9759
9853
  layerSurface(id) {
9760
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _534 => _534.layer]);
9854
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _544 => _544.layer]);
9761
9855
  return isPixelLayer(l) ? l.surface : null;
9762
9856
  }
9763
9857
  }, _class19.__initStatic(), _class19);
@@ -9779,7 +9873,7 @@ function insertAfter(layers, id, node) {
9779
9873
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
9780
9874
  }
9781
9875
  function isLiveEffect(s) {
9782
- return _optionalChain([s, 'access', _535 => _535.paint, 'optionalAccess', _536 => _536.type]) === "effect" && s.paint.live === true;
9876
+ return _optionalChain([s, 'access', _545 => _545.paint, 'optionalAccess', _546 => _546.type]) === "effect" && s.paint.live === true;
9783
9877
  }
9784
9878
  function framePaint(p, t) {
9785
9879
  return { ...p, time: p.time + t };
@@ -9804,7 +9898,7 @@ function clipRect(r, width, height) {
9804
9898
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
9805
9899
  }
9806
9900
  function withLiveStroke(doc, stroke) {
9807
- const list = _optionalChain([doc, 'access', _537 => _537.liveStrokes, 'optionalAccess', _538 => _538[stroke.layerId]]);
9901
+ const list = _optionalChain([doc, 'access', _547 => _547.liveStrokes, 'optionalAccess', _548 => _548[stroke.layerId]]);
9808
9902
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
9809
9903
  }
9810
9904
  function shiftDocument(doc, dx, dy) {
@@ -9831,9 +9925,9 @@ function shiftDocument(doc, dx, dy) {
9831
9925
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
9832
9926
  if (doc.paintEvents) {
9833
9927
  out.paintEvents = doc.paintEvents.map((e) => {
9834
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _539 => _539.data, 'optionalAccess', _540 => _540.stickers]) : void 0;
9928
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _549 => _549.data, 'optionalAccess', _550 => _550.stickers]) : void 0;
9835
9929
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
9836
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _541 => _541.data, 'optionalAccess', _542 => _542.strokes]) : void 0;
9930
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _551 => _551.data, 'optionalAccess', _552 => _552.strokes]) : void 0;
9837
9931
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
9838
9932
  });
9839
9933
  }
@@ -9922,8 +10016,8 @@ function strokeSchedule(points) {
9922
10016
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
9923
10017
  }
9924
10018
  function strokeDuration(points, max = 1800) {
9925
- const t0 = _optionalChain([points, 'access', _543 => _543[0], 'optionalAccess', _544 => _544.t]);
9926
- const t1 = _optionalChain([points, 'access', _545 => _545[points.length - 1], 'optionalAccess', _546 => _546.t]);
10019
+ const t0 = _optionalChain([points, 'access', _553 => _553[0], 'optionalAccess', _554 => _554.t]);
10020
+ const t1 = _optionalChain([points, 'access', _555 => _555[points.length - 1], 'optionalAccess', _556 => _556.t]);
9927
10021
  let ms;
9928
10022
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
9929
10023
  else {
@@ -9977,7 +10071,7 @@ var PaintDirector = class {
9977
10071
  }
9978
10072
  where(id) {
9979
10073
  const a = this.presence.get(id);
9980
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _547 => _547.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _548 => _548.y]), () => ( 0)) };
10074
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _557 => _557.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _558 => _558.y]), () => ( 0)) };
9981
10075
  }
9982
10076
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
9983
10077
  async glide(id, to, ms = 380) {
@@ -10024,8 +10118,8 @@ var PaintDirector = class {
10024
10118
  }
10025
10119
  case "replay": {
10026
10120
  await this.say(id, command.note, 500);
10027
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _549 => _549.replay, 'access', _550 => _550.strokeIds, 'optionalAccess', _551 => _551.includes, 'call', _552 => _552(s.id)]));
10028
- const first = _optionalChain([source, 'access', _553 => _553[0], 'optionalAccess', _554 => _554.points, 'access', _555 => _555[0]]);
10121
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _559 => _559.replay, 'access', _560 => _560.strokeIds, 'optionalAccess', _561 => _561.includes, 'call', _562 => _562(s.id)]));
10122
+ const first = _optionalChain([source, 'access', _563 => _563[0], 'optionalAccess', _564 => _564.points, 'access', _565 => _565[0]]);
10029
10123
  if (first) await this.glide(id, first);
10030
10124
  const result = c.replayStrokes(command.replay);
10031
10125
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -11462,7 +11556,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11462
11556
  inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brush_presets to start from (default the active brush)." }, name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." }, ..._chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES, unset: _chunkPYTJBVW5cjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
11463
11557
  annotations: { title: "Set the brush", ...SET4 },
11464
11558
  handler: async ({ id, unset, ...patch }) => {
11465
- const stamps = _optionalChain([patch, 'access', _556 => _556.tip, 'optionalAccess', _557 => _557.stamps]);
11559
+ const stamps = _optionalChain([patch, 'access', _566 => _566.tip, 'optionalAccess', _567 => _567.stamps]);
11466
11560
  if (stamps) await c.prepareStickers(stamps);
11467
11561
  const r = c.setBrushFacets(patch, id, unset);
11468
11562
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -11579,6 +11673,41 @@ function createPaintEditorToolProvider(controller, options = {}) {
11579
11673
  return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11580
11674
  }
11581
11675
  });
11676
+ add({
11677
+ name: "stroke_path",
11678
+ title: "Brush along a path",
11679
+ description: "Brushes vector path data (SVG path d in document pixels: M, L, H, V, C, S, Q, T, A and Z) on a pixel layer with a library brush or the active one, as if drawn by hand along it: the outline of a shape, a lettering guide, a curve from a vector tool. Each subpath becomes one recorded stroke, sampled every spacing px, with an optional pressure profile spread along each subpath (a taper such as [0.2, 1, 0.2]); closed subpaths end where they start. Brushes behave as in paint_stroke (grain, pick-up, wet and thick paint, guides off). One undo step for the whole path. Returns the layer id, changed bounds, dab count and the recorded strokeIds (for replay_strokes, update_stroke).",
11680
+ inputSchema: {
11681
+ type: "object",
11682
+ properties: {
11683
+ path: { type: "string", minLength: 1, description: 'SVG path data in document pixels, e.g. "M 40 200 C 120 40 280 40 360 200". Several subpaths paint several strokes.' },
11684
+ spacing: { type: "number", minimum: 0.25, maximum: 100, description: "Distance between samples along the path in document pixels (default 2); the brush spaces its own dabs, so this only sets how closely curves are followed." },
11685
+ pressure: { type: "array", minItems: 1, maxItems: 64, items: { type: "number", minimum: 0, maximum: 1 }, description: "Pen pressure along each subpath, spread evenly from start to end (default full pressure); [0.2, 1, 0.2] tapers both ends." },
11686
+ layerId: LAYER_ID4,
11687
+ brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
11688
+ brush: { type: "object", description: "Facets to change for this stroke only, laid over brushId or the active brush (as set_brush takes them).", properties: _chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES, additionalProperties: false },
11689
+ color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
11690
+ paint: { ..._chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA, description: "What the strokes paint with instead of the editor's paint: a colour, or gradient paint that changes colour as each stroke goes." },
11691
+ seed: { type: "integer", minimum: 0, description: "Jitter seed of the first subpath, the next ones take the following seeds (default new ones); the same seed and path give the same marks." }
11692
+ },
11693
+ required: ["path"],
11694
+ additionalProperties: false
11695
+ },
11696
+ annotations: { title: "Brush along a path", ...WRITE5 },
11697
+ coordinates: { out: ["bounds"] },
11698
+ handler: async (a) => {
11699
+ await c.wetIdle();
11700
+ const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
11701
+ const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
11702
+ if (base) {
11703
+ const refs = brushStickerRefs(_chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
11704
+ if (refs.length) await c.prepareStickers(refs);
11705
+ }
11706
+ const path = options.origin && typeof a.path === "string" && a.path.trim() ? _chunkGF2RBSDMcjs.bezierPathToSvg.call(void 0, a.path, { offset: { x: -options.origin.x, y: -options.origin.y } }) : a.path;
11707
+ const r = c.strokePath({ path, spacing: a.spacing, pressure: a.pressure, layerId: a.layerId, brushId: a.brushId, brush, color: a.color, paint: a.paint, seed: a.seed });
11708
+ return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11709
+ }
11710
+ });
11582
11711
  add({
11583
11712
  name: "get_live_stroke",
11584
11713
  title: "Get the stroke being painted",
@@ -11622,7 +11751,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11622
11751
  if (ids) {
11623
11752
  for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke "${id}". Call list_strokes without ids for the ids.`);
11624
11753
  }
11625
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _558 => _558.document, 'access', _559 => _559.liveStrokes, 'optionalAccess', _560 => _560[s.layerId], 'optionalAccess', _561 => _561.includes, 'call', _562 => _562(s)]) === true)) };
11754
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _568 => _568.document, 'access', _569 => _569.liveStrokes, 'optionalAccess', _570 => _570[s.layerId], 'optionalAccess', _571 => _571.includes, 'call', _572 => _572(s)]) === true)) };
11626
11755
  }
11627
11756
  });
11628
11757
  add({
@@ -11931,16 +12060,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
11931
12060
  }
11932
12061
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
11933
12062
  if (!origin && !onChange) return tool;
11934
- const write = !_optionalChain([tool, 'access', _563 => _563.annotations, 'optionalAccess', _564 => _564.readOnlyHint]);
12063
+ const write = !_optionalChain([tool, 'access', _573 => _573.annotations, 'optionalAccess', _574 => _574.readOnlyHint]);
11935
12064
  const done = (result) => {
11936
- if (write) _optionalChain([onChange, 'optionalCall', _565 => _565({ tool: tool.name })]);
11937
- return origin && _optionalChain([coordinates, 'optionalAccess', _566 => _566.out]) ? fromDocument(result, coordinates.out, origin) : result;
12065
+ if (write) _optionalChain([onChange, 'optionalCall', _575 => _575({ tool: tool.name })]);
12066
+ return origin && _optionalChain([coordinates, 'optionalAccess', _576 => _576.out]) ? fromDocument(result, coordinates.out, origin) : result;
11938
12067
  };
11939
12068
  return {
11940
12069
  ...tool,
11941
12070
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
11942
12071
  handler: (args, context) => {
11943
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _567 => _567.in]) ? toDocument(args, coordinates.in, origin) : args, context);
12072
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _577 => _577.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11944
12073
  return r instanceof Promise ? r.then(done) : done(r);
11945
12074
  }
11946
12075
  };
@@ -11957,7 +12086,7 @@ function strokeSummary(s, withPoints, live) {
11957
12086
  color: s.color,
11958
12087
  points: withPoints ? s.points : s.points.length,
11959
12088
  seed: s.seed,
11960
- copies: _nullishCoalesce(_optionalChain([s, 'access', _568 => _568.copies, 'optionalAccess', _569 => _569.length]), () => ( 0)),
12089
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _578 => _578.copies, 'optionalAccess', _579 => _579.length]), () => ( 0)),
11961
12090
  live,
11962
12091
  bounds: { x: Math.floor(Math.min(...xs) - pad), y: Math.floor(Math.min(...ys) - pad), width: Math.ceil(Math.max(...xs) - Math.min(...xs) + 2 * pad), height: Math.ceil(Math.max(...ys) - Math.min(...ys) + 2 * pad) }
11963
12092
  };
@@ -12055,13 +12184,13 @@ var PaintGesture = (_class20 = class {
12055
12184
  const p = this.doc(e);
12056
12185
  const s = this.controller.getState();
12057
12186
  const layerId = s.document.activeLayerId;
12058
- if (!layerId || !_optionalChain([s, 'access', _570 => _570.document, 'access', _571 => _571.liveStrokes, 'optionalAccess', _572 => _572[layerId]])) {
12187
+ if (!layerId || !_optionalChain([s, 'access', _580 => _580.document, 'access', _581 => _581.liveStrokes, 'optionalAccess', _582 => _582[layerId]])) {
12059
12188
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
12060
12189
  return false;
12061
12190
  }
12062
12191
  try {
12063
12192
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
12064
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _573 => _573.id]), () => ( null)));
12193
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _583 => _583.id]), () => ( null)));
12065
12194
  if (!hit) return false;
12066
12195
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
12067
12196
  return true;
@@ -12073,7 +12202,7 @@ var PaintGesture = (_class20 = class {
12073
12202
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
12074
12203
  get strokeDrag() {
12075
12204
  const m = this.mode;
12076
- return _optionalChain([m, 'optionalAccess', _574 => _574.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
12205
+ return _optionalChain([m, 'optionalAccess', _584 => _584.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
12077
12206
  }
12078
12207
  /**
12079
12208
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -12147,7 +12276,7 @@ var PaintGesture = (_class20 = class {
12147
12276
  if (!m || m.pointerId !== e.pointerId) return;
12148
12277
  this.mode = null;
12149
12278
  this.predicted = [];
12150
- if (m.kind === "stroke") _optionalChain([this, 'access', _575 => _575.controller, 'access', _576 => _576.activeStroke, 'optionalAccess', _577 => _577.end, 'call', _578 => _578()]);
12279
+ if (m.kind === "stroke") _optionalChain([this, 'access', _585 => _585.controller, 'access', _586 => _586.activeStroke, 'optionalAccess', _587 => _587.end, 'call', _588 => _588()]);
12151
12280
  if (m.kind === "move-stroke") {
12152
12281
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
12153
12282
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -12171,8 +12300,8 @@ var PaintGesture = (_class20 = class {
12171
12300
  cancel() {
12172
12301
  this.penDown = false;
12173
12302
  this.predicted = [];
12174
- if (_optionalChain([this, 'access', _579 => _579.mode, 'optionalAccess', _580 => _580.kind]) === "stroke") _optionalChain([this, 'access', _581 => _581.controller, 'access', _582 => _582.activeStroke, 'optionalAccess', _583 => _583.cancel, 'call', _584 => _584()]);
12175
- if (_optionalChain([this, 'access', _585 => _585.mode, 'optionalAccess', _586 => _586.kind]) === "sticker") this.controller.cancelStickerPreview();
12303
+ if (_optionalChain([this, 'access', _589 => _589.mode, 'optionalAccess', _590 => _590.kind]) === "stroke") _optionalChain([this, 'access', _591 => _591.controller, 'access', _592 => _592.activeStroke, 'optionalAccess', _593 => _593.cancel, 'call', _594 => _594()]);
12304
+ if (_optionalChain([this, 'access', _595 => _595.mode, 'optionalAccess', _596 => _596.kind]) === "sticker") this.controller.cancelStickerPreview();
12176
12305
  this.mode = null;
12177
12306
  }
12178
12307
  get active() {
@@ -12275,7 +12404,7 @@ function guideOverlay(controller, drag) {
12275
12404
  const size = s.document.canvas;
12276
12405
  const out = [];
12277
12406
  const layerId = s.document.activeLayerId;
12278
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _587 => _587.document, 'access', _588 => _588.liveStrokes, 'optionalAccess', _589 => _589[layerId], 'optionalAccess', _590 => _590.some, 'call', _591 => _591((x) => x.id === s.selectedStroke)]) : false;
12407
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _597 => _597.document, 'access', _598 => _598.liveStrokes, 'optionalAccess', _599 => _599[layerId], 'optionalAccess', _600 => _600.some, 'call', _601 => _601((x) => x.id === s.selectedStroke)]) : false;
12279
12408
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
12280
12409
  if (area) {
12281
12410
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -12288,7 +12417,7 @@ function guideOverlay(controller, drag) {
12288
12417
  ];
12289
12418
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
12290
12419
  }
12291
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _592 => _592.document, 'access', _593 => _593.stickers, 'optionalAccess', _594 => _594[layerId], 'optionalAccess', _595 => _595.find, 'call', _596 => _596((x) => x.id === s.selectedSticker)]) : void 0;
12420
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _602 => _602.document, 'access', _603 => _603.stickers, 'optionalAccess', _604 => _604[layerId], 'optionalAccess', _605 => _605.find, 'call', _606 => _606((x) => x.id === s.selectedSticker)]) : void 0;
12292
12421
  if (picked) {
12293
12422
  const r = picked.size / 2 + 2;
12294
12423
  const a = picked.rotation * Math.PI / 180;
@@ -12318,7 +12447,7 @@ var PAPER_SLIDERS = [
12318
12447
  ];
12319
12448
  function readPath(obj, path) {
12320
12449
  let v = obj;
12321
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _597 => _597[k]]);
12450
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _607 => _607[k]]);
12322
12451
  return typeof v === "number" ? v : 0;
12323
12452
  }
12324
12453
  function patchPath(obj, path, value) {
@@ -12434,7 +12563,7 @@ function startWetClock(controller, frame, cancel) {
12434
12563
  id = raf(loop);
12435
12564
  return () => {
12436
12565
  stopped = true;
12437
- _optionalChain([caf, 'optionalCall', _598 => _598(id)]);
12566
+ _optionalChain([caf, 'optionalCall', _608 => _608(id)]);
12438
12567
  };
12439
12568
  }
12440
12569
  function drawWaterOverlay(controller, ctx) {
@@ -12480,6 +12609,12 @@ function toggleDotTexture(textures, stamp) {
12480
12609
  if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
12481
12610
  return textures.length < _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
12482
12611
  }
12612
+ var PATH_STROKE_TAPERS = [
12613
+ { id: "even", label: "Even" },
12614
+ { id: "both", label: "Taper both ends", pressure: [0.2, 1, 0.2] },
12615
+ { id: "in", label: "Fade in", pressure: [0.2, 1] },
12616
+ { id: "out", label: "Fade out", pressure: [1, 0.2] }
12617
+ ];
12483
12618
  var STROKE_SLIDERS = [
12484
12619
  { path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
12485
12620
  { path: "tip.opacity", label: "Opacity", min: 0, max: 1, step: 0.01 },
@@ -12786,7 +12921,7 @@ function createPaintChangeFeed(controller, options = {}) {
12786
12921
  const doc = state.document;
12787
12922
  const layers = /* @__PURE__ */ new Map();
12788
12923
  for (const l of controller.listLayers()) layers.set(l.id, { name: l.name, visible: l.visible, opacity: l.opacity, blend: l.blend });
12789
- return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _599 => _599.paintEvents, 'optionalAccess', _600 => _600.length]), () => ( 0)), layers, stroking: state.stroking };
12924
+ return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _609 => _609.paintEvents, 'optionalAccess', _610 => _610.length]), () => ( 0)), layers, stroking: state.stroking };
12790
12925
  };
12791
12926
  let last = take();
12792
12927
  const check = () => {
@@ -12817,7 +12952,7 @@ function createPaintChangeFeed(controller, options = {}) {
12817
12952
  if (edited) pending = void 0;
12818
12953
  const change = {
12819
12954
  seq: ++seq,
12820
- origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _601 => _601.origin]), () => ( "user")),
12955
+ origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _611 => _611.origin]), () => ( "user")),
12821
12956
  ...commit ? { commit } : {},
12822
12957
  addedStrokes,
12823
12958
  removedStrokes,
@@ -12884,7 +13019,7 @@ function createPaintProposals(options) {
12884
13019
  };
12885
13020
  const strokeIds = () => new Set(controller.getStrokes().map((s) => s.id));
12886
13021
  const validate = (input) => {
12887
- if (!_optionalChain([input, 'access', _602 => _602.title, 'optionalAccess', _603 => _603.trim, 'call', _604 => _604()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
13022
+ if (!_optionalChain([input, 'access', _612 => _612.title, 'optionalAccess', _613 => _613.trim, 'call', _614 => _614()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
12888
13023
  if (!Array.isArray(input.ops) || !input.ops.length) throw new PaintEditorError("A proposal needs at least one op (stroke, wash or echo).");
12889
13024
  const place = _nullishCoalesce(input.place, () => ( "top"));
12890
13025
  if (place === "above") {
@@ -12896,7 +13031,7 @@ function createPaintProposals(options) {
12896
13031
  input.ops.forEach((op, i) => {
12897
13032
  const at = `ops[${i}]`;
12898
13033
  if (op.kind === "stroke") {
12899
- if (!_optionalChain([op, 'access', _605 => _605.points, 'optionalAccess', _606 => _606.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
13034
+ if (!_optionalChain([op, 'access', _615 => _615.points, 'optionalAccess', _616 => _616.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12900
13035
  points += op.points.length;
12901
13036
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
12902
13037
  const brush = op.brushId ? controller.getBrush(op.brushId) : controller.getState().brush;
@@ -12908,7 +13043,7 @@ function createPaintProposals(options) {
12908
13043
  if (!HEX4.test(_nullishCoalesce(op.color, () => ( "")))) throw new PaintEditorError(`${at}: a wash needs color as #rrggbb.`);
12909
13044
  if (op.opacity !== void 0 && !(op.opacity > 0 && op.opacity <= 1)) throw new PaintEditorError(`${at}: opacity must be in (0, 1].`);
12910
13045
  } else if (op.kind === "echo") {
12911
- if (!_optionalChain([op, 'access', _607 => _607.strokeIds, 'optionalAccess', _608 => _608.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
13046
+ if (!_optionalChain([op, 'access', _617 => _617.strokeIds, 'optionalAccess', _618 => _618.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12912
13047
  const unknown = op.strokeIds.filter((id) => !known.has(id));
12913
13048
  if (unknown.length) throw new PaintEditorError(`${at}: unknown stroke ${unknown.map((u) => `"${u}"`).join(", ")}. Call list_strokes for the ids.`);
12914
13049
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
@@ -12957,7 +13092,7 @@ function createPaintProposals(options) {
12957
13092
  ...input.layerId ? { layerId: input.layerId } : {},
12958
13093
  ...input.layerName ? { layerName: input.layerName } : {}
12959
13094
  });
12960
- const topLayerId = () => _optionalChain([controller, 'access', _609 => _609.listLayers, 'call', _610 => _610(), 'access', _611 => _611.find, 'call', _612 => _612((l) => l.parentId === null), 'optionalAccess', _613 => _613.id]);
13095
+ const topLayerId = () => _optionalChain([controller, 'access', _619 => _619.listLayers, 'call', _620 => _620(), 'access', _621 => _621.find, 'call', _622 => _622((l) => l.parentId === null), 'optionalAccess', _623 => _623.id]);
12961
13096
  return {
12962
13097
  getState: () => state,
12963
13098
  subscribe(listener) {
@@ -13144,7 +13279,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13144
13279
  },
13145
13280
  annotations: { title: "Propose paint", ...WRITE6 },
13146
13281
  handler: (args, context) => {
13147
- const origin = _optionalChain([context, 'access', _614 => _614.actor, 'optionalAccess', _615 => _615.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13282
+ const origin = _optionalChain([context, 'access', _624 => _624.actor, 'optionalAccess', _625 => _625.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13148
13283
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
13149
13284
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
13150
13285
  return { proposalId: proposal.id, ...rest };
@@ -13270,6 +13405,7 @@ function uiTables() {
13270
13405
  blendMenu: BLEND_MENU_GROUPS,
13271
13406
  layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_MENU.map(({ kind, label }) => ({ kind, label, controls: _chunkPVJMTLPJcjs.layerEffectControls.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, kind)) })),
13272
13407
  sliders: { paper: PAPER_SLIDERS, wet: WET_PARAM_SLIDERS, wetTilt: WET_TILT_SLIDERS, wetSpeed: WET_SPEED_SLIDER, light: LIGHT_SLIDERS, stroke: STROKE_SLIDERS, sticker: STICKER_SLIDERS },
13408
+ pathStrokeTapers: PATH_STROKE_TAPERS,
13273
13409
  padSampleSizes: PAD_SAMPLE_SIZES,
13274
13410
  wetGpu: WET_GPU_OPTIONS,
13275
13411
  labels: {
@@ -13670,4 +13806,7 @@ function paintContracts(options) {
13670
13806
 
13671
13807
 
13672
13808
 
13673
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkTZOX7KWVcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkTZOX7KWVcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkPYTJBVW5cjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkTZOX7KWVcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkTZOX7KWVcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkTZOX7KWVcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkTZOX7KWVcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkYHDHFJUCcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkTZOX7KWVcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkTZOX7KWVcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkTZOX7KWVcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkTZOX7KWVcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkTZOX7KWVcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkTZOX7KWVcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkTZOX7KWVcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkYHDHFJUCcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkTZOX7KWVcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkTZOX7KWVcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkTZOX7KWVcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_STICKER_STAMPS = _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkTZOX7KWVcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkTZOX7KWVcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkTZOX7KWVcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkTZOX7KWVcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkTZOX7KWVcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkTZOX7KWVcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkYHDHFJUCcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkTZOX7KWVcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkYHDHFJUCcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkTZOX7KWVcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkPYTJBVW5cjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkTZOX7KWVcjs.brushTakesPaint; exports.brushToJSON = _chunkTZOX7KWVcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkTZOX7KWVcjs.isWetBrush; exports.isWetCapable = _chunkTZOX7KWVcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkPYTJBVW5cjs.multiColorSliders; exports.multiColorToPaint = _chunkTZOX7KWVcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkTZOX7KWVcjs.normalizeBehavior; exports.normalizeBristle = _chunkTZOX7KWVcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkTZOX7KWVcjs.normalizeDynamics; exports.normalizeFlow = _chunkYHDHFJUCcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkTZOX7KWVcjs.normalizeImpasto; exports.normalizeLight = _chunkTZOX7KWVcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkTZOX7KWVcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkTZOX7KWVcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkTZOX7KWVcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkTZOX7KWVcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkTZOX7KWVcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkYHDHFJUCcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkTZOX7KWVcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkTZOX7KWVcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkPYTJBVW5cjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkTZOX7KWVcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkYHDHFJUCcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
13809
+
13810
+
13811
+
13812
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkTZOX7KWVcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkTZOX7KWVcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkPYTJBVW5cjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkTZOX7KWVcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkTZOX7KWVcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkTZOX7KWVcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkTZOX7KWVcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkYHDHFJUCcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkTZOX7KWVcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkTZOX7KWVcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkTZOX7KWVcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkTZOX7KWVcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkTZOX7KWVcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkTZOX7KWVcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkTZOX7KWVcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkYHDHFJUCcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkTZOX7KWVcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkTZOX7KWVcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkTZOX7KWVcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkTZOX7KWVcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkTZOX7KWVcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkTZOX7KWVcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkTZOX7KWVcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkTZOX7KWVcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkTZOX7KWVcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkYHDHFJUCcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkTZOX7KWVcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkYHDHFJUCcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkTZOX7KWVcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkPYTJBVW5cjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkTZOX7KWVcjs.brushTakesPaint; exports.brushToJSON = _chunkTZOX7KWVcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkTZOX7KWVcjs.isWetBrush; exports.isWetCapable = _chunkTZOX7KWVcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkPYTJBVW5cjs.multiColorSliders; exports.multiColorToPaint = _chunkTZOX7KWVcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkTZOX7KWVcjs.normalizeBehavior; exports.normalizeBristle = _chunkTZOX7KWVcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkTZOX7KWVcjs.normalizeDynamics; exports.normalizeFlow = _chunkYHDHFJUCcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkTZOX7KWVcjs.normalizeImpasto; exports.normalizeLight = _chunkTZOX7KWVcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkTZOX7KWVcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkTZOX7KWVcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkTZOX7KWVcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkTZOX7KWVcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkTZOX7KWVcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkYHDHFJUCcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkTZOX7KWVcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkTZOX7KWVcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkPYTJBVW5cjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkTZOX7KWVcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkYHDHFJUCcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;