hyperframes 0.8.82 → 0.8.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/backgroundChecksWorker.js +1 -1
  2. package/dist/cli.js +1921 -1560
  3. package/dist/fontLocalizeCli.js +304 -217
  4. package/dist/hyperframe-runtime.js +81 -56
  5. package/dist/hyperframe.manifest.json +1 -1
  6. package/dist/hyperframe.runtime.iife.js +81 -56
  7. package/dist/hyperframes-player.global.js +1 -1
  8. package/dist/studio/assets/{hyperframes-player-zGIbZhLJ.js → hyperframes-player-BAerMCex.js} +1 -1
  9. package/dist/studio/assets/{index-BiLCTunu.js → index-BUhcVhNy.js} +1 -1
  10. package/dist/studio/assets/{index-DSazIt7R.js → index-BYhK_KMc.js} +193 -193
  11. package/dist/studio/assets/{index-DStmfnpZ.js → index-Iv0HI7eM.js} +1 -1
  12. package/dist/studio/{chunk-I7XNAIOF.js → chunk-3IOCVWB6.js} +6 -97
  13. package/dist/studio/chunk-3IOCVWB6.js.map +1 -0
  14. package/dist/studio/chunk-62DDWOSH.js +189 -0
  15. package/dist/studio/chunk-62DDWOSH.js.map +1 -0
  16. package/dist/studio/chunk-LPZMAGS7.js +1871 -0
  17. package/dist/studio/chunk-LPZMAGS7.js.map +1 -0
  18. package/dist/studio/chunk-QZ6HNNFG.js +934 -0
  19. package/dist/studio/chunk-QZ6HNNFG.js.map +1 -0
  20. package/dist/studio/chunk-S65AQH6M.js +101 -0
  21. package/dist/studio/chunk-S65AQH6M.js.map +1 -0
  22. package/dist/studio/{domEditingLayers-MHFDKAQ7.js → domEditingLayers-ZOOMN7CQ.js} +3 -2
  23. package/dist/studio/index.d.ts +669 -330
  24. package/dist/studio/index.html +1 -1
  25. package/dist/studio/index.js +20501 -23167
  26. package/dist/studio/index.js.map +1 -1
  27. package/dist/studio/player.d.ts +30 -0
  28. package/dist/studio/player.js +10 -0
  29. package/dist/studio/player.js.map +1 -0
  30. package/dist/studio/ui.d.ts +294 -0
  31. package/dist/studio/ui.js +66 -0
  32. package/dist/studio/ui.js.map +1 -0
  33. package/package.json +1 -1
  34. package/dist/studio/chunk-I7XNAIOF.js.map +0 -1
  35. /package/dist/studio/{domEditingLayers-MHFDKAQ7.js.map → domEditingLayers-ZOOMN7CQ.js.map} +0 -0
@@ -1,331 +1,23 @@
1
- import * as react from 'react';
2
- import { ButtonHTMLAttributes, ReactNode, ElementType, ComponentPropsWithoutRef, ReactElement, RefObject, MutableRefObject, DragEventHandler, ComponentProps, RefCallback, MouseEvent, CSSProperties, UIEvent, PointerEvent } from 'react';
1
+ export { Button, ButtonSize, ButtonVariant, ContextMenu, HyperframesLoader, HyperframesLoaderProps, HyperframesLogo, IconButton, Input, InputProps, Menu, MenuItem, MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NumberField, NumberFieldProps, Popover, PopupPreviewState, PreviewState, Select, SelectOption, SelectProps, Slider, SliderProps, Tab, TabPanel, Tabs, TabsList, Toggle, ToggleProps, Tooltip, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, popupSurface } from './ui.js';
3
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
5
- import * as node_modules_cn_dist_types from 'node_modules/cn/dist/types';
6
- import { ContextMenu as ContextMenu$1 } from '@base-ui/react/context-menu';
7
- import { Menu as Menu$1 } from '@base-ui/react/menu';
8
- import { Popover as Popover$1 } from '@base-ui/react/popover';
3
+ import * as react from 'react';
4
+ import { RefObject, MutableRefObject, ReactNode, DragEventHandler, ComponentProps, RefCallback, MouseEvent, CSSProperties, UIEvent, PointerEvent } from 'react';
9
5
  import { RuntimeTimelineClipIdentity, HyperframePickerElementInfo } from '@hyperframes/core';
10
6
  import { GsapAnimation, ParsedGsap, PropertyGroupName } from '@hyperframes/core/gsap-parser';
7
+ export { Player } from './player.js';
8
+ import { Composition } from '@hyperframes/sdk';
11
9
  import { MusicBeatAnalysis } from '@hyperframes/core/beats';
12
10
  import * as zustand from 'zustand';
13
11
  import { StoreApi } from 'zustand';
14
12
  import { GsapAnimation as GsapAnimation$1, ArcPathSegment } from '@hyperframes/parsers/gsap-parser';
13
+ import * as _hyperframes_parsers from '@hyperframes/parsers';
15
14
  import { CanvasResolution } from '@hyperframes/parsers';
16
- import { Composition } from '@hyperframes/sdk';
17
15
  export { SeamTransitionFrameSource, SeamTransitionLoopHandle, SeamTransitionLoopOptions, playSeamTransitionLoop } from '@hyperframes/shader-transitions';
