@pixerate/editor 0.107.0 → 0.109.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 (78) hide show
  1. package/THIRD_PARTY_NOTICES.md +4 -0
  2. package/dist/animation/index.cjs +5 -5
  3. package/dist/animation/index.cjs.map +1 -1
  4. package/dist/animation/index.js +9 -9
  5. package/dist/animation-editor/index.cjs +59 -59
  6. package/dist/animation-editor/index.cjs.map +1 -1
  7. package/dist/animation-editor/index.d.cts +2 -1
  8. package/dist/animation-editor/index.d.ts +2 -1
  9. package/dist/animation-editor/index.js +29 -29
  10. package/dist/canvas/index.cjs +27 -27
  11. package/dist/canvas/index.cjs.map +1 -1
  12. package/dist/canvas/index.js +11 -11
  13. package/dist/{chunk-2FGRTYJN.cjs → chunk-477UVMNR.cjs} +3 -3
  14. package/dist/{chunk-2FGRTYJN.cjs.map → chunk-477UVMNR.cjs.map} +1 -1
  15. package/dist/{chunk-T3QZ6S47.cjs → chunk-AZTZRLDI.cjs} +40 -2
  16. package/dist/chunk-AZTZRLDI.cjs.map +1 -0
  17. package/dist/{chunk-63EFQCT5.js → chunk-BLWCAQCW.js} +2879 -3362
  18. package/dist/chunk-BLWCAQCW.js.map +1 -0
  19. package/dist/{chunk-G4BIYE6R.js → chunk-CFMWALBM.js} +39 -1
  20. package/dist/chunk-CFMWALBM.js.map +1 -0
  21. package/dist/{chunk-FRD3FUXI.cjs → chunk-D37BX2ZA.cjs} +2081 -460
  22. package/dist/chunk-D37BX2ZA.cjs.map +1 -0
  23. package/dist/chunk-JLYX4V57.cjs +2001 -0
  24. package/dist/chunk-JLYX4V57.cjs.map +1 -0
  25. package/dist/chunk-KB2YBCVS.js +2001 -0
  26. package/dist/chunk-KB2YBCVS.js.map +1 -0
  27. package/dist/{chunk-SOROZ2BF.js → chunk-RE77QYUF.js} +1938 -317
  28. package/dist/chunk-RE77QYUF.js.map +1 -0
  29. package/dist/{chunk-KANRAHTL.cjs → chunk-W3GXSUSQ.cjs} +2830 -3313
  30. package/dist/chunk-W3GXSUSQ.cjs.map +1 -0
  31. package/dist/{chunk-JK6M6V7G.js → chunk-Z3YWVUWT.js} +4 -4
  32. package/dist/{export-a9bnF7Cl.d.ts → export-BLPLaE6Z.d.ts} +417 -16
  33. package/dist/{export-JGWQEPJn.d.cts → export-DSUc4fQD.d.cts} +417 -16
  34. package/dist/image-editor/index.cjs +1527 -1001
  35. package/dist/image-editor/index.cjs.map +1 -1
  36. package/dist/image-editor/index.d.cts +73 -9
  37. package/dist/image-editor/index.d.ts +73 -9
  38. package/dist/image-editor/index.js +814 -288
  39. package/dist/image-editor/index.js.map +1 -1
  40. package/dist/paint-editor/index.cjs +252 -64
  41. package/dist/paint-editor/index.cjs.map +1 -1
  42. package/dist/paint-editor/index.d.cts +101 -4
  43. package/dist/paint-editor/index.d.ts +101 -4
  44. package/dist/paint-editor/index.js +196 -8
  45. package/dist/paint-editor/index.js.map +1 -1
  46. package/dist/raster/index.cjs +4 -2
  47. package/dist/raster/index.cjs.map +1 -1
  48. package/dist/raster/index.d.cts +3 -129
  49. package/dist/raster/index.d.ts +3 -129
  50. package/dist/raster/index.js +3 -1
  51. package/dist/{compositor-D92URMlm.d.cts → render-C-fO_mes.d.cts} +135 -1
  52. package/dist/{compositor-Kt_M4ruo.d.ts → render-OLIMk_v0.d.ts} +135 -1
  53. package/dist/{svg-vme0PLNo.d.ts → svg-D_cfkhlB.d.cts} +6 -608
  54. package/dist/{svg-Bj1MQFh6.d.cts → svg-wIaKLrU0.d.ts} +6 -608
  55. package/dist/types-DtL_qLFz.d.ts +630 -0
  56. package/dist/types-DyQq-WPY.d.cts +630 -0
  57. package/dist/vector/index.cjs +1080 -1051
  58. package/dist/vector/index.cjs.map +1 -1
  59. package/dist/vector/index.d.cts +268 -7
  60. package/dist/vector/index.d.ts +268 -7
  61. package/dist/vector/index.js +495 -466
  62. package/dist/vector/index.js.map +1 -1
  63. package/dist/video-editor/index.cjs +3 -3
  64. package/dist/video-editor/index.js +2 -2
  65. package/package.json +1 -1
  66. package/skills/pixerate-image-editor/SKILL.md +50 -7
  67. package/skills/pixerate-vector/SKILL.md +35 -5
  68. package/dist/chunk-63EFQCT5.js.map +0 -1
  69. package/dist/chunk-DWGZUSES.cjs +0 -694
  70. package/dist/chunk-DWGZUSES.cjs.map +0 -1
  71. package/dist/chunk-FRD3FUXI.cjs.map +0 -1
  72. package/dist/chunk-G4BIYE6R.js.map +0 -1
  73. package/dist/chunk-KANRAHTL.cjs.map +0 -1
  74. package/dist/chunk-KKREERP2.js +0 -694
  75. package/dist/chunk-KKREERP2.js.map +0 -1
  76. package/dist/chunk-SOROZ2BF.js.map +0 -1
  77. package/dist/chunk-T3QZ6S47.cjs.map +0 -1
  78. /package/dist/{chunk-JK6M6V7G.js.map → chunk-Z3YWVUWT.js.map} +0 -0
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkFRD3FUXIcjs = require('../chunk-FRD3FUXI.cjs');
7
+ var _chunkD37BX2ZAcjs = require('../chunk-D37BX2ZA.cjs');
8
8
 
9
9
 
10
10
 
@@ -17,7 +17,7 @@ var _chunkFRD3FUXIcjs = require('../chunk-FRD3FUXI.cjs');
17
17
 
18
18
 
19
19
 
