@bendyline/squisq-editor-react 2.13.14 → 2.13.16

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.
@@ -19,7 +19,7 @@ import {
19
19
  useDictationState,
20
20
  useEditorContext,
21
21
  useEditorContextOptional
22
- } from "./chunk-D2QFSFG2.js";
22
+ } from "./chunk-UQUYPT5P.js";
23
23
  import {
24
24
  monacoLanguageRequestKey,
25
25
  monacoLanguagesForDocument,
@@ -46,13 +46,12 @@ import {
46
46
  ShapePalette
47
47
  } from "./chunk-HLU6ZBS7.js";
48
48
  import {
49
- BlockThumbnail,
50
49
  RecorderPanel,
51
50
  buildPreviewDoc,
52
51
  documentTitleFromFileName,
53
52
  resolveBlockVisual,
54
53
  useModalDialog
55
- } from "./chunk-FOKUOC7E.js";
54
+ } from "./chunk-ECS2FFXA.js";
56
55
  import {
57
56
  Icon
58
57
  } from "./chunk-UYB5CPRE.js";
@@ -9741,10 +9740,24 @@ async function storeCopy(provider, path, file, clipboardImage) {
9741
9740
  mimeType: clipboardImage.type || "image/png"
9742
9741
  } : null);
9743
9742
  if (!copied) return null;
9744
- const existing = await readStoredFile(provider, path);
9745
- if (existing && await sameBytes(existing.data, copied.data)) return path;
9743
+ const stored = await storedCopyOf(provider, path, copied.data);
9744
+ if (stored) return stored;
9746
9745
  return provider.addMedia(await unusedName(provider, copied.name), copied.data, copied.mimeType);
9747
9746
  }