18
-
19
- type ButtonVariant = "primary" | "secondary" | "danger" | "ghost";
20
- type ButtonSize = "sm" | "md" | "lg";
21
- /** Forces one interactive look for a gallery shot. CSS-only; see the header. */
22
- type PreviewState = "hover" | "active" | "focus";
23
- interface ButtonBaseProps extends ButtonHTMLAttributes<HTMLButtonElement> {
24
- variant?: ButtonVariant;
25
- size?: ButtonSize;
26
- "data-preview-state"?: PreviewState;
27
- }
28
- interface ButtonProps extends ButtonBaseProps {
29
- loading?: boolean;
30
- icon?: ReactNode;
31
- }
32
- /**
33
- * Shared by Button and IconButton. `disabled:` keeps pointer events alive so a
34
- * wrapping Tooltip can still explain why the control is disabled.
35
- */
36
- declare const buttonBase: string;
37
- /**
38
- * One entry per variant. The `data-[preview-state=…]` half of each string
39
- * repeats the `hover:` and `active:` half exactly; the test pairs them.
40
- */
41
- declare const buttonVariants: Record<ButtonVariant, string>;
42
- /**
43
- * The three control heights, 24 / 28 / 32 px, from `--spacing-ctl-*`.
44
- * Exported so the Capture download `<a href>` can wear the same recipe as a Button.
45
- */
46
- declare const buttonSizes: Record<ButtonSize, string>;
47
- declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
48
-
49
- declare function HyperframesLogo(): react_jsx_runtime.JSX.Element;
50
-
51
- interface IconButtonProps extends ButtonBaseProps {
52
- icon: ReactNode;
53
- "aria-label": string;
54
- }
55
- declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
56
-
57
- /**
58
- * Base UI lets `className` be a function of the part's state. Studio's parts
59
- * merge a string with `cn`, so the string form is the one they accept.
60
- */
61
- type StyledProps$1<T extends ElementType> = Omit<ComponentPropsWithoutRef<T>, "className"> & {
62
- className?: string;
63
- };
64
- /**
65
- * Groups a tab list with its panels. Uncontrolled by default; pass `value` and
66
- * `onValueChange` for a strip whose selection lives in a store.
67
- */
68
- declare function Tabs(props: ComponentPropsWithoutRef<typeof Tabs$1.Root>): react_jsx_runtime.JSX.Element;
69
- /** The strip. Give it an `aria-label`: a tablist with no name is unlabelled. */
70
- declare function TabsList({ className, ...props }: StyledProps$1<typeof Tabs$1.List>): react_jsx_runtime.JSX.Element;
71
- interface TabProps extends StyledProps$1<typeof Tabs$1.Tab> {
72
- value: string;
73
- "data-preview-state"?: PreviewState;
74
- }
75
- /**
76
- * aria-selected drives the selected look (Base UI sets it) so assistive tech
77
- * and sighted users match. data-preview-state is for gallery shots only.
78
- */
79
- declare function Tab({ value, className, ...props }: TabProps): react_jsx_runtime.JSX.Element;
80
- /** The panel for one tab. Base UI wires `aria-labelledby` back to its tab. */
81
- declare function TabPanel({ className, ...props }: StyledProps$1<typeof Tabs$1.Panel>): react_jsx_runtime.JSX.Element;
82
-
83
- interface HyperframesLoaderProps {
84
- /** Status text shown below the mark. */
85
- title: string;
86
- /** Optional secondary detail line. */
87
- detail?: string;
88
- /** Optional monospace third line for IDs, counts, or percentages. */
89
- mono?: string;
90
- /** Pixel size of the mark itself; status text scales independently. */
91
- size?: number;
92
- /** Optional normalized progress value from 0 to 1. */
93
- progress?: number;
94
- }
95
- declare function HyperframesLoader({ title, detail, mono, size, progress, }: HyperframesLoaderProps): react_jsx_runtime.JSX.Element;
96
-
97
- interface TooltipProps {
98
- label: string;
99
- /** A single element, wrapped in a box-less span so a disabled one still gets hover. */
100
- children: ReactElement<{
101
- "aria-describedby"?: string;
102
- }>;
103
- /** Hover delay in ms. */
104
- delay?: number;
105
- side?: "top" | "bottom" | "left" | "right";
106
- }
107
- declare function Tooltip({ label, children, delay, side }: TooltipProps): react_jsx_runtime.JSX.Element;
108
-
109
- /**
110
- * Studio's tailwind-merge config: teaches it the two scales `theme.css`
111
- * invents (`text-step-*`, `ctl`/`ctl-sm`/`ctl-lg`) so overrides replace, not stack.
112
- */
113
- declare const cn: node_modules_cn_dist_types.CnFunction;
114
-
115
- /**
116
- * Base UI lets `className` be a function of the part's state. Studio's parts
117
- * merge a string with `cn`, so the string form is the one they accept.
118
- */
119
- type StyledProps<T extends ElementType> = Omit<ComponentPropsWithoutRef<T>, "className"> & {
120
- className?: string;
121
- };
122
- /** Forces the settled open look for a gallery shot; CSS-only, open state stays controlled. */
123
- type PopupPreviewState = "open";
124
- /** Where the portal puts the popup. `null` keeps it inline, next to its trigger. */
125
- type PortalContainer$1 = ComponentPropsWithoutRef<typeof Menu$1.Portal>["container"];
126
- /**
127
- * Chrome shared by every floating panel (`Popover` too); callers add their own shadow token.
128
- */
129
- declare const popupSurface: string;
130
- type MenuItemTone = "default" | "danger";
131
- interface PositionedProps {
132
- side?: "top" | "bottom" | "left" | "right";
133
- align?: "start" | "center" | "end";
134
- sideOffset?: number;
135
- /** Portal target. Pass the shadow root when the trigger lives in one. */
136
- container?: PortalContainer$1;
137
- /** Names the popup for assistive tech. A menu with no name is unlabelled. */
138
- "aria-label"?: string;
139
- className?: string;
140
- "data-preview-state"?: PopupPreviewState;
141
- }
142
- interface MenuProps extends PositionedProps, Omit<ComponentPropsWithoutRef<typeof Menu$1.Root>, "children"> {
143
- /** A single element. It becomes the trigger; no wrapper is added around it. */
144
- trigger: ReactElement;
145
- /** The items: `MenuItem`, `MenuRadioGroup`, `MenuSeparator`. */
146
- children: ReactNode;
147
- }
148
- /**
149
- * A menu opened by its trigger. Uncontrolled by default; pass `open` and
150
- * `onOpenChange` for a menu whose state lives in a store.
151
- */
152
- declare function Menu({ trigger, children, side, align, sideOffset, container, className, "aria-label": ariaLabel, "data-preview-state": previewState, ...root }: MenuProps): react_jsx_runtime.JSX.Element;
153
- interface ContextMenuProps extends PositionedProps, Omit<ComponentPropsWithoutRef<typeof ContextMenu$1.Root>, "children"> {
154
- /**
155
- * The right-clickable area, as the caller's own element. Its children are
156
- * kept: the trigger renders that element rather than wrapping it.
157
- */
158
- trigger: ReactElement;
159
- children: ReactNode;
160
- }
161
- /** Opened by right click or long press at the pointer, so `side` and `align` are not offered. */
162
- declare function ContextMenu({ trigger, children, container, className, "aria-label": ariaLabel, "data-preview-state": previewState, ...root }: Omit<ContextMenuProps, "side" | "align" | "sideOffset">): react_jsx_runtime.JSX.Element;
163
- /** Keyboard shortcut hint, mono and tabular; exported for hints that are not a plain string. */
164
- declare function MenuShortcut({ className, ...props }: StyledProps<"span">): react_jsx_runtime.JSX.Element;
165
- interface MenuItemProps extends StyledProps<typeof Menu$1.Item> {
166
- /** Rendered as a dim mono hint on the trailing edge. Decorative. */
167
- shortcut?: string;
168
- /** `danger` for a destructive action (Delete, Remove). */
169
- tone?: MenuItemTone;
170
- "data-preview-state"?: "hover";
171
- }
172
- /** One action. `disabled` items are skipped by the arrow keys, not just dimmed. */
173
- declare function MenuItem({ shortcut, tone, className, children, ...props }: MenuItemProps): react_jsx_runtime.JSX.Element;
174
- /** Single-choice group; selection is `aria-checked` on each item, which the dot indicator draws from. */
175
- declare function MenuRadioGroup(props: ComponentPropsWithoutRef<typeof Menu$1.RadioGroup>): react_jsx_runtime.JSX.Element;
176
- interface MenuRadioItemProps extends StyledProps<typeof Menu$1.RadioItem> {
177
- "data-preview-state"?: "hover";
178
- }
179
- /** One choice in a `MenuRadioGroup`. The dot renders only while it is checked. */
180
- declare function MenuRadioItem({ className, children, ...props }: MenuRadioItemProps): react_jsx_runtime.JSX.Element;
181
- /** A hairline between two groups of items. */
182
- declare function MenuSeparator({ className, ...props }: StyledProps<typeof Menu$1.Separator>): react_jsx_runtime.JSX.Element;
183
-
184
- type PortalContainer = ComponentPropsWithoutRef<typeof Popover$1.Portal>["container"];
185
- interface PopoverProps extends Omit<ComponentPropsWithoutRef<typeof Popover$1.Root>, "children"> {
186
- /** A single element. It becomes the trigger; no wrapper is added around it. */
187
- trigger: ReactElement;
188
- /** Arbitrary content. The popover owns none of its keys. */
189
- children: ReactNode;
190
- side?: "top" | "bottom" | "left" | "right";
191
- align?: "start" | "center" | "end";
192
- sideOffset?: number;
193
- /** Portal target. Pass the shadow root when the trigger lives in one. */
194
- container?: PortalContainer;
195
- /** Names the popup for assistive tech. */
196
- "aria-label"?: string;
197
- /**
198
- * What to focus on open. Defaults to Base UI's behaviour (the first tabbable
199
- * element), which is what a rename field wants.
200
- */
201
- initialFocus?: ComponentPropsWithoutRef<typeof Popover$1.Popup>["initialFocus"];
202
- className?: string;
203
- "data-preview-state"?: PopupPreviewState;
204
- }
205
- declare function Popover({ trigger, children, side, align, sideOffset, container, className, initialFocus, "aria-label": ariaLabel, "data-preview-state": previewState, ...root }: PopoverProps): react_jsx_runtime.JSX.Element;
206
-
207
- /**
208
- * Shared field look (also used by NumberField and Select). Each interactive state is written
209
- * twice, real and `data-[preview-state=...]`; `valueControls.test.tsx` asserts the lists match.
210
- */
211
- declare const fieldBase: string;
212
- /** The text itself, inside the box. The box owns the border and the ring. */
213
- declare const fieldText: string;
214
- interface InputProps extends Omit<ComponentPropsWithoutRef<"input">, "value" | "onChange" | "className"> {
215
- /** The committed value. A draft lives inside until Enter or blur. */
216
- value: string;
217
- /** Called with the draft on Enter and on blur, only when it really changed. */
218
- onCommit: (next: string) => void;
219
- /** Called once per committed change, for design-input telemetry. */
220
- onTrack?: () => void;
221
- /** Marks the field invalid: red boundary and `aria-invalid`. */
222
- invalid?: boolean;
223
- className?: string;
224
- "data-preview-state"?: PreviewState;
225
- }
226
- declare function Input({ value, onCommit, onTrack, invalid, disabled, className, "data-preview-state": previewState, ...props }: InputProps): react_jsx_runtime.JSX.Element;
227
-
228
- interface NumberFieldProps {
229
- /** Accessible name. The inspector's row label is the usual one. */
230
- label: string;
231
- /** The committed value. */
232
- value: number;
233
- /** Called when a commit boundary produces a value different from `value`. */
234
- onCommit: (next: number) => void;
235
- /** Called once per committed change, for design-input telemetry. */
236
- onTrack?: () => void;
237
- /** Rendered beside the number: "px", "%", "deg". Never part of the text. */
238
- unit?: string;
239
- min?: number;
240
- max?: number;
241
- step?: number;
242
- disabled?: boolean;
243
- className?: string;
244
- "data-preview-state"?: PreviewState;
245
- }
246
- declare function NumberField({ label, value, onCommit, onTrack, unit, min, max, step, disabled, className, "data-preview-state": previewState, }: NumberFieldProps): react_jsx_runtime.JSX.Element;
247
-
248
- interface SelectOption {
249
- label: string;
250
- value: string;
251
- /** Offered but not choosable; the label stays visible so the reason stays visible too. */
252
- disabled?: boolean;
253
- }
254
- interface SelectProps {
255
- /** Accessible name for the trigger. */
256
- label: string;
257
- value: string;
258
- options: SelectOption[];
259
- /** Called when a different option is chosen. */
260
- onCommit: (next: string) => void;
261
- /** Called once per committed change, for design-input telemetry. */
262
- onTrack?: () => void;
263
- disabled?: boolean;
264
- className?: string;
265
- "data-preview-state"?: PreviewState;
266
- }
267
- declare function Select({ label, value, options, onCommit, onTrack, disabled, className, "data-preview-state": previewState, }: SelectProps): react_jsx_runtime.JSX.Element;
268
-
269
- interface SliderProps {
270
- /** Accessible name for the thumb. The inspector's row label is the usual one. */
271
- label: string;
272
- /** The committed value. */
273
- value: number;
274
- min: number;
275
- max: number;
276
- step?: number;
277
- /** Every intermediate value while dragging or stepping. Not a commit. */
278
- onPreview?: (next: number) => void;
279
- /** Called at a commit boundary when the value really changed. */
280
- onCommit: (next: number) => void;
281
- /** Called once per commit boundary, for design-input telemetry. */
282
- onTrack?: () => void;
283
- disabled?: boolean;
284
- className?: string;
285
- "data-preview-state"?: PreviewState;
286
- }
287
- declare function Slider({ label, value, min, max, step, onPreview, onCommit, onTrack, disabled, className, "data-preview-state": previewState, }: SliderProps): react_jsx_runtime.JSX.Element;
288
-
289
- interface ToggleProps {
290
- /** Accessible name. */
291
- label: string;
292
- checked: boolean;
293
- /** Called on every flip. */
294
- onCommit: (next: boolean) => void;
295
- /** Called once per flip, for design-input telemetry. */
296
- onTrack?: () => void;
297
- disabled?: boolean;
298
- className?: string;
299
- "data-preview-state"?: PreviewState;
300
- }
301
- declare function Toggle({ label, checked, onCommit, onTrack, disabled, className, "data-preview-state": previewState, }: ToggleProps): react_jsx_runtime.JSX.Element;
302
-
303
- interface PlayerProps {
304
- projectId?: string;
305
- directUrl?: string;
306
- onLoad: () => void;
307
- /** Fires once the loaded document is painted and every loader (shader, assets) has cleared. */
308
- onReadyToShowChange?: (ready: boolean) => void;
309
- onPreviewError?: (message: string) => void;
310
- onCompositionLoadingChange?: (loading: boolean) => void;
311
- onPainted?: (details: {
312
- iframe: HTMLIFrameElement;
313
- startedAt: number;
314
- loadId: number;
315
- }) => void;
316
- portrait?: boolean;
317
- style?: React.CSSProperties;
318
- suppressLoadingOverlay?: boolean;
319
- }
320
- /**
321
- * Renders a composition preview using the <hyperframes-player> web component.
322
- *
323
- * The web component handles iframe scaling, dimension detection, and
324
- * ResizeObserver internally. This wrapper bridges its inner iframe to the
325
- * forwarded ref so useTimelinePlayer can access it for clip manifest parsing,
326
- * timeline probing, and DOM inspection.
327
- */
328
- declare const Player: react.ForwardRefExoticComponent<PlayerProps & react.RefAttributes<HTMLIFrameElement>>;
16
+ import '@base-ui/react/tabs';
17
+ import 'node_modules/cn/dist/types';
18
+ import '@base-ui/react/context-menu';
19
+ import '@base-ui/react/menu';
20
+ import '@base-ui/react/popover';
329
21
 
