@pixerate/editor 0.260.0 → 0.262.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/agent/index.cjs +19 -3
  2. package/dist/agent/index.js +21 -5
  3. package/dist/bridge/cli.cjs +4 -3
  4. package/dist/bridge/cli.js +3 -2
  5. package/dist/bridge/index.cjs +4 -3
  6. package/dist/bridge/index.js +3 -2
  7. package/dist/{chunk-KBNCEZZB.cjs → chunk-5NRD76T7.cjs} +9 -7
  8. package/dist/{chunk-SPPDMY7T.js → chunk-6LWEL5DO.js} +4 -2
  9. package/dist/{chunk-RTPBM46F.cjs → chunk-7TD63DZP.cjs} +1 -294
  10. package/dist/{chunk-ABHOYBZD.js → chunk-K4BGRCSH.js} +1 -294
  11. package/dist/chunk-SYEOA5MS.js +301 -0
  12. package/dist/{chunk-5DLCOQOQ.cjs → chunk-YBC3RKT2.cjs} +177 -16
  13. package/dist/chunk-ZEKI6EPI.cjs +301 -0
  14. package/dist/{chunk-UCYW4M66.js → chunk-ZQI3WUPP.js} +163 -2
  15. package/dist/paint-editor/contract.d.cts +11 -0
  16. package/dist/paint-editor/contract.d.ts +11 -0
  17. package/dist/paint-editor/controller.d.cts +17 -0
  18. package/dist/paint-editor/controller.d.ts +17 -0
  19. package/dist/paint-editor/index.cjs +245 -84
  20. package/dist/paint-editor/index.d.cts +2 -1
  21. package/dist/paint-editor/index.d.ts +2 -1
  22. package/dist/paint-editor/index.js +163 -2
  23. package/dist/paint-editor/path-samples.d.cts +19 -0
  24. package/dist/paint-editor/path-samples.d.ts +19 -0
  25. package/dist/paint-editor/ui.d.cts +6 -0
  26. package/dist/paint-editor/ui.d.ts +6 -0
  27. package/dist/tools/conformance.d.cts +138 -0
  28. package/dist/tools/conformance.d.ts +138 -0
  29. package/dist/tools/index.cjs +19 -3
  30. package/dist/tools/index.d.cts +1 -0
  31. package/dist/tools/index.d.ts +1 -0
  32. package/dist/tools/index.js +21 -5
  33. package/package.json +1 -1
  34. package/skills/pixerate-paint-editor/SKILL.md +2 -0
  35. package/skills/pixerate-paint-sketch-to-finish/SKILL.md +5 -1
@@ -21,6 +21,9 @@ var _chunkAVTPZO4Zcjs = require('../chunk-AVTPZO4Z.cjs');
21
21
  var _chunkCBVNCWJMcjs = require('../chunk-CBVNCWJM.cjs');
22
22
 
23
23
 
24
+ var _chunk7TD63DZPcjs = require('../chunk-7TD63DZP.cjs');
25
+
26
+
24
27
 
25
28
 
26
29
 
@@ -150,7 +153,11 @@ var _chunkTZOX7KWVcjs = require('../chunk-TZOX7KWV.cjs');
150
153
 
151
154
  var _chunkJSDND7DFcjs = require('../chunk-JSDND7DF.cjs');
152
155
  require('../chunk-CVFAAZXE.cjs');
153
- require('../chunk-GF2RBSDM.cjs');
156
+
157
+
158
+
159
+
160
+ var _chunkGF2RBSDMcjs = require('../chunk-GF2RBSDM.cjs');
154
161
  require('../chunk-NM3G4VQT.cjs');
155
162
 
156
163
 
@@ -275,6 +282,7 @@ require('../chunk-UWEQ55MY.cjs');
275
282
 
276
283
 
277
284
 
285
+
278
286
  var _chunkSJ2CPTQCcjs = require('../chunk-SJ2CPTQC.cjs');
279
287
  require('../chunk-2BSBFBOA.cjs');
280
288
  require('../chunk-4ZC5QJE2.cjs');
@@ -5221,6 +5229,55 @@ function engineChanges(base, next) {
5221
5229
  return rest;
5222
5230
  }
5223
5231
 
