@pixerate/editor 0.266.1 → 0.267.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 (117) hide show
  1. package/dist/agent/index.cjs +8 -4
  2. package/dist/agent/index.js +6 -2
  3. package/dist/animation-editor/controller.d.cts +8 -0
  4. package/dist/animation-editor/controller.d.ts +8 -0
  5. package/dist/animation-editor/effect-tools.d.cts +1 -1
  6. package/dist/animation-editor/effect-tools.d.ts +1 -1
  7. package/dist/animation-editor/index.cjs +172 -105
  8. package/dist/animation-editor/index.js +91 -24
  9. package/dist/brushes/index.cjs +59 -59
  10. package/dist/brushes/index.js +5 -5
  11. package/dist/brushes/profiles.d.cts +6 -1
  12. package/dist/brushes/profiles.d.ts +6 -1
  13. package/dist/{brushstrokeRender-FSUWXUZY.cjs → brushstrokeRender-L7JYRR2R.cjs} +16 -16
  14. package/dist/{brushstrokeRender-KD453OBX.js → brushstrokeRender-NLFPEBGI.js} +4 -4
  15. package/dist/canvas/brushTypes.d.cts +12 -0
  16. package/dist/canvas/brushTypes.d.ts +12 -0
  17. package/dist/canvas/brushstroke.d.cts +1 -1
  18. package/dist/canvas/brushstroke.d.ts +1 -1
  19. package/dist/canvas/drawController.d.cts +19 -4
  20. package/dist/canvas/drawController.d.ts +19 -4
  21. package/dist/canvas/index.cjs +144 -105
  22. package/dist/canvas/index.js +46 -7
  23. package/dist/{chunk-XORJ7UZO.cjs → chunk-3VHH6V67.cjs} +13 -12
  24. package/dist/{chunk-T2LDTEXK.js → chunk-4IDUYB45.js} +2217 -56
  25. package/dist/chunk-7UKFXXWL.js +802 -0
  26. package/dist/chunk-ADMRNWR7.js +340 -0
  27. package/dist/{chunk-CIJBSUM5.js → chunk-AGNUD5BI.js} +2 -2
  28. package/dist/{chunk-WLUVZKVD.cjs → chunk-DT4YQUGT.cjs} +32 -32
  29. package/dist/{chunk-DXYHQ2VN.js → chunk-EF7LZAXQ.js} +1 -1
  30. package/dist/chunk-EXB2EGBE.cjs +802 -0
  31. package/dist/{chunk-4ODRXQRW.js → chunk-EYSHTYLG.js} +1 -1
  32. package/dist/{chunk-R44Y3EFS.js → chunk-FGJHJIMN.js} +8 -336
  33. package/dist/{chunk-AQZQWXEU.cjs → chunk-G7NHE2VD.cjs} +35 -35
  34. package/dist/{chunk-XC6DPRYI.js → chunk-GSTSZPSR.js} +154 -949
  35. package/dist/{chunk-VRK322ZC.cjs → chunk-HIO6E7LC.cjs} +2 -2
  36. package/dist/{chunk-TOID45I2.cjs → chunk-J2TNIZ55.cjs} +1 -1
  37. package/dist/{chunk-YHDHFJUC.cjs → chunk-J5VQYK7T.cjs} +217 -1012
  38. package/dist/{chunk-3C33YTNN.js → chunk-JGWVZPT6.js} +2 -2
  39. package/dist/{chunk-ACFSFUQH.js → chunk-JL6YH5WD.js} +4 -0
  40. package/dist/{chunk-3SBLVGOM.cjs → chunk-LA5Y4ETA.cjs} +23 -23
  41. package/dist/{chunk-MVUQSK5J.cjs → chunk-LHPEG5AU.cjs} +107 -435
  42. package/dist/{chunk-DOZ6F2K2.js → chunk-NSETJI74.js} +3 -2
  43. package/dist/{chunk-XRXFVRGY.cjs → chunk-OKHKA43L.cjs} +2364 -203
  44. package/dist/{chunk-LK4SXL3V.js → chunk-OSEXT7JL.js} +1 -1
  45. package/dist/{chunk-PE6YJMQT.cjs → chunk-PFHJS4HE.cjs} +20 -19
  46. package/dist/{chunk-ZQI3WUPP.js → chunk-QCLY5SFS.js} +12 -0
  47. package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
  48. package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
  49. package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
  50. package/dist/{chunk-RFJZGTHA.cjs → chunk-XVOP3CGQ.cjs} +9 -9
  51. package/dist/{chunk-EZOJBP4D.js → chunk-YIC6MAJ2.js} +1 -1
  52. package/dist/chunk-YZWM6ZIP.cjs +340 -0
  53. package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
  54. package/dist/{chunk-YBC3RKT2.cjs → chunk-ZGXJ7BTR.cjs} +13 -1
  55. package/dist/commands/builtins.d.cts +12 -1
  56. package/dist/commands/builtins.d.ts +12 -1
  57. package/dist/commands/index.cjs +2 -2
  58. package/dist/commands/index.js +1 -1
  59. package/dist/image-editor/controller.d.cts +1 -1
  60. package/dist/image-editor/controller.d.ts +1 -1
  61. package/dist/image-editor/index.cjs +837 -833
  62. package/dist/image-editor/index.js +105 -101
  63. package/dist/paint/index.cjs +5 -3
  64. package/dist/paint/index.js +46 -44
  65. package/dist/paint-editor/controller.d.cts +5 -3
  66. package/dist/paint-editor/controller.d.ts +5 -3
  67. package/dist/paint-editor/index.cjs +832 -2295
  68. package/dist/paint-editor/index.js +285 -1748
  69. package/dist/paint-editor/path-samples.d.cts +2 -0
  70. package/dist/paint-editor/path-samples.d.ts +2 -0
  71. package/dist/paint-editor/presence.d.cts +20 -1
  72. package/dist/paint-editor/presence.d.ts +20 -1
  73. package/dist/stickers/helpers.d.cts +2 -0
  74. package/dist/stickers/helpers.d.ts +2 -0
  75. package/dist/stickers/index.cjs +41 -35
  76. package/dist/stickers/index.js +22 -16
  77. package/dist/stickers/types.d.cts +4 -2
  78. package/dist/stickers/types.d.ts +4 -2
  79. package/dist/tools/conformance.d.cts +8 -0
  80. package/dist/tools/conformance.d.ts +8 -0
  81. package/dist/tools/index.cjs +6 -2
  82. package/dist/tools/index.js +5 -1
  83. package/dist/vector/backdrop.d.cts +13 -0
  84. package/dist/vector/backdrop.d.ts +13 -0
  85. package/dist/vector/brushstroke.d.cts +54 -7
  86. package/dist/vector/brushstroke.d.ts +54 -7
  87. package/dist/vector/brushstrokeMedia.d.cts +96 -0
  88. package/dist/vector/brushstrokeMedia.d.ts +96 -0
  89. package/dist/vector/controller.d.cts +17 -3
  90. package/dist/vector/controller.d.ts +17 -3
  91. package/dist/vector/index.cjs +1846 -1386
  92. package/dist/vector/index.d.cts +2 -0
  93. package/dist/vector/index.d.ts +2 -0
  94. package/dist/vector/index.js +517 -57
  95. package/dist/vector/render.d.cts +6 -0
  96. package/dist/vector/render.d.ts +6 -0
  97. package/dist/vector/types.d.cts +14 -0
  98. package/dist/vector/types.d.ts +14 -0
  99. package/package.json +1 -1
  100. package/skills/pixerate-animation-editor/SKILL.md +1 -0
  101. package/skills/pixerate-brushes/SKILL.md +2 -2
  102. package/skills/pixerate-brushes-design/SKILL.md +7 -4
  103. package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
  104. package/skills/pixerate-canvas/SKILL.md +11 -1
  105. package/skills/pixerate-image-editor/SKILL.md +19 -64
  106. package/skills/pixerate-image-editor/references/color-management.md +2 -1
  107. package/skills/pixerate-image-editor/references/free-transform.md +12 -0
  108. package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
  109. package/skills/pixerate-image-editor/references/painting.md +17 -0
  110. package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
  111. package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
  112. package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
  113. package/skills/pixerate-paint-editor/SKILL.md +8 -4
  114. package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
  115. package/skills/pixerate-vector/SKILL.md +16 -6
  116. package/skills/pixerate-vector/references/best-practices.md +1 -0
  117. package/skills/pixerate-vector/references/commands.md +19 -0
