@pixerate/editor 0.234.0 → 0.235.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.
@@ -1,9 +1,3 @@
1
- import {
2
- effectLayerInput,
3
- effectLayerOffered,
4
- effectLayerRole,
5
- effectSubjectKind
6
- } from "../chunk-I277KJLQ.js";
7
1
  import {
8
2
  createVectorMorph
9
3
  } from "../chunk-YMREOA67.js";
@@ -15,6 +9,14 @@ import {
15
9
  namedWithSuggestion,
16
10
  suggestName
17
11
  } from "../chunk-EUKY4KFX.js";
12
+ import {
13
+ effectLayerInput,
14
+ effectLayerOffered,
15
+ effectLayerRole,
16
+ effectSubjectKind,
17
+ effectTemplateTools,
18
+ fillEffectTemplate
19
+ } from "../chunk-G3RUKJ5C.js";
18
20
  import {
19
21
  IDENTITY_MATRIX,
20
22
  applyMatrix,
@@ -1802,7 +1804,10 @@ var MotionLayersEngine = class {
1802
1804
  this.reset();
1803
1805
  this.listeners.clear();
1804
1806
  }
1807
+ /** Goes up each time pictures come in or are cleared, so a view that caches frames knows to draw again. */
1808
+ revision = 0;
1805
1809
  notify() {
1810
+ this.revision++;
1806
1811
  this.listeners.forEach((l) => l());
1807
1812
  }
1808
1813
  size(b) {
@@ -4484,6 +4489,57 @@ async function checkMotionShotLayers(scene, provider) {
4484
4489
  return issues;
4485
4490
  }
4486
4491
 
4492
+ // src/animation-editor/sequence.ts
4493
+ var fresh = (used, base) => {
4494
+ const clean = base.replace(/[^\w.-]+/g, "-").replace(/^[^A-Za-z_]+/, "") || "item";
4495
+ if (!used.has(clean)) return used.add(clean), clean;
4496
+ for (let i = 2; ; i++) if (!used.has(`${clean}-${i}`)) return used.add(`${clean}-${i}`), `${clean}-${i}`;
4497
+ };
4498
+ function motionShotsFromSequence(sequence, options = {}) {
4499
+ const sx = (options.width ?? sequence.stage.width) / sequence.stage.width;
4500
+ const sy = (options.height ?? sequence.stage.height) / sequence.stage.height;
4501
+ const scale = (r) => ({ x: r.x * sx, y: r.y * sy, width: r.width * sx, height: r.height * sy });
4502
+ const full = { x: 0, y: 0, width: sequence.stage.width * sx, height: sequence.stage.height * sy };
4503
+ const shotIds = new Set(options.shotIds ?? []);
4504
+ const layerIds = new Set(options.layerIds ?? []);
4505
+ const notes = [];
4506
+ const provider = options.provider ? { provider: options.provider } : {};
4507
+ const shots = sequence.shots.map((s, i) => {
4508
+ const id = fresh(shotIds, `shot${i + 1}`);
4509
+ const framing = s.camera?.framing ? scale(s.camera.framing) : void 0;
4510
+ const view = framing ?? full;
4511
+ const layers = [];
4512
+ for (const layer of s.layers) {
4513
+ if (layer.subject && "video" in layer.subject) {
4514
+ notes.push(`Shot ${i + 1}: a layer plays a video, which an animation cannot; it was left out (the video editor plays it).`);
4515
+ continue;
4516
+ }
4517
+ const { id: given, rect, subject, ...rest } = layer;
4518
+ layers.push({ ...rest, id: fresh(layerIds, given ?? "layer"), ...subject ? { subject } : {}, ...rect ? { rect: scale(rect) } : {}, ...layer.effect ? provider : {} });
4519
+ }
4520
+ if (s.title) layers.push({ id: fresh(layerIds, `${id}-title`), subject: { text: s.title }, role: "overlay", rect: { x: view.x + view.width * 0.1, y: view.y + view.height * 0.38, width: view.width * 0.8, height: view.height * 0.24 } });
4521
+ if (s.caption) layers.push({ id: fresh(layerIds, `${id}-caption`), subject: { text: s.caption }, role: "overlay", rect: { x: view.x + view.width * 0.1, y: view.y + view.height * 0.8, width: view.width * 0.8, height: view.height * 0.1 } });
4522
+ const camera = framing || s.camera?.in !== void 0 || s.camera?.during !== void 0 ? { ...framing ?? {}, ...s.camera?.in !== void 0 ? { in: s.camera.in } : {}, ...s.camera?.during !== void 0 ? { during: s.camera.during } : {} } : void 0;
4523
+ return {
4524
+ id,
4525
+ label: s.title ?? s.caption ?? `Shot ${i + 1}`,
4526
+ ...camera ? { camera } : {},
4527
+ run: [],
4528
+ hold: s.hold,
4529
+ ...layers.length ? { layers } : {},
4530
+ ...i > 0 && s.transition ? { transition: { ...s.transition, ...provider } } : {}
4531
+ };
4532
+ });
4533
+ return { shots, notes };
4534
+ }
4535
+ function motionSceneFromSequence(sequence, options = {}) {
4536
+ const { shots, notes } = motionShotsFromSequence(sequence, options);
4537
+ return {
4538
+ scene: { version: 1, name: sequence.name, ...sequence.title ? { description: sequence.title } : {}, artwork: { width: sequence.stage.width, height: sequence.stage.height, background: options.background ?? "#000000", nodes: [] }, shots },
4539
+ notes
4540
+ };
4541
+ }
4542
+
4487
4543
  // src/animation-editor/effects.ts
4488
4544
  var sourceOf = (c) => c.source;
4489
4545
  function motionSceneEffects(scene) {
@@ -4667,6 +4723,7 @@ var AnimationEditorController = class {
4667
4723
  redoLabel: h.redoName,
4668
4724
  revision: this.revision,
4669
4725
  effectsProvider: this.effects.provider,
4726
+ layerPictures: this.layers.revision,
4670
4727
  recording: this.recording ? {
4671
4728
  shot: this.recording.options.id,
4672
4729
  at: this.recording.options.at,
@@ -5175,6 +5232,42 @@ var AnimationEditorController = class {
5175
5232
  if (!r.ok) return r;
5176
5233
  return this.layerResult(shot, void 0);
5177
5234
  }
5235
+ /**
5236
+ * Fills a provider sequence template and loads it: `replace` (default) makes a new scene the
5237
+ * size of the template's stage from its shots; `append` adds its shots after the current ones,
5238
+ * scaled to the artwork. Values are checked first and every problem is refused at once. One
5239
+ * undo step. Returns the new shot and layer ids, slots left open and notes.
5240
+ */
5241
+ async fillTemplate(template, values = {}, options = {}) {
5242
+ const reason = this.readOnlyReason();
5243
+ if (reason) return this.refuse(reason);
5244
+ const mode = options.mode ?? "replace";
5245
+ let filled;
5246
+ try {
5247
+ filled = await fillEffectTemplate(this.effects.provider, template, values, options.name ? { name: options.name } : {});
5248
+ } catch (error) {
5249
+ if (isEffectError(error) || error instanceof Error) return this.refuse(error.message);
5250
+ throw error;
5251
+ }
5252
+ const provider = this.effects.provider.id;
5253
+ const label = `Template ${filled.template.name}`;
5254
+ let shots;
5255
+ let notes;
5256
+ let r;
5257
+ if (mode === "replace") {
5258
+ const made = motionSceneFromSequence(filled.sequence, { provider });
5259
+ shots = made.scene.shots;
5260
+ notes = made.notes;
5261
+ r = this.apply({ op: "replace_scene", scene: made.scene }, label);
5262
+ } else {
5263
+ const made = motionShotsFromSequence(filled.sequence, { provider, width: this.scene.artwork.width, height: this.scene.artwork.height, shotIds: this.scene.shots.map((s) => s.id), layerIds: this.scene.shots.flatMap((s) => (s.layers ?? []).map((l) => l.id)) });
5264
+ shots = made.shots;
5265
+ notes = made.notes;
5266
+ r = this.apply({ op: "insert_shots", shots: made.shots }, label);
5267
+ }
5268
+ if (!r.ok) return r;
5269
+ return { ok: true, template, mode, shots: shots.map((s) => s.id), layers: shots.flatMap((s) => (s.layers ?? []).map((l) => l.id)), openSlots: filled.openSlots, notes: [...filled.notes, ...notes] };
5270
+ }
5178
5271
  // ---------------------------------------------------------------------------------------
5179
5272
  // Recording
5180
5273
  // ---------------------------------------------------------------------------------------
@@ -7087,6 +7180,20 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
7087
7180
  extraTools: (ctx) => [
7088
7181
  ...animationCameraMoveTools(controller, ctx),
7089
7182
  ...animationShotLayerTools(controller, ctx),
7183
+ ...effectTemplateTools(
7184
+ {
7185
+ provider: () => controller.effectsProvider,
7186
+ fillDetails: "mode replace (default) makes a new scene from the template's shots, the size of its stage; mode append adds its shots after the current ones, scaled to the artwork. Each shot keeps its framing and camera moves, its layers and its transition; its title and caption become overlay word layers. Returns { template, mode, shots (new shot ids), layers (new layer ids), openSlots, notes }. Check the result with render_animation_frame.",
7187
+ fillOptions: { mode: { type: "string", enum: ["replace", "append"], description: "replace (default): a new scene from the template; append: its shots after the current ones." } },
7188
+ fill: async (template, values, options2) => {
7189
+ const r = await controller.fillTemplate(template, values, { name: options2.name, mode: options2.mode });
7190
+ if (!r.ok) throw new Error(r.error);
7191
+ const { ok: _ok, ...rest } = r;
7192
+ return rest;
7193
+ }
7194
+ },
7195
+ ctx
7196
+ ),
7090
7197
  {
7091
7198
  name: "add_vector_effect",
7092
7199
  title: "Add a vector effect",
@@ -7296,6 +7403,7 @@ export {
7296
7403
  motionRevealPadding,
7297
7404
  motionRulerTicks,
7298
7405
  motionSceneEffects,
7406
+ motionSceneFromSequence,
7299
7407
  motionSceneHasLayers,
7300
7408
  motionSceneShapeProblems,
7301
7409
  motionSceneToJson,
@@ -7304,6 +7412,7 @@ export {
7304
7412
  motionShotCueTime,
7305
7413
  motionShotLayersInfo,
7306
7414
  motionShotTimeScale,
7415
+ motionShotsFromSequence,
7307
7416
  motionStageSvg,
7308
7417
  motionTakeProblems,
7309
7418
  motionTakeShot,
@@ -144,6 +144,8 @@ export declare class MotionLayersEngine implements MotionLayerPictures {
144
144
  /** Forgets every picture and failure (a new provider, or the host changed). */
145
145
  reset(): void;
146
146
  dispose(): void;
147
+ /** Goes up each time pictures come in or are cleared, so a view that caches frames knows to draw again. */
148
+ revision: number;
147
149
  private notify;
148
150
  private size;
149
151
  private snap;
@@ -144,6 +144,8 @@ export declare class MotionLayersEngine implements MotionLayerPictures {
144
144
  /** Forgets every picture and failure (a new provider, or the host changed). */
145
145
  reset(): void;
146
146
  dispose(): void;
147
+ /** Goes up each time pictures come in or are cleared, so a view that caches frames knows to draw again. */
148
+ revision: number;
147
149
  private notify;
148
150
  private size;
149
151
  private snap;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * An effects provider's `EffectSequence` (what a sequence template fills to) as animation shots:
3
+ * each shot keeps its framing and camera moves, its layers and its transition. Its title and
4
+ * caption become overlay word layers placed in the shot's framing. Rects and framings are scaled
5
+ * from the sequence's stage to the artwork.
6
+ */
7
+ import type { EffectSequence } from '../effects/types.cjs';
8
+ import type { MotionScene, MotionShot } from './types.cjs';
9
+ export interface MotionShotsFromSequence {
10
+ shots: MotionShot[];
11
+ /** What could not be carried over, in sentences. */
12
+ notes: string[];
13
+ }
14
+ export interface MotionSequenceOptions {
15
+ /** The artwork size the shots are for (default the sequence's stage). */
16
+ width?: number;
17
+ height?: number;
18
+ /** Shot ids already used (new ones avoid them). */
19
+ shotIds?: Iterable<string>;
20
+ /** Layer ids already used (new ones avoid them). */
21
+ layerIds?: Iterable<string>;
22
+ /** The provider the sequence's effects come from, saved on layers and transitions. */
23
+ provider?: string;
24
+ }
25
+ /** The shots of a sequence, sized for the artwork (see the module comment). */
26
+ export declare function motionShotsFromSequence(sequence: EffectSequence, options?: MotionSequenceOptions): MotionShotsFromSequence;
27
+ /** A new scene from a sequence: an empty artwork the size of its stage, and its shots. */
28
+ export declare function motionSceneFromSequence(sequence: EffectSequence, options?: Pick<MotionSequenceOptions, 'provider'> & {
29
+ background?: string;
30
+ }): {
31
+ scene: MotionScene;
32
+ notes: string[];
33
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * An effects provider's `EffectSequence` (what a sequence template fills to) as animation shots:
3
+ * each shot keeps its framing and camera moves, its layers and its transition. Its title and
4
+ * caption become overlay word layers placed in the shot's framing. Rects and framings are scaled
5
+ * from the sequence's stage to the artwork.
6
+ */
7
+ import type { EffectSequence } from '../effects/types.js';
8
+ import type { MotionScene, MotionShot } from './types.js';
9
+ export interface MotionShotsFromSequence {
10
+ shots: MotionShot[];
11
+ /** What could not be carried over, in sentences. */
12
+ notes: string[];
13
+ }
14
+ export interface MotionSequenceOptions {
15
+ /** The artwork size the shots are for (default the sequence's stage). */
16
+ width?: number;
17
+ height?: number;
18
+ /** Shot ids already used (new ones avoid them). */
19
+ shotIds?: Iterable<string>;
20
+ /** Layer ids already used (new ones avoid them). */
21
+ layerIds?: Iterable<string>;
22
+ /** The provider the sequence's effects come from, saved on layers and transitions. */
23
+ provider?: string;
24
+ }
25
+ /** The shots of a sequence, sized for the artwork (see the module comment). */
26
+ export declare function motionShotsFromSequence(sequence: EffectSequence, options?: MotionSequenceOptions): MotionShotsFromSequence;
27
+ /** A new scene from a sequence: an empty artwork the size of its stage, and its shots. */
28
+ export declare function motionSceneFromSequence(sequence: EffectSequence, options?: Pick<MotionSequenceOptions, 'provider'> & {
29
+ background?: string;
30
+ }): {
31
+ scene: MotionScene;
32
+ notes: string[];
33
+ };
@@ -1,5 +1,8 @@
1
1
  import {
2
2
  EFFECT_LAYER_ROLES,
3
+ EFFECT_TRANSITION_MS,
4
+ EffectUnsupportedError,
5
+ NoEffectsProviderError,
3
6
  hasEffectTags
4
7
  } from "./chunk-SIK3LT6M.js";
5
8
 
@@ -231,6 +234,103 @@ function effectSequenceSlots(sequence) {
231
234
  for (const shot of sequence.shots) for (const l of shot.layers) if (l.subject && "slot" in l.subject) out.add(l.subject.slot);
232
235
  return [...out];
233
236
  }
237
+ async function fillEffectTemplate(provider, id, values = {}, options = {}) {
238
+ if (!provider) throw new NoEffectsProviderError();
239
+ if (!provider.capabilities.supportsTemplates || !provider.describeTemplate || !provider.instantiateTemplate) throw new EffectUnsupportedError(`${provider.name} has no sequence templates (capabilities.supportsTemplates is not set).`);
240
+ const template = await provider.describeTemplate(id);
241
+ const errors = checkTemplateValues(template.slots, values);
242
+ if (errors.length) throw new Error(`${errors.join(" ")} describe_template lists what each slot takes.`);
243
+ const result = await provider.instantiateTemplate(id, values, options);
244
+ if (!result.ok) throw new Error(`${result.errors.join(" ")} describe_template lists what each slot takes.`);
245
+ const problems = checkEffectSequence(result.sequence, await provider.list());
246
+ if (problems.length) throw new Error(`${provider.name} filled "${id}" with a sequence this editor cannot load: ${problems.join(" ")}`);
247
+ return { template, sequence: result.sequence, openSlots: [...result.openSlots], notes: [...result.notes] };
248
+ }
249
+ function effectLayerSpan(layer, shotIndex, shotStarts, total) {
250
+ const at = (t, fallback) => t === void 0 ? fallback : typeof t === "number" ? shotStarts[shotIndex] + t : shotStarts[shotIndex + t.shots] ?? total;
251
+ const start = at(layer.from, shotStarts[shotIndex]);
252
+ return { start, end: Math.max(start, at(layer.until ?? { shots: 1 }, total)) };
253
+ }
254
+ function effectSequenceTiming(sequence) {
255
+ const starts = [];
256
+ const leadIns = [];
257
+ let t = 0;
258
+ sequence.shots.forEach((shot, i) => {
259
+ const transition = i > 0 && shot.transition ? shot.transition.ms ?? EFFECT_TRANSITION_MS : 0;
260
+ const move = typeof shot.camera?.in === "object" && i > 0 ? shot.camera.in.ms ?? 0 : 0;
261
+ const lead = Math.max(transition, move);
262
+ starts.push(t);
263
+ leadIns.push(lead);
264
+ t += lead + shot.hold;
265
+ });
266
+ return { starts, leadIns, total: t };
267
+ }
268
+
269
+ // src/effects/template-tools.ts
270
+ var unavailable = (provider) => !provider ? "No effects provider is registered, so there are no sequence templates." : !provider.capabilities.supportsTemplates || !provider.listTemplates ? `${provider.name} has no sequence templates (capabilities.supportsTemplates is not set).` : null;
271
+ function effectTemplateTools(host, ctx) {
272
+ const require2 = () => {
273
+ const provider = host.provider();
274
+ const reason = unavailable(provider);
275
+ if (reason) throw new Error(reason);
276
+ return provider;
277
+ };
278
+ return [
279
+ {
280
+ name: "list_templates",
281
+ title: "List sequence templates",
282
+ description: "Lists the effects provider's sequence templates (ready-made scenes of several shots with slots to fill: a product reveal, before and after, a stat countdown\u2026), best match first: { available, templates: [{ id, name, description, tags, shots, durationMs }] }. Then describe_template for a template's slots and fill_template to use it. Without a provider that has templates it returns available: false and the reason.",
283
+ inputSchema: {
284
+ type: "object",
285
+ properties: {
286
+ query: { type: "string", description: "Words to match in the name, id, tags or description (default: every template)." },
287
+ tags: { type: "array", items: { type: "string", minLength: 1 }, description: "Only templates carrying every one of these tags." },
288
+ limit: { type: "integer", minimum: 1, maximum: 100, description: "Most templates to return (default all)." }
289
+ },
290
+ additionalProperties: false
291
+ },
292
+ annotations: { title: "List sequence templates", ...ctx.annotations.read },
293
+ handler: async ({ query, tags, limit }) => {
294
+ const provider = host.provider();
295
+ const reason = unavailable(provider);
296
+ if (reason) return { available: false, reason, templates: [] };
297
+ return { available: true, provider: provider.name, templates: await provider.listTemplates({ ...query ? { query } : {}, ...tags ? { tags } : {}, ...limit ? { limit } : {} }) };
298
+ }
299
+ },
300
+ {
301
+ name: "describe_template",
302
+ title: "Describe a sequence template",
303
+ description: `Describes a template's slots in the order a form shows them: { id, name, description, shots, slots: [{ name, type (image, video, svg, text, color, number), label, description, default or hasDefault, maxLength, min, max, integer }], slotSummaries (one line each), valuesSchema (the JSON Schema fill_template's values follow), exampleValues (the text, colour and number defaults, to change) }. Subject slots (image, video, svg) take a URL, markup, or { "slot": name } to leave them for the host.`,
304
+ inputSchema: { type: "object", properties: { template: { type: "string", minLength: 1, description: "A template id from list_templates." } }, required: ["template"], additionalProperties: false },
305
+ annotations: { title: "Describe a sequence template", ...ctx.annotations.read },
306
+ handler: async ({ template }) => {
307
+ const d = await require2().describeTemplate(template);
308
+ return { ...d, slotSummaries: d.slots.map(templateSlotSummary), valuesSchema: templateValuesSchema(d.slots), exampleValues: templateDefaultValues(d.slots) };
309
+ }
310
+ },
311
+ {
312
+ name: "fill_template",
313
+ title: "Fill a sequence template",
314
+ description: `Fills a template's slots and loads the result. ${host.fillDetails} Slots left out take their defaults. Values are checked first: every value that does not fit (an unknown slot, a wrong type, a number out of range, text too long) is refused at once, naming what the slot takes, and nothing changes. One undo step. Subject slots left open draw nothing until filled; the result's openSlots says which.`,
315
+ inputSchema: {
316
+ type: "object",
317
+ properties: {
318
+ template: { type: "string", minLength: 1, description: "A template id from list_templates." },
319
+ values: { type: "object", description: "Slot values by name, following describe_template's valuesSchema (default: every slot's default)." },
320
+ name: { type: "string", pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$", description: "A name for the result: lowercase words and dashes (default the template's)." },
321
+ ...host.fillOptions ?? {}
322
+ },
323
+ required: ["template"],
324
+ additionalProperties: false
325
+ },
326
+ annotations: { title: "Fill a sequence template", ...ctx.annotations.write },
327
+ handler: async ({ template, values, ...options }) => {
328
+ require2();
329
+ return host.fill(template, values ?? {}, options);
330
+ }
331
+ }
332
+ ];
333
+ }
234
334
 
235
335
  export {
236
336
  EFFECT_SEQUENCE_NAME,
@@ -251,5 +351,9 @@ export {
251
351
  effectSubjectProblem,
252
352
  checkEffectSequence,
253
353
  effectSequenceEffects,
254
- effectSequenceSlots
354
+ effectSequenceSlots,
355
+ fillEffectTemplate,
356
+ effectLayerSpan,
357
+ effectSequenceTiming,
358
+ effectTemplateTools
255
359
  };
@@ -1,6 +1,9 @@
1
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; }
2
2
 
3
3
 
4
+
5
+
6
+
4
7
  var _chunkJAOSL334cjs = require('./chunk-JAOSL334.cjs');
5
8
 
6
9
  // src/effects/templates.ts
@@ -231,6 +234,107 @@ function effectSequenceSlots(sequence) {
231
234
  for (const shot of sequence.shots) for (const l of shot.layers) if (l.subject && "slot" in l.subject) out.add(l.subject.slot);
232
235
  return [...out];
233
236
  }
237
+ async function fillEffectTemplate(provider, id, values = {}, options = {}) {
238
+ if (!provider) throw new (0, _chunkJAOSL334cjs.NoEffectsProviderError)();
239
+ if (!provider.capabilities.supportsTemplates || !provider.describeTemplate || !provider.instantiateTemplate) throw new (0, _chunkJAOSL334cjs.EffectUnsupportedError)(`${provider.name} has no sequence templates (capabilities.supportsTemplates is not set).`);
240
+ const template = await provider.describeTemplate(id);
241
+ const errors = checkTemplateValues(template.slots, values);
242
+ if (errors.length) throw new Error(`${errors.join(" ")} describe_template lists what each slot takes.`);
243
+ const result = await provider.instantiateTemplate(id, values, options);
244
+ if (!result.ok) throw new Error(`${result.errors.join(" ")} describe_template lists what each slot takes.`);
245
+ const problems = checkEffectSequence(result.sequence, await provider.list());
246
+ if (problems.length) throw new Error(`${provider.name} filled "${id}" with a sequence this editor cannot load: ${problems.join(" ")}`);
247
+ return { template, sequence: result.sequence, openSlots: [...result.openSlots], notes: [...result.notes] };
248
+ }
249
+ function effectLayerSpan(layer, shotIndex, shotStarts, total) {
250
+ const at = (t, fallback) => t === void 0 ? fallback : typeof t === "number" ? shotStarts[shotIndex] + t : _nullishCoalesce(shotStarts[shotIndex + t.shots], () => ( total));
251
+ const start = at(layer.from, shotStarts[shotIndex]);
252
+ return { start, end: Math.max(start, at(_nullishCoalesce(layer.until, () => ( { shots: 1 })), total)) };
253
+ }
254
+ function effectSequenceTiming(sequence) {
255
+ const starts = [];
256
+ const leadIns = [];
257
+ let t = 0;
258
+ sequence.shots.forEach((shot, i) => {
259
+ const transition = i > 0 && shot.transition ? _nullishCoalesce(shot.transition.ms, () => ( _chunkJAOSL334cjs.EFFECT_TRANSITION_MS)) : 0;
260
+ const move = typeof _optionalChain([shot, 'access', _4 => _4.camera, 'optionalAccess', _5 => _5.in]) === "object" && i > 0 ? _nullishCoalesce(shot.camera.in.ms, () => ( 0)) : 0;
261
+ const lead = Math.max(transition, move);
262
+ starts.push(t);
263
+ leadIns.push(lead);
264
+ t += lead + shot.hold;
265
+ });
266
+ return { starts, leadIns, total: t };
267
+ }
268
+
269
+ // src/effects/template-tools.ts
270
+ var unavailable = (provider) => !provider ? "No effects provider is registered, so there are no sequence templates." : !provider.capabilities.supportsTemplates || !provider.listTemplates ? `${provider.name} has no sequence templates (capabilities.supportsTemplates is not set).` : null;
271
+ function effectTemplateTools(host, ctx) {
272
+ const require2 = () => {
273
+ const provider = host.provider();
274
+ const reason = unavailable(provider);
275
+ if (reason) throw new Error(reason);
276
+ return provider;
277
+ };
278
+ return [
279
+ {
280
+ name: "list_templates",
281
+ title: "List sequence templates",
282
+ description: "Lists the effects provider's sequence templates (ready-made scenes of several shots with slots to fill: a product reveal, before and after, a stat countdown\u2026), best match first: { available, templates: [{ id, name, description, tags, shots, durationMs }] }. Then describe_template for a template's slots and fill_template to use it. Without a provider that has templates it returns available: false and the reason.",
283
+ inputSchema: {
284
+ type: "object",
285
+ properties: {
286
+ query: { type: "string", description: "Words to match in the name, id, tags or description (default: every template)." },
287
+ tags: { type: "array", items: { type: "string", minLength: 1 }, description: "Only templates carrying every one of these tags." },
288
+ limit: { type: "integer", minimum: 1, maximum: 100, description: "Most templates to return (default all)." }
289
+ },
290
+ additionalProperties: false
291
+ },
292
+ annotations: { title: "List sequence templates", ...ctx.annotations.read },
293
+ handler: async ({ query, tags, limit }) => {
294
+ const provider = host.provider();
295
+ const reason = unavailable(provider);
296
+ if (reason) return { available: false, reason, templates: [] };
297
+ return { available: true, provider: provider.name, templates: await provider.listTemplates({ ...query ? { query } : {}, ...tags ? { tags } : {}, ...limit ? { limit } : {} }) };
298
+ }
299
+ },
300
+ {
301
+ name: "describe_template",
302
+ title: "Describe a sequence template",
303
+ description: `Describes a template's slots in the order a form shows them: { id, name, description, shots, slots: [{ name, type (image, video, svg, text, color, number), label, description, default or hasDefault, maxLength, min, max, integer }], slotSummaries (one line each), valuesSchema (the JSON Schema fill_template's values follow), exampleValues (the text, colour and number defaults, to change) }. Subject slots (image, video, svg) take a URL, markup, or { "slot": name } to leave them for the host.`,
304
+ inputSchema: { type: "object", properties: { template: { type: "string", minLength: 1, description: "A template id from list_templates." } }, required: ["template"], additionalProperties: false },
305
+ annotations: { title: "Describe a sequence template", ...ctx.annotations.read },
306
+ handler: async ({ template }) => {
307
+ const d = await require2().describeTemplate(template);
308
+ return { ...d, slotSummaries: d.slots.map(templateSlotSummary), valuesSchema: templateValuesSchema(d.slots), exampleValues: templateDefaultValues(d.slots) };
309
+ }
310
+ },
311
+ {
312
+ name: "fill_template",
313
+ title: "Fill a sequence template",
314
+ description: `Fills a template's slots and loads the result. ${host.fillDetails} Slots left out take their defaults. Values are checked first: every value that does not fit (an unknown slot, a wrong type, a number out of range, text too long) is refused at once, naming what the slot takes, and nothing changes. One undo step. Subject slots left open draw nothing until filled; the result's openSlots says which.`,
315
+ inputSchema: {
316
+ type: "object",
317
+ properties: {
318
+ template: { type: "string", minLength: 1, description: "A template id from list_templates." },
319
+ values: { type: "object", description: "Slot values by name, following describe_template's valuesSchema (default: every slot's default)." },
320
+ name: { type: "string", pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$", description: "A name for the result: lowercase words and dashes (default the template's)." },
321
+ ..._nullishCoalesce(host.fillOptions, () => ( {}))
322
+ },
323
+ required: ["template"],
324
+ additionalProperties: false
325
+ },
326
+ annotations: { title: "Fill a sequence template", ...ctx.annotations.write },
327
+ handler: async ({ template, values, ...options }) => {
328
+ require2();
329
+ return host.fill(template, _nullishCoalesce(values, () => ( {})), options);
330
+ }
331
+ }
332
+ ];
333
+ }
334
+
335
+
336
+
337
+
234
338
 
235
339
 
236
340
 
@@ -252,4 +356,4 @@ function effectSequenceSlots(sequence) {
252
356
 
253
357
 
254
358
 
255
- exports.EFFECT_SEQUENCE_NAME = EFFECT_SEQUENCE_NAME; exports.isSubjectTemplateSlot = isSubjectTemplateSlot; exports.effectSubjectKind = effectSubjectKind; exports.templateSlotTakes = templateSlotTakes; exports.templateValueProblem = templateValueProblem; exports.checkTemplateValues = checkTemplateValues; exports.templateSlotSchema = templateSlotSchema; exports.templateValuesSchema = templateValuesSchema; exports.templateDefaultValues = templateDefaultValues; exports.templateSlotSummary = templateSlotSummary; exports.searchTemplateSummaries = searchTemplateSummaries; exports.effectLayerRole = effectLayerRole; exports.effectLayerInput = effectLayerInput; exports.EFFECT_LAYER_USES = EFFECT_LAYER_USES; exports.effectLayerOffered = effectLayerOffered; exports.effectSubjectProblem = effectSubjectProblem; exports.checkEffectSequence = checkEffectSequence; exports.effectSequenceEffects = effectSequenceEffects; exports.effectSequenceSlots = effectSequenceSlots;
359
+ exports.EFFECT_SEQUENCE_NAME = EFFECT_SEQUENCE_NAME; exports.isSubjectTemplateSlot = isSubjectTemplateSlot; exports.effectSubjectKind = effectSubjectKind; exports.templateSlotTakes = templateSlotTakes; exports.templateValueProblem = templateValueProblem; exports.checkTemplateValues = checkTemplateValues; exports.templateSlotSchema = templateSlotSchema; exports.templateValuesSchema = templateValuesSchema; exports.templateDefaultValues = templateDefaultValues; exports.templateSlotSummary = templateSlotSummary; exports.searchTemplateSummaries = searchTemplateSummaries; exports.effectLayerRole = effectLayerRole; exports.effectLayerInput = effectLayerInput; exports.EFFECT_LAYER_USES = EFFECT_LAYER_USES; exports.effectLayerOffered = effectLayerOffered; exports.effectSubjectProblem = effectSubjectProblem; exports.checkEffectSequence = checkEffectSequence; exports.effectSequenceEffects = effectSequenceEffects; exports.effectSequenceSlots = effectSequenceSlots; exports.fillEffectTemplate = fillEffectTemplate; exports.effectLayerSpan = effectLayerSpan; exports.effectSequenceTiming = effectSequenceTiming; exports.effectTemplateTools = effectTemplateTools;
@@ -24,7 +24,11 @@ var _chunkA7PQNIBXcjs = require('../chunk-A7PQNIBX.cjs');
24
24
 
25
25
 
26
26
 
27
- var _chunk6RZVFYGJcjs = require('../chunk-6RZVFYGJ.cjs');
27
+
28
+
29
+
30
+
31
+ var _chunkJWCKJNDRcjs = require('../chunk-JWCKJNDR.cjs');
28
32
 
29
33
 
30
34
  var _chunkPY4GWSE2cjs = require('../chunk-PY4GWSE2.cjs');
@@ -223,14 +227,14 @@ function checkSlot(templateId, slot, issues) {
223
227
  if (!slot || typeof slot.name !== "string" || !/^[A-Za-z][\w-]*$/.test(slot.name)) return at('needs a name of letters, digits, "-" and "_", starting with a letter');
224
228
  if (!_chunkJAOSL334cjs.EFFECT_TEMPLATE_SLOT_TYPES.includes(slot.type)) return at(`type "${slot.type}" is not one of ${_chunkJAOSL334cjs.EFFECT_TEMPLATE_SLOT_TYPES.join(", ")}`);
225
229
  if (typeof slot.label !== "string" || !slot.label) at("needs a label");
226
- if (_chunk6RZVFYGJcjs.isSubjectTemplateSlot.call(void 0, slot)) {
230
+ if (_chunkJWCKJNDRcjs.isSubjectTemplateSlot.call(void 0, slot)) {
227
231
  if (typeof slot.hasDefault !== "boolean") at("a subject slot needs hasDefault (a boolean)");
228
232
  if ("default" in slot) at("a subject slot describes hasDefault, not its default");
229
233
  return;
230
234
  }
231
235
  const fallback = slot.default;
232
236
  if (fallback === void 0) return at("needs a default");
233
- const problem = _chunk6RZVFYGJcjs.templateValueProblem.call(void 0, slot, fallback);
237
+ const problem = _chunkJWCKJNDRcjs.templateValueProblem.call(void 0, slot, fallback);
234
238
  if (problem) at(`its default does not fit: ${problem}`);
235
239
  if (slot.type === "number" && slot.min !== void 0 && slot.max !== void 0 && slot.min > slot.max) at("min is above max");
236
240
  }
@@ -276,11 +280,11 @@ async function checkTemplates(provider, list, issues) {
276
280
  const result = await provider.instantiateTemplate(id);
277
281
  if (!result.ok) at(`instantiateTemplate with the defaults failed: ${result.errors.join(" ")}`);
278
282
  else {
279
- for (const p of _chunk6RZVFYGJcjs.checkEffectSequence.call(void 0, result.sequence, list)) at(`with the defaults, ${p}`);
283
+ for (const p of _chunkJWCKJNDRcjs.checkEffectSequence.call(void 0, result.sequence, list)) at(`with the defaults, ${p}`);
280
284
  if (_optionalChain([result, 'access', _15 => _15.sequence, 'optionalAccess', _16 => _16.shots, 'optionalAccess', _17 => _17.length]) !== summary.shots) at(`listTemplates says ${summary.shots} shots; the sequence has ${_optionalChain([result, 'access', _18 => _18.sequence, 'optionalAccess', _19 => _19.shots, 'optionalAccess', _20 => _20.length])}`);
281
285
  if (!Array.isArray(result.openSlots) || !Array.isArray(result.notes)) at("instantiateTemplate needs openSlots and notes lists");
282
286
  else {
283
- const open = Array.isArray(_optionalChain([result, 'access', _21 => _21.sequence, 'optionalAccess', _22 => _22.shots])) ? _chunk6RZVFYGJcjs.effectSequenceSlots.call(void 0, result.sequence) : [];
287
+ const open = Array.isArray(_optionalChain([result, 'access', _21 => _21.sequence, 'optionalAccess', _22 => _22.shots])) ? _chunkJWCKJNDRcjs.effectSequenceSlots.call(void 0, result.sequence) : [];
284
288
  if (open.some((s) => !result.openSlots.includes(s))) at(`openSlots ${JSON.stringify(result.openSlots)} misses slots the sequence leaves open (${open.join(", ")})`);
285
289
  }
286
290
  }
@@ -498,7 +502,7 @@ function fill(t, values) {
498
502
  const slots = new Map(t.slots.map((s) => [s.name, s]));
499
503
  const valueOf = (name) => {
500
504
  const s = slots.get(name);
501
- return _nullishCoalesce(values[name], () => ( (_chunk6RZVFYGJcjs.isSubjectTemplateSlot.call(void 0, s) ? s.subjectDefault : s.default)));
505
+ return _nullishCoalesce(values[name], () => ( (_chunkJWCKJNDRcjs.isSubjectTemplateSlot.call(void 0, s) ? s.subjectDefault : s.default)));
502
506
  };
503
507
  const walk = (v, key) => {
504
508
  if (typeof v === "string") {
@@ -525,16 +529,16 @@ function fakeTemplateMethods() {
525
529
  return t;
526
530
  };
527
531
  return {
528
- listTemplates: (options) => _chunk6RZVFYGJcjs.searchTemplateSummaries.call(void 0, TEMPLATES.map((t) => t.summary), options).map((s) => structuredClone(s)),
532
+ listTemplates: (options) => _chunkJWCKJNDRcjs.searchTemplateSummaries.call(void 0, TEMPLATES.map((t) => t.summary), options).map((s) => structuredClone(s)),
529
533
  describeTemplate: (id) => structuredClone(describeOf(get(id))),
530
534
  instantiateTemplate(id, values = {}, options = {}) {
531
535
  const t = get(id);
532
- const errors = _chunk6RZVFYGJcjs.checkTemplateValues.call(void 0, describeOf(t).slots, values);
533
- if (options.name !== void 0 && (typeof options.name !== "string" || !_chunk6RZVFYGJcjs.EFFECT_SEQUENCE_NAME.test(options.name))) errors.push(`The sequence name is lowercase words and dashes (like "${t.summary.id.replace(/^fake\./, "")}").`);
536
+ const errors = _chunkJWCKJNDRcjs.checkTemplateValues.call(void 0, describeOf(t).slots, values);
537
+ if (options.name !== void 0 && (typeof options.name !== "string" || !_chunkJWCKJNDRcjs.EFFECT_SEQUENCE_NAME.test(options.name))) errors.push(`The sequence name is lowercase words and dashes (like "${t.summary.id.replace(/^fake\./, "")}").`);
534
538
  if (errors.length) return { ok: false, errors };
535
539
  const sequence = fill(t, values);
536
540
  if (options.name) sequence.name = options.name;
537
- return { ok: true, sequence, openSlots: _chunk6RZVFYGJcjs.effectSequenceSlots.call(void 0, sequence), notes: [] };
541
+ return { ok: true, sequence, openSlots: _chunkJWCKJNDRcjs.effectSequenceSlots.call(void 0, sequence), notes: [] };
538
542
  }
539
543
  };
540
544
  }
@@ -1607,4 +1611,8 @@ function createEffectAuthoringToolProvider(host, options) {
1607
1611
 
1608
1612
 
1609
1613
 
1610
- exports.CAMERA_MOVE_MAX_MS = _chunkJAOSL334cjs.CAMERA_MOVE_MAX_MS; exports.CAMERA_MOVE_ROLES = _chunkJAOSL334cjs.CAMERA_MOVE_ROLES; exports.EFFECT_ERROR_CODES = _chunkJAOSL334cjs.EFFECT_ERROR_CODES; exports.EFFECT_KINDS = _chunkJAOSL334cjs.EFFECT_KINDS; exports.EFFECT_LAYER_ROLES = _chunkJAOSL334cjs.EFFECT_LAYER_ROLES; exports.EFFECT_LAYER_USES = _chunk6RZVFYGJcjs.EFFECT_LAYER_USES; exports.EFFECT_SEQUENCE_NAME = _chunk6RZVFYGJcjs.EFFECT_SEQUENCE_NAME; exports.EFFECT_SUBJECT_KINDS = _chunkJAOSL334cjs.EFFECT_SUBJECT_KINDS; exports.EFFECT_TEMPLATE_SLOT_TYPES = _chunkJAOSL334cjs.EFFECT_TEMPLATE_SLOT_TYPES; exports.EFFECT_TRANSITION_MS = _chunkJAOSL334cjs.EFFECT_TRANSITION_MS; exports.EFFECT_USES = _chunkJAOSL334cjs.EFFECT_USES; exports.EFFECT_USE_LABELS = EFFECT_USE_LABELS; exports.EffectControlError = _chunkJAOSL334cjs.EffectControlError; exports.EffectDisposedError = _chunkJAOSL334cjs.EffectDisposedError; exports.EffectError = _chunkJAOSL334cjs.EffectError; exports.EffectRendererPool = _chunkPY4GWSE2cjs.EffectRendererPool; exports.EffectUnsupportedError = _chunkJAOSL334cjs.EffectUnsupportedError; exports.EffectsSlot = _chunkJAOSL334cjs.EffectsSlot; exports.NoEffectsProviderError = _chunkJAOSL334cjs.NoEffectsProviderError; exports.UnknownEffectError = _chunkJAOSL334cjs.UnknownEffectError; exports.UnknownTemplateError = _chunkJAOSL334cjs.UnknownTemplateError; exports.applyEffectMask = _chunkJAOSL334cjs.applyEffectMask; exports.cameraBoxOfView = _chunkJAOSL334cjs.cameraBoxOfView; exports.cameraMoveField = _chunkJAOSL334cjs.cameraMoveField; exports.cameraMoveIdList = _chunkJAOSL334cjs.cameraMoveIdList; exports.cameraMoveParts = _chunkJAOSL334cjs.cameraMoveParts; exports.cameraMovesFor = _chunkJAOSL334cjs.cameraMovesFor; exports.cameraViewOfBox = _chunkJAOSL334cjs.cameraViewOfBox; exports.checkEffectProvider = checkEffectProvider; exports.checkEffectSequence = _chunk6RZVFYGJcjs.checkEffectSequence; exports.checkTemplateValues = _chunk6RZVFYGJcjs.checkTemplateValues; exports.countEffectTags = _chunkJAOSL334cjs.countEffectTags; exports.createEffectAuthoringSession = _chunkA7PQNIBXcjs.createEffectAuthoringSession; exports.createEffectAuthoringToolProvider = createEffectAuthoringToolProvider; exports.createEffectPixels = _chunkJAOSL334cjs.createEffectPixels; exports.createEffectToolProvider = _chunkJAOSL334cjs.createEffectToolProvider; exports.createFakeEffectProvider = createFakeEffectProvider; exports.effectControlField = effectControlField; exports.effectFieldValue = effectFieldValue; exports.effectFontFamilies = effectFontFamilies; exports.effectLayerInput = _chunk6RZVFYGJcjs.effectLayerInput; exports.effectLayerOffered = _chunk6RZVFYGJcjs.effectLayerOffered; exports.effectLayerRole = _chunk6RZVFYGJcjs.effectLayerRole; exports.effectOffered = _chunkJAOSL334cjs.effectOffered; exports.effectParameterFields = effectParameterFields; exports.effectSampleInputs = effectSampleInputs; exports.effectSamplePicture = effectSamplePicture; exports.effectSequenceEffects = _chunk6RZVFYGJcjs.effectSequenceEffects; exports.effectSequenceSlots = _chunk6RZVFYGJcjs.effectSequenceSlots; exports.effectSubjectKind = _chunk6RZVFYGJcjs.effectSubjectKind; exports.effectSubjectProblem = _chunk6RZVFYGJcjs.effectSubjectProblem; exports.effectValueErrors = _chunkJAOSL334cjs.effectValueErrors; exports.encodeEffectFloat = _chunkJAOSL334cjs.encodeEffectFloat; exports.groupEffectsByCategory = groupEffectsByCategory; exports.hasEffectTags = _chunkJAOSL334cjs.hasEffectTags; exports.isCameraView = _chunkJAOSL334cjs.isCameraView; exports.isEffectError = _chunkJAOSL334cjs.isEffectError; exports.isEffectFontControl = isEffectFontControl; exports.isEffectPixels = _chunkJAOSL334cjs.isEffectPixels; exports.isSubjectTemplateSlot = _chunk6RZVFYGJcjs.isSubjectTemplateSlot; exports.linearToSrgb = _chunkJAOSL334cjs.linearToSrgb; exports.normaliseEffectTag = _chunkJAOSL334cjs.normaliseEffectTag; exports.renderEffectThumbnail = renderEffectThumbnail; exports.resolveCameraMoveSpec = _chunkJAOSL334cjs.resolveCameraMoveSpec; exports.resolveEffectValues = _chunkJAOSL334cjs.resolveEffectValues; exports.sampleCameraViews = _chunkJAOSL334cjs.sampleCameraViews; exports.sampleEffectCameraMove = _chunkJAOSL334cjs.sampleEffectCameraMove; exports.searchEffectSummaries = _chunkJAOSL334cjs.searchEffectSummaries; exports.searchTemplateSummaries = _chunk6RZVFYGJcjs.searchTemplateSummaries; exports.srgbToLinear = _chunkJAOSL334cjs.srgbToLinear; exports.templateDefaultValues = _chunk6RZVFYGJcjs.templateDefaultValues; exports.templateSlotSchema = _chunk6RZVFYGJcjs.templateSlotSchema; exports.templateSlotSummary = _chunk6RZVFYGJcjs.templateSlotSummary; exports.templateSlotTakes = _chunk6RZVFYGJcjs.templateSlotTakes; exports.templateValueProblem = _chunk6RZVFYGJcjs.templateValueProblem; exports.templateValuesSchema = _chunk6RZVFYGJcjs.templateValuesSchema;
1614
+
1615
+
1616
+
1617
+
1618
+ exports.CAMERA_MOVE_MAX_MS = _chunkJAOSL334cjs.CAMERA_MOVE_MAX_MS; exports.CAMERA_MOVE_ROLES = _chunkJAOSL334cjs.CAMERA_MOVE_ROLES; exports.EFFECT_ERROR_CODES = _chunkJAOSL334cjs.EFFECT_ERROR_CODES; exports.EFFECT_KINDS = _chunkJAOSL334cjs.EFFECT_KINDS; exports.EFFECT_LAYER_ROLES = _chunkJAOSL334cjs.EFFECT_LAYER_ROLES; exports.EFFECT_LAYER_USES = _chunkJWCKJNDRcjs.EFFECT_LAYER_USES; exports.EFFECT_SEQUENCE_NAME = _chunkJWCKJNDRcjs.EFFECT_SEQUENCE_NAME; exports.EFFECT_SUBJECT_KINDS = _chunkJAOSL334cjs.EFFECT_SUBJECT_KINDS; exports.EFFECT_TEMPLATE_SLOT_TYPES = _chunkJAOSL334cjs.EFFECT_TEMPLATE_SLOT_TYPES; exports.EFFECT_TRANSITION_MS = _chunkJAOSL334cjs.EFFECT_TRANSITION_MS; exports.EFFECT_USES = _chunkJAOSL334cjs.EFFECT_USES; exports.EFFECT_USE_LABELS = EFFECT_USE_LABELS; exports.EffectControlError = _chunkJAOSL334cjs.EffectControlError; exports.EffectDisposedError = _chunkJAOSL334cjs.EffectDisposedError; exports.EffectError = _chunkJAOSL334cjs.EffectError; exports.EffectRendererPool = _chunkPY4GWSE2cjs.EffectRendererPool; exports.EffectUnsupportedError = _chunkJAOSL334cjs.EffectUnsupportedError; exports.EffectsSlot = _chunkJAOSL334cjs.EffectsSlot; exports.NoEffectsProviderError = _chunkJAOSL334cjs.NoEffectsProviderError; exports.UnknownEffectError = _chunkJAOSL334cjs.UnknownEffectError; exports.UnknownTemplateError = _chunkJAOSL334cjs.UnknownTemplateError; exports.applyEffectMask = _chunkJAOSL334cjs.applyEffectMask; exports.cameraBoxOfView = _chunkJAOSL334cjs.cameraBoxOfView; exports.cameraMoveField = _chunkJAOSL334cjs.cameraMoveField; exports.cameraMoveIdList = _chunkJAOSL334cjs.cameraMoveIdList; exports.cameraMoveParts = _chunkJAOSL334cjs.cameraMoveParts; exports.cameraMovesFor = _chunkJAOSL334cjs.cameraMovesFor; exports.cameraViewOfBox = _chunkJAOSL334cjs.cameraViewOfBox; exports.checkEffectProvider = checkEffectProvider; exports.checkEffectSequence = _chunkJWCKJNDRcjs.checkEffectSequence; exports.checkTemplateValues = _chunkJWCKJNDRcjs.checkTemplateValues; exports.countEffectTags = _chunkJAOSL334cjs.countEffectTags; exports.createEffectAuthoringSession = _chunkA7PQNIBXcjs.createEffectAuthoringSession; exports.createEffectAuthoringToolProvider = createEffectAuthoringToolProvider; exports.createEffectPixels = _chunkJAOSL334cjs.createEffectPixels; exports.createEffectToolProvider = _chunkJAOSL334cjs.createEffectToolProvider; exports.createFakeEffectProvider = createFakeEffectProvider; exports.effectControlField = effectControlField; exports.effectFieldValue = effectFieldValue; exports.effectFontFamilies = effectFontFamilies; exports.effectLayerInput = _chunkJWCKJNDRcjs.effectLayerInput; exports.effectLayerOffered = _chunkJWCKJNDRcjs.effectLayerOffered; exports.effectLayerRole = _chunkJWCKJNDRcjs.effectLayerRole; exports.effectLayerSpan = _chunkJWCKJNDRcjs.effectLayerSpan; exports.effectOffered = _chunkJAOSL334cjs.effectOffered; exports.effectParameterFields = effectParameterFields; exports.effectSampleInputs = effectSampleInputs; exports.effectSamplePicture = effectSamplePicture; exports.effectSequenceEffects = _chunkJWCKJNDRcjs.effectSequenceEffects; exports.effectSequenceSlots = _chunkJWCKJNDRcjs.effectSequenceSlots; exports.effectSequenceTiming = _chunkJWCKJNDRcjs.effectSequenceTiming; exports.effectSubjectKind = _chunkJWCKJNDRcjs.effectSubjectKind; exports.effectSubjectProblem = _chunkJWCKJNDRcjs.effectSubjectProblem; exports.effectTemplateTools = _chunkJWCKJNDRcjs.effectTemplateTools; exports.effectValueErrors = _chunkJAOSL334cjs.effectValueErrors; exports.encodeEffectFloat = _chunkJAOSL334cjs.encodeEffectFloat; exports.fillEffectTemplate = _chunkJWCKJNDRcjs.fillEffectTemplate; exports.groupEffectsByCategory = groupEffectsByCategory; exports.hasEffectTags = _chunkJAOSL334cjs.hasEffectTags; exports.isCameraView = _chunkJAOSL334cjs.isCameraView; exports.isEffectError = _chunkJAOSL334cjs.isEffectError; exports.isEffectFontControl = isEffectFontControl; exports.isEffectPixels = _chunkJAOSL334cjs.isEffectPixels; exports.isSubjectTemplateSlot = _chunkJWCKJNDRcjs.isSubjectTemplateSlot; exports.linearToSrgb = _chunkJAOSL334cjs.linearToSrgb; exports.normaliseEffectTag = _chunkJAOSL334cjs.normaliseEffectTag; exports.renderEffectThumbnail = renderEffectThumbnail; exports.resolveCameraMoveSpec = _chunkJAOSL334cjs.resolveCameraMoveSpec; exports.resolveEffectValues = _chunkJAOSL334cjs.resolveEffectValues; exports.sampleCameraViews = _chunkJAOSL334cjs.sampleCameraViews; exports.sampleEffectCameraMove = _chunkJAOSL334cjs.sampleEffectCameraMove; exports.searchEffectSummaries = _chunkJAOSL334cjs.searchEffectSummaries; exports.searchTemplateSummaries = _chunkJWCKJNDRcjs.searchTemplateSummaries; exports.srgbToLinear = _chunkJAOSL334cjs.srgbToLinear; exports.templateDefaultValues = _chunkJWCKJNDRcjs.templateDefaultValues; exports.templateSlotSchema = _chunkJWCKJNDRcjs.templateSlotSchema; exports.templateSlotSummary = _chunkJWCKJNDRcjs.templateSlotSummary; exports.templateSlotTakes = _chunkJWCKJNDRcjs.templateSlotTakes; exports.templateValueProblem = _chunkJWCKJNDRcjs.templateValueProblem; exports.templateValuesSchema = _chunkJWCKJNDRcjs.templateValuesSchema;
@@ -11,6 +11,7 @@ export * from './templates.cjs';
11
11
  export * from './conformance.cjs';
12
12
  export * from './fake.cjs';
13
13
  export * from './tools.cjs';
14
+ export * from './template-tools.cjs';
14
15
  export * from './ui.cjs';
15
16
  export * from './pool.cjs';
16
17
  export * from './authoring.cjs';
@@ -11,6 +11,7 @@ export * from './templates.js';
11
11
  export * from './conformance.js';
12
12
  export * from './fake.js';
13
13
  export * from './tools.js';
14
+ export * from './template-tools.js';
14
15
  export * from './ui.js';
15
16
  export * from './pool.js';
16
17
  export * from './authoring.js';