5232
+ // src/paint-editor/path-samples.ts
5233
+ var FLATTEN_TOLERANCE = 0.1;
5234
+ var MAX_PATH_SAMPLES = 2e4;
5235
+ function profileAt(profile, t) {
5236
+ if (profile.length === 1) return profile[0];
5237
+ const at = t * (profile.length - 1);
5238
+ const i = Math.min(profile.length - 2, Math.floor(at));
5239
+ return profile[i] + (profile[i + 1] - profile[i]) * (at - i);
5240
+ }
5241
+ function samplePath(d, options = {}) {
5242
+ const spacing = _nullishCoalesce(options.spacing, () => ( 2));
5243
+ if (!(spacing >= 0.25 && spacing <= 100)) throw new Error(`spacing ${spacing} is out of range; use 0.25..100 document pixels.`);
5244
+ const profile = options.pressure;
5245
+ 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.");
5246
+ let contours;
5247
+ try {
5248
+ contours = _chunkGF2RBSDMcjs.pathToContours.call(void 0, d);
5249
+ } catch (e) {
5250
+ 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".`);
5251
+ }
5252
+ const out = [];
5253
+ for (const contour of contours) {
5254
+ if (!contour.segments.length) continue;
5255
+ const line = _chunkGF2RBSDMcjs.flattenChain.call(void 0, contour.segments, FLATTEN_TOLERANCE);
5256
+ if (contour.closed && line.length) line.push(line[0]);
5257
+ const lengths = [0];
5258
+ 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]));
5259
+ const total = lengths[lengths.length - 1];
5260
+ const n = Math.max(1, Math.ceil(total / spacing));
5261
+ 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))}).`);
5262
+ const points = [];
5263
+ let j = 0;
5264
+ for (let k = 0; k <= n; k++) {
5265
+ const at = total * k / n;
5266
+ while (j < line.length - 2 && lengths[j + 1] < at) j++;
5267
+ const span = lengths[j + 1] - lengths[j] || 1;
5268
+ const f = line.length > 1 ? Math.min(1, Math.max(0, (at - lengths[j]) / span)) : 0;
5269
+ const a = line[j];
5270
+ const b = line[Math.min(j + 1, line.length - 1)];
5271
+ const x = Math.round((a[0] + (b[0] - a[0]) * f) * 1e3) / 1e3;
5272
+ const y = Math.round((a[1] + (b[1] - a[1]) * f) * 1e3) / 1e3;
5273
+ points.push(profile ? { x, y, pressure: Math.round(profileAt(profile, k / n) * 1e3) / 1e3 } : { x, y });
5274
+ }
5275
+ out.push(points);
5276
+ }
5277
+ if (!out.length) throw new Error('path has no segments to brush; give SVG path data such as "M 10 10 L 200 80".');
5278
+ return out;
5279
+ }
5280
+
5224
5281
  // src/paint-editor/live-strokes.ts
5225
5282
  var LIVE_STROKE_ENGINES = ["dab", "particle", "bristle", "mixer"];
5226
5283
  function liveStrokeRefusal(brush) {
@@ -7857,6 +7914,47 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7857
7914
  else this.emit([]);
7858
7915
  return result;
7859
7916
  }
7917
+ /**
7918
+ * Brushes vector path data (SVG `d`, document pixels) with the active brush, or `brushId` /
7919
+ * `brush`, as if drawn by hand: one recorded stroke per subpath, sampled every `spacing` px
7920
+ * with an optional `pressure` profile along each. All of it is one undo step. A given `seed`
7921
+ * seeds the first subpath; the next ones take the following seeds.
7922
+ */
7923
+ strokePath(init) {
7924
+ this.requireIdle("painting");
7925
+ 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".');
7926
+ let subpaths;
7927
+ try {
7928
+ subpaths = samplePath(init.path, init);
7929
+ } catch (e) {
7930
+ throw new PaintEditorError(e instanceof Error ? e.message : String(e));
7931
+ }
7932
+ const { path: _path, spacing: _spacing, pressure: _pressure, ...stroke } = init;
7933
+ const before = this.doc;
7934
+ let doc = this.doc;
7935
+ let bounds = null;
7936
+ let dabs = 0;
7937
+ const strokeIds = [];
7938
+ let last = null;
7939
+ try {
7940
+ subpaths.forEach((points, i) => {
7941
+ last = this.runStroke(doc, { ...stroke, ...stroke.seed !== void 0 ? { seed: stroke.seed + i } : {}, start: points[0] }, points);
7942
+ doc = last.doc;
7943
+ bounds = unionRect(bounds, last.result.bounds);
7944
+ dabs += last.result.dabs;
7945
+ if (last.result.strokeId) strokeIds.push(last.result.strokeId);
7946
+ });
7947
+ } catch (e) {
7948
+ this.wetOp = null;
7949
+ throw e;
7950
+ }
7951
+ const run = last;
7952
+ if (_optionalChain([run, 'optionalAccess', _429 => _429.result, 'access', _430 => _430.mixerLoad])) this.keepLoad(run.brush, run.result.mixerLoad);
7953
+ 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);
7954
+ else this.emit([]);
7955
+ const layerId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([run, 'optionalAccess', _433 => _433.result, 'access', _434 => _434.layerId]), () => ( stroke.layerId)), () => ( this.doc.activeLayerId)), () => ( ""));
7956
+ 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 } : {} };
7957
+ }
7860
7958
  /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
7861
7959
  checkPoints(points) {
7862
7960
  if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
@@ -7878,7 +7976,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7878
7976
  */
7879
7977
  replayStrokes(options) {
7880
7978
  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.");
7979
+ if (!_optionalChain([options, 'access', _439 => _439.strokeIds, 'optionalAccess', _440 => _440.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7882
7980
  const strokes = options.strokeIds.map((id) => {
7883
7981
  const s = this.doc.strokes.find((x) => x.id === id);
7884
7982
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -7892,7 +7990,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7892
7990
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
7893
7991
  if (options.color === void 0) {
7894
7992
  for (const s of strokes) {
7895
- if (_optionalChain([s, 'access', _431 => _431.paint, 'optionalAccess', _432 => _432.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7993
+ if (_optionalChain([s, 'access', _441 => _441.paint, 'optionalAccess', _442 => _442.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7896
7994
  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
7995
  }
7898
7996
  }
@@ -7950,7 +8048,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7950
8048
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
7951
8049
  lightOf(layerId) {
7952
8050
  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]]));
8051
+ const info = lightInfo(_optionalChain([this, 'access', _443 => _443.doc, 'access', _444 => _444.light, 'optionalAccess', _445 => _445[l.id]]));
7954
8052
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
7955
8053
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
7956
8054
  }
@@ -8001,7 +8099,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8001
8099
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8002
8100
  if (!id) return null;
8003
8101
  this.requireLayer(id);
8004
- const ch = _optionalChain([this, 'access', _436 => _436.doc, 'access', _437 => _437.thick, 'optionalAccess', _438 => _438[id]]);
8102
+ const ch = _optionalChain([this, 'access', _446 => _446.doc, 'access', _447 => _447.thick, 'optionalAccess', _448 => _448[id]]);
8005
8103
  if (!ch) return null;
8006
8104
  const r = reliefInfo(ch);
8007
8105
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -8111,7 +8209,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8111
8209
  wetState() {
8112
8210
  const st = this.getState().wet;
8113
8211
  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() };
8212
+ 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
8213
  }
8116
8214
  /**
8117
8215
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -8196,7 +8294,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8196
8294
  }
8197
8295
  /** Records a settings change as a wet event (not an undo step). */
8198
8296
  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 }] };
8297
+ 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
8298
  }
8201
8299
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
8202
8300
  setWetParams(layerId, update) {
@@ -8265,7 +8363,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8265
8363
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkPVJMTLPJcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
8266
8364
  const live = this.live;
8267
8365
  if (!live) return this.animatedView();
8268
- if (_optionalChain([this, 'access', _443 => _443.liveLayers, 'optionalAccess', _444 => _444.key]) === live.surface) return this.liveLayers.layers;
8366
+ if (_optionalChain([this, 'access', _453 => _453.liveLayers, 'optionalAccess', _454 => _454.key]) === live.surface) return this.liveLayers.layers;
8269
8367
  const layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
8270
8368
  this.liveLayers = { key: live.surface, layers };
8271
8369
  return layers;
@@ -8288,7 +8386,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8288
8386
  tracingNode(t) {
8289
8387
  const { width, height } = this.doc.canvas;
8290
8388
  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;
8389
+ if (_optionalChain([this, 'access', _455 => _455.tracingCache, 'optionalAccess', _456 => _456.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8292
8390
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
8293
8391
  const image = resampleInto(src, t.rect, width, height);
8294
8392
  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 +8413,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8315
8413
  let out = layers;
8316
8414
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
8317
8415
  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]);
8416
+ const ch = _optionalChain([live, 'optionalAccess', _457 => _457.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _458 => _458[id]]);
8417
+ const l = ch && _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _459 => _459.layer]);
8320
8418
  if (!ch || !isPixelLayer(l)) continue;
8321
8419
  let cache = this.litCaches.get(id);
8322
8420
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -8336,13 +8434,13 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8336
8434
  if (!ids.size) return layers;
8337
8435
  let out = layers;
8338
8436
  for (const id of ids) {
8339
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _450 => _450.layer]);
8437
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, out, id), 'optionalAccess', _460 => _460.layer]);
8340
8438
  if (!isPixelLayer(l)) continue;
8341
8439
  let cache = this.lightCaches.get(id);
8342
8440
  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]]));
8441
+ 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
8442
  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]);
8443
+ const committed = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _466 => _466.layer]);
8346
8444
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
8347
8445
  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
8446
  }
@@ -8354,7 +8452,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8354
8452
  if (!l.visible) continue;
8355
8453
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
8356
8454
  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]]);
8455
+ 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
8456
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
8359
8457
  }
8360
8458
  }
@@ -8383,7 +8481,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8383
8481
  if (backlight) layers = [...layers, backlight];
8384
8482
  if (options.layerIds) {
8385
8483
  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))));
8484
+ 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
8485
  layers = picked.map((l) => ({ ...l, visible: true }));
8388
8486
  }
8389
8487
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -8399,7 +8497,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8399
8497
  */
8400
8498
  compositeTiles(rect, onTile, options = {}) {
8401
8499
  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)) });
8500
+ 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
8501
  }
8404
8502
  /** The canvas as canvas-sized RGBA (paper included by default). */
8405
8503
  compositePixels(options = {}) {
@@ -8478,7 +8576,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8478
8576
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id)));
8479
8577
  if (Object.keys(spills).length) ext.lightSpill = spills;
8480
8578
  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])));
8579
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _475 => _475.layer])));
8482
8580
  if (effectLayers) ext.effectLayers = effectLayers;
8483
8581
  else delete ext.effectLayers;
8484
8582
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -8514,7 +8612,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8514
8612
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
8515
8613
  const liveStrokes = {};
8516
8614
  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;
8615
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _476 => _476.layer])) || !Array.isArray(list)) continue;
8518
8616
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
8519
8617
  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
8618
  liveStrokes[id] = ok;
@@ -8524,7 +8622,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8524
8622
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
8525
8623
  const effectLayers = {};
8526
8624
  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;
8625
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _477 => _477.layer]))) continue;
8528
8626
  const source = readPaintEffectSource(v);
8529
8627
  if (source) effectLayers[id] = source;
8530
8628
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -8552,7 +8650,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8552
8650
  if (ext.light && typeof ext.light === "object") {
8553
8651
  const light = {};
8554
8652
  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;
8653
+ if (!isPixelLayer(_optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _478 => _478.layer]))) continue;
8556
8654
  try {
8557
8655
  light[id] = lightFromJSON(v);
8558
8656
  } catch (e) {
@@ -8588,7 +8686,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8588
8686
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
8589
8687
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
8590
8688
  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)));
8689
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _479 => _479.exec, 'call', _480 => _480(s.id), 'optionalAccess', _481 => _481[1]]), () => ( 0)));
8592
8690
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8593
8691
  }
8594
8692
  this.undoStack = [];
@@ -8596,7 +8694,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8596
8694
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
8597
8695
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
8598
8696
  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)));
8697
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _482 => _482.exec, 'call', _483 => _483(s.id), 'optionalAccess', _484 => _484[1]]), () => ( 0)));
8600
8698
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8601
8699
  }
8602
8700
  }
@@ -8695,8 +8793,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8695
8793
  const layers = toStandard(dried);
8696
8794
  const result = _chunk43NT242Dcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
8697
8795
  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)));
8796
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _485 => _485.find, 'call', _486 => _486((m) => m.id === mode), 'optionalAccess', _487 => _487.label]), () => ( mode));
8797
+ 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
8798
  const list = names.map((n) => `"${n}"`).join(", ");
8701
8799
  const one = names.length === 1;
8702
8800
  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 +8916,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8818
8916
  const { src, pixels } = this.importImage(options, "The reference image");
8819
8917
  const ref2 = {
8820
8918
  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}`,
