@cutcraft/kit 0.0.0-stage → 0.2.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.
@@ -0,0 +1,1305 @@
1
+ import { ZodObject, z } from "zod";
2
+ /**
3
+ * What the ingest service knows about an asset. The model never sees pixels;
4
+ * it edits against this, and the resolver turns `word:`/`shot:` references
5
+ * into seconds with it.
6
+ */
7
+ interface AssetManifest {
8
+ readonly assets: Readonly<Record<string, AssetEntry>>;
9
+ }
10
+ interface AssetEntry {
11
+ readonly id: string;
12
+ readonly kind: "video" | "audio" | "image";
13
+ /** Seconds. Images report 0 and may be held for any duration. */
14
+ readonly duration: number;
15
+ readonly fps?: number;
16
+ readonly width?: number;
17
+ readonly height?: number;
18
+ readonly audio?: {
19
+ readonly sampleRate: number;
20
+ readonly channels: number;
21
+ readonly streams: number;
22
+ };
23
+ readonly transcript?: {
24
+ readonly words: readonly TranscriptWord[];
25
+ };
26
+ readonly shots?: readonly Shot[];
27
+ readonly silences?: readonly Silence[];
28
+ readonly waveform?: WaveformSummary;
29
+ /** Where the subject (a face, a person) sits in the picture, sampled over time; several boxes may share a `t`. */
30
+ readonly subjects?: readonly SubjectBox[];
31
+ }
32
+ /** A subject's box at source second `t`, as fractions of the source picture (0..1 from its top left). */
33
+ interface SubjectBox {
34
+ readonly t: number;
35
+ readonly x: number;
36
+ readonly y: number;
37
+ readonly w: number;
38
+ readonly h: number;
39
+ }
40
+ interface TranscriptWord {
41
+ readonly i: number;
42
+ readonly text: string;
43
+ readonly start: number;
44
+ readonly end: number;
45
+ readonly speaker?: string;
46
+ /**
47
+ * The times are shared out from a longer span (an SRT or VTT cue, a segment without word times), not measured per
48
+ * word: a cut on this word lands near it, not exactly on it.
49
+ */
50
+ readonly estimated?: boolean;
51
+ }
52
+ interface Shot {
53
+ readonly i: number;
54
+ readonly start: number;
55
+ readonly end: number;
56
+ }
57
+ interface Silence {
58
+ readonly i: number;
59
+ readonly start: number;
60
+ readonly end: number;
61
+ }
62
+ interface WaveformSummary {
63
+ readonly binSeconds: number;
64
+ readonly peaks: readonly number[];
65
+ readonly rms: readonly number[];
66
+ }
67
+ declare const EMPTY_MANIFEST: AssetManifest;
68
+ declare function assetIdOf(ref: string): string;
69
+ declare function lookupAsset(manifest: AssetManifest, ref: string): AssetEntry | null;
70
+ interface ShaderDefinition {
71
+ readonly kind: "effect" | "transition";
72
+ readonly name: string;
73
+ /** The params `<Effect params>` or `<Transition params>` takes, validated and given defaults by this schema. */
74
+ readonly params: ZodObject;
75
+ /**
76
+ * GLSL ES 3.00 that defines `vec4 effect(vec2 uv)` (an effect) or `vec4 transition(vec2 uv)` (a transition). It may
77
+ * read `image` (an effect's picture) or `from` and `to` (a transition's two pictures) as `sampler2D`, `resolution`
78
+ * (vec2, pixels), `time` (seconds into the element), `progress` (0..1 through a transition), and each param by its
79
+ * name: a number as a float, a boolean as a bool, an array of 2 to 4 numbers as a vec, a colour string as a vec3.
80
+ */
81
+ readonly shader: string;
82
+ }
83
+ /** The shaders a module loaded by `loadModule` declared, stored on its exports under this key. */
84
+ declare const MODULE_SHADERS: unique symbol;
85
+ interface DefineOptions {
86
+ readonly name: string;
87
+ readonly params?: ZodObject;
88
+ readonly shader: string;
89
+ }
90
+ /**
91
+ * Declares an effect drawn by a GLSL function, and returns its name for `<Effect type>`. Call it at the top of the file.
92
+ *
93
+ * const glitch = defineEffect({
94
+ * name: "glitch",
95
+ * params: z.object({ amount: z.number().min(0).max(1).default(0.3) }),
96
+ * shader: `vec4 effect(vec2 uv) {
97
+ * float shift = amount * 0.02 * sin(time * 40.0 + uv.y * 80.0);
98
+ * return vec4(texture(image, uv + vec2(shift, 0)).r, texture(image, uv).g, texture(image, uv - vec2(shift, 0)).b,
99
+ * texture(image, uv).a);
100
+ * }`,
101
+ * });
102
+ * <Clip id="city" src="asset:city"><Effect id="g" type={glitch} params={{ amount: 0.5 }} /></Clip>
103
+ */
104
+ declare function defineEffect(options: DefineOptions): string;
105
+ /**
106
+ * Declares a transition drawn by a GLSL function of the two pictures, and returns its name for `<Transition type>`.
107
+ *
108
+ * const sweep = defineTransition({
109
+ * name: "sweep",
110
+ * shader: `vec4 transition(vec2 uv) { return uv.x < progress ? texture(to, uv) : texture(from, uv); }`,
111
+ * });
112
+ */
113
+ declare function defineTransition(options: DefineOptions): string;
114
+ /** Runs `load` and returns the shaders declared while it ran: how `loadModule` keeps each file's apart. */
115
+ declare function collectShaders(load: () => void): ShaderDefinition[];
116
+ /** The shaders a module declared: those `loadModule` recorded for it, or else every one declared outside a load. */
117
+ declare function shadersOf(mod: object): readonly ShaderDefinition[];
118
+ /** The shader a file declares under this name for an `<Effect>` or `<Transition>`, if any. */
119
+ declare function shaderFor(shaders: readonly ShaderDefinition[], kind: ShaderDefinition["kind"], type: unknown): ShaderDefinition | undefined;
120
+ /** Whether a file draws anything with a shader it declares: what only a renderer with WebGL draws. */
121
+ declare function usesShaders(state: {
122
+ readonly shaders: readonly ShaderDefinition[];
123
+ readonly items: ReadonlyMap<string, {
124
+ readonly kind: string;
125
+ readonly props: Readonly<Record<string, unknown>>;
126
+ }>;
127
+ }): boolean;
128
+ /**
129
+ * The font families the player ships: the preview and the export load them
130
+ * from `@cutcraft/player/fonts.css`. All are under the SIL
131
+ * Open Font License, from the `@fontsource` packages named here. Each comes in
132
+ * regular and bold, and italic where the family has one.
133
+ */
134
+ interface BundledFont {
135
+ readonly family: string;
136
+ /** The `@fontsource` package, and the file prefix inside its `files/` directory. */
137
+ readonly id: string;
138
+ readonly italic: boolean;
139
+ }
140
+ declare const BUNDLED_FONTS: readonly BundledFont[];
141
+ declare const BUNDLED_FONT_WEIGHTS: readonly [400, 700];
142
+ declare function isBundledFont(family: string): boolean;
143
+ type FontStyle = "normal" | "italic";
144
+ /** Where a declared face's file comes from. */
145
+ type FontSource =
146
+ /** A file found the way an asset is: `<id>.ttf` (`.otf`, `.woff`, `.woff2`) in the media folder, or the player's `media`. */
147
+ {
148
+ readonly kind: "asset";
149
+ readonly id: string;
150
+ } |
151
+ /** Google Fonts: the export downloads it once into a local cache; the player loads it from Google. */
152
+ {
153
+ readonly kind: "google";
154
+ };
155
+ /** One face a file declares with `font()` or `googleFont()`. */
156
+ interface DeclaredFont {
157
+ readonly family: string;
158
+ readonly weight: number;
159
+ readonly style: FontStyle;
160
+ readonly source: FontSource;
161
+ }
162
+ /** The faces a module loaded by `loadModule` declared, stored on its exports under this key. */
163
+ declare const MODULE_FONTS: unique symbol;
164
+ /**
165
+ * Declares a face from a font file and returns its family, to pass as a `font` prop, a theme font or a CSS
166
+ * `fontFamily`. Call it at the top of the file with literal arguments, as the editor and lint read them from the source.
167
+ *
168
+ * const brand = font({ family: "Brand Sans", src: "asset:brand", weight: 700 });
169
+ * <Title id="hello" font={brand}>Hello</Title>
170
+ *
171
+ * `src: "asset:brand"` finds `brand.ttf` (or `.otf`, `.woff`, `.woff2`) where the export finds media, and asks the
172
+ * player's `media` for `brand`.
173
+ */
174
+ declare function font(options: {
175
+ readonly family: string;
176
+ readonly src: string;
177
+ readonly weight?: number;
178
+ readonly style?: FontStyle;
179
+ }): string;
180
+ /**
181
+ * Declares a Google Fonts family, in each weight and style given (default 400, normal), and returns the family. The
182
+ * export downloads the files once into `~/.cache/cutcraft/fonts` (`CUTCRAFT_FONT_CACHE` moves it) and reads them from
183
+ * there; the player loads them from Google.
184
+ *
185
+ * const titan = googleFont("Titan One");
186
+ * const inter = googleFont("Inter Tight", { weights: [400, 700], styles: ["normal", "italic"] });
187
+ */
188
+ declare function googleFont(family: string, options?: {
189
+ readonly weights?: readonly number[];
190
+ readonly styles?: readonly FontStyle[];
191
+ }): string;
192
+ /** Runs `load` and returns the faces declared while it ran: how `loadModule` keeps each file's faces apart. */
193
+ declare function collectFonts(load: () => void): DeclaredFont[];
194
+ /** The faces a module declared: those `loadModule` recorded for it, or else every face declared outside a load. */
195
+ declare function fontsOf(mod: object): readonly DeclaredFont[];
196
+ type ResolveErrorCode = "DANGLING_ANCHOR" |
197
+ /** `at` names a moment the anchor does not play: trimmed out, or the anchor is not footage. */
198
+ "INVALID_ANCHOR" |
199
+ /** `at` on an anchor the first version cannot map: reversed, or with speed keys or freezes. */
200
+ "UNSUPPORTED_ANCHOR" | "CYCLE" | "TRIM_PAST_SOURCE" | "UNKNOWN_REF" | "NOT_ADJACENT" | "INSUFFICIENT_HANDLES" | "NO_VISUAL_PARENT" | "DUPLICATE_ID" | "MISSING_ASSET" | "START_ON_SEQUENCE" | "MISSING_START" | "AMBIGUOUS_DURATION" | "INVALID_CHILD" | "INVALID_TIME_RANGE" | "UNKNOWN_TOKEN" | "UNKNOWN_STYLE" | "SCHEMA";
201
+ interface ResolveError {
202
+ readonly code: ResolveErrorCode;
203
+ readonly id: string;
204
+ readonly prop?: string;
205
+ readonly message: string;
206
+ }
207
+ declare function isResolveError(value: unknown): value is ResolveError;
208
+ type Editable = "literal" | "generated" | "opaque";
209
+ /** Prop keys under this prefix address a Layer's handles rather than the Layer's own props. */
210
+ declare const INTERIOR_PREFIX = "interior.";
211
+ /**
212
+ * One vocabulary element as collected from the React element tree, before
213
+ * schema parsing and before placement. `props` are the raw JSX props minus
214
+ * `children`.
215
+ */
216
+ interface CollectedNode {
217
+ readonly id: string;
218
+ readonly kind: string;
219
+ readonly props: Readonly<Record<string, unknown>>;
220
+ readonly children: readonly CollectedNode[];
221
+ /** Text content for elements whose children are text (Title). */
222
+ readonly text?: string;
223
+ readonly parent: string | null;
224
+ readonly editable: Editable;
225
+ /** Props whose source value is an expression the editor cannot write (known only when a SourceIndex was supplied). */
226
+ readonly lockedProps: readonly string[];
227
+ /** Prop → `schema` key for props that read the file's props; a write to one rewrites `defaults`. */
228
+ readonly boundProps: Readonly<Record<string, string>>;
229
+ /** For helper output: which helper produced the node, under which parent, and the helper's nth use in the file. */
230
+ readonly origin?: {
231
+ readonly helper: string;
232
+ readonly callerId: string | null;
233
+ readonly callIndex: number;
234
+ };
235
+ /** A Layer's handles: the one component inside it and its props. The component's body stays opaque. */
236
+ readonly interior?: LayerInterior;
237
+ }
238
+ interface LayerInterior {
239
+ readonly component: string;
240
+ readonly props: Readonly<Record<string, unknown>>;
241
+ }
242
+ interface CollectedTree {
243
+ readonly root: CollectedNode;
244
+ readonly byId: ReadonlyMap<string, CollectedNode>;
245
+ readonly errors: readonly ResolveError[];
246
+ /** The faces the file declares (`font()`, `googleFont()`); set by `collectModule`. */
247
+ readonly fonts?: readonly DeclaredFont[];
248
+ /** The effects and transitions the file declares (`defineEffect()`, `defineTransition()`); set by `collectModule`. */
249
+ readonly shaders?: readonly ShaderDefinition[];
250
+ }
251
+ declare function walk(node: CollectedNode, visit: (node: CollectedNode, depth: number) => void, depth?: number): void;
252
+ declare function findParentOf(tree: CollectedTree, id: string): CollectedNode | null;
253
+ type Json = null | boolean | number | string | Json[] | {
254
+ [key: string]: Json;
255
+ };
256
+ /** One change recorded by an action. Patches address elements by id, never by position in the file. */
257
+ type Patch = {
258
+ readonly op: "set";
259
+ readonly id: string;
260
+ readonly prop: string;
261
+ readonly value: Json | undefined;
262
+ } | {
263
+ readonly op: "text";
264
+ readonly id: string;
265
+ readonly text: string;
266
+ } | {
267
+ readonly op: "insert";
268
+ readonly id: string;
269
+ readonly parent: string;
270
+ readonly after: string | null;
271
+ readonly node: CollectedNode;
272
+ } | {
273
+ readonly op: "remove";
274
+ readonly id: string;
275
+ } | {
276
+ readonly op: "move";
277
+ readonly id: string;
278
+ readonly parent: string;
279
+ readonly after: string | null;
280
+ } | {
281
+ readonly op: "bake";
282
+ readonly id: string;
283
+ };
284
+ type Presence = "present" | "inserted" | "removed";
285
+ /** The reduced effect of every patch on one element. */
286
+ interface NetPatch {
287
+ readonly id: string;
288
+ presence: Presence;
289
+ readonly props: Map<string, Json | undefined>;
290
+ text?: string;
291
+ place?: {
292
+ parent: string;
293
+ after: string | null;
294
+ };
295
+ node?: CollectedNode;
296
+ bake: boolean;
297
+ }
298
+ interface PatchLog {
299
+ readonly entries: readonly Patch[];
300
+ readonly net: ReadonlyMap<string, NetPatch>;
301
+ /** Increments on every append or truncate; resolve() memoises on it. */
302
+ readonly version: number;
303
+ append(patch: Patch): void;
304
+ /** Current length, for history entries to remember what they appended. */
305
+ mark(): number;
306
+ /** Drop every entry at or after `mark` and rebuild `net`. */
307
+ truncate(mark: number): void;
308
+ clear(): void;
309
+ }
310
+ declare const TRACK_LAYOUTS: readonly ["sequence", "free"];
311
+ declare const TRACK_ROLES: readonly ["general", "captions", "dialogue", "music", "effects", "ambience"];
312
+ declare const FIT_MODES: readonly ["contain", "cover", "stretch", "none"];
313
+ declare const BLEND_MODES: readonly ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity", "add", "linear-dodge"];
314
+ declare const EASINGS: readonly ["linear", "ease", "ease-in", "ease-out", "ease-in-out", "hold", "bezier", "smoothstep", "smootherstep", "snappy", "smooth", "spring", "easeInQuad", "easeOutQuad", "easeInOutQuad", "easeInCubic", "easeOutCubic", "easeInOutCubic", "easeInQuart", "easeOutQuart", "easeInOutQuart", "easeInQuint", "easeOutQuint", "easeInOutQuint", "easeInSine", "easeOutSine", "easeInOutSine", "easeInExpo", "easeOutExpo", "easeInOutExpo", "easeInCirc", "easeOutCirc", "easeInOutCirc", "easeInBack", "easeOutBack", "easeInOutBack", "easeInBackStrong", "easeOutBackStrong", "easeInOutBackStrong", "easeInElastic", "easeOutElastic", "easeInOutElastic", "easeInElasticSoft", "easeOutElasticSoft", "easeInOutElasticSoft", "easeInBounce", "easeOutBounce", "easeInOutBounce", "easeInBounceSmall", "easeOutBounceSmall", "easeInOutBounceSmall"];
315
+ declare const MASK_EASINGS: readonly ["linear", "ease-in", "ease-out", "ease-in-out"];
316
+ declare const TRANSITION_TYPES: readonly ["crossfade", "dipToBlack", "dipToWhite", "wipe", "slide", "push"];
317
+ declare const VIDEO_EFFECT_TYPES: readonly ["brightness", "contrast", "saturation", "hue", "temperature", "tint", "blur", "vignette", "grain", "shadow", "grayscale", "sepia", "invert", "levels"];
318
+ declare const TEXT_ANIMATION_PRESETS: readonly ["none", "typewriter", "fade", "slide-up", "slide-down", "slide-left", "slide-right", "scale", "word-by-word"];
319
+ declare const CAPTION_ANIMATIONS: readonly ["none", "word-highlight", "word-by-word", "karaoke", "typewriter"];
320
+ declare const GRAPHIC_ANIMATIONS: readonly ["none", "fade", "slide-left", "slide-right", "slide-up", "slide-down", "scale", "rotate", "bounce", "pop", "draw", "wipe-left", "wipe-right", "wipe-up", "wipe-down", "reveal-center", "reveal-edges", "elastic", "flip-horizontal", "flip-vertical"];
321
+ declare const SHAPE_TYPES: readonly ["rectangle", "circle", "ellipse", "triangle", "arrow", "line", "polygon", "path", "star"];
322
+ declare const KEYFRAME_PROPERTIES: readonly ["transform.position.x", "transform.position.y", "transform.scale.x", "transform.scale.y", "transform.rotation", "transform.opacity", "transform.anchor.x", "transform.anchor.y", "transform.borderRadius", "transform.crop.x", "transform.crop.y", "transform.crop.width", "transform.crop.height", "audio.volume", "audio.pan", "colorGrade.temperature", "colorGrade.tint"];
323
+ /** `effect.<effectId>.<param>` is also a valid keyframe property; see `isKeyframeProperty`. */
324
+ declare const KEYFRAME_PROPERTY_PATTERN: RegExp;
325
+ declare function isKeyframeProperty(value: string): boolean;
326
+ declare const CAPTION_POSITIONS: readonly ["top", "center", "bottom"];
327
+ declare const TEXT_ALIGNS: readonly ["left", "center", "right", "justify"];
328
+ declare const TEXT_VALIGNS: readonly ["top", "middle", "bottom"];
329
+ declare const TEXT_DECORATIONS: readonly ["none", "underline", "line-through", "overline"];
330
+ declare const ANIMATION_UNITS: readonly ["character", "word", "line"];
331
+ declare const MASK_TYPES: readonly ["shape", "drawn"];
332
+ declare const SVG_COLOR_MODES: readonly ["none", "tint", "replace"];
333
+ declare const AUTOMATION_LANES: readonly ["volume", "pan"];
334
+ declare const TRACK_FLAGS: readonly ["locked", "hidden", "muted", "solo"];
335
+ declare const zTrackLayout: z.ZodEnum<{
336
+ sequence: "sequence";
337
+ free: "free";
338
+ }>;
339
+ declare const zTrackRole: z.ZodEnum<{
340
+ general: "general";
341
+ captions: "captions";
342
+ dialogue: "dialogue";
343
+ music: "music";
344
+ effects: "effects";
345
+ ambience: "ambience";
346
+ }>;
347
+ declare const zFitMode: z.ZodEnum<{
348
+ contain: "contain";
349
+ cover: "cover";
350
+ stretch: "stretch";
351
+ none: "none";
352
+ }>;
353
+ declare const zBlendMode: z.ZodEnum<{
354
+ normal: "normal";
355
+ multiply: "multiply";
356
+ screen: "screen";
357
+ overlay: "overlay";
358
+ darken: "darken";
359
+ lighten: "lighten";
360
+ "color-dodge": "color-dodge";
361
+ "color-burn": "color-burn";
362
+ "hard-light": "hard-light";
363
+ "soft-light": "soft-light";
364
+ difference: "difference";
365
+ exclusion: "exclusion";
366
+ hue: "hue";
367
+ saturation: "saturation";
368
+ color: "color";
369
+ luminosity: "luminosity";
370
+ add: "add";
371
+ "linear-dodge": "linear-dodge";
372
+ }>;
373
+ declare const zEasing: z.ZodEnum<{
374
+ linear: "linear";
375
+ ease: "ease";
376
+ "ease-in": "ease-in";
377
+ "ease-out": "ease-out";
378
+ "ease-in-out": "ease-in-out";
379
+ hold: "hold";
380
+ bezier: "bezier";
381
+ smoothstep: "smoothstep";
382
+ smootherstep: "smootherstep";
383
+ snappy: "snappy";
384
+ smooth: "smooth";
385
+ spring: "spring";
386
+ easeInQuad: "easeInQuad";
387
+ easeOutQuad: "easeOutQuad";
388
+ easeInOutQuad: "easeInOutQuad";
389
+ easeInCubic: "easeInCubic";
390
+ easeOutCubic: "easeOutCubic";
391
+ easeInOutCubic: "easeInOutCubic";
392
+ easeInQuart: "easeInQuart";
393
+ easeOutQuart: "easeOutQuart";
394
+ easeInOutQuart: "easeInOutQuart";
395
+ easeInQuint: "easeInQuint";
396
+ easeOutQuint: "easeOutQuint";
397
+ easeInOutQuint: "easeInOutQuint";
398
+ easeInSine: "easeInSine";
399
+ easeOutSine: "easeOutSine";
400
+ easeInOutSine: "easeInOutSine";
401
+ easeInExpo: "easeInExpo";
402
+ easeOutExpo: "easeOutExpo";
403
+ easeInOutExpo: "easeInOutExpo";
404
+ easeInCirc: "easeInCirc";
405
+ easeOutCirc: "easeOutCirc";
406
+ easeInOutCirc: "easeInOutCirc";
407
+ easeInBack: "easeInBack";
408
+ easeOutBack: "easeOutBack";
409
+ easeInOutBack: "easeInOutBack";
410
+ easeInBackStrong: "easeInBackStrong";
411
+ easeOutBackStrong: "easeOutBackStrong";
412
+ easeInOutBackStrong: "easeInOutBackStrong";
413
+ easeInElastic: "easeInElastic";
414
+ easeOutElastic: "easeOutElastic";
415
+ easeInOutElastic: "easeInOutElastic";
416
+ easeInElasticSoft: "easeInElasticSoft";
417
+ easeOutElasticSoft: "easeOutElasticSoft";
418
+ easeInOutElasticSoft: "easeInOutElasticSoft";
419
+ easeInBounce: "easeInBounce";
420
+ easeOutBounce: "easeOutBounce";
421
+ easeInOutBounce: "easeInOutBounce";
422
+ easeInBounceSmall: "easeInBounceSmall";
423
+ easeOutBounceSmall: "easeOutBounceSmall";
424
+ easeInOutBounceSmall: "easeInOutBounceSmall";
425
+ }>;
426
+ declare const zMaskEasing: z.ZodEnum<{
427
+ linear: "linear";
428
+ "ease-in": "ease-in";
429
+ "ease-out": "ease-out";
430
+ "ease-in-out": "ease-in-out";
431
+ }>;
432
+ declare const zTransitionType: z.ZodEnum<{
433
+ crossfade: "crossfade";
434
+ dipToBlack: "dipToBlack";
435
+ dipToWhite: "dipToWhite";
436
+ wipe: "wipe";
437
+ slide: "slide";
438
+ push: "push";
439
+ }>;
440
+ declare const zVideoEffectType: z.ZodEnum<{
441
+ hue: "hue";
442
+ saturation: "saturation";
443
+ brightness: "brightness";
444
+ contrast: "contrast";
445
+ temperature: "temperature";
446
+ tint: "tint";
447
+ blur: "blur";
448
+ vignette: "vignette";
449
+ grain: "grain";
450
+ shadow: "shadow";
451
+ grayscale: "grayscale";
452
+ sepia: "sepia";
453
+ invert: "invert";
454
+ levels: "levels";
455
+ }>;
456
+ declare const zTextAnimationPreset: z.ZodEnum<{
457
+ none: "none";
458
+ typewriter: "typewriter";
459
+ fade: "fade";
460
+ "slide-up": "slide-up";
461
+ "slide-down": "slide-down";
462
+ "slide-left": "slide-left";
463
+ "slide-right": "slide-right";
464
+ scale: "scale";
465
+ "word-by-word": "word-by-word";
466
+ }>;
467
+ declare const zCaptionAnimation: z.ZodEnum<{
468
+ none: "none";
469
+ typewriter: "typewriter";
470
+ "word-by-word": "word-by-word";
471
+ "word-highlight": "word-highlight";
472
+ karaoke: "karaoke";
473
+ }>;
474
+ declare const zGraphicAnimation: z.ZodEnum<{
475
+ none: "none";
476
+ fade: "fade";
477
+ "slide-up": "slide-up";
478
+ "slide-down": "slide-down";
479
+ "slide-left": "slide-left";
480
+ "slide-right": "slide-right";
481
+ scale: "scale";
482
+ rotate: "rotate";
483
+ bounce: "bounce";
484
+ pop: "pop";
485
+ draw: "draw";
486
+ "wipe-left": "wipe-left";
487
+ "wipe-right": "wipe-right";
488
+ "wipe-up": "wipe-up";
489
+ "wipe-down": "wipe-down";
490
+ "reveal-center": "reveal-center";
491
+ "reveal-edges": "reveal-edges";
492
+ elastic: "elastic";
493
+ "flip-horizontal": "flip-horizontal";
494
+ "flip-vertical": "flip-vertical";
495
+ }>;
496
+ declare const zShapeType: z.ZodEnum<{
497
+ rectangle: "rectangle";
498
+ circle: "circle";
499
+ ellipse: "ellipse";
500
+ triangle: "triangle";
501
+ arrow: "arrow";
502
+ line: "line";
503
+ polygon: "polygon";
504
+ path: "path";
505
+ star: "star";
506
+ }>;
507
+ declare const zKeyframeProperty: z.ZodString;
508
+ type TrackLayout = (typeof TRACK_LAYOUTS)[number];
509
+ type TrackRole = (typeof TRACK_ROLES)[number];
510
+ type FitMode = (typeof FIT_MODES)[number];
511
+ type BlendMode = (typeof BLEND_MODES)[number];
512
+ type Easing = (typeof EASINGS)[number];
513
+ type TransitionType = (typeof TRANSITION_TYPES)[number];
514
+ type VideoEffectType = (typeof VIDEO_EFFECT_TYPES)[number];
515
+ type TrackFlag = (typeof TRACK_FLAGS)[number];
516
+ /**
517
+ * The built-in themes and motion styles a file can name. A theme is a palette,
518
+ * fonts, a corner radius, a motion style and named presets per element kind;
519
+ * presets refer to the palette and fonts through tokens, so one set of presets
520
+ * serves every theme.
521
+ */
522
+ declare const THEME_NAMES: readonly ["midnight", "paper", "neon", "pastel", "mono", "bold"];
523
+ type ThemeName = (typeof THEME_NAMES)[number];
524
+ declare const MOTION_NAMES: readonly ["none", "calm", "snappy", "bouncy", "editorial"];
525
+ type MotionName = (typeof MOTION_NAMES)[number];
526
+ /** The palette names every built-in theme fills. `onPrimary` is text drawn on a `primary` fill. */
527
+ declare const PALETTE_KEYS: readonly ["primary", "secondary", "accent", "background", "surface", "text", "muted", "onPrimary"];
528
+ declare const FONT_KEYS: readonly ["heading", "body", "mono"];
529
+ interface MotionAnimation {
530
+ readonly type: string;
531
+ readonly duration: number;
532
+ readonly easing: string;
533
+ }
534
+ /** What a motion style fills where an element says nothing: its entrance, its exit, and a transition's type and length. */
535
+ interface MotionStyle {
536
+ readonly enter?: MotionAnimation | undefined;
537
+ readonly exit?: MotionAnimation | undefined;
538
+ readonly transition?: {
539
+ readonly type?: string | undefined;
540
+ readonly duration?: number | undefined;
541
+ } | undefined;
542
+ }
543
+ type Presets = Readonly<Record<string, Readonly<Record<string, Readonly<Record<string, unknown>>>>>>;
544
+ interface ThemeDefinition {
545
+ readonly palette: Readonly<Record<(typeof PALETTE_KEYS)[number], string>>;
546
+ readonly fonts: Readonly<Record<(typeof FONT_KEYS)[number], string>>;
547
+ readonly radius: number;
548
+ readonly motion: MotionName;
549
+ readonly styles: Presets;
550
+ }
551
+ declare const MOTIONS: Readonly<Record<MotionName, MotionStyle>>;
552
+ declare const THEMES: Readonly<Record<ThemeName, ThemeDefinition>>;
553
+ /** The theme tokens resolve against when a file declares none. Its motion and default presets apply only when declared. */
554
+ declare const DEFAULT_THEME: ThemeName;
555
+ /** A file's theme with its base theme merged in: what tokens, presets and motion defaults resolve against. */
556
+ interface ResolvedTheme {
557
+ /** Whether the file declares a theme. Without one, tokens and named presets still resolve against the default theme; motion and `default` presets do not apply. */
558
+ readonly declared: boolean;
559
+ readonly base: string;
560
+ readonly palette: Readonly<Record<string, string>>;
561
+ readonly fonts: Readonly<Record<string, string>>;
562
+ readonly radius: number;
563
+ /** Null when the motion style fills nothing. */
564
+ readonly motion: MotionStyle | null;
565
+ readonly styles: Presets;
566
+ /** Every token by name, without the `$`. */
567
+ readonly tokens: Readonly<Record<string, string | number>>;
568
+ }
569
+ /** Where a themed prop's value came from: `$primary`, `style:h1`, `motion` or `theme`. */
570
+ type ThemeOrigin = string;
571
+ interface ThemeIssue {
572
+ readonly code: "UNKNOWN_TOKEN" | "UNKNOWN_STYLE";
573
+ readonly prop: string;
574
+ readonly message: string;
575
+ }
576
+ interface Themed {
577
+ readonly props: Record<string, unknown>;
578
+ /** Prop path (dot-separated) → where its value came from. Empty when nothing was themed. */
579
+ readonly from: Readonly<Record<string, ThemeOrigin>>;
580
+ readonly issues: readonly ThemeIssue[];
581
+ }
582
+ /** The theme a composition's raw `theme` prop describes. Memoised per object; an invalid theme falls back to its base (the schema reports why). */
583
+ declare function resolveTheme(raw: unknown): ResolvedTheme;
584
+ /** The value of `$name`, or undefined. */
585
+ declare function themeToken(theme: ResolvedTheme, name: string): string | number | undefined;
586
+ /**
587
+ * An element's raw props with its theme applied, before the schema parses them:
588
+ * the preset its `style` names (or the kind's `default` preset) fills the props
589
+ * the element leaves out, the motion style fills `enter`/`exit` (a transition's
590
+ * type and duration), and whole-string `$token` values become theme values. The
591
+ * element's own props always win. Returns the input object when nothing was themed.
592
+ */
593
+ declare function applyTheme(kind: string, raw: Readonly<Record<string, unknown>>, theme: ResolvedTheme): Themed;
594
+ interface Placement {
595
+ readonly id: string;
596
+ readonly kind: string;
597
+ readonly track: string | null;
598
+ readonly parent: string | null;
599
+ readonly children: readonly string[];
600
+ readonly start: number;
601
+ readonly end: number;
602
+ readonly duration: number;
603
+ readonly source?: {
604
+ readonly in: number;
605
+ readonly out: number;
606
+ readonly speed: number;
607
+ readonly asset: string;
608
+ };
609
+ /** Schema-parsed props with defaults applied, after patches. Raw props when the schema rejected them. */
610
+ readonly props: Readonly<Record<string, unknown>>;
611
+ readonly editable: Editable;
612
+ readonly lockedProps: readonly string[];
613
+ /** Prop → `schema` key; editable, but the fold writes the value into `defaults` rather than the element. */
614
+ readonly boundProps: Readonly<Record<string, string>>;
615
+ readonly errors: readonly ResolveError[];
616
+ /** For transitions between siblings: the two clips. */
617
+ readonly between?: readonly [string, string];
618
+ /** A Layer's handles: the component inside it and its current props. */
619
+ readonly interior?: LayerInterior;
620
+ /** Props the theme supplied, by dot path: `$primary`, `style:h1`, `motion` or `theme`. Absent when none did. */
621
+ readonly themed?: Readonly<Record<string, ThemeOrigin>>;
622
+ }
623
+ interface ResolvedTrack {
624
+ readonly id: string;
625
+ readonly layout: TrackLayout;
626
+ readonly order: number;
627
+ readonly locked: boolean;
628
+ readonly hidden: boolean;
629
+ readonly muted: boolean;
630
+ readonly solo: boolean;
631
+ readonly role?: TrackRole;
632
+ readonly group?: string;
633
+ readonly items: readonly string[];
634
+ }
635
+ interface ResolvedState {
636
+ readonly composition: {
637
+ readonly id: string;
638
+ readonly fps: number;
639
+ readonly width: number;
640
+ readonly height: number;
641
+ readonly duration: number;
642
+ };
643
+ readonly tracks: readonly ResolvedTrack[];
644
+ readonly items: ReadonlyMap<string, Placement>;
645
+ readonly errors: readonly ResolveError[];
646
+ readonly tree: CollectedTree;
647
+ readonly manifest: AssetManifest;
648
+ readonly log: PatchLog | undefined;
649
+ /** The composition's theme, its base merged in; the default theme when the file declares none. */
650
+ readonly theme: ResolvedTheme;
651
+ /** The faces the file declares (`font()`, `googleFont()`), which every renderer loads. */
652
+ readonly fonts: readonly DeclaredFont[];
653
+ /** The effects and transitions the file declares (`defineEffect()`, `defineTransition()`). */
654
+ readonly shaders: readonly ShaderDefinition[];
655
+ }
656
+ /** Absolute placements for every element, computed from the tree, the manifests and the patch log. Memoised per log on its version. */
657
+ declare function resolve(tree: CollectedTree, manifest: AssetManifest, log?: PatchLog): ResolvedState;
658
+ /** Whether two placements would render and edit the same; used to hand back the previous object. */
659
+ declare function samePlacement(a: Placement, b: Placement): boolean;
660
+ type TimeRef = number | `word:${number}` | `word:${number}.end` | `shot:${number}` | `shot:${number}.end` | `silence:${number}` | `silence:${number}.end` | `marker:${string}`;
661
+ type ParsedTimeRef = {
662
+ readonly kind: "seconds";
663
+ readonly value: number;
664
+ } | {
665
+ readonly kind: "word" | "shot" | "silence";
666
+ readonly index: number;
667
+ readonly edge: "start" | "end";
668
+ } | {
669
+ readonly kind: "marker";
670
+ readonly id: string;
671
+ } | {
672
+ readonly kind: "invalid";
673
+ readonly reason: string;
674
+ };
675
+ declare function isTimeRefString(value: unknown): value is string;
676
+ declare function parseTimeRef(ref: unknown): ParsedTimeRef;
677
+ /**
678
+ * Turn a reference into seconds. Word, shot and silence references are source
679
+ * times on the asset; marker references are composition times.
680
+ */
681
+ declare function resolveTimeRef(ref: unknown, asset: AssetEntry | null, markers: ReadonlyMap<string, number>, ctx: {
682
+ readonly id: string;
683
+ readonly prop: string;
684
+ }): number | ResolveError;
685
+ type ActionErrorCode = "ELEMENT_NOT_FOUND" | "TRACK_LOCKED" | "LOCKED_PROP" | "OPAQUE_TARGET" | "INVALID_PARAMS" | "INVALID_TIME_RANGE" | "OUT_OF_BOUNDS" | "NOT_ADJACENT" | "INSUFFICIENT_HANDLES" | "CYCLE" | "DUPLICATE_ID" | "UNSUPPORTED_ON_LAYOUT" | "UNKNOWN_ACTION" | "NOT_IMPLEMENTED";
686
+ interface ActionError {
687
+ readonly code: ActionErrorCode;
688
+ readonly message: string;
689
+ readonly path?: string;
690
+ }
691
+ interface ValidationResult {
692
+ readonly valid: boolean;
693
+ readonly errors: readonly ActionError[];
694
+ }
695
+ declare const ok: ValidationResult;
696
+ declare function invalid(...errors: ActionError[]): ValidationResult;
697
+ /** Where a new element goes. Sequence tracks take `after`; free tracks take `start`; overlays may anchor. */
698
+ type PlacementSpec = {
699
+ readonly after: string | null;
700
+ } | {
701
+ readonly start: number;
702
+ } | {
703
+ readonly anchor: string;
704
+ readonly offset?: number;
705
+ };
706
+ /** A serialisable element to insert: raw JSX props, optional text, optional children. */
707
+ interface NodeSpec {
708
+ readonly id: string;
709
+ readonly kind: string;
710
+ readonly props: Readonly<Record<string, Json | undefined>>;
711
+ readonly text?: string;
712
+ readonly children?: readonly NodeSpec[];
713
+ }
714
+ declare function nodeSpecOf(node: CollectedNode): NodeSpec;
715
+ declare function nodeOfSpec(spec: NodeSpec, parent: string | null): CollectedNode;
716
+ type Id = string;
717
+ type Props = Readonly<Record<string, Json | undefined>>;
718
+ interface CompositionActions {
719
+ "composition/updateSettings": {
720
+ fps?: number;
721
+ width?: number;
722
+ height?: number;
723
+ sampleRate?: number;
724
+ channels?: number;
725
+ };
726
+ "composition/setBackground": {
727
+ mode?: "color" | "blur";
728
+ color?: string;
729
+ };
730
+ /** The tweaks panel: rewrites the file's `defaults` literal. */
731
+ "composition/setProps": {
732
+ defaults: Readonly<Record<string, Json>>;
733
+ };
734
+ /** Swap the theme (or remove it with null); with `merge`, lay the given parts over the current theme instead. */
735
+ "composition/setTheme": {
736
+ theme: Readonly<Record<string, Json>> | null;
737
+ merge?: boolean;
738
+ };
739
+ /** One theme value: a palette colour, a font role or `radius`, by token name without the `$`. */
740
+ "theme/setToken": {
741
+ token: string;
742
+ value: string | number;
743
+ };
744
+ "batch/apply": {
745
+ actions: readonly ActionInput[];
746
+ };
747
+ }
748
+ interface TrackActions {
749
+ "track/add": {
750
+ trackId: Id;
751
+ position?: number;
752
+ layout?: TrackLayout;
753
+ role?: TrackRole;
754
+ name?: string;
755
+ };
756
+ "track/remove": {
757
+ trackId: Id;
758
+ };
759
+ "track/restore": {
760
+ trackId: Id;
761
+ node: NodeSpec;
762
+ position: number;
763
+ };
764
+ "track/duplicate": {
765
+ sourceTrackId: Id;
766
+ trackId: Id;
767
+ idMap: Readonly<Record<Id, Id>>;
768
+ position?: number;
769
+ };
770
+ "track/rename": {
771
+ trackId: Id;
772
+ name: string;
773
+ };
774
+ "track/reorder": {
775
+ trackId: Id;
776
+ position: number;
777
+ };
778
+ "track/setFlag": {
779
+ trackId: Id;
780
+ flag: TrackFlag;
781
+ value: boolean;
782
+ };
783
+ "track/setLayout": {
784
+ trackId: Id;
785
+ layout: TrackLayout;
786
+ };
787
+ "track/setGroup": {
788
+ trackId: Id;
789
+ group?: Id;
790
+ };
791
+ "track/consolidate": {
792
+ trackId: Id;
793
+ };
794
+ "track/restorePositions": {
795
+ trackId: Id;
796
+ positions: readonly {
797
+ id: Id;
798
+ start: number;
799
+ }[];
800
+ };
801
+ }
802
+ interface ClipActions {
803
+ "clip/add": {
804
+ id: Id;
805
+ trackId: Id;
806
+ src: string;
807
+ place: PlacementSpec;
808
+ in?: TimeRef;
809
+ out?: TimeRef;
810
+ duration?: number;
811
+ };
812
+ /** An <Audio> (sound only: music, a voice-over), placed like a clip; `duration: "fill"` runs to the composition's end. */
813
+ "audio/add": {
814
+ id: Id;
815
+ trackId: Id;
816
+ src: string;
817
+ place: PlacementSpec;
818
+ in?: TimeRef;
819
+ out?: TimeRef;
820
+ duration?: number | "fill";
821
+ };
822
+ "clip/remove": {
823
+ id: Id;
824
+ };
825
+ "clip/restore": {
826
+ id: Id;
827
+ node: NodeSpec;
828
+ trackId: Id;
829
+ place: PlacementSpec;
830
+ };
831
+ "clip/rippleDelete": {
832
+ id: Id;
833
+ };
834
+ "clip/rippleRestore": {
835
+ id: Id;
836
+ node: NodeSpec;
837
+ trackId: Id;
838
+ place: PlacementSpec;
839
+ affected: readonly {
840
+ id: Id;
841
+ start: number;
842
+ }[];
843
+ };
844
+ "clip/move": {
845
+ id: Id;
846
+ trackId?: Id;
847
+ place: PlacementSpec;
848
+ };
849
+ "clip/trim": {
850
+ id: Id;
851
+ edge: "in" | "out";
852
+ value: TimeRef;
853
+ };
854
+ "clip/split": {
855
+ id: Id;
856
+ at: number;
857
+ newId: Id;
858
+ };
859
+ "clip/merge": {
860
+ id: Id;
861
+ rightId: Id;
862
+ original: NodeSpec;
863
+ };
864
+ "clip/slip": {
865
+ id: Id;
866
+ delta: number;
867
+ };
868
+ "clip/slide": {
869
+ id: Id;
870
+ delta: number;
871
+ };
872
+ "clip/roll": {
873
+ leftId: Id;
874
+ rightId: Id;
875
+ delta: number;
876
+ };
877
+ "clip/trimToPlayhead": {
878
+ id: Id;
879
+ at: number;
880
+ edge: "in" | "out";
881
+ };
882
+ "clip/restoreTiming": {
883
+ id: Id;
884
+ in?: TimeRef;
885
+ out?: TimeRef;
886
+ duration?: Json;
887
+ start?: number;
888
+ };
889
+ "clip/closeGapBefore": {
890
+ id: Id;
891
+ };
892
+ "clip/setSpeed": {
893
+ id: Id;
894
+ speed: number;
895
+ };
896
+ "clip/setReverse": {
897
+ id: Id;
898
+ value: boolean;
899
+ };
900
+ "clip/setBlend": {
901
+ id: Id;
902
+ mode?: string;
903
+ opacity?: number;
904
+ };
905
+ "clip/setFit": {
906
+ id: Id;
907
+ value?: string;
908
+ };
909
+ "clip/setSource": {
910
+ id: Id;
911
+ src: string;
912
+ };
913
+ "clip/setAnchor": {
914
+ id: Id;
915
+ anchor?: Id | "start";
916
+ offset?: number;
917
+ };
918
+ }
919
+ interface SpeedActions {
920
+ "speed/setKeys": {
921
+ id: Id;
922
+ keys: readonly NodeSpec[];
923
+ after?: Id | null;
924
+ };
925
+ "speed/setFreezes": {
926
+ id: Id;
927
+ freezes: readonly NodeSpec[];
928
+ after?: Id | null;
929
+ };
930
+ }
931
+ interface TransformActions {
932
+ "transform/update": {
933
+ id: Id;
934
+ transform: Readonly<Record<string, Json>>;
935
+ };
936
+ }
937
+ interface ChildStack<K extends string> {
938
+ add: {
939
+ id: Id;
940
+ childId: Id;
941
+ type: K;
942
+ params?: Readonly<Record<string, Json>>;
943
+ index?: number;
944
+ };
945
+ remove: {
946
+ id: Id;
947
+ childId: Id;
948
+ };
949
+ restore: {
950
+ id: Id;
951
+ node: NodeSpec;
952
+ after: Id | null;
953
+ };
954
+ update: {
955
+ id: Id;
956
+ childId: Id;
957
+ params: Readonly<Record<string, Json>>;
958
+ };
959
+ toggle: {
960
+ id: Id;
961
+ childId: Id;
962
+ enabled: boolean;
963
+ };
964
+ setOrder: {
965
+ id: Id;
966
+ childIds: readonly Id[];
967
+ };
968
+ setStack: {
969
+ id: Id;
970
+ nodes: readonly NodeSpec[];
971
+ after?: Id | null;
972
+ };
973
+ }
974
+ interface EffectActions {
975
+ "effect/add": ChildStack<string>["add"];
976
+ "effect/remove": ChildStack<string>["remove"];
977
+ "effect/restore": ChildStack<string>["restore"];
978
+ "effect/update": ChildStack<string>["update"];
979
+ "effect/toggle": ChildStack<string>["toggle"];
980
+ "effect/setOrder": ChildStack<string>["setOrder"];
981
+ "effect/setStack": ChildStack<string>["setStack"];
982
+ "colorGrade/set": {
983
+ id: Id;
984
+ grading?: Readonly<Record<string, Json>>;
985
+ };
986
+ }
987
+ interface KeyframeActions {
988
+ "keyframe/add": {
989
+ id: Id;
990
+ keyId: Id;
991
+ property: string;
992
+ at: number;
993
+ value: Json;
994
+ easing?: string;
995
+ };
996
+ "keyframe/remove": {
997
+ id: Id;
998
+ keyId: Id;
999
+ };
1000
+ "keyframe/restore": {
1001
+ id: Id;
1002
+ node: NodeSpec;
1003
+ after: Id | null;
1004
+ };
1005
+ "keyframe/update": {
1006
+ id: Id;
1007
+ keyId: Id;
1008
+ value?: Json;
1009
+ easing?: string;
1010
+ };
1011
+ "keyframe/move": {
1012
+ id: Id;
1013
+ keyId: Id;
1014
+ at: number;
1015
+ };
1016
+ "keyframe/setAll": {
1017
+ id: Id;
1018
+ nodes: readonly NodeSpec[];
1019
+ after?: Id | null;
1020
+ };
1021
+ }
1022
+ interface TransitionActions {
1023
+ "transition/add": {
1024
+ transitionId: Id;
1025
+ between: readonly [Id, Id] | {
1026
+ on: Id;
1027
+ edge: "in" | "out";
1028
+ };
1029
+ /** A built-in transition, or one the file declares with `defineTransition()`. */
1030
+ type: TransitionType | (string & {});
1031
+ duration: number;
1032
+ params?: Readonly<Record<string, Json>>;
1033
+ };
1034
+ "transition/remove": {
1035
+ transitionId: Id;
1036
+ };
1037
+ "transition/restore": {
1038
+ transitionId: Id;
1039
+ node: NodeSpec;
1040
+ trackId: Id;
1041
+ after: Id | null;
1042
+ };
1043
+ "transition/update": {
1044
+ transitionId: Id;
1045
+ type?: TransitionType | (string & {});
1046
+ duration?: number;
1047
+ params?: Readonly<Record<string, Json>>;
1048
+ };
1049
+ }
1050
+ interface AudioActions {
1051
+ "audio/setVolume": {
1052
+ id: Id;
1053
+ volume: number;
1054
+ };
1055
+ "audio/setFade": {
1056
+ id: Id;
1057
+ in?: number;
1058
+ out?: number;
1059
+ };
1060
+ "audio/setAutomation": {
1061
+ id: Id;
1062
+ lane: "volume" | "pan";
1063
+ points: readonly (readonly [number, number])[];
1064
+ };
1065
+ "audio/setDuck": {
1066
+ id: Id;
1067
+ duck?: {
1068
+ under: Id;
1069
+ to: number;
1070
+ attack?: number;
1071
+ release?: number;
1072
+ };
1073
+ };
1074
+ }
1075
+ interface Overlay {
1076
+ create: {
1077
+ id: Id;
1078
+ kind: string;
1079
+ trackId: Id;
1080
+ place: PlacementSpec;
1081
+ props: Props;
1082
+ text?: string;
1083
+ children?: readonly NodeSpec[];
1084
+ after?: Id | null;
1085
+ };
1086
+ update: {
1087
+ id: Id;
1088
+ props: Props;
1089
+ };
1090
+ remove: {
1091
+ id: Id;
1092
+ };
1093
+ }
1094
+ interface OverlayActions {
1095
+ "text/create": Overlay["create"];
1096
+ "text/update": Overlay["update"];
1097
+ "text/remove": Overlay["remove"];
1098
+ "text/setContent": {
1099
+ id: Id;
1100
+ text: string;
1101
+ };
1102
+ "shape/create": Overlay["create"];
1103
+ "shape/update": Overlay["update"];
1104
+ "shape/remove": Overlay["remove"];
1105
+ "svg/create": Overlay["create"];
1106
+ "svg/update": Overlay["update"];
1107
+ "svg/remove": Overlay["remove"];
1108
+ "sticker/create": Overlay["create"];
1109
+ "sticker/update": Overlay["update"];
1110
+ "sticker/remove": Overlay["remove"];
1111
+ "graphic/create": Overlay["create"];
1112
+ "graphic/update": Overlay["update"];
1113
+ "graphic/remove": Overlay["remove"];
1114
+ "adjustment/create": Overlay["create"];
1115
+ "adjustment/update": Overlay["update"];
1116
+ "adjustment/remove": Overlay["remove"];
1117
+ "nested/create": Overlay["create"];
1118
+ "nested/update": Overlay["update"];
1119
+ "nested/remove": Overlay["remove"];
1120
+ "nested/extract": {
1121
+ id: Id;
1122
+ };
1123
+ }
1124
+ interface CaptionActions {
1125
+ "caption/import": {
1126
+ captionsId: Id;
1127
+ src?: string;
1128
+ items?: readonly NodeSpec[];
1129
+ };
1130
+ "caption/add": {
1131
+ captionsId: Id;
1132
+ captionId: Id;
1133
+ start: TimeRef;
1134
+ end: TimeRef;
1135
+ text: string;
1136
+ words?: Json;
1137
+ };
1138
+ "caption/update": {
1139
+ captionId: Id;
1140
+ text?: string;
1141
+ start?: TimeRef;
1142
+ end?: TimeRef;
1143
+ words?: Json;
1144
+ };
1145
+ "caption/remove": {
1146
+ captionId: Id;
1147
+ };
1148
+ "caption/restore": {
1149
+ captionsId: Id;
1150
+ node: NodeSpec;
1151
+ after: Id | null;
1152
+ };
1153
+ "caption/setStyle": {
1154
+ captionsId: Id;
1155
+ style?: Readonly<Record<string, Json>>;
1156
+ };
1157
+ "caption/setAnimation": {
1158
+ captionsId: Id;
1159
+ animation: string;
1160
+ };
1161
+ "caption/setAll": {
1162
+ captionsId: Id;
1163
+ nodes: readonly NodeSpec[];
1164
+ after?: Id | null;
1165
+ };
1166
+ }
1167
+ interface MarkerActions {
1168
+ "marker/add": {
1169
+ markerId: Id;
1170
+ at: number;
1171
+ label?: string;
1172
+ color?: string;
1173
+ };
1174
+ "marker/update": {
1175
+ markerId: Id;
1176
+ at?: number;
1177
+ label?: string;
1178
+ color?: string;
1179
+ };
1180
+ "marker/remove": {
1181
+ markerId: Id;
1182
+ };
1183
+ "marker/restore": {
1184
+ node: NodeSpec;
1185
+ after: Id | null;
1186
+ };
1187
+ }
1188
+ interface MaskActions {
1189
+ "mask/create": {
1190
+ id: Id;
1191
+ parentId: Id;
1192
+ props: Props;
1193
+ };
1194
+ "mask/update": {
1195
+ id: Id;
1196
+ props: Props;
1197
+ };
1198
+ "mask/remove": {
1199
+ id: Id;
1200
+ };
1201
+ "mask/restore": {
1202
+ id: Id;
1203
+ parentId: Id;
1204
+ node: NodeSpec;
1205
+ after: Id | null;
1206
+ };
1207
+ "mask/setPath": {
1208
+ id: Id;
1209
+ path: Json;
1210
+ };
1211
+ }
1212
+ interface MulticamActions {
1213
+ "multicam/create": {
1214
+ id: Id;
1215
+ trackId: Id;
1216
+ place: PlacementSpec;
1217
+ angles: readonly NodeSpec[];
1218
+ sync?: number;
1219
+ };
1220
+ "multicam/remove": {
1221
+ id: Id;
1222
+ };
1223
+ "multicam/restore": {
1224
+ id: Id;
1225
+ node: NodeSpec;
1226
+ trackId: Id;
1227
+ place: PlacementSpec;
1228
+ };
1229
+ "multicam/setActiveAngle": {
1230
+ id: Id;
1231
+ angle: Id;
1232
+ };
1233
+ "multicam/addCut": {
1234
+ id: Id;
1235
+ cutId: Id;
1236
+ at: number;
1237
+ angle: Id;
1238
+ };
1239
+ "multicam/moveCut": {
1240
+ cutId: Id;
1241
+ at: number;
1242
+ };
1243
+ "multicam/removeCut": {
1244
+ cutId: Id;
1245
+ };
1246
+ "multicam/restoreCut": {
1247
+ id: Id;
1248
+ node: NodeSpec;
1249
+ after: Id | null;
1250
+ };
1251
+ "multicam/flatten": {
1252
+ id: Id;
1253
+ };
1254
+ }
1255
+ interface LayerActions {
1256
+ "layer/setTiming": {
1257
+ id: Id;
1258
+ duration?: Json;
1259
+ anchor?: Id | "start";
1260
+ offset?: number;
1261
+ start?: number;
1262
+ };
1263
+ "layer/setProps": {
1264
+ id: Id;
1265
+ props: Readonly<Record<string, Json | undefined>>;
1266
+ };
1267
+ "layer/setTransform": {
1268
+ id: Id;
1269
+ transform: Readonly<Record<string, Json>>;
1270
+ };
1271
+ }
1272
+ interface SourceActions {
1273
+ "source/bake": {
1274
+ id: Id;
1275
+ };
1276
+ "source/setProp": {
1277
+ id: Id;
1278
+ prop: string;
1279
+ value: Json | undefined;
1280
+ };
1281
+ /** Several literal props at once; the inverse of every prop-writing action. */
1282
+ "source/setProps": {
1283
+ id: Id;
1284
+ props: Readonly<Record<string, Json | undefined>>;
1285
+ };
1286
+ }
1287
+ type ActionMap = CompositionActions & TrackActions & ClipActions & SpeedActions & TransformActions & EffectActions & KeyframeActions & TransitionActions & AudioActions & OverlayActions & CaptionActions & MarkerActions & MaskActions & MulticamActions & LayerActions & SourceActions;
1288
+ type ActionType = keyof ActionMap;
1289
+ interface Action<T extends ActionType = ActionType> {
1290
+ readonly type: T;
1291
+ readonly actionId: string;
1292
+ readonly ts: number;
1293
+ readonly params: ActionMap[T];
1294
+ }
1295
+ type ActionInput<T extends ActionType = ActionType> = {
1296
+ readonly type: T;
1297
+ readonly params: ActionMap[T];
1298
+ };
1299
+ type Namespace = ActionType extends `${infer N}/${string}` ? N : never;
1300
+ /** Rapid repeats of these on the same target collapse into one undo step (OpenReel's rule). */
1301
+ declare const AUTO_GROUP_TYPES: ReadonlySet<ActionType>;
1302
+ declare const TARGET_PARAM_KEYS: readonly ["id", "leftId", "trackId", "transitionId", "childId", "keyId", "captionId", "captionsId", "cutId", "markerId"];
1303
+ declare function targetIdOf(action: ActionInput): string | null;
1304
+ declare function describeAction(action: ActionInput): string;
1305
+ export { FONT_KEYS as $, zTrackRole as $t, ValidationResult as A, ShaderDefinition as An, TEXT_DECORATIONS as At, Placement as B, Shot as Bn, VIDEO_EFFECT_TYPES as Bt, TransitionActions as C, MODULE_FONTS as Cn, KEYFRAME_PROPERTY_PATTERN as Ct, ActionErrorCode as D, googleFont as Dn, SVG_COLOR_MODES as Dt, ActionError as E, fontsOf as En, SHAPE_TYPES as Et, ParsedTimeRef as F, shadersOf as Fn, TRANSITION_TYPES as Ft, ResolvedTheme as G, assetIdOf as Gn, zEasing as Gt, ResolvedTrack as H, SubjectBox as Hn, isKeyframeProperty as Ht, TimeRef as I, usesShaders as In, TrackFlag as It, Themed as J, zKeyframeProperty as Jt, ThemeIssue as K, lookupAsset as Kn, zFitMode as Kt, isTimeRefString as L, AssetEntry as Ln, TrackLayout as Lt, nodeOfSpec as M, defineEffect as Mn, TRACK_FLAGS as Mt, nodeSpecOf as N, defineTransition as Nn, TRACK_LAYOUTS as Nt, NodeSpec as O, isBundledFont as On, TEXT_ALIGNS as Ot, ok as P, shaderFor as Pn, TRACK_ROLES as Pt, DEFAULT_THEME as Q, zTrackLayout as Qt, parseTimeRef as R, AssetManifest as Rn, TrackRole as Rt, TransformActions as S, FontStyle as Sn, KEYFRAME_PROPERTIES as St, targetIdOf as T, font as Tn, MASK_TYPES as Tt, resolve as U, TranscriptWord as Un, zBlendMode as Ut, ResolvedState as V, Silence as Vn, VideoEffectType as Vt, samePlacement as W, WaveformSummary as Wn, zCaptionAnimation as Wt, resolveTheme as X, zShapeType as Xt, applyTheme as Y, zMaskEasing as Yt, themeToken as Z, zTextAnimationPreset as Zt, OverlayActions as _, BUNDLED_FONTS as _n, EASINGS as _t, ActionType as a, PatchLog as an, PALETTE_KEYS as at, TARGET_PARAM_KEYS as b, DeclaredFont as bn, FitMode as bt, ClipActions as c, CollectedTree as cn, THEME_NAMES as ct, KeyframeActions as d, LayerInterior as dn, ANIMATION_UNITS as dt, zTransitionType as en, MOTIONS as et, LayerActions as f, findParentOf as fn, AUTOMATION_LANES as ft, Namespace as g, isResolveError as gn, CAPTION_POSITIONS as gt, MulticamActions as h, ResolveErrorCode as hn, CAPTION_ANIMATIONS as ht, ActionMap as i, Patch as in, MotionStyle as it, invalid as j, collectShaders as jn, TEXT_VALIGNS as jt, PlacementSpec as k, MODULE_SHADERS as kn, TEXT_ANIMATION_PRESETS as kt, CompositionActions as l, Editable as ln, ThemeDefinition as lt, MaskActions as m, ResolveError as mn, BlendMode as mt, Action as n, Json as nn, MotionAnimation as nt, AudioActions as o, Presence as on, Presets as ot, MarkerActions as p, walk as pn, BLEND_MODES as pt, ThemeOrigin as q, zGraphicAnimation as qt, ActionInput as r, NetPatch as rn, MotionName as rt, CaptionActions as s, CollectedNode as sn, THEMES as st, AUTO_GROUP_TYPES as t, zVideoEffectType as tn, MOTION_NAMES as tt, EffectActions as u, INTERIOR_PREFIX as un, ThemeName as ut, SourceActions as v, BUNDLED_FONT_WEIGHTS as vn, Easing as vt, describeAction as w, collectFonts as wn, MASK_EASINGS as wt, TrackActions as x, FontSource as xn, GRAPHIC_ANIMATIONS as xt, SpeedActions as y, BundledFont as yn, FIT_MODES as yt, resolveTimeRef as z, EMPTY_MANIFEST as zn, TransitionType as zt };