@@ -18,7 +18,7 @@ import {
18
18
  unionBounds,
19
19
  vectorGradientPoints,
20
20
  widthProfileAt
21
- } from "./chunk-T2LDTEXK.js";
21
+ } from "./chunk-4IDUYB45.js";
22
22
  import {
23
23
  segmentLength,
24
24
  segmentParamAtLength,
@@ -7,7 +7,8 @@
7
7
 
8
8
 
9
9
 
10
- var _chunkOTN6VB5Scjs = require('./chunk-OTN6VB5S.cjs');
10
+
11
+ var _chunkRDFHWAHLcjs = require('./chunk-RDFHWAHL.cjs');
11
12
 
12
13
 
13
14
  var _chunkU67EN7GGcjs = require('./chunk-U67EN7GG.cjs');
@@ -17,26 +18,26 @@ var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, o
17
18
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
18
19
  function stickerForAgent(provider, s) {
19
20
  const { id, thumbnail: _thumbnail, ...rest } = s;
20
- return { ref: _chunkOTN6VB5Scjs.stickerRefOf.call(void 0, provider, id), ...rest };
21
+ return { ref: _chunkRDFHWAHLcjs.stickerRefOf.call(void 0, provider, id), ...rest };
21
22
  }
22
23
  async function knownRefs(provider, cap = 500) {
23
24
  const refs = [];
24
25
  let after;
25
26
  while (refs.length < cap) {
26
- const page = await provider.list({ limit: _chunkOTN6VB5Scjs.MAX_STICKER_PAGE, ...after ? { after } : {} });
27
- refs.push(...page.items.map((s) => _chunkOTN6VB5Scjs.stickerRefOf.call(void 0, provider, s.id)));
27
+ const page = await provider.list({ limit: _chunkRDFHWAHLcjs.MAX_STICKER_PAGE, ...after ? { after } : {} });
28
+ refs.push(...page.items.map((s) => _chunkRDFHWAHLcjs.stickerRefOf.call(void 0, provider, s.id)));
28
29
  if (!page.next || !page.items.length) break;
29
30
  after = page.next;
30
31
  }
31
32
  return refs;
32
33
  }
33
34
  async function describeStickerRef(provider, ref) {
34
- _chunkOTN6VB5Scjs.parseStickerRef.call(void 0, ref);
35
- const id = _chunkOTN6VB5Scjs.stickerIdFor.call(void 0, provider, ref);
35
+ _chunkRDFHWAHLcjs.parseStickerRef.call(void 0, ref);
36
+ const id = _chunkRDFHWAHLcjs.stickerIdFor.call(void 0, provider, ref);
36
37
  const found = id === null ? void 0 : await provider.describe(id);
37
38
  if (found) return found;
38
- const near = _chunkOTN6VB5Scjs.closestStickerRefs.call(void 0, ref, await knownRefs(provider));
39
- const owner = _chunkOTN6VB5Scjs.parseStickerRef.call(void 0, ref).provider;
39
+ const near = _chunkRDFHWAHLcjs.closestStickerRefs.call(void 0, ref, await knownRefs(provider));
40
+ const owner = _chunkRDFHWAHLcjs.parseStickerRef.call(void 0, ref).provider;
40
41
  const where = id === null && !provider.namespaced ? ` The sticker library is "${provider.id}", not "${owner}".` : "";
41
42
  throw new (0, _chunkU67EN7GGcjs.StickerError)("unknown_sticker", `No sticker "${ref}".${where} Closest: ${near.join(", ") || "none"}; find_stickers lists them.`);
42
43
  }
@@ -53,7 +54,7 @@ function createStickerTools(options) {
53
54
  collection: { type: "string", minLength: 1, description: "Only this collection id (the result lists them; default every collection)." },
54
55
  tags: { type: "array", maxItems: 10, items: { type: "string", description: "A tag." }, description: "Only stickers with every one of these tags." },
55
56
  commercial: { type: "boolean", description: "true: only stickers whose licence allows commercial use." },
56
- limit: { type: "integer", minimum: 1, maximum: _chunkOTN6VB5Scjs.MAX_STICKER_PAGE, description: "Page size (default 24)." },
57
+ limit: { type: "integer", minimum: 1, maximum: _chunkRDFHWAHLcjs.MAX_STICKER_PAGE, description: "Page size (default 24)." },
57
58
  after: { type: "string", description: "next from the previous page." }
58
59
  },
59
60
  additionalProperties: false
@@ -65,15 +66,15 @@ function createStickerTools(options) {
65
66
  if (category !== void 0 && categories && !categories.some((c) => c.id === category)) {
66
67
  throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `No category "${category}" in "${p.name}"; categories: ${categories.map((c) => c.id).join(", ")}.`);
67
68
  }
68
- const collections = await _asyncNullishCoalesce(await _optionalChain([p, 'access', _3 => _3.listCollections, 'optionalCall', _4 => _4()]), async () => ( null));
69
- if (collection !== void 0 && !_optionalChain([collections, 'optionalAccess', _5 => _5.some, 'call', _6 => _6((c) => c.id === collection)])) {
70
- throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", _optionalChain([collections, 'optionalAccess', _7 => _7.length]) ? `No collection "${collection}" in "${p.name}"; collections: ${collections.map((c) => c.id).join(", ")}.` : `"${p.name}" has no collections; leave collection out.`);
69
+ const collections = await _asyncNullishCoalesce(await _chunkRDFHWAHLcjs.providerCollections.call(void 0, p), async () => ( null));
70
+ if (collection !== void 0 && !_optionalChain([collections, 'optionalAccess', _3 => _3.some, 'call', _4 => _4((c) => c.id === collection)])) {
71
+ throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", _optionalChain([collections, 'optionalAccess', _5 => _5.length]) ? `No collection "${collection}" in "${p.name}"; collections: ${collections.map((c) => c.id).join(", ")}.` : `"${p.name}" has no collections; leave collection out.`);
71
72
  }
72
73
  const o = { ...category !== void 0 ? { category } : {}, ...collection !== void 0 ? { collection } : {}, ...tags ? { tags } : {}, ...commercial ? { licence: { commercial: true } } : {}, ...limit !== void 0 ? { limit } : {}, ...after !== void 0 ? { after } : {} };
73
74
  const q = typeof query === "string" ? query.trim() : "";
74
75
  if (q && !p.capabilities.supportsSearch) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `"${p.name}" can't search; leave query out and filter by category instead.`);
75
76
  const page = q ? await p.search(q, o) : await p.list(o);
76
- return { provider: p.id, items: page.items.map((s) => stickerForAgent(p, s)), total: page.total, ...page.next ? { next: page.next } : {}, ...categories ? { categories } : {}, ..._optionalChain([collections, 'optionalAccess', _8 => _8.length]) ? { collections } : {} };
77
+ return { provider: p.id, items: page.items.map((s) => stickerForAgent(p, s)), total: page.total, ...page.next ? { next: page.next } : {}, ...categories ? { categories } : {}, ..._optionalChain([collections, 'optionalAccess', _6 => _6.length]) ? { collections } : {} };
77
78
  }