20
- var _chunkT3QZ6S47cjs = require('../chunk-T3QZ6S47.cjs');
20
+ var _chunkAZTZRLDIcjs = require('../chunk-AZTZRLDI.cjs');
21
21
  require('../chunk-MUUXNRU4.cjs');
22
22
 
23
23
 
@@ -54,7 +54,16 @@ var _chunkHUFQD4CBcjs = require('../chunk-HUFQD4CB.cjs');
54
54
 
55
55
 
56
56
  var _chunkSZ6KMZNMcjs = require('../chunk-SZ6KMZNM.cjs');
57
- require('../chunk-DWGZUSES.cjs');
57
+
58
+
59
+
60
+
61
+
62
+ var _chunkEGFUVXKKcjs = require('../chunk-EGFUVXKK.cjs');
63
+ require('../chunk-W3GXSUSQ.cjs');
64
+ require('../chunk-XGD3FSNC.cjs');
65
+ require('../chunk-MR3Z4OQI.cjs');
66
+ require('../chunk-A6PHCAGX.cjs');
58
67
 
59
68
  // src/paint-editor/noise.ts
60
69
  function mix32(h) {
@@ -1268,7 +1277,7 @@ var PROFILE = {
1268
1277
  }
1269
1278
  };
1270
1279
  function createPaintCompositor() {
1271
- return new (0, _chunkT3QZ6S47cjs.RasterCompositor)(PROFILE);
1280
+ return new (0, _chunkAZTZRLDIcjs.RasterCompositor)(PROFILE);
1272
1281
  }
1273
1282
  function downsampleRgba(data, width, height, tw, th) {
1274
1283
  tw = Math.max(1, Math.round(tw));
@@ -1339,11 +1348,11 @@ function header(state, options) {
1339
1348
  return out;
1340
1349
  }
1341
1350
  function serializePaintDocument(state, options = {}) {
1342
- const { layers, assets } = _chunkFRD3FUXIcjs.serializeLayers.call(void 0, state.layers);
1351
+ const { layers, assets } = _chunkD37BX2ZAcjs.serializeLayers.call(void 0, state.layers);
1343
1352
  return { ...header(state, options), layers, assets };
1344
1353
  }
1345
1354
  async function serializePaintDocumentExternal(state, store, options = {}) {
1346
- const { layers, assets } = await _chunkFRD3FUXIcjs.serializeLayersExternal.call(void 0, state.layers, store);
1355
+ const { layers, assets } = await _chunkD37BX2ZAcjs.serializeLayersExternal.call(void 0, state.layers, store);
1347
1356
  return { ...header(state, options), layers, assets };
1348
1357
  }
1349
1358
  function paintLayersOnly(layers, problems) {
@@ -1380,16 +1389,16 @@ function deserializePaintDocument(raw) {
1380
1389
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
1381
1390
  const paper = normalizePaper(_nullishCoalesce(r.paper, () => ( {})));
1382
1391
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
1383
- const layers = paintLayersOnly(_chunkFRD3FUXIcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1392
+ const layers = paintLayersOnly(_chunkD37BX2ZAcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1384
1393
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
1385
- const activeLayerId = wanted && _chunkT3QZ6S47cjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkT3QZ6S47cjs.flattenLayers.call(void 0, layers), 'access', _25 => _25.filter, 'call', _26 => _26((l) => l.type === "pixel"), 'access', _27 => _27.pop, 'call', _28 => _28(), 'optionalAccess', _29 => _29.id]), () => ( null));
1394
+ const activeLayerId = wanted && _chunkAZTZRLDIcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.flattenLayers.call(void 0, layers), 'access', _25 => _25.filter, 'call', _26 => _26((l) => l.type === "pixel"), 'access', _27 => _27.pop, 'call', _28 => _28(), 'optionalAccess', _29 => _29.id]), () => ( null));
1386
1395
  return { state: { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) }, extensions: documentExtensions(r), guides: r.guides, swatches: r.swatches, problems };
1387
1396
  }
1388
1397
  async function deserializePaintDocumentAsync(raw, store) {
1389
1398
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
1390
1399
  const r = raw;
1391
1400
  const problems = [];
1392
- const assets = await _chunkFRD3FUXIcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1401
+ const assets = await _chunkD37BX2ZAcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1393
1402
  const loaded = deserializePaintDocument({ ...r, assets });
1394
1403
  return { ...loaded, problems: [...problems, ...loaded.problems] };
1395
1404
  }
@@ -2207,7 +2216,7 @@ var PaintEditorController = (_class9 = class {
2207
2216
  }
2208
2217
  // --- Layers --------------------------------------------------------------------
2209
2218
  getLayer(id) {
2210
- return _optionalChain([_chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _35 => _35.layer]);
2219
+ return _optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _35 => _35.layer]);
2211
2220
  }
2212
2221
  /** The active pixel layer (or `undefined`). */
