@pixerate/editor 0.249.0 → 0.250.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 (69) hide show
  1. package/dist/animation-editor/index.cjs +114 -113
  2. package/dist/animation-editor/index.js +7 -6
  3. package/dist/{brushstrokeRender-T3JZST44.js → brushstrokeRender-2FHFLSEG.js} +4 -3
  4. package/dist/{brushstrokeRender-GCKK7V2I.cjs → brushstrokeRender-QGRXOKDA.cjs} +7 -6
  5. package/dist/canvas/index.cjs +71 -15
  6. package/dist/canvas/index.d.cts +1 -0
  7. package/dist/canvas/index.d.ts +1 -0
  8. package/dist/canvas/index.js +58 -2
  9. package/dist/canvas/stickers.d.cts +35 -0
  10. package/dist/canvas/stickers.d.ts +35 -0
  11. package/dist/{chunk-RXZL4NG5.js → chunk-226QDRO3.js} +1 -1
  12. package/dist/{chunk-UBRJOIR5.js → chunk-3TWOCSCY.js} +1 -1
  13. package/dist/{chunk-ZEYMKDYS.cjs → chunk-4JNWA3VT.cjs} +53 -20
  14. package/dist/{chunk-L3JFOTBQ.js → chunk-5E2Q7ZHI.js} +1 -1
  15. package/dist/{chunk-AU6MWQKZ.js → chunk-ABL7IWFZ.js} +1 -1
  16. package/dist/{chunk-LJRCU3BJ.cjs → chunk-ATK6ABN3.cjs} +15 -13
  17. package/dist/{chunk-H4AOUUBE.cjs → chunk-GT77U7QG.cjs} +18 -16
  18. package/dist/{chunk-GHCSC2WP.cjs → chunk-ISIO63Q5.cjs} +21 -15
  19. package/dist/{chunk-OFH6Q67U.js → chunk-JA57JIT5.js} +9 -3
  20. package/dist/{chunk-PZP2SZIZ.js → chunk-KDLBJ6QR.js} +1 -1
  21. package/dist/{chunk-LP2MCSBE.cjs → chunk-M2VKFE5L.cjs} +86 -86
  22. package/dist/{chunk-DOIU7VJG.js → chunk-NOHJP5TK.js} +1 -1
  23. package/dist/{chunk-O75V4ZS3.js → chunk-NTRAVM2I.js} +1 -1
  24. package/dist/{chunk-J7T5QZ45.js → chunk-OTEPAQJX.js} +4 -2
  25. package/dist/{chunk-QOBCBGGI.cjs → chunk-QKXO6JPP.cjs} +14 -14
  26. package/dist/{chunk-6BIDVPED.js → chunk-SMSGP2HQ.js} +1 -1
  27. package/dist/chunk-SZTI6EER.js +13 -0
  28. package/dist/{chunk-EJLRBS5Q.js → chunk-U4NUOKBT.js} +4 -2
  29. package/dist/chunk-U67EN7GG.cjs +13 -0
  30. package/dist/{chunk-5RH3VXAK.js → chunk-WKH5ZAUA.js} +45 -12
  31. package/dist/{chunk-IOFVM3L3.cjs → chunk-WPUXGDH4.cjs} +2 -2
  32. package/dist/{chunk-2SMMZDMG.cjs → chunk-X7WRL5ZZ.cjs} +35 -35
  33. package/dist/{chunk-WLJZZHUZ.cjs → chunk-YM6ZBTXG.cjs} +23 -23
  34. package/dist/{chunk-KYX7NZ5V.cjs → chunk-YW43M56C.cjs} +1 -1
  35. package/dist/{chunk-K5DS2JTA.cjs → chunk-Z3BRH4JK.cjs} +6 -6
  36. package/dist/{chunk-XNZFVYC2.cjs → chunk-ZBCT5MEA.cjs} +7 -7
  37. package/dist/effects/helpers.d.cts +6 -0
  38. package/dist/effects/helpers.d.ts +6 -0
  39. package/dist/effects/index.cjs +62 -60
  40. package/dist/effects/index.js +5 -3
  41. package/dist/effects/tools.d.cts +6 -0
  42. package/dist/effects/tools.d.ts +6 -0
  43. package/dist/image-editor/effects.d.cts +1 -1
  44. package/dist/image-editor/effects.d.ts +1 -1
  45. package/dist/image-editor/index.cjs +814 -791
  46. package/dist/image-editor/index.d.cts +1 -0
  47. package/dist/image-editor/index.d.ts +1 -0
  48. package/dist/image-editor/index.js +35 -12
  49. package/dist/image-editor/stickers.d.cts +9 -0
  50. package/dist/image-editor/stickers.d.ts +9 -0
  51. package/dist/paint-editor/index.cjs +165 -164
  52. package/dist/paint-editor/index.js +8 -7
  53. package/dist/stickers/index.cjs +22 -16
  54. package/dist/stickers/index.d.cts +1 -1
  55. package/dist/stickers/index.d.ts +1 -1
  56. package/dist/stickers/index.js +9 -3
  57. package/dist/stickers/tools.d.cts +57 -1
  58. package/dist/stickers/tools.d.ts +57 -1
  59. package/dist/vector/index.cjs +1003 -969
  60. package/dist/vector/index.d.cts +1 -0
  61. package/dist/vector/index.d.ts +1 -0
  62. package/dist/vector/index.js +40 -6
  63. package/dist/vector/stickers.d.cts +11 -0
  64. package/dist/vector/stickers.d.ts +11 -0
  65. package/dist/video-editor/index.cjs +344 -344
  66. package/dist/video-editor/index.js +4 -4
  67. package/package.json +1 -1
  68. package/skills/pixerate-image-editor/SKILL.md +1 -1
  69. package/skills/pixerate-stickers/SKILL.md +13 -1
@@ -1,5 +1,8 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await 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;
2
2
 
3
+ var _chunkU67EN7GGcjs = require('./chunk-U67EN7GG.cjs');
4
+
5
+
3
6
  var _chunk3K6HWEXZcjs = require('./chunk-3K6HWEXZ.cjs');
4
7
 
5
8
  // src/stickers/stamps.ts
@@ -58,25 +61,15 @@ function stampCoverage(kind, u, v, t) {
58
61
  }
59
62
  }
60
63
 
61
- // src/stickers/errors.ts
62
- var StickerError = class extends Error {
63
- constructor(code, message) {
64
- super(message);
65
- this.code = code;
66
- this.name = "StickerError";
67
- }
68
-
69
- };
70
-
71
64
  // src/stickers/helpers.ts
72
65
  var DEFAULT_STICKER_PAGE = 24;
73
66
  var MAX_STICKER_PAGE = 100;
74
67
  var EDITOR_STICKERS_ID = "editor";