78
79
  };
79
80
  const describe = {
@@ -86,28 +87,28 @@ function createStickerTools(options) {
86
87
  const p = options.provider();
87
88
  const d = await describeStickerRef(p, ref);
88
89
  const { thumbnail: _thumbnail, id, ...rest } = d;
89
- return { ref: _chunkOTN6VB5Scjs.stickerRefOf.call(void 0, p, id), ...rest };
90
+ return { ref: _chunkRDFHWAHLcjs.stickerRefOf.call(void 0, p, id), ...rest };
90
91
  }
91
92
  };
92
93
  return options.insert ? [find, describe, createInsertStickerTool(options.provider, options.insert)] : [find, describe];
93
94
  }
94
95
  async function loadForHost(provider, ref, d, host, colour, size, variant) {
95
- const id = _chunkOTN6VB5Scjs.stickerIdFor.call(void 0, provider, ref);
96
+ const id = _chunkRDFHWAHLcjs.stickerIdFor.call(void 0, provider, ref);
96
97
  const format = d.formats.includes(host.format) ? host.format : _nullishCoalesce(d.formats[0], () => ( host.format));
97
98
  return provider.load(id, { format, ...format === "png" ? { size: Math.max(8, Math.min(_nullishCoalesce(provider.capabilities.maxSize, () => ( 1024)), Math.round(size))) } : {}, ...colour && d.tintable ? { colour } : {}, ...variant !== "light" ? { variant } : {} });
98
99
  }
