@pixerate/editor 0.104.0 → 0.106.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 (31) hide show
  1. package/dist/{chunk-NQLQ2JOI.js → chunk-4X5MIVCE.js} +1155 -295
  2. package/dist/chunk-4X5MIVCE.js.map +1 -0
  3. package/dist/{chunk-VSMM7B3P.cjs → chunk-ZID226ZG.cjs} +1169 -309
  4. package/dist/chunk-ZID226ZG.cjs.map +1 -0
  5. package/dist/{compositor-CTMU-B1t.d.cts → compositor-Bc3PNP3C.d.cts} +1 -1
  6. package/dist/{compositor-B1ZrKR89.d.ts → compositor-BsYYllvR.d.ts} +1 -1
  7. package/dist/{export-X9rY79p0.d.cts → export-_m3Es4ru.d.cts} +19 -4
  8. package/dist/{export-BLpMyCYg.d.ts → export-iMrop3Jm.d.ts} +19 -4
  9. package/dist/image-editor/index.cjs +714 -539
  10. package/dist/image-editor/index.cjs.map +1 -1
  11. package/dist/image-editor/index.d.cts +50 -9
  12. package/dist/image-editor/index.d.ts +50 -9
  13. package/dist/image-editor/index.js +228 -53
  14. package/dist/image-editor/index.js.map +1 -1
  15. package/dist/{mixer-DGcH6HLu.d.cts → mixer-C1M1Nua_.d.cts} +1 -1
  16. package/dist/{mixer-DG_9Yu2W.d.ts → mixer-Cu5a9Bzd.d.ts} +1 -1
  17. package/dist/paint/index.d.cts +2 -2
  18. package/dist/paint/index.d.ts +2 -2
  19. package/dist/paint-editor/index.cjs +348 -32
  20. package/dist/paint-editor/index.cjs.map +1 -1
  21. package/dist/paint-editor/index.d.cts +154 -13
  22. package/dist/paint-editor/index.d.ts +154 -13
  23. package/dist/paint-editor/index.js +317 -1
  24. package/dist/paint-editor/index.js.map +1 -1
  25. package/dist/raster/index.d.cts +4 -4
  26. package/dist/raster/index.d.ts +4 -4
  27. package/dist/{surface-AfHCH7BR.d.cts → surface-BBJN9wxg.d.cts} +1 -1
  28. package/dist/{surface-AfHCH7BR.d.ts → surface-BBJN9wxg.d.ts} +1 -1
  29. package/package.json +1 -1
  30. package/dist/chunk-NQLQ2JOI.js.map +0 -1
  31. package/dist/chunk-VSMM7B3P.cjs.map +0 -1
@@ -1,10 +1,10 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11;
2
2
 
3
3
 
4
4
 
5
5
 
6
6
 
7
- var _chunkVSMM7B3Pcjs = require('../chunk-VSMM7B3P.cjs');
7
+ var _chunkZID226ZGcjs = require('../chunk-ZID226ZG.cjs');
8
8
 
9
9
 
10
10
 
@@ -1336,11 +1336,11 @@ function header(state, options) {
1336
1336
  return out;
1337
1337
  }
1338
1338
  function serializePaintDocument(state, options = {}) {
1339
- const { layers, assets } = _chunkVSMM7B3Pcjs.serializeLayers.call(void 0, state.layers);
1339
+ const { layers, assets } = _chunkZID226ZGcjs.serializeLayers.call(void 0, state.layers);
1340
1340
  return { ...header(state, options), layers, assets };
1341
1341
  }
1342
1342
  async function serializePaintDocumentExternal(state, store, options = {}) {
1343
- const { layers, assets } = await _chunkVSMM7B3Pcjs.serializeLayersExternal.call(void 0, state.layers, store);
1343
+ const { layers, assets } = await _chunkZID226ZGcjs.serializeLayersExternal.call(void 0, state.layers, store);
1344
1344
  return { ...header(state, options), layers, assets };
1345
1345
  }
1346
1346
  function paintLayersOnly(layers, problems) {
@@ -1377,7 +1377,7 @@ function deserializePaintDocument(raw) {
1377
1377
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
1378
1378
  const paper = normalizePaper(_nullishCoalesce(r.paper, () => ( {})));
1379
1379
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
1380
- const layers = paintLayersOnly(_chunkVSMM7B3Pcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1380
+ const layers = paintLayersOnly(_chunkZID226ZGcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1381
1381
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
1382
1382
  const activeLayerId = wanted && _chunkWSTEXEKDcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.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));
1383
1383
  return { state: { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) }, extensions: documentExtensions(r), guides: r.guides, swatches: r.swatches, problems };
@@ -1386,7 +1386,7 @@ async function deserializePaintDocumentAsync(raw, store) {
1386
1386
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
1387
1387
  const r = raw;
1388
1388
  const problems = [];
1389
- const assets = await _chunkVSMM7B3Pcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1389
+ const assets = await _chunkZID226ZGcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1390
1390
  const loaded = deserializePaintDocument({ ...r, assets });
1391
1391
  return { ...loaded, problems: [...problems, ...loaded.problems] };
1392
1392
  }
@@ -1509,6 +1509,28 @@ function defaultImageEncoder() {
1509
1509
  return new Uint8Array(await blob.arrayBuffer());
1510
1510
  };
1511
1511
  }
