@pixerate/flair 0.19.0 → 0.20.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/dist/cli.js CHANGED
@@ -3,11 +3,11 @@ import {
3
3
  standaloneHtml,
4
4
  standaloneSceneHtml,
5
5
  validateScene
6
- } from "./chunk-HP7CYHS5.js";
6
+ } from "./chunk-NGKNI3QX.js";
7
7
  import {
8
8
  simulateScene
9
9
  } from "./chunk-WAMA45G3.js";
10
- import "./chunk-HA6FIMH2.js";
10
+ import "./chunk-ARKC7LDW.js";
11
11
  import "./chunk-EHDJ3CPJ.js";
12
12
  import "./chunk-WMZQCUFJ.js";
13
13
  import {
@@ -1,11 +1,11 @@
1
- import { g as VectorControl, d as EffectPreset, E as EffectDefinition } from '../types-Cl5n9s-3.js';
1
+ import { g as VectorControl, d as EffectPreset, E as EffectDefinition } from '../types-CawMRRXq.js';
2
2
  import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-Ec6P0Vpy.js';
3
3
  import { S as SvgMotion, C as Clock } from '../svg-BEOJriIW.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-Cn4_d5Qs.js';
8
+ import { C as CompileError, a as CompileStatus } from '../renderer-C2P1qGzP.js';
9
9
  import { AgentToolProvider, McpToolResult, ToolRegistryOptions, ToolRegistry, McpToolDefinition } from '@pixerate/editor/tools';
10
10
  import { ParameterImageOption, ParametersController, ParameterField, ParameterSchema, ParameterValue, ParameterValues } from '@pixerate/editor/parameters';
11
11
 
@@ -6,7 +6,7 @@ import {
6
6
  renderVectorEffect,
7
7
  vectorControlIssues,
8
8
  vectorEffectControls
9
- } from "../chunk-WEDILTUN.js";
9
+ } from "../chunk-TCNONB22.js";
10
10
  import {
11
11
  svgMotionIssues,
12
12
  svgView
@@ -15,7 +15,7 @@ import "../chunk-OHW7UG6D.js";
15
15
  import {
16
16
  BUILTIN_UNIFORMS,
17
17
  interpolateOklab
18
- } from "../chunk-HA6FIMH2.js";
18
+ } from "../chunk-ARKC7LDW.js";
19
19
  import "../chunk-EHDJ3CPJ.js";
