hyperframes 0.8.64 → 0.8.65

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.
@@ -3656,15 +3656,28 @@ function effectiveThumbnailMode(preferredMode, policy = studioThumbnailRuntimePo
3656
3656
  }
3657
3657
 
3658
3658
  // src/player/store/thumbnailSlice.ts
3659
+ var EVERY_COMPOSITION = "*";
3660
+ function revisionKey(path) {
3661
+ return (path.split(/[?#]/)[0] ?? "").replace(/\\/g, "/").replace(/^\.?\//, "");
3662
+ }
3663
+ function thumbnailRevisionOf(revisions, compositionPath) {
3664
+ return (revisions[EVERY_COMPOSITION] ?? 0) + (revisions[revisionKey(compositionPath)] ?? 0);
3665
+ }
3659
3666
  function createThumbnailSlice(set) {
3660
3667
  return {
3661
3668
  thumbnailMode: defaultThumbnailMode(readStudioUiPreferences().thumbnailMode),
3662
- thumbnailContentRevision: 0,
3669
+ thumbnailRevisions: {},
3663
3670
  setThumbnailMode: (mode) => {
3664
3671
  writeStudioUiPreferences({ thumbnailMode: mode });
3665
3672
  set({ thumbnailMode: mode });
3666
3673
  },
3667
- bumpThumbnailContentRevision: () => set((state) => ({ thumbnailContentRevision: state.thumbnailContentRevision + 1 }))
3674
+ bumpThumbnailRevisions: (compositions) => set(({ thumbnailRevisions }) => {
3675
+ const next = { ...thumbnailRevisions };
3676
+ for (const path of compositions?.map(revisionKey) ?? [EVERY_COMPOSITION]) {
3677
+ next[path] = (next[path] ?? 0) + 1;
3678
+ }
3679
+ return { thumbnailRevisions: next };
3680
+ })
3668
3681
  };
3669
3682
  }
3670
3683
 
@@ -4765,7 +4778,7 @@ import {
4765
4778
  } from "react";
4766
4779
 
4767
4780
  // src/player/components/useTimelineProviderState.tsx
4768
- import { useRef as useRef31, useMemo as useMemo22, useCallback as useCallback21, useState as useState20 } from "react";
4781
+ import { useRef as useRef31, useMemo as useMemo22, useCallback as useCallback21, useState as useState21 } from "react";
4769
4782
 
4770
4783
  // src/hooks/useMusicBeatAnalysis.ts
4771
4784
  import { useEffect as useEffect10, useMemo as useMemo4, useRef as useRef10 } from "react";
@@ -6647,6 +6660,20 @@ function deriveTimelineTransitionSeams(elements) {
6647
6660
  }
6648
6661
  return seams;
6649
6662
  }
6663
+ function deriveTimelineTransitionSeamsByTrack(elements) {
6664
+ const tracks = /* @__PURE__ */ new Map();
6665
+ for (const element of elements) {
6666
+ const track2 = tracks.get(element.track);
6667
+ if (track2) track2.push(element);
6668
+ else tracks.set(element.track, [element]);
6669
+ }
6670
+ const byTrack = /* @__PURE__ */ new Map();
6671
+ for (const [track2, trackElements] of tracks) {
6672
+ const seams = deriveTimelineTransitionSeams(trackElements);
6673
+ if (seams.length > 0) byTrack.set(track2, seams);
6674
+ }
6675
+ return byTrack;
6676
+ }
6650
6677
 
6651
6678
  // src/player/components/timelineZones.ts
6652
6679
  function classifyZone(el) {
@@ -8673,9 +8700,6 @@ function resolveResizingElementIds(resizingClip) {
8673
8700
  if (resizingClip) return [resizingClip.element.key ?? resizingClip.element.id];
8674
8701
  return void 0;
8675
8702
  }
8676
- function resolveRenderClipContent(rowVirtualizationActive, isScrolling, renderClipContent) {
8677
- return rowVirtualizationActive && isScrolling ? void 0 : renderClipContent;
8678
- }
8679
8703
  function shouldIgnoreTimelinePointerDown(target) {
8680
8704
  return target instanceof Element && target.closest("button, input, select, a") !== null;
8681
8705
  }
@@ -13987,12 +14011,48 @@ function useTimelineScrollViewport(scrollRef, resyncShortcutHintOn) {
13987
14011
  return { viewport, showShortcutHint, setScrollRef, syncScrollViewport };
13988
14012
  }
13989
14013
 
14014
+ // src/player/components/timelineClipChildren.tsx
14015
+ import { useState as useState17 } from "react";
14016
+ import { Fragment as Fragment7, jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
14017
+ function resolveClipRenderContext(element, visibleTimeRange, interactive) {
14018
+ if (interactive) return { priority: "interaction", rich: false };
14019
+ const visible = element.start < visibleTimeRange.end && element.start + element.duration > visibleTimeRange.start;
14020
+ return { priority: visible ? "visible" : "overscan", rich: false };
14021
+ }
14022
+ function ClipLintDot({ element }) {
14023
+ const lint = usePlayerStore((s) => s.lintFindingsByElement.get(element.key ?? element.id));
14024
+ if (!lint || lint.count === 0) return null;
14025
+ return /* @__PURE__ */ jsx38(
14026
+ "span",
14027
+ {
14028
+ className: "absolute w-1.5 h-1.5 rounded-full bg-amber-400",
14029
+ style: { top: 7, right: 7 },
14030
+ title: lint.messages.join("\n")
14031
+ }
14032
+ );
14033
+ }
14034
+ function ClipContentOnceShown({ hold, children }) {
14035
+ const [shown2, setShown] = useState17(!hold);
14036
+ if (!shown2 && !hold) setShown(true);
14037
+ return shown2 ? children : null;
14038
+ }
14039
+ function renderClipChildren(element, clipStyle, renderClipContent, renderClipOverlay, context = { priority: "visible", rich: false }) {
14040
+ return /* @__PURE__ */ jsxs26(Fragment7, { children: [
14041
+ renderClipOverlay?.(element),
14042
+ !renderClipContent && /* @__PURE__ */ jsx38(ClipLintDot, { element }),
14043
+ renderClipContent && // borderRadius: inherit — the clip itself is overflow-visible (keyframe
14044
+ // diamonds hang outside its bounds), so the thumbnail layer must clip
14045
+ // itself to the clip's rounded corners or sharp corners poke out.
14046
+ /* @__PURE__ */ jsx38("div", { className: "absolute inset-0 overflow-hidden", style: { borderRadius: "inherit" }, children: renderClipContent(element, clipStyle, context) })
14047
+ ] });
14048
+ }
14049
+
13990
14050
  // src/player/components/useResolvedTimelineEditCallbacks.ts
13991
14051
  import { useMemo as useMemo12 } from "react";
13992
14052
 
13993
14053
  // src/contexts/TimelineEditContext.tsx
13994
14054
  import { useContext as useContext6, useMemo as useMemo11 } from "react";
13995
- import { jsx as jsx38 } from "react/jsx-runtime";
14055
+ import { jsx as jsx39 } from "react/jsx-runtime";
13996
14056
  var TimelineEditContext = createStableContext(
13997
14057
  "TimelineEditContext",
13998
14058
  null
@@ -14039,7 +14099,7 @@ function TimelineEditProvider({
14039
14099
  value.onTogglePropertyGroupKeyframe
14040
14100
  ]
14041
14101
  );
14042
- return /* @__PURE__ */ jsx38(TimelineEditContext.Provider, { value: memoized, children });
14102
+ return /* @__PURE__ */ jsx39(TimelineEditContext.Provider, { value: memoized, children });
14043
14103
  }
14044
14104
 
14045
14105
  // src/player/components/useResolvedTimelineEditCallbacks.ts
@@ -14573,8 +14633,8 @@ function useTimelineGapHighlights(input) {
14573
14633
  }
14574
14634
 
14575
14635
  // src/player/components/TimelineRazorInteraction.tsx
14576
- import { useCallback as useCallback16, useState as useState17 } from "react";
14577
- import { jsx as jsx39 } from "react/jsx-runtime";
14636
+ import { useCallback as useCallback16, useState as useState18 } from "react";
14637
+ import { jsx as jsx40 } from "react/jsx-runtime";
14578
14638
  function useTimelineRazorInteraction({
14579
14639
  active,
14580
14640
  scrollRef,
@@ -14582,7 +14642,7 @@ function useTimelineRazorInteraction({
14582
14642
  pixelsPerSecond,
14583
14643
  onSplitAll
14584
14644
  }) {
14585
- const [razorGuideX, setRazorGuideX] = useState17(null);
14645
+ const [razorGuideX, setRazorGuideX] = useState18(null);
14586
14646
  const updateRazorGuide = useCallback16(
14587
14647
  (event) => {
14588
14648
  const scroll = scrollRef.current;
@@ -14612,7 +14672,7 @@ function useTimelineRazorInteraction({
14612
14672
  return { razorGuideX, updateRazorGuide, clearRazorGuide, splitAllAtPointer };
14613
14673
  }
14614
14674
  function TimelineRazorGuideOverlay({ x }) {
14615
- return /* @__PURE__ */ jsx39(
14675
+ return /* @__PURE__ */ jsx40(
14616
14676
  "div",
14617
14677
  {
14618
14678
  className: "absolute top-0 bottom-0 pointer-events-none z-10",
@@ -14749,9 +14809,9 @@ function getTimelinePreviewElement(element, resizingClip) {
14749
14809
  }
14750
14810
 
14751
14811
  // src/player/components/useTimelineShiftModifier.ts
14752
- import { useState as useState18 } from "react";
14812
+ import { useState as useState19 } from "react";
14753
14813
  function useTimelineShiftModifier() {
14754
- const [shiftHeld, setShiftHeld] = useState18(false);
14814
+ const [shiftHeld, setShiftHeld] = useState19(false);
14755
14815
  useMountEffect(() => {
14756
14816
  const handleKey = (event) => event.key === "Shift" && setShiftHeld(event.type === "keydown");
14757
14817
  const handleBlur = () => setShiftHeld(false);
@@ -15658,7 +15718,7 @@ import {
15658
15718
  useLayoutEffect as useLayoutEffect4,
15659
15719
  useMemo as useMemo21,
15660
15720
  useRef as useRef30,
15661
- useState as useState19
15721
+ useState as useState20
15662
15722
  } from "react";
15663
15723
 
15664
15724
  // src/player/components/timelineFocusIdentity.ts
@@ -15791,7 +15851,7 @@ function useTimelineRowVirtualization({
15791
15851
  syncScrollViewport
15792
15852
  }) {
15793
15853
  const enabled = STUDIO_TIMELINE_ROW_VIRTUALIZATION_ENABLED;
15794
- const [domFocusedRowKey, setDomFocusedRowKey] = useState19();
15854
+ const [domFocusedRowKey, setDomFocusedRowKey] = useState20();
15795
15855
  const onTimelineFocus = useCallback20((event) => {
15796
15856
  setDomFocusedRowKey(getFocusedTimelineRowKey(event.target));
15797
15857
  }, []);
@@ -15924,7 +15984,7 @@ function useTimelineLogicalFocus(input) {
15924
15984
  }
15925
15985
 
15926
15986
  // src/player/components/useTimelineProviderState.tsx
15927
- import { jsx as jsx40 } from "react/jsx-runtime";
15987
+ import { jsx as jsx41 } from "react/jsx-runtime";
15928
15988
  function useTimelineProviderState({
15929
15989
  onSeek,
15930
15990
  onDrillDown,
@@ -15998,12 +16058,12 @@ function useTimelineProviderState({
15998
16058
  const containerRef = useRef31(null);
15999
16059
  const scrollRef = useRef31(null);
16000
16060
  const activeTool = usePlayerStore((s) => s.activeTool);
16001
- const [hoveredClip, setHoveredClip] = useState20(null);
16061
+ const [hoveredClip, setHoveredClip] = useState21(null);
16002
16062
  const isDragging = useRef31(false);
16003
16063
  const shiftHeld = useTimelineShiftModifier();
16004
- const [showPopover, setShowPopover] = useState20(false);
16005
- const [kfContextMenu, setKfContextMenu] = useState20(null);
16006
- const [clipContextMenu, setClipContextMenu] = useState20(null);
16064
+ const [showPopover, setShowPopover] = useState21(false);
16065
+ const [kfContextMenu, setKfContextMenu] = useState21(null);
16066
+ const [clipContextMenu, setClipContextMenu] = useState21(null);
16007
16067
  const setContainerRef = useCallback21((el) => {
16008
16068
  containerRef.current = el;
16009
16069
  }, []);
@@ -16377,10 +16437,10 @@ function useTimelineProviderState({
16377
16437
  onRazorSplit: editContext.onRazorSplit,
16378
16438
  onRazorSplitAll: editContext.onRazorSplitAll
16379
16439
  };
16380
- const timelineRenderClipContent = resolveRenderClipContent(
16381
- timelineFocus.rowVirtualizationActive,
16382
- viewport.isScrolling,
16383
- renderClipContent
16440
+ const holdNewClipContent = timelineFocus.rowVirtualizationActive && viewport.isScrolling;
16441
+ const timelineRenderClipContent = useMemo22(
16442
+ () => renderClipContent && ((element, style, context) => /* @__PURE__ */ jsx41(ClipContentOnceShown, { hold: holdNewClipContent, children: renderClipContent(element, style, context) })),
16443
+ [holdNewClipContent, renderClipContent]
16384
16444
  );
16385
16445
  const timelineMeta = buildTimelineMeta({
16386
16446
  emptyState: {
@@ -16432,7 +16492,7 @@ function useTimelineProviderState({
16432
16492
  },
16433
16493
  elementCount: timelineElements.length,
16434
16494
  labelColumnWidth: LABEL_COL_W,
16435
- razorGuide: activeTool === "razor" && razorGuideX !== null ? /* @__PURE__ */ jsx40(TimelineRazorGuideOverlay, { x: razorGuideX }) : null
16495
+ razorGuide: activeTool === "razor" && razorGuideX !== null ? /* @__PURE__ */ jsx41(TimelineRazorGuideOverlay, { x: razorGuideX }) : null
16436
16496
  });
16437
16497
  const contextValue = {
16438
16498
  state: {
@@ -16455,18 +16515,18 @@ function useTimelineProviderState({
16455
16515
  }
16456
16516
 
16457
16517
  // src/player/components/TimelineProvider.tsx
16458
- import { jsx as jsx41 } from "react/jsx-runtime";
16518
+ import { jsx as jsx42 } from "react/jsx-runtime";
16459
16519
  var TimelineContext = createContext3(null);
16460
16520
  function TimelineProvider({ children, ...props }) {
16461
16521
  const editContext = useTimelineEditContextValue();
16462
16522
  if (!editContext) {
16463
- return /* @__PURE__ */ jsx41(TimelineEditProvider, { value: props, children: /* @__PURE__ */ jsx41(TimelineProviderState, { ...props, children }) });
16523
+ return /* @__PURE__ */ jsx42(TimelineEditProvider, { value: props, children: /* @__PURE__ */ jsx42(TimelineProviderState, { ...props, children }) });
16464
16524
  }
16465
- return /* @__PURE__ */ jsx41(TimelineProviderState, { ...props, children });
16525
+ return /* @__PURE__ */ jsx42(TimelineProviderState, { ...props, children });
16466
16526
  }
16467
16527
  function TimelineProviderState({ children, ...props }) {
16468
16528
  const value = useTimelineProviderState(props);
16469
- return /* @__PURE__ */ jsx41(TimelineContext.Provider, { value, children });
16529
+ return /* @__PURE__ */ jsx42(TimelineContext.Provider, { value, children });
16470
16530
  }
16471
16531
  function useTimelineContext() {
16472
16532
  const value = useTimelineContextOptional();
@@ -16482,7 +16542,7 @@ import { memo as memo13 } from "react";
16482
16542
 
16483
16543
  // src/player/components/TimelineRuler.tsx
16484
16544
  import { memo as memo9 } from "react";
16485
- import { Fragment as Fragment7, jsx as jsx42, jsxs as jsxs26 } from "react/jsx-runtime";
16545
+ import { Fragment as Fragment8, jsx as jsx43, jsxs as jsxs27 } from "react/jsx-runtime";
16486
16546
  var TimelineRuler = memo9(function TimelineRuler2({
16487
16547
  major,
16488
16548
  minor,
@@ -16502,8 +16562,8 @@ var TimelineRuler = memo9(function TimelineRuler2({
16502
16562
  const beatEntries = getTimelineBeatEntries(beatTimes, beatStrengths, renderTimeRange);
16503
16563
  const avgBeatInterval = beatTimes.length > 1 ? (beatTimes[beatTimes.length - 1] - beatTimes[0]) / (beatTimes.length - 1) : null;
16504
16564
  const showBeats = avgBeatInterval !== null && avgBeatInterval * pps >= 5;
16505
- return /* @__PURE__ */ jsxs26(Fragment7, { children: [
16506
- /* @__PURE__ */ jsx42(
16565
+ return /* @__PURE__ */ jsxs27(Fragment8, { children: [
16566
+ /* @__PURE__ */ jsx43(
16507
16567
  "svg",
16508
16568
  {
16509
16569
  className: "absolute pointer-events-none",
@@ -16513,7 +16573,7 @@ var TimelineRuler = memo9(function TimelineRuler2({
16513
16573
  const x = t * pps;
16514
16574
  const strength = Math.pow(Math.min(1, beatStrength ?? 0.5), 2.2);
16515
16575
  const opacity = 0.08 + strength * 0.62;
16516
- return /* @__PURE__ */ jsx42(
16576
+ return /* @__PURE__ */ jsx43(
16517
16577
  "line",
16518
16578
  {
16519
16579
  "data-timeline-grid-cell": "beat",
@@ -16530,13 +16590,13 @@ var TimelineRuler = memo9(function TimelineRuler2({
16530
16590
  })
16531
16591
  }
16532
16592
  ),
16533
- /* @__PURE__ */ jsxs26(
16593
+ /* @__PURE__ */ jsxs27(
16534
16594
  "div",
16535
16595
  {
16536
16596
  className: "sticky top-0 flex",
16537
16597
  style: { height: RULER_H, width: contentOrigin + trackContentWidth, zIndex: 70 },
16538
16598
  children: [
16539
- /* @__PURE__ */ jsx42(
16599
+ /* @__PURE__ */ jsx43(
16540
16600
  "div",
16541
16601
  {
16542
16602
  className: "sticky left-0 z-12 shrink-0",
@@ -16547,7 +16607,7 @@ var TimelineRuler = memo9(function TimelineRuler2({
16547
16607
  }
16548
16608
  }
16549
16609
  ),
16550
- /* @__PURE__ */ jsxs26(
16610
+ /* @__PURE__ */ jsxs27(
16551
16611
  "div",
16552
16612
  {
16553
16613
  className: "relative overflow-hidden",
@@ -16559,24 +16619,24 @@ var TimelineRuler = memo9(function TimelineRuler2({
16559
16619
  background: theme.shellBackground
16560
16620
  },
16561
16621
  children: [
16562
- minor.map((t) => /* @__PURE__ */ jsx42(
16622
+ minor.map((t) => /* @__PURE__ */ jsx43(
16563
16623
  "div",
16564
16624
  {
16565
16625
  "data-timeline-grid-cell": "minor",
16566
16626
  className: "absolute bottom-0",
16567
16627
  style: { left: t * pps - 0.5 },
16568
- children: /* @__PURE__ */ jsx42("div", { className: "w-px h-2", style: { background: theme.tickMinor } })
16628
+ children: /* @__PURE__ */ jsx43("div", { className: "w-px h-2", style: { background: theme.tickMinor } })
16569
16629
  },
16570
16630
  `m-${t}`
16571
16631
  )),
16572
- major.map((t) => /* @__PURE__ */ jsxs26(
16632
+ major.map((t) => /* @__PURE__ */ jsxs27(
16573
16633
  "div",
16574
16634
  {
16575
16635
  "data-timeline-grid-cell": "major",
16576
16636
  className: "absolute top-0",
16577
16637
  style: { left: t * pps - 0.5 },
16578
16638
  children: [
16579
- /* @__PURE__ */ jsx42(
16639
+ /* @__PURE__ */ jsx43(
16580
16640
  "span",
16581
16641
  {
16582
16642
  className: "absolute font-mono tabular-nums leading-none whitespace-nowrap",
@@ -16589,7 +16649,7 @@ var TimelineRuler = memo9(function TimelineRuler2({
16589
16649
  children: timeDisplayMode === "frame" ? secondsToFrame(t) : formatTimelineTickLabel(t, effectiveDuration, majorTickInterval)
16590
16650
  }
16591
16651
  ),
16592
- /* @__PURE__ */ jsx42("div", { className: "w-px", style: { height: RULER_H, background: theme.tickMajor } })
16652
+ /* @__PURE__ */ jsx43("div", { className: "w-px", style: { height: RULER_H, background: theme.tickMajor } })
16593
16653
  ]
16594
16654
  },
16595
16655
  `M-${t}`
@@ -16604,11 +16664,11 @@ var TimelineRuler = memo9(function TimelineRuler2({
16604
16664
  });
16605
16665
 
16606
16666
  // src/player/components/TimelineRulerPart.tsx
16607
- import { jsx as jsx43 } from "react/jsx-runtime";
16667
+ import { jsx as jsx44 } from "react/jsx-runtime";
16608
16668
  function TimelineRulerPart() {
16609
16669
  const { state } = useTimelineContext();
16610
16670
  const props = state.canvas;
16611
- return /* @__PURE__ */ jsx43(
16671
+ return /* @__PURE__ */ jsx44(
16612
16672
  TimelineRuler,
16613
16673
  {
16614
16674
  major: props.major,
@@ -16627,7 +16687,7 @@ function TimelineRulerPart() {
16627
16687
  }
16628
16688
 
16629
16689
  // src/player/components/PlayheadIndicator.tsx
16630
- import { Fragment as Fragment8, jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
16690
+ import { Fragment as Fragment9, jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
16631
16691
  function PlayheadIndicator({
16632
16692
  color = "var(--timeline-accent)",
16633
16693
  glowColor = "var(--timeline-playhead-glow)",
@@ -16637,8 +16697,8 @@ function PlayheadIndicator({
16637
16697
  const HEAD_W = PLAYHEAD_HEAD_W;
16638
16698
  const HEAD_H = 9;
16639
16699
  const HEAD_TOTAL_H = 1 + HEAD_H;
16640
- return /* @__PURE__ */ jsxs27(Fragment8, { children: [
16641
- /* @__PURE__ */ jsx44(
16700
+ return /* @__PURE__ */ jsxs28(Fragment9, { children: [
16701
+ /* @__PURE__ */ jsx45(
16642
16702
  "div",
16643
16703
  {
16644
16704
  "aria-hidden": "true",
@@ -16651,7 +16711,7 @@ function PlayheadIndicator({
16651
16711
  }
16652
16712
  }
16653
16713
  ),
16654
- /* @__PURE__ */ jsx44(
16714
+ /* @__PURE__ */ jsx45(
16655
16715
  "div",
16656
16716
  {
16657
16717
  className: "absolute bottom-0",
@@ -16665,7 +16725,7 @@ function PlayheadIndicator({
16665
16725
  }
16666
16726
  }
16667
16727
  ),
16668
- /* @__PURE__ */ jsx44(
16728
+ /* @__PURE__ */ jsx45(
16669
16729
  "div",
16670
16730
  {
16671
16731
  className: stickyHead ? "sticky" : "absolute",
@@ -16675,7 +16735,7 @@ function PlayheadIndicator({
16675
16735
  // Zero height keeps it from covering rows (sticky strip trick).
16676
16736
  height: stickyHead ? 0 : void 0
16677
16737
  },
16678
- children: /* @__PURE__ */ jsx44(
16738
+ children: /* @__PURE__ */ jsx45(
16679
16739
  "div",
16680
16740
  {
16681
16741
  style: {
@@ -16707,7 +16767,7 @@ import { memo as memo10 } from "react";
16707
16767
  import {
16708
16768
  useEffect as useEffect26,
16709
16769
  useRef as useRef32,
16710
- useState as useState21
16770
+ useState as useState22
16711
16771
  } from "react";
16712
16772
  import {
16713
16773
  HF_AUDIO_FADE_IN_ATTR,
@@ -16715,15 +16775,15 @@ import {
16715
16775
  clampFadesToDuration,
16716
16776
  formatFadeSeconds
16717
16777
  } from "@hyperframes/core/audio-fade";
16718
- import { Fragment as Fragment9, jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
16778
+ import { Fragment as Fragment10, jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
16719
16779
  var HANDLE_SIZE = 10;
16720
16780
  var HANDLE_HIT = 16;
16721
16781
  var DRAG_THRESHOLD_PX = 2;
16722
16782
  function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16723
16783
  const { onSetElementAttributeLive, onSetElementAttributeQuiet } = useTimelineEditContextOptional();
16724
16784
  const canEdit = Boolean(onSetElementAttributeLive && onSetElementAttributeQuiet);
16725
- const [draft, setDraft] = useState21(null);
16726
- const [dragging, setDragging] = useState21(null);
16785
+ const [draft, setDraft] = useState22(null);
16786
+ const [dragging, setDragging] = useState22(null);
16727
16787
  const authoredIn = el.fadeIn ?? 0;
16728
16788
  const authoredOut = el.fadeOut ?? 0;
16729
16789
  useEffect26(() => setDraft(null), [authoredIn, authoredOut]);
@@ -16829,8 +16889,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16829
16889
  touchAction: "none",
16830
16890
  outline: "none"
16831
16891
  });
16832
- return /* @__PURE__ */ jsxs28(Fragment9, { children: [
16833
- (showIn || showOut) && /* @__PURE__ */ jsxs28(
16892
+ return /* @__PURE__ */ jsxs29(Fragment10, { children: [
16893
+ (showIn || showOut) && /* @__PURE__ */ jsxs29(
16834
16894
  "svg",
16835
16895
  {
16836
16896
  "aria-hidden": "true",
@@ -16847,8 +16907,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16847
16907
  viewBox: `0 0 ${Math.max(widthPx, 1)} 100`,
16848
16908
  preserveAspectRatio: "none",
16849
16909
  children: [
16850
- showIn && /* @__PURE__ */ jsxs28(Fragment9, { children: [
16851
- /* @__PURE__ */ jsx45(
16910
+ showIn && /* @__PURE__ */ jsxs29(Fragment10, { children: [
16911
+ /* @__PURE__ */ jsx46(
16852
16912
  "polygon",
16853
16913
  {
16854
16914
  "data-testid": "clip-fade-in",
@@ -16857,7 +16917,7 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16857
16917
  fillOpacity: 0.35
16858
16918
  }
16859
16919
  ),
16860
- /* @__PURE__ */ jsx45(
16920
+ /* @__PURE__ */ jsx46(
16861
16921
  "line",
16862
16922
  {
16863
16923
  x1: 0,
@@ -16871,8 +16931,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16871
16931
  }
16872
16932
  )
16873
16933
  ] }),
16874
- showOut && /* @__PURE__ */ jsxs28(Fragment9, { children: [
16875
- /* @__PURE__ */ jsx45(
16934
+ showOut && /* @__PURE__ */ jsxs29(Fragment10, { children: [
16935
+ /* @__PURE__ */ jsx46(
16876
16936
  "polygon",
16877
16937
  {
16878
16938
  "data-testid": "clip-fade-out",
@@ -16881,7 +16941,7 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16881
16941
  fillOpacity: 0.35
16882
16942
  }
16883
16943
  ),
16884
- /* @__PURE__ */ jsx45(
16944
+ /* @__PURE__ */ jsx46(
16885
16945
  "line",
16886
16946
  {
16887
16947
  x1: widthPx - outPx,
@@ -16898,8 +16958,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16898
16958
  ]
16899
16959
  }
16900
16960
  ),
16901
- canEdit && /* @__PURE__ */ jsxs28(Fragment9, { children: [
16902
- /* @__PURE__ */ jsx45(
16961
+ canEdit && /* @__PURE__ */ jsxs29(Fragment10, { children: [
16962
+ /* @__PURE__ */ jsx46(
16903
16963
  FadeHandle,
16904
16964
  {
16905
16965
  direction: "in",
@@ -16914,7 +16974,7 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16914
16974
  onKeyDown: onHandleKeyDown
16915
16975
  }
16916
16976
  ),
16917
- /* @__PURE__ */ jsx45(
16977
+ /* @__PURE__ */ jsx46(
16918
16978
  FadeHandle,
16919
16979
  {
16920
16980
  direction: "out",
@@ -16945,7 +17005,7 @@ function FadeHandle({
16945
17005
  onKeyDown
16946
17006
  }) {
16947
17007
  const label = direction === "in" ? "Fade in" : "Fade out";
16948
- return /* @__PURE__ */ jsx45(
17008
+ return /* @__PURE__ */ jsx46(
16949
17009
  "div",
16950
17010
  {
16951
17011
  role: "slider",
@@ -16965,12 +17025,12 @@ function FadeHandle({
16965
17025
  onKeyDown,
16966
17026
  onClick: (e) => e.stopPropagation(),
16967
17027
  onDoubleClick: (e) => e.stopPropagation(),
16968
- children: /* @__PURE__ */ jsx45(FadeDot, { active: dragging })
17028
+ children: /* @__PURE__ */ jsx46(FadeDot, { active: dragging })
16969
17029
  }
16970
17030
  );
16971
17031
  }
16972
17032
  function FadeDot({ active }) {
16973
- return /* @__PURE__ */ jsx45(
17033
+ return /* @__PURE__ */ jsx46(
16974
17034
  "span",
16975
17035
  {
16976
17036
  "aria-hidden": "true",
@@ -16989,7 +17049,7 @@ function FadeDot({ active }) {
16989
17049
  }
16990
17050
 
16991
17051
  // src/player/components/TimelineClip.tsx
16992
- import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
17052
+ import { jsx as jsx47, jsxs as jsxs30 } from "react/jsx-runtime";
16993
17053
  var TimelineClip = memo10(function TimelineClip2({
16994
17054
  el,
16995
17055
  pps,
@@ -17061,7 +17121,7 @@ var TimelineClip = memo10(function TimelineClip2({
17061
17121
  textAlign: "left",
17062
17122
  transform: isDragging ? "translateY(-1px)" : void 0
17063
17123
  };
17064
- return /* @__PURE__ */ jsxs29(
17124
+ return /* @__PURE__ */ jsxs30(
17065
17125
  "button",
17066
17126
  {
17067
17127
  type: "button",
@@ -17087,7 +17147,7 @@ var TimelineClip = memo10(function TimelineClip2({
17087
17147
  onDoubleClick,
17088
17148
  onContextMenu,
17089
17149
  children: [
17090
- showHandles && capabilities.canTrimStart && /* @__PURE__ */ jsx46(
17150
+ showHandles && capabilities.canTrimStart && /* @__PURE__ */ jsx47(
17091
17151
  "div",
17092
17152
  {
17093
17153
  "aria-hidden": "true",
@@ -17101,7 +17161,7 @@ var TimelineClip = memo10(function TimelineClip2({
17101
17161
  cursor: "col-resize",
17102
17162
  zIndex: 4
17103
17163
  },
17104
- children: /* @__PURE__ */ jsx46(
17164
+ children: /* @__PURE__ */ jsx47(
17105
17165
  "div",
17106
17166
  {
17107
17167
  className: "timeline-clip__handle-bar",
@@ -17119,7 +17179,7 @@ var TimelineClip = memo10(function TimelineClip2({
17119
17179
  )
17120
17180
  }
17121
17181
  ),
17122
- showHandles && capabilities.canTrimEnd && /* @__PURE__ */ jsx46(
17182
+ showHandles && capabilities.canTrimEnd && /* @__PURE__ */ jsx47(
17123
17183
  "div",
17124
17184
  {
17125
17185
  "aria-hidden": "true",
@@ -17133,7 +17193,7 @@ var TimelineClip = memo10(function TimelineClip2({
17133
17193
  cursor: "col-resize",
17134
17194
  zIndex: 4
17135
17195
  },
17136
- children: /* @__PURE__ */ jsx46(
17196
+ children: /* @__PURE__ */ jsx47(
17137
17197
  "div",
17138
17198
  {
17139
17199
  className: "timeline-clip__handle-bar",
@@ -17151,15 +17211,15 @@ var TimelineClip = memo10(function TimelineClip2({
17151
17211
  )
17152
17212
  }
17153
17213
  ),
17154
- showLabel && /* @__PURE__ */ jsx46("span", { className: "timeline-clip__label", children: displayLabel }),
17155
- showDefaultText && /* @__PURE__ */ jsxs29("span", { className: "timeline-clip__timecode", children: [
17214
+ showLabel && /* @__PURE__ */ jsx47("span", { className: "timeline-clip__label", children: displayLabel }),
17215
+ showDefaultText && /* @__PURE__ */ jsxs30("span", { className: "timeline-clip__timecode", children: [
17156
17216
  startLabel,
17157
17217
  "-",
17158
17218
  endLabel,
17159
17219
  "s"
17160
17220
  ] }),
17161
17221
  children,
17162
- (isAudioClip || el.hasAudio) && !isGestureActor && /* @__PURE__ */ jsx46(
17222
+ (isAudioClip || el.hasAudio) && !isGestureActor && /* @__PURE__ */ jsx47(
17163
17223
  TimelineClipFades,
17164
17224
  {
17165
17225
  el,
@@ -17174,7 +17234,7 @@ var TimelineClip = memo10(function TimelineClip2({
17174
17234
  });
17175
17235
 
17176
17236
  // src/player/components/TimelineCompactDiamonds.tsx
17177
- import { jsx as jsx47 } from "react/jsx-runtime";
17237
+ import { jsx as jsx48 } from "react/jsx-runtime";
17178
17238
  function TimelineCompactDiamonds({
17179
17239
  element,
17180
17240
  elementId: elementId2,
@@ -17195,7 +17255,7 @@ function TimelineCompactDiamonds({
17195
17255
  suppressClickRef
17196
17256
  }) {
17197
17257
  const width = Math.max(element.duration * pixelsPerSecond, 4);
17198
- return /* @__PURE__ */ jsx47(
17258
+ return /* @__PURE__ */ jsx48(
17199
17259
  "div",
17200
17260
  {
17201
17261
  className: "absolute pointer-events-none",
@@ -17206,7 +17266,7 @@ function TimelineCompactDiamonds({
17206
17266
  height: rowHeight - 2 * CLIP_Y,
17207
17267
  zIndex: isSelected ? 11 : 6
17208
17268
  },
17209
- children: /* @__PURE__ */ jsx47(
17269
+ children: /* @__PURE__ */ jsx48(
17210
17270
  TimelineClipDiamonds,
17211
17271
  {
17212
17272
  keyframesData,
@@ -17243,7 +17303,7 @@ import {
17243
17303
  useEffect as useEffect27,
17244
17304
  useMemo as useMemo23,
17245
17305
  useRef as useRef37,
17246
- useState as useState26
17306
+ useState as useState27
17247
17307
  } from "react";
17248
17308
  import {
17249
17309
  sampleAutomationLane as sampleAutomationLane5
@@ -17378,7 +17438,7 @@ function withLane(automation, lane) {
17378
17438
  }
17379
17439
 
17380
17440
  // src/player/components/useAutomationLaneGestures.ts
17381
- import { useCallback as useCallback25, useRef as useRef36, useState as useState25 } from "react";
17441
+ import { useCallback as useCallback25, useRef as useRef36, useState as useState26 } from "react";
17382
17442
 
17383
17443
  // src/player/components/automationLaneSelection.ts
17384
17444
  import {
@@ -17443,7 +17503,7 @@ function capturePointer(e) {
17443
17503
  }
17444
17504
 
17445
17505
  // src/player/components/useAutomationEdgeStretch.ts
17446
- import { useCallback as useCallback22, useRef as useRef33, useState as useState22 } from "react";
17506
+ import { useCallback as useCallback22, useRef as useRef33, useState as useState23 } from "react";
17447
17507
  var EDGE_GRAB_PX = 8;
17448
17508
  var EDGE_DRAG_PX = 3;
17449
17509
  var MIN_SELECTION_SEC = 0.02;
@@ -17468,9 +17528,9 @@ function useAutomationEdgeStretch({
17468
17528
  onRangeClear,
17469
17529
  onHint
17470
17530
  }) {
17471
- const [drag, setDrag] = useState22(null);
17531
+ const [drag, setDrag] = useState23(null);
17472
17532
  const crossed = useRef33(false);
17473
- const [hover, setHover] = useState22(false);
17533
+ const [hover, setHover] = useState23(false);
17474
17534
  const edgeAt = useCallback22(
17475
17535
  (clientX) => {
17476
17536
  if (!rangeSelection) return null;
@@ -17574,7 +17634,7 @@ function useAutomationEdgeStretch({
17574
17634
  }
17575
17635
 
17576
17636
  // src/player/components/useAutomationRangeDrag.ts
17577
- import { useCallback as useCallback23, useRef as useRef34, useState as useState23 } from "react";
17637
+ import { useCallback as useCallback23, useRef as useRef34, useState as useState24 } from "react";
17578
17638
 
17579
17639
  // src/player/components/automationLaneDragMath.ts
17580
17640
  var SNAP_SEC = 0.04;
@@ -17692,7 +17752,7 @@ function useAutomationRangeDrag({
17692
17752
  onRangeSelect,
17693
17753
  onRangeClear
17694
17754
  }) {
17695
- const [box, setBox] = useState23(null);
17755
+ const [box, setBox] = useState24(null);
17696
17756
  const crossed = useRef34(false);
17697
17757
  const arm = useCallback23(
17698
17758
  (e) => {
@@ -17735,7 +17795,7 @@ function useAutomationRangeDrag({
17735
17795
  }
17736
17796
 
17737
17797
  // src/player/components/useAutomationSegmentDrag.ts
17738
- import { useCallback as useCallback24, useRef as useRef35, useState as useState24 } from "react";
17798
+ import { useCallback as useCallback24, useRef as useRef35, useState as useState25 } from "react";
17739
17799
  import {
17740
17800
  sampleAutomationLane as sampleAutomationLane3
17741
17801
  } from "@hyperframes/core/audio-automation";
@@ -17753,8 +17813,8 @@ function useAutomationSegmentDrag({
17753
17813
  readOnly,
17754
17814
  onHint
17755
17815
  }) {
17756
- const [dragIndex, setDragIndex] = useState24(null);
17757
- const [hoverIndex, setHoverIndex] = useState24(null);
17816
+ const [dragIndex, setDragIndex] = useState25(null);
17817
+ const [hoverIndex, setHoverIndex] = useState25(null);
17758
17818
  const snapshot3 = useRef35(null);
17759
17819
  const hitIndex = useCallback24(
17760
17820
  (clientX, clientY) => {
@@ -17831,9 +17891,9 @@ function useAutomationLaneGestures({
17831
17891
  duration,
17832
17892
  rangeSelection
17833
17893
  }) {
17834
- const [dragIndex, setDragIndex] = useState25(null);
17835
- const [curveIndex, setCurveIndex] = useState25(null);
17836
- const [hint, setHint] = useState25(null);
17894
+ const [dragIndex, setDragIndex] = useState26(null);
17895
+ const [curveIndex, setCurveIndex] = useState26(null);
17896
+ const [hint, setHint] = useState26(null);
17837
17897
  const stretch = useAutomationEdgeStretch({
17838
17898
  getBox,
17839
17899
  lane,
@@ -17858,7 +17918,7 @@ function useAutomationLaneGestures({
17858
17918
  });
17859
17919
  const dragOrigin = useRef36(null);
17860
17920
  const groupDrag = useRef36(null);
17861
- const [editing, setEditing] = useState25(null);
17921
+ const [editing, setEditing] = useState26(null);
17862
17922
  const rangeDrag = useAutomationRangeDrag({
17863
17923
  pointAt,
17864
17924
  xOf,
@@ -18191,7 +18251,7 @@ function useAutomationLaneGestures({
18191
18251
  }
18192
18252
 
18193
18253
  // src/player/components/AutomationValueInput.tsx
18194
- import { jsx as jsx48 } from "react/jsx-runtime";
18254
+ import { jsx as jsx49 } from "react/jsx-runtime";
18195
18255
  function AutomationValueInput({
18196
18256
  text,
18197
18257
  leftPx,
@@ -18200,7 +18260,7 @@ function AutomationValueInput({
18200
18260
  onCommit,
18201
18261
  onCancel
18202
18262
  }) {
18203
- return /* @__PURE__ */ jsx48(
18263
+ return /* @__PURE__ */ jsx49(
18204
18264
  "input",
18205
18265
  {
18206
18266
  className: "hf-automation-value pointer-events-auto absolute rounded-[3px] border border-panel-border-input bg-panel-bg-2 px-1 font-mono text-[9px] text-panel-text-1",
@@ -18272,7 +18332,7 @@ function generateShape(input) {
18272
18332
  }
18273
18333
 
18274
18334
  // src/player/components/AutomationSelectionMenu.tsx
18275
- import { jsx as jsx49, jsxs as jsxs30 } from "react/jsx-runtime";
18335
+ import { jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
18276
18336
  var AutomationSelectionMenu = memo11(function AutomationSelectionMenu2({
18277
18337
  x,
18278
18338
  y,
@@ -18289,14 +18349,14 @@ var AutomationSelectionMenu = memo11(function AutomationSelectionMenu2({
18289
18349
  const adjustedX = x + menuWidth > window.innerWidth ? x - menuWidth : x;
18290
18350
  const adjustedY = overflowY > 0 ? y - overflowY - 8 : y;
18291
18351
  return createPortal2(
18292
- /* @__PURE__ */ jsxs30(
18352
+ /* @__PURE__ */ jsxs31(
18293
18353
  "div",
18294
18354
  {
18295
18355
  ref: menuRef,
18296
18356
  className: "hf-automation-menu fixed z-200 min-w-[140px] rounded-sm border border-panel-border-input bg-panel-bg-2 py-1 shadow-lg",
18297
18357
  style: { left: adjustedX, top: adjustedY },
18298
18358
  children: [
18299
- AUTOMATION_SHAPES.map((shape) => /* @__PURE__ */ jsx49(
18359
+ AUTOMATION_SHAPES.map((shape) => /* @__PURE__ */ jsx50(
18300
18360
  "button",
18301
18361
  {
18302
18362
  type: "button",
@@ -18309,8 +18369,8 @@ var AutomationSelectionMenu = memo11(function AutomationSelectionMenu2({
18309
18369
  },
18310
18370
  shape.id
18311
18371
  )),
18312
- /* @__PURE__ */ jsx49("div", { className: "my-1 border-t border-panel-border-input" }),
18313
- /* @__PURE__ */ jsx49(
18372
+ /* @__PURE__ */ jsx50("div", { className: "my-1 border-t border-panel-border-input" }),
18373
+ /* @__PURE__ */ jsx50(
18314
18374
  "button",
18315
18375
  {
18316
18376
  type: "button",
@@ -18370,7 +18430,7 @@ function simplifyPoints(points, range, epsilon = 0.02) {
18370
18430
  }
18371
18431
 
18372
18432
  // src/player/components/AutomationEnvelopePaths.tsx
18373
- import { Fragment as Fragment10, jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
18433
+ import { Fragment as Fragment11, jsx as jsx51, jsxs as jsxs32 } from "react/jsx-runtime";
18374
18434
  function AutomationEnvelopePaths({
18375
18435
  path,
18376
18436
  lane,
@@ -18381,8 +18441,8 @@ function AutomationEnvelopePaths({
18381
18441
  yOf
18382
18442
  }) {
18383
18443
  const activePath = activeSegment === null ? null : envelopeSegmentPath({ lane, range, index: activeSegment, xOf, yOf });
18384
- return /* @__PURE__ */ jsxs31(Fragment10, { children: [
18385
- /* @__PURE__ */ jsx50(
18444
+ return /* @__PURE__ */ jsxs32(Fragment11, { children: [
18445
+ /* @__PURE__ */ jsx51(
18386
18446
  "path",
18387
18447
  {
18388
18448
  "data-automation-envelope": "",
@@ -18393,7 +18453,7 @@ function AutomationEnvelopePaths({
18393
18453
  opacity: lane.points.length === 0 ? 0.35 : 0.95
18394
18454
  }
18395
18455
  ),
18396
- activePath ? /* @__PURE__ */ jsx50(
18456
+ activePath ? /* @__PURE__ */ jsx51(
18397
18457
  "path",
18398
18458
  {
18399
18459
  "data-automation-segment-active": activeSegment ?? void 0,
@@ -18410,7 +18470,7 @@ function AutomationEnvelopePaths({
18410
18470
  }
18411
18471
 
18412
18472
  // src/player/components/TimelineAutomationLane.tsx
18413
- import { jsx as jsx51, jsxs as jsxs32 } from "react/jsx-runtime";
18473
+ import { jsx as jsx52, jsxs as jsxs33 } from "react/jsx-runtime";
18414
18474
  var POINT_R = 4.9;
18415
18475
  var LANE_BORDER = defaultTimelineTheme.rowBorder;
18416
18476
  function pointInBox(point, box) {
@@ -18437,7 +18497,7 @@ function ReadOnlyNote({
18437
18497
  widthPx
18438
18498
  }) {
18439
18499
  if (!readOnly || !note || !hovered || hasRange) return null;
18440
- return /* @__PURE__ */ jsx51(
18500
+ return /* @__PURE__ */ jsx52(
18441
18501
  "div",
18442
18502
  {
18443
18503
  "data-automation-readonly-note": "",
@@ -18479,7 +18539,7 @@ function TimelineAutomationLane({
18479
18539
  }) {
18480
18540
  const stored = laneFor(automation, target);
18481
18541
  const svgRef = useRef37(null);
18482
- const [draft, setDraft] = useState26(
18542
+ const [draft, setDraft] = useState27(
18483
18543
  null
18484
18544
  );
18485
18545
  const lane = useMemo23(
@@ -18569,8 +18629,8 @@ function TimelineAutomationLane({
18569
18629
  },
18570
18630
  [lane, commitPoints, readOnly]
18571
18631
  );
18572
- const [menuAt, setMenuAt] = useState26(null);
18573
- const [hovered, setHovered] = useState26(false);
18632
+ const [menuAt, setMenuAt] = useState27(null);
18633
+ const [hovered, setHovered] = useState27(false);
18574
18634
  const insertShape = useCallback26(
18575
18635
  (shape) => {
18576
18636
  if (!rangeSelection) return;
@@ -18606,14 +18666,14 @@ function TimelineAutomationLane({
18606
18666
  [readOnly, rangeSelection, pointAt]
18607
18667
  );
18608
18668
  const currentValue = lane.points.length > 0 && playheadSec !== null ? sampleAutomationLane5(lane, playheadSec, range.scale) : null;
18609
- return /* @__PURE__ */ jsxs32(
18669
+ return /* @__PURE__ */ jsxs33(
18610
18670
  "div",
18611
18671
  {
18612
18672
  className: "hf-automation-lane pointer-events-none absolute",
18613
18673
  style: { top: topPx, left: 0, right: 0, height: h },
18614
18674
  "data-automation-lane": target,
18615
18675
  children: [
18616
- /* @__PURE__ */ jsx51(
18676
+ /* @__PURE__ */ jsx52(
18617
18677
  "div",
18618
18678
  {
18619
18679
  "data-automation-lane-border": "",
@@ -18621,7 +18681,7 @@ function TimelineAutomationLane({
18621
18681
  style: { top: 0, left: 0, right: 0, height: 1, background: LANE_BORDER, zIndex: 1 }
18622
18682
  }
18623
18683
  ),
18624
- /* @__PURE__ */ jsxs32(
18684
+ /* @__PURE__ */ jsxs33(
18625
18685
  "svg",
18626
18686
  {
18627
18687
  ref: svgRef,
@@ -18656,8 +18716,8 @@ function TimelineAutomationLane({
18656
18716
  role: "group",
18657
18717
  "aria-label": `${range.label} automation`,
18658
18718
  children: [
18659
- /* @__PURE__ */ jsx51("title", { children: laneTitle(readOnly) }),
18660
- /* @__PURE__ */ jsx51(
18719
+ /* @__PURE__ */ jsx52("title", { children: laneTitle(readOnly) }),
18720
+ /* @__PURE__ */ jsx52(
18661
18721
  "line",
18662
18722
  {
18663
18723
  x1: PAD_X,
@@ -18668,7 +18728,7 @@ function TimelineAutomationLane({
18668
18728
  strokeDasharray: "3 4"
18669
18729
  }
18670
18730
  ),
18671
- rangeSelection ? /* @__PURE__ */ jsx51(
18731
+ rangeSelection ? /* @__PURE__ */ jsx52(
18672
18732
  "rect",
18673
18733
  {
18674
18734
  "data-automation-selection": "",
@@ -18683,7 +18743,7 @@ function TimelineAutomationLane({
18683
18743
  pointerEvents: "none"
18684
18744
  }
18685
18745
  ) : null,
18686
- /* @__PURE__ */ jsx51(
18746
+ /* @__PURE__ */ jsx52(
18687
18747
  AutomationEnvelopePaths,
18688
18748
  {
18689
18749
  path,
@@ -18698,7 +18758,7 @@ function TimelineAutomationLane({
18698
18758
  lane.points.map((p, i) => {
18699
18759
  const inRange = pointInBox(p, rangeSelection);
18700
18760
  const { radius, stroke, strokeWidth } = pointCircleStyle(inRange, i === dragIndex);
18701
- return /* @__PURE__ */ jsx51(
18761
+ return /* @__PURE__ */ jsx52(
18702
18762
  "circle",
18703
18763
  {
18704
18764
  "data-automation-point": i,
@@ -18727,7 +18787,7 @@ function TimelineAutomationLane({
18727
18787
  `${i}-${p.t}`
18728
18788
  );
18729
18789
  }),
18730
- playheadSec !== null && currentValue !== null ? /* @__PURE__ */ jsx51(
18790
+ playheadSec !== null && currentValue !== null ? /* @__PURE__ */ jsx52(
18731
18791
  "circle",
18732
18792
  {
18733
18793
  "data-automation-playhead": "",
@@ -18742,7 +18802,7 @@ function TimelineAutomationLane({
18742
18802
  ]
18743
18803
  }
18744
18804
  ),
18745
- editing ? /* @__PURE__ */ jsx51(
18805
+ editing ? /* @__PURE__ */ jsx52(
18746
18806
  AutomationValueInput,
18747
18807
  {
18748
18808
  text: editing.text,
@@ -18753,7 +18813,7 @@ function TimelineAutomationLane({
18753
18813
  onCancel: gestures.cancelEdit
18754
18814
  }
18755
18815
  ) : null,
18756
- hint ? /* @__PURE__ */ jsx51(
18816
+ hint ? /* @__PURE__ */ jsx52(
18757
18817
  "div",
18758
18818
  {
18759
18819
  className: "hf-automation-hint pointer-events-none absolute rounded-[3px] bg-[var(--timeline-overlay-bg)] px-1 py-0.5 font-mono text-[9px] text-[var(--timeline-text-solid)]",
@@ -18761,7 +18821,7 @@ function TimelineAutomationLane({
18761
18821
  children: hint
18762
18822
  }
18763
18823
  ) : null,
18764
- /* @__PURE__ */ jsx51(
18824
+ /* @__PURE__ */ jsx52(
18765
18825
  ReadOnlyNote,
18766
18826
  {
18767
18827
  readOnly,
@@ -18772,7 +18832,7 @@ function TimelineAutomationLane({
18772
18832
  widthPx
18773
18833
  }
18774
18834
  ),
18775
- menuAt && rangeSelection ? /* @__PURE__ */ jsx51(
18835
+ menuAt && rangeSelection ? /* @__PURE__ */ jsx52(
18776
18836
  AutomationSelectionMenu,
18777
18837
  {
18778
18838
  x: menuAt.x,
@@ -18789,7 +18849,7 @@ function TimelineAutomationLane({
18789
18849
  }
18790
18850
 
18791
18851
  // src/player/components/TimelineAutomationLaneSlot.tsx
18792
- import { Fragment as Fragment11, jsx as jsx52 } from "react/jsx-runtime";
18852
+ import { Fragment as Fragment12, jsx as jsx53 } from "react/jsx-runtime";
18793
18853
  function ClipAutomationLanes({
18794
18854
  element,
18795
18855
  rows,
@@ -18814,10 +18874,10 @@ function ClipAutomationLanes({
18814
18874
  }, [bound]);
18815
18875
  if (rows.length === 0) return null;
18816
18876
  const inClip = currentTime >= element.start && currentTime <= element.start + element.duration;
18817
- return /* @__PURE__ */ jsx52(Fragment11, { children: rows.map(({ lane, rowIndex }) => {
18877
+ return /* @__PURE__ */ jsx53(Fragment12, { children: rows.map(({ lane, rowIndex }) => {
18818
18878
  const range = resolveAutomationRange3(lane.target, bound.chain ?? void 0);
18819
18879
  if (!range) return null;
18820
- return /* @__PURE__ */ jsx52(
18880
+ return /* @__PURE__ */ jsx53(
18821
18881
  TimelineAutomationLane,
18822
18882
  {
18823
18883
  duration: element.duration,
@@ -18870,7 +18930,7 @@ function TimelineAutomationLaneSlot({
18870
18930
  }
18871
18931
  });
18872
18932
  const top = topOffset ?? getTimelineLaneTop(laneCount);
18873
- return /* @__PURE__ */ jsx52(Fragment11, { children: clips.map((element) => /* @__PURE__ */ jsx52(
18933
+ return /* @__PURE__ */ jsx53(Fragment12, { children: clips.map((element) => /* @__PURE__ */ jsx53(
18874
18934
  ClipAutomationLanes,
18875
18935
  {
18876
18936
  element,
@@ -19410,10 +19470,10 @@ import { classifyAudioName as classifyAudioName2 } from "@hyperframes/core/audio
19410
19470
  import { Eye as Eye2, EyeSlash } from "@phosphor-icons/react";
19411
19471
 
19412
19472
  // src/player/components/TrackClipCount.tsx
19413
- import { jsx as jsx53 } from "react/jsx-runtime";
19473
+ import { jsx as jsx54 } from "react/jsx-runtime";
19414
19474
  function TrackClipCount({ clipCount }) {
19415
19475
  if (clipCount < 2) return null;
19416
- return /* @__PURE__ */ jsx53(
19476
+ return /* @__PURE__ */ jsx54(
19417
19477
  "span",
19418
19478
  {
19419
19479
  "aria-label": `${clipCount} clips`,
@@ -19437,13 +19497,13 @@ function trackDisplaySuffix(displayNumber) {
19437
19497
  }
19438
19498
 
19439
19499
  // src/player/components/TimelineTrackPlainHeader.tsx
19440
- import { Fragment as Fragment12, jsx as jsx54, jsxs as jsxs33 } from "react/jsx-runtime";
19500
+ import { Fragment as Fragment13, jsx as jsx55, jsxs as jsxs34 } from "react/jsx-runtime";
19441
19501
  function visibilityButtonLabel(hidden, suffix) {
19442
19502
  return hidden ? `Show track${suffix}` : `Hide track${suffix}`;
19443
19503
  }
19444
19504
  function visibilityButtonIcon(hidden) {
19445
19505
  const Icon = hidden ? EyeSlash : Eye2;
19446
- return /* @__PURE__ */ jsx54(Icon, { size: 14, weight: "bold", "aria-hidden": "true" });
19506
+ return /* @__PURE__ */ jsx55(Icon, { size: 14, weight: "bold", "aria-hidden": "true" });
19447
19507
  }
19448
19508
  function VisibilityButton({
19449
19509
  hidden,
@@ -19452,10 +19512,10 @@ function VisibilityButton({
19452
19512
  visible,
19453
19513
  onToggle
19454
19514
  }) {
19455
- if (!visible) return /* @__PURE__ */ jsx54("span", { "aria-hidden": "true", className: "h-6 w-6 shrink-0" });
19515
+ if (!visible) return /* @__PURE__ */ jsx55("span", { "aria-hidden": "true", className: "h-6 w-6 shrink-0" });
19456
19516
  const suffix = trackDisplaySuffix(trackDisplayNumber2);
19457
19517
  const label = visibilityButtonLabel(hidden, suffix);
19458
- return /* @__PURE__ */ jsx54(
19518
+ return /* @__PURE__ */ jsx55(
19459
19519
  "button",
19460
19520
  {
19461
19521
  type: "button",
@@ -19482,8 +19542,8 @@ function PlainTrackHeader({
19482
19542
  onToggleTrackHidden,
19483
19543
  trailing
19484
19544
  }) {
19485
- return /* @__PURE__ */ jsx54(Fragment12, { children: /* @__PURE__ */ jsxs33("div", { className: "flex min-w-0 items-center gap-1", children: [
19486
- isAudioTrack && /* @__PURE__ */ jsx54(
19545
+ return /* @__PURE__ */ jsx55(Fragment13, { children: /* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 items-center gap-1", children: [
19546
+ isAudioTrack && /* @__PURE__ */ jsx55(
19487
19547
  Music,
19488
19548
  {
19489
19549
  size: 12,
@@ -19492,10 +19552,10 @@ function PlainTrackHeader({
19492
19552
  className: "text-[var(--timeline-text-faint)]"
19493
19553
  }
19494
19554
  ),
19495
- showTrackLabel && /* @__PURE__ */ jsx54("span", { title: trackLabel, className: "min-w-0 truncate text-[11px] leading-tight", children: trackLabel }),
19496
- showTrackLabel && /* @__PURE__ */ jsx54(TrackClipCount, { clipCount }),
19497
- /* @__PURE__ */ jsxs33("div", { className: "ml-auto flex shrink-0 items-center gap-1", children: [
19498
- /* @__PURE__ */ jsx54(
19555
+ showTrackLabel && /* @__PURE__ */ jsx55("span", { title: trackLabel, className: "min-w-0 truncate text-[11px] leading-tight", children: trackLabel }),
19556
+ showTrackLabel && /* @__PURE__ */ jsx55(TrackClipCount, { clipCount }),
19557
+ /* @__PURE__ */ jsxs34("div", { className: "ml-auto flex shrink-0 items-center gap-1", children: [
19558
+ /* @__PURE__ */ jsx55(
19499
19559
  VisibilityButton,
19500
19560
  {
19501
19561
  hidden: isTrackHidden,
@@ -19612,7 +19672,7 @@ function carverAgainst(doc, id) {
19612
19672
  }
19613
19673
 
19614
19674
  // src/player/components/TimelineFxButton.tsx
19615
- import { useEffect as useEffect32, useRef as useRef43, useState as useState27 } from "react";
19675
+ import { useEffect as useEffect32, useRef as useRef43, useState as useState28 } from "react";
19616
19676
  import { createPortal as createPortal3 } from "react-dom";
19617
19677
  import {
19618
19678
  enabledAudioFxNodes,
@@ -19630,7 +19690,7 @@ import {
19630
19690
  } from "@hyperframes/core/audio-fx-presets";
19631
19691
  import { PRESET_PROBLEM } from "@hyperframes/core/audio-fx-copy";
19632
19692
  import { useRef as useRef39 } from "react";
19633
- import { jsx as jsx55, jsxs as jsxs34 } from "react/jsx-runtime";
19693
+ import { jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
19634
19694
  var FAMILY_LABEL = {
19635
19695
  voice: "Voice",
19636
19696
  repair: "Fix",
@@ -19650,15 +19710,15 @@ function FxPresetMenu({
19650
19710
  onAuditionTracked?.(id);
19651
19711
  };
19652
19712
  const families = trackKind === "music" || trackKind === "sfx" ? HF_AUDIO_FX_PRESET_FAMILIES.filter((f) => f !== "voice") : HF_AUDIO_FX_PRESET_FAMILIES;
19653
- return /* @__PURE__ */ jsx55(
19713
+ return /* @__PURE__ */ jsx56(
19654
19714
  "div",
19655
19715
  {
19656
19716
  className: "hf-fx-preset-menu space-y-1.5 rounded-[4px] border border-panel-border-input p-1.5",
19657
19717
  onMouseLeave: onAudition ? () => onAudition(null) : void 0,
19658
19718
  onBlur: onAudition ? () => onAudition(null) : void 0,
19659
- children: families.map((family) => /* @__PURE__ */ jsxs34("div", { className: "hf-fx-preset-group space-y-0.5", children: [
19660
- /* @__PURE__ */ jsx55("span", { className: "hf-fx-preset-group-label block font-mono text-[9px] uppercase tracking-wide text-panel-text-2", children: FAMILY_LABEL[family] }),
19661
- audioFxPresetsByFamily(family).map((preset) => /* @__PURE__ */ jsxs34(
19719
+ children: families.map((family) => /* @__PURE__ */ jsxs35("div", { className: "hf-fx-preset-group space-y-0.5", children: [
19720
+ /* @__PURE__ */ jsx56("span", { className: "hf-fx-preset-group-label block font-mono text-[9px] uppercase tracking-wide text-panel-text-2", children: FAMILY_LABEL[family] }),
19721
+ audioFxPresetsByFamily(family).map((preset) => /* @__PURE__ */ jsxs35(
19662
19722
  "button",
19663
19723
  {
19664
19724
  type: "button",
@@ -19674,21 +19734,21 @@ function FxPresetMenu({
19674
19734
  onAudition?.(preset.id);
19675
19735
  },
19676
19736
  children: [
19677
- /* @__PURE__ */ jsx55("span", { className: "hf-fx-preset-problem block truncate text-[10px]", children: PRESET_PROBLEM[preset.id] ?? preset.description }),
19678
- /* @__PURE__ */ jsxs34("span", { className: "block truncate font-mono text-[9px] text-panel-text-2", children: [
19679
- /* @__PURE__ */ jsx55("span", { className: "hf-fx-preset-name", children: preset.label }),
19680
- /* @__PURE__ */ jsxs34("span", { className: "hf-fx-preset-count", children: [
19737
+ /* @__PURE__ */ jsx56("span", { className: "hf-fx-preset-problem block truncate text-[10px]", children: PRESET_PROBLEM[preset.id] ?? preset.description }),
19738
+ /* @__PURE__ */ jsxs35("span", { className: "block truncate font-mono text-[9px] text-panel-text-2", children: [
19739
+ /* @__PURE__ */ jsx56("span", { className: "hf-fx-preset-name", children: preset.label }),
19740
+ /* @__PURE__ */ jsxs35("span", { className: "hf-fx-preset-count", children: [
19681
19741
  " \xB7 ",
19682
19742
  preset.nodes.length,
19683
19743
  " effect",
19684
19744
  preset.nodes.length === 1 ? "" : "s"
19685
19745
  ] })
19686
19746
  ] }),
19687
- onAudition ? /* @__PURE__ */ jsxs34("span", { className: "hf-fx-preset-wave", "aria-hidden": "true", children: [
19688
- /* @__PURE__ */ jsx55("span", {}),
19689
- /* @__PURE__ */ jsx55("span", {}),
19690
- /* @__PURE__ */ jsx55("span", {}),
19691
- /* @__PURE__ */ jsx55("span", {})
19747
+ onAudition ? /* @__PURE__ */ jsxs35("span", { className: "hf-fx-preset-wave", "aria-hidden": "true", children: [
19748
+ /* @__PURE__ */ jsx56("span", {}),
19749
+ /* @__PURE__ */ jsx56("span", {}),
19750
+ /* @__PURE__ */ jsx56("span", {}),
19751
+ /* @__PURE__ */ jsx56("span", {})
19692
19752
  ] }) : null
19693
19753
  ]
19694
19754
  },
@@ -19852,7 +19912,7 @@ function useFxAudition(chain, onChainPreview, onAuditionTransport) {
19852
19912
  }
19853
19913
 
19854
19914
  // src/components/editor/TimelineFxPopover.tsx
19855
- import { jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
19915
+ import { jsx as jsx57, jsxs as jsxs36 } from "react/jsx-runtime";
19856
19916
  var POPOVER_WIDTH = 260;
19857
19917
  var VIEWPORT_MARGIN4 = 8;
19858
19918
  var MIN_POPOVER_HEIGHT = 160;
@@ -19921,7 +19981,7 @@ function TimelineFxPopover({
19921
19981
  audition(null);
19922
19982
  onClose();
19923
19983
  };
19924
- return /* @__PURE__ */ jsxs35(
19984
+ return /* @__PURE__ */ jsxs36(
19925
19985
  "div",
19926
19986
  {
19927
19987
  ref: rootRef,
@@ -19932,7 +19992,7 @@ function TimelineFxPopover({
19932
19992
  onKeyDown,
19933
19993
  onPointerDown: (event) => event.stopPropagation(),
19934
19994
  children: [
19935
- /* @__PURE__ */ jsx56("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx56(
19995
+ /* @__PURE__ */ jsx57("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx57(
19936
19996
  FxPresetMenu,
19937
19997
  {
19938
19998
  trackKind,
@@ -19941,8 +20001,8 @@ function TimelineFxPopover({
19941
20001
  onAuditionTracked: (id) => trackPresetAuditioned(id, { trackKind })
19942
20002
  }
19943
20003
  ) }),
19944
- /* @__PURE__ */ jsxs35("div", { className: "mt-2 flex shrink-0 items-center justify-between border-t border-white/10 pt-2 text-[10px] text-white/55", children: [
19945
- /* @__PURE__ */ jsx56(
20004
+ /* @__PURE__ */ jsxs36("div", { className: "mt-2 flex shrink-0 items-center justify-between border-t border-white/10 pt-2 text-[10px] text-white/55", children: [
20005
+ /* @__PURE__ */ jsx57(
19946
20006
  "button",
19947
20007
  {
19948
20008
  type: "button",
@@ -19954,7 +20014,7 @@ function TimelineFxPopover({
19954
20014
  children: "+ effect"
19955
20015
  }
19956
20016
  ),
19957
- /* @__PURE__ */ jsx56(
20017
+ /* @__PURE__ */ jsx57(
19958
20018
  "button",
19959
20019
  {
19960
20020
  type: "button",
@@ -20028,7 +20088,7 @@ function useAuditionTransport() {
20028
20088
  }
20029
20089
 
20030
20090
  // src/player/components/TimelineFxButton.tsx
20031
- import { jsx as jsx57, jsxs as jsxs36 } from "react/jsx-runtime";
20091
+ import { jsx as jsx58, jsxs as jsxs37 } from "react/jsx-runtime";
20032
20092
  var GROUP_DIALOG_SIZE = { width: 256, height: 160 };
20033
20093
  function groupDialogPosition(anchorRect) {
20034
20094
  const { left, top } = resolveFloatingPanelPosition(
@@ -20047,11 +20107,11 @@ function GroupNameDialog({
20047
20107
  onCancel,
20048
20108
  onConfirm
20049
20109
  }) {
20050
- const [label, setLabel] = useState27(defaultLabel ?? "Voiceover");
20110
+ const [label, setLabel] = useState28(defaultLabel ?? "Voiceover");
20051
20111
  const inputRef = useRef43(null);
20052
20112
  useEffect32(() => inputRef.current?.select(), []);
20053
20113
  if (refusal) {
20054
- return /* @__PURE__ */ jsx57(
20114
+ return /* @__PURE__ */ jsx58(
20055
20115
  "div",
20056
20116
  {
20057
20117
  role: "dialog",
@@ -20064,12 +20124,12 @@ function GroupNameDialog({
20064
20124
  event.stopPropagation();
20065
20125
  onCancel();
20066
20126
  },
20067
- children: /* @__PURE__ */ jsx57("p", { children: refusal })
20127
+ children: /* @__PURE__ */ jsx58("p", { children: refusal })
20068
20128
  }
20069
20129
  );
20070
20130
  }
20071
20131
  const confirm = () => onConfirm(label.trim() || defaultLabel || "Voiceover");
20072
- return /* @__PURE__ */ jsxs36(
20132
+ return /* @__PURE__ */ jsxs37(
20073
20133
  "div",
20074
20134
  {
20075
20135
  role: "dialog",
@@ -20085,8 +20145,8 @@ function GroupNameDialog({
20085
20145
  if (event.key === "Enter") confirm();
20086
20146
  },
20087
20147
  children: [
20088
- /* @__PURE__ */ jsx57("p", { className: "mb-1.5 font-medium text-[var(--timeline-text-solid)]", children: "Name this group" }),
20089
- /* @__PURE__ */ jsx57(
20148
+ /* @__PURE__ */ jsx58("p", { className: "mb-1.5 font-medium text-[var(--timeline-text-solid)]", children: "Name this group" }),
20149
+ /* @__PURE__ */ jsx58(
20090
20150
  "input",
20091
20151
  {
20092
20152
  ref: inputRef,
@@ -20097,13 +20157,13 @@ function GroupNameDialog({
20097
20157
  className: "w-full rounded-sm border border-[var(--timeline-border-strong)] bg-[var(--timeline-input-bg)] px-1.5 py-1 text-[11px] text-[var(--timeline-text-solid)] outline-hidden focus:border-[var(--timeline-accent)]"
20098
20158
  }
20099
20159
  ),
20100
- /* @__PURE__ */ jsxs36("p", { className: "mt-2 leading-snug", children: [
20160
+ /* @__PURE__ */ jsxs37("p", { className: "mt-2 leading-snug", children: [
20101
20161
  "Effects you add to the group apply to ",
20102
20162
  clipCount === 2 ? "both" : `all ${clipCount}`,
20103
20163
  " clips at once, and they share one volume."
20104
20164
  ] }),
20105
- /* @__PURE__ */ jsxs36("div", { className: "mt-2.5 flex justify-end gap-1.5", children: [
20106
- /* @__PURE__ */ jsx57(
20165
+ /* @__PURE__ */ jsxs37("div", { className: "mt-2.5 flex justify-end gap-1.5", children: [
20166
+ /* @__PURE__ */ jsx58(
20107
20167
  "button",
20108
20168
  {
20109
20169
  type: "button",
@@ -20112,7 +20172,7 @@ function GroupNameDialog({
20112
20172
  children: "Cancel"
20113
20173
  }
20114
20174
  ),
20115
- /* @__PURE__ */ jsx57(
20175
+ /* @__PURE__ */ jsx58(
20116
20176
  "button",
20117
20177
  {
20118
20178
  type: "button",
@@ -20135,9 +20195,9 @@ function parseFxChainOrEmpty(raw) {
20135
20195
  }
20136
20196
  }
20137
20197
  function TimelineFxButton(props) {
20138
- const [open, setOpen] = useState27(false);
20198
+ const [open, setOpen] = useState28(false);
20139
20199
  const buttonRef = useRef43(null);
20140
- const [anchorRect, setAnchorRect] = useState27(null);
20200
+ const [anchorRect, setAnchorRect] = useState28(null);
20141
20201
  const transport = useAuditionTransport();
20142
20202
  const borrowedMute = useRef43(false);
20143
20203
  const openAt = () => {
@@ -20145,8 +20205,8 @@ function TimelineFxButton(props) {
20145
20205
  setOpen(true);
20146
20206
  };
20147
20207
  if (props.variant === "group-pointer") {
20148
- return /* @__PURE__ */ jsxs36("div", { className: "relative shrink-0", children: [
20149
- /* @__PURE__ */ jsx57(
20208
+ return /* @__PURE__ */ jsxs37("div", { className: "relative shrink-0", children: [
20209
+ /* @__PURE__ */ jsx58(
20150
20210
  "button",
20151
20211
  {
20152
20212
  type: "button",
@@ -20164,7 +20224,7 @@ function TimelineFxButton(props) {
20164
20224
  }
20165
20225
  ),
20166
20226
  open && anchorRect && createPortal3(
20167
- /* @__PURE__ */ jsx57(
20227
+ /* @__PURE__ */ jsx58(
20168
20228
  GroupNameDialog,
20169
20229
  {
20170
20230
  refusal: props.refusal,
@@ -20184,8 +20244,8 @@ function TimelineFxButton(props) {
20184
20244
  }
20185
20245
  const chain = parseFxChainOrEmpty(props.fxChainRaw);
20186
20246
  const nodeCount = enabledAudioFxNodes(chain).length;
20187
- return /* @__PURE__ */ jsxs36("div", { className: "relative shrink-0", children: [
20188
- /* @__PURE__ */ jsxs36(
20247
+ return /* @__PURE__ */ jsxs37("div", { className: "relative shrink-0", children: [
20248
+ /* @__PURE__ */ jsxs37(
20189
20249
  "button",
20190
20250
  {
20191
20251
  type: "button",
@@ -20206,7 +20266,7 @@ function TimelineFxButton(props) {
20206
20266
  }
20207
20267
  ),
20208
20268
  open && anchorRect && createPortal3(
20209
- /* @__PURE__ */ jsx57(
20269
+ /* @__PURE__ */ jsx58(
20210
20270
  TimelineFxPopover,
20211
20271
  {
20212
20272
  anchorRect,
@@ -20230,14 +20290,14 @@ function TimelineFxButton(props) {
20230
20290
  }
20231
20291
 
20232
20292
  // src/player/components/LayerDisclosureRow.tsx
20233
- import { jsx as jsx58, jsxs as jsxs37 } from "react/jsx-runtime";
20293
+ import { jsx as jsx59, jsxs as jsxs38 } from "react/jsx-runtime";
20234
20294
  function LaneToggleButton({
20235
20295
  name,
20236
20296
  isExpanded,
20237
20297
  lanesId,
20238
20298
  onToggle
20239
20299
  }) {
20240
- return /* @__PURE__ */ jsx58(
20300
+ return /* @__PURE__ */ jsx59(
20241
20301
  "button",
20242
20302
  {
20243
20303
  type: "button",
@@ -20252,7 +20312,7 @@ function LaneToggleButton({
20252
20312
  event.stopPropagation();
20253
20313
  onToggle();
20254
20314
  },
20255
- children: /* @__PURE__ */ jsx58("span", { "aria-hidden": "true", children: "\u223F" })
20315
+ children: /* @__PURE__ */ jsx59("span", { "aria-hidden": "true", children: "\u223F" })
20256
20316
  }
20257
20317
  );
20258
20318
  }
@@ -20266,7 +20326,7 @@ function LayerDisclosureRow({
20266
20326
  onToggleClipExpanded,
20267
20327
  children
20268
20328
  }) {
20269
- return /* @__PURE__ */ jsxs37(
20329
+ return /* @__PURE__ */ jsxs38(
20270
20330
  "div",
20271
20331
  {
20272
20332
  className: "absolute left-0 top-0 flex items-center gap-1.5 overflow-hidden px-1.5 text-[11px]",
@@ -20277,7 +20337,7 @@ function LayerDisclosureRow({
20277
20337
  background: gutterBackground
20278
20338
  },
20279
20339
  children: [
20280
- /* @__PURE__ */ jsx58(
20340
+ /* @__PURE__ */ jsx59(
20281
20341
  "span",
20282
20342
  {
20283
20343
  "aria-hidden": "true",
@@ -20285,10 +20345,10 @@ function LayerDisclosureRow({
20285
20345
  children: "\u25C7"
20286
20346
  }
20287
20347
  ),
20288
- /* @__PURE__ */ jsx58("span", { title: name, className: "min-w-0 flex-1 truncate font-medium leading-tight", children: name }),
20289
- /* @__PURE__ */ jsx58(TrackClipCount, { clipCount }),
20348
+ /* @__PURE__ */ jsx59("span", { title: name, className: "min-w-0 flex-1 truncate font-medium leading-tight", children: name }),
20349
+ /* @__PURE__ */ jsx59(TrackClipCount, { clipCount }),
20290
20350
  children,
20291
- /* @__PURE__ */ jsx58(
20351
+ /* @__PURE__ */ jsx59(
20292
20352
  LaneToggleButton,
20293
20353
  {
20294
20354
  name,
@@ -20438,7 +20498,7 @@ function resolveLaneHeaderState(lane, currentTime, clipPercentage) {
20438
20498
  }
20439
20499
 
20440
20500
  // src/player/components/trackHeaderLabelRows.tsx
20441
- import { jsx as jsx59, jsxs as jsxs38 } from "react/jsx-runtime";
20501
+ import { jsx as jsx60, jsxs as jsxs39 } from "react/jsx-runtime";
20442
20502
  function PropertyGroupNavigation({
20443
20503
  navigation,
20444
20504
  label,
@@ -20452,8 +20512,8 @@ function PropertyGroupNavigation({
20452
20512
  onSeek?.(expandedElement.start + keyframe.percentage / 100 * expandedElement.duration);
20453
20513
  }
20454
20514
  };
20455
- return /* @__PURE__ */ jsxs38("span", { className: "flex shrink-0 items-center gap-0.5", children: [
20456
- /* @__PURE__ */ jsx59(
20515
+ return /* @__PURE__ */ jsxs39("span", { className: "flex shrink-0 items-center gap-0.5", children: [
20516
+ /* @__PURE__ */ jsx60(
20457
20517
  "button",
20458
20518
  {
20459
20519
  type: "button",
@@ -20468,7 +20528,7 @@ function PropertyGroupNavigation({
20468
20528
  }
20469
20529
  ),
20470
20530
  children,
20471
- /* @__PURE__ */ jsx59(
20531
+ /* @__PURE__ */ jsx60(
20472
20532
  "button",
20473
20533
  {
20474
20534
  type: "button",
@@ -20504,7 +20564,7 @@ function PropertyGroupHeaderRow({
20504
20564
  currentTime,
20505
20565
  clipPercentage
20506
20566
  );
20507
- return /* @__PURE__ */ jsxs38(
20567
+ return /* @__PURE__ */ jsxs39(
20508
20568
  "div",
20509
20569
  {
20510
20570
  id: timelineLogicalRowCellId(lanesId, timelinePropertyRowId(elementId2, lane.group), "header"),
@@ -20524,25 +20584,25 @@ function PropertyGroupHeaderRow({
20524
20584
  background: gutterBackground
20525
20585
  },
20526
20586
  children: [
20527
- /* @__PURE__ */ jsxs38("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20528
- /* @__PURE__ */ jsx59(
20587
+ /* @__PURE__ */ jsxs39("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20588
+ /* @__PURE__ */ jsx60(
20529
20589
  "span",
20530
20590
  {
20531
20591
  className: "absolute left-1.5 top-0 w-px bg-white/15",
20532
20592
  style: { height: isLastLane ? "50%" : "100%" }
20533
20593
  }
20534
20594
  ),
20535
- /* @__PURE__ */ jsx59("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20595
+ /* @__PURE__ */ jsx60("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20536
20596
  ] }),
20537
- /* @__PURE__ */ jsx59("span", { className: "w-[46px] shrink-0 truncate text-white", title: label, children: label }),
20538
- /* @__PURE__ */ jsx59(
20597
+ /* @__PURE__ */ jsx60("span", { className: "w-[46px] shrink-0 truncate text-white", title: label, children: label }),
20598
+ /* @__PURE__ */ jsx60(
20539
20599
  PropertyGroupNavigation,
20540
20600
  {
20541
20601
  navigation,
20542
20602
  label,
20543
20603
  expandedElement,
20544
20604
  onSeek,
20545
- children: /* @__PURE__ */ jsx59(
20605
+ children: /* @__PURE__ */ jsx60(
20546
20606
  "button",
20547
20607
  {
20548
20608
  type: "button",
@@ -20561,7 +20621,7 @@ function PropertyGroupHeaderRow({
20561
20621
  )
20562
20622
  }
20563
20623
  ),
20564
- /* @__PURE__ */ jsx59(
20624
+ /* @__PURE__ */ jsx60(
20565
20625
  "span",
20566
20626
  {
20567
20627
  className: "min-w-0 flex-1 truncate text-right tabular-nums text-white/45",
@@ -20587,7 +20647,7 @@ function AutomationLaneHeaderRow({
20587
20647
  isCarve,
20588
20648
  onReveal
20589
20649
  }) {
20590
- return /* @__PURE__ */ jsxs38(
20650
+ return /* @__PURE__ */ jsxs39(
20591
20651
  "div",
20592
20652
  {
20593
20653
  "data-automation-lane-label": label,
@@ -20600,17 +20660,17 @@ function AutomationLaneHeaderRow({
20600
20660
  background: gutterBackground
20601
20661
  },
20602
20662
  children: [
20603
- /* @__PURE__ */ jsxs38("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20604
- /* @__PURE__ */ jsx59(
20663
+ /* @__PURE__ */ jsxs39("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20664
+ /* @__PURE__ */ jsx60(
20605
20665
  "span",
20606
20666
  {
20607
20667
  className: "absolute left-1.5 top-0 w-px bg-white/15",
20608
20668
  style: { height: isLastLane ? "50%" : "100%" }
20609
20669
  }
20610
20670
  ),
20611
- /* @__PURE__ */ jsx59("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20671
+ /* @__PURE__ */ jsx60("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20612
20672
  ] }),
20613
- /* @__PURE__ */ jsxs38(
20673
+ /* @__PURE__ */ jsxs39(
20614
20674
  "button",
20615
20675
  {
20616
20676
  type: "button",
@@ -20625,8 +20685,8 @@ function AutomationLaneHeaderRow({
20625
20685
  onReveal?.();
20626
20686
  },
20627
20687
  children: [
20628
- /* @__PURE__ */ jsx59("span", { "data-automation-lane-name": "", className: "truncate font-mono text-[9px] text-white/70", children: name }),
20629
- param ? /* @__PURE__ */ jsx59(
20688
+ /* @__PURE__ */ jsx60("span", { "data-automation-lane-name": "", className: "truncate font-mono text-[9px] text-white/70", children: name }),
20689
+ param ? /* @__PURE__ */ jsx60(
20630
20690
  "span",
20631
20691
  {
20632
20692
  "data-automation-lane-param": "",
@@ -20634,7 +20694,7 @@ function AutomationLaneHeaderRow({
20634
20694
  children: param
20635
20695
  }
20636
20696
  ) : null,
20637
- alsoAutomatedBy ? /* @__PURE__ */ jsxs38(
20697
+ alsoAutomatedBy ? /* @__PURE__ */ jsxs39(
20638
20698
  "span",
20639
20699
  {
20640
20700
  "data-automation-lane-also": "",
@@ -20649,7 +20709,7 @@ function AutomationLaneHeaderRow({
20649
20709
  ]
20650
20710
  }
20651
20711
  ),
20652
- onRemove && target !== null && !isCarve && /* @__PURE__ */ jsx59(
20712
+ onRemove && target !== null && !isCarve && /* @__PURE__ */ jsx60(
20653
20713
  "button",
20654
20714
  {
20655
20715
  type: "button",
@@ -20671,7 +20731,7 @@ function AutomationLaneHeaderRow({
20671
20731
 
20672
20732
  // src/player/components/TimelineTrackHeader.tsx
20673
20733
  import { useMemo as useMemo26 } from "react";
20674
- import { Fragment as Fragment13, jsx as jsx60, jsxs as jsxs39 } from "react/jsx-runtime";
20734
+ import { Fragment as Fragment14, jsx as jsx61, jsxs as jsxs40 } from "react/jsx-runtime";
20675
20735
  var GROUP_MEMBER_RAIL = "var(--timeline-accent-rail)";
20676
20736
  var GROUP_MEMBER_INDENT = 14;
20677
20737
  var GROUP_MEMBER_TINT = "var(--timeline-group-member-tint)";
@@ -20791,7 +20851,7 @@ function TimelineTrackHeader({
20791
20851
  if (!allGroupableClipIds || allGroupableClipIds.length < 2) return;
20792
20852
  void onGroupClips(allGroupableClipIds, mintGroupId(doc), label);
20793
20853
  };
20794
- return /* @__PURE__ */ jsxs39(
20854
+ return /* @__PURE__ */ jsxs40(
20795
20855
  "div",
20796
20856
  {
20797
20857
  role: "rowheader",
@@ -20813,12 +20873,12 @@ function TimelineTrackHeader({
20813
20873
  } : {}
20814
20874
  },
20815
20875
  children: [
20816
- !isKeyframeLayer ? /* @__PURE__ */ jsx60(Fragment13, { children: /* @__PURE__ */ jsx60(
20876
+ !isKeyframeLayer ? /* @__PURE__ */ jsx61(Fragment14, { children: /* @__PURE__ */ jsx61(
20817
20877
  "div",
20818
20878
  {
20819
20879
  className: showTrackLabel ? "flex flex-col justify-center gap-0.5 px-1.5 text-[var(--timeline-handle)]" : "flex flex-col items-center justify-center gap-0.5",
20820
20880
  style: { height: TRACK_H },
20821
- children: /* @__PURE__ */ jsx60(
20881
+ children: /* @__PURE__ */ jsx61(
20822
20882
  PlainTrackHeader,
20823
20883
  {
20824
20884
  trackNumber,
@@ -20829,8 +20889,8 @@ function TimelineTrackHeader({
20829
20889
  isTrackHidden,
20830
20890
  isAudioTrack,
20831
20891
  onToggleTrackHidden,
20832
- trailing: /* @__PURE__ */ jsxs39(Fragment13, { children: [
20833
- singleAudioClip && /* @__PURE__ */ jsx60(
20892
+ trailing: /* @__PURE__ */ jsxs40(Fragment14, { children: [
20893
+ singleAudioClip && /* @__PURE__ */ jsx61(
20834
20894
  TimelineFxButton,
20835
20895
  {
20836
20896
  variant: "chain",
@@ -20848,7 +20908,7 @@ function TimelineTrackHeader({
20848
20908
  onOpenRack: () => openClipFxRack(singleAudioClip)
20849
20909
  }
20850
20910
  ),
20851
- clipCount > 1 && !isTrackGrouped && (isAudioTrack ? canGroupWholeTrack : isVideoWithAudioTrack) && /* @__PURE__ */ jsx60(
20911
+ clipCount > 1 && !isTrackGrouped && (isAudioTrack ? canGroupWholeTrack : isVideoWithAudioTrack) && /* @__PURE__ */ jsx61(
20852
20912
  TimelineFxButton,
20853
20913
  {
20854
20914
  variant: "group-pointer",
@@ -20858,7 +20918,7 @@ function TimelineTrackHeader({
20858
20918
  onGroupClips: groupUngroupedClips
20859
20919
  }
20860
20920
  ),
20861
- disclosable && /* @__PURE__ */ jsx60(
20921
+ disclosable && /* @__PURE__ */ jsx61(
20862
20922
  LaneToggleButton,
20863
20923
  {
20864
20924
  name: laneOwnerName,
@@ -20871,7 +20931,7 @@ function TimelineTrackHeader({
20871
20931
  }
20872
20932
  )
20873
20933
  }
20874
- ) }) : /* @__PURE__ */ jsx60(Fragment13, { children: /* @__PURE__ */ jsx60(
20934
+ ) }) : /* @__PURE__ */ jsx61(Fragment14, { children: /* @__PURE__ */ jsx61(
20875
20935
  LayerDisclosureRow,
20876
20936
  {
20877
20937
  name: laneOwnerName,
@@ -20881,7 +20941,7 @@ function TimelineTrackHeader({
20881
20941
  columnWidth: showTrackLabel ? LABEL_COL_W : contentOrigin,
20882
20942
  lanesId,
20883
20943
  onToggleClipExpanded,
20884
- children: /* @__PURE__ */ jsx60(
20944
+ children: /* @__PURE__ */ jsx61(
20885
20945
  VisibilityButton,
20886
20946
  {
20887
20947
  hidden: isTrackHidden,
@@ -20893,7 +20953,7 @@ function TimelineTrackHeader({
20893
20953
  )
20894
20954
  }
20895
20955
  ) }),
20896
- isExpanded && keyframeClip && lanes.map((lane, laneIndex) => /* @__PURE__ */ jsx60(
20956
+ isExpanded && keyframeClip && lanes.map((lane, laneIndex) => /* @__PURE__ */ jsx61(
20897
20957
  PropertyGroupHeaderRow,
20898
20958
  {
20899
20959
  lanesId,
@@ -20913,7 +20973,7 @@ function TimelineTrackHeader({
20913
20973
  )),
20914
20974
  isExpanded && automationRows.map((row, index) => {
20915
20975
  const revealTarget = row.target;
20916
- return /* @__PURE__ */ jsx60(
20976
+ return /* @__PURE__ */ jsx61(
20917
20977
  AutomationLaneHeaderRow,
20918
20978
  {
20919
20979
  target: row.target,
@@ -20950,7 +21010,7 @@ import {
20950
21010
  } from "@hyperframes/core/audio-fx";
20951
21011
 
20952
21012
  // src/player/components/TimelineTrackRow.tsx
20953
- import { jsx as jsx61, jsxs as jsxs40 } from "react/jsx-runtime";
21013
+ import { jsx as jsx62, jsxs as jsxs41 } from "react/jsx-runtime";
20954
21014
  function TimelineTrackRow({
20955
21015
  index,
20956
21016
  rowKey,
@@ -20966,7 +21026,7 @@ function TimelineTrackRow({
20966
21026
  rovingTargetId = null,
20967
21027
  children
20968
21028
  }) {
20969
- return /* @__PURE__ */ jsxs40(
21029
+ return /* @__PURE__ */ jsxs41(
20970
21030
  "div",
20971
21031
  {
20972
21032
  role: "rowgroup",
@@ -20981,7 +21041,7 @@ function TimelineTrackRow({
20981
21041
  borderBottom: `1px solid ${borderColor}`
20982
21042
  },
20983
21043
  children: [
20984
- /* @__PURE__ */ jsx61(
21044
+ /* @__PURE__ */ jsx62(
20985
21045
  "div",
20986
21046
  {
20987
21047
  role: "row",
@@ -21003,7 +21063,7 @@ function TimelineTrackRow({
21003
21063
  return (
21004
21064
  // ponytail: aria-owns maps this hidden logical row onto the two visible
21005
21065
  // property-lane cells without duplicating interactive controls.
21006
- /* @__PURE__ */ jsxs40(
21066
+ /* @__PURE__ */ jsxs41(
21007
21067
  "div",
21008
21068
  {
21009
21069
  role: "row",
@@ -21013,7 +21073,7 @@ function TimelineTrackRow({
21013
21073
  "data-timeline-logical-row-id": row.id,
21014
21074
  className: "sr-only",
21015
21075
  children: [
21016
- /* @__PURE__ */ jsx61(
21076
+ /* @__PURE__ */ jsx62(
21017
21077
  "div",
21018
21078
  {
21019
21079
  role: "rowheader",
@@ -21022,7 +21082,7 @@ function TimelineTrackRow({
21022
21082
  children: group
21023
21083
  }
21024
21084
  ),
21025
- /* @__PURE__ */ jsxs40(
21085
+ /* @__PURE__ */ jsxs41(
21026
21086
  "div",
21027
21087
  {
21028
21088
  role: "gridcell",
@@ -21048,13 +21108,13 @@ function TimelineTrackRow({
21048
21108
  }
21049
21109
 
21050
21110
  // src/player/components/TimelineGroupHeader.tsx
21051
- import { jsx as jsx62, jsxs as jsxs41 } from "react/jsx-runtime";
21111
+ import { jsx as jsx63, jsxs as jsxs42 } from "react/jsx-runtime";
21052
21112
  function GroupNameButton({
21053
21113
  label,
21054
21114
  memberCount,
21055
21115
  onOpenFxRack
21056
21116
  }) {
21057
- return /* @__PURE__ */ jsxs41(
21117
+ return /* @__PURE__ */ jsxs42(
21058
21118
  "button",
21059
21119
  {
21060
21120
  type: "button",
@@ -21068,7 +21128,7 @@ function GroupNameButton({
21068
21128
  onOpenFxRack();
21069
21129
  },
21070
21130
  children: [
21071
- /* @__PURE__ */ jsx62(
21131
+ /* @__PURE__ */ jsx63(
21072
21132
  "span",
21073
21133
  {
21074
21134
  "aria-hidden": "true",
@@ -21076,8 +21136,8 @@ function GroupNameButton({
21076
21136
  children: "\u25A4"
21077
21137
  }
21078
21138
  ),
21079
- /* @__PURE__ */ jsx62("span", { title: label, className: "min-w-0 truncate text-left font-medium leading-tight", children: label }),
21080
- /* @__PURE__ */ jsx62(
21139
+ /* @__PURE__ */ jsx63("span", { title: label, className: "min-w-0 truncate text-left font-medium leading-tight", children: label }),
21140
+ /* @__PURE__ */ jsx63(
21081
21141
  "span",
21082
21142
  {
21083
21143
  className: "shrink-0 rounded-full bg-[var(--timeline-tick-major)] px-1 text-[9px] leading-[14px] tabular-nums text-[var(--timeline-handle)]",
@@ -21106,7 +21166,7 @@ function TimelineGroupHeader({
21106
21166
  columnWidth,
21107
21167
  theme
21108
21168
  }) {
21109
- return /* @__PURE__ */ jsxs41(
21169
+ return /* @__PURE__ */ jsxs42(
21110
21170
  "div",
21111
21171
  {
21112
21172
  role: "rowheader",
@@ -21120,7 +21180,7 @@ function TimelineGroupHeader({
21120
21180
  borderRight: `1px solid ${theme.gutterBorder}`
21121
21181
  },
21122
21182
  children: [
21123
- /* @__PURE__ */ jsx62(
21183
+ /* @__PURE__ */ jsx63(
21124
21184
  "button",
21125
21185
  {
21126
21186
  type: "button",
@@ -21134,12 +21194,12 @@ function TimelineGroupHeader({
21134
21194
  event.stopPropagation();
21135
21195
  onToggleExpanded();
21136
21196
  },
21137
- children: /* @__PURE__ */ jsx62("span", { "aria-hidden": "true", children: isExpanded ? "\u25BE" : "\u25B8" })
21197
+ children: /* @__PURE__ */ jsx63("span", { "aria-hidden": "true", children: isExpanded ? "\u25BE" : "\u25B8" })
21138
21198
  }
21139
21199
  ),
21140
- /* @__PURE__ */ jsx62(GroupNameButton, { label, memberCount, onOpenFxRack }),
21141
- /* @__PURE__ */ jsxs41("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
21142
- /* @__PURE__ */ jsx62(
21200
+ /* @__PURE__ */ jsx63(GroupNameButton, { label, memberCount, onOpenFxRack }),
21201
+ /* @__PURE__ */ jsxs42("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
21202
+ /* @__PURE__ */ jsx63(
21143
21203
  TimelineFxButton,
21144
21204
  {
21145
21205
  fxChainRaw: fxChain,
@@ -21149,7 +21209,7 @@ function TimelineGroupHeader({
21149
21209
  onOpenRack: onOpenFxRack
21150
21210
  }
21151
21211
  ),
21152
- laneCount > 0 && /* @__PURE__ */ jsxs41(
21212
+ laneCount > 0 && /* @__PURE__ */ jsxs42(
21153
21213
  "button",
21154
21214
  {
21155
21215
  type: "button",
@@ -21164,8 +21224,8 @@ function TimelineGroupHeader({
21164
21224
  onToggleLanes();
21165
21225
  },
21166
21226
  children: [
21167
- /* @__PURE__ */ jsx62("span", { "aria-hidden": "true", children: "\u223F" }),
21168
- /* @__PURE__ */ jsx62("span", { className: "text-[9px] tabular-nums text-[var(--timeline-handle)]", children: laneCount })
21227
+ /* @__PURE__ */ jsx63("span", { "aria-hidden": "true", children: "\u223F" }),
21228
+ /* @__PURE__ */ jsx63("span", { className: "text-[9px] tabular-nums text-[var(--timeline-handle)]", children: laneCount })
21169
21229
  ]
21170
21230
  }
21171
21231
  )
@@ -21179,13 +21239,13 @@ function TimelineGroupHeader({
21179
21239
  import { sampleAutomationLane as sampleAutomationLane7 } from "@hyperframes/core/audio-automation";
21180
21240
 
21181
21241
  // src/hooks/useLivePlayheadTime.ts
21182
- import { useEffect as useEffect33, useRef as useRef44, useState as useState28 } from "react";
21242
+ import { useEffect as useEffect33, useRef as useRef44, useState as useState29 } from "react";
21183
21243
  var THROTTLE_MS = 33;
21184
21244
  function useLivePlayheadTime() {
21185
21245
  const storeTime = usePlayerStore((s) => s.currentTime);
21186
21246
  const isPlaying = usePlayerStore((s) => s.isPlaying);
21187
21247
  const liveRef = useRef44(storeTime);
21188
- const [, forceRender] = useState28(0);
21248
+ const [, forceRender] = useState29(0);
21189
21249
  if (!isPlaying) liveRef.current = storeTime;
21190
21250
  useEffect33(() => {
21191
21251
  if (!isPlaying) return;
@@ -21208,7 +21268,7 @@ function useLivePlayheadTime() {
21208
21268
  }
21209
21269
 
21210
21270
  // src/player/components/TimelineGroupLaneLabels.tsx
21211
- import { Fragment as Fragment14, jsx as jsx63, jsxs as jsxs42 } from "react/jsx-runtime";
21271
+ import { Fragment as Fragment15, jsx as jsx64, jsxs as jsxs43 } from "react/jsx-runtime";
21212
21272
  function TimelineGroupLaneLabels({
21213
21273
  groupElement,
21214
21274
  groupLabel: groupLabel2,
@@ -21220,12 +21280,12 @@ function TimelineGroupLaneLabels({
21220
21280
  }) {
21221
21281
  const currentTime = useLivePlayheadTime();
21222
21282
  const laneGroups = groupAutomationLanes([groupElement]);
21223
- return /* @__PURE__ */ jsx63(Fragment14, { children: laneGroups.map((laneGroup, index) => {
21283
+ return /* @__PURE__ */ jsx64(Fragment15, { children: laneGroups.map((laneGroup, index) => {
21224
21284
  const lane = laneGroup.entries[0]?.lane;
21225
21285
  if (!lane) return null;
21226
21286
  const parts = { name: laneGroup.name, param: laneGroup.param };
21227
21287
  const value = sampleAutomationLane7(lane, currentTime);
21228
- return /* @__PURE__ */ jsxs42(
21288
+ return /* @__PURE__ */ jsxs43(
21229
21289
  "button",
21230
21290
  {
21231
21291
  type: "button",
@@ -21247,7 +21307,7 @@ function TimelineGroupLaneLabels({
21247
21307
  onReveal?.(lane.target);
21248
21308
  },
21249
21309
  children: [
21250
- /* @__PURE__ */ jsx63(
21310
+ /* @__PURE__ */ jsx64(
21251
21311
  "span",
21252
21312
  {
21253
21313
  "aria-hidden": "true",
@@ -21255,11 +21315,11 @@ function TimelineGroupLaneLabels({
21255
21315
  children: "\u25A4"
21256
21316
  }
21257
21317
  ),
21258
- /* @__PURE__ */ jsxs42("span", { className: "flex min-w-0 flex-1 flex-col justify-center leading-tight", children: [
21259
- /* @__PURE__ */ jsx63("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-bright)]", children: parts.name }),
21260
- parts.param ? /* @__PURE__ */ jsx63("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-dim)]", children: parts.param }) : null
21318
+ /* @__PURE__ */ jsxs43("span", { className: "flex min-w-0 flex-1 flex-col justify-center leading-tight", children: [
21319
+ /* @__PURE__ */ jsx64("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-bright)]", children: parts.name }),
21320
+ parts.param ? /* @__PURE__ */ jsx64("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-dim)]", children: parts.param }) : null
21261
21321
  ] }),
21262
- /* @__PURE__ */ jsx63("span", { className: "shrink-0 font-mono text-[9px] tabular-nums text-[var(--timeline-handle)]", children: value.toFixed(2) })
21322
+ /* @__PURE__ */ jsx64("span", { className: "shrink-0 font-mono text-[9px] tabular-nums text-[var(--timeline-handle)]", children: value.toFixed(2) })
21263
21323
  ]
21264
21324
  },
21265
21325
  lane.target
@@ -21268,7 +21328,7 @@ function TimelineGroupLaneLabels({
21268
21328
  }
21269
21329
 
21270
21330
  // src/player/components/TimelineGroupRow.tsx
21271
- import { jsx as jsx64, jsxs as jsxs43 } from "react/jsx-runtime";
21331
+ import { jsx as jsx65, jsxs as jsxs44 } from "react/jsx-runtime";
21272
21332
  var GROUP_LANE_ACCENT = "var(--timeline-accent)";
21273
21333
  function TimelineGroupRow({
21274
21334
  index,
@@ -21316,7 +21376,7 @@ function TimelineGroupRow({
21316
21376
  })
21317
21377
  );
21318
21378
  };
21319
- return /* @__PURE__ */ jsxs43(
21379
+ return /* @__PURE__ */ jsxs44(
21320
21380
  TimelineTrackRow,
21321
21381
  {
21322
21382
  index,
@@ -21332,13 +21392,13 @@ function TimelineGroupRow({
21332
21392
  borderColor: theme.rowBorder,
21333
21393
  rovingTargetId,
21334
21394
  children: [
21335
- /* @__PURE__ */ jsxs43(
21395
+ /* @__PURE__ */ jsxs44(
21336
21396
  "div",
21337
21397
  {
21338
21398
  className: "sticky left-0 z-12 shrink-0",
21339
21399
  style: { width: contentOrigin >= LABEL_COL_W ? LABEL_COL_W : contentOrigin },
21340
21400
  children: [
21341
- /* @__PURE__ */ jsx64(
21401
+ /* @__PURE__ */ jsx65(
21342
21402
  TimelineGroupHeader,
21343
21403
  {
21344
21404
  label: group.label,
@@ -21357,7 +21417,7 @@ function TimelineGroupRow({
21357
21417
  theme
21358
21418
  }
21359
21419
  ),
21360
- isLaneOpen && /* @__PURE__ */ jsx64(
21420
+ isLaneOpen && /* @__PURE__ */ jsx65(
21361
21421
  TimelineGroupLaneLabels,
21362
21422
  {
21363
21423
  groupElement,
@@ -21376,14 +21436,14 @@ function TimelineGroupRow({
21376
21436
  // slot positions absolutely, so mounted straight on the row it resolved
21377
21437
  // against the row instead and drew the envelope across the label gutter
21378
21438
  // from x=0.
21379
- /* @__PURE__ */ jsx64(
21439
+ /* @__PURE__ */ jsx65(
21380
21440
  "div",
21381
21441
  {
21382
21442
  role: "gridcell",
21383
21443
  "aria-colindex": 2,
21384
21444
  style: { width: trackContentWidth, marginLeft: contentGutter },
21385
21445
  className: "relative",
21386
- children: /* @__PURE__ */ jsx64(
21446
+ children: /* @__PURE__ */ jsx65(
21387
21447
  TimelineAutomationLaneSlot,
21388
21448
  {
21389
21449
  elements: [groupElement],
@@ -23178,36 +23238,6 @@ function createClipGestureHandlers(el, elementKey3, previewElement, capabilities
23178
23238
  return { onResizeStart, onPointerDown, onClick };
23179
23239
  }
23180
23240
 
23181
- // src/player/components/timelineClipChildren.tsx
23182
- import { Fragment as Fragment15, jsx as jsx65, jsxs as jsxs44 } from "react/jsx-runtime";
23183
- function resolveClipRenderContext(element, visibleTimeRange, interactive) {
23184
- if (interactive) return { priority: "interaction", rich: false };
23185
- const visible = element.start < visibleTimeRange.end && element.start + element.duration > visibleTimeRange.start;
23186
- return { priority: visible ? "visible" : "overscan", rich: false };
23187
- }
23188
- function ClipLintDot({ element }) {
23189
- const lint = usePlayerStore((s) => s.lintFindingsByElement.get(element.key ?? element.id));
23190
- if (!lint || lint.count === 0) return null;
23191
- return /* @__PURE__ */ jsx65(
23192
- "span",
23193
- {
23194
- className: "absolute w-1.5 h-1.5 rounded-full bg-amber-400",
23195
- style: { top: 7, right: 7 },
23196
- title: lint.messages.join("\n")
23197
- }
23198
- );
23199
- }
23200
- function renderClipChildren(element, clipStyle, renderClipContent, renderClipOverlay, context = { priority: "visible", rich: false }) {
23201
- return /* @__PURE__ */ jsxs44(Fragment15, { children: [
23202
- renderClipOverlay?.(element),
23203
- !renderClipContent && /* @__PURE__ */ jsx65(ClipLintDot, { element }),
23204
- renderClipContent && // borderRadius: inherit — the clip itself is overflow-visible (keyframe
23205
- // diamonds hang outside its bounds), so the thumbnail layer must clip
23206
- // itself to the clip's rounded corners or sharp corners poke out.
23207
- /* @__PURE__ */ jsx65("div", { className: "absolute inset-0 overflow-hidden", style: { borderRadius: "inherit" }, children: renderClipContent(element, clipStyle, context) })
23208
- ] });
23209
- }
23210
-
23211
23241
  // src/player/components/useTimelineKeyboardActor.ts
23212
23242
  import { useCallback as useCallback29, useMemo as useMemo28 } from "react";
23213
23243
  function eventTarget(event) {
@@ -23416,8 +23446,7 @@ function TimelineClipJoins({
23416
23446
  // src/player/components/TimelineTransitionOverlays.tsx
23417
23447
  import { Fragment as Fragment16, jsx as jsx68, jsxs as jsxs46 } from "react/jsx-runtime";
23418
23448
  function TimelineTransitionOverlays({
23419
- transitionElements,
23420
- track: track2,
23449
+ seams,
23421
23450
  rowElements,
23422
23451
  rowBackground,
23423
23452
  pixelsPerSecond,
@@ -23425,9 +23454,6 @@ function TimelineTransitionOverlays({
23425
23454
  clipBarHeight
23426
23455
  }) {
23427
23456
  const top = CLIP_Y + (clipBarHeight ?? rowHeight - 2 * CLIP_Y) / 2;
23428
- const seams = deriveTimelineTransitionSeams(transitionElements).filter(
23429
- (seam) => seam.incoming.track === track2
23430
- );
23431
23457
  return /* @__PURE__ */ jsxs46(Fragment16, { children: [
23432
23458
  /* @__PURE__ */ jsx68(
23433
23459
  TimelineClipJoins,
@@ -23523,8 +23549,8 @@ function TimelineLanes({
23523
23549
  const expandedClipIds = usePlayerStore((s) => s.expandedClipIds);
23524
23550
  const { collapsedGroupIds, expandedLaneOwnerIds, toggleGroupExpanded, toggleLaneOwnerExpanded } = useTimelineGroupDisclosure();
23525
23551
  const automationLanes = useAutomationLanes();
23526
- const allTransitionElements = useMemo29(
23527
- () => tracks.flatMap(([, elements]) => elements.map(getPreviewElement)),
23552
+ const transitionSeamsByTrack = useMemo29(
23553
+ () => deriveTimelineTransitionSeamsByTrack(tracks.flatMap(([, els]) => els.map(getPreviewElement))),
23528
23554
  [getPreviewElement, tracks]
23529
23555
  );
23530
23556
  const compositionDuration = usePlayerStore((s) => s.duration);
@@ -23901,8 +23927,7 @@ function TimelineLanes({
23901
23927
  /* @__PURE__ */ jsx69(
23902
23928
  TimelineTransitionOverlays,
23903
23929
  {
23904
- transitionElements: allTransitionElements,
23905
- track: trackNum,
23930
+ seams: transitionSeamsByTrack.get(trackNum) ?? [],
23906
23931
  rowElements: draggedClip?.started ? [] : automationElements,
23907
23932
  rowBackground,
23908
23933
  pixelsPerSecond: pps,
@@ -24211,7 +24236,7 @@ var TimelineCanvas = memo13(function TimelineCanvas2() {
24211
24236
  import { useEffect as useEffect35 } from "react";
24212
24237
 
24213
24238
  // src/player/components/EditModal.tsx
24214
- import { useState as useState29, useCallback as useCallback30, useMemo as useMemo30, useRef as useRef45 } from "react";
24239
+ import { useState as useState30, useCallback as useCallback30, useMemo as useMemo30, useRef as useRef45 } from "react";
24215
24240
 
24216
24241
  // src/utils/clipboard.ts
24217
24242
  function copyWithSelection(text) {
@@ -24287,14 +24312,14 @@ function EditPopover({ rangeStart, rangeEnd, anchorX, anchorY, onClose }) {
24287
24312
  const start = Math.min(rangeStart, rangeEnd);
24288
24313
  const end = Math.max(rangeStart, rangeEnd);
24289
24314
  const storageKey = draftKey(start, end);
24290
- const [prompt, setPromptState] = useState29(() => readDraft(storageKey));
24315
+ const [prompt, setPromptState] = useState30(() => readDraft(storageKey));
24291
24316
  const setPrompt = (value) => {
24292
24317
  setPromptState(value);
24293
24318
  writeDraft(storageKey, value);
24294
24319
  };
24295
- const [copiedAgentPrompt, setCopiedAgentPrompt] = useState29(false);
24296
- const [copiedPromptOnly, setCopiedPromptOnly] = useState29(false);
24297
- const [copyError, setCopyError] = useState29(false);
24320
+ const [copiedAgentPrompt, setCopiedAgentPrompt] = useState30(false);
24321
+ const [copiedPromptOnly, setCopiedPromptOnly] = useState30(false);
24322
+ const [copyError, setCopyError] = useState30(false);
24298
24323
  const popoverRef = useRef45(null);
24299
24324
  const textareaRef = useRef45(null);
24300
24325
  const elementsInRange = useMemo30(() => {
@@ -24431,7 +24456,7 @@ function EditPopover({ rangeStart, rangeEnd, anchorX, anchorY, onClose }) {
24431
24456
  }
24432
24457
 
24433
24458
  // src/player/components/KeyframeDiamondContextMenu.tsx
24434
- import { useState as useState30 } from "react";
24459
+ import { useState as useState31 } from "react";
24435
24460
  import { createPortal as createPortal4 } from "react-dom";
24436
24461
 
24437
24462
  // src/player/components/menuKeyboardNav.ts
@@ -24492,7 +24517,7 @@ function KeyframeDiamondContextMenu({
24492
24517
  animationId: state.animationId
24493
24518
  };
24494
24519
  useMenuKeyboardNav(menuRef);
24495
- const [copyStatus, setCopyStatus] = useState30("idle");
24520
+ const [copyStatus, setCopyStatus] = useState31("idle");
24496
24521
  const handleCopyProperties = async () => {
24497
24522
  if (!onCopyProperties) return;
24498
24523
  const result = await onCopyProperties(state.elementId, keyframe);
@@ -25203,7 +25228,7 @@ var Timeline = Object.assign(TimelineComposed, {
25203
25228
  });
25204
25229
 
25205
25230
  // src/player/components/VideoThumbnail.tsx
25206
- import { memo as memo17, useCallback as useCallback32, useMemo as useMemo31, useRef as useRef47, useState as useState31 } from "react";
25231
+ import { memo as memo17, useCallback as useCallback32, useMemo as useMemo31, useRef as useRef47, useState as useState32 } from "react";
25207
25232
 
25208
25233
  // src/hooks/useThumbnailLease.ts
25209
25234
  import { useCallback as useCallback31, useLayoutEffect as useLayoutEffect5, useRef as useRef46, useSyncExternalStore as useSyncExternalStore2 } from "react";
@@ -25241,6 +25266,7 @@ var ThumbnailScheduler = class {
25241
25266
  nextLeaseId = 1;
25242
25267
  nextSequence = 1;
25243
25268
  scrolling = false;
25269
+ previewReloading = false;
25244
25270
  cacheBytes = 0;
25245
25271
  waveformCacheBytes = 0;
25246
25272
  activeByBucket = { video: 0, composition: 0, general: 0 };
@@ -25274,7 +25300,8 @@ var ThumbnailScheduler = class {
25274
25300
  disposed: false,
25275
25301
  cached: false,
25276
25302
  lastAccess: this.nextSequence++,
25277
- snapshot: Object.freeze({ status: "queued" })
25303
+ snapshot: Object.freeze({ status: "queued" }),
25304
+ preempted: false
25278
25305
  };
25279
25306
  this.entries.set(scopedKey, entry2);
25280
25307
  }
@@ -25323,6 +25350,23 @@ var ThumbnailScheduler = class {
25323
25350
  this.scrolling = scrolling;
25324
25351
  if (!scrolling) this.pump();
25325
25352
  }
25353
+ /**
25354
+ * Hold server-rendered composition thumbnails while the preview loads a new document: both
25355
+ * are served by the same Studio server, and the preview is what the person is waiting for.
25356
+ */
25357
+ setPreviewReloading(reloading) {
25358
+ if (this.previewReloading === reloading) return;
25359
+ this.previewReloading = reloading;
25360
+ if (!reloading) {
25361
+ this.pump();
25362
+ return;
25363
+ }
25364
+ for (const entry2 of this.entries.values()) {
25365
+ if (entry2.state !== "loading" || entry2.request.kind !== "composition") continue;
25366
+ entry2.preempted = true;
25367
+ entry2.controller?.abort();
25368
+ }
25369
+ }
25326
25370
  /** Evict project cache entries that are no longer owned by mounted consumers. */
25327
25371
  invalidateProject(projectId) {
25328
25372
  for (const [key2, entry2] of this.entries) {
@@ -25365,6 +25409,7 @@ var ThumbnailScheduler = class {
25365
25409
  });
25366
25410
  for (const entry2 of queued) {
25367
25411
  if (this.scrolling && entry2.request.rich) continue;
25412
+ if (this.previewReloading && entry2.request.kind === "composition") continue;
25368
25413
  const bucket = concurrencyBucket(entry2.request.kind);
25369
25414
  if (this.activeByBucket[bucket] >= this.bucketLimit(bucket)) continue;
25370
25415
  this.start(entry2, bucket);
@@ -25385,6 +25430,7 @@ var ThumbnailScheduler = class {
25385
25430
  this.deleteEntry(entry2.scopedKey, entry2);
25386
25431
  return;
25387
25432
  }
25433
+ if (this.requeuePreempted(entry2)) return;
25388
25434
  entry2.state = "error";
25389
25435
  entry2.error = errorFrom(reason);
25390
25436
  entry2.failedAt = this.now();
@@ -25401,6 +25447,7 @@ var ThumbnailScheduler = class {
25401
25447
  acceptResult(entry2, controller, result) {
25402
25448
  if (controller.signal.aborted || this.entries.get(entry2.scopedKey) !== entry2) {
25403
25449
  this.safeDispose(result.dispose);
25450
+ this.requeuePreempted(entry2);
25404
25451
  return;
25405
25452
  }
25406
25453
  this.validateResult(result);
@@ -25414,6 +25461,14 @@ var ThumbnailScheduler = class {
25414
25461
  this.evict();
25415
25462
  if (!entry2.cached && entry2.leases.size === 0) this.deleteEntry(entry2.scopedKey, entry2);
25416
25463
  }
25464
+ requeuePreempted(entry2) {
25465
+ if (!entry2.preempted || this.entries.get(entry2.scopedKey) !== entry2) return false;
25466
+ entry2.preempted = false;
25467
+ entry2.state = "queued";
25468
+ entry2.snapshot = Object.freeze({ status: "queued" });
25469
+ this.notify(entry2);
25470
+ return true;
25471
+ }
25417
25472
  validateResult(result) {
25418
25473
  if (Number.isFinite(result.weight) && result.weight >= 0) return;
25419
25474
  this.safeDispose(result.dispose);
@@ -25824,7 +25879,7 @@ var VideoThumbnail = memo17(function VideoThumbnail2({
25824
25879
  sessionEpoch = 0,
25825
25880
  priority = "visible"
25826
25881
  }) {
25827
- const [containerWidth, setContainerWidth] = useState31(0);
25882
+ const [containerWidth, setContainerWidth] = useState32(0);
25828
25883
  const observerRef = useRef47(null);
25829
25884
  const requestFrameCount = quantizeThumbnailFrameCount(
25830
25885
  computeThumbnailStrip(containerWidth, 16 / 9).frameCount
@@ -25924,7 +25979,7 @@ var VideoThumbnail = memo17(function VideoThumbnail2({
25924
25979
  });
25925
25980
 
25926
25981
  // src/player/components/CompositionThumbnail.tsx
25927
- import { memo as memo18, useCallback as useCallback33, useMemo as useMemo32, useRef as useRef48, useState as useState32 } from "react";
25982
+ import { memo as memo18, useCallback as useCallback33, useMemo as useMemo32, useRef as useRef48, useState as useState33 } from "react";
25928
25983
  import { jsx as jsx82, jsxs as jsxs58 } from "react/jsx-runtime";
25929
25984
  var CLIP_HEIGHT = 66;
25930
25985
  var THUMBNAIL_URL_VERSION = "v3";
@@ -25952,6 +26007,10 @@ function buildCompositionThumbnailUrl({
25952
26007
  }
25953
26008
  return thumbnailUrl2.toString();
25954
26009
  }
26010
+ function compositionPathOfPreviewUrl(previewUrl) {
26011
+ const match = /\/preview\/comp\/([^?#]+)/.exec(previewUrl);
26012
+ return match?.[1] ? decodeURIComponent(match[1]) : "index.html";
26013
+ }
25955
26014
  async function loadCompositionImage(url, signal) {
25956
26015
  const response = await fetch(url, { signal });
25957
26016
  if (!response.ok) throw new Error(`Composition thumbnail failed (${response.status})`);
@@ -25983,7 +26042,7 @@ var CompositionThumbnail = memo18(function CompositionThumbnail2({
25983
26042
  contentRevision = 0,
25984
26043
  priority = "visible"
25985
26044
  }) {
25986
- const [containerWidth, setContainerWidth] = useState32(0);
26045
+ const [containerWidth, setContainerWidth] = useState33(0);
25987
26046
  const observerRef = useRef48(null);
25988
26047
  const url = buildCompositionThumbnailUrl({
25989
26048
  previewUrl,
@@ -27739,7 +27798,7 @@ function useTimelineSyncCallbacks({
27739
27798
  }
27740
27799
 
27741
27800
  // src/player/hooks/useShadowPreviewReload.ts
27742
- import { useCallback as useCallback36, useRef as useRef51, useState as useState33 } from "react";
27801
+ import { useCallback as useCallback36, useRef as useRef51, useState as useState34 } from "react";
27743
27802
 
27744
27803
  // src/utils/studioDebug.ts
27745
27804
  function makeStudioDebugLogger(name) {
@@ -27797,7 +27856,7 @@ function useShadowPreviewReload({
27797
27856
  const budgetGenRef = useRef51(null);
27798
27857
  const cancelPendingLoadRef = useRef51(() => {
27799
27858
  });
27800
- const [previewSlots, setPreviewSlots] = useState33([{ gen: 0, role: "live" }]);
27859
+ const [previewSlots, setPreviewSlots] = useState34([{ gen: 0, role: "live" }]);
27801
27860
  const stopPendingShadow = useCallback36(() => {
27802
27861
  clearTimeout(readyTimerRef.current);
27803
27862
  budgetGenRef.current = null;
@@ -27814,6 +27873,7 @@ function useShadowPreviewReload({
27814
27873
  isRefreshingRef.current = false;
27815
27874
  pendingSeekRef.current = null;
27816
27875
  setPreviewSlots(planShadowDiscard);
27876
+ thumbnailScheduler.setPreviewReloading(false);
27817
27877
  const message = `The preview did not reload (${cause}). The previous preview is still showing.`;
27818
27878
  logReload("shadow-failed", { cause });
27819
27879
  console.error(`[studio] ${message}`);
@@ -27835,6 +27895,7 @@ function useShadowPreviewReload({
27835
27895
  applyPreviewAudioState();
27836
27896
  setPreviewSlots((prev) => planShadowPromotion(prev, gen));
27837
27897
  onPromotedRef.current?.();
27898
+ thumbnailScheduler.setPreviewReloading(false);
27838
27899
  },
27839
27900
  [stopPendingShadow, iframeRef, attachIframeShortcutListeners, applyPreviewAudioState]
27840
27901
  );
@@ -27900,6 +27961,7 @@ function useShadowPreviewReload({
27900
27961
  budgetGenRef.current = gen;
27901
27962
  armReadyTimer(gen);
27902
27963
  setPreviewSlots((prev) => planShadowReload(prev, gen, url));
27964
+ thumbnailScheduler.setPreviewReloading(true);
27903
27965
  },
27904
27966
  [stopPendingShadow, armReadyTimer]
27905
27967
  );
@@ -27910,6 +27972,7 @@ function useShadowPreviewReload({
27910
27972
  isRefreshingRef.current = false;
27911
27973
  pendingSeekRef.current = null;
27912
27974
  setPreviewSlots(planShadowDiscard);
27975
+ thumbnailScheduler.setPreviewReloading(false);
27913
27976
  }, [stopPendingShadow, isRefreshingRef, pendingSeekRef]);
27914
27977
  useMountEffect(() => {
27915
27978
  const onVisibilityChange = () => {
@@ -27924,6 +27987,7 @@ function useShadowPreviewReload({
27924
27987
  return () => {
27925
27988
  document.removeEventListener("visibilitychange", onVisibilityChange);
27926
27989
  stopPendingShadow();
27990
+ thumbnailScheduler.setPreviewReloading(false);
27927
27991
  };
27928
27992
  });
27929
27993
  return {
@@ -28794,16 +28858,16 @@ function useTimelinePlayer({
28794
28858
  import { useCallback as useCallback41, useMemo as useMemo33 } from "react";
28795
28859
 
28796
28860
  // src/components/nle/NLEContext.tsx
28797
- import { useContext as useContext8, useState as useState35, useCallback as useCallback40, useRef as useRef54, useEffect as useEffect38 } from "react";
28861
+ import { useContext as useContext8, useState as useState36, useCallback as useCallback40, useRef as useRef54, useEffect as useEffect38 } from "react";
28798
28862
 
28799
28863
  // src/components/nle/useCompositionStack.ts
28800
- import { useState as useState34, useCallback as useCallback39, useRef as useRef53, useEffect as useEffect37 } from "react";
28864
+ import { useState as useState35, useCallback as useCallback39, useRef as useRef53, useEffect as useEffect37 } from "react";
28801
28865
  function useCompositionStack({
28802
28866
  projectId,
28803
28867
  activeCompositionPath,
28804
28868
  onCompositionChange
28805
28869
  }) {
28806
- const [compositionStack, setCompositionStack] = useState34([
28870
+ const [compositionStack, setCompositionStack] = useState35([
28807
28871
  {
28808
28872
  id: "master",
28809
28873
  label: "Master",
@@ -28821,7 +28885,7 @@ function useCompositionStack({
28821
28885
  });
28822
28886
  }, []);
28823
28887
  const masterSeekRef = useRef53(0);
28824
- const [compIdToSrc, setCompIdToSrc] = useState34(/* @__PURE__ */ new Map());
28888
+ const [compIdToSrc, setCompIdToSrc] = useState35(/* @__PURE__ */ new Map());
28825
28889
  const compIdToSrcRef = useRef53(compIdToSrc);
28826
28890
  compIdToSrcRef.current = compIdToSrc;
28827
28891
  const handleNavigateComposition = useCallback39(
@@ -28955,7 +29019,7 @@ function NLEProvider({
28955
29019
  usePlayerStore.getState().beginTimelineSession(projectId);
28956
29020
  useAssetPreviewStore.getState().clearPreviewAsset();
28957
29021
  }, [projectId]);
28958
- const [previewCompositionSize, setPreviewCompositionSize] = useState35(null);
29022
+ const [previewCompositionSize, setPreviewCompositionSize] = useState36(null);
28959
29023
  const prevRefreshKeyRef = useRef54(refreshKey);
28960
29024
  useEffect38(() => {
28961
29025
  if (refreshKey === prevRefreshKeyRef.current) return;
@@ -29081,7 +29145,7 @@ function NLEProvider({
29081
29145
  });
29082
29146
  }, [compIdToSrc]);
29083
29147
  const hasLoadedOnceRef = useRef54(false);
29084
- const [compositionLoading, setCompositionLoadingRaw] = useState35(true);
29148
+ const [compositionLoading, setCompositionLoadingRaw] = useState36(true);
29085
29149
  const setCompositionLoading = useCallback40((loading) => {
29086
29150
  if (!loading) hasLoadedOnceRef.current = true;
29087
29151
  if (loading && hasLoadedOnceRef.current) return;
@@ -29200,7 +29264,7 @@ function readPreviewCompositionSize(iframe) {
29200
29264
  }
29201
29265
 
29202
29266
  // src/components/nle/NLEPreview.tsx
29203
- import { memo as memo19, useCallback as useCallback43, useEffect as useEffect39, useRef as useRef56, useState as useState36 } from "react";
29267
+ import { memo as memo19, useCallback as useCallback43, useEffect as useEffect39, useRef as useRef56, useState as useState37 } from "react";
29204
29268
 
29205
29269
  // src/components/nle/previewZoom.ts
29206
29270
  var MIN_PREVIEW_ZOOM_PERCENT = 25;
@@ -29434,11 +29498,11 @@ var NLEPreview = memo19(function NLEPreview2({
29434
29498
  }, [activeKey, resetPreviewSlots]);
29435
29499
  const liveGenRef = useRef56(null);
29436
29500
  const reportPreviewFirstFrame = usePreviewFirstFrameTelemetry(previewSlots);
29437
- const [compositionSize, setCompositionSize] = useState36(null);
29501
+ const [compositionSize, setCompositionSize] = useState37(null);
29438
29502
  const gutterPx = usePreviewGuidesStore((s) => s.rulerVisible ? RULER_GUTTER_PX : 0);
29439
- const [stageSize, setStageSize] = useState36(() => resolvePreviewStageSize(0, 0, null, portrait));
29503
+ const [stageSize, setStageSize] = useState37(() => resolvePreviewStageSize(0, 0, null, portrait));
29440
29504
  const zoomRef = useRef56(loadInitialZoom());
29441
- const [settledZoom, setSettledZoom] = useState36(() => zoomRef.current);
29505
+ const [settledZoom, setSettledZoom] = useState37(() => zoomRef.current);
29442
29506
  const hudRef = useRef56(null);
29443
29507
  const hudTimerRef = useRef56(null);
29444
29508
  const settleTimerRef = useRef56(null);
@@ -29840,7 +29904,7 @@ function CompositionBreadcrumb({ stack, onNavigate }) {
29840
29904
  }
29841
29905
 
29842
29906
  // src/components/nle/usePreviewBlockDrop.ts
29843
- import { useCallback as useCallback44, useRef as useRef57, useState as useState37 } from "react";
29907
+ import { useCallback as useCallback44, useRef as useRef57, useState as useState38 } from "react";
29844
29908
 
29845
29909
  // src/components/editor/previewReadOnlyContext.tsx
29846
29910
  import { useContext as useContext9, useMemo as useMemo34 } from "react";
@@ -29908,7 +29972,7 @@ function usePreviewBlockDrop({
29908
29972
  onBlockDrop: onBlockDropProp
29909
29973
  }) {
29910
29974
  const onBlockDrop = usePreviewReadOnly() ? void 0 : onBlockDropProp;
29911
- const [isDragOver, setIsDragOver] = useState37(false);
29975
+ const [isDragOver, setIsDragOver] = useState38(false);
29912
29976
  const dragDepthRef = useRef57(0);
29913
29977
  const handleDragEnter = useCallback44(
29914
29978
  (e) => {
@@ -30111,7 +30175,7 @@ function AssetPreviewOverlay() {
30111
30175
  import { memo as memo20, useRef as useRef60 } from "react";
30112
30176
 
30113
30177
  // src/components/editor/useDomEditCompositionRect.ts
30114
- import { useState as useState38 } from "react";
30178
+ import { useState as useState39 } from "react";
30115
30179
 
30116
30180
  // src/components/editor/overlayFrameLoop.ts
30117
30181
  var AWAKE_MS = 400;
@@ -30239,7 +30303,7 @@ function useDomEditCompositionRect({
30239
30303
  iframeRef,
30240
30304
  overlayRef
30241
30305
  }) {
30242
- const [compRect, setCompRect] = useState38({
30306
+ const [compRect, setCompRect] = useState39({
30243
30307
  left: 0,
30244
30308
  top: 0,
30245
30309
  width: 0,
@@ -30280,7 +30344,7 @@ function safeBoxInsetPercent(boxPercent) {
30280
30344
  }
30281
30345
 
30282
30346
  // src/components/editor/PreviewOverlayProvider.tsx
30283
- import { createContext as createContext4, useContext as useContext10, useRef as useRef59, useState as useState39 } from "react";
30347
+ import { createContext as createContext4, useContext as useContext10, useRef as useRef59, useState as useState40 } from "react";
30284
30348
 
30285
30349
  // src/components/editor/usePreviewCompositionRect.ts
30286
30350
  import { useEffect as useEffect41, useRef as useRef58 } from "react";
@@ -30322,7 +30386,7 @@ function readSnapPrefs() {
30322
30386
  }
30323
30387
  function PreviewOverlayProvider({ iframe, children }) {
30324
30388
  const overlayRef = useRef59(null);
30325
- const [snapPrefs, setSnapPrefs] = useState39(readSnapPrefs);
30389
+ const [snapPrefs, setSnapPrefs] = useState40(readSnapPrefs);
30326
30390
  const rulerVisible = usePreviewGuidesStore((state) => state.rulerVisible);
30327
30391
  const safeMarginsVisible = usePreviewGuidesStore((state) => state.safeMarginsVisible);
30328
30392
  const liveIframe = useLivePreviewIframe();
@@ -31100,7 +31164,7 @@ function TimelinePane({
31100
31164
  import { useCallback as useCallback59 } from "react";
31101
31165
 
31102
31166
  // src/captions/components/CaptionOverlay.tsx
31103
- import { memo as memo22, useEffect as useEffect43, useState as useState40, useCallback as useCallback48, useRef as useRef63 } from "react";
31167
+ import { memo as memo22, useEffect as useEffect43, useState as useState41, useCallback as useCallback48, useRef as useRef63 } from "react";
31104
31168
 
31105
31169
  // src/captions/keyboard.ts
31106
31170
  var CAPTION_NUDGE_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]);
@@ -31325,7 +31389,7 @@ var CaptionOverlay = memo22(function CaptionOverlay2({ iframeRef }) {
31325
31389
  const selectedSegmentIds = useCaptionStore((s) => s.selectedSegmentIds);
31326
31390
  const selectSegment = useCaptionStore((s) => s.selectSegment);
31327
31391
  const clearSelection = useCaptionStore((s) => s.clearSelection);
31328
- const [wordBoxes, setWordBoxes] = useState40([]);
31392
+ const [wordBoxes, setWordBoxes] = useState41([]);
31329
31393
  const overlayRef = useRef63(null);
31330
31394
  const modelRef = useRef63(model);
31331
31395
  modelRef.current = model;
@@ -31733,7 +31797,7 @@ var CaptionOverlay = memo22(function CaptionOverlay2({ iframeRef }) {
31733
31797
  import { memo as memo25, useEffect as useEffect51, useMemo as useMemo37, useRef as useRef73 } from "react";
31734
31798
 
31735
31799
  // src/components/editor/marqueeCommit.ts
31736
- import { useCallback as useCallback49, useRef as useRef64, useState as useState41 } from "react";
31800
+ import { useCallback as useCallback49, useRef as useRef64, useState as useState42 } from "react";
31737
31801
 
31738
31802
  // src/utils/studioPreviewHelpers.ts
31739
31803
  var FULL_BLEED_RATIO = 0.95;
@@ -32771,8 +32835,8 @@ async function runMarqueeIntersection(rect, candidates, activeCompositionPath) {
32771
32835
  }
32772
32836
  function useMarqueeGestures(deps) {
32773
32837
  const marqueeRef = useRef64(null);
32774
- const [marqueeRect, setMarqueeRect] = useState41(null);
32775
- const [candidateRects, setCandidateRects] = useState41([]);
32838
+ const [marqueeRect, setMarqueeRect] = useState42(null);
32839
+ const [candidateRects, setCandidateRects] = useState42([]);
32776
32840
  const candidatesRef = useRef64(null);
32777
32841
  const commitMarquee = useCallback49(
32778
32842
  async (rect, additive) => {
@@ -32895,11 +32959,11 @@ function MarqueeOverlay({ candidateRects, marqueeRect }) {
32895
32959
  }
32896
32960
 
32897
32961
  // src/components/editor/useZOrderCrossedFlash.tsx
32898
- import { useCallback as useCallback50, useEffect as useEffect44, useRef as useRef65, useState as useState42 } from "react";
32962
+ import { useCallback as useCallback50, useEffect as useEffect44, useRef as useRef65, useState as useState43 } from "react";
32899
32963
  import { jsx as jsx95 } from "react/jsx-runtime";
32900
32964
  var Z_ORDER_CROSSED_FLASH_MS = 600;
32901
32965
  function useZOrderCrossedFlash({ overlayRef, iframeRef }) {
32902
- const [zOrderFlashRect, setZOrderFlashRect] = useState42(null);
32966
+ const [zOrderFlashRect, setZOrderFlashRect] = useState43(null);
32903
32967
  const timeoutRef = useRef65(null);
32904
32968
  useEffect44(
32905
32969
  () => () => {
@@ -32939,7 +33003,7 @@ function ZOrderCrossedFlash({ rect }) {
32939
33003
  }
32940
33004
 
32941
33005
  // src/components/editor/useCanvasContextMenuState.ts
32942
- import { useCallback as useCallback51, useEffect as useEffect45, useState as useState43 } from "react";
33006
+ import { useCallback as useCallback51, useEffect as useEffect45, useState as useState44 } from "react";
32943
33007
  function useCanvasContextMenuState({
32944
33008
  selection,
32945
33009
  selectionRef,
@@ -32947,7 +33011,7 @@ function useCanvasContextMenuState({
32947
33011
  onCanvasPointerMoveRef,
32948
33012
  onSelectionChangeRef
32949
33013
  }) {
32950
- const [contextMenu, setContextMenu] = useState43(null);
33014
+ const [contextMenu, setContextMenu] = useState44(null);
32951
33015
  const closeContextMenu = useCallback51(() => setContextMenu(null), []);
32952
33016
  useEffect45(() => {
32953
33017
  if (!contextMenu) return;
@@ -33039,7 +33103,7 @@ function hasDomEditRotationChanged(initialAngle, nextAngle) {
33039
33103
  }
33040
33104
 
33041
33105
  // src/components/editor/useDomEditOverlayRects.ts
33042
- import { useRef as useRef66, useState as useState44 } from "react";
33106
+ import { useRef as useRef66, useState as useState45 } from "react";
33043
33107
  function childRectsEqual(a, b) {
33044
33108
  if (a.length !== b.length) return false;
33045
33109
  for (let i = 0; i < a.length; i++) {
@@ -33056,10 +33120,10 @@ function useDomEditOverlayRects({
33056
33120
  hoverSelectionRef,
33057
33121
  rafPausedRef
33058
33122
  }) {
33059
- const [overlayRect, setOverlayRectState] = useState44(null);
33060
- const [hoverRect, setHoverRectState] = useState44(null);
33061
- const [groupOverlayItems, setGroupOverlayItemsState] = useState44([]);
33062
- const [childRects, setChildRectsState] = useState44([]);
33123
+ const [overlayRect, setOverlayRectState] = useState45(null);
33124
+ const [hoverRect, setHoverRectState] = useState45(null);
33125
+ const [groupOverlayItems, setGroupOverlayItemsState] = useState45([]);
33126
+ const [childRects, setChildRectsState] = useState45([]);
33063
33127
  const overlayRectRef = useRef66(null);
33064
33128
  const hoverRectRef = useRef66(null);
33065
33129
  const groupOverlayItemsRef = useRef66([]);
@@ -33396,16 +33460,22 @@ function roundRotationAngle(angle) {
33396
33460
  function normalizeStudioFileChangePath(path) {
33397
33461
  return path.trim().replace(/\\/g, "/").replace(/^\.?\//, "");
33398
33462
  }
33463
+ function asPayloadRecord(payload) {
33464
+ return payload && typeof payload === "object" ? payload : null;
33465
+ }
33399
33466
  function readFileChangeField(payload, key2) {
33400
- if (!payload || typeof payload !== "object") return null;
33401
- const record = payload;
33402
- const value = record[key2];
33467
+ const value = asPayloadRecord(payload)?.[key2];
33403
33468
  return typeof value === "string" ? value : null;
33404
33469
  }
33405
33470
  function readStudioFileChangePath(payload) {
33406
33471
  const path = readFileChangeField(payload, "path") ?? readFileChangeField(payload, "filePath");
33407
33472
  return path === null ? null : normalizeStudioFileChangePath(path);
33408
33473
  }
33474
+ function readFileChangeAffectedCompositions(payload) {
33475
+ const value = asPayloadRecord(payload)?.affectedCompositions;
33476
+ if (!Array.isArray(value) || !value.every((path) => typeof path === "string")) return null;
33477
+ return value.map(normalizeStudioFileChangePath);
33478
+ }
33409
33479
 
33410
33480
  // src/components/editor/gsapAnimatesProperty.ts
33411
33481
  function gsapAnimatesProperty(el, ...props) {
@@ -36263,7 +36333,7 @@ var SnapGuideOverlay = memo23(function SnapGuideOverlay2({
36263
36333
  });
36264
36334
 
36265
36335
  // src/components/editor/DomEditCropHandles.tsx
36266
- import { useEffect as useEffect47, useRef as useRef69, useState as useState45 } from "react";
36336
+ import { useEffect as useEffect47, useRef as useRef69, useState as useState46 } from "react";
36267
36337
  import { Fragment as Fragment25, jsx as jsx98, jsxs as jsxs69 } from "react/jsx-runtime";
36268
36338
  var EDGE_HIT_THICKNESS = 12;
36269
36339
  var EDGE_HIT_LENGTH = 32;
@@ -36297,14 +36367,14 @@ function DomEditCropHandles({
36297
36367
  onStyleCommit
36298
36368
  }) {
36299
36369
  const gestureRef = useRef69(null);
36300
- const [dragging, setDragging] = useState45(false);
36301
- const [hotEdge, setHotEdge] = useState45(null);
36370
+ const [dragging, setDragging] = useState46(false);
36371
+ const [hotEdge, setHotEdge] = useState46(null);
36302
36372
  const cropStateFor = (element) => {
36303
36373
  const parsed = readElementCropInsets(element);
36304
36374
  const { radius, ...insets } = parsed ?? { top: 0, right: 0, bottom: 0, left: 0, radius: 0 };
36305
36375
  return { element, croppable: parsed !== null, insets, radius };
36306
36376
  };
36307
- const [state, setState] = useState45(() => cropStateFor(selection.element));
36377
+ const [state, setState] = useState46(() => cropStateFor(selection.element));
36308
36378
  if (state.element !== selection.element) {
36309
36379
  setState(cropStateFor(selection.element));
36310
36380
  }
@@ -36982,7 +37052,7 @@ var CanvasContextMenu = memo24(function CanvasContextMenu2({
36982
37052
  import { useRef as useRef71 } from "react";
36983
37053
 
36984
37054
  // src/components/editor/InlineTextToolbar.tsx
36985
- import { useCallback as useCallback53, useEffect as useEffect48, useState as useState46 } from "react";
37055
+ import { useCallback as useCallback53, useEffect as useEffect48, useState as useState47 } from "react";
36986
37056
 
36987
37057
  // src/components/editor/inlineTextStyleRange.ts
36988
37058
  import {
@@ -37483,7 +37553,7 @@ function InlineTextToolbar({
37483
37553
  session,
37484
37554
  iframe
37485
37555
  }) {
37486
- const [placement, setPlacement] = useState46(null);
37556
+ const [placement, setPlacement] = useState47(null);
37487
37557
  const refresh = useCallback53(() => {
37488
37558
  setPlacement(session && iframe ? placeOverSelection(session.element, iframe) : null);
37489
37559
  }, [session, iframe]);
@@ -37673,7 +37743,7 @@ function toPickerColour(value, doc) {
37673
37743
  }
37674
37744
 
37675
37745
  // src/hooks/useInlineTextEdit.ts
37676
- import { useCallback as useCallback54, useEffect as useEffect49, useRef as useRef70, useState as useState47 } from "react";
37746
+ import { useCallback as useCallback54, useEffect as useEffect49, useRef as useRef70, useState as useState48 } from "react";
37677
37747
  import { sanitizeRichTextChildren } from "@hyperframes/core/rich-text-sanitize";
37678
37748
  var EDITABLE = "true";
37679
37749
  var EDITING_OUTLINE = "2px solid #3CE6AC";
@@ -37689,7 +37759,7 @@ function useInlineTextEdit({
37689
37759
  onPause
37690
37760
  }) {
37691
37761
  const readOnly = usePreviewReadOnly();
37692
- const [session, setSession] = useState47(null);
37762
+ const [session, setSession] = useState48(null);
37693
37763
  const openRef = useRef70(null);
37694
37764
  const framesRef = useRef70(null);
37695
37765
  const teardown = useCallback54(() => {
@@ -37939,7 +38009,7 @@ function useInlineTextEditing(selectionRef) {
37939
38009
  }
37940
38010
 
37941
38011
  // src/components/editor/useOffCanvasIndicators.ts
37942
- import { useEffect as useEffect50, useRef as useRef72, useState as useState48 } from "react";
38012
+ import { useEffect as useEffect50, useRef as useRef72, useState as useState49 } from "react";
37943
38013
 
37944
38014
  // src/components/editor/offCanvasIndicatorGeometry.ts
37945
38015
  function rounded(value) {
@@ -38096,7 +38166,7 @@ function useOffCanvasIndicators({
38096
38166
  activeCompositionPath
38097
38167
  }) {
38098
38168
  const offCanvasElementsRef = useRef72(/* @__PURE__ */ new Map());
38099
- const [offCanvasRects, setOffCanvasRects] = useState48([]);
38169
+ const [offCanvasRects, setOffCanvasRects] = useState49([]);
38100
38170
  const offCanvasDirtyRef = useRef72(true);
38101
38171
  const offCanvasSigRef = useRef72("");
38102
38172
  const offCanvasObserverRef = useRef72(null);
@@ -38512,7 +38582,7 @@ import {
38512
38582
  useLayoutEffect as useLayoutEffect6,
38513
38583
  useReducer,
38514
38584
  useRef as useRef74,
38515
- useState as useState49,
38585
+ useState as useState50,
38516
38586
  useSyncExternalStore as useSyncExternalStore4
38517
38587
  } from "react";
38518
38588
 
@@ -39347,7 +39417,7 @@ function TopologyLens({ iframeRef, activeCompositionPath }) {
39347
39417
  const overlayRef = useRef74(null);
39348
39418
  const state = useTopologyLensState();
39349
39419
  const reducedMotion = useSyncExternalStore4(subscribeReducedMotion, getReducedMotion, () => false);
39350
- const [measured, setMeasured] = useState49(null);
39420
+ const [measured, setMeasured] = useState50(null);
39351
39421
  const callId = state.phase === "hidden" ? null : state.callId;
39352
39422
  const handle = state.phase === "hidden" ? null : state.target.handle;
39353
39423
  const phase = state.phase;
@@ -39624,7 +39694,7 @@ function writeKeyframeCache(sourceFile, elementId2, data) {
39624
39694
  }
39625
39695
 
39626
39696
  // src/components/editor/MotionPathOverlay.tsx
39627
- import { memo as memo26, useEffect as useEffect54, useRef as useRef76, useState as useState51 } from "react";
39697
+ import { memo as memo26, useEffect as useEffect54, useRef as useRef76, useState as useState52 } from "react";
39628
39698
 
39629
39699
  // src/hooks/gestureTransaction.ts
39630
39700
  var transactionCounter = 0;
@@ -40355,7 +40425,7 @@ function commitCreatePath(targetSelector, position, x, y, commit) {
40355
40425
  }
40356
40426
 
40357
40427
  // src/components/editor/useMotionPathData.ts
40358
- import { useEffect as useEffect53, useRef as useRef75, useState as useState50 } from "react";
40428
+ import { useEffect as useEffect53, useRef as useRef75, useState as useState51 } from "react";
40359
40429
 
40360
40430
  // src/hooks/gsapRuntimeKeyframes.ts
40361
40431
  import { buildArcPath } from "@hyperframes/core/gsap-parser-acorn";
@@ -40662,13 +40732,13 @@ function hasMotionPathPlugin(iframe) {
40662
40732
  }
40663
40733
  }
40664
40734
  function useMotionPathData(iframeRef, selector) {
40665
- const [rect, setRect] = useState50(null);
40666
- const [geometry, setGeometry] = useState50(null);
40735
+ const [rect, setRect] = useState51(null);
40736
+ const [geometry, setGeometry] = useState51(null);
40667
40737
  const resolvedForRef = useRef75(null);
40668
40738
  const geometryResolved = resolvedForRef.current === selector;
40669
- const [visibleInPreview, setVisibleInPreview] = useState50(true);
40670
- const [home, setHome] = useState50(null);
40671
- const [pScale, setPScale] = useState50(1);
40739
+ const [visibleInPreview, setVisibleInPreview] = useState51(true);
40740
+ const [home, setHome] = useState51(null);
40741
+ const [pScale, setPScale] = useState51(1);
40672
40742
  useEffect53(() => {
40673
40743
  if (!selector) {
40674
40744
  setRect(null);
@@ -40754,10 +40824,10 @@ var MotionPathOverlay = memo26(function MotionPathOverlay2({
40754
40824
  iframeRef,
40755
40825
  selectorFor(selection)
40756
40826
  );
40757
- const [draft, setDraft] = useState51(null);
40758
- const [ghost, setGhost] = useState51(null);
40759
- const [hoverNode, setHoverNode] = useState51(null);
40760
- const [kfMenu, setKfMenu] = useState51(null);
40827
+ const [draft, setDraft] = useState52(null);
40828
+ const [ghost, setGhost] = useState52(null);
40829
+ const [hoverNode, setHoverNode] = useState52(null);
40830
+ const [kfMenu, setKfMenu] = useState52(null);
40761
40831
  const activeKeyframePct = usePlayerStore((s) => s.activeKeyframePct);
40762
40832
  const timelineElement = usePlayerStore((state) => {
40763
40833
  if (!selection) return void 0;
@@ -41111,11 +41181,11 @@ var MotionPathOverlay = memo26(function MotionPathOverlay2({
41111
41181
  });
41112
41182
 
41113
41183
  // src/components/editor/SnapToolbar.tsx
41114
- import { memo as memo27, useCallback as useCallback55, useEffect as useEffect55, useRef as useRef77, useState as useState52 } from "react";
41184
+ import { memo as memo27, useCallback as useCallback55, useEffect as useEffect55, useRef as useRef77, useState as useState53 } from "react";
41115
41185
  import { MagnetStraight, GridFour, Path, Ruler, FrameCorners } from "@phosphor-icons/react";
41116
41186
  import { jsx as jsx108, jsxs as jsxs78 } from "react/jsx-runtime";
41117
41187
  var SnapToolbar = memo27(function SnapToolbar2() {
41118
- const [gridPopoverOpen, setGridPopoverOpen] = useState52(false);
41188
+ const [gridPopoverOpen, setGridPopoverOpen] = useState53(false);
41119
41189
  const { state, actions } = usePreviewOverlayContext();
41120
41190
  const { snapPrefs: prefs, rulerVisible, safeMarginsVisible } = state;
41121
41191
  const motionPathCreateAvailable = usePlayerStore((s) => s.motionPathCreateAvailable);
@@ -41327,7 +41397,7 @@ var GridOverlay = memo28(function GridOverlay2() {
41327
41397
  });
41328
41398
 
41329
41399
  // src/hooks/useCompositionDimensions.ts
41330
- import { useEffect as useEffect56, useState as useState53 } from "react";
41400
+ import { useEffect as useEffect56, useState as useState54 } from "react";
41331
41401
  function readCompositionSizeMessage(data) {
41332
41402
  if (!isStageSizeMessage(data)) return null;
41333
41403
  const message = data;
@@ -41351,7 +41421,7 @@ function readPositiveDimensions(width, height) {
41351
41421
  return { width: parsedWidth, height: parsedHeight };
41352
41422
  }
41353
41423
  function useCompositionDimensions(iframeRef) {
41354
- const [compositionDimensions, setCompositionDimensions] = useState53(
41424
+ const [compositionDimensions, setCompositionDimensions] = useState54(
41355
41425
  null
41356
41426
  );
41357
41427
  const livePreviewIframe = useLivePreviewIframe();
@@ -43519,7 +43589,7 @@ function PreviewOverlays({
43519
43589
  import { useCallback as useCallback61, useMemo as useMemo39 } from "react";
43520
43590
 
43521
43591
  // src/hooks/useGsapTweenCache.ts
43522
- import { useEffect as useEffect58, useMemo as useMemo38, useRef as useRef80, useState as useState54, useCallback as useCallback60 } from "react";
43592
+ import { useEffect as useEffect58, useMemo as useMemo38, useRef as useRef80, useState as useState55, useCallback as useCallback60 } from "react";
43523
43593
 
43524
43594
  // src/hooks/gsapRuntimeReaders.ts
43525
43595
  import { classifyPropertyGroup as classifyPropertyGroup3 } from "@hyperframes/core/gsap-parser";
@@ -44448,9 +44518,9 @@ function getAnimationsForElement(animations, target, element) {
44448
44518
  );
44449
44519
  }
44450
44520
  function useGsapAnimationsForElement(projectId, sourceFile, target, version, iframeRef) {
44451
- const [allAnimations, setAllAnimations] = useState54([]);
44452
- const [multipleTimelines, setMultipleTimelines] = useState54(false);
44453
- const [unsupportedTimelinePattern, setUnsupportedTimelinePattern] = useState54(false);
44521
+ const [allAnimations, setAllAnimations] = useState55([]);
44522
+ const [multipleTimelines, setMultipleTimelines] = useState55(false);
44523
+ const [unsupportedTimelinePattern, setUnsupportedTimelinePattern] = useState55(false);
44454
44524
  const lastFetchKeyRef = useRef80("");
44455
44525
  const retryTimerRef = useRef80(null);
44456
44526
  const domClipChildrenKey = usePlayerStore(
@@ -44638,7 +44708,7 @@ function useGsapAnimationsForElement(projectId, sourceFile, target, version, ifr
44638
44708
  return { animations, multipleTimelines, unsupportedTimelinePattern };
44639
44709
  }
44640
44710
  function useGsapCacheVersion() {
44641
- const [version, setVersion] = useState54(0);
44711
+ const [version, setVersion] = useState55(0);
44642
44712
  const bump = useCallback60(() => setVersion((v) => v + 1), []);
44643
44713
  return { version, bump };
44644
44714
  }
@@ -47146,7 +47216,7 @@ var AudioWaveform = memo30(function AudioWaveform2({
47146
47216
  });
47147
47217
 
47148
47218
  // src/player/components/ImageThumbnail.tsx
47149
- import { memo as memo31, useCallback as useCallback66, useMemo as useMemo43, useRef as useRef84, useState as useState55 } from "react";
47219
+ import { memo as memo31, useCallback as useCallback66, useMemo as useMemo43, useRef as useRef84, useState as useState56 } from "react";
47150
47220
  import { jsx as jsx114, jsxs as jsxs83 } from "react/jsx-runtime";
47151
47221
  var ImageThumbnail = memo31(function ImageThumbnail2({
47152
47222
  imageSrc,
@@ -47157,7 +47227,7 @@ var ImageThumbnail = memo31(function ImageThumbnail2({
47157
47227
  priority = "visible",
47158
47228
  rich = false
47159
47229
  }) {
47160
- const [containerWidth, setContainerWidth] = useState55(0);
47230
+ const [containerWidth, setContainerWidth] = useState56(0);
47161
47231
  const observerRef = useRef84(null);
47162
47232
  const request = useMemo43(
47163
47233
  () => ({
@@ -47327,7 +47397,7 @@ function useRenderClipContent({
47327
47397
  const thumbnailMode = usePlayerStore((s) => s.thumbnailMode);
47328
47398
  const effectiveMode = effectiveThumbnailMode(thumbnailMode);
47329
47399
  const sessionEpoch = usePlayerStore((s) => s.timelineSessionEpoch);
47330
- const contentRevision = usePlayerStore((s) => s.thumbnailContentRevision);
47400
+ const thumbnailRevisions = usePlayerStore((s) => s.thumbnailRevisions);
47331
47401
  const elements = usePlayerStore((s) => s.elements);
47332
47402
  return useCallback67(
47333
47403
  // Pre-existing clip-content dispatcher; reduced by extracting renderAudioClip.
@@ -47355,7 +47425,7 @@ function useRenderClipContent({
47355
47425
  duration: el.duration,
47356
47426
  projectId: pid,
47357
47427
  sessionEpoch,
47358
- contentRevision,
47428
+ contentRevision: thumbnailRevisionOf(thumbnailRevisions, compSrc),
47359
47429
  priority: context.priority,
47360
47430
  rich: context.rich
47361
47431
  });
@@ -47374,7 +47444,10 @@ function useRenderClipContent({
47374
47444
  duration: el.duration,
47375
47445
  projectId: pid,
47376
47446
  sessionEpoch,
47377
- contentRevision,
47447
+ contentRevision: thumbnailRevisionOf(
47448
+ thumbnailRevisions,
47449
+ compositionPathOfPreviewUrl(activePreviewUrl)
47450
+ ),
47378
47451
  priority: context.priority,
47379
47452
  rich: context.rich
47380
47453
  });
@@ -47416,7 +47489,7 @@ function useRenderClipContent({
47416
47489
  duration: el.duration,
47417
47490
  projectId: pid,
47418
47491
  sessionEpoch,
47419
- contentRevision,
47492
+ contentRevision: thumbnailRevisionOf(thumbnailRevisions, "index.html"),
47420
47493
  priority: context.priority,
47421
47494
  rich: context.rich
47422
47495
  });
@@ -47430,7 +47503,7 @@ function useRenderClipContent({
47430
47503
  effectiveTimelineDuration,
47431
47504
  effectiveMode,
47432
47505
  sessionEpoch,
47433
- contentRevision,
47506
+ thumbnailRevisions,
47434
47507
  elements
47435
47508
  ]
47436
47509
  );
@@ -47567,7 +47640,7 @@ var SourceEditor = memo32(function SourceEditor2({
47567
47640
  });
47568
47641
 
47569
47642
  // src/components/editor/PropertyPanel.tsx
47570
- import { memo as memo36, useMemo as useMemo59, useRef as useRef116, useState as useState99 } from "react";
47643
+ import { memo as memo36, useMemo as useMemo59, useRef as useRef116, useState as useState100 } from "react";
47571
47644
 
47572
47645
  // src/components/editor/InspectorHeaderActions.tsx
47573
47646
  import { Eye as Eye3, EyeSlash as EyeSlash2 } from "@phosphor-icons/react";
@@ -48224,13 +48297,13 @@ function buildElementInfoText(element, sourceLabel, gsapAnimations, previewIfram
48224
48297
  }
48225
48298
 
48226
48299
  // src/components/editor/propertyPanelPrimitives.tsx
48227
- import { useCallback as useCallback71, useEffect as useEffect66, useRef as useRef88, useState as useState58 } from "react";
48300
+ import { useCallback as useCallback71, useEffect as useEffect66, useRef as useRef88, useState as useState59 } from "react";
48228
48301
 
48229
48302
  // src/components/editor/propertyPanelCommitField.tsx
48230
- import { useEffect as useEffect65, useRef as useRef87, useState as useState57 } from "react";
48303
+ import { useEffect as useEffect65, useRef as useRef87, useState as useState58 } from "react";
48231
48304
 
48232
48305
  // src/components/editor/useInspectorGestureTransaction.ts
48233
- import { useCallback as useCallback70, useEffect as useEffect64, useRef as useRef86, useState as useState56 } from "react";
48306
+ import { useCallback as useCallback70, useEffect as useEffect64, useRef as useRef86, useState as useState57 } from "react";
48234
48307
  function isPromiseCommit(result) {
48235
48308
  return Boolean(result && typeof result.then === "function");
48236
48309
  }
@@ -48330,7 +48403,7 @@ function useInspectorGestureDraft({
48330
48403
  onPreview,
48331
48404
  onCommit
48332
48405
  }) {
48333
- const [draft, setDraft] = useState56(sourceValue);
48406
+ const [draft, setDraft] = useState57(sourceValue);
48334
48407
  const transaction = useInspectorGestureTransaction({
48335
48408
  sourceValue,
48336
48409
  onPreview: (next) => {
@@ -48363,7 +48436,7 @@ function CommitField({
48363
48436
  onPreview,
48364
48437
  onCommit
48365
48438
  }) {
48366
- const [draft, setDraft] = useState57(value);
48439
+ const [draft, setDraft] = useState58(value);
48367
48440
  const valueRef = useRef87(value);
48368
48441
  const draftRef = useRef87(draft);
48369
48442
  const inputRef = useRef87(null);
@@ -48632,7 +48705,7 @@ function SliderControl({
48632
48705
  onCommit
48633
48706
  }) {
48634
48707
  const track2 = useTrackDesignInput();
48635
- const [draft, setDraft] = useState58(value);
48708
+ const [draft, setDraft] = useState59(value);
48636
48709
  const commitTimerRef = useRef88(null);
48637
48710
  const interactionChangedRef = useRef88(false);
48638
48711
  const valueRef = useRef88(value);
@@ -48750,7 +48823,7 @@ function Section({
48750
48823
  accessory,
48751
48824
  defaultCollapsed = false
48752
48825
  }) {
48753
- const [collapsed, setCollapsed] = useState58(defaultCollapsed);
48826
+ const [collapsed, setCollapsed] = useState59(defaultCollapsed);
48754
48827
  const collapseIcon = /* @__PURE__ */ jsx119(
48755
48828
  "svg",
48756
48829
  {
@@ -48874,7 +48947,7 @@ function createTransformCommitHandlers({
48874
48947
  import { resolveEditingSections } from "@hyperframes/core/editing";
48875
48948
 
48876
48949
  // src/components/editor/propertyPanelMediaSection.tsx
48877
- import { useEffect as useEffect67, useState as useState59 } from "react";
48950
+ import { useEffect as useEffect67, useState as useState60 } from "react";
48878
48951
  import {
48879
48952
  AUDIO_GAIN_FADER_MAX as AUDIO_GAIN_FADER_MAX2,
48880
48953
  AUDIO_GAIN_FADER_MIN as AUDIO_GAIN_FADER_MIN2,
@@ -48913,11 +48986,11 @@ function MediaSection({
48913
48986
  const sourceDuration = Number.parseFloat(element.dataAttributes["source-duration"] ?? "") || el.duration || 0;
48914
48987
  const mediaStartMax = Math.max(30, Math.ceil(sourceDuration || mediaStart + 10));
48915
48988
  const srcAttr = el.getAttribute("src") ?? "";
48916
- const [copied, setCopied] = useState59(false);
48917
- const [removeBusy, setRemoveBusy] = useState59(false);
48918
- const [removeProgress, setRemoveProgress] = useState59(null);
48919
- const [createPlate, setCreatePlate] = useState59(false);
48920
- const [quality, setQuality] = useState59("balanced");
48989
+ const [copied, setCopied] = useState60(false);
48990
+ const [removeBusy, setRemoveBusy] = useState60(false);
48991
+ const [removeProgress, setRemoveProgress] = useState60(null);
48992
+ const [createPlate, setCreatePlate] = useState60(false);
48993
+ const [quality, setQuality] = useState60("balanced");
48921
48994
  const absoluteSrc = projectDir && srcAttr && !srcAttr.startsWith("http") ? `${projectDir}/${srcAttr}` : srcAttr;
48922
48995
  const projectSrc = srcAttr && !/^(?:https?:|data:|blob:)/i.test(srcAttr) ? stripQueryAndHash(srcAttr.startsWith("./") ? srcAttr.slice(2) : srcAttr) : "";
48923
48996
  const canRemoveBackground = Boolean(onRemoveBackground && isVisualMedia && projectSrc);
@@ -49231,14 +49304,14 @@ function MediaSection({
49231
49304
  import { isHfColorGradingActive as isHfColorGradingActive2 } from "@hyperframes/core/color-grading";
49232
49305
 
49233
49306
  // src/components/editor/propertyPanelColorGradingControls.tsx
49234
- import { useMemo as useMemo45, useRef as useRef90, useState as useState61 } from "react";
49307
+ import { useMemo as useMemo45, useRef as useRef90, useState as useState62 } from "react";
49235
49308
  import {
49236
49309
  HF_COLOR_GRADING_PRESETS,
49237
49310
  normalizeHfColorGrading
49238
49311
  } from "@hyperframes/core/color-grading";
49239
49312
 
49240
49313
  // src/components/editor/propertyPanelColorGradingSlider.tsx
49241
- import { useCallback as useCallback72, useEffect as useEffect68, useRef as useRef89, useState as useState60 } from "react";
49314
+ import { useCallback as useCallback72, useEffect as useEffect68, useRef as useRef89, useState as useState61 } from "react";
49242
49315
  import { jsx as jsx121, jsxs as jsxs87 } from "react/jsx-runtime";
49243
49316
  var SLIDER_THUMB_SIZE = 10;
49244
49317
  var SLIDER_THUMB_RADIUS = SLIDER_THUMB_SIZE / 2;
@@ -49275,8 +49348,8 @@ function ColorGradingSliderControl({
49275
49348
  settings
49276
49349
  }) {
49277
49350
  const track2 = useTrackDesignInput();
49278
- const [draftState, setDraftState] = useState60(null);
49279
- const [inputDraft, setInputDraft] = useState60(null);
49351
+ const [draftState, setDraftState] = useState61(null);
49352
+ const [inputDraft, setInputDraft] = useState61(null);
49280
49353
  const commitTimerRef = useRef89(null);
49281
49354
  const interactionChangedRef = useRef89(false);
49282
49355
  const valueRef = useRef89(value);
@@ -49671,10 +49744,10 @@ function ColorGradingControls({
49671
49744
  }) {
49672
49745
  const track2 = useTrackDesignInput();
49673
49746
  const lutInputRef = useRef90(null);
49674
- const [lutOpen, setLutOpen] = useState61(false);
49675
- const [detailSettings, setDetailSettings] = useState61(null);
49676
- const [lutImporting, setLutImporting] = useState61(false);
49677
- const [lutImportError, setLutImportError] = useState61(null);
49747
+ const [lutOpen, setLutOpen] = useState62(false);
49748
+ const [detailSettings, setDetailSettings] = useState62(null);
49749
+ const [lutImporting, setLutImporting] = useState62(false);
49750
+ const [lutImportError, setLutImportError] = useState62(null);
49678
49751
  const lutAssets = useMemo45(
49679
49752
  () => assets.filter((asset) => LUT_EXT.test(asset)).sort((a, b) => a.localeCompare(b)),
49680
49753
  [assets]
@@ -49955,7 +50028,7 @@ function ColorGradingControls({
49955
50028
  }
49956
50029
 
49957
50030
  // src/components/editor/useColorGradingController.ts
49958
- import { useCallback as useCallback74, useEffect as useEffect70, useMemo as useMemo46, useRef as useRef92, useState as useState63 } from "react";
50031
+ import { useCallback as useCallback74, useEffect as useEffect70, useMemo as useMemo46, useRef as useRef92, useState as useState64 } from "react";
49959
50032
  import {
49960
50033
  HF_COLOR_GRADING_ATTR,
49961
50034
  hasHfColorGradingAuthoredValues,
@@ -50023,7 +50096,7 @@ function addStudioPendingEditFlushListener(handler) {
50023
50096
  }
50024
50097
 
50025
50098
  // src/components/editor/useColorGradingPreviews.ts
50026
- import { useCallback as useCallback73, useEffect as useEffect69, useRef as useRef91, useState as useState62 } from "react";
50099
+ import { useCallback as useCallback73, useEffect as useEffect69, useRef as useRef91, useState as useState63 } from "react";
50027
50100
  import {
50028
50101
  HF_COLOR_GRADING_ACTIVE_EFFECT_KEYS,
50029
50102
  HF_COLOR_GRADING_EFFECT_APPLY_DEFAULTS,
@@ -50092,11 +50165,11 @@ function useColorGradingPreviews({
50092
50165
  previewIframeRef,
50093
50166
  postColorGrading
50094
50167
  }) {
50095
- const [state, setState] = useState62(() => ({
50168
+ const [state, setState] = useState63(() => ({
50096
50169
  identityKey,
50097
50170
  previews: emptyPreviews()
50098
50171
  }));
50099
- const [request, setRequest] = useState62(null);
50172
+ const [request, setRequest] = useState63(null);
50100
50173
  const animatedRef = useRef91(null);
50101
50174
  if (state.identityKey !== identityKey) {
50102
50175
  setState({ identityKey, previews: emptyPreviews() });
@@ -50368,11 +50441,11 @@ function useColorGradingController({
50368
50441
  onSetAttributeLive,
50369
50442
  onApplyScope
50370
50443
  }) {
50371
- const [grading, setGrading] = useState63(() => readColorGradingFromElement(element));
50372
- const [compareEnabled, setCompareEnabled] = useState63(false);
50373
- const [applyScope, setApplyScope] = useState63("source-file");
50374
- const [applyBusy, setApplyBusy] = useState63(false);
50375
- const [runtimeStatus, setRuntimeStatus] = useState63(() => ({
50444
+ const [grading, setGrading] = useState64(() => readColorGradingFromElement(element));
50445
+ const [compareEnabled, setCompareEnabled] = useState64(false);
50446
+ const [applyScope, setApplyScope] = useState64("source-file");
50447
+ const [applyBusy, setApplyBusy] = useState64(false);
50448
+ const [runtimeStatus, setRuntimeStatus] = useState64(() => ({
50376
50449
  state: "pending",
50377
50450
  message: "Waiting for runtime"
50378
50451
  }));
@@ -50380,7 +50453,7 @@ function useColorGradingController({
50380
50453
  () => selectedMediaAssetPath(element, projectId),
50381
50454
  [element, projectId]
50382
50455
  );
50383
- const [mediaMetadata, setMediaMetadata] = useState63(null);
50456
+ const [mediaMetadata, setMediaMetadata] = useState64(null);
50384
50457
  const persistTimerRef = useRef92(null);
50385
50458
  const pendingPersistValueRef = useRef92(void 0);
50386
50459
  const pendingPersistGradingRef = useRef92(null);
@@ -50893,10 +50966,10 @@ function ColorGradingSection({
50893
50966
  }
50894
50967
 
50895
50968
  // src/components/editor/propertyPanelSections.tsx
50896
- import { useEffect as useEffect76, useRef as useRef97, useState as useState72 } from "react";
50969
+ import { useEffect as useEffect76, useRef as useRef97, useState as useState73 } from "react";
50897
50970
 
50898
50971
  // src/components/editor/propertyPanelColor.tsx
50899
- import { useCallback as useCallback75, useEffect as useEffect71, useLayoutEffect as useLayoutEffect7, useRef as useRef93, useState as useState64 } from "react";
50972
+ import { useCallback as useCallback75, useEffect as useEffect71, useLayoutEffect as useLayoutEffect7, useRef as useRef93, useState as useState65 } from "react";
50900
50973
  import { createPortal as createPortal8 } from "react-dom";
50901
50974
  import { jsx as jsx124, jsxs as jsxs90 } from "react/jsx-runtime";
50902
50975
  var COLOR_PICKER_SIZE = { width: 292, height: 386 };
@@ -51015,12 +51088,12 @@ function ColorField({
51015
51088
  const track2 = useTrackDesignInput();
51016
51089
  const buttonRef = useRef93(null);
51017
51090
  const panelRef = useRef93(null);
51018
- const [open, setOpen] = useState64(false);
51019
- const [panelPosition, setPanelPosition] = useState64(null);
51020
- const [draftColor, setDraftColor] = useState64(() => colorFromCss(value));
51091
+ const [open, setOpen] = useState65(false);
51092
+ const [panelPosition, setPanelPosition] = useState65(null);
51093
+ const [draftColor, setDraftColor] = useState65(() => colorFromCss(value));
51021
51094
  const draftColorRef = useRef93(draftColor);
51022
51095
  draftColorRef.current = draftColor;
51023
- const [hexDraft, setHexDraft] = useState64(() => toHexColor(colorFromCss(value)).toUpperCase());
51096
+ const [hexDraft, setHexDraft] = useState65(() => toHexColor(colorFromCss(value)).toUpperCase());
51024
51097
  const hsv = rgbToHsv(draftColor);
51025
51098
  const hueColor = formatCssColor({
51026
51099
  ...hsvToRgb({ hue: hsv.hue, saturation: 1, value: 1 }),
@@ -51403,7 +51476,7 @@ function ColorField({
51403
51476
  }
51404
51477
 
51405
51478
  // src/components/editor/propertyPanelFont.tsx
51406
- import { useEffect as useEffect72, useMemo as useMemo47, useRef as useRef94, useState as useState65 } from "react";
51479
+ import { useEffect as useEffect72, useMemo as useMemo47, useRef as useRef94, useState as useState66 } from "react";
51407
51480
 
51408
51481
  // src/components/editor/fontAssets.ts
51409
51482
  var FONT_EXT_RE = /\.(eot|otf|ttc|ttf|woff2?)$/i;
@@ -51520,16 +51593,16 @@ function FontFamilyField({
51520
51593
  const containerRef = useRef94(null);
51521
51594
  const inputRef = useRef94(null);
51522
51595
  const fontInputRef = useRef94(null);
51523
- const [open, setOpen] = useState65(false);
51524
- const [query, setQuery] = useState65("");
51525
- const [activeIndex, setActiveIndex] = useState65(-1);
51526
- const [localFonts, setLocalFonts] = useState65([]);
51527
- const [localFontData, setLocalFontData] = useState65([]);
51528
- const [googleFonts, setGoogleFonts] = useState65(() => [...POPULAR_GOOGLE_FONT_FAMILIES]);
51529
- const [loadingLocalFonts, setLoadingLocalFonts] = useState65(false);
51530
- const [loadingGoogleFonts, setLoadingGoogleFonts] = useState65(false);
51531
- const [importingFonts, setImportingFonts] = useState65(false);
51532
- const [fontNotice, setFontNotice] = useState65(null);
51596
+ const [open, setOpen] = useState66(false);
51597
+ const [query, setQuery] = useState66("");
51598
+ const [activeIndex, setActiveIndex] = useState66(-1);
51599
+ const [localFonts, setLocalFonts] = useState66([]);
51600
+ const [localFontData, setLocalFontData] = useState66([]);
51601
+ const [googleFonts, setGoogleFonts] = useState66(() => [...POPULAR_GOOGLE_FONT_FAMILIES]);
51602
+ const [loadingLocalFonts, setLoadingLocalFonts] = useState66(false);
51603
+ const [loadingGoogleFonts, setLoadingGoogleFonts] = useState66(false);
51604
+ const [importingFonts, setImportingFonts] = useState66(false);
51605
+ const [fontNotice, setFontNotice] = useState66(null);
51533
51606
  const canQueryLocalFonts = typeof window !== "undefined" && typeof window.queryLocalFonts === "function";
51534
51607
  const commitFontFamily = (nextValue) => {
51535
51608
  if (nextValue !== value) track2("select", "Font family");
@@ -51887,10 +51960,10 @@ function FontFamilyField({
51887
51960
  import { useEffect as useEffect74 } from "react";
51888
51961
 
51889
51962
  // src/components/panels/VariablesBindElement.tsx
51890
- import { useMemo as useMemo48, useState as useState67 } from "react";
51963
+ import { useMemo as useMemo48, useState as useState68 } from "react";
51891
51964
 
51892
51965
  // src/components/panels/VariablesValueControls.tsx
51893
- import { useState as useState66 } from "react";
51966
+ import { useState as useState67 } from "react";
51894
51967
  import { jsx as jsx126, jsxs as jsxs92 } from "react/jsx-runtime";
51895
51968
  var VARIABLES_INPUT_CLASS = "w-full bg-neutral-900 border border-neutral-800 rounded-sm px-2 py-1 text-[10px] text-neutral-200 focus:outline-hidden focus:border-neutral-700";
51896
51969
  function DraftTextInput({
@@ -51904,7 +51977,7 @@ function DraftTextInput({
51904
51977
  max,
51905
51978
  step
51906
51979
  }) {
51907
- const [draft, setDraft] = useState66(null);
51980
+ const [draft, setDraft] = useState67(null);
51908
51981
  return /* @__PURE__ */ jsx126(
51909
51982
  "input",
51910
51983
  {
@@ -51945,7 +52018,7 @@ function ColorControl({
51945
52018
  onCommit
51946
52019
  }) {
51947
52020
  const colorValue = typeof current === "string" ? current : "#000000";
51948
- const [draft, setDraft] = useState66(null);
52021
+ const [draft, setDraft] = useState67(null);
51949
52022
  return /* @__PURE__ */ jsxs92("div", { className: "flex items-center gap-2", children: [
51950
52023
  /* @__PURE__ */ jsx126(
51951
52024
  "input",
@@ -51977,7 +52050,7 @@ function NumberControl({
51977
52050
  }) {
51978
52051
  const numberValue = typeof current === "number" ? current : Number(current) || 0;
51979
52052
  const hasRange = decl.min !== void 0 && decl.max !== void 0;
51980
- const [dragValue, setDragValue] = useState66(null);
52053
+ const [dragValue, setDragValue] = useState67(null);
51981
52054
  const commitDrag = () => {
51982
52055
  if (dragValue !== null && dragValue !== numberValue) onCommit(dragValue);
51983
52056
  setDragValue(null);
@@ -52167,8 +52240,8 @@ function VariablesBindElement({
52167
52240
  sdkSession,
52168
52241
  onBind
52169
52242
  }) {
52170
- const [activeKey, setActiveKey] = useState67(null);
52171
- const [idDraft, setIdDraft] = useState67("");
52243
+ const [activeKey, setActiveKey] = useState68(null);
52244
+ const [idDraft, setIdDraft] = useState68("");
52172
52245
  const actions = useMemo48(() => buildBindActions(selection, sdkSession), [selection, sdkSession]);
52173
52246
  if (actions.length === 0) return null;
52174
52247
  const active = actions.find((a) => a.key === activeKey) ?? null;
@@ -52280,7 +52353,7 @@ function uniqueId(base2, existing) {
52280
52353
  }
52281
52354
 
52282
52355
  // src/contexts/VariablePromoteContext.tsx
52283
- import { useContext as useContext12, useEffect as useEffect73, useMemo as useMemo49, useState as useState68 } from "react";
52356
+ import { useContext as useContext12, useEffect as useEffect73, useMemo as useMemo49, useState as useState69 } from "react";
52284
52357
  import { jsx as jsx128 } from "react/jsx-runtime";
52285
52358
  var VariablePromoteContext = createStableContext(
52286
52359
  "VariablePromoteContext",
@@ -52298,7 +52371,7 @@ function VariablePromoteProvider({
52298
52371
  onPersistError,
52299
52372
  children
52300
52373
  }) {
52301
- const [revision, setRevision] = useState68(0);
52374
+ const [revision, setRevision] = useState69(0);
52302
52375
  useEffect73(() => {
52303
52376
  if (!session) return;
52304
52377
  return session.on("change", () => setRevision((r) => r + 1));
@@ -52411,7 +52484,7 @@ function PromotableControl({
52411
52484
  }
52412
52485
 
52413
52486
  // src/components/editor/propertyPanelStyleSections.tsx
52414
- import { useEffect as useEffect75, useRef as useRef96, useState as useState71 } from "react";
52487
+ import { useEffect as useEffect75, useRef as useRef96, useState as useState72 } from "react";
52415
52488
 
52416
52489
  // src/components/editor/gradientValue.ts
52417
52490
  var RADIAL_SIZE_KEYWORDS = [
@@ -52755,7 +52828,7 @@ function parseColorString(value) {
52755
52828
  }
52756
52829
 
52757
52830
  // src/components/editor/propertyPanelFill.tsx
52758
- import { useMemo as useMemo50, useRef as useRef95, useState as useState69 } from "react";
52831
+ import { useMemo as useMemo50, useRef as useRef95, useState as useState70 } from "react";
52759
52832
 
52760
52833
  // src/components/icons/ReverseGradientIcon.tsx
52761
52834
  import { jsx as jsx130, jsxs as jsxs95 } from "react/jsx-runtime";
@@ -52828,8 +52901,8 @@ function ImageFillField({
52828
52901
  }) {
52829
52902
  const track2 = useTrackDesignInput();
52830
52903
  const fileInputRef = useRef95(null);
52831
- const [uploading, setUploading] = useState69(false);
52832
- const [uploadError, setUploadError] = useState69(null);
52904
+ const [uploading, setUploading] = useState70(false);
52905
+ const [uploadError, setUploadError] = useState70(null);
52833
52906
  const imageAssets = useMemo50(() => assets.filter((a) => IMAGE_EXT.test(a)), [assets]);
52834
52907
  const selectedAsset = useMemo50(
52835
52908
  () => resolveSelectedAsset(value, sourceFile, imageAssets),
@@ -53217,7 +53290,7 @@ function GradientField({
53217
53290
  }
53218
53291
 
53219
53292
  // src/components/editor/BorderRadiusEditor.tsx
53220
- import { useCallback as useCallback76, useState as useState70 } from "react";
53293
+ import { useCallback as useCallback76, useState as useState71 } from "react";
53221
53294
  import { jsx as jsx132, jsxs as jsxs97 } from "react/jsx-runtime";
53222
53295
  var PREVIEW_W = 72;
53223
53296
  var PREVIEW_H = 52;
@@ -53238,7 +53311,7 @@ function BorderRadiusEditor({
53238
53311
  onCommit
53239
53312
  }) {
53240
53313
  const uniform = tl === tr && tr === br && br === bl;
53241
- const [linked, setLinked] = useState70(uniform);
53314
+ const [linked, setLinked] = useState71(uniform);
53242
53315
  const maxVal = Math.max(tl, tr, br, bl, 1);
53243
53316
  const sTL = scaleRadius(tl, maxVal);
53244
53317
  const sTR = scaleRadius(tr, maxVal);
@@ -53440,7 +53513,7 @@ function StyleSections({
53440
53513
  const backgroundImage = styles["background-image"] ?? "none";
53441
53514
  const hasTextControls = isTextEditableSelection(element);
53442
53515
  const fillMode = backgroundImage && backgroundImage !== "none" ? backgroundImage.includes("gradient") ? "Gradient" : "Image" : "Solid";
53443
- const [preferredFillMode, setPreferredFillMode] = useState71(fillMode);
53516
+ const [preferredFillMode, setPreferredFillMode] = useState72(fillMode);
53444
53517
  const imageUrl = extractBackgroundImageUrl(backgroundImage);
53445
53518
  const lastGradientRef = useRef96(
53446
53519
  backgroundImage.includes("gradient") ? backgroundImage : null
@@ -53897,7 +53970,7 @@ function TextAreaField({
53897
53970
  onCommit
53898
53971
  }) {
53899
53972
  const track2 = useTrackDesignInput();
53900
- const [draft, setDraft] = useState72(value);
53973
+ const [draft, setDraft] = useState73(value);
53901
53974
  const textareaRef = useRef97(null);
53902
53975
  const commitTimerRef = useRef97(null);
53903
53976
  const interactionChangedRef = useRef97(false);
@@ -54208,7 +54281,7 @@ function TextSection({
54208
54281
  }) {
54209
54282
  const track2 = useTrackDesignInput();
54210
54283
  const hasTextControls = isTextEditableSelection(element);
54211
- const [activeTextFieldKey, setActiveTextFieldKey] = useState72(
54284
+ const [activeTextFieldKey, setActiveTextFieldKey] = useState73(
54212
54285
  element.textFields[0]?.key ?? null
54213
54286
  );
54214
54287
  useEffect76(() => {
@@ -54309,11 +54382,11 @@ function TextSection({
54309
54382
  import { memo as memo35 } from "react";
54310
54383
 
54311
54384
  // src/components/editor/GsapAnimationList.tsx
54312
- import { useCallback as useCallback79, useState as useState74 } from "react";
54385
+ import { useCallback as useCallback79, useState as useState75 } from "react";
54313
54386
  import { useShallow } from "zustand/react/shallow";
54314
54387
 
54315
54388
  // src/components/editor/AnimationCard.tsx
54316
- import { memo as memo34, useCallback as useCallback78, useEffect as useEffect77, useMemo as useMemo51, useRef as useRef98, useState as useState73 } from "react";
54389
+ import { memo as memo34, useCallback as useCallback78, useEffect as useEffect77, useMemo as useMemo51, useRef as useRef98, useState as useState74 } from "react";
54317
54390
  import { SUPPORTED_EASES, SUPPORTED_PROPS } from "@hyperframes/core/gsap-constants";
54318
54391
 
54319
54392
  // src/components/editor/gsapAnimationHelpers.ts
@@ -54831,11 +54904,11 @@ var AnimationCard = memo34(function AnimationCard2({
54831
54904
  onSetAllKeyframeEases,
54832
54905
  onUnroll
54833
54906
  }) {
54834
- const [expanded, setExpanded] = useState73(defaultExpanded);
54835
- const [addingProp, setAddingProp] = useState73(false);
54836
- const [addingFromProp, setAddingFromProp] = useState73(false);
54837
- const [expandedKfPct, setExpandedKfPct] = useState73(null);
54838
- const [focusedCollidingAnimationTargets, setFocusedCollidingAnimationTargets] = useState73();
54907
+ const [expanded, setExpanded] = useState74(defaultExpanded);
54908
+ const [addingProp, setAddingProp] = useState74(false);
54909
+ const [addingFromProp, setAddingFromProp] = useState74(false);
54910
+ const [expandedKfPct, setExpandedKfPct] = useState74(null);
54911
+ const [focusedCollidingAnimationTargets, setFocusedCollidingAnimationTargets] = useState74();
54839
54912
  const cardRef = useRef98(null);
54840
54913
  const pendingAutoScrollRef = useRef98(false);
54841
54914
  useEffect77(() => {
@@ -54910,7 +54983,7 @@ var AnimationCard = memo34(function AnimationCard2({
54910
54983
  },
54911
54984
  [animation.id, onUpdateMeta]
54912
54985
  );
54913
- const [copied, setCopied] = useState73(false);
54986
+ const [copied, setCopied] = useState74(false);
54914
54987
  const methodLabel = METHOD_LABELS[animation.method] ?? animation.method;
54915
54988
  const easeName = (animation.keyframes ? animation.keyframes.easeEach : void 0) ?? animation.ease ?? "none";
54916
54989
  const easeLabel = easeName.startsWith("custom(") ? "Custom curve" : EASE_LABELS[easeName] ?? easeName;
@@ -55342,7 +55415,7 @@ function GsapAnimationList({
55342
55415
  ...callbacks
55343
55416
  }) {
55344
55417
  const track2 = useTrackDesignInput();
55345
- const [addMenuOpen, setAddMenuOpen] = useState74(false);
55418
+ const [addMenuOpen, setAddMenuOpen] = useState75(false);
55346
55419
  const trackedCallbacks = withTrackedGsapAnimationCallbacks(callbacks, track2);
55347
55420
  const { focusedEaseSegment, timelineProjectId, timelineSessionEpoch, selectedElementId } = usePlayerStore(
55348
55421
  useShallow((state) => ({
@@ -55416,10 +55489,10 @@ var GsapAnimationSection = memo35(function GsapAnimationSection2({
55416
55489
  });
55417
55490
 
55418
55491
  // src/components/editor/propertyPanel3dTransform.tsx
55419
- import { useState as useState76 } from "react";
55492
+ import { useState as useState77 } from "react";
55420
55493
 
55421
55494
  // src/components/editor/Transform3DCube.tsx
55422
- import { useEffect as useEffect78, useRef as useRef99, useState as useState75 } from "react";
55495
+ import { useEffect as useEffect78, useRef as useRef99, useState as useState76 } from "react";
55423
55496
 
55424
55497
  // src/components/editor/transform3dProjection.ts
55425
55498
  var DEG = Math.PI / 180;
@@ -55533,8 +55606,8 @@ function Transform3DCube({
55533
55606
  onKeyframe,
55534
55607
  keyframed
55535
55608
  }) {
55536
- const [draft, setDraft] = useState75(null);
55537
- const [depthDraft, setDepthDraft] = useState75(null);
55609
+ const [draft, setDraft] = useState76(null);
55610
+ const [depthDraft, setDepthDraft] = useState76(null);
55538
55611
  const dragRef = useRef99(null);
55539
55612
  const shown2 = draft ?? pose;
55540
55613
  const shownZ = depthDraft ?? z;
@@ -55930,7 +56003,7 @@ function PropertyPanel3dTransform({
55930
56003
  onConvertToKeyframes,
55931
56004
  onLivePreviewProps
55932
56005
  }) {
55933
- const [collapsed, setCollapsed] = useState76(false);
56006
+ const [collapsed, setCollapsed] = useState77(false);
55934
56007
  const ctx3 = {
55935
56008
  element,
55936
56009
  gsapRuntimeValues,
@@ -56063,7 +56136,7 @@ function PropertyPanel3dTransform({
56063
56136
  }
56064
56137
 
56065
56138
  // src/components/editor/PropertyPanelFlat.tsx
56066
- import { useEffect as useEffect98, useMemo as useMemo58, useRef as useRef115, useState as useState98 } from "react";
56139
+ import { useEffect as useEffect98, useMemo as useMemo58, useRef as useRef115, useState as useState99 } from "react";
56067
56140
  import { useShallow as useShallow2 } from "zustand/react/shallow";
56068
56141
 
56069
56142
  // src/components/editor/audioFxSummary.ts
@@ -56273,10 +56346,10 @@ function PropertyPanelFlatFooter({
56273
56346
  }
56274
56347
 
56275
56348
  // src/components/editor/propertyPanelFlatPrimitives.tsx
56276
- import { useEffect as useEffect80, useRef as useRef101, useState as useState78 } from "react";
56349
+ import { useEffect as useEffect80, useRef as useRef101, useState as useState79 } from "react";
56277
56350
 
56278
56351
  // src/components/editor/propertyPanelFlatSliderReadout.tsx
56279
- import { useEffect as useEffect79, useRef as useRef100, useState as useState77 } from "react";
56352
+ import { useEffect as useEffect79, useRef as useRef100, useState as useState78 } from "react";
56280
56353
  import { jsx as jsx147 } from "react/jsx-runtime";
56281
56354
  function FlatSliderReadout({
56282
56355
  label,
@@ -56286,9 +56359,9 @@ function FlatSliderReadout({
56286
56359
  onCommitText,
56287
56360
  onCommitted
56288
56361
  }) {
56289
- const [editing, setEditing] = useState77(false);
56290
- const [text, setText] = useState77("");
56291
- const [invalid, setInvalid] = useState77(false);
56362
+ const [editing, setEditing] = useState78(false);
56363
+ const [text, setText] = useState78("");
56364
+ const [invalid, setInvalid] = useState78(false);
56292
56365
  const inputRef = useRef100(null);
56293
56366
  const editable = Boolean(onCommitText) && !disabled;
56294
56367
  useEffect79(() => {
@@ -56634,7 +56707,7 @@ function FlatSlider({
56634
56707
  onCommitText
56635
56708
  }) {
56636
56709
  const track2 = useTrackDesignInput();
56637
- const [draft, setDraft] = useState78(value);
56710
+ const [draft, setDraft] = useState79(value);
56638
56711
  const commitTimerRef = useRef101(null);
56639
56712
  const lastCommitAtRef = useRef101(0);
56640
56713
  const pendingRef = useRef101(null);
@@ -56857,7 +56930,7 @@ function isSelectionHidden(fromTimeline, element) {
56857
56930
  }
56858
56931
 
56859
56932
  // src/components/editor/propertyPanelFlatTextSection.tsx
56860
- import { useEffect as useEffect81, useState as useState79 } from "react";
56933
+ import { useEffect as useEffect81, useState as useState80 } from "react";
56861
56934
  import { Fragment as Fragment36, jsx as jsx151, jsxs as jsxs114 } from "react/jsx-runtime";
56862
56935
  var ALIGN_OPTIONS = [
56863
56936
  { key: "left", label: "left", node: "L" },
@@ -57066,10 +57139,10 @@ function FlatTextSection({
57066
57139
  onRemoveTextField
57067
57140
  }) {
57068
57141
  const track2 = useTrackDesignInput();
57069
- const [activeFieldKey, setActiveFieldKey] = useState79(
57142
+ const [activeFieldKey, setActiveFieldKey] = useState80(
57070
57143
  element.textFields[0]?.key ?? null
57071
57144
  );
57072
- const [autoFocusFieldKey, setAutoFocusFieldKey] = useState79(null);
57145
+ const [autoFocusFieldKey, setAutoFocusFieldKey] = useState80(null);
57073
57146
  useEffect81(() => {
57074
57147
  const nextFields = element.textFields;
57075
57148
  setActiveFieldKey((current) => {
@@ -57222,7 +57295,7 @@ function FlatTextLayerList({
57222
57295
  }
57223
57296
 
57224
57297
  // src/components/editor/propertyPanelFlatStyleSections.tsx
57225
- import { useEffect as useEffect82, useState as useState80 } from "react";
57298
+ import { useEffect as useEffect82, useState as useState81 } from "react";
57226
57299
 
57227
57300
  // src/components/editor/propertyPanelFlatStyleHelpers.ts
57228
57301
  var STROKE_STYLE_OPTIONS = [
@@ -57340,7 +57413,7 @@ function FlatFillFields({
57340
57413
  const backgroundImage = styles["background-image"] ?? "none";
57341
57414
  const hasTextControls = isTextEditableSelection(element);
57342
57415
  const fillMode = backgroundImage && backgroundImage !== "none" ? backgroundImage.includes("gradient") ? "Gradient" : "Image" : "Solid";
57343
- const [preferredFillMode, setPreferredFillMode] = useState80(fillMode);
57416
+ const [preferredFillMode, setPreferredFillMode] = useState81(fillMode);
57344
57417
  const imageUrl = extractBackgroundImageUrl(backgroundImage);
57345
57418
  useEffect82(() => {
57346
57419
  setPreferredFillMode(fillMode);
@@ -58233,7 +58306,7 @@ function motionSectionLabel(args) {
58233
58306
  }
58234
58307
 
58235
58308
  // src/components/editor/propertyPanelAudioFxGroup.tsx
58236
- import { useMemo as useMemo54, useState as useState86 } from "react";
58309
+ import { useMemo as useMemo54, useState as useState87 } from "react";
58237
58310
  import {
58238
58311
  HF_AUDIO_FX_ATTR as HF_AUDIO_FX_ATTR6,
58239
58312
  HF_AUDIO_FX_DATA_KEY as HF_AUDIO_FX_DATA_KEY2,
@@ -58296,7 +58369,7 @@ function automationAttrValue(automation) {
58296
58369
  }
58297
58370
 
58298
58371
  // src/components/editor/propertyPanelFxSection.tsx
58299
- import { useCallback as useCallback82, useEffect as useEffect85, useMemo as useMemo53, useRef as useRef103, useState as useState84 } from "react";
58372
+ import { useCallback as useCallback82, useEffect as useEffect85, useMemo as useMemo53, useRef as useRef103, useState as useState85 } from "react";
58300
58373
 
58301
58374
  // src/components/editor/audioFxRevealTarget.ts
58302
58375
  import { parseAutomationTarget as parseAutomationTarget2 } from "@hyperframes/core/audio-automation";
@@ -58376,7 +58449,7 @@ import { DEFAULT_CARVE } from "@hyperframes/core/audio-carve";
58376
58449
  import { fxAutomationTarget as fxAutomationTarget2 } from "@hyperframes/core/audio-automation";
58377
58450
 
58378
58451
  // src/components/editor/propertyPanelFxControls.tsx
58379
- import { useCallback as useCallback80, useEffect as useEffect83, useRef as useRef102, useState as useState81 } from "react";
58452
+ import { useCallback as useCallback80, useEffect as useEffect83, useRef as useRef102, useState as useState82 } from "react";
58380
58453
  import { jsx as jsx157, jsxs as jsxs120 } from "react/jsx-runtime";
58381
58454
  function toSlider(p, value) {
58382
58455
  if (p.scale !== "log" || p.min <= 0) return value;
@@ -58423,11 +58496,11 @@ function FxParamRow({
58423
58496
  onAutomate,
58424
58497
  onRemoveAutomation
58425
58498
  }) {
58426
- const [dragging, setDragging] = useState81(false);
58427
- const [local, setLocal] = useState81(value);
58499
+ const [dragging, setDragging] = useState82(false);
58500
+ const [local, setLocal] = useState82(value);
58428
58501
  const latest = useRef102(value);
58429
- const [pending2, setPending] = useState81(null);
58430
- const [typing, setTyping] = useState81(null);
58502
+ const [pending2, setPending] = useState82(null);
58503
+ const [typing, setTyping] = useState82(null);
58431
58504
  const edited = useRef102(false);
58432
58505
  useEffect83(() => {
58433
58506
  if (!dragging) setLocal(value);
@@ -59085,7 +59158,7 @@ function CarveAnalysis({
59085
59158
  }
59086
59159
 
59087
59160
  // src/components/editor/propertyPanelFxEqModule.tsx
59088
- import { useCallback as useCallback81, useEffect as useEffect84, useState as useState82 } from "react";
59161
+ import { useCallback as useCallback81, useEffect as useEffect84, useState as useState83 } from "react";
59089
59162
  import {
59090
59163
  audioEqSummary,
59091
59164
  HF_AUDIO_EQ_RANGE_DB
@@ -59105,8 +59178,8 @@ function Fader2({
59105
59178
  onPreview,
59106
59179
  onCommit
59107
59180
  }) {
59108
- const [local, setLocal] = useState82(band.gain);
59109
- const [dragging, setDragging] = useState82(false);
59181
+ const [local, setLocal] = useState83(band.gain);
59182
+ const [dragging, setDragging] = useState83(false);
59110
59183
  useEffect84(() => {
59111
59184
  if (!dragging) setLocal(band.gain);
59112
59185
  }, [band.gain, dragging]);
@@ -59243,7 +59316,7 @@ function FxEqModule({
59243
59316
  import { getAudioFxPreset as getAudioFxPreset3 } from "@hyperframes/core/audio-fx-presets";
59244
59317
 
59245
59318
  // src/components/editor/propertyPanelFxNodeRow.tsx
59246
- import { useMemo as useMemo52, useState as useState83 } from "react";
59319
+ import { useMemo as useMemo52, useState as useState84 } from "react";
59247
59320
  import {
59248
59321
  defaultAudioFxParams as defaultAudioFxParams3,
59249
59322
  getAudioFxDef as getAudioFxDef3
@@ -59677,7 +59750,7 @@ function FxNodeRow({
59677
59750
  () => def && primary ? { ...def, params: def.params.filter((p) => p.key === primary) } : def,
59678
59751
  [def, primary]
59679
59752
  );
59680
- const [details, setDetails] = useState83(false);
59753
+ const [details, setDetails] = useState84(false);
59681
59754
  if (!registryDef || !def || !onlyPrimary) return null;
59682
59755
  const oneKnob = primary !== null || derived !== null;
59683
59756
  const copy = EFFECT_COPY[node.type];
@@ -60230,9 +60303,9 @@ function FxSection({
60230
60303
  const presetAutomated = automatedPresets ?? /* @__PURE__ */ new Set();
60231
60304
  const previewCarve = onCarvePreview ?? onCarveChange;
60232
60305
  const showCarve = !carvedAgainstBy && (sourceOptions.length > 0 || carve !== null);
60233
- const [adding, setAdding] = useState84(false);
60234
- const [picking, setPicking] = useState84(false);
60235
- const [openNode, setOpenNode] = useState84(0);
60306
+ const [adding, setAdding] = useState85(false);
60307
+ const [picking, setPicking] = useState85(false);
60308
+ const [openNode, setOpenNode] = useState85(0);
60236
60309
  const mutate = useCallback82(
60237
60310
  (nodes) => onChainChange({ ...chain, nodes }),
60238
60311
  [chain, onChainChange]
@@ -60318,7 +60391,7 @@ function FxSection({
60318
60391
  },
60319
60392
  [chain.nodes, mutate, onRemoveNodeAutomation, trackKind]
60320
60393
  );
60321
- const [carveOpen, setCarveOpen] = useState84(true);
60394
+ const [carveOpen, setCarveOpen] = useState85(true);
60322
60395
  const carveNodes = useMemo53(() => chain.nodes.filter((n) => n.fromCarve), [chain.nodes]);
60323
60396
  const handBuilt = useMemo53(
60324
60397
  () => chain.nodes.map((node, i) => ({ node, i })).filter(({ node }) => !node.fromCarve && !node.fromEq),
@@ -60334,7 +60407,7 @@ function FxSection({
60334
60407
  }
60335
60408
  return out;
60336
60409
  }, [handBuilt]);
60337
- const [collapsedRuns, setCollapsedRuns] = useState84(/* @__PURE__ */ new Set());
60410
+ const [collapsedRuns, setCollapsedRuns] = useState85(/* @__PURE__ */ new Set());
60338
60411
  const eqIds = useMemo53(() => audioEqIds(chain), [chain]);
60339
60412
  const positions = useMemo53(() => {
60340
60413
  const map = /* @__PURE__ */ new Map();
@@ -60342,9 +60415,9 @@ function FxSection({
60342
60415
  for (const { i } of handBuilt) map.set(i, ++at);
60343
60416
  return map;
60344
60417
  }, [handBuilt, eqIds.length, showCarve]);
60345
- const [openEq, setOpenEq] = useState84(null);
60346
- const [consumedRevealNonce, setConsumedRevealNonce] = useState84(null);
60347
- const [pendingReveal, setPendingReveal] = useState84(null);
60418
+ const [openEq, setOpenEq] = useState85(null);
60419
+ const [consumedRevealNonce, setConsumedRevealNonce] = useState85(null);
60420
+ const [pendingReveal, setPendingReveal] = useState85(null);
60348
60421
  const rootRef = useRef103(null);
60349
60422
  if (revealNonce != null && revealNonce !== consumedRevealNonce) {
60350
60423
  setConsumedRevealNonce(revealNonce);
@@ -60857,7 +60930,7 @@ import {
60857
60930
  } from "@hyperframes/core/audio-groups";
60858
60931
 
60859
60932
  // src/components/editor/useFxLevelling.ts
60860
- import { useRef as useRef106, useState as useState85 } from "react";
60933
+ import { useRef as useRef106, useState as useState86 } from "react";
60861
60934
  import {
60862
60935
  HF_AUDIO_FX_ATTR as HF_AUDIO_FX_ATTR5,
60863
60936
  serializeAudioFxChain as serializeAudioFxChain4
@@ -60915,7 +60988,7 @@ function useFxLevelling(element, chain, automation, onSetAttributeQuiet, onSetAt
60915
60988
  }
60916
60989
  };
60917
60990
  const auditionTransport = useAuditionTransport();
60918
- const [auditioningLevel, setAuditioningLevel] = useState85(false);
60991
+ const [auditioningLevel, setAuditioningLevel] = useState86(false);
60919
60992
  const auditionRun = useRef106(0);
60920
60993
  const stopLevelAudition = () => {
60921
60994
  setAuditioningLevel(false);
@@ -61070,7 +61143,7 @@ function AudioFxGroup({
61070
61143
  }
61071
61144
  };
61072
61145
  const removeNodeAutomation = (nodeId) => removeNodesAutomation([nodeId]);
61073
- const [analysing, setAnalysing] = useState86(false);
61146
+ const [analysing, setAnalysing] = useState87(false);
61074
61147
  const storeElements = usePlayerStore((s) => s.elements);
61075
61148
  const signalPath = useMemo54(() => {
61076
61149
  const doc = element.element?.ownerDocument;
@@ -61208,13 +61281,13 @@ function useVolumeAutomation(element, currentTime, onSetAttributeQuiet) {
61208
61281
  }
61209
61282
 
61210
61283
  // src/components/editor/useAudioFxRevealSection.ts
61211
- import { useEffect as useEffect88, useState as useState87 } from "react";
61284
+ import { useEffect as useEffect88, useState as useState88 } from "react";
61212
61285
  function useAudioFxRevealSection(input) {
61213
61286
  const revealedAudioFxTarget = usePlayerStore((s) => s.revealedAudioFxTarget);
61214
61287
  const timelineProjectId = usePlayerStore((s) => s.timelineProjectId);
61215
61288
  const timelineSessionEpoch = usePlayerStore((s) => s.timelineSessionEpoch);
61216
61289
  const clearRevealedAudioFxTarget = usePlayerStore((s) => s.clearRevealedAudioFxTarget);
61217
- const [consumed, setConsumed] = useState87(null);
61290
+ const [consumed, setConsumed] = useState88(null);
61218
61291
  useEffect88(() => {
61219
61292
  if (consumed === null) return;
61220
61293
  return () => clearRevealedAudioFxTarget(consumed);
@@ -61230,7 +61303,7 @@ function useAudioFxRevealSection(input) {
61230
61303
  }
61231
61304
 
61232
61305
  // src/components/editor/propertyPanelFlatMediaSection.tsx
61233
- import { useEffect as useEffect89, useState as useState88 } from "react";
61306
+ import { useEffect as useEffect89, useState as useState89 } from "react";
61234
61307
 
61235
61308
  // src/components/editor/propertyPanelFlatToggle.tsx
61236
61309
  import { jsx as jsx169, jsxs as jsxs130 } from "react/jsx-runtime";
@@ -61384,11 +61457,11 @@ function FlatMediaSection({
61384
61457
  const objectFit = styles["object-fit"] || "contain";
61385
61458
  const objectPosition = styles["object-position"] || "center";
61386
61459
  const srcAttr = el.getAttribute("src") ?? "";
61387
- const [copied, setCopied] = useState88(false);
61388
- const [removeBusy, setRemoveBusy] = useState88(false);
61389
- const [removeProgress, setRemoveProgress] = useState88(null);
61390
- const [createPlate, setCreatePlate] = useState88(false);
61391
- const [quality, setQuality] = useState88("balanced");
61460
+ const [copied, setCopied] = useState89(false);
61461
+ const [removeBusy, setRemoveBusy] = useState89(false);
61462
+ const [removeProgress, setRemoveProgress] = useState89(null);
61463
+ const [createPlate, setCreatePlate] = useState89(false);
61464
+ const [quality, setQuality] = useState89("balanced");
61392
61465
  const absoluteSrc = projectDir && srcAttr && !srcAttr.startsWith("http") ? `${projectDir}/${srcAttr}` : srcAttr;
61393
61466
  const projectSrc = srcAttr && !/^(?:https?:|data:|blob:)/i.test(srcAttr) ? stripQueryAndHash(srcAttr.startsWith("./") ? srcAttr.slice(2) : srcAttr) : "";
61394
61467
  const canRemoveBackground = Boolean(onRemoveBackground && isVisualMedia && projectSrc);
@@ -61748,7 +61821,7 @@ function createGsapLivePreview(iframeRef) {
61748
61821
  }
61749
61822
 
61750
61823
  // src/components/editor/propertyPanelFlatColorGradingSection.tsx
61751
- import { useEffect as useEffect95, useMemo as useMemo56, useRef as useRef114, useState as useState94 } from "react";
61824
+ import { useEffect as useEffect95, useMemo as useMemo56, useRef as useRef114, useState as useState95 } from "react";
61752
61825
  import {
61753
61826
  HF_COLOR_GRADING_GRADE_PRESETS,
61754
61827
  normalizeHfColorGrading as normalizeHfColorGrading5,
@@ -61780,7 +61853,7 @@ function presetPreviewHandlers({
61780
61853
  }
61781
61854
 
61782
61855
  // src/components/editor/propertyPanelColorCurves.tsx
61783
- import { useState as useState90 } from "react";
61856
+ import { useState as useState91 } from "react";
61784
61857
 
61785
61858
  // src/components/editor/propertyPanelColorCurveGraph.tsx
61786
61859
  import { useMemo as useMemo55, useRef as useRef107 } from "react";
@@ -62206,7 +62279,7 @@ function formatPointValue(value, tab, axis) {
62206
62279
  }
62207
62280
 
62208
62281
  // src/components/editor/propertyPanelGradingNumberField.tsx
62209
- import { useEffect as useEffect90, useRef as useRef108, useState as useState89 } from "react";
62282
+ import { useEffect as useEffect90, useRef as useRef108, useState as useState90 } from "react";
62210
62283
  import { jsx as jsx172, jsxs as jsxs133 } from "react/jsx-runtime";
62211
62284
  function GradingNumberField({
62212
62285
  label,
@@ -62224,7 +62297,7 @@ function GradingNumberField({
62224
62297
  onSettle,
62225
62298
  onCancel
62226
62299
  }) {
62227
- const [draft, setDraft] = useState89(() => formatValue2(value));
62300
+ const [draft, setDraft] = useState90(() => formatValue2(value));
62228
62301
  const focusedRef = useRef108(false);
62229
62302
  const cancelBlurRef = useRef108(false);
62230
62303
  const baselineRef = useRef108(value);
@@ -62313,8 +62386,8 @@ function ColorCurves({
62313
62386
  onPreview,
62314
62387
  onCommit
62315
62388
  }) {
62316
- const [activeKey, setActiveKey] = useState90("master");
62317
- const [selectedIndex, setSelectedIndex] = useState90(null);
62389
+ const [activeKey, setActiveKey] = useState91("master");
62390
+ const [selectedIndex, setSelectedIndex] = useState91(null);
62318
62391
  const { draft, setDraft, transaction } = useInspectorGestureDraft({
62319
62392
  sourceValue: value,
62320
62393
  onPreview,
@@ -62458,10 +62531,10 @@ function ColorCurves({
62458
62531
  }
62459
62532
 
62460
62533
  // src/components/editor/propertyPanelColorScopes.tsx
62461
- import { useEffect as useEffect92, useRef as useRef110, useState as useState92 } from "react";
62534
+ import { useEffect as useEffect92, useRef as useRef110, useState as useState93 } from "react";
62462
62535
 
62463
62536
  // src/components/editor/useColorGradingScopes.ts
62464
- import { useEffect as useEffect91, useRef as useRef109, useState as useState91 } from "react";
62537
+ import { useEffect as useEffect91, useRef as useRef109, useState as useState92 } from "react";
62465
62538
 
62466
62539
  // src/components/editor/colorGradingFrameAnalysis.ts
62467
62540
  import {
@@ -62618,9 +62691,9 @@ function useColorGradingScopes({
62618
62691
  captureFrame,
62619
62692
  refreshKey
62620
62693
  }) {
62621
- const [analysis, setAnalysis] = useState91(null);
62622
- const [status, setStatus] = useState91("idle");
62623
- const [refreshVersion, setRefreshVersion] = useState91(0);
62694
+ const [analysis, setAnalysis] = useState92(null);
62695
+ const [status, setStatus] = useState92("idle");
62696
+ const [refreshVersion, setRefreshVersion] = useState92(0);
62624
62697
  const captureRef = useRef109(captureFrame);
62625
62698
  captureRef.current = captureFrame;
62626
62699
  useEffect91(() => {
@@ -62797,8 +62870,8 @@ function PropertyPanelColorScopes({
62797
62870
  captureFrame,
62798
62871
  refreshKey
62799
62872
  }) {
62800
- const [open, setOpen] = useState92(false);
62801
- const [mode, setMode] = useState92("waveform");
62873
+ const [open, setOpen] = useState93(false);
62874
+ const [mode, setMode] = useState93("waveform");
62802
62875
  const canvasRef = useRef110(null);
62803
62876
  const { analysis, status, refresh } = useColorGradingScopes({
62804
62877
  open,
@@ -62869,7 +62942,7 @@ function PropertyPanelColorScopes({
62869
62942
  }
62870
62943
 
62871
62944
  // src/components/editor/propertyPanelColorSecondary.tsx
62872
- import { useEffect as useEffect93, useRef as useRef111, useState as useState93 } from "react";
62945
+ import { useEffect as useEffect93, useRef as useRef111, useState as useState94 } from "react";
62873
62946
  import {
62874
62947
  getHfColorGradingCapabilities,
62875
62948
  normalizeHfColorGrading as normalizeHfColorGrading4
@@ -62913,12 +62986,12 @@ function PropertyPanelColorSecondary({
62913
62986
  captureFrame,
62914
62987
  onCommit
62915
62988
  }) {
62916
- const [selectedIndex, setSelectedIndex] = useState93(0);
62917
- const [sampleFrame, setSampleFrame] = useState93(null);
62918
- const [samplePixels, setSamplePixels] = useState93(null);
62919
- const [showMatte, setShowMatte] = useState93(false);
62920
- const [captureError, setCaptureError] = useState93(null);
62921
- const [sampling, setSampling] = useState93(false);
62989
+ const [selectedIndex, setSelectedIndex] = useState94(0);
62990
+ const [sampleFrame, setSampleFrame] = useState94(null);
62991
+ const [samplePixels, setSamplePixels] = useState94(null);
62992
+ const [showMatte, setShowMatte] = useState94(false);
62993
+ const [captureError, setCaptureError] = useState94(null);
62994
+ const [sampling, setSampling] = useState94(false);
62922
62995
  const matteCanvasRef = useRef111(null);
62923
62996
  const activeIndex = Math.min(selectedIndex, Math.max(0, secondaries.length - 1));
62924
62997
  const selected = secondaries[activeIndex];
@@ -63767,8 +63840,8 @@ function FlatColorGradingSection({
63767
63840
  }) {
63768
63841
  const track2 = useTrackDesignInput();
63769
63842
  const lutInputRef = useRef114(null);
63770
- const [lutOpen, setLutOpen] = useState94(false);
63771
- const [detailSettingsOpen, setDetailSettingsOpen] = useState94(null);
63843
+ const [lutOpen, setLutOpen] = useState95(false);
63844
+ const [detailSettingsOpen, setDetailSettingsOpen] = useState95(null);
63772
63845
  const lutAssets = useMemo56(
63773
63846
  () => assets.filter((asset) => LUT_EXT.test(asset)).sort((a, b) => a.localeCompare(b)),
63774
63847
  [assets]
@@ -64154,7 +64227,7 @@ function FlatColorGradingSection({
64154
64227
  }
64155
64228
 
64156
64229
  // src/components/editor/propertyPanelFlatEffectsSection.tsx
64157
- import { useEffect as useEffect96, useState as useState95 } from "react";
64230
+ import { useEffect as useEffect96, useState as useState96 } from "react";
64158
64231
  import {
64159
64232
  HF_COLOR_GRADING_EFFECT_APPLY_DEFAULTS as HF_COLOR_GRADING_EFFECT_APPLY_DEFAULTS3,
64160
64233
  HF_COLOR_GRADING_EFFECT_PRESETS,
@@ -64530,9 +64603,9 @@ function FlatEffectsSection({
64530
64603
  }) {
64531
64604
  const track2 = useTrackDesignInput();
64532
64605
  const activeEffects = EFFECT_SPECS.filter((effect) => grading.effects[effect.key] > 1e-4);
64533
- const [catalogOpen, setCatalogOpen] = useState95(activeEffects.length === 0);
64534
- const [catalogGroup, setCatalogGroup] = useState95(EFFECT_GROUPS[0].label);
64535
- const [selectedKey, setSelectedKey] = useState95(
64606
+ const [catalogOpen, setCatalogOpen] = useState96(activeEffects.length === 0);
64607
+ const [catalogGroup, setCatalogGroup] = useState96(EFFECT_GROUPS[0].label);
64608
+ const [selectedKey, setSelectedKey] = useState96(
64536
64609
  activeEffects[0]?.key ?? null
64537
64610
  );
64538
64611
  const selectedEffect = activeEffects.find((effect) => effect.key === selectedKey) ?? activeEffects[0] ?? null;
@@ -64921,10 +64994,10 @@ function FlatEffectsSection({
64921
64994
  }
64922
64995
 
64923
64996
  // src/components/editor/propertyPanelFlatOverlaysSection.tsx
64924
- import { useState as useState97 } from "react";
64997
+ import { useState as useState98 } from "react";
64925
64998
 
64926
64999
  // src/hooks/useBlockCatalog.ts
64927
- import { useState as useState96, useEffect as useEffect97, useMemo as useMemo57 } from "react";
65000
+ import { useState as useState97, useEffect as useEffect97, useMemo as useMemo57 } from "react";
64928
65001
 
64929
65002
  // src/utils/blockCategories.ts
64930
65003
  import {
@@ -64967,11 +65040,11 @@ function loadCatalog() {
64967
65040
  return catalogRequest;
64968
65041
  }
64969
65042
  function useBlockCatalog() {
64970
- const [blocks, setBlocks] = useState96(() => catalogCache ?? []);
64971
- const [loading, setLoading] = useState96(catalogCache === null);
64972
- const [error, setError] = useState96(null);
64973
- const [search, setSearch] = useState96("");
64974
- const [category, setCategory] = useState96(null);
65043
+ const [blocks, setBlocks] = useState97(() => catalogCache ?? []);
65044
+ const [loading, setLoading] = useState97(catalogCache === null);
65045
+ const [error, setError] = useState97(null);
65046
+ const [search, setSearch] = useState97("");
65047
+ const [category, setCategory] = useState97(null);
64975
65048
  useEffect97(() => {
64976
65049
  if (catalogCache) return;
64977
65050
  let cancelled = false;
@@ -65039,8 +65112,8 @@ function FlatOverlaysSection({
65039
65112
  const track2 = useTrackDesignInput();
65040
65113
  const { blocks, loading, error } = useBlockCatalog();
65041
65114
  const overlays = filterMediaTreatmentOverlays(blocks);
65042
- const [adding, setAdding] = useState97(null);
65043
- const [previewing, setPreviewing] = useState97(null);
65115
+ const [adding, setAdding] = useState98(null);
65116
+ const [previewing, setPreviewing] = useState98(null);
65044
65117
  if (loading) {
65045
65118
  return /* @__PURE__ */ jsx181("div", { className: "py-4 text-center text-[10px] text-panel-text-4", children: "Loading overlays\u2026" });
65046
65119
  }
@@ -65207,7 +65280,7 @@ function PropertyPanelFlat({
65207
65280
  onUpdateSegmentEase,
65208
65281
  onSetAllKeyframeEases
65209
65282
  }) {
65210
- const [openGroupId, setOpenGroupId] = useState98(
65283
+ const [openGroupId, setOpenGroupId] = useState99(
65211
65284
  () => isTextEditableSelection(element) ? "text" : showEditableSections ? "style" : sections.media ? "media" : (
65212
65285
  // An `<hf-audio-group>` has no style, no layout and no media — its
65213
65286
  // chain is the only reason to select one. Without this the fallback
@@ -65225,7 +65298,7 @@ function PropertyPanelFlat({
65225
65298
  );
65226
65299
  const storeElements = usePlayerStore((state) => state.elements);
65227
65300
  const renderedElementId = scopedElementKey(element);
65228
- const [consumedFocus, setConsumedFocus] = useState98(focusedEaseSegment);
65301
+ const [consumedFocus, setConsumedFocus] = useState99(focusedEaseSegment);
65229
65302
  if (focusedEaseSegment !== consumedFocus) {
65230
65303
  setConsumedFocus(focusedEaseSegment);
65231
65304
  const focusesThisPanel = focusedEaseSegment !== null && // A request from a previous project/session/selection is stale: it must
@@ -65246,7 +65319,7 @@ function PropertyPanelFlat({
65246
65319
  reveal.consume(reveal.revealNonce);
65247
65320
  setOpenGroupId("audio-fx");
65248
65321
  }
65249
- const [justToggledIds, setJustToggledIds] = useState98([]);
65322
+ const [justToggledIds, setJustToggledIds] = useState99([]);
65250
65323
  const justToggledTimeoutRef = useRef115(null);
65251
65324
  const panelBodyRef = useRef115(null);
65252
65325
  useEffect98(() => {
@@ -65856,7 +65929,7 @@ var PropertyPanel = memo36(function PropertyPanel2(props) {
65856
65929
  } = props;
65857
65930
  const styles = element?.computedStyles ?? EMPTY_STYLES;
65858
65931
  const { showToast } = useStudioShellContext();
65859
- const [clipboardCopied, setClipboardCopied] = useState99(false);
65932
+ const [clipboardCopied, setClipboardCopied] = useState100(false);
65860
65933
  const clipboardTimerRef = useRef116(void 0);
65861
65934
  const timelineElements = usePlayerStore((s) => s.elements);
65862
65935
  const selectedElementId = usePlayerStore((s) => s.selectedElementId);
@@ -66261,11 +66334,11 @@ var PropertyPanel = memo36(function PropertyPanel2(props) {
66261
66334
  });
66262
66335
 
66263
66336
  // src/components/editor/FileTree.tsx
66264
- import { memo as memo38, useState as useState101, useCallback as useCallback84, useMemo as useMemo61, useRef as useRef118 } from "react";
66337
+ import { memo as memo38, useState as useState102, useCallback as useCallback84, useMemo as useMemo61, useRef as useRef118 } from "react";
66265
66338
  import { Plus as Plus2, FolderSimplePlus as FolderSimplePlus2 } from "@phosphor-icons/react";
66266
66339
 
66267
66340
  // src/components/editor/FileTreeNodes.tsx
66268
- import { memo as memo37, useState as useState100, useCallback as useCallback83, useMemo as useMemo60, useRef as useRef117, useEffect as useEffect99 } from "react";
66341
+ import { memo as memo37, useState as useState101, useCallback as useCallback83, useMemo as useMemo60, useRef as useRef117, useEffect as useEffect99 } from "react";
66269
66342
  import {
66270
66343
  PencilSimple,
66271
66344
  Copy,
@@ -66541,8 +66614,8 @@ function InlineInput({
66541
66614
  }) {
66542
66615
  const inputRef = useRef117(null);
66543
66616
  const committedRef = useRef117(false);
66544
- const [value, setValue] = useState100(defaultValue);
66545
- const [error, setError] = useState100(null);
66617
+ const [value, setValue] = useState101(defaultValue);
66618
+ const [error, setError] = useState101(null);
66546
66619
  const validate = (name) => {
66547
66620
  if (/[/\\]/.test(name)) return "Name can't contain / or \\";
66548
66621
  if (name.includes("..")) return "Name can't contain ..";
@@ -66746,7 +66819,7 @@ var TreeFolder = memo37(function TreeFolder2({
66746
66819
  dragOverFolder,
66747
66820
  lintFindingsByFile
66748
66821
  }) {
66749
- const [isOpen, setIsOpen] = useState100(defaultOpen);
66822
+ const [isOpen, setIsOpen] = useState101(defaultOpen);
66750
66823
  const toggle = useCallback83(() => setIsOpen((v) => !v), []);
66751
66824
  const children = useMemo60(() => sortChildren(node.children), [node.children]);
66752
66825
  const Chevron = isOpen ? ChevronDown : ChevronRight;
@@ -66881,10 +66954,10 @@ var FileTree = memo38(function FileTree2({
66881
66954
  }) {
66882
66955
  const tree = useMemo61(() => buildTree(files), [files]);
66883
66956
  const children = useMemo61(() => sortChildren(tree.children), [tree]);
66884
- const [contextMenu, setContextMenu] = useState101(null);
66885
- const [inlineInput, setInlineInput] = useState101(null);
66886
- const [deleteTarget, setDeleteTarget] = useState101(null);
66887
- const [dragOverFolder, setDragOverFolder] = useState101(null);
66957
+ const [contextMenu, setContextMenu] = useState102(null);
66958
+ const [inlineInput, setInlineInput] = useState102(null);
66959
+ const [deleteTarget, setDeleteTarget] = useState102(null);
66960
+ const [dragOverFolder, setDragOverFolder] = useState102(null);
66888
66961
  const dragSourceRef = useRef118(null);
66889
66962
  const hasFileOps = !!(onCreateFile || onCreateFolder || onDeleteFile || onRenameFile || onDuplicateFile);
66890
66963
  const handleContextMenu = useCallback84(
@@ -67147,7 +67220,7 @@ var FileTree = memo38(function FileTree2({
67147
67220
  });
67148
67221
 
67149
67222
  // src/App.tsx
67150
- import { useState as useState152, useCallback as useCallback177, useRef as useRef185, useMemo as useMemo77, useLayoutEffect as useLayoutEffect10 } from "react";
67223
+ import { useState as useState153, useCallback as useCallback177, useRef as useRef185, useMemo as useMemo77, useLayoutEffect as useLayoutEffect10 } from "react";
67151
67224
 
67152
67225
  // src/hooks/useRightPanelIntents.ts
67153
67226
  import { useCallback as useCallback85, useEffect as useEffect100, useRef as useRef119 } from "react";
@@ -67198,7 +67271,7 @@ function useRightPanelIntent() {
67198
67271
  }
67199
67272
 
67200
67273
  // src/components/renders/useRenderQueue.ts
67201
- import { useState as useState103, useEffect as useEffect102, useCallback as useCallback87, useRef as useRef121, useMemo as useMemo62 } from "react";
67274
+ import { useState as useState104, useEffect as useEffect102, useCallback as useCallback87, useRef as useRef121, useMemo as useMemo62 } from "react";
67202
67275
 
67203
67276
  // src/components/renders/serverError.ts
67204
67277
  async function readServerError(res) {
@@ -67216,7 +67289,7 @@ async function readServerError(res) {
67216
67289
  }
67217
67290
 
67218
67291
  // src/components/renders/useFfmpegStatus.ts
67219
- import { useCallback as useCallback86, useEffect as useEffect101, useRef as useRef120, useState as useState102 } from "react";
67292
+ import { useCallback as useCallback86, useEffect as useEffect101, useRef as useRef120, useState as useState103 } from "react";
67220
67293
  function ffmpegInstallMessage(status) {
67221
67294
  const title = status?.title ?? "FFmpeg not found";
67222
67295
  const remedy = status?.command ?? status?.hint;
@@ -67245,8 +67318,8 @@ async function probe() {
67245
67318
  }
67246
67319
  }
67247
67320
  function useFfmpegStatus() {
67248
- const [status, setStatus] = useState102(cached4);
67249
- const [checking, setChecking] = useState102(cached4 === null);
67321
+ const [status, setStatus] = useState103(cached4);
67322
+ const [checking, setChecking] = useState103(cached4 === null);
67250
67323
  const mounted = useRef120(true);
67251
67324
  useEffect101(() => {
67252
67325
  mounted.current = true;
@@ -67440,9 +67513,9 @@ function writeHiddenIds(projectId, ids) {
67440
67513
  }
67441
67514
  }
67442
67515
  function useRenderQueue(projectId, activeCompPathRef) {
67443
- const [jobs, setJobs] = useState103([]);
67444
- const [loadError, setLoadError] = useState103(null);
67445
- const [actionError, setActionError] = useState103(null);
67516
+ const [jobs, setJobs] = useState104([]);
67517
+ const [loadError, setLoadError] = useState104(null);
67518
+ const [actionError, setActionError] = useState104(null);
67446
67519
  const { status: ffmpeg, checking: ffmpegChecking, recheck: recheckFfmpeg } = useFfmpegStatus();
67447
67520
  const ffmpegMissing = ffmpeg !== null && !ffmpeg.ok;
67448
67521
  const eventSourceRef = useRef121(null);
@@ -67760,7 +67833,7 @@ function useRenderQueue(projectId, activeCompPathRef) {
67760
67833
  }
67761
67834
 
67762
67835
  // src/components/LintModal.tsx
67763
- import { useRef as useRef123, useState as useState104 } from "react";
67836
+ import { useRef as useRef123, useState as useState105 } from "react";
67764
67837
  import { XIcon, WarningIcon, CheckCircleIcon, CaretRightIcon } from "@phosphor-icons/react";
67765
67838
 
67766
67839
  // src/components/ui/useDialogBehavior.ts
@@ -67834,8 +67907,8 @@ function LintModal({
67834
67907
  const errors = findings.filter((f) => f.severity === "error");
67835
67908
  const warnings = findings.filter((f) => f.severity === "warning");
67836
67909
  const hasIssues = findings.length > 0;
67837
- const [copied, setCopied] = useState104(false);
67838
- const [copyFailed, setCopyFailed] = useState104(false);
67910
+ const [copied, setCopied] = useState105(false);
67911
+ const [copyFailed, setCopyFailed] = useState105(false);
67839
67912
  const containerRef = useRef123(null);
67840
67913
  const { requestClose } = useDialogBehavior({ open: true, onClose, containerRef });
67841
67914
  const handleCopyToAgent = async () => {
@@ -67938,7 +68011,7 @@ ${pathLine}${lines.join("\n\n")}`;
67938
68011
  }
67939
68012
 
67940
68013
  // src/components/AskAgentModal.tsx
67941
- import { useState as useState105, useRef as useRef124 } from "react";
68014
+ import { useState as useState106, useRef as useRef124 } from "react";
67942
68015
  import { jsx as jsx190, jsxs as jsxs149 } from "react/jsx-runtime";
67943
68016
  function getAgentModalPositionStyle(anchorPoint) {
67944
68017
  if (!anchorPoint || typeof window === "undefined") return void 0;
@@ -67964,7 +68037,7 @@ function AskAgentModal({
67964
68037
  onSubmit,
67965
68038
  onClose
67966
68039
  }) {
67967
- const [value, setValue] = useState105("");
68040
+ const [value, setValue] = useState106("");
67968
68041
  const inputRef = useRef124(null);
67969
68042
  const containerRef = useRef124(null);
67970
68043
  const modalPositionStyle = getAgentModalPositionStyle(anchorPoint);
@@ -68130,7 +68203,7 @@ function StudioToast({ message, tone, leaving, onDismiss }) {
68130
68203
  }
68131
68204
 
68132
68205
  // src/components/feedback/StudioFeedbackCard.tsx
68133
- import { memo as memo39, useState as useState106, useCallback as useCallback89, useRef as useRef125, useEffect as useEffect104 } from "react";
68206
+ import { memo as memo39, useState as useState107, useCallback as useCallback89, useRef as useRef125, useEffect as useEffect104 } from "react";
68134
68207
 
68135
68208
  // src/components/feedback/projectProvenance.ts
68136
68209
  var CONFIG_FILE = "hyperframes.json";
@@ -68207,13 +68280,13 @@ var THANKS_MS = 1e4;
68207
68280
  var INTERVIEW_URL = "https://calendar.app.google/yRHT7oPsHWcqFfFv5";
68208
68281
  var RATINGS = Array.from({ length: 11 }, (_, n) => n);
68209
68282
  var StudioFeedbackCard = memo39(function StudioFeedbackCard2() {
68210
- const [request, setRequest] = useState106(null);
68211
- const [step, setStep] = useState106("rating");
68212
- const [rating, setRating] = useState106(null);
68213
- const [followUp, setFollowUp] = useState106(FAILURE_FOLLOW_UP);
68214
- const [comment, setComment] = useState106("");
68215
- const [hint, setHint] = useState106(null);
68216
- const [exiting, setExiting] = useState106(false);
68283
+ const [request, setRequest] = useState107(null);
68284
+ const [step, setStep] = useState107("rating");
68285
+ const [rating, setRating] = useState107(null);
68286
+ const [followUp, setFollowUp] = useState107(FAILURE_FOLLOW_UP);
68287
+ const [comment, setComment] = useState107("");
68288
+ const [hint, setHint] = useState107(null);
68289
+ const [exiting, setExiting] = useState107(false);
68217
68290
  const inputRef = useRef125(null);
68218
68291
  const timerRef = useRef125(null);
68219
68292
  const stateRef = useRef125({ request, rating, step });
@@ -68549,7 +68622,7 @@ function SaveQueuePausedBanner({ message, onRetry }) {
68549
68622
  }
68550
68623
 
68551
68624
  // src/components/ExternalFileConflictBanner.tsx
68552
- import { useRef as useRef126, useState as useState107 } from "react";
68625
+ import { useRef as useRef126, useState as useState108 } from "react";
68553
68626
  import { Fragment as Fragment50, jsx as jsx195, jsxs as jsxs154 } from "react/jsx-runtime";
68554
68627
  function errorMessage(error) {
68555
68628
  return error instanceof Error ? error.message : String(error);
@@ -68708,7 +68781,7 @@ function FailedDraftReview({
68708
68781
  function ExternalFileConflictBanner({
68709
68782
  coordinator
68710
68783
  }) {
68711
- const [reviewing, setReviewing] = useState107(false);
68784
+ const [reviewing, setReviewing] = useState108(false);
68712
68785
  const blocked = coordinator.blocked;
68713
68786
  if (!blocked) return null;
68714
68787
  const conflict = blocked.status === "conflict" ? blocked : null;
@@ -68779,10 +68852,10 @@ function ExternalFileConflictBanner({
68779
68852
  }
68780
68853
 
68781
68854
  // src/components/ProjectUnreachableBanner.tsx
68782
- import { useEffect as useEffect105, useState as useState108 } from "react";
68855
+ import { useEffect as useEffect105, useState as useState109 } from "react";
68783
68856
  import { Fragment as Fragment51, jsx as jsx196, jsxs as jsxs155 } from "react/jsx-runtime";
68784
68857
  function ProjectUnreachableBanner({ projectId }) {
68785
- const [served, setServed] = useState108(null);
68858
+ const [served, setServed] = useState109(null);
68786
68859
  useEffect105(() => {
68787
68860
  let cancelled = false;
68788
68861
  fetch("/api/projects").then((res) => res.ok ? res.json() : { projects: [] }).then((data) => {
@@ -68992,7 +69065,7 @@ function useCaptionSync(projectId) {
68992
69065
  }
68993
69066
 
68994
69067
  // src/hooks/usePersistentEditHistory.ts
68995
- import { useCallback as useCallback91, useEffect as useEffect106, useMemo as useMemo63, useRef as useRef128, useState as useState109 } from "react";
69068
+ import { useCallback as useCallback91, useEffect as useEffect106, useMemo as useMemo63, useRef as useRef128, useState as useState110 } from "react";
68996
69069
 
68997
69070
  // src/utils/editHistory.ts
68998
69071
  var DEFAULT_MAX_ENTRIES = 100;
@@ -69349,8 +69422,8 @@ function usePersistentEditHistory(options) {
69349
69422
  [options.storage]
69350
69423
  );
69351
69424
  const now2 = options.now ?? Date.now;
69352
- const [state, setState] = useState109(() => createEmptyEditHistory());
69353
- const [loaded, setLoaded] = useState109(false);
69425
+ const [state, setState] = useState110(() => createEmptyEditHistory());
69426
+ const [loaded, setLoaded] = useState110(false);
69354
69427
  const projectId = options.projectId;
69355
69428
  const storeRef = useRef128(null);
69356
69429
  const storeProjectIdRef = useRef128(null);
@@ -69492,13 +69565,13 @@ function usePanelLayout(initialState2) {
69492
69565
  }
69493
69566
 
69494
69567
  // src/hooks/useFileManager.ts
69495
- import { useState as useState111, useCallback as useCallback96, useRef as useRef132 } from "react";
69568
+ import { useState as useState112, useCallback as useCallback96, useRef as useRef132 } from "react";
69496
69569
 
69497
69570
  // src/hooks/useFileTree.ts
69498
- import { useState as useState110, useCallback as useCallback93, useEffect as useEffect108, useMemo as useMemo64, useRef as useRef130 } from "react";
69571
+ import { useState as useState111, useCallback as useCallback93, useEffect as useEffect108, useMemo as useMemo64, useRef as useRef130 } from "react";
69499
69572
  var EMPTY_FILE_LIST = [];
69500
69573
  function useFileTree({ projectId, projectIdRef }) {
69501
- const [fetched, setFetched] = useState110(null);
69574
+ const [fetched, setFetched] = useState111(null);
69502
69575
  const current = fetched?.projectId === projectId ? fetched : null;
69503
69576
  const fileTree = current?.fileTree ?? EMPTY_FILE_LIST;
69504
69577
  const compositionPaths = current?.compositionPaths ?? EMPTY_FILE_LIST;
@@ -69840,8 +69913,8 @@ function useFileManager({
69840
69913
  recordEdit,
69841
69914
  setRefreshKey
69842
69915
  }) {
69843
- const [editingFile, setEditingFile] = useState111(null);
69844
- const [revealSourceOffset, setRevealSourceOffset] = useState111(null);
69916
+ const [editingFile, setEditingFile] = useState112(null);
69917
+ const [revealSourceOffset, setRevealSourceOffset] = useState112(null);
69845
69918
  const editingPathRef = useRef132(editingFile?.path);
69846
69919
  editingPathRef.current = editingFile?.path;
69847
69920
  const projectIdRef = useRef132(projectId);
@@ -70192,7 +70265,7 @@ function useFileManager({
70192
70265
  }
70193
70266
 
70194
70267
  // src/hooks/usePreviewPersistence.ts
70195
- import { useCallback as useCallback97, useRef as useRef133, useState as useState112 } from "react";
70268
+ import { useCallback as useCallback97, useRef as useRef133, useState as useState113 } from "react";
70196
70269
 
70197
70270
  // src/utils/gsapUndoRestore.ts
70198
70271
  function elementIdentityKey(el) {
@@ -70427,7 +70500,7 @@ function usePreviewPersistence({
70427
70500
  reloadPreview
70428
70501
  }) {
70429
70502
  void _recordEdit;
70430
- const [domEditSaveQueuePaused, setDomEditSaveQueuePaused] = useState112(null);
70503
+ const [domEditSaveQueuePaused, setDomEditSaveQueuePaused] = useState113(null);
70431
70504
  const domTextCommitVersionRef = useRef133(0);
70432
70505
  const showToastRef = useRef133(showToast);
70433
70506
  showToastRef.current = showToast;
@@ -70525,9 +70598,9 @@ function usePreviewPersistence({
70525
70598
  }
70526
70599
 
70527
70600
  // src/hooks/usePreviewDocumentVersion.ts
70528
- import { useCallback as useCallback98, useEffect as useEffect109, useRef as useRef134, useState as useState113 } from "react";
70601
+ import { useCallback as useCallback98, useEffect as useEffect109, useRef as useRef134, useState as useState114 } from "react";
70529
70602
  function usePreviewDocumentVersion() {
70530
- const [previewDocumentVersion, setPreviewDocumentVersion] = useState113(0);
70603
+ const [previewDocumentVersion, setPreviewDocumentVersion] = useState114(0);
70531
70604
  const refreshTimersRef = useRef134([]);
70532
70605
  const refresh = useCallback98(() => {
70533
70606
  for (const id of refreshTimersRef.current) clearTimeout(id);
@@ -72910,7 +72983,7 @@ function persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps,
72910
72983
  import { useCallback as useCallback133 } from "react";
72911
72984
 
72912
72985
  // src/hooks/useAskAgentModal.ts
72913
- import { useState as useState114, useCallback as useCallback111, useRef as useRef142, useEffect as useEffect110 } from "react";
72986
+ import { useState as useState115, useCallback as useCallback111, useRef as useRef142, useEffect as useEffect110 } from "react";
72914
72987
  function useAskAgentModal({
72915
72988
  activeCompPath,
72916
72989
  projectDir,
@@ -72919,13 +72992,13 @@ function useAskAgentModal({
72919
72992
  domEditSelectionRef,
72920
72993
  domEditSelection
72921
72994
  }) {
72922
- const [agentPromptTagSnippet, setAgentPromptTagSnippet] = useState114();
72923
- const [agentPromptSelectionContext, setAgentPromptSelectionContext] = useState114();
72924
- const [agentModalAnchorPoint, setAgentModalAnchorPoint] = useState114(
72995
+ const [agentPromptTagSnippet, setAgentPromptTagSnippet] = useState115();
72996
+ const [agentPromptSelectionContext, setAgentPromptSelectionContext] = useState115();
72997
+ const [agentModalAnchorPoint, setAgentModalAnchorPoint] = useState115(
72925
72998
  null
72926
72999
  );
72927
- const [copiedAgentPrompt, setCopiedAgentPrompt] = useState114(false);
72928
- const [agentModalOpen, setAgentModalOpen] = useState114(false);
73000
+ const [copiedAgentPrompt, setCopiedAgentPrompt] = useState115(false);
73001
+ const [agentModalOpen, setAgentModalOpen] = useState115(false);
72929
73002
  const copiedAgentTimerRef = useRef142(null);
72930
73003
  const preloadAgentPromptSnippet = useCallback111(
72931
73004
  async (selection) => {
@@ -73022,7 +73095,7 @@ function useAskAgentModal({
73022
73095
  }
73023
73096
 
73024
73097
  // src/hooks/useDomSelection.ts
73025
- import { useState as useState115, useCallback as useCallback112, useRef as useRef143, useEffect as useEffect112 } from "react";
73098
+ import { useState as useState116, useCallback as useCallback112, useRef as useRef143, useEffect as useEffect112 } from "react";
73026
73099
 
73027
73100
  // src/utils/domEditHelpers.ts
73028
73101
  function domEditSelectionsTargetSame(a, b) {
@@ -73245,10 +73318,10 @@ function useDomSelection({
73245
73318
  refreshKey,
73246
73319
  rightPanelTab
73247
73320
  }) {
73248
- const [domEditSelection, setDomEditSelection] = useState115(null);
73249
- const [domEditGroupSelections, setDomEditGroupSelections] = useState115([]);
73250
- const [domEditHoverSelection, setDomEditHoverSelection] = useState115(null);
73251
- const [activeGroupElement, setActiveGroupElementState] = useState115(null);
73321
+ const [domEditSelection, setDomEditSelection] = useState116(null);
73322
+ const [domEditGroupSelections, setDomEditGroupSelections] = useState116([]);
73323
+ const [domEditHoverSelection, setDomEditHoverSelection] = useState116(null);
73324
+ const [activeGroupElement, setActiveGroupElementState] = useState116(null);
73252
73325
  const rightPanelTabRef = useRef143(rightPanelTab);
73253
73326
  rightPanelTabRef.current = rightPanelTab;
73254
73327
  const domEditSelectionRef = useRef143(domEditSelection);
@@ -79445,7 +79518,7 @@ function useSdkSelectionSync(session, domEditSelection, domEditGroupSelections)
79445
79518
  import { useEffect as useEffect119 } from "react";
79446
79519
 
79447
79520
  // src/hooks/useSdkSession.ts
79448
- import { useState as useState116, useEffect as useEffect118, useCallback as useCallback134, useRef as useRef154 } from "react";
79521
+ import { useState as useState117, useEffect as useEffect118, useCallback as useCallback134, useRef as useRef154 } from "react";
79449
79522
  import { openComposition as openComposition3 } from "@hyperframes/sdk";
79450
79523
 
79451
79524
  // src/hooks/externalFileReloadBus.ts
@@ -79555,7 +79628,7 @@ function disposeSdkSession(session) {
79555
79628
  }
79556
79629
  }
79557
79630
  function useSdkSession(projectId, activeCompPath, fileTree = [], fileTreeLoaded = false) {
79558
- const [ownedSession, setOwnedSession] = useState116(null);
79631
+ const [ownedSession, setOwnedSession] = useState117(null);
79559
79632
  const ownedSessionRef = useRef154(null);
79560
79633
  const sessionOwnersRef = useRef154(/* @__PURE__ */ new WeakMap());
79561
79634
  const generationRef = useRef154(0);
@@ -79563,10 +79636,10 @@ function useSdkSession(projectId, activeCompPath, fileTree = [], fileTreeLoaded
79563
79636
  projectIdRef.current = projectId;
79564
79637
  const activeCompPathRef = useRef154(activeCompPath);
79565
79638
  activeCompPathRef.current = activeCompPath;
79566
- const [reloadToken, setReloadToken] = useState116(0);
79639
+ const [reloadToken, setReloadToken] = useState117(0);
79567
79640
  const reloadTokenRef = useRef154(reloadToken);
79568
79641
  reloadTokenRef.current = reloadToken;
79569
- const [unreachableProject, setUnreachableProject] = useState116(null);
79642
+ const [unreachableProject, setUnreachableProject] = useState117(null);
79570
79643
  useEffect118(
79571
79644
  () => addExternalFileReloadListener((changedPath) => {
79572
79645
  if (changedPath === activeCompPathRef.current) setReloadToken((token) => token + 1);
@@ -79785,7 +79858,7 @@ async function deleteExternalConflictSnapshot(projectId, filePath) {
79785
79858
  }
79786
79859
 
79787
79860
  // src/hooks/useExternalFileChangeCoordinator.ts
79788
- import { useCallback as useCallback135, useEffect as useEffect120, useRef as useRef155, useState as useState117 } from "react";
79861
+ import { useCallback as useCallback135, useEffect as useEffect120, useRef as useRef155, useState as useState118 } from "react";
79789
79862
  function testHotAdapter() {
79790
79863
  const value = globalThis.__HF_STUDIO_HOT_TEST_ADAPTER__;
79791
79864
  if (!value || typeof value !== "object") return null;
@@ -79836,7 +79909,7 @@ function useExternalFileChangeCoordinator({
79836
79909
  resetSaveQueues,
79837
79910
  onAcceptedPersistedFileChange
79838
79911
  }) {
79839
- const [blocked, setBlocked] = useState117(null);
79912
+ const [blocked, setBlocked] = useState118(null);
79840
79913
  const generationRef = useRef155(0);
79841
79914
  const mountedRef = useRef155(true);
79842
79915
  const lastEventIdentityRef = useRef155(null);
@@ -79933,7 +80006,7 @@ function useExternalFileChangeCoordinator({
79933
80006
  }
79934
80007
  if (!mountedRef.current || generation !== generationRef.current) return;
79935
80008
  setBlocked(null);
79936
- onAcceptedPersistedFileChange(path);
80009
+ onAcceptedPersistedFileChange(path, readFileChangeAffectedCompositions(payload));
79937
80010
  reloadAcceptedGeneration(path);
79938
80011
  return;
79939
80012
  }
@@ -80043,7 +80116,7 @@ function useExternalFileChangeCoordinator({
80043
80116
  const ownWriteToken = consumeStudioWriteToken(token);
80044
80117
  const ownContentEcho = content != null && isSelfWriteEcho(path, content);
80045
80118
  if (ownWriteToken || ownContentEcho) {
80046
- onAcceptedPersistedFileChange(path);
80119
+ onAcceptedPersistedFileChange(path, readFileChangeAffectedCompositions(payload));
80047
80120
  logReload("suppressed", {
80048
80121
  path,
80049
80122
  why: ownWriteToken ? "own write token" : "own content echo"
@@ -80088,7 +80161,7 @@ function useExternalFileChangeCoordinator({
80088
80161
  onUseExternalFile?.(path, external);
80089
80162
  await deleteConflictSnapshot?.(projectId, path);
80090
80163
  setBlocked(null);
80091
- onAcceptedPersistedFileChange(path);
80164
+ onAcceptedPersistedFileChange(path, readFileChangeAffectedCompositions(current.payload));
80092
80165
  reloadAcceptedGeneration(path);
80093
80166
  },
80094
80167
  [
@@ -80170,8 +80243,10 @@ function useStudioExternalFileChanges({
80170
80243
  }) {
80171
80244
  const { flushPendingSourceSave, discardPendingSourceSave } = fileManager;
80172
80245
  const { drainPendingDomEditSaves, resetDomEditSaveQueueBreaker } = previewPersistence;
80173
- const bumpThumbnailContentRevision = usePlayerStore(
80174
- (state) => state.bumpThumbnailContentRevision
80246
+ const bumpThumbnailRevisions = usePlayerStore((state) => state.bumpThumbnailRevisions);
80247
+ const onAcceptedPersistedFileChange = useCallback136(
80248
+ (_path, affectedCompositions) => bumpThumbnailRevisions(affectedCompositions),
80249
+ [bumpThumbnailRevisions]
80175
80250
  );
80176
80251
  const drainPendingChanges = useCallback136(async () => {
80177
80252
  const source = await flushPendingSourceSave();
@@ -80200,12 +80275,12 @@ function useStudioExternalFileChanges({
80200
80275
  readProjectFile: fileManager.readProjectFile,
80201
80276
  onUseExternalFile: fileManager.updateEditingFileContent,
80202
80277
  resetSaveQueues: resetDomEditSaveQueueBreaker,
80203
- onAcceptedPersistedFileChange: bumpThumbnailContentRevision
80278
+ onAcceptedPersistedFileChange
80204
80279
  });
80205
80280
  }
80206
80281
 
80207
80282
  // src/hooks/useBlockHandlers.ts
80208
- import { useCallback as useCallback137, useMemo as useMemo67, useRef as useRef156, useState as useState118 } from "react";
80283
+ import { useCallback as useCallback137, useMemo as useMemo67, useRef as useRef156, useState as useState119 } from "react";
80209
80284
 
80210
80285
  // src/utils/blockInstaller.ts
80211
80286
  function getMaxZIndexFromIframe(iframe) {
@@ -80395,7 +80470,7 @@ function useBlockHandlers({
80395
80470
  setRightCollapsed,
80396
80471
  setRightPanelTab
80397
80472
  }) {
80398
- const [activeBlockParams, setActiveBlockParams] = useState118(null);
80473
+ const [activeBlockParams, setActiveBlockParams] = useState119(null);
80399
80474
  const blockCtx = useMemo67(
80400
80475
  () => ({
80401
80476
  activeCompPath: blockCtxDeps.activeCompPath,
@@ -81644,9 +81719,9 @@ function useCaptionDetection({
81644
81719
  }
81645
81720
 
81646
81721
  // src/hooks/useConsoleErrorCapture.ts
81647
- import { useCallback as useCallback141, useEffect as useEffect123, useRef as useRef160, useState as useState119 } from "react";
81722
+ import { useCallback as useCallback141, useEffect as useEffect123, useRef as useRef160, useState as useState120 } from "react";
81648
81723
  function useConsoleErrorCapture(previewIframe) {
81649
- const [consoleErrors, setConsoleErrors] = useState119(null);
81724
+ const [consoleErrors, setConsoleErrors] = useState120(null);
81650
81725
  const consoleErrorsRef = useRef160([]);
81651
81726
  const resetErrors = useCallback141(() => {
81652
81727
  consoleErrorsRef.current = [];
@@ -81717,15 +81792,15 @@ function useConsoleErrorCapture(previewIframe) {
81717
81792
  }
81718
81793
 
81719
81794
  // src/hooks/useFrameCapture.ts
81720
- import { useState as useState120, useCallback as useCallback142, useRef as useRef161 } from "react";
81795
+ import { useState as useState121, useCallback as useCallback142, useRef as useRef161 } from "react";
81721
81796
  function useFrameCapture({
81722
81797
  projectId,
81723
81798
  activeCompPath,
81724
81799
  showToast,
81725
81800
  waitForPendingDomEditSaves
81726
81801
  }) {
81727
- const [captureFrameTime, setCaptureFrameTime] = useState120(0);
81728
- const [capturing, setCapturing] = useState120(false);
81802
+ const [captureFrameTime, setCaptureFrameTime] = useState121(0);
81803
+ const [capturing, setCapturing] = useState121(false);
81729
81804
  const capturingRef = useRef161(false);
81730
81805
  useMountEffect(() => {
81731
81806
  setCaptureFrameTime(usePlayerStore.getState().currentTime);
@@ -81811,7 +81886,7 @@ function useFrameCapture({
81811
81886
  }
81812
81887
 
81813
81888
  // src/hooks/useLintModal.ts
81814
- import { useState as useState121, useCallback as useCallback143, useEffect as useEffect124, useRef as useRef162, useMemo as useMemo69 } from "react";
81889
+ import { useState as useState122, useCallback as useCallback143, useEffect as useEffect124, useRef as useRef162, useMemo as useMemo69 } from "react";
81815
81890
  function parseFinding(f) {
81816
81891
  return {
81817
81892
  severity: f.severity === "error" ? "error" : "warning",
@@ -81822,9 +81897,9 @@ function parseFinding(f) {
81822
81897
  };
81823
81898
  }
81824
81899
  function useLintModal(projectId, refreshKey) {
81825
- const [lintModal, setLintModal] = useState121(null);
81826
- const [linting, setLinting] = useState121(false);
81827
- const [backgroundFindings, setBackgroundFindings] = useState121([]);
81900
+ const [lintModal, setLintModal] = useState122(null);
81901
+ const [linting, setLinting] = useState122(false);
81902
+ const [backgroundFindings, setBackgroundFindings] = useState122([]);
81828
81903
  const autoLintRanRef = useRef162(false);
81829
81904
  const runLint = useCallback143(
81830
81905
  async (opts) => {
@@ -81902,13 +81977,13 @@ function useLintModal(projectId, refreshKey) {
81902
81977
  }
81903
81978
 
81904
81979
  // src/hooks/useToast.ts
81905
- import { useState as useState122, useCallback as useCallback144, useRef as useRef163 } from "react";
81980
+ import { useState as useState123, useCallback as useCallback144, useRef as useRef163 } from "react";
81906
81981
  var AUTO_DISMISS_MS2 = 4e3;
81907
81982
  var EXIT_MS2 = 160;
81908
81983
  var MAX_TOASTS = 3;
81909
81984
  var nextToastId = 1;
81910
81985
  function useToast() {
81911
- const [toasts, setToasts] = useState122([]);
81986
+ const [toasts, setToasts] = useState123([]);
81912
81987
  const timersRef = useRef163(/* @__PURE__ */ new Map());
81913
81988
  const clearTimer = useCallback144((id) => {
81914
81989
  const timer = timersRef.current.get(id);
@@ -81959,7 +82034,7 @@ function useToast() {
81959
82034
  }
81960
82035
 
81961
82036
  // src/hooks/useStudioUrlState.ts
81962
- import { useCallback as useCallback145, useEffect as useEffect125, useRef as useRef164, useState as useState123 } from "react";
82037
+ import { useCallback as useCallback145, useEffect as useEffect125, useRef as useRef164, useState as useState124 } from "react";
81963
82038
 
81964
82039
  // src/utils/studioUrlState.ts
81965
82040
  var VALID_TABS = ["layers", "design", "renders", "slideshow", "variables"];
@@ -82194,7 +82269,7 @@ function useStudioUrlState({
82194
82269
  const hydratedSeekRef = useRef164(initialState2.currentTime == null);
82195
82270
  const hydratedInitialTimeRef = useRef164(initialState2.currentTime == null);
82196
82271
  const hydratedSelectionRef = useRef164(initialState2.selection == null);
82197
- const [selectionHydrated, setSelectionHydrated] = useState123(initialState2.selection == null);
82272
+ const [selectionHydrated, setSelectionHydrated] = useState124(initialState2.selection == null);
82198
82273
  const pendingSelectionRef = useRef164(initialState2.selection);
82199
82274
  const stableTimeRef = useRef164(initialState2.currentTime);
82200
82275
  const selectionApplySeqRef = useRef164(0);
@@ -82425,10 +82500,10 @@ function useGlobalFileDrop(handleTimelineFileDrop) {
82425
82500
  }
82426
82501
 
82427
82502
  // src/hooks/useGestureCommit.ts
82428
- import { useState as useState125, useCallback as useCallback148, useRef as useRef166, useEffect as useEffect127 } from "react";
82503
+ import { useState as useState126, useCallback as useCallback148, useRef as useRef166, useEffect as useEffect127 } from "react";
82429
82504
 
82430
82505
  // src/hooks/useGestureRecording.ts
82431
- import { useCallback as useCallback147, useEffect as useEffect126, useRef as useRef165, useState as useState124 } from "react";
82506
+ import { useCallback as useCallback147, useEffect as useEffect126, useRef as useRef165, useState as useState125 } from "react";
82432
82507
  function readBasePosition(element, iframeEl) {
82433
82508
  let baseOpacity = 1;
82434
82509
  let baseScale = 1;
@@ -82571,8 +82646,8 @@ function releaseRuntimePreview(r) {
82571
82646
  r.runtime = null;
82572
82647
  }
82573
82648
  function useGestureRecording() {
82574
- const [isRecording, setIsRecording] = useState124(false);
82575
- const [recordingDuration, setRecordingDuration] = useState124(0);
82649
+ const [isRecording, setIsRecording] = useState125(false);
82650
+ const [recordingDuration, setRecordingDuration] = useState125(0);
82576
82651
  const isRecordingRef = useRef165(false);
82577
82652
  const refs = useRef165(createRecordingRefs());
82578
82653
  const samplesRef = useRef165(refs.current.samples);
@@ -82955,7 +83030,7 @@ function useGestureCommit({
82955
83030
  readOnlyPreview
82956
83031
  }) {
82957
83032
  const gestureRecording = useGestureRecording();
82958
- const [gestureState, setGestureState] = useState125("idle");
83033
+ const [gestureState, setGestureState] = useState126("idle");
82959
83034
  const gestureStateRef = useRef166("idle");
82960
83035
  const recordingAutoStopRef = useRef166(void 0);
82961
83036
  const recordingStartTimeRef = useRef166(0);
@@ -83315,7 +83390,7 @@ var GestureTrailOverlay = memo40(function GestureTrailOverlay2({
83315
83390
  import { useCallback as useCallback156 } from "react";
83316
83391
 
83317
83392
  // src/components/MediaPreview.tsx
83318
- import { useState as useState126 } from "react";
83393
+ import { useState as useState127 } from "react";
83319
83394
  import { jsx as jsx198, jsxs as jsxs157 } from "react/jsx-runtime";
83320
83395
  function MediaErrorPanel({ name, filePath }) {
83321
83396
  return /* @__PURE__ */ jsxs157("div", { className: "flex flex-col items-center justify-center h-full p-4 bg-neutral-950 gap-2", children: [
@@ -83345,7 +83420,7 @@ function MediaErrorPanel({ name, filePath }) {
83345
83420
  function MediaPreview({ projectId, filePath }) {
83346
83421
  const serveUrl = buildProjectApiPath(projectId, `/preview/${filePath}`);
83347
83422
  const name = filePath.split("/").pop() ?? filePath;
83348
- const [failedPath, setFailedPath] = useState126(null);
83423
+ const [failedPath, setFailedPath] = useState127(null);
83349
83424
  const failed2 = failedPath === filePath;
83350
83425
  const setFailed = () => setFailedPath(filePath);
83351
83426
  if (failed2) return /* @__PURE__ */ jsx198(MediaErrorPanel, { name, filePath });
@@ -83431,7 +83506,7 @@ function MediaPreview({ projectId, filePath }) {
83431
83506
  }
83432
83507
 
83433
83508
  // src/components/sidebar/AssetsTab.tsx
83434
- import { memo as memo41, useState as useState132, useCallback as useCallback152, useRef as useRef170, useMemo as useMemo74, useEffect as useEffect133 } from "react";
83509
+ import { memo as memo41, useState as useState133, useCallback as useCallback152, useRef as useRef170, useMemo as useMemo74, useEffect as useEffect133 } from "react";
83435
83510
 
83436
83511
  // src/components/ui/SearchInput.tsx
83437
83512
  import { jsx as jsx199, jsxs as jsxs158 } from "react/jsx-runtime";
@@ -83542,11 +83617,11 @@ var CATEGORY_LABELS = {
83542
83617
  var FILTER_ORDER = ["audio", "images", "video", "fonts"];
83543
83618
 
83544
83619
  // src/components/sidebar/AudioRow.tsx
83545
- import { useState as useState128, useRef as useRef168, useEffect as useEffect129, useCallback as useCallback150 } from "react";
83620
+ import { useState as useState129, useRef as useRef168, useEffect as useEffect129, useCallback as useCallback150 } from "react";
83546
83621
  import { classifyWebAudioMediaRoute } from "@hyperframes/core/runtime/web-audio-route";
83547
83622
 
83548
83623
  // src/components/sidebar/AssetContextMenu.tsx
83549
- import { useCallback as useCallback149, useEffect as useEffect128, useLayoutEffect as useLayoutEffect8, useRef as useRef167, useState as useState127 } from "react";
83624
+ import { useCallback as useCallback149, useEffect as useEffect128, useLayoutEffect as useLayoutEffect8, useRef as useRef167, useState as useState128 } from "react";
83550
83625
  import { Fragment as Fragment53, jsx as jsx200, jsxs as jsxs159 } from "react/jsx-runtime";
83551
83626
  function isValidAssetName(name) {
83552
83627
  return name.length > 0 && !/[/\\]/.test(name) && !name.includes("..");
@@ -83562,10 +83637,10 @@ function ContextMenu3({
83562
83637
  onAddAtPlayhead
83563
83638
  }) {
83564
83639
  const menuRef = useRef167(null);
83565
- const [pos, setPos] = useState127({ x, y });
83566
- const [mode, setMode] = useState127("menu");
83567
- const [renameDraft, setRenameDraft] = useState127(() => filename(asset));
83568
- const [renameError, setRenameError] = useState127(null);
83640
+ const [pos, setPos] = useState128({ x, y });
83641
+ const [mode, setMode] = useState128("menu");
83642
+ const [renameDraft, setRenameDraft] = useState128(() => filename(asset));
83643
+ const [renameError, setRenameError] = useState128(null);
83569
83644
  useLayoutEffect8(() => {
83570
83645
  const el = menuRef.current;
83571
83646
  if (!el) return;
@@ -83809,9 +83884,9 @@ function AudioRow({
83809
83884
  onRename,
83810
83885
  onAddAssetToTimeline
83811
83886
  }) {
83812
- const [contextMenu, setContextMenu] = useState128(null);
83813
- const [playing, setPlaying] = useState128(false);
83814
- const [bars, setBars] = useState128([]);
83887
+ const [contextMenu, setContextMenu] = useState129(null);
83888
+ const [playing, setPlaying] = useState129(false);
83889
+ const [bars, setBars] = useState129([]);
83815
83890
  const audioRef = useRef168(null);
83816
83891
  const actxRef = useRef168(null);
83817
83892
  const analyserRef = useRef168(null);
@@ -84043,7 +84118,7 @@ function AudioRow({
84043
84118
  }
84044
84119
 
84045
84120
  // src/components/sidebar/GlobalAssetsView.tsx
84046
- import { useEffect as useEffect130, useMemo as useMemo73, useState as useState129 } from "react";
84121
+ import { useEffect as useEffect130, useMemo as useMemo73, useState as useState130 } from "react";
84047
84122
  import { jsx as jsx202, jsxs as jsxs161 } from "react/jsx-runtime";
84048
84123
  function globalAssetRows(records, query = "") {
84049
84124
  const q = query.trim().toLowerCase();
@@ -84058,7 +84133,7 @@ function globalAssetRows(records, query = "") {
84058
84133
  }));
84059
84134
  }
84060
84135
  function GlobalAssetsView({ searchQuery }) {
84061
- const [records, setRecords] = useState129(null);
84136
+ const [records, setRecords] = useState130(null);
84062
84137
  useEffect130(() => {
84063
84138
  let cancelled = false;
84064
84139
  fetch("/api/assets/global").then((r) => r.ok ? r.json() : { assets: [] }).then((d) => {
@@ -84102,17 +84177,17 @@ function GlobalAssetsView({ searchQuery }) {
84102
84177
  }
84103
84178
 
84104
84179
  // src/components/sidebar/AssetCard.tsx
84105
- import { useState as useState131, useEffect as useEffect132, useRef as useRef169, useCallback as useCallback151 } from "react";
84180
+ import { useState as useState132, useEffect as useEffect132, useRef as useRef169, useCallback as useCallback151 } from "react";
84106
84181
 
84107
84182
  // src/components/ui/VideoFrameThumbnail.tsx
84108
- import { useState as useState130, useEffect as useEffect131 } from "react";
84183
+ import { useState as useState131, useEffect as useEffect131 } from "react";
84109
84184
  import { jsx as jsx203 } from "react/jsx-runtime";
84110
84185
  function VideoFrameThumbnail({
84111
84186
  src,
84112
84187
  fallbackLabel
84113
84188
  }) {
84114
- const [frame, setFrame] = useState130(null);
84115
- const [failed2, setFailed] = useState130(false);
84189
+ const [frame, setFrame] = useState131(null);
84190
+ const [failed2, setFailed] = useState131(false);
84116
84191
  useEffect131(() => {
84117
84192
  setFailed(false);
84118
84193
  const video = document.createElement("video");
@@ -84179,7 +84254,7 @@ function openAssetContextMenu(e, setContextMenu) {
84179
84254
  setContextMenu({ x: e.clientX, y: e.clientY });
84180
84255
  }
84181
84256
  function useProbedDuration(src, skip) {
84182
- const [duration, setDuration] = useState131(void 0);
84257
+ const [duration, setDuration] = useState132(void 0);
84183
84258
  useEffect132(() => {
84184
84259
  if (skip) return;
84185
84260
  let cancelled = false;
@@ -84230,9 +84305,9 @@ function AssetCard({
84230
84305
  onRename,
84231
84306
  onAddAssetToTimeline
84232
84307
  }) {
84233
- const [contextMenu, setContextMenu] = useState131(null);
84234
- const [hovered, setHovered] = useState131(false);
84235
- const [imgError, setImgError] = useState131(false);
84308
+ const [contextMenu, setContextMenu] = useState132(null);
84309
+ const [hovered, setHovered] = useState132(false);
84310
+ const [imgError, setImgError] = useState132(false);
84236
84311
  const isCopied = copyFeedback?.path === asset && copyFeedback.ok;
84237
84312
  const fullName = asset.split("/").pop() ?? asset;
84238
84313
  const name = basename2(asset);
@@ -84374,7 +84449,7 @@ function FontRow({
84374
84449
  onRename,
84375
84450
  onAddAssetToTimeline
84376
84451
  }) {
84377
- const [contextMenu, setContextMenu] = useState131(null);
84452
+ const [contextMenu, setContextMenu] = useState132(null);
84378
84453
  const name = basename2(asset);
84379
84454
  const extension = ext(asset);
84380
84455
  const isCopied = copyFeedback?.path === asset && copyFeedback.ok;
@@ -84569,14 +84644,14 @@ var AssetsTab = memo41(function AssetsTab2({
84569
84644
  onAddAssetToTimeline
84570
84645
  }) {
84571
84646
  const fileInputRef = useRef170(null);
84572
- const [dragOver, setDragOver] = useState132(false);
84573
- const [copyFeedback, setCopyFeedback] = useState132(null);
84574
- const [importing, setImporting] = useState132(false);
84575
- const [activeFilter, setActiveFilter] = useState132("all");
84576
- const [usageFilter, setUsageFilter] = useState132("all");
84577
- const [searchQuery, setSearchQuery] = useState132("");
84578
- const [viewMode, setViewMode] = useState132("local");
84579
- const [manifest, setManifest] = useState132(/* @__PURE__ */ new Map());
84647
+ const [dragOver, setDragOver] = useState133(false);
84648
+ const [copyFeedback, setCopyFeedback] = useState133(null);
84649
+ const [importing, setImporting] = useState133(false);
84650
+ const [activeFilter, setActiveFilter] = useState133("all");
84651
+ const [usageFilter, setUsageFilter] = useState133("all");
84652
+ const [searchQuery, setSearchQuery] = useState133("");
84653
+ const [viewMode, setViewMode] = useState133("local");
84654
+ const [manifest, setManifest] = useState133(/* @__PURE__ */ new Map());
84580
84655
  const manifest404Ref = useRef170(/* @__PURE__ */ new Set());
84581
84656
  const assetsKey = assets.join("|");
84582
84657
  useEffect133(() => {
@@ -84836,20 +84911,20 @@ var AssetsTab = memo41(function AssetsTab2({
84836
84911
  });
84837
84912
 
84838
84913
  // src/components/sidebar/BlocksTab.tsx
84839
- import { memo as memo42, useState as useState134, useCallback as useCallback154, useRef as useRef172, useEffect as useEffect135 } from "react";
84914
+ import { memo as memo42, useState as useState135, useCallback as useCallback154, useRef as useRef172, useEffect as useEffect135 } from "react";
84840
84915
  import { createPortal as createPortal9 } from "react-dom";
84841
84916
 
84842
84917
  // src/components/sidebar/PromptPreviewModal.tsx
84843
- import { useState as useState133, useCallback as useCallback153, useEffect as useEffect134, useRef as useRef171 } from "react";
84918
+ import { useState as useState134, useCallback as useCallback153, useEffect as useEffect134, useRef as useRef171 } from "react";
84844
84919
  import { jsx as jsx206, jsxs as jsxs164 } from "react/jsx-runtime";
84845
84920
  function PromptPreviewModal({
84846
84921
  title,
84847
84922
  prompt,
84848
84923
  onClose
84849
84924
  }) {
84850
- const [value, setValue] = useState133(prompt);
84851
- const [copyState, setCopyState] = useState133("idle");
84852
- const [entered, setEntered] = useState133(false);
84925
+ const [value, setValue] = useState134(prompt);
84926
+ const [copyState, setCopyState] = useState134("idle");
84927
+ const [entered, setEntered] = useState134(false);
84853
84928
  const containerRef = useRef171(null);
84854
84929
  const textareaRef = useRef171(null);
84855
84930
  const valueRef = useRef171(value);
@@ -84962,7 +85037,7 @@ function PromptPreviewModal({
84962
85037
  import { jsx as jsx207, jsxs as jsxs165 } from "react/jsx-runtime";
84963
85038
  var BlocksTab = memo42(function BlocksTab2({ onAddBlock, onPreviewBlock }) {
84964
85039
  const { loading, error, search, setSearch, category, setCategory, filteredBlocks } = useBlockCatalog();
84965
- const [promptModal, setPromptModal] = useState134(null);
85040
+ const [promptModal, setPromptModal] = useState135(null);
84966
85041
  if (loading) {
84967
85042
  return /* @__PURE__ */ jsx207("div", { className: "flex flex-1 items-center justify-center text-neutral-600 text-xs", children: "Loading blocks\u2026" });
84968
85043
  }
@@ -85147,8 +85222,8 @@ function BlockCard({
85147
85222
  onShowPrompt,
85148
85223
  onPreview
85149
85224
  }) {
85150
- const [hovered, setHovered] = useState134(false);
85151
- const [addState, setAddState] = useState134("idle");
85225
+ const [hovered, setHovered] = useState135(false);
85226
+ const [addState, setAddState] = useState135("idle");
85152
85227
  const hoverTimer = useRef172(null);
85153
85228
  const colors = getCategoryColors(category);
85154
85229
  const needsWebGL = tags?.includes("html-in-canvas") || tags?.includes("webgl");
@@ -85327,7 +85402,7 @@ function BlockCard({
85327
85402
  }
85328
85403
 
85329
85404
  // src/components/sidebar/CompositionsTab.tsx
85330
- import { memo as memo43, useCallback as useCallback155, useEffect as useEffect136, useRef as useRef173, useState as useState135 } from "react";
85405
+ import { memo as memo43, useCallback as useCallback155, useEffect as useEffect136, useRef as useRef173, useState as useState136 } from "react";
85331
85406
  import { jsx as jsx208, jsxs as jsxs166 } from "react/jsx-runtime";
85332
85407
  var DEFAULT_PREVIEW_STAGE = { width: 1920, height: 1080 };
85333
85408
  var CARD_W = 80;
@@ -85397,10 +85472,10 @@ function CompCard({
85397
85472
  onAddToTimeline,
85398
85473
  contentRevision
85399
85474
  }) {
85400
- const [hovered, setHovered] = useState135(false);
85401
- const [stageSize, setStageSize] = useState135(DEFAULT_PREVIEW_STAGE);
85402
- const [livePreviewLoaded, setLivePreviewLoaded] = useState135(false);
85403
- const [failedThumbnailUrl, setFailedThumbnailUrl] = useState135(null);
85475
+ const [hovered, setHovered] = useState136(false);
85476
+ const [stageSize, setStageSize] = useState136(DEFAULT_PREVIEW_STAGE);
85477
+ const [livePreviewLoaded, setLivePreviewLoaded] = useState136(false);
85478
+ const [failedThumbnailUrl, setFailedThumbnailUrl] = useState136(null);
85404
85479
  const iframeRef = useRef173(null);
85405
85480
  const hoverTimer = useRef173(null);
85406
85481
  const syncTimer = useRef173(null);
@@ -85627,7 +85702,7 @@ var CompositionsTab = memo43(function CompositionsTab2({
85627
85702
  isRendering,
85628
85703
  lintFindingsByFile
85629
85704
  }) {
85630
- const contentRevision = usePlayerStore((state) => state.thumbnailContentRevision);
85705
+ const thumbnailRevisions = usePlayerStore((state) => state.thumbnailRevisions);
85631
85706
  if (compositions.length === 0) {
85632
85707
  return /* @__PURE__ */ jsx208("div", { className: "flex-1 flex items-center justify-center px-4", children: /* @__PURE__ */ jsx208("p", { className: "text-xs text-neutral-600 text-center", children: "No compositions found" }) });
85633
85708
  }
@@ -85643,7 +85718,7 @@ var CompositionsTab = memo43(function CompositionsTab2({
85643
85718
  onAddToTimeline: onAddToTimeline ? () => onAddToTimeline(comp) : void 0,
85644
85719
  isRendering,
85645
85720
  lintInfo: lintFindingsByFile?.get(comp),
85646
- contentRevision
85721
+ contentRevision: thumbnailRevisionOf(thumbnailRevisions, comp)
85647
85722
  },
85648
85723
  `${projectId}:${comp}`
85649
85724
  )) });
@@ -85883,10 +85958,10 @@ function CodeBody({
85883
85958
  import { useCallback as useCallback172 } from "react";
85884
85959
 
85885
85960
  // src/components/editor/LayersPanel.tsx
85886
- import { memo as memo44, useState as useState137, useCallback as useCallback158, useEffect as useEffect137, useRef as useRef175 } from "react";
85961
+ import { memo as memo44, useState as useState138, useCallback as useCallback158, useEffect as useEffect137, useRef as useRef175 } from "react";
85887
85962
 
85888
85963
  // src/components/editor/useLayerDrag.ts
85889
- import { useRef as useRef174, useState as useState136, useCallback as useCallback157 } from "react";
85964
+ import { useRef as useRef174, useState as useState137, useCallback as useCallback157 } from "react";
85890
85965
  var DRAG_THRESHOLD_PX4 = 4;
85891
85966
  function isLayerDraggable(layer) {
85892
85967
  if (!(layer.selector || layer.id)) return false;
@@ -85954,8 +86029,8 @@ function useLayerDrag({
85954
86029
  onSingleSibling
85955
86030
  }) {
85956
86031
  const dragRef = useRef174(null);
85957
- const [dragKey, setDragKey] = useState136(null);
85958
- const [insertionLineY, setInsertionLineY] = useState136(null);
86032
+ const [dragKey, setDragKey] = useState137(null);
86033
+ const [insertionLineY, setInsertionLineY] = useState137(null);
85959
86034
  const handleRowPointerDown = useCallback157(
85960
86035
  (layerIndex, e) => {
85961
86036
  if (e.button !== 0) return;
@@ -86157,8 +86232,8 @@ var LayersPanel = memo44(function LayersPanel2() {
86157
86232
  handleDomZIndexReorderCommit,
86158
86233
  setActiveGroupElement
86159
86234
  } = useDomEditContext();
86160
- const [layers, setLayers] = useState137([]);
86161
- const [collapsed, setCollapsed] = useState137({});
86235
+ const [layers, setLayers] = useState138([]);
86236
+ const [collapsed, setCollapsed] = useState138({});
86162
86237
  const prevDocVersionRef = useRef175(0);
86163
86238
  const scrollContainerRef = useRef175(null);
86164
86239
  const mirrorLayerReorderToTimeline = useLayerReorderTimelineMirror();
@@ -86497,13 +86572,13 @@ var LayersPanel = memo44(function LayersPanel2() {
86497
86572
  });
86498
86573
 
86499
86574
  // src/captions/components/CaptionPropertyPanel.tsx
86500
- import { memo as memo46, useCallback as useCallback160, useState as useState139 } from "react";
86575
+ import { memo as memo46, useCallback as useCallback160, useState as useState140 } from "react";
86501
86576
 
86502
86577
  // src/captions/components/CaptionAnimationPanel.tsx
86503
86578
  import { memo as memo45, useCallback as useCallback159 } from "react";
86504
86579
 
86505
86580
  // src/captions/components/shared.tsx
86506
- import { useEffect as useEffect138, useRef as useRef176, useState as useState138 } from "react";
86581
+ import { useEffect as useEffect138, useRef as useRef176, useState as useState139 } from "react";
86507
86582
  import { jsx as jsx213, jsxs as jsxs170 } from "react/jsx-runtime";
86508
86583
  var inputCls = "w-full bg-neutral-900 border border-neutral-800 rounded-sm px-1.5 py-0.5 text-2xs text-neutral-200 font-mono outline-hidden focus:border-studio-accent disabled:opacity-40 disabled:cursor-not-allowed";
86509
86584
  function Section2({ label, children }) {
@@ -86528,7 +86603,7 @@ function NumberField2({
86528
86603
  ariaLabel,
86529
86604
  onCommit
86530
86605
  }) {
86531
- const [draft, setDraft] = useState138(null);
86606
+ const [draft, setDraft] = useState139(null);
86532
86607
  const focusedRef = useRef176(false);
86533
86608
  useEffect138(() => {
86534
86609
  if (!focusedRef.current) setDraft(null);
@@ -86824,7 +86899,7 @@ var CaptionPropertyPanel = memo46(function CaptionPropertyPanel2({
86824
86899
  const selectedGroupId = useCaptionStore((s) => s.selectedGroupId);
86825
86900
  const updateSelectedStyle = useCaptionStore((s) => s.updateSelectedStyle);
86826
86901
  const updateGroupStyle = useCaptionStore((s) => s.updateGroupStyle);
86827
- const [activeTab, setActiveTab] = useState139("style");
86902
+ const [activeTab, setActiveTab] = useState140("style");
86828
86903
  const firstSegmentId = selectedSegmentIds.size > 0 ? [...selectedSegmentIds][0] : void 0;
86829
86904
  const firstSegment = model?.segments.get(firstSegmentId ?? "");
86830
86905
  let ownerGroupId = null;
@@ -87022,7 +87097,7 @@ var CaptionPropertyPanel = memo46(function CaptionPropertyPanel2({
87022
87097
  });
87023
87098
 
87024
87099
  // src/components/editor/BlockParamsPanel.tsx
87025
- import { memo as memo47, useCallback as useCallback161, useEffect as useEffect139, useRef as useRef177, useState as useState140 } from "react";
87100
+ import { memo as memo47, useCallback as useCallback161, useEffect as useEffect139, useRef as useRef177, useState as useState141 } from "react";
87026
87101
  import { jsx as jsx216, jsxs as jsxs173 } from "react/jsx-runtime";
87027
87102
  var BlockParamsPanel = memo47(function BlockParamsPanel2({
87028
87103
  blockName,
@@ -87033,7 +87108,7 @@ var BlockParamsPanel = memo47(function BlockParamsPanel2({
87033
87108
  }) {
87034
87109
  const fileManager = useFileManagerContextOptional();
87035
87110
  const { setRefreshKey } = useStudioPlaybackContext();
87036
- const [values, setValues] = useState140(() => {
87111
+ const [values, setValues] = useState141(() => {
87037
87112
  const initial = {};
87038
87113
  for (const p of params) {
87039
87114
  initial[p.key] = p.default;
@@ -87043,7 +87118,7 @@ var BlockParamsPanel = memo47(function BlockParamsPanel2({
87043
87118
  const appliedRef = useRef177(
87044
87119
  Object.fromEntries(params.map((p) => [p.key, p.default]))
87045
87120
  );
87046
- const [commitState, setCommitState] = useState140({ tone: "idle" });
87121
+ const [commitState, setCommitState] = useState141({ tone: "idle" });
87047
87122
  const commitTimersRef = useRef177(/* @__PURE__ */ new Map());
87048
87123
  const commitParamNow = useCallback161(
87049
87124
  async (key2, nextValue) => {
@@ -87253,12 +87328,12 @@ function ParamControl({
87253
87328
  import { memo as memo51 } from "react";
87254
87329
 
87255
87330
  // src/components/renders/RenderQueue.tsx
87256
- import { memo as memo50, useState as useState143, useRef as useRef179, useEffect as useEffect141, useLayoutEffect as useLayoutEffect9, useId as useId7 } from "react";
87331
+ import { memo as memo50, useState as useState144, useRef as useRef179, useEffect as useEffect141, useLayoutEffect as useLayoutEffect9, useId as useId7 } from "react";
87257
87332
  import { createPortal as createPortal10 } from "react-dom";
87258
87333
  import { CANVAS_DIMENSIONS } from "@hyperframes/parsers";
87259
87334
 
87260
87335
  // src/components/renders/RenderQueueItem.tsx
87261
- import { memo as memo48, useCallback as useCallback162, useState as useState141 } from "react";
87336
+ import { memo as memo48, useCallback as useCallback162, useState as useState142 } from "react";
87262
87337
  import { Fragment as Fragment58, jsx as jsx217, jsxs as jsxs174 } from "react/jsx-runtime";
87263
87338
  function formatDuration2(ms) {
87264
87339
  if (ms < 1e3) return `${ms}ms`;
@@ -87277,9 +87352,9 @@ var RenderQueueItem = memo48(function RenderQueueItem2({
87277
87352
  onDelete,
87278
87353
  onCancel
87279
87354
  }) {
87280
- const [hovered, setHovered] = useState141(false);
87281
- const [videoReady, setVideoReady] = useState141(false);
87282
- const [confirmingDelete, setConfirmingDelete] = useState141(false);
87355
+ const [hovered, setHovered] = useState142(false);
87356
+ const [videoReady, setVideoReady] = useState142(false);
87357
+ const [confirmingDelete, setConfirmingDelete] = useState142(false);
87283
87358
  const fileSrc = buildProjectApiPath(projectId, `/renders/file/${job.filename}`);
87284
87359
  const handleOpen = useCallback162(() => {
87285
87360
  window.open(fileSrc, "_blank");
@@ -87484,7 +87559,7 @@ var RenderQueueItem = memo48(function RenderQueueItem2({
87484
87559
  });
87485
87560
 
87486
87561
  // src/components/renders/FfmpegRequiredNotice.tsx
87487
- import { memo as memo49, useEffect as useEffect140, useRef as useRef178, useState as useState142 } from "react";
87562
+ import { memo as memo49, useEffect as useEffect140, useRef as useRef178, useState as useState143 } from "react";
87488
87563
  import { jsx as jsx218, jsxs as jsxs175 } from "react/jsx-runtime";
87489
87564
  var DOWNLOAD_URL = "https://ffmpeg.org/download.html";
87490
87565
  var CUE_MS = 1600;
@@ -87494,8 +87569,8 @@ var FfmpegRequiredNotice = memo49(function FfmpegRequiredNotice2({
87494
87569
  checking,
87495
87570
  onRecheck
87496
87571
  }) {
87497
- const [copied, setCopied] = useState142(false);
87498
- const [recheckFailed, setRecheckFailed] = useState142(false);
87572
+ const [copied, setCopied] = useState143(false);
87573
+ const [recheckFailed, setRecheckFailed] = useState143(false);
87499
87574
  const wasChecking = useRef178(false);
87500
87575
  const cueTimer = useRef178(void 0);
87501
87576
  useEffect140(() => {
@@ -87625,8 +87700,8 @@ var FORMAT_INFO = {
87625
87700
  };
87626
87701
  var FORMAT_PANEL_SIZE = { width: 208, height: 150 };
87627
87702
  function FormatInfoTooltip({ format }) {
87628
- const [open, setOpen] = useState143(false);
87629
- const [position, setPosition] = useState143(null);
87703
+ const [open, setOpen] = useState144(false);
87704
+ const [position, setPosition] = useState144(null);
87630
87705
  const triggerRef = useRef179(null);
87631
87706
  const timeoutRef = useRef179(void 0);
87632
87707
  const panelId = useId7();
@@ -87747,10 +87822,10 @@ function FormatExportButton({
87747
87822
  onRecheckFfmpeg
87748
87823
  }) {
87749
87824
  const persisted = getPersistedRenderSettings();
87750
- const [format, setFormat] = useState143(persisted.format);
87751
- const [quality, setQuality] = useState143(persisted.quality);
87752
- const [resolution, setResolution] = useState143("auto");
87753
- const [fps, setFps] = useState143(persisted.fps);
87825
+ const [format, setFormat] = useState144(persisted.format);
87826
+ const [quality, setQuality] = useState144(persisted.quality);
87827
+ const [resolution, setResolution] = useState144("auto");
87828
+ const [fps, setFps] = useState144(persisted.fps);
87754
87829
  const missingFfmpeg = ffmpeg && !ffmpeg.ok ? ffmpeg : null;
87755
87830
  const showQuality = format !== "mov";
87756
87831
  return /* @__PURE__ */ jsxs176("div", { className: "flex flex-col gap-3", children: [
@@ -88032,11 +88107,11 @@ var RenderQueuePanel = memo51(function RenderQueuePanel2() {
88032
88107
  });
88033
88108
 
88034
88109
  // src/components/panels/SlideshowPanel.tsx
88035
- import { useState as useState145, useEffect as useEffect142, useCallback as useCallback164, useRef as useRef180 } from "react";
88110
+ import { useState as useState146, useEffect as useEffect142, useCallback as useCallback164, useRef as useRef180 } from "react";
88036
88111
  import { parseSlideshowManifest } from "@hyperframes/core/slideshow";
88037
88112
 
88038
88113
  // src/components/panels/SlideshowSubPanels.tsx
88039
- import { useState as useState144, useCallback as useCallback163, useId as useId8 } from "react";
88114
+ import { useState as useState145, useCallback as useCallback163, useId as useId8 } from "react";
88040
88115
  import { jsx as jsx221, jsxs as jsxs177 } from "react/jsx-runtime";
88041
88116
  function SectionHeader({
88042
88117
  children,
@@ -88222,7 +88297,7 @@ function BranchTree({
88222
88297
  selectedSequenceId,
88223
88298
  onSelectBranchSlide
88224
88299
  }) {
88225
- const [newLabel, setNewLabel] = useState144("");
88300
+ const [newLabel, setNewLabel] = useState145("");
88226
88301
  const inputId = useId8();
88227
88302
  const handleCreate = useCallback163(() => {
88228
88303
  const label = newLabel.trim();
@@ -88283,9 +88358,9 @@ function BranchItem({
88283
88358
  selectedSequenceId,
88284
88359
  onSelectBranchSlide
88285
88360
  }) {
88286
- const [editing, setEditing] = useState144(false);
88287
- const [draft, setDraft] = useState144(seq.label);
88288
- const [confirmingDelete, setConfirmingDelete] = useState144(false);
88361
+ const [editing, setEditing] = useState145(false);
88362
+ const [draft, setDraft] = useState145(seq.label);
88363
+ const [confirmingDelete, setConfirmingDelete] = useState145(false);
88289
88364
  const commitRename = useCallback163(() => {
88290
88365
  const label = draft.trim();
88291
88366
  if (label && label !== seq.label) onRename(seq.id, label);
@@ -88413,8 +88488,8 @@ function HotspotTool({
88413
88488
  onAddHotspot,
88414
88489
  onRemoveHotspot
88415
88490
  }) {
88416
- const [targetSequenceId, setTargetSequenceId] = useState144("");
88417
- const [hotspotLabel, setHotspotLabel] = useState144("");
88491
+ const [targetSequenceId, setTargetSequenceId] = useState145("");
88492
+ const [hotspotLabel, setHotspotLabel] = useState145("");
88418
88493
  const hotspots = slide?.hotspots ?? [];
88419
88494
  const selectedElementId = domEditSelection?.element?.id ?? null;
88420
88495
  const selectedHfId = domEditSelection?.hfId ?? null;
@@ -88707,19 +88782,19 @@ function makeSlideshowNotesController() {
88707
88782
  function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
88708
88783
  const { editingFile } = useFileManagerContext();
88709
88784
  const compHtml = editingFile?.content ?? null;
88710
- const [manifest, setManifest] = useState145(() => {
88785
+ const [manifest, setManifest] = useState146(() => {
88711
88786
  if (!compHtml) return { slides: [] };
88712
88787
  return safeParseManifest(compHtml);
88713
88788
  });
88714
- const [selectedSceneId, setSelectedSceneId] = useState145(null);
88715
- const [selectedSequenceId, setSelectedSequenceId] = useState145(null);
88716
- const [expandedSections, setExpandedSections] = useState145(
88789
+ const [selectedSceneId, setSelectedSceneId] = useState146(null);
88790
+ const [selectedSequenceId, setSelectedSequenceId] = useState146(null);
88791
+ const [expandedSections, setExpandedSections] = useState146(
88717
88792
  () => /* @__PURE__ */ new Set(["slides", "inspector"])
88718
88793
  );
88719
- const [persistError, setPersistError] = useState145(false);
88720
- const [retrying, setRetrying] = useState145(false);
88794
+ const [persistError, setPersistError] = useState146(false);
88795
+ const [retrying, setRetrying] = useState146(false);
88721
88796
  const undoStackRef = useRef180([]);
88722
- const [undoDepth, setUndoDepth] = useState145(0);
88797
+ const [undoDepth, setUndoDepth] = useState146(0);
88723
88798
  const currentTime = usePlayerStore((s) => s.currentTime);
88724
88799
  const { domEditSelection } = useDomEditSelectionContext();
88725
88800
  const manifestRef = useRef180(manifest);
@@ -89048,7 +89123,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
89048
89123
  }
89049
89124
 
89050
89125
  // src/components/panels/VariablesPanel.tsx
89051
- import { memo as memo52, useCallback as useCallback168, useEffect as useEffect144, useMemo as useMemo75, useState as useState149 } from "react";
89126
+ import { memo as memo52, useCallback as useCallback168, useEffect as useEffect144, useMemo as useMemo75, useState as useState150 } from "react";
89052
89127
 
89053
89128
  // src/hooks/useVariablesPersist.ts
89054
89129
  import { useCallback as useCallback165 } from "react";
@@ -89096,10 +89171,10 @@ function useVariablesPersist({
89096
89171
  }
89097
89172
 
89098
89173
  // src/components/panels/VariablesOtherCompositions.tsx
89099
- import { useCallback as useCallback167, useState as useState148 } from "react";
89174
+ import { useCallback as useCallback167, useState as useState149 } from "react";
89100
89175
 
89101
89176
  // src/hooks/useProjectCompositionVariables.ts
89102
- import { useCallback as useCallback166, useEffect as useEffect143, useState as useState146 } from "react";
89177
+ import { useCallback as useCallback166, useEffect as useEffect143, useState as useState147 } from "react";
89103
89178
  import { openComposition as openComposition4 } from "@hyperframes/sdk";
89104
89179
  async function readGroup(path, readProjectFile) {
89105
89180
  let content;
@@ -89122,7 +89197,7 @@ async function readGroup(path, readProjectFile) {
89122
89197
  }
89123
89198
  }
89124
89199
  function useProjectCompositionVariables(fileTree, excludePath, readProjectFile, refreshKey) {
89125
- const [groups, setGroups] = useState146([]);
89200
+ const [groups, setGroups] = useState147([]);
89126
89201
  useEffect143(() => {
89127
89202
  let cancelled = false;
89128
89203
  const htmlFiles = fileTree.filter((p) => p.endsWith(".html") && p !== excludePath);
@@ -89172,7 +89247,7 @@ function useEditVariablesInFile(deps) {
89172
89247
  }
89173
89248
 
89174
89249
  // src/components/panels/VariablesDeclarationForm.tsx
89175
- import { useState as useState147 } from "react";
89250
+ import { useState as useState148 } from "react";
89176
89251
  import { jsx as jsx223, jsxs as jsxs179 } from "react/jsx-runtime";
89177
89252
  var VARIABLE_TYPES = [
89178
89253
  "string",
@@ -89314,8 +89389,8 @@ function DeclarationForm({
89314
89389
  onSubmit,
89315
89390
  onCancel
89316
89391
  }) {
89317
- const [draft, setDraft] = useState147(initial);
89318
- const [error, setError] = useState147(null);
89392
+ const [draft, setDraft] = useState148(initial);
89393
+ const [error, setError] = useState148(null);
89319
89394
  const editingExisting = initial.id.length > 0;
89320
89395
  const set = (patch) => setDraft((d) => ({ ...d, ...patch }));
89321
89396
  const submit = () => {
@@ -89505,7 +89580,7 @@ function VariablesOtherCompositions({
89505
89580
  recordEdit,
89506
89581
  reloadPreview
89507
89582
  }) {
89508
- const [selfRefresh, setSelfRefresh] = useState148(0);
89583
+ const [selfRefresh, setSelfRefresh] = useState149(0);
89509
89584
  const groups = useProjectCompositionVariables(
89510
89585
  fileTree,
89511
89586
  excludePath,
@@ -89518,7 +89593,7 @@ function VariablesOtherCompositions({
89518
89593
  recordEdit,
89519
89594
  reloadPreview
89520
89595
  });
89521
- const [editingKey, setEditingKey] = useState148(null);
89596
+ const [editingKey, setEditingKey] = useState149(null);
89522
89597
  const onSave = useCallback167(
89523
89598
  (path, decl) => {
89524
89599
  setEditingKey(null);
@@ -89728,13 +89803,13 @@ var VariablesPanel = memo52(function VariablesPanel2({
89728
89803
  const effectiveCompPath = activeCompPath ?? resolveMasterCompositionPath(compositions);
89729
89804
  const previewValues = usePreviewVariablesStore((s) => s.values);
89730
89805
  const setPreviewValues = usePreviewVariablesStore((s) => s.setValues);
89731
- const [revision, setRevision] = useState149(0);
89806
+ const [revision, setRevision] = useState150(0);
89732
89807
  useEffect144(() => {
89733
89808
  if (!sdkSession) return;
89734
89809
  return sdkSession.on("change", () => setRevision((r) => r + 1));
89735
89810
  }, [sdkSession]);
89736
- const [addOpen, setAddOpen] = useState149(false);
89737
- const [editingId, setEditingId] = useState149(null);
89811
+ const [addOpen, setAddOpen] = useState150(false);
89812
+ const [editingId, setEditingId] = useState150(null);
89738
89813
  const persistVariables = useVariablesPersist({
89739
89814
  sdkSession,
89740
89815
  activeCompPath: effectiveCompPath,
@@ -91612,7 +91687,7 @@ function StudioSplash({ waiting }) {
91612
91687
  }
91613
91688
 
91614
91689
  // src/hooks/useServerConnection.ts
91615
- import { useEffect as useEffect148, useState as useState150 } from "react";
91690
+ import { useEffect as useEffect148, useState as useState151 } from "react";
91616
91691
  async function resolveHashProject(id) {
91617
91692
  try {
91618
91693
  const res = await fetch(`/api/projects/${encodeURIComponent(id)}`);
@@ -91642,9 +91717,9 @@ function reportHashVerdict(stage, verdict) {
91642
91717
  });
91643
91718
  }
91644
91719
  function useServerConnection() {
91645
- const [projectId, setProjectId] = useState150(null);
91646
- const [resolving, setResolving] = useState150(true);
91647
- const [waitingForServer, setWaitingForServer] = useState150(false);
91720
+ const [projectId, setProjectId] = useState151(null);
91721
+ const [resolving, setResolving] = useState151(true);
91722
+ const [waitingForServer, setWaitingForServer] = useState151(false);
91648
91723
  useMountEffect(() => {
91649
91724
  const hashProjectId = parseProjectIdFromHash(window.location.hash);
91650
91725
  let cancelled = false;
@@ -91735,7 +91810,7 @@ function useTimelineAddAtPlayhead(addAsset, addComposition) {
91735
91810
  }
91736
91811
 
91737
91812
  // src/hooks/useActiveComposition.ts
91738
- import { useState as useState151 } from "react";
91813
+ import { useState as useState152 } from "react";
91739
91814
 
91740
91815
  // src/hooks/useHydrateActiveCompPathFromUrl.ts
91741
91816
  import { useEffect as useEffect150 } from "react";
@@ -91839,8 +91914,8 @@ function useActiveComposition({
91839
91914
  setEditingFile,
91840
91915
  showToast
91841
91916
  }) {
91842
- const [activeCompPath, setActiveCompPath] = useState151(null);
91843
- const [activeCompPathHydrated, setActiveCompPathHydrated] = useState151(
91917
+ const [activeCompPath, setActiveCompPath] = useState152(null);
91918
+ const [activeCompPathHydrated, setActiveCompPathHydrated] = useState152(
91844
91919
  () => isHydratedFromUrlState(initialUrlStateRef.current)
91845
91920
  );
91846
91921
  useResetSelectionOnProjectSwitch({
@@ -91880,12 +91955,12 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
91880
91955
  const { projectId, resolving, waitingForServer } = useServerConnection();
91881
91956
  const initialUrlStateRef = useRef185(readStudioUrlStateFromWindow());
91882
91957
  useStudioSessionStart(projectId, resolving, waitingForServer);
91883
- const [compIdToSrc, setCompIdToSrc] = useState152(/* @__PURE__ */ new Map());
91958
+ const [compIdToSrc, setCompIdToSrc] = useState153(/* @__PURE__ */ new Map());
91884
91959
  const previewIframe = useOwnPreviewIframe();
91885
- const [compositionLoading, setCompositionLoading] = useState152(true);
91886
- const [refreshKey, setRefreshKey] = useState152(0);
91960
+ const [compositionLoading, setCompositionLoading] = useState153(true);
91961
+ const [refreshKey, setRefreshKey] = useState153(0);
91887
91962
  const [previewDocumentVersion, refreshPreviewDocumentVersion] = usePreviewDocumentVersion();
91888
- const [blockPreview, setBlockPreview] = useState152(null);
91963
+ const [blockPreview, setBlockPreview] = useState153(null);
91889
91964
  const previewIframeRef = useRef185(null);
91890
91965
  const captionEditMode = useCaptionStore((s) => s.isEditMode);
91891
91966
  const captionHasSelection = useCaptionStore((s) => s.selectedSegmentIds.size > 0);
@@ -92387,10 +92462,10 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
92387
92462
  }
92388
92463
 
92389
92464
  // src/hooks/useElementPicker.ts
92390
- import { useState as useState153, useCallback as useCallback178, useRef as useRef186 } from "react";
92465
+ import { useState as useState154, useCallback as useCallback178, useRef as useRef186 } from "react";
92391
92466
  function useElementPicker(iframeRef, options) {
92392
- const [isPickMode, setIsPickMode] = useState153(false);
92393
- const [pickedElement, setPickedElement] = useState153(null);
92467
+ const [isPickMode, setIsPickMode] = useState154(false);
92468
+ const [pickedElement, setPickedElement] = useState154(null);
92394
92469
  const activeOverrideRef = useRef186(null);
92395
92470
  const getActiveIframe = useCallback178(() => {
92396
92471
  return activeOverrideRef.current ?? iframeRef.current;