1512
+ async function decodeImageBlob(blob) {
1513
+ const g = globalThis;
1514
+ if (typeof g.createImageBitmap !== "function" || typeof g.OffscreenCanvas !== "function") throw new Error("Decoding images needs a browser (createImageBitmap and OffscreenCanvas).");
1515
+ const bitmap = await g.createImageBitmap(blob);
1516
+ const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);
1517
+ const ctx = canvas.getContext("2d");
1518
+ if (!ctx) throw new Error("No 2D context to decode with.");
1519
+ ctx.drawImage(bitmap, 0, 0);
1520
+ const data = new Uint8ClampedArray(ctx.getImageData(0, 0, bitmap.width, bitmap.height).data);
1521
+ _optionalChain([bitmap, 'access', _30 => _30.close, 'optionalCall', _31 => _31()]);
1522
+ return { width: bitmap.width, height: bitmap.height, data };
1523
+ }
1524
+ function downloadBytes(bytes, fileName, mimeType) {
1525
+ const g = globalThis;
1526
+ if (!g.document || !g.URL || !g.Blob) throw new Error("Downloading needs a browser.");
1527
+ const url = g.URL.createObjectURL(new g.Blob([bytes], { type: mimeType }));
1528
+ const a = g.document.createElement("a");
1529
+ a.href = url;
1530
+ a.download = fileName;
1531
+ a.click();
1532
+ setTimeout(() => g.URL.revokeObjectURL(url), 1e3);
1533
+ }
1512
1534
 
1513
1535
  // src/paint-editor/thumbnails.ts
1514
1536
  function thumbnailStroke(width, height) {
@@ -2001,7 +2023,7 @@ function unionRect(a, b) {
2001
2023
  const y = Math.min(a.y, b.y);
2002
2024
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
2003
2025
  }
2004
- var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _30 => _30.type]) === "pixel";
2026
+ var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _32 => _32.type]) === "pixel";
2005
2027
  var PaintEditorController = (_class9 = class {
2006
2028
 
2007
2029
  __init33() {this.extensions = {}}
@@ -2073,8 +2095,8 @@ var PaintEditorController = (_class9 = class {
2073
2095
  hand: this.hand,
2074
2096
  canUndo: this.undoStack.length > 0 && !this.session,
2075
2097
  canRedo: this.redoStack.length > 0 && !this.session,
2076
- undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _31 => _31.label]), () => ( null)),
2077
- redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _32 => _32.label]), () => ( null)),
2098
+ undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _33 => _33.label]), () => ( null)),
2099
+ redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _34 => _34.label]), () => ( null)),
2078
2100
  guides: this.guides,
2079
2101
  swatches: this.swatches,
2080
2102
  mixingPadVersion: this.pad.version,
@@ -2182,7 +2204,7 @@ var PaintEditorController = (_class9 = class {
2182
2204
  }
2183
2205
  // --- Layers --------------------------------------------------------------------
2184
2206
  getLayer(id) {
2185
- return _optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _33 => _33.layer]);
2207
+ return _optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _35 => _35.layer]);
2186
2208
  }
2187
2209
  /** The active pixel layer (or `undefined`). */
2188
2210
  getActiveLayer() {
@@ -2201,7 +2223,7 @@ var PaintEditorController = (_class9 = class {
2201
2223
  walk(this.doc.layers, null, 0);
2202
2224
  return out;
2203
2225
  }
2204
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _34 => _34.parent, 'optionalAccess', _35 => _35.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _36 => _36.path, 'access', _37 => _37.length]), () => ( 0))) {
2226
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _36 => _36.parent, 'optionalAccess', _37 => _37.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _38 => _38.path, 'access', _39 => _39.length]), () => ( 0))) {
2205
2227
  let bounds = null;
2206
2228
  if (l.type === "pixel") {
2207
2229
  const b = _chunkCRMAXIUVcjs.contentBounds.call(void 0, l.surface);
@@ -2248,7 +2270,7 @@ var PaintEditorController = (_class9 = class {
2248
2270
  this.requireIdle("adding a layer");
2249
2271
  const count = _chunkWSTEXEKDcjs.flattenLayers.call(void 0, this.doc.layers).length;
2250
2272
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
2251
- const name = _optionalChain([options, 'access', _38 => _38.name, 'optionalAccess', _39 => _39.trim, 'call', _40 => _40()]) || (type === "group" ? `Group ${count + 1}` : `Layer ${count + 1}`);
2273
+ const name = _optionalChain([options, 'access', _40 => _40.name, 'optionalAccess', _41 => _41.trim, 'call', _42 => _42()]) || (type === "group" ? `Group ${count + 1}` : `Layer ${count + 1}`);
2252
2274
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
2253
2275
  let parentId = null;
2254
2276
  let index;
@@ -2260,7 +2282,7 @@ var PaintEditorController = (_class9 = class {
2260
2282
  } else if (above) {
2261
2283
  const loc = _chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, above);
2262
2284
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
2263
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _41 => _41.parent, 'optionalAccess', _42 => _42.id]), () => ( null));
2285
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _43 => _43.parent, 'optionalAccess', _44 => _44.id]), () => ( null));
2264
2286
  index = loc.index + 1;