99
100
  async function insertSticker(provider, host, options) {
100
101
  const d = await describeStickerRef(provider, options.ref);
101
- const has = _chunkOTN6VB5Scjs.stickerVariantsOf.call(void 0, d);
102
+ const has = _chunkRDFHWAHLcjs.stickerVariantsOf.call(void 0, d);
102
103
  if (options.variant !== void 0 && !has.includes(options.variant)) throw new (0, _chunkU67EN7GGcjs.StickerError)("unsupported_variant", `"${options.ref}" has no ${JSON.stringify(options.variant)} variant; it has ${has.join(", ")}. Leave variant out to pick for the background.`);
103
- const variant = _nullishCoalesce(options.variant, () => ( _chunkOTN6VB5Scjs.stickerVariantFor.call(void 0, d, _nullishCoalesce(_optionalChain([host, 'access', _9 => _9.dark, 'optionalCall', _10 => _10()]), () => ( false)))));
104
+ const variant = _nullishCoalesce(options.variant, () => ( _chunkRDFHWAHLcjs.stickerVariantFor.call(void 0, d, _nullishCoalesce(_optionalChain([host, 'access', _7 => _7.dark, 'optionalCall', _8 => _8()]), () => ( false)))));
104
105
  if (options.color !== void 0 && !d.tintable) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `"${options.ref}" is not tintable (its art has its own colours); leave color out, or pick a tintable sticker (find_stickers lists tintable).`);