20
20
  import {
21
21
  realClock
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { C as ControlValue, a as ControlDef } from './controls-Ec6P0Vpy.js';
2
2
  export { c as ControlCheck, b as ControlType, T as TextureSettings, d as checkControlValue, e as coerceControlValue, f as componentCount, g as controlValue, h as describeValue, i as hexToRgb, j as humanise, k as imageUrls, l as isImageUrl, p as parseColor, m as parseControls, r as rgbToHex } from './controls-Ec6P0Vpy.js';
3
- import { L as LiveSource } from './renderer-Cn4_d5Qs.js';
4
- export { B as BUILTIN_UNIFORMS, C as CompileError, b as CompileResult, a as CompileStatus, c as CompiledShader, F as FrameState, I as ImageLoadError, R as RendererStats, S as SVG_EDGE, d as ShaderCompileError, e as ShaderRenderer, f as ShaderRendererOptions, T as TextureCache, g as TextureSource, V as VERTEX_SOURCE, h as applyTextureSettings, i as compileShader, j as createContext, k as drawFrame, l as formatCompileError, m as isSvgUrl, n as loadImage, p as parseCompileLog, o as preloadImages, r as releaseImages, q as resetGlCaches, s as seekVideo, t as sizeSvg, w as wrapSource } from './renderer-Cn4_d5Qs.js';
3
+ import { L as LiveSource } from './renderer-C2P1qGzP.js';
4
+ export { B as BUILTIN_UNIFORMS, C as CompileError, b as CompileResult, a as CompileStatus, c as CompiledShader, F as FrameState, I as ImageLoadError, R as RendererStats, S as SVG_EDGE, d as ShaderCompileError, e as ShaderRenderer, f as ShaderRendererOptions, T as TextureCache, g as TextureSource, V as VERTEX_SOURCE, h as applyTextureSettings, i as compileShader, j as createContext, k as drawFrame, l as formatCompileError, m as isSvgUrl, n as loadImage, p as parseCompileLog, o as preloadImages, r as releaseImages, q as resetGlCaches, s as seekVideo, t as sizeSvg, w as wrapSource } from './renderer-C2P1qGzP.js';
5
5
  import { C as Clock } from './svg-BEOJriIW.js';
6
6
  export { A as AnimateCountOptions, D as DataKey, E as EASES, c as EaseName, M as ManualClock, d as SCRAMBLE_MS, e as STEP_MS, f as SVG_PICTURE, g as SvgAnimation, h as SvgBox, i as SvgElementFrame, S as SvgMotion, b as SvgPlayer, j as SvgPlayerOptions, a as SvgTrigger, k as SvgView, l as SvgViewOptions, m as animateCount, n as defaultDataKey, o as formatCount, p as jitter, q as lerpAttr, r as lerpData, s as pageHidden, t as parseSvg, u as realClock, v as stepData, w as stepProgress, x as stepStart, y as svgDuration, z as svgFrame, B as svgMotionIssues, F as svgOpeningTag, G as svgView, H as writtenText } from './svg-BEOJriIW.js';
7
7
  export { BoxAlignment, BoxFit, FittedBoxResult, FormatUnitOptions, MorphOptions, StackLayoutOptions, SvgFrameMarkupOptions, SvgInlineLayout, UnitFormat, computeBoxFit, formatUnit, layoutStack, morphPaths, morphSequence, parseViewBox, remap, stepVariant, svgFrameMarkup, svgInlineLayout, svgViewBox } from './vector/index.js';
@@ -87,15 +87,23 @@ declare function registerThumbnail(canvas: HTMLCanvasElement, source: string, va
87
87
  /**
88
88
  * The pointer as shaders see it, beyond Shadertoy's `iMouse`: where it is
89
89
  * while it is over the canvas, how hovered the canvas is (eased in and out),
90
- * how long it has been pressed, and the last few clicks, so effects can
91
- * answer hovers, presses and taps. Times are in `iTime` seconds, so a
92
- * recording can script them (see `ShaderFrames`' `pointer` and `clicks`).
90
+ * how long it has been pressed, the last few clicks, and where it has just
91
+ * been (its trail), so effects can answer hovers, presses, taps and moves.
92
+ * Times are in `iTime` seconds, so a recording can script them (see
93
+ * `ShaderFrames`' `pointer`, `clicks` and `trail`).
93
94
  */
94
95
  /** How many clicks `iClicks` holds; older ones drop off. */
95
96
  declare const MAX_CLICKS = 8;
97
+ /** How many of the pointer's recent positions `iTrail` holds; older ones drop off. */
98
+ declare const MAX_TRAIL = 32;
99
+ /**
100
+ * The least time between two positions in the trail, in seconds: moves in
101
+ * between update the newest. With {@link MAX_TRAIL}, about a second of path.
102
+ */
103
+ declare const TRAIL_SECONDS: number;
96
104
  /** How long hovering eases in or out, in seconds. */
97
105
  declare const HOVER_SECONDS = 0.25;
98
- /** A click: where (pixels from the bottom left, like `iMouse`) and when (`iTime` seconds). */
106
+ /** A click, or a point of the trail: where (pixels from the bottom left, like `iMouse`) and when (`iTime` seconds). */
99
107
  interface ShaderClick {
100
108
  x: number;
101
109
  y: number;
@@ -106,6 +114,12 @@ interface ShaderClick {
106
114
  * each click at or before `time`, zeros for the rest.
107
115
  */
108
116
  declare function clicksUniform(clicks: readonly ShaderClick[], time: number): Float32Array;
117
+ /**
118
+ * `iTrail` from the pointer's positions, oldest first in the list: the
119
+ * newest {@link MAX_TRAIL} at or before `time`, newest first, as
120
+ * `vec4(x, y, time, 1)`, zeros for the rest.
121
+ */
122
+ declare function trailUniform(trail: readonly ShaderClick[], time: number): Float32Array;
109
123
  /**
110
124
  * Follows one canvas's pointer for `iPointer` and `iClicks`: feed it pointer
111
125
  * events with the `iTime` they happen at, and read the uniforms for a frame.
@@ -119,14 +133,19 @@ declare class PointerTracker {
119
133
  private pressedAt;
120
134
  private releasedAt;
121
135
  private clicks;
122
- /** The pointer moved to (x, y), in pixels from the bottom left. */
123
- move(x: number, y: number): void;
136
+ private trail;
137
+ /**
138
+ * The pointer moved to (x, y), in pixels from the bottom left. With a
139
+ * `time`, the move joins the trail: a new point at most every
140
+ * {@link TRAIL_SECONDS}, the newest point following the pointer between.
141
+ */
142
+ move(x: number, y: number, time?: number): void;
124
143
  /** The pointer came over the canvas (`true`) or left it. */
125
144
  hover(over: boolean, time: number): void;
126
145
  /** A press at (x, y): counts as a click. */
127
146
  down(x: number, y: number, time: number): void;
128
147
  up(time: number): void;
129
- /** Forgets clicks and presses (when time jumps back, say). */
148
+ /** Forgets clicks, presses and the trail (when time jumps back, say). */
130
149
  clear(): void;
131
150
  /** How hovered the canvas is at `time`, 0–1, eased. */
132
151
  hovered(time: number): number;
@@ -138,6 +157,8 @@ declare class PointerTracker {
138
157
  pointer(time: number): [number, number, number, number];
139
158
  /** `iClicks` at `time` (see {@link clicksUniform}). */
140
159
  clicksAt(time: number): Float32Array;
160
+ /** `iTrail` at `time` (see {@link trailUniform}). */
161
+ trailAt(time: number): Float32Array;
141
162
  }
142
163
 
143
164
  interface ShaderFramesOptions {
@@ -161,6 +182,8 @@ interface RenderOptions {
161
182
  pointer?: [number, number, number, number];
162
183
  /** Clicks so far, for `iClicks` (the latest `MAX_CLICKS` at or before the frame's time count). */
163
184
  clicks?: readonly ShaderClick[];
185
+ /** Where the pointer has been, oldest first, for `iTrail` (the latest `MAX_TRAIL` at or before the frame's time count). */
186
+ trail?: readonly ShaderClick[];
164
187
  }
165
188
  /**
166
189
  * Renders a shader at exact times you choose, off screen. There is no
@@ -1703,4 +1726,4 @@ declare function exportFcp7Xml(scene: Scene, options?: Fcp7ExportOptions): strin
1703
1726
  */
1704
1727
  declare function exportCmx3600Edl(scene: Scene, options?: EdlExportOptions): string;
1705
1728
 
1706
- export { ALL_BLEND_MODES, ALL_TRANSITION_TYPES, type AgentToolDefinition, type AscCdl, type BatchCommand, type BatchExecutionResult, type BatchExecutionStepResult, type Behavior, type BehaviorBase, type BlendMode, type BlockDissolveOptions, type BlurEffect, type BurstEffect, CAMERA_MS, CAMERA_STEP_MS, COMMON_FRAME_RATES, type CameraAngle, type CameraLens, type CameraSample, type CameraShot, type ClearCommand, Clock, type ColorRGB, type ColorRGBA, type ColorRgba, type ColorSpace, ControlDef, ControlValue, type CounterEffect, type CrossZoomOptions, type CustomCommand, DEFAULT_PERSPECTIVE, DEFAULT_STAGE, type DeleteCommand, type DynamicFraming, EASY_EASE, EFFECT_FADE_MS, EFFECT_TYPES, type EasingCurve, type EdlExportOptions, type Effect, type EffectBase, type ElementCommand, FLAIR_AGENT_TOOLS, type Fcp7ExportOptions, type FlowEffect, type FramingOptions, type GifOptions, type GlassWipeOptions, type GlowEffect, type GradientEffect, type GridWipeOptions, HOVER_SECONDS, type HighlightEffect, type KeyframeEase, type LiftGammaGain, type LightLeakOptions, type LinearWipeOptions, LiveSource, type LottieAnimatable, type LottieAnimation, type LottieExportOptions, type LottieKeyframe, type LottieLayer, type LottieShapeItem, type LottieTransform, MAX_CLICKS, MAX_TILT, type MediaEffect, MemorySceneBoard, type MotnExportOptions, NO_CHECK, type OscillateBehavior, type OvershootBehavior, type PathWaypoint, type PlayOptions, type PlayResult, type Point, PointerTracker, type PopupWidget, type RadialIrisOptions, type RampBehavior, type RateBehavior, type RationalFrameRate, type Rect, type RenderOptions, type ReplicatorConfig, type ReplicatorPattern, type ReplicatorSequence, type Review, type ReviewOptions, type RigWidget, type RippleEffect, type RunningEffect, SMALL_TEXT_PX, type SMPTEFields, type Scene, type SceneBoard, type SceneCommand, type SceneElement, type SceneIssue, type SceneMedia, type SceneOutline, type SceneOutlineShot, type SceneRig, type SceneToolResult, type ShaderClick, ShaderFrames, type ShaderFramesOptions, type ShimmerEffect, type Shot, type ShotCamera, type ShotCheck, type ShotLog, type ShotTiming, type SliderSnapshot, type SliderWidget, type SpatialMotionPath, type SpatialPathSample, type SpotlightEffect, type Stage, type StandaloneOptions, type StandardFrameRateKey, type ThrowBehavior, type ThumbnailHandle, ThumbnailPool, type ThumbnailPoolOptions, type TimerEffect, type ToggleWidget, type TransitionOptions, type TransitionSample, type TransitionType, type TwisterOptions, type UpdateCommand, type Vec2, type Vec3, type View, type WriggleBehavior, applyAscCdl, applyLiftGammaGain, applyRig, applySceneBatch, applySceneTool, applyVibrance, areaOf, between, bez1d, bez1dDerivative, blendRgba, blendTransitionPixel, boardHeight, boundsOf, calculateFramingRect, calculateShotTimings, cameraAngle, cameraAt, cameraBlur, cameraFilter, cameraSamples, cameraTrack, cameraTransform, centreOf, checkShot, clicksUniform, convertColorSpace, createFrameRate, createLottieEase, createMotionPath, easeInOutCubic, easeProgress, effectGone, effectOpacity, evaluateBehavior, evaluateKeyframeSegment, expandReplicator, exportCmx3600Edl, exportFcp7Xml, exportLottie, exportMotn, formatTimecode, fractalWiggle, frame, framesToSMPTE, framesToTimecode, getColorGradingGLSL, getDropFrameCount, getGlslBlendFunction, getOklabGLSL, getTimecodeBase, getTransitionGLSL, getWhiteBalanceGains, hash64, holdTime, interpolateOklab, interpolateOklch, isAngled, isDeleteCommand, isElementCommand, isUpdateCommand, linearRgbToSrgb, linearSrgbToOklab, linearToSrgb, loopTime, mixSeeds, motionBlur, motionBlurAngle, moveBlur, noise1d, noise3d, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToOklab, overlapArea, parseTimecode, pingPongTime, playScene, projectPoint, quinticFade, recordGif, registerThumbnail, reviewScene, sampleMotionPath, sampleMotionPathAtTime, sampleTransition, sceneStage, screenBox, setRigWidget, sharedThumbnailPool, shotView, simulateScene, smpteToFrames, solveBezierU, speedRampTime, srgbToLinear, srgbToLinearRgb, srgbToOklab, standaloneHtml, standaloneSceneHtml, strobeTime, substituteVariables, supportsDropFrame, timecodeToFrames, titleBox, touchedIds, unitFloat, validateScene, viewAt, visibleRect };
1729
+ export { ALL_BLEND_MODES, ALL_TRANSITION_TYPES, type AgentToolDefinition, type AscCdl, type BatchCommand, type BatchExecutionResult, type BatchExecutionStepResult, type Behavior, type BehaviorBase, type BlendMode, type BlockDissolveOptions, type BlurEffect, type BurstEffect, CAMERA_MS, CAMERA_STEP_MS, COMMON_FRAME_RATES, type CameraAngle, type CameraLens, type CameraSample, type CameraShot, type ClearCommand, Clock, type ColorRGB, type ColorRGBA, type ColorRgba, type ColorSpace, ControlDef, ControlValue, type CounterEffect, type CrossZoomOptions, type CustomCommand, DEFAULT_PERSPECTIVE, DEFAULT_STAGE, type DeleteCommand, type DynamicFraming, EASY_EASE, EFFECT_FADE_MS, EFFECT_TYPES, type EasingCurve, type EdlExportOptions, type Effect, type EffectBase, type ElementCommand, FLAIR_AGENT_TOOLS, type Fcp7ExportOptions, type FlowEffect, type FramingOptions, type GifOptions, type GlassWipeOptions, type GlowEffect, type GradientEffect, type GridWipeOptions, HOVER_SECONDS, type HighlightEffect, type KeyframeEase, type LiftGammaGain, type LightLeakOptions, type LinearWipeOptions, LiveSource, type LottieAnimatable, type LottieAnimation, type LottieExportOptions, type LottieKeyframe, type LottieLayer, type LottieShapeItem, type LottieTransform, MAX_CLICKS, MAX_TILT, MAX_TRAIL, type MediaEffect, MemorySceneBoard, type MotnExportOptions, NO_CHECK, type OscillateBehavior, type OvershootBehavior, type PathWaypoint, type PlayOptions, type PlayResult, type Point, PointerTracker, type PopupWidget, type RadialIrisOptions, type RampBehavior, type RateBehavior, type RationalFrameRate, type Rect, type RenderOptions, type ReplicatorConfig, type ReplicatorPattern, type ReplicatorSequence, type Review, type ReviewOptions, type RigWidget, type RippleEffect, type RunningEffect, SMALL_TEXT_PX, type SMPTEFields, type Scene, type SceneBoard, type SceneCommand, type SceneElement, type SceneIssue, type SceneMedia, type SceneOutline, type SceneOutlineShot, type SceneRig, type SceneToolResult, type ShaderClick, ShaderFrames, type ShaderFramesOptions, type ShimmerEffect, type Shot, type ShotCamera, type ShotCheck, type ShotLog, type ShotTiming, type SliderSnapshot, type SliderWidget, type SpatialMotionPath, type SpatialPathSample, type SpotlightEffect, type Stage, type StandaloneOptions, type StandardFrameRateKey, TRAIL_SECONDS, type ThrowBehavior, type ThumbnailHandle, ThumbnailPool, type ThumbnailPoolOptions, type TimerEffect, type ToggleWidget, type TransitionOptions, type TransitionSample, type TransitionType, type TwisterOptions, type UpdateCommand, type Vec2, type Vec3, type View, type WriggleBehavior, applyAscCdl, applyLiftGammaGain, applyRig, applySceneBatch, applySceneTool, applyVibrance, areaOf, between, bez1d, bez1dDerivative, blendRgba, blendTransitionPixel, boardHeight, boundsOf, calculateFramingRect, calculateShotTimings, cameraAngle, cameraAt, cameraBlur, cameraFilter, cameraSamples, cameraTrack, cameraTransform, centreOf, checkShot, clicksUniform, convertColorSpace, createFrameRate, createLottieEase, createMotionPath, easeInOutCubic, easeProgress, effectGone, effectOpacity, evaluateBehavior, evaluateKeyframeSegment, expandReplicator, exportCmx3600Edl, exportFcp7Xml, exportLottie, exportMotn, formatTimecode, fractalWiggle, frame, framesToSMPTE, framesToTimecode, getColorGradingGLSL, getDropFrameCount, getGlslBlendFunction, getOklabGLSL, getTimecodeBase, getTransitionGLSL, getWhiteBalanceGains, hash64, holdTime, interpolateOklab, interpolateOklch, isAngled, isDeleteCommand, isElementCommand, isUpdateCommand, linearRgbToSrgb, linearSrgbToOklab, linearToSrgb, loopTime, mixSeeds, motionBlur, motionBlurAngle, moveBlur, noise1d, noise3d, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToOklab, overlapArea, parseTimecode, pingPongTime, playScene, projectPoint, quinticFade, recordGif, registerThumbnail, reviewScene, sampleMotionPath, sampleMotionPathAtTime, sampleTransition, sceneStage, screenBox, setRigWidget, sharedThumbnailPool, shotView, simulateScene, smpteToFrames, solveBezierU, speedRampTime, srgbToLinear, srgbToLinearRgb, srgbToOklab, standaloneHtml, standaloneSceneHtml, strobeTime, substituteVariables, supportsDropFrame, timecodeToFrames, titleBox, touchedIds, trailUniform, unitFloat, validateScene, viewAt, visibleRect };
package/dist/index.js CHANGED
@@ -60,7 +60,7 @@ import {
60
60
  standaloneHtml,
61
61
  standaloneSceneHtml,
62
62
  validateScene
63
- } from "./chunk-HP7CYHS5.js";
63
+ } from "./chunk-NGKNI3QX.js";
64
64
  import {
65
65
  CAMERA_MS,
66
66
  CAMERA_STEP_MS,
@@ -123,9 +123,11 @@ import {
123
123
  HOVER_SECONDS,
124
124
  ImageLoadError,
125
125
  MAX_CLICKS,
126
+ MAX_TRAIL,
126
127
  PointerTracker,
127
128
  SVG_EDGE,
128
129
  ShaderCompileError,
130
+ TRAIL_SECONDS,
129
131
  TextureCache,
130
132
  VERTEX_SOURCE,
131
133
  applyAscCdl,
@@ -161,8 +163,9 @@ import {
161
163
  srgbToLinear,
162
164
  srgbToLinearRgb,
163
165
  srgbToOklab,
166
+ trailUniform,
164
167
  wrapSource
165
- } from "./chunk-HA6FIMH2.js";
168
+ } from "./chunk-ARKC7LDW.js";
166
169
  import {
167
170
  ALL_TRANSITION_TYPES,
168
171
  blendTransitionPixel,
@@ -1187,6 +1190,7 @@ export {
1187
1190
  ImageLoadError,
1188
1191
  MAX_CLICKS,
1189
1192
  MAX_TILT,
1193
+ MAX_TRAIL,
1190
1194
  ManualClock,
1191
1195
  MemorySceneBoard,
1192
1196
  NO_CHECK,
@@ -1200,6 +1204,7 @@ export {
1200
1204
  ShaderFrames,
1201
1205
  ShaderRenderer,
1202
1206
  SvgPlayer,
1207
+ TRAIL_SECONDS,
1203
1208
  TextureCache,
1204
1209
  ThumbnailPool,
1205
1210
  VERTEX_SOURCE,
@@ -1363,6 +1368,7 @@ export {
1363
1368
  timecodeToFrames,
1364
1369
  titleBox,
1365
1370
  touchedIds,
1371
+ trailUniform,
1366
1372
  unitFloat,
1367
1373
  validateScene,
1368
1374
  viewAt,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/time/retiming.ts","../src/time/keyframe.ts","../src/time/timecode.ts","../src/scene/rig.ts","../src/scene/replicator.ts","../src/scene/motionpath.ts","../src/agent/tools.ts","../src/agent/batch.ts"],"sourcesContent":["/**\n * Retiming math engine inspired by Apple Motion's RetimingMath framework.\n * Provides deterministic time transformation functors for looping, bouncing (ping-pong),\n * freezing (hold), posterizing/stepping (strobe), and non-linear speed ramps.\n */\n\nexport type EasingCurve = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';\n\n/**\n * Loops time within [start, start + duration).\n * Handles negative time values smoothly.\n */\nexport function loopTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const rel = t - start;\n const mod = ((rel % duration) + duration) % duration;\n return start + mod;\n}\n\n/**\n * Reflects time back and forth (triangle wave) between start and start + duration.\n */\nexport function pingPongTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const period = 2 * duration;\n const rel = t - start;\n const mod = ((rel % period) + period) % period;\n const offset = mod <= duration ? mod : period - mod;\n return start + offset;\n}\n\n/**\n * Freezes time at a specified timestamp.\n */\nexport function holdTime(_t: number, holdAt: number): number {\n return holdAt;\n}\n\n/**\n * Quantizes continuous time into discrete intervals matching a target frame rate (posterize time).\n * @param t Current timestamp.\n * @param fps Target stepped frame rate (e.g. 12 for stop-motion).\n * @param unit 'ms' (default) if t is in milliseconds, or 'sec' if t is in seconds.\n */\nexport function strobeTime(t: number, fps: number, unit: 'ms' | 'sec' = 'ms'): number {\n if (fps <= 0) return t;\n const interval = (unit === 'ms' ? 1000 : 1) / fps;\n return Math.floor(t / interval) * interval;\n}\n\n/**\n * Applies a non-linear speed ramp curve to time progression within an interval [start, start + duration].\n */\nexport function speedRampTime(\n t: number,\n start: number,\n duration: number,\n ease: EasingCurve = 'easeInOut',\n): number {\n if (duration <= 0 || t <= start) return t;\n if (t >= start + duration) return t;\n\n const p = (t - start) / duration;\n let eased: number;\n switch (ease) {\n case 'linear':\n eased = p;\n break;\n case 'easeIn':\n eased = p * p;\n break;\n case 'easeOut':\n eased = p * (2 - p);\n break;\n case 'easeInOut':\n default:\n eased = p < 0.5 ? 2 * p * p : -1 + (4 - 2 * p) * p;\n break;\n }\n\n return start + eased * duration;\n}\n","/**\n * Keyframe velocity and cubic Bezier easing engine matching Adobe After Effects interpolation semantics.\n *\n * Temporal interpolation between two keyframes is characterized by:\n * - Speed (units / second)\n * - Influence (fraction 0..1, corresponding to 0.1%..100% in the Keyframe Velocity dialog)\n *\n * For normalized values going from 0 to 1 over a segment, easeProgress(outSpeedNorm, outInf, inSpeedNorm, inInf, x)\n * solves the monotone cubic Bezier root x(u) = x and computes value y(u).\n */\n\nexport interface KeyframeEase {\n /** Speed in value units per second (or normalized speed if evaluating normalized segment). */\n speed: number;\n /** Influence as a fraction between 0.0 and 1.0 (e.g. 0.3333 for 33.33%). */\n influence: number;\n}\n\n/** Easy Ease preset: 0 speed, 33.333% influence. */\nexport const EASY_EASE: KeyframeEase = {\n speed: 0,\n influence: 1 / 3,\n};\n\n/** Evaluates a 1D cubic Bezier polynomial at parameter u in [0, 1]. */\nexport function bez1d(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return v * v * v * p0 + 3.0 * v * v * u * p1 + 3.0 * v * u * u * p2 + u * u * u * p3;\n}\n\n/** Evaluates the first derivative of a 1D cubic Bezier polynomial at parameter u. */\nexport function bez1dDerivative(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return 3.0 * v * v * (p1 - p0) + 6.0 * v * u * (p2 - p1) + 3.0 * u * u * (p3 - p2);\n}\n\n/**\n * Solves bez1d(x0, x1, x2, x3, u) = x for u in [0, 1] assuming x(u) is monotone.\n * Uses closed-form inverse for 100% influence midpoint, Newton-Raphson iteration,\n * and high-precision bisection fallback.\n */\nexport function solveBezierU(x0: number, x1: number, x2: number, x3: number, x: number): number {\n if (x <= x0) return 0.0;\n if (x >= x3) return 1.0;\n\n // Closed-form solution for 100% influence on both sides (x1 === x3 && x2 === x0).\n // x(u) = x0 + (x3 - x0) * (0.5 + 4 * (u - 0.5)^3)\n if (Math.abs(x1 - x3) < 1e-12 && Math.abs(x2 - x0) < 1e-12) {\n const progress = (x - x0) / (x3 - x0);\n return 0.5 + Math.cbrt((progress - 0.5) * 0.25);\n }\n\n // Initial estimate\n let u = (x - x0) / (x3 - x0);\n\n // Up to 8 Newton-Raphson iterations\n for (let iter = 0; iter < 8; iter++) {\n const f = bez1d(x0, x1, x2, x3, u) - x;\n const d = bez1dDerivative(x0, x1, x2, x3, u);\n if (Math.abs(d) < 1e-12) break;\n if (Math.abs(f / d) < 1e-12) return u;\n const nextU = u - f / d;\n if (nextU < 0.0 || nextU > 1.0) break;\n u = nextU;\n }\n\n // Bisection fallback for robustness\n let lo = 0.0;\n let hi = 1.0;\n for (let iter = 0; iter < 60; iter++) {\n const mid = (lo + hi) * 0.5;\n if (bez1d(x0, x1, x2, x3, mid) < x) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return (lo + hi) * 0.5;\n}\n\n/**\n * Fraction of progress 0..1 through a 1D Bezier temporal segment whose value goes from 0 to 1,\n * with normalized out/in speeds (speed * duration / deltaValue) and influences.\n *\n * @param outSpeedNorm Normalized outgoing speed (speed * duration / deltaValue).\n * @param outInfluence Outgoing influence fraction [0, 1].\n * @param inSpeedNorm Normalized incoming speed (speed * duration / deltaValue).\n * @param inInfluence Incoming influence fraction [0, 1].\n * @param x Normalized time progress in segment [0, 1].\n */\nexport function easeProgress(\n outSpeedNorm: number,\n outInfluence: number,\n inSpeedNorm: number,\n inInfluence: number,\n x: number,\n): number {\n const i0 = Math.min(1.0, Math.max(0.0, outInfluence));\n const i1 = Math.min(1.0, Math.max(0.0, inInfluence));\n const u = solveBezierU(0.0, i0, 1.0 - i1, 1.0, x);\n return bez1d(0.0, outSpeedNorm * i0, 1.0 - inSpeedNorm * i1, 1.0, u);\n}\n\n/**\n * Evaluates an interpolated keyframe segment between two values over duration.\n *\n * @param from Starting value at t = 0.\n * @param to Ending value at t = duration.\n * @param duration Duration of the keyframe segment in seconds.\n * @param t Current elapsed time in seconds (0 <= t <= duration).\n * @param outEase Outgoing ease specification at start keyframe.\n * @param inEase Incoming ease specification at end keyframe.\n */\nexport function evaluateKeyframeSegment(\n from: number,\n to: number,\n duration: number,\n t: number,\n outEase: KeyframeEase = EASY_EASE,\n inEase: KeyframeEase = EASY_EASE,\n): number {\n if (duration <= 0 || t <= 0) return from;\n if (t >= duration) return to;\n\n const delta = to - from;\n const x = t / duration;\n\n // Zero delta: maintain from\n if (Math.abs(delta) < 1e-12) {\n return from;\n }\n\n const outSpeedNorm = (outEase.speed * duration) / delta;\n const inSpeedNorm = (inEase.speed * duration) / delta;\n\n const progress = easeProgress(outSpeedNorm, outEase.influence, inSpeedNorm, inEase.influence, x);\n return from + progress * delta;\n}\n","/**\n * SMPTE 12M Timecode engine and broadcast frame-rate converter.\n *\n * Supports non-drop-frame (NDF) and drop-frame (DF) timecode for broadcast standards\n * (23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60, 120 fps).\n *\n * Drop-frame timecode drops frames 00 and 01 at the start of each minute,\n * except every 10th minute (e.g. 00:01:00;02 instead of 00:01:00;00).\n */\n\nexport interface RationalFrameRate {\n readonly num: number;\n readonly den: number;\n}\n\nexport const COMMON_FRAME_RATES = {\n FPS_23_976: { num: 24000, den: 1001 },\n FPS_24: { num: 24, den: 1 },\n FPS_25: { num: 25, den: 1 },\n FPS_29_97: { num: 30000, den: 1001 },\n FPS_30: { num: 30, den: 1 },\n FPS_48: { num: 48, den: 1 },\n FPS_50: { num: 50, den: 1 },\n FPS_59_94: { num: 60000, den: 1001 },\n FPS_60: { num: 60, den: 1 },\n FPS_120: { num: 120, den: 1 },\n} as const;\n\nexport type StandardFrameRateKey = keyof typeof COMMON_FRAME_RATES;\n\n/** Greatest common divisor helper. */\nfunction gcd(a: number, b: number): number {\n let x = Math.abs(Math.round(a));\n let y = Math.abs(Math.round(b));\n while (y !== 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x || 1;\n}\n\n/** Creates a reduced rational frame rate. */\nexport function createFrameRate(num: number, den = 1): RationalFrameRate {\n if (den <= 0 || num <= 0) {\n return { num: 30, den: 1 };\n }\n const g = gcd(num, den);\n return { num: Math.round(num / g), den: Math.round(den / g) };\n}\n\n/** Returns the timecode base (frames counted per second in timecode display). */\nexport function getTimecodeBase(rate: RationalFrameRate): number {\n return Math.ceil(rate.num / rate.den);\n}\n\n/** Whether a given frame rate supports drop-frame counting (29.97, 59.94, etc.). */\nexport function supportsDropFrame(rate: RationalFrameRate): boolean {\n return rate.den === 1001 && getTimecodeBase(rate) % 30 === 0;\n}\n\n/** Number of dropped frames per minute (e.g. 2 for 29.97, 4 for 59.94). */\nexport function getDropFrameCount(rate: RationalFrameRate): number {\n const base = getTimecodeBase(rate);\n return Math.floor(base / 15);\n}\n\nexport interface SMPTEFields {\n negative: boolean;\n hours: number;\n minutes: number;\n seconds: number;\n frames: number;\n}\n\n/**\n * Converts a continuous frame count to SMPTE fields (hours, minutes, seconds, frames).\n */\nexport function framesToSMPTE(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): SMPTEFields {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const neg = frame < 0;\n let n = Math.abs(Math.round(frame));\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n if (isDrop) {\n const perMinute = base * 60 - drop;\n const per10Minutes = perMinute * 10 + drop;\n const d = Math.floor(n / per10Minutes);\n const m = n % per10Minutes;\n\n n += drop * 9 * d;\n if (m > drop) {\n n += drop * Math.floor((m - drop) / perMinute);\n }\n }\n\n const frames = n % base;\n const seconds = Math.floor(n / base) % 60;\n const minutes = Math.floor(n / (base * 60)) % 60;\n const hours = Math.floor(n / (base * 3600));\n\n return { negative: neg, hours, minutes, seconds, frames };\n}\n\n/**\n * Converts SMPTE fields back to a continuous frame number.\n */\nexport function smpteToFrames(\n fields: { hours: number; minutes: number; seconds: number; frames: number },\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): number {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n const totalSecs = fields.hours * 3600 + fields.minutes * 60 + fields.seconds;\n let n = totalSecs * base + fields.frames;\n\n if (isDrop) {\n const totalMinutes = fields.hours * 60 + fields.minutes;\n n -= drop * (totalMinutes - Math.floor(totalMinutes / 10));\n }\n\n return n;\n}\n\n/**\n * Formats a frame number as standard SMPTE timecode (HH:MM:SS:FF or HH;MM;SS;FF).\n */\nexport function formatTimecode(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): string {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const { negative, hours, minutes, seconds, frames } = framesToSMPTE(frame, rate, isDrop);\n const sep = isDrop ? ';' : ':';\n const base = getTimecodeBase(rate);\n const frameWidth = base >= 100 ? 3 : 2;\n\n const hStr = String(hours).padStart(2, '0');\n const mStr = String(minutes).padStart(2, '0');\n const sStr = String(seconds).padStart(2, '0');\n const fStr = String(frames).padStart(frameWidth, '0');\n\n return `${negative ? '-' : ''}${hStr}${sep}${mStr}${sep}${sStr}${sep}${fStr}`;\n}\n\n/**\n * Parses user or NLE input into a frame number.\n * Supports:\n * - Standard timecodes: `01:00:00:00`, `01;00;00;00`, `00.01.20.15`\n * - Right-aligned numbers: `1000` -> `00:00:10:00`\n * - Relative offsets: `+15` (+15 frames), `-1.00` (-1 second)\n *\n * @param input The timecode string to parse.\n * @param rate Rational frame rate (default: 30 fps).\n * @param dropFrame Whether drop-frame arithmetic applies.\n * @param currentFrame Current playhead position for relative additions.\n */\nexport function parseTimecode(\n input: string,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n currentFrame = 0,\n): number {\n const s = input.trim();\n if (!s) {\n throw new Error('Empty timecode string');\n }\n\n let relativeSign: 1 | -1 | null = null;\n let body = s;\n if (s.startsWith('+')) {\n relativeSign = 1;\n body = s.slice(1);\n } else if (s.startsWith('-')) {\n relativeSign = -1;\n body = s.slice(1);\n }\n\n const parts = body.split(/[:;.,]/);\n let parsedFrame = 0;\n\n if (parts.length === 1) {\n const digits = parts[0]!;\n if (!/^\\d+$/.test(digits)) {\n throw new Error(`Invalid timecode: \"${input}\"`);\n }\n\n if (relativeSign !== null) {\n // Relative bare digits are treated as frames\n const count = parseInt(digits, 10);\n return currentFrame + relativeSign * count;\n }\n\n // Right-aligned pairs: e.g. \"1000\" -> HH=0, MM=0, SS=10, FF=0\n const nums: number[] = [];\n let end = digits.length;\n while (end > 0) {\n const start = Math.max(0, end - 2);\n nums.unshift(parseInt(digits.slice(start, end), 10));\n end = start;\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n } else {\n if (parts.length > 4) {\n throw new Error(`Too many timecode fields in \"${input}\"`);\n }\n const nums = parts.map((p) => (p.length === 0 ? 0 : parseInt(p, 10)));\n if (nums.some((n) => isNaN(n))) {\n throw new Error(`Invalid number in timecode: \"${input}\"`);\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n }\n\n if (relativeSign !== null) {\n return currentFrame + relativeSign * parsedFrame;\n }\n\n return parsedFrame;\n}\n","import type { Scene } from './types.js';\n\nexport interface SliderSnapshot {\n at: number;\n values: Record<string, number | string>;\n}\n\nexport interface SliderWidget {\n type: 'slider';\n name: string;\n value: number;\n snapshots: SliderSnapshot[];\n}\n\nexport interface PopupWidget {\n type: 'popup';\n name: string;\n selected: string;\n options: Record<string, Record<string, number | string>>;\n}\n\nexport interface ToggleWidget {\n type: 'toggle';\n name: string;\n enabled: boolean;\n on: Record<string, number | string>;\n off: Record<string, number | string>;\n}\n\nexport type RigWidget = SliderWidget | PopupWidget | ToggleWidget;\n\nexport interface SceneRig {\n widgets: Record<string, RigWidget>;\n}\n\n/**\n * Updates a widget within a SceneRig and returns the updated SceneRig.\n */\nexport function setRigWidget(\n rig: SceneRig,\n widgetName: string,\n value: number | string | boolean,\n): SceneRig {\n const widget = rig.widgets[widgetName];\n if (!widget) {\n throw new Error(`Rig widget \"${widgetName}\" not found.`);\n }\n\n const updatedWidgets = { ...rig.widgets };\n\n if (widget.type === 'slider') {\n if (typeof value !== 'number') {\n throw new Error(`Slider widget \"${widgetName}\" expects numeric value.`);\n }\n updatedWidgets[widgetName] = { ...widget, value };\n } else if (widget.type === 'popup') {\n if (typeof value !== 'string') {\n throw new Error(`Popup widget \"${widgetName}\" expects string value.`);\n }\n updatedWidgets[widgetName] = { ...widget, selected: value };\n } else if (widget.type === 'toggle') {\n if (typeof value !== 'boolean') {\n throw new Error(`Toggle widget \"${widgetName}\" expects boolean value.`);\n }\n updatedWidgets[widgetName] = { ...widget, enabled: value };\n }\n\n return { widgets: updatedWidgets };\n}\n\n/**\n * Evaluates resolved values for a given widget.\n */\nfunction resolveWidgetValues(widget: RigWidget): Record<string, number | string> {\n if (widget.type === 'popup') {\n return widget.options[widget.selected] ?? {};\n }\n\n if (widget.type === 'toggle') {\n return widget.enabled ? widget.on : widget.off;\n }\n\n if (widget.type === 'slider') {\n const { snapshots, value } = widget;\n if (!snapshots || snapshots.length === 0) return {};\n\n const sorted = [...snapshots].sort((a, b) => a.at - b.at);\n if (value <= sorted[0]!.at) {\n return { ...sorted[0]!.values };\n }\n if (value >= sorted[sorted.length - 1]!.at) {\n return { ...sorted[sorted.length - 1]!.values };\n }\n\n // Find bounding snapshots\n let idx = 0;\n while (idx < sorted.length - 1 && sorted[idx + 1]!.at < value) {\n idx++;\n }\n\n const s0 = sorted[idx]!;\n const s1 = sorted[idx + 1]!;\n const span = s1.at - s0.at;\n const t = span > 0 ? (value - s0.at) / span : 0;\n\n const result: Record<string, number | string> = {};\n const allKeys = new Set([...Object.keys(s0.values), ...Object.keys(s1.values)]);\n\n for (const k of allKeys) {\n const v0 = s0.values[k];\n const v1 = s1.values[k];\n if (typeof v0 === 'number' && typeof v1 === 'number') {\n result[k] = v0 + (v1 - v0) * t;\n } else if (v0 !== undefined && v1 !== undefined) {\n result[k] = t < 0.5 ? v0 : v1;\n } else {\n result[k] = v1 !== undefined ? v1 : (v0 as number | string);\n }\n }\n\n return result;\n }\n\n return {};\n}\n\n/**\n * Propagates rig widget state into the scene's shader uniforms and elements.\n */\nexport function applyRig(rig: SceneRig, scene: Scene): Scene {\n // Deep clone media and shots to prevent mutation\n const nextMedia: Record<string, any> = {};\n if (scene.media) {\n for (const [id, m] of Object.entries(scene.media)) {\n nextMedia[id] = {\n ...m,\n values: { ...(m.values ?? {}) },\n };\n }\n }\n\n const nextShots = scene.shots.map((shot) => {\n if (!shot.run) return { ...shot };\n return {\n ...shot,\n run: shot.run.map((cmd) => {\n if (cmd.type === 'element' && 'element' in cmd && cmd.element) {\n return { ...cmd, element: { ...cmd.element } };\n }\n if (cmd.type === 'update' && 'props' in cmd && (cmd as any).props) {\n return { ...cmd, props: { ...(cmd as any).props } };\n }\n return { ...cmd };\n }),\n };\n });\n\n // Collect all resolved values across all widgets in the rig\n const resolvedAll: Record<string, number | string> = {};\n for (const widget of Object.values(rig.widgets)) {\n Object.assign(resolvedAll, resolveWidgetValues(widget));\n }\n\n // Apply resolved values\n for (const [targetKey, val] of Object.entries(resolvedAll)) {\n if (targetKey.startsWith('media.')) {\n const parts = targetKey.split('.');\n const mediaId = parts[1]!;\n const prop = parts.length > 3 && parts[2] === 'values' ? parts[3]! : parts[2]!;\n if (nextMedia[mediaId]) {\n nextMedia[mediaId].values[prop] = val;\n }\n } else if (targetKey.startsWith('element.')) {\n const parts = targetKey.split('.');\n const elId = parts[1]!;\n const prop = parts[2]!;\n for (const shot of nextShots) {\n if (shot.run) {\n for (const cmd of shot.run) {\n if (cmd.type === 'element' && 'element' in cmd && (cmd as any).element?.id === elId) {\n (cmd.element as any)[prop] = val;\n } else if (cmd.type === 'update' && 'id' in cmd && cmd.id === elId) {\n (cmd as any).props[prop] = val;\n }\n }\n }\n }\n } else {\n // General uniform shorthand: uniforms.<name> or simply <name>\n const uniformName = targetKey.replace(/^uniforms\\./, '');\n for (const m of Object.values(nextMedia)) {\n m.values[uniformName] = val;\n }\n }\n }\n\n return {\n ...scene,\n media: Object.keys(nextMedia).length > 0 ? nextMedia : scene.media,\n shots: nextShots,\n rig,\n };\n}\n","import type { SceneElement } from './geometry.js';\n\nexport type ReplicatorPattern = 'grid' | 'line' | 'circle' | 'spiral';\n\nexport interface ReplicatorSequence {\n /** Property to modulate per item. */\n property?: 'opacity' | 'rotation' | 'scale' | 'x' | 'y';\n /** Incremental offset or delta added per instance. */\n offset?: number;\n /** Milliseconds delay per instance for staggered triggers. */\n delayPerItem?: number;\n}\n\nexport interface ReplicatorConfig {\n pattern: ReplicatorPattern;\n count: number;\n /** Origin point [x, y] to anchor the layout (defaults to prototype.x, prototype.y). */\n origin?: [number, number];\n\n // Grid options\n columns?: number;\n rows?: number;\n columnSpacing?: number;\n rowSpacing?: number;\n\n // Line options\n startPoint?: [number, number];\n endPoint?: [number, number];\n spacing?: number;\n\n // Circle / Spiral options\n radius?: number;\n startAngle?: number; // radians\n spiralTightness?: number; // radius expansion per instance\n\n // Sequence modulation\n sequence?: ReplicatorSequence;\n}\n\n/**\n * Procedurally replicates a prototype SceneElement into an array of positioned\n * and sequenced instances (grid, circular array, line, or spiral).\n */\nexport function expandReplicator(\n prototype: SceneElement,\n config: ReplicatorConfig,\n): SceneElement[] {\n const count = Math.max(0, Math.floor(config.count));\n if (count === 0) return [];\n\n const originX = config.origin ? config.origin[0] : prototype.x;\n const originY = config.origin ? config.origin[1] : prototype.y;\n const elements: SceneElement[] = [];\n\n for (let i = 0; i < count; i++) {\n const el: SceneElement = {\n ...prototype,\n id: `${prototype.id}_${i}`,\n };\n\n let px = originX;\n let py = originY;\n\n switch (config.pattern) {\n case 'grid': {\n const cols = config.columns ?? Math.ceil(Math.sqrt(count));\n const colSpacing = config.columnSpacing ?? (prototype.width + 20);\n const rowSpacing = config.rowSpacing ?? (prototype.height + 20);\n const col = i % cols;\n const row = Math.floor(i / cols);\n px = originX + col * colSpacing;\n py = originY + row * rowSpacing;\n break;\n }\n\n case 'line': {\n if (config.startPoint && config.endPoint) {\n const t = count > 1 ? i / (count - 1) : 0;\n px = config.startPoint[0] + (config.endPoint[0] - config.startPoint[0]) * t;\n py = config.startPoint[1] + (config.endPoint[1] - config.startPoint[1]) * t;\n } else {\n const spacing = config.spacing ?? (prototype.width + 20);\n px = originX + i * spacing;\n py = originY;\n }\n break;\n }\n\n case 'circle': {\n const radius = config.radius ?? 150;\n const angleStep = (2 * Math.PI) / count;\n const angle = (config.startAngle ?? 0) + i * angleStep;\n px = originX + radius * Math.cos(angle);\n py = originY + radius * Math.sin(angle);\n break;\n }\n\n case 'spiral': {\n const baseRadius = config.radius ?? 40;\n const tightness = config.spiralTightness ?? 12;\n const angleStep = Math.PI / 4; // 45 degrees per step\n const angle = (config.startAngle ?? 0) + i * angleStep;\n const r = baseRadius + tightness * i;\n px = originX + r * Math.cos(angle);\n py = originY + r * Math.sin(angle);\n break;\n }\n }\n\n el.x = px;\n el.y = py;\n\n // Apply sequence property modulation\n if (config.sequence && config.sequence.offset !== undefined) {\n const { property, offset } = config.sequence;\n if (property === 'opacity') {\n const base = prototype.opacity ?? 1.0;\n el.opacity = Math.max(0, Math.min(1, base + i * offset));\n } else if (property === 'rotation') {\n const base = (prototype as any).rotation ?? 0;\n (el as any).rotation = base + i * offset;\n } else if (property === 'scale') {\n const factor = 1 + i * offset;\n el.width = Math.max(1, prototype.width * factor);\n el.height = Math.max(1, prototype.height * factor);\n } else if (property === 'x') {\n el.x += i * offset;\n } else if (property === 'y') {\n el.y += i * offset;\n }\n }\n\n elements.push(el);\n }\n\n return elements;\n}\n","/**\n * Constant-Velocity Spatial Motion Paths & Arc-Length Parameterization.\n *\n * Implements multi-segment cubic Bezier spatial trajectories with numerical\n * arc-length integration, ensuring constant pixel-speed traversal, tangent heading,\n * normal vectors, curvature, and seamless combination with temporal AE keyframe easing.\n */\n\nimport { evaluateKeyframeSegment, type KeyframeEase } from '../time/keyframe.js';\n\nexport type Vec2 = [number, number];\nexport type Vec3 = [number, number, number];\n\nexport interface PathWaypoint {\n /** Anchor position in 2D or 3D scene coordinates [x, y] or [x, y, z]. */\n point: Vec2 | Vec3;\n /** In-tangent handle relative to anchor point (vector pointing from handle to anchor or vice-versa). Default: [0, 0, 0] */\n inTangent?: Vec2 | Vec3;\n /** Out-tangent handle relative to anchor point (vector pointing from anchor toward next handle). Default: [0, 0, 0] */\n outTangent?: Vec2 | Vec3;\n}\n\nexport interface SpatialPathSample {\n /** Position on curve [x, y, z]. */\n position: Vec3;\n /** Normalized unit tangent vector [dx, dy, dz]. */\n tangent: Vec3;\n /** 2D heading angle in radians (atan2(dy, dx)). */\n heading: number;\n /** 2D unit normal vector [-dy, dx, 0]. */\n normal: Vec3;\n /** Instantaneous curvature kappa (1 / radius of curvature). */\n curvature: number;\n /** Distance traversed along the path in absolute units. */\n distance: number;\n}\n\ninterface SegmentSample {\n t: number;\n s: number;\n pos: Vec3;\n}\n\ninterface PathSegment {\n p0: Vec3;\n p1: Vec3;\n p2: Vec3;\n p3: Vec3;\n length: number;\n samples: SegmentSample[];\n}\n\nexport interface SpatialMotionPath {\n waypoints: PathWaypoint[];\n closed: boolean;\n totalLength: number;\n segments: PathSegment[];\n}\n\nfunction toVec3(p: Vec2 | Vec3 | undefined): Vec3 {\n if (!p) return [0, 0, 0];\n return [p[0], p[1], p[2] ?? 0];\n}\n\nfunction cubicPos(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicVel(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = -3 * u * u;\n const b = 3 * u * u - 6 * u * t;\n const c = 6 * u * t - 3 * t * t;\n const d = 3 * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicAcc(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = 6 * u;\n const b = -12 * u + 6 * t;\n const c = 6 * u - 12 * t;\n const d = 6 * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction dist3(a: Vec3, b: Vec3): number {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const dz = b[2] - a[2];\n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Creates and compiles a constant-velocity SpatialMotionPath from a sequence of waypoints.\n * Computes fine-grained arc-length tables along all Bezier segments.\n */\nexport function createMotionPath(\n waypoints: PathWaypoint[],\n options?: { closed?: boolean; resolution?: number }\n): SpatialMotionPath {\n if (waypoints.length < 2) {\n throw new Error('SpatialMotionPath requires at least 2 waypoints.');\n }\n\n const closed = options?.closed ?? false;\n const segmentCount = closed ? waypoints.length : waypoints.length - 1;\n const segments: PathSegment[] = [];\n let totalLength = 0;\n\n for (let i = 0; i < segmentCount; i++) {\n const nextIdx = (i + 1) % waypoints.length;\n const w0 = waypoints[i];\n const w1 = waypoints[nextIdx];\n\n const p0 = toVec3(w0.point);\n const outT = toVec3(w0.outTangent);\n const p1: Vec3 = [p0[0] + outT[0], p0[1] + outT[1], p0[2] + outT[2]];\n\n const p3 = toVec3(w1.point);\n const inT = toVec3(w1.inTangent);\n const p2: Vec3 = [p3[0] + inT[0], p3[1] + inT[1], p3[2] + inT[2]];\n\n // Chord length estimate\n const chord = dist3(p0, p1) + dist3(p1, p2) + dist3(p2, p3);\n const stepCount = Math.max(16, Math.min(256, Math.ceil(chord / (options?.resolution ?? 2))));\n\n const samples: SegmentSample[] = [];\n let segLen = 0;\n let prev = p0;\n samples.push({ t: 0, s: 0, pos: p0 });\n\n for (let k = 1; k <= stepCount; k++) {\n const t = k / stepCount;\n const pos = cubicPos(p0, p1, p2, p3, t);\n segLen += dist3(prev, pos);\n samples.push({ t, s: segLen, pos });\n prev = pos;\n }\n\n segments.push({\n p0,\n p1,\n p2,\n p3,\n length: segLen,\n samples,\n });\n totalLength += segLen;\n }\n\n return {\n waypoints,\n closed,\n totalLength,\n segments,\n };\n}\n\n/**\n * Samples the spatial motion path at a normalized distance fraction [0..1].\n * Guarantees strictly constant pixel speed regardless of control handle asymmetry.\n */\nexport function sampleMotionPath(path: SpatialMotionPath, distanceFraction: number): SpatialPathSample {\n const clampedFraction = Math.max(0, Math.min(1, distanceFraction));\n const targetDistance = clampedFraction * path.totalLength;\n\n if (path.totalLength === 0) {\n const p = toVec3(path.waypoints[0].point);\n return {\n position: p,\n tangent: [1, 0, 0],\n heading: 0,\n normal: [0, 1, 0],\n curvature: 0,\n distance: 0,\n };\n }\n\n // Find target segment\n let accumulated = 0;\n let targetSeg = path.segments[0];\n let segDistance = targetDistance;\n\n for (const seg of path.segments) {\n if (accumulated + seg.length >= targetDistance || seg === path.segments[path.segments.length - 1]) {\n targetSeg = seg;\n segDistance = Math.max(0, Math.min(seg.length, targetDistance - accumulated));\n break;\n }\n accumulated += seg.length;\n }\n\n // Binary search for exact sample in target segment's arc length table\n const samples = targetSeg.samples;\n let low = 0;\n let high = samples.length - 1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (samples[mid].s < segDistance) {\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n const idx = Math.max(0, Math.min(samples.length - 2, high));\n const s0 = samples[idx];\n const s1 = samples[idx + 1];\n\n const segRange = s1.s - s0.s;\n const factor = segRange > 1e-7 ? (segDistance - s0.s) / segRange : 0;\n const t = s0.t + factor * (s1.t - s0.t);\n\n // Evaluate exact position, velocity, acceleration at t\n const pos = cubicPos(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const vel = cubicVel(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const acc = cubicAcc(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n\n const speed = Math.sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);\n const safeSpeed = speed > 1e-6 ? speed : 1;\n const tangent: Vec3 = [vel[0] / safeSpeed, vel[1] / safeSpeed, vel[2] / safeSpeed];\n\n const heading = Math.atan2(tangent[1], tangent[0]);\n const normal: Vec3 = [-tangent[1], tangent[0], 0];\n\n // Curvature: kappa = |v x a| / |v|^3\n const cx = vel[1] * acc[2] - vel[2] * acc[1];\n const cy = vel[2] * acc[0] - vel[0] * acc[2];\n const cz = vel[0] * acc[1] - vel[1] * acc[0];\n const crossMag = Math.sqrt(cx * cx + cy * cy + cz * cz);\n const curvature = crossMag / (safeSpeed * safeSpeed * safeSpeed);\n\n return {\n position: pos,\n tangent,\n heading,\n normal,\n curvature,\n distance: targetDistance,\n };\n}\n\n/**\n * Samples a spatial motion path driven by elapsed time and AE keyframe velocity easing.\n * Combines spatial arc-length constancy with temporal speed curves.\n */\nexport function sampleMotionPathAtTime(\n path: SpatialMotionPath,\n time: number,\n duration: number,\n ease?: {\n easeIn?: KeyframeEase;\n easeOut?: KeyframeEase;\n }\n): SpatialPathSample {\n const distanceFraction = evaluateKeyframeSegment(\n 0,\n 1,\n duration,\n time,\n ease?.easeOut,\n ease?.easeIn\n );\n return sampleMotionPath(path, distanceFraction);\n}\n\n","import type { Scene, SceneMedia, Shot } from '../scene/types.js';\nimport { validateScene, type SceneIssue } from '../scene/validate.js';\nimport { simulateScene } from '../scene/player.js';\nimport type { Review } from '../scene/report.js';\nimport { applyRig, setRigWidget } from '../scene/rig.js';\n\nexport interface AgentToolDefinition {\n name: string;\n description: string;\n input_schema: Record<string, unknown>;\n}\n\nexport const FLAIR_AGENT_TOOLS: AgentToolDefinition[] = [\n {\n name: 'get_scene',\n description: 'Returns the current scene JSON (or a concise structural outline) and any static validation issues.',\n input_schema: {\n type: 'object',\n properties: {\n view: {\n type: 'string',\n enum: ['full', 'outline'],\n description:\n 'When \"outline\", returns scene hierarchy, timing, and framing without dense commands or raw media sources.',\n },\n },\n additionalProperties: false,\n },\n },\n {\n name: 'write_scene',\n description: 'Overwrites the entire scene with a new specification and validates it.',\n input_schema: {\n type: 'object',\n properties: {\n scene: {\n type: 'object',\n description:\n 'Full Scene object with name, stage, media, and shots. A shot camera frames a box {x, y, width, height} or elements {frame: [ids]}, and may add tilt, turn, roll (degrees, tilt/turn up to 75), perspective (default 1.2) and motionBlur (0-3, 1 natural); angles persist until changed.',\n },\n },\n required: ['scene'],\n additionalProperties: false,\n },\n },\n {\n name: 'update_shot',\n description: 'Updates fields of a specific shot (1-based index) without rewriting the whole scene.',\n input_schema: {\n type: 'object',\n properties: {\n shot: { type: 'integer', minimum: 1, description: '1-based index of the shot to update.' },\n set: { type: 'object', description: 'Fields to set or replace on this shot.' },\n remove: {\n type: 'array',\n items: { type: 'string' },\n description: 'Field names to delete from this shot.',\n },\n },\n required: ['shot'],\n additionalProperties: false,\n },\n },\n {\n name: 'insert_shots',\n description: 'Inserts one or more shots at a given position.',\n input_schema: {\n type: 'object',\n properties: {\n after: {\n type: 'integer',\n minimum: 0,\n description: '0 to insert at the beginning, or 1-based index of shot to insert after.',\n },\n shots: {\n type: 'array',\n items: { type: 'object' },\n description: 'Array of Shot objects to insert.',\n },\n },\n required: ['after', 'shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'delete_shots',\n description: 'Deletes one or more shots by 1-based index.',\n input_schema: {\n type: 'object',\n properties: {\n shots: {\n type: 'array',\n items: { type: 'integer', minimum: 1 },\n description: '1-based shot numbers to delete.',\n },\n },\n required: ['shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'set_media',\n description: 'Adds, updates, or removes embedded media (e.g. bespoke WebGL shaders) by ID.',\n input_schema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Media identifier.' },\n media: {\n type: ['object', 'null'],\n description: 'SceneMedia object (e.g. { type: \"shader\", source: \"...\" }), or null to remove.',\n },\n },\n required: ['id', 'media'],\n additionalProperties: false,\n },\n },\n {\n name: 'preview_scene',\n description: 'Simulates the scene fast and off-screen, returning timing, layout checks, and review report.',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'set_rig_widget',\n description: 'Adjusts a high-level creative rig widget (slider, popup, or toggle) and propagates parameters to shaders and elements.',\n input_schema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Rig widget identifier/name.' },\n value: {\n type: ['number', 'string', 'boolean'],\n description: 'New value (number for slider, string for popup, boolean for toggle).',\n },\n },\n required: ['name', 'value'],\n additionalProperties: false,\n },\n },\n];\n\nexport interface SceneOutlineShot {\n shot: number;\n caption?: string;\n title?: string;\n hold?: number;\n camera?: Shot['camera'];\n commandCount: number;\n effects?: string[];\n}\n\nexport interface SceneOutline {\n name: string;\n title?: string;\n description?: string;\n stage?: Scene['stage'];\n target?: Scene['target'];\n mediaIds: string[];\n shots: SceneOutlineShot[];\n}\n\nexport type SceneToolResult =\n | { ok: true; scene: Scene; outline?: SceneOutline; issues: SceneIssue[]; review?: Review }\n | { ok: false; error: string };\n\n/**\n * Pure state machine that applies tool operations to a Scene.\n */\nexport async function applySceneTool(\n scene: Scene,\n toolName: string,\n input: Record<string, any> = {},\n): Promise<SceneToolResult> {\n switch (toolName) {\n case 'get_scene': {\n const issues = validateScene(scene);\n if (input.view === 'outline') {\n const outline: SceneOutline = {\n name: scene.name,\n title: scene.title,\n description: scene.description,\n stage: scene.stage,\n target: scene.target,\n mediaIds: Object.keys(scene.media || {}),\n shots: scene.shots.map((s, i) => ({\n shot: i + 1,\n caption: s.caption,\n title: s.title,\n hold: s.hold,\n camera: s.camera,\n commandCount: s.run?.length ?? 0,\n effects: s.effects?.map((e) => e.type),\n })),\n };\n return { ok: true, scene, outline, issues };\n }\n return { ok: true, scene, issues };\n }\n\n case 'write_scene': {\n if (!input.scene || typeof input.scene !== 'object') {\n return { ok: false, error: 'Expected scene object in arguments.' };\n }\n const newScene = input.scene as Scene;\n const issues = validateScene(newScene);\n return { ok: true, scene: newScene, issues };\n }\n\n case 'update_shot': {\n const idx = input.shot - 1;\n if (idx < 0 || idx >= scene.shots.length) {\n return { ok: false, error: `Invalid shot number ${input.shot}; scene has ${scene.shots.length} shots.` };\n }\n const existing = scene.shots[idx]!;\n const updated: Record<string, any> = { ...existing, ...(input.set || {}) };\n if (Array.isArray(input.remove)) {\n for (const k of input.remove) {\n delete updated[k];\n }\n }\n const shots = [...scene.shots];\n shots[idx] = updated as Shot;\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'insert_shots': {\n const after = input.after ?? scene.shots.length;\n if (after < 0 || after > scene.shots.length) {\n return { ok: false, error: `Invalid after index ${after}.` };\n }\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to insert.' };\n }\n const shots = [...scene.shots.slice(0, after), ...input.shots, ...scene.shots.slice(after)];\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'delete_shots': {\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to delete.' };\n }\n const toDelete = new Set(input.shots.map((n: number) => n - 1));\n const shots = scene.shots.filter((_, i) => !toDelete.has(i));\n if (shots.length === 0) {\n return { ok: false, error: 'Cannot delete all shots in scene.' };\n }\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'set_media': {\n if (!input.id || typeof input.id !== 'string') {\n return { ok: false, error: 'Expected string media id.' };\n }\n const media = { ...(scene.media || {}) };\n if (input.media === null) {\n delete media[input.id];\n } else {\n media[input.id] = input.media as SceneMedia;\n }\n const newScene = { ...scene, media };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'preview_scene': {\n const { review } = await simulateScene(scene);\n return { ok: true, scene, issues: validateScene(scene), review };\n }\n\n case 'set_rig_widget': {\n if (!scene.rig || !scene.rig.widgets || !scene.rig.widgets[input.name]) {\n return { ok: false, error: `Scene does not have a rig widget named \"${input.name}\".` };\n }\n try {\n const updatedRig = setRigWidget(scene.rig, input.name, input.value);\n const newScene = applyRig(updatedRig, scene);\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n } catch (err: any) {\n return { ok: false, error: err.message || String(err) };\n }\n }\n\n default:\n return { ok: false, error: `Unknown tool name: ${toolName}` };\n }\n}\n","/**\n * Atomic Agent Multi-Tool Batching with Result Variable Substitution.\n * Inspired by EffectCraft's atomic batch execution protocol.\n *\n * Allows AI agents to execute multi-step modifications to a Scene in a single turn,\n * with atomic rollback on failure and cross-step variable substitution ($1.prop, $2.prop).\n */\n\nimport type { Scene } from '../scene/types.js';\nimport { applySceneTool, type SceneToolResult } from './tools.js';\n\nexport interface BatchCommand {\n /** Name of the tool to execute (e.g. 'update_shot', 'insert_shots', 'set_rig_widget'). */\n tool: string;\n /** Parameters for the tool call. */\n params?: Record<string, any>;\n}\n\nexport interface BatchExecutionStepResult {\n step: number;\n tool: string;\n result: SceneToolResult;\n}\n\nexport interface BatchExecutionResult {\n ok: boolean;\n scene: Scene;\n steps: BatchExecutionStepResult[];\n error?: string;\n failedStep?: number;\n}\n\n/**\n * Resolves nested property path on an object (e.g. \"a.b[0].c\").\n */\nfunction getByPath(obj: any, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const parts = path.replace(/\\[(\\w+)\\]/g, '.$1').split('.');\n let curr = obj;\n for (const part of parts) {\n if (curr === undefined || curr === null) return undefined;\n curr = curr[part];\n }\n return curr;\n}\n\n/**\n * Recursively substitutes `$stepIndex.path` references in parameters using previous step results.\n * E.g., \"$1.scene.shots[0].duration\" -> substituted with the duration value from step 1 result.\n */\nexport function substituteVariables(\n value: any,\n stepResults: Map<number, SceneToolResult>,\n): any {\n if (typeof value === 'string') {\n // Check if the entire string is a substitution reference: \"$1.path.to.prop\"\n const match = /^\\$(\\d+)\\.(.+)$/.exec(value);\n if (match) {\n const stepIdx = parseInt(match[1]!, 10);\n const path = match[2]!;\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return resolved;\n }\n }\n }\n // Partial template string substitution: \"Hello $1.scene.name\"\n return value.replace(/\\$(\\d+)\\.([a-zA-Z0-9_.[\\]]+)/g, (fullMatch, stepStr, path) => {\n const stepIdx = parseInt(stepStr, 10);\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return String(resolved);\n }\n }\n return fullMatch;\n });\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => substituteVariables(item, stepResults));\n }\n\n if (value !== null && typeof value === 'object') {\n const copy: Record<string, any> = {};\n for (const [k, v] of Object.entries(value)) {\n copy[k] = substituteVariables(v, stepResults);\n }\n return copy;\n }\n\n return value;\n}\n\n/**\n * Executes an atomic batch of scene tools with transactional rollback.\n * If any step fails, the scene rolls back to the initial state and returns the failure.\n *\n * @param scene Initial scene state before batch.\n * @param commands Ordered array of tool commands to execute.\n */\nexport async function applySceneBatch(\n scene: Scene,\n commands: BatchCommand[],\n): Promise<BatchExecutionResult> {\n let currentScene = scene;\n const stepResults = new Map<number, SceneToolResult>();\n const executedSteps: BatchExecutionStepResult[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const stepNumber = i + 1; // 1-based indexing for user/agent ergonomics\n const cmd = commands[i]!;\n\n // Perform variable substitution using results of earlier steps\n const resolvedParams = substituteVariables(cmd.params || {}, stepResults);\n\n // Prevent recursive batch execution to avoid cycles\n if (cmd.tool === 'batch_scene_tool') {\n return {\n ok: false,\n scene, // Rollback\n steps: executedSteps,\n error: `Nested batch_scene_tool is not allowed at step ${stepNumber}.`,\n failedStep: stepNumber,\n };\n }\n\n const stepResult = await applySceneTool(currentScene, cmd.tool, resolvedParams);\n stepResults.set(stepNumber, stepResult);\n executedSteps.push({\n step: stepNumber,\n tool: cmd.tool,\n result: stepResult,\n });\n\n if (!stepResult.ok) {\n // Transactional rollback: discard intermediate scenes and return original\n return {\n ok: false,\n scene, // Rollback to initial\n steps: executedSteps,\n error: `Step ${stepNumber} (${cmd.tool}) failed: ${stepResult.error}`,\n failedStep: stepNumber,\n };\n }\n\n currentScene = stepResult.scene;\n }\n\n return {\n ok: true,\n scene: currentScene,\n steps: executedSteps,\n };\n}\n"],"mappings":"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","names":["frame"]}
1
+ {"version":3,"sources":["../src/time/retiming.ts","../src/time/keyframe.ts","../src/time/timecode.ts","../src/scene/rig.ts","../src/scene/replicator.ts","../src/scene/motionpath.ts","../src/agent/tools.ts","../src/agent/batch.ts"],"sourcesContent":["/**\n * Retiming math engine inspired by Apple Motion's RetimingMath framework.\n * Provides deterministic time transformation functors for looping, bouncing (ping-pong),\n * freezing (hold), posterizing/stepping (strobe), and non-linear speed ramps.\n */\n\nexport type EasingCurve = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';\n\n/**\n * Loops time within [start, start + duration).\n * Handles negative time values smoothly.\n */\nexport function loopTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const rel = t - start;\n const mod = ((rel % duration) + duration) % duration;\n return start + mod;\n}\n\n/**\n * Reflects time back and forth (triangle wave) between start and start + duration.\n */\nexport function pingPongTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const period = 2 * duration;\n const rel = t - start;\n const mod = ((rel % period) + period) % period;\n const offset = mod <= duration ? mod : period - mod;\n return start + offset;\n}\n\n/**\n * Freezes time at a specified timestamp.\n */\nexport function holdTime(_t: number, holdAt: number): number {\n return holdAt;\n}\n\n/**\n * Quantizes continuous time into discrete intervals matching a target frame rate (posterize time).\n * @param t Current timestamp.\n * @param fps Target stepped frame rate (e.g. 12 for stop-motion).\n * @param unit 'ms' (default) if t is in milliseconds, or 'sec' if t is in seconds.\n */\nexport function strobeTime(t: number, fps: number, unit: 'ms' | 'sec' = 'ms'): number {\n if (fps <= 0) return t;\n const interval = (unit === 'ms' ? 1000 : 1) / fps;\n return Math.floor(t / interval) * interval;\n}\n\n/**\n * Applies a non-linear speed ramp curve to time progression within an interval [start, start + duration].\n */\nexport function speedRampTime(\n t: number,\n start: number,\n duration: number,\n ease: EasingCurve = 'easeInOut',\n): number {\n if (duration <= 0 || t <= start) return t;\n if (t >= start + duration) return t;\n\n const p = (t - start) / duration;\n let eased: number;\n switch (ease) {\n case 'linear':\n eased = p;\n break;\n case 'easeIn':\n eased = p * p;\n break;\n case 'easeOut':\n eased = p * (2 - p);\n break;\n case 'easeInOut':\n default:\n eased = p < 0.5 ? 2 * p * p : -1 + (4 - 2 * p) * p;\n break;\n }\n\n return start + eased * duration;\n}\n","/**\n * Keyframe velocity and cubic Bezier easing engine matching Adobe After Effects interpolation semantics.\n *\n * Temporal interpolation between two keyframes is characterized by:\n * - Speed (units / second)\n * - Influence (fraction 0..1, corresponding to 0.1%..100% in the Keyframe Velocity dialog)\n *\n * For normalized values going from 0 to 1 over a segment, easeProgress(outSpeedNorm, outInf, inSpeedNorm, inInf, x)\n * solves the monotone cubic Bezier root x(u) = x and computes value y(u).\n */\n\nexport interface KeyframeEase {\n /** Speed in value units per second (or normalized speed if evaluating normalized segment). */\n speed: number;\n /** Influence as a fraction between 0.0 and 1.0 (e.g. 0.3333 for 33.33%). */\n influence: number;\n}\n\n/** Easy Ease preset: 0 speed, 33.333% influence. */\nexport const EASY_EASE: KeyframeEase = {\n speed: 0,\n influence: 1 / 3,\n};\n\n/** Evaluates a 1D cubic Bezier polynomial at parameter u in [0, 1]. */\nexport function bez1d(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return v * v * v * p0 + 3.0 * v * v * u * p1 + 3.0 * v * u * u * p2 + u * u * u * p3;\n}\n\n/** Evaluates the first derivative of a 1D cubic Bezier polynomial at parameter u. */\nexport function bez1dDerivative(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return 3.0 * v * v * (p1 - p0) + 6.0 * v * u * (p2 - p1) + 3.0 * u * u * (p3 - p2);\n}\n\n/**\n * Solves bez1d(x0, x1, x2, x3, u) = x for u in [0, 1] assuming x(u) is monotone.\n * Uses closed-form inverse for 100% influence midpoint, Newton-Raphson iteration,\n * and high-precision bisection fallback.\n */\nexport function solveBezierU(x0: number, x1: number, x2: number, x3: number, x: number): number {\n if (x <= x0) return 0.0;\n if (x >= x3) return 1.0;\n\n // Closed-form solution for 100% influence on both sides (x1 === x3 && x2 === x0).\n // x(u) = x0 + (x3 - x0) * (0.5 + 4 * (u - 0.5)^3)\n if (Math.abs(x1 - x3) < 1e-12 && Math.abs(x2 - x0) < 1e-12) {\n const progress = (x - x0) / (x3 - x0);\n return 0.5 + Math.cbrt((progress - 0.5) * 0.25);\n }\n\n // Initial estimate\n let u = (x - x0) / (x3 - x0);\n\n // Up to 8 Newton-Raphson iterations\n for (let iter = 0; iter < 8; iter++) {\n const f = bez1d(x0, x1, x2, x3, u) - x;\n const d = bez1dDerivative(x0, x1, x2, x3, u);\n if (Math.abs(d) < 1e-12) break;\n if (Math.abs(f / d) < 1e-12) return u;\n const nextU = u - f / d;\n if (nextU < 0.0 || nextU > 1.0) break;\n u = nextU;\n }\n\n // Bisection fallback for robustness\n let lo = 0.0;\n let hi = 1.0;\n for (let iter = 0; iter < 60; iter++) {\n const mid = (lo + hi) * 0.5;\n if (bez1d(x0, x1, x2, x3, mid) < x) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return (lo + hi) * 0.5;\n}\n\n/**\n * Fraction of progress 0..1 through a 1D Bezier temporal segment whose value goes from 0 to 1,\n * with normalized out/in speeds (speed * duration / deltaValue) and influences.\n *\n * @param outSpeedNorm Normalized outgoing speed (speed * duration / deltaValue).\n * @param outInfluence Outgoing influence fraction [0, 1].\n * @param inSpeedNorm Normalized incoming speed (speed * duration / deltaValue).\n * @param inInfluence Incoming influence fraction [0, 1].\n * @param x Normalized time progress in segment [0, 1].\n */\nexport function easeProgress(\n outSpeedNorm: number,\n outInfluence: number,\n inSpeedNorm: number,\n inInfluence: number,\n x: number,\n): number {\n const i0 = Math.min(1.0, Math.max(0.0, outInfluence));\n const i1 = Math.min(1.0, Math.max(0.0, inInfluence));\n const u = solveBezierU(0.0, i0, 1.0 - i1, 1.0, x);\n return bez1d(0.0, outSpeedNorm * i0, 1.0 - inSpeedNorm * i1, 1.0, u);\n}\n\n/**\n * Evaluates an interpolated keyframe segment between two values over duration.\n *\n * @param from Starting value at t = 0.\n * @param to Ending value at t = duration.\n * @param duration Duration of the keyframe segment in seconds.\n * @param t Current elapsed time in seconds (0 <= t <= duration).\n * @param outEase Outgoing ease specification at start keyframe.\n * @param inEase Incoming ease specification at end keyframe.\n */\nexport function evaluateKeyframeSegment(\n from: number,\n to: number,\n duration: number,\n t: number,\n outEase: KeyframeEase = EASY_EASE,\n inEase: KeyframeEase = EASY_EASE,\n): number {\n if (duration <= 0 || t <= 0) return from;\n if (t >= duration) return to;\n\n const delta = to - from;\n const x = t / duration;\n\n // Zero delta: maintain from\n if (Math.abs(delta) < 1e-12) {\n return from;\n }\n\n const outSpeedNorm = (outEase.speed * duration) / delta;\n const inSpeedNorm = (inEase.speed * duration) / delta;\n\n const progress = easeProgress(outSpeedNorm, outEase.influence, inSpeedNorm, inEase.influence, x);\n return from + progress * delta;\n}\n","/**\n * SMPTE 12M Timecode engine and broadcast frame-rate converter.\n *\n * Supports non-drop-frame (NDF) and drop-frame (DF) timecode for broadcast standards\n * (23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60, 120 fps).\n *\n * Drop-frame timecode drops frames 00 and 01 at the start of each minute,\n * except every 10th minute (e.g. 00:01:00;02 instead of 00:01:00;00).\n */\n\nexport interface RationalFrameRate {\n readonly num: number;\n readonly den: number;\n}\n\nexport const COMMON_FRAME_RATES = {\n FPS_23_976: { num: 24000, den: 1001 },\n FPS_24: { num: 24, den: 1 },\n FPS_25: { num: 25, den: 1 },\n FPS_29_97: { num: 30000, den: 1001 },\n FPS_30: { num: 30, den: 1 },\n FPS_48: { num: 48, den: 1 },\n FPS_50: { num: 50, den: 1 },\n FPS_59_94: { num: 60000, den: 1001 },\n FPS_60: { num: 60, den: 1 },\n FPS_120: { num: 120, den: 1 },\n} as const;\n\nexport type StandardFrameRateKey = keyof typeof COMMON_FRAME_RATES;\n\n/** Greatest common divisor helper. */\nfunction gcd(a: number, b: number): number {\n let x = Math.abs(Math.round(a));\n let y = Math.abs(Math.round(b));\n while (y !== 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x || 1;\n}\n\n/** Creates a reduced rational frame rate. */\nexport function createFrameRate(num: number, den = 1): RationalFrameRate {\n if (den <= 0 || num <= 0) {\n return { num: 30, den: 1 };\n }\n const g = gcd(num, den);\n return { num: Math.round(num / g), den: Math.round(den / g) };\n}\n\n/** Returns the timecode base (frames counted per second in timecode display). */\nexport function getTimecodeBase(rate: RationalFrameRate): number {\n return Math.ceil(rate.num / rate.den);\n}\n\n/** Whether a given frame rate supports drop-frame counting (29.97, 59.94, etc.). */\nexport function supportsDropFrame(rate: RationalFrameRate): boolean {\n return rate.den === 1001 && getTimecodeBase(rate) % 30 === 0;\n}\n\n/** Number of dropped frames per minute (e.g. 2 for 29.97, 4 for 59.94). */\nexport function getDropFrameCount(rate: RationalFrameRate): number {\n const base = getTimecodeBase(rate);\n return Math.floor(base / 15);\n}\n\nexport interface SMPTEFields {\n negative: boolean;\n hours: number;\n minutes: number;\n seconds: number;\n frames: number;\n}\n\n/**\n * Converts a continuous frame count to SMPTE fields (hours, minutes, seconds, frames).\n */\nexport function framesToSMPTE(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): SMPTEFields {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const neg = frame < 0;\n let n = Math.abs(Math.round(frame));\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n if (isDrop) {\n const perMinute = base * 60 - drop;\n const per10Minutes = perMinute * 10 + drop;\n const d = Math.floor(n / per10Minutes);\n const m = n % per10Minutes;\n\n n += drop * 9 * d;\n if (m > drop) {\n n += drop * Math.floor((m - drop) / perMinute);\n }\n }\n\n const frames = n % base;\n const seconds = Math.floor(n / base) % 60;\n const minutes = Math.floor(n / (base * 60)) % 60;\n const hours = Math.floor(n / (base * 3600));\n\n return { negative: neg, hours, minutes, seconds, frames };\n}\n\n/**\n * Converts SMPTE fields back to a continuous frame number.\n */\nexport function smpteToFrames(\n fields: { hours: number; minutes: number; seconds: number; frames: number },\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): number {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n const totalSecs = fields.hours * 3600 + fields.minutes * 60 + fields.seconds;\n let n = totalSecs * base + fields.frames;\n\n if (isDrop) {\n const totalMinutes = fields.hours * 60 + fields.minutes;\n n -= drop * (totalMinutes - Math.floor(totalMinutes / 10));\n }\n\n return n;\n}\n\n/**\n * Formats a frame number as standard SMPTE timecode (HH:MM:SS:FF or HH;MM;SS;FF).\n */\nexport function formatTimecode(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): string {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const { negative, hours, minutes, seconds, frames } = framesToSMPTE(frame, rate, isDrop);\n const sep = isDrop ? ';' : ':';\n const base = getTimecodeBase(rate);\n const frameWidth = base >= 100 ? 3 : 2;\n\n const hStr = String(hours).padStart(2, '0');\n const mStr = String(minutes).padStart(2, '0');\n const sStr = String(seconds).padStart(2, '0');\n const fStr = String(frames).padStart(frameWidth, '0');\n\n return `${negative ? '-' : ''}${hStr}${sep}${mStr}${sep}${sStr}${sep}${fStr}`;\n}\n\n/**\n * Parses user or NLE input into a frame number.\n * Supports:\n * - Standard timecodes: `01:00:00:00`, `01;00;00;00`, `00.01.20.15`\n * - Right-aligned numbers: `1000` -> `00:00:10:00`\n * - Relative offsets: `+15` (+15 frames), `-1.00` (-1 second)\n *\n * @param input The timecode string to parse.\n * @param rate Rational frame rate (default: 30 fps).\n * @param dropFrame Whether drop-frame arithmetic applies.\n * @param currentFrame Current playhead position for relative additions.\n */\nexport function parseTimecode(\n input: string,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n currentFrame = 0,\n): number {\n const s = input.trim();\n if (!s) {\n throw new Error('Empty timecode string');\n }\n\n let relativeSign: 1 | -1 | null = null;\n let body = s;\n if (s.startsWith('+')) {\n relativeSign = 1;\n body = s.slice(1);\n } else if (s.startsWith('-')) {\n relativeSign = -1;\n body = s.slice(1);\n }\n\n const parts = body.split(/[:;.,]/);\n let parsedFrame = 0;\n\n if (parts.length === 1) {\n const digits = parts[0]!;\n if (!/^\\d+$/.test(digits)) {\n throw new Error(`Invalid timecode: \"${input}\"`);\n }\n\n if (relativeSign !== null) {\n // Relative bare digits are treated as frames\n const count = parseInt(digits, 10);\n return currentFrame + relativeSign * count;\n }\n\n // Right-aligned pairs: e.g. \"1000\" -> HH=0, MM=0, SS=10, FF=0\n const nums: number[] = [];\n let end = digits.length;\n while (end > 0) {\n const start = Math.max(0, end - 2);\n nums.unshift(parseInt(digits.slice(start, end), 10));\n end = start;\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n } else {\n if (parts.length > 4) {\n throw new Error(`Too many timecode fields in \"${input}\"`);\n }\n const nums = parts.map((p) => (p.length === 0 ? 0 : parseInt(p, 10)));\n if (nums.some((n) => isNaN(n))) {\n throw new Error(`Invalid number in timecode: \"${input}\"`);\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n }\n\n if (relativeSign !== null) {\n return currentFrame + relativeSign * parsedFrame;\n }\n\n return parsedFrame;\n}\n","import type { Scene } from './types.js';\n\nexport interface SliderSnapshot {\n at: number;\n values: Record<string, number | string>;\n}\n\nexport interface SliderWidget {\n type: 'slider';\n name: string;\n value: number;\n snapshots: SliderSnapshot[];\n}\n\nexport interface PopupWidget {\n type: 'popup';\n name: string;\n selected: string;\n options: Record<string, Record<string, number | string>>;\n}\n\nexport interface ToggleWidget {\n type: 'toggle';\n name: string;\n enabled: boolean;\n on: Record<string, number | string>;\n off: Record<string, number | string>;\n}\n\nexport type RigWidget = SliderWidget | PopupWidget | ToggleWidget;\n\nexport interface SceneRig {\n widgets: Record<string, RigWidget>;\n}\n\n/**\n * Updates a widget within a SceneRig and returns the updated SceneRig.\n */\nexport function setRigWidget(\n rig: SceneRig,\n widgetName: string,\n value: number | string | boolean,\n): SceneRig {\n const widget = rig.widgets[widgetName];\n if (!widget) {\n throw new Error(`Rig widget \"${widgetName}\" not found.`);\n }\n\n const updatedWidgets = { ...rig.widgets };\n\n if (widget.type === 'slider') {\n if (typeof value !== 'number') {\n throw new Error(`Slider widget \"${widgetName}\" expects numeric value.`);\n }\n updatedWidgets[widgetName] = { ...widget, value };\n } else if (widget.type === 'popup') {\n if (typeof value !== 'string') {\n throw new Error(`Popup widget \"${widgetName}\" expects string value.`);\n }\n updatedWidgets[widgetName] = { ...widget, selected: value };\n } else if (widget.type === 'toggle') {\n if (typeof value !== 'boolean') {\n throw new Error(`Toggle widget \"${widgetName}\" expects boolean value.`);\n }\n updatedWidgets[widgetName] = { ...widget, enabled: value };\n }\n\n return { widgets: updatedWidgets };\n}\n\n/**\n * Evaluates resolved values for a given widget.\n */\nfunction resolveWidgetValues(widget: RigWidget): Record<string, number | string> {\n if (widget.type === 'popup') {\n return widget.options[widget.selected] ?? {};\n }\n\n if (widget.type === 'toggle') {\n return widget.enabled ? widget.on : widget.off;\n }\n\n if (widget.type === 'slider') {\n const { snapshots, value } = widget;\n if (!snapshots || snapshots.length === 0) return {};\n\n const sorted = [...snapshots].sort((a, b) => a.at - b.at);\n if (value <= sorted[0]!.at) {\n return { ...sorted[0]!.values };\n }\n if (value >= sorted[sorted.length - 1]!.at) {\n return { ...sorted[sorted.length - 1]!.values };\n }\n\n // Find bounding snapshots\n let idx = 0;\n while (idx < sorted.length - 1 && sorted[idx + 1]!.at < value) {\n idx++;\n }\n\n const s0 = sorted[idx]!;\n const s1 = sorted[idx + 1]!;\n const span = s1.at - s0.at;\n const t = span > 0 ? (value - s0.at) / span : 0;\n\n const result: Record<string, number | string> = {};\n const allKeys = new Set([...Object.keys(s0.values), ...Object.keys(s1.values)]);\n\n for (const k of allKeys) {\n const v0 = s0.values[k];\n const v1 = s1.values[k];\n if (typeof v0 === 'number' && typeof v1 === 'number') {\n result[k] = v0 + (v1 - v0) * t;\n } else if (v0 !== undefined && v1 !== undefined) {\n result[k] = t < 0.5 ? v0 : v1;\n } else {\n result[k] = v1 !== undefined ? v1 : (v0 as number | string);\n }\n }\n\n return result;\n }\n\n return {};\n}\n\n/**\n * Propagates rig widget state into the scene's shader uniforms and elements.\n */\nexport function applyRig(rig: SceneRig, scene: Scene): Scene {\n // Deep clone media and shots to prevent mutation\n const nextMedia: Record<string, any> = {};\n if (scene.media) {\n for (const [id, m] of Object.entries(scene.media)) {\n nextMedia[id] = {\n ...m,\n values: { ...(m.values ?? {}) },\n };\n }\n }\n\n const nextShots = scene.shots.map((shot) => {\n if (!shot.run) return { ...shot };\n return {\n ...shot,\n run: shot.run.map((cmd) => {\n if (cmd.type === 'element' && 'element' in cmd && cmd.element) {\n return { ...cmd, element: { ...cmd.element } };\n }\n if (cmd.type === 'update' && 'props' in cmd && (cmd as any).props) {\n return { ...cmd, props: { ...(cmd as any).props } };\n }\n return { ...cmd };\n }),\n };\n });\n\n // Collect all resolved values across all widgets in the rig\n const resolvedAll: Record<string, number | string> = {};\n for (const widget of Object.values(rig.widgets)) {\n Object.assign(resolvedAll, resolveWidgetValues(widget));\n }\n\n // Apply resolved values\n for (const [targetKey, val] of Object.entries(resolvedAll)) {\n if (targetKey.startsWith('media.')) {\n const parts = targetKey.split('.');\n const mediaId = parts[1]!;\n const prop = parts.length > 3 && parts[2] === 'values' ? parts[3]! : parts[2]!;\n if (nextMedia[mediaId]) {\n nextMedia[mediaId].values[prop] = val;\n }\n } else if (targetKey.startsWith('element.')) {\n const parts = targetKey.split('.');\n const elId = parts[1]!;\n const prop = parts[2]!;\n for (const shot of nextShots) {\n if (shot.run) {\n for (const cmd of shot.run) {\n if (cmd.type === 'element' && 'element' in cmd && (cmd as any).element?.id === elId) {\n (cmd.element as any)[prop] = val;\n } else if (cmd.type === 'update' && 'id' in cmd && cmd.id === elId) {\n (cmd as any).props[prop] = val;\n }\n }\n }\n }\n } else {\n // General uniform shorthand: uniforms.<name> or simply <name>\n const uniformName = targetKey.replace(/^uniforms\\./, '');\n for (const m of Object.values(nextMedia)) {\n m.values[uniformName] = val;\n }\n }\n }\n\n return {\n ...scene,\n media: Object.keys(nextMedia).length > 0 ? nextMedia : scene.media,\n shots: nextShots,\n rig,\n };\n}\n","import type { SceneElement } from './geometry.js';\n\nexport type ReplicatorPattern = 'grid' | 'line' | 'circle' | 'spiral';\n\nexport interface ReplicatorSequence {\n /** Property to modulate per item. */\n property?: 'opacity' | 'rotation' | 'scale' | 'x' | 'y';\n /** Incremental offset or delta added per instance. */\n offset?: number;\n /** Milliseconds delay per instance for staggered triggers. */\n delayPerItem?: number;\n}\n\nexport interface ReplicatorConfig {\n pattern: ReplicatorPattern;\n count: number;\n /** Origin point [x, y] to anchor the layout (defaults to prototype.x, prototype.y). */\n origin?: [number, number];\n\n // Grid options\n columns?: number;\n rows?: number;\n columnSpacing?: number;\n rowSpacing?: number;\n\n // Line options\n startPoint?: [number, number];\n endPoint?: [number, number];\n spacing?: number;\n\n // Circle / Spiral options\n radius?: number;\n startAngle?: number; // radians\n spiralTightness?: number; // radius expansion per instance\n\n // Sequence modulation\n sequence?: ReplicatorSequence;\n}\n\n/**\n * Procedurally replicates a prototype SceneElement into an array of positioned\n * and sequenced instances (grid, circular array, line, or spiral).\n */\nexport function expandReplicator(\n prototype: SceneElement,\n config: ReplicatorConfig,\n): SceneElement[] {\n const count = Math.max(0, Math.floor(config.count));\n if (count === 0) return [];\n\n const originX = config.origin ? config.origin[0] : prototype.x;\n const originY = config.origin ? config.origin[1] : prototype.y;\n const elements: SceneElement[] = [];\n\n for (let i = 0; i < count; i++) {\n const el: SceneElement = {\n ...prototype,\n id: `${prototype.id}_${i}`,\n };\n\n let px = originX;\n let py = originY;\n\n switch (config.pattern) {\n case 'grid': {\n const cols = config.columns ?? Math.ceil(Math.sqrt(count));\n const colSpacing = config.columnSpacing ?? (prototype.width + 20);\n const rowSpacing = config.rowSpacing ?? (prototype.height + 20);\n const col = i % cols;\n const row = Math.floor(i / cols);\n px = originX + col * colSpacing;\n py = originY + row * rowSpacing;\n break;\n }\n\n case 'line': {\n if (config.startPoint && config.endPoint) {\n const t = count > 1 ? i / (count - 1) : 0;\n px = config.startPoint[0] + (config.endPoint[0] - config.startPoint[0]) * t;\n py = config.startPoint[1] + (config.endPoint[1] - config.startPoint[1]) * t;\n } else {\n const spacing = config.spacing ?? (prototype.width + 20);\n px = originX + i * spacing;\n py = originY;\n }\n break;\n }\n\n case 'circle': {\n const radius = config.radius ?? 150;\n const angleStep = (2 * Math.PI) / count;\n const angle = (config.startAngle ?? 0) + i * angleStep;\n px = originX + radius * Math.cos(angle);\n py = originY + radius * Math.sin(angle);\n break;\n }\n\n case 'spiral': {\n const baseRadius = config.radius ?? 40;\n const tightness = config.spiralTightness ?? 12;\n const angleStep = Math.PI / 4; // 45 degrees per step\n const angle = (config.startAngle ?? 0) + i * angleStep;\n const r = baseRadius + tightness * i;\n px = originX + r * Math.cos(angle);\n py = originY + r * Math.sin(angle);\n break;\n }\n }\n\n el.x = px;\n el.y = py;\n\n // Apply sequence property modulation\n if (config.sequence && config.sequence.offset !== undefined) {\n const { property, offset } = config.sequence;\n if (property === 'opacity') {\n const base = prototype.opacity ?? 1.0;\n el.opacity = Math.max(0, Math.min(1, base + i * offset));\n } else if (property === 'rotation') {\n const base = (prototype as any).rotation ?? 0;\n (el as any).rotation = base + i * offset;\n } else if (property === 'scale') {\n const factor = 1 + i * offset;\n el.width = Math.max(1, prototype.width * factor);\n el.height = Math.max(1, prototype.height * factor);\n } else if (property === 'x') {\n el.x += i * offset;\n } else if (property === 'y') {\n el.y += i * offset;\n }\n }\n\n elements.push(el);\n }\n\n return elements;\n}\n","/**\n * Constant-Velocity Spatial Motion Paths & Arc-Length Parameterization.\n *\n * Implements multi-segment cubic Bezier spatial trajectories with numerical\n * arc-length integration, ensuring constant pixel-speed traversal, tangent heading,\n * normal vectors, curvature, and seamless combination with temporal AE keyframe easing.\n */\n\nimport { evaluateKeyframeSegment, type KeyframeEase } from '../time/keyframe.js';\n\nexport type Vec2 = [number, number];\nexport type Vec3 = [number, number, number];\n\nexport interface PathWaypoint {\n /** Anchor position in 2D or 3D scene coordinates [x, y] or [x, y, z]. */\n point: Vec2 | Vec3;\n /** In-tangent handle relative to anchor point (vector pointing from handle to anchor or vice-versa). Default: [0, 0, 0] */\n inTangent?: Vec2 | Vec3;\n /** Out-tangent handle relative to anchor point (vector pointing from anchor toward next handle). Default: [0, 0, 0] */\n outTangent?: Vec2 | Vec3;\n}\n\nexport interface SpatialPathSample {\n /** Position on curve [x, y, z]. */\n position: Vec3;\n /** Normalized unit tangent vector [dx, dy, dz]. */\n tangent: Vec3;\n /** 2D heading angle in radians (atan2(dy, dx)). */\n heading: number;\n /** 2D unit normal vector [-dy, dx, 0]. */\n normal: Vec3;\n /** Instantaneous curvature kappa (1 / radius of curvature). */\n curvature: number;\n /** Distance traversed along the path in absolute units. */\n distance: number;\n}\n\ninterface SegmentSample {\n t: number;\n s: number;\n pos: Vec3;\n}\n\ninterface PathSegment {\n p0: Vec3;\n p1: Vec3;\n p2: Vec3;\n p3: Vec3;\n length: number;\n samples: SegmentSample[];\n}\n\nexport interface SpatialMotionPath {\n waypoints: PathWaypoint[];\n closed: boolean;\n totalLength: number;\n segments: PathSegment[];\n}\n\nfunction toVec3(p: Vec2 | Vec3 | undefined): Vec3 {\n if (!p) return [0, 0, 0];\n return [p[0], p[1], p[2] ?? 0];\n}\n\nfunction cubicPos(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicVel(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = -3 * u * u;\n const b = 3 * u * u - 6 * u * t;\n const c = 6 * u * t - 3 * t * t;\n const d = 3 * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicAcc(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = 6 * u;\n const b = -12 * u + 6 * t;\n const c = 6 * u - 12 * t;\n const d = 6 * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction dist3(a: Vec3, b: Vec3): number {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const dz = b[2] - a[2];\n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Creates and compiles a constant-velocity SpatialMotionPath from a sequence of waypoints.\n * Computes fine-grained arc-length tables along all Bezier segments.\n */\nexport function createMotionPath(\n waypoints: PathWaypoint[],\n options?: { closed?: boolean; resolution?: number }\n): SpatialMotionPath {\n if (waypoints.length < 2) {\n throw new Error('SpatialMotionPath requires at least 2 waypoints.');\n }\n\n const closed = options?.closed ?? false;\n const segmentCount = closed ? waypoints.length : waypoints.length - 1;\n const segments: PathSegment[] = [];\n let totalLength = 0;\n\n for (let i = 0; i < segmentCount; i++) {\n const nextIdx = (i + 1) % waypoints.length;\n const w0 = waypoints[i];\n const w1 = waypoints[nextIdx];\n\n const p0 = toVec3(w0.point);\n const outT = toVec3(w0.outTangent);\n const p1: Vec3 = [p0[0] + outT[0], p0[1] + outT[1], p0[2] + outT[2]];\n\n const p3 = toVec3(w1.point);\n const inT = toVec3(w1.inTangent);\n const p2: Vec3 = [p3[0] + inT[0], p3[1] + inT[1], p3[2] + inT[2]];\n\n // Chord length estimate\n const chord = dist3(p0, p1) + dist3(p1, p2) + dist3(p2, p3);\n const stepCount = Math.max(16, Math.min(256, Math.ceil(chord / (options?.resolution ?? 2))));\n\n const samples: SegmentSample[] = [];\n let segLen = 0;\n let prev = p0;\n samples.push({ t: 0, s: 0, pos: p0 });\n\n for (let k = 1; k <= stepCount; k++) {\n const t = k / stepCount;\n const pos = cubicPos(p0, p1, p2, p3, t);\n segLen += dist3(prev, pos);\n samples.push({ t, s: segLen, pos });\n prev = pos;\n }\n\n segments.push({\n p0,\n p1,\n p2,\n p3,\n length: segLen,\n samples,\n });\n totalLength += segLen;\n }\n\n return {\n waypoints,\n closed,\n totalLength,\n segments,\n };\n}\n\n/**\n * Samples the spatial motion path at a normalized distance fraction [0..1].\n * Guarantees strictly constant pixel speed regardless of control handle asymmetry.\n */\nexport function sampleMotionPath(path: SpatialMotionPath, distanceFraction: number): SpatialPathSample {\n const clampedFraction = Math.max(0, Math.min(1, distanceFraction));\n const targetDistance = clampedFraction * path.totalLength;\n\n if (path.totalLength === 0) {\n const p = toVec3(path.waypoints[0].point);\n return {\n position: p,\n tangent: [1, 0, 0],\n heading: 0,\n normal: [0, 1, 0],\n curvature: 0,\n distance: 0,\n };\n }\n\n // Find target segment\n let accumulated = 0;\n let targetSeg = path.segments[0];\n let segDistance = targetDistance;\n\n for (const seg of path.segments) {\n if (accumulated + seg.length >= targetDistance || seg === path.segments[path.segments.length - 1]) {\n targetSeg = seg;\n segDistance = Math.max(0, Math.min(seg.length, targetDistance - accumulated));\n break;\n }\n accumulated += seg.length;\n }\n\n // Binary search for exact sample in target segment's arc length table\n const samples = targetSeg.samples;\n let low = 0;\n let high = samples.length - 1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (samples[mid].s < segDistance) {\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n const idx = Math.max(0, Math.min(samples.length - 2, high));\n const s0 = samples[idx];\n const s1 = samples[idx + 1];\n\n const segRange = s1.s - s0.s;\n const factor = segRange > 1e-7 ? (segDistance - s0.s) / segRange : 0;\n const t = s0.t + factor * (s1.t - s0.t);\n\n // Evaluate exact position, velocity, acceleration at t\n const pos = cubicPos(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const vel = cubicVel(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const acc = cubicAcc(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n\n const speed = Math.sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);\n const safeSpeed = speed > 1e-6 ? speed : 1;\n const tangent: Vec3 = [vel[0] / safeSpeed, vel[1] / safeSpeed, vel[2] / safeSpeed];\n\n const heading = Math.atan2(tangent[1], tangent[0]);\n const normal: Vec3 = [-tangent[1], tangent[0], 0];\n\n // Curvature: kappa = |v x a| / |v|^3\n const cx = vel[1] * acc[2] - vel[2] * acc[1];\n const cy = vel[2] * acc[0] - vel[0] * acc[2];\n const cz = vel[0] * acc[1] - vel[1] * acc[0];\n const crossMag = Math.sqrt(cx * cx + cy * cy + cz * cz);\n const curvature = crossMag / (safeSpeed * safeSpeed * safeSpeed);\n\n return {\n position: pos,\n tangent,\n heading,\n normal,\n curvature,\n distance: targetDistance,\n };\n}\n\n/**\n * Samples a spatial motion path driven by elapsed time and AE keyframe velocity easing.\n * Combines spatial arc-length constancy with temporal speed curves.\n */\nexport function sampleMotionPathAtTime(\n path: SpatialMotionPath,\n time: number,\n duration: number,\n ease?: {\n easeIn?: KeyframeEase;\n easeOut?: KeyframeEase;\n }\n): SpatialPathSample {\n const distanceFraction = evaluateKeyframeSegment(\n 0,\n 1,\n duration,\n time,\n ease?.easeOut,\n ease?.easeIn\n );\n return sampleMotionPath(path, distanceFraction);\n}\n\n","import type { Scene, SceneMedia, Shot } from '../scene/types.js';\nimport { validateScene, type SceneIssue } from '../scene/validate.js';\nimport { simulateScene } from '../scene/player.js';\nimport type { Review } from '../scene/report.js';\nimport { applyRig, setRigWidget } from '../scene/rig.js';\n\nexport interface AgentToolDefinition {\n name: string;\n description: string;\n input_schema: Record<string, unknown>;\n}\n\nexport const FLAIR_AGENT_TOOLS: AgentToolDefinition[] = [\n {\n name: 'get_scene',\n description: 'Returns the current scene JSON (or a concise structural outline) and any static validation issues.',\n input_schema: {\n type: 'object',\n properties: {\n view: {\n type: 'string',\n enum: ['full', 'outline'],\n description:\n 'When \"outline\", returns scene hierarchy, timing, and framing without dense commands or raw media sources.',\n },\n },\n additionalProperties: false,\n },\n },\n {\n name: 'write_scene',\n description: 'Overwrites the entire scene with a new specification and validates it.',\n input_schema: {\n type: 'object',\n properties: {\n scene: {\n type: 'object',\n description:\n 'Full Scene object with name, stage, media, and shots. A shot camera frames a box {x, y, width, height} or elements {frame: [ids]}, and may add tilt, turn, roll (degrees, tilt/turn up to 75), perspective (default 1.2) and motionBlur (0-3, 1 natural); angles persist until changed.',\n },\n },\n required: ['scene'],\n additionalProperties: false,\n },\n },\n {\n name: 'update_shot',\n description: 'Updates fields of a specific shot (1-based index) without rewriting the whole scene.',\n input_schema: {\n type: 'object',\n properties: {\n shot: { type: 'integer', minimum: 1, description: '1-based index of the shot to update.' },\n set: { type: 'object', description: 'Fields to set or replace on this shot.' },\n remove: {\n type: 'array',\n items: { type: 'string' },\n description: 'Field names to delete from this shot.',\n },\n },\n required: ['shot'],\n additionalProperties: false,\n },\n },\n {\n name: 'insert_shots',\n description: 'Inserts one or more shots at a given position.',\n input_schema: {\n type: 'object',\n properties: {\n after: {\n type: 'integer',\n minimum: 0,\n description: '0 to insert at the beginning, or 1-based index of shot to insert after.',\n },\n shots: {\n type: 'array',\n items: { type: 'object' },\n description: 'Array of Shot objects to insert.',\n },\n },\n required: ['after', 'shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'delete_shots',\n description: 'Deletes one or more shots by 1-based index.',\n input_schema: {\n type: 'object',\n properties: {\n shots: {\n type: 'array',\n items: { type: 'integer', minimum: 1 },\n description: '1-based shot numbers to delete.',\n },\n },\n required: ['shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'set_media',\n description: 'Adds, updates, or removes embedded media (e.g. bespoke WebGL shaders) by ID.',\n input_schema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Media identifier.' },\n media: {\n type: ['object', 'null'],\n description: 'SceneMedia object (e.g. { type: \"shader\", source: \"...\" }), or null to remove.',\n },\n },\n required: ['id', 'media'],\n additionalProperties: false,\n },\n },\n {\n name: 'preview_scene',\n description: 'Simulates the scene fast and off-screen, returning timing, layout checks, and review report.',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'set_rig_widget',\n description: 'Adjusts a high-level creative rig widget (slider, popup, or toggle) and propagates parameters to shaders and elements.',\n input_schema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Rig widget identifier/name.' },\n value: {\n type: ['number', 'string', 'boolean'],\n description: 'New value (number for slider, string for popup, boolean for toggle).',\n },\n },\n required: ['name', 'value'],\n additionalProperties: false,\n },\n },\n];\n\nexport interface SceneOutlineShot {\n shot: number;\n caption?: string;\n title?: string;\n hold?: number;\n camera?: Shot['camera'];\n commandCount: number;\n effects?: string[];\n}\n\nexport interface SceneOutline {\n name: string;\n title?: string;\n description?: string;\n stage?: Scene['stage'];\n target?: Scene['target'];\n mediaIds: string[];\n shots: SceneOutlineShot[];\n}\n\nexport type SceneToolResult =\n | { ok: true; scene: Scene; outline?: SceneOutline; issues: SceneIssue[]; review?: Review }\n | { ok: false; error: string };\n\n/**\n * Pure state machine that applies tool operations to a Scene.\n */\nexport async function applySceneTool(\n scene: Scene,\n toolName: string,\n input: Record<string, any> = {},\n): Promise<SceneToolResult> {\n switch (toolName) {\n case 'get_scene': {\n const issues = validateScene(scene);\n if (input.view === 'outline') {\n const outline: SceneOutline = {\n name: scene.name,\n title: scene.title,\n description: scene.description,\n stage: scene.stage,\n target: scene.target,\n mediaIds: Object.keys(scene.media || {}),\n shots: scene.shots.map((s, i) => ({\n shot: i + 1,\n caption: s.caption,\n title: s.title,\n hold: s.hold,\n camera: s.camera,\n commandCount: s.run?.length ?? 0,\n effects: s.effects?.map((e) => e.type),\n })),\n };\n return { ok: true, scene, outline, issues };\n }\n return { ok: true, scene, issues };\n }\n\n case 'write_scene': {\n if (!input.scene || typeof input.scene !== 'object') {\n return { ok: false, error: 'Expected scene object in arguments.' };\n }\n const newScene = input.scene as Scene;\n const issues = validateScene(newScene);\n return { ok: true, scene: newScene, issues };\n }\n\n case 'update_shot': {\n const idx = input.shot - 1;\n if (idx < 0 || idx >= scene.shots.length) {\n return { ok: false, error: `Invalid shot number ${input.shot}; scene has ${scene.shots.length} shots.` };\n }\n const existing = scene.shots[idx]!;\n const updated: Record<string, any> = { ...existing, ...(input.set || {}) };\n if (Array.isArray(input.remove)) {\n for (const k of input.remove) {\n delete updated[k];\n }\n }\n const shots = [...scene.shots];\n shots[idx] = updated as Shot;\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'insert_shots': {\n const after = input.after ?? scene.shots.length;\n if (after < 0 || after > scene.shots.length) {\n return { ok: false, error: `Invalid after index ${after}.` };\n }\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to insert.' };\n }\n const shots = [...scene.shots.slice(0, after), ...input.shots, ...scene.shots.slice(after)];\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'delete_shots': {\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to delete.' };\n }\n const toDelete = new Set(input.shots.map((n: number) => n - 1));\n const shots = scene.shots.filter((_, i) => !toDelete.has(i));\n if (shots.length === 0) {\n return { ok: false, error: 'Cannot delete all shots in scene.' };\n }\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'set_media': {\n if (!input.id || typeof input.id !== 'string') {\n return { ok: false, error: 'Expected string media id.' };\n }\n const media = { ...(scene.media || {}) };\n if (input.media === null) {\n delete media[input.id];\n } else {\n media[input.id] = input.media as SceneMedia;\n }\n const newScene = { ...scene, media };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'preview_scene': {\n const { review } = await simulateScene(scene);\n return { ok: true, scene, issues: validateScene(scene), review };\n }\n\n case 'set_rig_widget': {\n if (!scene.rig || !scene.rig.widgets || !scene.rig.widgets[input.name]) {\n return { ok: false, error: `Scene does not have a rig widget named \"${input.name}\".` };\n }\n try {\n const updatedRig = setRigWidget(scene.rig, input.name, input.value);\n const newScene = applyRig(updatedRig, scene);\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n } catch (err: any) {\n return { ok: false, error: err.message || String(err) };\n }\n }\n\n default:\n return { ok: false, error: `Unknown tool name: ${toolName}` };\n }\n}\n","/**\n * Atomic Agent Multi-Tool Batching with Result Variable Substitution.\n * Inspired by EffectCraft's atomic batch execution protocol.\n *\n * Allows AI agents to execute multi-step modifications to a Scene in a single turn,\n * with atomic rollback on failure and cross-step variable substitution ($1.prop, $2.prop).\n */\n\nimport type { Scene } from '../scene/types.js';\nimport { applySceneTool, type SceneToolResult } from './tools.js';\n\nexport interface BatchCommand {\n /** Name of the tool to execute (e.g. 'update_shot', 'insert_shots', 'set_rig_widget'). */\n tool: string;\n /** Parameters for the tool call. */\n params?: Record<string, any>;\n}\n\nexport interface BatchExecutionStepResult {\n step: number;\n tool: string;\n result: SceneToolResult;\n}\n\nexport interface BatchExecutionResult {\n ok: boolean;\n scene: Scene;\n steps: BatchExecutionStepResult[];\n error?: string;\n failedStep?: number;\n}\n\n/**\n * Resolves nested property path on an object (e.g. \"a.b[0].c\").\n */\nfunction getByPath(obj: any, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const parts = path.replace(/\\[(\\w+)\\]/g, '.$1').split('.');\n let curr = obj;\n for (const part of parts) {\n if (curr === undefined || curr === null) return undefined;\n curr = curr[part];\n }\n return curr;\n}\n\n/**\n * Recursively substitutes `$stepIndex.path` references in parameters using previous step results.\n * E.g., \"$1.scene.shots[0].duration\" -> substituted with the duration value from step 1 result.\n */\nexport function substituteVariables(\n value: any,\n stepResults: Map<number, SceneToolResult>,\n): any {\n if (typeof value === 'string') {\n // Check if the entire string is a substitution reference: \"$1.path.to.prop\"\n const match = /^\\$(\\d+)\\.(.+)$/.exec(value);\n if (match) {\n const stepIdx = parseInt(match[1]!, 10);\n const path = match[2]!;\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return resolved;\n }\n }\n }\n // Partial template string substitution: \"Hello $1.scene.name\"\n return value.replace(/\\$(\\d+)\\.([a-zA-Z0-9_.[\\]]+)/g, (fullMatch, stepStr, path) => {\n const stepIdx = parseInt(stepStr, 10);\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return String(resolved);\n }\n }\n return fullMatch;\n });\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => substituteVariables(item, stepResults));\n }\n\n if (value !== null && typeof value === 'object') {\n const copy: Record<string, any> = {};\n for (const [k, v] of Object.entries(value)) {\n copy[k] = substituteVariables(v, stepResults);\n }\n return copy;\n }\n\n return value;\n}\n\n/**\n * Executes an atomic batch of scene tools with transactional rollback.\n * If any step fails, the scene rolls back to the initial state and returns the failure.\n *\n * @param scene Initial scene state before batch.\n * @param commands Ordered array of tool commands to execute.\n */\nexport async function applySceneBatch(\n scene: Scene,\n commands: BatchCommand[],\n): Promise<BatchExecutionResult> {\n let currentScene = scene;\n const stepResults = new Map<number, SceneToolResult>();\n const executedSteps: BatchExecutionStepResult[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const stepNumber = i + 1; // 1-based indexing for user/agent ergonomics\n const cmd = commands[i]!;\n\n // Perform variable substitution using results of earlier steps\n const resolvedParams = substituteVariables(cmd.params || {}, stepResults);\n\n // Prevent recursive batch execution to avoid cycles\n if (cmd.tool === 'batch_scene_tool') {\n return {\n ok: false,\n scene, // Rollback\n steps: executedSteps,\n error: `Nested batch_scene_tool is not allowed at step ${stepNumber}.`,\n failedStep: stepNumber,\n };\n }\n\n const stepResult = await applySceneTool(currentScene, cmd.tool, resolvedParams);\n stepResults.set(stepNumber, stepResult);\n executedSteps.push({\n step: stepNumber,\n tool: cmd.tool,\n result: stepResult,\n });\n\n if (!stepResult.ok) {\n // Transactional rollback: discard intermediate scenes and return original\n return {\n ok: false,\n scene, // Rollback to initial\n steps: executedSteps,\n error: `Step ${stepNumber} (${cmd.tool}) failed: ${stepResult.error}`,\n failedStep: stepNumber,\n };\n }\n\n currentScene = stepResult.scene;\n }\n\n return {\n ok: true,\n scene: currentScene,\n steps: executedSteps,\n };\n}\n"],"mappings":"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","names":["frame"]}
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes } from 'react';
3
- import { V as VectorEffect$1 } from '../types-Cl5n9s-3.js';
3
+ import { V as VectorEffect$1 } from '../types-CawMRRXq.js';
4
4
  import { C as ControlValue } from '../controls-Ec6P0Vpy.js';
5
5
  import { S as SvgMotion, a as SvgTrigger, C as Clock, b as SvgPlayer } from '../svg-BEOJriIW.js';
6
6
 
@@ -2,7 +2,7 @@ import {
2
2
  effectDefaults,
3
3
  getEffect,
4
4
  renderVectorEffect
5
- } from "../chunk-WEDILTUN.js";
5
+ } from "../chunk-TCNONB22.js";
6
6
  import {
7
7
  svgFrameMarkup,
8
8
  svgInlineLayout,