75
68
  function checkStickerSearchOptions(options = {}) {
76
69
  if (options.limit !== void 0 && !(Number.isInteger(options.limit) && options.limit >= 1 && options.limit <= MAX_STICKER_PAGE)) {
77
- throw new StickerError("invalid_argument", `limit must be a whole number from 1 to ${MAX_STICKER_PAGE}, got ${options.limit}.`);
70
+ throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `limit must be a whole number from 1 to ${MAX_STICKER_PAGE}, got ${options.limit}.`);
78
71
  }
79
- if (options.after !== void 0 && !/^\d+$/.test(options.after)) throw new StickerError("invalid_argument", `after "${options.after}" is not a cursor from this provider; pass the next value of the previous page.`);
72
+ if (options.after !== void 0 && !/^\d+$/.test(options.after)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `after "${options.after}" is not a cursor from this provider; pass the next value of the previous page.`);
80
73
  }
81
74
  var words = (s) => s.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
82
75
  function stickerPage(items, options = {}, query = "") {
@@ -97,13 +90,13 @@ function stickerPage(items, options = {}, query = "") {
97
90
  return { items: page, total: matches.length, ...start + limit < matches.length ? { next: String(start + limit) } : {} };
98
91
  }
99
92
  function parseStickerRef(ref) {
100
- if (typeof ref !== "string" || !ref) throw new StickerError("invalid_argument", 'A sticker ref is a "provider:id" string, e.g. "editor:star" (find_stickers lists them).');
93
+ 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).');
101
94
  const i = ref.indexOf(":");
102
95
  if (i === -1) {
103
96
  if (STAMP_KINDS.includes(ref)) return { provider: EDITOR_STICKERS_ID, id: ref };
104
- throw new StickerError("invalid_argument", `"${ref}" is not a sticker ref; refs are "provider:id" (e.g. "editor:${STAMP_KINDS[1]}"); find_stickers lists them.`);
97
+ throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `"${ref}" is not a sticker ref; refs are "provider:id" (e.g. "editor:${STAMP_KINDS[1]}"); find_stickers lists them.`);
105
98
  }
106
- if (i === 0 || i === ref.length - 1) throw new StickerError("invalid_argument", `"${ref}" is not a sticker ref; refs are "provider:id".`);
99
+ if (i === 0 || i === ref.length - 1) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `"${ref}" is not a sticker ref; refs are "provider:id".`);
107
100
  return { provider: ref.slice(0, i), id: ref.slice(i + 1) };
108
101
  }