105
106
  if (options.width !== void 0 && !(options.width > 0)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `width must be a positive size, got ${options.width}.`);
106
107
  const w = _nullishCoalesce(options.width, () => ( d.width));
107
108
  const h = w * d.height / d.width;
108
109
  const centre = host.defaultCentre();
109
110
  const asset = await loadForHost(provider, options.ref, d, host, options.color, Math.max(w, h), variant);
110
- const ref = _chunkOTN6VB5Scjs.stickerRefOf.call(void 0, provider, d.id);
111
+ const ref = _chunkRDFHWAHLcjs.stickerRefOf.call(void 0, provider, d.id);
111
112
  const made = await host.insert({ ref, description: d, asset, variant, x: _nullishCoalesce(options.x, () => ( centre.x)), y: _nullishCoalesce(options.y, () => ( centre.y)), width: w, height: h, ...options.color ? { colour: options.color.toLowerCase() } : {} });
112
113
  return { ...made, ref, width: w, height: h, variant, licence: d.licence };
113
114
  }
@@ -124,7 +125,7 @@ function createInsertStickerTool(provider, host) {
124
125
  y: { type: "number", description: "Centre y in document units (default the middle of the view or document)." },
125
126
  width: { type: "number", exclusiveMinimum: 0, maximum: 1e4, description: "Width in document units (default the natural width); the height follows the aspect." },
126
127
  color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", description: "Tint #rrggbb for tintable stickers (default the sticker's own colour); refused for stickers that are not tintable." },
127
- variant: { type: "string", enum: [..._chunkOTN6VB5Scjs.STICKER_VARIANTS], description: "light or dark art (default: dark on a dark background when the sticker has it, else light); one the sticker does not list (find_stickers variants) is refused." }
128
+ variant: { type: "string", enum: [..._chunkRDFHWAHLcjs.STICKER_VARIANTS], description: "light or dark art (default: dark on a dark background when the sticker has it, else light); one the sticker does not list (find_stickers variants) is refused." }
128
129
  },
129
130
  required: ["ref"],
130
131
  additionalProperties: false
@@ -727,6 +727,16 @@ function resultText(result) {
727
727
  }
728
728
  return void 0;
729
729
  }
730
+ var CONFORMANCE_NUMBER_TOLERANCE = 1e-9;
731
+ function conformanceValuesMatch(a, b) {
732
+ if (typeof a === "number" && typeof b === "number") return a === b || Math.abs(a - b) <= CONFORMANCE_NUMBER_TOLERANCE * Math.max(1, Math.abs(a), Math.abs(b));
733
+ if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((x, i) => conformanceValuesMatch(x, b[i]));
734
+ if (a && b && typeof a === "object" && typeof b === "object") {
735
+ const ka = Object.keys(a), kb = Object.keys(b);
736
+ return ka.length === kb.length && ka.every((k) => k in b && conformanceValuesMatch(a[k], b[k]));
737
+ }
738
+ return a === b;
739
+ }
730
740
  async function runConformanceScenario(scenario, host) {
731
741
  const ids = new ConformanceIds();
732
742
  const isId = host.isGeneratedId?.bind(host);
@@ -772,5 +782,7 @@ export {
772
782
  omitConformancePaths,
773
783
  resolveConformanceArguments,
774
784
  conformanceResult,
785
+ CONFORMANCE_NUMBER_TOLERANCE,
786
+ conformanceValuesMatch,
775
787
  runConformanceScenario
776
788
  };
@@ -382,9 +382,72 @@ function createDrawCommands(target, options = {}) {
382
382
  readOnly: true,
383
383
  run: async () => ({ brushes: await target.listBrushes() })
384
384
  },
385
+ ...createBrushChoiceCommands(target, base, prefix),
385
386
  ...createGestureCommands(target, base, prefix, options)
386
387
  ];
387
388
  }