2213
2222
  getActiveLayer() {
@@ -2226,12 +2235,12 @@ var PaintEditorController = (_class9 = class {
2226
2235
  walk(this.doc.layers, null, 0);
2227
2236
  return out;
2228
2237
  }
2229
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _36 => _36.parent, 'optionalAccess', _37 => _37.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _38 => _38.path, 'access', _39 => _39.length]), () => ( 0))) {
2238
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _36 => _36.parent, 'optionalAccess', _37 => _37.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _38 => _38.path, 'access', _39 => _39.length]), () => ( 0))) {
2230
2239
  let bounds = null;
2231
2240
  if (l.type === "pixel") {
2232
2241
  const b = _chunkSZ6KMZNMcjs.contentBounds.call(void 0, l.surface);
2233
2242
  bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;
2234
- } else for (const c of _chunkT3QZ6S47cjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
2243
+ } else for (const c of _chunkAZTZRLDIcjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
2235
2244
  return {
2236
2245
  id: l.id,
2237
2246
  name: l.name,
@@ -2258,7 +2267,7 @@ var PaintEditorController = (_class9 = class {
2258
2267
  if (!id) throw new PaintEditorError(`There is no active layer to ${what}; add one with add_layer.`);
2259
2268
  const l = this.requireLayer(id);
2260
2269
  if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; ${what} a pixel layer inside it.`);
2261
- if (_chunkT3QZ6S47cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
2270
+ if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
2262
2271
  if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) before you ${what} it.`);
2263
2272
  return l;
2264
2273
  }
@@ -2271,7 +2280,7 @@ var PaintEditorController = (_class9 = class {
2271
2280
  /** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */
2272
2281
  addLayer(options = {}) {
2273
2282
  this.requireIdle("adding a layer");
2274
- const count = _chunkT3QZ6S47cjs.flattenLayers.call(void 0, this.doc.layers).length;
2283
+ const count = _chunkAZTZRLDIcjs.flattenLayers.call(void 0, this.doc.layers).length;
2275
2284
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
2276
2285
  const name = _optionalChain([options, 'access', _40 => _40.name, 'optionalAccess', _41 => _41.trim, 'call', _42 => _42()]) || (type === "group" ? `Group ${count + 1}` : `Layer ${count + 1}`);
2277
2286
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
@@ -2283,19 +2292,19 @@ var PaintEditorController = (_class9 = class {
2283
2292
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
2284
2293
  parentId = g.id;
2285
2294
  } else if (above) {
2286
- const loc = _chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, above);
2295
+ const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, above);
2287
2296
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
2288
2297
  parentId = _nullishCoalesce(_optionalChain([loc, 'access', _43 => _43.parent, 'optionalAccess', _44 => _44.id]), () => ( null));
2289
2298
  index = loc.index + 1;
2290
2299
  }
2291
- const layers = _chunkT3QZ6S47cjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
2300
+ const layers = _chunkAZTZRLDIcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
2292
2301
  this.commit(type === "group" ? "Add group" : "Add layer", { ...this.doc, layers, activeLayerId: layer.id });
2293
2302
  return this.describeLayer(layer);
2294
2303
  }
2295
2304
  updateLayer(id, update) {
2296
2305
  this.requireIdle("changing a layer");
2297
2306
  const l = this.requireLayer(id);
2298
- if (_chunkT3QZ6S47cjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
2307
+ if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
2299
2308
  if (update.opacity !== void 0 && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);
2300
2309
  if (update.blend !== void 0 && !_chunkSZ6KMZNMcjs.isBlendMode.call(void 0, update.blend) && !(l.type === "group" && update.blend === "pass-through")) {
2301
2310
  throw new PaintEditorError(`Unknown blend mode "${update.blend}". Call get_canvas_info for the blend modes.`);
@@ -2311,57 +2320,57 @@ var PaintEditorController = (_class9 = class {
2311
2320
  const locks = { ..._nullishCoalesce(l.locks, () => ( {})), ...update.locks };
2312
2321
  next.locks = Object.values(locks).some(Boolean) ? locks : void 0;
2313
2322
  }
2314
- this.commit("Layer properties", { ...this.doc, layers: _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
2323
+ this.commit("Layer properties", { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
2315
2324
  return this.describeLayer(next);
2316
2325
  }
2317
2326
  removeLayer(id) {
2318
2327
  this.requireIdle("removing a layer");
2319
2328
  const l = this.requireLayer(id);
2320
- if (_chunkT3QZ6S47cjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
2321
- const layers = _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
2329
+ if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
2330
+ const layers = _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
2322
2331
  let active = this.doc.activeLayerId;
2323
- if (active && !_chunkT3QZ6S47cjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkT3QZ6S47cjs.flattenLayers.call(void 0, layers), 'access', _45 => _45.filter, 'call', _46 => _46((x) => x.type === "pixel"), 'access', _47 => _47.pop, 'call', _48 => _48(), 'optionalAccess', _49 => _49.id]), () => ( null));
2332
+ if (active && !_chunkAZTZRLDIcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkAZTZRLDIcjs.flattenLayers.call(void 0, layers), 'access', _45 => _45.filter, 'call', _46 => _46((x) => x.type === "pixel"), 'access', _47 => _47.pop, 'call', _48 => _48(), 'optionalAccess', _49 => _49.id]), () => ( null));
2324
2333
  this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active });
2325
2334
  return { removed: id, activeLayerId: active };
2326
2335
  }
2327
2336
  duplicateLayer(id) {
2328
2337
  this.requireIdle("duplicating a layer");
2329
- const loc = _chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, id);
2338
+ const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id);
2330
2339
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
2331
2340
  const copy = (l) => l.type === "group" ? { ...l, id: newPaintLayerId(), children: l.children.map(copy) } : { ...l, id: newPaintLayerId() };
2332
2341
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
2333
- const layers = _chunkT3QZ6S47cjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _50 => _50.parent, 'optionalAccess', _51 => _51.id]), () => ( null)), loc.index + 1);
2342
+ const layers = _chunkAZTZRLDIcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _50 => _50.parent, 'optionalAccess', _51 => _51.id]), () => ( null)), loc.index + 1);
2334
2343
  this.commit("Duplicate layer", { ...this.doc, layers, activeLayerId: dup.id });
2335
2344
  return this.describeLayer(dup);
2336
2345
  }
2337
2346
  /** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */
2338
2347
  moveLayer(id, index, parentId) {
2339
2348
  this.requireIdle("moving a layer");
2340
- const loc = _chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, id);
2349
+ const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id);
2341
2350
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
2342
2351
  const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _52 => _52.parent, 'optionalAccess', _53 => _53.id]), () => ( null)) : parentId;