8919
+ name: _optionalChain([options, 'access', _491 => _491.name, 'optionalAccess', _492 => _492.trim, 'call', _493 => _493()]) || `Reference ${this.guides.references.length + 1}`,
8822
8920
  src,
8823
8921
  width: pixels.width,
8824
8922
  height: pixels.height,
@@ -8897,7 +8995,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8897
8995
  try {
8898
8996
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
8899
8997
  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)));
8998
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _494 => _494.exec, 'call', _495 => _495(ref2.id), 'optionalAccess', _496 => _496[1]]), () => ( 0)));
8901
8999
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
8902
9000
  } catch (e) {
8903
9001
  problems.push(e.message);
@@ -8908,7 +9006,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8908
9006
  guides.stencils = [];
8909
9007
  r.stencils.forEach((raw2, i) => {
8910
9008
  try {
8911
- const id = typeof _optionalChain([raw2, 'optionalAccess', _487 => _487.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
9009
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _497 => _497.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
8912
9010
  guides.stencils.push(normalizeStencil(raw2, id));
8913
9011
  const n = Number(id.slice(7));
8914
9012
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -8931,12 +9029,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8931
9029
  /** The next free sticker number (ids `st<n>` are unique across the document). */
8932
9030
  nextStickerNumber(doc = this.doc) {
8933
9031
  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))));
9032
+ 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
9033
  return n + 1;
8936
9034
  }
8937
9035
  stickerLayer(layerId) {
8938
9036
  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]]);