2265
2287
  }
2266
2288
  const layers = _chunkWSTEXEKDcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
@@ -2295,7 +2317,7 @@ var PaintEditorController = (_class9 = class {
2295
2317
  if (_chunkWSTEXEKDcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
2296
2318
  const layers = _chunkWSTEXEKDcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
2297
2319
  let active = this.doc.activeLayerId;
2298
- if (active && !_chunkWSTEXEKDcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.flattenLayers.call(void 0, layers), 'access', _43 => _43.filter, 'call', _44 => _44((x) => x.type === "pixel"), 'access', _45 => _45.pop, 'call', _46 => _46(), 'optionalAccess', _47 => _47.id]), () => ( null));
2320
+ if (active && !_chunkWSTEXEKDcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkWSTEXEKDcjs.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));
2299
2321
  this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active });
2300
2322
  return { removed: id, activeLayerId: active };
2301
2323
  }
@@ -2305,7 +2327,7 @@ var PaintEditorController = (_class9 = class {
2305
2327
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
2306
2328
  const copy = (l) => l.type === "group" ? { ...l, id: newPaintLayerId(), children: l.children.map(copy) } : { ...l, id: newPaintLayerId() };
2307
2329
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
2308
- const layers = _chunkWSTEXEKDcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _48 => _48.parent, 'optionalAccess', _49 => _49.id]), () => ( null)), loc.index + 1);
2330
+ const layers = _chunkWSTEXEKDcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _50 => _50.parent, 'optionalAccess', _51 => _51.id]), () => ( null)), loc.index + 1);
2309
2331
  this.commit("Duplicate layer", { ...this.doc, layers, activeLayerId: dup.id });
2310
2332
  return this.describeLayer(dup);
2311
2333
  }