389
+ function createBrushChoiceCommands(target, base, prefix) {
390
+ const { brushSettings, selectBrush, setColorLocked, setColorScheme } = target;
391
+ if (!brushSettings || !selectBrush || !setColorLocked || !setColorScheme) return [];
392
+ const settings = () => brushSettings();
393
+ const RESULT = "Returns { brush, color, colorScheme, colorLocked, colorFollowsScheme } (colorFollowsScheme: the colour is a brush's light / dark default and changes with the scheme).";
394
+ return [
395
+ {
396
+ ...base,
397
+ id: `${prefix}selectBrush`,
398
+ label: "Choose Pen Brush",
399
+ keywords: ["brush", "pen", "pick brush", "chalk", "pencil", "ink"],
400
+ description: `Chooses the brush the pen and highlighter draw with by hand (brushId from canvas.listBrushes, or null for a plain vector stroke), at the brush's own size. A brush with a default colour (the ballpoint's blue, the chalk's light / dark pair) makes it the stroke colour unless keepColour or the colour is locked (canvas.setColorLocked). Does not draw; canvas.drawFreehand takes its own brush. ${RESULT}`,
401
+ params: {
402
+ type: "object",
403
+ additionalProperties: false,
404
+ required: ["brushId"],
405
+ properties: {
406
+ brushId: { type: ["string", "null"], minLength: 1, description: "A brush id from canvas.listBrushes, or null for a plain vector stroke." },
407
+ keepColour: { type: "boolean", description: "Keep the current stroke colour this once instead of taking the brush's default colour (default false)." }
408
+ }
409
+ },
410
+ run: async (_ctx, params) => {
411
+ await selectBrush(params.brushId, params.keepColour ? { keepColour: true } : {});
412
+ return settings();
413
+ }
414
+ },
415
+ {
416
+ ...base,
417
+ id: `${prefix}setColorLocked`,
418
+ label: "Keep My Colour",
419
+ keywords: ["lock colour", "keep colour", "brush colour", "color lock"],
420
+ description: `Locks or unlocks the stroke colour ("Keep my colour"): while locked, canvas.selectBrush keeps the current colour instead of taking a brush's default colour. ${RESULT}`,
421
+ params: {
422
+ type: "object",
423
+ additionalProperties: false,
424
+ required: ["locked"],
425
+ properties: { locked: { type: "boolean", description: "true locks the colour, false unlocks it (the canvas starts unlocked)." } }
426
+ },
427
+ run: (_ctx, params) => {
428
+ setColorLocked(params.locked);
429
+ return settings();
430
+ }
431
+ },
432
+ {
433
+ ...base,
434
+ id: `${prefix}setColorScheme`,
435
+ label: "Brush Colours for Light / Dark",
436
+ keywords: ["colour scheme", "dark mode", "light mode", "theme", "brush colour"],
437
+ description: `Sets the colour scheme that picks the side of a brush's light / dark default colour (white chalk in dark, dark chalk in light). A stroke colour that came from such a default follows; strokes already drawn keep theirs, and canvas.drawFreehand resolves brush defaults for this scheme. The host usually sets it to match its theme. ${RESULT}`,
438
+ params: {
439
+ type: "object",
440
+ additionalProperties: false,
441
+ required: ["scheme"],
442
+ properties: { scheme: { type: "string", enum: ["light", "dark"], description: "light (dark chalk on a light background) or dark (light chalk on a dark one)." } }
443
+ },
444
+ run: (_ctx, params) => {
445
+ setColorScheme(params.scheme);
446
+ return settings();
447
+ }
448
+ }
449
+ ];
450
+ }
388
451
  var GESTURE_RECT_PARAM = {
389
452
  type: "object",
390
453
  additionalProperties: false,
@@ -115,6 +115,9 @@ function stickerCollections(items, names = {}) {
115
115
  }
116
116
  return [...out.values()];
117
117
  }