9037
+ const stickers = _optionalChain([this, 'access', _501 => _501.doc, 'access', _502 => _502.stickers, 'optionalAccess', _503 => _503[l.id]]);
8940
9038
  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
9039
  return { layer: l, stickers };
8942
9040
  }
@@ -8995,7 +9093,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8995
9093
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8996
9094
  if (!id) return [];
8997
9095
  this.requireLayer(id);
8998
- return (_nullishCoalesce(_optionalChain([this, 'access', _494 => _494.doc, 'access', _495 => _495.stickers, 'optionalAccess', _496 => _496[id]]), () => ( []))).map((s) => ({ ...s }));
9096
+ return (_nullishCoalesce(_optionalChain([this, 'access', _504 => _504.doc, 'access', _505 => _505.stickers, 'optionalAccess', _506 => _506[id]]), () => ( []))).map((s) => ({ ...s }));
8999
9097
  }
9000
9098
  /**
9001
9099
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -9016,7 +9114,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9016
9114
  }
9017
9115
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
9018
9116
  previewBase() {
9019
- return _optionalChain([this, 'access', _497 => _497.stickerPreview, 'optionalAccess', _498 => _498.shown]) === this.doc ? this.stickerPreview.base : null;
9117
+ return _optionalChain([this, 'access', _507 => _507.stickerPreview, 'optionalAccess', _508 => _508.shown]) === this.doc ? this.stickerPreview.base : null;
9020
9118
  }
9021
9119
  readStickerUpdate(update) {
9022
9120
  try {
@@ -9031,7 +9129,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9031
9129
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
9032
9130
  if (!id) return null;
9033
9131
  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);
9132
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _509 => _509.doc, 'access', _510 => _510.stickers, 'optionalAccess', _511 => _511[id]]), () => ( [])), x, y, this.stickerArt.get);
9035
9133
  return hit ? { ...hit } : null;
9036
9134
  }
9037
9135
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -9087,8 +9185,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9087
9185
  const layer = this.wetLayer(layerId, "add stickers to");
9088
9186
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
9089
9187
  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])) {
9188
+ const existing = _optionalChain([this, 'access', _512 => _512.doc, 'access', _513 => _513.stickers, 'optionalAccess', _514 => _514[layer.id]]);
9189
+ if (!_optionalChain([existing, 'optionalAccess', _515 => _515.length])) {
9092
9190
  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
9191
  }
9094
9192
  let n = this.nextStickerNumber();
@@ -9105,7 +9203,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9105
9203
  const id = n++;
9106
9204
  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
9205
  });
9108
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _506 => _506.length]) ? added.map(stickerRect) : void 0);
9206
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _516 => _516.length]) ? added.map(stickerRect) : void 0);
9109
9207
  return added.map((s) => ({ ...s }));
9110
9208
  }
9111
9209
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -9144,20 +9242,20 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9144
9242
  }
9145
9243
  liveStrokeLayer(layerId, what) {
9146
9244
  const l = this.wetLayer(layerId, what);
9147
- const strokes = _optionalChain([this, 'access', _507 => _507.doc, 'access', _508 => _508.liveStrokes, 'optionalAccess', _509 => _509[l.id]]);
9245
+ const strokes = _optionalChain([this, 'access', _517 => _517.doc, 'access', _518 => _518.liveStrokes, 'optionalAccess', _519 => _519[l.id]]);
9148
9246
  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
9247
  return { layer: l, strokes };
9150
9248
  }
9151
9249
  /** Whether a layer is a live stroke layer. */