2343
2352
  if (target) {
2344
2353
  const g = this.requireLayer(target);
2345
2354
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
2346
- if (target === id || loc.layer.type === "group" && _chunkT3QZ6S47cjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
2355
+ if (target === id || loc.layer.type === "group" && _chunkAZTZRLDIcjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
2347
2356
  }
2348
- const without = _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
2349
- const siblings = target ? _chunkT3QZ6S47cjs.findLayer.call(void 0, without, target).layer.children : without;
2357
+ const without = _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
2358
+ const siblings = target ? _chunkAZTZRLDIcjs.findLayer.call(void 0, without, target).layer.children : without;
2350
2359
  if (!Number.isInteger(index) || index < 0 || index > siblings.length) throw new PaintEditorError(`index ${index} is out of range; use 0..${siblings.length} (0 is the bottom).`);
2351
- const layers = _chunkT3QZ6S47cjs.insertLayer.call(void 0, without, loc.layer, target, index);
2360
+ const layers = _chunkAZTZRLDIcjs.insertLayer.call(void 0, without, loc.layer, target, index);
2352
2361
  this.commit("Move layer", { ...this.doc, layers });
2353
2362
  return this.describeLayer(loc.layer);
2354
2363
  }
2355
2364
  /** Merges a pixel layer into the pixel layer below it (keeping the lower one's settings). */
2356
2365
  mergeDown(id) {
2357
2366
  this.requireIdle("merging");
2358
- const loc = _chunkT3QZ6S47cjs.findLayer.call(void 0, this.doc.layers, id);
2367
+ const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, this.doc.layers, id);
2359
2368
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
2360
2369
  const siblings = loc.parent ? loc.parent.children : this.doc.layers;
2361
2370
  const below = siblings[loc.index - 1];
2362
2371
  const upper = loc.layer;
2363
2372
  if (!isPixelLayer(upper) || !isPixelLayer(below)) throw new PaintEditorError("Merge down needs a pixel layer directly above another pixel layer in the same group.");
2364
- if (_chunkT3QZ6S47cjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
2373
+ if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
2365
2374
  const rect = unionRect(this.describeLayer(below).bounds, this.describeLayer(upper).bounds);
2366
2375
  let surface = _chunkSZ6KMZNMcjs.emptySurface.call(void 0, 4);
2367
2376
  if (rect) {
@@ -2370,7 +2379,7 @@ var PaintEditorController = (_class9 = class {
2370
2379
  surface = _chunkSZ6KMZNMcjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data: px }, 4, rect.x, rect.y);
2371
2380
  }
2372
2381
  const merged = { ...below, surface, offset: { x: 0, y: 0 } };
2373
- const layers = _chunkT3QZ6S47cjs.mapLayer.call(void 0, _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
2382
+ const layers = _chunkAZTZRLDIcjs.mapLayer.call(void 0, _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
2374
2383
  this.commit("Merge down", { ...this.doc, layers, activeLayerId: below.id });
2375
2384
  return this.describeLayer(merged);
2376
2385
  }
@@ -2379,7 +2388,7 @@ var PaintEditorController = (_class9 = class {
2379
2388
  this.requireIdle("clearing");
2380
2389
  const l = this.paintTarget(layerId, "clear");
2381
2390
  const bounds = this.describeLayer(l).bounds;
2382
- this.commit("Clear layer", { ...this.doc, layers: _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunkSZ6KMZNMcjs.emptySurface.call(void 0, 4) })) });
2391
+ this.commit("Clear layer", { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunkSZ6KMZNMcjs.emptySurface.call(void 0, 4) })) });
2383
2392
  return { layerId: l.id, bounds };
2384
2393
  }
2385
2394
  /**
@@ -2414,12 +2423,12 @@ var PaintEditorController = (_class9 = class {
2414
2423
  background: rgbaOf(this.doc.paper.color),
2415
2424
  opacity,
2416
2425
  blend,
2417
- lockTransparency: _chunkT3QZ6S47cjs.isLayerLocked.call(void 0, l, "transparency"),
2426
+ lockTransparency: _chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "transparency"),
2418
2427
  selection: null,
2419
2428
  offset: l.offset
2420
2429
  };
2421
2430
  const surface = this.applyCoverage(l, coverage, rect, apply);
2422
- this.commit("Fill layer", { ...this.doc, layers: _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })) });
2431
+ this.commit("Fill layer", { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })) });
2423
2432
  return { layerId: l.id, bounds: rect };
2424
2433
  }
2425
2434
  applyCoverage(l, coverage, rect, apply) {
@@ -2602,11 +2611,11 @@ var PaintEditorController = (_class9 = class {
2602
2611
  const layer = (() => {
2603
2612
  const id = _nullishCoalesce(init.layerId, () => ( doc.activeLayerId));
2604
2613
  if (!id) throw new PaintEditorError("There is no active layer to paint on; add one with add_layer.");
2605
- const loc = _chunkT3QZ6S47cjs.findLayer.call(void 0, doc.layers, id);
2614
+ const loc = _chunkAZTZRLDIcjs.findLayer.call(void 0, doc.layers, id);
2606
2615
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
2607
2616
  const l = loc.layer;
2608
2617
  if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; paint on a pixel layer inside it.`);
2609
- if (_chunkT3QZ6S47cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
2618
+ if (_chunkAZTZRLDIcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
2610
2619
  if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) to paint on it.`);
2611
2620
  return l;
2612
2621
  })();
@@ -2623,7 +2632,7 @@ var PaintEditorController = (_class9 = class {
2623
2632
  layerId: layer.id,
2624
2633
  surface: layer.surface,
2625
2634
  offset: layer.offset,
2626
- lockTransparency: _chunkT3QZ6S47cjs.isLayerLocked.call(void 0, layer, "transparency"),
2635
+ lockTransparency: _chunkAZTZRLDIcjs.isLayerLocked.call(void 0, layer, "transparency"),
2627
2636
  brush,
2628
2637
  color: rgba,
2629
2638
  background: rgbaOf(doc.paper.color),
@@ -2675,7 +2684,7 @@ var PaintEditorController = (_class9 = class {
2675
2684
  const stroke = this.record(s);
2676
2685
  s.result.strokeId = stroke.id;
2677
2686
  const l = this.getLayer(s.layerId);
2678
- this.commit(`${brush.name} stroke`, { ...this.doc, layers: _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke] });
2687
+ this.commit(`${brush.name} stroke`, { ...this.doc, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke] });
2679
2688
  }
2680
2689
  };
2681
2690
  const session = this.sessionFor(this.doc, { snapToPerspective: true, ...init }, host);
@@ -2697,8 +2706,8 @@ var PaintEditorController = (_class9 = class {
2697
2706
  if (cancelled || !surface) return;
2698
2707
  const stroke = this.record(s);
2699
2708
  s.result.strokeId = stroke.id;
2700
- const l = _chunkT3QZ6S47cjs.findLayer.call(void 0, out.layers, s.layerId).layer;
2701
- out = { ...out, layers: _chunkT3QZ6S47cjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface })), strokes: [...out.strokes, stroke] };
2709
+ const l = _chunkAZTZRLDIcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
2710
+ out = { ...out, layers: _chunkAZTZRLDIcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface })), strokes: [...out.strokes, stroke] };
2702
2711
  }
2703
2712
  };
2704
2713
  const session = this.sessionFor(doc, init, host);
@@ -2716,6 +2725,7 @@ var PaintEditorController = (_class9 = class {
2716
2725
  else this.emit([]);
2717
2726
  return result;
2718
2727
  }
2728
+ /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
2719
2729
  checkPoints(points) {
2720
2730
  if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
2721
2731
  const out = [];
@@ -2769,7 +2779,7 @@ var PaintEditorController = (_class9 = class {
2769
2779
  brush = normalizePaintBrush({ tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
2770
2780
  }
2771
2781
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
2772
- if (!_chunkT3QZ6S47cjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
2782
+ if (!_chunkAZTZRLDIcjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
2773
2783
  const run = this.runStroke(doc, { layerId, color: _nullishCoalesce(options.color, () => ( s.color)), brush, seed: s.seed, copies: _nullishCoalesce(v.copies, () => ( [])) }, v.points);
2774
2784
  doc = run.doc;
2775
2785
  bounds = unionRect(bounds, run.result.bounds);
@@ -2789,7 +2799,7 @@ var PaintEditorController = (_class9 = class {
2789
2799
  const live = this.live;
2790
2800
  if (!live) return this.doc.layers;
2791
2801
  if (_optionalChain([this, 'access', _63 => _63.liveLayers, 'optionalAccess', _64 => _64.key]) === live.surface) return this.liveLayers.layers;
2792
- const layers = _chunkT3QZ6S47cjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
2802
+ const layers = _chunkAZTZRLDIcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
2793
2803
  this.liveLayers = { key: live.surface, layers };
2794
2804
  return layers;
2795
2805
  }
@@ -2893,7 +2903,7 @@ var PaintEditorController = (_class9 = class {
2893
2903
  /** The canvas as PNG bytes (paper included by default; `scale` below 1 shrinks it). */