@@ -2314,7 +2336,7 @@ var PaintEditorController = (_class9 = class {
2314
2336
  this.requireIdle("moving a layer");
2315
2337
  const loc = _chunkWSTEXEKDcjs.findLayer.call(void 0, this.doc.layers, id);
2316
2338
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
2317
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _50 => _50.parent, 'optionalAccess', _51 => _51.id]), () => ( null)) : parentId;
2339
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _52 => _52.parent, 'optionalAccess', _53 => _53.id]), () => ( null)) : parentId;
2318
2340
  if (target) {
2319
2341
  const g = this.requireLayer(target);
2320
2342
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
@@ -2402,7 +2424,7 @@ var PaintEditorController = (_class9 = class {
2402
2424
  const tiles = new Map(base.tiles);
2403
2425
  for (const { tx, ty } of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {
2404
2426
  const key = _chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty);
2405
- const src = _nullishCoalesce(_optionalChain([base, 'access', _52 => _52.tiles, 'access', _53 => _53.get, 'call', _54 => _54(key), 'optionalAccess', _55 => _55.data]), () => ( new Uint8ClampedArray(_chunkCRMAXIUVcjs.TILE * _chunkCRMAXIUVcjs.TILE * 4)));
2427
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _54 => _54.tiles, 'access', _55 => _55.get, 'call', _56 => _56(key), 'optionalAccess', _57 => _57.data]), () => ( new Uint8ClampedArray(_chunkCRMAXIUVcjs.TILE * _chunkCRMAXIUVcjs.TILE * 4)));
2406
2428
  const tile = _chunkCRMAXIUVcjs.finishTile.call(void 0, _chunkPV42JITTcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
2407
2429
  if (tile) tiles.set(key, tile);
2408
2430
  else tiles.delete(key);
@@ -2588,7 +2610,7 @@ var PaintEditorController = (_class9 = class {
2588
2610
  const brush = this.strokeBrush(init);
2589
2611
  let color = init.color === void 0 ? this.color : parseColor(init.color);
2590
2612
  const tracing = this.guides.tracing;
2591
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _56 => _56.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
2613
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _58 => _58.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
2592
2614
  const perspective = this.guides.perspective;
2593
2615
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
2594
2616
  const rgba = rgbaOf(color);
@@ -2642,7 +2664,7 @@ var PaintEditorController = (_class9 = class {
2642
2664
  this.live = null;
2643
2665
  this.liveLayers = null;
2644
2666
  const brush = s.init.brush;
2645
- if (!cancelled && _optionalChain([s, 'access', _57 => _57.result, 'optionalAccess', _58 => _58.mixerLoad]) && brush.loadsColor) this.mixerLoad = s.result.mixerLoad;
2667
+ if (!cancelled && _optionalChain([s, 'access', _59 => _59.result, 'optionalAccess', _60 => _60.mixerLoad]) && brush.loadsColor) this.mixerLoad = s.result.mixerLoad;
2646
2668
  if (cancelled || !surface) {
2647
2669
  this.emit();
2648
2670
  return;
@@ -2711,7 +2733,7 @@ var PaintEditorController = (_class9 = class {
2711
2733
  */
2712
2734
  replayStrokes(options) {
2713
2735
  this.requireIdle("replaying");
2714
- if (!_optionalChain([options, 'access', _59 => _59.strokeIds, 'optionalAccess', _60 => _60.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
2736
+ if (!_optionalChain([options, 'access', _61 => _61.strokeIds, 'optionalAccess', _62 => _62.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
2715
2737
  const strokes = options.strokeIds.map((id) => {
2716
2738
  const s = this.doc.strokes.find((x) => x.id === id);
2717
2739
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -2763,7 +2785,7 @@ var PaintEditorController = (_class9 = class {
2763
2785
  currentLayers() {
2764
2786
  const live = this.live;
2765
2787
  if (!live) return this.doc.layers;
2766
- if (_optionalChain([this, 'access', _61 => _61.liveLayers, 'optionalAccess', _62 => _62.key]) === live.surface) return this.liveLayers.layers;
2788
+ if (_optionalChain([this, 'access', _63 => _63.liveLayers, 'optionalAccess', _64 => _64.key]) === live.surface) return this.liveLayers.layers;
2767
2789
  const layers = _chunkWSTEXEKDcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
2768
2790
  this.liveLayers = { key: live.surface, layers };
2769
2791
  return layers;
@@ -2778,7 +2800,7 @@ var PaintEditorController = (_class9 = class {
2778
2800
  tracingNode(t) {
2779
2801
  const { width, height } = this.doc.canvas;
2780
2802
  const key = this.tracingVersion * 100003 + width * 7 + height;
2781
- if (_optionalChain([this, 'access', _63 => _63.tracingCache, 'optionalAccess', _64 => _64.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
2803
+ if (_optionalChain([this, 'access', _65 => _65.tracingCache, 'optionalAccess', _66 => _66.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
2782
2804
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
2783
2805
  const image = resampleInto(src, t.rect, width, height);
2784
2806
  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 };
@@ -2803,7 +2825,7 @@ var PaintEditorController = (_class9 = class {
2803
2825
  */
2804
2826
  compositeTiles(rect, onTile, options = {}) {
2805
2827
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
2806
- this.viewCompositor.compositeTiles(this.renderLayers({}, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _65 => _65.live, 'optionalAccess', _66 => _66.layerId]), () => ( this.doc.activeLayerId)) });
2828
+ this.viewCompositor.compositeTiles(this.renderLayers({}, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _67 => _67.live, 'optionalAccess', _68 => _68.layerId]), () => ( this.doc.activeLayerId)) });
2807
2829
  }
2808
2830
  /** The canvas as canvas-sized RGBA (paper included by default). */
2809
2831
  compositePixels(options = {}) {
@@ -2837,7 +2859,7 @@ var PaintEditorController = (_class9 = class {
2837
2859
  this.swatches = loaded.swatches.filter((x) => Boolean(x) && typeof x.color === "string" && /^#[0-9a-f]{6}$/i.test(x.color)).map((x) => typeof x.name === "string" ? { color: x.color.toLowerCase(), name: x.name } : { color: x.color.toLowerCase() });
2838
2860
  }
2839
2861
  for (const s of loaded.state.strokes) {
2840
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _67 => _67.exec, 'call', _68 => _68(s.id), 'optionalAccess', _69 => _69[1]]), () => ( 0)));
2862
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _69 => _69.exec, 'call', _70 => _70(s.id), 'optionalAccess', _71 => _71[1]]), () => ( 0)));
2841
2863
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
2842
2864
  }
2843
2865
  this.undoStack = [];
@@ -2914,7 +2936,7 @@ var PaintEditorController = (_class9 = class {
2914
2936
  offset: { x: 0, y: 0 }
2915
2937
  };
2916
2938
  const merged = this.compositePixels({ paper: true }).data;
2917
- const result = _chunkVSMM7B3Pcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...this.doc.layers], merged, resolution: dpi });
2939
+ const result = _chunkZID226ZGcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...this.doc.layers], merged, resolution: dpi });
2918
2940
  const pigment = _chunkWSTEXEKDcjs.flattenLayers.call(void 0, this.doc.layers).filter((l) => l.blend === "pigment");
2919
2941
  if (pigment.length) result.warnings.push(`Pigment blending has no PSD equivalent; ${pigment.map((l) => `"${l.name}"`).join(", ")} ${pigment.length === 1 ? "was" : "were"} written as Normal, so ${pigment.length === 1 ? "it looks" : "they look"} different in Photoshop.`);
2920
2942
  return result;
@@ -3028,7 +3050,7 @@ var PaintEditorController = (_class9 = class {
3028
3050
  const { src, pixels } = this.importImage(options, "The reference image");
3029
3051
  const ref = {
3030
3052
  id: `ref${this.nextReferenceId++}`,
3031
- name: _optionalChain([options, 'access', _70 => _70.name, 'optionalAccess', _71 => _71.trim, 'call', _72 => _72()]) || `Reference ${this.guides.references.length + 1}`,
3053
+ name: _optionalChain([options, 'access', _72 => _72.name, 'optionalAccess', _73 => _73.trim, 'call', _74 => _74()]) || `Reference ${this.guides.references.length + 1}`,
3032
3054
  src,
3033
3055
  width: pixels.width,
3034
3056
  height: pixels.height,
@@ -3107,7 +3129,7 @@ var PaintEditorController = (_class9 = class {
3107
3129
  try {
3108
3130
  const px = this.decodeImage(ref.src, `Reference "${ref.name}"`);
3109
3131
  guides.references.push({ id: ref.id, name: String(_nullishCoalesce(ref.name, () => ( ref.id))), src: ref.src, width: px.width, height: px.height, x: Number(ref.x) || 0, y: Number(ref.y) || 0, displayWidth: Number(ref.displayWidth) || 240, visible: ref.visible !== false });
3110
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _73 => _73.exec, 'call', _74 => _74(ref.id), 'optionalAccess', _75 => _75[1]]), () => ( 0)));
3132
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _75 => _75.exec, 'call', _76 => _76(ref.id), 'optionalAccess', _77 => _77[1]]), () => ( 0)));
3111
3133
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
3112
3134
  } catch (e) {
3113
3135
  problems.push(e.message);
@@ -3127,7 +3149,7 @@ var PaintEditorController = (_class9 = class {
3127
3149
  }
3128
3150
  addSwatch(color, name) {
3129
3151
  const c = parseColor(color);
3130
- this.swatches = [...this.swatches, _optionalChain([name, 'optionalAccess', _76 => _76.trim, 'call', _77 => _77()]) ? { color: c, name: name.trim() } : { color: c }];
3152
+ this.swatches = [...this.swatches, _optionalChain([name, 'optionalAccess', _78 => _78.trim, 'call', _79 => _79()]) ? { color: c, name: name.trim() } : { color: c }];
3131
3153
  this.emit([]);
3132
3154
  return this.swatches;
3133
3155
  }
@@ -3175,7 +3197,7 @@ var PaintEditorController = (_class9 = class {
3175
3197
  }
3176
3198
  /** A layer's tile surface (live while stroking), for thumbnails. */
3177
3199
  layerSurface(id) {
3178
- const l = _optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _78 => _78.layer]);
3200
+ const l = _optionalChain([_chunkWSTEXEKDcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _80 => _80.layer]);
3179
3201
  return isPixelLayer(l) ? l.surface : null;
3180
3202
  }
3181
3203
  }, _class9);
@@ -3905,7 +3927,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
3905
3927
  annotations: { title: "List brushes", ...READ2 },
3906
3928
  handler: () => {
3907
3929
  const s = c.getState();
3908
- return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _79 => _79.getBrush, 'call', _80 => _80(s.brush.id), 'optionalAccess', _81 => _81.builtin])), brushes: s.brushes.map(brushSummary) };
3930
+ return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _81 => _81.getBrush, 'call', _82 => _82(s.brush.id), 'optionalAccess', _83 => _83.builtin])), brushes: s.brushes.map(brushSummary) };
3909
3931
  }
3910
3932
  });
3911
3933
  add({
@@ -4124,7 +4146,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
4124
4146
  color: s.color,
4125
4147
  points: ids ? s.points : s.points.length,
4126
4148
  seed: s.seed,
4127
- copies: _nullishCoalesce(_optionalChain([s, 'access', _82 => _82.copies, 'optionalAccess', _83 => _83.length]), () => ( 0)),
4149
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _84 => _84.copies, 'optionalAccess', _85 => _85.length]), () => ( 0)),
4128
4150
  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) }