9152
9250
  isLiveStrokeLayer(layerId) {
9153
- return Boolean(_optionalChain([this, 'access', _510 => _510.doc, 'access', _511 => _511.liveStrokes, 'optionalAccess', _512 => _512[layerId]]));
9251
+ return Boolean(_optionalChain([this, 'access', _520 => _520.doc, 'access', _521 => _521.liveStrokes, 'optionalAccess', _522 => _522[layerId]]));
9154
9252
  }
9155
9253
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
9156
9254
  convertToLiveStrokes(layerId) {
9157
9255
  this.requireIdle("converting a layer");
9158
9256
  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"}).`);
9257
+ if (_optionalChain([this, 'access', _523 => _523.doc, 'access', _524 => _524.liveStrokes, 'optionalAccess', _525 => _525[l.id]])) return this.describeLayer(l);
9258
+ 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
9259
  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
9260
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
9163
9261
  return this.describeLayer(this.getLayer(l.id));
@@ -9170,7 +9268,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9170
9268
  findLiveStroke(id) {
9171
9269
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
9172
9270
  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]);
9271
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _530 => _530.layer]);
9174
9272
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
9175
9273
  }
9176
9274
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -9265,9 +9363,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9265
9363
  const layers = /* @__PURE__ */ new Map();
9266
9364
  for (const f of found) layers.set(f.layer.id, f.layer);
9267
9365
  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));
9366
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _531 => _531.liveStrokes, 'optionalAccess', _532 => _532[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9269
9367
  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));
9368
+ 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
9369
  }
9272
9370
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
9273
9371
  return { removed: [...ids], bounds };
@@ -9335,7 +9433,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9335
9433
  }
9336
9434
  withLiveStrokes(doc, layer, list, dirty) {
9337
9435
  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]);
9436
+ const current = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _535 => _535.layer]);
9339
9437
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
9340
9438
  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
9439
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
@@ -9413,7 +9511,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9413
9511
  if (!this.animatedLayers.size) return this.doc.layers;
9414
9512
  let layers = this.doc.layers;
9415
9513
  for (const [id, a] of this.animatedLayers) {
9416
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _526 => _526.layer]);
9514
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _536 => _536.layer]);
9417
9515
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkPVJMTLPJcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
9418
9516
  }
9419
9517
  return layers;
@@ -9423,7 +9521,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9423
9521
  const layers = [];
9424
9522
  const sources = /* @__PURE__ */ new Map();
9425
9523
  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]);
9524
+ const layer = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _537 => _537.layer]);
9427
9525
  const live = strokes.filter(isLiveEffect);
9428
9526
  if (!isPixelLayer(layer) || !live.length) continue;
9429
9527
  layers.push({ layer, strokes });
@@ -9554,7 +9652,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9554
9652
  stencilSelection(stencils = this.guides.stencils) {
9555
9653
  const { width, height } = this.doc.canvas;
9556
9654
  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;
9655
+ if (_optionalChain([this, 'access', _538 => _538.stencilCache, 'optionalAccess', _539 => _539.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9558
9656
  const mask = stencilMask(stencils, width, height);
9559
9657
  this.stencilCache = { key: stencils, size, mask };
9560
9658
  return mask;
@@ -9616,7 +9714,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9616
9714
  makeSwatch(color, name) {
9617
9715
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
9618
9716
  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();
9717
+ if (_optionalChain([name, 'optionalAccess', _540 => _540.trim, 'call', _541 => _541()])) out.name = name.trim();
9620
9718
  if (p.type === "gradient") out.paint = p;
9621
9719
  return out;
9622
9720
  }
@@ -9668,7 +9766,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9668
9766
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
9669
9767
  */
9670
9768
  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]) }));
9769
+ 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
9770
  let r;
9673
9771
  try {
9674
9772
  r = this.pad.mix(parsed, options);
@@ -9757,7 +9855,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9757
9855
  }
9758
9856
  /** A layer's tile surface (live while stroking), for thumbnails. */
9759
9857
  layerSurface(id) {
9760
- const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _534 => _534.layer]);
9858
+ const l = _optionalChain([_chunkPVJMTLPJcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _544 => _544.layer]);
9761
9859
  return isPixelLayer(l) ? l.surface : null;
9762
9860
  }
9763
9861
  }, _class19.__initStatic(), _class19);
@@ -9779,7 +9877,7 @@ function insertAfter(layers, id, node) {
9779
9877
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
9780
9878
  }
9781
9879
  function isLiveEffect(s) {
9782
- return _optionalChain([s, 'access', _535 => _535.paint, 'optionalAccess', _536 => _536.type]) === "effect" && s.paint.live === true;
9880
+ return _optionalChain([s, 'access', _545 => _545.paint, 'optionalAccess', _546 => _546.type]) === "effect" && s.paint.live === true;
9783
9881
  }
9784
9882
  function framePaint(p, t) {
9785
9883
  return { ...p, time: p.time + t };
@@ -9804,7 +9902,7 @@ function clipRect(r, width, height) {
9804
9902
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
9805
9903
  }
9806
9904
  function withLiveStroke(doc, stroke) {
9807
- const list = _optionalChain([doc, 'access', _537 => _537.liveStrokes, 'optionalAccess', _538 => _538[stroke.layerId]]);
9905
+ const list = _optionalChain([doc, 'access', _547 => _547.liveStrokes, 'optionalAccess', _548 => _548[stroke.layerId]]);
9808
9906
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
9809
9907
  }
9810
9908
  function shiftDocument(doc, dx, dy) {
@@ -9831,9 +9929,9 @@ function shiftDocument(doc, dx, dy) {
9831
9929
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
9832
9930
  if (doc.paintEvents) {
9833
9931
  out.paintEvents = doc.paintEvents.map((e) => {
9834
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _539 => _539.data, 'optionalAccess', _540 => _540.stickers]) : void 0;
9932
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _549 => _549.data, 'optionalAccess', _550 => _550.stickers]) : void 0;
9835
9933
  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;
9934
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _551 => _551.data, 'optionalAccess', _552 => _552.strokes]) : void 0;
9837
9935
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
9838
9936
  });