109
102
  function normalizeStickerRef(ref) {
@@ -164,6 +157,7 @@ var StickersSlot = (_class = class {
164
157
 
165
158
  // src/stickers/tools.ts
166
159
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
160
+ var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
167
161
  function stickerForAgent(provider, s) {
168
162
  const { id, thumbnail: _thumbnail, ...rest } = s;
169
163
  return { ref: stickerRefOf(provider, id), ...rest };
@@ -187,7 +181,7 @@ async function describeStickerRef(provider, ref) {
187
181
  const near = closestStickerRefs(ref, await knownRefs(provider));
188
182
  const owner = parseStickerRef(ref).provider;
189
183
  const where = id === null && !provider.namespaced ? ` The sticker library is "${provider.id}", not "${owner}".` : "";
190
- throw new StickerError("unknown_sticker", `No sticker "${ref}".${where} Closest: ${near.join(", ") || "none"}; find_stickers lists them.`);
184
+ throw new (0, _chunkU67EN7GGcjs.StickerError)("unknown_sticker", `No sticker "${ref}".${where} Closest: ${near.join(", ") || "none"}; find_stickers lists them.`);
191
185
  }
192
186
  function createStickerTools(options) {
193
187
  const find = {
@@ -211,11 +205,11 @@ function createStickerTools(options) {
211
205
  const p = options.provider();
212
206
  const categories = await _asyncNullishCoalesce(await _optionalChain([p, 'access', _4 => _4.categories, 'optionalCall', _5 => _5()]), async () => ( null));
213
207
  if (category !== void 0 && categories && !categories.some((c) => c.id === category)) {
214
- throw new StickerError("invalid_argument", `No category "${category}" in "${p.name}"; categories: ${categories.map((c) => c.id).join(", ")}.`);
208
+ throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `No category "${category}" in "${p.name}"; categories: ${categories.map((c) => c.id).join(", ")}.`);
215
209
  }
216
210
  const o = { ...category !== void 0 ? { category } : {}, ...tags ? { tags } : {}, ...commercial ? { licence: { commercial: true } } : {}, ...limit !== void 0 ? { limit } : {}, ...after !== void 0 ? { after } : {} };
217
211
  const q = typeof query === "string" ? query.trim() : "";
218
- if (q && !p.capabilities.supportsSearch) throw new StickerError("invalid_argument", `"${p.name}" can't search; leave query out and filter by category instead.`);
212
+ 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.`);
219
213
  const page = q ? await p.search(q, o) : await p.list(o);
220
214
  return { provider: p.id, items: page.items.map((s) => stickerForAgent(p, s)), total: page.total, ...page.next ? { next: page.next } : {}, ...categories ? { categories } : {} };
221
215
  }
@@ -233,7 +227,45 @@ function createStickerTools(options) {
233
227
  return { ref: stickerRefOf(p, id), ...rest };
234
228
  }
235
229
  };
236
- return [find, describe];
230
+ return options.insert ? [find, describe, createInsertStickerTool(options.provider, options.insert)] : [find, describe];
231
+ }
232
+ async function loadForHost(provider, ref, d, host, colour, size) {
233
+ const id = stickerIdFor(provider, ref);
234
+ const format = d.formats.includes(host.format) ? host.format : _nullishCoalesce(d.formats[0], () => ( host.format));
235
+ 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 } : {} });
236
+ }
237
+ async function insertSticker(provider, host, options) {
238
+ const d = await describeStickerRef(provider, options.ref);
239
+ 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).`);
240
+ if (options.width !== void 0 && !(options.width > 0)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `width must be a positive size, got ${options.width}.`);
241
+ const w = _nullishCoalesce(options.width, () => ( d.width));
242
+ const h = w * d.height / d.width;
243
+ const centre = host.defaultCentre();
244
+ const asset = await loadForHost(provider, options.ref, d, host, options.color, Math.max(w, h));
245
+ const ref = stickerRefOf(provider, d.id);
246
+ const made = await host.insert({ ref, description: d, asset, x: _nullishCoalesce(options.x, () => ( centre.x)), y: _nullishCoalesce(options.y, () => ( centre.y)), width: w, height: h, ...options.color ? { colour: options.color.toLowerCase() } : {} });
247
+ return { ...made, ref, width: w, height: h, licence: d.licence };
248
+ }
249
+ function createInsertStickerTool(provider, host) {
250
+ return {
251
+ name: "insert_sticker",
252
+ title: "Insert a sticker",
253
+ description: `Puts one sticker from the sticker library (ref from find_stickers) into the document as a new ${host.noun}, centred at x, y and width wide (its natural aspect kept; default its natural size), tinted to color when the sticker is tintable. Its art is loaded first; an unknown ref is refused with the closest ones. One undo step. Returns the new ${host.noun}'s id (for the editor's own tools, such as effects on it), the ref and its licence (credit any attribution it asks for).`,
254
+ inputSchema: {
255
+ type: "object",
256
+ properties: {
257
+ ref: { type: "string", minLength: 1, description: "Sticker ref provider:id from find_stickers (e.g. editor:star)." },
258
+ x: { type: "number", description: "Centre x in document units (default the middle of the view or document)." },
259
+ y: { type: "number", description: "Centre y in document units (default the middle of the view or document)." },
260
+ width: { type: "number", exclusiveMinimum: 0, maximum: 1e4, description: "Width in document units (default the natural width); the height follows the aspect." },
261
+ 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." }
262
+ },
263
+ required: ["ref"],
264
+ additionalProperties: false
265
+ },
266
+ annotations: { title: "Insert a sticker", ...WRITE },
267
+ handler: ({ ref, x, y, width, color }) => insertSticker(provider(), host, { ref, x, y, width, color })
268
+ };
237
269
  }
238
270
  function createStickerToolProvider(options) {
239
271
  return {
@@ -266,4 +298,5 @@ function createStickerToolProvider(options) {
266
298
 
267
299
 
268
300
 
269
- exports.STAMP_KINDS = STAMP_KINDS; exports.stampCoverage = stampCoverage; exports.StickerError = StickerError; 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.parseStickerRef = parseStickerRef; exports.normalizeStickerRef = normalizeStickerRef; exports.editorStampOf = editorStampOf; exports.stickerRefOf = stickerRefOf; exports.stickerIdFor = stickerIdFor; exports.closestStickerRefs = closestStickerRefs; exports.StickersSlot = StickersSlot; exports.stickerForAgent = stickerForAgent; exports.describeStickerRef = describeStickerRef; exports.createStickerTools = createStickerTools; exports.createStickerToolProvider = createStickerToolProvider;
301
+
302
+ exports.STAMP_KINDS = STAMP_KINDS; exports.stampCoverage = stampCoverage; 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.parseStickerRef = parseStickerRef; exports.normalizeStickerRef = normalizeStickerRef; exports.editorStampOf = editorStampOf; exports.stickerRefOf = stickerRefOf; exports.stickerIdFor = stickerIdFor; exports.closestStickerRefs = closestStickerRefs; exports.StickersSlot = StickersSlot; exports.stickerForAgent = stickerForAgent; exports.describeStickerRef = describeStickerRef; exports.createStickerTools = createStickerTools; exports.insertSticker = insertSticker; exports.createInsertStickerTool = createInsertStickerTool; exports.createStickerToolProvider = createStickerToolProvider;
@@ -7,7 +7,7 @@ import {
7
7
  EffectsSlot,
8
8
  createEffectPixels,
9
9
  effectValueErrors
10
- } from "./chunk-OFH6Q67U.js";
10
+ } from "./chunk-JA57JIT5.js";
11
11
  import {
12
12
  validateJsonSchema
13
13
  } from "./chunk-V2ZCJRDM.js";
@@ -3,7 +3,7 @@ import {
3
3
  EffectDisposedError,
4
4
  EffectUnsupportedError,
5
5
  effectValueErrors
6
- } from "./chunk-OFH6Q67U.js";
6
+ } from "./chunk-JA57JIT5.js";
7
7
  import {
8
8
  HistoryManager
9
9
  } from "./chunk-NS62CQ2B.js";
@@ -4,8 +4,10 @@
4
4
 
5
5
 
6
6
 
7
+ var _chunk4JNWA3VTcjs = require('./chunk-4JNWA3VT.cjs');
7
8
 
8
- var _chunkZEYMKDYScjs = require('./chunk-ZEYMKDYS.cjs');
9
+
10
+ var _chunkU67EN7GGcjs = require('./chunk-U67EN7GG.cjs');
9
11
 
10
12
 
11
13
  var _chunkW5M3J7PVcjs = require('./chunk-W5M3J7PV.cjs');
@@ -30,7 +32,7 @@ var HEX = /^#[0-9a-fA-F]{6}$/;
30
32
  function stampOutline(kind) {
31
33
  const n = GRID;
32
34
  const f = new Float32Array((n + 1) * (n + 1));
33
- for (let j = 0; j <= n; j++) for (let i = 0; i <= n; i++) f[j * (n + 1) + i] = _chunkZEYMKDYScjs.stampCoverage.call(void 0, kind, i / n * 2 - 1, j / n * 2 - 1, SHAPE_SEED) - 0.5;
35
+ for (let j = 0; j <= n; j++) for (let i = 0; i <= n; i++) f[j * (n + 1) + i] = _chunk4JNWA3VTcjs.stampCoverage.call(void 0, kind, i / n * 2 - 1, j / n * 2 - 1, SHAPE_SEED) - 0.5;
34
36
  const at = (i, j) => f[j * (n + 1) + i];
35
37
  const points = /* @__PURE__ */ new Map();
36
38
  const point = (key, i0, j0, i1, j1) => {
@@ -167,7 +169,7 @@ function stampPixels(kind, size, colour) {
167
169
  for (let y = 0; y < size; y++) {
168
170
  for (let x = 0; x < size; x++) {
169
171
  let c = 0;
170
- for (let sy = 0; sy < ss; sy++) for (let sx = 0; sx < ss; sx++) c += _chunkZEYMKDYScjs.stampCoverage.call(void 0, kind, (x + (sx + 0.5) / ss) / size * 2 - 1, (y + (sy + 0.5) / ss) / size * 2 - 1, SHAPE_SEED);
172
+ for (let sy = 0; sy < ss; sy++) for (let sx = 0; sx < ss; sx++) c += _chunk4JNWA3VTcjs.stampCoverage.call(void 0, kind, (x + (sx + 0.5) / ss) / size * 2 - 1, (y + (sy + 0.5) / ss) / size * 2 - 1, SHAPE_SEED);
171
173
  const a = Math.round(c / (ss * ss) * 255);
172
174
  if (!a) continue;
173
175
  const i = (y * size + x) * 4;
@@ -189,32 +191,32 @@ function editorStickers() {
189
191
  return { id: k, name: m.name, category: m.category, tags: m.tags, description: m.description, width: BOX, height: BOX, thumbnail: thumbs.get(k), formats: ["svg", "png"], licence: { ...LICENCE }, tintable: true };
190
192
  };
191
193
  const kind = (id) => {
192
- if (!_chunkZEYMKDYScjs.STAMP_KINDS.includes(id)) throw new (0, _chunkZEYMKDYScjs.StickerError)("unknown_sticker", `The editor has no sticker "${id}"; its stickers are ${_chunkZEYMKDYScjs.STAMP_KINDS.join(", ")}.`);
194
+ if (!_chunk4JNWA3VTcjs.STAMP_KINDS.includes(id)) throw new (0, _chunkU67EN7GGcjs.StickerError)("unknown_sticker", `The editor has no sticker "${id}"; its stickers are ${_chunk4JNWA3VTcjs.STAMP_KINDS.join(", ")}.`);
193
195
  return id;
194
196
  };
195
197
  return {
196
- id: _chunkZEYMKDYScjs.EDITOR_STICKERS_ID,
198
+ id: _chunk4JNWA3VTcjs.EDITOR_STICKERS_ID,
197
199
  name: "Editor stickers",
198
200
  version: "1",
199
201
  capabilities: { supportsSearch: true, supportsSvg: true, supportsRaster: true, maxSize: 1024 },
200
- list: (options) => _chunkZEYMKDYScjs.stickerPage.call(void 0, _chunkZEYMKDYScjs.STAMP_KINDS.map(summary), options),
201
- search: (query, options) => _chunkZEYMKDYScjs.stickerPage.call(void 0, _chunkZEYMKDYScjs.STAMP_KINDS.map(summary), options, query),
202
+ list: (options) => _chunk4JNWA3VTcjs.stickerPage.call(void 0, _chunk4JNWA3VTcjs.STAMP_KINDS.map(summary), options),
203
+ search: (query, options) => _chunk4JNWA3VTcjs.stickerPage.call(void 0, _chunk4JNWA3VTcjs.STAMP_KINDS.map(summary), options, query),
202
204
  describe(id) {
203
- if (!_chunkZEYMKDYScjs.STAMP_KINDS.includes(id)) return void 0;
205
+ if (!_chunk4JNWA3VTcjs.STAMP_KINDS.includes(id)) return void 0;
204
206
  const k = id;
205
207
  return { ...summary(k), silhouette: outline(k), colours: [META[k].colour] };
206
208
  },
207
- categories: () => [...new Set(_chunkZEYMKDYScjs.STAMP_KINDS.map((k) => META[k].category))].map((c) => ({ id: c, name: c[0].toUpperCase() + c.slice(1), count: _chunkZEYMKDYScjs.STAMP_KINDS.filter((k) => META[k].category === c).length })),
209
+ categories: () => [...new Set(_chunk4JNWA3VTcjs.STAMP_KINDS.map((k) => META[k].category))].map((c) => ({ id: c, name: c[0].toUpperCase() + c.slice(1), count: _chunk4JNWA3VTcjs.STAMP_KINDS.filter((k) => META[k].category === c).length })),
208
210
  load(id, options = {}) {
209
211
  const k = kind(id);
210
212
  const colour = _nullishCoalesce(options.colour, () => ( META[k].colour));
211
- if (!HEX.test(colour)) throw new (0, _chunkZEYMKDYScjs.StickerError)("invalid_argument", `colour ${JSON.stringify(colour)} must be #rrggbb.`);
213
+ if (!HEX.test(colour)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `colour ${JSON.stringify(colour)} must be #rrggbb.`);
212
214
  if (options.format === "png") {
213
215
  const size = _nullishCoalesce(options.size, () => ( 256));
214
- if (!(Number.isInteger(size) && size >= 8 && size <= 1024)) throw new (0, _chunkZEYMKDYScjs.StickerError)("invalid_argument", `size must be a whole number of px from 8 to 1024, got ${size}.`);
216
+ if (!(Number.isInteger(size) && size >= 8 && size <= 1024)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `size must be a whole number of px from 8 to 1024, got ${size}.`);
215
217
  return { kind: "image", url: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, size, size, stampPixels(k, size, colour.toLowerCase())), width: size, height: size };
216
218
  }
217
- if (options.format !== void 0 && options.format !== "svg") throw new (0, _chunkZEYMKDYScjs.StickerError)("unsupported_format", `format must be svg or png, got ${JSON.stringify(options.format)}.`);
219
+ if (options.format !== void 0 && options.format !== "svg") throw new (0, _chunkU67EN7GGcjs.StickerError)("unsupported_format", `format must be svg or png, got ${JSON.stringify(options.format)}.`);
218
220
  const d = outline(k);
219
221
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${BOX} ${BOX}" width="${BOX}" height="${BOX}"><path fill="${colour.toLowerCase()}" fill-rule="evenodd" d="${d}"/></svg>`;
220
222
  return { kind: "svg", svg, silhouette: d };
@@ -288,7 +290,7 @@ var StickerBrowser = (_class = class {
288
290
  const res = q && p.capabilities.supportsSearch ? await p.search(q, options) : await p.list(options);
289
291
  if (run !== this.run) return;
290
292
  this.next = res.next;
291
- const items = res.items.map((s) => ({ ...s, ref: _chunkZEYMKDYScjs.stickerRefOf.call(void 0, p, s.id) }));
293
+ const items = res.items.map((s) => ({ ...s, ref: _chunk4JNWA3VTcjs.stickerRefOf.call(void 0, p, s.id) }));
292
294
  this.set({ items: first ? items : [...this.s.items, ...items], total: res.total, hasMore: Boolean(res.next), loading: false });
293
295
  }
294
296
  }, _class);
@@ -5,8 +5,10 @@
5
5
 
6
6
 
7
7
 
8
+ var _chunk4JNWA3VTcjs = require('./chunk-4JNWA3VT.cjs');
8
9
 
9
- var _chunkZEYMKDYScjs = require('./chunk-ZEYMKDYS.cjs');
10
+
11
+ var _chunkU67EN7GGcjs = require('./chunk-U67EN7GG.cjs');
10
12
 
11
13
 
12
14
 
@@ -613,7 +615,7 @@ var defaultStickerRasterizer = async (asset, size) => {
613
615
  }
614
616
  const g = globalThis;
615
617
  if (!g.createImageBitmap || !g.OffscreenCanvas) {
616
- throw new (0, _chunkZEYMKDYScjs.StickerError)("unsupported_format", `This environment can't draw ${asset.kind === "svg" ? "SVG" : "non-PNG"} sticker art; pass rasterizeSticker in the paint editor's options (or use a provider that offers png).`);
618
+ throw new (0, _chunkU67EN7GGcjs.StickerError)("unsupported_format", `This environment can't draw ${asset.kind === "svg" ? "SVG" : "non-PNG"} sticker art; pass rasterizeSticker in the paint editor's options (or use a provider that offers png).`);
617
619
  }
618
620
  const blob = asset.kind === "svg" ? new Blob([asset.svg], { type: "image/svg+xml" }) : await (await g.fetch(asset.url)).blob();
619
621
  const bitmap = await g.createImageBitmap(blob);
@@ -635,7 +637,7 @@ var StickerArtCache = (_class4 = class {constructor() { _class4.prototype.__init
635
637
  }}
636
638
  /** `ready`, `loading`, `failed` (with the reason) or `none` (never asked for). Editor stamps are always `ready`. */
637
639
  status(ref) {
638
- if (_chunkZEYMKDYScjs.editorStampOf.call(void 0, ref)) return { status: "ready" };
640
+ if (_chunk4JNWA3VTcjs.editorStampOf.call(void 0, ref)) return { status: "ready" };
639
641
  const e = this.entries.get(ref);
640
642
  if (!e) return { status: "none" };
641
643
  return e.status === "failed" ? { status: "failed", error: e.error } : { status: e.status };
@@ -646,18 +648,18 @@ var StickerArtCache = (_class4 = class {constructor() { _class4.prototype.__init
646
648
  * the next call.
647
649
  */
648
650
  ensure(provider, ref, rasterize) {
649
- if (_chunkZEYMKDYScjs.editorStampOf.call(void 0, ref)) return Promise.resolve(null);
651
+ if (_chunk4JNWA3VTcjs.editorStampOf.call(void 0, ref)) return Promise.resolve(null);
650
652
  const e = this.entries.get(ref);
651
653
  if (_optionalChain([e, 'optionalAccess', _9 => _9.status]) === "ready") return Promise.resolve(e.art);
652
654
  if (_optionalChain([e, 'optionalAccess', _10 => _10.status]) === "loading") return e.promise;
653
655
  const promise = (async () => {
654
- const d = await _chunkZEYMKDYScjs.describeStickerRef.call(void 0, provider, ref);
655
- const id = _chunkZEYMKDYScjs.stickerIdFor.call(void 0, provider, ref);
656
+ const d = await _chunk4JNWA3VTcjs.describeStickerRef.call(void 0, provider, ref);
657
+ const id = _chunk4JNWA3VTcjs.stickerIdFor.call(void 0, provider, ref);
656
658
  const max = _nullishCoalesce(provider.capabilities.maxSize, () => ( STICKER_ART_SIZE));
657
659
  const size = Math.min(STICKER_ART_SIZE, max);
658
660
  const asset = await provider.load(id, d.formats.includes("png") ? { format: "png", size } : { format: _nullishCoalesce(d.formats[0], () => ( "svg")), size });
659
661
  const px = await rasterize(asset, size);
660
- if (!(px.width > 0 && px.height > 0) || px.data.length !== px.width * px.height * 4) throw new (0, _chunkZEYMKDYScjs.StickerError)("load_failed", `The art for "${ref}" came back empty or the wrong size.`);
662
+ if (!(px.width > 0 && px.height > 0) || px.data.length !== px.width * px.height * 4) throw new (0, _chunkU67EN7GGcjs.StickerError)("load_failed", `The art for "${ref}" came back empty or the wrong size.`);
661
663
  return { ...px, tintable: d.tintable };
662
664
  })();
663
665
  this.entries.set(ref, { status: "loading", promise });
@@ -716,7 +718,7 @@ var unit2 = (v, d) => typeof v === "number" && Number.isFinite(v) ? Math.min(1,
716
718
  function normalizeStickerSettings(raw = {}, base = DEFAULT_STICKER) {
717
719
  const refs = (list) => list.flatMap((s) => {
718
720
  try {
719
- return [_chunkZEYMKDYScjs.normalizeStickerRef.call(void 0, s)];
721
+ return [_chunk4JNWA3VTcjs.normalizeStickerRef.call(void 0, s)];
720
722
  } catch (e3) {
721
723
  return [];
722
724
  }
@@ -744,12 +746,12 @@ function stickerRect(s) {
744
746
  function stickerStamp(s) {
745
747
  if (s.ref) {
746
748
  try {
747
- return _chunkZEYMKDYScjs.editorStampOf.call(void 0, s.ref);
749
+ return _chunk4JNWA3VTcjs.editorStampOf.call(void 0, s.ref);
748
750
  } catch (e4) {
749
751
  return null;
750
752
  }
751
753
  }
752
- return s.stamp && _chunkZEYMKDYScjs.STAMP_KINDS.includes(s.stamp) ? s.stamp : null;
754
+ return s.stamp && _chunk4JNWA3VTcjs.STAMP_KINDS.includes(s.stamp) ? s.stamp : null;
753
755
  }
754
756
  function drawSticker(medium, s, art) {
755
757
  const kind = stickerStamp(s);
@@ -774,7 +776,7 @@ function drawSticker(medium, s, art) {
774
776
  const v = (-dx * sa + dy * ca) / rad;
775
777
  if (u < -1.05 || u > 1.05 || v < -1.05 || v > 1.05) continue;
776
778
  let c = 0;
777
- for (let k = 0; k < 4; k++) c += _chunkZEYMKDYScjs.stampCoverage.call(void 0, kind, u + ((k & 1) - 0.5) / rad / 2, v + ((k >> 1) - 0.5) / rad / 2, s.seed);
779
+ for (let k = 0; k < 4; k++) c += _chunk4JNWA3VTcjs.stampCoverage.call(void 0, kind, u + ((k & 1) - 0.5) / rad / 2, v + ((k >> 1) - 0.5) / rad / 2, s.seed);
778
780
  c /= 4;
779
781
  if (c <= 0) continue;
780
782
  cov[p] = c;
@@ -946,12 +948,12 @@ function normalizeStickerUpdate(u) {
946
948
  const out = {};
947
949
  if (u.ref !== void 0 && u.stamp !== void 0) throw new Error("Give ref or stamp, not both (stamp is the older name for an editor stamp).");
948
950
  if (u.stamp !== void 0) {
949
- if (!_chunkZEYMKDYScjs.STAMP_KINDS.includes(u.stamp)) throw new Error(`stamp ${JSON.stringify(u.stamp)} is not a stamp; use ${_chunkZEYMKDYScjs.STAMP_KINDS.join(", ")}, or ref for any sticker (find_stickers).`);
951
+ if (!_chunk4JNWA3VTcjs.STAMP_KINDS.includes(u.stamp)) throw new Error(`stamp ${JSON.stringify(u.stamp)} is not a stamp; use ${_chunk4JNWA3VTcjs.STAMP_KINDS.join(", ")}, or ref for any sticker (find_stickers).`);
950
952
  out.ref = `editor:${u.stamp}`;
951
953
  out.stamp = u.stamp;
952
954
  }
953
955
  if (u.ref !== void 0) {
954
- out.ref = _chunkZEYMKDYScjs.normalizeStickerRef.call(void 0, u.ref);
956
+ out.ref = _chunk4JNWA3VTcjs.normalizeStickerRef.call(void 0, u.ref);
955
957
  const stamp = stickerStamp({ ref: out.ref });
956
958
  if (stamp) out.stamp = stamp;
957
959
  else out.stamp = void 0;
@@ -1020,7 +1022,7 @@ function stickerAt(stickers, x, y, art) {
1020
1022
  if (s.size < 16) return s;
1021
1023
  const kind = stickerStamp(s);
1022
1024
  if (kind) {
1023
- if (_chunkZEYMKDYScjs.stampCoverage.call(void 0, kind, u, v, s.seed) > 0.25) return s;
1025
+ if (_chunk4JNWA3VTcjs.stampCoverage.call(void 0, kind, u, v, s.seed) > 0.25) return s;
1024
1026
  continue;
1025
1027
  }
1026
1028
  const pic = _optionalChain([art, 'optionalCall', _15 => _15(s.ref)]);
@@ -1140,7 +1142,7 @@ var MarkStroke = (_class6 = class {
1140
1142
  for (let sx = 0; sx < ss; sx++) {
1141
1143
  const dx = rect.x + xx + (sx + 0.5) / ss - x;
1142
1144
  const dy = rect.y + yy + (sy + 0.5) / ss - y;
1143
- sum += _chunkZEYMKDYScjs.stampCoverage.call(void 0, kind, (dx * c + dy * s) * inv, (dy * c - dx * s) * inv, seed);
1145
+ sum += _chunk4JNWA3VTcjs.stampCoverage.call(void 0, kind, (dx * c + dy * s) * inv, (dy * c - dx * s) * inv, seed);
1144
1146
  }
1145
1147
  }
1146
1148
  vals[k] = sum / (ss * ss) * a;
@@ -1219,7 +1221,7 @@ var DEFAULT_PARTICLE = {
1219
1221
  var unit3 = (v, d) => typeof v === "number" && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d;
1220
1222
  var oneOf = (v, all, d) => all.includes(v) ? v : d;
1221
1223
  function normalizeParticle(raw = {}, base = DEFAULT_PARTICLE) {
1222
- const textures = Array.isArray(raw.dotTextures) ? raw.dotTextures.filter((t) => _chunkZEYMKDYScjs.STAMP_KINDS.includes(t)).slice(0, MAX_DOT_TEXTURES) : [..._nullishCoalesce(base.dotTextures, () => ( []))];
1224
+ const textures = Array.isArray(raw.dotTextures) ? raw.dotTextures.filter((t) => _chunk4JNWA3VTcjs.STAMP_KINDS.includes(t)).slice(0, MAX_DOT_TEXTURES) : [..._nullishCoalesce(base.dotTextures, () => ( []))];
1223
1225
  return {
1224
1226
  kind: oneOf(raw.kind, PARTICLE_KINDS, base.kind),
1225
1227
  render: oneOf(raw.render, PARTICLE_RENDERS, base.render),
@@ -168,6 +168,10 @@ function applyEffectMask(result, mask, source) {
168
168
  }
169
169
  return result;
170
170
  }
171
+ function layerImageInput(d) {
172
+ const images = d.inputs.filter((i) => i.kind === "image");
173
+ return _nullishCoalesce(_optionalChain([(_nullishCoalesce(_nullishCoalesce(images.find((i) => i.name === "source"), () => ( images.find((i) => i.required))), () => ( images[0]))), 'optionalAccess', _9 => _9.name]), () => ( null));
174
+ }
171
175
  var EffectsSlot = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this); }
172
176
  __init() {this.current = null}
173
177
  __init2() {this.listeners = /* @__PURE__ */ new Set()}
@@ -234,7 +238,7 @@ async function sampleEffectCameraMove(provider, id, request) {
234
238
  }
235
239
  var cameraMoveField = (role) => role === "transition" ? "in" : "during";
236
240
  function cameraMovesFor(catalog, role) {
237
- return catalog.filter((e) => e.kind === "camera" && _optionalChain([e, 'access', _9 => _9.camera, 'optionalAccess', _10 => _10.role]) === role);
241
+ return catalog.filter((e) => e.kind === "camera" && _optionalChain([e, 'access', _10 => _10.camera, 'optionalAccess', _11 => _11.role]) === role);
238
242
  }
239
243
  function cameraMoveIdList(catalog, role) {
240
244
  const ids = cameraMovesFor(catalog, role).map((e) => JSON.stringify(e.id));
@@ -324,12 +328,12 @@ var summaryOut = (e) => ({
324
328
  category: e.category,
325
329
  uses: e.uses,
326
330
  ...e.description ? { description: e.description } : {},
327
- ..._optionalChain([e, 'access', _11 => _11.tags, 'optionalAccess', _12 => _12.length]) ? { tags: e.tags } : {},
331
+ ..._optionalChain([e, 'access', _12 => _12.tags, 'optionalAccess', _13 => _13.length]) ? { tags: e.tags } : {},
328
332
  transparent: e.transparent,
329
333
  loop: e.loop,
330
334
  ...e.duration !== void 0 ? { duration: e.duration } : {},
331
335
  ...e.camera ? { camera: e.camera } : {},
332
- ..._optionalChain([e, 'access', _13 => _13.accepts, 'optionalAccess', _14 => _14.length]) ? { accepts: e.accepts } : {}
336
+ ..._optionalChain([e, 'access', _14 => _14.accepts, 'optionalAccess', _15 => _15.length]) ? { accepts: e.accepts } : {}
333
337
  });
334
338
  function createEffectToolProvider(host) {
335
339
  let catalog = null;
@@ -337,7 +341,7 @@ function createEffectToolProvider(host) {
337
341
  const notify = () => listeners.forEach((l) => l());
338
342
  const catalogFor = (provider) => {
339
343
  if (!provider) return null;
340
- if (_optionalChain([catalog, 'optionalAccess', _15 => _15.provider]) !== provider) {
344
+ if (_optionalChain([catalog, 'optionalAccess', _16 => _16.provider]) !== provider) {
341
345
  const entry = { provider, effects: null };
342
346
  catalog = entry;
343
347
  Promise.resolve().then(() => provider.list()).then((effects) => {
@@ -373,8 +377,9 @@ function createEffectToolProvider(host) {
373
377
  description: `${what}: control name \u2192 value, as listed by describe_effect (its "controls" schema: types, ranges, units and defaults). Only the given controls change; colours are "#rrggbb".${keyframes ? " A number control may instead be keyframes { keys: [{ t: ms from the start, v, ease }] }." : ""} Unknown controls and out-of-range values are refused with the valid ones.`
374
378
  });
375
379
  const effectIdSchema = (uses) => {
376
- const effects = _optionalChain([catalogFor, 'call', _16 => _16(host.provider()), 'optionalAccess', _17 => _17.filter, 'call', _18 => _18((e) => effectOffered(e, uses))]);
377
- const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}).`;
380
+ const open = host.applyImageInputs && uses === host.applyUses;
381
+ const effects = open ? void 0 : _optionalChain([catalogFor, 'call', _17 => _17(host.provider()), 'optionalAccess', _18 => _18.filter, 'call', _19 => _19((e) => effectOffered(e, uses))]);
382
+ const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}${open ? `, or any effect whose describe_effect inputs take an image: the ${host.target.noun} is its picture` : ""}).`;
378
383
  return effects && effects.length && effects.length <= ENUM_LIMIT ? { type: "string", enum: effects.map((e) => e.id), description: `${base} One of: ${effects.map((e) => `${e.id} (${e.name})`).join(", ")}.` } : { type: "string", minLength: 1, description: base };
379
384
  };
380
385
  const context = { requireProvider: writable, valuesSchema, effectIdSchema, annotations: ANNOTATIONS };
@@ -403,8 +408,8 @@ function createEffectToolProvider(host) {
403
408
  if (!p) return { available: false, reason: NO_PROVIDER, effects: [], total: 0 };
404
409
  const tags = args.tags;
405
410
  const accepts = args.accepts;
406
- let found = (await explain(async () => p.search(_nullishCoalesce(args.query, () => ( "")), { kind: args.kind, category: args.category, use: args.use, tags, ..._optionalChain([accepts, 'optionalAccess', _19 => _19.length]) ? { accepts } : {} }))).filter((e) => hasEffectTags(e, tags));
407
- if (_optionalChain([accepts, 'optionalAccess', _20 => _20.includes, 'call', _21 => _21("path")])) {
411
+ let found = (await explain(async () => p.search(_nullishCoalesce(args.query, () => ( "")), { kind: args.kind, category: args.category, use: args.use, tags, ..._optionalChain([accepts, 'optionalAccess', _20 => _20.length]) ? { accepts } : {} }))).filter((e) => hasEffectTags(e, tags));
412
+ if (_optionalChain([accepts, 'optionalAccess', _21 => _21.includes, 'call', _22 => _22("path")])) {
408
413
  const kept = [];
409
414
  for (const e of found) {
410
415
  if (e.accepts) {
@@ -415,7 +420,7 @@ function createEffectToolProvider(host) {
415
420
  }
416
421
  const limit = _nullishCoalesce(args.limit, () => ( 20));
417
422
  const out = { available: true, provider: { id: p.id, name: p.name, capabilities: p.capabilities }, effects: found.slice(0, limit).map(summaryOut), total: found.length, tags: countEffectTags(found).slice(0, TAG_LIMIT) };
418
- if (_optionalChain([tags, 'optionalAccess', _22 => _22.length]) && !found.length) {
423
+ if (_optionalChain([tags, 'optionalAccess', _23 => _23.length]) && !found.length) {
419
424
  const known = countEffectTags(await explain(async () => p.list()));
420
425
  const have = new Set(known.map((k) => k.tag));
421
426
  const unknown = tags.filter((t) => !have.has(normaliseEffectTag(t)));
@@ -435,7 +440,7 @@ function createEffectToolProvider(host) {
435
440
  if (!p) return { available: false, reason: NO_PROVIDER };
436
441
  const d = await explain(async () => p.describe(args.effect));
437
442
  const pathControls = pathControlsOf(d);
438
- return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses), ...pathControls.length ? { pathControls } : {} };
443
+ return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses) || !!host.applyImageInputs && d.kind !== "motion" && layerImageInput(d) !== null, ...pathControls.length ? { pathControls } : {} };
439
444
  }
440
445
  },
441
446
  {
@@ -531,16 +536,16 @@ function createEffectToolProvider(host) {
531
536
  ...host.description ? { description: host.description } : {},
532
537
  ...host.skill ? { skill: host.skill } : {},
533
538
  tools: () => {
534
- const extra = _nullishCoalesce(_optionalChain([host, 'access', _23 => _23.extraTools, 'optionalCall', _24 => _24(context)]), () => ( []));
535
- if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access', _25 => _25.annotations, 'optionalAccess', _26 => _26.readOnlyHint]))];
539
+ const extra = _nullishCoalesce(_optionalChain([host, 'access', _24 => _24.extraTools, 'optionalCall', _25 => _25(context)]), () => ( []));
540
+ if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access', _26 => _26.annotations, 'optionalAccess', _27 => _27.readOnlyHint]))];
536
541
  return [...readTools(), ...writeTools(), ...extra];
537
542
  },
538
543
  subscribe: (l) => {
539
544
  listeners.add(l);
540
- const off = _optionalChain([host, 'access', _27 => _27.subscribe, 'optionalCall', _28 => _28(l)]);
545
+ const off = _optionalChain([host, 'access', _28 => _28.subscribe, 'optionalCall', _29 => _29(l)]);
541
546
  return () => {
542
547
  listeners.delete(l);
543
- _optionalChain([off, 'optionalCall', _29 => _29()]);
548
+ _optionalChain([off, 'optionalCall', _30 => _30()]);
544
549
  };
545
550
  }
546
551
  };
@@ -592,4 +597,5 @@ function createEffectToolProvider(host) {
592
597
 
593
598
 
594
599
 
595
- exports.EFFECT_KINDS = EFFECT_KINDS; exports.EFFECT_USES = EFFECT_USES; exports.CAMERA_MOVE_ROLES = CAMERA_MOVE_ROLES; exports.EFFECT_ACCEPTS = EFFECT_ACCEPTS; exports.EFFECT_PATH_FORMAT = EFFECT_PATH_FORMAT; exports.EFFECT_SUBJECT_KINDS = EFFECT_SUBJECT_KINDS; exports.EFFECT_LAYER_ROLES = EFFECT_LAYER_ROLES; exports.EFFECT_TRANSITION_MS = EFFECT_TRANSITION_MS; exports.EFFECT_TEMPLATE_SLOT_TYPES = EFFECT_TEMPLATE_SLOT_TYPES; exports.EFFECT_ERROR_CODES = EFFECT_ERROR_CODES; exports.EffectError = EffectError; exports.UnknownEffectError = UnknownEffectError; exports.UnknownTemplateError = UnknownTemplateError; exports.EffectControlError = EffectControlError; exports.EffectUnsupportedError = EffectUnsupportedError; exports.EffectDisposedError = EffectDisposedError; exports.NoEffectsProviderError = NoEffectsProviderError; exports.isEffectError = isEffectError; exports.effectValueErrors = effectValueErrors; exports.resolveEffectValues = resolveEffectValues; exports.effectOffered = effectOffered; exports.normaliseEffectTag = normaliseEffectTag; exports.hasEffectTags = hasEffectTags; exports.countEffectTags = countEffectTags; exports.pathControlsOf = pathControlsOf; exports.searchEffectSummaries = searchEffectSummaries; exports.createEffectPixels = createEffectPixels; exports.isEffectPixels = isEffectPixels; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.encodeEffectFloat = encodeEffectFloat; exports.applyEffectMask = applyEffectMask; exports.EffectsSlot = EffectsSlot; exports.isCameraView = isCameraView; exports.sampleCameraViews = sampleCameraViews; exports.sampleEffectCameraMove = sampleEffectCameraMove; exports.cameraMoveField = cameraMoveField; exports.cameraMovesFor = cameraMovesFor; exports.cameraMoveIdList = cameraMoveIdList; exports.cameraMoveParts = cameraMoveParts; exports.CAMERA_MOVE_MAX_MS = CAMERA_MOVE_MAX_MS; exports.resolveCameraMoveSpec = resolveCameraMoveSpec; exports.cameraViewOfBox = cameraViewOfBox; exports.cameraBoxOfView = cameraBoxOfView; exports.createEffectToolProvider = createEffectToolProvider;
600
+
601
+ exports.EFFECT_KINDS = EFFECT_KINDS; exports.EFFECT_USES = EFFECT_USES; exports.CAMERA_MOVE_ROLES = CAMERA_MOVE_ROLES; exports.EFFECT_ACCEPTS = EFFECT_ACCEPTS; exports.EFFECT_PATH_FORMAT = EFFECT_PATH_FORMAT; exports.EFFECT_SUBJECT_KINDS = EFFECT_SUBJECT_KINDS; exports.EFFECT_LAYER_ROLES = EFFECT_LAYER_ROLES; exports.EFFECT_TRANSITION_MS = EFFECT_TRANSITION_MS; exports.EFFECT_TEMPLATE_SLOT_TYPES = EFFECT_TEMPLATE_SLOT_TYPES; exports.EFFECT_ERROR_CODES = EFFECT_ERROR_CODES; exports.EffectError = EffectError; exports.UnknownEffectError = UnknownEffectError; exports.UnknownTemplateError = UnknownTemplateError; exports.EffectControlError = EffectControlError; exports.EffectUnsupportedError = EffectUnsupportedError; exports.EffectDisposedError = EffectDisposedError; exports.NoEffectsProviderError = NoEffectsProviderError; exports.isEffectError = isEffectError; exports.effectValueErrors = effectValueErrors; exports.resolveEffectValues = resolveEffectValues; exports.effectOffered = effectOffered; exports.normaliseEffectTag = normaliseEffectTag; exports.hasEffectTags = hasEffectTags; exports.countEffectTags = countEffectTags; exports.pathControlsOf = pathControlsOf; exports.searchEffectSummaries = searchEffectSummaries; exports.createEffectPixels = createEffectPixels; exports.isEffectPixels = isEffectPixels; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.encodeEffectFloat = encodeEffectFloat; exports.applyEffectMask = applyEffectMask; exports.layerImageInput = layerImageInput; exports.EffectsSlot = EffectsSlot; exports.isCameraView = isCameraView; exports.sampleCameraViews = sampleCameraViews; exports.sampleEffectCameraMove = sampleEffectCameraMove; exports.cameraMoveField = cameraMoveField; exports.cameraMovesFor = cameraMovesFor; exports.cameraMoveIdList = cameraMoveIdList; exports.cameraMoveParts = cameraMoveParts; exports.CAMERA_MOVE_MAX_MS = CAMERA_MOVE_MAX_MS; exports.resolveCameraMoveSpec = resolveCameraMoveSpec; exports.cameraViewOfBox = cameraViewOfBox; exports.cameraBoxOfView = cameraBoxOfView; exports.createEffectToolProvider = createEffectToolProvider;
@@ -168,6 +168,10 @@ function applyEffectMask(result, mask, source) {
168
168
  }
169
169
  return result;
170
170
  }
171
+ function layerImageInput(d) {
172
+ const images = d.inputs.filter((i) => i.kind === "image");
173
+ return (images.find((i) => i.name === "source") ?? images.find((i) => i.required) ?? images[0])?.name ?? null;
174
+ }
171
175
  var EffectsSlot = class {
172
176
  current = null;
173
177
  listeners = /* @__PURE__ */ new Set();
@@ -373,8 +377,9 @@ function createEffectToolProvider(host) {
373
377
  description: `${what}: control name \u2192 value, as listed by describe_effect (its "controls" schema: types, ranges, units and defaults). Only the given controls change; colours are "#rrggbb".${keyframes ? " A number control may instead be keyframes { keys: [{ t: ms from the start, v, ease }] }." : ""} Unknown controls and out-of-range values are refused with the valid ones.`
374
378
  });
375
379
  const effectIdSchema = (uses) => {
376
- const effects = catalogFor(host.provider())?.filter((e) => effectOffered(e, uses));
377
- const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}).`;
380
+ const open = host.applyImageInputs && uses === host.applyUses;
381
+ const effects = open ? void 0 : catalogFor(host.provider())?.filter((e) => effectOffered(e, uses));
382
+ const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}${open ? `, or any effect whose describe_effect inputs take an image: the ${host.target.noun} is its picture` : ""}).`;
378
383
  return effects && effects.length && effects.length <= ENUM_LIMIT ? { type: "string", enum: effects.map((e) => e.id), description: `${base} One of: ${effects.map((e) => `${e.id} (${e.name})`).join(", ")}.` } : { type: "string", minLength: 1, description: base };
379
384
  };
380
385
  const context = { requireProvider: writable, valuesSchema, effectIdSchema, annotations: ANNOTATIONS };
@@ -435,7 +440,7 @@ function createEffectToolProvider(host) {
435
440
  if (!p) return { available: false, reason: NO_PROVIDER };
436
441
  const d = await explain(async () => p.describe(args.effect));
437
442
  const pathControls = pathControlsOf(d);
438
- return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses), ...pathControls.length ? { pathControls } : {} };
443
+ return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses) || !!host.applyImageInputs && d.kind !== "motion" && layerImageInput(d) !== null, ...pathControls.length ? { pathControls } : {} };
439
444
  }
440
445
  },
441
446
  {
@@ -579,6 +584,7 @@ export {
579
584
  linearToSrgb,
580
585
  encodeEffectFloat,
581
586
  applyEffectMask,
587
+ layerImageInput,
582
588
  EffectsSlot,
583
589
  isCameraView,
584
590
  sampleCameraViews,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BUILTIN_BRUSHES
3
- } from "./chunk-J7T5QZ45.js";
3
+ } from "./chunk-OTEPAQJX.js";
4
4
  import {
5
5
  parseProvenance
6
6
  } from "./chunk-M6DNZNVY.js";