118
+ function providerCollections(provider) {
119
+ return provider.collections ? provider.collections() : _optionalChain([provider, 'access', _10 => _10.listCollections, 'optionalCall', _11 => _11()]);
120
+ }
118
121
  function parseStickerRef(ref) {
119
122
  if (typeof ref !== "string" || !ref) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", 'A sticker ref is a "provider:id" string, e.g. "editor:star" (find_stickers lists them).');
120
123
  const i = ref.indexOf(":");
@@ -201,4 +204,5 @@ var StickersSlot = (_class = class {
201
204
 
202
205
 
203
206
 
204
- exports.STAMP_KINDS = STAMP_KINDS; exports.stampCoverage = stampCoverage; exports.STICKER_VARIANTS = STICKER_VARIANTS; exports.DEFAULT_STICKER_PAGE = DEFAULT_STICKER_PAGE; exports.MAX_STICKER_PAGE = MAX_STICKER_PAGE; exports.EDITOR_STICKERS_ID = EDITOR_STICKERS_ID; exports.checkStickerSearchOptions = checkStickerSearchOptions; exports.stickerPage = stickerPage; exports.stickerVariantsOf = stickerVariantsOf; exports.checkStickerVariant = checkStickerVariant; exports.stickerVariantFor = stickerVariantFor; exports.stickerCollections = stickerCollections; exports.parseStickerRef = parseStickerRef; exports.normalizeStickerRef = normalizeStickerRef; exports.editorStampOf = editorStampOf; exports.stickerRefOf = stickerRefOf; exports.stickerIdFor = stickerIdFor; exports.closestStickerRefs = closestStickerRefs; exports.StickersSlot = StickersSlot;
207
+
208
+ exports.STAMP_KINDS = STAMP_KINDS; exports.stampCoverage = stampCoverage; exports.STICKER_VARIANTS = STICKER_VARIANTS; exports.DEFAULT_STICKER_PAGE = DEFAULT_STICKER_PAGE; exports.MAX_STICKER_PAGE = MAX_STICKER_PAGE; exports.EDITOR_STICKERS_ID = EDITOR_STICKERS_ID; exports.checkStickerSearchOptions = checkStickerSearchOptions; exports.stickerPage = stickerPage; exports.stickerVariantsOf = stickerVariantsOf; exports.checkStickerVariant = checkStickerVariant; exports.stickerVariantFor = stickerVariantFor; exports.stickerCollections = stickerCollections; exports.providerCollections = providerCollections; exports.parseStickerRef = parseStickerRef; exports.normalizeStickerRef = normalizeStickerRef; exports.editorStampOf = editorStampOf; exports.stickerRefOf = stickerRefOf; exports.stickerIdFor = stickerIdFor; exports.closestStickerRefs = closestStickerRefs; exports.StickersSlot = StickersSlot;
@@ -3,11 +3,12 @@ import {
3
3
  STICKER_VARIANTS,
4
4
  closestStickerRefs,
5
5
  parseStickerRef,
6
+ providerCollections,
6
7
  stickerIdFor,
7
8
  stickerRefOf,
8
9
  stickerVariantFor,
9
10
  stickerVariantsOf
10
- } from "./chunk-ACFSFUQH.js";
11
+ } from "./chunk-JL6YH5WD.js";
11
12
  import {
12
13
  StickerError
13
14
  } from "./chunk-SZTI6EER.js";
@@ -65,7 +66,7 @@ function createStickerTools(options) {
65
66
  if (category !== void 0 && categories && !categories.some((c) => c.id === category)) {
66
67
  throw new StickerError("invalid_argument", `No category "${category}" in "${p.name}"; categories: ${categories.map((c) => c.id).join(", ")}.`);
67
68
  }
68
- const collections = await p.listCollections?.() ?? null;
69
+ const collections = await providerCollections(p) ?? null;
69
70
  if (collection !== void 0 && !collections?.some((c) => c.id === collection)) {
70
71
  throw new StickerError("invalid_argument", collections?.length ? `No collection "${collection}" in "${p.name}"; collections: ${collections.map((c) => c.id).join(", ")}.` : `"${p.name}" has no collections; leave collection out.`);
71
72
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkOTN6VB5Scjs = require('./chunk-OTN6VB5S.cjs');
5
+ var _chunkRDFHWAHLcjs = require('./chunk-RDFHWAHL.cjs');
6
6
 
7
7
 
8
8
  var _chunkWOFXZ3XUcjs = require('./chunk-WOFXZ3XU.cjs');
@@ -780,7 +780,7 @@ var DEFAULT_STICKER = { stamps: ["editor:star"], density: 0.4, sizeJitter: 0.4,
780
780
  function normalizeStickerSettings(raw = {}, base = DEFAULT_STICKER) {
781
781
  const refs = (list2) => list2.flatMap((s) => {
782
782
  try {
783
- return [_chunkOTN6VB5Scjs.normalizeStickerRef.call(void 0, s)];
783
+ return [_chunkRDFHWAHLcjs.normalizeStickerRef.call(void 0, s)];
784
784
  } catch (e2) {
785
785
  return [];
786
786
  }
@@ -827,7 +827,7 @@ function normalizeParticle(raw = {}, base = DEFAULT_PARTICLE) {
827
827
  const texture = (t) => {
828
828
  if (typeof t !== "string") return null;
829
829
  const bare = t.startsWith("editor:") ? t.slice(7) : t;
830
- if (_chunkOTN6VB5Scjs.STAMP_KINDS.includes(bare)) return bare;
830
+ if (_chunkRDFHWAHLcjs.STAMP_KINDS.includes(bare)) return bare;
831
831
  return /^[^:\s]+:\S+$/.test(t) && t.length <= 200 ? t : null;
832
832
  };
833
833
  const textures = Array.isArray(raw.dotTextures) ? raw.dotTextures.map(texture).filter((t) => t !== null).slice(0, MAX_DOT_TEXTURES) : [..._nullishCoalesce(base.dotTextures, () => ( []))];
@@ -963,7 +963,7 @@ var DEFAULT_SPRAY = { density: 0.5, size: 0.12 };
963
963
  function readStamp(raw, base) {
964
964
  if (raw === null) return null;
965
965
  if (typeof raw !== "string") return base;
966
- if (_chunkOTN6VB5Scjs.STAMP_KINDS.includes(raw)) return `editor:${raw}`;
966
+ if (_chunkRDFHWAHLcjs.STAMP_KINDS.includes(raw)) return `editor:${raw}`;
967
967
  return /^[^:\s]+:\S+$/.test(raw) && raw.length <= 200 ? raw : base;
968
968
  }
969
969
  function readSpray(raw, base) {
@@ -1113,7 +1113,7 @@ var NOT = { toEngine: (v) => !v, toFacet: (v) => !v };
1113
1113
  var EDITOR_STAMPS = {
1114
1114
  toEngine: (v) => v.flatMap((ref) => {
1115
1115
  try {
1116
- const stamp = _chunkOTN6VB5Scjs.editorStampOf.call(void 0, ref);
1116
+ const stamp = _chunkRDFHWAHLcjs.editorStampOf.call(void 0, ref);
1117
1117
  return stamp ? [stamp] : ref.includes(":") ? [ref] : [];
1118
1118
  } catch (e3) {
1119
1119
  return [];
@@ -1372,11 +1372,11 @@ var object = (description, properties, required) => ({
1372
1372
  additionalProperties: false
1373
1373
  });
1374
1374
  var MIXING = oneOf2(["pigment", "rgb"], "How colours mix: pigment (Kubelka-Munk, blue and yellow make green) or rgb (straight averages). Default pigment; a Mixer Brush and the smudge tool default to rgb.");
1375
- var BRUSH_STAMP_PATTERN = `^(?:[^:\\s]+:\\S+|${_chunkOTN6VB5Scjs.STAMP_KINDS.join("|")})$`;
1375
+ var BRUSH_STAMP_PATTERN = `^(?:[^:\\s]+:\\S+|${_chunkRDFHWAHLcjs.STAMP_KINDS.join("|")})$`;
1376
1376
  var STAMP = {
1377
1377
  type: "string",
1378
1378
  pattern: BRUSH_STAMP_PATTERN,
1379
- description: `A sticker ref provider:id (find_stickers lists them; the editor's own are ${_chunkOTN6VB5Scjs.STAMP_KINDS.map((k) => `editor:${k}`).join(", ")}). A bare editor stamp (star) means editor:star.`
1379
+ description: `A sticker ref provider:id (find_stickers lists them; the editor's own are ${_chunkRDFHWAHLcjs.STAMP_KINDS.map((k) => `editor:${k}`).join(", ")}). A bare editor stamp (star) means editor:star.`
1380
1380
  };
1381
1381
  var BRISTLES = object("Bristle tips: the tuft. Missing fields take their defaults.", {
1382
1382
  count: int(3, 128, "Bristles in the tuft (default 32)."),
@@ -1787,7 +1787,7 @@ function normalizeBrushSpec(raw, problems = []) {
1787
1787
  delete brush.tip.stamps;
1788
1788
  }
1789
1789
  if (brush.tip.stamps) {
1790
- const stamps = brush.tip.stamps.map((s) => _chunkOTN6VB5Scjs.normalizeStickerRef.call(void 0, s));
1790
+ const stamps = brush.tip.stamps.map((s) => _chunkRDFHWAHLcjs.normalizeStickerRef.call(void 0, s));
1791
1791
  if (stamps.length) brush.tip.stamps = stamps;
1792
1792
  else {
1793
1793
  drop("tip.stamps", "none of the stamps can be laid");
@@ -1886,7 +1886,7 @@ var CANVAS_PROFILE = {
1886
1886
  velocity: "ignored",
1887
1887
  tilt: "full"
1888
1888
  };
1889
- var VECTOR_PROFILE = { ...CANVAS_PROFILE, id: "vector", name: "Vector editor", light: "ignored" };
1889
+ var VECTOR_PROFILE = { ...CANVAS_PROFILE, id: "vector", name: "Vector editor", kinds: ["mark", "tool"], tools: ["blender", "smudge"], surfaces: ["dry", "wet"], reservoir: "full", light: "ignored" };
1890
1890
  var BRUSH_HOST_PROFILES = { paint: PAINT_PROFILE, image: IMAGE_PROFILE, canvas: CANVAS_PROFILE, vector: VECTOR_PROFILE };
1891
1891
  function brushColourKind(paint) {
1892
1892
  if (typeof paint === "string") return "solid";
@@ -5,7 +5,7 @@ import {
5
5
  moveAnchorHandle,
6
6
  subpathSegment,
7
7
  subpathSegmentCount
8
- } from "./chunk-T2LDTEXK.js";
8
+ } from "./chunk-4IDUYB45.js";
9
9
  import {
10
10
  segmentPoint
11
11
  } from "./chunk-WEIK3UYB.js";