9839
9937
  }
@@ -9922,8 +10020,8 @@ function strokeSchedule(points) {
9922
10020
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
9923
10021
  }
9924
10022
  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]);
10023
+ const t0 = _optionalChain([points, 'access', _553 => _553[0], 'optionalAccess', _554 => _554.t]);
10024
+ const t1 = _optionalChain([points, 'access', _555 => _555[points.length - 1], 'optionalAccess', _556 => _556.t]);
9927
10025
  let ms;
9928
10026
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
9929
10027
  else {
@@ -9977,7 +10075,7 @@ var PaintDirector = class {
9977
10075
  }
9978
10076
  where(id) {
9979
10077
  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)) };
10078
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _557 => _557.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _558 => _558.y]), () => ( 0)) };
9981
10079
  }
9982
10080
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
9983
10081
  async glide(id, to, ms = 380) {
@@ -10024,8 +10122,8 @@ var PaintDirector = class {
10024
10122
  }
10025
10123
  case "replay": {
10026
10124
  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]]);
10125
+ 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)]));
10126
+ const first = _optionalChain([source, 'access', _563 => _563[0], 'optionalAccess', _564 => _564.points, 'access', _565 => _565[0]]);
10029
10127
  if (first) await this.glide(id, first);
10030
10128
  const result = c.replayStrokes(command.replay);
10031
10129
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -11462,7 +11560,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11462
11560
  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
11561
  annotations: { title: "Set the brush", ...SET4 },
11464
11562
  handler: async ({ id, unset, ...patch }) => {
11465
- const stamps = _optionalChain([patch, 'access', _556 => _556.tip, 'optionalAccess', _557 => _557.stamps]);
11563
+ const stamps = _optionalChain([patch, 'access', _566 => _566.tip, 'optionalAccess', _567 => _567.stamps]);
11466
11564
  if (stamps) await c.prepareStickers(stamps);
11467
11565
  const r = c.setBrushFacets(patch, id, unset);
11468
11566
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -11579,6 +11677,41 @@ function createPaintEditorToolProvider(controller, options = {}) {
11579
11677
  return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11580
11678
  }
11581
11679
  });
11680
+ add({
11681
+ name: "stroke_path",
11682
+ title: "Brush along a path",
11683
+ 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).",
11684
+ inputSchema: {
11685
+ type: "object",
11686
+ properties: {
11687
+ 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.' },
11688
+ 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." },
11689
+ 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." },
11690
+ layerId: LAYER_ID4,
11691
+ brushId: { type: "string", description: "Brush id from list_brush_presets (default the active brush)." },
11692
+ 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 },
11693
+ color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
11694
+ 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." },
11695
+ 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." }
11696
+ },
11697
+ required: ["path"],
11698
+ additionalProperties: false
11699
+ },
11700
+ annotations: { title: "Brush along a path", ...WRITE5 },
11701
+ coordinates: { out: ["bounds"] },
11702
+ handler: async (a) => {
11703
+ await c.wetIdle();
11704
+ const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
11705
+ const brush = a.brush ? c.brushChanges(a.brush, a.brushId) : void 0;
11706
+ if (base) {
11707
+ const refs = brushStickerRefs(_chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, { ..._nullishCoalesce(brush, () => ( {})), id: base.id }, base));
11708
+ if (refs.length) await c.prepareStickers(refs);
11709
+ }
11710
+ 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;
11711
+ 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 });
11712
+ return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11713
+ }
11714
+ });
11582
11715
  add({
11583
11716
  name: "get_live_stroke",
11584
11717
  title: "Get the stroke being painted",
@@ -11622,7 +11755,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11622
11755
  if (ids) {
11623
11756
  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
11757
  }
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)) };
11758
+ 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
11759
  }
11627
11760
  });
11628
11761
  add({
@@ -11931,16 +12064,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
11931
12064
  }
11932
12065
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
11933
12066
  if (!origin && !onChange) return tool;
11934
- const write = !_optionalChain([tool, 'access', _563 => _563.annotations, 'optionalAccess', _564 => _564.readOnlyHint]);
12067
+ const write = !_optionalChain([tool, 'access', _573 => _573.annotations, 'optionalAccess', _574 => _574.readOnlyHint]);
11935
12068
  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;
12069
+ if (write) _optionalChain([onChange, 'optionalCall', _575 => _575({ tool: tool.name })]);
12070
+ return origin && _optionalChain([coordinates, 'optionalAccess', _576 => _576.out]) ? fromDocument(result, coordinates.out, origin) : result;
11938
12071
  };
11939
12072
  return {
11940
12073
  ...tool,
11941
12074
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
11942
12075
  handler: (args, context) => {
11943
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _567 => _567.in]) ? toDocument(args, coordinates.in, origin) : args, context);
12076
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _577 => _577.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11944
12077
  return r instanceof Promise ? r.then(done) : done(r);
11945
12078
  }
11946
12079
  };