9747
+ async function storedCopyOf(provider, path, data) {
9748
+ let entries;
9749
+ try {
9750
+ entries = await provider.listMedia();
9751
+ } catch {
9752
+ return null;
9753
+ }
9754
+ const candidates = entries.filter((entry) => entry.size === data.size).sort((a, b) => Number(b.name === path) - Number(a.name === path));
9755
+ for (const { name } of candidates) {
9756
+ const existing = await readStoredFile(provider, name);
9757
+ if (existing && await sameBytes(existing.data, data)) return name;
9758
+ }
9759
+ return null;
9760
+ }
9748
9761
  async function sameBytes(a, b) {
9749
9762
  if (a.size !== b.size) return false;
9750
9763
  const [left, right] = await Promise.all([a.arrayBuffer(), b.arrayBuffer()]);
@@ -24645,10 +24658,38 @@ function renameNodeOp(diagram, nodeId, label) {
24645
24658
  if (!node2) return diagram;
24646
24659
  const clean = sanitizeAsciiLabel(label);
24647
24660
  if (clean.length === 0 || clean === node2.label) return diagram;
24648
- return {
24661
+ const renamed = {
24649
24662
  ...diagram,
24650
24663
  nodes: diagram.nodes.map((n) => n.id === nodeId ? { ...n, label: clean } : n)
24651
24664
  };
24665
+ const isContainer = diagram.nodes.some((n) => n.containerId === nodeId);
24666
+ const oldW = Math.max(node2.wCols, labelBoxWidth(node2.label, isContainer));
24667
+ const newW = Math.max(node2.wCols, labelBoxWidth(clean, isContainer));
24668
+ return makeRoomToTheRight(renamed, node2, oldW, newW);
24669
+ }
24670
+ var SIBLING_GAP = 1;
24671
+ function labelBoxWidth(label, isContainer) {
24672
+ const lines2 = label.split("\n");
24673
+ const widest = (ls) => ls.reduce((w, l2) => Math.max(w, Array.from(l2).length), 0);
24674
+ if (!isContainer) return widest(lines2) + 4;
24675
+ return Math.max(widest(lines2.slice(0, 1)) + 6, widest(lines2.slice(1)) + 4);
24676
+ }
24677
+ function makeRoomToTheRight(diagram, node2, oldW, newW) {
24678
+ if (newW <= oldW) return diagram;
24679
+ const drawnRight = node2.col + node2.wCols - 1;
24680
+ const newRight = node2.col + newW - 1;
24681
+ const r0 = node2.row - SIBLING_GAP;
24682
+ const r1 = node2.row + node2.hRows - 1 + SIBLING_GAP;
24683
+ let shift = 0;
24684
+ for (const n of diagram.nodes) {
24685
+ if (n.col <= drawnRight || n.row > r1 || n.row + n.hRows - 1 < r0) continue;
24686
+ shift = Math.max(shift, newRight + SIBLING_GAP + 1 - n.col);
24687
+ }
24688
+ if (shift === 0) return diagram;
24689
+ return {
24690
+ ...diagram,
24691
+ nodes: diagram.nodes.map((n) => n.col > drawnRight ? { ...n, col: n.col + shift } : n)
24692
+ };
24652
24693
  }
24653
24694
  function addNodeOp(diagram, opts) {
24654
24695
  let label = opts.label;
@@ -24695,7 +24736,7 @@ function removeNodeOp(diagram, nodeId) {
24695
24736
  }
24696
24737
 
24697
24738
  // src/asciiDiagram/asciiDiagramData.ts
24698
- import { useEffect as useEffect35, useMemo as useMemo29, useState as useState45 } from "react";
24739
+ import { useEffect as useEffect36, useMemo as useMemo29, useState as useState45 } from "react";
24699
24740
  import {
24700
24741
  asciiCellToCanvas,
24701
24742
  asciiDiagramToTemplateData,
@@ -24716,7 +24757,7 @@ import {
24716
24757
  } from "@bendyline/squisq/doc";
24717
24758
 
24718
24759
  // src/asciiDiagram/AsciiDiagramWidget.tsx
24719
- import { useCallback as useCallback35, useMemo as useMemo28, useRef as useRef39, useState as useState44 } from "react";
24760
+ import { useCallback as useCallback35, useEffect as useEffect35, useMemo as useMemo28, useRef as useRef39, useState as useState44 } from "react";
24720
24761
 
24721
24762
  // src/asciiDiagram/asciiDiagramCommands.ts
24722
24763
  import {
@@ -24901,7 +24942,7 @@ function applyRepairCommand(editor, blockId) {
24901
24942
  if (!repaired) return false;
24902
24943
  return replaceAsciiFenceText(editor, pos, repaired.art, "diagram");
24903
24944
  }
24904
- function applyOp(editor, blockId, op, diagramOffset) {
24945
+ function applyOp(editor, blockId, op, { diagramOffset, onRejected }) {
24905
24946
  const pos = findAsciiDiagramBlockPos(editor, blockId);
24906
24947
  if (pos === null) return false;
24907
24948
  const node2 = editor.state.doc.nodeAt(pos);
@@ -24913,12 +24954,15 @@ function applyOp(editor, blockId, op, diagramOffset) {
24913
24954
  if (next === diagram && diagram === sourceDiagram) return false;
24914
24955
  const rendered = renderAsciiDiagram(next);
24915
24956
  const verification = parseAsciiDiagram(rendered);
24916
- if (verification.nodes.length !== next.nodes.length) return false;
24957
+ if (verification.nodes.length !== next.nodes.length || verification.edges.length !== next.edges.length) {
24958
+ onRejected?.();
24959
+ return false;
24960
+ }
24917
24961
  return replaceAsciiFenceText(editor, pos, rendered, "diagram");
24918
24962
  }
24919
24963
  function applyAsciiDiagramCommand(editor, blockId, cmd, options = {}) {
24920
24964
  if (!editor.isEditable) return false;
24921
- const apply = (op) => applyOp(editor, blockId, op, options.diagramOffset);
24965
+ const apply = (op) => applyOp(editor, blockId, op, options);
24922
24966
  switch (cmd.kind) {
24923
24967
  case "moveNode": {
24924
24968
  const { col, row } = canvasToAsciiCell(cmd.x, cmd.y);
@@ -24960,6 +25004,8 @@ function applyAsciiDiagramCommand(editor, blockId, cmd, options = {}) {
24960
25004
  import { jsx as jsx54, jsxs as jsxs42 } from "react/jsx-runtime";
24961
25005
  var MIN_DIAGRAM_HEIGHT = 160;
24962
25006
  var DEFAULT_DIAGRAM_HEIGHT = 420;
25007
+ var REJECTED_NOTICE_MS = 6e3;
25008
+ var REJECTED_EDIT_MESSAGE = "That change wasn't applied: the diagram couldn't be redrawn without losing a box or connection. Try giving the boxes more room, or edit the ASCII source.";
24963
25009
  function AsciiDiagramWidget({
24964
25010
  editor,
24965
25011
  blockId,
@@ -24982,12 +25028,20 @@ function AsciiDiagramWidget({
24982
25028
  const offset = canvasOffsetRef.current ?? { col: 0, row: 0 };
24983
25029
  return asciiDiagramToCanvas(offsetAsciiDiagram(view.diagram, offset));
24984
25030
  }, [view, canvasOffsetVersion]);
25031
+ const [rejectedAt, setRejectedAt] = useState44(null);
25032
+ useEffect35(() => {
25033
+ if (rejectedAt === null) return;
25034
+ const timer = setTimeout(() => setRejectedAt(null), REJECTED_NOTICE_MS);
25035
+ return () => clearTimeout(timer);
25036
+ }, [rejectedAt]);
24985
25037
  const dispatch = useCallback35(
24986
25038
  (cmd) => {
24987
25039
  const offset = canvasOffsetRef.current ?? { col: 0, row: 0 };
24988
25040
  const applied = applyAsciiDiagramCommand(editor, blockId, cmd, {
24989
- diagramOffset: offset
25041
+ diagramOffset: offset,
25042
+ onRejected: () => setRejectedAt(Date.now())
24990
25043
  });
25044
+ if (applied) setRejectedAt(null);
24991
25045
  if (applied && (offset.col !== 0 || offset.row !== 0)) {
24992
25046
  canvasOffsetRef.current = { col: 0, row: 0 };
24993
25047
  setCanvasOffsetVersion((version) => version + 1);
@@ -25086,6 +25140,7 @@ function AsciiDiagramWidget({
25086
25140
  ] }),
25087
25141
  /* @__PURE__ */ jsx54("ul", { children: view.warnings.map((w, i) => /* @__PURE__ */ jsx54("li", { children: w }, i)) })
25088
25142
  ] }) : null;
25143
+ const notice = /* @__PURE__ */ jsx54("div", { className: "squisq-ascii-diagram-notice", role: "status", "aria-live": "polite", children: rejectedAt !== null && REJECTED_EDIT_MESSAGE });
25089
25144
  const canvas = /* @__PURE__ */ jsx54(
25090
25145
  DiagramCanvas,
25091
25146
  {
@@ -25109,7 +25164,8 @@ function AsciiDiagramWidget({
25109
25164
  style: effectiveHeight != null ? { height: effectiveHeight } : void 0,
25110
25165
  children: /* @__PURE__ */ jsx54(DiagramMaximizedOverlay, { host: host ?? null, onClose: () => setMaximized(false), children: /* @__PURE__ */ jsxs42("div", { className: "squisq-scene-block-max", children: [
25111
25166
  canvas,
25112
- /* @__PURE__ */ jsx54("div", { className: "squisq-scene-side-toolbar", children: toolbar })
25167
+ /* @__PURE__ */ jsx54("div", { className: "squisq-scene-side-toolbar", children: toolbar }),
25168
+ notice
25113
25169
  ] }) })
25114
25170
  }
25115
25171
  );
@@ -25139,6 +25195,7 @@ function AsciiDiagramWidget({
25139
25195
  ]
25140
25196
  }
25141
25197
  ),
25198
+ notice,
25142
25199
  warnings
25143
25200
  ] });
25144
25201
  }
@@ -25407,7 +25464,7 @@ function asciiDiagramToCanvas(diagram) {
25407
25464
  }
25408
25465
  function useAsciiDiagramData(editor, blockId) {
25409
25466
  const [version, setVersion] = useState45(0);
25410
- useEffect35(() => {
25467
+ useEffect36(() => {
25411
25468
  const onUpdate = () => setVersion((v2) => v2 + 1);
25412
25469
  editor.on("transaction", onUpdate);
25413
25470
  return () => {
@@ -27253,7 +27310,7 @@ function mermaidErrorMessage(error) {
27253
27310
  }
27254
27311
 
27255
27312
  // src/mermaid/mermaidSurfaceTheme.ts
27256
- import { useEffect as useEffect36, useMemo as useMemo30, useState as useState46 } from "react";
27313
+ import { useEffect as useEffect37, useMemo as useMemo30, useState as useState46 } from "react";
27257
27314
  import { relativeLuminance } from "@bendyline/squisq/schemas";
27258
27315
  var EDITOR_SURFACE = {
27259
27316
  light: {
@@ -27290,7 +27347,7 @@ function resolveMermaidSurfaceTheme(host, theme) {
27290
27347
  }
27291
27348
  function useMermaidSurfaceTheme(host, theme) {
27292
27349
  const [surface, setSurface] = useState46(() => readHostSurface(host));
27293
- useEffect36(() => {
27350
+ useEffect37(() => {
27294
27351
  const sync = () => setSurface((current) => {
27295
27352
  const next = readHostSurface(host);
27296
27353
  return current.scheme === next.scheme && current.inheritsThemeColors === next.inheritsThemeColors ? current : next;
@@ -27316,7 +27373,7 @@ function useMermaidSurfaceTheme(host, theme) {
27316
27373
  }
27317
27374
 
27318
27375
  // src/mermaid/MermaidDiagramCanvas.tsx
27319
- import { useCallback as useCallback36, useEffect as useEffect37, useId as useId12, useLayoutEffect as useLayoutEffect10, useRef as useRef40, useState as useState47 } from "react";
27376
+ import { useCallback as useCallback36, useEffect as useEffect38, useId as useId12, useLayoutEffect as useLayoutEffect10, useRef as useRef40, useState as useState47 } from "react";
27320
27377
  import { jsx as jsx55, jsxs as jsxs43 } from "react/jsx-runtime";
27321
27378
  var renderSequence = 0;
27322
27379
  function excludesCanvasPan(target, viewport) {
@@ -27393,7 +27450,7 @@ function MermaidDiagramCanvas({
27393
27450
  const [panning, setPanning] = useState47(false);
27394
27451
  const [selectionAnchor, setSelectionAnchor] = useState47(null);
27395
27452
  const [renameValue, setRenameValue] = useState47("");
27396
- useEffect37(() => {
27453
+ useEffect38(() => {
27397
27454
  if (!panning) return;
27398
27455
  const finish = () => {
27399
27456
  panDragRef.current = null;
@@ -27421,7 +27478,7 @@ function MermaidDiagramCanvas({
27421
27478
  window.removeEventListener("blur", finish);
27422
27479
  };
27423
27480
  }, [panning]);
27424
- useEffect37(() => {
27481
+ useEffect38(() => {
27425
27482
  let current = true;
27426
27483
  const id = `squisq-mermaid-svg-${++renderSequence}`;
27427
27484
  setRendering(true);
@@ -27692,7 +27749,7 @@ function MermaidDiagramCanvas({
27692
27749
  updateSelectionAnchor,
27693
27750
  zoom
27694
27751
  ]);
27695
- useEffect37(() => {
27752
+ useEffect38(() => {
27696
27753
  const scroll = scrollRef.current;
27697
27754
  if (!scroll) return;
27698
27755
  const update = () => updateSelectionAnchor();
@@ -28097,7 +28154,7 @@ function CanvasAction({
28097
28154
  }
28098
28155
 
28099
28156
  // src/mermaid/MermaidShapePalette.tsx
28100
- import { useEffect as useEffect38, useLayoutEffect as useLayoutEffect11, useMemo as useMemo31, useRef as useRef41, useState as useState48 } from "react";
28157
+ import { useEffect as useEffect39, useLayoutEffect as useLayoutEffect11, useMemo as useMemo31, useRef as useRef41, useState as useState48 } from "react";
28101
28158
  import { jsx as jsx56, jsxs as jsxs44 } from "react/jsx-runtime";
28102
28159
  var CATEGORIES = ["Basic", "Process", "Data", "Documents", "Symbols"];
28103
28160
  var PALETTE_WIDTH = 360;
@@ -28108,7 +28165,7 @@ function MermaidShapePalette({ selected, onPick, onClose }) {
28108
28165
  const [query, setQuery] = useState48("");
28109
28166
  const [position, setPosition] = useState48(null);
28110
28167
  const ref = useRef41(null);
28111
- useEffect38(() => {
28168
+ useEffect39(() => {
28112
28169
  const onPointerDown = (event) => {
28113
28170
  const target = event.target;
28114
28171
  if (target?.closest(".squisq-scene-block-toolbar")) return;
@@ -28279,7 +28336,7 @@ function MermaidShapeThumb({ shape }) {
28279
28336
  }
28280
28337
 
28281
28338
  // src/mermaid/mermaidData.ts
28282
- import { useEffect as useEffect40, useMemo as useMemo32, useState as useState50 } from "react";
28339
+ import { useEffect as useEffect41, useMemo as useMemo32, useState as useState50 } from "react";
28283
28340
 
28284
28341
  // src/mermaid/MermaidDiagramExtension.ts
28285
28342
  import { Extension as Extension7 } from "@tiptap/core";
@@ -28290,7 +28347,7 @@ import { createElement as createElement10 } from "react";
28290
28347
  // src/mermaid/MermaidDiagramWidget.tsx
28291
28348
  import {
28292
28349
  useCallback as useCallback37,
28293
- useEffect as useEffect39,
28350
+ useEffect as useEffect40,
28294
28351
  useLayoutEffect as useLayoutEffect12,
28295
28352
  useRef as useRef42,
28296
28353
  useState as useState49,
@@ -28930,7 +28987,7 @@ function MermaidDiagramWidget({
28930
28987
  },
28931
28988
  [effectiveHeight]
28932
28989
  );
28933
- useEffect39(() => {
28990
+ useEffect40(() => {
28934
28991
  if (!editNotice) return;
28935
28992
  const timeout = window.setTimeout(() => setEditNotice(""), 7e3);
28936
28993
  return () => window.clearTimeout(timeout);
@@ -29167,7 +29224,7 @@ function MermaidDiagramWidget({
29167
29224
  ] });
29168
29225
  }
29169
29226
  function useDismissibleMermaidPopover(ref, onClose) {
29170
- useEffect39(() => {
29227
+ useEffect40(() => {
29171
29228
  const onPointerDown = (event) => {
29172
29229
  const target = event.target;
29173
29230
  if (target?.closest(".squisq-scene-block-toolbar")) return;
@@ -29547,7 +29604,7 @@ var MermaidDiagramExtension = Extension7.create({
29547
29604
  // src/mermaid/mermaidData.ts
29548
29605
  function useMermaidDiagramData(editor, blockId) {
29549
29606
  const [version, setVersion] = useState50(0);
29550
- useEffect40(() => {
29607
+ useEffect41(() => {
29551
29608
  const onTransaction = () => setVersion((value) => value + 1);
29552
29609
  editor.on("transaction", onTransaction);
29553
29610
  return () => {
@@ -29572,7 +29629,7 @@ function describeSvgIslandRemovals(diagnostics) {
29572
29629
  }
29573
29630
 
29574
29631
  // src/svgIsland/SvgIslandWidget.tsx
29575
- import { useEffect as useEffect42, useMemo as useMemo33, useState as useState52 } from "react";
29632
+ import { useEffect as useEffect43, useMemo as useMemo33, useState as useState52 } from "react";
29576
29633
  import { parseSvgIsland } from "@bendyline/squisq/markdown";
29577
29634
  import { SvgIslandImage } from "@bendyline/squisq-react";
29578
29635
 
@@ -29628,7 +29685,7 @@ function FenceMonacoEditor({
29628
29685
  }
29629
29686
 
29630
29687
  // src/codeSnippet/fenceEditorHooks.ts
29631
- import { useEffect as useEffect41, useState as useState51 } from "react";
29688
+ import { useEffect as useEffect42, useState as useState51 } from "react";
29632
29689
  function schemeFromHost(host) {
29633
29690
  return host?.closest("[data-theme]")?.dataset.theme === "dark" ? "dark" : "light";
29634
29691
  }
@@ -29636,7 +29693,7 @@ function useHostColorScheme(host) {
29636
29693
  const [scheme, setScheme] = useState51(
29637
29694
  () => host != null && !host.isConnected ? null : schemeFromHost(host)
29638
29695
  );
29639
- useEffect41(() => {
29696
+ useEffect42(() => {
29640
29697
  if (host != null && !host.isConnected) {
29641
29698
  setScheme(null);
29642
29699
  const raf = requestAnimationFrame(() => {
@@ -29655,7 +29712,7 @@ function useHostColorScheme(host) {
29655
29712
  }
29656
29713
  function useEditorEditable(editor) {
29657
29714
  const [editable, setEditable] = useState51(editor.isEditable);
29658
- useEffect41(() => {
29715
+ useEffect42(() => {
29659
29716
  const sync = () => setEditable(editor.isEditable);
29660
29717
  editor.on("update", sync);
29661
29718
  editor.on("transaction", sync);
@@ -29818,7 +29875,7 @@ import { jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
29818
29875
  var nextModelInstanceId = 0;
29819
29876
  function useSvgIslandView(editor, blockId) {
29820
29877
  const [version, setVersion] = useState52(0);
29821
- useEffect42(() => {
29878
+ useEffect43(() => {
29822
29879
  const onTransaction = () => setVersion((value) => value + 1);
29823
29880
  editor.on("transaction", onTransaction);
29824
29881
  return () => {
@@ -29920,13 +29977,13 @@ import { Decoration as Decoration8, DecorationSet as DecorationSet8 } from "@tip
29920
29977
  import { createElement as createElement12 } from "react";
29921
29978
 
29922
29979
  // src/codeSnippet/CodeSnippetWidget.tsx
29923
- import { useCallback as useCallback38, useEffect as useEffect44, useRef as useRef43, useState as useState54 } from "react";
29980
+ import { useCallback as useCallback38, useEffect as useEffect45, useRef as useRef43, useState as useState54 } from "react";
29924
29981
 
29925
29982
  // src/codeSnippet/codeSnippetData.ts
29926
- import { useEffect as useEffect43, useMemo as useMemo34, useState as useState53 } from "react";
29983
+ import { useEffect as useEffect44, useMemo as useMemo34, useState as useState53 } from "react";
29927
29984
  function useCodeSnippetData(editor, blockId) {
29928
29985
  const [version, setVersion] = useState53(0);
29929
- useEffect43(() => {
29986
+ useEffect44(() => {
29930
29987
  const onTransaction = () => setVersion((value) => value + 1);
29931
29988
  editor.on("transaction", onTransaction);
29932
29989
  return () => {
@@ -29993,7 +30050,7 @@ function CodeSnippetWidget({
29993
30050
  sourceRef.current = data?.source ?? "";
29994
30051
  const languageRef = useRef43("");
29995
30052
  languageRef.current = data?.fenceLanguage ?? "";
29996
- useEffect44(
30053
+ useEffect45(
29997
30054
  () => () => {
29998
30055
  if (copyResetTimer.current !== void 0) clearTimeout(copyResetTimer.current);
29999
30056
  },
@@ -30238,7 +30295,7 @@ import { Decoration as Decoration9, DecorationSet as DecorationSet9 } from "@tip
30238
30295
  import { createElement as createElement13 } from "react";
30239
30296
 
30240
30297
  // src/fenceWidgets/HostFenceWidget.tsx
30241
- import { Component as Component2, useEffect as useEffect45, useMemo as useMemo35, useState as useState55 } from "react";
30298
+ import { Component as Component2, useEffect as useEffect46, useMemo as useMemo35, useState as useState55 } from "react";
30242
30299
  import { jsx as jsx61 } from "react/jsx-runtime";
30243
30300
  var HostFenceErrorBoundary = class extends Component2 {
30244
30301
  constructor() {
@@ -30254,7 +30311,7 @@ var HostFenceErrorBoundary = class extends Component2 {
30254
30311
  };
30255
30312
  function HostFenceWidget({ editor, blockId, getRenderers, getTheme }) {
30256
30313
  const [version, setVersion] = useState55(0);
30257
- useEffect45(() => {
30314
+ useEffect46(() => {
30258
30315
  const onUpdate = () => setVersion((v2) => v2 + 1);
30259
30316
  editor.on("transaction", onUpdate);
30260
30317
  return () => {
@@ -30727,7 +30784,7 @@ import { createElement as createElement14 } from "react";
30727
30784
  import { isDataFilePath } from "@bendyline/squisq/doc";
30728
30785
 
30729
30786
  // src/dataCard/DataCardWidget.tsx
30730
- import { useCallback as useCallback39, useEffect as useEffect46, useMemo as useMemo36, useRef as useRef44, useState as useState56 } from "react";
30787
+ import { useCallback as useCallback39, useEffect as useEffect47, useMemo as useMemo36, useRef as useRef44, useState as useState56 } from "react";
30731
30788
  import { EMPTY_TABLE_VIEW_STATE } from "@bendyline/squisq/table";
30732
30789
 
30733
30790
  // src/dataCard/gridSave.ts
@@ -31131,7 +31188,7 @@ var XLSX_SESSION_LOCKED_REASON = "Date cells and shared-formula masters stay loc
31131
31188
  var pendingFormulas = /* @__PURE__ */ new WeakMap();
31132
31189
  function useCardLink(editor, blockId) {
31133
31190
  const [version, setVersion] = useState56(0);
31134
- useEffect46(() => {
31191
+ useEffect47(() => {
31135
31192
  const bump = () => setVersion((v2) => v2 + 1);
31136
31193
  editor.on("transaction", bump);
31137
31194
  return () => {
@@ -31151,7 +31208,7 @@ function useCardLink(editor, blockId) {
31151
31208
  }
31152
31209
  function useMediaRevision(getMediaRevision) {
31153
31210
  const [revision, setRevision] = useState56(() => getMediaRevision());
31154
- useEffect46(() => {
31211
+ useEffect47(() => {
31155
31212
  const timer = window.setInterval(() => {
31156
31213
  const next = getMediaRevision();
31157
31214
  setRevision((prev) => prev === next ? prev : next);
@@ -31195,7 +31252,7 @@ function DataCardWidget({
31195
31252
  regionParams.anchor,
31196
31253
  regionParams.headerRow
31197
31254
  ]);
31198
- useEffect46(() => {
31255
+ useEffect47(() => {
31199
31256
  if (!href || cardPos === null) return;
31200
31257
  const provider = activeProvider;
31201
31258
  if (!provider) {
@@ -31357,7 +31414,7 @@ function DataCardWidget({
31357
31414
  cancelled = true;
31358
31415
  };
31359
31416
  }, [href, revision, activeProvider, activeContainer, regionIdentity, editor]);
31360
- useEffect46(
31417
+ useEffect47(
31361
31418
  () => () => {
31362
31419
  gridRef.current?.formulaSession?.dispose();
31363
31420
  gridRef.current?.provider.dispose();
@@ -32094,7 +32151,7 @@ function pasteVideoEmbedCode(view, text) {
32094
32151
  }
32095
32152
 
32096
32153
  // src/treeview/treeViewData.ts
32097
- import { useEffect as useEffect47, useMemo as useMemo37, useState as useState58 } from "react";
32154
+ import { useEffect as useEffect48, useMemo as useMemo37, useState as useState58 } from "react";
32098
32155
 
32099
32156
  // src/treeview/TreeViewExtension.ts
32100
32157
  import { Extension as Extension15 } from "@tiptap/core";
@@ -32803,7 +32860,7 @@ var TreeViewExtension = Extension15.create({
32803
32860
  // src/treeview/treeViewData.ts
32804
32861
  function useTreeViewData(editor, blockId) {
32805
32862
  const [version, setVersion] = useState58(0);
32806
- useEffect47(() => {
32863
+ useEffect48(() => {
32807
32864
  const onUpdate = () => setVersion((v2) => v2 + 1);
32808
32865
  editor.on("transaction", onUpdate);
32809
32866
  return () => {
@@ -32829,7 +32886,7 @@ function shouldPasteAsTreeFence(text) {
32829
32886
  }
32830
32887
 
32831
32888
  // src/timeline/timelineData.ts
32832
- import { useEffect as useEffect49, useMemo as useMemo39, useRef as useRef47, useState as useState60 } from "react";
32889
+ import { useEffect as useEffect50, useMemo as useMemo39, useRef as useRef47, useState as useState60 } from "react";
32833
32890
 
32834
32891
  // src/timeline/TimelineViewExtension.ts
32835
32892
  import { Extension as Extension16 } from "@tiptap/core";
@@ -32843,7 +32900,7 @@ import {
32843
32900
  } from "@bendyline/squisq/doc";
32844
32901
 
32845
32902
  // src/timeline/TimelineEditorWidget.tsx
32846
- import { useCallback as useCallback41, useEffect as useEffect48, useMemo as useMemo38, useRef as useRef46, useState as useState59 } from "react";
32903
+ import { useCallback as useCallback41, useEffect as useEffect49, useMemo as useMemo38, useRef as useRef46, useState as useState59 } from "react";
32847
32904
  import {
32848
32905
  asciiTimelineToTemplateData
32849
32906
  } from "@bendyline/squisq/doc";
@@ -33394,7 +33451,7 @@ function TimelineEditorWidget({ editor, blockId }) {
33394
33451
  }
33395
33452
  return null;
33396
33453
  }, [selectedEventId, view]);
33397
- useEffect48(() => {
33454
+ useEffect49(() => {
33398
33455
  if (!view) return;
33399
33456
  const ids = new Set(
33400
33457
  view.timeline.tracks.flatMap((track) => track.events.map((event) => event.id))
@@ -33402,13 +33459,13 @@ function TimelineEditorWidget({ editor, blockId }) {
33402
33459
  if (selectedEventId && ids.has(selectedEventId)) return;
33403
33460
  setSelectedEventId(view.timeline.tracks[0]?.events[0]?.id ?? null);
33404
33461
  }, [selectedEventId, view]);
33405
- useEffect48(() => {
33462
+ useEffect49(() => {
33406
33463
  if (editable) return;
33407
33464
  setAddingTrackId(null);
33408
33465
  setEditingTrackId(null);
33409
33466
  setHover(null);
33410
33467
  }, [editable]);
33411
- useEffect48(() => {
33468
+ useEffect49(() => {
33412
33469
  if (!editingTrackId || view?.timeline.tracks.some((track) => track.id === editingTrackId)) {
33413
33470
  return;
33414
33471
  }
@@ -33815,7 +33872,7 @@ function InlineTrackLabel({
33815
33872
  onFinish
33816
33873
  }) {
33817
33874
  const [draft, setDraft] = useState59(label);
33818
- useEffect48(() => {
33875
+ useEffect49(() => {
33819
33876
  if (editing) setDraft(label);
33820
33877
  }, [editing, label]);
33821
33878
  const commitLabel = () => {
@@ -33874,8 +33931,8 @@ function EventInspector({
33874
33931
  const { event } = selected;
33875
33932
  const [label, setLabel] = useState59(event.label);
33876
33933
  const [description, setDescription] = useState59(event.description ?? "");
33877
- useEffect48(() => setLabel(event.label), [event.label]);
33878
- useEffect48(() => setDescription(event.description ?? ""), [event.description]);
33934
+ useEffect49(() => setLabel(event.label), [event.label]);
33935
+ useEffect49(() => setDescription(event.description ?? ""), [event.description]);
33879
33936
  const update = (patch) => dispatch(patch);
33880
33937
  const commitLabel = () => {
33881
33938
  const next = label.trim();
@@ -34185,7 +34242,7 @@ var TimelineViewExtension = Extension16.create({
34185
34242
  function useTimelineData(editor, blockId) {
34186
34243
  const [version, setVersion] = useState60(0);
34187
34244
  const dataCache = useRef47(null);
34188
- useEffect49(() => {
34245
+ useEffect50(() => {
34189
34246
  const onEditorChange = () => setVersion((value) => value + 1);
34190
34247
  editor.on("transaction", onEditorChange);
34191
34248
  editor.on("update", onEditorChange);
@@ -34220,7 +34277,7 @@ function shouldPasteAsTimelineFence(text) {
34220
34277
  }
34221
34278
 
34222
34279
  // src/BlockPropertiesPopover.tsx
34223
- import { useEffect as useEffect50, useId as useId13, useRef as useRef48, useState as useState61 } from "react";
34280
+ import { useEffect as useEffect51, useId as useId13, useRef as useRef48, useState as useState61 } from "react";
34224
34281
  import { createPortal as createPortal14 } from "react-dom";
34225
34282
  import { Fragment as Fragment22, jsx as jsx65, jsxs as jsxs51 } from "react/jsx-runtime";
34226
34283
  var TRANSITION_FLYOUT = ".squisq-transition-flyout";
@@ -34239,10 +34296,10 @@ function BlockPropertiesPopover({
34239
34296
  const [inner, setInner] = useState61(blockAttrs);
34240
34297
  const [templateInner, setTemplateInner] = useState61(templateParams);
34241
34298
  const [style, setStyle] = useState61(() => computeStyle3(anchorRect));
34242
- useEffect50(() => {
34299
+ useEffect51(() => {
34243
34300
  requestAnimationFrame(() => setStyle(computeStyle3(anchorRect, panelRef.current)));
34244
34301
  }, [anchorRect]);
34245
- useEffect50(() => {
34302
+ useEffect51(() => {
34246
34303
  const onKey = (e2) => {
34247
34304
  if (e2.key === "Escape") onClose();
34248
34305
  };
@@ -34493,7 +34550,7 @@ function persistFromWrite(bodyMd, state) {
34493
34550
  }
34494
34551
 
34495
34552
  // src/WysiwygEditor.tsx
34496
- import { useCallback as useCallback43, useEffect as useEffect55, useMemo as useMemo42, useRef as useRef51, useState as useState67 } from "react";
34553
+ import { useCallback as useCallback43, useEffect as useEffect56, useMemo as useMemo42, useRef as useRef51, useState as useState67 } from "react";
34497
34554
  import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
34498
34555
  import { Selection as Selection2 } from "@tiptap/pm/state";
34499
34556
  import { Extension as Extension18, getHTMLFromFragment } from "@tiptap/core";
@@ -34538,7 +34595,7 @@ import Link2 from "@tiptap/extension-link";
34538
34595
  // src/WikiLink.tsx
34539
34596
  import { Node as Node2, InputRule } from "@tiptap/core";
34540
34597
  import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
34541
- import { useEffect as useEffect51, useState as useState62 } from "react";
34598
+ import { useEffect as useEffect52, useState as useState62 } from "react";
34542
34599
  import { wikiLinkPath as wikiLinkPath3, parseWikiLink as parseWikiLink3 } from "@bendyline/squisq/markdown";
34543
34600
 
34544
34601
  // src/wikiSuggestionPlugin.ts
@@ -34711,7 +34768,7 @@ function WikiLinkView({ node: node2, editor }) {
34711
34768
  const [exists, setExists] = useState62(null);
34712
34769
  const [error, setError] = useState62("");
34713
34770
  const [busy, setBusy] = useState62(false);
34714
- useEffect51(() => {
34771
+ useEffect52(() => {
34715
34772
  let cancelled = false;
34716
34773
  setExists(null);
34717
34774
  setError("");
@@ -34906,7 +34963,7 @@ var InlineIcon = Node3.create({
34906
34963
  });
34907
34964
 
34908
34965
  // src/ImageNodeView.tsx
34909
- import { useEffect as useEffect52, useRef as useRef49, useState as useState63 } from "react";
34966
+ import { useEffect as useEffect53, useRef as useRef49, useState as useState63 } from "react";
34910
34967
  import { NodeViewWrapper as NodeViewWrapper2, ReactNodeViewRenderer as ReactNodeViewRenderer2 } from "@tiptap/react";
34911
34968
  import Image from "@tiptap/extension-image";
34912
34969
  import { mergeAttributes as mergeAttributes3 } from "@tiptap/core";
@@ -34940,7 +34997,7 @@ function ImageComponent({ node: node2, selected, editor, updateAttributes }) {
34940
34997
  const sanitizedSvg = useSanitizedSvgImage(loadedSrc, isSvg);
34941
34998
  const resolvedSrc = sanitizedSvg ?? "";
34942
34999
  const resolutionFailed = needsResolution && currentResolution?.url === null || sanitizedSvg === null;
34943
- useEffect52(() => {
35000
+ useEffect53(() => {
34944
35001
  if (isUploading || !mediaProvider || !resolveAs) return;
34945
35002
  setImageLoad(null);
34946
35003
  let cancelled = false;
@@ -35279,15 +35336,15 @@ function MediaEditButton({ src, kind, fx, className }) {
35279
35336
 
35280
35337
  // src/tiptap/TiptapVideo.tsx
35281
35338
  import { NodeViewWrapper as NodeViewWrapper3, ReactNodeViewRenderer as ReactNodeViewRenderer3 } from "@tiptap/react";
35282
- import { useEffect as useEffect54, useState as useState65 } from "react";
35339
+ import { useEffect as useEffect55, useState as useState65 } from "react";
35283
35340
 
35284
35341
  // src/tiptap/useResolvedMediaSrc.ts
35285
- import { useEffect as useEffect53, useState as useState64 } from "react";
35342
+ import { useEffect as useEffect54, useState as useState64 } from "react";
35286
35343
  function useResolvedMediaSrc(src) {
35287
35344
  const { mediaProvider, mediaRevision } = useEditorContext();
35288
35345
  const isRelative = !!src && !src.startsWith("blob:") && !src.startsWith("http:") && !src.startsWith("https:") && !src.startsWith("data:") && !src.startsWith("/");
35289
35346
  const [resolved, setResolved] = useState64(isRelative && mediaProvider ? "" : src);
35290
- useEffect53(() => {
35347
+ useEffect54(() => {
35291
35348
  if (!mediaProvider || !isRelative) {
35292
35349
  setResolved(src);
35293
35350
  return;
@@ -35346,7 +35403,7 @@ function VideoMedia({
35346
35403
  const resolvedSrc = useResolvedMediaSrc(src ?? "");
35347
35404
  const [audioOnly, setAudioOnly] = useState65(false);
35348
35405
  const resolvedPoster = useResolvedMediaSrc(poster ?? "");
35349
- useEffect54(() => {
35406
+ useEffect55(() => {
35350
35407
  setAudioOnly(false);
35351
35408
  }, [resolvedSrc]);
35352
35409
  const handleLoadedMetadata = (event) => {
@@ -35674,7 +35731,7 @@ function startNarrationTimingJob(input) {
35674
35731
  else jobs.delete(input.src);
35675
35732
  notify();
35676
35733
  };
35677
- import("./narrationTimingsFromAudio-ICMDSWPI.js").then(
35734
+ import("./narrationTimingsFromAudio-O67QKISS.js").then(
35678
35735
  ({ updateNarrationTimingsFromAudio }) => updateNarrationTimingsFromAudio({
35679
35736
  ...input,
35680
35737
  signal: job.abort.signal,
@@ -36653,7 +36710,7 @@ function WysiwygEditor({
36653
36710
  mermaidThemeStoreRef.current = createMermaidThemeStore(activeTheme ?? DEFAULT_THEME4);
36654
36711
  }
36655
36712
  const mermaidThemeStore = mermaidThemeStoreRef.current;
36656
- useEffect55(() => {
36713
+ useEffect56(() => {
36657
36714
  mermaidThemeStore.setTheme(activeTheme ?? DEFAULT_THEME4);
36658
36715
  }, [activeTheme, mermaidThemeStore]);
36659
36716
  const { docTemplates, onDocTemplatesChange } = useDocCustomTemplates();
@@ -36673,19 +36730,19 @@ function WysiwygEditor({
36673
36730
  [docTemplates, onDocTemplatesChange]
36674
36731
  );
36675
36732
  const mentionProviderRef = useRef51(mentionProvider);
36676
- useEffect55(() => {
36733
+ useEffect56(() => {
36677
36734
  mentionProviderRef.current = mentionProvider;
36678
36735
  }, [mentionProvider]);
36679
36736
  const fenceRenderersRef = useRef51(fenceRenderers);
36680
- useEffect55(() => {
36737
+ useEffect56(() => {
36681
36738
  fenceRenderersRef.current = fenceRenderers;
36682
36739
  }, [fenceRenderers]);
36683
36740
  const onCopyCodeRef = useRef51(onCopyCode);
36684
- useEffect55(() => {
36741
+ useEffect56(() => {
36685
36742
  onCopyCodeRef.current = onCopyCode;
36686
36743
  }, [onCopyCode]);
36687
36744
  const activeThemeRef = useRef51(activeTheme);
36688
- useEffect55(() => {
36745
+ useEffect56(() => {
36689
36746
  activeThemeRef.current = activeTheme;
36690
36747
  }, [activeTheme]);
36691
36748
  const resolvedPlaceholder = useMemo42(() => placeholder ?? pickEmptyPrompt(), [placeholder]);
@@ -36696,30 +36753,30 @@ function WysiwygEditor({
36696
36753
  const pendingLocalSourcesRef = useRef51([]);
36697
36754
  const mediaProviderRef = useRef51(mediaProvider);
36698
36755
  const mediaRevisionRef = useRef51(mediaRevision);
36699
- useEffect55(() => {
36756
+ useEffect56(() => {
36700
36757
  mediaRevisionRef.current = mediaRevision;
36701
36758
  }, [mediaRevision]);
36702
36759
  const onOpenFilesPanelRef = useRef51(onOpenFilesPanel);
36703
- useEffect55(() => {
36760
+ useEffect56(() => {
36704
36761
  onOpenFilesPanelRef.current = onOpenFilesPanel;
36705
36762
  }, [onOpenFilesPanel]);
36706
36763
  const calcEngineFactoryRef = useRef51(calcEngineFactory);
36707
- useEffect55(() => {
36764
+ useEffect56(() => {
36708
36765
  calcEngineFactoryRef.current = calcEngineFactory;
36709
36766
  }, [calcEngineFactory]);
36710
36767
  const workspaceContainerRef = useRef51(workspaceContainer);
36711
- useEffect55(() => {
36768
+ useEffect56(() => {
36712
36769
  workspaceContainerRef.current = workspaceContainer;
36713
36770
  }, [workspaceContainer]);
36714
36771
  const bumpMediaRevisionRef = useRef51(bumpMediaRevision);
36715
- useEffect55(() => {
36772
+ useEffect56(() => {
36716
36773
  bumpMediaRevisionRef.current = bumpMediaRevision;
36717
36774
  }, [bumpMediaRevision]);
36718
- useEffect55(() => {
36775
+ useEffect56(() => {
36719
36776
  mediaProviderRef.current = mediaProvider;
36720
36777
  }, [mediaProvider]);
36721
36778
  const [accessoryPaths, setAccessoryPaths] = useState67(() => /* @__PURE__ */ new Set());
36722
- useEffect55(() => {
36779
+ useEffect56(() => {
36723
36780
  if (!mediaProvider) {
36724
36781
  setAccessoryPaths(/* @__PURE__ */ new Set());
36725
36782
  return;
@@ -36759,7 +36816,7 @@ function WysiwygEditor({
36759
36816
  initialContentRef.current = markdownToTiptap(initialDisplayBodyRef.current);
36760
36817
  }
36761
36818
  const submitOnEnterRef = useRef51(submitOnEnter);
36762
- useEffect55(() => {
36819
+ useEffect56(() => {
36763
36820
  submitOnEnterRef.current = submitOnEnter;
36764
36821
  }, [submitOnEnter]);
36765
36822
  const editor = useEditor2({
@@ -36991,7 +37048,7 @@ function WysiwygEditor({
36991
37048
  }
36992
37049
  }
36993
37050
  });
36994
- useEffect55(() => {
37051
+ useEffect56(() => {
36995
37052
  let cancelled = false;
36996
37053
  queueMicrotask(() => {
36997
37054
  if (!cancelled && editor && !editor.isDestroyed)
@@ -37001,13 +37058,13 @@ function WysiwygEditor({
37001
37058
  cancelled = true;
37002
37059
  };
37003
37060
  }, [editor, wikiLinks]);
37004
- useEffect55(() => {
37061
+ useEffect56(() => {
37005
37062
  if (editor) {
37006
37063
  setTiptapEditor(editor);
37007
37064
  }
37008
37065
  return () => setTiptapEditor(null);
37009
37066
  }, [editor, setTiptapEditor]);
37010
- useEffect55(() => {
37067
+ useEffect56(() => {
37011
37068
  if (!editor) return;
37012
37069
  const syncPlaceholders = () => {
37013
37070
  syncAccessoryFileLinkPlaceholders(editor.view.dom, accessoryPaths);
@@ -37018,7 +37075,7 @@ function WysiwygEditor({
37018
37075
  editor.off("update", syncPlaceholders);
37019
37076
  };
37020
37077
  }, [accessoryPaths, editor]);
37021
- useEffect55(() => {
37078
+ useEffect56(() => {
37022
37079
  if (editor) editor.setEditable(!readOnly);
37023
37080
  }, [editor, readOnly]);
37024
37081
  const containerRef = useRef51(null);
@@ -37030,7 +37087,7 @@ function WysiwygEditor({
37030
37087
  if (editor && !editor.isDestroyed) editor.commands.focus();
37031
37088
  });
37032
37089
  }, [editor]);
37033
- useEffect55(() => {
37090
+ useEffect56(() => {
37034
37091
  if (!editor) return;
37035
37092
  const root = containerRef.current;
37036
37093
  if (!root) return;
@@ -37086,7 +37143,7 @@ function WysiwygEditor({
37086
37143
  root.addEventListener("mousedown", onClick);
37087
37144
  return () => root.removeEventListener("mousedown", onClick);
37088
37145
  }, [editor]);
37089
- useEffect55(() => {
37146
+ useEffect56(() => {
37090
37147
  if (!editor) return;
37091
37148
  const previousLayout = sourceLayoutRef.current;
37092
37149
  const layoutChanged = previousLayout !== layoutMode;
@@ -37197,7 +37254,7 @@ function WysiwygEditor({
37197
37254
  }
37198
37255
  return out;
37199
37256
  }, [activeTheme, themeInheritance]);
37200
- useEffect55(() => {
37257
+ useEffect56(() => {
37201
37258
  if (!editor || editor.isDestroyed) return;
37202
37259
  editor.view.dispatch(editor.state.tr.setMeta(DOCUMENT_TRAY_KEY, layoutMode === "document"));
37203
37260
  }, [editor, layoutMode]);
@@ -37436,14 +37493,14 @@ import { VIEWPORT_PRESETS as VIEWPORT_PRESETS5 } from "@bendyline/squisq/schemas
37436
37493
  import { BlockRenderer as BlockRenderer3, MediaContext as MediaContext4 } from "@bendyline/squisq-react";
37437
37494
 
37438
37495
  // src/useHeadingLayout.ts
37439
- import { useCallback as useCallback44, useEffect as useEffect56, useMemo as useMemo43, useState as useState68 } from "react";
37496
+ import { useCallback as useCallback44, useEffect as useEffect57, useMemo as useMemo43, useState as useState68 } from "react";
37440
37497
  import { flattenBlocks as flattenBlocks3, hasTemplate } from "@bendyline/squisq/doc";
37441
37498
  function useHeadingLayout(refInsideWrapper) {
37442
37499
  const { doc, activeView, monacoEditor, tiptapEditor } = useEditorContext();
37443
37500
  const flatBlocks = useMemo43(() => doc ? flattenBlocks3(doc.blocks) : [], [doc]);
37444
37501
  const [entries, setEntries] = useState68([]);
37445
37502
  const [pageEdges, setPageEdges] = useState68(null);
37446
- useEffect56(() => {
37503
+ useEffect57(() => {
37447
37504
  if (activeView !== "wysiwyg") return;
37448
37505
  const node2 = refInsideWrapper.current;
37449
37506
  if (!node2) return;
@@ -37511,7 +37568,7 @@ function useHeadingLayout(refInsideWrapper) {
37511
37568
  window.removeEventListener("resize", recompute);
37512
37569
  };
37513
37570
  }, [activeView, flatBlocks, refInsideWrapper]);
37514
- useEffect56(() => {
37571
+ useEffect57(() => {
37515
37572
  if (activeView !== "raw") return;
37516
37573
  if (!monacoEditor) return;
37517
37574
  const node2 = refInsideWrapper.current;
@@ -37572,7 +37629,7 @@ function useHeadingLayout(refInsideWrapper) {
37572
37629
  window.removeEventListener("resize", recompute);
37573
37630
  };
37574
37631
  }, [activeView, monacoEditor, flatBlocks, refInsideWrapper]);
37575
- useEffect56(() => {
37632
+ useEffect57(() => {
37576
37633
  setEntries([]);
37577
37634
  setPageEdges(null);
37578
37635
  }, [activeView]);
@@ -37656,7 +37713,7 @@ import { flattenRenderableBlocks, DEFAULT_THEME as DEFAULT_THEME5 } from "@bendy
37656
37713
  import { extractPlainText as extractPlainText3 } from "@bendyline/squisq/markdown";
37657
37714
 
37658
37715
  // src/usePreviewProjection.ts
37659
- import { useEffect as useEffect57, useState as useState69 } from "react";
37716
+ import { useEffect as useEffect58, useState as useState69 } from "react";
37660
37717
  import {
37661
37718
  resolveAudioMapping,
37662
37719
  resolveDataReferences
@@ -37703,7 +37760,7 @@ function preserveEquivalentAudio(previous, next) {
37703
37760
  }
37704
37761
  function usePreviewProjection(doc, transformStyle, workspaceContainer, documentTitle2, mediaRevision) {
37705
37762
  const [projection, setProjection] = useState69(null);
37706
- useEffect57(() => {
37763
+ useEffect58(() => {
37707
37764
  if (!doc || !doc.blocks.length) {
37708
37765
  setProjection(null);
37709
37766
  return;
@@ -37982,7 +38039,7 @@ function InlinePreviewGutter({
37982
38039
  import {
37983
38040
  memo,
37984
38041
  useCallback as useCallback45,
37985
- useEffect as useEffect58,
38042
+ useEffect as useEffect59,
37986
38043
  useMemo as useMemo46,
37987
38044
  useRef as useRef53,
37988
38045
  useState as useState71
@@ -38455,10 +38512,10 @@ function useActiveOutlineBlockId() {
38455
38512
  flatBlocksRef.current = flatBlocks;
38456
38513
  const headingLocations = flatBlocks.map((block) => `${block.id}:${block.sourceHeading?.position?.start.line ?? ""}`).join("\0");
38457
38514
  const [activeId, setActiveId] = useState71(null);
38458
- useEffect58(() => {
38515
+ useEffect59(() => {
38459
38516
  setActiveId(null);
38460
38517
  }, [activeView]);
38461
- useEffect58(() => {
38518
+ useEffect59(() => {
38462
38519
  if (activeView !== "wysiwyg" || !tiptapEditor) return;
38463
38520
  const update = () => {
38464
38521
  const { from } = tiptapEditor.state.selection;
@@ -38480,7 +38537,7 @@ function useActiveOutlineBlockId() {
38480
38537
  tiptapEditor.off("update", update);
38481
38538
  };
38482
38539
  }, [activeView, tiptapEditor, headingLocations]);
38483
- useEffect58(() => {
38540
+ useEffect59(() => {
38484
38541
  if (activeView !== "raw" || !monacoEditor) return;
38485
38542
  const update = () => {
38486
38543
  const line = monacoEditor.getPosition()?.lineNumber;
@@ -38567,7 +38624,7 @@ function bumpHeadingLevelInSource(source, line, delta) {
38567
38624
  }
38568
38625
 
38569
38626
  // src/codeContext/CodeContextZones.tsx
38570
- import { useCallback as useCallback47, useEffect as useEffect60, useMemo as useMemo48, useRef as useRef55, useState as useState72 } from "react";
38627
+ import { useCallback as useCallback47, useEffect as useEffect61, useMemo as useMemo48, useRef as useRef55, useState as useState72 } from "react";
38571
38628
  import { createPortal as createPortal15 } from "react-dom";
38572
38629
 
38573
38630
  // src/codeContext/diffContextSections.ts
@@ -38691,7 +38748,7 @@ function setOrdinal(zone, ordinal) {
38691
38748
  // src/codeContext/CodeContextSectionView.tsx
38692
38749
  import { parseMarkdown as parseMarkdown8 } from "@bendyline/squisq/markdown";
38693
38750
  import { MarkdownRenderer } from "@bendyline/squisq-react";
38694
- import { useCallback as useCallback46, useEffect as useEffect59, useMemo as useMemo47, useRef as useRef54 } from "react";
38751
+ import { useCallback as useCallback46, useEffect as useEffect60, useMemo as useMemo47, useRef as useRef54 } from "react";
38695
38752
  import { jsx as jsx75, jsxs as jsxs61 } from "react/jsx-runtime";
38696
38753
  function CodeContextSectionView({
38697
38754
  section,
@@ -38711,7 +38768,7 @@ function CodeContextSectionView({
38711
38768
  () => expanded && section.markdown ? parseMarkdown8(section.markdown).children : null,
38712
38769
  [expanded, section.markdown]
38713
38770
  );
38714
- useEffect59(() => {
38771
+ useEffect60(() => {
38715
38772
  const el = rootRef.current;
38716
38773
  if (!el || typeof ResizeObserver === "undefined") return;
38717
38774
  const report = () => {
@@ -38787,7 +38844,7 @@ function CodeContextZones({ options }) {
38787
38844
  const [, setZonesVersion] = useState72(0);
38788
38845
  const [expandedById, setExpandedById] = useState72({});
38789
38846
  const seenIds = useRef55(/* @__PURE__ */ new Set());
38790
- useEffect60(() => {
38847
+ useEffect61(() => {
38791
38848
  if (!monacoEditor) return;
38792
38849
  const mgr = new CodeContextZoneManager(monacoEditor);
38793
38850
  const off = mgr.onDidChangeZones(() => setZonesVersion((v2) => v2 + 1));
@@ -38810,7 +38867,7 @@ function CodeContextZones({ options }) {
38810
38867
  });
38811
38868
  return out;
38812
38869
  }, [fileTop, sections]);
38813
- useEffect60(() => {
38870
+ useEffect61(() => {
38814
38871
  if (!manager) return;
38815
38872
  manager.sync(resolved.map((r) => r.spec));
38816
38873
  setExpandedById((prev) => {
@@ -39276,20 +39333,44 @@ function placeClipInBlock(source, fromLine, targetHeadingLine, spec, startAt) {
39276
39333
  }
39277
39334
 
39278
39335
  // src/TimelineTrack.tsx
39279
- import { useCallback as useCallback49, useEffect as useEffect63, useMemo as useMemo49, useRef as useRef58, useState as useState75 } from "react";
39336
+ import { useCallback as useCallback49, useEffect as useEffect64, useMemo as useMemo49, useRef as useRef58, useState as useState75 } from "react";
39280
39337
  import {
39281
39338
  resolveMediaSchedule as resolveMediaSchedule2,
39282
39339
  getDocPlaybackDuration,
39283
- VIEWPORT_PRESETS as VIEWPORT_PRESETS6
39340
+ VIEWPORT_PRESETS as VIEWPORT_PRESETS7
39284
39341
  } from "@bendyline/squisq/schemas";
39285
39342
  import { flattenBlocks as flattenBlocks5, DEFAULT_THEME as DEFAULT_THEME6, getPinnedBlockMeta } from "@bendyline/squisq/doc";
39286
39343
  import { createMediaTimeMap } from "@bendyline/squisq/mediaEdit";
39287
39344
  import { usesDynamicPresentation } from "@bendyline/squisq/transform";
39288
39345
  import { useProcessedAudio as useProcessedAudio2 } from "@bendyline/squisq-video-react/media-edit";
39289
- import { MediaClipLayer, MediaContext as MediaContext5 } from "@bendyline/squisq-react";
39346
+ import { MediaClipLayer, MediaContext as MediaContext6 } from "@bendyline/squisq-react";
39347
+
39348
+ // src/TimelineBlockPreview.tsx
39349
+ import { memo as memo2 } from "react";
39350
+ import { VIEWPORT_PRESETS as VIEWPORT_PRESETS6 } from "@bendyline/squisq/schemas";
39351
+ import { BlockRenderer as BlockRenderer4, MediaContext as MediaContext5 } from "@bendyline/squisq-react";
39352
+ import { jsx as jsx78 } from "react/jsx-runtime";
39353
+ var BlockThumbnail = memo2(function BlockThumbnail2({
39354
+ visual,
39355
+ buildPlayback = "all",
39356
+ viewport = VIEWPORT_PRESETS6.landscape,
39357
+ basePath = "/",
39358
+ mediaProvider = null
39359
+ }) {
39360
+ return /* @__PURE__ */ jsx78(MediaContext5.Provider, { value: mediaProvider, children: /* @__PURE__ */ jsx78(
39361
+ BlockRenderer4,
39362
+ {
39363
+ buildPlayback,
39364
+ block: visual,
39365
+ blockTime: 0,
39366
+ basePath,
39367
+ viewport
39368
+ }
39369
+ ) });
39370
+ });
39290
39371
 
39291
39372
  // src/useTimelineClock.ts
39292
- import { useCallback as useCallback48, useEffect as useEffect61, useRef as useRef56, useState as useState73 } from "react";
39373
+ import { useCallback as useCallback48, useEffect as useEffect62, useRef as useRef56, useState as useState73 } from "react";
39293
39374
  function advanceTime(prev, dt, total) {
39294
39375
  if (total <= 0) return 0;
39295
39376
  return Math.min(total, Math.max(0, prev + dt));
@@ -39318,10 +39399,10 @@ function useTimelineClock(total) {
39318
39399
  const mediaHostRef = useRef56(null);
39319
39400
  currentTimeRef.current = currentTime;
39320
39401
  isPlayingRef.current = isPlaying;
39321
- useEffect61(() => {
39402
+ useEffect62(() => {
39322
39403
  setCurrentTime((t) => Math.min(t, Math.max(0, total)));
39323
39404
  }, [total]);
39324
- useEffect61(() => {
39405
+ useEffect62(() => {
39325
39406
  if (!isPlaying) return;
39326
39407
  lastRef.current = performance.now();
39327
39408
  const tick = (now) => {
@@ -39419,9 +39500,9 @@ function timelineBars(clips) {
39419
39500
  }
39420
39501
 
39421
39502
  // src/TimelineItemMenu.tsx
39422
- import { useEffect as useEffect62, useLayoutEffect as useLayoutEffect14, useRef as useRef57, useState as useState74 } from "react";
39503
+ import { useEffect as useEffect63, useLayoutEffect as useLayoutEffect14, useRef as useRef57, useState as useState74 } from "react";
39423
39504
  import { createPortal as createPortal16 } from "react-dom";
39424
- import { Fragment as Fragment27, jsx as jsx78, jsxs as jsxs63 } from "react/jsx-runtime";
39505
+ import { Fragment as Fragment27, jsx as jsx79, jsxs as jsxs63 } from "react/jsx-runtime";
39425
39506
  function TimelineItemMenu({
39426
39507
  anchor,
39427
39508
  target,
@@ -39450,7 +39531,7 @@ function TimelineItemMenu({
39450
39531
  resizeObserver?.disconnect();
39451
39532
  };
39452
39533
  }, [anchor]);
39453
- useEffect62(() => {
39534
+ useEffect63(() => {
39454
39535
  const onKeyDown = (event) => {
39455
39536
  if (event.key !== "Escape") return;
39456
39537
  event.preventDefault();
@@ -39482,10 +39563,10 @@ function TimelineItemMenu({
39482
39563
  style: { ...style, ...accentStyle(accentColor) },
39483
39564
  children: [
39484
39565
  /* @__PURE__ */ jsxs63("div", { className: "squisq-timeline-item-menu-header", children: [
39485
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-kind", children: target.kind === "block" ? "Block" : "Video" }),
39486
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-title", title: target.title, children: target.title })
39566
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-kind", children: target.kind === "block" ? "Block" : "Video" }),
39567
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-title", title: target.title, children: target.title })
39487
39568
  ] }),
39488
- target.kind === "block" ? /* @__PURE__ */ jsx78(
39569
+ target.kind === "block" ? /* @__PURE__ */ jsx79(
39489
39570
  BlockMenu,
39490
39571
  {
39491
39572
  target,
@@ -39497,8 +39578,8 @@ function TimelineItemMenu({
39497
39578
  onTransition: onBlockTransition
39498
39579
  }
39499
39580
  ) : /* @__PURE__ */ jsxs63(Fragment27, { children: [
39500
- /* @__PURE__ */ jsx78(VideoMenu, { target, onPatch: onVideoPatch }),
39501
- onEditMedia && /* @__PURE__ */ jsx78(
39581
+ /* @__PURE__ */ jsx79(VideoMenu, { target, onPatch: onVideoPatch }),
39582
+ onEditMedia && /* @__PURE__ */ jsx79(
39502
39583
  "button",
39503
39584
  {
39504
39585
  type: "button",
@@ -39549,7 +39630,7 @@ function BlockMenu({
39549
39630
  "Dynamic slides time each slide from the narration or reading pace, so this section's length and start can't be pinned.",
39550
39631
  pinned && " A pinned time here stops a narrated deck from playing."
39551
39632
  ] }),
39552
- pinned && onClearTiming && /* @__PURE__ */ jsx78(
39633
+ pinned && onClearTiming && /* @__PURE__ */ jsx79(
39553
39634
  "button",
39554
39635
  {
39555
39636
  type: "button",
@@ -39564,7 +39645,7 @@ function BlockMenu({
39564
39645
  )
39565
39646
  ] }) : /* @__PURE__ */ jsxs63(Fragment27, { children: [
39566
39647
  /* @__PURE__ */ jsxs63("label", { className: "squisq-timeline-item-menu-check", children: [
39567
- /* @__PURE__ */ jsx78(
39648
+ /* @__PURE__ */ jsx79(
39568
39649
  "input",
39569
39650
  {
39570
39651
  type: "checkbox",
@@ -39572,10 +39653,10 @@ function BlockMenu({
39572
39653
  onChange: (event) => toggleAutotime(event.target.checked)
39573
39654
  }
39574
39655
  ),
39575
- /* @__PURE__ */ jsx78("span", { children: "Autotime block" })
39656
+ /* @__PURE__ */ jsx79("span", { children: "Autotime block" })
39576
39657
  ] }),
39577
- /* @__PURE__ */ jsx78("p", { className: "squisq-timeline-item-menu-hint", children: "Uses narration, content, and interior media when no explicit duration is set." }),
39578
- /* @__PURE__ */ jsx78(
39658
+ /* @__PURE__ */ jsx79("p", { className: "squisq-timeline-item-menu-hint", children: "Uses narration, content, and interior media when no explicit duration is set." }),
39659
+ /* @__PURE__ */ jsx79(
39579
39660
  MenuNumberField,
39580
39661
  {
39581
39662
  label: "Duration",
@@ -39589,7 +39670,7 @@ function BlockMenu({
39589
39670
  }
39590
39671
  }
39591
39672
  ),
39592
- /* @__PURE__ */ jsx78(
39673
+ /* @__PURE__ */ jsx79(
39593
39674
  MenuNumberField,
39594
39675
  {
39595
39676
  label: "Start time",
@@ -39604,8 +39685,8 @@ function BlockMenu({
39604
39685
  )
39605
39686
  ] }),
39606
39687
  /* @__PURE__ */ jsxs63("div", { className: "squisq-timeline-item-menu-row", children: [
39607
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-label", children: "Transition" }),
39608
- /* @__PURE__ */ jsx78(
39688
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-label", children: "Transition" }),
39689
+ /* @__PURE__ */ jsx79(
39609
39690
  TransitionPicker,
39610
39691
  {
39611
39692
  value: transition,
@@ -39637,14 +39718,14 @@ function VideoMenu({
39637
39718
  ];
39638
39719
  return /* @__PURE__ */ jsxs63("div", { className: "squisq-timeline-item-menu-body", children: [
39639
39720
  /* @__PURE__ */ jsxs63("div", { className: "squisq-timeline-item-menu-field", children: [
39640
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-label", children: "Placement" }),
39641
- /* @__PURE__ */ jsx78(
39721
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-label", children: "Placement" }),
39722
+ /* @__PURE__ */ jsx79(
39642
39723
  "div",
39643
39724
  {
39644
39725
  className: "squisq-timeline-item-menu-segments",
39645
39726
  role: "group",
39646
39727
  "aria-label": "Video placement",
39647
- children: placementOptions.map((option) => /* @__PURE__ */ jsx78(
39728
+ children: placementOptions.map((option) => /* @__PURE__ */ jsx79(
39648
39729
  "button",
39649
39730
  {
39650
39731
  type: "button",
@@ -39666,7 +39747,7 @@ function VideoMenu({
39666
39747
  ] }),
39667
39748
  placed && /* @__PURE__ */ jsxs63(Fragment27, { children: [
39668
39749
  /* @__PURE__ */ jsxs63("label", { className: "squisq-timeline-item-menu-check", children: [
39669
- /* @__PURE__ */ jsx78(
39750
+ /* @__PURE__ */ jsx79(
39670
39751
  "input",
39671
39752
  {
39672
39753
  type: "checkbox",
@@ -39680,11 +39761,11 @@ function VideoMenu({
39680
39761
  }
39681
39762
  }
39682
39763
  ),
39683
- /* @__PURE__ */ jsx78("span", { children: "Lock to block" })
39764
+ /* @__PURE__ */ jsx79("span", { children: "Lock to block" })
39684
39765
  ] }),
39685
39766
  placement === "picture-in-picture" && /* @__PURE__ */ jsxs63(Fragment27, { children: [
39686
39767
  /* @__PURE__ */ jsxs63("label", { className: "squisq-timeline-item-menu-field", children: [
39687
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-label", children: "PIP size" }),
39768
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-label", children: "PIP size" }),
39688
39769
  /* @__PURE__ */ jsxs63(
39689
39770
  "select",
39690
39771
  {
@@ -39701,14 +39782,14 @@ function VideoMenu({
39701
39782
  titleCase(target.defaultPipSize),
39702
39783
  ")"
39703
39784
  ] }),
39704
- /* @__PURE__ */ jsx78("option", { value: "small", children: "Small" }),
39705
- /* @__PURE__ */ jsx78("option", { value: "large", children: "Large" })
39785
+ /* @__PURE__ */ jsx79("option", { value: "small", children: "Small" }),
39786
+ /* @__PURE__ */ jsx79("option", { value: "large", children: "Large" })
39706
39787
  ]
39707
39788
  }
39708
39789
  )
39709
39790
  ] }),
39710
39791
  /* @__PURE__ */ jsxs63("label", { className: "squisq-timeline-item-menu-field", children: [
39711
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-label", children: "PIP shape" }),
39792
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-label", children: "PIP shape" }),
39712
39793
  /* @__PURE__ */ jsxs63(
39713
39794
  "select",
39714
39795
  {
@@ -39725,14 +39806,14 @@ function VideoMenu({
39725
39806
  titleCase(target.defaultPipShape),
39726
39807
  ")"
39727
39808
  ] }),
39728
- /* @__PURE__ */ jsx78("option", { value: "square", children: "Square" }),
39729
- /* @__PURE__ */ jsx78("option", { value: "wide", children: "Wide (16:9)" })
39809
+ /* @__PURE__ */ jsx79("option", { value: "square", children: "Square" }),
39810
+ /* @__PURE__ */ jsx79("option", { value: "wide", children: "Wide (16:9)" })
39730
39811
  ]
39731
39812
  }
39732
39813
  )
39733
39814
  ] }),
39734
39815
  /* @__PURE__ */ jsxs63("label", { className: "squisq-timeline-item-menu-field", children: [
39735
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-label", children: "PIP position" }),
39816
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-label", children: "PIP position" }),
39736
39817
  /* @__PURE__ */ jsxs63(
39737
39818
  "select",
39738
39819
  {
@@ -39749,10 +39830,10 @@ function VideoMenu({
39749
39830
  positionLabel(target.defaultPipPosition),
39750
39831
  ")"
39751
39832
  ] }),
39752
- /* @__PURE__ */ jsx78("option", { value: "top-left", children: "Top left" }),
39753
- /* @__PURE__ */ jsx78("option", { value: "top-right", children: "Top right" }),
39754
- /* @__PURE__ */ jsx78("option", { value: "bottom-left", children: "Bottom left" }),
39755
- /* @__PURE__ */ jsx78("option", { value: "bottom-right", children: "Bottom right" })
39833
+ /* @__PURE__ */ jsx79("option", { value: "top-left", children: "Top left" }),
39834
+ /* @__PURE__ */ jsx79("option", { value: "top-right", children: "Top right" }),
39835
+ /* @__PURE__ */ jsx79("option", { value: "bottom-left", children: "Bottom left" }),
39836
+ /* @__PURE__ */ jsx79("option", { value: "bottom-right", children: "Bottom right" })
39756
39837
  ]
39757
39838
  }
39758
39839
  )
@@ -39770,9 +39851,9 @@ function MenuNumberField({
39770
39851
  onChange
39771
39852
  }) {
39772
39853
  return /* @__PURE__ */ jsxs63("label", { className: "squisq-timeline-item-menu-field", children: [
39773
- /* @__PURE__ */ jsx78("span", { className: "squisq-timeline-item-menu-label", children: label }),
39854
+ /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-item-menu-label", children: label }),
39774
39855
  /* @__PURE__ */ jsxs63("span", { className: "squisq-timeline-item-menu-number", children: [
39775
- /* @__PURE__ */ jsx78(
39856
+ /* @__PURE__ */ jsx79(
39776
39857
  "input",
39777
39858
  {
39778
39859
  type: "number",
@@ -39785,7 +39866,7 @@ function MenuNumberField({
39785
39866
  onChange: (event) => onChange(event.target.value)
39786
39867
  }
39787
39868
  ),
39788
- /* @__PURE__ */ jsx78("span", { children: "sec" })
39869
+ /* @__PURE__ */ jsx79("span", { children: "sec" })
39789
39870
  ] })
39790
39871
  ] });
39791
39872
  }
@@ -39830,8 +39911,8 @@ function menuStyle(anchor, element) {
39830
39911
  }
39831
39912
 
39832
39913
  // src/TimelineTrack.tsx
39833
- import { jsx as jsx79, jsxs as jsxs64 } from "react/jsx-runtime";
39834
- var PREVIEW_VIEWPORT = VIEWPORT_PRESETS6.landscape;
39914
+ import { jsx as jsx80, jsxs as jsxs64 } from "react/jsx-runtime";
39915
+ var PREVIEW_VIEWPORT = VIEWPORT_PRESETS7.landscape;
39835
39916
  var DEFAULT_PX_PER_SECOND = 18;
39836
39917
  var ZOOM_MIN = 4;
39837
39918
  var ZOOM_MAX = 160;
@@ -39853,9 +39934,9 @@ function TimelineVideoFilmstrip({
39853
39934
  FILMSTRIP_MAX_FRAMES,
39854
39935
  Math.max(1, Math.ceil(width / FILMSTRIP_FRAME_WIDTH))
39855
39936
  );
39856
- return /* @__PURE__ */ jsx79("div", { className: "squisq-timeline-video-filmstrip", "aria-hidden": "true", children: Array.from({ length: frameCount }, (_2, index2) => {
39937
+ return /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-video-filmstrip", "aria-hidden": "true", children: Array.from({ length: frameCount }, (_2, index2) => {
39857
39938
  const sampleTime = Math.max(0, sourceStart) + Math.max(0, sourceLength) * ((index2 + 0.5) / frameCount);
39858
- return /* @__PURE__ */ jsx79(
39939
+ return /* @__PURE__ */ jsx80(
39859
39940
  "video",
39860
39941
  {
39861
39942
  src: resolvedSrc,
@@ -39938,7 +40019,7 @@ function TimelineTrack({
39938
40019
  play();
39939
40020
  }, [play]);
39940
40021
  const [scrubbing, setScrubbing] = useState75(false);
39941
- useEffect63(() => {
40022
+ useEffect64(() => {
39942
40023
  if (!scrubbing) return;
39943
40024
  const onMove = (e2) => {
39944
40025
  const scroll = scrollRef.current;
@@ -39976,7 +40057,7 @@ function TimelineTrack({
39976
40057
  [blocks]
39977
40058
  );
39978
40059
  const followedBlockRef = useRef58(null);
39979
- useEffect63(() => {
40060
+ useEffect64(() => {
39980
40061
  if (!isPlaying) {
39981
40062
  followedBlockRef.current = null;
39982
40063
  return;
@@ -39987,7 +40068,7 @@ function TimelineTrack({
39987
40068
  const line = headingLine(block);
39988
40069
  if (line != null) goToBlockByLine(line);
39989
40070
  }, [isPlaying, currentTime, blockAtTime, goToBlockByLine]);
39990
- useEffect63(() => {
40071
+ useEffect64(() => {
39991
40072
  if (!isPlaying) return;
39992
40073
  const scroll = scrollRef.current;
39993
40074
  if (!scroll) return;
@@ -40036,7 +40117,7 @@ function TimelineTrack({
40036
40117
  const zoomIn = useCallback49(() => setPxPerSecond((s) => Math.min(ZOOM_MAX, s * ZOOM_FACTOR)), []);
40037
40118
  const zoomOut = useCallback49(() => setPxPerSecond((s) => Math.max(ZOOM_MIN, s / ZOOM_FACTOR)), []);
40038
40119
  const [viewportWidth, setViewportWidth] = useState75(0);
40039
- useEffect63(() => {
40120
+ useEffect64(() => {
40040
40121
  const el = scrollRef.current;
40041
40122
  if (!el || typeof ResizeObserver === "undefined") return;
40042
40123
  const update = () => setViewportWidth(el.clientWidth);
@@ -40050,7 +40131,7 @@ function TimelineTrack({
40050
40131
  const dragRef = useRef58(null);
40051
40132
  dragRef.current = drag;
40052
40133
  const isDragging = drag != null && !drag.committed;
40053
- useEffect63(() => {
40134
+ useEffect64(() => {
40054
40135
  if (!isDragging) return;
40055
40136
  const onMove = (e2) => {
40056
40137
  const d = dragRef.current;
@@ -40081,7 +40162,7 @@ function TimelineTrack({
40081
40162
  window.removeEventListener("pointerup", onUp);
40082
40163
  };
40083
40164
  }, [isDragging]);
40084
- useEffect63(() => {
40165
+ useEffect64(() => {
40085
40166
  if (dragRef.current?.committed) setDrag(null);
40086
40167
  }, [doc]);
40087
40168
  const beginDrag = useCallback49(
@@ -40167,7 +40248,7 @@ function TimelineTrack({
40167
40248
  for (let t = 0; t <= rulerEnd + 1e-3 && ticks.length < 1e3; t += tickSeconds) ticks.push(t);
40168
40249
  return /* @__PURE__ */ jsxs64("div", { className: "squisq-timeline", style: { height }, "data-testid": "timeline-track", children: [
40169
40250
  /* @__PURE__ */ jsxs64("div", { className: "squisq-timeline-controls", children: [
40170
- /* @__PURE__ */ jsx79(
40251
+ /* @__PURE__ */ jsx80(
40171
40252
  "button",
40172
40253
  {
40173
40254
  type: "button",
@@ -40184,7 +40265,7 @@ function TimelineTrack({
40184
40265
  " / ",
40185
40266
  formatClock3(total)
40186
40267
  ] }),
40187
- /* @__PURE__ */ jsx79(
40268
+ /* @__PURE__ */ jsx80(
40188
40269
  "button",
40189
40270
  {
40190
40271
  type: "button",
@@ -40196,7 +40277,7 @@ function TimelineTrack({
40196
40277
  children: "\u2212"
40197
40278
  }
40198
40279
  ),
40199
- /* @__PURE__ */ jsx79(
40280
+ /* @__PURE__ */ jsx80(
40200
40281
  "button",
40201
40282
  {
40202
40283
  type: "button",
@@ -40209,8 +40290,8 @@ function TimelineTrack({
40209
40290
  }
40210
40291
  )
40211
40292
  ] }),
40212
- /* @__PURE__ */ jsx79("div", { className: "squisq-timeline-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs64("div", { className: "squisq-timeline-inner", style: { width }, children: [
40213
- /* @__PURE__ */ jsx79("div", { className: "squisq-timeline-row squisq-timeline-row--blocks", children: blocks.map((b, i) => {
40293
+ /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs64("div", { className: "squisq-timeline-inner", style: { width }, children: [
40294
+ /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-row squisq-timeline-row--blocks", children: blocks.map((b, i) => {
40214
40295
  const line = headingLine(b);
40215
40296
  const isActive = line != null && line === activeBlockStartLine;
40216
40297
  const left = previewLeft(i);
@@ -40227,7 +40308,7 @@ function TimelineTrack({
40227
40308
  if (line != null) goToBlockByLine(line);
40228
40309
  },
40229
40310
  children: [
40230
- visualByBlock.has(b.id) && /* @__PURE__ */ jsx79("div", { className: "squisq-timeline-block-thumb", "aria-hidden": true, children: /* @__PURE__ */ jsx79(
40311
+ visualByBlock.has(b.id) && /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-block-thumb", "aria-hidden": true, children: /* @__PURE__ */ jsx80(
40231
40312
  BlockThumbnail,
40232
40313
  {
40233
40314
  visual: visualByBlock.get(b.id),
@@ -40235,7 +40316,7 @@ function TimelineTrack({
40235
40316
  mediaProvider
40236
40317
  }
40237
40318
  ) }),
40238
- !timingLocked && prev && headingLine(prev) != null && /* @__PURE__ */ jsx79(
40319
+ !timingLocked && prev && headingLine(prev) != null && /* @__PURE__ */ jsx80(
40239
40320
  "span",
40240
40321
  {
40241
40322
  className: "squisq-timeline-edge squisq-timeline-edge--left",
@@ -40256,8 +40337,8 @@ function TimelineTrack({
40256
40337
  )
40257
40338
  }
40258
40339
  ),
40259
- /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-block-label", children: b.title ?? b.id }),
40260
- line != null && /* @__PURE__ */ jsx79(
40340
+ /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-block-label", children: b.title ?? b.id }),
40341
+ line != null && /* @__PURE__ */ jsx80(
40261
40342
  "button",
40262
40343
  {
40263
40344
  type: "button",
@@ -40279,7 +40360,7 @@ function TimelineTrack({
40279
40360
  children: "\u2026"
40280
40361
  }
40281
40362
  ),
40282
- !timingLocked && line != null && /* @__PURE__ */ jsx79(
40363
+ !timingLocked && line != null && /* @__PURE__ */ jsx80(
40283
40364
  "span",
40284
40365
  {
40285
40366
  className: "squisq-timeline-edge squisq-timeline-edge--right",
@@ -40328,7 +40409,7 @@ function TimelineTrack({
40328
40409
  ...raw.edits ? { edits: raw.edits } : {}
40329
40410
  } : { kind: c.kind, src: c.src, clipStart: c.sourceIn };
40330
40411
  };
40331
- return /* @__PURE__ */ jsx79(
40412
+ return /* @__PURE__ */ jsx80(
40332
40413
  "div",
40333
40414
  {
40334
40415
  className: "squisq-timeline-row squisq-timeline-row--media",
@@ -40365,7 +40446,7 @@ function TimelineTrack({
40365
40446
  if (next) setMarkdownSource(next);
40366
40447
  },
40367
40448
  children: [
40368
- c.kind === "video" && /* @__PURE__ */ jsx79(
40449
+ c.kind === "video" && /* @__PURE__ */ jsx80(
40369
40450
  TimelineVideoFilmstrip,
40370
40451
  {
40371
40452
  src: c.src,
@@ -40374,8 +40455,8 @@ function TimelineTrack({
40374
40455
  width: clipWidth
40375
40456
  }
40376
40457
  ),
40377
- /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-clip-label", children: timelineMediaLabel(c.src, c.kind) }),
40378
- cutMarks.map((at2) => /* @__PURE__ */ jsx79(
40458
+ /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-clip-label", children: timelineMediaLabel(c.src, c.kind) }),
40459
+ cutMarks.map((at2) => /* @__PURE__ */ jsx80(
40379
40460
  "span",
40380
40461
  {
40381
40462
  className: "squisq-timeline-cut-mark",
@@ -40384,7 +40465,7 @@ function TimelineTrack({
40384
40465
  },
40385
40466
  at2
40386
40467
  )),
40387
- c.kind === "video" && c.sourceLine != null && /* @__PURE__ */ jsx79(
40468
+ c.kind === "video" && c.sourceLine != null && /* @__PURE__ */ jsx80(
40388
40469
  "button",
40389
40470
  {
40390
40471
  type: "button",
@@ -40410,7 +40491,7 @@ function TimelineTrack({
40410
40491
  children: "\u2026"
40411
40492
  }
40412
40493
  ),
40413
- editable && /* @__PURE__ */ jsx79(
40494
+ editable && /* @__PURE__ */ jsx80(
40414
40495
  "span",
40415
40496
  {
40416
40497
  className: "squisq-timeline-edge squisq-timeline-edge--right",
@@ -40460,7 +40541,7 @@ function TimelineTrack({
40460
40541
  ...m.clipStart != null ? { clipStart: m.clipStart } : {},
40461
40542
  ...m.clipEnd != null ? { clipEnd: m.clipEnd } : {}
40462
40543
  };
40463
- return /* @__PURE__ */ jsx79(
40544
+ return /* @__PURE__ */ jsx80(
40464
40545
  "div",
40465
40546
  {
40466
40547
  className: "squisq-timeline-row squisq-timeline-row--media",
@@ -40487,7 +40568,7 @@ function TimelineTrack({
40487
40568
  { onClick: () => selectClipAt(b.startTime, b.id) }
40488
40569
  ),
40489
40570
  children: [
40490
- m.kind === "video" && /* @__PURE__ */ jsx79(
40571
+ m.kind === "video" && /* @__PURE__ */ jsx80(
40491
40572
  TimelineVideoFilmstrip,
40492
40573
  {
40493
40574
  src: m.src,
@@ -40496,8 +40577,8 @@ function TimelineTrack({
40496
40577
  width: clipWidth
40497
40578
  }
40498
40579
  ),
40499
- /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-clip-label", children: timelineMediaLabel(m.src, m.kind) }),
40500
- m.kind === "video" && m.sourceLine != null && /* @__PURE__ */ jsx79(
40580
+ /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-clip-label", children: timelineMediaLabel(m.src, m.kind) }),
40581
+ m.kind === "video" && m.sourceLine != null && /* @__PURE__ */ jsx80(
40501
40582
  "button",
40502
40583
  {
40503
40584
  type: "button",
@@ -40522,7 +40603,7 @@ function TimelineTrack({
40522
40603
  children: "\u2026"
40523
40604
  }
40524
40605
  ),
40525
- m.sourceLine != null && /* @__PURE__ */ jsx79(
40606
+ m.sourceLine != null && /* @__PURE__ */ jsx80(
40526
40607
  "span",
40527
40608
  {
40528
40609
  className: "squisq-timeline-edge squisq-timeline-edge--right",
@@ -40544,7 +40625,7 @@ function TimelineTrack({
40544
40625
  })
40545
40626
  )
40546
40627
  ] }),
40547
- /* @__PURE__ */ jsx79(
40628
+ /* @__PURE__ */ jsx80(
40548
40629
  "div",
40549
40630
  {
40550
40631
  className: "squisq-timeline-row squisq-timeline-row--ruler",
@@ -40552,10 +40633,10 @@ function TimelineTrack({
40552
40633
  const rect = e2.currentTarget.getBoundingClientRect();
40553
40634
  seek((e2.clientX - rect.left) / pxPerSecond);
40554
40635
  },
40555
- children: ticks.map((t) => /* @__PURE__ */ jsx79("div", { className: "squisq-timeline-tick", style: { left: t * pxPerSecond }, children: /* @__PURE__ */ jsx79("span", { className: "squisq-timeline-tick-label", children: formatDur(t) }) }, t))
40636
+ children: ticks.map((t) => /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-tick", style: { left: t * pxPerSecond }, children: /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-tick-label", children: formatDur(t) }) }, t))
40556
40637
  }
40557
40638
  ),
40558
- /* @__PURE__ */ jsx79(
40639
+ /* @__PURE__ */ jsx80(
40559
40640
  "div",
40560
40641
  {
40561
40642
  className: "squisq-timeline-playhead",
@@ -40567,11 +40648,11 @@ function TimelineTrack({
40567
40648
  pause();
40568
40649
  setScrubbing(true);
40569
40650
  },
40570
- children: /* @__PURE__ */ jsx79("div", { className: "squisq-timeline-playhead-knob" })
40651
+ children: /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-playhead-knob" })
40571
40652
  }
40572
40653
  )
40573
40654
  ] }) }),
40574
- /* @__PURE__ */ jsx79("div", { ref: activeClock.registerMediaHost, className: "squisq-timeline-media-host", "aria-hidden": true, children: /* @__PURE__ */ jsx79(MediaContext5.Provider, { value: mediaProvider ?? null, children: /* @__PURE__ */ jsx79(
40655
+ /* @__PURE__ */ jsx80("div", { ref: activeClock.registerMediaHost, className: "squisq-timeline-media-host", "aria-hidden": true, children: /* @__PURE__ */ jsx80(MediaContext6.Provider, { value: mediaProvider ?? null, children: /* @__PURE__ */ jsx80(
40575
40656
  MediaClipLayer,
40576
40657
  {
40577
40658
  schedule: playbackClips,
@@ -40580,7 +40661,7 @@ function TimelineTrack({
40580
40661
  basePath
40581
40662
  }
40582
40663
  ) }) }),
40583
- itemMenu && itemMenuTarget && /* @__PURE__ */ jsx79(
40664
+ itemMenu && itemMenuTarget && /* @__PURE__ */ jsx80(
40584
40665
  TimelineItemMenu,
40585
40666
  {
40586
40667
  anchor: itemMenu.anchor,
@@ -40651,7 +40732,7 @@ function formatDur(seconds) {
40651
40732
  // src/TimelineVideoPanel.tsx
40652
40733
  import { useMemo as useMemo50 } from "react";
40653
40734
  import { MediaClipLayer as MediaClipLayer2 } from "@bendyline/squisq-react";
40654
- import { jsx as jsx80, jsxs as jsxs65 } from "react/jsx-runtime";
40735
+ import { jsx as jsx81, jsxs as jsxs65 } from "react/jsx-runtime";
40655
40736
  function TimelineVideoPanel({
40656
40737
  schedule,
40657
40738
  currentTime,
@@ -40672,10 +40753,10 @@ function TimelineVideoPanel({
40672
40753
  "aria-label": "Timeline video preview",
40673
40754
  children: [
40674
40755
  /* @__PURE__ */ jsxs65("header", { className: "squisq-timeline-video-header", children: [
40675
- /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-video-title", children: "Video monitor" }),
40676
- /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-video-label", title: activeLabel, children: activeLabel }),
40677
- /* @__PURE__ */ jsx80("span", { className: "squisq-timeline-video-time", children: formatClock4(currentTime) }),
40678
- onClose && /* @__PURE__ */ jsx80(
40756
+ /* @__PURE__ */ jsx81("span", { className: "squisq-timeline-video-title", children: "Video monitor" }),
40757
+ /* @__PURE__ */ jsx81("span", { className: "squisq-timeline-video-label", title: activeLabel, children: activeLabel }),
40758
+ /* @__PURE__ */ jsx81("span", { className: "squisq-timeline-video-time", children: formatClock4(currentTime) }),
40759
+ onClose && /* @__PURE__ */ jsx81(
40679
40760
  "button",
40680
40761
  {
40681
40762
  type: "button",
@@ -40687,8 +40768,8 @@ function TimelineVideoPanel({
40687
40768
  }
40688
40769
  )
40689
40770
  ] }),
40690
- /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-video-body", children: /* @__PURE__ */ jsxs65("div", { className: "squisq-timeline-video-stage", children: [
40691
- /* @__PURE__ */ jsx80(
40771
+ /* @__PURE__ */ jsx81("div", { className: "squisq-timeline-video-body", children: /* @__PURE__ */ jsxs65("div", { className: "squisq-timeline-video-stage", children: [
40772
+ /* @__PURE__ */ jsx81(
40692
40773
  MediaClipLayer2,
40693
40774
  {
40694
40775
  schedule: videos,
@@ -40700,7 +40781,7 @@ function TimelineVideoPanel({
40700
40781
  muted: true
40701
40782
  }
40702
40783
  ),
40703
- activeVideos.length === 0 && /* @__PURE__ */ jsx80("div", { className: "squisq-timeline-video-empty", children: "Move the playhead onto a video clip" })
40784
+ activeVideos.length === 0 && /* @__PURE__ */ jsx81("div", { className: "squisq-timeline-video-empty", children: "Move the playhead onto a video clip" })
40704
40785
  ] }) })
40705
40786
  ]
40706
40787
  }
@@ -40716,7 +40797,7 @@ function formatClock4(seconds) {
40716
40797
  import { useMemo as useMemo51 } from "react";
40717
40798
  import { getDocPlaybackDuration as getDocPlaybackDuration2, resolveMediaSchedule as resolveMediaSchedule3 } from "@bendyline/squisq/schemas";
40718
40799
  import { DocPlayer } from "@bendyline/squisq-react";
40719
- import { jsx as jsx81, jsxs as jsxs66 } from "react/jsx-runtime";
40800
+ import { jsx as jsx82, jsxs as jsxs66 } from "react/jsx-runtime";
40720
40801
  function TimelineCompositionPanel({
40721
40802
  doc,
40722
40803
  clock,
@@ -40788,11 +40869,11 @@ function TimelineCompositionPanel({
40788
40869
  "aria-label": "Timeline video composition preview",
40789
40870
  children: [
40790
40871
  /* @__PURE__ */ jsxs66("header", { className: "squisq-timeline-video-header", children: [
40791
- /* @__PURE__ */ jsx81("span", { className: "squisq-timeline-video-title", children: "Video composition" }),
40792
- /* @__PURE__ */ jsx81("span", { className: "squisq-timeline-video-label", children: formatPresentation(effectiveVideoPresentation) }),
40793
- /* @__PURE__ */ jsx81(PreviewToolbarControls, { displayMode: "video" }),
40794
- /* @__PURE__ */ jsx81("span", { className: "squisq-timeline-video-time", children: formatClock5(clock.currentTime) }),
40795
- onClose && /* @__PURE__ */ jsx81(
40872
+ /* @__PURE__ */ jsx82("span", { className: "squisq-timeline-video-title", children: "Video composition" }),
40873
+ /* @__PURE__ */ jsx82("span", { className: "squisq-timeline-video-label", children: formatPresentation(effectiveVideoPresentation) }),
40874
+ /* @__PURE__ */ jsx82(PreviewToolbarControls, { displayMode: "video" }),
40875
+ /* @__PURE__ */ jsx82("span", { className: "squisq-timeline-video-time", children: formatClock5(clock.currentTime) }),
40876
+ onClose && /* @__PURE__ */ jsx82(
40796
40877
  "button",
40797
40878
  {
40798
40879
  type: "button",
@@ -40804,7 +40885,7 @@ function TimelineCompositionPanel({
40804
40885
  }
40805
40886
  )
40806
40887
  ] }),
40807
- /* @__PURE__ */ jsx81("div", { className: "squisq-timeline-video-body", children: /* @__PURE__ */ jsx81("div", { className: "squisq-timeline-composition-stage", children: playerDoc ? /* @__PURE__ */ jsx81(
40888
+ /* @__PURE__ */ jsx82("div", { className: "squisq-timeline-video-body", children: /* @__PURE__ */ jsx82("div", { className: "squisq-timeline-composition-stage", children: playerDoc ? /* @__PURE__ */ jsx82(
40808
40889
  DocPlayer,
40809
40890
  {
40810
40891
  doc: playerDoc,
@@ -40830,7 +40911,7 @@ function TimelineCompositionPanel({
40830
40911
  enableSwipe: false,
40831
40912
  globalKeyboardShortcuts: false
40832
40913
  }
40833
- ) : /* @__PURE__ */ jsx81("div", { className: "squisq-timeline-video-empty", children: "Preparing video composition\u2026" }) }) })
40914
+ ) : /* @__PURE__ */ jsx82("div", { className: "squisq-timeline-video-empty", children: "Preparing video composition\u2026" }) }) })
40834
40915
  ]
40835
40916
  }
40836
40917
  );
@@ -40847,7 +40928,7 @@ function formatPresentation(presentation) {
40847
40928
  }
40848
40929
 
40849
40930
  // src/TimelineToolbar.tsx
40850
- import { jsx as jsx82, jsxs as jsxs67 } from "react/jsx-runtime";
40931
+ import { jsx as jsx83, jsxs as jsxs67 } from "react/jsx-runtime";
40851
40932
  function TimelineToolbar({
40852
40933
  literalVideoVisible,
40853
40934
  compositionVisible,
@@ -40864,7 +40945,7 @@ function TimelineToolbar({
40864
40945
  "aria-label": "Timeline view controls",
40865
40946
  "data-testid": "timeline-toolbar",
40866
40947
  children: [
40867
- /* @__PURE__ */ jsx82("span", { className: "squisq-timeline-toolbar-title", children: "Preview panes" }),
40948
+ /* @__PURE__ */ jsx83("span", { className: "squisq-timeline-toolbar-title", children: "Preview panes" }),
40868
40949
  /* @__PURE__ */ jsxs67(
40869
40950
  "button",
40870
40951
  {
@@ -40877,7 +40958,7 @@ function TimelineToolbar({
40877
40958
  "data-tooltip": literalVideoVisible ? "Hide literal video" : "Show literal video",
40878
40959
  children: [
40879
40960
  /* @__PURE__ */ jsxs67("svg", { width: "15", height: "15", viewBox: "0 0 15 15", "aria-hidden": "true", children: [
40880
- /* @__PURE__ */ jsx82(
40961
+ /* @__PURE__ */ jsx83(
40881
40962
  "rect",
40882
40963
  {
40883
40964
  x: "1.5",
@@ -40890,7 +40971,7 @@ function TimelineToolbar({
40890
40971
  strokeWidth: "1.4"
40891
40972
  }
40892
40973
  ),
40893
- /* @__PURE__ */ jsx82(
40974
+ /* @__PURE__ */ jsx83(
40894
40975
  "path",
40895
40976
  {
40896
40977
  d: "M10 5.5 13.5 4v7L10 9.5z",
@@ -40901,7 +40982,7 @@ function TimelineToolbar({
40901
40982
  }
40902
40983
  )
40903
40984
  ] }),
40904
- /* @__PURE__ */ jsx82("span", { children: "Video monitor" })
40985
+ /* @__PURE__ */ jsx83("span", { children: "Video monitor" })
40905
40986
  ]
40906
40987
  }
40907
40988
  ),
@@ -40917,7 +40998,7 @@ function TimelineToolbar({
40917
40998
  "data-tooltip": compositionVisible ? "Hide video composition" : "Show video composition",
40918
40999
  children: [
40919
41000
  /* @__PURE__ */ jsxs67("svg", { width: "15", height: "15", viewBox: "0 0 15 15", "aria-hidden": "true", children: [
40920
- /* @__PURE__ */ jsx82(
41001
+ /* @__PURE__ */ jsx83(
40921
41002
  "rect",
40922
41003
  {
40923
41004
  x: "1.5",
@@ -40930,10 +41011,10 @@ function TimelineToolbar({
40930
41011
  strokeWidth: "1.4"
40931
41012
  }
40932
41013
  ),
40933
- /* @__PURE__ */ jsx82("path", { d: "M5 13h5M7.5 11v2", stroke: "currentColor", strokeWidth: "1.4" }),
40934
- /* @__PURE__ */ jsx82("path", { d: "m6.3 5 3 1.5-3 1.5z", fill: "currentColor" })
41014
+ /* @__PURE__ */ jsx83("path", { d: "M5 13h5M7.5 11v2", stroke: "currentColor", strokeWidth: "1.4" }),
41015
+ /* @__PURE__ */ jsx83("path", { d: "m6.3 5 3 1.5-3 1.5z", fill: "currentColor" })
40935
41016
  ] }),
40936
- /* @__PURE__ */ jsx82("span", { children: "Video composition" })
41017
+ /* @__PURE__ */ jsx83("span", { children: "Video composition" })
40937
41018
  ]
40938
41019
  }
40939
41020
  )
@@ -40943,7 +41024,7 @@ function TimelineToolbar({
40943
41024
  }
40944
41025
 
40945
41026
  // src/PlainHtmlPreview.tsx
40946
- import { useCallback as useCallback50, useEffect as useEffect64, useMemo as useMemo52, useRef as useRef59, useState as useState76 } from "react";
41027
+ import { useCallback as useCallback50, useEffect as useEffect65, useMemo as useMemo52, useRef as useRef59, useState as useState76 } from "react";
40947
41028
  import {
40948
41029
  isSvgImageSource as isSvgImageSource2,
40949
41030
  parseMarkdown as parseMarkdown9,
@@ -40987,7 +41068,7 @@ function isFontAwesomeRule(rule) {
40987
41068
  }
40988
41069
 
40989
41070
  // src/PlainHtmlPreview.tsx
40990
- import { jsx as jsx83 } from "react/jsx-runtime";
41071
+ import { jsx as jsx84 } from "react/jsx-runtime";
40991
41072
  var cachedRender = null;
40992
41073
  var cachedRenderPromise = null;
40993
41074
  function loadRenderFn() {
@@ -41053,7 +41134,7 @@ function PlainHtmlPreview({
41053
41134
  const parsedDoc = useMemo52(() => parseMarkdown9(markdown), [markdown]);
41054
41135
  const [wikiProjection, setWikiProjection] = useState76(null);
41055
41136
  const mdDoc = wikiProjection?.source === parsedDoc && wikiProjection.support === wikiLinks ? wikiProjection.doc : parsedDoc;
41056
- useEffect64(() => {
41137
+ useEffect65(() => {
41057
41138
  if (!wikiLinks) return;
41058
41139
  let cancelled = false;
41059
41140
  void resolveWikiLinks(
@@ -41072,7 +41153,7 @@ function PlainHtmlPreview({
41072
41153
  };
41073
41154
  }, [parsedDoc, wikiLinks]);
41074
41155
  const [resolvedImages, setResolvedImages] = useState76(null);
41075
- useEffect64(() => {
41156
+ useEffect65(() => {
41076
41157
  if (!mediaProvider) {
41077
41158
  setResolvedImages(null);
41078
41159
  return;
@@ -41109,7 +41190,7 @@ function PlainHtmlPreview({
41109
41190
  }, [resolvedImages, images]);
41110
41191
  const iconsCss = useMemo52(() => collectInlineFontAwesomeCss(), []);
41111
41192
  const [preparation, setPreparation] = useState76(null);
41112
- useEffect64(() => {
41193
+ useEffect65(() => {
41113
41194
  let cancelled = false;
41114
41195
  loadPreparation().then(
41115
41196
  (loaded) => {
@@ -41136,7 +41217,7 @@ function PlainHtmlPreview({
41136
41217
  );
41137
41218
  const [prepared, setPrepared] = useState76(null);
41138
41219
  const preparedOnceRef = useRef59(false);
41139
- useEffect64(() => {
41220
+ useEffect65(() => {
41140
41221
  if (!preparation || !needsPreparation) return;
41141
41222
  let cancelled = false;
41142
41223
  const prepare = () => {
@@ -41164,7 +41245,7 @@ function PlainHtmlPreview({
41164
41245
  }, [preparation, needsPreparation, mdDoc, container, dataTableCache]);
41165
41246
  const view = needsPreparation ? prepared : null;
41166
41247
  const [renderFn, setRenderFn] = useState76(() => cachedRender);
41167
- useEffect64(() => {
41248
+ useEffect65(() => {
41168
41249
  if (renderFn) return;
41169
41250
  let cancelled = false;
41170
41251
  loadRenderFn().then((fn) => {
@@ -41205,7 +41286,7 @@ function PlainHtmlPreview({
41205
41286
  frameDocument.addEventListener("click", handleClick, true);
41206
41287
  removeFrameLinkHandlerRef.current = () => frameDocument.removeEventListener("click", handleClick, true);
41207
41288
  }, [onLinkClick]);
41208
- useEffect64(() => {
41289
+ useEffect65(() => {
41209
41290
  installFrameLinkHandler();
41210
41291
  return () => removeFrameLinkHandlerRef.current();
41211
41292
  }, [html, installFrameLinkHandler]);
@@ -41301,11 +41382,11 @@ function PlainHtmlPreview({
41301
41382
  style2.remove();
41302
41383
  };
41303
41384
  }, [onCopyCode, showCodeCopyButton]);
41304
- useEffect64(() => {
41385
+ useEffect65(() => {
41305
41386
  installFrameCodeCopyControls();
41306
41387
  return () => removeFrameCodeCopyControlsRef.current();
41307
41388
  }, [html, installFrameCodeCopyControls]);
41308
- useEffect64(() => {
41389
+ useEffect65(() => {
41309
41390
  if (!globalKeyboardShortcuts) return;
41310
41391
  const handleKeyDown = (event) => {
41311
41392
  if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.key !== "ArrowDown" && event.key !== "ArrowUp") {
@@ -41329,7 +41410,7 @@ function PlainHtmlPreview({
41329
41410
  document.addEventListener("keydown", handleKeyDown);
41330
41411
  return () => document.removeEventListener("keydown", handleKeyDown);
41331
41412
  }, [globalKeyboardShortcuts]);
41332
- return /* @__PURE__ */ jsx83(
41413
+ return /* @__PURE__ */ jsx84(
41333
41414
  "iframe",
41334
41415
  {
41335
41416
  ref: setIframeRef,
@@ -41390,7 +41471,7 @@ function collectImageRefs(doc) {
41390
41471
  }
41391
41472
 
41392
41473
  // src/PreviewPanel.tsx
41393
- import { useState as useState80, useEffect as useEffect69, useMemo as useMemo57, useCallback as useCallback54, useRef as useRef63 } from "react";
41474
+ import { useState as useState80, useEffect as useEffect70, useMemo as useMemo57, useCallback as useCallback54, useRef as useRef63 } from "react";
41394
41475
  import { createPortal as createPortal18 } from "react-dom";
41395
41476
  import {
41396
41477
  DashboardView,
@@ -41535,7 +41616,7 @@ import {
41535
41616
  createContext as createContext7,
41536
41617
  useCallback as useCallback51,
41537
41618
  useContext as useContext7,
41538
- useEffect as useEffect65,
41619
+ useEffect as useEffect66,
41539
41620
  useId as useId15,
41540
41621
  useLayoutEffect as useLayoutEffect15,
41541
41622
  useMemo as useMemo53,
@@ -41544,7 +41625,7 @@ import {
41544
41625
  } from "react";
41545
41626
  import { createPortal as createPortal17 } from "react-dom";
41546
41627
  import { inferDocumentTitle as inferDocumentTitle2 } from "@bendyline/squisq/markdown";
41547
- import { jsx as jsx84, jsxs as jsxs68 } from "react/jsx-runtime";
41628
+ import { jsx as jsx85, jsxs as jsxs68 } from "react/jsx-runtime";
41548
41629
  var PresentationModeContext = createContext7(null);
41549
41630
  function usePresentationMode() {
41550
41631
  const value = useContext7(PresentationModeContext);
@@ -41802,12 +41883,12 @@ function PresentationModeProvider({
41802
41883
  },
41803
41884
  [availableTargets, selectedTarget, stop]
41804
41885
  );
41805
- useEffect65(() => {
41886
+ useEffect66(() => {
41806
41887
  if (availableTargets.includes(selectedTarget)) return;
41807
41888
  setSelectedTarget("control");
41808
41889
  if (activeTargetRef.current !== null) void stop();
41809
41890
  }, [availableTargets, selectedTarget, stop]);
41810
- useEffect65(() => {
41891
+ useEffect66(() => {
41811
41892
  const root = rootRef.current;
41812
41893
  const ownerDocument = root?.ownerDocument;
41813
41894
  if (!root || !ownerDocument) return;
@@ -41819,7 +41900,7 @@ function PresentationModeProvider({
41819
41900
  ownerDocument.addEventListener("fullscreenchange", handleFullscreenChange);
41820
41901
  return () => ownerDocument.removeEventListener("fullscreenchange", handleFullscreenChange);
41821
41902
  }, [rootRef]);
41822
- useEffect65(() => {
41903
+ useEffect66(() => {
41823
41904
  const root = rootRef.current;
41824
41905
  if (!root) return;
41825
41906
  if (activeTarget) root.dataset.presentationMode = activeTarget;
@@ -41828,10 +41909,10 @@ function PresentationModeProvider({
41828
41909
  delete root.dataset.presentationMode;
41829
41910
  };
41830
41911
  }, [activeTarget, rootRef]);
41831
- useEffect65(() => {
41912
+ useEffect66(() => {
41832
41913
  if (activeView !== "preview" && activeTargetRef.current !== null) void stop();
41833
41914
  }, [activeView, stop]);
41834
- useEffect65(() => {
41915
+ useEffect66(() => {
41835
41916
  const previous = previousActiveTargetRef.current;
41836
41917
  previousActiveTargetRef.current = activeTarget;
41837
41918
  if (previous === null || activeTarget !== null) return;
@@ -41839,7 +41920,7 @@ function PresentationModeProvider({
41839
41920
  returnFocusRef.current = null;
41840
41921
  if (target?.isConnected) target.focus();
41841
41922
  }, [activeTarget]);
41842
- useEffect65(() => {
41923
+ useEffect66(() => {
41843
41924
  if (activeTarget !== "control") return;
41844
41925
  const ownerDocument = rootRef.current?.ownerDocument;
41845
41926
  if (!ownerDocument) return;
@@ -41851,7 +41932,7 @@ function PresentationModeProvider({
41851
41932
  ownerDocument.addEventListener("keydown", handleKeyDown);
41852
41933
  return () => ownerDocument.removeEventListener("keydown", handleKeyDown);
41853
41934
  }, [activeTarget, rootRef, stop]);
41854
- useEffect65(() => {
41935
+ useEffect66(() => {
41855
41936
  if (!error) return;
41856
41937
  const timer = window.setTimeout(() => setError(null), 6e3);
41857
41938
  return () => window.clearTimeout(timer);
@@ -41886,7 +41967,7 @@ function PresentationModeProvider({
41886
41967
  window.removeEventListener("resize", updatePosition);
41887
41968
  };
41888
41969
  }, [activeTarget, rootRef]);
41889
- useEffect65(
41970
+ useEffect66(
41890
41971
  () => () => {
41891
41972
  popupCleanupRef.current?.();
41892
41973
  const popup = popupRef.current;
@@ -41938,8 +42019,8 @@ function PresentationModeProvider({
41938
42019
  "aria-label": "Exit presentation mode",
41939
42020
  title: "Exit presentation mode (Esc)",
41940
42021
  children: [
41941
- /* @__PURE__ */ jsx84(Icon, { icon: "fa-solid fa-compress" }),
41942
- /* @__PURE__ */ jsx84("span", { children: "Exit presentation" })
42022
+ /* @__PURE__ */ jsx85(Icon, { icon: "fa-solid fa-compress" }),
42023
+ /* @__PURE__ */ jsx85("span", { children: "Exit presentation" })
41943
42024
  ]
41944
42025
  }
41945
42026
  ) : null;
@@ -41948,7 +42029,7 @@ function PresentationModeProvider({
41948
42029
  (activeTarget === "control" || activeTarget === "fullscreen") && exitButton,
41949
42030
  activeTarget === "window" && popupRoot && exitButton ? createPortal17(exitButton, popupRoot) : null,
41950
42031
  error && typeof document !== "undefined" ? createPortal17(
41951
- /* @__PURE__ */ jsx84("div", { className: "squisq-presentation-error", "data-theme": colorScheme, role: "alert", children: error }),
42032
+ /* @__PURE__ */ jsx85("div", { className: "squisq-presentation-error", "data-theme": colorScheme, role: "alert", children: error }),
41952
42033
  document.body
41953
42034
  ) : null
41954
42035
  ] });
@@ -42015,7 +42096,7 @@ function PresentationModeControl() {
42015
42096
  updatePosition();
42016
42097
  setOpen(true);
42017
42098
  }, [updatePosition]);
42018
- useEffect65(() => {
42099
+ useEffect66(() => {
42019
42100
  if (!open) return;
42020
42101
  const handlePointerDown = (event) => {
42021
42102
  const target = event.target;
@@ -42045,7 +42126,7 @@ function PresentationModeControl() {
42045
42126
  (checked ?? first)?.focus();
42046
42127
  }, [anchor, open]);
42047
42128
  return /* @__PURE__ */ jsxs68("div", { className: "squisq-presentation-control", children: [
42048
- /* @__PURE__ */ jsx84(
42129
+ /* @__PURE__ */ jsx85(
42049
42130
  "button",
42050
42131
  {
42051
42132
  type: "button",
@@ -42054,10 +42135,10 @@ function PresentationModeControl() {
42054
42135
  "aria-pressed": activeTarget !== null,
42055
42136
  "data-tooltip": activeTarget ? "Exit presentation" : `Present: ${selected.label}`,
42056
42137
  onClick: () => void (activeTarget ? stop() : start()),
42057
- children: /* @__PURE__ */ jsx84(Icon, { icon: "fa-solid fa-display" })
42138
+ children: /* @__PURE__ */ jsx85(Icon, { icon: "fa-solid fa-display" })
42058
42139
  }
42059
42140
  ),
42060
- options.length > 1 && /* @__PURE__ */ jsx84(
42141
+ options.length > 1 && /* @__PURE__ */ jsx85(
42061
42142
  "button",
42062
42143
  {
42063
42144
  ref: triggerRef,
@@ -42073,11 +42154,11 @@ function PresentationModeControl() {
42073
42154
  event.preventDefault();
42074
42155
  openMenu();
42075
42156
  },
42076
- children: /* @__PURE__ */ jsx84("svg", { width: "10", height: "10", viewBox: "0 0 10 10", "aria-hidden": "true", children: /* @__PURE__ */ jsx84("path", { d: "M2 3.5 5 6.5 8 3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.4" }) })
42157
+ children: /* @__PURE__ */ jsx85("svg", { width: "10", height: "10", viewBox: "0 0 10 10", "aria-hidden": "true", children: /* @__PURE__ */ jsx85("path", { d: "M2 3.5 5 6.5 8 3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.4" }) })
42077
42158
  }
42078
42159
  ),
42079
42160
  open && anchor ? createPortal17(
42080
- /* @__PURE__ */ jsx84(
42161
+ /* @__PURE__ */ jsx85(
42081
42162
  "div",
42082
42163
  {
42083
42164
  ref: menuRef,
@@ -42123,24 +42204,24 @@ function PresentationModeControl() {
42123
42204
  if (!alreadyThere) void start(option.target);
42124
42205
  },
42125
42206
  children: [
42126
- /* @__PURE__ */ jsx84(
42207
+ /* @__PURE__ */ jsx85(
42127
42208
  "span",
42128
42209
  {
42129
42210
  className: "squisq-use-mode-menu-icon squisq-presentation-menu-icon",
42130
42211
  "aria-hidden": "true",
42131
- children: /* @__PURE__ */ jsx84(Icon, { icon: option.icon })
42212
+ children: /* @__PURE__ */ jsx85(Icon, { icon: option.icon })
42132
42213
  }
42133
42214
  ),
42134
42215
  /* @__PURE__ */ jsxs68("span", { className: "squisq-use-mode-menu-copy squisq-presentation-menu-copy", children: [
42135
- /* @__PURE__ */ jsx84("span", { className: "squisq-use-mode-menu-label squisq-presentation-menu-label", children: option.label }),
42136
- /* @__PURE__ */ jsx84("span", { className: "squisq-use-mode-menu-summary squisq-presentation-menu-summary", children: disabled ? "Full screen is unavailable." : option.summary })
42216
+ /* @__PURE__ */ jsx85("span", { className: "squisq-use-mode-menu-label squisq-presentation-menu-label", children: option.label }),
42217
+ /* @__PURE__ */ jsx85("span", { className: "squisq-use-mode-menu-summary squisq-presentation-menu-summary", children: disabled ? "Full screen is unavailable." : option.summary })
42137
42218
  ] }),
42138
- /* @__PURE__ */ jsx84(
42219
+ /* @__PURE__ */ jsx85(
42139
42220
  "span",
42140
42221
  {
42141
42222
  className: "squisq-use-mode-menu-check squisq-presentation-menu-check",
42142
42223
  "aria-hidden": "true",
42143
- children: isSelected && /* @__PURE__ */ jsx84(Icon, { icon: "fa-solid fa-check" })
42224
+ children: isSelected && /* @__PURE__ */ jsx85(Icon, { icon: "fa-solid fa-check" })
42144
42225
  }
42145
42226
  )
42146
42227
  ]
@@ -42160,12 +42241,12 @@ import {
42160
42241
  createContext as createContext8,
42161
42242
  useCallback as useCallback52,
42162
42243
  useContext as useContext8,
42163
- useEffect as useEffect66,
42244
+ useEffect as useEffect67,
42164
42245
  useMemo as useMemo54,
42165
42246
  useRef as useRef61,
42166
42247
  useState as useState78
42167
42248
  } from "react";
42168
- import { jsx as jsx85, jsxs as jsxs69 } from "react/jsx-runtime";
42249
+ import { jsx as jsx86, jsxs as jsxs69 } from "react/jsx-runtime";
42169
42250
  var PrintModeContext = createContext8(null);
42170
42251
  function usePrintMode() {
42171
42252
  const value = useContext8(PrintModeContext);
@@ -42230,7 +42311,7 @@ function PrintModeProvider({ rootRef, children }) {
42230
42311
  markPrinting();
42231
42312
  ownerWindow.print();
42232
42313
  }, [markPrinting, rootRef]);
42233
- useEffect66(() => {
42314
+ useEffect67(() => {
42234
42315
  const root = rootRef.current;
42235
42316
  if (!root) return;
42236
42317
  if (active) root.dataset.printPreview = "true";
@@ -42239,10 +42320,10 @@ function PrintModeProvider({ rootRef, children }) {
42239
42320
  delete root.dataset.printPreview;
42240
42321
  };
42241
42322
  }, [active, rootRef]);
42242
- useEffect66(() => {
42323
+ useEffect67(() => {
42243
42324
  if (activeView !== "preview" && active) close();
42244
42325
  }, [active, activeView, close]);
42245
- useEffect66(() => {
42326
+ useEffect67(() => {
42246
42327
  if (!active) return;
42247
42328
  const ownerWindow = rootRef.current?.ownerDocument.defaultView;
42248
42329
  const ownerDocument = rootRef.current?.ownerDocument;
@@ -42276,7 +42357,7 @@ function PrintModeProvider({ rootRef, children }) {
42276
42357
  }),
42277
42358
  [active, close, open, print, registerPrintHandler, slidesPerPage]
42278
42359
  );
42279
- return /* @__PURE__ */ jsx85(PrintModeContext.Provider, { value, children });
42360
+ return /* @__PURE__ */ jsx86(PrintModeContext.Provider, { value, children });
42280
42361
  }
42281
42362
  function PrintModeControl() {
42282
42363
  const { open } = usePrintMode();
@@ -42289,8 +42370,8 @@ function PrintModeControl() {
42289
42370
  "aria-label": "Print",
42290
42371
  "data-tooltip": "Print",
42291
42372
  children: [
42292
- /* @__PURE__ */ jsx85(Icon, { icon: "fa-solid fa-print" }),
42293
- /* @__PURE__ */ jsx85("span", { children: "Print" })
42373
+ /* @__PURE__ */ jsx86(Icon, { icon: "fa-solid fa-print" }),
42374
+ /* @__PURE__ */ jsx86("span", { children: "Print" })
42294
42375
  ]
42295
42376
  }
42296
42377
  );
@@ -42300,8 +42381,8 @@ function PrintPreviewToolbar() {
42300
42381
  const { activeDisplayMode } = usePreviewSettings();
42301
42382
  const { slidesPerPage, setSlidesPerPage, print, close } = usePrintMode();
42302
42383
  return /* @__PURE__ */ jsxs69("div", { className: "squisq-print-toolbar", "aria-label": "Print preview controls", children: [
42303
- /* @__PURE__ */ jsx85("span", { className: "squisq-print-toolbar-title", children: "Print preview" }),
42304
- activeDisplayMode === "slideshow" && /* @__PURE__ */ jsx85("div", { className: "squisq-print-density", role: "group", "aria-label": "Slides per page", children: SLIDES_PER_PAGE_OPTIONS.map((value) => /* @__PURE__ */ jsxs69(
42384
+ /* @__PURE__ */ jsx86("span", { className: "squisq-print-toolbar-title", children: "Print preview" }),
42385
+ activeDisplayMode === "slideshow" && /* @__PURE__ */ jsx86("div", { className: "squisq-print-density", role: "group", "aria-label": "Slides per page", children: SLIDES_PER_PAGE_OPTIONS.map((value) => /* @__PURE__ */ jsxs69(
42305
42386
  "button",
42306
42387
  {
42307
42388
  type: "button",
@@ -42310,7 +42391,7 @@ function PrintPreviewToolbar() {
42310
42391
  "aria-label": `${value} ${value === 1 ? "slide" : "slides"} per page`,
42311
42392
  onClick: () => setSlidesPerPage(value),
42312
42393
  children: [
42313
- /* @__PURE__ */ jsx85("span", { children: value }),
42394
+ /* @__PURE__ */ jsx86("span", { children: value }),
42314
42395
  /* @__PURE__ */ jsxs69("span", { className: "squisq-print-density-label", children: [
42315
42396
  " ",
42316
42397
  value === 1 ? "slide" : "slides",
@@ -42320,22 +42401,22 @@ function PrintPreviewToolbar() {
42320
42401
  },
42321
42402
  value
42322
42403
  )) }),
42323
- /* @__PURE__ */ jsx85("div", { className: "squisq-print-toolbar-spacer" }),
42404
+ /* @__PURE__ */ jsx86("div", { className: "squisq-print-toolbar-spacer" }),
42324
42405
  /* @__PURE__ */ jsxs69("button", { type: "button", className: "squisq-print-action", onClick: print, children: [
42325
- /* @__PURE__ */ jsx85(Icon, { icon: "fa-solid fa-print" }),
42326
- /* @__PURE__ */ jsx85("span", { children: "Print" })
42406
+ /* @__PURE__ */ jsx86(Icon, { icon: "fa-solid fa-print" }),
42407
+ /* @__PURE__ */ jsx86("span", { children: "Print" })
42327
42408
  ] }),
42328
42409
  /* @__PURE__ */ jsxs69("button", { type: "button", className: "squisq-print-close", onClick: close, children: [
42329
- /* @__PURE__ */ jsx85(Icon, { icon: "fa-solid fa-xmark" }),
42330
- /* @__PURE__ */ jsx85("span", { children: "Close" })
42410
+ /* @__PURE__ */ jsx86(Icon, { icon: "fa-solid fa-xmark" }),
42411
+ /* @__PURE__ */ jsx86("span", { children: "Close" })
42331
42412
  ] })
42332
42413
  ] });
42333
42414
  }
42334
42415
 
42335
42416
  // src/print/PrintPreview.tsx
42336
- import { useCallback as useCallback53, useEffect as useEffect67, useMemo as useMemo55, useRef as useRef62 } from "react";
42417
+ import { useCallback as useCallback53, useEffect as useEffect68, useMemo as useMemo55, useRef as useRef62 } from "react";
42337
42418
  import {
42338
- BlockRenderer as BlockRenderer4,
42419
+ BlockRenderer as BlockRenderer5,
42339
42420
  FlashcardFaceView,
42340
42421
  LinearDocView,
42341
42422
  useDocPlayback,
@@ -42346,7 +42427,7 @@ import {
42346
42427
  } from "@bendyline/squisq/schemas";
42347
42428
  import { expandCoverBlock as expandCoverBlock2, materializeFlashcards } from "@bendyline/squisq/doc";
42348
42429
  import { resolveTransformStyle } from "@bendyline/squisq/transform";
42349
- import { jsx as jsx86, jsxs as jsxs70 } from "react/jsx-runtime";
42430
+ import { jsx as jsx87, jsxs as jsxs70 } from "react/jsx-runtime";
42350
42431
  function chunk(values, size) {
42351
42432
  const groups = [];
42352
42433
  for (let index2 = 0; index2 < values.length; index2 += size) {
@@ -42390,7 +42471,7 @@ function PrintPreview({
42390
42471
  [contentDoc]
42391
42472
  );
42392
42473
  const isTextDocument = displayMode === "page" || displayMode === "narrate";
42393
- useEffect67(() => {
42474
+ useEffect68(() => {
42394
42475
  if (!isTextDocument) return registerPrintHandler(null);
42395
42476
  return registerPrintHandler(() => {
42396
42477
  const frameWindow = documentFrameRef.current?.contentWindow;
@@ -42400,7 +42481,7 @@ function PrintPreview({
42400
42481
  }, [isTextDocument, registerPrintHandler]);
42401
42482
  const title = contentDoc?.frontmatter?.title ?? contentDoc?.startBlock?.title ?? void 0;
42402
42483
  if (isTextDocument) {
42403
- return /* @__PURE__ */ jsx86("div", { className: "squisq-print-preview squisq-print-preview--document", children: /* @__PURE__ */ jsx86("div", { className: "squisq-print-document-paper", children: /* @__PURE__ */ jsx86(
42484
+ return /* @__PURE__ */ jsx87("div", { className: "squisq-print-preview squisq-print-preview--document", children: /* @__PURE__ */ jsx87("div", { className: "squisq-print-document-paper", children: /* @__PURE__ */ jsx87(
42404
42485
  PlainHtmlPreview,
42405
42486
  {
42406
42487
  markdown: documentMarkdown,
@@ -42415,8 +42496,8 @@ function PrintPreview({
42415
42496
  }
42416
42497
  if (displayMode === "linear") {
42417
42498
  return /* @__PURE__ */ jsxs70("div", { className: "squisq-print-preview squisq-print-preview--page", children: [
42418
- /* @__PURE__ */ jsx86("style", { children: "@page { margin: 0; }" }),
42419
- /* @__PURE__ */ jsx86("div", { className: "squisq-print-page-paper", children: /* @__PURE__ */ jsx86(
42499
+ /* @__PURE__ */ jsx87("style", { children: "@page { margin: 0; }" }),
42500
+ /* @__PURE__ */ jsx87("div", { className: "squisq-print-page-paper", children: /* @__PURE__ */ jsx87(
42420
42501
  LinearDocView,
42421
42502
  {
42422
42503
  className: "squisq-print-linear",
@@ -42451,7 +42532,7 @@ function PrintPreview({
42451
42532
  "--squisq-print-flashcard-surface": theme.colors.backgroundLight
42452
42533
  },
42453
42534
  children: [
42454
- /* @__PURE__ */ jsx86("style", { children: "@page { size: landscape; margin: 0; }" }),
42535
+ /* @__PURE__ */ jsx87("style", { children: "@page { size: landscape; margin: 0; }" }),
42455
42536
  flashcardDeck?.cards.map((card, index2) => /* @__PURE__ */ jsxs70("article", { className: "squisq-print-flashcard-sheet", children: [
42456
42537
  /* @__PURE__ */ jsxs70("header", { children: [
42457
42538
  /* @__PURE__ */ jsxs70("span", { children: [
@@ -42460,25 +42541,25 @@ function PrintPreview({
42460
42541
  " of ",
42461
42542
  flashcardDeck.cards.length
42462
42543
  ] }),
42463
- card.label && /* @__PURE__ */ jsx86("strong", { children: card.label })
42544
+ card.label && /* @__PURE__ */ jsx87("strong", { children: card.label })
42464
42545
  ] }),
42465
42546
  /* @__PURE__ */ jsxs70("div", { className: "squisq-print-flashcard-pair", children: [
42466
42547
  /* @__PURE__ */ jsxs70("section", { className: "squisq-print-flashcard-face", "aria-label": "Question side", children: [
42467
- /* @__PURE__ */ jsx86("small", { children: "Front" }),
42468
- /* @__PURE__ */ jsx86(FlashcardFaceView, { ...faceProps, face: card.front }),
42469
- card.kind === "multiple-choice" && /* @__PURE__ */ jsx86("ol", { className: "squisq-print-flashcard-choices", children: card.choices?.map((choice) => /* @__PURE__ */ jsx86("li", { children: /* @__PURE__ */ jsx86(FlashcardFaceView, { ...faceProps, face: choice.content }) }, choice.id)) })
42548
+ /* @__PURE__ */ jsx87("small", { children: "Front" }),
42549
+ /* @__PURE__ */ jsx87(FlashcardFaceView, { ...faceProps, face: card.front }),
42550
+ card.kind === "multiple-choice" && /* @__PURE__ */ jsx87("ol", { className: "squisq-print-flashcard-choices", children: card.choices?.map((choice) => /* @__PURE__ */ jsx87("li", { children: /* @__PURE__ */ jsx87(FlashcardFaceView, { ...faceProps, face: choice.content }) }, choice.id)) })
42470
42551
  ] }),
42471
42552
  /* @__PURE__ */ jsxs70("section", { className: "squisq-print-flashcard-face", "aria-label": "Answer side", children: [
42472
- /* @__PURE__ */ jsx86("small", { children: "Back" }),
42473
- /* @__PURE__ */ jsx86(FlashcardFaceView, { ...faceProps, face: card.back }),
42553
+ /* @__PURE__ */ jsx87("small", { children: "Back" }),
42554
+ /* @__PURE__ */ jsx87(FlashcardFaceView, { ...faceProps, face: card.back }),
42474
42555
  card.explanation && /* @__PURE__ */ jsxs70("div", { className: "squisq-print-flashcard-explanation", children: [
42475
- /* @__PURE__ */ jsx86("small", { children: "Explanation" }),
42476
- /* @__PURE__ */ jsx86(FlashcardFaceView, { ...faceProps, face: card.explanation })
42556
+ /* @__PURE__ */ jsx87("small", { children: "Explanation" }),
42557
+ /* @__PURE__ */ jsx87(FlashcardFaceView, { ...faceProps, face: card.explanation })
42477
42558
  ] })
42478
42559
  ] })
42479
42560
  ] })
42480
42561
  ] }, card.id)),
42481
- (!flashcardDeck || flashcardDeck.cards.length === 0) && /* @__PURE__ */ jsx86("p", { className: "squisq-print-empty", children: "Nothing to print." })
42562
+ (!flashcardDeck || flashcardDeck.cards.length === 0) && /* @__PURE__ */ jsx87("p", { className: "squisq-print-empty", children: "Nothing to print." })
42482
42563
  ]
42483
42564
  }
42484
42565
  );
@@ -42498,15 +42579,15 @@ function PrintPreview({
42498
42579
  "data-slides-per-page": density,
42499
42580
  style: previewStyle,
42500
42581
  children: [
42501
- /* @__PURE__ */ jsx86("style", { children: `@page { size: ${orientation}; margin: 0; }` }),
42502
- sheets.map((sheet, pageIndex) => /* @__PURE__ */ jsx86(
42582
+ /* @__PURE__ */ jsx87("style", { children: `@page { size: ${orientation}; margin: 0; }` }),
42583
+ sheets.map((sheet, pageIndex) => /* @__PURE__ */ jsx87(
42503
42584
  "div",
42504
42585
  {
42505
42586
  className: "squisq-print-sheet",
42506
42587
  "data-slides-per-page": density,
42507
42588
  "aria-label": `Print page ${pageIndex + 1}`,
42508
- children: sheet.map((block) => /* @__PURE__ */ jsx86("div", { className: "squisq-print-slide-cell", children: /* @__PURE__ */ jsx86("div", { className: "squisq-print-slide-frame", children: /* @__PURE__ */ jsx86(
42509
- BlockRenderer4,
42589
+ children: sheet.map((block) => /* @__PURE__ */ jsx87("div", { className: "squisq-print-slide-cell", children: /* @__PURE__ */ jsx87("div", { className: "squisq-print-slide-frame", children: /* @__PURE__ */ jsx87(
42590
+ BlockRenderer5,
42510
42591
  {
42511
42592
  block,
42512
42593
  blockTime: Math.max(0, block.duration),
@@ -42519,7 +42600,7 @@ function PrintPreview({
42519
42600
  },
42520
42601
  `${density}-${pageIndex}`
42521
42602
  )),
42522
- sheets.length === 0 && /* @__PURE__ */ jsx86("p", { className: "squisq-print-empty", children: "Nothing to print." })
42603
+ sheets.length === 0 && /* @__PURE__ */ jsx87("p", { className: "squisq-print-empty", children: "Nothing to print." })
42523
42604
  ]
42524
42605
  }
42525
42606
  );
@@ -42529,7 +42610,7 @@ function PrintPreview({
42529
42610
  import {
42530
42611
  createContext as createContext9,
42531
42612
  useContext as useContext9,
42532
- useEffect as useEffect68,
42613
+ useEffect as useEffect69,
42533
42614
  useMemo as useMemo56,
42534
42615
  useState as useState79
42535
42616
  } from "react";
@@ -42573,7 +42654,7 @@ function collectSlideshowDataSources(doc) {
42573
42654
  }
42574
42655
 
42575
42656
  // src/slideshow/SlideshowDataGrid.tsx
42576
- import { Fragment as Fragment28, jsx as jsx87 } from "react/jsx-runtime";
42657
+ import { Fragment as Fragment28, jsx as jsx88 } from "react/jsx-runtime";
42577
42658
  var EMPTY_CONTEXT = {
42578
42659
  container: null,
42579
42660
  mediaRevision: 0,
@@ -42591,7 +42672,7 @@ function SlideshowDataGridProvider({
42591
42672
  () => ({ container: container ?? null, mediaRevision, sources }),
42592
42673
  [container, mediaRevision, sources]
42593
42674
  );
42594
- return /* @__PURE__ */ jsx87(SlideshowDataGridContext.Provider, { value, children });
42675
+ return /* @__PURE__ */ jsx88(SlideshowDataGridContext.Provider, { value, children });
42595
42676
  }
42596
42677
  var EMPTY_VIEW = { sort: [], filter: [] };
42597
42678
  function sourceKey(source) {
@@ -42636,7 +42717,7 @@ function SlideshowDataGridRenderer({
42636
42717
  const activeSourceKey = sourceKey(source);
42637
42718
  const [remote, setRemote] = useState79({ key: "", status: "idle" });
42638
42719
  const [gridModule, setGridModule] = useState79(null);
42639
- useEffect68(() => {
42720
+ useEffect69(() => {
42640
42721
  let active = true;
42641
42722
  void loadGridModule().then((module) => {
42642
42723
  if (active) setGridModule(module);
@@ -42645,7 +42726,7 @@ function SlideshowDataGridRenderer({
42645
42726
  active = false;
42646
42727
  };
42647
42728
  }, []);
42648
- useEffect68(() => {
42729
+ useEffect69(() => {
42649
42730
  if (!container || !source || !gridModule) {
42650
42731
  setRemote({ key: activeSourceKey, status: "idle" });
42651
42732
  return;
@@ -42696,14 +42777,14 @@ function SlideshowDataGridRenderer({
42696
42777
  () => useLocalGrid && gridModule ? new gridModule.TableStoreClient({ headers: previewHeaders, cells: previewRows }) : null,
42697
42778
  [previewHeaders, previewRows, useLocalGrid, gridModule]
42698
42779
  );
42699
- useEffect68(() => () => localProvider?.dispose(), [localProvider]);
42780
+ useEffect69(() => () => localProvider?.dispose(), [localProvider]);
42700
42781
  const ready = currentRemote?.status === "ready" ? currentRemote : void 0;
42701
42782
  const provider = ready?.provider ?? localProvider;
42702
42783
  const ingest = ready?.ingest ?? (localProvider ? { headers: previewHeaders, cells: previewRows } : void 0);
42703
42784
  const initialView = ready?.initialView ?? EMPTY_VIEW;
42704
42785
  const [view, setView] = useState79(initialView);
42705
- useEffect68(() => setView(initialView), [initialView, provider]);
42706
- if (!provider || !ingest || !gridModule) return /* @__PURE__ */ jsx87(Fragment28, { children: fallback });
42786
+ useEffect69(() => setView(initialView), [initialView, provider]);
42787
+ if (!provider || !ingest || !gridModule) return /* @__PURE__ */ jsx88(Fragment28, { children: fallback });
42707
42788
  const { style } = layer.content;
42708
42789
  const rowHeight = Math.max(32, style.fontSize * 2.1);
42709
42790
  const footerHeight = Math.max(28, style.fontSize * 1.5);
@@ -42732,7 +42813,7 @@ function SlideshowDataGridRenderer({
42732
42813
  "--squisq-grid-accent": style.headerBackground,
42733
42814
  "--squisq-grid-resize-handle": style.headerBackground
42734
42815
  };
42735
- return /* @__PURE__ */ jsx87("div", { className: "squisq-slideshow-data-grid", style: gridStyle, children: /* @__PURE__ */ jsx87(
42816
+ return /* @__PURE__ */ jsx88("div", { className: "squisq-slideshow-data-grid", style: gridStyle, children: /* @__PURE__ */ jsx88(
42736
42817
  gridModule.DataGrid,
42737
42818
  {
42738
42819
  provider,
@@ -42748,7 +42829,7 @@ function SlideshowDataGridRenderer({
42748
42829
 
42749
42830
  // src/PreviewPanel.tsx
42750
42831
  import { useProcessedAudio as useProcessedAudio3 } from "@bendyline/squisq-video-react/media-edit";
42751
- import { jsx as jsx88, jsxs as jsxs71 } from "react/jsx-runtime";
42832
+ import { jsx as jsx89, jsxs as jsxs71 } from "react/jsx-runtime";
42752
42833
  function PreviewPanel({
42753
42834
  basePath = "/",
42754
42835
  className,
@@ -42839,11 +42920,11 @@ function PreviewPanel({
42839
42920
  const isNarrateMode = activeDisplayMode === "narrate";
42840
42921
  const isDashboardMode = activeDisplayMode === "dashboard";
42841
42922
  const isFlashcardsMode = activeDisplayMode === "flashcards";
42842
- useEffect69(() => {
42923
+ useEffect70(() => {
42843
42924
  if (presentation?.activeTarget === "window") return;
42844
42925
  setPlaybackState(null);
42845
42926
  }, [presentation?.activeTarget]);
42846
- useEffect69(() => {
42927
+ useEffect70(() => {
42847
42928
  if (presentation?.activeTarget !== "window" || !presentation.popupRoot) return;
42848
42929
  const mainRoot = mainSurfaceRef.current;
42849
42930
  const followerRoot = popupSurfaceRef.current;
@@ -42906,22 +42987,22 @@ function PreviewPanel({
42906
42987
  presentation?.popupRoot
42907
42988
  ]);
42908
42989
  if (isParsing && !isNarrateMode && !previewDoc) {
42909
- return /* @__PURE__ */ jsx88("div", { className: `squisq-preview-status ${className || ""}`, "data-testid": "preview-panel", children: /* @__PURE__ */ jsx88("p", { children: "Parsing\u2026" }) });
42990
+ return /* @__PURE__ */ jsx89("div", { className: `squisq-preview-status ${className || ""}`, "data-testid": "preview-panel", children: /* @__PURE__ */ jsx89("p", { children: "Parsing\u2026" }) });
42910
42991
  }
42911
42992
  if (parseError && !isNarrateMode) {
42912
42993
  return /* @__PURE__ */ jsxs71("div", { className: `squisq-preview-status ${className || ""}`, "data-testid": "preview-panel", children: [
42913
- /* @__PURE__ */ jsx88("h3", { children: "Parse Error" }),
42914
- /* @__PURE__ */ jsx88("pre", { children: parseError })
42994
+ /* @__PURE__ */ jsx89("h3", { children: "Parse Error" }),
42995
+ /* @__PURE__ */ jsx89("pre", { children: parseError })
42915
42996
  ] });
42916
42997
  }
42917
42998
  if (!previewDoc && !isDocumentMode && !isNarrateMode) {
42918
- return /* @__PURE__ */ jsx88("div", { className: `squisq-preview-status ${className || ""}`, "data-testid": "preview-panel", children: /* @__PURE__ */ jsx88("p", { children: "No content to preview. Start typing in the editor." }) });
42999
+ return /* @__PURE__ */ jsx89("div", { className: `squisq-preview-status ${className || ""}`, "data-testid": "preview-panel", children: /* @__PURE__ */ jsx89("p", { children: "No content to preview. Start typing in the editor." }) });
42919
43000
  }
42920
43001
  const fillsContainer = printMode?.active || isDocumentMode || isPageMode || isNarrateMode || isFlashcardsMode ? "stretch" : "center";
42921
43002
  const audienceWindowOpen = presentation?.activeTarget === "window";
42922
43003
  const renderSurface = (audience) => {
42923
43004
  if (!audience && printMode?.active) {
42924
- return /* @__PURE__ */ jsx88(
43005
+ return /* @__PURE__ */ jsx89(
42925
43006
  PrintPreview,
42926
43007
  {
42927
43008
  displayMode: activeDisplayMode,
@@ -42939,7 +43020,7 @@ function PreviewPanel({
42939
43020
  );
42940
43021
  }
42941
43022
  if (isDocumentMode) {
42942
- return /* @__PURE__ */ jsx88(
43023
+ return /* @__PURE__ */ jsx89(
42943
43024
  PlainHtmlPreview,
42944
43025
  {
42945
43026
  markdown: documentMarkdown,
@@ -42958,7 +43039,7 @@ function PreviewPanel({
42958
43039
  }
42959
43040
  if (isNarrateMode) {
42960
43041
  if (audience) return null;
42961
- return /* @__PURE__ */ jsx88(
43042
+ return /* @__PURE__ */ jsx89(
42962
43043
  TeleprompterView,
42963
43044
  {
42964
43045
  doc,
@@ -42977,7 +43058,7 @@ function PreviewPanel({
42977
43058
  );
42978
43059
  }
42979
43060
  if (isPageMode) {
42980
- return /* @__PURE__ */ jsx88(
43061
+ return /* @__PURE__ */ jsx89(
42981
43062
  LinearDocView2,
42982
43063
  {
42983
43064
  doc: contentDoc ?? doc,
@@ -42994,7 +43075,7 @@ function PreviewPanel({
42994
43075
  );
42995
43076
  }
42996
43077
  if (isFlashcardsMode) {
42997
- return /* @__PURE__ */ jsx88(
43078
+ return /* @__PURE__ */ jsx89(
42998
43079
  FlashcardView,
42999
43080
  {
43000
43081
  doc: contentDoc ?? doc,
@@ -43009,7 +43090,7 @@ function PreviewPanel({
43009
43090
  );
43010
43091
  }
43011
43092
  if (isDashboardMode) {
43012
- return /* @__PURE__ */ jsx88("div", { className: "squisq-dashboard-fit", children: /* @__PURE__ */ jsx88(
43093
+ return /* @__PURE__ */ jsx89("div", { className: "squisq-dashboard-fit", children: /* @__PURE__ */ jsx89(
43013
43094
  DashboardView,
43014
43095
  {
43015
43096
  doc: contentDoc ?? doc,
@@ -43024,10 +43105,10 @@ function PreviewPanel({
43024
43105
  ) });
43025
43106
  }
43026
43107
  if (audience && !followerAudioController) {
43027
- return /* @__PURE__ */ jsx88("div", { className: "squisq-presentation-connecting", children: "Connecting presentation..." });
43108
+ return /* @__PURE__ */ jsx89("div", { className: "squisq-presentation-connecting", children: "Connecting presentation..." });
43028
43109
  }
43029
43110
  const audienceCaptionMode = playbackState?.captionMode;
43030
- return /* @__PURE__ */ jsx88(
43111
+ return /* @__PURE__ */ jsx89(
43031
43112
  DocPlayer2,
43032
43113
  {
43033
43114
  doc: previewDoc,
@@ -43078,7 +43159,7 @@ function PreviewPanel({
43078
43159
  container: workspaceContainer,
43079
43160
  mediaRevision,
43080
43161
  children: [
43081
- /* @__PURE__ */ jsx88(
43162
+ /* @__PURE__ */ jsx89(
43082
43163
  "div",
43083
43164
  {
43084
43165
  className: `squisq-preview-container ${className || ""}`,
@@ -43091,16 +43172,16 @@ function PreviewPanel({
43091
43172
  overflow: "hidden",
43092
43173
  background: "var(--squisq-bg)"
43093
43174
  },
43094
- children: /* @__PURE__ */ jsx88("div", { ref: mainSurfaceRef, className: "squisq-preview-player", style: surfaceStyle, children: renderSurface(false) })
43175
+ children: /* @__PURE__ */ jsx89("div", { ref: mainSurfaceRef, className: "squisq-preview-player", style: surfaceStyle, children: renderSurface(false) })
43095
43176
  }
43096
43177
  ),
43097
43178
  audienceWindowOpen && presentation?.popupRoot && !isNarrateMode ? createPortal18(
43098
- /* @__PURE__ */ jsx88(
43179
+ /* @__PURE__ */ jsx89(
43099
43180
  "div",
43100
43181
  {
43101
43182
  className: "squisq-editor-shell squisq-presentation-window",
43102
43183
  "data-theme": colorScheme,
43103
- children: /* @__PURE__ */ jsx88("div", { className: "squisq-preview-container squisq-presentation-window-preview", children: /* @__PURE__ */ jsx88(
43184
+ children: /* @__PURE__ */ jsx89("div", { className: "squisq-preview-container squisq-presentation-window-preview", children: /* @__PURE__ */ jsx89(
43104
43185
  "div",
43105
43186
  {
43106
43187
  ref: popupSurfaceRef,
@@ -43120,10 +43201,98 @@ function PreviewPanel({
43120
43201
  }
43121
43202
 
43122
43203
  // src/MediaBin.tsx
43123
- import { useState as useState81, useEffect as useEffect70, useRef as useRef64, useCallback as useCallback55 } from "react";
43204
+ import { useState as useState82, useEffect as useEffect72, useRef as useRef65, useCallback as useCallback55 } from "react";
43124
43205
  import { isSvgImageSource as isSvgImageSource3 } from "@bendyline/squisq/markdown";
43125
43206
  import { sanitizedSvgImageUrl as sanitizedSvgImageUrl2 } from "@bendyline/squisq-react";
43126
- import { jsx as jsx89, jsxs as jsxs72 } from "react/jsx-runtime";
43207
+
43208
+ // src/MediaPreviewDialog.tsx
43209
+ import { useEffect as useEffect71, useId as useId16, useRef as useRef64, useState as useState81 } from "react";
43210
+ import { jsx as jsx90, jsxs as jsxs72 } from "react/jsx-runtime";
43211
+ function MediaPreviewDialog({
43212
+ kind,
43213
+ name,
43214
+ detail,
43215
+ src,
43216
+ failed = false,
43217
+ isDark,
43218
+ onClose
43219
+ }) {
43220
+ const overlayRef = useRef64(null);
43221
+ const dialogRef = useRef64(null);
43222
+ const titleId = useId16();
43223
+ const [playbackFailed, setPlaybackFailed] = useState81(false);
43224
+ useModalDialog({ rootRef: overlayRef, dialogRef, onClose });
43225
+ useEffect71(() => setPlaybackFailed(false), [src]);
43226
+ let body;
43227
+ if (failed || playbackFailed || src === "") {
43228
+ body = /* @__PURE__ */ jsx90("div", { className: "squisq-media-preview-message", children: "This file can\u2019t be previewed." });
43229
+ } else if (src === null) {
43230
+ body = /* @__PURE__ */ jsx90("div", { className: "squisq-media-preview-message", children: "Loading\u2026" });
43231
+ } else if (kind === "image") {
43232
+ body = /* @__PURE__ */ jsx90(ImageViewer, { src, alt: name, theme: isDark ? "dark" : "light" });
43233
+ } else if (kind === "video") {
43234
+ body = /* @__PURE__ */ jsx90(
43235
+ "video",
43236
+ {
43237
+ className: "squisq-media-preview-video",
43238
+ src,
43239
+ controls: true,
43240
+ autoPlay: true,
43241
+ playsInline: true,
43242
+ onError: () => setPlaybackFailed(true)
43243
+ }
43244
+ );
43245
+ } else {
43246
+ body = /* @__PURE__ */ jsxs72("div", { className: "squisq-media-preview-audio", children: [
43247
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-preview-audio-icon", "aria-hidden": "true", children: "\u{1F50A}" }),
43248
+ /* @__PURE__ */ jsx90("audio", { src, controls: true, autoPlay: true, onError: () => setPlaybackFailed(true) })
43249
+ ] });
43250
+ }
43251
+ return /* @__PURE__ */ jsx90(
43252
+ "div",
43253
+ {
43254
+ ref: overlayRef,
43255
+ className: "squisq-media-preview",
43256
+ "data-theme": isDark ? "dark" : "light",
43257
+ onMouseDown: (event) => {
43258
+ if (event.target === event.currentTarget) onClose();
43259
+ },
43260
+ ...ownsContextMenuProps,
43261
+ children: /* @__PURE__ */ jsxs72(
43262
+ "div",
43263
+ {
43264
+ ref: dialogRef,
43265
+ className: `squisq-media-preview-surface squisq-media-preview-surface--${kind}`,
43266
+ role: "dialog",
43267
+ "aria-modal": "true",
43268
+ "aria-labelledby": titleId,
43269
+ tabIndex: -1,
43270
+ "data-testid": "media-preview-dialog",
43271
+ children: [
43272
+ /* @__PURE__ */ jsxs72("header", { className: "squisq-media-preview-header", children: [
43273
+ /* @__PURE__ */ jsx90("span", { id: titleId, className: "squisq-media-preview-title", title: name, children: name }),
43274
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-preview-detail", children: detail }),
43275
+ /* @__PURE__ */ jsx90(
43276
+ "button",
43277
+ {
43278
+ type: "button",
43279
+ className: "squisq-media-preview-close",
43280
+ onClick: onClose,
43281
+ "aria-label": "Close",
43282
+ children: "\xD7"
43283
+ }
43284
+ )
43285
+ ] }),
43286
+ /* @__PURE__ */ jsx90("div", { className: "squisq-media-preview-body", children: body })
43287
+ ]
43288
+ }
43289
+ )
43290
+ }
43291
+ );
43292
+ }
43293
+
43294
+ // src/MediaBin.tsx
43295
+ import { Fragment as Fragment29, jsx as jsx91, jsxs as jsxs73 } from "react/jsx-runtime";
43127
43296
  function formatSize(bytes) {
43128
43297
  if (bytes < 1024) return `${bytes} B`;
43129
43298
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
@@ -43195,23 +43364,24 @@ function MediaBin({
43195
43364
  allowBinaryDownloads = true,
43196
43365
  highlightPath = null
43197
43366
  }) {
43198
- const [entries, setEntries] = useState81([]);
43199
- const listRef = useRef64(null);
43200
- useEffect70(() => {
43367
+ const [entries, setEntries] = useState82([]);
43368
+ const listRef = useRef65(null);
43369
+ useEffect72(() => {
43201
43370
  if (!highlightPath || !listRef.current) return;
43202
43371
  const item = listRef.current.querySelector(`[data-media-path="${CSS.escape(highlightPath)}"]`);
43203
43372
  if (item instanceof HTMLElement) {
43204
43373
  item.scrollIntoView({ block: "nearest" });
43205
43374
  }
43206
43375
  }, [highlightPath, entries]);
43207
- const [thumbUrls, setThumbUrls] = useState81({});
43208
- const [loading, setLoading] = useState81(false);
43209
- const [isDropActive, setIsDropActive] = useState81(false);
43210
- const [downloadingPath, setDownloadingPath] = useState81(null);
43211
- const [contextMenu, setContextMenu] = useState81(null);
43212
- const fileInputRef = useRef64(null);
43213
- const contextMenuRef = useRef64(null);
43214
- const dropDepthRef = useRef64(0);
43376
+ const [thumbUrls, setThumbUrls] = useState82({});
43377
+ const [loading, setLoading] = useState82(false);
43378
+ const [isDropActive, setIsDropActive] = useState82(false);
43379
+ const [downloadingPath, setDownloadingPath] = useState82(null);
43380
+ const [contextMenu, setContextMenu] = useState82(null);
43381
+ const [preview, setPreview] = useState82(null);
43382
+ const fileInputRef = useRef65(null);
43383
+ const contextMenuRef = useRef65(null);
43384
+ const dropDepthRef = useRef65(0);
43215
43385
  const updateEntries = useCallback55(
43216
43386
  async (provider) => {
43217
43387
  const list = sortMediaEntries(filterVisibleMediaEntries(await provider.listMedia()));
@@ -43230,7 +43400,7 @@ function MediaBin({
43230
43400
  },
43231
43401
  [onCountChange]
43232
43402
  );
43233
- useEffect70(() => {
43403
+ useEffect72(() => {
43234
43404
  if (!contextMenu) return;
43235
43405
  const handlePointerDown = (event) => {
43236
43406
  if (contextMenuRef.current?.contains(event.target)) return;
@@ -43251,7 +43421,7 @@ function MediaBin({
43251
43421
  window.removeEventListener("resize", close);
43252
43422
  };
43253
43423
  }, [contextMenu]);
43254
- useEffect70(() => {
43424
+ useEffect72(() => {
43255
43425
  if (!mediaProvider) {
43256
43426
  setEntries([]);
43257
43427
  setThumbUrls({});
@@ -43408,6 +43578,27 @@ function MediaBin({
43408
43578
  const openContextMenu = useCallback55((entry, x, y) => {
43409
43579
  setContextMenu({ entry, x, y });
43410
43580
  }, []);
43581
+ useEffect72(() => {
43582
+ setPreview(null);
43583
+ }, [mediaProvider]);
43584
+ const openPreview = useCallback55(
43585
+ async (entry) => {
43586
+ if (!mediaProvider || squisqMediaKind(entry.mimeType) === "file") return;
43587
+ const thumb = thumbUrls[entry.name];
43588
+ setPreview({ entry, src: thumb ?? null, failed: false });
43589
+ if (thumb !== void 0) return;
43590
+ let src = null;
43591
+ try {
43592
+ src = isImageMime(entry.mimeType) ? await resolveThumbnailUrl(mediaProvider, entry.name) : await mediaProvider.resolveUrl(entry.name);
43593
+ } catch {
43594
+ }
43595
+ setPreview(
43596
+ (current) => current?.entry.name === entry.name ? { entry, src, failed: src === null } : current
43597
+ );
43598
+ },
43599
+ [mediaProvider, thumbUrls]
43600
+ );
43601
+ const closePreview = useCallback55(() => setPreview(null), []);
43411
43602
  const removeLabel = contextMenu ? isImageMime(contextMenu.entry.mimeType) ? "Remove image" : "Remove file" : "Remove file";
43412
43603
  const menuLeft = contextMenu ? Math.min(contextMenu.x, Math.max(8, window.innerWidth - 168)) : 0;
43413
43604
  const menuTop = contextMenu ? Math.min(contextMenu.y, Math.max(8, window.innerHeight - 48)) : 0;
@@ -43417,189 +43608,217 @@ function MediaBin({
43417
43608
  };
43418
43609
  const handleItemKeyDown = useCallback55(
43419
43610
  (entry, event) => {
43611
+ if (event.key === "Enter" || event.key === " ") {
43612
+ if (event.target !== event.currentTarget) return;
43613
+ if (squisqMediaKind(entry.mimeType) === "file") return;
43614
+ event.preventDefault();
43615
+ void openPreview(entry);
43616
+ return;
43617
+ }
43420
43618
  if (event.key !== "ContextMenu" && !(event.shiftKey && event.key === "F10")) return;
43421
43619
  event.preventDefault();
43422
43620
  const rect = event.currentTarget.getBoundingClientRect();
43423
43621
  openContextMenu(entry, rect.left + 16, rect.top + 16);
43424
43622
  },
43425
- [openContextMenu]
43623
+ [openContextMenu, openPreview]
43426
43624
  );
43427
- return /* @__PURE__ */ jsxs72(
43428
- "div",
43429
- {
43430
- className: [
43431
- "squisq-media-bin",
43432
- isDark ? "squisq-media-bin--dark" : "",
43433
- isDropActive ? "squisq-media-bin--drop-active" : ""
43434
- ].filter(Boolean).join(" "),
43435
- onDragEnter: handleDragEnter,
43436
- onDragOver: handleDragOver,
43437
- onDragLeave: handleDragLeave,
43438
- onDrop: handleDrop,
43439
- "aria-busy": loading,
43440
- ...ownsContextMenuProps,
43441
- children: [
43442
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-header", children: [
43443
- /* @__PURE__ */ jsxs72("span", { className: "squisq-media-bin-title", children: [
43444
- "Attachments ",
43445
- entries.length > 0 && `(${entries.length})`
43446
- ] }),
43447
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-actions", children: [
43448
- onRecord && /* @__PURE__ */ jsxs72(
43449
- "button",
43450
- {
43451
- type: "button",
43452
- className: "squisq-media-bin-record",
43453
- onClick: onRecord,
43454
- disabled: !mediaProvider,
43455
- title: mediaProvider ? "Record media" : "Load a content zip or select a storage slot first",
43456
- "aria-label": "Record media",
43457
- "aria-haspopup": "dialog",
43458
- "aria-expanded": isRecorderOpen,
43459
- children: [
43460
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-action-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-record-dot" }) }),
43461
- /* @__PURE__ */ jsx89("span", { children: "Record" })
43462
- ]
43463
- }
43464
- ),
43465
- /* @__PURE__ */ jsxs72(
43466
- "button",
43467
- {
43468
- type: "button",
43469
- className: "squisq-media-bin-upload",
43470
- onClick: handleUploadClick,
43471
- disabled: !mediaProvider || loading,
43472
- title: mediaProvider ? "Upload files" : "Load a content zip or select a storage slot first",
43473
- children: [
43474
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-action-icon", children: "+" }),
43475
- /* @__PURE__ */ jsx89("span", { children: "Upload" })
43476
- ]
43477
- }
43478
- )
43479
- ] })
43480
- ] }),
43481
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-list", ref: listRef, children: [
43482
- !mediaProvider && /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-empty", children: [
43483
- "No media context.",
43484
- /* @__PURE__ */ jsx89("br", {}),
43485
- "Load a content zip or select a storage slot."
43625
+ const previewKind = preview ? squisqMediaKind(preview.entry.mimeType) : "file";
43626
+ return /* @__PURE__ */ jsxs73(Fragment29, { children: [
43627
+ /* @__PURE__ */ jsxs73(
43628
+ "div",
43629
+ {
43630
+ className: [
43631
+ "squisq-media-bin",
43632
+ isDark ? "squisq-media-bin--dark" : "",
43633
+ isDropActive ? "squisq-media-bin--drop-active" : ""
43634
+ ].filter(Boolean).join(" "),
43635
+ onDragEnter: handleDragEnter,
43636
+ onDragOver: handleDragOver,
43637
+ onDragLeave: handleDragLeave,
43638
+ onDrop: handleDrop,
43639
+ "aria-busy": loading,
43640
+ ...ownsContextMenuProps,
43641
+ children: [
43642
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-header", children: [
43643
+ /* @__PURE__ */ jsxs73("span", { className: "squisq-media-bin-title", children: [
43644
+ "Attachments ",
43645
+ entries.length > 0 && `(${entries.length})`
43646
+ ] }),
43647
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-actions", children: [
43648
+ onRecord && /* @__PURE__ */ jsxs73(
43649
+ "button",
43650
+ {
43651
+ type: "button",
43652
+ className: "squisq-media-bin-record",
43653
+ onClick: onRecord,
43654
+ disabled: !mediaProvider,
43655
+ title: mediaProvider ? "Record media" : "Load a content zip or select a storage slot first",
43656
+ "aria-label": "Record media",
43657
+ "aria-haspopup": "dialog",
43658
+ "aria-expanded": isRecorderOpen,
43659
+ children: [
43660
+ /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-action-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-record-dot" }) }),
43661
+ /* @__PURE__ */ jsx91("span", { children: "Record" })
43662
+ ]
43663
+ }
43664
+ ),
43665
+ /* @__PURE__ */ jsxs73(
43666
+ "button",
43667
+ {
43668
+ type: "button",
43669
+ className: "squisq-media-bin-upload",
43670
+ onClick: handleUploadClick,
43671
+ disabled: !mediaProvider || loading,
43672
+ title: mediaProvider ? "Upload files" : "Load a content zip or select a storage slot first",
43673
+ children: [
43674
+ /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-action-icon", children: "+" }),
43675
+ /* @__PURE__ */ jsx91("span", { children: "Upload" })
43676
+ ]
43677
+ }
43678
+ )
43679
+ ] })
43486
43680
  ] }),
43487
- mediaProvider && entries.length === 0 && !loading && /* @__PURE__ */ jsx89("div", { className: "squisq-media-bin-empty", children: "No files yet." }),
43488
- entries.map((entry) => {
43489
- const thumb = thumbUrls[entry.name];
43490
- const basename = basenameForPath(entry.name);
43491
- const altText = basename.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
43492
- const isUnused = !!usedMediaPaths && !usedMediaPaths.has(entry.name);
43493
- const handleDragStart = (e2) => {
43494
- const payload = {
43495
- name: entry.name,
43496
- mimeType: entry.mimeType,
43497
- alt: altText
43681
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-list", ref: listRef, children: [
43682
+ !mediaProvider && /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-empty", children: [
43683
+ "No media context.",
43684
+ /* @__PURE__ */ jsx91("br", {}),
43685
+ "Load a content zip or select a storage slot."
43686
+ ] }),
43687
+ mediaProvider && entries.length === 0 && !loading && /* @__PURE__ */ jsx91("div", { className: "squisq-media-bin-empty", children: "No files yet." }),
43688
+ entries.map((entry) => {
43689
+ const thumb = thumbUrls[entry.name];
43690
+ const basename = basenameForPath(entry.name);
43691
+ const altText = basename.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
43692
+ const isUnused = !!usedMediaPaths && !usedMediaPaths.has(entry.name);
43693
+ const isPreviewable = squisqMediaKind(entry.mimeType) !== "file";
43694
+ const handleDragStart = (e2) => {
43695
+ const payload = {
43696
+ name: entry.name,
43697
+ mimeType: entry.mimeType,
43698
+ alt: altText
43699
+ };
43700
+ e2.dataTransfer.setData(SQUISQ_MEDIA_MIME, JSON.stringify(payload));
43701
+ e2.dataTransfer.setData("text/plain", buildSquisqMediaReference(payload));
43702
+ e2.dataTransfer.effectAllowed = "copy";
43498
43703
  };
43499
- e2.dataTransfer.setData(SQUISQ_MEDIA_MIME, JSON.stringify(payload));
43500
- e2.dataTransfer.setData("text/plain", buildSquisqMediaReference(payload));
43501
- e2.dataTransfer.effectAllowed = "copy";
43502
- };
43503
- return /* @__PURE__ */ jsxs72(
43504
- "div",
43505
- {
43506
- "data-media-path": entry.name,
43507
- className: entry.name === highlightPath ? "squisq-media-bin-item squisq-media-bin-item--highlight" : "squisq-media-bin-item",
43508
- title: `${entry.name}
43704
+ return /* @__PURE__ */ jsxs73(
43705
+ "div",
43706
+ {
43707
+ "data-media-path": entry.name,
43708
+ className: [
43709
+ "squisq-media-bin-item",
43710
+ isPreviewable ? "squisq-media-bin-item--previewable" : "",
43711
+ entry.name === highlightPath ? "squisq-media-bin-item--highlight" : ""
43712
+ ].filter(Boolean).join(" "),
43713
+ title: `${entry.name}
43509
43714
  ${entry.mimeType}
43510
43715
  ${formatSize(entry.size)}`,
43511
- draggable: true,
43512
- tabIndex: 0,
43513
- onContextMenu: (e2) => {
43514
- e2.preventDefault();
43515
- openContextMenu(entry, e2.clientX, e2.clientY);
43716
+ draggable: true,
43717
+ tabIndex: 0,
43718
+ onClick: isPreviewable ? () => void openPreview(entry) : void 0,
43719
+ onContextMenu: (e2) => {
43720
+ e2.preventDefault();
43721
+ openContextMenu(entry, e2.clientX, e2.clientY);
43722
+ },
43723
+ onDragStart: handleDragStart,
43724
+ onKeyDown: (e2) => handleItemKeyDown(entry, e2),
43725
+ children: [
43726
+ thumb ? /* @__PURE__ */ jsx91(
43727
+ "img",
43728
+ {
43729
+ src: thumb,
43730
+ alt: basename,
43731
+ className: "squisq-media-bin-thumb",
43732
+ draggable: false
43733
+ }
43734
+ ) : /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) }),
43735
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-meta", children: [
43736
+ /* @__PURE__ */ jsx91("div", { className: "squisq-media-bin-name", children: basename }),
43737
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-detail-row", children: [
43738
+ /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-size", children: formatSize(entry.size) }),
43739
+ isUnused && /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-unused-badge", title: "Not used in document", children: "Unused" })
43740
+ ] })
43741
+ ] }),
43742
+ allowBinaryDownloads && /* @__PURE__ */ jsx91(
43743
+ "button",
43744
+ {
43745
+ type: "button",
43746
+ className: "squisq-media-bin-download",
43747
+ title: `Download ${basename}`,
43748
+ "aria-label": `Download ${basename}`,
43749
+ disabled: !mediaProvider || downloadingPath !== null,
43750
+ draggable: false,
43751
+ onClick: (event) => {
43752
+ event.stopPropagation();
43753
+ void handleDownloadEntry(entry);
43754
+ },
43755
+ onDragStart: (event) => event.preventDefault(),
43756
+ children: /* @__PURE__ */ jsx91("span", { "aria-hidden": "true", children: downloadingPath === entry.name ? "\u2026" : "\u2193" })
43757
+ }
43758
+ )
43759
+ ]
43516
43760
  },
43517
- onDragStart: handleDragStart,
43518
- onKeyDown: (e2) => handleItemKeyDown(entry, e2),
43519
- children: [
43520
- thumb ? /* @__PURE__ */ jsx89(
43521
- "img",
43522
- {
43523
- src: thumb,
43524
- alt: basename,
43525
- className: "squisq-media-bin-thumb",
43526
- draggable: false
43527
- }
43528
- ) : /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) }),
43529
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-meta", children: [
43530
- /* @__PURE__ */ jsx89("div", { className: "squisq-media-bin-name", children: basename }),
43531
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-detail-row", children: [
43532
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-size", children: formatSize(entry.size) }),
43533
- isUnused && /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-unused-badge", title: "Not used in document", children: "Unused" })
43534
- ] })
43535
- ] }),
43536
- allowBinaryDownloads && /* @__PURE__ */ jsx89(
43537
- "button",
43538
- {
43539
- type: "button",
43540
- className: "squisq-media-bin-download",
43541
- title: `Download ${basename}`,
43542
- "aria-label": `Download ${basename}`,
43543
- disabled: !mediaProvider || downloadingPath !== null,
43544
- draggable: false,
43545
- onClick: (event) => {
43546
- event.stopPropagation();
43547
- void handleDownloadEntry(entry);
43548
- },
43549
- onDragStart: (event) => event.preventDefault(),
43550
- children: /* @__PURE__ */ jsx89("span", { "aria-hidden": "true", children: downloadingPath === entry.name ? "\u2026" : "\u2193" })
43551
- }
43552
- )
43553
- ]
43554
- },
43555
- entry.name
43556
- );
43557
- })
43558
- ] }),
43559
- isDropActive && /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-drop-target", "aria-hidden": "true", children: [
43560
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-drop-target-icon", children: "+" }),
43561
- /* @__PURE__ */ jsx89("strong", { children: "Drop media here" }),
43562
- /* @__PURE__ */ jsx89("span", { children: "Attach to this document" })
43563
- ] }),
43564
- contextMenu && /* @__PURE__ */ jsx89(
43565
- "div",
43566
- {
43567
- ref: contextMenuRef,
43568
- className: "squisq-media-bin-context-menu",
43569
- role: "menu",
43570
- "aria-label": `${contextMenu.entry.name} actions`,
43571
- style: contextMenuStyle,
43572
- children: /* @__PURE__ */ jsx89(
43573
- "button",
43574
- {
43575
- type: "button",
43576
- role: "menuitem",
43577
- className: "squisq-media-bin-context-menu-item squisq-media-bin-context-menu-item--danger",
43578
- onClick: () => handleRemoveEntry(contextMenu.entry),
43579
- disabled: !mediaProvider || loading,
43580
- children: removeLabel
43581
- }
43582
- )
43583
- }
43584
- ),
43585
- /* @__PURE__ */ jsx89(
43586
- "input",
43587
- {
43588
- ref: fileInputRef,
43589
- type: "file",
43590
- multiple: true,
43591
- style: { display: "none" },
43592
- onChange: handleFileChange
43593
- }
43594
- )
43595
- ]
43596
- }
43597
- );
43761
+ entry.name
43762
+ );
43763
+ })
43764
+ ] }),
43765
+ isDropActive && /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-drop-target", "aria-hidden": "true", children: [
43766
+ /* @__PURE__ */ jsx91("span", { className: "squisq-media-bin-drop-target-icon", children: "+" }),
43767
+ /* @__PURE__ */ jsx91("strong", { children: "Drop media here" }),
43768
+ /* @__PURE__ */ jsx91("span", { children: "Attach to this document" })
43769
+ ] }),
43770
+ contextMenu && /* @__PURE__ */ jsx91(
43771
+ "div",
43772
+ {
43773
+ ref: contextMenuRef,
43774
+ className: "squisq-media-bin-context-menu",
43775
+ role: "menu",
43776
+ "aria-label": `${contextMenu.entry.name} actions`,
43777
+ style: contextMenuStyle,
43778
+ children: /* @__PURE__ */ jsx91(
43779
+ "button",
43780
+ {
43781
+ type: "button",
43782
+ role: "menuitem",
43783
+ className: "squisq-media-bin-context-menu-item squisq-media-bin-context-menu-item--danger",
43784
+ onClick: () => handleRemoveEntry(contextMenu.entry),
43785
+ disabled: !mediaProvider || loading,
43786
+ children: removeLabel
43787
+ }
43788
+ )
43789
+ }
43790
+ ),
43791
+ /* @__PURE__ */ jsx91(
43792
+ "input",
43793
+ {
43794
+ ref: fileInputRef,
43795
+ type: "file",
43796
+ multiple: true,
43797
+ style: { display: "none" },
43798
+ onChange: handleFileChange
43799
+ }
43800
+ )
43801
+ ]
43802
+ }
43803
+ ),
43804
+ preview && previewKind !== "file" && /* @__PURE__ */ jsx91(
43805
+ MediaPreviewDialog,
43806
+ {
43807
+ kind: previewKind,
43808
+ name: basenameForPath(preview.entry.name),
43809
+ detail: `${formatSize(preview.entry.size)} \xB7 ${preview.entry.mimeType}`,
43810
+ src: preview.src,
43811
+ failed: preview.failed,
43812
+ isDark,
43813
+ onClose: closePreview
43814
+ }
43815
+ )
43816
+ ] });
43598
43817
  }
43599
43818
 
43600
43819
  // src/DropZoneOverlay.tsx
43601
- import { useState as useState82 } from "react";
43602
- import { Fragment as Fragment29, jsx as jsx90, jsxs as jsxs73 } from "react/jsx-runtime";
43820
+ import { useState as useState83 } from "react";
43821
+ import { Fragment as Fragment30, jsx as jsx92, jsxs as jsxs74 } from "react/jsx-runtime";
43603
43822
  function DropZoneOverlay({
43604
43823
  dragContentType,
43605
43824
  zoneProps,
@@ -43607,8 +43826,8 @@ function DropZoneOverlay({
43607
43826
  }) {
43608
43827
  const showMedia = dragContentType === "media" || dragContentType === "mixed";
43609
43828
  const showText = dragContentType === "text" || dragContentType === "mixed";
43610
- return /* @__PURE__ */ jsx90("div", { className: "squisq-drop-overlay", children: /* @__PURE__ */ jsxs73("div", { className: "squisq-drop-overlay-inner", children: [
43611
- showMedia && /* @__PURE__ */ jsx90(
43829
+ return /* @__PURE__ */ jsx92("div", { className: "squisq-drop-overlay", children: /* @__PURE__ */ jsxs74("div", { className: "squisq-drop-overlay-inner", children: [
43830
+ showMedia && /* @__PURE__ */ jsx92(
43612
43831
  DropZone,
43613
43832
  {
43614
43833
  target: "media",
@@ -43620,8 +43839,8 @@ function DropZoneOverlay({
43620
43839
  variant: "media"
43621
43840
  }
43622
43841
  ),
43623
- showText && /* @__PURE__ */ jsxs73(Fragment29, { children: [
43624
- /* @__PURE__ */ jsx90(
43842
+ showText && /* @__PURE__ */ jsxs74(Fragment30, { children: [
43843
+ /* @__PURE__ */ jsx92(
43625
43844
  DropZone,
43626
43845
  {
43627
43846
  target: "insert",
@@ -43632,7 +43851,7 @@ function DropZoneOverlay({
43632
43851
  variant: "insert"
43633
43852
  }
43634
43853
  ),
43635
- /* @__PURE__ */ jsx90(
43854
+ /* @__PURE__ */ jsx92(
43636
43855
  DropZone,
43637
43856
  {
43638
43857
  target: "replace",
@@ -43655,9 +43874,9 @@ function DropZone({
43655
43874
  disabled,
43656
43875
  variant
43657
43876
  }) {
43658
- const [isHovering, setIsHovering] = useState82(false);
43877
+ const [isHovering, setIsHovering] = useState83(false);
43659
43878
  const props = zoneProps(target);
43660
- return /* @__PURE__ */ jsxs73(
43879
+ return /* @__PURE__ */ jsxs74(
43661
43880
  "div",
43662
43881
  {
43663
43882
  className: [
@@ -43690,16 +43909,16 @@ function DropZone({
43690
43909
  props.onDrop(e2);
43691
43910
  },
43692
43911
  children: [
43693
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-icon", children: icon }),
43694
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-label", children: label }),
43695
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-desc", children: description })
43912
+ /* @__PURE__ */ jsx92("span", { className: "squisq-drop-zone-icon", children: icon }),
43913
+ /* @__PURE__ */ jsx92("span", { className: "squisq-drop-zone-label", children: label }),
43914
+ /* @__PURE__ */ jsx92("span", { className: "squisq-drop-zone-desc", children: description })
43696
43915
  ]
43697
43916
  }
43698
43917
  );
43699
43918
  }
43700
43919
 
43701
43920
  // src/Tooltip.tsx
43702
- import { useEffect as useEffect71, useLayoutEffect as useLayoutEffect16, useRef as useRef65, useState as useState83 } from "react";
43921
+ import { useEffect as useEffect73, useLayoutEffect as useLayoutEffect16, useRef as useRef66, useState as useState84 } from "react";
43703
43922
  import { createPortal as createPortal19 } from "react-dom";
43704
43923
 
43705
43924
  // src/tooltipPlacement.ts
@@ -43712,16 +43931,16 @@ function clampTooltipLeft(anchorX, tooltipWidth, viewportWidth, edgePadding = ED
43712
43931
  }
43713
43932
 
43714
43933
  // src/Tooltip.tsx
43715
- import { jsx as jsx91 } from "react/jsx-runtime";
43934
+ import { jsx as jsx93 } from "react/jsx-runtime";
43716
43935
  var SHOW_DELAY_MS = 180;
43717
43936
  function TooltipLayer() {
43718
- const [state, setState3] = useState83(null);
43719
- const tooltipRef = useRef65(null);
43720
- const timerRef = useRef65(null);
43721
- const currentTargetRef = useRef65(null);
43722
- const visibleRef = useRef65(false);
43723
- const pressedTargetRef = useRef65(null);
43724
- const lastPointerWasTouchRef = useRef65(false);
43937
+ const [state, setState3] = useState84(null);
43938
+ const tooltipRef = useRef66(null);
43939
+ const timerRef = useRef66(null);
43940
+ const currentTargetRef = useRef66(null);
43941
+ const visibleRef = useRef66(false);
43942
+ const pressedTargetRef = useRef66(null);
43943
+ const lastPointerWasTouchRef = useRef66(false);
43725
43944
  useLayoutEffect16(() => {
43726
43945
  if (!state) return;
43727
43946
  const node2 = tooltipRef.current;
@@ -43733,7 +43952,7 @@ function TooltipLayer() {
43733
43952
  node2.style.left = `${left}px`;
43734
43953
  node2.style.visibility = "visible";
43735
43954
  }, [state]);
43736
- useEffect71(() => {
43955
+ useEffect73(() => {
43737
43956
  const clearTimer = () => {
43738
43957
  if (timerRef.current) {
43739
43958
  clearTimeout(timerRef.current);
@@ -43815,7 +44034,7 @@ function TooltipLayer() {
43815
44034
  }, []);
43816
44035
  if (!state) return null;
43817
44036
  return createPortal19(
43818
- /* @__PURE__ */ jsx91(
44037
+ /* @__PURE__ */ jsx93(
43819
44038
  "div",
43820
44039
  {
43821
44040
  role: "tooltip",
@@ -43835,18 +44054,18 @@ function TooltipLayer() {
43835
44054
  }
43836
44055
 
43837
44056
  // src/EditorShell.tsx
43838
- import { useEffect as useEffect78, useRef as useRef74, useState as useState90, useCallback as useCallback63, useMemo as useMemo62 } from "react";
44057
+ import { useEffect as useEffect80, useRef as useRef75, useState as useState91, useCallback as useCallback63, useMemo as useMemo62 } from "react";
43839
44058
 
43840
44059
  // src/BlockPreviewPanel.tsx
43841
44060
  import { useMemo as useMemo58 } from "react";
43842
- import { VIEWPORT_PRESETS as VIEWPORT_PRESETS7 } from "@bendyline/squisq/schemas";
44061
+ import { VIEWPORT_PRESETS as VIEWPORT_PRESETS8 } from "@bendyline/squisq/schemas";
43843
44062
  import { flattenBlocks as flattenBlocks6, DEFAULT_THEME as DEFAULT_THEME7 } from "@bendyline/squisq/doc";
43844
- import { jsx as jsx92 } from "react/jsx-runtime";
44063
+ import { jsx as jsx94 } from "react/jsx-runtime";
43845
44064
  function BlockPreviewPanel({ basePath = "/" }) {
43846
44065
  const { doc, activeBlockStartLine, mediaProvider, workspaceContainer, fileName, mediaRevision } = useEditorContext();
43847
44066
  const previewSettings = usePreviewSettingsOptional();
43848
44067
  const theme = previewSettings?.activeTheme ?? DEFAULT_THEME7;
43849
- const viewport = previewSettings?.activeViewport ?? VIEWPORT_PRESETS7.landscape;
44068
+ const viewport = previewSettings?.activeViewport ?? VIEWPORT_PRESETS8.landscape;
43850
44069
  const projection = usePreviewProjection(doc, "", workspaceContainer, fileName, mediaRevision);
43851
44070
  const previewDoc = projection?.contentDoc ?? doc;
43852
44071
  const block = useMemo58(() => {
@@ -43860,12 +44079,12 @@ function BlockPreviewPanel({ basePath = "/" }) {
43860
44079
  [previewDoc, block, theme, viewport]
43861
44080
  );
43862
44081
  if (!visual) return null;
43863
- return /* @__PURE__ */ jsx92("div", { className: "squisq-block-preview-panel", "data-testid": "block-preview-panel", "aria-hidden": true, children: /* @__PURE__ */ jsx92(
44082
+ return /* @__PURE__ */ jsx94("div", { className: "squisq-block-preview-panel", "data-testid": "block-preview-panel", "aria-hidden": true, children: /* @__PURE__ */ jsx94(
43864
44083
  "div",
43865
44084
  {
43866
44085
  className: "squisq-block-preview-frame",
43867
44086
  style: { aspectRatio: `${viewport.width} / ${viewport.height}` },
43868
- children: /* @__PURE__ */ jsx92(
44087
+ children: /* @__PURE__ */ jsx94(
43869
44088
  BlockThumbnail,
43870
44089
  {
43871
44090
  visual,
@@ -43879,23 +44098,23 @@ function BlockPreviewPanel({ basePath = "/" }) {
43879
44098
  }
43880
44099
 
43881
44100
  // src/NavigationSheet.tsx
43882
- import { useCallback as useCallback57, useEffect as useEffect73, useId as useId16, useRef as useRef68, useState as useState84 } from "react";
44101
+ import { useCallback as useCallback57, useEffect as useEffect75, useId as useId17, useRef as useRef69, useState as useState85 } from "react";
43883
44102
 
43884
44103
  // src/BlockPreviewList.tsx
43885
- import { useCallback as useCallback56, useRef as useRef66 } from "react";
43886
- import { VIEWPORT_PRESETS as VIEWPORT_PRESETS8 } from "@bendyline/squisq/schemas";
44104
+ import { useCallback as useCallback56, useRef as useRef67 } from "react";
44105
+ import { VIEWPORT_PRESETS as VIEWPORT_PRESETS9 } from "@bendyline/squisq/schemas";
43887
44106
  import { flattenBlocks as flattenBlocks7 } from "@bendyline/squisq/doc";
43888
- import { BlockRenderer as BlockRenderer5, MediaContext as MediaContext6 } from "@bendyline/squisq-react";
43889
- import { Fragment as Fragment30, jsx as jsx93, jsxs as jsxs74 } from "react/jsx-runtime";
44107
+ import { BlockRenderer as BlockRenderer6, MediaContext as MediaContext7 } from "@bendyline/squisq-react";
44108
+ import { Fragment as Fragment31, jsx as jsx95, jsxs as jsxs75 } from "react/jsx-runtime";
43890
44109
  function BlockPreviewList({
43891
44110
  basePath = "/",
43892
- viewport = VIEWPORT_PRESETS8.landscape,
44111
+ viewport = VIEWPORT_PRESETS9.landscape,
43893
44112
  mediaProvider = null,
43894
44113
  onNavigate
43895
44114
  }) {
43896
44115
  const { doc, activeView, layoutMode, goToBlockByLine, monacoEditor } = useEditorContext();
43897
44116
  const items = useBlockPreviewItems(viewport);
43898
- const listRef = useRef66(null);
44117
+ const listRef = useRef67(null);
43899
44118
  const handleSelect = useCallback56(
43900
44119
  (item) => {
43901
44120
  const line = blockStartLine(item.sourceBlock);
@@ -43922,9 +44141,9 @@ function BlockPreviewList({
43922
44141
  [activeView, doc, goToBlockByLine, layoutMode, monacoEditor, onNavigate]
43923
44142
  );
43924
44143
  if (items.length === 0) {
43925
- return /* @__PURE__ */ jsx93("div", { className: "squisq-preview-list-empty", children: /* @__PURE__ */ jsx93("p", { children: "Add some content to see block previews." }) });
44144
+ return /* @__PURE__ */ jsx95("div", { className: "squisq-preview-list-empty", children: /* @__PURE__ */ jsx95("p", { children: "Add some content to see block previews." }) });
43926
44145
  }
43927
- return /* @__PURE__ */ jsx93(MediaContext6.Provider, { value: mediaProvider, children: /* @__PURE__ */ jsx93("ul", { ref: listRef, className: "squisq-preview-list", "aria-label": "Block previews", children: items.map((item) => /* @__PURE__ */ jsx93("li", { children: /* @__PURE__ */ jsxs74(
44146
+ return /* @__PURE__ */ jsx95(MediaContext7.Provider, { value: mediaProvider, children: /* @__PURE__ */ jsx95("ul", { ref: listRef, className: "squisq-preview-list", "aria-label": "Block previews", children: items.map((item) => /* @__PURE__ */ jsx95("li", { children: /* @__PURE__ */ jsxs75(
43928
44147
  "button",
43929
44148
  {
43930
44149
  type: "button",
@@ -43932,21 +44151,21 @@ function BlockPreviewList({
43932
44151
  "data-template": item.template,
43933
44152
  onClick: () => handleSelect(item),
43934
44153
  children: [
43935
- /* @__PURE__ */ jsxs74("span", { className: "squisq-inline-preview-card-label", children: [
43936
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-template", children: templateLabel(item.template) }),
43937
- item.headingText && /* @__PURE__ */ jsxs74(Fragment30, { children: [
43938
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-sep", "aria-hidden": "true", children: "\u2014" }),
43939
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-title", children: item.headingText })
44154
+ /* @__PURE__ */ jsxs75("span", { className: "squisq-inline-preview-card-label", children: [
44155
+ /* @__PURE__ */ jsx95("span", { className: "squisq-inline-preview-card-template", children: templateLabel(item.template) }),
44156
+ item.headingText && /* @__PURE__ */ jsxs75(Fragment31, { children: [
44157
+ /* @__PURE__ */ jsx95("span", { className: "squisq-inline-preview-card-sep", "aria-hidden": "true", children: "\u2014" }),
44158
+ /* @__PURE__ */ jsx95("span", { className: "squisq-inline-preview-card-title", children: item.headingText })
43940
44159
  ] })
43941
44160
  ] }),
43942
- /* @__PURE__ */ jsx93(
44161
+ /* @__PURE__ */ jsx95(
43943
44162
  "span",
43944
44163
  {
43945
44164
  className: "squisq-inline-preview-card-svg",
43946
44165
  "aria-hidden": "true",
43947
44166
  style: { aspectRatio: `${viewport.width} / ${viewport.height}` },
43948
- children: /* @__PURE__ */ jsx93(
43949
- BlockRenderer5,
44167
+ children: /* @__PURE__ */ jsx95(
44168
+ BlockRenderer6,
43950
44169
  {
43951
44170
  block: item.block,
43952
44171
  buildPlayback: "all",
@@ -43963,7 +44182,7 @@ function BlockPreviewList({
43963
44182
  }
43964
44183
 
43965
44184
  // src/useNavigationSheetSwipe.ts
43966
- import { useEffect as useEffect72, useRef as useRef67 } from "react";
44185
+ import { useEffect as useEffect74, useRef as useRef68 } from "react";
43967
44186
  var NAVIGATION_SHEET_MAX_BODY_WIDTH = 720;
43968
44187
  var EDGE_ZONE_PX = 24;
43969
44188
  var AXIS_LOCK_PX = 10;
@@ -43978,9 +44197,9 @@ function useNavigationSheetSwipe({
43978
44197
  onOpen,
43979
44198
  onClose
43980
44199
  }) {
43981
- const callbacksRef = useRef67({ onDragStart, onOpen, onClose });
44200
+ const callbacksRef = useRef68({ onDragStart, onOpen, onClose });
43982
44201
  callbacksRef.current = { onDragStart, onOpen, onClose };
43983
- useEffect72(() => {
44202
+ useEffect74(() => {
43984
44203
  const sheet = sheetRef.current;
43985
44204
  const surface = sheet?.parentElement;
43986
44205
  if (!sheet || !surface) return;
@@ -44086,7 +44305,7 @@ function useNavigationSheetSwipe({
44086
44305
  }
44087
44306
 
44088
44307
  // src/NavigationSheet.tsx
44089
- import { Fragment as Fragment31, jsx as jsx94, jsxs as jsxs75 } from "react/jsx-runtime";
44308
+ import { Fragment as Fragment32, jsx as jsx96, jsxs as jsxs76 } from "react/jsx-runtime";
44090
44309
  var PANEL_LABELS = {
44091
44310
  outline: "Outline",
44092
44311
  previews: "Block previews"
@@ -44104,17 +44323,17 @@ function NavigationSheet({
44104
44323
  basePath,
44105
44324
  mediaProvider
44106
44325
  }) {
44107
- const sheetRef = useRef68(null);
44108
- const panelRef = useRef68(null);
44109
- const scrimRef = useRef68(null);
44110
- const tabIdPrefix = useId16();
44111
- const [dragPanel, setDragPanel] = useState84(null);
44326
+ const sheetRef = useRef69(null);
44327
+ const panelRef = useRef69(null);
44328
+ const scrimRef = useRef69(null);
44329
+ const tabIdPrefix = useId17();
44330
+ const [dragPanel, setDragPanel] = useState85(null);
44112
44331
  const open = panel !== null;
44113
44332
  const shown = panel ?? dragPanel;
44114
- const [lastShown, setLastShown] = useState84(shown);
44333
+ const [lastShown, setLastShown] = useState85(shown);
44115
44334
  if (shown && shown !== lastShown) setLastShown(shown);
44116
44335
  const content = shown ?? lastShown;
44117
- useEffect73(() => {
44336
+ useEffect75(() => {
44118
44337
  if (shown || !lastShown) return;
44119
44338
  const timer = setTimeout(() => setLastShown(null), CLOSE_LINGER_MS);
44120
44339
  return () => clearTimeout(timer);
@@ -44139,14 +44358,14 @@ function NavigationSheet({
44139
44358
  onClose: close
44140
44359
  });
44141
44360
  useEscapeDismissal(open, close);
44142
- useEffect73(() => {
44361
+ useEffect75(() => {
44143
44362
  const scrim = scrimRef.current;
44144
44363
  if (!scrim) return;
44145
44364
  const stop = (event) => event.stopPropagation();
44146
44365
  scrim.addEventListener("pointerdown", stop);
44147
44366
  return () => scrim.removeEventListener("pointerdown", stop);
44148
44367
  }, []);
44149
- useEffect73(() => {
44368
+ useEffect75(() => {
44150
44369
  const sheet = sheetRef.current;
44151
44370
  const surface = sheet?.parentElement;
44152
44371
  if (!open || !sheet || !surface) return;
@@ -44159,7 +44378,7 @@ function NavigationSheet({
44159
44378
  for (const sibling of siblings) sibling.inert = false;
44160
44379
  };
44161
44380
  }, [open]);
44162
- return /* @__PURE__ */ jsxs75(
44381
+ return /* @__PURE__ */ jsxs76(
44163
44382
  "div",
44164
44383
  {
44165
44384
  ref: sheetRef,
@@ -44167,8 +44386,8 @@ function NavigationSheet({
44167
44386
  "data-state": open ? "open" : dragPanel ? "dragging" : "closed",
44168
44387
  "data-testid": "navigation-sheet",
44169
44388
  children: [
44170
- /* @__PURE__ */ jsx94("div", { ref: scrimRef, className: "squisq-navigation-sheet-scrim", onClick: close }),
44171
- /* @__PURE__ */ jsx94(
44389
+ /* @__PURE__ */ jsx96("div", { ref: scrimRef, className: "squisq-navigation-sheet-scrim", onClick: close }),
44390
+ /* @__PURE__ */ jsx96(
44172
44391
  "div",
44173
44392
  {
44174
44393
  ref: panelRef,
@@ -44176,9 +44395,9 @@ function NavigationSheet({
44176
44395
  role: "dialog",
44177
44396
  "aria-label": content ? PANEL_LABELS[content] : "Document navigation",
44178
44397
  tabIndex: -1,
44179
- children: content && /* @__PURE__ */ jsxs75(Fragment31, { children: [
44180
- /* @__PURE__ */ jsxs75("div", { className: "squisq-navigation-sheet-header", children: [
44181
- /* @__PURE__ */ jsx94("div", { className: "squisq-navigation-sheet-tabs", role: "tablist", children: PANELS.map((option) => /* @__PURE__ */ jsx94(
44398
+ children: content && /* @__PURE__ */ jsxs76(Fragment32, { children: [
44399
+ /* @__PURE__ */ jsxs76("div", { className: "squisq-navigation-sheet-header", children: [
44400
+ /* @__PURE__ */ jsx96("div", { className: "squisq-navigation-sheet-tabs", role: "tablist", children: PANELS.map((option) => /* @__PURE__ */ jsx96(
44182
44401
  "button",
44183
44402
  {
44184
44403
  type: "button",
@@ -44192,25 +44411,25 @@ function NavigationSheet({
44192
44411
  },
44193
44412
  option
44194
44413
  )) }),
44195
- /* @__PURE__ */ jsx94(
44414
+ /* @__PURE__ */ jsx96(
44196
44415
  "button",
44197
44416
  {
44198
44417
  type: "button",
44199
44418
  className: "squisq-navigation-sheet-close",
44200
44419
  "aria-label": "Close",
44201
44420
  onClick: close,
44202
- children: /* @__PURE__ */ jsx94(Icon, { icon: "xmark" })
44421
+ children: /* @__PURE__ */ jsx96(Icon, { icon: "xmark" })
44203
44422
  }
44204
44423
  )
44205
44424
  ] }),
44206
- /* @__PURE__ */ jsx94(
44425
+ /* @__PURE__ */ jsx96(
44207
44426
  "div",
44208
44427
  {
44209
44428
  id: `${tabIdPrefix}-body`,
44210
44429
  className: "squisq-navigation-sheet-body",
44211
44430
  role: "tabpanel",
44212
44431
  "aria-labelledby": `${tabIdPrefix}-${content}`,
44213
- children: content === "outline" ? /* @__PURE__ */ jsx94(OutlinePanel, { presentation: "sheet", readOnly, onNavigate: close }) : /* @__PURE__ */ jsx94(
44432
+ children: content === "outline" ? /* @__PURE__ */ jsx96(OutlinePanel, { presentation: "sheet", readOnly, onNavigate: close }) : /* @__PURE__ */ jsx96(
44214
44433
  BlockPreviewList,
44215
44434
  {
44216
44435
  basePath,
@@ -44229,7 +44448,7 @@ function NavigationSheet({
44229
44448
  }
44230
44449
 
44231
44450
  // src/proofing/ProofingPanel.tsx
44232
- import { jsx as jsx95, jsxs as jsxs76 } from "react/jsx-runtime";
44451
+ import { jsx as jsx97, jsxs as jsxs77 } from "react/jsx-runtime";
44233
44452
  var CATEGORY_LABELS = {
44234
44453
  spelling: "Spelling",
44235
44454
  grammar: "Grammar",
@@ -44239,14 +44458,14 @@ function ProofingPanel() {
44239
44458
  const state = useProofingState();
44240
44459
  if (!state || !state.panelVisible || !state.enabled) return null;
44241
44460
  const { findings, activeFindingId } = state;
44242
- return /* @__PURE__ */ jsxs76("aside", { className: "squisq-proof-panel", "aria-label": "Proofing findings", children: [
44243
- /* @__PURE__ */ jsxs76("div", { className: "squisq-proof-panel-header", children: [
44244
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-title", children: [
44461
+ return /* @__PURE__ */ jsxs77("aside", { className: "squisq-proof-panel", "aria-label": "Proofing findings", children: [
44462
+ /* @__PURE__ */ jsxs77("div", { className: "squisq-proof-panel-header", children: [
44463
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-title", children: [
44245
44464
  "Proofing",
44246
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-count", children: findings.length })
44465
+ /* @__PURE__ */ jsx97("span", { className: "squisq-proof-panel-count", children: findings.length })
44247
44466
  ] }),
44248
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-actions", children: [
44249
- /* @__PURE__ */ jsx95(
44467
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-actions", children: [
44468
+ /* @__PURE__ */ jsx97(
44250
44469
  "button",
44251
44470
  {
44252
44471
  type: "button",
@@ -44258,7 +44477,7 @@ function ProofingPanel() {
44258
44477
  children: "\u2191"
44259
44478
  }
44260
44479
  ),
44261
- /* @__PURE__ */ jsx95(
44480
+ /* @__PURE__ */ jsx97(
44262
44481
  "button",
44263
44482
  {
44264
44483
  type: "button",
@@ -44270,7 +44489,7 @@ function ProofingPanel() {
44270
44489
  children: "\u2193"
44271
44490
  }
44272
44491
  ),
44273
- /* @__PURE__ */ jsx95(
44492
+ /* @__PURE__ */ jsx97(
44274
44493
  "button",
44275
44494
  {
44276
44495
  type: "button",
@@ -44283,20 +44502,20 @@ function ProofingPanel() {
44283
44502
  )
44284
44503
  ] })
44285
44504
  ] }),
44286
- state.status === "loading" && /* @__PURE__ */ jsx95("div", { className: "squisq-proof-panel-empty", children: "Loading proofing engine\u2026" }),
44287
- state.status === "error" && /* @__PURE__ */ jsxs76("div", { className: "squisq-proof-panel-empty", children: [
44505
+ state.status === "loading" && /* @__PURE__ */ jsx97("div", { className: "squisq-proof-panel-empty", children: "Loading proofing engine\u2026" }),
44506
+ state.status === "error" && /* @__PURE__ */ jsxs77("div", { className: "squisq-proof-panel-empty", children: [
44288
44507
  "Proofing failed to load.",
44289
- /* @__PURE__ */ jsx95("button", { type: "button", className: "squisq-proof-panel-retry", onClick: state.retrySetup, children: "Retry" })
44508
+ /* @__PURE__ */ jsx97("button", { type: "button", className: "squisq-proof-panel-retry", onClick: state.retrySetup, children: "Retry" })
44290
44509
  ] }),
44291
- state.status === "ready" && findings.length === 0 && /* @__PURE__ */ jsx95("div", { className: "squisq-proof-panel-empty", children: "No issues found." }),
44292
- /* @__PURE__ */ jsx95("ul", { className: "squisq-proof-panel-list", children: findings.map((finding) => /* @__PURE__ */ jsx95("li", { children: /* @__PURE__ */ jsxs76(
44510
+ state.status === "ready" && findings.length === 0 && /* @__PURE__ */ jsx97("div", { className: "squisq-proof-panel-empty", children: "No issues found." }),
44511
+ /* @__PURE__ */ jsx97("ul", { className: "squisq-proof-panel-list", children: findings.map((finding) => /* @__PURE__ */ jsx97("li", { children: /* @__PURE__ */ jsxs77(
44293
44512
  "button",
44294
44513
  {
44295
44514
  type: "button",
44296
44515
  className: finding.id === activeFindingId ? "squisq-proof-panel-row squisq-proof-panel-row--active" : "squisq-proof-panel-row",
44297
44516
  onClick: () => state.selectFinding(finding.id),
44298
44517
  children: [
44299
- /* @__PURE__ */ jsx95(
44518
+ /* @__PURE__ */ jsx97(
44300
44519
  "span",
44301
44520
  {
44302
44521
  className: `squisq-proof-dot squisq-proof-dot--${finding.category}`,
@@ -44304,9 +44523,9 @@ function ProofingPanel() {
44304
44523
  "aria-hidden": true
44305
44524
  }
44306
44525
  ),
44307
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-row-body", children: [
44308
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-excerpt", children: finding.originalText }),
44309
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-message", children: proofMessageText(finding) })
44526
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-row-body", children: [
44527
+ /* @__PURE__ */ jsx97("span", { className: "squisq-proof-panel-excerpt", children: finding.originalText }),
44528
+ /* @__PURE__ */ jsx97("span", { className: "squisq-proof-panel-message", children: proofMessageText(finding) })
44310
44529
  ] })
44311
44530
  ]
44312
44531
  }
@@ -44315,13 +44534,13 @@ function ProofingPanel() {
44315
44534
  }
44316
44535
 
44317
44536
  // src/imageEditor/ImageEditModal.tsx
44318
- import { useCallback as useCallback58, useEffect as useEffect74, useMemo as useMemo59, useRef as useRef69, useState as useState85 } from "react";
44537
+ import { useCallback as useCallback58, useEffect as useEffect76, useMemo as useMemo59, useRef as useRef70, useState as useState86 } from "react";
44319
44538
  import { DARK_SURFACE, LIGHT_SURFACE } from "@bendyline/squisq/schemas";
44320
44539
  import {
44321
44540
  MemoryContentContainer,
44322
44541
  scopeContainer
44323
44542
  } from "@bendyline/squisq/storage";
44324
- import { jsx as jsx96, jsxs as jsxs77 } from "react/jsx-runtime";
44543
+ import { jsx as jsx98, jsxs as jsxs78 } from "react/jsx-runtime";
44325
44544
  function ImageEditModal({
44326
44545
  relativePath,
44327
44546
  container,
@@ -44332,8 +44551,8 @@ function ImageEditModal({
44332
44551
  versioningAutoSaveIdleMs,
44333
44552
  shellTheme
44334
44553
  }) {
44335
- const modalRef = useRef69(null);
44336
- const surfaceRef = useRef69(null);
44554
+ const modalRef = useRef70(null);
44555
+ const surfaceRef = useRef70(null);
44337
44556
  useModalDialog({ rootRef: modalRef, dialogRef: surfaceRef, onClose });
44338
44557
  const extension = relativePath.split(/[?#]/, 1)[0]?.split(".").pop()?.toLowerCase();
44339
44558
  const saveFormat = extension === "png" ? "png" : extension === "jpg" || extension === "jpeg" ? "jpeg" : extension === "webp" ? "webp" : null;
@@ -44348,9 +44567,9 @@ function ImageEditModal({
44348
44567
  const parent = container ?? new MemoryContentContainer();
44349
44568
  return scopeContainer(parent, `.imageEdits/${scopedName}`);
44350
44569
  }, [container, relativePath]);
44351
- const [initialSrc, setInitialSrc] = useState85(null);
44352
- const [resolveError, setResolveError] = useState85(null);
44353
- useEffect74(() => {
44570
+ const [initialSrc, setInitialSrc] = useState86(null);
44571
+ const [resolveError, setResolveError] = useState86(null);
44572
+ useEffect76(() => {
44354
44573
  let cancelled = false;
44355
44574
  setInitialSrc(null);
44356
44575
  setResolveError(null);
@@ -44380,7 +44599,7 @@ function ImageEditModal({
44380
44599
  },
44381
44600
  [mediaProvider, relativePath, onSaved]
44382
44601
  );
44383
- return /* @__PURE__ */ jsx96(
44602
+ return /* @__PURE__ */ jsx98(
44384
44603
  "div",
44385
44604
  {
44386
44605
  ref: modalRef,
@@ -44392,11 +44611,11 @@ function ImageEditModal({
44392
44611
  onClick: (e2) => {
44393
44612
  if (e2.target === e2.currentTarget) onClose();
44394
44613
  },
44395
- children: /* @__PURE__ */ jsxs77("div", { ref: surfaceRef, className: "squisq-image-edit-modal__surface", children: [
44396
- /* @__PURE__ */ jsxs77("header", { className: "squisq-image-edit-modal__header", children: [
44397
- /* @__PURE__ */ jsx96("span", { className: "squisq-image-edit-modal__title", children: "Edit image" }),
44398
- /* @__PURE__ */ jsx96("span", { className: "squisq-image-edit-modal__path", children: relativePath }),
44399
- /* @__PURE__ */ jsx96(
44614
+ children: /* @__PURE__ */ jsxs78("div", { ref: surfaceRef, className: "squisq-image-edit-modal__surface", children: [
44615
+ /* @__PURE__ */ jsxs78("header", { className: "squisq-image-edit-modal__header", children: [
44616
+ /* @__PURE__ */ jsx98("span", { className: "squisq-image-edit-modal__title", children: "Edit image" }),
44617
+ /* @__PURE__ */ jsx98("span", { className: "squisq-image-edit-modal__path", children: relativePath }),
44618
+ /* @__PURE__ */ jsx98(
44400
44619
  "button",
44401
44620
  {
44402
44621
  type: "button",
@@ -44408,10 +44627,10 @@ function ImageEditModal({
44408
44627
  }
44409
44628
  )
44410
44629
  ] }),
44411
- /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__body", children: resolveError ? /* @__PURE__ */ jsxs77("div", { className: "squisq-image-edit-modal__error", children: [
44630
+ /* @__PURE__ */ jsx98("div", { className: "squisq-image-edit-modal__body", children: resolveError ? /* @__PURE__ */ jsxs78("div", { className: "squisq-image-edit-modal__error", children: [
44412
44631
  "Failed to load image: ",
44413
44632
  resolveError
44414
- ] }) : !saveFormat ? /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__error", children: "Editing supports PNG, JPEG, and WebP images without changing the asset type." }) : !initialSrc ? /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsx96(
44633
+ ] }) : !saveFormat ? /* @__PURE__ */ jsx98("div", { className: "squisq-image-edit-modal__error", children: "Editing supports PNG, JPEG, and WebP images without changing the asset type." }) : !initialSrc ? /* @__PURE__ */ jsx98("div", { className: "squisq-image-edit-modal__loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsx98(
44415
44634
  ImageEditor,
44416
44635
  {
44417
44636
  filesContainer: sidecar,
@@ -44472,18 +44691,18 @@ function MediaEditContextMenuItems() {
44472
44691
  // src/mediaEdit/MediaEditModal.tsx
44473
44692
  import {
44474
44693
  useCallback as useCallback62,
44475
- useEffect as useEffect77,
44476
- useId as useId17,
44694
+ useEffect as useEffect79,
44695
+ useId as useId18,
44477
44696
  useMemo as useMemo61,
44478
- useRef as useRef73,
44479
- useState as useState89
44697
+ useRef as useRef74,
44698
+ useState as useState90
44480
44699
  } from "react";
44481
44700
  import {
44482
44701
  useMediaEditStatus as useMediaEditStatus2
44483
44702
  } from "@bendyline/squisq-video-react/media-edit";
44484
44703
 
44485
44704
  // src/mediaEdit/MediaEditAudioSection.tsx
44486
- import { useCallback as useCallback59, useEffect as useEffect75, useRef as useRef70, useState as useState86 } from "react";
44705
+ import { useCallback as useCallback59, useEffect as useEffect77, useRef as useRef71, useState as useState87 } from "react";
44487
44706
  import { MEDIA_FX_SPECS as MEDIA_FX_SPECS2, serializeMediaFx } from "@bendyline/squisq/mediaEdit";
44488
44707
 
44489
44708
  // src/mediaEdit/mediaEditDraft.ts
@@ -44582,7 +44801,7 @@ function centeredCrop(ratio, frameWidth, frameHeight) {
44582
44801
  }
44583
44802
 
44584
44803
  // src/mediaEdit/MediaEditAudioSection.tsx
44585
- import { Fragment as Fragment32, jsx as jsx97, jsxs as jsxs78 } from "react/jsx-runtime";
44804
+ import { Fragment as Fragment33, jsx as jsx99, jsxs as jsxs79 } from "react/jsx-runtime";
44586
44805
  var STAGES = [
44587
44806
  {
44588
44807
  id: "highpass",
@@ -44636,8 +44855,8 @@ var LOUDNESS_PRESETS = [
44636
44855
  ];
44637
44856
  var PREVIEW_SECONDS = 10;
44638
44857
  function useMediaDuration(url) {
44639
- const [duration, setDuration] = useState86(null);
44640
- useEffect75(() => {
44858
+ const [duration, setDuration] = useState87(null);
44859
+ useEffect77(() => {
44641
44860
  setDuration(null);
44642
44861
  if (!url || typeof Audio === "undefined") return;
44643
44862
  const probe = new Audio();
@@ -44654,12 +44873,12 @@ function useMediaDuration(url) {
44654
44873
  return duration;
44655
44874
  }
44656
44875
  function usePreviewPlayer(preview) {
44657
- const ctxRef = useRef70(null);
44658
- const sourceRef = useRef70(null);
44659
- const startedRef = useRef70(null);
44660
- const [playing, setPlaying] = useState86(null);
44661
- const cueRef = useRef70(0);
44662
- const [position, setPosition] = useState86(0);
44876
+ const ctxRef = useRef71(null);
44877
+ const sourceRef = useRef71(null);
44878
+ const startedRef = useRef71(null);
44879
+ const [playing, setPlaying] = useState87(null);
44880
+ const cueRef = useRef71(0);
44881
+ const [position, setPosition] = useState87(0);
44663
44882
  const frames = preview?.original[0]?.length ?? 0;
44664
44883
  const duration = preview && frames > 0 ? frames / preview.sampleRate : 0;
44665
44884
  const currentOffset = useCallback59(() => {
@@ -44677,8 +44896,8 @@ function usePreviewPlayer(preview) {
44677
44896
  setPosition(0);
44678
44897
  setPlaying(null);
44679
44898
  }, []);
44680
- useEffect75(() => stop, [preview, stop]);
44681
- useEffect75(
44899
+ useEffect77(() => stop, [preview, stop]);
44900
+ useEffect77(
44682
44901
  () => () => {
44683
44902
  void ctxRef.current?.close();
44684
44903
  ctxRef.current = null;
@@ -44717,7 +44936,7 @@ function usePreviewPlayer(preview) {
44717
44936
  },
44718
44937
  [duration, playing, play]
44719
44938
  );
44720
- useEffect75(() => {
44939
+ useEffect77(() => {
44721
44940
  if (!playing) return;
44722
44941
  let frame = requestAnimationFrame(function tick() {
44723
44942
  setPosition(currentOffset());
@@ -44728,26 +44947,26 @@ function usePreviewPlayer(preview) {
44728
44947
  return { playing, play, stop, seek, position, duration };
44729
44948
  }
44730
44949
  function PlayIcon() {
44731
- return /* @__PURE__ */ jsx97(
44950
+ return /* @__PURE__ */ jsx99(
44732
44951
  "svg",
44733
44952
  {
44734
44953
  className: "squisq-media-edit-icon",
44735
44954
  viewBox: "0 0 10 10",
44736
44955
  "aria-hidden": "true",
44737
44956
  focusable: "false",
44738
- children: /* @__PURE__ */ jsx97("path", { d: "M2 1 9 5 2 9Z" })
44957
+ children: /* @__PURE__ */ jsx99("path", { d: "M2 1 9 5 2 9Z" })
44739
44958
  }
44740
44959
  );
44741
44960
  }
44742
44961
  function StopIcon() {
44743
- return /* @__PURE__ */ jsx97(
44962
+ return /* @__PURE__ */ jsx99(
44744
44963
  "svg",
44745
44964
  {
44746
44965
  className: "squisq-media-edit-icon",
44747
44966
  viewBox: "0 0 10 10",
44748
44967
  "aria-hidden": "true",
44749
44968
  focusable: "false",
44750
- children: /* @__PURE__ */ jsx97("rect", { x: "1.5", y: "1.5", width: "7", height: "7", rx: "1" })
44969
+ children: /* @__PURE__ */ jsx99("rect", { x: "1.5", y: "1.5", width: "7", height: "7", rx: "1" })
44751
44970
  }
44752
44971
  );
44753
44972
  }
@@ -44765,14 +44984,14 @@ function MediaEditAudioSection({
44765
44984
  const duration = useMediaDuration(resolvedSrc);
44766
44985
  const windowMin = item.clipStart ?? 0;
44767
44986
  const windowMax = Math.max(windowMin, (item.clipEnd ?? duration ?? windowMin) - 1);
44768
- const [previewFrom, setPreviewFrom] = useState86(windowMin);
44769
- const [preview, setPreview] = useState86(null);
44770
- const [previewedFx, setPreviewedFx] = useState86(null);
44771
- const [previewing, setPreviewing] = useState86(false);
44772
- const [previewError, setPreviewError] = useState86(null);
44773
- const previewAbort = useRef70(null);
44987
+ const [previewFrom, setPreviewFrom] = useState87(windowMin);
44988
+ const [preview, setPreview] = useState87(null);
44989
+ const [previewedFx, setPreviewedFx] = useState87(null);
44990
+ const [previewing, setPreviewing] = useState87(false);
44991
+ const [previewError, setPreviewError] = useState87(null);
44992
+ const previewAbort = useRef71(null);
44774
44993
  const player = usePreviewPlayer(preview);
44775
- useEffect75(() => () => previewAbort.current?.abort(), []);
44994
+ useEffect77(() => () => previewAbort.current?.abort(), []);
44776
44995
  const runPreview = useCallback59(async () => {
44777
44996
  if (draftFx.ops.length === 0) return;
44778
44997
  previewAbort.current?.abort();
@@ -44797,23 +45016,23 @@ function MediaEditAudioSection({
44797
45016
  setPreviewing(false);
44798
45017
  }
44799
45018
  }, [draftFx.ops.length, manager, item.src, knownFx, previewFrom]);
44800
- return /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-section", children: [
44801
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-presets", role: "group", "aria-label": "Presets", children: [
44802
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("voice") }), children: "Clean up voice" }),
44803
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("levels") }), children: "Levels only" }),
44804
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("none") }), children: "None" })
45019
+ return /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-section", children: [
45020
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-presets", role: "group", "aria-label": "Presets", children: [
45021
+ /* @__PURE__ */ jsx99("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("voice") }), children: "Clean up voice" }),
45022
+ /* @__PURE__ */ jsx99("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("levels") }), children: "Levels only" }),
45023
+ /* @__PURE__ */ jsx99("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("none") }), children: "None" })
44805
45024
  ] }),
44806
- /* @__PURE__ */ jsx97("ul", { className: "squisq-media-edit-stages", children: STAGES.map((stage) => {
45025
+ /* @__PURE__ */ jsx99("ul", { className: "squisq-media-edit-stages", children: STAGES.map((stage) => {
44807
45026
  const s = draft.fx[stage.id];
44808
45027
  const inputId = `${idPrefix}-${stage.id}`;
44809
- return /* @__PURE__ */ jsxs78(
45028
+ return /* @__PURE__ */ jsxs79(
44810
45029
  "li",
44811
45030
  {
44812
45031
  className: "squisq-media-edit-stage",
44813
45032
  "data-enabled": s.enabled ? "true" : "false",
44814
45033
  children: [
44815
- /* @__PURE__ */ jsxs78("label", { className: "squisq-media-edit-stage__toggle", children: [
44816
- /* @__PURE__ */ jsx97(
45034
+ /* @__PURE__ */ jsxs79("label", { className: "squisq-media-edit-stage__toggle", children: [
45035
+ /* @__PURE__ */ jsx99(
44817
45036
  "input",
44818
45037
  {
44819
45038
  type: "checkbox",
@@ -44821,9 +45040,9 @@ function MediaEditAudioSection({
44821
45040
  onChange: (e2) => setStage(stage.id, { enabled: e2.target.checked })
44822
45041
  }
44823
45042
  ),
44824
- /* @__PURE__ */ jsx97("span", { className: "squisq-media-edit-stage__label", children: stage.label })
45043
+ /* @__PURE__ */ jsx99("span", { className: "squisq-media-edit-stage__label", children: stage.label })
44825
45044
  ] }),
44826
- /* @__PURE__ */ jsx97(
45045
+ /* @__PURE__ */ jsx99(
44827
45046
  "input",
44828
45047
  {
44829
45048
  id: inputId,
@@ -44839,9 +45058,9 @@ function MediaEditAudioSection({
44839
45058
  onChange: (e2) => setStage(stage.id, { value: stage.toValue(Number(e2.target.value)) })
44840
45059
  }
44841
45060
  ),
44842
- /* @__PURE__ */ jsx97("output", { className: "squisq-media-edit-stage__value", htmlFor: inputId, children: stage.format(s.value) }),
44843
- /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-stage__hint", children: stage.hint }),
44844
- stage.id === "loudness" && s.enabled && /* @__PURE__ */ jsx97("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Targets", children: LOUDNESS_PRESETS.map((preset) => /* @__PURE__ */ jsxs78(
45061
+ /* @__PURE__ */ jsx99("output", { className: "squisq-media-edit-stage__value", htmlFor: inputId, children: stage.format(s.value) }),
45062
+ /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-stage__hint", children: stage.hint }),
45063
+ stage.id === "loudness" && s.enabled && /* @__PURE__ */ jsx99("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Targets", children: LOUDNESS_PRESETS.map((preset) => /* @__PURE__ */ jsxs79(
44845
45064
  "button",
44846
45065
  {
44847
45066
  type: "button",
@@ -44861,14 +45080,14 @@ function MediaEditAudioSection({
44861
45080
  stage.id
44862
45081
  );
44863
45082
  }) }),
44864
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-preview", "aria-label": "Preview", children: [
44865
- duration != null && windowMax > windowMin && /* @__PURE__ */ jsxs78("label", { className: "squisq-media-edit-preview__from", children: [
44866
- /* @__PURE__ */ jsxs78("span", { children: [
45083
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview", "aria-label": "Preview", children: [
45084
+ duration != null && windowMax > windowMin && /* @__PURE__ */ jsxs79("label", { className: "squisq-media-edit-preview__from", children: [
45085
+ /* @__PURE__ */ jsxs79("span", { children: [
44867
45086
  "Preview from ",
44868
45087
  previewFrom.toFixed(0),
44869
45088
  " s"
44870
45089
  ] }),
44871
- /* @__PURE__ */ jsx97(
45090
+ /* @__PURE__ */ jsx99(
44872
45091
  "input",
44873
45092
  {
44874
45093
  type: "range",
@@ -44880,7 +45099,7 @@ function MediaEditAudioSection({
44880
45099
  }
44881
45100
  )
44882
45101
  ] }),
44883
- /* @__PURE__ */ jsx97("div", { className: "squisq-media-edit-preview__actions", children: /* @__PURE__ */ jsx97(
45102
+ /* @__PURE__ */ jsx99("div", { className: "squisq-media-edit-preview__actions", children: /* @__PURE__ */ jsx99(
44884
45103
  "button",
44885
45104
  {
44886
45105
  type: "button",
@@ -44889,10 +45108,10 @@ function MediaEditAudioSection({
44889
45108
  children: previewing ? "Rendering preview\u2026" : preview ? "Update preview" : "Create preview"
44890
45109
  }
44891
45110
  ) }),
44892
- preview != null && player.duration > 0 && /* @__PURE__ */ jsxs78(Fragment32, { children: [
44893
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-playback", "data-playing": player.playing ?? void 0, children: [
44894
- /* @__PURE__ */ jsx97("span", { className: "squisq-media-edit-playback__label", children: player.playing ? `${player.playing === "original" ? "Original" : "Processed"} from ${Math.round(preview.startSec)} s` : "Stopped" }),
44895
- /* @__PURE__ */ jsx97(
45111
+ preview != null && player.duration > 0 && /* @__PURE__ */ jsxs79(Fragment33, { children: [
45112
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-playback", "data-playing": player.playing ?? void 0, children: [
45113
+ /* @__PURE__ */ jsx99("span", { className: "squisq-media-edit-playback__label", children: player.playing ? `${player.playing === "original" ? "Original" : "Processed"} from ${Math.round(preview.startSec)} s` : "Stopped" }),
45114
+ /* @__PURE__ */ jsx99(
44896
45115
  "input",
44897
45116
  {
44898
45117
  type: "range",
@@ -44906,14 +45125,14 @@ function MediaEditAudioSection({
44906
45125
  onChange: (e2) => player.seek(Number(e2.target.value))
44907
45126
  }
44908
45127
  ),
44909
- /* @__PURE__ */ jsxs78("span", { className: "squisq-media-edit-playback__time", children: [
45128
+ /* @__PURE__ */ jsxs79("span", { className: "squisq-media-edit-playback__time", children: [
44910
45129
  formatClock6(player.position),
44911
45130
  " / ",
44912
45131
  formatClock6(player.duration)
44913
45132
  ] })
44914
45133
  ] }),
44915
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-preview__actions", children: [
44916
- /* @__PURE__ */ jsxs78(
45134
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview__actions", children: [
45135
+ /* @__PURE__ */ jsxs79(
44917
45136
  "button",
44918
45137
  {
44919
45138
  type: "button",
@@ -44921,12 +45140,12 @@ function MediaEditAudioSection({
44921
45140
  disabled: previewing,
44922
45141
  onClick: () => player.play("original"),
44923
45142
  children: [
44924
- /* @__PURE__ */ jsx97(PlayIcon, {}),
45143
+ /* @__PURE__ */ jsx99(PlayIcon, {}),
44925
45144
  "Original"
44926
45145
  ]
44927
45146
  }
44928
45147
  ),
44929
- /* @__PURE__ */ jsxs78(
45148
+ /* @__PURE__ */ jsxs79(
44930
45149
  "button",
44931
45150
  {
44932
45151
  type: "button",
@@ -44934,26 +45153,26 @@ function MediaEditAudioSection({
44934
45153
  disabled: previewing,
44935
45154
  onClick: () => player.play("processed"),
44936
45155
  children: [
44937
- /* @__PURE__ */ jsx97(PlayIcon, {}),
45156
+ /* @__PURE__ */ jsx99(PlayIcon, {}),
44938
45157
  "Processed"
44939
45158
  ]
44940
45159
  }
44941
45160
  ),
44942
- /* @__PURE__ */ jsxs78("button", { type: "button", disabled: !player.playing, onClick: player.stop, children: [
44943
- /* @__PURE__ */ jsx97(StopIcon, {}),
45161
+ /* @__PURE__ */ jsxs79("button", { type: "button", disabled: !player.playing, onClick: player.stop, children: [
45162
+ /* @__PURE__ */ jsx99(StopIcon, {}),
44944
45163
  "Stop"
44945
45164
  ] })
44946
45165
  ] })
44947
45166
  ] }),
44948
- preview != null && previewedFx !== knownFx && /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-note", children: "Settings changed \u2014 update the preview to hear them." }),
44949
- previewError && /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: previewError })
45167
+ preview != null && previewedFx !== knownFx && /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note", children: "Settings changed \u2014 update the preview to hear them." }),
45168
+ previewError && /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: previewError })
44950
45169
  ] })
44951
45170
  ] });
44952
45171
  }
44953
45172
 
44954
45173
  // src/mediaEdit/MediaEditTimingSection.tsx
44955
- import { useCallback as useCallback60, useEffect as useEffect76, useRef as useRef71, useState as useState87 } from "react";
44956
- import { jsx as jsx98, jsxs as jsxs79 } from "react/jsx-runtime";
45174
+ import { useCallback as useCallback60, useEffect as useEffect78, useRef as useRef72, useState as useState88 } from "react";
45175
+ import { jsx as jsx100, jsxs as jsxs80 } from "react/jsx-runtime";
44957
45176
  var DEFAULT_MAX_PAUSE = 0.8;
44958
45177
  function formatDb(value) {
44959
45178
  if (value === 0) return "0 dB";
@@ -44966,11 +45185,11 @@ function MediaEditTimingSection({
44966
45185
  manager,
44967
45186
  idPrefix
44968
45187
  }) {
44969
- const [maxPause, setMaxPause] = useState87(DEFAULT_MAX_PAUSE);
44970
- const [finding, setFinding] = useState87(false);
44971
- const [error, setError] = useState87(null);
44972
- const abortRef = useRef71(null);
44973
- useEffect76(() => () => abortRef.current?.abort(), []);
45188
+ const [maxPause, setMaxPause] = useState88(DEFAULT_MAX_PAUSE);
45189
+ const [finding, setFinding] = useState88(false);
45190
+ const [error, setError] = useState88(null);
45191
+ const abortRef = useRef72(null);
45192
+ useEffect78(() => () => abortRef.current?.abort(), []);
44974
45193
  const findPauses = useCallback60(async () => {
44975
45194
  abortRef.current?.abort();
44976
45195
  const controller = new AbortController();
@@ -44994,10 +45213,10 @@ function MediaEditTimingSection({
44994
45213
  }
44995
45214
  }, [manager, item.src, maxPause, draft, onChange]);
44996
45215
  const saved = cutSeconds(draft.cuts);
44997
- return /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-section", children: [
44998
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
44999
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-pause`, children: "Shorten pauses longer than" }),
45000
- /* @__PURE__ */ jsx98(
45216
+ return /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-section", children: [
45217
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45218
+ /* @__PURE__ */ jsx100("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-pause`, children: "Shorten pauses longer than" }),
45219
+ /* @__PURE__ */ jsx100(
45001
45220
  "input",
45002
45221
  {
45003
45222
  id: `${idPrefix}-pause`,
@@ -45010,14 +45229,14 @@ function MediaEditTimingSection({
45010
45229
  onChange: (e2) => setMaxPause(Number(e2.target.value))
45011
45230
  }
45012
45231
  ),
45013
- /* @__PURE__ */ jsxs79("output", { htmlFor: `${idPrefix}-pause`, children: [
45232
+ /* @__PURE__ */ jsxs80("output", { htmlFor: `${idPrefix}-pause`, children: [
45014
45233
  maxPause.toFixed(1),
45015
45234
  " s"
45016
45235
  ] })
45017
45236
  ] }),
45018
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview__actions", children: [
45019
- /* @__PURE__ */ jsx98("button", { type: "button", onClick: findPauses, disabled: finding, children: finding ? "Finding pauses\u2026" : "Find pauses" }),
45020
- /* @__PURE__ */ jsx98(
45237
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-preview__actions", children: [
45238
+ /* @__PURE__ */ jsx100("button", { type: "button", onClick: findPauses, disabled: finding, children: finding ? "Finding pauses\u2026" : "Find pauses" }),
45239
+ /* @__PURE__ */ jsx100(
45021
45240
  "button",
45022
45241
  {
45023
45242
  type: "button",
@@ -45027,11 +45246,11 @@ function MediaEditTimingSection({
45027
45246
  }
45028
45247
  )
45029
45248
  ] }),
45030
- /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note", role: "status", "aria-live": "polite", children: draft.cuts.length === 0 ? "No pauses shortened." : `${draft.cuts.length} ${draft.cuts.length === 1 ? "pause" : "pauses"} shortened, saving ${formatClock6(saved)}.` }),
45031
- error && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: error }),
45032
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
45033
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-gain`, children: "Volume" }),
45034
- /* @__PURE__ */ jsx98(
45249
+ /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-note", role: "status", "aria-live": "polite", children: draft.cuts.length === 0 ? "No pauses shortened." : `${draft.cuts.length} ${draft.cuts.length === 1 ? "pause" : "pauses"} shortened, saving ${formatClock6(saved)}.` }),
45250
+ error && /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: error }),
45251
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45252
+ /* @__PURE__ */ jsx100("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-gain`, children: "Volume" }),
45253
+ /* @__PURE__ */ jsx100(
45035
45254
  "input",
45036
45255
  {
45037
45256
  id: `${idPrefix}-gain`,
@@ -45044,11 +45263,11 @@ function MediaEditTimingSection({
45044
45263
  onChange: (e2) => onChange({ ...draft, gain: Number(e2.target.value) })
45045
45264
  }
45046
45265
  ),
45047
- /* @__PURE__ */ jsx98("output", { htmlFor: `${idPrefix}-gain`, children: formatDb(draft.gain) })
45266
+ /* @__PURE__ */ jsx100("output", { htmlFor: `${idPrefix}-gain`, children: formatDb(draft.gain) })
45048
45267
  ] }),
45049
- ["fadeIn", "fadeOut"].map((key) => /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
45050
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-${key}`, children: key === "fadeIn" ? "Fade in" : "Fade out" }),
45051
- /* @__PURE__ */ jsx98(
45268
+ ["fadeIn", "fadeOut"].map((key) => /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45269
+ /* @__PURE__ */ jsx100("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-${key}`, children: key === "fadeIn" ? "Fade in" : "Fade out" }),
45270
+ /* @__PURE__ */ jsx100(
45052
45271
  "input",
45053
45272
  {
45054
45273
  id: `${idPrefix}-${key}`,
@@ -45061,7 +45280,7 @@ function MediaEditTimingSection({
45061
45280
  onChange: (e2) => onChange({ ...draft, [key]: Number(e2.target.value) })
45062
45281
  }
45063
45282
  ),
45064
- /* @__PURE__ */ jsx98("output", { htmlFor: `${idPrefix}-${key}`, children: draft[key] === 0 ? "Off" : `${draft[key].toFixed(1)} s` })
45283
+ /* @__PURE__ */ jsx100("output", { htmlFor: `${idPrefix}-${key}`, children: draft[key] === 0 ? "Off" : `${draft[key].toFixed(1)} s` })
45065
45284
  ] }, key))
45066
45285
  ] });
45067
45286
  }
@@ -45069,11 +45288,11 @@ function MediaEditTimingSection({
45069
45288
  // src/mediaEdit/MediaEditFrameSection.tsx
45070
45289
  import {
45071
45290
  useCallback as useCallback61,
45072
- useRef as useRef72,
45073
- useState as useState88
45291
+ useRef as useRef73,
45292
+ useState as useState89
45074
45293
  } from "react";
45075
45294
  import { normalizeMediaCrop } from "@bendyline/squisq/mediaEdit";
45076
- import { jsx as jsx99, jsxs as jsxs80 } from "react/jsx-runtime";
45295
+ import { jsx as jsx101, jsxs as jsxs81 } from "react/jsx-runtime";
45077
45296
  var FULL = { x: 0, y: 0, w: 1, h: 1 };
45078
45297
  var MIN_EDGE = 0.05;
45079
45298
  var NUDGE = 0.01;
@@ -45096,9 +45315,9 @@ function clampCrop(crop) {
45096
45315
  }
45097
45316
  function MediaEditFrameSection({ item, draft, onChange }) {
45098
45317
  const src = useResolvedMediaSrc(item.src);
45099
- const [frame, setFrame] = useState88(null);
45100
- const [aspect, setAspect] = useState88(null);
45101
- const stageRef = useRef72(null);
45318
+ const [frame, setFrame] = useState89(null);
45319
+ const [aspect, setAspect] = useState89(null);
45320
+ const stageRef = useRef73(null);
45102
45321
  const crop = draft.crop ?? FULL;
45103
45322
  const setCrop = useCallback61(
45104
45323
  (next) => onChange({ ...draft, crop: normalizeMediaCrop(clampCrop(next)) }),
@@ -45153,9 +45372,9 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45153
45372
  );
45154
45373
  };
45155
45374
  const pct = (n) => `${(n * 100).toFixed(2)}%`;
45156
- return /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-section", children: [
45157
- /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Crop aspect", children: [
45158
- ASPECTS.map((option) => /* @__PURE__ */ jsx99(
45375
+ return /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-section", children: [
45376
+ /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Crop aspect", children: [
45377
+ ASPECTS.map((option) => /* @__PURE__ */ jsx101(
45159
45378
  "button",
45160
45379
  {
45161
45380
  type: "button",
@@ -45170,7 +45389,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45170
45389
  },
45171
45390
  option.label
45172
45391
  )),
45173
- /* @__PURE__ */ jsx99(
45392
+ /* @__PURE__ */ jsx101(
45174
45393
  "button",
45175
45394
  {
45176
45395
  type: "button",
@@ -45183,14 +45402,14 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45183
45402
  }
45184
45403
  )
45185
45404
  ] }),
45186
- /* @__PURE__ */ jsxs80(
45405
+ /* @__PURE__ */ jsxs81(
45187
45406
  "div",
45188
45407
  {
45189
45408
  ref: stageRef,
45190
45409
  className: "squisq-media-edit-crop",
45191
45410
  style: frame ? { aspectRatio: `${frame.w} / ${frame.h}` } : void 0,
45192
45411
  children: [
45193
- src && /* @__PURE__ */ jsx99(
45412
+ src && /* @__PURE__ */ jsx101(
45194
45413
  "video",
45195
45414
  {
45196
45415
  src,
@@ -45206,7 +45425,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45206
45425
  }
45207
45426
  }
45208
45427
  ),
45209
- /* @__PURE__ */ jsx99(
45428
+ /* @__PURE__ */ jsx101(
45210
45429
  "div",
45211
45430
  {
45212
45431
  className: "squisq-media-edit-crop__rect",
@@ -45217,7 +45436,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45217
45436
  style: { left: pct(crop.x), top: pct(crop.y), width: pct(crop.w), height: pct(crop.h) },
45218
45437
  onPointerDown: startDrag("move"),
45219
45438
  onKeyDown,
45220
- children: ["nw", "ne", "sw", "se"].map((handle) => /* @__PURE__ */ jsx99(
45439
+ children: ["nw", "ne", "sw", "se"].map((handle) => /* @__PURE__ */ jsx101(
45221
45440
  "span",
45222
45441
  {
45223
45442
  className: `squisq-media-edit-crop__handle squisq-media-edit-crop__handle--${handle}`,
@@ -45230,12 +45449,12 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45230
45449
  ]
45231
45450
  }
45232
45451
  ),
45233
- /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note", children: draft.crop ? "Only the framed area is shown and exported." : "Drag the corners or pick an aspect to crop." })
45452
+ /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-note", children: draft.crop ? "Only the framed area is shown and exported." : "Drag the corners or pick an aspect to crop." })
45234
45453
  ] });
45235
45454
  }
45236
45455
 
45237
45456
  // src/mediaEdit/MediaEditModal.tsx
45238
- import { Fragment as Fragment33, jsx as jsx100, jsxs as jsxs81 } from "react/jsx-runtime";
45457
+ import { Fragment as Fragment34, jsx as jsx102, jsxs as jsxs82 } from "react/jsx-runtime";
45239
45458
  var TABS = [
45240
45459
  { id: "audio", label: "Audio cleanup" },
45241
45460
  { id: "timing", label: "Timing" },
@@ -45257,7 +45476,7 @@ function useRenderStatus(item, manager) {
45257
45476
  }
45258
45477
  var percent = (status) => `${Math.round((status.progress ?? 0) * 100)}%`;
45259
45478
  function RenderStatusBadge({ status }) {
45260
- return /* @__PURE__ */ jsxs81("span", { className: "squisq-media-edit-badge", "data-state": status.state, children: [
45479
+ return /* @__PURE__ */ jsxs82("span", { className: "squisq-media-edit-badge", "data-state": status.state, children: [
45261
45480
  status.state === "ready" && "Processed",
45262
45481
  status.state === "queued" && "Queued",
45263
45482
  status.state === "rendering" && `Processing ${percent(status)}`,
@@ -45270,43 +45489,43 @@ function RenderStatusText({
45270
45489
  }) {
45271
45490
  switch (status.state) {
45272
45491
  case "ready":
45273
- return /* @__PURE__ */ jsx100(Fragment33, { children: "Processed audio is in use." });
45492
+ return /* @__PURE__ */ jsx102(Fragment34, { children: "Processed audio is in use." });
45274
45493
  case "queued":
45275
- return /* @__PURE__ */ jsx100(Fragment33, { children: "Waiting to process\u2026" });
45494
+ return /* @__PURE__ */ jsx102(Fragment34, { children: "Waiting to process\u2026" });
45276
45495
  case "rendering":
45277
- return /* @__PURE__ */ jsxs81(Fragment33, { children: [
45496
+ return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45278
45497
  "Processing\u2026 ",
45279
45498
  percent(status)
45280
45499
  ] });
45281
45500
  case "failed":
45282
- return /* @__PURE__ */ jsxs81(Fragment33, { children: [
45501
+ return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45283
45502
  "Processing failed: ",
45284
45503
  status.error,
45285
45504
  " ",
45286
- /* @__PURE__ */ jsx100("button", { type: "button", onClick: onRetry, children: "Retry" })
45505
+ /* @__PURE__ */ jsx102("button", { type: "button", onClick: onRetry, children: "Retry" })
45287
45506
  ] });
45288
45507
  }
45289
45508
  }
45290
45509
  function MediaEditModal({ target, onClose }) {
45291
45510
  const { doc, markdownSource, setMarkdownSource, mediaEditRenders } = useEditorContext();
45292
- const modalRef = useRef73(null);
45293
- const surfaceRef = useRef73(null);
45294
- const titleId = useId17();
45511
+ const modalRef = useRef74(null);
45512
+ const surfaceRef = useRef74(null);
45513
+ const titleId = useId18();
45295
45514
  useModalDialog({ rootRef: modalRef, dialogRef: surfaceRef, onClose });
45296
45515
  const item = useMemo61(() => doc ? findEditableMedia(doc, target) : null, [doc, target]);
45297
45516
  const companions = useMemo61(() => doc && item ? groupCompanions(doc, item) : [], [doc, item]);
45298
45517
  const renderStatus = useRenderStatus(item, mediaEditRenders);
45299
- const [draft, setDraft] = useState89(() => draftFromEdits(item?.edits));
45518
+ const [draft, setDraft] = useState90(() => draftFromEdits(item?.edits));
45300
45519
  const seedKey = item ? `${item.sourceLine}|${editsSignature(item.edits)}` : null;
45301
- const seededRef = useRef73(null);
45302
- useEffect77(() => {
45520
+ const seededRef = useRef74(null);
45521
+ useEffect79(() => {
45303
45522
  if (seedKey === null || seededRef.current === seedKey) return;
45304
45523
  seededRef.current = seedKey;
45305
45524
  setDraft(draftFromEdits(item?.edits));
45306
45525
  }, [seedKey]);
45307
45526
  const tabs = TABS.filter((t) => t.id !== "frame" || item?.kind === "video");
45308
- const [activeTab, setActiveTab] = useState89("audio");
45309
- const tabRefs = useRef73(/* @__PURE__ */ new Map());
45527
+ const [activeTab, setActiveTab] = useState90("audio");
45528
+ const tabRefs = useRef74(/* @__PURE__ */ new Map());
45310
45529
  const onTabKeyDown = (event, index2) => {
45311
45530
  const next = event.key === "ArrowRight" ? (index2 + 1) % tabs.length : event.key === "ArrowLeft" ? (index2 - 1 + tabs.length) % tabs.length : event.key === "Home" ? 0 : event.key === "End" ? tabs.length - 1 : null;
45312
45531
  if (next == null) return;
@@ -45334,7 +45553,7 @@ function MediaEditModal({ target, onClose }) {
45334
45553
  const tabbed = item != null && mediaEditRenders != null;
45335
45554
  const tabId = (tab) => `${titleId}-tab-${tab}`;
45336
45555
  const panelId = (tab) => `${titleId}-panel-${tab}`;
45337
- return /* @__PURE__ */ jsx100(
45556
+ return /* @__PURE__ */ jsx102(
45338
45557
  "div",
45339
45558
  {
45340
45559
  ref: modalRef,
@@ -45343,7 +45562,7 @@ function MediaEditModal({ target, onClose }) {
45343
45562
  onClick: (e2) => {
45344
45563
  if (e2.target === e2.currentTarget) onClose();
45345
45564
  },
45346
- children: /* @__PURE__ */ jsxs81(
45565
+ children: /* @__PURE__ */ jsxs82(
45347
45566
  "div",
45348
45567
  {
45349
45568
  ref: surfaceRef,
@@ -45352,11 +45571,11 @@ function MediaEditModal({ target, onClose }) {
45352
45571
  "aria-modal": "true",
45353
45572
  "aria-labelledby": titleId,
45354
45573
  children: [
45355
- /* @__PURE__ */ jsxs81("header", { className: "squisq-media-edit-modal__header", children: [
45356
- /* @__PURE__ */ jsx100("span", { id: titleId, className: "squisq-media-edit-modal__title", children: title }),
45357
- /* @__PURE__ */ jsx100("span", { className: "squisq-media-edit-modal__path", children: target.src }),
45358
- renderStatus && /* @__PURE__ */ jsx100(RenderStatusBadge, { status: renderStatus }),
45359
- /* @__PURE__ */ jsx100(
45574
+ /* @__PURE__ */ jsxs82("header", { className: "squisq-media-edit-modal__header", children: [
45575
+ /* @__PURE__ */ jsx102("span", { id: titleId, className: "squisq-media-edit-modal__title", children: title }),
45576
+ /* @__PURE__ */ jsx102("span", { className: "squisq-media-edit-modal__path", children: target.src }),
45577
+ renderStatus && /* @__PURE__ */ jsx102(RenderStatusBadge, { status: renderStatus }),
45578
+ /* @__PURE__ */ jsx102(
45360
45579
  "button",
45361
45580
  {
45362
45581
  type: "button",
@@ -45367,11 +45586,11 @@ function MediaEditModal({ target, onClose }) {
45367
45586
  }
45368
45587
  )
45369
45588
  ] }),
45370
- !item ? /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-modal__empty", children: "This clip is no longer in the document." }) : !mediaEditRenders ? /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-modal__empty", children: "Media editing needs a media folder for this document." }) : /* @__PURE__ */ jsxs81(Fragment33, { children: [
45371
- /* @__PURE__ */ jsx100("div", { className: "squisq-media-edit-tabs", role: "tablist", "aria-label": "Edit sections", children: tabs.map((tab, index2) => {
45589
+ !item ? /* @__PURE__ */ jsx102("p", { className: "squisq-media-edit-modal__empty", children: "This clip is no longer in the document." }) : !mediaEditRenders ? /* @__PURE__ */ jsx102("p", { className: "squisq-media-edit-modal__empty", children: "Media editing needs a media folder for this document." }) : /* @__PURE__ */ jsxs82(Fragment34, { children: [
45590
+ /* @__PURE__ */ jsx102("div", { className: "squisq-media-edit-tabs", role: "tablist", "aria-label": "Edit sections", children: tabs.map((tab, index2) => {
45372
45591
  const selected = tab.id === activeTab;
45373
45592
  const edited = tabHasEdits(tab.id, draft);
45374
- return /* @__PURE__ */ jsxs81(
45593
+ return /* @__PURE__ */ jsxs82(
45375
45594
  "button",
45376
45595
  {
45377
45596
  ref: (el) => {
@@ -45390,21 +45609,21 @@ function MediaEditModal({ target, onClose }) {
45390
45609
  onKeyDown: (e2) => onTabKeyDown(e2, index2),
45391
45610
  children: [
45392
45611
  tab.label,
45393
- edited && /* @__PURE__ */ jsx100("span", { className: "squisq-sr-only", children: " (edited)" })
45612
+ edited && /* @__PURE__ */ jsx102("span", { className: "squisq-sr-only", children: " (edited)" })
45394
45613
  ]
45395
45614
  },
45396
45615
  tab.id
45397
45616
  );
45398
45617
  }) }),
45399
- /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-modal__body", children: [
45400
- /* @__PURE__ */ jsx100(
45618
+ /* @__PURE__ */ jsxs82("div", { className: "squisq-media-edit-modal__body", children: [
45619
+ /* @__PURE__ */ jsx102(
45401
45620
  "div",
45402
45621
  {
45403
45622
  role: "tabpanel",
45404
45623
  id: panelId("audio"),
45405
45624
  "aria-labelledby": tabId("audio"),
45406
45625
  hidden: activeTab !== "audio",
45407
- children: /* @__PURE__ */ jsx100(
45626
+ children: /* @__PURE__ */ jsx102(
45408
45627
  MediaEditAudioSection,
45409
45628
  {
45410
45629
  item,
@@ -45416,14 +45635,14 @@ function MediaEditModal({ target, onClose }) {
45416
45635
  )
45417
45636
  }
45418
45637
  ),
45419
- /* @__PURE__ */ jsx100(
45638
+ /* @__PURE__ */ jsx102(
45420
45639
  "div",
45421
45640
  {
45422
45641
  role: "tabpanel",
45423
45642
  id: panelId("timing"),
45424
45643
  "aria-labelledby": tabId("timing"),
45425
45644
  hidden: activeTab !== "timing",
45426
- children: /* @__PURE__ */ jsx100(
45645
+ children: /* @__PURE__ */ jsx102(
45427
45646
  MediaEditTimingSection,
45428
45647
  {
45429
45648
  item,
@@ -45435,17 +45654,17 @@ function MediaEditModal({ target, onClose }) {
45435
45654
  )
45436
45655
  }
45437
45656
  ),
45438
- item.kind === "video" && /* @__PURE__ */ jsx100(
45657
+ item.kind === "video" && /* @__PURE__ */ jsx102(
45439
45658
  "div",
45440
45659
  {
45441
45660
  role: "tabpanel",
45442
45661
  id: panelId("frame"),
45443
45662
  "aria-labelledby": tabId("frame"),
45444
45663
  hidden: activeTab !== "frame",
45445
- children: /* @__PURE__ */ jsx100(MediaEditFrameSection, { item, draft, onChange: setDraft })
45664
+ children: /* @__PURE__ */ jsx102(MediaEditFrameSection, { item, draft, onChange: setDraft })
45446
45665
  }
45447
45666
  ),
45448
- companions.length > 0 && /* @__PURE__ */ jsxs81("p", { className: "squisq-media-edit-note", children: [
45667
+ companions.length > 0 && /* @__PURE__ */ jsxs82("p", { className: "squisq-media-edit-note", children: [
45449
45668
  "Cleanup and pause cuts also apply to ",
45450
45669
  companions.length,
45451
45670
  " linked",
@@ -45455,16 +45674,16 @@ function MediaEditModal({ target, onClose }) {
45455
45674
  ] })
45456
45675
  ] })
45457
45676
  ] }),
45458
- /* @__PURE__ */ jsxs81("footer", { className: "squisq-media-edit-modal__footer", children: [
45459
- /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-status", role: "status", "data-state": renderStatus?.state, children: renderStatus && item && mediaEditRenders && /* @__PURE__ */ jsx100(
45677
+ /* @__PURE__ */ jsxs82("footer", { className: "squisq-media-edit-modal__footer", children: [
45678
+ /* @__PURE__ */ jsx102("p", { className: "squisq-media-edit-status", role: "status", "data-state": renderStatus?.state, children: renderStatus && item && mediaEditRenders && /* @__PURE__ */ jsx102(
45460
45679
  RenderStatusText,
45461
45680
  {
45462
45681
  status: renderStatus,
45463
45682
  onRetry: () => mediaEditRenders.retry(item.clip)
45464
45683
  }
45465
45684
  ) }),
45466
- /* @__PURE__ */ jsx100("button", { type: "button", onClick: onClose, children: "Cancel" }),
45467
- /* @__PURE__ */ jsx100(
45685
+ /* @__PURE__ */ jsx102("button", { type: "button", onClick: onClose, children: "Cancel" }),
45686
+ /* @__PURE__ */ jsx102(
45468
45687
  "button",
45469
45688
  {
45470
45689
  type: "button",
@@ -45724,12 +45943,12 @@ import {
45724
45943
  MemoryContentContainer as MemoryContentContainer2,
45725
45944
  createMediaProviderFromContainer
45726
45945
  } from "@bendyline/squisq/storage";
45727
- import { MediaContext as MediaContext7, useMediaClipDurations } from "@bendyline/squisq-react";
45946
+ import { MediaContext as MediaContext8, useMediaClipDurations } from "@bendyline/squisq-react";
45728
45947
  import {
45729
45948
  createMediaEditRenderManager,
45730
45949
  useProcessedAudio as useProcessedAudio4
45731
45950
  } from "@bendyline/squisq-video-react/media-edit";
45732
- import { Fragment as Fragment34, jsx as jsx101, jsxs as jsxs82 } from "react/jsx-runtime";
45951
+ import { Fragment as Fragment35, jsx as jsx103, jsxs as jsxs83 } from "react/jsx-runtime";
45733
45952
  function EditorShell({
45734
45953
  ariaLabel,
45735
45954
  initialMarkdown = "",
@@ -45835,11 +46054,11 @@ function EditorShell({
45835
46054
  () => mediaEditRenders === void 0 && effectiveMediaProvider ? createMediaEditRenderManager({ mediaProvider: effectiveMediaProvider }) : null,
45836
46055
  [mediaEditRenders, effectiveMediaProvider]
45837
46056
  );
45838
- useEffect78(() => () => ownedMediaEditRenders?.dispose(), [ownedMediaEditRenders]);
46057
+ useEffect80(() => () => ownedMediaEditRenders?.dispose(), [ownedMediaEditRenders]);
45839
46058
  const effectiveMediaEditRenders = mediaEditRenders === void 0 ? ownedMediaEditRenders : mediaEditRenders;
45840
46059
  const filesToggleEnabled = showFilesToggle ?? effectiveMediaProvider !== void 0;
45841
46060
  const effectiveInitialView = hostMode === "chat" || !showPlayTab && initialView === "preview" ? "wysiwyg" : initialView;
45842
- return /* @__PURE__ */ jsx101(MediaContext7.Provider, { value: effectiveMediaProvider ?? null, children: /* @__PURE__ */ jsx101(
46061
+ return /* @__PURE__ */ jsx103(MediaContext8.Provider, { value: effectiveMediaProvider ?? null, children: /* @__PURE__ */ jsx103(
45843
46062
  EditorProvider,
45844
46063
  {
45845
46064
  initialMarkdown,
@@ -45885,7 +46104,7 @@ function EditorShell({
45885
46104
  themeInheritance,
45886
46105
  viewPreferences,
45887
46106
  onViewPreferencesChange,
45888
- children: /* @__PURE__ */ jsx101(ProofingRoot, { children: /* @__PURE__ */ jsx101(ReviewRoot, { providers: reviewProviders, children: /* @__PURE__ */ jsx101(PageTemplateContext.Provider, { value: pageTemplates, children: /* @__PURE__ */ jsx101(
46107
+ children: /* @__PURE__ */ jsx103(ProofingRoot, { children: /* @__PURE__ */ jsx103(ReviewRoot, { providers: reviewProviders, children: /* @__PURE__ */ jsx103(PageTemplateContext.Provider, { value: pageTemplates, children: /* @__PURE__ */ jsx103(
45889
46108
  EditorShellInner,
45890
46109
  {
45891
46110
  ariaLabel: ariaLabel ?? (hostMode === "chat" ? "Message" : fileName ? `Edit ${fileName}` : "Document editor"),
@@ -45951,11 +46170,11 @@ function UseModeToolbarControls({
45951
46170
  summarizationDesigner
45952
46171
  }) {
45953
46172
  const printMode = usePrintMode();
45954
- if (printMode.active) return /* @__PURE__ */ jsx101(PrintPreviewToolbar, {});
45955
- return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45956
- /* @__PURE__ */ jsx101(PreviewToolbarControls, { summarizationDesigner }),
45957
- /* @__PURE__ */ jsx101(PresentationModeControl, {}),
45958
- allowPrint && /* @__PURE__ */ jsx101(PrintModeControl, {})
46173
+ if (printMode.active) return /* @__PURE__ */ jsx103(PrintPreviewToolbar, {});
46174
+ return /* @__PURE__ */ jsxs83(Fragment35, { children: [
46175
+ /* @__PURE__ */ jsx103(PreviewToolbarControls, { summarizationDesigner }),
46176
+ /* @__PURE__ */ jsx103(PresentationModeControl, {}),
46177
+ allowPrint && /* @__PURE__ */ jsx103(PrintModeControl, {})
45959
46178
  ] });
45960
46179
  }
45961
46180
  function UseModeProviders({
@@ -45964,13 +46183,13 @@ function UseModeProviders({
45964
46183
  allowPresentationWindow,
45965
46184
  allowPresentationFullscreen
45966
46185
  }) {
45967
- return /* @__PURE__ */ jsx101(
46186
+ return /* @__PURE__ */ jsx103(
45968
46187
  PresentationModeProvider,
45969
46188
  {
45970
46189
  rootRef,
45971
46190
  allowWindow: allowPresentationWindow,
45972
46191
  allowFullscreen: allowPresentationFullscreen,
45973
- children: /* @__PURE__ */ jsx101(PrintModeProvider, { rootRef, children })
46192
+ children: /* @__PURE__ */ jsx103(PrintModeProvider, { rootRef, children })
45974
46193
  }
45975
46194
  );
45976
46195
  }
@@ -46029,8 +46248,8 @@ function EditorShellInner({
46029
46248
  defaultThemeId,
46030
46249
  defaultThemeLabel
46031
46250
  }) {
46032
- const shellRef = useRef74(null);
46033
- const [uncontrolledNavigationSheet, setUncontrolledNavigationSheet] = useState90(null);
46251
+ const shellRef = useRef75(null);
46252
+ const [uncontrolledNavigationSheet, setUncontrolledNavigationSheet] = useState91(null);
46034
46253
  const navigationSheetPanel = navigationSheet === void 0 ? uncontrolledNavigationSheet : navigationSheet;
46035
46254
  const handleNavigationSheetChange = useCallback63(
46036
46255
  (panel) => {
@@ -46069,8 +46288,8 @@ function EditorShellInner({
46069
46288
  } = useEditorContext();
46070
46289
  const processedAudio = useProcessedAudio4(mediaEditRenders);
46071
46290
  const { docThemes, onDocThemesChange } = useDocCustomThemes();
46072
- const lastEditingView = useRef74(activeView === "raw" ? "raw" : "wysiwyg");
46073
- useEffect78(() => {
46291
+ const lastEditingView = useRef75(activeView === "raw" ? "raw" : "wysiwyg");
46292
+ useEffect80(() => {
46074
46293
  if (activeView !== "preview") lastEditingView.current = activeView;
46075
46294
  }, [activeView]);
46076
46295
  const editingView = activeView === "preview" ? lastEditingView.current : activeView;
@@ -46117,32 +46336,32 @@ function EditorShellInner({
46117
46336
  );
46118
46337
  const timelineClock = useTimelineClock(isTimelineMode ? timelineDuration : 0);
46119
46338
  const hasTimelineVideo = timelineVideoSchedule.length > 0;
46120
- const [timelineVideoVisible, setTimelineVideoVisible] = useState90(false);
46121
- const [timelineCompositionVisible, setTimelineCompositionVisible] = useState90(false);
46339
+ const [timelineVideoVisible, setTimelineVideoVisible] = useState91(false);
46340
+ const [timelineCompositionVisible, setTimelineCompositionVisible] = useState91(false);
46122
46341
  const timelinePreviewCount = Number(timelineVideoVisible) + Number(timelineCompositionVisible);
46123
- const [showFiles, setShowFiles] = useState90(false);
46124
- const [filesFocusPath, setFilesFocusPath] = useState90(null);
46125
- const [mediaRefreshKey, setMediaRefreshKey] = useState90(0);
46126
- const [mediaCount, setMediaCount] = useState90(0);
46127
- const [mediaBinRecorderOpen, setMediaBinRecorderOpen] = useState90(false);
46342
+ const [showFiles, setShowFiles] = useState91(false);
46343
+ const [filesFocusPath, setFilesFocusPath] = useState91(null);
46344
+ const [mediaRefreshKey, setMediaRefreshKey] = useState91(0);
46345
+ const [mediaCount, setMediaCount] = useState91(0);
46346
+ const [mediaBinRecorderOpen, setMediaBinRecorderOpen] = useState91(false);
46128
46347
  const mediaListRefreshKey = mediaRefreshKey + mediaRevision;
46129
46348
  const usedMediaPaths = useMemo62(
46130
46349
  () => collectMediaReferencesFromMarkdown(markdownSource),
46131
46350
  [markdownSource]
46132
46351
  );
46133
- const imageEditFallbackContainerRef = useRef74(null);
46352
+ const imageEditFallbackContainerRef = useRef75(null);
46134
46353
  if (imageEditFallbackContainerRef.current === null) {
46135
46354
  imageEditFallbackContainerRef.current = new MemoryContentContainer2();
46136
46355
  }
46137
46356
  const imageEditFallbackContainer = imageEditFallbackContainerRef.current;
46138
46357
  const isDark = colorScheme === "dark";
46139
- useEffect78(() => {
46358
+ useEffect80(() => {
46140
46359
  if (!isTimelineMode || !hasTimelineVideo) setTimelineVideoVisible(false);
46141
46360
  }, [isTimelineMode, hasTimelineVideo]);
46142
- useEffect78(() => {
46361
+ useEffect80(() => {
46143
46362
  if (!isTimelineMode || !doc?.blocks.length) setTimelineCompositionVisible(false);
46144
46363
  }, [isTimelineMode, doc]);
46145
- useEffect78(() => {
46364
+ useEffect80(() => {
46146
46365
  if (!mediaProvider) {
46147
46366
  setMediaCount(0);
46148
46367
  return;
@@ -46166,7 +46385,7 @@ function EditorShellInner({
46166
46385
  cancelled = true;
46167
46386
  };
46168
46387
  }, [mediaProvider, mediaListRefreshKey]);
46169
- useEffect78(() => {
46388
+ useEffect80(() => {
46170
46389
  if (showFilesWhenNotEmpty && mediaCount > 0) setShowFiles(true);
46171
46390
  }, [mediaCount, showFilesWhenNotEmpty]);
46172
46391
  const handleToggleFiles = useCallback63(() => {
@@ -46185,8 +46404,8 @@ function EditorShellInner({
46185
46404
  },
46186
46405
  [insertionTarget]
46187
46406
  );
46188
- const docBasenameRef = useRef74("document");
46189
- useEffect78(() => {
46407
+ const docBasenameRef = useRef75("document");
46408
+ useEffect80(() => {
46190
46409
  let cancelled = false;
46191
46410
  docBasenameRef.current = "document";
46192
46411
  void resolveDocBasename(workspaceContainer).then((base) => {
@@ -46269,7 +46488,7 @@ function EditorShellInner({
46269
46488
  onDrop: handleFileDrop,
46270
46489
  enabled: !readOnly
46271
46490
  });
46272
- useEffect78(() => {
46491
+ useEffect80(() => {
46273
46492
  onChange?.(markdownSource);
46274
46493
  }, [markdownSource, onChange]);
46275
46494
  const handleShellKeyDown = useCallback63((e2) => {
@@ -46325,7 +46544,7 @@ function EditorShellInner({
46325
46544
  anchor.removeAttribute("data-squisq-link-title");
46326
46545
  }, []);
46327
46546
  const autoGrow = minHeight !== void 0 || maxHeight !== void 0;
46328
- const shell = /* @__PURE__ */ jsxs82(
46547
+ const shell = /* @__PURE__ */ jsxs83(
46329
46548
  "div",
46330
46549
  {
46331
46550
  ref: shellRef,
@@ -46364,7 +46583,7 @@ function EditorShellInner({
46364
46583
  },
46365
46584
  ...containerProps,
46366
46585
  children: [
46367
- /* @__PURE__ */ jsx101(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx101(
46586
+ /* @__PURE__ */ jsx103(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx103(
46368
46587
  PreviewSettingsProvider,
46369
46588
  {
46370
46589
  doc,
@@ -46372,25 +46591,25 @@ function EditorShellInner({
46372
46591
  themeOverride,
46373
46592
  defaultThemeId,
46374
46593
  defaultThemeLabel,
46375
- children: /* @__PURE__ */ jsxs82(
46594
+ children: /* @__PURE__ */ jsxs83(
46376
46595
  UseModeProviders,
46377
46596
  {
46378
46597
  rootRef: shellRef,
46379
46598
  allowPresentationWindow,
46380
46599
  allowPresentationFullscreen,
46381
46600
  children: [
46382
- isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs82("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
46601
+ isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs83("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
46383
46602
  toolbarSlotLeft,
46384
- /* @__PURE__ */ jsx101("div", { style: { flex: 1 } }),
46603
+ /* @__PURE__ */ jsx103("div", { style: { flex: 1 } }),
46385
46604
  toolbarSlotRight
46386
- ] }) : /* @__PURE__ */ jsx101("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx101(
46605
+ ] }) : /* @__PURE__ */ jsx103("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx103(
46387
46606
  Toolbar,
46388
46607
  {
46389
46608
  showFiles,
46390
46609
  fileCount: mediaCount,
46391
46610
  onToggleFiles: !isCodeMode && filesToggleEnabled ? handleToggleFiles : void 0,
46392
46611
  slotLeft: toolbarSlotLeft,
46393
- slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx101(
46612
+ slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx103(
46394
46613
  UseModeToolbarControls,
46395
46614
  {
46396
46615
  allowPrint,
@@ -46407,7 +46626,7 @@ function EditorShellInner({
46407
46626
  findShortcut
46408
46627
  }
46409
46628
  ) }),
46410
- /* @__PURE__ */ jsxs82(
46629
+ /* @__PURE__ */ jsxs83(
46411
46630
  "div",
46412
46631
  {
46413
46632
  className: "squisq-editor-content",
@@ -46421,7 +46640,7 @@ function EditorShellInner({
46421
46640
  display: "flex"
46422
46641
  },
46423
46642
  children: [
46424
- /* @__PURE__ */ jsxs82(
46643
+ /* @__PURE__ */ jsxs83(
46425
46644
  "div",
46426
46645
  {
46427
46646
  className: "squisq-editor-primary",
@@ -46432,7 +46651,7 @@ function EditorShellInner({
46432
46651
  position: "relative"
46433
46652
  },
46434
46653
  children: [
46435
- isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx101(
46654
+ isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx103(
46436
46655
  ImageEditor,
46437
46656
  {
46438
46657
  filesContainer: imageEditorContainer,
@@ -46442,16 +46661,16 @@ function EditorShellInner({
46442
46661
  onExport: onImageExport,
46443
46662
  surface: colorScheme === "dark" ? DARK_SURFACE2 : LIGHT_SURFACE2
46444
46663
  }
46445
- ) : /* @__PURE__ */ jsx101(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
46446
- !isImageMode && editingView === "raw" && /* @__PURE__ */ jsxs82(
46664
+ ) : /* @__PURE__ */ jsx103(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
46665
+ !isImageMode && editingView === "raw" && /* @__PURE__ */ jsxs83(
46447
46666
  "div",
46448
46667
  {
46449
46668
  className: "squisq-editor-with-gutter",
46450
46669
  hidden: isPreview,
46451
46670
  style: isPreview ? { display: "none" } : void 0,
46452
46671
  children: [
46453
- isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx101(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46454
- /* @__PURE__ */ jsx101(
46672
+ isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx103(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46673
+ /* @__PURE__ */ jsx103(
46455
46674
  BlockCardView,
46456
46675
  {
46457
46676
  active: isCardMode,
@@ -46460,7 +46679,7 @@ function EditorShellInner({
46460
46679
  onPrev: prevBlock,
46461
46680
  onNext: nextBlock,
46462
46681
  onAdd: addBlock,
46463
- children: /* @__PURE__ */ jsx101("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx101(
46682
+ children: /* @__PURE__ */ jsx103("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx103(
46464
46683
  RawEditor,
46465
46684
  {
46466
46685
  ariaLabel: `${ariaLabel} \u2014 source`,
@@ -46472,9 +46691,9 @@ function EditorShellInner({
46472
46691
  },
46473
46692
  "raw-frame"
46474
46693
  ),
46475
- isCodeMode && codeContext && /* @__PURE__ */ jsx101(CodeContextZones, { options: codeContext }, "code-context"),
46476
- isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(BlockPreviewPanel, { basePath }, "block-preview"),
46477
- isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(
46694
+ isCodeMode && codeContext && /* @__PURE__ */ jsx103(CodeContextZones, { options: codeContext }, "code-context"),
46695
+ isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx103(BlockPreviewPanel, { basePath }, "block-preview"),
46696
+ isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx103(
46478
46697
  InlinePreviewGutter,
46479
46698
  {
46480
46699
  width: inlinePreviewWidth,
@@ -46483,7 +46702,7 @@ function EditorShellInner({
46483
46702
  },
46484
46703
  "inline"
46485
46704
  ),
46486
- isMarkdownMode && /* @__PURE__ */ jsx101(
46705
+ isMarkdownMode && /* @__PURE__ */ jsx103(
46487
46706
  NavigationSheet,
46488
46707
  {
46489
46708
  panel: navigationSheetPanel,
@@ -46498,15 +46717,15 @@ function EditorShellInner({
46498
46717
  },
46499
46718
  "raw-shell"
46500
46719
  ),
46501
- isMarkdownMode && editingView === "wysiwyg" && /* @__PURE__ */ jsxs82(
46720
+ isMarkdownMode && editingView === "wysiwyg" && /* @__PURE__ */ jsxs83(
46502
46721
  "div",
46503
46722
  {
46504
46723
  className: "squisq-editor-with-gutter",
46505
46724
  hidden: isPreview,
46506
46725
  style: isPreview ? { display: "none" } : void 0,
46507
46726
  children: [
46508
- outlineVisible && /* @__PURE__ */ jsx101(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46509
- /* @__PURE__ */ jsx101(
46727
+ outlineVisible && /* @__PURE__ */ jsx103(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46728
+ /* @__PURE__ */ jsx103(
46510
46729
  BlockCardView,
46511
46730
  {
46512
46731
  active: isCardMode,
@@ -46515,7 +46734,7 @@ function EditorShellInner({
46515
46734
  onPrev: prevBlock,
46516
46735
  onNext: nextBlock,
46517
46736
  onAdd: addBlock,
46518
- children: /* @__PURE__ */ jsx101(
46737
+ children: /* @__PURE__ */ jsx103(
46519
46738
  WysiwygEditor,
46520
46739
  {
46521
46740
  ariaLabel,
@@ -46533,8 +46752,8 @@ function EditorShellInner({
46533
46752
  },
46534
46753
  "wysiwyg-frame"
46535
46754
  ),
46536
- isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(BlockPreviewPanel, { basePath }, "block-preview"),
46537
- !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(
46755
+ isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx103(BlockPreviewPanel, { basePath }, "block-preview"),
46756
+ !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx103(
46538
46757
  InlinePreviewGutter,
46539
46758
  {
46540
46759
  width: inlinePreviewWidth,
@@ -46543,7 +46762,7 @@ function EditorShellInner({
46543
46762
  },
46544
46763
  "inline"
46545
46764
  ),
46546
- /* @__PURE__ */ jsx101(
46765
+ /* @__PURE__ */ jsx103(
46547
46766
  NavigationSheet,
46548
46767
  {
46549
46768
  panel: navigationSheetPanel,
@@ -46558,7 +46777,7 @@ function EditorShellInner({
46558
46777
  },
46559
46778
  "wysiwyg-shell"
46560
46779
  ),
46561
- isMarkdownMode && isPreview && /* @__PURE__ */ jsx101(
46780
+ isMarkdownMode && isPreview && /* @__PURE__ */ jsx103(
46562
46781
  PreviewPanel,
46563
46782
  {
46564
46783
  basePath,
@@ -46571,7 +46790,7 @@ function EditorShellInner({
46571
46790
  ]
46572
46791
  }
46573
46792
  ),
46574
- isTimelineMode && timelineVideoVisible && /* @__PURE__ */ jsx101(
46793
+ isTimelineMode && timelineVideoVisible && /* @__PURE__ */ jsx103(
46575
46794
  TimelineVideoPanel,
46576
46795
  {
46577
46796
  schedule: timelineVideoSchedule,
@@ -46581,7 +46800,7 @@ function EditorShellInner({
46581
46800
  onClose: () => setTimelineVideoVisible(false)
46582
46801
  }
46583
46802
  ),
46584
- isTimelineMode && timelineCompositionVisible && /* @__PURE__ */ jsx101(
46803
+ isTimelineMode && timelineCompositionVisible && /* @__PURE__ */ jsx103(
46585
46804
  TimelineCompositionPanel,
46586
46805
  {
46587
46806
  doc,
@@ -46591,7 +46810,7 @@ function EditorShellInner({
46591
46810
  onClose: () => setTimelineCompositionVisible(false)
46592
46811
  }
46593
46812
  ),
46594
- isMarkdownMode && showFiles && /* @__PURE__ */ jsx101(
46813
+ isMarkdownMode && showFiles && /* @__PURE__ */ jsx103(
46595
46814
  MediaBin,
46596
46815
  {
46597
46816
  mediaProvider,
@@ -46607,11 +46826,11 @@ function EditorShellInner({
46607
46826
  highlightPath: filesFocusPath
46608
46827
  }
46609
46828
  ),
46610
- isMarkdownMode && /* @__PURE__ */ jsx101(ProofingPanel, {}),
46611
- isMarkdownMode && /* @__PURE__ */ jsx101(ReviewPanel, {}),
46829
+ isMarkdownMode && /* @__PURE__ */ jsx103(ProofingPanel, {}),
46830
+ isMarkdownMode && /* @__PURE__ */ jsx103(ReviewPanel, {}),
46612
46831
  isMarkdownMode && sidePanelSlot,
46613
- isMarkdownMode && /* @__PURE__ */ jsx101(ThemeDesignerDock, {}),
46614
- isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx101(
46832
+ isMarkdownMode && /* @__PURE__ */ jsx103(ThemeDesignerDock, {}),
46833
+ isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx103(
46615
46834
  DropZoneOverlay,
46616
46835
  {
46617
46836
  dragContentType,
@@ -46622,7 +46841,7 @@ function EditorShellInner({
46622
46841
  ]
46623
46842
  }
46624
46843
  ),
46625
- isTimelineMode && /* @__PURE__ */ jsx101(
46844
+ isTimelineMode && /* @__PURE__ */ jsx103(
46626
46845
  TimelineToolbar,
46627
46846
  {
46628
46847
  literalVideoVisible: timelineVideoVisible,
@@ -46633,7 +46852,7 @@ function EditorShellInner({
46633
46852
  onToggleComposition: () => setTimelineCompositionVisible((visible) => !visible)
46634
46853
  }
46635
46854
  ),
46636
- isTimelineMode && /* @__PURE__ */ jsx101(
46855
+ isTimelineMode && /* @__PURE__ */ jsx103(
46637
46856
  TimelineTrack,
46638
46857
  {
46639
46858
  doc: timelineDoc,
@@ -46642,8 +46861,8 @@ function EditorShellInner({
46642
46861
  basePath
46643
46862
  }
46644
46863
  ),
46645
- statusBarVisible && !isImageMode && /* @__PURE__ */ jsx101(StatusBar, { slotRight: statusBarSlotRight }),
46646
- isMarkdownMode && allowRecording && mediaProvider && /* @__PURE__ */ jsx101(
46864
+ statusBarVisible && !isImageMode && /* @__PURE__ */ jsx103(StatusBar, { slotRight: statusBarSlotRight }),
46865
+ isMarkdownMode && allowRecording && mediaProvider && /* @__PURE__ */ jsx103(
46647
46866
  RecorderEntry,
46648
46867
  {
46649
46868
  open: mediaBinRecorderOpen,
@@ -46656,8 +46875,8 @@ function EditorShellInner({
46656
46875
  )
46657
46876
  }
46658
46877
  ) }),
46659
- /* @__PURE__ */ jsx101(TooltipLayer, {}),
46660
- imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx101(
46878
+ /* @__PURE__ */ jsx103(TooltipLayer, {}),
46879
+ imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx103(
46661
46880
  ImageEditModal,
46662
46881
  {
46663
46882
  relativePath: imageEditTarget,
@@ -46673,12 +46892,12 @@ function EditorShellInner({
46673
46892
  shellTheme: colorScheme
46674
46893
  }
46675
46894
  ),
46676
- mediaEditTarget !== null && /* @__PURE__ */ jsx101(MediaEditModal, { target: mediaEditTarget, onClose: closeMediaEdit })
46895
+ mediaEditTarget !== null && /* @__PURE__ */ jsx103(MediaEditModal, { target: mediaEditTarget, onClose: closeMediaEdit })
46677
46896
  ]
46678
46897
  }
46679
46898
  );
46680
- return /* @__PURE__ */ jsxs82(EditorContextMenuProvider, { rootRef: shellRef, readOnly, children: [
46681
- /* @__PURE__ */ jsx101(MediaEditContextMenuItems, {}),
46899
+ return /* @__PURE__ */ jsxs83(EditorContextMenuProvider, { rootRef: shellRef, readOnly, children: [
46900
+ /* @__PURE__ */ jsx103(MediaEditContextMenuItems, {}),
46682
46901
  shell
46683
46902
  ] });
46684
46903
  }