2894
2904
  exportPng(options = {}) {
2895
2905
  const img = this.scaled(options);
2896
- return _chunkT3QZ6S47cjs.encodePng.call(void 0, img.width, img.height, img.data);
2906
+ return _chunkAZTZRLDIcjs.encodePng.call(void 0, img.width, img.height, img.data);
2897
2907
  }
2898
2908
  scaled(options) {
2899
2909
  const full = this.compositePixels(options);
@@ -2947,7 +2957,7 @@ var PaintEditorController = (_class9 = class {
2947
2957
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
2948
2958
  });
2949
2959
  const layers = toStandard(this.doc.layers);
2950
- const result = _chunkFRD3FUXIcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
2960
+ const result = _chunkD37BX2ZAcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
2951
2961
  for (const [mode, names] of changed) {
2952
2962
  const label = _nullishCoalesce(_optionalChain([_chunkSZ6KMZNMcjs.BLEND_MODES, 'access', _72 => _72.find, 'call', _73 => _73((m) => m.id === mode), 'optionalAccess', _74 => _74.label]), () => ( mode));
2953
2963
  const std = _nullishCoalesce(_optionalChain([_chunkSZ6KMZNMcjs.BLEND_MODES, 'access', _75 => _75.find, 'call', _76 => _76((m) => m.id === _chunkSZ6KMZNMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _77 => _77.label]), () => ( _chunkSZ6KMZNMcjs.standardBlendMode.call(void 0, mode)));
@@ -2960,7 +2970,7 @@ var PaintEditorController = (_class9 = class {
2960
2970
  /** `render_preview` as a base64 PNG. */
2961
2971
  previewPngBase64(options = {}) {
2962
2972
  const img = this.renderPreview(options);
2963
- return { data: _chunkT3QZ6S47cjs.bytesToBase64.call(void 0, _chunkT3QZ6S47cjs.encodePng.call(void 0, img.width, img.height, img.data)), width: img.width, height: img.height };
2973
+ return { data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, _chunkAZTZRLDIcjs.encodePng.call(void 0, img.width, img.height, img.data)), width: img.width, height: img.height };
2964
2974
  }
2965
2975
  // --- Guides --------------------------------------------------------------------
2966
2976
  setGuides(next) {
@@ -2998,17 +3008,17 @@ var PaintEditorController = (_class9 = class {
2998
3008
  pixels = this.decodeImage(input.png.trim().startsWith("data:") ? input.png.trim() : `data:image/png;base64,${input.png.trim()}`, what);
2999
3009
  } else throw new PaintEditorError(`${what}: pass png (a PNG as base64 or a data URL) or pixels.`);
3000
3010
  if (pixels.width > MAX_IMAGE_SIDE || pixels.height > MAX_IMAGE_SIDE) throw new PaintEditorError(`${what} is ${pixels.width}\xD7${pixels.height}; the limit is ${MAX_IMAGE_SIDE} px per side.`);
3001
- const src = _chunkT3QZ6S47cjs.pngDataUrl.call(void 0, pixels.width, pixels.height, pixels.data);
3011
+ const src = _chunkAZTZRLDIcjs.pngDataUrl.call(void 0, pixels.width, pixels.height, pixels.data);
3002
3012
  this.imagePixels.set(src, pixels);
3003
3013
  return { src, pixels };
3004
3014
  }
3005
3015
  decodeImage(src, what = "Image") {
3006
3016
  const cached = this.imagePixels.get(src);
3007
3017
  if (cached) return cached;
3008
- const parsed = _chunkT3QZ6S47cjs.parseDataUrl.call(void 0, src);
3018
+ const parsed = _chunkAZTZRLDIcjs.parseDataUrl.call(void 0, src);
3009
3019
  if (!parsed) throw new PaintEditorError(`${what} is not a data URL or base64 PNG.`);
3010
3020
  try {
3011
- const png = _chunkT3QZ6S47cjs.decodePng.call(void 0, parsed.bytes);
3021
+ const png = _chunkAZTZRLDIcjs.decodePng.call(void 0, parsed.bytes);
3012
3022
  const px = { width: png.width, height: png.height, data: png.data };
3013
3023
  this.imagePixels.set(src, px);
3014
3024
  return px;
@@ -3213,7 +3223,7 @@ var PaintEditorController = (_class9 = class {
3213
3223
  }
3214
3224
  /** A layer's tile surface (live while stroking), for thumbnails. */
3215
3225
  layerSurface(id) {
3216
- const l = _optionalChain([_chunkT3QZ6S47cjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _86 => _86.layer]);
3226
+ const l = _optionalChain([_chunkAZTZRLDIcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _86 => _86.layer]);
3217
3227
  return isPixelLayer(l) ? l.surface : null;
3218
3228
  }
3219
3229
  }, _class9);
@@ -3250,6 +3260,169 @@ function resampleInto(src, rect, width, height) {
3250
3260
  return { width, height, data: out };
3251
3261
  }
3252
3262
 
3263
+ // src/paint-editor/presence.ts
3264
+ var PaintPresence = class extends _chunkEGFUVXKKcjs.PresenceStore {
3265
+ };
3266
+ var FRAME = 16;
3267
+ function strokeSchedule(points) {
3268
+ if (points.length < 2) return points.map(() => 1);
3269
+ const t0 = points[0].t;
3270
+ const t1 = points[points.length - 1].t;
3271
+ if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) {
3272
+ return points.map((p) => Math.min(1, Math.max(0, (p.t - t0) / (t1 - t0))));
3273
+ }
3274
+ const acc = [0];
3275
+ for (let i = 1; i < points.length; i++) acc.push(acc[i - 1] + Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y));
3276
+ const total = acc[acc.length - 1];
3277
+ return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
3278
+ }
3279
+ function strokeDuration(points, max = 1800) {
3280
+ const t0 = _optionalChain([points, 'access', _87 => _87[0], 'optionalAccess', _88 => _88.t]);
3281
+ const t1 = _optionalChain([points, 'access', _89 => _89[points.length - 1], 'optionalAccess', _90 => _90.t]);
3282
+ let ms;
3283
+ if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
3284
+ else {
3285
+ let length = 0;
3286
+ for (let i = 1; i < points.length; i++) length += Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y);
3287
+ ms = length / 1.5;
3288
+ }
3289
+ return Math.min(max, Math.max(250, ms));
3290
+ }
3291
+ function sweepPath(rect, rows = 4) {
3292
+ const inset = Math.min(rect.width, rect.height) * 0.08;
3293
+ const left = rect.x + inset;
3294
+ const right = rect.x + rect.width - inset;
3295
+ const out = [];
3296
+ for (let r = 0; r < rows; r++) {
3297
+ const y = rect.y + inset + (rect.height - 2 * inset) * (r + 0.5) / rows;
3298
+ out.push(r % 2 ? { x: right, y } : { x: left, y }, r % 2 ? { x: left, y } : { x: right, y });
3299
+ }
3300
+ return out;
3301
+ }
3302
+ var centre = (r) => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });
3303
+ var PaintDirector = class {
3304
+ constructor(controller, presence, options = {}) {
3305
+ this.controller = controller;
3306
+ this.presence = presence;
3307
+ this.options = options;
3308
+ this.clock = _nullishCoalesce(options.clock, () => ( _chunkEGFUVXKKcjs.realPresenceClock));
3309
+ this.queue = new (0, _chunkEGFUVXKKcjs.PerformanceQueue)(presence, { clock: this.clock, linger: options.linger });
3310
+ }
3311
+
3312
+
3313
+
3314
+
3315
+
3316
+ /** Acts out `commands` in order for `actor`. Resolves with one result per command. */
3317
+ perform(actor, commands) {
3318
+ return this.queue.run(actor, async () => {
3319
+ const results = [];
3320
+ for (const command of commands) {
3321
+ try {
3322
+ results.push({ ok: true, command, result: await this.performOne(actor.id, command) });
3323
+ } catch (error) {
3324
+ results.push({ ok: false, command, message: error instanceof Error ? error.message : String(error) });
3325
+ }
3326
+ }
3327
+ return results;
3328
+ });
3329
+ }
3330
+ ms(n) {
3331
+ return Math.round(n / Math.max(0.1, _nullishCoalesce(this.options.speed, () => ( 1))));
3332
+ }
3333
+ where(id) {
3334
+ const a = this.presence.get(id);
3335
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _91 => _91.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _92 => _92.y]), () => ( 0)) };
3336
+ }
3337
+ /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
3338
+ async glide(id, to, ms = 380) {
3339
+ const a = this.presence.get(id);
3340
+ if (!a || a.x === 0 && a.y === 0) {
3341
+ this.presence.set({ id, x: to.x, y: to.y });
3342
+ return;
3343
+ }
3344
+ await _chunkEGFUVXKKcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, this.where(id), to, this.ms(ms));
3345
+ }
3346
+ async say(id, text, ms) {
3347
+ if (!text) return;
3348
+ this.presence.set({ id, message: text });
3349
+ await this.clock.wait(this.ms(ms));
3350
+ }
3351
+ async performOne(id, command) {
3352
+ const c = this.controller;
3353
+ switch (command.kind) {
3354
+ case "say":
3355
+ await this.say(id, command.text, 900);
3356
+ return void 0;
3357
+ case "point":
3358
+ await this.say(id, command.note, 500);
3359
+ await this.glide(id, command.at);
3360
+ this.presence.set({ id, pressed: true });
3361
+ await this.clock.wait(this.ms(110));
3362
+ this.presence.set({ id, pressed: false });
3363
+ return void 0;
3364
+ case "stroke":
3365
+ await this.say(id, command.note, 500);
3366
+ return this.stroke(id, command.stroke);
3367
+ case "fill": {
3368
+ await this.say(id, command.note, 500);
3369
+ const { width, height } = c.getState().document.canvas;
3370
+ const path = sweepPath({ x: 0, y: 0, width, height });
3371
+ await this.glide(id, path[0]);
3372
+ this.presence.set({ id, pressed: true });
3373
+ try {
3374
+ for (let i = 1; i < path.length; i++) await _chunkEGFUVXKKcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, path[i - 1], path[i], this.ms(i % 2 ? 260 : 90));
3375
+ } finally {
3376
+ this.presence.set({ id, pressed: false });
3377
+ }
3378
+ return c.fillLayer(command.fill);
3379
+ }
3380
+ case "replay": {
3381
+ await this.say(id, command.note, 500);
3382
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _93 => _93.replay, 'access', _94 => _94.strokeIds, 'optionalAccess', _95 => _95.includes, 'call', _96 => _96(s.id)]));
3383
+ const first = _optionalChain([source, 'access', _97 => _97[0], 'optionalAccess', _98 => _98.points, 'access', _99 => _99[0]]);
3384
+ if (first) await this.glide(id, first);
3385
+ const result = c.replayStrokes(command.replay);
3386
+ if (result.bounds) await this.glide(id, centre(result.bounds), 520);
3387
+ return result;
3388
+ }
3389
+ }
3390
+ }
3391
+ /** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
3392
+ async stroke(id, init) {
3393
+ const c = this.controller;
3394
+ const points = c.checkPoints(init.points);
3395
+ const { points: _points, ...rest } = init;
3396
+ const session = c.beginStroke({ snapToPerspective: false, start: points[0], ...rest });
3397
+ try {
3398
+ await this.glide(id, points[0]);
3399
+ this.presence.set({ id, pressed: true });
3400
+ const at = strokeSchedule(points);
3401
+ const duration = this.ms(strokeDuration(points, this.options.maxStrokeMs));
3402
+ let next = 0;
3403
+ const frames = Math.max(1, Math.round(duration / FRAME));
3404
+ for (let f = 1; f <= frames; f++) {
3405
+ const t = f / frames;
3406
+ const from = next;
3407
+ while (next < points.length && at[next] <= t + 1e-9) next++;
3408
+ if (next > from) {
3409
+ session.push(points.slice(from, next));
3410
+ const p = points[next - 1];
3411
+ this.presence.set({ id, x: p.x, y: p.y });
3412
+ }
3413
+ if (f < frames) await this.clock.wait(duration / frames);
3414
+ }
3415
+ if (next < points.length) session.push(points.slice(next));
3416
+ this.presence.set({ id, pressed: false });
3417
+ return session.end();
3418
+ } catch (error) {
3419
+ if (c.activeStroke === session) session.cancel();
3420
+ this.presence.set({ id, pressed: false });
3421
+ throw error;
3422
+ }
3423
+ }
3424
+ };
3425
+
3253
3426
  // src/paint-editor/guide-tools.ts
3254
3427
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
3255
3428
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
@@ -3570,7 +3743,7 @@ function createPaintGuideTools(c) {
3570
3743
  const pad = c.mixingPad;
3571
3744
  return {
3572
3745
  content: [
3573
- { type: "image", data: _chunkT3QZ6S47cjs.bytesToBase64.call(void 0, _chunkT3QZ6S47cjs.encodePng.call(void 0, pad.width, pad.height, pad.pixels())), mimeType: "image/png" },
3746
+ { type: "image", data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, _chunkAZTZRLDIcjs.encodePng.call(void 0, pad.width, pad.height, pad.pixels())), mimeType: "image/png" },
3574
3747
  { type: "text", text: `Mixing pad ${pad.width}\xD7${pad.height}` }
3575
3748
  ]
3576
3749
  };
@@ -3685,6 +3858,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
3685
3858
  const c = controller;
3686
3859
  const tools = [];
3687
3860
  const add = (t) => tools.push(t);
3861
+ const act = async (command, direct) => {
3862
+ if (!options.director) return direct();
3863
+ const [r] = await options.director.perform(_nullishCoalesce(options.actor, () => ( { id: "agent", name: "Agent" })), [command]);
3864
+ if (!r || !r.ok) throw new Error(r && !r.ok ? r.message : "The director did not run the command.");
3865
+ return r.result;
3866
+ };
3688
3867
  add({
3689
3868
  name: "get_canvas_info",
3690
3869
  title: "Get the canvas",
@@ -3949,7 +4128,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
3949
4128
  additionalProperties: false
3950
4129
  },
3951
4130
  annotations: { title: "Fill a layer", ...WRITE2 },
3952
- handler: (a) => c.fillLayer(a)
4131
+ handler: (a) => act({ kind: "fill", fill: a }, () => c.fillLayer(a))
3953
4132
  });
3954
4133
  add({
3955
4134
  name: "clear_layer",
@@ -3967,7 +4146,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
3967
4146
  annotations: { title: "List brushes", ...READ2 },
3968
4147
  handler: () => {
3969
4148
  const s = c.getState();
3970
- return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _87 => _87.getBrush, 'call', _88 => _88(s.brush.id), 'optionalAccess', _89 => _89.builtin])), brushes: s.brushes.map(brushSummary) };
4149
+ return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _100 => _100.getBrush, 'call', _101 => _101(s.brush.id), 'optionalAccess', _102 => _102.builtin])), brushes: s.brushes.map(brushSummary) };
3971
4150
  }
3972
4151
  });
3973
4152
  add({
@@ -4065,7 +4244,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
4065
4244
  const t = c.brushThumbnail(_nullishCoalesce(id, () => ( c.getState().brush.id)), { width, height, color });
4066
4245
  return {
4067
4246
  content: [
4068
- { type: "image", data: _chunkT3QZ6S47cjs.bytesToBase64.call(void 0, _chunkT3QZ6S47cjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" },
4247
+ { type: "image", data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, _chunkAZTZRLDIcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" },
4069
4248
  { type: "text", text: `Brush ${_nullishCoalesce(id, () => ( c.getState().brush.id))} ${t.width}\xD7${t.height}` }
4070
4249
  ]
4071
4250
  };
@@ -4132,7 +4311,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
4132
4311
  add({
4133
4312
  name: "paint_stroke",
4134
4313
  title: "Paint a brush stroke",
4135
- description: "Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.",
4314
+ description: "Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. With an agent cursor (a director), the stroke is painted live along the points at the pace of their times. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.",
4136
4315
  inputSchema: {
4137
4316
  type: "object",
4138
4317
  properties: {
@@ -4148,8 +4327,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
4148
4327
  additionalProperties: false
4149
4328
  },
4150
4329
  annotations: { title: "Paint a brush stroke", ...WRITE2 },
4151
- handler: (a) => {
4152
- const r = c.paintStroke({ points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective });
4330
+ handler: async (a) => {
4331
+ const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective };
4332
+ const r = await act({ kind: "stroke", stroke }, () => c.paintStroke(stroke));
4153
4333
  return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
4154
4334
  }
4155
4335
  });
@@ -4186,7 +4366,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
4186
4366
  color: s.color,
4187
4367
  points: ids ? s.points : s.points.length,
4188
4368
  seed: s.seed,
4189
- copies: _nullishCoalesce(_optionalChain([s, 'access', _90 => _90.copies, 'optionalAccess', _91 => _91.length]), () => ( 0)),
4369
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _103 => _103.copies, 'optionalAccess', _104 => _104.length]), () => ( 0)),
4190
4370
  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) }
4191
4371
  };
4192
4372
  })
@@ -4223,7 +4403,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
4223
4403
  additionalProperties: false
4224
4404
  },
4225
4405
  annotations: { title: "Replay strokes, varied", ...WRITE2 },
4226
- handler: (a) => c.replayStrokes(a)
4406
+ handler: (a) => {
4407
+ const replay = a;
4408
+ return act({ kind: "replay", replay }, () => c.replayStrokes(replay));
4409
+ }
4227
4410
  });
4228
4411
  add({
4229
4412
  name: "set_view",
@@ -4316,7 +4499,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
4316
4499
  annotations: { title: "Export the painting", ...READ2 },
4317
4500
  handler: async ({ format, quality, scale, paper }) => {
4318
4501
  const bytes = await c.exportImage({ format, quality, scale, paper });
4319
- return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data: _chunkT3QZ6S47cjs.bytesToBase64.call(void 0, bytes) };
4502
+ return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, bytes) };
4320
4503
  }
4321
4504
  });
4322
4505
  add({
@@ -4327,7 +4510,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
4327
4510
  annotations: { title: "Export as PSD", ...READ2 },
4328
4511
  handler: () => {
4329
4512
  const r = c.exportPsd();
4330
- return { data: _chunkT3QZ6S47cjs.bytesToBase64.call(void 0, r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };
4513
+ return { data: _chunkAZTZRLDIcjs.bytesToBase64.call(void 0, r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };
4331
4514
  }
4332
4515
  });
4333
4516
  add({
@@ -4457,12 +4640,12 @@ var PaintGesture = (_class10 = class {
4457
4640
  if (!m || m.pointerId !== e.pointerId) return;
4458
4641
  this.mode = null;
4459
4642
  this.predicted = [];
4460
- if (m.kind === "stroke") _optionalChain([this, 'access', _92 => _92.controller, 'access', _93 => _93.activeStroke, 'optionalAccess', _94 => _94.end, 'call', _95 => _95()]);
4643
+ if (m.kind === "stroke") _optionalChain([this, 'access', _105 => _105.controller, 'access', _106 => _106.activeStroke, 'optionalAccess', _107 => _107.end, 'call', _108 => _108()]);
4461
4644
  }
4462
4645
  cancel() {
4463
4646
  this.penDown = false;
4464
4647
  this.predicted = [];
4465
- if (_optionalChain([this, 'access', _96 => _96.mode, 'optionalAccess', _97 => _97.kind]) === "stroke") _optionalChain([this, 'access', _98 => _98.controller, 'access', _99 => _99.activeStroke, 'optionalAccess', _100 => _100.cancel, 'call', _101 => _101()]);
4648
+ if (_optionalChain([this, 'access', _109 => _109.mode, 'optionalAccess', _110 => _110.kind]) === "stroke") _optionalChain([this, 'access', _111 => _111.controller, 'access', _112 => _112.activeStroke, 'optionalAccess', _113 => _113.cancel, 'call', _114 => _114()]);
4466
4649
  this.mode = null;
4467
4650
  }
4468
4651
  get active() {
@@ -4590,7 +4773,7 @@ var PAPER_SLIDERS = [
4590
4773
  ];
4591
4774
  function readPath(obj, path) {
4592
4775
  let v = obj;
4593
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _102 => _102[k]]);
4776
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _115 => _115[k]]);
4594
4777
  return typeof v === "number" ? v : 0;
4595
4778
  }
4596
4779
  function patchPath(obj, path, value) {
@@ -4777,5 +4960,10 @@ var BLEND_MENU_GROUPS = [
4777
4960
 
4778
4961
 
4779
4962
 
4780
- exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkSZ6KMZNMcjs.BLEND_MODES; exports.BRUSH_ID = BRUSH_ID; exports.BRUSH_ROTATIONS = BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = BUILTIN_BRUSHES; exports.DEFAULT_BRUSH_ID = DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = DEFAULT_DYNAMICS; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DryStroke = DryStroke; exports.GRAIN_PATTERNS = GRAIN_PATTERNS; exports.GRAIN_TILE = GRAIN_TILE; exports.HARMONY_KINDS = HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.MAX_BRUSH_SIZE = _chunkHUFQD4CBcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MixingPad = MixingPad; exports.PAINTERLY_BLEND_MODES = _chunkSZ6KMZNMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = PAINT_BRUSH_ENGINES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintGesture = PaintGesture; exports.PaintStrokeSession = PaintStrokeSession; exports.PaperGrain = PaperGrain; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.TileableNoise = TileableNoise; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushToJSON = brushToJSON; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony; exports.composeAffine = composeAffine; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintLayer = createPaintLayer; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.fitZoom = fitZoom; exports.grainCatch = grainCatch; exports.grainHeights = grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = hash2; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkSZ6KMZNMcjs.isBlendMode; exports.isPainterlyBlendMode = _chunkSZ6KMZNMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.mapPenPoint = mapPenPoint; exports.mix32 = mix32; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.newPaintLayerId = newPaintLayerId; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = normalizeDynamics; exports.normalizePaintBrush = normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.pointerToPenPoint = pointerToPenPoint; exports.rand01 = rand01; exports.randSigned = randSigned; exports.readPath = readPath; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.samplePressure = samplePressure; exports.screenToDocument = screenToDocument; exports.seedFromString = seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.standardBlendMode = _chunkSZ6KMZNMcjs.standardBlendMode; exports.strokeBounds = strokeBounds; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.toStrokePoint = toStrokePoint; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = wheelToHue;
4963
+
4964
+
4965
+
4966
+
4967
+
4968
+ exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkSZ6KMZNMcjs.BLEND_MODES; exports.BRUSH_ID = BRUSH_ID; exports.BRUSH_ROTATIONS = BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = BUILTIN_BRUSHES; exports.DEFAULT_BRUSH_ID = DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = DEFAULT_DYNAMICS; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DryStroke = DryStroke; exports.GRAIN_PATTERNS = GRAIN_PATTERNS; exports.GRAIN_TILE = GRAIN_TILE; exports.HARMONY_KINDS = HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.MAX_BRUSH_SIZE = _chunkHUFQD4CBcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MixingPad = MixingPad; exports.PAINTERLY_BLEND_MODES = _chunkSZ6KMZNMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = PAINT_BRUSH_ENGINES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintGesture = PaintGesture; exports.PaintPresence = PaintPresence; exports.PaintStrokeSession = PaintStrokeSession; exports.PaperGrain = PaperGrain; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.TileableNoise = TileableNoise; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.brushToJSON = brushToJSON; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony; exports.composeAffine = composeAffine; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintLayer = createPaintLayer; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.fitZoom = fitZoom; exports.grainCatch = grainCatch; exports.grainHeights = grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = hash2; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkSZ6KMZNMcjs.isBlendMode; exports.isPainterlyBlendMode = _chunkSZ6KMZNMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.mapPenPoint = mapPenPoint; exports.mix32 = mix32; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.newPaintLayerId = newPaintLayerId; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = normalizeDynamics; exports.normalizePaintBrush = normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.pointerToPenPoint = pointerToPenPoint; exports.rand01 = rand01; exports.randSigned = randSigned; exports.readPath = readPath; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.samplePressure = samplePressure; exports.screenToDocument = screenToDocument; exports.seedFromString = seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.standardBlendMode = _chunkSZ6KMZNMcjs.standardBlendMode; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.toStrokePoint = toStrokePoint; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = wheelToHue;
4781
4969
  //# sourceMappingURL=index.cjs.map