@@ -11957,7 +12090,7 @@ function strokeSummary(s, withPoints, live) {
11957
12090
  color: s.color,
11958
12091
  points: withPoints ? s.points : s.points.length,
11959
12092
  seed: s.seed,
11960
- copies: _nullishCoalesce(_optionalChain([s, 'access', _568 => _568.copies, 'optionalAccess', _569 => _569.length]), () => ( 0)),
12093
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _578 => _578.copies, 'optionalAccess', _579 => _579.length]), () => ( 0)),
11961
12094
  live,
11962
12095
  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
12096
  };
@@ -12055,13 +12188,13 @@ var PaintGesture = (_class20 = class {
12055
12188
  const p = this.doc(e);
12056
12189
  const s = this.controller.getState();
12057
12190
  const layerId = s.document.activeLayerId;
12058
- if (!layerId || !_optionalChain([s, 'access', _570 => _570.document, 'access', _571 => _571.liveStrokes, 'optionalAccess', _572 => _572[layerId]])) {
12191
+ if (!layerId || !_optionalChain([s, 'access', _580 => _580.document, 'access', _581 => _581.liveStrokes, 'optionalAccess', _582 => _582[layerId]])) {
12059
12192
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
12060
12193
  return false;
12061
12194
  }
12062
12195
  try {
12063
12196
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
12064
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _573 => _573.id]), () => ( null)));
12197
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _583 => _583.id]), () => ( null)));
12065
12198
  if (!hit) return false;
12066
12199
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
12067
12200
  return true;
@@ -12073,7 +12206,7 @@ var PaintGesture = (_class20 = class {
12073
12206
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
12074
12207
  get strokeDrag() {
12075
12208
  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;
12209
+ 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
12210
  }
12078
12211
  /**
12079
12212
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -12147,7 +12280,7 @@ var PaintGesture = (_class20 = class {
12147
12280
  if (!m || m.pointerId !== e.pointerId) return;
12148
12281
  this.mode = null;
12149
12282
  this.predicted = [];
12150
- if (m.kind === "stroke") _optionalChain([this, 'access', _575 => _575.controller, 'access', _576 => _576.activeStroke, 'optionalAccess', _577 => _577.end, 'call', _578 => _578()]);
12283
+ if (m.kind === "stroke") _optionalChain([this, 'access', _585 => _585.controller, 'access', _586 => _586.activeStroke, 'optionalAccess', _587 => _587.end, 'call', _588 => _588()]);
12151
12284
  if (m.kind === "move-stroke") {
12152
12285
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
12153
12286
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -12171,8 +12304,8 @@ var PaintGesture = (_class20 = class {
12171
12304
  cancel() {
12172
12305
  this.penDown = false;
12173
12306
  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();
12307
+ 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()]);
12308
+ if (_optionalChain([this, 'access', _595 => _595.mode, 'optionalAccess', _596 => _596.kind]) === "sticker") this.controller.cancelStickerPreview();
12176
12309
  this.mode = null;
12177
12310
  }
12178
12311
  get active() {
@@ -12275,7 +12408,7 @@ function guideOverlay(controller, drag) {
12275
12408
  const size = s.document.canvas;
12276
12409
  const out = [];
12277
12410
  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;
12411
+ 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
12412
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
12280
12413
  if (area) {
12281
12414
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -12288,7 +12421,7 @@ function guideOverlay(controller, drag) {
12288
12421
  ];
12289
12422
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
12290
12423
  }
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;
12424
+ 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
12425
  if (picked) {
12293
12426
  const r = picked.size / 2 + 2;
12294
12427
  const a = picked.rotation * Math.PI / 180;
@@ -12318,7 +12451,7 @@ var PAPER_SLIDERS = [
12318
12451
  ];
12319
12452
  function readPath(obj, path) {
12320
12453
  let v = obj;
12321
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _597 => _597[k]]);
12454
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _607 => _607[k]]);
12322
12455
  return typeof v === "number" ? v : 0;
12323
12456
  }
12324
12457
  function patchPath(obj, path, value) {
@@ -12434,7 +12567,7 @@ function startWetClock(controller, frame, cancel) {
12434
12567
  id = raf(loop);
12435
12568
  return () => {
12436
12569
  stopped = true;
12437
- _optionalChain([caf, 'optionalCall', _598 => _598(id)]);
12570
+ _optionalChain([caf, 'optionalCall', _608 => _608(id)]);
12438
12571
  };
12439
12572
  }
12440
12573
  function drawWaterOverlay(controller, ctx) {
@@ -12480,6 +12613,12 @@ function toggleDotTexture(textures, stamp) {
12480
12613
  if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
12481
12614
  return textures.length < _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
12482
12615
  }
12616
+ var PATH_STROKE_TAPERS = [
12617
+ { id: "even", label: "Even" },
12618
+ { id: "both", label: "Taper both ends", pressure: [0.2, 1, 0.2] },
12619
+ { id: "in", label: "Fade in", pressure: [0.2, 1] },
12620
+ { id: "out", label: "Fade out", pressure: [1, 0.2] }
12621
+ ];
12483
12622
  var STROKE_SLIDERS = [
12484
12623
  { path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
12485
12624
  { path: "tip.opacity", label: "Opacity", min: 0, max: 1, step: 0.01 },
@@ -12786,7 +12925,7 @@ function createPaintChangeFeed(controller, options = {}) {
12786
12925
  const doc = state.document;
12787
12926
  const layers = /* @__PURE__ */ new Map();
12788
12927
  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 };
12928
+ 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
12929
  };
12791
12930
  let last = take();
