@pixerate/flair 0.9.0 → 0.11.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.
- package/CHANGELOG.md +22 -0
- package/README.md +14 -6
- package/dist/catalog/index.d.ts +3 -3
- package/dist/catalog/index.js +1 -1
- package/dist/chunk-36OCXXPY.js +10447 -0
- package/dist/chunk-36OCXXPY.js.map +1 -0
- package/dist/{chunk-EQS4EXNM.js → chunk-SH66CNLC.js} +52 -6
- package/dist/chunk-SH66CNLC.js.map +1 -0
- package/dist/{chunk-TDMD5XAU.js → chunk-YACVME3D.js} +75 -4
- package/dist/{chunk-TDMD5XAU.js.map → chunk-YACVME3D.js.map} +1 -1
- package/dist/{chunk-EZRRKQFV.js → chunk-YLJWC4N2.js} +96 -1
- package/dist/chunk-YLJWC4N2.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/editor/index.d.ts +3 -4
- package/dist/editor/index.js +4 -4
- package/dist/editor/index.js.map +1 -1
- package/dist/index.d.ts +65 -6
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/{renderer-0_Ap1tyi.d.ts → renderer-SNYZu__R.d.ts} +17 -0
- package/dist/svg-CpeanaE_.d.ts +375 -0
- package/dist/{types-CgHG5JLv.d.ts → types-DwXdtN-Y.d.ts} +8 -2
- package/dist/vector/index.d.ts +2 -120
- package/dist/vector/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-EQS4EXNM.js.map +0 -1
- package/dist/chunk-EZRRKQFV.js.map +0 -1
- package/dist/chunk-F754SFRY.js +0 -4973
- package/dist/chunk-F754SFRY.js.map +0 -1
- package/dist/clock-BhdXWH-n.d.ts +0 -47
- package/dist/motion-Ce0lmzm3.d.ts +0 -179
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { d as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-
|
|
1
|
+
import { d as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-DwXdtN-Y.js';
|
|
2
2
|
import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-Syr6drzO.js';
|
|
3
|
-
import { S as SvgMotion } from '../
|
|
3
|
+
import { S as SvgMotion, C as Clock } from '../svg-CpeanaE_.js';
|
|
4
4
|
import { AnimationEasingPreset, AnimationEasing, AnimationTrack, AnimationKeyframe, cubicBezierAt as cubicBezierAt$1, evaluateEasing as evaluateEasing$1 } from '@pixerate/editor/animation';
|
|
5
5
|
export { CubicBezierEasing, SpringEasing } from '@pixerate/editor/animation';
|
|
6
6
|
import { CommandRegistry, CommandSpec } from '@pixerate/editor/commands';
|
|
7
7
|
import { HistoryManager, HistoryState } from '@pixerate/editor/history';
|
|
8
|
-
import { C as CompileError, a as CompileStatus } from '../renderer-
|
|
9
|
-
import { C as Clock } from '../clock-BhdXWH-n.js';
|
|
8
|
+
import { C as CompileError, a as CompileStatus } from '../renderer-SNYZu__R.js';
|
|
10
9
|
import { AgentToolProvider, McpToolResult, ToolRegistryOptions, ToolRegistry, McpToolDefinition } from '@pixerate/editor/tools';
|
|
11
10
|
import { ParameterImageOption, ParametersController, ParameterField, ParameterSchema, ParameterValue, ParameterValues } from '@pixerate/editor/parameters';
|
|
12
11
|
|
package/dist/editor/index.js
CHANGED
|
@@ -5,16 +5,16 @@ import {
|
|
|
5
5
|
renderVectorEffect,
|
|
6
6
|
vectorControlIssues,
|
|
7
7
|
vectorEffectControls
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-36OCXXPY.js";
|
|
9
9
|
import {
|
|
10
10
|
svgMotionIssues,
|
|
11
11
|
svgView
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-YACVME3D.js";
|
|
13
13
|
import "../chunk-OHW7UG6D.js";
|
|
14
14
|
import {
|
|
15
15
|
BUILTIN_UNIFORMS,
|
|
16
16
|
interpolateOklab
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-YLJWC4N2.js";
|
|
18
18
|
import "../chunk-EHDJ3CPJ.js";
|
|
19
19
|
import {
|
|
20
20
|
realClock
|
|
@@ -918,7 +918,7 @@ Start with \`effect.describe\` to see what is being edited. To start from someth
|
|
|
918
918
|
|
|
919
919
|
Shader effects are GLSL ES 3.00 fragment shaders written Shadertoy-style:
|
|
920
920
|
- Define \`void mainImage(out vec4 fragColor, in vec2 fragCoord)\`; the output is opaque unless the host renders with \`alpha: true\` (overlays), when \`fragColor.a\` is coverage.
|
|
921
|
-
- Built-in uniforms (do not declare them): ${BUILTIN_UNIFORMS.map((u) => `\`${u.type} ${u.name}\` (${u.doc})`).join("; ")}.
|
|
921
|
+
- Built-in uniforms (do not declare them): ${BUILTIN_UNIFORMS.map((u) => `\`${u.type} ${u.name}${"size" in u ? `[${u.size}]` : ""}\` (${u.doc})`).join("; ")}.
|
|
922
922
|
- Declare controls as uniforms with an annotation on the same line, e.g.
|
|
923
923
|
uniform float uSpeed; // @control min=0 max=4 default=1 label="Speed"
|
|
924
924
|
uniform vec3 uTint; // @control color default=#77C16A label="Tint"
|
package/dist/editor/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/editor/timeline.ts","../../src/editor/document.ts","../../src/editor/editor.ts","../../src/editor/commands.ts","../../src/editor/agent.ts","../../src/editor/bind.ts","../../src/editor/parameters.ts"],"sourcesContent":["/**\n * Keyframed control values. A track holds keyframes `{ time (ms), value,\n * easing }` for one control; the easing governs the segment leaving its\n * keyframe. Easing comes from `@pixerate/editor/animation`, and tracks keep\n * its `AnimationTrack` shape; Flair adds what control values need beyond\n * numbers and colours (vectors, booleans, images, ints).\n */\n\nimport {\n ANIMATION_EASING_PRESETS,\n cubicBezierAt as editorCubicBezierAt,\n evaluateEasing as evaluateAnimationEasing,\n isAnimationEasing,\n type AnimationEasing,\n type AnimationEasingPreset,\n type AnimationKeyframe,\n type AnimationTrack,\n type CubicBezierEasing,\n type SpringEasing,\n} from \"@pixerate/editor/animation\";\nimport type { ControlDef, ControlValue } from \"../shader/controls.js\";\nimport { interpolateOklab, type ColorRGB } from \"../shader/color.js\";\n\n/** Named easings (CSS keywords plus back and spring curves). */\nexport type EasingPreset = AnimationEasingPreset;\nexport type Easing = AnimationEasing;\nexport type { CubicBezierEasing, SpringEasing };\n\n/** Every easing preset, in picker order. */\nexport const EASING_PRESETS: readonly EasingPreset[] = ANIMATION_EASING_PRESETS;\n\n/** Eased progress at `u` (0–1) through a segment `durationMs` long (`@pixerate/editor`'s easing engine). */\nexport const evaluateEasing = evaluateAnimationEasing;\n\n/** CSS `cubic-bezier(x1, y1, x2, y2)` solved for y at progress x. */\nexport const cubicBezierAt = editorCubicBezierAt;\n\n/**\n * Whether `value` is an easing (a preset name, a cubic bezier or a spring),\n * with a spring's stiffness, damping and mass above 0 when given.\n */\nexport function isEasing(value: unknown): value is Easing {\n if (!isAnimationEasing(value)) return false;\n if (typeof value !== \"object\" || value.type !== \"spring\") return true;\n return [value.stiffness, value.damping, value.mass].every((v) => v === undefined || v > 0);\n}\n\n/** A keyframe of a control: like `AnimationKeyframe`, with any control value (vectors and booleans too). */\nexport interface Keyframe extends Omit<AnimationKeyframe, \"value\"> {\n value: ControlValue;\n}\n\n/** A control's keyframes: `AnimationTrack`'s shape, with control values. */\nexport interface Track extends Omit<AnimationTrack, \"keyframes\"> {\n /** Sorted by time, at most one per time. */\n keyframes: Keyframe[];\n}\n\n/**\n * A control value `t` of the way from `a` to `b`: numbers and vectors blend\n * (overshooting with back and spring easings), colours blend in Oklab, `int`s\n * round, and booleans and images switch halfway.\n */\nexport function interpolateControlValue(control: ControlDef | undefined, a: ControlValue, b: ControlValue, t: number): ControlValue {\n if (typeof a === \"number\" && typeof b === \"number\") {\n const v = a + (b - a) * t;\n return control?.type === \"int\" ? Math.round(v) : v;\n }\n if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {\n if (control?.color && a.length >= 3) {\n const rgb = interpolateOklab(a.slice(0, 3) as ColorRGB, b.slice(0, 3) as ColorRGB, t);\n const out = rgb.map((c) => Math.min(1, Math.max(0, c)));\n return a.length === 4 ? [...out, a[3]! + (b[3]! - a[3]!) * t] : out;\n }\n return a.map((v, i) => v + (b[i]! - v) * t);\n }\n return t < 0.5 ? a : b;\n}\n\n/** A track's value at `time` (ms), or undefined when it has no keyframes or is disabled. */\nexport function evaluateTrack(track: Track | undefined, time: number, control?: ControlDef): ControlValue | undefined {\n if (!track || track.enabled === false || track.keyframes.length === 0) return undefined;\n const keys = track.keyframes;\n if (time <= keys[0]!.time) return keys[0]!.value;\n const last = keys[keys.length - 1]!;\n if (time >= last.time) return last.value;\n let i = 0;\n while (i < keys.length - 2 && keys[i + 1]!.time <= time) i++;\n const from = keys[i]!;\n const to = keys[i + 1]!;\n const span = to.time - from.time;\n const u = span > 0 ? (time - from.time) / span : 1;\n return interpolateControlValue(control, from.value, to.value, evaluateEasing(from.easing, u, span));\n}\n\n/** Keyframes sorted by time, one per time (the later of two at the same time wins). */\nexport function normalizeKeyframes(keyframes: readonly Keyframe[]): Keyframe[] {\n const byTime = new Map<number, Keyframe>();\n for (const k of keyframes) byTime.set(Math.round(k.time * 1000) / 1000, { ...k, time: Math.round(k.time * 1000) / 1000 });\n return [...byTime.values()].sort((a, b) => a.time - b.time);\n}\n\n/** The keyframe times across tracks, sorted and without duplicates. */\nexport function keyframeTimes(tracks: Record<string, Track>): number[] {\n return [...new Set(Object.values(tracks).flatMap((t) => t.keyframes.map((k) => k.time)))].sort((a, b) => a - b);\n}\n","/**\n * The document an effect editor edits: an effect (a shader's source, or a\n * vector picture with its controls), the values picked for its controls,\n * keyframed tracks, presets and a timeline. Plain JSON, so it can be saved,\n * diffed, and written by an agent.\n */\n\nimport { getEffect, renderVectorEffect, vectorControlIssues, vectorEffectControls } from \"../catalog/index.js\";\nimport type { EffectDefinition, EffectPreset, VectorControl } from \"../catalog/types.js\";\nimport { checkControlValue, controlValue, parseControls, type ControlDef, type ControlValue } from \"../shader/controls.js\";\nimport { svgMotionIssues, type SvgMotion } from \"../vector/motion.js\";\nimport { evaluateTrack, isEasing, normalizeKeyframes, type Track } from \"./timeline.js\";\n\n/**\n * What is being edited: a fragment shader, or an animated SVG. Both declare\n * their controls in themselves (`// @control`, `{{name: type …}}`); a vector\n * effect's optional `controls` list is for pictures written before that.\n */\nexport type EffectSource =\n | { kind: \"shader\"; source: string }\n | { kind: \"vector\"; motion: SvgMotion; controls?: VectorControl[]; hold?: number };\n\nexport interface EffectDocument {\n /** Format version (1). */\n version: 1;\n name: string;\n /** The catalog effect it started from, if any. */\n basedOn?: string;\n effect: EffectSource;\n /** Picked control values; controls without one use their default. */\n values: Record<string, ControlValue>;\n /** Keyframed controls, by control name. A track overrides the control's value. */\n tracks: Record<string, Track>;\n /** Timeline length in ms. */\n duration: number;\n loop: boolean;\n presets: EffectPreset[];\n}\n\nconst DEFAULT_SHADER = `// A new effect: edit me.\nuniform vec3 uColorA; // @control color default=#6366F1 label=\"Colour A\"\nuniform vec3 uColorB; // @control color default=#EC4899 label=\"Colour B\"\nuniform float uSpeed; // @control min=0 max=4 default=1 label=\"Speed\"\n\nvoid mainImage(out vec4 fragColor, in vec2 fragCoord) {\n vec2 uv = fragCoord / iResolution.xy;\n float t = 0.5 + 0.5 * sin(uv.x * 3.0 + iTime * uSpeed);\n fragColor = vec4(mix(uColorA, uColorB, t), 1.0);\n}\n`;\n\n/** Ms of timeline a new document gets (the effect's loop when it has one). */\nconst DEFAULT_DURATION = 5000;\n\n/**\n * A new document: blank (a small starter shader), from a catalog effect (by\n * id or definition), or from a shader's source.\n */\nexport function createEffectDocument(from?: string | EffectDefinition | { source: string; name?: string }): EffectDocument {\n if (from === undefined) return blankDocument(\"Untitled effect\", DEFAULT_SHADER);\n if (typeof from === \"object\" && !(\"kind\" in from)) return blankDocument(from.name ?? \"Untitled effect\", from.source);\n const effect = typeof from === \"string\" ? getEffect(from) : from;\n if (!effect) throw new Error(`There is no effect \"${String(from)}\" in the catalog.`);\n return {\n version: 1,\n name: effect.name,\n basedOn: effect.id,\n effect:\n effect.kind === \"shader\"\n ? { kind: \"shader\", source: effect.source }\n : {\n kind: \"vector\",\n motion: structuredClone(effect.motion),\n ...(effect.controls && { controls: effect.controls.map((c) => ({ ...c })) }),\n hold: effect.hold,\n },\n values: {},\n tracks: {},\n duration: effect.kind === \"shader\" && effect.loop ? Math.round(effect.loop * 1000) : DEFAULT_DURATION,\n loop: true,\n presets: (effect.presets ?? []).map((p) => ({ name: p.name, values: { ...p.values } })),\n };\n}\n\nfunction blankDocument(name: string, source: string): EffectDocument {\n return { version: 1, name, effect: { kind: \"shader\", source }, values: {}, tracks: {}, duration: DEFAULT_DURATION, loop: true, presets: [] };\n}\n\n/** The document's controls. */\nexport function documentControls(doc: EffectDocument): ControlDef[] {\n if (doc.effect.kind === \"shader\") return parseControls(doc.effect.source);\n return vectorEffectControls(doc.effect);\n}\n\n/** Every control's value at `time` (ms): its track if it has one, else the picked value, else its default. */\nexport function valuesAt(doc: EffectDocument, time: number, controls = documentControls(doc)): Record<string, ControlValue> {\n const out: Record<string, ControlValue> = {};\n for (const control of controls) {\n const tracked = evaluateTrack(doc.tracks[control.name], time, control);\n out[control.name] = tracked ?? controlValue(control, doc.values);\n }\n return out;\n}\n\n/** A vector document's picture with the values at `time` filled in; undefined for shaders. */\nexport function motionAt(doc: EffectDocument, time: number): SvgMotion | undefined {\n if (doc.effect.kind !== \"vector\") return undefined;\n // Derived placeholders are code, so they come from the catalog effect the document started from.\n const base = doc.basedOn ? getEffect(doc.basedOn) : undefined;\n const derived = base?.kind === \"vector\" ? base.derived : undefined;\n return renderVectorEffect({ motion: doc.effect.motion, controls: doc.effect.controls, derived }, valuesAt(doc, time));\n}\n\n/**\n * Problems with a document, as sentences: unknown controls in values, tracks\n * or presets, values a control cannot take, bad keyframes, and (for vector\n * effects) problems with the picture. Shader compile errors come from the\n * GPU, not from here.\n */\nexport function documentIssues(doc: EffectDocument): string[] {\n const issues: string[] = [];\n if (!(doc.duration > 0)) issues.push(\"`duration` must be above 0 ms\");\n if (doc.effect.kind === \"shader\" && !/void\\s+mainImage\\s*\\(/.test(doc.effect.source))\n issues.push(\"the shader needs `void mainImage(out vec4 fragColor, in vec2 fragCoord)`\");\n const controls = new Map(documentControls(doc).map((c) => [c.name, c]));\n const check = (where: string, name: string, value: unknown) => {\n const control = controls.get(name);\n if (!control) return void issues.push(`${where}: there is no control \"${name}\"`);\n const result = checkControlValue(control, value);\n if (!result.ok) issues.push(`${where}: ${result.message}`);\n };\n for (const [name, value] of Object.entries(doc.values)) check(\"values\", name, value);\n for (const [name, track] of Object.entries(doc.tracks)) {\n track.keyframes.forEach((k, i) => {\n const where = `tracks.${name}[${i}]`;\n if (!(k.time >= 0)) issues.push(`${where}: \\`time\\` must be 0 or more`);\n if (k.easing !== undefined && !isEasing(k.easing)) issues.push(`${where}: unknown easing`);\n check(where, name, k.value);\n });\n }\n for (const preset of doc.presets) for (const [name, value] of Object.entries(preset.values)) check(`preset \"${preset.name}\"`, name, value);\n if (doc.effect.kind === \"vector\") {\n const motion = motionAt(doc, 0)!;\n issues.push(...vectorControlIssues(doc.effect.motion), ...svgMotionIssues(motion));\n if (/\\{\\{[^}]+\\}\\}/.test(JSON.stringify(motion))) issues.push(\"the picture has placeholders no control fills\");\n }\n return issues;\n}\n\n/** Reads a document from JSON (or a parsed object), checking its shape. */\nexport function parseEffectDocument(input: string | unknown): { ok: true; document: EffectDocument } | { ok: false; errors: string[] } {\n let raw: unknown = input;\n if (typeof input === \"string\") {\n try {\n raw = JSON.parse(input);\n } catch (e) {\n return { ok: false, errors: [`not JSON: ${(e as Error).message}`] };\n }\n }\n const errors: string[] = [];\n const o = (raw ?? {}) as Partial<EffectDocument> & Record<string, unknown>;\n if (o.version !== 1) errors.push(\"`version` must be 1\");\n if (typeof o.name !== \"string\") errors.push(\"`name` must be a string\");\n const effect = o.effect as Partial<EffectSource> | undefined;\n if (!effect || (effect.kind !== \"shader\" && effect.kind !== \"vector\")) errors.push('`effect.kind` must be \"shader\" or \"vector\"');\n else if (effect.kind === \"shader\" && typeof (effect as { source?: unknown }).source !== \"string\") errors.push(\"`effect.source` must be a string\");\n else if (effect.kind === \"vector\") {\n const v = effect as Partial<Extract<EffectSource, { kind: \"vector\" }>>;\n if (!v.motion || typeof v.motion.svg !== \"string\") errors.push(\"`effect.motion.svg` must be a string\");\n if (v.controls !== undefined && !Array.isArray(v.controls)) errors.push(\"`effect.controls` must be a list\");\n }\n const isRecord = (v: unknown) => !!v && typeof v === \"object\" && !Array.isArray(v);\n if (o.values !== undefined && !isRecord(o.values)) errors.push(\"`values` must be an object\");\n if (o.tracks !== undefined && !isRecord(o.tracks)) errors.push(\"`tracks` must be an object\");\n for (const [name, track] of Object.entries((isRecord(o.tracks) ? o.tracks : {}) as Record<string, Track>))\n if (!track || !Array.isArray(track.keyframes)) errors.push(`\\`tracks.${name}.keyframes\\` must be a list`);\n if (o.presets !== undefined && !Array.isArray(o.presets)) errors.push(\"`presets` must be a list\");\n if (errors.length) return { ok: false, errors };\n const tracks = Object.fromEntries(\n Object.entries((o.tracks ?? {}) as Record<string, Track>).map(([k, t]) => [k, { ...t, keyframes: normalizeKeyframes(t.keyframes) }]),\n );\n return {\n ok: true,\n document: {\n version: 1,\n name: o.name!,\n basedOn: typeof o.basedOn === \"string\" ? o.basedOn : undefined,\n effect: o.effect as EffectSource,\n values: (o.values ?? {}) as Record<string, ControlValue>,\n tracks,\n duration: typeof o.duration === \"number\" && o.duration > 0 ? o.duration : DEFAULT_DURATION,\n loop: o.loop !== false,\n presets: (o.presets ?? []) as EffectPreset[],\n },\n };\n}\n","/**\n * A UI-agnostic effect editor: the document, its undo history, a playhead,\n * and commands that menus, shortcuts, a palette and agents all run by id.\n * Bring your own UI (any framework, or none) and your own renderer binding\n * (see `bindShaderRenderer` and `bindSvgView`).\n */\n\nimport { createCommandRegistry, createHistoryCommands, type CommandRegistry } from \"@pixerate/editor/commands\";\nimport { createHistoryManager, HistoryManager, type HistoryState } from \"@pixerate/editor/history\";\nimport type { EffectDefinition } from \"../catalog/types.js\";\nimport type { CompileError } from \"../shader/program.js\";\nimport { checkControlValue, type ControlDef, type ControlValue } from \"../shader/controls.js\";\nimport { realClock, type Clock } from \"../time/clock.js\";\nimport type { SvgMotion } from \"../vector/motion.js\";\nimport { effectCommands } from \"./commands.js\";\nimport {\n createEffectDocument,\n documentControls,\n documentIssues,\n parseEffectDocument,\n valuesAt,\n type EffectDocument,\n} from \"./document.js\";\nimport { evaluateTrack, isEasing, normalizeKeyframes, type Easing, type Keyframe } from \"./timeline.js\";\n\n/** What an edit did: `ok`, or why it was refused (in a sentence an agent can act on). */\nexport type EditResult = { ok: true } | { ok: false; message: string };\n\n/** The result of compiling the shader, as reported by a renderer (see `reportCompile`). */\nexport interface CompileReport {\n ok: boolean;\n errors: CompileError[];\n}\n\nexport interface EffectEditorState {\n document: EffectDocument;\n controls: ControlDef[];\n /** Every control's value at the playhead. */\n values: Record<string, ControlValue>;\n /** Problems with the document (see `documentIssues`). */\n issues: string[];\n /** The latest compile report, or null before a renderer reported one (and for vector effects). */\n compile: CompileReport | null;\n /** Playhead, ms. */\n time: number;\n playing: boolean;\n /** Whether changing a value keyframes it at the playhead. */\n recording: boolean;\n history: HistoryState;\n}\n\nexport interface EffectEditorOptions {\n /** The document to edit, or what to start one from (see `createEffectDocument`). */\n document?: EffectDocument;\n from?: string | EffectDefinition | { source: string; name?: string };\n /** Undo history to record into (default: a new one, 100 steps deep). */\n history?: HistoryManager;\n /** Time source for playback (default: animation frames). */\n clock?: Clock;\n /** Ms within which value changes to one control merge into one undo step (default 400). */\n mergeWindowMs?: number;\n}\n\nconst ok: EditResult = { ok: true };\nconst fail = (message: string): EditResult => ({ ok: false, message });\n\n/**\n * Edits one effect. Every change to the document is an undo step (value\n * changes in quick succession, like a slider drag, merge into one), and\n * subscribers hear about every change to the state.\n */\nexport class EffectEditor {\n readonly history: HistoryManager;\n /** Every editing action, by id: for menus, shortcuts, a command palette and agents. */\n readonly commands: CommandRegistry<EffectEditor>;\n private doc: EffectDocument;\n private controlsCache: { doc: EffectDocument; controls: ControlDef[]; issues: string[] } | null = null;\n private compileReport: CompileReport | null = null;\n private time = 0;\n private playing = false;\n private recording = false;\n private readonly clock: Clock;\n private readonly mergeWindowMs: number;\n private readonly listeners = new Set<(state: EffectEditorState) => void>();\n private state: EffectEditorState | null = null;\n private readonly unsubscribeHistory: () => void;\n private disposed = false;\n\n constructor(options: EffectEditorOptions = {}) {\n this.doc = options.document ?? createEffectDocument(options.from);\n this.history = options.history ?? createHistoryManager({ maxDepth: 100 });\n this.clock = options.clock ?? realClock;\n this.mergeWindowMs = options.mergeWindowMs ?? 400;\n this.commands = createCommandRegistry<EffectEditor>({ context: this });\n this.commands.register([...createHistoryCommands(this.history), ...effectCommands()]);\n this.unsubscribeHistory = this.history.subscribe(() => this.changed());\n }\n\n // ── Reading ────────────────────────────────────────────────────────\n\n get document(): EffectDocument {\n return this.doc;\n }\n\n /** The current state; the same object until something changes (safe for `useSyncExternalStore`). */\n getState(): EffectEditorState {\n if (!this.state) {\n const { controls, issues } = this.analysis();\n this.state = {\n document: this.doc,\n controls,\n values: valuesAt(this.doc, this.time, controls),\n issues,\n compile: this.doc.effect.kind === \"shader\" ? this.compileReport : null,\n time: this.time,\n playing: this.playing,\n recording: this.recording,\n history: this.history.getState(),\n };\n }\n return this.state;\n }\n\n /** Calls `listener` with the new state after every change; returns an unsubscribe function. */\n subscribe(listener: (state: EffectEditorState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /** The document's controls. */\n get controls(): ControlDef[] {\n return this.analysis().controls;\n }\n\n /** The document as JSON. */\n toJSON(): EffectDocument {\n return this.doc;\n }\n\n // ── Whole documents ─────────────────────────────────────────────────\n\n /** Replaces the document (one undo step). */\n replaceDocument(next: EffectDocument, label = \"Replace effect\"): EditResult {\n const parsed = parseEffectDocument(next);\n if (!parsed.ok) return fail(parsed.errors.join(\"; \"));\n this.commit(label, parsed.document);\n return ok;\n }\n\n /** Starts over from a catalog effect, a shader source, or blank (one undo step). */\n load(from?: string | EffectDefinition | { source: string; name?: string }, preset?: string): EditResult {\n let next: EffectDocument;\n try {\n next = createEffectDocument(from);\n } catch (e) {\n return fail((e as Error).message);\n }\n if (preset) {\n const values = next.presets.find((p) => p.name === preset)?.values;\n if (!values) return fail(`\"${next.name}\" has no preset \"${preset}\"; it has ${next.presets.map((p) => `\"${p.name}\"`).join(\", \") || \"none\"}.`);\n next = { ...next, values: { ...values } };\n }\n this.compileReport = null;\n this.commit(`Load ${next.name}`, next);\n return ok;\n }\n\n rename(name: string): EditResult {\n if (!name.trim()) return fail(\"A name cannot be empty.\");\n this.commit(\"Rename\", { ...this.doc, name: name.trim() });\n return ok;\n }\n\n // ── The effect itself ───────────────────────────────────────────────\n\n /** Replaces a shader's source. Compile errors arrive later, from the renderer (see `reportCompile`). */\n setSource(source: string): EditResult {\n if (this.doc.effect.kind !== \"shader\") return fail(\"This is a vector effect; use setMotion.\");\n if (source === this.doc.effect.source) return ok;\n this.commit(\"Edit source\", { ...this.doc, effect: { kind: \"shader\", source } }, \"source\");\n return ok;\n }\n\n /** Replaces a vector effect's picture, whose `{{name: type …}}` placeholders declare its controls (and optionally a `controls` list). */\n setMotion(motion: SvgMotion, controls?: Extract<EffectDocument[\"effect\"], { kind: \"vector\" }>[\"controls\"]): EditResult {\n if (this.doc.effect.kind !== \"vector\") return fail(\"This is a shader effect; use setSource.\");\n this.commit(\"Edit picture\", { ...this.doc, effect: { ...this.doc.effect, motion, controls: controls ?? this.doc.effect.controls } });\n return ok;\n }\n\n /** Called by a renderer binding with the result of compiling the current source. */\n reportCompile(report: CompileReport): void {\n this.compileReport = { ok: report.ok, errors: [...report.errors] };\n this.changed();\n }\n\n // ── Values ──────────────────────────────────────────────────────────\n\n /**\n * Sets a control's value. With a track on that control (or while\n * recording) it sets a keyframe at the playhead instead. Quick successive\n * changes to one control merge into one undo step.\n */\n setValue(name: string, value: unknown): EditResult {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n const check = checkControlValue(control, value);\n if (!check.ok) return fail(check.message);\n if (this.recording || this.doc.tracks[name]) return this.setKeyframe(name, this.time, check.value, undefined, `value:${name}`);\n this.commit(`Set ${control.label}`, { ...this.doc, values: { ...this.doc.values, [name]: check.value } }, `value:${name}`);\n return ok;\n }\n\n /** Sets several values in one undo step; refuses them all if any is wrong. */\n setValues(values: Record<string, unknown>): EditResult {\n const next = { ...this.doc.values };\n const tracks = { ...this.doc.tracks };\n for (const [name, value] of Object.entries(values)) {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n const check = checkControlValue(control, value);\n if (!check.ok) return fail(check.message);\n if (this.recording || tracks[name]) {\n const keyframes = [...(tracks[name]?.keyframes ?? []), { time: this.time, value: check.value }];\n tracks[name] = { ...tracks[name], keyframes: normalizeKeyframes(keyframes) };\n } else next[name] = check.value;\n }\n this.commit(\"Set values\", { ...this.doc, values: next, tracks });\n return ok;\n }\n\n /** Back to defaults: the named controls, or all of them (values only; tracks stay). */\n resetValues(names?: readonly string[]): EditResult {\n const unknown = names?.find((n) => !this.control(n));\n if (unknown) return this.unknownControl(unknown);\n const values = names ? Object.fromEntries(Object.entries(this.doc.values).filter(([k]) => !names.includes(k))) : {};\n this.commit(\"Reset values\", { ...this.doc, values });\n return ok;\n }\n\n /** Random values in each control's range (colours anywhere), for exploring. Images and text keep theirs. */\n randomize(names?: readonly string[], random: () => number = Math.random): EditResult {\n const values: Record<string, ControlValue> = {};\n for (const control of this.controls) {\n if (names ? !names.includes(control.name) : control.type === \"sampler2D\" || control.type === \"text\") continue;\n const pick = () => {\n const v = control.min + random() * (control.max - control.min);\n return control.type === \"int\" ? Math.round(v) : +v.toFixed(3);\n };\n if (control.type === \"bool\") values[control.name] = random() < 0.5;\n else if (control.type === \"sampler2D\" || control.type === \"text\") continue;\n else if (control.color) values[control.name] = Array.from({ length: control.type === \"vec4\" ? 4 : 3 }, () => +random().toFixed(3));\n else if (control.type === \"float\" || control.type === \"int\") values[control.name] = pick();\n else values[control.name] = Array.from({ length: Number(control.type.slice(3)) }, pick);\n }\n return this.setValues(values);\n }\n\n // ── Presets ─────────────────────────────────────────────────────────\n\n applyPreset(name: string): EditResult {\n const preset = this.doc.presets.find((p) => p.name === name);\n if (!preset) return fail(`There is no preset \"${name}\"; there are ${this.doc.presets.map((p) => `\"${p.name}\"`).join(\", \") || \"none\"}.`);\n this.commit(`Apply ${name}`, { ...this.doc, values: { ...this.doc.values, ...preset.values } });\n return ok;\n }\n\n /** Saves the current values (all, or the named ones) as a preset, replacing one of the same name. */\n savePreset(name: string, names?: readonly string[]): EditResult {\n if (!name.trim()) return fail(\"A preset needs a name.\");\n const all = valuesAt(this.doc, this.time, this.controls);\n const values = Object.fromEntries(Object.entries(all).filter(([k]) => (names ? names.includes(k) : true)));\n const presets = [...this.doc.presets.filter((p) => p.name !== name), { name: name.trim(), values }];\n this.commit(`Save preset ${name}`, { ...this.doc, presets });\n return ok;\n }\n\n deletePreset(name: string): EditResult {\n if (!this.doc.presets.some((p) => p.name === name)) return fail(`There is no preset \"${name}\".`);\n this.commit(`Delete preset ${name}`, { ...this.doc, presets: this.doc.presets.filter((p) => p.name !== name) });\n return ok;\n }\n\n // ── Keyframes ───────────────────────────────────────────────────────\n\n /** Sets (or replaces) a keyframe; `value` defaults to the control's value at that time. */\n setKeyframe(name: string, time: number, value?: unknown, easing?: Easing, mergeKey?: string): EditResult {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n if (!(time >= 0)) return fail(\"A keyframe's time is 0 ms or more.\");\n if (easing !== undefined && !isEasing(easing)) return fail(`Unknown easing ${JSON.stringify(easing)}.`);\n let v: ControlValue;\n if (value === undefined) v = valuesAt(this.doc, time, [control])[name]!;\n else {\n const check = checkControlValue(control, value);\n if (!check.ok) return fail(check.message);\n v = check.value;\n }\n const track = this.doc.tracks[name];\n const existing = track?.keyframes.find((k) => Math.abs(k.time - time) < 1e-3);\n const keyframe: Keyframe = { time, value: v, ...((easing ?? existing?.easing) !== undefined && { easing: easing ?? existing?.easing }) };\n const keyframes = normalizeKeyframes([...(track?.keyframes ?? []), keyframe]);\n this.commit(`Keyframe ${control.label}`, { ...this.doc, tracks: { ...this.doc.tracks, [name]: { ...track, keyframes } } }, mergeKey);\n return ok;\n }\n\n removeKeyframe(name: string, time: number): EditResult {\n const track = this.doc.tracks[name];\n const keyframes = track?.keyframes.filter((k) => Math.abs(k.time - time) >= 1e-3);\n if (!track || keyframes!.length === track.keyframes.length) return fail(`\"${name}\" has no keyframe at ${time} ms.`);\n const tracks = { ...this.doc.tracks };\n if (keyframes!.length) tracks[name] = { ...track, keyframes: keyframes! };\n else delete tracks[name];\n this.commit(\"Delete keyframe\", { ...this.doc, tracks });\n return ok;\n }\n\n setKeyframeEasing(name: string, time: number, easing: Easing): EditResult {\n if (!isEasing(easing)) return fail(`Unknown easing ${JSON.stringify(easing)}.`);\n const track = this.doc.tracks[name];\n if (!track?.keyframes.some((k) => Math.abs(k.time - time) < 1e-3)) return fail(`\"${name}\" has no keyframe at ${time} ms.`);\n const keyframes = track.keyframes.map((k) => (Math.abs(k.time - time) < 1e-3 ? { ...k, easing } : k));\n this.commit(\"Set easing\", { ...this.doc, tracks: { ...this.doc.tracks, [name]: { ...track, keyframes } } });\n return ok;\n }\n\n /** Removes a control's track; it keeps the value it had at the playhead. */\n clearTrack(name: string): EditResult {\n if (!this.doc.tracks[name]) return fail(`\"${name}\" has no keyframes.`);\n const control = this.control(name);\n const value = control ? evaluateTrack(this.doc.tracks[name], this.time, control) : undefined;\n const tracks = { ...this.doc.tracks };\n delete tracks[name];\n const values = value === undefined ? this.doc.values : { ...this.doc.values, [name]: value };\n this.commit(\"Clear keyframes\", { ...this.doc, tracks, values });\n return ok;\n }\n\n /**\n * Replaces a control's whole track (or removes it with `undefined`), one\n * undo step. Every keyframe is checked like `setKeyframe`; values may be\n * any form the control accepts (colours as \"#RRGGBB\" too).\n */\n setTrack(name: string, track: { keyframes: readonly { time: number; value: unknown; easing?: unknown }[]; enabled?: boolean } | undefined): EditResult {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n const tracks = { ...this.doc.tracks };\n if (!track || track.keyframes.length === 0) {\n if (!tracks[name]) return ok;\n delete tracks[name];\n this.commit(\"Clear keyframes\", { ...this.doc, tracks });\n return ok;\n }\n const keyframes: Keyframe[] = [];\n for (const k of track.keyframes) {\n if (!(k.time >= 0)) return fail(\"A keyframe's time is 0 ms or more.\");\n if (k.easing !== undefined && !isEasing(k.easing)) return fail(`Unknown easing ${JSON.stringify(k.easing)}.`);\n const check = checkControlValue(control, k.value);\n if (!check.ok) return fail(`At ${k.time} ms: ${check.message}`);\n keyframes.push({ time: k.time, value: check.value, ...(k.easing !== undefined && { easing: k.easing as Easing }) });\n }\n tracks[name] = { keyframes: normalizeKeyframes(keyframes), ...(track.enabled === false && { enabled: false }) };\n this.commit(`Keyframes ${control.label}`, { ...this.doc, tracks });\n return ok;\n }\n\n setTiming(timing: { duration?: number; loop?: boolean }): EditResult {\n if (timing.duration !== undefined && !(timing.duration > 0)) return fail(\"The duration must be above 0 ms.\");\n this.commit(\"Set timing\", { ...this.doc, duration: timing.duration ?? this.doc.duration, loop: timing.loop ?? this.doc.loop });\n return ok;\n }\n\n // ── Playhead ────────────────────────────────────────────────────────\n\n play(): void {\n if (this.playing || this.disposed) return;\n if (!this.doc.loop && this.time >= this.doc.duration) this.time = 0;\n this.playing = true;\n this.changed();\n void this.run();\n }\n\n pause(): void {\n if (!this.playing) return;\n this.playing = false;\n this.changed();\n }\n\n toggle(): void {\n if (this.playing) this.pause();\n else this.play();\n }\n\n /** Moves the playhead (clamped to the timeline). */\n seek(time: number): void {\n const t = Math.min(Math.max(0, time), this.doc.duration);\n if (t === this.time) return;\n this.time = t;\n this.changed();\n }\n\n stop(): void {\n this.playing = false;\n this.time = 0;\n this.changed();\n }\n\n /** While recording, changing a value keyframes it at the playhead. */\n setRecording(recording: boolean): void {\n if (recording === this.recording) return;\n this.recording = recording;\n this.changed();\n }\n\n undo(): boolean {\n return this.history.undo();\n }\n\n redo(): boolean {\n return this.history.redo();\n }\n\n dispose(): void {\n this.disposed = true;\n this.playing = false;\n this.unsubscribeHistory();\n this.listeners.clear();\n }\n\n // ── Internals ───────────────────────────────────────────────────────\n\n private async run(): Promise<void> {\n let last = this.clock.now();\n while (this.playing && !this.disposed) {\n await this.clock.frame();\n if (!this.playing || this.disposed) return;\n const now = this.clock.now();\n let next = this.time + (now - last);\n last = now;\n if (next >= this.doc.duration) {\n if (this.doc.loop) next %= this.doc.duration;\n else {\n this.time = this.doc.duration;\n this.playing = false;\n this.changed();\n return;\n }\n }\n this.time = next;\n this.changed();\n }\n }\n\n private analysis() {\n if (this.controlsCache?.doc !== this.doc) {\n this.controlsCache = { doc: this.doc, controls: documentControls(this.doc), issues: documentIssues(this.doc) };\n }\n return this.controlsCache;\n }\n\n private control(name: string): ControlDef | undefined {\n return this.controls.find((c) => c.name === name);\n }\n\n private unknownControl(name: string): EditResult {\n return fail(`There is no control \"${name}\"; the controls are ${this.controls.map((c) => c.name).join(\", \") || \"none\"}.`);\n }\n\n private commit(label: string, next: EffectDocument, mergeKey?: string): void {\n const before = this.doc;\n const command = HistoryManager.createSnapshotCommand<EffectDocument>({\n name: label,\n before,\n after: next,\n apply: (doc) => {\n this.doc = doc;\n if (this.time > doc.duration) this.time = doc.duration;\n this.changed();\n },\n tag: mergeKey,\n });\n if (mergeKey) this.history.executeMerged(command, { key: mergeKey, windowMs: this.mergeWindowMs });\n else this.history.execute(command);\n }\n\n private changed(): void {\n this.state = null;\n if (this.listeners.size === 0) return;\n const state = this.getState();\n for (const listener of [...this.listeners]) listener(state);\n }\n}\n\n/** A new {@link EffectEditor}. */\nexport function createEffectEditor(options: EffectEditorOptions = {}): EffectEditor {\n return new EffectEditor(options);\n}\n","/**\n * The effect editor's commands. Menus, shortcuts, a command palette and\n * agents (through `createCommandToolProvider`) all run these by id, so every\n * entry point shares the same checks and undo steps.\n */\n\nimport type { CommandSpec } from \"@pixerate/editor/commands\";\nimport { EFFECT_CATEGORIES } from \"../catalog/types.js\";\nimport { findEffects } from \"../catalog/index.js\";\nimport type { EditResult, EffectEditor } from \"./editor.js\";\nimport { EASING_PRESETS, type Easing } from \"./timeline.js\";\n\n/** Throws the refusal, so the command registry reports it as a failed command with its message. */\nfunction done(result: EditResult): { ok: true } {\n if (!result.ok) throw new Error(result.message);\n return result;\n}\n\nconst easingSchema = {\n description: `An easing preset (${EASING_PRESETS.join(\", \")}) or {\"type\":\"cubic-bezier\",\"x1\",\"y1\",\"x2\",\"y2\"} or {\"type\":\"spring\",\"stiffness\",\"damping\",\"mass\"}.`,\n} as const;\n\nconst valueSchema = {\n description:\n 'A control value: a number (float, int), true/false (bool), an array of numbers (vec2–vec4; colours 0–1), a \"#RRGGBB\" colour, an image URL (sampler2D), or a string (text).',\n} as const;\n\n/** A summary of the editor's state for agents: the document, controls, values at the playhead, issues and compile errors. */\nexport function describeEditor(editor: EffectEditor) {\n const state = editor.getState();\n const doc = state.document;\n return {\n name: doc.name,\n basedOn: doc.basedOn,\n kind: doc.effect.kind,\n ...(doc.effect.kind === \"shader\" ? { source: doc.effect.source } : { motion: doc.effect.motion, ...(doc.effect.controls && { vectorControls: doc.effect.controls }) }),\n controls: state.controls.map((c) => ({\n name: c.name,\n type: c.type,\n label: c.label,\n ...(c.color && { color: true }),\n ...(c.type !== \"bool\" && c.type !== \"sampler2D\" && c.type !== \"text\" && { min: c.min, max: c.max, step: c.step }),\n default: c.default,\n })),\n values: state.values,\n tracks: doc.tracks,\n presets: doc.presets.map((p) => p.name),\n timeline: { duration: doc.duration, loop: doc.loop, time: state.time, playing: state.playing, recording: state.recording },\n issues: state.issues,\n compile: state.compile,\n history: { canUndo: state.history.canUndo, canRedo: state.history.canRedo },\n };\n}\n\n/** The effect editor's commands (the registry adds `history.undo` / `history.redo`). */\nexport function effectCommands(): CommandSpec<EffectEditor>[] {\n return [\n {\n id: \"effect.describe\",\n label: \"Describe effect\",\n group: \"Effect\",\n description: \"The effect being edited: its source (or picture), controls, values at the playhead, keyframes, presets, timeline, issues and compile errors.\",\n readOnly: true,\n run: (editor) => describeEditor(editor),\n },\n {\n id: \"catalog.search\",\n label: \"Search effects\",\n group: \"Catalog\",\n description: \"Searches the built-in effect catalog. Load one with effect.load to start from it.\",\n readOnly: true,\n params: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Words to look for (all must match).\" },\n category: { type: \"string\", enum: EFFECT_CATEGORIES },\n kind: { type: \"string\", enum: [\"shader\", \"vector\"] },\n },\n additionalProperties: false,\n },\n run: (_, params: { text?: string; category?: (typeof EFFECT_CATEGORIES)[number]; kind?: \"shader\" | \"vector\" }) =>\n findEffects(params ?? {}).map((e) => ({ id: e.id, name: e.name, kind: e.kind, category: e.category, description: e.description, presets: e.presets?.map((p) => p.name) ?? [] })),\n },\n {\n id: \"effect.load\",\n label: \"Load effect\",\n group: \"Effect\",\n description: \"Starts over from a catalog effect (by id, optionally with one of its presets), or from a shader's source.\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"A catalog effect id (see catalog.search).\" },\n preset: { type: \"string\" },\n source: { type: \"string\", description: \"A shader source to start from instead of a catalog effect.\" },\n name: { type: \"string\" },\n },\n additionalProperties: false,\n },\n run: (editor, p: { id?: string; preset?: string; source?: string; name?: string }) =>\n done(p?.source !== undefined ? editor.load({ source: p.source, name: p.name }) : editor.load(p?.id, p?.preset)),\n },\n {\n id: \"effect.setSource\",\n label: \"Set shader source\",\n group: \"Effect\",\n description:\n \"Replaces the shader's GLSL ES 3.00 source (Shadertoy-style mainImage; controls are uniforms annotated `// @control`). Compile errors show up in effect.describe once the preview has compiled it.\",\n params: { type: \"object\", properties: { source: { type: \"string\" } }, required: [\"source\"], additionalProperties: false },\n run: (editor, p: { source: string }) => done(editor.setSource(p.source)),\n },\n {\n id: \"effect.rename\",\n label: \"Rename effect\",\n group: \"Effect\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.rename(p.name)),\n },\n {\n id: \"values.set\",\n label: \"Set values\",\n group: \"Values\",\n description: \"Sets control values by name, all or nothing. A keyframed control (or any, while recording) gets a keyframe at the playhead instead.\",\n params: {\n type: \"object\",\n properties: { values: { type: \"object\", additionalProperties: valueSchema, description: \"Control name → value.\" } },\n required: [\"values\"],\n additionalProperties: false,\n },\n run: (editor, p: { values: Record<string, unknown> }) => done(editor.setValues(p.values)),\n },\n {\n id: \"values.reset\",\n label: \"Reset values\",\n group: \"Values\",\n description: \"Puts controls back to their defaults: the named ones, or all.\",\n params: { type: \"object\", properties: { names: { type: \"array\", items: { type: \"string\" } } }, additionalProperties: false },\n run: (editor, p: { names?: string[] }) => done(editor.resetValues(p?.names)),\n },\n {\n id: \"values.randomize\",\n label: \"Randomize values\",\n group: \"Values\",\n keywords: [\"shuffle\", \"surprise\", \"explore\"],\n params: { type: \"object\", properties: { names: { type: \"array\", items: { type: \"string\" } } }, additionalProperties: false },\n run: (editor, p: { names?: string[] }) => done(editor.randomize(p?.names)),\n },\n {\n id: \"preset.apply\",\n label: \"Apply preset\",\n group: \"Presets\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.applyPreset(p.name)),\n },\n {\n id: \"preset.save\",\n label: \"Save preset\",\n group: \"Presets\",\n description: \"Saves the values at the playhead (all, or the named controls) as a preset.\",\n params: {\n type: \"object\",\n properties: { name: { type: \"string\" }, names: { type: \"array\", items: { type: \"string\" } } },\n required: [\"name\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; names?: string[] }) => done(editor.savePreset(p.name, p.names)),\n },\n {\n id: \"preset.delete\",\n label: \"Delete preset\",\n group: \"Presets\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.deletePreset(p.name)),\n },\n {\n id: \"keyframe.set\",\n label: \"Set keyframe\",\n group: \"Keyframes\",\n description: \"Keyframes a control at a time (ms). Without a value, keyframes its current value there. The easing shapes the segment leaving this keyframe.\",\n params: {\n type: \"object\",\n properties: { name: { type: \"string\" }, time: { type: \"number\", minimum: 0 }, value: valueSchema, easing: easingSchema },\n required: [\"name\", \"time\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; time: number; value?: unknown; easing?: Easing }) => done(editor.setKeyframe(p.name, p.time, p.value, p.easing)),\n },\n {\n id: \"keyframe.remove\",\n label: \"Delete keyframe\",\n group: \"Keyframes\",\n params: { type: \"object\", properties: { name: { type: \"string\" }, time: { type: \"number\" } }, required: [\"name\", \"time\"], additionalProperties: false },\n run: (editor, p: { name: string; time: number }) => done(editor.removeKeyframe(p.name, p.time)),\n },\n {\n id: \"keyframe.setEasing\",\n label: \"Set keyframe easing\",\n group: \"Keyframes\",\n params: {\n type: \"object\",\n properties: { name: { type: \"string\" }, time: { type: \"number\" }, easing: easingSchema },\n required: [\"name\", \"time\", \"easing\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; time: number; easing: Easing }) => done(editor.setKeyframeEasing(p.name, p.time, p.easing)),\n },\n {\n id: \"keyframe.setTrack\",\n label: \"Set keyframes\",\n group: \"Keyframes\",\n description: \"Replaces all of a control's keyframes at once (an empty list removes them). Times are ms; each easing shapes the segment leaving its keyframe.\",\n params: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n keyframes: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: { time: { type: \"number\", minimum: 0 }, value: valueSchema, easing: easingSchema },\n required: [\"time\", \"value\"],\n },\n },\n },\n required: [\"name\", \"keyframes\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; keyframes: { time: number; value: unknown; easing?: unknown }[] }) => done(editor.setTrack(p.name, { keyframes: p.keyframes })),\n },\n {\n id: \"keyframe.clear\",\n label: \"Clear keyframes\",\n group: \"Keyframes\",\n description: \"Removes a control's keyframes; it keeps the value it has at the playhead.\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.clearTrack(p.name)),\n },\n {\n id: \"timeline.setTiming\",\n label: \"Set timing\",\n group: \"Timeline\",\n params: {\n type: \"object\",\n properties: { duration: { type: \"number\", exclusiveMinimum: 0, description: \"Ms.\" }, loop: { type: \"boolean\" } },\n additionalProperties: false,\n },\n run: (editor, p: { duration?: number; loop?: boolean }) => done(editor.setTiming(p ?? {})),\n },\n {\n id: \"timeline.play\",\n label: \"Play\",\n group: \"Timeline\",\n run: (editor) => editor.play(),\n },\n {\n id: \"timeline.pause\",\n label: \"Pause\",\n group: \"Timeline\",\n run: (editor) => editor.pause(),\n },\n {\n id: \"timeline.toggle\",\n label: \"Play / pause\",\n group: \"Timeline\",\n shortcut: \"Space\",\n run: (editor) => editor.toggle(),\n },\n {\n id: \"timeline.seek\",\n label: \"Go to time\",\n group: \"Timeline\",\n params: { type: \"object\", properties: { time: { type: \"number\", minimum: 0, description: \"Ms.\" } }, required: [\"time\"], additionalProperties: false },\n run: (editor, p: { time: number }) => editor.seek(p.time),\n },\n {\n id: \"timeline.stop\",\n label: \"Stop\",\n group: \"Timeline\",\n run: (editor) => editor.stop(),\n },\n {\n id: \"timeline.toggleRecording\",\n label: \"Record keyframes\",\n group: \"Timeline\",\n description: \"While recording, changing a value keyframes it at the playhead.\",\n run: (editor) => editor.setRecording(!editor.getState().recording),\n },\n ];\n}\n","/**\n * Agents edit effects through the editor's commands. Flair ships the tools\n * and the instructions; the model, its credentials and the agent loop are\n * the host's. Serve the tools with `@pixerate/editor/tools`' `ToolRegistry`\n * (MCP `tools/list` and `tools/call`), or call them directly with `callTool`.\n */\n\nimport { createCommandToolProvider } from \"@pixerate/editor/commands\";\nimport {\n createToolRegistry,\n toToolResult,\n type AgentTool,\n type AgentToolProvider,\n type McpToolDefinition,\n type McpToolResult,\n type ToolRegistry,\n type ToolRegistryOptions,\n} from \"@pixerate/editor/tools\";\nimport { BUILTIN_UNIFORMS } from \"../shader/program.js\";\nimport type { EffectEditor } from \"./editor.js\";\n\nexport interface EffectToolProviderOptions {\n /** Provider id (default `flair-effect`). */\n id?: string;\n /** Prefix every tool name with `<namespace>__`. */\n namespace?: string;\n /**\n * Captures the preview as a data URL (PNG or JPEG), adding a `view_effect`\n * tool so the agent can look at what it made. With `ShaderRenderer`:\n * `() => renderer.capture({ type: \"image/png\" })`.\n */\n capture?: () => string | null | undefined | Promise<string | null | undefined>;\n /** Commands agents may not see or run. */\n exclude?: (id: string) => boolean;\n}\n\n/**\n * The effect editor as agent tools (MCP-shaped, for `@pixerate/editor`'s\n * `ToolRegistry` or any tool loop):\n *\n * - `list_commands`, `run_command`, `run_commands`: every editor command\n * (describe, search the catalog, load, set source, values, presets,\n * keyframes, timing, undo and redo).\n * - `view_effect`, when `capture` is given: an image of the preview.\n */\nexport function createEffectToolProvider(editor: EffectEditor, options: EffectToolProviderOptions = {}): AgentToolProvider {\n const base = createCommandToolProvider(editor.commands, {\n id: options.id ?? \"flair-effect\",\n namespace: options.namespace,\n exclude: options.exclude,\n });\n const extra: AgentTool[] = [];\n if (options.capture) {\n const capture = options.capture;\n extra.push({\n name: options.namespace ? `${options.namespace}__view_effect` : \"view_effect\",\n title: \"View effect\",\n description: \"An image of the effect's preview as it is drawn now, to check what your changes look like.\",\n inputSchema: { type: \"object\", properties: {}, additionalProperties: false },\n annotations: { readOnlyHint: true },\n handler: async () => {\n const url = await capture();\n const match = url ? /^data:([^;,]+);base64,(.*)$/.exec(url) : null;\n if (!match) return { content: [{ type: \"text\", text: \"Nothing to show yet: the preview has not drawn a frame.\" }], isError: true };\n return { content: [{ type: \"image\", data: match[2]!, mimeType: match[1]! }] };\n },\n });\n }\n const baseTools = () => (typeof base.tools === \"function\" ? base.tools() : base.tools);\n return { id: base.id, namespace: base.namespace, subscribe: base.subscribe, tools: () => [...baseTools(), ...extra] };\n}\n\n/**\n * A `ToolRegistry` (from `@pixerate/editor/tools`) serving the effect editor's\n * tools: `listTools()` and `callTool(name, args)` are MCP's `tools/list` and\n * `tools/call`, with arguments checked against each tool's schema. Register\n * more providers on it to give the agent other tools too.\n */\nexport function createEffectToolRegistry(\n editor: EffectEditor,\n options: EffectToolProviderOptions & { registry?: ToolRegistryOptions } = {},\n): ToolRegistry {\n const registry = createToolRegistry({ validateArguments: true, ...options.registry });\n registry.register(createEffectToolProvider(editor, options));\n return registry;\n}\n\n/** A provider's tool definitions without their handlers, to send to a model. */\nexport function toolDefinitions(provider: AgentToolProvider): McpToolDefinition[] {\n const tools = typeof provider.tools === \"function\" ? provider.tools() : provider.tools;\n return tools.map(({ handler: _handler, ...definition }) => definition);\n}\n\n/**\n * Runs one of a provider's tools by name without a registry: the handler's\n * result comes back as an MCP `tools/call` result, and a thrown error as an\n * `isError` result. (A `ToolRegistry` also checks the arguments first.)\n */\nexport async function callTool(provider: AgentToolProvider, name: string, args: Record<string, unknown> = {}): Promise<McpToolResult> {\n const tools = typeof provider.tools === \"function\" ? provider.tools() : provider.tools;\n const tool = tools.find((t) => t.name === name);\n if (!tool) return { content: [{ type: \"text\", text: `There is no tool \"${name}\".` }], isError: true };\n try {\n return toToolResult(await tool.handler(args, { name, providerId: provider.id }));\n } catch (e) {\n return { content: [{ type: \"text\", text: (e as Error).message }], isError: true };\n }\n}\n\n/** A system prompt for agents that author effects with these tools. Add your product's own guidance to it. */\nexport const EFFECT_AGENT_INSTRUCTIONS = `You design web visual effects in an effect editor. Work through its tools: \\`list_commands\\` shows every command with its parameters; \\`run_command\\` runs one; \\`run_commands\\` runs several in order.\n\nStart with \\`effect.describe\\` to see what is being edited. To start from something close, use \\`catalog.search\\` then \\`effect.load\\` (with a preset if one fits). Every change is one undo step; \\`history.undo\\` reverts a step.\n\nShader effects are GLSL ES 3.00 fragment shaders written Shadertoy-style:\n- Define \\`void mainImage(out vec4 fragColor, in vec2 fragCoord)\\`; the output is opaque unless the host renders with \\`alpha: true\\` (overlays), when \\`fragColor.a\\` is coverage.\n- Built-in uniforms (do not declare them): ${BUILTIN_UNIFORMS.map((u) => `\\`${u.type} ${u.name}\\` (${u.doc})`).join(\"; \")}.\n- Declare controls as uniforms with an annotation on the same line, e.g.\n uniform float uSpeed; // @control min=0 max=4 default=1 label=\"Speed\"\n uniform vec3 uTint; // @control color default=#77C16A label=\"Tint\"\n uniform bool uGrain; // @control default=true label=\"Film grain\"\n uniform sampler2D uPhoto; // @control filter=linear wrap=clamp label=\"Photo\"\n Types: float, int, bool, vec2, vec3, vec4, sampler2D. Every uniform you declare should be a control.\n- Write float literals with a decimal point (1.0, not 1); GLSL does not convert int to float implicitly. Use \\`texture()\\`, not \\`texture2D()\\`.\n- After \\`effect.setSource\\`, call \\`effect.describe\\` and read \\`compile\\`: fix any errors (their line numbers match your source) before going on.\n\nVector effects are animated SVG pictures that declare their controls in themselves, like shader uniforms: the first \\`{{name: type …}}\\` declares a control (types: float, int, bool, color, text; attributes as for \\`@control\\`, values with spaces in single quotes), and every \\`{{name}}\\` is replaced by its value, e.g.\n <!-- {{title: text default='Hello' label='Title'}} {{accent: color default=#6366F1}} --><text fill=\"{{accent}}\">{{title}}</text>\nChange their controls' values freely (a text control takes any words); edit the picture with care, keeping element ids that animations refer to.\n\nMake effects that loop smoothly and read well behind content: keep motion calm unless asked otherwise, keep contrast where text may sit, and expose the few controls a designer would actually want (colours, speed, scale, intensity) with sensible ranges. Use keyframes (\\`keyframe.set\\`, in ms) for changes over the timeline. When you can, look at the result with \\`view_effect\\` and refine it.`;\n","/**\n * Keeps a preview in step with an editor: the editor owns the playhead and\n * the values; the preview draws what it is told.\n */\n\nimport type { ControlValue } from \"../shader/controls.js\";\nimport type { CompileStatus } from \"../shader/renderer.js\";\nimport { svgView, type SvgView } from \"../vector/svg.js\";\nimport { motionAt } from \"./document.js\";\nimport type { EffectEditor, EffectEditorState } from \"./editor.js\";\n\n/** What {@link bindShaderRenderer} needs of a renderer (`ShaderRenderer` fits). */\nexport interface ShaderPreview {\n setSource(source: string): CompileStatus;\n setValues(values: Record<string, ControlValue> | undefined): void;\n /** Seconds. */\n seek(time: number): void;\n pause(): void;\n}\n\n/**\n * Drives a shader preview from the editor: the source (reporting compile\n * results back), the values at the playhead, and the time. The renderer is\n * paused so the editor's playhead is the only clock. Returns an unbind\n * function.\n */\nexport function bindShaderRenderer(editor: EffectEditor, renderer: ShaderPreview): () => void {\n let source: string | undefined;\n renderer.pause();\n const sync = (state: EffectEditorState) => {\n const effect = state.document.effect;\n if (effect.kind !== \"shader\") return;\n if (effect.source !== source) {\n source = effect.source;\n editor.reportCompile(renderer.setSource(source));\n }\n renderer.setValues(state.values);\n renderer.seek(state.time / 1000);\n };\n sync(editor.getState());\n return editor.subscribe(sync);\n}\n\n/**\n * Draws a vector effect into `container` from the editor: the picture with\n * the values at the playhead, at the playhead's time. Returns an unbind\n * function, which also removes the picture.\n */\nexport function bindSvgView(editor: EffectEditor, container: HTMLElement): () => void {\n let view: SvgView | undefined;\n let key: string | undefined;\n const sync = (state: EffectEditorState) => {\n const motion = motionAt(state.document, state.time);\n if (!motion) {\n view?.element.remove();\n view = undefined;\n key = undefined;\n return;\n }\n const next = JSON.stringify(motion);\n if (next !== key) {\n key = next;\n view?.element.remove();\n view = svgView(motion);\n container.appendChild(view.element);\n }\n view!.draw(state.time);\n };\n sync(editor.getState());\n const unsubscribe = editor.subscribe(sync);\n return () => {\n unsubscribe();\n view?.element.remove();\n };\n}\n","/**\n * An effect's controls as a `@pixerate/editor/parameters` schema, and a\n * parameters controller kept in step with an `EffectEditor`. With them, any\n * parameters UI (the ready-made React and Svelte panels, or your own) edits\n * an effect: values, image picks and keyframe diamonds go through the effect\n * editor, so its undo history and agent tools see every change.\n */\n\nimport {\n ParametersController,\n rgba01ToHex,\n type ParameterField,\n type ParameterImageOption,\n type ParameterKeyframes,\n type ParameterSchema,\n type ParameterTrack,\n type ParameterValue,\n type ParameterValues,\n} from \"@pixerate/editor/parameters\";\nimport type { ControlDef, ControlValue } from \"../shader/controls.js\";\nimport type { EffectEditor, EffectEditorState } from \"./editor.js\";\nimport type { Track } from \"./timeline.js\";\n\nexport interface EffectParameterOptions {\n /** Pictures image controls offer to pick from (any URL still works). */\n images?: readonly ParameterImageOption[];\n /** Schema title (default: none). */\n title?: string;\n}\n\n/** One control as a parameter field. */\nexport function parameterFieldFor(control: ControlDef, options: EffectParameterOptions = {}): ParameterField {\n const base = { id: control.name, label: control.label };\n switch (control.type) {\n case \"bool\":\n return { ...base, type: \"boolean\", default: control.default === true };\n case \"int\":\n return { ...base, type: \"int\", min: control.min, max: control.max, step: Math.max(1, Math.round(control.step)), default: Number(control.default) };\n case \"float\":\n return { ...base, type: \"number\", min: control.min, max: control.max, step: control.step, default: Number(control.default) };\n case \"sampler2D\":\n return { ...base, type: \"image\", default: String(control.default), ...(options.images && { options: options.images }) };\n case \"text\":\n return { ...base, type: \"text\", default: String(control.default) };\n default: {\n const value = control.default as number[];\n if (control.color) {\n const alpha = control.type === \"vec4\";\n return { ...base, type: \"color\", alpha, default: rgba01ToHex(value, alpha) };\n }\n return { ...base, type: \"vector\", size: value.length as 2 | 3 | 4, min: control.min, max: control.max, step: control.step, default: [...value] };\n }\n }\n}\n\n/** An effect's controls as a parameters schema. */\nexport function parameterSchemaFor(controls: readonly ControlDef[], options: EffectParameterOptions = {}): ParameterSchema {\n return { ...(options.title && { title: options.title }), fields: controls.map((c) => parameterFieldFor(c, options)) };\n}\n\n/** A control value as a parameter value: colours become `#rrggbb` (`#rrggbbaa` for `vec4`). */\nexport function toParameterValue(control: ControlDef, value: ControlValue): ParameterValue {\n if (control.color && Array.isArray(value)) return rgba01ToHex(value, control.type === \"vec4\");\n return Array.isArray(value) ? [...value] : value;\n}\n\n/** Control values as parameter values (see {@link toParameterValue}). */\nexport function toParameterValues(controls: readonly ControlDef[], values: Record<string, ControlValue>): ParameterValues {\n const out: ParameterValues = {};\n for (const control of controls) if (values[control.name] !== undefined) out[control.name] = toParameterValue(control, values[control.name]!);\n return out;\n}\n\nfunction toParameterTrack(control: ControlDef | undefined, track: Track | undefined): ParameterTrack | undefined {\n if (!track) return undefined;\n return {\n ...(track.enabled === false && { enabled: false }),\n keyframes: track.keyframes.map((k) => ({ ...k, value: control ? toParameterValue(control, k.value) : (k.value as ParameterValue) })),\n };\n}\n\nexport interface EffectParametersBinding {\n /** Drive a parameters UI with it (e.g. `<ParametersPanel controller={…} />`). */\n readonly controller: ParametersController;\n /** Stops following the editor. */\n dispose(): void;\n}\n\n/**\n * A `ParametersController` for the effect in `editor`, kept in step with it:\n * the schema follows the effect's controls (a recompiled shader updates it),\n * values and the playhead follow the editor, and changes made through the\n * controller (fields, keyframe diamonds, reset, randomize) are applied to the\n * editor, which records the undo steps. Use the editor's undo, not the\n * controller's, and its presets (the controller's own presets are not saved).\n */\nexport function bindEffectParameters(editor: EffectEditor, options: EffectParameterOptions = {}): EffectParametersBinding {\n let state = editor.getState();\n let controls = state.controls;\n let signature = JSON.stringify(controls);\n let syncing = false;\n const byName = () => new Map(controls.map((c) => [c.name, c]));\n\n const keyframes: ParameterKeyframes = {\n getTrack: (id) => toParameterTrack(byName().get(id), editor.getState().document.tracks[id]),\n setTrack: (id, track) => {\n editor.setTrack(id, track);\n },\n subscribe: (listener) => editor.subscribe(() => listener()),\n };\n\n const controller = new ParametersController({\n schema: parameterSchemaFor(controls, options),\n values: toParameterValues(controls, state.values),\n time: state.time,\n keyframes,\n onChange: (values, changed) => {\n if (syncing) return;\n const result =\n changed.length === 1\n ? editor.setValue(changed[0]!, values[changed[0]!])\n : editor.setValues(Object.fromEntries(changed.map((id) => [id, values[id]])));\n // A refused change (or one that keyframed instead): show what the editor holds.\n if (!result.ok) sync(editor.getState());\n },\n });\n\n const sync = (next: EffectEditorState) => {\n state = next;\n const nextSignature = JSON.stringify(next.controls);\n syncing = true;\n try {\n if (nextSignature !== signature) {\n signature = nextSignature;\n controls = next.controls;\n controller.setSchema(parameterSchemaFor(controls, options));\n }\n controller.setTime(next.time, toParameterValues(controls, next.values));\n } finally {\n syncing = false;\n }\n };\n\n const unsubscribe = editor.subscribe(sync);\n return {\n controller,\n dispose: () => {\n unsubscribe();\n controller.destroy();\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/editor/timeline.ts","../../src/editor/document.ts","../../src/editor/editor.ts","../../src/editor/commands.ts","../../src/editor/agent.ts","../../src/editor/bind.ts","../../src/editor/parameters.ts"],"sourcesContent":["/**\n * Keyframed control values. A track holds keyframes `{ time (ms), value,\n * easing }` for one control; the easing governs the segment leaving its\n * keyframe. Easing comes from `@pixerate/editor/animation`, and tracks keep\n * its `AnimationTrack` shape; Flair adds what control values need beyond\n * numbers and colours (vectors, booleans, images, ints).\n */\n\nimport {\n ANIMATION_EASING_PRESETS,\n cubicBezierAt as editorCubicBezierAt,\n evaluateEasing as evaluateAnimationEasing,\n isAnimationEasing,\n type AnimationEasing,\n type AnimationEasingPreset,\n type AnimationKeyframe,\n type AnimationTrack,\n type CubicBezierEasing,\n type SpringEasing,\n} from \"@pixerate/editor/animation\";\nimport type { ControlDef, ControlValue } from \"../shader/controls.js\";\nimport { interpolateOklab, type ColorRGB } from \"../shader/color.js\";\n\n/** Named easings (CSS keywords plus back and spring curves). */\nexport type EasingPreset = AnimationEasingPreset;\nexport type Easing = AnimationEasing;\nexport type { CubicBezierEasing, SpringEasing };\n\n/** Every easing preset, in picker order. */\nexport const EASING_PRESETS: readonly EasingPreset[] = ANIMATION_EASING_PRESETS;\n\n/** Eased progress at `u` (0–1) through a segment `durationMs` long (`@pixerate/editor`'s easing engine). */\nexport const evaluateEasing = evaluateAnimationEasing;\n\n/** CSS `cubic-bezier(x1, y1, x2, y2)` solved for y at progress x. */\nexport const cubicBezierAt = editorCubicBezierAt;\n\n/**\n * Whether `value` is an easing (a preset name, a cubic bezier or a spring),\n * with a spring's stiffness, damping and mass above 0 when given.\n */\nexport function isEasing(value: unknown): value is Easing {\n if (!isAnimationEasing(value)) return false;\n if (typeof value !== \"object\" || value.type !== \"spring\") return true;\n return [value.stiffness, value.damping, value.mass].every((v) => v === undefined || v > 0);\n}\n\n/** A keyframe of a control: like `AnimationKeyframe`, with any control value (vectors and booleans too). */\nexport interface Keyframe extends Omit<AnimationKeyframe, \"value\"> {\n value: ControlValue;\n}\n\n/** A control's keyframes: `AnimationTrack`'s shape, with control values. */\nexport interface Track extends Omit<AnimationTrack, \"keyframes\"> {\n /** Sorted by time, at most one per time. */\n keyframes: Keyframe[];\n}\n\n/**\n * A control value `t` of the way from `a` to `b`: numbers and vectors blend\n * (overshooting with back and spring easings), colours blend in Oklab, `int`s\n * round, and booleans and images switch halfway.\n */\nexport function interpolateControlValue(control: ControlDef | undefined, a: ControlValue, b: ControlValue, t: number): ControlValue {\n if (typeof a === \"number\" && typeof b === \"number\") {\n const v = a + (b - a) * t;\n return control?.type === \"int\" ? Math.round(v) : v;\n }\n if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {\n if (control?.color && a.length >= 3) {\n const rgb = interpolateOklab(a.slice(0, 3) as ColorRGB, b.slice(0, 3) as ColorRGB, t);\n const out = rgb.map((c) => Math.min(1, Math.max(0, c)));\n return a.length === 4 ? [...out, a[3]! + (b[3]! - a[3]!) * t] : out;\n }\n return a.map((v, i) => v + (b[i]! - v) * t);\n }\n return t < 0.5 ? a : b;\n}\n\n/** A track's value at `time` (ms), or undefined when it has no keyframes or is disabled. */\nexport function evaluateTrack(track: Track | undefined, time: number, control?: ControlDef): ControlValue | undefined {\n if (!track || track.enabled === false || track.keyframes.length === 0) return undefined;\n const keys = track.keyframes;\n if (time <= keys[0]!.time) return keys[0]!.value;\n const last = keys[keys.length - 1]!;\n if (time >= last.time) return last.value;\n let i = 0;\n while (i < keys.length - 2 && keys[i + 1]!.time <= time) i++;\n const from = keys[i]!;\n const to = keys[i + 1]!;\n const span = to.time - from.time;\n const u = span > 0 ? (time - from.time) / span : 1;\n return interpolateControlValue(control, from.value, to.value, evaluateEasing(from.easing, u, span));\n}\n\n/** Keyframes sorted by time, one per time (the later of two at the same time wins). */\nexport function normalizeKeyframes(keyframes: readonly Keyframe[]): Keyframe[] {\n const byTime = new Map<number, Keyframe>();\n for (const k of keyframes) byTime.set(Math.round(k.time * 1000) / 1000, { ...k, time: Math.round(k.time * 1000) / 1000 });\n return [...byTime.values()].sort((a, b) => a.time - b.time);\n}\n\n/** The keyframe times across tracks, sorted and without duplicates. */\nexport function keyframeTimes(tracks: Record<string, Track>): number[] {\n return [...new Set(Object.values(tracks).flatMap((t) => t.keyframes.map((k) => k.time)))].sort((a, b) => a - b);\n}\n","/**\n * The document an effect editor edits: an effect (a shader's source, or a\n * vector picture with its controls), the values picked for its controls,\n * keyframed tracks, presets and a timeline. Plain JSON, so it can be saved,\n * diffed, and written by an agent.\n */\n\nimport { getEffect, renderVectorEffect, vectorControlIssues, vectorEffectControls } from \"../catalog/index.js\";\nimport type { EffectDefinition, EffectPreset, VectorControl } from \"../catalog/types.js\";\nimport { checkControlValue, controlValue, parseControls, type ControlDef, type ControlValue } from \"../shader/controls.js\";\nimport { svgMotionIssues, type SvgMotion } from \"../vector/motion.js\";\nimport { evaluateTrack, isEasing, normalizeKeyframes, type Track } from \"./timeline.js\";\n\n/**\n * What is being edited: a fragment shader, or an animated SVG. Both declare\n * their controls in themselves (`// @control`, `{{name: type …}}`); a vector\n * effect's optional `controls` list is for pictures written before that.\n */\nexport type EffectSource =\n | { kind: \"shader\"; source: string }\n | { kind: \"vector\"; motion: SvgMotion; controls?: VectorControl[]; hold?: number };\n\nexport interface EffectDocument {\n /** Format version (1). */\n version: 1;\n name: string;\n /** The catalog effect it started from, if any. */\n basedOn?: string;\n effect: EffectSource;\n /** Picked control values; controls without one use their default. */\n values: Record<string, ControlValue>;\n /** Keyframed controls, by control name. A track overrides the control's value. */\n tracks: Record<string, Track>;\n /** Timeline length in ms. */\n duration: number;\n loop: boolean;\n presets: EffectPreset[];\n}\n\nconst DEFAULT_SHADER = `// A new effect: edit me.\nuniform vec3 uColorA; // @control color default=#6366F1 label=\"Colour A\"\nuniform vec3 uColorB; // @control color default=#EC4899 label=\"Colour B\"\nuniform float uSpeed; // @control min=0 max=4 default=1 label=\"Speed\"\n\nvoid mainImage(out vec4 fragColor, in vec2 fragCoord) {\n vec2 uv = fragCoord / iResolution.xy;\n float t = 0.5 + 0.5 * sin(uv.x * 3.0 + iTime * uSpeed);\n fragColor = vec4(mix(uColorA, uColorB, t), 1.0);\n}\n`;\n\n/** Ms of timeline a new document gets (the effect's loop when it has one). */\nconst DEFAULT_DURATION = 5000;\n\n/**\n * A new document: blank (a small starter shader), from a catalog effect (by\n * id or definition), or from a shader's source.\n */\nexport function createEffectDocument(from?: string | EffectDefinition | { source: string; name?: string }): EffectDocument {\n if (from === undefined) return blankDocument(\"Untitled effect\", DEFAULT_SHADER);\n if (typeof from === \"object\" && !(\"kind\" in from)) return blankDocument(from.name ?? \"Untitled effect\", from.source);\n const effect = typeof from === \"string\" ? getEffect(from) : from;\n if (!effect) throw new Error(`There is no effect \"${String(from)}\" in the catalog.`);\n return {\n version: 1,\n name: effect.name,\n basedOn: effect.id,\n effect:\n effect.kind === \"shader\"\n ? { kind: \"shader\", source: effect.source }\n : {\n kind: \"vector\",\n motion: structuredClone(effect.motion),\n ...(effect.controls && { controls: effect.controls.map((c) => ({ ...c })) }),\n hold: effect.hold,\n },\n values: {},\n tracks: {},\n duration: effect.kind === \"shader\" && effect.loop ? Math.round(effect.loop * 1000) : DEFAULT_DURATION,\n loop: true,\n presets: (effect.presets ?? []).map((p) => ({ name: p.name, values: { ...p.values } })),\n };\n}\n\nfunction blankDocument(name: string, source: string): EffectDocument {\n return { version: 1, name, effect: { kind: \"shader\", source }, values: {}, tracks: {}, duration: DEFAULT_DURATION, loop: true, presets: [] };\n}\n\n/** The document's controls. */\nexport function documentControls(doc: EffectDocument): ControlDef[] {\n if (doc.effect.kind === \"shader\") return parseControls(doc.effect.source);\n return vectorEffectControls(doc.effect);\n}\n\n/** Every control's value at `time` (ms): its track if it has one, else the picked value, else its default. */\nexport function valuesAt(doc: EffectDocument, time: number, controls = documentControls(doc)): Record<string, ControlValue> {\n const out: Record<string, ControlValue> = {};\n for (const control of controls) {\n const tracked = evaluateTrack(doc.tracks[control.name], time, control);\n out[control.name] = tracked ?? controlValue(control, doc.values);\n }\n return out;\n}\n\n/** A vector document's picture with the values at `time` filled in; undefined for shaders. */\nexport function motionAt(doc: EffectDocument, time: number): SvgMotion | undefined {\n if (doc.effect.kind !== \"vector\") return undefined;\n // Derived placeholders are code, so they come from the catalog effect the document started from.\n const base = doc.basedOn ? getEffect(doc.basedOn) : undefined;\n const derived = base?.kind === \"vector\" ? base.derived : undefined;\n return renderVectorEffect({ motion: doc.effect.motion, controls: doc.effect.controls, derived }, valuesAt(doc, time));\n}\n\n/**\n * Problems with a document, as sentences: unknown controls in values, tracks\n * or presets, values a control cannot take, bad keyframes, and (for vector\n * effects) problems with the picture. Shader compile errors come from the\n * GPU, not from here.\n */\nexport function documentIssues(doc: EffectDocument): string[] {\n const issues: string[] = [];\n if (!(doc.duration > 0)) issues.push(\"`duration` must be above 0 ms\");\n if (doc.effect.kind === \"shader\" && !/void\\s+mainImage\\s*\\(/.test(doc.effect.source))\n issues.push(\"the shader needs `void mainImage(out vec4 fragColor, in vec2 fragCoord)`\");\n const controls = new Map(documentControls(doc).map((c) => [c.name, c]));\n const check = (where: string, name: string, value: unknown) => {\n const control = controls.get(name);\n if (!control) return void issues.push(`${where}: there is no control \"${name}\"`);\n const result = checkControlValue(control, value);\n if (!result.ok) issues.push(`${where}: ${result.message}`);\n };\n for (const [name, value] of Object.entries(doc.values)) check(\"values\", name, value);\n for (const [name, track] of Object.entries(doc.tracks)) {\n track.keyframes.forEach((k, i) => {\n const where = `tracks.${name}[${i}]`;\n if (!(k.time >= 0)) issues.push(`${where}: \\`time\\` must be 0 or more`);\n if (k.easing !== undefined && !isEasing(k.easing)) issues.push(`${where}: unknown easing`);\n check(where, name, k.value);\n });\n }\n for (const preset of doc.presets) for (const [name, value] of Object.entries(preset.values)) check(`preset \"${preset.name}\"`, name, value);\n if (doc.effect.kind === \"vector\") {\n const motion = motionAt(doc, 0)!;\n issues.push(...vectorControlIssues(doc.effect.motion), ...svgMotionIssues(motion));\n if (/\\{\\{[^}]+\\}\\}/.test(JSON.stringify(motion))) issues.push(\"the picture has placeholders no control fills\");\n }\n return issues;\n}\n\n/** Reads a document from JSON (or a parsed object), checking its shape. */\nexport function parseEffectDocument(input: string | unknown): { ok: true; document: EffectDocument } | { ok: false; errors: string[] } {\n let raw: unknown = input;\n if (typeof input === \"string\") {\n try {\n raw = JSON.parse(input);\n } catch (e) {\n return { ok: false, errors: [`not JSON: ${(e as Error).message}`] };\n }\n }\n const errors: string[] = [];\n const o = (raw ?? {}) as Partial<EffectDocument> & Record<string, unknown>;\n if (o.version !== 1) errors.push(\"`version` must be 1\");\n if (typeof o.name !== \"string\") errors.push(\"`name` must be a string\");\n const effect = o.effect as Partial<EffectSource> | undefined;\n if (!effect || (effect.kind !== \"shader\" && effect.kind !== \"vector\")) errors.push('`effect.kind` must be \"shader\" or \"vector\"');\n else if (effect.kind === \"shader\" && typeof (effect as { source?: unknown }).source !== \"string\") errors.push(\"`effect.source` must be a string\");\n else if (effect.kind === \"vector\") {\n const v = effect as Partial<Extract<EffectSource, { kind: \"vector\" }>>;\n if (!v.motion || typeof v.motion.svg !== \"string\") errors.push(\"`effect.motion.svg` must be a string\");\n if (v.controls !== undefined && !Array.isArray(v.controls)) errors.push(\"`effect.controls` must be a list\");\n }\n const isRecord = (v: unknown) => !!v && typeof v === \"object\" && !Array.isArray(v);\n if (o.values !== undefined && !isRecord(o.values)) errors.push(\"`values` must be an object\");\n if (o.tracks !== undefined && !isRecord(o.tracks)) errors.push(\"`tracks` must be an object\");\n for (const [name, track] of Object.entries((isRecord(o.tracks) ? o.tracks : {}) as Record<string, Track>))\n if (!track || !Array.isArray(track.keyframes)) errors.push(`\\`tracks.${name}.keyframes\\` must be a list`);\n if (o.presets !== undefined && !Array.isArray(o.presets)) errors.push(\"`presets` must be a list\");\n if (errors.length) return { ok: false, errors };\n const tracks = Object.fromEntries(\n Object.entries((o.tracks ?? {}) as Record<string, Track>).map(([k, t]) => [k, { ...t, keyframes: normalizeKeyframes(t.keyframes) }]),\n );\n return {\n ok: true,\n document: {\n version: 1,\n name: o.name!,\n basedOn: typeof o.basedOn === \"string\" ? o.basedOn : undefined,\n effect: o.effect as EffectSource,\n values: (o.values ?? {}) as Record<string, ControlValue>,\n tracks,\n duration: typeof o.duration === \"number\" && o.duration > 0 ? o.duration : DEFAULT_DURATION,\n loop: o.loop !== false,\n presets: (o.presets ?? []) as EffectPreset[],\n },\n };\n}\n","/**\n * A UI-agnostic effect editor: the document, its undo history, a playhead,\n * and commands that menus, shortcuts, a palette and agents all run by id.\n * Bring your own UI (any framework, or none) and your own renderer binding\n * (see `bindShaderRenderer` and `bindSvgView`).\n */\n\nimport { createCommandRegistry, createHistoryCommands, type CommandRegistry } from \"@pixerate/editor/commands\";\nimport { createHistoryManager, HistoryManager, type HistoryState } from \"@pixerate/editor/history\";\nimport type { EffectDefinition } from \"../catalog/types.js\";\nimport type { CompileError } from \"../shader/program.js\";\nimport { checkControlValue, type ControlDef, type ControlValue } from \"../shader/controls.js\";\nimport { realClock, type Clock } from \"../time/clock.js\";\nimport type { SvgMotion } from \"../vector/motion.js\";\nimport { effectCommands } from \"./commands.js\";\nimport {\n createEffectDocument,\n documentControls,\n documentIssues,\n parseEffectDocument,\n valuesAt,\n type EffectDocument,\n} from \"./document.js\";\nimport { evaluateTrack, isEasing, normalizeKeyframes, type Easing, type Keyframe } from \"./timeline.js\";\n\n/** What an edit did: `ok`, or why it was refused (in a sentence an agent can act on). */\nexport type EditResult = { ok: true } | { ok: false; message: string };\n\n/** The result of compiling the shader, as reported by a renderer (see `reportCompile`). */\nexport interface CompileReport {\n ok: boolean;\n errors: CompileError[];\n}\n\nexport interface EffectEditorState {\n document: EffectDocument;\n controls: ControlDef[];\n /** Every control's value at the playhead. */\n values: Record<string, ControlValue>;\n /** Problems with the document (see `documentIssues`). */\n issues: string[];\n /** The latest compile report, or null before a renderer reported one (and for vector effects). */\n compile: CompileReport | null;\n /** Playhead, ms. */\n time: number;\n playing: boolean;\n /** Whether changing a value keyframes it at the playhead. */\n recording: boolean;\n history: HistoryState;\n}\n\nexport interface EffectEditorOptions {\n /** The document to edit, or what to start one from (see `createEffectDocument`). */\n document?: EffectDocument;\n from?: string | EffectDefinition | { source: string; name?: string };\n /** Undo history to record into (default: a new one, 100 steps deep). */\n history?: HistoryManager;\n /** Time source for playback (default: animation frames). */\n clock?: Clock;\n /** Ms within which value changes to one control merge into one undo step (default 400). */\n mergeWindowMs?: number;\n}\n\nconst ok: EditResult = { ok: true };\nconst fail = (message: string): EditResult => ({ ok: false, message });\n\n/**\n * Edits one effect. Every change to the document is an undo step (value\n * changes in quick succession, like a slider drag, merge into one), and\n * subscribers hear about every change to the state.\n */\nexport class EffectEditor {\n readonly history: HistoryManager;\n /** Every editing action, by id: for menus, shortcuts, a command palette and agents. */\n readonly commands: CommandRegistry<EffectEditor>;\n private doc: EffectDocument;\n private controlsCache: { doc: EffectDocument; controls: ControlDef[]; issues: string[] } | null = null;\n private compileReport: CompileReport | null = null;\n private time = 0;\n private playing = false;\n private recording = false;\n private readonly clock: Clock;\n private readonly mergeWindowMs: number;\n private readonly listeners = new Set<(state: EffectEditorState) => void>();\n private state: EffectEditorState | null = null;\n private readonly unsubscribeHistory: () => void;\n private disposed = false;\n\n constructor(options: EffectEditorOptions = {}) {\n this.doc = options.document ?? createEffectDocument(options.from);\n this.history = options.history ?? createHistoryManager({ maxDepth: 100 });\n this.clock = options.clock ?? realClock;\n this.mergeWindowMs = options.mergeWindowMs ?? 400;\n this.commands = createCommandRegistry<EffectEditor>({ context: this });\n this.commands.register([...createHistoryCommands(this.history), ...effectCommands()]);\n this.unsubscribeHistory = this.history.subscribe(() => this.changed());\n }\n\n // ── Reading ────────────────────────────────────────────────────────\n\n get document(): EffectDocument {\n return this.doc;\n }\n\n /** The current state; the same object until something changes (safe for `useSyncExternalStore`). */\n getState(): EffectEditorState {\n if (!this.state) {\n const { controls, issues } = this.analysis();\n this.state = {\n document: this.doc,\n controls,\n values: valuesAt(this.doc, this.time, controls),\n issues,\n compile: this.doc.effect.kind === \"shader\" ? this.compileReport : null,\n time: this.time,\n playing: this.playing,\n recording: this.recording,\n history: this.history.getState(),\n };\n }\n return this.state;\n }\n\n /** Calls `listener` with the new state after every change; returns an unsubscribe function. */\n subscribe(listener: (state: EffectEditorState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /** The document's controls. */\n get controls(): ControlDef[] {\n return this.analysis().controls;\n }\n\n /** The document as JSON. */\n toJSON(): EffectDocument {\n return this.doc;\n }\n\n // ── Whole documents ─────────────────────────────────────────────────\n\n /** Replaces the document (one undo step). */\n replaceDocument(next: EffectDocument, label = \"Replace effect\"): EditResult {\n const parsed = parseEffectDocument(next);\n if (!parsed.ok) return fail(parsed.errors.join(\"; \"));\n this.commit(label, parsed.document);\n return ok;\n }\n\n /** Starts over from a catalog effect, a shader source, or blank (one undo step). */\n load(from?: string | EffectDefinition | { source: string; name?: string }, preset?: string): EditResult {\n let next: EffectDocument;\n try {\n next = createEffectDocument(from);\n } catch (e) {\n return fail((e as Error).message);\n }\n if (preset) {\n const values = next.presets.find((p) => p.name === preset)?.values;\n if (!values) return fail(`\"${next.name}\" has no preset \"${preset}\"; it has ${next.presets.map((p) => `\"${p.name}\"`).join(\", \") || \"none\"}.`);\n next = { ...next, values: { ...values } };\n }\n this.compileReport = null;\n this.commit(`Load ${next.name}`, next);\n return ok;\n }\n\n rename(name: string): EditResult {\n if (!name.trim()) return fail(\"A name cannot be empty.\");\n this.commit(\"Rename\", { ...this.doc, name: name.trim() });\n return ok;\n }\n\n // ── The effect itself ───────────────────────────────────────────────\n\n /** Replaces a shader's source. Compile errors arrive later, from the renderer (see `reportCompile`). */\n setSource(source: string): EditResult {\n if (this.doc.effect.kind !== \"shader\") return fail(\"This is a vector effect; use setMotion.\");\n if (source === this.doc.effect.source) return ok;\n this.commit(\"Edit source\", { ...this.doc, effect: { kind: \"shader\", source } }, \"source\");\n return ok;\n }\n\n /** Replaces a vector effect's picture, whose `{{name: type …}}` placeholders declare its controls (and optionally a `controls` list). */\n setMotion(motion: SvgMotion, controls?: Extract<EffectDocument[\"effect\"], { kind: \"vector\" }>[\"controls\"]): EditResult {\n if (this.doc.effect.kind !== \"vector\") return fail(\"This is a shader effect; use setSource.\");\n this.commit(\"Edit picture\", { ...this.doc, effect: { ...this.doc.effect, motion, controls: controls ?? this.doc.effect.controls } });\n return ok;\n }\n\n /** Called by a renderer binding with the result of compiling the current source. */\n reportCompile(report: CompileReport): void {\n this.compileReport = { ok: report.ok, errors: [...report.errors] };\n this.changed();\n }\n\n // ── Values ──────────────────────────────────────────────────────────\n\n /**\n * Sets a control's value. With a track on that control (or while\n * recording) it sets a keyframe at the playhead instead. Quick successive\n * changes to one control merge into one undo step.\n */\n setValue(name: string, value: unknown): EditResult {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n const check = checkControlValue(control, value);\n if (!check.ok) return fail(check.message);\n if (this.recording || this.doc.tracks[name]) return this.setKeyframe(name, this.time, check.value, undefined, `value:${name}`);\n this.commit(`Set ${control.label}`, { ...this.doc, values: { ...this.doc.values, [name]: check.value } }, `value:${name}`);\n return ok;\n }\n\n /** Sets several values in one undo step; refuses them all if any is wrong. */\n setValues(values: Record<string, unknown>): EditResult {\n const next = { ...this.doc.values };\n const tracks = { ...this.doc.tracks };\n for (const [name, value] of Object.entries(values)) {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n const check = checkControlValue(control, value);\n if (!check.ok) return fail(check.message);\n if (this.recording || tracks[name]) {\n const keyframes = [...(tracks[name]?.keyframes ?? []), { time: this.time, value: check.value }];\n tracks[name] = { ...tracks[name], keyframes: normalizeKeyframes(keyframes) };\n } else next[name] = check.value;\n }\n this.commit(\"Set values\", { ...this.doc, values: next, tracks });\n return ok;\n }\n\n /** Back to defaults: the named controls, or all of them (values only; tracks stay). */\n resetValues(names?: readonly string[]): EditResult {\n const unknown = names?.find((n) => !this.control(n));\n if (unknown) return this.unknownControl(unknown);\n const values = names ? Object.fromEntries(Object.entries(this.doc.values).filter(([k]) => !names.includes(k))) : {};\n this.commit(\"Reset values\", { ...this.doc, values });\n return ok;\n }\n\n /** Random values in each control's range (colours anywhere), for exploring. Images and text keep theirs. */\n randomize(names?: readonly string[], random: () => number = Math.random): EditResult {\n const values: Record<string, ControlValue> = {};\n for (const control of this.controls) {\n if (names ? !names.includes(control.name) : control.type === \"sampler2D\" || control.type === \"text\") continue;\n const pick = () => {\n const v = control.min + random() * (control.max - control.min);\n return control.type === \"int\" ? Math.round(v) : +v.toFixed(3);\n };\n if (control.type === \"bool\") values[control.name] = random() < 0.5;\n else if (control.type === \"sampler2D\" || control.type === \"text\") continue;\n else if (control.color) values[control.name] = Array.from({ length: control.type === \"vec4\" ? 4 : 3 }, () => +random().toFixed(3));\n else if (control.type === \"float\" || control.type === \"int\") values[control.name] = pick();\n else values[control.name] = Array.from({ length: Number(control.type.slice(3)) }, pick);\n }\n return this.setValues(values);\n }\n\n // ── Presets ─────────────────────────────────────────────────────────\n\n applyPreset(name: string): EditResult {\n const preset = this.doc.presets.find((p) => p.name === name);\n if (!preset) return fail(`There is no preset \"${name}\"; there are ${this.doc.presets.map((p) => `\"${p.name}\"`).join(\", \") || \"none\"}.`);\n this.commit(`Apply ${name}`, { ...this.doc, values: { ...this.doc.values, ...preset.values } });\n return ok;\n }\n\n /** Saves the current values (all, or the named ones) as a preset, replacing one of the same name. */\n savePreset(name: string, names?: readonly string[]): EditResult {\n if (!name.trim()) return fail(\"A preset needs a name.\");\n const all = valuesAt(this.doc, this.time, this.controls);\n const values = Object.fromEntries(Object.entries(all).filter(([k]) => (names ? names.includes(k) : true)));\n const presets = [...this.doc.presets.filter((p) => p.name !== name), { name: name.trim(), values }];\n this.commit(`Save preset ${name}`, { ...this.doc, presets });\n return ok;\n }\n\n deletePreset(name: string): EditResult {\n if (!this.doc.presets.some((p) => p.name === name)) return fail(`There is no preset \"${name}\".`);\n this.commit(`Delete preset ${name}`, { ...this.doc, presets: this.doc.presets.filter((p) => p.name !== name) });\n return ok;\n }\n\n // ── Keyframes ───────────────────────────────────────────────────────\n\n /** Sets (or replaces) a keyframe; `value` defaults to the control's value at that time. */\n setKeyframe(name: string, time: number, value?: unknown, easing?: Easing, mergeKey?: string): EditResult {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n if (!(time >= 0)) return fail(\"A keyframe's time is 0 ms or more.\");\n if (easing !== undefined && !isEasing(easing)) return fail(`Unknown easing ${JSON.stringify(easing)}.`);\n let v: ControlValue;\n if (value === undefined) v = valuesAt(this.doc, time, [control])[name]!;\n else {\n const check = checkControlValue(control, value);\n if (!check.ok) return fail(check.message);\n v = check.value;\n }\n const track = this.doc.tracks[name];\n const existing = track?.keyframes.find((k) => Math.abs(k.time - time) < 1e-3);\n const keyframe: Keyframe = { time, value: v, ...((easing ?? existing?.easing) !== undefined && { easing: easing ?? existing?.easing }) };\n const keyframes = normalizeKeyframes([...(track?.keyframes ?? []), keyframe]);\n this.commit(`Keyframe ${control.label}`, { ...this.doc, tracks: { ...this.doc.tracks, [name]: { ...track, keyframes } } }, mergeKey);\n return ok;\n }\n\n removeKeyframe(name: string, time: number): EditResult {\n const track = this.doc.tracks[name];\n const keyframes = track?.keyframes.filter((k) => Math.abs(k.time - time) >= 1e-3);\n if (!track || keyframes!.length === track.keyframes.length) return fail(`\"${name}\" has no keyframe at ${time} ms.`);\n const tracks = { ...this.doc.tracks };\n if (keyframes!.length) tracks[name] = { ...track, keyframes: keyframes! };\n else delete tracks[name];\n this.commit(\"Delete keyframe\", { ...this.doc, tracks });\n return ok;\n }\n\n setKeyframeEasing(name: string, time: number, easing: Easing): EditResult {\n if (!isEasing(easing)) return fail(`Unknown easing ${JSON.stringify(easing)}.`);\n const track = this.doc.tracks[name];\n if (!track?.keyframes.some((k) => Math.abs(k.time - time) < 1e-3)) return fail(`\"${name}\" has no keyframe at ${time} ms.`);\n const keyframes = track.keyframes.map((k) => (Math.abs(k.time - time) < 1e-3 ? { ...k, easing } : k));\n this.commit(\"Set easing\", { ...this.doc, tracks: { ...this.doc.tracks, [name]: { ...track, keyframes } } });\n return ok;\n }\n\n /** Removes a control's track; it keeps the value it had at the playhead. */\n clearTrack(name: string): EditResult {\n if (!this.doc.tracks[name]) return fail(`\"${name}\" has no keyframes.`);\n const control = this.control(name);\n const value = control ? evaluateTrack(this.doc.tracks[name], this.time, control) : undefined;\n const tracks = { ...this.doc.tracks };\n delete tracks[name];\n const values = value === undefined ? this.doc.values : { ...this.doc.values, [name]: value };\n this.commit(\"Clear keyframes\", { ...this.doc, tracks, values });\n return ok;\n }\n\n /**\n * Replaces a control's whole track (or removes it with `undefined`), one\n * undo step. Every keyframe is checked like `setKeyframe`; values may be\n * any form the control accepts (colours as \"#RRGGBB\" too).\n */\n setTrack(name: string, track: { keyframes: readonly { time: number; value: unknown; easing?: unknown }[]; enabled?: boolean } | undefined): EditResult {\n const control = this.control(name);\n if (!control) return this.unknownControl(name);\n const tracks = { ...this.doc.tracks };\n if (!track || track.keyframes.length === 0) {\n if (!tracks[name]) return ok;\n delete tracks[name];\n this.commit(\"Clear keyframes\", { ...this.doc, tracks });\n return ok;\n }\n const keyframes: Keyframe[] = [];\n for (const k of track.keyframes) {\n if (!(k.time >= 0)) return fail(\"A keyframe's time is 0 ms or more.\");\n if (k.easing !== undefined && !isEasing(k.easing)) return fail(`Unknown easing ${JSON.stringify(k.easing)}.`);\n const check = checkControlValue(control, k.value);\n if (!check.ok) return fail(`At ${k.time} ms: ${check.message}`);\n keyframes.push({ time: k.time, value: check.value, ...(k.easing !== undefined && { easing: k.easing as Easing }) });\n }\n tracks[name] = { keyframes: normalizeKeyframes(keyframes), ...(track.enabled === false && { enabled: false }) };\n this.commit(`Keyframes ${control.label}`, { ...this.doc, tracks });\n return ok;\n }\n\n setTiming(timing: { duration?: number; loop?: boolean }): EditResult {\n if (timing.duration !== undefined && !(timing.duration > 0)) return fail(\"The duration must be above 0 ms.\");\n this.commit(\"Set timing\", { ...this.doc, duration: timing.duration ?? this.doc.duration, loop: timing.loop ?? this.doc.loop });\n return ok;\n }\n\n // ── Playhead ────────────────────────────────────────────────────────\n\n play(): void {\n if (this.playing || this.disposed) return;\n if (!this.doc.loop && this.time >= this.doc.duration) this.time = 0;\n this.playing = true;\n this.changed();\n void this.run();\n }\n\n pause(): void {\n if (!this.playing) return;\n this.playing = false;\n this.changed();\n }\n\n toggle(): void {\n if (this.playing) this.pause();\n else this.play();\n }\n\n /** Moves the playhead (clamped to the timeline). */\n seek(time: number): void {\n const t = Math.min(Math.max(0, time), this.doc.duration);\n if (t === this.time) return;\n this.time = t;\n this.changed();\n }\n\n stop(): void {\n this.playing = false;\n this.time = 0;\n this.changed();\n }\n\n /** While recording, changing a value keyframes it at the playhead. */\n setRecording(recording: boolean): void {\n if (recording === this.recording) return;\n this.recording = recording;\n this.changed();\n }\n\n undo(): boolean {\n return this.history.undo();\n }\n\n redo(): boolean {\n return this.history.redo();\n }\n\n dispose(): void {\n this.disposed = true;\n this.playing = false;\n this.unsubscribeHistory();\n this.listeners.clear();\n }\n\n // ── Internals ───────────────────────────────────────────────────────\n\n private async run(): Promise<void> {\n let last = this.clock.now();\n while (this.playing && !this.disposed) {\n await this.clock.frame();\n if (!this.playing || this.disposed) return;\n const now = this.clock.now();\n let next = this.time + (now - last);\n last = now;\n if (next >= this.doc.duration) {\n if (this.doc.loop) next %= this.doc.duration;\n else {\n this.time = this.doc.duration;\n this.playing = false;\n this.changed();\n return;\n }\n }\n this.time = next;\n this.changed();\n }\n }\n\n private analysis() {\n if (this.controlsCache?.doc !== this.doc) {\n this.controlsCache = { doc: this.doc, controls: documentControls(this.doc), issues: documentIssues(this.doc) };\n }\n return this.controlsCache;\n }\n\n private control(name: string): ControlDef | undefined {\n return this.controls.find((c) => c.name === name);\n }\n\n private unknownControl(name: string): EditResult {\n return fail(`There is no control \"${name}\"; the controls are ${this.controls.map((c) => c.name).join(\", \") || \"none\"}.`);\n }\n\n private commit(label: string, next: EffectDocument, mergeKey?: string): void {\n const before = this.doc;\n const command = HistoryManager.createSnapshotCommand<EffectDocument>({\n name: label,\n before,\n after: next,\n apply: (doc) => {\n this.doc = doc;\n if (this.time > doc.duration) this.time = doc.duration;\n this.changed();\n },\n tag: mergeKey,\n });\n if (mergeKey) this.history.executeMerged(command, { key: mergeKey, windowMs: this.mergeWindowMs });\n else this.history.execute(command);\n }\n\n private changed(): void {\n this.state = null;\n if (this.listeners.size === 0) return;\n const state = this.getState();\n for (const listener of [...this.listeners]) listener(state);\n }\n}\n\n/** A new {@link EffectEditor}. */\nexport function createEffectEditor(options: EffectEditorOptions = {}): EffectEditor {\n return new EffectEditor(options);\n}\n","/**\n * The effect editor's commands. Menus, shortcuts, a command palette and\n * agents (through `createCommandToolProvider`) all run these by id, so every\n * entry point shares the same checks and undo steps.\n */\n\nimport type { CommandSpec } from \"@pixerate/editor/commands\";\nimport { EFFECT_CATEGORIES } from \"../catalog/types.js\";\nimport { findEffects } from \"../catalog/index.js\";\nimport type { EditResult, EffectEditor } from \"./editor.js\";\nimport { EASING_PRESETS, type Easing } from \"./timeline.js\";\n\n/** Throws the refusal, so the command registry reports it as a failed command with its message. */\nfunction done(result: EditResult): { ok: true } {\n if (!result.ok) throw new Error(result.message);\n return result;\n}\n\nconst easingSchema = {\n description: `An easing preset (${EASING_PRESETS.join(\", \")}) or {\"type\":\"cubic-bezier\",\"x1\",\"y1\",\"x2\",\"y2\"} or {\"type\":\"spring\",\"stiffness\",\"damping\",\"mass\"}.`,\n} as const;\n\nconst valueSchema = {\n description:\n 'A control value: a number (float, int), true/false (bool), an array of numbers (vec2–vec4; colours 0–1), a \"#RRGGBB\" colour, an image URL (sampler2D), or a string (text).',\n} as const;\n\n/** A summary of the editor's state for agents: the document, controls, values at the playhead, issues and compile errors. */\nexport function describeEditor(editor: EffectEditor) {\n const state = editor.getState();\n const doc = state.document;\n return {\n name: doc.name,\n basedOn: doc.basedOn,\n kind: doc.effect.kind,\n ...(doc.effect.kind === \"shader\" ? { source: doc.effect.source } : { motion: doc.effect.motion, ...(doc.effect.controls && { vectorControls: doc.effect.controls }) }),\n controls: state.controls.map((c) => ({\n name: c.name,\n type: c.type,\n label: c.label,\n ...(c.color && { color: true }),\n ...(c.type !== \"bool\" && c.type !== \"sampler2D\" && c.type !== \"text\" && { min: c.min, max: c.max, step: c.step }),\n default: c.default,\n })),\n values: state.values,\n tracks: doc.tracks,\n presets: doc.presets.map((p) => p.name),\n timeline: { duration: doc.duration, loop: doc.loop, time: state.time, playing: state.playing, recording: state.recording },\n issues: state.issues,\n compile: state.compile,\n history: { canUndo: state.history.canUndo, canRedo: state.history.canRedo },\n };\n}\n\n/** The effect editor's commands (the registry adds `history.undo` / `history.redo`). */\nexport function effectCommands(): CommandSpec<EffectEditor>[] {\n return [\n {\n id: \"effect.describe\",\n label: \"Describe effect\",\n group: \"Effect\",\n description: \"The effect being edited: its source (or picture), controls, values at the playhead, keyframes, presets, timeline, issues and compile errors.\",\n readOnly: true,\n run: (editor) => describeEditor(editor),\n },\n {\n id: \"catalog.search\",\n label: \"Search effects\",\n group: \"Catalog\",\n description: \"Searches the built-in effect catalog. Load one with effect.load to start from it.\",\n readOnly: true,\n params: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Words to look for (all must match).\" },\n category: { type: \"string\", enum: EFFECT_CATEGORIES },\n kind: { type: \"string\", enum: [\"shader\", \"vector\"] },\n },\n additionalProperties: false,\n },\n run: (_, params: { text?: string; category?: (typeof EFFECT_CATEGORIES)[number]; kind?: \"shader\" | \"vector\" }) =>\n findEffects(params ?? {}).map((e) => ({ id: e.id, name: e.name, kind: e.kind, category: e.category, description: e.description, presets: e.presets?.map((p) => p.name) ?? [] })),\n },\n {\n id: \"effect.load\",\n label: \"Load effect\",\n group: \"Effect\",\n description: \"Starts over from a catalog effect (by id, optionally with one of its presets), or from a shader's source.\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"A catalog effect id (see catalog.search).\" },\n preset: { type: \"string\" },\n source: { type: \"string\", description: \"A shader source to start from instead of a catalog effect.\" },\n name: { type: \"string\" },\n },\n additionalProperties: false,\n },\n run: (editor, p: { id?: string; preset?: string; source?: string; name?: string }) =>\n done(p?.source !== undefined ? editor.load({ source: p.source, name: p.name }) : editor.load(p?.id, p?.preset)),\n },\n {\n id: \"effect.setSource\",\n label: \"Set shader source\",\n group: \"Effect\",\n description:\n \"Replaces the shader's GLSL ES 3.00 source (Shadertoy-style mainImage; controls are uniforms annotated `// @control`). Compile errors show up in effect.describe once the preview has compiled it.\",\n params: { type: \"object\", properties: { source: { type: \"string\" } }, required: [\"source\"], additionalProperties: false },\n run: (editor, p: { source: string }) => done(editor.setSource(p.source)),\n },\n {\n id: \"effect.rename\",\n label: \"Rename effect\",\n group: \"Effect\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.rename(p.name)),\n },\n {\n id: \"values.set\",\n label: \"Set values\",\n group: \"Values\",\n description: \"Sets control values by name, all or nothing. A keyframed control (or any, while recording) gets a keyframe at the playhead instead.\",\n params: {\n type: \"object\",\n properties: { values: { type: \"object\", additionalProperties: valueSchema, description: \"Control name → value.\" } },\n required: [\"values\"],\n additionalProperties: false,\n },\n run: (editor, p: { values: Record<string, unknown> }) => done(editor.setValues(p.values)),\n },\n {\n id: \"values.reset\",\n label: \"Reset values\",\n group: \"Values\",\n description: \"Puts controls back to their defaults: the named ones, or all.\",\n params: { type: \"object\", properties: { names: { type: \"array\", items: { type: \"string\" } } }, additionalProperties: false },\n run: (editor, p: { names?: string[] }) => done(editor.resetValues(p?.names)),\n },\n {\n id: \"values.randomize\",\n label: \"Randomize values\",\n group: \"Values\",\n keywords: [\"shuffle\", \"surprise\", \"explore\"],\n params: { type: \"object\", properties: { names: { type: \"array\", items: { type: \"string\" } } }, additionalProperties: false },\n run: (editor, p: { names?: string[] }) => done(editor.randomize(p?.names)),\n },\n {\n id: \"preset.apply\",\n label: \"Apply preset\",\n group: \"Presets\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.applyPreset(p.name)),\n },\n {\n id: \"preset.save\",\n label: \"Save preset\",\n group: \"Presets\",\n description: \"Saves the values at the playhead (all, or the named controls) as a preset.\",\n params: {\n type: \"object\",\n properties: { name: { type: \"string\" }, names: { type: \"array\", items: { type: \"string\" } } },\n required: [\"name\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; names?: string[] }) => done(editor.savePreset(p.name, p.names)),\n },\n {\n id: \"preset.delete\",\n label: \"Delete preset\",\n group: \"Presets\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.deletePreset(p.name)),\n },\n {\n id: \"keyframe.set\",\n label: \"Set keyframe\",\n group: \"Keyframes\",\n description: \"Keyframes a control at a time (ms). Without a value, keyframes its current value there. The easing shapes the segment leaving this keyframe.\",\n params: {\n type: \"object\",\n properties: { name: { type: \"string\" }, time: { type: \"number\", minimum: 0 }, value: valueSchema, easing: easingSchema },\n required: [\"name\", \"time\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; time: number; value?: unknown; easing?: Easing }) => done(editor.setKeyframe(p.name, p.time, p.value, p.easing)),\n },\n {\n id: \"keyframe.remove\",\n label: \"Delete keyframe\",\n group: \"Keyframes\",\n params: { type: \"object\", properties: { name: { type: \"string\" }, time: { type: \"number\" } }, required: [\"name\", \"time\"], additionalProperties: false },\n run: (editor, p: { name: string; time: number }) => done(editor.removeKeyframe(p.name, p.time)),\n },\n {\n id: \"keyframe.setEasing\",\n label: \"Set keyframe easing\",\n group: \"Keyframes\",\n params: {\n type: \"object\",\n properties: { name: { type: \"string\" }, time: { type: \"number\" }, easing: easingSchema },\n required: [\"name\", \"time\", \"easing\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; time: number; easing: Easing }) => done(editor.setKeyframeEasing(p.name, p.time, p.easing)),\n },\n {\n id: \"keyframe.setTrack\",\n label: \"Set keyframes\",\n group: \"Keyframes\",\n description: \"Replaces all of a control's keyframes at once (an empty list removes them). Times are ms; each easing shapes the segment leaving its keyframe.\",\n params: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n keyframes: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: { time: { type: \"number\", minimum: 0 }, value: valueSchema, easing: easingSchema },\n required: [\"time\", \"value\"],\n },\n },\n },\n required: [\"name\", \"keyframes\"],\n additionalProperties: false,\n },\n run: (editor, p: { name: string; keyframes: { time: number; value: unknown; easing?: unknown }[] }) => done(editor.setTrack(p.name, { keyframes: p.keyframes })),\n },\n {\n id: \"keyframe.clear\",\n label: \"Clear keyframes\",\n group: \"Keyframes\",\n description: \"Removes a control's keyframes; it keeps the value it has at the playhead.\",\n params: { type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"], additionalProperties: false },\n run: (editor, p: { name: string }) => done(editor.clearTrack(p.name)),\n },\n {\n id: \"timeline.setTiming\",\n label: \"Set timing\",\n group: \"Timeline\",\n params: {\n type: \"object\",\n properties: { duration: { type: \"number\", exclusiveMinimum: 0, description: \"Ms.\" }, loop: { type: \"boolean\" } },\n additionalProperties: false,\n },\n run: (editor, p: { duration?: number; loop?: boolean }) => done(editor.setTiming(p ?? {})),\n },\n {\n id: \"timeline.play\",\n label: \"Play\",\n group: \"Timeline\",\n run: (editor) => editor.play(),\n },\n {\n id: \"timeline.pause\",\n label: \"Pause\",\n group: \"Timeline\",\n run: (editor) => editor.pause(),\n },\n {\n id: \"timeline.toggle\",\n label: \"Play / pause\",\n group: \"Timeline\",\n shortcut: \"Space\",\n run: (editor) => editor.toggle(),\n },\n {\n id: \"timeline.seek\",\n label: \"Go to time\",\n group: \"Timeline\",\n params: { type: \"object\", properties: { time: { type: \"number\", minimum: 0, description: \"Ms.\" } }, required: [\"time\"], additionalProperties: false },\n run: (editor, p: { time: number }) => editor.seek(p.time),\n },\n {\n id: \"timeline.stop\",\n label: \"Stop\",\n group: \"Timeline\",\n run: (editor) => editor.stop(),\n },\n {\n id: \"timeline.toggleRecording\",\n label: \"Record keyframes\",\n group: \"Timeline\",\n description: \"While recording, changing a value keyframes it at the playhead.\",\n run: (editor) => editor.setRecording(!editor.getState().recording),\n },\n ];\n}\n","/**\n * Agents edit effects through the editor's commands. Flair ships the tools\n * and the instructions; the model, its credentials and the agent loop are\n * the host's. Serve the tools with `@pixerate/editor/tools`' `ToolRegistry`\n * (MCP `tools/list` and `tools/call`), or call them directly with `callTool`.\n */\n\nimport { createCommandToolProvider } from \"@pixerate/editor/commands\";\nimport {\n createToolRegistry,\n toToolResult,\n type AgentTool,\n type AgentToolProvider,\n type McpToolDefinition,\n type McpToolResult,\n type ToolRegistry,\n type ToolRegistryOptions,\n} from \"@pixerate/editor/tools\";\nimport { BUILTIN_UNIFORMS } from \"../shader/program.js\";\nimport type { EffectEditor } from \"./editor.js\";\n\nexport interface EffectToolProviderOptions {\n /** Provider id (default `flair-effect`). */\n id?: string;\n /** Prefix every tool name with `<namespace>__`. */\n namespace?: string;\n /**\n * Captures the preview as a data URL (PNG or JPEG), adding a `view_effect`\n * tool so the agent can look at what it made. With `ShaderRenderer`:\n * `() => renderer.capture({ type: \"image/png\" })`.\n */\n capture?: () => string | null | undefined | Promise<string | null | undefined>;\n /** Commands agents may not see or run. */\n exclude?: (id: string) => boolean;\n}\n\n/**\n * The effect editor as agent tools (MCP-shaped, for `@pixerate/editor`'s\n * `ToolRegistry` or any tool loop):\n *\n * - `list_commands`, `run_command`, `run_commands`: every editor command\n * (describe, search the catalog, load, set source, values, presets,\n * keyframes, timing, undo and redo).\n * - `view_effect`, when `capture` is given: an image of the preview.\n */\nexport function createEffectToolProvider(editor: EffectEditor, options: EffectToolProviderOptions = {}): AgentToolProvider {\n const base = createCommandToolProvider(editor.commands, {\n id: options.id ?? \"flair-effect\",\n namespace: options.namespace,\n exclude: options.exclude,\n });\n const extra: AgentTool[] = [];\n if (options.capture) {\n const capture = options.capture;\n extra.push({\n name: options.namespace ? `${options.namespace}__view_effect` : \"view_effect\",\n title: \"View effect\",\n description: \"An image of the effect's preview as it is drawn now, to check what your changes look like.\",\n inputSchema: { type: \"object\", properties: {}, additionalProperties: false },\n annotations: { readOnlyHint: true },\n handler: async () => {\n const url = await capture();\n const match = url ? /^data:([^;,]+);base64,(.*)$/.exec(url) : null;\n if (!match) return { content: [{ type: \"text\", text: \"Nothing to show yet: the preview has not drawn a frame.\" }], isError: true };\n return { content: [{ type: \"image\", data: match[2]!, mimeType: match[1]! }] };\n },\n });\n }\n const baseTools = () => (typeof base.tools === \"function\" ? base.tools() : base.tools);\n return { id: base.id, namespace: base.namespace, subscribe: base.subscribe, tools: () => [...baseTools(), ...extra] };\n}\n\n/**\n * A `ToolRegistry` (from `@pixerate/editor/tools`) serving the effect editor's\n * tools: `listTools()` and `callTool(name, args)` are MCP's `tools/list` and\n * `tools/call`, with arguments checked against each tool's schema. Register\n * more providers on it to give the agent other tools too.\n */\nexport function createEffectToolRegistry(\n editor: EffectEditor,\n options: EffectToolProviderOptions & { registry?: ToolRegistryOptions } = {},\n): ToolRegistry {\n const registry = createToolRegistry({ validateArguments: true, ...options.registry });\n registry.register(createEffectToolProvider(editor, options));\n return registry;\n}\n\n/** A provider's tool definitions without their handlers, to send to a model. */\nexport function toolDefinitions(provider: AgentToolProvider): McpToolDefinition[] {\n const tools = typeof provider.tools === \"function\" ? provider.tools() : provider.tools;\n return tools.map(({ handler: _handler, ...definition }) => definition);\n}\n\n/**\n * Runs one of a provider's tools by name without a registry: the handler's\n * result comes back as an MCP `tools/call` result, and a thrown error as an\n * `isError` result. (A `ToolRegistry` also checks the arguments first.)\n */\nexport async function callTool(provider: AgentToolProvider, name: string, args: Record<string, unknown> = {}): Promise<McpToolResult> {\n const tools = typeof provider.tools === \"function\" ? provider.tools() : provider.tools;\n const tool = tools.find((t) => t.name === name);\n if (!tool) return { content: [{ type: \"text\", text: `There is no tool \"${name}\".` }], isError: true };\n try {\n return toToolResult(await tool.handler(args, { name, providerId: provider.id }));\n } catch (e) {\n return { content: [{ type: \"text\", text: (e as Error).message }], isError: true };\n }\n}\n\n/** A system prompt for agents that author effects with these tools. Add your product's own guidance to it. */\nexport const EFFECT_AGENT_INSTRUCTIONS = `You design web visual effects in an effect editor. Work through its tools: \\`list_commands\\` shows every command with its parameters; \\`run_command\\` runs one; \\`run_commands\\` runs several in order.\n\nStart with \\`effect.describe\\` to see what is being edited. To start from something close, use \\`catalog.search\\` then \\`effect.load\\` (with a preset if one fits). Every change is one undo step; \\`history.undo\\` reverts a step.\n\nShader effects are GLSL ES 3.00 fragment shaders written Shadertoy-style:\n- Define \\`void mainImage(out vec4 fragColor, in vec2 fragCoord)\\`; the output is opaque unless the host renders with \\`alpha: true\\` (overlays), when \\`fragColor.a\\` is coverage.\n- Built-in uniforms (do not declare them): ${BUILTIN_UNIFORMS.map((u) => `\\`${u.type} ${u.name}${\"size\" in u ? `[${u.size}]` : \"\"}\\` (${u.doc})`).join(\"; \")}.\n- Declare controls as uniforms with an annotation on the same line, e.g.\n uniform float uSpeed; // @control min=0 max=4 default=1 label=\"Speed\"\n uniform vec3 uTint; // @control color default=#77C16A label=\"Tint\"\n uniform bool uGrain; // @control default=true label=\"Film grain\"\n uniform sampler2D uPhoto; // @control filter=linear wrap=clamp label=\"Photo\"\n Types: float, int, bool, vec2, vec3, vec4, sampler2D. Every uniform you declare should be a control.\n- Write float literals with a decimal point (1.0, not 1); GLSL does not convert int to float implicitly. Use \\`texture()\\`, not \\`texture2D()\\`.\n- After \\`effect.setSource\\`, call \\`effect.describe\\` and read \\`compile\\`: fix any errors (their line numbers match your source) before going on.\n\nVector effects are animated SVG pictures that declare their controls in themselves, like shader uniforms: the first \\`{{name: type …}}\\` declares a control (types: float, int, bool, color, text; attributes as for \\`@control\\`, values with spaces in single quotes), and every \\`{{name}}\\` is replaced by its value, e.g.\n <!-- {{title: text default='Hello' label='Title'}} {{accent: color default=#6366F1}} --><text fill=\"{{accent}}\">{{title}}</text>\nChange their controls' values freely (a text control takes any words); edit the picture with care, keeping element ids that animations refer to.\n\nMake effects that loop smoothly and read well behind content: keep motion calm unless asked otherwise, keep contrast where text may sit, and expose the few controls a designer would actually want (colours, speed, scale, intensity) with sensible ranges. Use keyframes (\\`keyframe.set\\`, in ms) for changes over the timeline. When you can, look at the result with \\`view_effect\\` and refine it.`;\n","/**\n * Keeps a preview in step with an editor: the editor owns the playhead and\n * the values; the preview draws what it is told.\n */\n\nimport type { ControlValue } from \"../shader/controls.js\";\nimport type { CompileStatus } from \"../shader/renderer.js\";\nimport { svgView, type SvgView } from \"../vector/svg.js\";\nimport { motionAt } from \"./document.js\";\nimport type { EffectEditor, EffectEditorState } from \"./editor.js\";\n\n/** What {@link bindShaderRenderer} needs of a renderer (`ShaderRenderer` fits). */\nexport interface ShaderPreview {\n setSource(source: string): CompileStatus;\n setValues(values: Record<string, ControlValue> | undefined): void;\n /** Seconds. */\n seek(time: number): void;\n pause(): void;\n}\n\n/**\n * Drives a shader preview from the editor: the source (reporting compile\n * results back), the values at the playhead, and the time. The renderer is\n * paused so the editor's playhead is the only clock. Returns an unbind\n * function.\n */\nexport function bindShaderRenderer(editor: EffectEditor, renderer: ShaderPreview): () => void {\n let source: string | undefined;\n renderer.pause();\n const sync = (state: EffectEditorState) => {\n const effect = state.document.effect;\n if (effect.kind !== \"shader\") return;\n if (effect.source !== source) {\n source = effect.source;\n editor.reportCompile(renderer.setSource(source));\n }\n renderer.setValues(state.values);\n renderer.seek(state.time / 1000);\n };\n sync(editor.getState());\n return editor.subscribe(sync);\n}\n\n/**\n * Draws a vector effect into `container` from the editor: the picture with\n * the values at the playhead, at the playhead's time. Returns an unbind\n * function, which also removes the picture.\n */\nexport function bindSvgView(editor: EffectEditor, container: HTMLElement): () => void {\n let view: SvgView | undefined;\n let key: string | undefined;\n const sync = (state: EffectEditorState) => {\n const motion = motionAt(state.document, state.time);\n if (!motion) {\n view?.element.remove();\n view = undefined;\n key = undefined;\n return;\n }\n const next = JSON.stringify(motion);\n if (next !== key) {\n key = next;\n view?.element.remove();\n view = svgView(motion);\n container.appendChild(view.element);\n }\n view!.draw(state.time);\n };\n sync(editor.getState());\n const unsubscribe = editor.subscribe(sync);\n return () => {\n unsubscribe();\n view?.element.remove();\n };\n}\n","/**\n * An effect's controls as a `@pixerate/editor/parameters` schema, and a\n * parameters controller kept in step with an `EffectEditor`. With them, any\n * parameters UI (the ready-made React and Svelte panels, or your own) edits\n * an effect: values, image picks and keyframe diamonds go through the effect\n * editor, so its undo history and agent tools see every change.\n */\n\nimport {\n ParametersController,\n rgba01ToHex,\n type ParameterField,\n type ParameterImageOption,\n type ParameterKeyframes,\n type ParameterSchema,\n type ParameterTrack,\n type ParameterValue,\n type ParameterValues,\n} from \"@pixerate/editor/parameters\";\nimport type { ControlDef, ControlValue } from \"../shader/controls.js\";\nimport type { EffectEditor, EffectEditorState } from \"./editor.js\";\nimport type { Track } from \"./timeline.js\";\n\nexport interface EffectParameterOptions {\n /** Pictures image controls offer to pick from (any URL still works). */\n images?: readonly ParameterImageOption[];\n /** Schema title (default: none). */\n title?: string;\n}\n\n/** One control as a parameter field. */\nexport function parameterFieldFor(control: ControlDef, options: EffectParameterOptions = {}): ParameterField {\n const base = { id: control.name, label: control.label };\n switch (control.type) {\n case \"bool\":\n return { ...base, type: \"boolean\", default: control.default === true };\n case \"int\":\n return { ...base, type: \"int\", min: control.min, max: control.max, step: Math.max(1, Math.round(control.step)), default: Number(control.default) };\n case \"float\":\n return { ...base, type: \"number\", min: control.min, max: control.max, step: control.step, default: Number(control.default) };\n case \"sampler2D\":\n return { ...base, type: \"image\", default: String(control.default), ...(options.images && { options: options.images }) };\n case \"text\":\n return { ...base, type: \"text\", default: String(control.default) };\n default: {\n const value = control.default as number[];\n if (control.color) {\n const alpha = control.type === \"vec4\";\n return { ...base, type: \"color\", alpha, default: rgba01ToHex(value, alpha) };\n }\n return { ...base, type: \"vector\", size: value.length as 2 | 3 | 4, min: control.min, max: control.max, step: control.step, default: [...value] };\n }\n }\n}\n\n/** An effect's controls as a parameters schema. */\nexport function parameterSchemaFor(controls: readonly ControlDef[], options: EffectParameterOptions = {}): ParameterSchema {\n return { ...(options.title && { title: options.title }), fields: controls.map((c) => parameterFieldFor(c, options)) };\n}\n\n/** A control value as a parameter value: colours become `#rrggbb` (`#rrggbbaa` for `vec4`). */\nexport function toParameterValue(control: ControlDef, value: ControlValue): ParameterValue {\n if (control.color && Array.isArray(value)) return rgba01ToHex(value, control.type === \"vec4\");\n return Array.isArray(value) ? [...value] : value;\n}\n\n/** Control values as parameter values (see {@link toParameterValue}). */\nexport function toParameterValues(controls: readonly ControlDef[], values: Record<string, ControlValue>): ParameterValues {\n const out: ParameterValues = {};\n for (const control of controls) if (values[control.name] !== undefined) out[control.name] = toParameterValue(control, values[control.name]!);\n return out;\n}\n\nfunction toParameterTrack(control: ControlDef | undefined, track: Track | undefined): ParameterTrack | undefined {\n if (!track) return undefined;\n return {\n ...(track.enabled === false && { enabled: false }),\n keyframes: track.keyframes.map((k) => ({ ...k, value: control ? toParameterValue(control, k.value) : (k.value as ParameterValue) })),\n };\n}\n\nexport interface EffectParametersBinding {\n /** Drive a parameters UI with it (e.g. `<ParametersPanel controller={…} />`). */\n readonly controller: ParametersController;\n /** Stops following the editor. */\n dispose(): void;\n}\n\n/**\n * A `ParametersController` for the effect in `editor`, kept in step with it:\n * the schema follows the effect's controls (a recompiled shader updates it),\n * values and the playhead follow the editor, and changes made through the\n * controller (fields, keyframe diamonds, reset, randomize) are applied to the\n * editor, which records the undo steps. Use the editor's undo, not the\n * controller's, and its presets (the controller's own presets are not saved).\n */\nexport function bindEffectParameters(editor: EffectEditor, options: EffectParameterOptions = {}): EffectParametersBinding {\n let state = editor.getState();\n let controls = state.controls;\n let signature = JSON.stringify(controls);\n let syncing = false;\n const byName = () => new Map(controls.map((c) => [c.name, c]));\n\n const keyframes: ParameterKeyframes = {\n getTrack: (id) => toParameterTrack(byName().get(id), editor.getState().document.tracks[id]),\n setTrack: (id, track) => {\n editor.setTrack(id, track);\n },\n subscribe: (listener) => editor.subscribe(() => listener()),\n };\n\n const controller = new ParametersController({\n schema: parameterSchemaFor(controls, options),\n values: toParameterValues(controls, state.values),\n time: state.time,\n keyframes,\n onChange: (values, changed) => {\n if (syncing) return;\n const result =\n changed.length === 1\n ? editor.setValue(changed[0]!, values[changed[0]!])\n : editor.setValues(Object.fromEntries(changed.map((id) => [id, values[id]])));\n // A refused change (or one that keyframed instead): show what the editor holds.\n if (!result.ok) sync(editor.getState());\n },\n });\n\n const sync = (next: EffectEditorState) => {\n state = next;\n const nextSignature = JSON.stringify(next.controls);\n syncing = true;\n try {\n if (nextSignature !== signature) {\n signature = nextSignature;\n controls = next.controls;\n controller.setSchema(parameterSchemaFor(controls, options));\n }\n controller.setTime(next.time, toParameterValues(controls, next.values));\n } finally {\n syncing = false;\n }\n };\n\n const unsubscribe = editor.subscribe(sync);\n return {\n controller,\n dispose: () => {\n unsubscribe();\n controller.destroy();\n },\n };\n}\n"],"mappings":"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","names":[]}
|