330
22
  interface ShortcutHint {
331
23
  key: string;
@@ -1081,6 +773,12 @@ interface TimelineRangeSelection {
1081
773
  anchorY: number;
1082
774
  }
1083
775
 
776
+ /** Durable evidence returned by the one Studio DOM persistence actor. */
777
+ interface DomEditPersistOutcome {
778
+ sourceFile: string;
779
+ version: string;
780
+ changed: boolean;
781
+ }
1084
782
  /**
1085
783
  * Durability report for a patch-batches commit. `durable === false` means the
1086
784
  * server could not locate at least one patch target on disk — the preview was
@@ -1095,7 +793,7 @@ interface DomEditPatchBatchesResult {
1095
793
  changed: boolean;
1096
794
  }
1097
795
 
1098
- interface RecordEditInput$2 {
796
+ interface RecordEditInput$4 {
1099
797
  label: string;
1100
798
  coalesceKey?: string;
1101
799
  files: Record<string, {
@@ -1119,7 +817,7 @@ interface UseTimelineEditingOptions {
1119
817
  showToast: (message: string, tone?: "error" | "info") => void;
1120
818
  writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
1121
819
  observeProjectFileVersion?: (path: string, version: string | null) => void;
1122
- recordEdit: (input: RecordEditInput$2) => Promise<void>;
820
+ recordEdit: (input: RecordEditInput$4) => Promise<void>;
1123
821
  reloadPreview: () => void;
1124
822
  previewIframeRef: RefObject<HTMLIFrameElement | null>;
1125
823
  pendingTimelineEditPathRef: MutableRefObject<Set<string>>;
@@ -1406,18 +1104,24 @@ interface TimelineTheme {
1406
1104
 
1407
1105
  type TimelineEditOverrides = Pick<TimelineEditCallbacks, "onMoveElement" | "onMoveElements" | "onResizeElement" | "onResizeElements" | "onBlockedEditAttempt" | "onSplitElement">;
1408
1106
 
1107
+ /** With both set, a lane move restacks the preview's z-index to match the rows; each overrides Studio's own. */
1108
+ interface TimelineStackingSyncProps {
1109
+ previewIframeRef?: RefObject<HTMLIFrameElement | null>;
1110
+ onZIndexReorder?: TimelineZIndexReorderCommit;
1111
+ }
1112
+
1409
1113
  interface TimelineClipRenderContext {
1410
1114
  priority: "overscan" | "visible" | "interaction";
1411
1115
  rich: boolean;
1412
1116
  }
1413
- interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides {
1117
+ interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides, TimelineStackingSyncProps {
1414
1118
  /** Project-scoped reset boundary; soft source refreshes retain the same epoch. */
1415
1119
  sessionEpoch?: number;
1416
- /** keepPlaying: true preserves the current play state across the seek. */
1417
1120
  onSeek?: (time: number, options?: {
1418
1121
  keepPlaying?: boolean;
1419
1122
  }) => void;
1420
1123
  onDrillDown?: (element: TimelineElement) => void;
1124
+ /** Picture only: takes no pointer input. Interactive content goes in renderClipOverlay. */
1421
1125
  renderClipContent?: (element: TimelineElement, style: {
1422
1126
  clip: string;
1423
1127
  label: string;
@@ -1443,7 +1147,7 @@ interface TimelineEmptyStateProps {
1443
1147
  }
1444
1148
  declare function TimelineEmptyState({ isDragOver, onFileDrop, onDragOver, onDragLeave, onDrop, }: TimelineEmptyStateProps): react_jsx_runtime.JSX.Element;
1445
1149
 
1446
- interface Rect {
1150
+ interface Rect$1 {
1447
1151
  left: number;
1448
1152
  top: number;
1449
1153
  width: number;
@@ -1790,7 +1494,7 @@ type TimelineCanvasState = Omit<TimelineLaneBaseProps, "setRangeSelection" | "se
1790
1494
  effectiveDuration: number;
1791
1495
  majorTickInterval: number;
1792
1496
  rangeSelection: TimelineRangeSelection | null;
1793
- marqueeRect: Rect | null;
1497
+ marqueeRect: Rect$1 | null;
1794
1498
  resizingClip: ResizingClipState | null;
1795
1499
  isScrubbing: boolean;
1796
1500
  playheadRef: React.RefObject<HTMLDivElement | null>;
@@ -2544,6 +2248,7 @@ interface StudioAppProps {
2544
2248
  }
2545
2249
  declare function StudioApp({ readOnlyPreview, readOnlyPreviewReason }?: StudioAppProps): react_jsx_runtime.JSX.Element;
2546
2250
 
2251
+ type RightPanelTab = "layers" | "design" | "renders" | "block-params" | "slideshow" | "variables";
2547
2252
  interface AgentModalAnchorPoint {
2548
2253
  x: number;
2549
2254
  y: number;
@@ -2744,7 +2449,7 @@ declare function findElementBlock(html: string, elementId: string): {
2744
2449
  isSelfClosing: boolean;
2745
2450
  } | null;
2746
2451
 
2747
- interface RecordEditInput$1 {
2452
+ interface RecordEditInput$3 {
2748
2453
  label: string;
2749
2454
  coalesceKey?: string;
2750
2455
  coalesceMs?: number;
@@ -2790,7 +2495,7 @@ declare function usePersistentEditHistory({ projectId }: UsePersistentEditHistor
2790
2495
  createdAt: number;
2791
2496
  }[];
2792
2497
  };
2793
- recordEdit: ({ label, coalesceKey, coalesceMs, files }: RecordEditInput$1) => Promise<void>;
2498
+ recordEdit: ({ label, coalesceKey, coalesceMs, files }: RecordEditInput$3) => Promise<void>;
2794
2499
  undo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
2795
2500
  redo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
2796
2501
  };
@@ -3026,7 +2731,7 @@ interface AudioMeterStripProps {
3026
2731
  }
3027
2732
  declare const AudioMeterStrip: react.NamedExoticComponent<AudioMeterStripProps>;
3028
2733
 
3029
- interface RecordEditInput {
2734
+ interface RecordEditInput$2 {
3030
2735
  label: string;
3031
2736
  coalesceKey?: string;
3032
2737
  files: Record<string, {
@@ -3040,7 +2745,7 @@ interface UseClipboardOptions {
3040
2745
  domEditSelectionRef: React.MutableRefObject<DomEditSelection | null>;
3041
2746
  showToast: (message: string, tone?: "error" | "info") => void;
3042
2747
  writeProjectFile: (path: string, content: string) => Promise<void>;
3043
- recordEdit: (input: RecordEditInput) => Promise<void>;
2748
+ recordEdit: (input: RecordEditInput$2) => Promise<void>;
3044
2749
  reloadPreview: () => void;
3045
2750
  handleTimelineElementsDelete: (elements: TimelineElement[]) => Promise<void>;
3046
2751
  handleDomEditElementDelete: (selection: DomEditSelection) => Promise<void>;
@@ -3055,4 +2760,638 @@ declare function useClipboard({ projectId, activeCompPath, domEditSelectionRef,
3055
2760
  canPaste: () => boolean;
3056
2761
  };
3057
2762
 
3058
- export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, AudioMeterStrip, type AudioMeterStripProps, AudioWaveform, type AudioWaveformProps, type BlockedTimelineEditIntent, Button, type ButtonSize, type ButtonVariant, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ContextMenu, DEFAULT_SHORTCUT_SECTIONS, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, HyperframesLoader, type HyperframesLoaderProps, HyperframesLogo, IconButton, ImageThumbnail, type ImageThumbnailProps, Input, type InputProps, Menu, MenuItem, type MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NLEPreview, NumberField, type NumberFieldProps, type PatchOperation, type PersistedRenderSettings, type PickedElement, Player, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, Popover, type PopupPreviewState, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, type PreviewSnapPreferences, type PreviewState, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, Select, type SelectOption, type SelectProps, type ShortcutHint, type ShortcutSection, Slider, type SliderProps, SnapToolbar, SourceEditor, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, Tab, TabPanel, Tabs, TabsList, type ThumbnailPriority, Timeline, TimelineClipMenu, type TimelineClipRenderContext, type TimelineEditCallbacks, type TimelineEditOutcome, type TimelineEditPermission, TimelineEditPopover, TimelineEditProvider, type TimelineElement, TimelineEmptyStatePart, TimelineFrame, TimelineGapMenu, TimelineHistoryButtons, type TimelineHistoryButtonsProps, TimelineKeyframeMenu, TimelineLanes, TimelineOverlays, TimelinePane, type TimelinePaneProps, TimelinePlayhead, TimelineProvider, TimelineRazorGuide, TimelineRuler, TimelineShortcutHint, type TimelineTheme, type TimelineTimeRange$1 as TimelineTimeRange, TimelineToolbar, type TimelineToolbarProps, Toggle, type ToggleProps, Tooltip, type UseClipboardOptions, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UseProjectFileWriterOptions, type UseRenderClipContentOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildPickerAgentContextPreview, buildPickerAgentPrompt, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, popupSurface, resolveIframe, resolveSourceFile, useClipboard, useEditHistoryActions, useElementPicker, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, useProjectFileWriter, useRenderClipContent, useRenderQueue, useTimelineContext, useTimelineEditing, useTimelinePlayer };
2763
+ /** The live markup to persist and the session snapshot to restore on failure. */
2764
+ interface InlineTextEditCommit {
2765
+ /** The exact preview node that owned the edit; a reload must not retarget it. */
2766
+ element: HTMLElement;
2767
+ html: string;
2768
+ previousHtml: string;
2769
+ }
2770
+
2771
+ declare const SNAP_THRESHOLD_PX = 6;
2772
+ /** Whether a move of this size has travelled far enough for snapping to apply. */
2773
+ declare function snapEngagedForTravel(dx: number, dy: number): boolean;
2774
+ interface SnapEdge {
2775
+ position: number;
2776
+ source: "grid";
2777
+ id: string;
2778
+ }
2779
+ interface SnapTarget {
2780
+ left: number;
2781
+ top: number;
2782
+ right: number;
2783
+ bottom: number;
2784
+ centerX: number;
2785
+ centerY: number;
2786
+ id: string;
2787
+ }
2788
+ interface SnapGuide {
2789
+ axis: "x" | "y";
2790
+ position: number;
2791
+ /** Extent of the guide line (min of involved elements). */
2792
+ from: number;
2793
+ /** Extent of the guide line (max of involved elements). */
2794
+ to: number;
2795
+ }
2796
+ interface SpacingGuide {
2797
+ axis: "x" | "y";
2798
+ /** Position of the gap (start of gap). */
2799
+ position: number;
2800
+ /** Size of the gap in pixels. */
2801
+ size: number;
2802
+ /** Extent for rendering the indicator. */
2803
+ from: number;
2804
+ /** Extent for rendering the indicator. */
2805
+ to: number;
2806
+ }
2807
+ interface SnapResult {
2808
+ dx: number;
2809
+ dy: number;
2810
+ guides: SnapGuide[];
2811
+ spacingGuides: SpacingGuide[];
2812
+ }
2813
+ interface Rect {
2814
+ left: number;
2815
+ top: number;
2816
+ width: number;
2817
+ height: number;
2818
+ }
2819
+ /**
2820
+ * Convert overlay rects to snap targets with precomputed edges & centers.
2821
+ */
2822
+ declare function extractSnapTargets(entries: Array<{
2823
+ rect: Rect;
2824
+ id: string;
2825
+ }>): SnapTarget[];
2826
+ /**
2827
+ * Create a snap target from the composition/overlay boundary.
2828
+ */
2829
+ declare function buildCompositionSnapTarget(rect: Rect): SnapTarget;
2830
+ /**
2831
+ * Generate grid-line snap edges.
2832
+ * `gridSpacing` is in composition pixels; `scale` converts to overlay pixels.
2833
+ * X edges are vertical grid lines; Y edges are horizontal grid lines.
2834
+ */
2835
+ declare function buildGridSnapEdges(compositionRect: Rect, gridSpacing: number, scale: number): {
2836
+ x: SnapEdge[];
2837
+ y: SnapEdge[];
2838
+ };
2839
+ declare function resolveSnapAdjustment(input: {
2840
+ movingRect: Rect;
2841
+ proposedDx: number;
2842
+ proposedDy: number;
2843
+ targets: SnapTarget[];
2844
+ gridEdges?: {
2845
+ x: SnapEdge[];
2846
+ y: SnapEdge[];
2847
+ };
2848
+ threshold: number;
2849
+ disabled: boolean;
2850
+ /** Set when the gesture has not travelled far enough for snapping yet. */
2851
+ disabledForTravel?: boolean;
2852
+ }): SnapResult;
2853
+ /**
2854
+ * Full-length guide line spanning the composition: a vertical line (axis "x")
2855
+ * runs the composition's height at the snapped x position; a horizontal line
2856
+ * (axis "y") runs the composition's width. `composition` is the composition
2857
+ * rect in overlay space — guide positions are already overlay-space, so the
2858
+ * line must be offset by the composition's left/top (the canvas is usually
2859
+ * letterboxed inside the overlay).
2860
+ */
2861
+ declare function resolveGuideLineRect(guide: SnapGuide, composition: Rect): Rect;
2862
+ declare function resolveEquidistanceGuides(input: {
2863
+ movingRect: Rect;
2864
+ targets: SnapTarget[];
2865
+ threshold: number;
2866
+ }): SpacingGuide[];
2867
+
2868
+ interface SnapContext {
2869
+ targets: SnapTarget[];
2870
+ compositionTarget: SnapTarget | null;
2871
+ gridEdges: {
2872
+ x: SnapEdge[];
2873
+ y: SnapEdge[];
2874
+ } | null;
2875
+ snapEnabled: boolean;
2876
+ }
2877
+ declare function collectSnapContext(input: {
2878
+ overlayEl: HTMLDivElement;
2879
+ iframe: HTMLIFrameElement;
2880
+ excludeElements: Set<HTMLElement>;
2881
+ }): SnapContext;
2882
+
2883
+ interface SnapGuidesState {
2884
+ guides: SnapGuide[];
2885
+ spacingGuides: SpacingGuide[];
2886
+ }
2887
+ interface SnapGuideOverlayProps {
2888
+ snapGuidesRef: RefObject<SnapGuidesState | null>;
2889
+ /** Composition rect in overlay space — guide lines span exactly this rect. */
2890
+ compositionLeft: number;
2891
+ compositionTop: number;
2892
+ compositionWidth: number;
2893
+ compositionHeight: number;
2894
+ }
2895
+ declare const SnapGuideOverlay: react.NamedExoticComponent<SnapGuideOverlayProps>;
2896
+
2897
+ interface ApplyDomSelectionOptions {
2898
+ revealPanel?: boolean;
2899
+ additive?: boolean;
2900
+ preserveGroup?: boolean;
2901
+ announce?: boolean;
2902
+ }
2903
+ interface ResolveDomSelectionOptions {
2904
+ preferClipAncestor?: boolean;
2905
+ skipSourceProbe?: boolean;
2906
+ activeGroupElement?: HTMLElement | null;
2907
+ /** Resolve this node itself instead of applying human group-capture behavior. */
2908
+ exactTarget?: boolean;
2909
+ }
2910
+ interface DomEditTimelineParams {
2911
+ projectId: string | null;
2912
+ activeCompPath: string | null;
2913
+ compIdToSrc: Map<string, string>;
2914
+ captionEditMode: boolean;
2915
+ previewIframeRef: MutableRefObject<HTMLIFrameElement | null>;
2916
+ timelineElements: TimelineElement[];
2917
+ getTimelineSelectionSet: () => ReadonlySet<string>;
2918
+ setSelectedTimelineElementId: (id: string | null, options?: SelectElementOptions) => void;
2919
+ /** Publishes a whole multi-selection to the timeline; the anchor is set separately. */
2920
+ setTimelineSelectionSet: (ids: Set<string>) => void;
2921
+ setRightCollapsed: (collapsed: boolean) => void;
2922
+ setRightPanelTab: (tab: RightPanelTab) => void;
2923
+ }
2924
+
2925
+ interface PreviewMouseDownOptions {
2926
+ preferClipAncestor?: boolean;
2927
+ hoverSelection?: DomEditSelection | null;
2928
+ }
2929
+
2930
+ interface DomEditGroupPathOffsetCommit {
2931
+ selection: DomEditSelection;
2932
+ next: {
2933
+ x: number;
2934
+ y: number;
2935
+ };
2936
+ }
2937
+
2938
+ /**
2939
+ * Why a DOM edit commit did not change the file.
2940
+ *
2941
+ * `runDomEditCommit` resolves on persist failure by design (see its contract
2942
+ * above), so a caller cannot learn whether the write landed by awaiting it — a
2943
+ * failed persist and a successful one are indistinguishable. Capture and apply
2944
+ * bugs still reject. The human path does not need to ask about handled persist
2945
+ * failures, because `onError` already put a toast on screen. A programmatic
2946
+ * caller has no screen, so it has to be told.
2947
+ */
2948
+ type DomEditCommitDeclineReason = "no-project" | "no-selection" | "geometry-property" | "styles-not-editable" | "not-text-editable" | "preview-stale" | "persist-failed";
2949
+ type DomEditCommitOutcome = {
2950
+ ok: true;
2951
+ persistence?: DomEditPersistOutcome;
2952
+ } | {
2953
+ ok: false;
2954
+ reason: DomEditCommitDeclineReason;
2955
+ };
2956
+
2957
+ /**
2958
+ * Which elements a delete acts on.
2959
+ *
2960
+ * Its own module so `useDomEditSession.ts` stays under the studio's 600-line
2961
+ * cap; it reads only its arguments.
2962
+ */
2963
+
2964
+ /** One entry in the studio's edit history, as `useDomEditSession`'s caller
2965
+ * supplies it. */
2966
+ interface RecordEditInput$1 {
2967
+ label: string;
2968
+ coalesceKey?: string;
2969
+ files: Record<string, {
2970
+ before: string;
2971
+ after: string;
2972
+ }>;
2973
+ }
2974
+
2975
+ interface UseDomEditSessionParams extends DomEditTimelineParams {
2976
+ compositionLoading: boolean;
2977
+ showToast: (message: string, tone?: "error" | "info") => void;
2978
+ isRecordingRef?: React.RefObject<boolean>;
2979
+ refreshPreviewDocumentVersion: () => void;
2980
+ queueDomEditSave: <T>(save: () => Promise<T>) => Promise<T>;
2981
+ readProjectFile: (path: string) => Promise<string>;
2982
+ writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
2983
+ updateEditingFileContent: (path: string, content: string) => void;
2984
+ editHistory: {
2985
+ recordEdit: (entry: RecordEditInput$1) => Promise<void>;
2986
+ };
2987
+ fileTree: string[];
2988
+ importedFontAssetsRef: React.MutableRefObject<ImportedFontAsset[]>;
2989
+ projectDir: string | null;
2990
+ projectIdRef: React.MutableRefObject<string | null>;
2991
+ previewIframe: HTMLIFrameElement | null;
2992
+ refreshKey: number;
2993
+ previewDocumentVersion: number;
2994
+ rightPanelTab: RightPanelTab;
2995
+ applyStudioManualEditsToPreviewRef: React.MutableRefObject<(iframe: HTMLIFrameElement) => Promise<void>>;
2996
+ syncPreviewHotkeys: (iframe: HTMLIFrameElement | null) => void;
2997
+ reloadPreview: () => void;
2998
+ setRefreshKey: React.Dispatch<React.SetStateAction<number>>;
2999
+ openSourceForSelection?: (sourceFile: string, target: PatchTarget) => void;
3000
+ sdkSession?: Composition | null;
3001
+ publishSdkSession?: PublishSdkSession;
3002
+ forceReloadSdkSession?: () => void;
3003
+ /** The timeline context menu's delete op — a canvas selection that IS a
3004
+ * timeline row hands off here instead of the REST remove-elements path. */
3005
+ handleTimelineElementsDelete: (elements: TimelineElement[]) => Promise<void>;
3006
+ readOnlyPreview: boolean;
3007
+ }
3008
+ declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, captionEditMode, compositionLoading, previewIframeRef, timelineElements, getTimelineSelectionSet, setSelectedTimelineElementId, setTimelineSelectionSet, setRightCollapsed, setRightPanelTab, showToast, isRecordingRef, refreshPreviewDocumentVersion, queueDomEditSave, readProjectFile, writeProjectFile, updateEditingFileContent, editHistory, fileTree, importedFontAssetsRef, projectDir, projectIdRef, previewIframe, refreshKey, previewDocumentVersion, rightPanelTab, applyStudioManualEditsToPreviewRef, syncPreviewHotkeys, reloadPreview, setRefreshKey: _setRefreshKey, openSourceForSelection, sdkSession, publishSdkSession, forceReloadSdkSession, handleTimelineElementsDelete, readOnlyPreview, }: UseDomEditSessionParams): {
3009
+ domEditSelection: DomEditSelection | null;
3010
+ domEditGroupSelections: DomEditSelection[];
3011
+ domEditHoverSelection: DomEditSelection | null;
3012
+ activeGroupElement: HTMLElement | null;
3013
+ agentModalOpen: boolean;
3014
+ agentModalAnchorPoint: AgentModalAnchorPoint | null;
3015
+ copiedAgentPrompt: boolean;
3016
+ agentPromptSelectionContext: string | undefined;
3017
+ domEditSelectionRef: react.MutableRefObject<DomEditSelection | null>;
3018
+ handleTimelineElementSelect: (element: TimelineElement | null) => Promise<void>;
3019
+ handlePreviewCanvasMouseDown: (e: React.MouseEvent<HTMLDivElement>, options?: PreviewMouseDownOptions) => Promise<void>;
3020
+ handlePreviewCanvasPointerMove: (e: React.PointerEvent<HTMLDivElement>, options?: {
3021
+ preferClipAncestor?: boolean;
3022
+ }) => Promise<DomEditSelection | null>;
3023
+ handlePreviewCanvasPointerLeave: () => void;
3024
+ applyDomSelection: (selection: DomEditSelection | null, options?: ApplyDomSelectionOptions) => void;
3025
+ clearDomSelection: () => void;
3026
+ refreshDomEditSelectionFromPreview: (selection: DomEditSelection) => Promise<void>;
3027
+ handleDomStyleCommit: (property: string, value: string) => Promise<DomEditCommitOutcome>;
3028
+ handleDomStyleCommitForSelection: (selection: DomEditSelection, property: string, value: string) => Promise<DomEditCommitOutcome>;
3029
+ handleDomAttributeCommit: (attr: string, value: string) => Promise<void>;
3030
+ handleDomAttributeLiveCommit: (attr: string, value: string | null, onSettled?: (ok: boolean) => void, live?: {
3031
+ previewOnly?: boolean;
3032
+ }) => Promise<void>;
3033
+ handleDomAttributeQuietCommit: (attr: string, value: string | null) => Promise<void>;
3034
+ handleDomHtmlAttributeCommit: (attr: string, value: string | null) => Promise<void>;
3035
+ handleDomAttributesCommit: (selection: DomEditSelection, attrs: Record<string, string>) => Promise<void>;
3036
+ handleDomPathOffsetCommit: (selection: DomEditSelection, next: {
3037
+ x: number;
3038
+ y: number;
3039
+ }, modifiers?: {
3040
+ altKey?: boolean;
3041
+ }) => Promise<void>;
3042
+ handleDomGroupPathOffsetCommit: (updates: DomEditGroupPathOffsetCommit[]) => Promise<void>;
3043
+ handleDomZIndexReorderCommit: (entries: Array<{
3044
+ element: HTMLElement;
3045
+ zIndex: number;
3046
+ id?: string;
3047
+ selector?: string;
3048
+ selectorIndex?: number;
3049
+ sourceFile: string;
3050
+ key?: string;
3051
+ }>, gestureCoalesceKey?: string, actionKind?: string) => Promise<void> | Promise<DomEditPatchBatchesResult>;
3052
+ handleDomBoxSizeCommit: (selection: DomEditSelection, next: {
3053
+ width: number;
3054
+ height: number;
3055
+ }, offset?: {
3056
+ x: number;
3057
+ y: number;
3058
+ }, restore?: () => void) => Promise<void>;
3059
+ handleDomRotationCommit: (selection: DomEditSelection, next: {
3060
+ angle: number;
3061
+ }) => Promise<void>;
3062
+ handleDomManualEditsReset: (selection: DomEditSelection) => Promise<void>;
3063
+ handleDomTextCommit: (value: string, fieldKey?: string) => Promise<DomEditCommitOutcome>;
3064
+ handleDomTextCommitForSelection: (selection: DomEditSelection, value: string, fieldKey?: string) => Promise<DomEditCommitOutcome>;
3065
+ handleDomRichTextCommit: ({ element, html, previousHtml }: InlineTextEditCommit) => Promise<void>;
3066
+ handleDomTextFieldStyleCommit: (fieldKey: string, property: string, value: string) => Promise<void>;
3067
+ handleDomAddTextField: (afterFieldKey?: string) => Promise<string | null>;
3068
+ handleDomRemoveTextField: (fieldKey: string) => Promise<void>;
3069
+ getGsapAnimationsForSelection: (selection: DomEditSelection) => _hyperframes_parsers.GsapAnimation[] | Promise<_hyperframes_parsers.GsapAnimation[]>;
3070
+ handleAskAgent: () => void;
3071
+ handleAgentModalSubmit: (userInstruction: string) => Promise<void>;
3072
+ handleBlockedDomMove: (selection: DomEditSelection) => void;
3073
+ handleDomManualDragStart: () => void;
3074
+ handleDomEditElementDelete: (selection: DomEditSelection, options?: {
3075
+ expandGroup?: boolean;
3076
+ }) => Promise<void>;
3077
+ handleGroupSelection: () => void;
3078
+ handleUngroupSelection: () => void;
3079
+ setActiveGroupElement: (el: HTMLElement | null) => void;
3080
+ buildDomSelectionFromTarget: (target: HTMLElement, options?: ResolveDomSelectionOptions) => Promise<DomEditSelection | null>;
3081
+ buildDomSelectionForTimelineElement: (element: TimelineElement) => Promise<DomEditSelection | null>;
3082
+ updateDomEditHoverSelection: (selection: DomEditSelection | null) => void;
3083
+ applyMarqueeSelection: (selections: DomEditSelection[], additive: boolean) => void;
3084
+ resolveImportedFontAsset: (fontFamilyValue: string) => ImportedFontAsset | null;
3085
+ setAgentModalOpen: react.Dispatch<react.SetStateAction<boolean>>;
3086
+ setAgentPromptSelectionContext: react.Dispatch<react.SetStateAction<string | undefined>>;
3087
+ setAgentModalAnchorPoint: react.Dispatch<react.SetStateAction<AgentModalAnchorPoint | null>>;
3088
+ selectedGsapAnimations: _hyperframes_parsers.GsapAnimation[];
3089
+ gsapMultipleTimelines: boolean;
3090
+ gsapUnsupportedTimelinePattern: boolean;
3091
+ handleGsapUpdateProperty: (animId: string, prop: string, value: number | string) => void;
3092
+ handleGsapUpdateMeta: (animId: string, updates: {
3093
+ duration?: number;
3094
+ ease?: string;
3095
+ position?: number;
3096
+ }, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
3097
+ handleGsapDeleteAnimation: (animId: string, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
3098
+ handleGsapDeleteAllForElement: (targetSelector: string) => void;
3099
+ handleGsapAddAnimation: (method: "to" | "from" | "set" | "fromTo", selectionOverride?: DomEditSelection | null) => Promise<boolean>;
3100
+ handleGsapAddProperty: (animId: string, prop: string) => void;
3101
+ handleGsapRemoveProperty: (animId: string, prop: string) => void;
3102
+ handleGsapUpdateFromProperty: (animId: string, prop: string, value: number | string) => void;
3103
+ handleGsapAddFromProperty: (animId: string, prop: string) => void;
3104
+ handleGsapRemoveFromProperty: (animId: string, prop: string) => void;
3105
+ handleGsapAddKeyframe: (animId: string, percentage: number, property: string, value: number | string, selectionOverride?: DomEditSelection | null) => void;
3106
+ handleGsapAddKeyframeBatch: (animId: string, percentage: number, properties: Record<string, number | string>, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => Promise<void>;
3107
+ handleGsapRemoveKeyframe: (animId: string, percentage: number, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => void;
3108
+ handleGsapMoveKeyframeToPlayhead: (animId: string, fromPercentage: number, selectionOverride?: DomEditSelection | null, animationOverride?: _hyperframes_parsers.GsapAnimation) => void;
3109
+ handleGsapMoveKeyframe: (animId: string, fromPercentage: number, toPercentage: number, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
3110
+ handleGsapResizeKeyframedTween: (animId: string, position: number, duration: number, pctRemap: Array<{
3111
+ from: number;
3112
+ to: number;
3113
+ }>, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
3114
+ handleGsapConvertToKeyframes: (animId: string, resolvedFromValues?: Record<string, number | string>, duration?: number, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => Promise<void>;
3115
+ handleGsapRemoveAllKeyframes: (animId: string, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
3116
+ handleResetSelectedElementKeyframes: () => boolean;
3117
+ handleUpdateKeyframeEase: (animationId: string, percentage: number, ease: string) => void;
3118
+ handleUpdateSegmentEase: (targets: AnimationKeyframeTarget[], ease: string) => void;
3119
+ handleSetAllKeyframeEases: (animationId: string, ease: string) => void;
3120
+ commitAnimatedProperty: (selection: DomEditSelection, property: string, value: number | string) => Promise<void>;
3121
+ commitAnimatedProperties: (selection: DomEditSelection, properties: Record<string, number | string>) => Promise<void>;
3122
+ handleSetArcPath: (animId: string, config: Parameters<(sel: DomEditSelection, animId: string, config: {
3123
+ enabled: boolean;
3124
+ autoRotate?: boolean | number;
3125
+ segments?: Array<{
3126
+ curviness: number;
3127
+ cp1?: {
3128
+ x: number;
3129
+ y: number;
3130
+ };
3131
+ cp2?: {
3132
+ x: number;
3133
+ y: number;
3134
+ };
3135
+ }>;
3136
+ }) => void>[2]) => void;
3137
+ handleUpdateArcSegment: (animId: string, segmentIndex: number, update: Parameters<(sel: DomEditSelection, animId: string, segmentIndex: number, update: {
3138
+ curviness?: number;
3139
+ cp1?: {
3140
+ x: number;
3141
+ y: number;
3142
+ };
3143
+ cp2?: {
3144
+ x: number;
3145
+ y: number;
3146
+ };
3147
+ }) => void>[3]) => void;
3148
+ handleUnroll: () => void;
3149
+ invalidateGsapCache: () => void;
3150
+ previewIframeRef: react.MutableRefObject<HTMLIFrameElement | null>;
3151
+ commitMutation: (mutation: Record<string, unknown>, options: {
3152
+ label: string;
3153
+ softReload?: boolean;
3154
+ }) => Promise<void>;
3155
+ };
3156
+
3157
+ interface DomEditSaveQueue {
3158
+ enqueue: <T>(save: () => Promise<T>) => Promise<T>;
3159
+ waitForIdle: () => Promise<DomEditSaveDrainResult>;
3160
+ reset: () => void;
3161
+ destroy: () => void;
3162
+ }
3163
+ type DomEditSaveDrainResult = StudioSaveDrainResult;
3164
+
3165
+ /** One file's restore from the edit-history store: before (live) / after (target) bytes. */
3166
+ interface UndoRestoreFile {
3167
+ previous: string;
3168
+ restored: string;
3169
+ }
3170
+
3171
+ /** The restore payload the undo/redo preview-sync consumes (from the history store). */
3172
+ interface HistoryPreviewRestore {
3173
+ paths?: string[];
3174
+ files?: Record<string, UndoRestoreFile>;
3175
+ }
3176
+ interface RecordEditInput {
3177
+ label: string;
3178
+ coalesceKey?: string;
3179
+ files: Record<string, {
3180
+ before: string;
3181
+ after: string;
3182
+ }>;
3183
+ }
3184
+ interface UsePreviewPersistenceParams {
3185
+ showToast: (message: string, tone?: "error" | "info") => void;
3186
+ readOptionalProjectFile: (path: string) => Promise<string>;
3187
+ writeProjectFile: (path: string, content: string) => Promise<void>;
3188
+ recordEdit: (entry: RecordEditInput) => Promise<void>;
3189
+ previewIframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
3190
+ activeCompPathRef: React.MutableRefObject<string | null>;
3191
+ /** Called to reload the preview after undo/redo or external file changes. */
3192
+ reloadPreview: () => void;
3193
+ }
3194
+ declare function usePreviewPersistence({ showToast, readOptionalProjectFile: _readOptionalProjectFile, writeProjectFile: _writeProjectFile, recordEdit: _recordEdit, previewIframeRef, activeCompPathRef, reloadPreview, }: UsePreviewPersistenceParams): {
3195
+ domTextCommitVersionRef: react.RefObject<number>;
3196
+ domEditSaveQueueRef: react.RefObject<DomEditSaveQueue | null>;
3197
+ applyStudioManualEditsToPreviewRef: react.RefObject<(iframe?: HTMLIFrameElement | null) => Promise<void>>;
3198
+ queueDomEditSave: <T>(save: () => Promise<T>) => Promise<T>;
3199
+ drainPendingDomEditSaves: () => Promise<{
3200
+ status: "clean";
3201
+ } | {
3202
+ status: "conflict";
3203
+ error: StudioFileConflictError;
3204
+ } | {
3205
+ status: "failed";
3206
+ error: unknown;
3207
+ }>;
3208
+ waitForPendingDomEditSaves: () => Promise<void>;
3209
+ domEditSaveQueuePaused: string | null;
3210
+ resetDomEditSaveQueueBreaker: () => void;
3211
+ applyCurrentStudioManualEditsToPreview: (iframe?: HTMLIFrameElement | null) => void;
3212
+ applyStudioManualEditsToPreview: (iframe?: HTMLIFrameElement | null) => Promise<void>;
3213
+ syncHistoryPreviewAfterApply: (restore: HistoryPreviewRestore) => Promise<void>;
3214
+ };
3215
+
3216
+ type DomEditValue = ReturnType<typeof useDomEditSession>;
3217
+ interface DomEditSelectionValue extends Pick<DomEditValue, "domEditSelection" | "domEditGroupSelections" | "domEditHoverSelection" | "activeGroupElement" | "domEditSelectionRef" | "selectedGsapAnimations" | "gsapMultipleTimelines" | "gsapUnsupportedTimelinePattern" | "agentModalOpen" | "agentModalAnchorPoint" | "copiedAgentPrompt" | "agentPromptSelectionContext"> {
3218
+ }
3219
+ declare function useDomEditSelectionContext(): DomEditSelectionValue;
3220
+ declare function DomEditProvider({ value: { domEditSelection, domEditGroupSelections, domEditHoverSelection, agentModalOpen, agentModalAnchorPoint, copiedAgentPrompt, agentPromptSelectionContext, domEditSelectionRef, handleTimelineElementSelect, handlePreviewCanvasMouseDown, handlePreviewCanvasPointerMove, handlePreviewCanvasPointerLeave, applyDomSelection, clearDomSelection, refreshDomEditSelectionFromPreview, handleDomStyleCommit, handleDomStyleCommitForSelection, handleDomAttributeCommit, handleDomAttributeLiveCommit, handleDomAttributeQuietCommit, handleDomHtmlAttributeCommit, handleDomAttributesCommit, handleDomPathOffsetCommit, handleDomGroupPathOffsetCommit, handleDomZIndexReorderCommit, handleDomBoxSizeCommit, handleDomRotationCommit, handleDomManualEditsReset, handleDomTextCommit, handleDomTextCommitForSelection, handleDomRichTextCommit, handleDomTextFieldStyleCommit, handleDomAddTextField, handleDomRemoveTextField, getGsapAnimationsForSelection, handleAskAgent, handleAgentModalSubmit, handleBlockedDomMove, handleDomManualDragStart, handleDomEditElementDelete, handleGroupSelection, handleUngroupSelection, setActiveGroupElement, activeGroupElement, buildDomSelectionFromTarget, buildDomSelectionForTimelineElement, updateDomEditHoverSelection, resolveImportedFontAsset, setAgentModalOpen, setAgentPromptSelectionContext, setAgentModalAnchorPoint, selectedGsapAnimations, gsapMultipleTimelines, gsapUnsupportedTimelinePattern, handleGsapUpdateProperty, handleGsapUpdateMeta, handleGsapDeleteAnimation, handleGsapDeleteAllForElement, handleGsapAddAnimation, handleGsapAddProperty, handleGsapRemoveProperty, handleGsapUpdateFromProperty, handleGsapAddFromProperty, handleGsapRemoveFromProperty, handleGsapAddKeyframe, handleGsapAddKeyframeBatch, handleGsapRemoveKeyframe, handleGsapMoveKeyframeToPlayhead, handleGsapMoveKeyframe, handleGsapResizeKeyframedTween, handleGsapConvertToKeyframes, handleGsapRemoveAllKeyframes, handleResetSelectedElementKeyframes, commitAnimatedProperty, commitAnimatedProperties, handleSetArcPath, handleUpdateArcSegment, handleUnroll, invalidateGsapCache, previewIframeRef, commitMutation, applyMarqueeSelection, handleUpdateKeyframeEase, handleUpdateSegmentEase, handleSetAllKeyframeEases, }, children, }: {
3221
+ value: DomEditValue;
3222
+ children: ReactNode;
3223
+ }): react_jsx_runtime.JSX.Element;
3224
+
3225
+ declare function PreviewReadOnlyProvider({ readOnly, reason, children, }: {
3226
+ readOnly: boolean;
3227
+ reason?: string;
3228
+ children: ReactNode;
3229
+ }): react_jsx_runtime.JSX.Element;
3230
+
3231
+ /**
3232
+ * Pure z-order helpers for the canvas right-click context menu.
3233
+ *
3234
+ * Layering strategy: z-index + CSS stacking context (position ≠ static).
3235
+ * All sibling z-index values are read from the live iframe DOM via
3236
+ * element.style.zIndex (inline style, set by the editor) falling back to
3237
+ * the computed value. Treat missing / "auto" as 0 for comparison purposes.
3238
+ *
3239
+ * "Overlapping siblings" = siblings whose bounding rects intersect the
3240
+ * target's bounding rect AND are actually visible at the current frame.
3241
+ * Forward/backward operate within that set; front/back operate across all
3242
+ * siblings (full painting family, visible or not — unchanged semantics).
3243
+ *
3244
+ * ── Visibility ───────────────────────────────────────────────────────────────
3245
+ * In HyperFrames compositions the nearest z-neighbor is often INVISIBLE at the
3246
+ * paused frame: the runtime hides time-inactive clips with inline
3247
+ * `visibility:hidden` / `display:none` (see core runtime
3248
+ * syncTimedElementVisibility), and GSAP timelines park elements at `opacity:0`.
3249
+ * Stepping "forward" over such a sibling looks like a silent no-op. The
3250
+ * forward/backward comparison set therefore keeps only siblings whose
3251
+ * element-level computed style is visible (display ≠ none, visibility ≠
3252
+ * hidden, opacity > 0.01) — all runtime hiding signals are inline styles, so
3253
+ * computed style covers them. Ancestor-chain checks are unnecessary here:
3254
+ * siblings share the target's ancestors. The probe is injectable
3255
+ * (ZOrderResolveOptions.isVisible) so the pure-module tests stay meaningful
3256
+ * without a real style engine, mirroring how tests stub rect reading.
3257
+ *
3258
+ * ── Tie-awareness ────────────────────────────────────────────────────────────
3259
+ * CSS paint order for elements that share a z-index is DOM document order:
3260
+ * the element that comes LATER in the DOM paints ON TOP. The old resolver
3261
+ * compared z-index alone, so a target tied with the element visually below it
3262
+ * (equal z, target later in DOM) had an empty "below" set and silently
3263
+ * no-op'd. This module computes true render order — sort by
3264
+ * (zIndex asc, DOM position asc), bottom→top — moves the target one step (or
3265
+ * to an end) in that order, then realizes the new order back into z values.
3266
+ *
3267
+ * The result is a MULTI-element patch: a single-element patch when a
3268
+ * strictly-between z value can express the new order given DOM-order
3269
+ * tie-breaking, otherwise a minimal renumber of the affected set (emitting
3270
+ * patches only for elements whose z actually changes). z is never negative
3271
+ * (project convention clamps z ≥ 0).
3272
+ */
3273
+ type ZOrderAction = "bring-forward" | "send-backward" | "bring-to-front" | "send-to-back";
3274
+ /** A resolved change: set `element`'s z-index to `zIndex`. */
3275
+ interface ZOrderPatch {
3276
+ element: HTMLElement;
3277
+ zIndex: number;
3278
+ }
3279
+
3280
+ interface DomEditOverlayProps {
3281
+ iframeRef: RefObject<HTMLIFrameElement | null>;
3282
+ activeCompositionPath: string | null;
3283
+ selection: DomEditSelection | null;
3284
+ groupSelections?: DomEditSelection[];
3285
+ hoverSelection: DomEditSelection | null;
3286
+ allowCanvasMovement?: boolean;
3287
+ /** "host": no hover, marquee or box re-select; Enter with nothing focused still opens text. */
3288
+ canvasInput?: "overlay" | "host";
3289
+ onTextEditingChange?: (editing: boolean) => void;
3290
+ /** A click on a single selection's box, in either mode; the event may be the pointerup. */
3291
+ onSelectionBoxClick?: (event: React.MouseEvent<HTMLDivElement>, selection: DomEditSelection) => void;
3292
+ onCanvasMouseDown: (event: React.MouseEvent<HTMLDivElement>, options?: PreviewMouseDownOptions) => void;
3293
+ onCanvasPointerMove: (event: React.PointerEvent<HTMLDivElement>, options?: {
3294
+ preferClipAncestor?: boolean;
3295
+ }) => Promise<DomEditSelection | null>;
3296
+ onCanvasPointerLeave: () => void;
3297
+ onSelectionChange: (selection: DomEditSelection, options?: {
3298
+ revealPanel?: boolean;
3299
+ additive?: boolean;
3300
+ }) => void;
3301
+ onBlockedMove: (selection: DomEditSelection) => void;
3302
+ onManualDragStart?: () => void;
3303
+ onPathOffsetCommit: (selection: DomEditSelection, next: {
3304
+ x: number;
3305
+ y: number;
3306
+ }, modifiers?: {
3307
+ altKey?: boolean;
3308
+ }) => Promise<void> | void;
3309
+ onGroupPathOffsetCommit: (updates: DomEditGroupPathOffsetCommit[]) => Promise<void> | void;
3310
+ onBoxSizeCommit: (selection: DomEditSelection, next: {
3311
+ width: number;
3312
+ height: number;
3313
+ }, offset?: {
3314
+ x: number;
3315
+ y: number;
3316
+ }, restore?: () => void) => Promise<void> | void;
3317
+ onRotationCommit: (selection: DomEditSelection, next: {
3318
+ angle: number;
3319
+ }) => Promise<void> | void;
3320
+ onStyleCommit?: (property: string, value: string) => Promise<unknown> | void;
3321
+ recordingState?: GestureRecordingState;
3322
+ onToggleRecording?: () => void;
3323
+ onMarqueeSelect?: (selections: DomEditSelection[], additive: boolean) => void;
3324
+ /**
3325
+ * Delete the selected canvas element.
3326
+ * Wire to handleDomEditElementDelete from useDomEditActionsContext —
3327
+ * same handler the Delete/Backspace hotkey uses.
3328
+ */
3329
+ onDeleteSelection?: (selection: DomEditSelection) => void;
3330
+ /**
3331
+ * Called with the resolved z-order patch list and the menu action that
3332
+ * produced it (feeds the undo coalesce key). The patch list is tie-aware and
3333
+ * may include sibling elements (see canvasContextMenuZOrder); the live DOM is
3334
+ * NOT yet mutated. Wire to handleDomZIndexReorderCommit from
3335
+ * useDomEditActionsContext. See CanvasContextMenu.tsx module comment.
3336
+ */
3337
+ onApplyZIndex?: (selection: DomEditSelection, patches: ZOrderPatch[], action: ZOrderAction,
3338
+ /** Sibling a forward/backward step moved past (pre-mutation render order);
3339
+ * null for front/back. Feeds the timeline z-mirror's crossedKey. */
3340
+ crossed: HTMLElement | null) => void;
3341
+ }
3342
+ declare const DomEditOverlay: react.NamedExoticComponent<DomEditOverlayProps>;
3343
+
3344
+ type HostInputProps = Pick<ComponentProps<typeof DomEditOverlay>, "canvasInput" | "onSelectionBoxClick">;
3345
+ interface ConnectedDomEditOverlayProps extends HostInputProps {
3346
+ activeCompositionPath: string | null;
3347
+ showHoverSelection: boolean;
3348
+ shouldShowSelectedDomBounds: boolean;
3349
+ isGestureRecording?: boolean;
3350
+ /** True when an in-place text edit opens its caret, false when it ends or unmounts. */
3351
+ onTextEditingChange?: (editing: boolean) => void;
3352
+ }
3353
+ declare function ConnectedDomEditOverlay({ activeCompositionPath, showHoverSelection, shouldShowSelectedDomBounds, isGestureRecording, canvasInput, onTextEditingChange, onSelectionBoxClick, }: ConnectedDomEditOverlayProps): react_jsx_runtime.JSX.Element;
3354
+
3355
+ interface MarqueeGesturesDeps<T = DomEditSelection> {
3356
+ iframeRef: React.RefObject<HTMLIFrameElement | null>;
3357
+ overlayRef: React.RefObject<HTMLDivElement | null>;
3358
+ activeCompositionPathRef: React.RefObject<string | null>;
3359
+ onMarqueeSelectRef: React.RefObject<((selections: T[], additive: boolean) => void) | undefined>;
3360
+ /** Turns the elements a drag touched into picks; without it, Studio's edit selections. */
3361
+ resolveHits?: (elements: HTMLElement[]) => T[] | Promise<T[]>;
3362
+ selectionRef?: React.RefObject<DomEditSelection | null>;
3363
+ /** Studio's pointer handling, for the events that are not part of a marquee. */
3364
+ gestures?: {
3365
+ onPointerMove: (event: React.PointerEvent<HTMLDivElement>) => void;
3366
+ onPointerUp: (event: React.PointerEvent<HTMLDivElement>) => void;
3367
+ clearPointerState: (ref: React.RefObject<DomEditSelection | null>) => void;
3368
+ };
3369
+ }
3370
+ interface MarqueeGestures {
3371
+ marqueeRect: Rect$1 | null;
3372
+ candidateRects: Rect$1[];
3373
+ /** Starts a marquee at this press; the host has decided it landed on empty canvas. */
3374
+ begin: (event: React.PointerEvent<HTMLElement>) => void;
3375
+ /** Drops an active marquee without selecting anything. */
3376
+ cancel: () => void;
3377
+ onPointerMove: (event: React.PointerEvent<HTMLDivElement>) => void;
3378
+ onPointerUp: (event: React.PointerEvent<HTMLDivElement>) => void;
3379
+ onPointerCancel: () => void;
3380
+ }
3381
+ declare function useMarqueeGestures(deps: MarqueeGesturesDeps): MarqueeGestures;
3382
+ declare function useMarqueeGestures<T>(deps: MarqueeGesturesDeps<T> & Required<Pick<MarqueeGesturesDeps<T>, "resolveHits">>): MarqueeGestures;
3383
+
3384
+ interface MarqueeOverlayProps {
3385
+ /** Elements the marquee currently intersects — outlined live before mouse-up. */
3386
+ candidateRects: Rect$1[];
3387
+ /** The marquee drag rectangle itself, or null when not marquee-selecting. */
3388
+ marqueeRect: Rect$1 | null;
3389
+ }
3390
+ /**
3391
+ * The marquee selection visuals: a live "candidate" outline on each element the
3392
+ * box currently touches, plus the dashed drag rectangle. Extracted from
3393
+ * DomEditOverlay to keep that file under the 600-line cap.
3394
+ */
3395
+ declare function MarqueeOverlay({ candidateRects, marqueeRect }: MarqueeOverlayProps): react_jsx_runtime.JSX.Element;
3396
+
3397
+ export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, AudioMeterStrip, type AudioMeterStripProps, AudioWaveform, type AudioWaveformProps, type BlockedTimelineEditIntent, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ConnectedDomEditOverlay, type ConnectedDomEditOverlayProps, DEFAULT_SHORTCUT_SECTIONS, type DomEditCapabilities, DomEditProvider, type DomEditSelection, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, ImageThumbnail, type ImageThumbnailProps, type MarqueeGestures, type MarqueeGesturesDeps, MarqueeOverlay, type MarqueeOverlayProps, type Rect$1 as MarqueeRect, NLEPreview, type PatchOperation, type PersistedRenderSettings, type PickedElement, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, PreviewReadOnlyProvider, type PreviewSnapPreferences, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, SNAP_THRESHOLD_PX, type ShortcutHint, type ShortcutSection, type SnapContext, type SnapEdge, type SnapGuide, SnapGuideOverlay, type SnapGuideOverlayProps, type SnapGuidesState, type Rect as SnapRect, type SnapResult, type SnapTarget, SnapToolbar, SourceEditor, type SpacingGuide, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, type ThumbnailPriority, Timeline, TimelineClipMenu, type TimelineClipRenderContext, type TimelineEditCallbacks, type TimelineEditOutcome, type TimelineEditPermission, TimelineEditPopover, TimelineEditProvider, type TimelineElement, TimelineEmptyStatePart, TimelineFrame, TimelineGapMenu, TimelineHistoryButtons, type TimelineHistoryButtonsProps, TimelineKeyframeMenu, TimelineLanes, TimelineOverlays, TimelinePane, type TimelinePaneProps, TimelinePlayhead, TimelineProvider, TimelineRazorGuide, TimelineRuler, TimelineShortcutHint, type TimelineTheme, type TimelineTimeRange$1 as TimelineTimeRange, TimelineToolbar, type TimelineToolbarProps, type TimelineZIndexReorderCommit, type UseClipboardOptions, type UseDomEditSessionParams, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UsePreviewPersistenceParams, type UseProjectFileWriterOptions, type UseRenderClipContentOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildCompositionSnapTarget, buildGridSnapEdges, buildPickerAgentContextPreview, buildPickerAgentPrompt, collectSnapContext, extractSnapTargets, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, resolveEquidistanceGuides, resolveGuideLineRect, resolveIframe, resolveSnapAdjustment, resolveSourceFile, snapEngagedForTravel, useClipboard, useDomEditSelectionContext, useDomEditSession, useEditHistoryActions, useElementPicker, useMarqueeGestures, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, usePreviewPersistence, useProjectFileWriter, useRenderClipContent, useRenderQueue, useTimelineContext, useTimelineEditing, useTimelinePlayer };