4129
4151
  };
4130
4152
  })
@@ -4293,6 +4315,300 @@ function createPaintEditorToolProvider(controller, options = {}) {
4293
4315
  return { id: _nullishCoalesce(options.id, () => ( "paint-editor")), namespace: options.namespace, tools };
4294
4316
  }
4295
4317
 
4318
+ // src/paint-editor/ui.ts
4319
+ var PAINT_TOOLS = [
4320
+ { id: "brush", label: "Brush", key: "b" },
4321
+ { id: "eyedropper", label: "Eyedropper", key: "i" },
4322
+ { id: "pan", label: "Pan", key: "h" },
4323
+ { id: "rotate", label: "Rotate view", key: "r" }
4324
+ ];
4325
+ var PaintGesture = (_class10 = class {
4326
+ constructor(controller, box) {;_class10.prototype.__init56.call(this);_class10.prototype.__init57.call(this);_class10.prototype.__init58.call(this);_class10.prototype.__init59.call(this);_class10.prototype.__init60.call(this);_class10.prototype.__init61.call(this);
4327
+ this.controller = controller;
4328
+ this.box = box;
4329
+ }
4330
+
4331
+
4332
+ __init56() {this.tool = "brush"}
4333
+ /** The last refusal (a hidden or locked layer), for the editor to show. */
4334
+ __init57() {this.error = null}
4335
+ /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */
4336
+ __init58() {this.predicted = []}
4337
+ __init59() {this.mode = null}
4338
+ __init60() {this.penAt = null}
4339
+ __init61() {this.penDown = false}
4340
+ doc(e) {
4341
+ const b = this.box();
4342
+ const s = this.controller.getState();
4343
+ return screenToDocument(s.view, s.document.canvas, b, e.clientX - b.left, e.clientY - b.top);
4344
+ }
4345
+ pen(e) {
4346
+ const p = this.doc(e);
4347
+ return pointerToPenPoint(e, p.x, p.y, this.controller.getState().view);
4348
+ }
4349
+ /** Pointer down; returns true when the gesture took the pointer (capture it). */
4350
+ down(e) {
4351
+ this.error = null;
4352
+ if (this.mode) return false;
4353
+ if (e.pointerType === "pen") {
4354
+ this.penDown = true;
4355
+ this.penAt = { x: e.clientX, y: e.clientY };
4356
+ } else if (e.pointerType === "touch" && (this.penDown || isPalmTouch({ x: e.clientX, y: e.clientY }, this.penAt, this.controller.getState().hand))) {
4357
+ return false;
4358
+ }
4359
+ const middle = e.button === 1;
4360
+ const tool = middle ? "pan" : this.tool;
4361
+ if (tool === "pan") {
4362
+ this.mode = { kind: "pan", pointerId: e.pointerId, x: e.clientX, y: e.clientY, pan: { ...this.controller.getState().view.pan } };
4363
+ return true;
4364
+ }
4365
+ if (tool === "rotate") {
4366
+ const b = this.box();
4367
+ this.mode = { kind: "rotate", pointerId: e.pointerId, angle: Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2), rotation: this.controller.getState().view.rotation };
4368
+ return true;
4369
+ }
4370
+ if (tool === "eyedropper" || e.altKey) {
4371
+ this.pick(e);
4372
+ return false;
4373
+ }
4374
+ try {
4375
+ const p = this.pen(e);
4376
+ const session = this.controller.beginStroke({ start: p });
4377
+ session.push([p]);
4378
+ this.mode = { kind: "stroke", pointerId: e.pointerId };
4379
+ return true;
4380
+ } catch (err) {
4381
+ this.error = err instanceof Error ? err.message : String(err);
4382
+ return false;
4383
+ }
4384
+ }
4385
+ pick(e) {
4386
+ const p = this.doc(e);
4387
+ const { width, height } = this.controller.document.canvas;
4388
+ if (p.x < 0 || p.y < 0 || p.x >= width || p.y >= height) return;
4389
+ this.controller.setColor(this.controller.pickColor(p.x, p.y).color);
4390
+ }
4391
+ move(e) {
4392
+ if (e.pointerType === "pen") this.penAt = { x: e.clientX, y: e.clientY };
4393
+ const m = this.mode;
4394
+ if (!m || m.pointerId !== e.pointerId) return;
4395
+ if (m.kind === "pan") {
4396
+ this.controller.setView({ pan: { x: m.pan.x + e.clientX - m.x, y: m.pan.y + e.clientY - m.y } });
4397
+ return;
4398
+ }
4399
+ if (m.kind === "rotate") {
4400
+ const b = this.box();
4401
+ const a = Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2);
4402
+ let r = m.rotation + (a - m.angle) * 180 / Math.PI;
4403
+ if (e.shiftKey) r = Math.round(r / 15) * 15;
4404
+ this.controller.setView({ rotation: r });
4405
+ return;
4406
+ }
4407
+ const session = this.controller.activeStroke;
4408
+ if (!session) return;
4409
+ const events = typeof e.getCoalescedEvents === "function" ? e.getCoalescedEvents() : [];
4410
+ session.push((events.length ? events : [e]).map((ev) => this.pen(ev)));
4411
+ const predicted = typeof e.getPredictedEvents === "function" ? e.getPredictedEvents() : [];
4412
+ this.predicted = predicted.map((ev) => this.pen(ev));
4413
+ }
4414
+ up(e) {
4415
+ if (e.pointerType === "pen") this.penDown = false;
4416
+ const m = this.mode;
4417
+ if (!m || m.pointerId !== e.pointerId) return;
4418
+ this.mode = null;
4419
+ this.predicted = [];
4420
+ if (m.kind === "stroke") _optionalChain([this, 'access', _86 => _86.controller, 'access', _87 => _87.activeStroke, 'optionalAccess', _88 => _88.end, 'call', _89 => _89()]);
4421
+ }
4422
+ cancel() {
4423
+ this.penDown = false;
4424
+ this.predicted = [];
4425
+ if (_optionalChain([this, 'access', _90 => _90.mode, 'optionalAccess', _91 => _91.kind]) === "stroke") _optionalChain([this, 'access', _92 => _92.controller, 'access', _93 => _93.activeStroke, 'optionalAccess', _94 => _94.cancel, 'call', _95 => _95()]);
4426
+ this.mode = null;
4427
+ }
4428
+ get active() {
4429
+ return this.mode !== null;
4430
+ }
4431
+ /** Wheel: zoom about the pointer (Ctrl / pinch or plain wheel), Shift+wheel rotates the view. */
4432
+ wheel(e) {
4433
+ const s = this.controller.getState();
4434
+ if (e.shiftKey) {
4435
+ this.controller.setView({ rotation: s.view.rotation + (e.deltaY > 0 ? 5 : -5) });
4436
+ return;
4437
+ }
4438
+ const b = this.box();
4439
+ const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, s.view.zoom * Math.exp(-e.deltaY * 15e-4)));
4440
+ const k = zoom / s.view.zoom;
4441
+ const px = e.clientX - b.left - b.width / 2;
4442
+ const py = e.clientY - b.top - b.height / 2;
4443
+ this.controller.setView({ zoom, pan: { x: px - (px - s.view.pan.x) * k, y: py - (py - s.view.pan.y) * k } });
4444
+ }
4445
+ }, _class10);
4446
+ function handlePaintShortcut(controller, gesture, e) {
4447
+ const mod = e.ctrlKey || e.metaKey;
4448
+ const key = e.key.toLowerCase();
4449
+ if (mod && key === "z") {
4450
+ if (controller.getState().stroking) return true;
4451
+ if (e.shiftKey) controller.redo();
4452
+ else controller.undo();
4453
+ return true;
4454
+ }
4455
+ if (mod && key === "y") {
4456
+ controller.redo();
4457
+ return true;
4458
+ }
4459
+ if (mod) return false;
4460
+ const tool = PAINT_TOOLS.find((t) => t.key === key);
4461
+ if (tool) {
4462
+ gesture.tool = tool.id;
4463
+ return true;
4464
+ }
4465
+ const brush = controller.getState().brush;
4466
+ if (key === "[" || key === "]") {
4467
+ const step = Math.max(1, Math.round(brush.tip.size * 0.15));
4468
+ controller.setBrush({ tip: { size: Math.max(1, brush.tip.size + (key === "]" ? step : -step)) } });
4469
+ return true;
4470
+ }
4471
+ if (key === "x") {
4472
+ controller.swapColors();
4473
+ return true;
4474
+ }
4475
+ if (key === "m") {
4476
+ controller.setView({ mirror: !controller.getState().view.mirror });
4477
+ return true;
4478
+ }
4479
+ if (key === "escape") {
4480
+ controller.resetView();
4481
+ return true;
4482
+ }
4483
+ return false;
4484
+ }
4485
+ var PaintCanvasPresenter = (_class11 = class {
4486
+ constructor(controller) {;_class11.prototype.__init62.call(this);_class11.prototype.__init63.call(this);_class11.prototype.__init64.call(this);
4487
+ this.controller = controller;
4488
+ }
4489
+
4490
+ __init62() {this.uploaded = /* @__PURE__ */ new Map()}
4491
+ __init63() {this.scratch = null}
4492
+ __init64() {this.size = ""}
4493
+ /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
4494
+ render(ctx) {
4495
+ const { width, height } = this.controller.document.canvas;
4496
+ const size = `${width}x${height}`;
4497
+ let dirty = this.controller.takeDirty();
4498
+ if (size !== this.size) {
4499
+ this.size = size;
4500
+ this.uploaded.clear();
4501
+ dirty = "all";
4502
+ }
4503
+ let drawn = 0;
4504
+ const rect = { x: 0, y: 0, width, height };
4505
+ this.controller.compositeTiles(rect, (tx, ty, data) => {
4506
+ const key = `${tx},${ty}`;
4507
+ if (this.uploaded.get(key) === data) return;
4508
+ this.uploaded.set(key, data);
4509
+ if (!this.scratch) this.scratch = ctx.createImageData(_chunkCRMAXIUVcjs.TILE, _chunkCRMAXIUVcjs.TILE);
4510
+ this.scratch.data.set(data);
4511
+ const ox = tx * _chunkCRMAXIUVcjs.TILE;
4512
+ const oy = ty * _chunkCRMAXIUVcjs.TILE;
4513
+ ctx.putImageData(this.scratch, ox, oy, 0, 0, Math.min(_chunkCRMAXIUVcjs.TILE, width - ox), Math.min(_chunkCRMAXIUVcjs.TILE, height - oy));
4514
+ drawn++;
4515
+ }, { dirty });
4516
+ return drawn;
4517
+ }
4518
+ }, _class11);
4519
+ function guideOverlay(controller) {
4520
+ const s = controller.getState();
4521
+ const size = s.document.canvas;
4522
+ const out = [];
4523
+ for (const [from, to] of symmetryAxisSegments(s.guides.symmetry, size)) out.push({ from, to, kind: "symmetry" });
4524
+ if (s.guides.perspective.enabled) for (const [from, to] of perspectiveGuideLines(s.guides.perspective, size, 16)) out.push({ from, to, kind: "perspective" });
4525
+ return out;
4526
+ }
4527
+ var BRUSH_SLIDERS = [
4528
+ { path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
4529
+ { path: "tip.opacity", label: "Opacity", min: 0, max: 1, step: 0.01 },
4530
+ { path: "tip.flow", label: "Flow", min: 0, max: 1, step: 0.01 },
4531
+ { path: "tip.hardness", label: "Hardness", min: 0, max: 1, step: 0.01 },
4532
+ { path: "tip.spacing", label: "Spacing", min: 0.01, max: 1, step: 0.01 },
4533
+ { path: "tip.roundness", label: "Roundness", min: 0.05, max: 1, step: 0.01 },
4534
+ { path: "tip.angle", label: "Angle", min: -180, max: 180, step: 1 },
4535
+ { path: "grain", label: "Grain", min: 0, max: 1, step: 0.01 },
4536
+ { path: "tip.smoothing", label: "Smoothing", min: 0, max: 0.95, step: 0.01 },
4537
+ { path: "pressureSmoothing", label: "Pressure smoothing", min: 0, max: 0.95, step: 0.01 },
4538
+ { path: "dynamics.minSize", label: "Min size", min: 0, max: 1, step: 0.01 },
4539
+ { path: "dynamics.tiltSize", label: "Tilt size", min: 0, max: 1, step: 0.01 },
4540
+ { path: "dynamics.velocitySize", label: "Speed size", min: -1, max: 1, step: 0.01 }
4541
+ ];
4542
+ var PAPER_SLIDERS = [
4543
+ { path: "depth", label: "Grain depth", min: 0, max: 1, step: 0.01 },
4544
+ { path: "scale", label: "Grain scale", min: 0.25, max: 8, step: 0.05 },
4545
+ { path: "shading", label: "Shading", min: 0, max: 1, step: 0.01 },
4546
+ { path: "dry.contrast", label: "Contrast", min: 0, max: 3, step: 0.05 },
4547
+ { path: "absorption", label: "Absorption", min: 0, max: 1, step: 0.01 },
4548
+ { path: "permeability", label: "Permeability", min: 0, max: 1, step: 0.01 },
4549
+ { path: "roughness", label: "Roughness", min: 0, max: 1, step: 0.01 }
4550
+ ];
4551
+ function readPath(obj, path) {
4552
+ let v = obj;
4553
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _96 => _96[k]]);
4554
+ return typeof v === "number" ? v : 0;
4555
+ }
4556
+ function patchPath(obj, path, value) {
4557
+ const [head, ...rest] = path.split(".");
4558
+ if (!rest.length) return { [head]: value };
4559
+ return { [head]: { ...obj[head], ...patchPath(_nullishCoalesce(obj[head], () => ( {})), rest.join("."), value) } };
4560
+ }
4561
+ function wheelPoint(angle, radius) {
4562
+ const a = (angle - 90) * Math.PI / 180;
4563
+ return { x: Math.cos(a) * radius, y: Math.sin(a) * radius };
4564
+ }
4565
+ function wheelAngle(x, y) {
4566
+ return (Math.atan2(y, x) * 180 / Math.PI + 90 + 360) % 360;
4567
+ }
4568
+ function renderColorWheel(size, wheel, inner = 0.64) {
4569
+ const data = new Uint8ClampedArray(size * size * 4);
4570
+ const r = size / 2;
4571
+ for (let y = 0; y < size; y++) {
4572
+ for (let x = 0; x < size; x++) {
4573
+ const dx = x + 0.5 - r;
4574
+ const dy = y + 0.5 - r;
4575
+ const d = Math.hypot(dx, dy) / r;
4576
+ if (d > 1 || d < inner) continue;
4577
+ const [cr, cg, cb] = hsvToRgb(wheelToHue(wheelAngle(dx, dy), wheel), 1, 1);
4578
+ const i = (y * size + x) * 4;
4579
+ const edge = Math.min(1, (1 - d) * r, (d - inner) * r);
4580
+ data[i] = cr;
4581
+ data[i + 1] = cg;
4582
+ data[i + 2] = cb;
4583
+ data[i + 3] = Math.round(255 * Math.max(0, edge));
4584
+ }
4585
+ }
4586
+ return { width: size, height: size, data };
4587
+ }
4588
+ function wheelPick(dx, dy, wheel, color) {
4589
+ const [r, g, b] = parseHexColor(color);
4590
+ const { s, v } = rgbToHsv(r, g, b);
4591
+ const [nr, ng, nb] = hsvToRgb(wheelToHue(wheelAngle(dx, dy), wheel), s || 1, v || 1);
4592
+ return rgbToHexColor(nr, ng, nb);
4593
+ }
4594
+
4595
+
4596
+
4597
+
4598
+
4599
+
4600
+
4601
+
4602
+
4603
+
4604
+
4605
+
4606
+
4607
+
4608
+
4609
+
4610
+
4611
+
4296
4612
 
4297
4613
 
4298
4614
 
@@ -4413,5 +4729,5 @@ function createPaintEditorToolProvider(controller, options = {}) {
4413
4729
 
4414
4730
 
4415
4731
 
4416
- exports.BRUSH_ID = BRUSH_ID; exports.BRUSH_ROTATIONS = BRUSH_ROTATIONS; 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 = _chunkPV42JITTcjs.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.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.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; 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.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downsampleRgba = downsampleRgba; exports.fitZoom = fitZoom; exports.grainCatch = grainCatch; exports.grainHeights = grainHeights; exports.hash2 = hash2; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = hueToWheel; exports.invertAffine = invertAffine; 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.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.pointerToPenPoint = pointerToPenPoint; exports.rand01 = rand01; exports.randSigned = randSigned; exports.renderBrushThumbnail = renderBrushThumbnail; 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.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.wheelToHue = wheelToHue;
4732
+ exports.BLEND_MODES = _chunkCRMAXIUVcjs.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 = _chunkPV42JITTcjs.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.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 = _chunkCRMAXIUVcjs.isBlendMode; 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.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;
4417
4733
  //# sourceMappingURL=index.cjs.map