12792
12931
  const check = () => {
@@ -12817,7 +12956,7 @@ function createPaintChangeFeed(controller, options = {}) {
12817
12956
  if (edited) pending = void 0;
12818
12957
  const change = {
12819
12958
  seq: ++seq,
12820
- origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _601 => _601.origin]), () => ( "user")),
12959
+ origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _611 => _611.origin]), () => ( "user")),
12821
12960
  ...commit ? { commit } : {},
12822
12961
  addedStrokes,
12823
12962
  removedStrokes,
@@ -12884,7 +13023,7 @@ function createPaintProposals(options) {
12884
13023
  };
12885
13024
  const strokeIds = () => new Set(controller.getStrokes().map((s) => s.id));
12886
13025
  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.");
13026
+ 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
13027
  if (!Array.isArray(input.ops) || !input.ops.length) throw new PaintEditorError("A proposal needs at least one op (stroke, wash or echo).");
12889
13028
  const place = _nullishCoalesce(input.place, () => ( "top"));
12890
13029
  if (place === "above") {
@@ -12896,7 +13035,7 @@ function createPaintProposals(options) {
12896
13035
  input.ops.forEach((op, i) => {
12897
13036
  const at = `ops[${i}]`;
12898
13037
  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.`);
13038
+ if (!_optionalChain([op, 'access', _615 => _615.points, 'optionalAccess', _616 => _616.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12900
13039
  points += op.points.length;
12901
13040
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
12902
13041
  const brush = op.brushId ? controller.getBrush(op.brushId) : controller.getState().brush;
@@ -12908,7 +13047,7 @@ function createPaintProposals(options) {
12908
13047
  if (!HEX4.test(_nullishCoalesce(op.color, () => ( "")))) throw new PaintEditorError(`${at}: a wash needs color as #rrggbb.`);
12909
13048
  if (op.opacity !== void 0 && !(op.opacity > 0 && op.opacity <= 1)) throw new PaintEditorError(`${at}: opacity must be in (0, 1].`);
12910
13049
  } 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).`);
13050
+ if (!_optionalChain([op, 'access', _617 => _617.strokeIds, 'optionalAccess', _618 => _618.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12912
13051
  const unknown = op.strokeIds.filter((id) => !known.has(id));
12913
13052
  if (unknown.length) throw new PaintEditorError(`${at}: unknown stroke ${unknown.map((u) => `"${u}"`).join(", ")}. Call list_strokes for the ids.`);
12914
13053
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
@@ -12957,7 +13096,7 @@ function createPaintProposals(options) {
12957
13096
  ...input.layerId ? { layerId: input.layerId } : {},
12958
13097
  ...input.layerName ? { layerName: input.layerName } : {}
12959
13098
  });
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]);
13099
+ 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
13100
  return {
12962
13101
  getState: () => state,
12963
13102
  subscribe(listener) {
@@ -13144,7 +13283,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13144
13283
  },
13145
13284
  annotations: { title: "Propose paint", ...WRITE6 },
13146
13285
  handler: (args, context) => {
13147
- const origin = _optionalChain([context, 'access', _614 => _614.actor, 'optionalAccess', _615 => _615.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13286
+ const origin = _optionalChain([context, 'access', _624 => _624.actor, 'optionalAccess', _625 => _625.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13148
13287
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
13149
13288
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
13150
13289
  return { proposalId: proposal.id, ...rest };
@@ -13270,6 +13409,7 @@ function uiTables() {
13270
13409
  blendMenu: BLEND_MENU_GROUPS,
13271
13410
  layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_MENU.map(({ kind, label }) => ({ kind, label, controls: _chunkPVJMTLPJcjs.layerEffectControls.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, kind)) })),
13272
13411
  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 },
13412
+ pathStrokeTapers: PATH_STROKE_TAPERS,
13273
13413
  padSampleSizes: PAD_SAMPLE_SIZES,
13274
13414
  wetGpu: WET_GPU_OPTIONS,
13275
13415
  labels: {
@@ -13310,6 +13450,27 @@ function paintContracts(options) {
13310
13450
  };
13311
13451
  return files;
13312
13452
  }
13453
+ var GENERATED_ID = /^(pl[0-9a-z]{9,}|[a-z]+_[0-9a-z]{8,}_[0-9a-z]+)$/;
13454
+ function createPaintConformanceHost(setup, options) {
13455
+ const controller = new PaintEditorController({ ...setup, wet: { kernel: "typescript", threads: 0, gpu: "off", ...setup.wet } });
13456
+ controller.setEffectsProvider(options.effects);
13457
+ const registry = new (0, _chunk7TD63DZPcjs.ToolRegistry)({ validateArguments: true });
13458
+ registry.register(createPaintEditorToolProvider(controller));
13459
+ registry.register(createPaintEffectsToolProvider(controller));
13460
+ registry.register(createPaintBrushLibraryToolProvider(controller));
13461
+ registry.register(createPaintProposalToolProvider(createPaintProposals({ controller })));
13462
+ return {
13463
+ callTool: (name, args) => registry.callTool(name, args),
13464
+ document: () => _chunkSJ2CPTQCcjs.toEditorDocumentFile.call(void 0, createPaintEditorDocument(controller)),
13465
+ pixels: ({ paper }) => controller.compositePixels({ paper }),
13466
+ isGeneratedId: (value) => GENERATED_ID.test(value),
13467
+ dispose: () => controller.dispose()
13468
+ };
13469
+ }
13470
+
13471
+
13472
+
13473
+
13313
13474
 
13314
13475
 
13315
13476
 
@@ -13670,4 +13831,4 @@ function paintContracts(options) {
13670
13831
 
13671
13832
 
13672
13833
 
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;
13834
+ 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.createPaintConformanceHost = createPaintConformanceHost; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = 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;