@bendyline/squisq-editor-react 2.13.13 → 2.13.15

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,
@@ -9741,10 +9741,24 @@ async function storeCopy(provider, path, file, clipboardImage) {
9741
9741
  mimeType: clipboardImage.type || "image/png"
9742
9742
  } : null);
9743
9743
  if (!copied) return null;
9744
- const existing = await readStoredFile(provider, path);
9745
- if (existing && await sameBytes(existing.data, copied.data)) return path;
9744
+ const stored = await storedCopyOf(provider, path, copied.data);
9745
+ if (stored) return stored;
9746
9746
  return provider.addMedia(await unusedName(provider, copied.name), copied.data, copied.mimeType);
9747
9747
  }
9748
+ async function storedCopyOf(provider, path, data) {
9749
+ let entries;
9750
+ try {
9751
+ entries = await provider.listMedia();
9752
+ } catch {
9753
+ return null;
9754
+ }
9755
+ const candidates = entries.filter((entry) => entry.size === data.size).sort((a, b) => Number(b.name === path) - Number(a.name === path));
9756
+ for (const { name } of candidates) {
9757
+ const existing = await readStoredFile(provider, name);
9758
+ if (existing && await sameBytes(existing.data, data)) return name;
9759
+ }
9760
+ return null;
9761
+ }
9748
9762
  async function sameBytes(a, b) {
9749
9763
  if (a.size !== b.size) return false;
9750
9764
  const [left, right] = await Promise.all([a.arrayBuffer(), b.arrayBuffer()]);
@@ -24645,10 +24659,38 @@ function renameNodeOp(diagram, nodeId, label) {
24645
24659
  if (!node2) return diagram;
24646
24660
  const clean = sanitizeAsciiLabel(label);
24647
24661
  if (clean.length === 0 || clean === node2.label) return diagram;
24648
- return {
24662
+ const renamed = {
24649
24663
  ...diagram,
24650
24664
  nodes: diagram.nodes.map((n) => n.id === nodeId ? { ...n, label: clean } : n)
24651
24665
  };
24666
+ const isContainer = diagram.nodes.some((n) => n.containerId === nodeId);
24667
+ const oldW = Math.max(node2.wCols, labelBoxWidth(node2.label, isContainer));
24668
+ const newW = Math.max(node2.wCols, labelBoxWidth(clean, isContainer));
24669
+ return makeRoomToTheRight(renamed, node2, oldW, newW);
24670
+ }
24671
+ var SIBLING_GAP = 1;
24672
+ function labelBoxWidth(label, isContainer) {
24673
+ const lines2 = label.split("\n");
24674
+ const widest = (ls) => ls.reduce((w, l2) => Math.max(w, Array.from(l2).length), 0);
24675
+ if (!isContainer) return widest(lines2) + 4;
24676
+ return Math.max(widest(lines2.slice(0, 1)) + 6, widest(lines2.slice(1)) + 4);
24677
+ }
24678
+ function makeRoomToTheRight(diagram, node2, oldW, newW) {
24679
+ if (newW <= oldW) return diagram;
24680
+ const drawnRight = node2.col + node2.wCols - 1;
24681
+ const newRight = node2.col + newW - 1;
24682
+ const r0 = node2.row - SIBLING_GAP;
24683
+ const r1 = node2.row + node2.hRows - 1 + SIBLING_GAP;
24684
+ let shift = 0;
24685
+ for (const n of diagram.nodes) {
24686
+ if (n.col <= drawnRight || n.row > r1 || n.row + n.hRows - 1 < r0) continue;
24687
+ shift = Math.max(shift, newRight + SIBLING_GAP + 1 - n.col);
24688
+ }
24689
+ if (shift === 0) return diagram;
24690
+ return {
24691
+ ...diagram,
24692
+ nodes: diagram.nodes.map((n) => n.col > drawnRight ? { ...n, col: n.col + shift } : n)
24693
+ };
24652
24694
  }
24653
24695
  function addNodeOp(diagram, opts) {
24654
24696
  let label = opts.label;
@@ -24695,7 +24737,7 @@ function removeNodeOp(diagram, nodeId) {
24695
24737
  }
24696
24738
 
24697
24739
  // src/asciiDiagram/asciiDiagramData.ts
24698
- import { useEffect as useEffect35, useMemo as useMemo29, useState as useState45 } from "react";
24740
+ import { useEffect as useEffect36, useMemo as useMemo29, useState as useState45 } from "react";
24699
24741
  import {
24700
24742
  asciiCellToCanvas,
24701
24743
  asciiDiagramToTemplateData,
@@ -24716,7 +24758,7 @@ import {
24716
24758
  } from "@bendyline/squisq/doc";
24717
24759
 
24718
24760
  // src/asciiDiagram/AsciiDiagramWidget.tsx
24719
- import { useCallback as useCallback35, useMemo as useMemo28, useRef as useRef39, useState as useState44 } from "react";
24761
+ import { useCallback as useCallback35, useEffect as useEffect35, useMemo as useMemo28, useRef as useRef39, useState as useState44 } from "react";
24720
24762
 
24721
24763
  // src/asciiDiagram/asciiDiagramCommands.ts
24722
24764
  import {
@@ -24901,7 +24943,7 @@ function applyRepairCommand(editor, blockId) {
24901
24943
  if (!repaired) return false;
24902
24944
  return replaceAsciiFenceText(editor, pos, repaired.art, "diagram");
24903
24945
  }
24904
- function applyOp(editor, blockId, op, diagramOffset) {
24946
+ function applyOp(editor, blockId, op, { diagramOffset, onRejected }) {
24905
24947
  const pos = findAsciiDiagramBlockPos(editor, blockId);
24906
24948
  if (pos === null) return false;
24907
24949
  const node2 = editor.state.doc.nodeAt(pos);
@@ -24913,12 +24955,15 @@ function applyOp(editor, blockId, op, diagramOffset) {
24913
24955
  if (next === diagram && diagram === sourceDiagram) return false;
24914
24956
  const rendered = renderAsciiDiagram(next);
24915
24957
  const verification = parseAsciiDiagram(rendered);
24916
- if (verification.nodes.length !== next.nodes.length) return false;
24958
+ if (verification.nodes.length !== next.nodes.length || verification.edges.length !== next.edges.length) {
24959
+ onRejected?.();
24960
+ return false;
24961
+ }
24917
24962
  return replaceAsciiFenceText(editor, pos, rendered, "diagram");
24918
24963
  }
24919
24964
  function applyAsciiDiagramCommand(editor, blockId, cmd, options = {}) {
24920
24965
  if (!editor.isEditable) return false;
24921
- const apply = (op) => applyOp(editor, blockId, op, options.diagramOffset);
24966
+ const apply = (op) => applyOp(editor, blockId, op, options);
24922
24967
  switch (cmd.kind) {
24923
24968
  case "moveNode": {
24924
24969
  const { col, row } = canvasToAsciiCell(cmd.x, cmd.y);
@@ -24960,6 +25005,8 @@ function applyAsciiDiagramCommand(editor, blockId, cmd, options = {}) {
24960
25005
  import { jsx as jsx54, jsxs as jsxs42 } from "react/jsx-runtime";
24961
25006
  var MIN_DIAGRAM_HEIGHT = 160;
24962
25007
  var DEFAULT_DIAGRAM_HEIGHT = 420;
25008
+ var REJECTED_NOTICE_MS = 6e3;
25009
+ 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
25010
  function AsciiDiagramWidget({
24964
25011
  editor,
24965
25012
  blockId,
@@ -24982,12 +25029,20 @@ function AsciiDiagramWidget({
24982
25029
  const offset = canvasOffsetRef.current ?? { col: 0, row: 0 };
24983
25030
  return asciiDiagramToCanvas(offsetAsciiDiagram(view.diagram, offset));
24984
25031
  }, [view, canvasOffsetVersion]);
25032
+ const [rejectedAt, setRejectedAt] = useState44(null);
25033
+ useEffect35(() => {
25034
+ if (rejectedAt === null) return;
25035
+ const timer = setTimeout(() => setRejectedAt(null), REJECTED_NOTICE_MS);
25036
+ return () => clearTimeout(timer);
25037
+ }, [rejectedAt]);
24985
25038
  const dispatch = useCallback35(
24986
25039
  (cmd) => {
24987
25040
  const offset = canvasOffsetRef.current ?? { col: 0, row: 0 };
24988
25041
  const applied = applyAsciiDiagramCommand(editor, blockId, cmd, {
24989
- diagramOffset: offset
25042
+ diagramOffset: offset,
25043
+ onRejected: () => setRejectedAt(Date.now())
24990
25044
  });
25045
+ if (applied) setRejectedAt(null);
24991
25046
  if (applied && (offset.col !== 0 || offset.row !== 0)) {
24992
25047
  canvasOffsetRef.current = { col: 0, row: 0 };
24993
25048
  setCanvasOffsetVersion((version) => version + 1);
@@ -25086,6 +25141,7 @@ function AsciiDiagramWidget({
25086
25141
  ] }),
25087
25142
  /* @__PURE__ */ jsx54("ul", { children: view.warnings.map((w, i) => /* @__PURE__ */ jsx54("li", { children: w }, i)) })
25088
25143
  ] }) : null;
25144
+ const notice = /* @__PURE__ */ jsx54("div", { className: "squisq-ascii-diagram-notice", role: "status", "aria-live": "polite", children: rejectedAt !== null && REJECTED_EDIT_MESSAGE });
25089
25145
  const canvas = /* @__PURE__ */ jsx54(
25090
25146
  DiagramCanvas,
25091
25147
  {
@@ -25109,7 +25165,8 @@ function AsciiDiagramWidget({
25109
25165
  style: effectiveHeight != null ? { height: effectiveHeight } : void 0,
25110
25166
  children: /* @__PURE__ */ jsx54(DiagramMaximizedOverlay, { host: host ?? null, onClose: () => setMaximized(false), children: /* @__PURE__ */ jsxs42("div", { className: "squisq-scene-block-max", children: [
25111
25167
  canvas,
25112
- /* @__PURE__ */ jsx54("div", { className: "squisq-scene-side-toolbar", children: toolbar })
25168
+ /* @__PURE__ */ jsx54("div", { className: "squisq-scene-side-toolbar", children: toolbar }),
25169
+ notice
25113
25170
  ] }) })
25114
25171
  }
25115
25172
  );
@@ -25139,6 +25196,7 @@ function AsciiDiagramWidget({
25139
25196
  ]
25140
25197
  }
25141
25198
  ),
25199
+ notice,
25142
25200
  warnings
25143
25201
  ] });
25144
25202
  }
@@ -25407,7 +25465,7 @@ function asciiDiagramToCanvas(diagram) {
25407
25465
  }
25408
25466
  function useAsciiDiagramData(editor, blockId) {
25409
25467
  const [version, setVersion] = useState45(0);
25410
- useEffect35(() => {
25468
+ useEffect36(() => {
25411
25469
  const onUpdate = () => setVersion((v2) => v2 + 1);
25412
25470
  editor.on("transaction", onUpdate);
25413
25471
  return () => {
@@ -27253,7 +27311,7 @@ function mermaidErrorMessage(error) {
27253
27311
  }
27254
27312
 
27255
27313
  // src/mermaid/mermaidSurfaceTheme.ts
27256
- import { useEffect as useEffect36, useMemo as useMemo30, useState as useState46 } from "react";
27314
+ import { useEffect as useEffect37, useMemo as useMemo30, useState as useState46 } from "react";
27257
27315
  import { relativeLuminance } from "@bendyline/squisq/schemas";
27258
27316
  var EDITOR_SURFACE = {
27259
27317
  light: {
@@ -27290,7 +27348,7 @@ function resolveMermaidSurfaceTheme(host, theme) {
27290
27348
  }
27291
27349
  function useMermaidSurfaceTheme(host, theme) {
27292
27350
  const [surface, setSurface] = useState46(() => readHostSurface(host));
27293
- useEffect36(() => {
27351
+ useEffect37(() => {
27294
27352
  const sync = () => setSurface((current) => {
27295
27353
  const next = readHostSurface(host);
27296
27354
  return current.scheme === next.scheme && current.inheritsThemeColors === next.inheritsThemeColors ? current : next;
@@ -27316,7 +27374,7 @@ function useMermaidSurfaceTheme(host, theme) {
27316
27374
  }
27317
27375
 
27318
27376
  // 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";
27377
+ import { useCallback as useCallback36, useEffect as useEffect38, useId as useId12, useLayoutEffect as useLayoutEffect10, useRef as useRef40, useState as useState47 } from "react";
27320
27378
  import { jsx as jsx55, jsxs as jsxs43 } from "react/jsx-runtime";
27321
27379
  var renderSequence = 0;
27322
27380
  function excludesCanvasPan(target, viewport) {
@@ -27393,7 +27451,7 @@ function MermaidDiagramCanvas({
27393
27451
  const [panning, setPanning] = useState47(false);
27394
27452
  const [selectionAnchor, setSelectionAnchor] = useState47(null);
27395
27453
  const [renameValue, setRenameValue] = useState47("");
27396
- useEffect37(() => {
27454
+ useEffect38(() => {
27397
27455
  if (!panning) return;
27398
27456
  const finish = () => {
27399
27457
  panDragRef.current = null;
@@ -27421,7 +27479,7 @@ function MermaidDiagramCanvas({
27421
27479
  window.removeEventListener("blur", finish);
27422
27480
  };
27423
27481
  }, [panning]);
27424
- useEffect37(() => {
27482
+ useEffect38(() => {
27425
27483
  let current = true;
27426
27484
  const id = `squisq-mermaid-svg-${++renderSequence}`;
27427
27485
  setRendering(true);
@@ -27692,7 +27750,7 @@ function MermaidDiagramCanvas({
27692
27750
  updateSelectionAnchor,
27693
27751
  zoom
27694
27752
  ]);
27695
- useEffect37(() => {
27753
+ useEffect38(() => {
27696
27754
  const scroll = scrollRef.current;
27697
27755
  if (!scroll) return;
27698
27756
  const update = () => updateSelectionAnchor();
@@ -28097,7 +28155,7 @@ function CanvasAction({
28097
28155
  }
28098
28156
 
28099
28157
  // src/mermaid/MermaidShapePalette.tsx
28100
- import { useEffect as useEffect38, useLayoutEffect as useLayoutEffect11, useMemo as useMemo31, useRef as useRef41, useState as useState48 } from "react";
28158
+ import { useEffect as useEffect39, useLayoutEffect as useLayoutEffect11, useMemo as useMemo31, useRef as useRef41, useState as useState48 } from "react";
28101
28159
  import { jsx as jsx56, jsxs as jsxs44 } from "react/jsx-runtime";
28102
28160
  var CATEGORIES = ["Basic", "Process", "Data", "Documents", "Symbols"];
28103
28161
  var PALETTE_WIDTH = 360;
@@ -28108,7 +28166,7 @@ function MermaidShapePalette({ selected, onPick, onClose }) {
28108
28166
  const [query, setQuery] = useState48("");
28109
28167
  const [position, setPosition] = useState48(null);
28110
28168
  const ref = useRef41(null);
28111
- useEffect38(() => {
28169
+ useEffect39(() => {
28112
28170
  const onPointerDown = (event) => {
28113
28171
  const target = event.target;
28114
28172
  if (target?.closest(".squisq-scene-block-toolbar")) return;
@@ -28279,7 +28337,7 @@ function MermaidShapeThumb({ shape }) {
28279
28337
  }
28280
28338
 
28281
28339
  // src/mermaid/mermaidData.ts
28282
- import { useEffect as useEffect40, useMemo as useMemo32, useState as useState50 } from "react";
28340
+ import { useEffect as useEffect41, useMemo as useMemo32, useState as useState50 } from "react";
28283
28341
 
28284
28342
  // src/mermaid/MermaidDiagramExtension.ts
28285
28343
  import { Extension as Extension7 } from "@tiptap/core";
@@ -28290,7 +28348,7 @@ import { createElement as createElement10 } from "react";
28290
28348
  // src/mermaid/MermaidDiagramWidget.tsx
28291
28349
  import {
28292
28350
  useCallback as useCallback37,
28293
- useEffect as useEffect39,
28351
+ useEffect as useEffect40,
28294
28352
  useLayoutEffect as useLayoutEffect12,
28295
28353
  useRef as useRef42,
28296
28354
  useState as useState49,
@@ -28930,7 +28988,7 @@ function MermaidDiagramWidget({
28930
28988
  },
28931
28989
  [effectiveHeight]
28932
28990
  );
28933
- useEffect39(() => {
28991
+ useEffect40(() => {
28934
28992
  if (!editNotice) return;
28935
28993
  const timeout = window.setTimeout(() => setEditNotice(""), 7e3);
28936
28994
  return () => window.clearTimeout(timeout);
@@ -29167,7 +29225,7 @@ function MermaidDiagramWidget({
29167
29225
  ] });
29168
29226
  }
29169
29227
  function useDismissibleMermaidPopover(ref, onClose) {
29170
- useEffect39(() => {
29228
+ useEffect40(() => {
29171
29229
  const onPointerDown = (event) => {
29172
29230
  const target = event.target;
29173
29231
  if (target?.closest(".squisq-scene-block-toolbar")) return;
@@ -29547,7 +29605,7 @@ var MermaidDiagramExtension = Extension7.create({
29547
29605
  // src/mermaid/mermaidData.ts
29548
29606
  function useMermaidDiagramData(editor, blockId) {
29549
29607
  const [version, setVersion] = useState50(0);
29550
- useEffect40(() => {
29608
+ useEffect41(() => {
29551
29609
  const onTransaction = () => setVersion((value) => value + 1);
29552
29610
  editor.on("transaction", onTransaction);
29553
29611
  return () => {
@@ -29572,7 +29630,7 @@ function describeSvgIslandRemovals(diagnostics) {
29572
29630
  }
29573
29631
 
29574
29632
  // src/svgIsland/SvgIslandWidget.tsx
29575
- import { useEffect as useEffect42, useMemo as useMemo33, useState as useState52 } from "react";
29633
+ import { useEffect as useEffect43, useMemo as useMemo33, useState as useState52 } from "react";
29576
29634
  import { parseSvgIsland } from "@bendyline/squisq/markdown";
29577
29635
  import { SvgIslandImage } from "@bendyline/squisq-react";
29578
29636
 
@@ -29628,7 +29686,7 @@ function FenceMonacoEditor({
29628
29686
  }
29629
29687
 
29630
29688
  // src/codeSnippet/fenceEditorHooks.ts
29631
- import { useEffect as useEffect41, useState as useState51 } from "react";
29689
+ import { useEffect as useEffect42, useState as useState51 } from "react";
29632
29690
  function schemeFromHost(host) {
29633
29691
  return host?.closest("[data-theme]")?.dataset.theme === "dark" ? "dark" : "light";
29634
29692
  }
@@ -29636,7 +29694,7 @@ function useHostColorScheme(host) {
29636
29694
  const [scheme, setScheme] = useState51(
29637
29695
  () => host != null && !host.isConnected ? null : schemeFromHost(host)
29638
29696
  );
29639
- useEffect41(() => {
29697
+ useEffect42(() => {
29640
29698
  if (host != null && !host.isConnected) {
29641
29699
  setScheme(null);
29642
29700
  const raf = requestAnimationFrame(() => {
@@ -29655,7 +29713,7 @@ function useHostColorScheme(host) {
29655
29713
  }
29656
29714
  function useEditorEditable(editor) {
29657
29715
  const [editable, setEditable] = useState51(editor.isEditable);
29658
- useEffect41(() => {
29716
+ useEffect42(() => {
29659
29717
  const sync = () => setEditable(editor.isEditable);
29660
29718
  editor.on("update", sync);
29661
29719
  editor.on("transaction", sync);
@@ -29818,7 +29876,7 @@ import { jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
29818
29876
  var nextModelInstanceId = 0;
29819
29877
  function useSvgIslandView(editor, blockId) {
29820
29878
  const [version, setVersion] = useState52(0);
29821
- useEffect42(() => {
29879
+ useEffect43(() => {
29822
29880
  const onTransaction = () => setVersion((value) => value + 1);
29823
29881
  editor.on("transaction", onTransaction);
29824
29882
  return () => {
@@ -29920,13 +29978,13 @@ import { Decoration as Decoration8, DecorationSet as DecorationSet8 } from "@tip
29920
29978
  import { createElement as createElement12 } from "react";
29921
29979
 
29922
29980
  // src/codeSnippet/CodeSnippetWidget.tsx
29923
- import { useCallback as useCallback38, useEffect as useEffect44, useRef as useRef43, useState as useState54 } from "react";
29981
+ import { useCallback as useCallback38, useEffect as useEffect45, useRef as useRef43, useState as useState54 } from "react";
29924
29982
 
29925
29983
  // src/codeSnippet/codeSnippetData.ts
29926
- import { useEffect as useEffect43, useMemo as useMemo34, useState as useState53 } from "react";
29984
+ import { useEffect as useEffect44, useMemo as useMemo34, useState as useState53 } from "react";
29927
29985
  function useCodeSnippetData(editor, blockId) {
29928
29986
  const [version, setVersion] = useState53(0);
29929
- useEffect43(() => {
29987
+ useEffect44(() => {
29930
29988
  const onTransaction = () => setVersion((value) => value + 1);
29931
29989
  editor.on("transaction", onTransaction);
29932
29990
  return () => {
@@ -29993,7 +30051,7 @@ function CodeSnippetWidget({
29993
30051
  sourceRef.current = data?.source ?? "";
29994
30052
  const languageRef = useRef43("");
29995
30053
  languageRef.current = data?.fenceLanguage ?? "";
29996
- useEffect44(
30054
+ useEffect45(
29997
30055
  () => () => {
29998
30056
  if (copyResetTimer.current !== void 0) clearTimeout(copyResetTimer.current);
29999
30057
  },
@@ -30238,7 +30296,7 @@ import { Decoration as Decoration9, DecorationSet as DecorationSet9 } from "@tip
30238
30296
  import { createElement as createElement13 } from "react";
30239
30297
 
30240
30298
  // src/fenceWidgets/HostFenceWidget.tsx
30241
- import { Component as Component2, useEffect as useEffect45, useMemo as useMemo35, useState as useState55 } from "react";
30299
+ import { Component as Component2, useEffect as useEffect46, useMemo as useMemo35, useState as useState55 } from "react";
30242
30300
  import { jsx as jsx61 } from "react/jsx-runtime";
30243
30301
  var HostFenceErrorBoundary = class extends Component2 {
30244
30302
  constructor() {
@@ -30254,7 +30312,7 @@ var HostFenceErrorBoundary = class extends Component2 {
30254
30312
  };
30255
30313
  function HostFenceWidget({ editor, blockId, getRenderers, getTheme }) {
30256
30314
  const [version, setVersion] = useState55(0);
30257
- useEffect45(() => {
30315
+ useEffect46(() => {
30258
30316
  const onUpdate = () => setVersion((v2) => v2 + 1);
30259
30317
  editor.on("transaction", onUpdate);
30260
30318
  return () => {
@@ -30727,7 +30785,7 @@ import { createElement as createElement14 } from "react";
30727
30785
  import { isDataFilePath } from "@bendyline/squisq/doc";
30728
30786
 
30729
30787
  // src/dataCard/DataCardWidget.tsx
30730
- import { useCallback as useCallback39, useEffect as useEffect46, useMemo as useMemo36, useRef as useRef44, useState as useState56 } from "react";
30788
+ import { useCallback as useCallback39, useEffect as useEffect47, useMemo as useMemo36, useRef as useRef44, useState as useState56 } from "react";
30731
30789
  import { EMPTY_TABLE_VIEW_STATE } from "@bendyline/squisq/table";
30732
30790
 
30733
30791
  // src/dataCard/gridSave.ts
@@ -31131,7 +31189,7 @@ var XLSX_SESSION_LOCKED_REASON = "Date cells and shared-formula masters stay loc
31131
31189
  var pendingFormulas = /* @__PURE__ */ new WeakMap();
31132
31190
  function useCardLink(editor, blockId) {
31133
31191
  const [version, setVersion] = useState56(0);
31134
- useEffect46(() => {
31192
+ useEffect47(() => {
31135
31193
  const bump = () => setVersion((v2) => v2 + 1);
31136
31194
  editor.on("transaction", bump);
31137
31195
  return () => {
@@ -31151,7 +31209,7 @@ function useCardLink(editor, blockId) {
31151
31209
  }
31152
31210
  function useMediaRevision(getMediaRevision) {
31153
31211
  const [revision, setRevision] = useState56(() => getMediaRevision());
31154
- useEffect46(() => {
31212
+ useEffect47(() => {
31155
31213
  const timer = window.setInterval(() => {
31156
31214
  const next = getMediaRevision();
31157
31215
  setRevision((prev) => prev === next ? prev : next);
@@ -31195,7 +31253,7 @@ function DataCardWidget({
31195
31253
  regionParams.anchor,
31196
31254
  regionParams.headerRow
31197
31255
  ]);
31198
- useEffect46(() => {
31256
+ useEffect47(() => {
31199
31257
  if (!href || cardPos === null) return;
31200
31258
  const provider = activeProvider;
31201
31259
  if (!provider) {
@@ -31357,7 +31415,7 @@ function DataCardWidget({
31357
31415
  cancelled = true;
31358
31416
  };
31359
31417
  }, [href, revision, activeProvider, activeContainer, regionIdentity, editor]);
31360
- useEffect46(
31418
+ useEffect47(
31361
31419
  () => () => {
31362
31420
  gridRef.current?.formulaSession?.dispose();
31363
31421
  gridRef.current?.provider.dispose();
@@ -32094,7 +32152,7 @@ function pasteVideoEmbedCode(view, text) {
32094
32152
  }
32095
32153
 
32096
32154
  // src/treeview/treeViewData.ts
32097
- import { useEffect as useEffect47, useMemo as useMemo37, useState as useState58 } from "react";
32155
+ import { useEffect as useEffect48, useMemo as useMemo37, useState as useState58 } from "react";
32098
32156
 
32099
32157
  // src/treeview/TreeViewExtension.ts
32100
32158
  import { Extension as Extension15 } from "@tiptap/core";
@@ -32803,7 +32861,7 @@ var TreeViewExtension = Extension15.create({
32803
32861
  // src/treeview/treeViewData.ts
32804
32862
  function useTreeViewData(editor, blockId) {
32805
32863
  const [version, setVersion] = useState58(0);
32806
- useEffect47(() => {
32864
+ useEffect48(() => {
32807
32865
  const onUpdate = () => setVersion((v2) => v2 + 1);
32808
32866
  editor.on("transaction", onUpdate);
32809
32867
  return () => {
@@ -32829,7 +32887,7 @@ function shouldPasteAsTreeFence(text) {
32829
32887
  }
32830
32888
 
32831
32889
  // src/timeline/timelineData.ts
32832
- import { useEffect as useEffect49, useMemo as useMemo39, useRef as useRef47, useState as useState60 } from "react";
32890
+ import { useEffect as useEffect50, useMemo as useMemo39, useRef as useRef47, useState as useState60 } from "react";
32833
32891
 
32834
32892
  // src/timeline/TimelineViewExtension.ts
32835
32893
  import { Extension as Extension16 } from "@tiptap/core";
@@ -32843,7 +32901,7 @@ import {
32843
32901
  } from "@bendyline/squisq/doc";
32844
32902
 
32845
32903
  // src/timeline/TimelineEditorWidget.tsx
32846
- import { useCallback as useCallback41, useEffect as useEffect48, useMemo as useMemo38, useRef as useRef46, useState as useState59 } from "react";
32904
+ import { useCallback as useCallback41, useEffect as useEffect49, useMemo as useMemo38, useRef as useRef46, useState as useState59 } from "react";
32847
32905
  import {
32848
32906
  asciiTimelineToTemplateData
32849
32907
  } from "@bendyline/squisq/doc";
@@ -33394,7 +33452,7 @@ function TimelineEditorWidget({ editor, blockId }) {
33394
33452
  }
33395
33453
  return null;
33396
33454
  }, [selectedEventId, view]);
33397
- useEffect48(() => {
33455
+ useEffect49(() => {
33398
33456
  if (!view) return;
33399
33457
  const ids = new Set(
33400
33458
  view.timeline.tracks.flatMap((track) => track.events.map((event) => event.id))
@@ -33402,13 +33460,13 @@ function TimelineEditorWidget({ editor, blockId }) {
33402
33460
  if (selectedEventId && ids.has(selectedEventId)) return;
33403
33461
  setSelectedEventId(view.timeline.tracks[0]?.events[0]?.id ?? null);
33404
33462
  }, [selectedEventId, view]);
33405
- useEffect48(() => {
33463
+ useEffect49(() => {
33406
33464
  if (editable) return;
33407
33465
  setAddingTrackId(null);
33408
33466
  setEditingTrackId(null);
33409
33467
  setHover(null);
33410
33468
  }, [editable]);
33411
- useEffect48(() => {
33469
+ useEffect49(() => {
33412
33470
  if (!editingTrackId || view?.timeline.tracks.some((track) => track.id === editingTrackId)) {
33413
33471
  return;
33414
33472
  }
@@ -33815,7 +33873,7 @@ function InlineTrackLabel({
33815
33873
  onFinish
33816
33874
  }) {
33817
33875
  const [draft, setDraft] = useState59(label);
33818
- useEffect48(() => {
33876
+ useEffect49(() => {
33819
33877
  if (editing) setDraft(label);
33820
33878
  }, [editing, label]);
33821
33879
  const commitLabel = () => {
@@ -33874,8 +33932,8 @@ function EventInspector({
33874
33932
  const { event } = selected;
33875
33933
  const [label, setLabel] = useState59(event.label);
33876
33934
  const [description, setDescription] = useState59(event.description ?? "");
33877
- useEffect48(() => setLabel(event.label), [event.label]);
33878
- useEffect48(() => setDescription(event.description ?? ""), [event.description]);
33935
+ useEffect49(() => setLabel(event.label), [event.label]);
33936
+ useEffect49(() => setDescription(event.description ?? ""), [event.description]);
33879
33937
  const update = (patch) => dispatch(patch);
33880
33938
  const commitLabel = () => {
33881
33939
  const next = label.trim();
@@ -34185,7 +34243,7 @@ var TimelineViewExtension = Extension16.create({
34185
34243
  function useTimelineData(editor, blockId) {
34186
34244
  const [version, setVersion] = useState60(0);
34187
34245
  const dataCache = useRef47(null);
34188
- useEffect49(() => {
34246
+ useEffect50(() => {
34189
34247
  const onEditorChange = () => setVersion((value) => value + 1);
34190
34248
  editor.on("transaction", onEditorChange);
34191
34249
  editor.on("update", onEditorChange);
@@ -34220,7 +34278,7 @@ function shouldPasteAsTimelineFence(text) {
34220
34278
  }
34221
34279
 
34222
34280
  // src/BlockPropertiesPopover.tsx
34223
- import { useEffect as useEffect50, useId as useId13, useRef as useRef48, useState as useState61 } from "react";
34281
+ import { useEffect as useEffect51, useId as useId13, useRef as useRef48, useState as useState61 } from "react";
34224
34282
  import { createPortal as createPortal14 } from "react-dom";
34225
34283
  import { Fragment as Fragment22, jsx as jsx65, jsxs as jsxs51 } from "react/jsx-runtime";
34226
34284
  var TRANSITION_FLYOUT = ".squisq-transition-flyout";
@@ -34239,10 +34297,10 @@ function BlockPropertiesPopover({
34239
34297
  const [inner, setInner] = useState61(blockAttrs);
34240
34298
  const [templateInner, setTemplateInner] = useState61(templateParams);
34241
34299
  const [style, setStyle] = useState61(() => computeStyle3(anchorRect));
34242
- useEffect50(() => {
34300
+ useEffect51(() => {
34243
34301
  requestAnimationFrame(() => setStyle(computeStyle3(anchorRect, panelRef.current)));
34244
34302
  }, [anchorRect]);
34245
- useEffect50(() => {
34303
+ useEffect51(() => {
34246
34304
  const onKey = (e2) => {
34247
34305
  if (e2.key === "Escape") onClose();
34248
34306
  };
@@ -34493,7 +34551,7 @@ function persistFromWrite(bodyMd, state) {
34493
34551
  }
34494
34552
 
34495
34553
  // src/WysiwygEditor.tsx
34496
- import { useCallback as useCallback43, useEffect as useEffect55, useMemo as useMemo42, useRef as useRef51, useState as useState67 } from "react";
34554
+ import { useCallback as useCallback43, useEffect as useEffect56, useMemo as useMemo42, useRef as useRef51, useState as useState67 } from "react";
34497
34555
  import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
34498
34556
  import { Selection as Selection2 } from "@tiptap/pm/state";
34499
34557
  import { Extension as Extension18, getHTMLFromFragment } from "@tiptap/core";
@@ -34538,7 +34596,7 @@ import Link2 from "@tiptap/extension-link";
34538
34596
  // src/WikiLink.tsx
34539
34597
  import { Node as Node2, InputRule } from "@tiptap/core";
34540
34598
  import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
34541
- import { useEffect as useEffect51, useState as useState62 } from "react";
34599
+ import { useEffect as useEffect52, useState as useState62 } from "react";
34542
34600
  import { wikiLinkPath as wikiLinkPath3, parseWikiLink as parseWikiLink3 } from "@bendyline/squisq/markdown";
34543
34601
 
34544
34602
  // src/wikiSuggestionPlugin.ts
@@ -34711,7 +34769,7 @@ function WikiLinkView({ node: node2, editor }) {
34711
34769
  const [exists, setExists] = useState62(null);
34712
34770
  const [error, setError] = useState62("");
34713
34771
  const [busy, setBusy] = useState62(false);
34714
- useEffect51(() => {
34772
+ useEffect52(() => {
34715
34773
  let cancelled = false;
34716
34774
  setExists(null);
34717
34775
  setError("");
@@ -34906,7 +34964,7 @@ var InlineIcon = Node3.create({
34906
34964
  });
34907
34965
 
34908
34966
  // src/ImageNodeView.tsx
34909
- import { useEffect as useEffect52, useRef as useRef49, useState as useState63 } from "react";
34967
+ import { useEffect as useEffect53, useRef as useRef49, useState as useState63 } from "react";
34910
34968
  import { NodeViewWrapper as NodeViewWrapper2, ReactNodeViewRenderer as ReactNodeViewRenderer2 } from "@tiptap/react";
34911
34969
  import Image from "@tiptap/extension-image";
34912
34970
  import { mergeAttributes as mergeAttributes3 } from "@tiptap/core";
@@ -34940,7 +34998,7 @@ function ImageComponent({ node: node2, selected, editor, updateAttributes }) {
34940
34998
  const sanitizedSvg = useSanitizedSvgImage(loadedSrc, isSvg);
34941
34999
  const resolvedSrc = sanitizedSvg ?? "";
34942
35000
  const resolutionFailed = needsResolution && currentResolution?.url === null || sanitizedSvg === null;
34943
- useEffect52(() => {
35001
+ useEffect53(() => {
34944
35002
  if (isUploading || !mediaProvider || !resolveAs) return;
34945
35003
  setImageLoad(null);
34946
35004
  let cancelled = false;
@@ -35279,15 +35337,15 @@ function MediaEditButton({ src, kind, fx, className }) {
35279
35337
 
35280
35338
  // src/tiptap/TiptapVideo.tsx
35281
35339
  import { NodeViewWrapper as NodeViewWrapper3, ReactNodeViewRenderer as ReactNodeViewRenderer3 } from "@tiptap/react";
35282
- import { useEffect as useEffect54, useState as useState65 } from "react";
35340
+ import { useEffect as useEffect55, useState as useState65 } from "react";
35283
35341
 
35284
35342
  // src/tiptap/useResolvedMediaSrc.ts
35285
- import { useEffect as useEffect53, useState as useState64 } from "react";
35343
+ import { useEffect as useEffect54, useState as useState64 } from "react";
35286
35344
  function useResolvedMediaSrc(src) {
35287
35345
  const { mediaProvider, mediaRevision } = useEditorContext();
35288
35346
  const isRelative = !!src && !src.startsWith("blob:") && !src.startsWith("http:") && !src.startsWith("https:") && !src.startsWith("data:") && !src.startsWith("/");
35289
35347
  const [resolved, setResolved] = useState64(isRelative && mediaProvider ? "" : src);
35290
- useEffect53(() => {
35348
+ useEffect54(() => {
35291
35349
  if (!mediaProvider || !isRelative) {
35292
35350
  setResolved(src);
35293
35351
  return;
@@ -35346,7 +35404,7 @@ function VideoMedia({
35346
35404
  const resolvedSrc = useResolvedMediaSrc(src ?? "");
35347
35405
  const [audioOnly, setAudioOnly] = useState65(false);
35348
35406
  const resolvedPoster = useResolvedMediaSrc(poster ?? "");
35349
- useEffect54(() => {
35407
+ useEffect55(() => {
35350
35408
  setAudioOnly(false);
35351
35409
  }, [resolvedSrc]);
35352
35410
  const handleLoadedMetadata = (event) => {
@@ -36653,7 +36711,7 @@ function WysiwygEditor({
36653
36711
  mermaidThemeStoreRef.current = createMermaidThemeStore(activeTheme ?? DEFAULT_THEME4);
36654
36712
  }
36655
36713
  const mermaidThemeStore = mermaidThemeStoreRef.current;
36656
- useEffect55(() => {
36714
+ useEffect56(() => {
36657
36715
  mermaidThemeStore.setTheme(activeTheme ?? DEFAULT_THEME4);
36658
36716
  }, [activeTheme, mermaidThemeStore]);
36659
36717
  const { docTemplates, onDocTemplatesChange } = useDocCustomTemplates();
@@ -36673,19 +36731,19 @@ function WysiwygEditor({
36673
36731
  [docTemplates, onDocTemplatesChange]
36674
36732
  );
36675
36733
  const mentionProviderRef = useRef51(mentionProvider);
36676
- useEffect55(() => {
36734
+ useEffect56(() => {
36677
36735
  mentionProviderRef.current = mentionProvider;
36678
36736
  }, [mentionProvider]);
36679
36737
  const fenceRenderersRef = useRef51(fenceRenderers);
36680
- useEffect55(() => {
36738
+ useEffect56(() => {
36681
36739
  fenceRenderersRef.current = fenceRenderers;
36682
36740
  }, [fenceRenderers]);
36683
36741
  const onCopyCodeRef = useRef51(onCopyCode);
36684
- useEffect55(() => {
36742
+ useEffect56(() => {
36685
36743
  onCopyCodeRef.current = onCopyCode;
36686
36744
  }, [onCopyCode]);
36687
36745
  const activeThemeRef = useRef51(activeTheme);
36688
- useEffect55(() => {
36746
+ useEffect56(() => {
36689
36747
  activeThemeRef.current = activeTheme;
36690
36748
  }, [activeTheme]);
36691
36749
  const resolvedPlaceholder = useMemo42(() => placeholder ?? pickEmptyPrompt(), [placeholder]);
@@ -36696,30 +36754,30 @@ function WysiwygEditor({
36696
36754
  const pendingLocalSourcesRef = useRef51([]);
36697
36755
  const mediaProviderRef = useRef51(mediaProvider);
36698
36756
  const mediaRevisionRef = useRef51(mediaRevision);
36699
- useEffect55(() => {
36757
+ useEffect56(() => {
36700
36758
  mediaRevisionRef.current = mediaRevision;
36701
36759
  }, [mediaRevision]);
36702
36760
  const onOpenFilesPanelRef = useRef51(onOpenFilesPanel);
36703
- useEffect55(() => {
36761
+ useEffect56(() => {
36704
36762
  onOpenFilesPanelRef.current = onOpenFilesPanel;
36705
36763
  }, [onOpenFilesPanel]);
36706
36764
  const calcEngineFactoryRef = useRef51(calcEngineFactory);
36707
- useEffect55(() => {
36765
+ useEffect56(() => {
36708
36766
  calcEngineFactoryRef.current = calcEngineFactory;
36709
36767
  }, [calcEngineFactory]);
36710
36768
  const workspaceContainerRef = useRef51(workspaceContainer);
36711
- useEffect55(() => {
36769
+ useEffect56(() => {
36712
36770
  workspaceContainerRef.current = workspaceContainer;
36713
36771
  }, [workspaceContainer]);
36714
36772
  const bumpMediaRevisionRef = useRef51(bumpMediaRevision);
36715
- useEffect55(() => {
36773
+ useEffect56(() => {
36716
36774
  bumpMediaRevisionRef.current = bumpMediaRevision;
36717
36775
  }, [bumpMediaRevision]);
36718
- useEffect55(() => {
36776
+ useEffect56(() => {
36719
36777
  mediaProviderRef.current = mediaProvider;
36720
36778
  }, [mediaProvider]);
36721
36779
  const [accessoryPaths, setAccessoryPaths] = useState67(() => /* @__PURE__ */ new Set());
36722
- useEffect55(() => {
36780
+ useEffect56(() => {
36723
36781
  if (!mediaProvider) {
36724
36782
  setAccessoryPaths(/* @__PURE__ */ new Set());
36725
36783
  return;
@@ -36759,7 +36817,7 @@ function WysiwygEditor({
36759
36817
  initialContentRef.current = markdownToTiptap(initialDisplayBodyRef.current);
36760
36818
  }
36761
36819
  const submitOnEnterRef = useRef51(submitOnEnter);
36762
- useEffect55(() => {
36820
+ useEffect56(() => {
36763
36821
  submitOnEnterRef.current = submitOnEnter;
36764
36822
  }, [submitOnEnter]);
36765
36823
  const editor = useEditor2({
@@ -36991,7 +37049,7 @@ function WysiwygEditor({
36991
37049
  }
36992
37050
  }
36993
37051
  });
36994
- useEffect55(() => {
37052
+ useEffect56(() => {
36995
37053
  let cancelled = false;
36996
37054
  queueMicrotask(() => {
36997
37055
  if (!cancelled && editor && !editor.isDestroyed)
@@ -37001,13 +37059,13 @@ function WysiwygEditor({
37001
37059
  cancelled = true;
37002
37060
  };
37003
37061
  }, [editor, wikiLinks]);
37004
- useEffect55(() => {
37062
+ useEffect56(() => {
37005
37063
  if (editor) {
37006
37064
  setTiptapEditor(editor);
37007
37065
  }
37008
37066
  return () => setTiptapEditor(null);
37009
37067
  }, [editor, setTiptapEditor]);
37010
- useEffect55(() => {
37068
+ useEffect56(() => {
37011
37069
  if (!editor) return;
37012
37070
  const syncPlaceholders = () => {
37013
37071
  syncAccessoryFileLinkPlaceholders(editor.view.dom, accessoryPaths);
@@ -37018,7 +37076,7 @@ function WysiwygEditor({
37018
37076
  editor.off("update", syncPlaceholders);
37019
37077
  };
37020
37078
  }, [accessoryPaths, editor]);
37021
- useEffect55(() => {
37079
+ useEffect56(() => {
37022
37080
  if (editor) editor.setEditable(!readOnly);
37023
37081
  }, [editor, readOnly]);
37024
37082
  const containerRef = useRef51(null);
@@ -37030,7 +37088,7 @@ function WysiwygEditor({
37030
37088
  if (editor && !editor.isDestroyed) editor.commands.focus();
37031
37089
  });
37032
37090
  }, [editor]);
37033
- useEffect55(() => {
37091
+ useEffect56(() => {
37034
37092
  if (!editor) return;
37035
37093
  const root = containerRef.current;
37036
37094
  if (!root) return;
@@ -37086,7 +37144,7 @@ function WysiwygEditor({
37086
37144
  root.addEventListener("mousedown", onClick);
37087
37145
  return () => root.removeEventListener("mousedown", onClick);
37088
37146
  }, [editor]);
37089
- useEffect55(() => {
37147
+ useEffect56(() => {
37090
37148
  if (!editor) return;
37091
37149
  const previousLayout = sourceLayoutRef.current;
37092
37150
  const layoutChanged = previousLayout !== layoutMode;
@@ -37197,7 +37255,7 @@ function WysiwygEditor({
37197
37255
  }
37198
37256
  return out;
37199
37257
  }, [activeTheme, themeInheritance]);
37200
- useEffect55(() => {
37258
+ useEffect56(() => {
37201
37259
  if (!editor || editor.isDestroyed) return;
37202
37260
  editor.view.dispatch(editor.state.tr.setMeta(DOCUMENT_TRAY_KEY, layoutMode === "document"));
37203
37261
  }, [editor, layoutMode]);
@@ -37436,14 +37494,14 @@ import { VIEWPORT_PRESETS as VIEWPORT_PRESETS5 } from "@bendyline/squisq/schemas
37436
37494
  import { BlockRenderer as BlockRenderer3, MediaContext as MediaContext4 } from "@bendyline/squisq-react";
37437
37495
 
37438
37496
  // src/useHeadingLayout.ts
37439
- import { useCallback as useCallback44, useEffect as useEffect56, useMemo as useMemo43, useState as useState68 } from "react";
37497
+ import { useCallback as useCallback44, useEffect as useEffect57, useMemo as useMemo43, useState as useState68 } from "react";
37440
37498
  import { flattenBlocks as flattenBlocks3, hasTemplate } from "@bendyline/squisq/doc";
37441
37499
  function useHeadingLayout(refInsideWrapper) {
37442
37500
  const { doc, activeView, monacoEditor, tiptapEditor } = useEditorContext();
37443
37501
  const flatBlocks = useMemo43(() => doc ? flattenBlocks3(doc.blocks) : [], [doc]);
37444
37502
  const [entries, setEntries] = useState68([]);
37445
37503
  const [pageEdges, setPageEdges] = useState68(null);
37446
- useEffect56(() => {
37504
+ useEffect57(() => {
37447
37505
  if (activeView !== "wysiwyg") return;
37448
37506
  const node2 = refInsideWrapper.current;
37449
37507
  if (!node2) return;
@@ -37511,7 +37569,7 @@ function useHeadingLayout(refInsideWrapper) {
37511
37569
  window.removeEventListener("resize", recompute);
37512
37570
  };
37513
37571
  }, [activeView, flatBlocks, refInsideWrapper]);
37514
- useEffect56(() => {
37572
+ useEffect57(() => {
37515
37573
  if (activeView !== "raw") return;
37516
37574
  if (!monacoEditor) return;
37517
37575
  const node2 = refInsideWrapper.current;
@@ -37572,7 +37630,7 @@ function useHeadingLayout(refInsideWrapper) {
37572
37630
  window.removeEventListener("resize", recompute);
37573
37631
  };
37574
37632
  }, [activeView, monacoEditor, flatBlocks, refInsideWrapper]);
37575
- useEffect56(() => {
37633
+ useEffect57(() => {
37576
37634
  setEntries([]);
37577
37635
  setPageEdges(null);
37578
37636
  }, [activeView]);
@@ -37656,7 +37714,7 @@ import { flattenRenderableBlocks, DEFAULT_THEME as DEFAULT_THEME5 } from "@bendy
37656
37714
  import { extractPlainText as extractPlainText3 } from "@bendyline/squisq/markdown";
37657
37715
 
37658
37716
  // src/usePreviewProjection.ts
37659
- import { useEffect as useEffect57, useState as useState69 } from "react";
37717
+ import { useEffect as useEffect58, useState as useState69 } from "react";
37660
37718
  import {
37661
37719
  resolveAudioMapping,
37662
37720
  resolveDataReferences
@@ -37703,7 +37761,7 @@ function preserveEquivalentAudio(previous, next) {
37703
37761
  }
37704
37762
  function usePreviewProjection(doc, transformStyle, workspaceContainer, documentTitle2, mediaRevision) {
37705
37763
  const [projection, setProjection] = useState69(null);
37706
- useEffect57(() => {
37764
+ useEffect58(() => {
37707
37765
  if (!doc || !doc.blocks.length) {
37708
37766
  setProjection(null);
37709
37767
  return;
@@ -37982,7 +38040,7 @@ function InlinePreviewGutter({
37982
38040
  import {
37983
38041
  memo,
37984
38042
  useCallback as useCallback45,
37985
- useEffect as useEffect58,
38043
+ useEffect as useEffect59,
37986
38044
  useMemo as useMemo46,
37987
38045
  useRef as useRef53,
37988
38046
  useState as useState71
@@ -38455,10 +38513,10 @@ function useActiveOutlineBlockId() {
38455
38513
  flatBlocksRef.current = flatBlocks;
38456
38514
  const headingLocations = flatBlocks.map((block) => `${block.id}:${block.sourceHeading?.position?.start.line ?? ""}`).join("\0");
38457
38515
  const [activeId, setActiveId] = useState71(null);
38458
- useEffect58(() => {
38516
+ useEffect59(() => {
38459
38517
  setActiveId(null);
38460
38518
  }, [activeView]);
38461
- useEffect58(() => {
38519
+ useEffect59(() => {
38462
38520
  if (activeView !== "wysiwyg" || !tiptapEditor) return;
38463
38521
  const update = () => {
38464
38522
  const { from } = tiptapEditor.state.selection;
@@ -38480,7 +38538,7 @@ function useActiveOutlineBlockId() {
38480
38538
  tiptapEditor.off("update", update);
38481
38539
  };
38482
38540
  }, [activeView, tiptapEditor, headingLocations]);
38483
- useEffect58(() => {
38541
+ useEffect59(() => {
38484
38542
  if (activeView !== "raw" || !monacoEditor) return;
38485
38543
  const update = () => {
38486
38544
  const line = monacoEditor.getPosition()?.lineNumber;
@@ -38567,7 +38625,7 @@ function bumpHeadingLevelInSource(source, line, delta) {
38567
38625
  }
38568
38626
 
38569
38627
  // src/codeContext/CodeContextZones.tsx
38570
- import { useCallback as useCallback47, useEffect as useEffect60, useMemo as useMemo48, useRef as useRef55, useState as useState72 } from "react";
38628
+ import { useCallback as useCallback47, useEffect as useEffect61, useMemo as useMemo48, useRef as useRef55, useState as useState72 } from "react";
38571
38629
  import { createPortal as createPortal15 } from "react-dom";
38572
38630
 
38573
38631
  // src/codeContext/diffContextSections.ts
@@ -38691,7 +38749,7 @@ function setOrdinal(zone, ordinal) {
38691
38749
  // src/codeContext/CodeContextSectionView.tsx
38692
38750
  import { parseMarkdown as parseMarkdown8 } from "@bendyline/squisq/markdown";
38693
38751
  import { MarkdownRenderer } from "@bendyline/squisq-react";
38694
- import { useCallback as useCallback46, useEffect as useEffect59, useMemo as useMemo47, useRef as useRef54 } from "react";
38752
+ import { useCallback as useCallback46, useEffect as useEffect60, useMemo as useMemo47, useRef as useRef54 } from "react";
38695
38753
  import { jsx as jsx75, jsxs as jsxs61 } from "react/jsx-runtime";
38696
38754
  function CodeContextSectionView({
38697
38755
  section,
@@ -38711,7 +38769,7 @@ function CodeContextSectionView({
38711
38769
  () => expanded && section.markdown ? parseMarkdown8(section.markdown).children : null,
38712
38770
  [expanded, section.markdown]
38713
38771
  );
38714
- useEffect59(() => {
38772
+ useEffect60(() => {
38715
38773
  const el = rootRef.current;
38716
38774
  if (!el || typeof ResizeObserver === "undefined") return;
38717
38775
  const report = () => {
@@ -38787,7 +38845,7 @@ function CodeContextZones({ options }) {
38787
38845
  const [, setZonesVersion] = useState72(0);
38788
38846
  const [expandedById, setExpandedById] = useState72({});
38789
38847
  const seenIds = useRef55(/* @__PURE__ */ new Set());
38790
- useEffect60(() => {
38848
+ useEffect61(() => {
38791
38849
  if (!monacoEditor) return;
38792
38850
  const mgr = new CodeContextZoneManager(monacoEditor);
38793
38851
  const off = mgr.onDidChangeZones(() => setZonesVersion((v2) => v2 + 1));
@@ -38810,7 +38868,7 @@ function CodeContextZones({ options }) {
38810
38868
  });
38811
38869
  return out;
38812
38870
  }, [fileTop, sections]);
38813
- useEffect60(() => {
38871
+ useEffect61(() => {
38814
38872
  if (!manager) return;
38815
38873
  manager.sync(resolved.map((r) => r.spec));
38816
38874
  setExpandedById((prev) => {
@@ -39276,7 +39334,7 @@ function placeClipInBlock(source, fromLine, targetHeadingLine, spec, startAt) {
39276
39334
  }
39277
39335
 
39278
39336
  // src/TimelineTrack.tsx
39279
- import { useCallback as useCallback49, useEffect as useEffect63, useMemo as useMemo49, useRef as useRef58, useState as useState75 } from "react";
39337
+ import { useCallback as useCallback49, useEffect as useEffect64, useMemo as useMemo49, useRef as useRef58, useState as useState75 } from "react";
39280
39338
  import {
39281
39339
  resolveMediaSchedule as resolveMediaSchedule2,
39282
39340
  getDocPlaybackDuration,
@@ -39289,7 +39347,7 @@ import { useProcessedAudio as useProcessedAudio2 } from "@bendyline/squisq-video
39289
39347
  import { MediaClipLayer, MediaContext as MediaContext5 } from "@bendyline/squisq-react";
39290
39348
 
39291
39349
  // src/useTimelineClock.ts
39292
- import { useCallback as useCallback48, useEffect as useEffect61, useRef as useRef56, useState as useState73 } from "react";
39350
+ import { useCallback as useCallback48, useEffect as useEffect62, useRef as useRef56, useState as useState73 } from "react";
39293
39351
  function advanceTime(prev, dt, total) {
39294
39352
  if (total <= 0) return 0;
39295
39353
  return Math.min(total, Math.max(0, prev + dt));
@@ -39318,10 +39376,10 @@ function useTimelineClock(total) {
39318
39376
  const mediaHostRef = useRef56(null);
39319
39377
  currentTimeRef.current = currentTime;
39320
39378
  isPlayingRef.current = isPlaying;
39321
- useEffect61(() => {
39379
+ useEffect62(() => {
39322
39380
  setCurrentTime((t) => Math.min(t, Math.max(0, total)));
39323
39381
  }, [total]);
39324
- useEffect61(() => {
39382
+ useEffect62(() => {
39325
39383
  if (!isPlaying) return;
39326
39384
  lastRef.current = performance.now();
39327
39385
  const tick = (now) => {
@@ -39419,7 +39477,7 @@ function timelineBars(clips) {
39419
39477
  }
39420
39478
 
39421
39479
  // src/TimelineItemMenu.tsx
39422
- import { useEffect as useEffect62, useLayoutEffect as useLayoutEffect14, useRef as useRef57, useState as useState74 } from "react";
39480
+ import { useEffect as useEffect63, useLayoutEffect as useLayoutEffect14, useRef as useRef57, useState as useState74 } from "react";
39423
39481
  import { createPortal as createPortal16 } from "react-dom";
39424
39482
  import { Fragment as Fragment27, jsx as jsx78, jsxs as jsxs63 } from "react/jsx-runtime";
39425
39483
  function TimelineItemMenu({
@@ -39450,7 +39508,7 @@ function TimelineItemMenu({
39450
39508
  resizeObserver?.disconnect();
39451
39509
  };
39452
39510
  }, [anchor]);
39453
- useEffect62(() => {
39511
+ useEffect63(() => {
39454
39512
  const onKeyDown = (event) => {
39455
39513
  if (event.key !== "Escape") return;
39456
39514
  event.preventDefault();
@@ -39938,7 +39996,7 @@ function TimelineTrack({
39938
39996
  play();
39939
39997
  }, [play]);
39940
39998
  const [scrubbing, setScrubbing] = useState75(false);
39941
- useEffect63(() => {
39999
+ useEffect64(() => {
39942
40000
  if (!scrubbing) return;
39943
40001
  const onMove = (e2) => {
39944
40002
  const scroll = scrollRef.current;
@@ -39976,7 +40034,7 @@ function TimelineTrack({
39976
40034
  [blocks]
39977
40035
  );
39978
40036
  const followedBlockRef = useRef58(null);
39979
- useEffect63(() => {
40037
+ useEffect64(() => {
39980
40038
  if (!isPlaying) {
39981
40039
  followedBlockRef.current = null;
39982
40040
  return;
@@ -39987,7 +40045,7 @@ function TimelineTrack({
39987
40045
  const line = headingLine(block);
39988
40046
  if (line != null) goToBlockByLine(line);
39989
40047
  }, [isPlaying, currentTime, blockAtTime, goToBlockByLine]);
39990
- useEffect63(() => {
40048
+ useEffect64(() => {
39991
40049
  if (!isPlaying) return;
39992
40050
  const scroll = scrollRef.current;
39993
40051
  if (!scroll) return;
@@ -40036,7 +40094,7 @@ function TimelineTrack({
40036
40094
  const zoomIn = useCallback49(() => setPxPerSecond((s) => Math.min(ZOOM_MAX, s * ZOOM_FACTOR)), []);
40037
40095
  const zoomOut = useCallback49(() => setPxPerSecond((s) => Math.max(ZOOM_MIN, s / ZOOM_FACTOR)), []);
40038
40096
  const [viewportWidth, setViewportWidth] = useState75(0);
40039
- useEffect63(() => {
40097
+ useEffect64(() => {
40040
40098
  const el = scrollRef.current;
40041
40099
  if (!el || typeof ResizeObserver === "undefined") return;
40042
40100
  const update = () => setViewportWidth(el.clientWidth);
@@ -40050,7 +40108,7 @@ function TimelineTrack({
40050
40108
  const dragRef = useRef58(null);
40051
40109
  dragRef.current = drag;
40052
40110
  const isDragging = drag != null && !drag.committed;
40053
- useEffect63(() => {
40111
+ useEffect64(() => {
40054
40112
  if (!isDragging) return;
40055
40113
  const onMove = (e2) => {
40056
40114
  const d = dragRef.current;
@@ -40081,7 +40139,7 @@ function TimelineTrack({
40081
40139
  window.removeEventListener("pointerup", onUp);
40082
40140
  };
40083
40141
  }, [isDragging]);
40084
- useEffect63(() => {
40142
+ useEffect64(() => {
40085
40143
  if (dragRef.current?.committed) setDrag(null);
40086
40144
  }, [doc]);
40087
40145
  const beginDrag = useCallback49(
@@ -40943,7 +41001,7 @@ function TimelineToolbar({
40943
41001
  }
40944
41002
 
40945
41003
  // src/PlainHtmlPreview.tsx
40946
- import { useCallback as useCallback50, useEffect as useEffect64, useMemo as useMemo52, useRef as useRef59, useState as useState76 } from "react";
41004
+ import { useCallback as useCallback50, useEffect as useEffect65, useMemo as useMemo52, useRef as useRef59, useState as useState76 } from "react";
40947
41005
  import {
40948
41006
  isSvgImageSource as isSvgImageSource2,
40949
41007
  parseMarkdown as parseMarkdown9,
@@ -41003,13 +41061,15 @@ function loadRenderFn() {
41003
41061
  var preparationPromise = null;
41004
41062
  function loadPreparation() {
41005
41063
  preparationPromise ?? (preparationPromise = Promise.all([
41006
- import("@bendyline/squisq-formats/html"),
41064
+ import("@bendyline/squisq-formats/html-prepare"),
41065
+ import("@bendyline/squisq-formats/html-icons"),
41007
41066
  import("@bendyline/squisq-formats/diagrams"),
41008
41067
  import("@bendyline/squisq-react/diagram-pictures")
41009
- ]).then(([html, diagrams, pictures]) => ({
41010
- needs: html.needsPlainHtmlPreparation,
41011
- prepare: html.prepareMarkdownDocForPlainHtml,
41012
- renderDiagram: diagrams.cachingDiagramRasterizer(pictures.createDiagramPictureRenderer())
41068
+ ]).then(([prep, icons, diagrams, pictures]) => ({
41069
+ needs: prep.needsPlainHtmlPreparation,
41070
+ prepare: prep.prepareMarkdownDocForPlainHtml,
41071
+ renderDiagram: diagrams.cachingDiagramRasterizer(pictures.createDiagramPictureRenderer()),
41072
+ outlineIcons: icons.plainHtmlIcons
41013
41073
  })));
41014
41074
  return preparationPromise;
41015
41075
  }
@@ -41051,7 +41111,7 @@ function PlainHtmlPreview({
41051
41111
  const parsedDoc = useMemo52(() => parseMarkdown9(markdown), [markdown]);
41052
41112
  const [wikiProjection, setWikiProjection] = useState76(null);
41053
41113
  const mdDoc = wikiProjection?.source === parsedDoc && wikiProjection.support === wikiLinks ? wikiProjection.doc : parsedDoc;
41054
- useEffect64(() => {
41114
+ useEffect65(() => {
41055
41115
  if (!wikiLinks) return;
41056
41116
  let cancelled = false;
41057
41117
  void resolveWikiLinks(
@@ -41070,7 +41130,7 @@ function PlainHtmlPreview({
41070
41130
  };
41071
41131
  }, [parsedDoc, wikiLinks]);
41072
41132
  const [resolvedImages, setResolvedImages] = useState76(null);
41073
- useEffect64(() => {
41133
+ useEffect65(() => {
41074
41134
  if (!mediaProvider) {
41075
41135
  setResolvedImages(null);
41076
41136
  return;
@@ -41107,7 +41167,7 @@ function PlainHtmlPreview({
41107
41167
  }, [resolvedImages, images]);
41108
41168
  const iconsCss = useMemo52(() => collectInlineFontAwesomeCss(), []);
41109
41169
  const [preparation, setPreparation] = useState76(null);
41110
- useEffect64(() => {
41170
+ useEffect65(() => {
41111
41171
  let cancelled = false;
41112
41172
  loadPreparation().then(
41113
41173
  (loaded) => {
@@ -41125,17 +41185,22 @@ function PlainHtmlPreview({
41125
41185
  [container, mediaRevision]
41126
41186
  );
41127
41187
  const needsPreparation = useMemo52(
41128
- () => preparation?.needs(mdDoc, { renderDiagram: preparation.renderDiagram, container }) ?? false,
41188
+ () => preparation?.needs(mdDoc, {
41189
+ renderDiagram: preparation.renderDiagram,
41190
+ outlineIcons: preparation.outlineIcons,
41191
+ container
41192
+ }) ?? false,
41129
41193
  [preparation, mdDoc, container]
41130
41194
  );
41131
41195
  const [prepared, setPrepared] = useState76(null);
41132
41196
  const preparedOnceRef = useRef59(false);
41133
- useEffect64(() => {
41197
+ useEffect65(() => {
41134
41198
  if (!preparation || !needsPreparation) return;
41135
41199
  let cancelled = false;
41136
41200
  const prepare = () => {
41137
41201
  preparation.prepare(mdDoc, {
41138
41202
  renderDiagram: preparation.renderDiagram,
41203
+ outlineIcons: preparation.outlineIcons,
41139
41204
  container,
41140
41205
  dataTableCache
41141
41206
  }).then(
@@ -41157,7 +41222,7 @@ function PlainHtmlPreview({
41157
41222
  }, [preparation, needsPreparation, mdDoc, container, dataTableCache]);
41158
41223
  const view = needsPreparation ? prepared : null;
41159
41224
  const [renderFn, setRenderFn] = useState76(() => cachedRender);
41160
- useEffect64(() => {
41225
+ useEffect65(() => {
41161
41226
  if (renderFn) return;
41162
41227
  let cancelled = false;
41163
41228
  loadRenderFn().then((fn) => {
@@ -41198,7 +41263,7 @@ function PlainHtmlPreview({
41198
41263
  frameDocument.addEventListener("click", handleClick, true);
41199
41264
  removeFrameLinkHandlerRef.current = () => frameDocument.removeEventListener("click", handleClick, true);
41200
41265
  }, [onLinkClick]);
41201
- useEffect64(() => {
41266
+ useEffect65(() => {
41202
41267
  installFrameLinkHandler();
41203
41268
  return () => removeFrameLinkHandlerRef.current();
41204
41269
  }, [html, installFrameLinkHandler]);
@@ -41294,11 +41359,11 @@ function PlainHtmlPreview({
41294
41359
  style2.remove();
41295
41360
  };
41296
41361
  }, [onCopyCode, showCodeCopyButton]);
41297
- useEffect64(() => {
41362
+ useEffect65(() => {
41298
41363
  installFrameCodeCopyControls();
41299
41364
  return () => removeFrameCodeCopyControlsRef.current();
41300
41365
  }, [html, installFrameCodeCopyControls]);
41301
- useEffect64(() => {
41366
+ useEffect65(() => {
41302
41367
  if (!globalKeyboardShortcuts) return;
41303
41368
  const handleKeyDown = (event) => {
41304
41369
  if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.key !== "ArrowDown" && event.key !== "ArrowUp") {
@@ -41383,7 +41448,7 @@ function collectImageRefs(doc) {
41383
41448
  }
41384
41449
 
41385
41450
  // src/PreviewPanel.tsx
41386
- import { useState as useState80, useEffect as useEffect69, useMemo as useMemo57, useCallback as useCallback54, useRef as useRef63 } from "react";
41451
+ import { useState as useState80, useEffect as useEffect70, useMemo as useMemo57, useCallback as useCallback54, useRef as useRef63 } from "react";
41387
41452
  import { createPortal as createPortal18 } from "react-dom";
41388
41453
  import {
41389
41454
  DashboardView,
@@ -41528,7 +41593,7 @@ import {
41528
41593
  createContext as createContext7,
41529
41594
  useCallback as useCallback51,
41530
41595
  useContext as useContext7,
41531
- useEffect as useEffect65,
41596
+ useEffect as useEffect66,
41532
41597
  useId as useId15,
41533
41598
  useLayoutEffect as useLayoutEffect15,
41534
41599
  useMemo as useMemo53,
@@ -41795,12 +41860,12 @@ function PresentationModeProvider({
41795
41860
  },
41796
41861
  [availableTargets, selectedTarget, stop]
41797
41862
  );
41798
- useEffect65(() => {
41863
+ useEffect66(() => {
41799
41864
  if (availableTargets.includes(selectedTarget)) return;
41800
41865
  setSelectedTarget("control");
41801
41866
  if (activeTargetRef.current !== null) void stop();
41802
41867
  }, [availableTargets, selectedTarget, stop]);
41803
- useEffect65(() => {
41868
+ useEffect66(() => {
41804
41869
  const root = rootRef.current;
41805
41870
  const ownerDocument = root?.ownerDocument;
41806
41871
  if (!root || !ownerDocument) return;
@@ -41812,7 +41877,7 @@ function PresentationModeProvider({
41812
41877
  ownerDocument.addEventListener("fullscreenchange", handleFullscreenChange);
41813
41878
  return () => ownerDocument.removeEventListener("fullscreenchange", handleFullscreenChange);
41814
41879
  }, [rootRef]);
41815
- useEffect65(() => {
41880
+ useEffect66(() => {
41816
41881
  const root = rootRef.current;
41817
41882
  if (!root) return;
41818
41883
  if (activeTarget) root.dataset.presentationMode = activeTarget;
@@ -41821,10 +41886,10 @@ function PresentationModeProvider({
41821
41886
  delete root.dataset.presentationMode;
41822
41887
  };
41823
41888
  }, [activeTarget, rootRef]);
41824
- useEffect65(() => {
41889
+ useEffect66(() => {
41825
41890
  if (activeView !== "preview" && activeTargetRef.current !== null) void stop();
41826
41891
  }, [activeView, stop]);
41827
- useEffect65(() => {
41892
+ useEffect66(() => {
41828
41893
  const previous = previousActiveTargetRef.current;
41829
41894
  previousActiveTargetRef.current = activeTarget;
41830
41895
  if (previous === null || activeTarget !== null) return;
@@ -41832,7 +41897,7 @@ function PresentationModeProvider({
41832
41897
  returnFocusRef.current = null;
41833
41898
  if (target?.isConnected) target.focus();
41834
41899
  }, [activeTarget]);
41835
- useEffect65(() => {
41900
+ useEffect66(() => {
41836
41901
  if (activeTarget !== "control") return;
41837
41902
  const ownerDocument = rootRef.current?.ownerDocument;
41838
41903
  if (!ownerDocument) return;
@@ -41844,7 +41909,7 @@ function PresentationModeProvider({
41844
41909
  ownerDocument.addEventListener("keydown", handleKeyDown);
41845
41910
  return () => ownerDocument.removeEventListener("keydown", handleKeyDown);
41846
41911
  }, [activeTarget, rootRef, stop]);
41847
- useEffect65(() => {
41912
+ useEffect66(() => {
41848
41913
  if (!error) return;
41849
41914
  const timer = window.setTimeout(() => setError(null), 6e3);
41850
41915
  return () => window.clearTimeout(timer);
@@ -41879,7 +41944,7 @@ function PresentationModeProvider({
41879
41944
  window.removeEventListener("resize", updatePosition);
41880
41945
  };
41881
41946
  }, [activeTarget, rootRef]);
41882
- useEffect65(
41947
+ useEffect66(
41883
41948
  () => () => {
41884
41949
  popupCleanupRef.current?.();
41885
41950
  const popup = popupRef.current;
@@ -42008,7 +42073,7 @@ function PresentationModeControl() {
42008
42073
  updatePosition();
42009
42074
  setOpen(true);
42010
42075
  }, [updatePosition]);
42011
- useEffect65(() => {
42076
+ useEffect66(() => {
42012
42077
  if (!open) return;
42013
42078
  const handlePointerDown = (event) => {
42014
42079
  const target = event.target;
@@ -42153,7 +42218,7 @@ import {
42153
42218
  createContext as createContext8,
42154
42219
  useCallback as useCallback52,
42155
42220
  useContext as useContext8,
42156
- useEffect as useEffect66,
42221
+ useEffect as useEffect67,
42157
42222
  useMemo as useMemo54,
42158
42223
  useRef as useRef61,
42159
42224
  useState as useState78
@@ -42223,7 +42288,7 @@ function PrintModeProvider({ rootRef, children }) {
42223
42288
  markPrinting();
42224
42289
  ownerWindow.print();
42225
42290
  }, [markPrinting, rootRef]);
42226
- useEffect66(() => {
42291
+ useEffect67(() => {
42227
42292
  const root = rootRef.current;
42228
42293
  if (!root) return;
42229
42294
  if (active) root.dataset.printPreview = "true";
@@ -42232,10 +42297,10 @@ function PrintModeProvider({ rootRef, children }) {
42232
42297
  delete root.dataset.printPreview;
42233
42298
  };
42234
42299
  }, [active, rootRef]);
42235
- useEffect66(() => {
42300
+ useEffect67(() => {
42236
42301
  if (activeView !== "preview" && active) close();
42237
42302
  }, [active, activeView, close]);
42238
- useEffect66(() => {
42303
+ useEffect67(() => {
42239
42304
  if (!active) return;
42240
42305
  const ownerWindow = rootRef.current?.ownerDocument.defaultView;
42241
42306
  const ownerDocument = rootRef.current?.ownerDocument;
@@ -42326,7 +42391,7 @@ function PrintPreviewToolbar() {
42326
42391
  }
42327
42392
 
42328
42393
  // src/print/PrintPreview.tsx
42329
- import { useCallback as useCallback53, useEffect as useEffect67, useMemo as useMemo55, useRef as useRef62 } from "react";
42394
+ import { useCallback as useCallback53, useEffect as useEffect68, useMemo as useMemo55, useRef as useRef62 } from "react";
42330
42395
  import {
42331
42396
  BlockRenderer as BlockRenderer4,
42332
42397
  FlashcardFaceView,
@@ -42383,7 +42448,7 @@ function PrintPreview({
42383
42448
  [contentDoc]
42384
42449
  );
42385
42450
  const isTextDocument = displayMode === "page" || displayMode === "narrate";
42386
- useEffect67(() => {
42451
+ useEffect68(() => {
42387
42452
  if (!isTextDocument) return registerPrintHandler(null);
42388
42453
  return registerPrintHandler(() => {
42389
42454
  const frameWindow = documentFrameRef.current?.contentWindow;
@@ -42522,7 +42587,7 @@ function PrintPreview({
42522
42587
  import {
42523
42588
  createContext as createContext9,
42524
42589
  useContext as useContext9,
42525
- useEffect as useEffect68,
42590
+ useEffect as useEffect69,
42526
42591
  useMemo as useMemo56,
42527
42592
  useState as useState79
42528
42593
  } from "react";
@@ -42629,7 +42694,7 @@ function SlideshowDataGridRenderer({
42629
42694
  const activeSourceKey = sourceKey(source);
42630
42695
  const [remote, setRemote] = useState79({ key: "", status: "idle" });
42631
42696
  const [gridModule, setGridModule] = useState79(null);
42632
- useEffect68(() => {
42697
+ useEffect69(() => {
42633
42698
  let active = true;
42634
42699
  void loadGridModule().then((module) => {
42635
42700
  if (active) setGridModule(module);
@@ -42638,7 +42703,7 @@ function SlideshowDataGridRenderer({
42638
42703
  active = false;
42639
42704
  };
42640
42705
  }, []);
42641
- useEffect68(() => {
42706
+ useEffect69(() => {
42642
42707
  if (!container || !source || !gridModule) {
42643
42708
  setRemote({ key: activeSourceKey, status: "idle" });
42644
42709
  return;
@@ -42689,13 +42754,13 @@ function SlideshowDataGridRenderer({
42689
42754
  () => useLocalGrid && gridModule ? new gridModule.TableStoreClient({ headers: previewHeaders, cells: previewRows }) : null,
42690
42755
  [previewHeaders, previewRows, useLocalGrid, gridModule]
42691
42756
  );
42692
- useEffect68(() => () => localProvider?.dispose(), [localProvider]);
42757
+ useEffect69(() => () => localProvider?.dispose(), [localProvider]);
42693
42758
  const ready = currentRemote?.status === "ready" ? currentRemote : void 0;
42694
42759
  const provider = ready?.provider ?? localProvider;
42695
42760
  const ingest = ready?.ingest ?? (localProvider ? { headers: previewHeaders, cells: previewRows } : void 0);
42696
42761
  const initialView = ready?.initialView ?? EMPTY_VIEW;
42697
42762
  const [view, setView] = useState79(initialView);
42698
- useEffect68(() => setView(initialView), [initialView, provider]);
42763
+ useEffect69(() => setView(initialView), [initialView, provider]);
42699
42764
  if (!provider || !ingest || !gridModule) return /* @__PURE__ */ jsx87(Fragment28, { children: fallback });
42700
42765
  const { style } = layer.content;
42701
42766
  const rowHeight = Math.max(32, style.fontSize * 2.1);
@@ -42832,11 +42897,11 @@ function PreviewPanel({
42832
42897
  const isNarrateMode = activeDisplayMode === "narrate";
42833
42898
  const isDashboardMode = activeDisplayMode === "dashboard";
42834
42899
  const isFlashcardsMode = activeDisplayMode === "flashcards";
42835
- useEffect69(() => {
42900
+ useEffect70(() => {
42836
42901
  if (presentation?.activeTarget === "window") return;
42837
42902
  setPlaybackState(null);
42838
42903
  }, [presentation?.activeTarget]);
42839
- useEffect69(() => {
42904
+ useEffect70(() => {
42840
42905
  if (presentation?.activeTarget !== "window" || !presentation.popupRoot) return;
42841
42906
  const mainRoot = mainSurfaceRef.current;
42842
42907
  const followerRoot = popupSurfaceRef.current;
@@ -43113,10 +43178,98 @@ function PreviewPanel({
43113
43178
  }
43114
43179
 
43115
43180
  // src/MediaBin.tsx
43116
- import { useState as useState81, useEffect as useEffect70, useRef as useRef64, useCallback as useCallback55 } from "react";
43181
+ import { useState as useState82, useEffect as useEffect72, useRef as useRef65, useCallback as useCallback55 } from "react";
43117
43182
  import { isSvgImageSource as isSvgImageSource3 } from "@bendyline/squisq/markdown";
43118
43183
  import { sanitizedSvgImageUrl as sanitizedSvgImageUrl2 } from "@bendyline/squisq-react";
43184
+
43185
+ // src/MediaPreviewDialog.tsx
43186
+ import { useEffect as useEffect71, useId as useId16, useRef as useRef64, useState as useState81 } from "react";
43119
43187
  import { jsx as jsx89, jsxs as jsxs72 } from "react/jsx-runtime";
43188
+ function MediaPreviewDialog({
43189
+ kind,
43190
+ name,
43191
+ detail,
43192
+ src,
43193
+ failed = false,
43194
+ isDark,
43195
+ onClose
43196
+ }) {
43197
+ const overlayRef = useRef64(null);
43198
+ const dialogRef = useRef64(null);
43199
+ const titleId = useId16();
43200
+ const [playbackFailed, setPlaybackFailed] = useState81(false);
43201
+ useModalDialog({ rootRef: overlayRef, dialogRef, onClose });
43202
+ useEffect71(() => setPlaybackFailed(false), [src]);
43203
+ let body;
43204
+ if (failed || playbackFailed || src === "") {
43205
+ body = /* @__PURE__ */ jsx89("div", { className: "squisq-media-preview-message", children: "This file can\u2019t be previewed." });
43206
+ } else if (src === null) {
43207
+ body = /* @__PURE__ */ jsx89("div", { className: "squisq-media-preview-message", children: "Loading\u2026" });
43208
+ } else if (kind === "image") {
43209
+ body = /* @__PURE__ */ jsx89(ImageViewer, { src, alt: name, theme: isDark ? "dark" : "light" });
43210
+ } else if (kind === "video") {
43211
+ body = /* @__PURE__ */ jsx89(
43212
+ "video",
43213
+ {
43214
+ className: "squisq-media-preview-video",
43215
+ src,
43216
+ controls: true,
43217
+ autoPlay: true,
43218
+ playsInline: true,
43219
+ onError: () => setPlaybackFailed(true)
43220
+ }
43221
+ );
43222
+ } else {
43223
+ body = /* @__PURE__ */ jsxs72("div", { className: "squisq-media-preview-audio", children: [
43224
+ /* @__PURE__ */ jsx89("span", { className: "squisq-media-preview-audio-icon", "aria-hidden": "true", children: "\u{1F50A}" }),
43225
+ /* @__PURE__ */ jsx89("audio", { src, controls: true, autoPlay: true, onError: () => setPlaybackFailed(true) })
43226
+ ] });
43227
+ }
43228
+ return /* @__PURE__ */ jsx89(
43229
+ "div",
43230
+ {
43231
+ ref: overlayRef,
43232
+ className: "squisq-media-preview",
43233
+ "data-theme": isDark ? "dark" : "light",
43234
+ onMouseDown: (event) => {
43235
+ if (event.target === event.currentTarget) onClose();
43236
+ },
43237
+ ...ownsContextMenuProps,
43238
+ children: /* @__PURE__ */ jsxs72(
43239
+ "div",
43240
+ {
43241
+ ref: dialogRef,
43242
+ className: `squisq-media-preview-surface squisq-media-preview-surface--${kind}`,
43243
+ role: "dialog",
43244
+ "aria-modal": "true",
43245
+ "aria-labelledby": titleId,
43246
+ tabIndex: -1,
43247
+ "data-testid": "media-preview-dialog",
43248
+ children: [
43249
+ /* @__PURE__ */ jsxs72("header", { className: "squisq-media-preview-header", children: [
43250
+ /* @__PURE__ */ jsx89("span", { id: titleId, className: "squisq-media-preview-title", title: name, children: name }),
43251
+ /* @__PURE__ */ jsx89("span", { className: "squisq-media-preview-detail", children: detail }),
43252
+ /* @__PURE__ */ jsx89(
43253
+ "button",
43254
+ {
43255
+ type: "button",
43256
+ className: "squisq-media-preview-close",
43257
+ onClick: onClose,
43258
+ "aria-label": "Close",
43259
+ children: "\xD7"
43260
+ }
43261
+ )
43262
+ ] }),
43263
+ /* @__PURE__ */ jsx89("div", { className: "squisq-media-preview-body", children: body })
43264
+ ]
43265
+ }
43266
+ )
43267
+ }
43268
+ );
43269
+ }
43270
+
43271
+ // src/MediaBin.tsx
43272
+ import { Fragment as Fragment29, jsx as jsx90, jsxs as jsxs73 } from "react/jsx-runtime";
43120
43273
  function formatSize(bytes) {
43121
43274
  if (bytes < 1024) return `${bytes} B`;
43122
43275
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
@@ -43188,23 +43341,24 @@ function MediaBin({
43188
43341
  allowBinaryDownloads = true,
43189
43342
  highlightPath = null
43190
43343
  }) {
43191
- const [entries, setEntries] = useState81([]);
43192
- const listRef = useRef64(null);
43193
- useEffect70(() => {
43344
+ const [entries, setEntries] = useState82([]);
43345
+ const listRef = useRef65(null);
43346
+ useEffect72(() => {
43194
43347
  if (!highlightPath || !listRef.current) return;
43195
43348
  const item = listRef.current.querySelector(`[data-media-path="${CSS.escape(highlightPath)}"]`);
43196
43349
  if (item instanceof HTMLElement) {
43197
43350
  item.scrollIntoView({ block: "nearest" });
43198
43351
  }
43199
43352
  }, [highlightPath, entries]);
43200
- const [thumbUrls, setThumbUrls] = useState81({});
43201
- const [loading, setLoading] = useState81(false);
43202
- const [isDropActive, setIsDropActive] = useState81(false);
43203
- const [downloadingPath, setDownloadingPath] = useState81(null);
43204
- const [contextMenu, setContextMenu] = useState81(null);
43205
- const fileInputRef = useRef64(null);
43206
- const contextMenuRef = useRef64(null);
43207
- const dropDepthRef = useRef64(0);
43353
+ const [thumbUrls, setThumbUrls] = useState82({});
43354
+ const [loading, setLoading] = useState82(false);
43355
+ const [isDropActive, setIsDropActive] = useState82(false);
43356
+ const [downloadingPath, setDownloadingPath] = useState82(null);
43357
+ const [contextMenu, setContextMenu] = useState82(null);
43358
+ const [preview, setPreview] = useState82(null);
43359
+ const fileInputRef = useRef65(null);
43360
+ const contextMenuRef = useRef65(null);
43361
+ const dropDepthRef = useRef65(0);
43208
43362
  const updateEntries = useCallback55(
43209
43363
  async (provider) => {
43210
43364
  const list = sortMediaEntries(filterVisibleMediaEntries(await provider.listMedia()));
@@ -43223,7 +43377,7 @@ function MediaBin({
43223
43377
  },
43224
43378
  [onCountChange]
43225
43379
  );
43226
- useEffect70(() => {
43380
+ useEffect72(() => {
43227
43381
  if (!contextMenu) return;
43228
43382
  const handlePointerDown = (event) => {
43229
43383
  if (contextMenuRef.current?.contains(event.target)) return;
@@ -43244,7 +43398,7 @@ function MediaBin({
43244
43398
  window.removeEventListener("resize", close);
43245
43399
  };
43246
43400
  }, [contextMenu]);
43247
- useEffect70(() => {
43401
+ useEffect72(() => {
43248
43402
  if (!mediaProvider) {
43249
43403
  setEntries([]);
43250
43404
  setThumbUrls({});
@@ -43401,6 +43555,27 @@ function MediaBin({
43401
43555
  const openContextMenu = useCallback55((entry, x, y) => {
43402
43556
  setContextMenu({ entry, x, y });
43403
43557
  }, []);
43558
+ useEffect72(() => {
43559
+ setPreview(null);
43560
+ }, [mediaProvider]);
43561
+ const openPreview = useCallback55(
43562
+ async (entry) => {
43563
+ if (!mediaProvider || squisqMediaKind(entry.mimeType) === "file") return;
43564
+ const thumb = thumbUrls[entry.name];
43565
+ setPreview({ entry, src: thumb ?? null, failed: false });
43566
+ if (thumb !== void 0) return;
43567
+ let src = null;
43568
+ try {
43569
+ src = isImageMime(entry.mimeType) ? await resolveThumbnailUrl(mediaProvider, entry.name) : await mediaProvider.resolveUrl(entry.name);
43570
+ } catch {
43571
+ }
43572
+ setPreview(
43573
+ (current) => current?.entry.name === entry.name ? { entry, src, failed: src === null } : current
43574
+ );
43575
+ },
43576
+ [mediaProvider, thumbUrls]
43577
+ );
43578
+ const closePreview = useCallback55(() => setPreview(null), []);
43404
43579
  const removeLabel = contextMenu ? isImageMime(contextMenu.entry.mimeType) ? "Remove image" : "Remove file" : "Remove file";
43405
43580
  const menuLeft = contextMenu ? Math.min(contextMenu.x, Math.max(8, window.innerWidth - 168)) : 0;
43406
43581
  const menuTop = contextMenu ? Math.min(contextMenu.y, Math.max(8, window.innerHeight - 48)) : 0;
@@ -43410,189 +43585,217 @@ function MediaBin({
43410
43585
  };
43411
43586
  const handleItemKeyDown = useCallback55(
43412
43587
  (entry, event) => {
43588
+ if (event.key === "Enter" || event.key === " ") {
43589
+ if (event.target !== event.currentTarget) return;
43590
+ if (squisqMediaKind(entry.mimeType) === "file") return;
43591
+ event.preventDefault();
43592
+ void openPreview(entry);
43593
+ return;
43594
+ }
43413
43595
  if (event.key !== "ContextMenu" && !(event.shiftKey && event.key === "F10")) return;
43414
43596
  event.preventDefault();
43415
43597
  const rect = event.currentTarget.getBoundingClientRect();
43416
43598
  openContextMenu(entry, rect.left + 16, rect.top + 16);
43417
43599
  },
43418
- [openContextMenu]
43600
+ [openContextMenu, openPreview]
43419
43601
  );
43420
- return /* @__PURE__ */ jsxs72(
43421
- "div",
43422
- {
43423
- className: [
43424
- "squisq-media-bin",
43425
- isDark ? "squisq-media-bin--dark" : "",
43426
- isDropActive ? "squisq-media-bin--drop-active" : ""
43427
- ].filter(Boolean).join(" "),
43428
- onDragEnter: handleDragEnter,
43429
- onDragOver: handleDragOver,
43430
- onDragLeave: handleDragLeave,
43431
- onDrop: handleDrop,
43432
- "aria-busy": loading,
43433
- ...ownsContextMenuProps,
43434
- children: [
43435
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-header", children: [
43436
- /* @__PURE__ */ jsxs72("span", { className: "squisq-media-bin-title", children: [
43437
- "Attachments ",
43438
- entries.length > 0 && `(${entries.length})`
43439
- ] }),
43440
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-actions", children: [
43441
- onRecord && /* @__PURE__ */ jsxs72(
43442
- "button",
43443
- {
43444
- type: "button",
43445
- className: "squisq-media-bin-record",
43446
- onClick: onRecord,
43447
- disabled: !mediaProvider,
43448
- title: mediaProvider ? "Record media" : "Load a content zip or select a storage slot first",
43449
- "aria-label": "Record media",
43450
- "aria-haspopup": "dialog",
43451
- "aria-expanded": isRecorderOpen,
43452
- children: [
43453
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-action-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-record-dot" }) }),
43454
- /* @__PURE__ */ jsx89("span", { children: "Record" })
43455
- ]
43456
- }
43457
- ),
43458
- /* @__PURE__ */ jsxs72(
43459
- "button",
43460
- {
43461
- type: "button",
43462
- className: "squisq-media-bin-upload",
43463
- onClick: handleUploadClick,
43464
- disabled: !mediaProvider || loading,
43465
- title: mediaProvider ? "Upload files" : "Load a content zip or select a storage slot first",
43466
- children: [
43467
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-action-icon", children: "+" }),
43468
- /* @__PURE__ */ jsx89("span", { children: "Upload" })
43469
- ]
43470
- }
43471
- )
43472
- ] })
43473
- ] }),
43474
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-list", ref: listRef, children: [
43475
- !mediaProvider && /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-empty", children: [
43476
- "No media context.",
43477
- /* @__PURE__ */ jsx89("br", {}),
43478
- "Load a content zip or select a storage slot."
43602
+ const previewKind = preview ? squisqMediaKind(preview.entry.mimeType) : "file";
43603
+ return /* @__PURE__ */ jsxs73(Fragment29, { children: [
43604
+ /* @__PURE__ */ jsxs73(
43605
+ "div",
43606
+ {
43607
+ className: [
43608
+ "squisq-media-bin",
43609
+ isDark ? "squisq-media-bin--dark" : "",
43610
+ isDropActive ? "squisq-media-bin--drop-active" : ""
43611
+ ].filter(Boolean).join(" "),
43612
+ onDragEnter: handleDragEnter,
43613
+ onDragOver: handleDragOver,
43614
+ onDragLeave: handleDragLeave,
43615
+ onDrop: handleDrop,
43616
+ "aria-busy": loading,
43617
+ ...ownsContextMenuProps,
43618
+ children: [
43619
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-header", children: [
43620
+ /* @__PURE__ */ jsxs73("span", { className: "squisq-media-bin-title", children: [
43621
+ "Attachments ",
43622
+ entries.length > 0 && `(${entries.length})`
43623
+ ] }),
43624
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-actions", children: [
43625
+ onRecord && /* @__PURE__ */ jsxs73(
43626
+ "button",
43627
+ {
43628
+ type: "button",
43629
+ className: "squisq-media-bin-record",
43630
+ onClick: onRecord,
43631
+ disabled: !mediaProvider,
43632
+ title: mediaProvider ? "Record media" : "Load a content zip or select a storage slot first",
43633
+ "aria-label": "Record media",
43634
+ "aria-haspopup": "dialog",
43635
+ "aria-expanded": isRecorderOpen,
43636
+ children: [
43637
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-action-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-record-dot" }) }),
43638
+ /* @__PURE__ */ jsx90("span", { children: "Record" })
43639
+ ]
43640
+ }
43641
+ ),
43642
+ /* @__PURE__ */ jsxs73(
43643
+ "button",
43644
+ {
43645
+ type: "button",
43646
+ className: "squisq-media-bin-upload",
43647
+ onClick: handleUploadClick,
43648
+ disabled: !mediaProvider || loading,
43649
+ title: mediaProvider ? "Upload files" : "Load a content zip or select a storage slot first",
43650
+ children: [
43651
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-action-icon", children: "+" }),
43652
+ /* @__PURE__ */ jsx90("span", { children: "Upload" })
43653
+ ]
43654
+ }
43655
+ )
43656
+ ] })
43479
43657
  ] }),
43480
- mediaProvider && entries.length === 0 && !loading && /* @__PURE__ */ jsx89("div", { className: "squisq-media-bin-empty", children: "No files yet." }),
43481
- entries.map((entry) => {
43482
- const thumb = thumbUrls[entry.name];
43483
- const basename = basenameForPath(entry.name);
43484
- const altText = basename.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
43485
- const isUnused = !!usedMediaPaths && !usedMediaPaths.has(entry.name);
43486
- const handleDragStart = (e2) => {
43487
- const payload = {
43488
- name: entry.name,
43489
- mimeType: entry.mimeType,
43490
- alt: altText
43658
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-list", ref: listRef, children: [
43659
+ !mediaProvider && /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-empty", children: [
43660
+ "No media context.",
43661
+ /* @__PURE__ */ jsx90("br", {}),
43662
+ "Load a content zip or select a storage slot."
43663
+ ] }),
43664
+ mediaProvider && entries.length === 0 && !loading && /* @__PURE__ */ jsx90("div", { className: "squisq-media-bin-empty", children: "No files yet." }),
43665
+ entries.map((entry) => {
43666
+ const thumb = thumbUrls[entry.name];
43667
+ const basename = basenameForPath(entry.name);
43668
+ const altText = basename.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
43669
+ const isUnused = !!usedMediaPaths && !usedMediaPaths.has(entry.name);
43670
+ const isPreviewable = squisqMediaKind(entry.mimeType) !== "file";
43671
+ const handleDragStart = (e2) => {
43672
+ const payload = {
43673
+ name: entry.name,
43674
+ mimeType: entry.mimeType,
43675
+ alt: altText
43676
+ };
43677
+ e2.dataTransfer.setData(SQUISQ_MEDIA_MIME, JSON.stringify(payload));
43678
+ e2.dataTransfer.setData("text/plain", buildSquisqMediaReference(payload));
43679
+ e2.dataTransfer.effectAllowed = "copy";
43491
43680
  };
43492
- e2.dataTransfer.setData(SQUISQ_MEDIA_MIME, JSON.stringify(payload));
43493
- e2.dataTransfer.setData("text/plain", buildSquisqMediaReference(payload));
43494
- e2.dataTransfer.effectAllowed = "copy";
43495
- };
43496
- return /* @__PURE__ */ jsxs72(
43497
- "div",
43498
- {
43499
- "data-media-path": entry.name,
43500
- className: entry.name === highlightPath ? "squisq-media-bin-item squisq-media-bin-item--highlight" : "squisq-media-bin-item",
43501
- title: `${entry.name}
43681
+ return /* @__PURE__ */ jsxs73(
43682
+ "div",
43683
+ {
43684
+ "data-media-path": entry.name,
43685
+ className: [
43686
+ "squisq-media-bin-item",
43687
+ isPreviewable ? "squisq-media-bin-item--previewable" : "",
43688
+ entry.name === highlightPath ? "squisq-media-bin-item--highlight" : ""
43689
+ ].filter(Boolean).join(" "),
43690
+ title: `${entry.name}
43502
43691
  ${entry.mimeType}
43503
43692
  ${formatSize(entry.size)}`,
43504
- draggable: true,
43505
- tabIndex: 0,
43506
- onContextMenu: (e2) => {
43507
- e2.preventDefault();
43508
- openContextMenu(entry, e2.clientX, e2.clientY);
43693
+ draggable: true,
43694
+ tabIndex: 0,
43695
+ onClick: isPreviewable ? () => void openPreview(entry) : void 0,
43696
+ onContextMenu: (e2) => {
43697
+ e2.preventDefault();
43698
+ openContextMenu(entry, e2.clientX, e2.clientY);
43699
+ },
43700
+ onDragStart: handleDragStart,
43701
+ onKeyDown: (e2) => handleItemKeyDown(entry, e2),
43702
+ children: [
43703
+ thumb ? /* @__PURE__ */ jsx90(
43704
+ "img",
43705
+ {
43706
+ src: thumb,
43707
+ alt: basename,
43708
+ className: "squisq-media-bin-thumb",
43709
+ draggable: false
43710
+ }
43711
+ ) : /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) }),
43712
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-meta", children: [
43713
+ /* @__PURE__ */ jsx90("div", { className: "squisq-media-bin-name", children: basename }),
43714
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-detail-row", children: [
43715
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-size", children: formatSize(entry.size) }),
43716
+ isUnused && /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-unused-badge", title: "Not used in document", children: "Unused" })
43717
+ ] })
43718
+ ] }),
43719
+ allowBinaryDownloads && /* @__PURE__ */ jsx90(
43720
+ "button",
43721
+ {
43722
+ type: "button",
43723
+ className: "squisq-media-bin-download",
43724
+ title: `Download ${basename}`,
43725
+ "aria-label": `Download ${basename}`,
43726
+ disabled: !mediaProvider || downloadingPath !== null,
43727
+ draggable: false,
43728
+ onClick: (event) => {
43729
+ event.stopPropagation();
43730
+ void handleDownloadEntry(entry);
43731
+ },
43732
+ onDragStart: (event) => event.preventDefault(),
43733
+ children: /* @__PURE__ */ jsx90("span", { "aria-hidden": "true", children: downloadingPath === entry.name ? "\u2026" : "\u2193" })
43734
+ }
43735
+ )
43736
+ ]
43509
43737
  },
43510
- onDragStart: handleDragStart,
43511
- onKeyDown: (e2) => handleItemKeyDown(entry, e2),
43512
- children: [
43513
- thumb ? /* @__PURE__ */ jsx89(
43514
- "img",
43515
- {
43516
- src: thumb,
43517
- alt: basename,
43518
- className: "squisq-media-bin-thumb",
43519
- draggable: false
43520
- }
43521
- ) : /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) }),
43522
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-meta", children: [
43523
- /* @__PURE__ */ jsx89("div", { className: "squisq-media-bin-name", children: basename }),
43524
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-detail-row", children: [
43525
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-size", children: formatSize(entry.size) }),
43526
- isUnused && /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-unused-badge", title: "Not used in document", children: "Unused" })
43527
- ] })
43528
- ] }),
43529
- allowBinaryDownloads && /* @__PURE__ */ jsx89(
43530
- "button",
43531
- {
43532
- type: "button",
43533
- className: "squisq-media-bin-download",
43534
- title: `Download ${basename}`,
43535
- "aria-label": `Download ${basename}`,
43536
- disabled: !mediaProvider || downloadingPath !== null,
43537
- draggable: false,
43538
- onClick: (event) => {
43539
- event.stopPropagation();
43540
- void handleDownloadEntry(entry);
43541
- },
43542
- onDragStart: (event) => event.preventDefault(),
43543
- children: /* @__PURE__ */ jsx89("span", { "aria-hidden": "true", children: downloadingPath === entry.name ? "\u2026" : "\u2193" })
43544
- }
43545
- )
43546
- ]
43547
- },
43548
- entry.name
43549
- );
43550
- })
43551
- ] }),
43552
- isDropActive && /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-drop-target", "aria-hidden": "true", children: [
43553
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-drop-target-icon", children: "+" }),
43554
- /* @__PURE__ */ jsx89("strong", { children: "Drop media here" }),
43555
- /* @__PURE__ */ jsx89("span", { children: "Attach to this document" })
43556
- ] }),
43557
- contextMenu && /* @__PURE__ */ jsx89(
43558
- "div",
43559
- {
43560
- ref: contextMenuRef,
43561
- className: "squisq-media-bin-context-menu",
43562
- role: "menu",
43563
- "aria-label": `${contextMenu.entry.name} actions`,
43564
- style: contextMenuStyle,
43565
- children: /* @__PURE__ */ jsx89(
43566
- "button",
43567
- {
43568
- type: "button",
43569
- role: "menuitem",
43570
- className: "squisq-media-bin-context-menu-item squisq-media-bin-context-menu-item--danger",
43571
- onClick: () => handleRemoveEntry(contextMenu.entry),
43572
- disabled: !mediaProvider || loading,
43573
- children: removeLabel
43574
- }
43575
- )
43576
- }
43577
- ),
43578
- /* @__PURE__ */ jsx89(
43579
- "input",
43580
- {
43581
- ref: fileInputRef,
43582
- type: "file",
43583
- multiple: true,
43584
- style: { display: "none" },
43585
- onChange: handleFileChange
43586
- }
43587
- )
43588
- ]
43589
- }
43590
- );
43738
+ entry.name
43739
+ );
43740
+ })
43741
+ ] }),
43742
+ isDropActive && /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-drop-target", "aria-hidden": "true", children: [
43743
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-drop-target-icon", children: "+" }),
43744
+ /* @__PURE__ */ jsx90("strong", { children: "Drop media here" }),
43745
+ /* @__PURE__ */ jsx90("span", { children: "Attach to this document" })
43746
+ ] }),
43747
+ contextMenu && /* @__PURE__ */ jsx90(
43748
+ "div",
43749
+ {
43750
+ ref: contextMenuRef,
43751
+ className: "squisq-media-bin-context-menu",
43752
+ role: "menu",
43753
+ "aria-label": `${contextMenu.entry.name} actions`,
43754
+ style: contextMenuStyle,
43755
+ children: /* @__PURE__ */ jsx90(
43756
+ "button",
43757
+ {
43758
+ type: "button",
43759
+ role: "menuitem",
43760
+ className: "squisq-media-bin-context-menu-item squisq-media-bin-context-menu-item--danger",
43761
+ onClick: () => handleRemoveEntry(contextMenu.entry),
43762
+ disabled: !mediaProvider || loading,
43763
+ children: removeLabel
43764
+ }
43765
+ )
43766
+ }
43767
+ ),
43768
+ /* @__PURE__ */ jsx90(
43769
+ "input",
43770
+ {
43771
+ ref: fileInputRef,
43772
+ type: "file",
43773
+ multiple: true,
43774
+ style: { display: "none" },
43775
+ onChange: handleFileChange
43776
+ }
43777
+ )
43778
+ ]
43779
+ }
43780
+ ),
43781
+ preview && previewKind !== "file" && /* @__PURE__ */ jsx90(
43782
+ MediaPreviewDialog,
43783
+ {
43784
+ kind: previewKind,
43785
+ name: basenameForPath(preview.entry.name),
43786
+ detail: `${formatSize(preview.entry.size)} \xB7 ${preview.entry.mimeType}`,
43787
+ src: preview.src,
43788
+ failed: preview.failed,
43789
+ isDark,
43790
+ onClose: closePreview
43791
+ }
43792
+ )
43793
+ ] });
43591
43794
  }
43592
43795
 
43593
43796
  // src/DropZoneOverlay.tsx
43594
- import { useState as useState82 } from "react";
43595
- import { Fragment as Fragment29, jsx as jsx90, jsxs as jsxs73 } from "react/jsx-runtime";
43797
+ import { useState as useState83 } from "react";
43798
+ import { Fragment as Fragment30, jsx as jsx91, jsxs as jsxs74 } from "react/jsx-runtime";
43596
43799
  function DropZoneOverlay({
43597
43800
  dragContentType,
43598
43801
  zoneProps,
@@ -43600,8 +43803,8 @@ function DropZoneOverlay({
43600
43803
  }) {
43601
43804
  const showMedia = dragContentType === "media" || dragContentType === "mixed";
43602
43805
  const showText = dragContentType === "text" || dragContentType === "mixed";
43603
- return /* @__PURE__ */ jsx90("div", { className: "squisq-drop-overlay", children: /* @__PURE__ */ jsxs73("div", { className: "squisq-drop-overlay-inner", children: [
43604
- showMedia && /* @__PURE__ */ jsx90(
43806
+ return /* @__PURE__ */ jsx91("div", { className: "squisq-drop-overlay", children: /* @__PURE__ */ jsxs74("div", { className: "squisq-drop-overlay-inner", children: [
43807
+ showMedia && /* @__PURE__ */ jsx91(
43605
43808
  DropZone,
43606
43809
  {
43607
43810
  target: "media",
@@ -43613,8 +43816,8 @@ function DropZoneOverlay({
43613
43816
  variant: "media"
43614
43817
  }
43615
43818
  ),
43616
- showText && /* @__PURE__ */ jsxs73(Fragment29, { children: [
43617
- /* @__PURE__ */ jsx90(
43819
+ showText && /* @__PURE__ */ jsxs74(Fragment30, { children: [
43820
+ /* @__PURE__ */ jsx91(
43618
43821
  DropZone,
43619
43822
  {
43620
43823
  target: "insert",
@@ -43625,7 +43828,7 @@ function DropZoneOverlay({
43625
43828
  variant: "insert"
43626
43829
  }
43627
43830
  ),
43628
- /* @__PURE__ */ jsx90(
43831
+ /* @__PURE__ */ jsx91(
43629
43832
  DropZone,
43630
43833
  {
43631
43834
  target: "replace",
@@ -43648,9 +43851,9 @@ function DropZone({
43648
43851
  disabled,
43649
43852
  variant
43650
43853
  }) {
43651
- const [isHovering, setIsHovering] = useState82(false);
43854
+ const [isHovering, setIsHovering] = useState83(false);
43652
43855
  const props = zoneProps(target);
43653
- return /* @__PURE__ */ jsxs73(
43856
+ return /* @__PURE__ */ jsxs74(
43654
43857
  "div",
43655
43858
  {
43656
43859
  className: [
@@ -43683,16 +43886,16 @@ function DropZone({
43683
43886
  props.onDrop(e2);
43684
43887
  },
43685
43888
  children: [
43686
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-icon", children: icon }),
43687
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-label", children: label }),
43688
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-desc", children: description })
43889
+ /* @__PURE__ */ jsx91("span", { className: "squisq-drop-zone-icon", children: icon }),
43890
+ /* @__PURE__ */ jsx91("span", { className: "squisq-drop-zone-label", children: label }),
43891
+ /* @__PURE__ */ jsx91("span", { className: "squisq-drop-zone-desc", children: description })
43689
43892
  ]
43690
43893
  }
43691
43894
  );
43692
43895
  }
43693
43896
 
43694
43897
  // src/Tooltip.tsx
43695
- import { useEffect as useEffect71, useLayoutEffect as useLayoutEffect16, useRef as useRef65, useState as useState83 } from "react";
43898
+ import { useEffect as useEffect73, useLayoutEffect as useLayoutEffect16, useRef as useRef66, useState as useState84 } from "react";
43696
43899
  import { createPortal as createPortal19 } from "react-dom";
43697
43900
 
43698
43901
  // src/tooltipPlacement.ts
@@ -43705,16 +43908,16 @@ function clampTooltipLeft(anchorX, tooltipWidth, viewportWidth, edgePadding = ED
43705
43908
  }
43706
43909
 
43707
43910
  // src/Tooltip.tsx
43708
- import { jsx as jsx91 } from "react/jsx-runtime";
43911
+ import { jsx as jsx92 } from "react/jsx-runtime";
43709
43912
  var SHOW_DELAY_MS = 180;
43710
43913
  function TooltipLayer() {
43711
- const [state, setState3] = useState83(null);
43712
- const tooltipRef = useRef65(null);
43713
- const timerRef = useRef65(null);
43714
- const currentTargetRef = useRef65(null);
43715
- const visibleRef = useRef65(false);
43716
- const pressedTargetRef = useRef65(null);
43717
- const lastPointerWasTouchRef = useRef65(false);
43914
+ const [state, setState3] = useState84(null);
43915
+ const tooltipRef = useRef66(null);
43916
+ const timerRef = useRef66(null);
43917
+ const currentTargetRef = useRef66(null);
43918
+ const visibleRef = useRef66(false);
43919
+ const pressedTargetRef = useRef66(null);
43920
+ const lastPointerWasTouchRef = useRef66(false);
43718
43921
  useLayoutEffect16(() => {
43719
43922
  if (!state) return;
43720
43923
  const node2 = tooltipRef.current;
@@ -43726,7 +43929,7 @@ function TooltipLayer() {
43726
43929
  node2.style.left = `${left}px`;
43727
43930
  node2.style.visibility = "visible";
43728
43931
  }, [state]);
43729
- useEffect71(() => {
43932
+ useEffect73(() => {
43730
43933
  const clearTimer = () => {
43731
43934
  if (timerRef.current) {
43732
43935
  clearTimeout(timerRef.current);
@@ -43808,7 +44011,7 @@ function TooltipLayer() {
43808
44011
  }, []);
43809
44012
  if (!state) return null;
43810
44013
  return createPortal19(
43811
- /* @__PURE__ */ jsx91(
44014
+ /* @__PURE__ */ jsx92(
43812
44015
  "div",
43813
44016
  {
43814
44017
  role: "tooltip",
@@ -43828,13 +44031,13 @@ function TooltipLayer() {
43828
44031
  }
43829
44032
 
43830
44033
  // src/EditorShell.tsx
43831
- import { useEffect as useEffect78, useRef as useRef74, useState as useState90, useCallback as useCallback63, useMemo as useMemo62 } from "react";
44034
+ import { useEffect as useEffect80, useRef as useRef75, useState as useState91, useCallback as useCallback63, useMemo as useMemo62 } from "react";
43832
44035
 
43833
44036
  // src/BlockPreviewPanel.tsx
43834
44037
  import { useMemo as useMemo58 } from "react";
43835
44038
  import { VIEWPORT_PRESETS as VIEWPORT_PRESETS7 } from "@bendyline/squisq/schemas";
43836
44039
  import { flattenBlocks as flattenBlocks6, DEFAULT_THEME as DEFAULT_THEME7 } from "@bendyline/squisq/doc";
43837
- import { jsx as jsx92 } from "react/jsx-runtime";
44040
+ import { jsx as jsx93 } from "react/jsx-runtime";
43838
44041
  function BlockPreviewPanel({ basePath = "/" }) {
43839
44042
  const { doc, activeBlockStartLine, mediaProvider, workspaceContainer, fileName, mediaRevision } = useEditorContext();
43840
44043
  const previewSettings = usePreviewSettingsOptional();
@@ -43853,12 +44056,12 @@ function BlockPreviewPanel({ basePath = "/" }) {
43853
44056
  [previewDoc, block, theme, viewport]
43854
44057
  );
43855
44058
  if (!visual) return null;
43856
- return /* @__PURE__ */ jsx92("div", { className: "squisq-block-preview-panel", "data-testid": "block-preview-panel", "aria-hidden": true, children: /* @__PURE__ */ jsx92(
44059
+ return /* @__PURE__ */ jsx93("div", { className: "squisq-block-preview-panel", "data-testid": "block-preview-panel", "aria-hidden": true, children: /* @__PURE__ */ jsx93(
43857
44060
  "div",
43858
44061
  {
43859
44062
  className: "squisq-block-preview-frame",
43860
44063
  style: { aspectRatio: `${viewport.width} / ${viewport.height}` },
43861
- children: /* @__PURE__ */ jsx92(
44064
+ children: /* @__PURE__ */ jsx93(
43862
44065
  BlockThumbnail,
43863
44066
  {
43864
44067
  visual,
@@ -43872,14 +44075,14 @@ function BlockPreviewPanel({ basePath = "/" }) {
43872
44075
  }
43873
44076
 
43874
44077
  // src/NavigationSheet.tsx
43875
- import { useCallback as useCallback57, useEffect as useEffect73, useId as useId16, useRef as useRef68, useState as useState84 } from "react";
44078
+ import { useCallback as useCallback57, useEffect as useEffect75, useId as useId17, useRef as useRef69, useState as useState85 } from "react";
43876
44079
 
43877
44080
  // src/BlockPreviewList.tsx
43878
- import { useCallback as useCallback56, useRef as useRef66 } from "react";
44081
+ import { useCallback as useCallback56, useRef as useRef67 } from "react";
43879
44082
  import { VIEWPORT_PRESETS as VIEWPORT_PRESETS8 } from "@bendyline/squisq/schemas";
43880
44083
  import { flattenBlocks as flattenBlocks7 } from "@bendyline/squisq/doc";
43881
44084
  import { BlockRenderer as BlockRenderer5, MediaContext as MediaContext6 } from "@bendyline/squisq-react";
43882
- import { Fragment as Fragment30, jsx as jsx93, jsxs as jsxs74 } from "react/jsx-runtime";
44085
+ import { Fragment as Fragment31, jsx as jsx94, jsxs as jsxs75 } from "react/jsx-runtime";
43883
44086
  function BlockPreviewList({
43884
44087
  basePath = "/",
43885
44088
  viewport = VIEWPORT_PRESETS8.landscape,
@@ -43888,7 +44091,7 @@ function BlockPreviewList({
43888
44091
  }) {
43889
44092
  const { doc, activeView, layoutMode, goToBlockByLine, monacoEditor } = useEditorContext();
43890
44093
  const items = useBlockPreviewItems(viewport);
43891
- const listRef = useRef66(null);
44094
+ const listRef = useRef67(null);
43892
44095
  const handleSelect = useCallback56(
43893
44096
  (item) => {
43894
44097
  const line = blockStartLine(item.sourceBlock);
@@ -43915,9 +44118,9 @@ function BlockPreviewList({
43915
44118
  [activeView, doc, goToBlockByLine, layoutMode, monacoEditor, onNavigate]
43916
44119
  );
43917
44120
  if (items.length === 0) {
43918
- return /* @__PURE__ */ jsx93("div", { className: "squisq-preview-list-empty", children: /* @__PURE__ */ jsx93("p", { children: "Add some content to see block previews." }) });
44121
+ return /* @__PURE__ */ jsx94("div", { className: "squisq-preview-list-empty", children: /* @__PURE__ */ jsx94("p", { children: "Add some content to see block previews." }) });
43919
44122
  }
43920
- 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(
44123
+ return /* @__PURE__ */ jsx94(MediaContext6.Provider, { value: mediaProvider, children: /* @__PURE__ */ jsx94("ul", { ref: listRef, className: "squisq-preview-list", "aria-label": "Block previews", children: items.map((item) => /* @__PURE__ */ jsx94("li", { children: /* @__PURE__ */ jsxs75(
43921
44124
  "button",
43922
44125
  {
43923
44126
  type: "button",
@@ -43925,20 +44128,20 @@ function BlockPreviewList({
43925
44128
  "data-template": item.template,
43926
44129
  onClick: () => handleSelect(item),
43927
44130
  children: [
43928
- /* @__PURE__ */ jsxs74("span", { className: "squisq-inline-preview-card-label", children: [
43929
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-template", children: templateLabel(item.template) }),
43930
- item.headingText && /* @__PURE__ */ jsxs74(Fragment30, { children: [
43931
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-sep", "aria-hidden": "true", children: "\u2014" }),
43932
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-title", children: item.headingText })
44131
+ /* @__PURE__ */ jsxs75("span", { className: "squisq-inline-preview-card-label", children: [
44132
+ /* @__PURE__ */ jsx94("span", { className: "squisq-inline-preview-card-template", children: templateLabel(item.template) }),
44133
+ item.headingText && /* @__PURE__ */ jsxs75(Fragment31, { children: [
44134
+ /* @__PURE__ */ jsx94("span", { className: "squisq-inline-preview-card-sep", "aria-hidden": "true", children: "\u2014" }),
44135
+ /* @__PURE__ */ jsx94("span", { className: "squisq-inline-preview-card-title", children: item.headingText })
43933
44136
  ] })
43934
44137
  ] }),
43935
- /* @__PURE__ */ jsx93(
44138
+ /* @__PURE__ */ jsx94(
43936
44139
  "span",
43937
44140
  {
43938
44141
  className: "squisq-inline-preview-card-svg",
43939
44142
  "aria-hidden": "true",
43940
44143
  style: { aspectRatio: `${viewport.width} / ${viewport.height}` },
43941
- children: /* @__PURE__ */ jsx93(
44144
+ children: /* @__PURE__ */ jsx94(
43942
44145
  BlockRenderer5,
43943
44146
  {
43944
44147
  block: item.block,
@@ -43956,7 +44159,7 @@ function BlockPreviewList({
43956
44159
  }
43957
44160
 
43958
44161
  // src/useNavigationSheetSwipe.ts
43959
- import { useEffect as useEffect72, useRef as useRef67 } from "react";
44162
+ import { useEffect as useEffect74, useRef as useRef68 } from "react";
43960
44163
  var NAVIGATION_SHEET_MAX_BODY_WIDTH = 720;
43961
44164
  var EDGE_ZONE_PX = 24;
43962
44165
  var AXIS_LOCK_PX = 10;
@@ -43971,9 +44174,9 @@ function useNavigationSheetSwipe({
43971
44174
  onOpen,
43972
44175
  onClose
43973
44176
  }) {
43974
- const callbacksRef = useRef67({ onDragStart, onOpen, onClose });
44177
+ const callbacksRef = useRef68({ onDragStart, onOpen, onClose });
43975
44178
  callbacksRef.current = { onDragStart, onOpen, onClose };
43976
- useEffect72(() => {
44179
+ useEffect74(() => {
43977
44180
  const sheet = sheetRef.current;
43978
44181
  const surface = sheet?.parentElement;
43979
44182
  if (!sheet || !surface) return;
@@ -44079,7 +44282,7 @@ function useNavigationSheetSwipe({
44079
44282
  }
44080
44283
 
44081
44284
  // src/NavigationSheet.tsx
44082
- import { Fragment as Fragment31, jsx as jsx94, jsxs as jsxs75 } from "react/jsx-runtime";
44285
+ import { Fragment as Fragment32, jsx as jsx95, jsxs as jsxs76 } from "react/jsx-runtime";
44083
44286
  var PANEL_LABELS = {
44084
44287
  outline: "Outline",
44085
44288
  previews: "Block previews"
@@ -44097,17 +44300,17 @@ function NavigationSheet({
44097
44300
  basePath,
44098
44301
  mediaProvider
44099
44302
  }) {
44100
- const sheetRef = useRef68(null);
44101
- const panelRef = useRef68(null);
44102
- const scrimRef = useRef68(null);
44103
- const tabIdPrefix = useId16();
44104
- const [dragPanel, setDragPanel] = useState84(null);
44303
+ const sheetRef = useRef69(null);
44304
+ const panelRef = useRef69(null);
44305
+ const scrimRef = useRef69(null);
44306
+ const tabIdPrefix = useId17();
44307
+ const [dragPanel, setDragPanel] = useState85(null);
44105
44308
  const open = panel !== null;
44106
44309
  const shown = panel ?? dragPanel;
44107
- const [lastShown, setLastShown] = useState84(shown);
44310
+ const [lastShown, setLastShown] = useState85(shown);
44108
44311
  if (shown && shown !== lastShown) setLastShown(shown);
44109
44312
  const content = shown ?? lastShown;
44110
- useEffect73(() => {
44313
+ useEffect75(() => {
44111
44314
  if (shown || !lastShown) return;
44112
44315
  const timer = setTimeout(() => setLastShown(null), CLOSE_LINGER_MS);
44113
44316
  return () => clearTimeout(timer);
@@ -44132,14 +44335,14 @@ function NavigationSheet({
44132
44335
  onClose: close
44133
44336
  });
44134
44337
  useEscapeDismissal(open, close);
44135
- useEffect73(() => {
44338
+ useEffect75(() => {
44136
44339
  const scrim = scrimRef.current;
44137
44340
  if (!scrim) return;
44138
44341
  const stop = (event) => event.stopPropagation();
44139
44342
  scrim.addEventListener("pointerdown", stop);
44140
44343
  return () => scrim.removeEventListener("pointerdown", stop);
44141
44344
  }, []);
44142
- useEffect73(() => {
44345
+ useEffect75(() => {
44143
44346
  const sheet = sheetRef.current;
44144
44347
  const surface = sheet?.parentElement;
44145
44348
  if (!open || !sheet || !surface) return;
@@ -44152,7 +44355,7 @@ function NavigationSheet({
44152
44355
  for (const sibling of siblings) sibling.inert = false;
44153
44356
  };
44154
44357
  }, [open]);
44155
- return /* @__PURE__ */ jsxs75(
44358
+ return /* @__PURE__ */ jsxs76(
44156
44359
  "div",
44157
44360
  {
44158
44361
  ref: sheetRef,
@@ -44160,8 +44363,8 @@ function NavigationSheet({
44160
44363
  "data-state": open ? "open" : dragPanel ? "dragging" : "closed",
44161
44364
  "data-testid": "navigation-sheet",
44162
44365
  children: [
44163
- /* @__PURE__ */ jsx94("div", { ref: scrimRef, className: "squisq-navigation-sheet-scrim", onClick: close }),
44164
- /* @__PURE__ */ jsx94(
44366
+ /* @__PURE__ */ jsx95("div", { ref: scrimRef, className: "squisq-navigation-sheet-scrim", onClick: close }),
44367
+ /* @__PURE__ */ jsx95(
44165
44368
  "div",
44166
44369
  {
44167
44370
  ref: panelRef,
@@ -44169,9 +44372,9 @@ function NavigationSheet({
44169
44372
  role: "dialog",
44170
44373
  "aria-label": content ? PANEL_LABELS[content] : "Document navigation",
44171
44374
  tabIndex: -1,
44172
- children: content && /* @__PURE__ */ jsxs75(Fragment31, { children: [
44173
- /* @__PURE__ */ jsxs75("div", { className: "squisq-navigation-sheet-header", children: [
44174
- /* @__PURE__ */ jsx94("div", { className: "squisq-navigation-sheet-tabs", role: "tablist", children: PANELS.map((option) => /* @__PURE__ */ jsx94(
44375
+ children: content && /* @__PURE__ */ jsxs76(Fragment32, { children: [
44376
+ /* @__PURE__ */ jsxs76("div", { className: "squisq-navigation-sheet-header", children: [
44377
+ /* @__PURE__ */ jsx95("div", { className: "squisq-navigation-sheet-tabs", role: "tablist", children: PANELS.map((option) => /* @__PURE__ */ jsx95(
44175
44378
  "button",
44176
44379
  {
44177
44380
  type: "button",
@@ -44185,25 +44388,25 @@ function NavigationSheet({
44185
44388
  },
44186
44389
  option
44187
44390
  )) }),
44188
- /* @__PURE__ */ jsx94(
44391
+ /* @__PURE__ */ jsx95(
44189
44392
  "button",
44190
44393
  {
44191
44394
  type: "button",
44192
44395
  className: "squisq-navigation-sheet-close",
44193
44396
  "aria-label": "Close",
44194
44397
  onClick: close,
44195
- children: /* @__PURE__ */ jsx94(Icon, { icon: "xmark" })
44398
+ children: /* @__PURE__ */ jsx95(Icon, { icon: "xmark" })
44196
44399
  }
44197
44400
  )
44198
44401
  ] }),
44199
- /* @__PURE__ */ jsx94(
44402
+ /* @__PURE__ */ jsx95(
44200
44403
  "div",
44201
44404
  {
44202
44405
  id: `${tabIdPrefix}-body`,
44203
44406
  className: "squisq-navigation-sheet-body",
44204
44407
  role: "tabpanel",
44205
44408
  "aria-labelledby": `${tabIdPrefix}-${content}`,
44206
- children: content === "outline" ? /* @__PURE__ */ jsx94(OutlinePanel, { presentation: "sheet", readOnly, onNavigate: close }) : /* @__PURE__ */ jsx94(
44409
+ children: content === "outline" ? /* @__PURE__ */ jsx95(OutlinePanel, { presentation: "sheet", readOnly, onNavigate: close }) : /* @__PURE__ */ jsx95(
44207
44410
  BlockPreviewList,
44208
44411
  {
44209
44412
  basePath,
@@ -44222,7 +44425,7 @@ function NavigationSheet({
44222
44425
  }
44223
44426
 
44224
44427
  // src/proofing/ProofingPanel.tsx
44225
- import { jsx as jsx95, jsxs as jsxs76 } from "react/jsx-runtime";
44428
+ import { jsx as jsx96, jsxs as jsxs77 } from "react/jsx-runtime";
44226
44429
  var CATEGORY_LABELS = {
44227
44430
  spelling: "Spelling",
44228
44431
  grammar: "Grammar",
@@ -44232,14 +44435,14 @@ function ProofingPanel() {
44232
44435
  const state = useProofingState();
44233
44436
  if (!state || !state.panelVisible || !state.enabled) return null;
44234
44437
  const { findings, activeFindingId } = state;
44235
- return /* @__PURE__ */ jsxs76("aside", { className: "squisq-proof-panel", "aria-label": "Proofing findings", children: [
44236
- /* @__PURE__ */ jsxs76("div", { className: "squisq-proof-panel-header", children: [
44237
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-title", children: [
44438
+ return /* @__PURE__ */ jsxs77("aside", { className: "squisq-proof-panel", "aria-label": "Proofing findings", children: [
44439
+ /* @__PURE__ */ jsxs77("div", { className: "squisq-proof-panel-header", children: [
44440
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-title", children: [
44238
44441
  "Proofing",
44239
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-count", children: findings.length })
44442
+ /* @__PURE__ */ jsx96("span", { className: "squisq-proof-panel-count", children: findings.length })
44240
44443
  ] }),
44241
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-actions", children: [
44242
- /* @__PURE__ */ jsx95(
44444
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-actions", children: [
44445
+ /* @__PURE__ */ jsx96(
44243
44446
  "button",
44244
44447
  {
44245
44448
  type: "button",
@@ -44251,7 +44454,7 @@ function ProofingPanel() {
44251
44454
  children: "\u2191"
44252
44455
  }
44253
44456
  ),
44254
- /* @__PURE__ */ jsx95(
44457
+ /* @__PURE__ */ jsx96(
44255
44458
  "button",
44256
44459
  {
44257
44460
  type: "button",
@@ -44263,7 +44466,7 @@ function ProofingPanel() {
44263
44466
  children: "\u2193"
44264
44467
  }
44265
44468
  ),
44266
- /* @__PURE__ */ jsx95(
44469
+ /* @__PURE__ */ jsx96(
44267
44470
  "button",
44268
44471
  {
44269
44472
  type: "button",
@@ -44276,20 +44479,20 @@ function ProofingPanel() {
44276
44479
  )
44277
44480
  ] })
44278
44481
  ] }),
44279
- state.status === "loading" && /* @__PURE__ */ jsx95("div", { className: "squisq-proof-panel-empty", children: "Loading proofing engine\u2026" }),
44280
- state.status === "error" && /* @__PURE__ */ jsxs76("div", { className: "squisq-proof-panel-empty", children: [
44482
+ state.status === "loading" && /* @__PURE__ */ jsx96("div", { className: "squisq-proof-panel-empty", children: "Loading proofing engine\u2026" }),
44483
+ state.status === "error" && /* @__PURE__ */ jsxs77("div", { className: "squisq-proof-panel-empty", children: [
44281
44484
  "Proofing failed to load.",
44282
- /* @__PURE__ */ jsx95("button", { type: "button", className: "squisq-proof-panel-retry", onClick: state.retrySetup, children: "Retry" })
44485
+ /* @__PURE__ */ jsx96("button", { type: "button", className: "squisq-proof-panel-retry", onClick: state.retrySetup, children: "Retry" })
44283
44486
  ] }),
44284
- state.status === "ready" && findings.length === 0 && /* @__PURE__ */ jsx95("div", { className: "squisq-proof-panel-empty", children: "No issues found." }),
44285
- /* @__PURE__ */ jsx95("ul", { className: "squisq-proof-panel-list", children: findings.map((finding) => /* @__PURE__ */ jsx95("li", { children: /* @__PURE__ */ jsxs76(
44487
+ state.status === "ready" && findings.length === 0 && /* @__PURE__ */ jsx96("div", { className: "squisq-proof-panel-empty", children: "No issues found." }),
44488
+ /* @__PURE__ */ jsx96("ul", { className: "squisq-proof-panel-list", children: findings.map((finding) => /* @__PURE__ */ jsx96("li", { children: /* @__PURE__ */ jsxs77(
44286
44489
  "button",
44287
44490
  {
44288
44491
  type: "button",
44289
44492
  className: finding.id === activeFindingId ? "squisq-proof-panel-row squisq-proof-panel-row--active" : "squisq-proof-panel-row",
44290
44493
  onClick: () => state.selectFinding(finding.id),
44291
44494
  children: [
44292
- /* @__PURE__ */ jsx95(
44495
+ /* @__PURE__ */ jsx96(
44293
44496
  "span",
44294
44497
  {
44295
44498
  className: `squisq-proof-dot squisq-proof-dot--${finding.category}`,
@@ -44297,9 +44500,9 @@ function ProofingPanel() {
44297
44500
  "aria-hidden": true
44298
44501
  }
44299
44502
  ),
44300
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-row-body", children: [
44301
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-excerpt", children: finding.originalText }),
44302
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-message", children: proofMessageText(finding) })
44503
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-row-body", children: [
44504
+ /* @__PURE__ */ jsx96("span", { className: "squisq-proof-panel-excerpt", children: finding.originalText }),
44505
+ /* @__PURE__ */ jsx96("span", { className: "squisq-proof-panel-message", children: proofMessageText(finding) })
44303
44506
  ] })
44304
44507
  ]
44305
44508
  }
@@ -44308,13 +44511,13 @@ function ProofingPanel() {
44308
44511
  }
44309
44512
 
44310
44513
  // src/imageEditor/ImageEditModal.tsx
44311
- import { useCallback as useCallback58, useEffect as useEffect74, useMemo as useMemo59, useRef as useRef69, useState as useState85 } from "react";
44514
+ import { useCallback as useCallback58, useEffect as useEffect76, useMemo as useMemo59, useRef as useRef70, useState as useState86 } from "react";
44312
44515
  import { DARK_SURFACE, LIGHT_SURFACE } from "@bendyline/squisq/schemas";
44313
44516
  import {
44314
44517
  MemoryContentContainer,
44315
44518
  scopeContainer
44316
44519
  } from "@bendyline/squisq/storage";
44317
- import { jsx as jsx96, jsxs as jsxs77 } from "react/jsx-runtime";
44520
+ import { jsx as jsx97, jsxs as jsxs78 } from "react/jsx-runtime";
44318
44521
  function ImageEditModal({
44319
44522
  relativePath,
44320
44523
  container,
@@ -44325,8 +44528,8 @@ function ImageEditModal({
44325
44528
  versioningAutoSaveIdleMs,
44326
44529
  shellTheme
44327
44530
  }) {
44328
- const modalRef = useRef69(null);
44329
- const surfaceRef = useRef69(null);
44531
+ const modalRef = useRef70(null);
44532
+ const surfaceRef = useRef70(null);
44330
44533
  useModalDialog({ rootRef: modalRef, dialogRef: surfaceRef, onClose });
44331
44534
  const extension = relativePath.split(/[?#]/, 1)[0]?.split(".").pop()?.toLowerCase();
44332
44535
  const saveFormat = extension === "png" ? "png" : extension === "jpg" || extension === "jpeg" ? "jpeg" : extension === "webp" ? "webp" : null;
@@ -44341,9 +44544,9 @@ function ImageEditModal({
44341
44544
  const parent = container ?? new MemoryContentContainer();
44342
44545
  return scopeContainer(parent, `.imageEdits/${scopedName}`);
44343
44546
  }, [container, relativePath]);
44344
- const [initialSrc, setInitialSrc] = useState85(null);
44345
- const [resolveError, setResolveError] = useState85(null);
44346
- useEffect74(() => {
44547
+ const [initialSrc, setInitialSrc] = useState86(null);
44548
+ const [resolveError, setResolveError] = useState86(null);
44549
+ useEffect76(() => {
44347
44550
  let cancelled = false;
44348
44551
  setInitialSrc(null);
44349
44552
  setResolveError(null);
@@ -44373,7 +44576,7 @@ function ImageEditModal({
44373
44576
  },
44374
44577
  [mediaProvider, relativePath, onSaved]
44375
44578
  );
44376
- return /* @__PURE__ */ jsx96(
44579
+ return /* @__PURE__ */ jsx97(
44377
44580
  "div",
44378
44581
  {
44379
44582
  ref: modalRef,
@@ -44385,11 +44588,11 @@ function ImageEditModal({
44385
44588
  onClick: (e2) => {
44386
44589
  if (e2.target === e2.currentTarget) onClose();
44387
44590
  },
44388
- children: /* @__PURE__ */ jsxs77("div", { ref: surfaceRef, className: "squisq-image-edit-modal__surface", children: [
44389
- /* @__PURE__ */ jsxs77("header", { className: "squisq-image-edit-modal__header", children: [
44390
- /* @__PURE__ */ jsx96("span", { className: "squisq-image-edit-modal__title", children: "Edit image" }),
44391
- /* @__PURE__ */ jsx96("span", { className: "squisq-image-edit-modal__path", children: relativePath }),
44392
- /* @__PURE__ */ jsx96(
44591
+ children: /* @__PURE__ */ jsxs78("div", { ref: surfaceRef, className: "squisq-image-edit-modal__surface", children: [
44592
+ /* @__PURE__ */ jsxs78("header", { className: "squisq-image-edit-modal__header", children: [
44593
+ /* @__PURE__ */ jsx97("span", { className: "squisq-image-edit-modal__title", children: "Edit image" }),
44594
+ /* @__PURE__ */ jsx97("span", { className: "squisq-image-edit-modal__path", children: relativePath }),
44595
+ /* @__PURE__ */ jsx97(
44393
44596
  "button",
44394
44597
  {
44395
44598
  type: "button",
@@ -44401,10 +44604,10 @@ function ImageEditModal({
44401
44604
  }
44402
44605
  )
44403
44606
  ] }),
44404
- /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__body", children: resolveError ? /* @__PURE__ */ jsxs77("div", { className: "squisq-image-edit-modal__error", children: [
44607
+ /* @__PURE__ */ jsx97("div", { className: "squisq-image-edit-modal__body", children: resolveError ? /* @__PURE__ */ jsxs78("div", { className: "squisq-image-edit-modal__error", children: [
44405
44608
  "Failed to load image: ",
44406
44609
  resolveError
44407
- ] }) : !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(
44610
+ ] }) : !saveFormat ? /* @__PURE__ */ jsx97("div", { className: "squisq-image-edit-modal__error", children: "Editing supports PNG, JPEG, and WebP images without changing the asset type." }) : !initialSrc ? /* @__PURE__ */ jsx97("div", { className: "squisq-image-edit-modal__loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsx97(
44408
44611
  ImageEditor,
44409
44612
  {
44410
44613
  filesContainer: sidecar,
@@ -44465,18 +44668,18 @@ function MediaEditContextMenuItems() {
44465
44668
  // src/mediaEdit/MediaEditModal.tsx
44466
44669
  import {
44467
44670
  useCallback as useCallback62,
44468
- useEffect as useEffect77,
44469
- useId as useId17,
44671
+ useEffect as useEffect79,
44672
+ useId as useId18,
44470
44673
  useMemo as useMemo61,
44471
- useRef as useRef73,
44472
- useState as useState89
44674
+ useRef as useRef74,
44675
+ useState as useState90
44473
44676
  } from "react";
44474
44677
  import {
44475
44678
  useMediaEditStatus as useMediaEditStatus2
44476
44679
  } from "@bendyline/squisq-video-react/media-edit";
44477
44680
 
44478
44681
  // src/mediaEdit/MediaEditAudioSection.tsx
44479
- import { useCallback as useCallback59, useEffect as useEffect75, useRef as useRef70, useState as useState86 } from "react";
44682
+ import { useCallback as useCallback59, useEffect as useEffect77, useRef as useRef71, useState as useState87 } from "react";
44480
44683
  import { MEDIA_FX_SPECS as MEDIA_FX_SPECS2, serializeMediaFx } from "@bendyline/squisq/mediaEdit";
44481
44684
 
44482
44685
  // src/mediaEdit/mediaEditDraft.ts
@@ -44575,7 +44778,7 @@ function centeredCrop(ratio, frameWidth, frameHeight) {
44575
44778
  }
44576
44779
 
44577
44780
  // src/mediaEdit/MediaEditAudioSection.tsx
44578
- import { Fragment as Fragment32, jsx as jsx97, jsxs as jsxs78 } from "react/jsx-runtime";
44781
+ import { Fragment as Fragment33, jsx as jsx98, jsxs as jsxs79 } from "react/jsx-runtime";
44579
44782
  var STAGES = [
44580
44783
  {
44581
44784
  id: "highpass",
@@ -44629,8 +44832,8 @@ var LOUDNESS_PRESETS = [
44629
44832
  ];
44630
44833
  var PREVIEW_SECONDS = 10;
44631
44834
  function useMediaDuration(url) {
44632
- const [duration, setDuration] = useState86(null);
44633
- useEffect75(() => {
44835
+ const [duration, setDuration] = useState87(null);
44836
+ useEffect77(() => {
44634
44837
  setDuration(null);
44635
44838
  if (!url || typeof Audio === "undefined") return;
44636
44839
  const probe = new Audio();
@@ -44647,12 +44850,12 @@ function useMediaDuration(url) {
44647
44850
  return duration;
44648
44851
  }
44649
44852
  function usePreviewPlayer(preview) {
44650
- const ctxRef = useRef70(null);
44651
- const sourceRef = useRef70(null);
44652
- const startedRef = useRef70(null);
44653
- const [playing, setPlaying] = useState86(null);
44654
- const cueRef = useRef70(0);
44655
- const [position, setPosition] = useState86(0);
44853
+ const ctxRef = useRef71(null);
44854
+ const sourceRef = useRef71(null);
44855
+ const startedRef = useRef71(null);
44856
+ const [playing, setPlaying] = useState87(null);
44857
+ const cueRef = useRef71(0);
44858
+ const [position, setPosition] = useState87(0);
44656
44859
  const frames = preview?.original[0]?.length ?? 0;
44657
44860
  const duration = preview && frames > 0 ? frames / preview.sampleRate : 0;
44658
44861
  const currentOffset = useCallback59(() => {
@@ -44670,8 +44873,8 @@ function usePreviewPlayer(preview) {
44670
44873
  setPosition(0);
44671
44874
  setPlaying(null);
44672
44875
  }, []);
44673
- useEffect75(() => stop, [preview, stop]);
44674
- useEffect75(
44876
+ useEffect77(() => stop, [preview, stop]);
44877
+ useEffect77(
44675
44878
  () => () => {
44676
44879
  void ctxRef.current?.close();
44677
44880
  ctxRef.current = null;
@@ -44710,7 +44913,7 @@ function usePreviewPlayer(preview) {
44710
44913
  },
44711
44914
  [duration, playing, play]
44712
44915
  );
44713
- useEffect75(() => {
44916
+ useEffect77(() => {
44714
44917
  if (!playing) return;
44715
44918
  let frame = requestAnimationFrame(function tick() {
44716
44919
  setPosition(currentOffset());
@@ -44721,26 +44924,26 @@ function usePreviewPlayer(preview) {
44721
44924
  return { playing, play, stop, seek, position, duration };
44722
44925
  }
44723
44926
  function PlayIcon() {
44724
- return /* @__PURE__ */ jsx97(
44927
+ return /* @__PURE__ */ jsx98(
44725
44928
  "svg",
44726
44929
  {
44727
44930
  className: "squisq-media-edit-icon",
44728
44931
  viewBox: "0 0 10 10",
44729
44932
  "aria-hidden": "true",
44730
44933
  focusable: "false",
44731
- children: /* @__PURE__ */ jsx97("path", { d: "M2 1 9 5 2 9Z" })
44934
+ children: /* @__PURE__ */ jsx98("path", { d: "M2 1 9 5 2 9Z" })
44732
44935
  }
44733
44936
  );
44734
44937
  }
44735
44938
  function StopIcon() {
44736
- return /* @__PURE__ */ jsx97(
44939
+ return /* @__PURE__ */ jsx98(
44737
44940
  "svg",
44738
44941
  {
44739
44942
  className: "squisq-media-edit-icon",
44740
44943
  viewBox: "0 0 10 10",
44741
44944
  "aria-hidden": "true",
44742
44945
  focusable: "false",
44743
- children: /* @__PURE__ */ jsx97("rect", { x: "1.5", y: "1.5", width: "7", height: "7", rx: "1" })
44946
+ children: /* @__PURE__ */ jsx98("rect", { x: "1.5", y: "1.5", width: "7", height: "7", rx: "1" })
44744
44947
  }
44745
44948
  );
44746
44949
  }
@@ -44758,14 +44961,14 @@ function MediaEditAudioSection({
44758
44961
  const duration = useMediaDuration(resolvedSrc);
44759
44962
  const windowMin = item.clipStart ?? 0;
44760
44963
  const windowMax = Math.max(windowMin, (item.clipEnd ?? duration ?? windowMin) - 1);
44761
- const [previewFrom, setPreviewFrom] = useState86(windowMin);
44762
- const [preview, setPreview] = useState86(null);
44763
- const [previewedFx, setPreviewedFx] = useState86(null);
44764
- const [previewing, setPreviewing] = useState86(false);
44765
- const [previewError, setPreviewError] = useState86(null);
44766
- const previewAbort = useRef70(null);
44964
+ const [previewFrom, setPreviewFrom] = useState87(windowMin);
44965
+ const [preview, setPreview] = useState87(null);
44966
+ const [previewedFx, setPreviewedFx] = useState87(null);
44967
+ const [previewing, setPreviewing] = useState87(false);
44968
+ const [previewError, setPreviewError] = useState87(null);
44969
+ const previewAbort = useRef71(null);
44767
44970
  const player = usePreviewPlayer(preview);
44768
- useEffect75(() => () => previewAbort.current?.abort(), []);
44971
+ useEffect77(() => () => previewAbort.current?.abort(), []);
44769
44972
  const runPreview = useCallback59(async () => {
44770
44973
  if (draftFx.ops.length === 0) return;
44771
44974
  previewAbort.current?.abort();
@@ -44790,23 +44993,23 @@ function MediaEditAudioSection({
44790
44993
  setPreviewing(false);
44791
44994
  }
44792
44995
  }, [draftFx.ops.length, manager, item.src, knownFx, previewFrom]);
44793
- return /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-section", children: [
44794
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-presets", role: "group", "aria-label": "Presets", children: [
44795
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("voice") }), children: "Clean up voice" }),
44796
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("levels") }), children: "Levels only" }),
44797
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("none") }), children: "None" })
44996
+ return /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-section", children: [
44997
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-presets", role: "group", "aria-label": "Presets", children: [
44998
+ /* @__PURE__ */ jsx98("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("voice") }), children: "Clean up voice" }),
44999
+ /* @__PURE__ */ jsx98("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("levels") }), children: "Levels only" }),
45000
+ /* @__PURE__ */ jsx98("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("none") }), children: "None" })
44798
45001
  ] }),
44799
- /* @__PURE__ */ jsx97("ul", { className: "squisq-media-edit-stages", children: STAGES.map((stage) => {
45002
+ /* @__PURE__ */ jsx98("ul", { className: "squisq-media-edit-stages", children: STAGES.map((stage) => {
44800
45003
  const s = draft.fx[stage.id];
44801
45004
  const inputId = `${idPrefix}-${stage.id}`;
44802
- return /* @__PURE__ */ jsxs78(
45005
+ return /* @__PURE__ */ jsxs79(
44803
45006
  "li",
44804
45007
  {
44805
45008
  className: "squisq-media-edit-stage",
44806
45009
  "data-enabled": s.enabled ? "true" : "false",
44807
45010
  children: [
44808
- /* @__PURE__ */ jsxs78("label", { className: "squisq-media-edit-stage__toggle", children: [
44809
- /* @__PURE__ */ jsx97(
45011
+ /* @__PURE__ */ jsxs79("label", { className: "squisq-media-edit-stage__toggle", children: [
45012
+ /* @__PURE__ */ jsx98(
44810
45013
  "input",
44811
45014
  {
44812
45015
  type: "checkbox",
@@ -44814,9 +45017,9 @@ function MediaEditAudioSection({
44814
45017
  onChange: (e2) => setStage(stage.id, { enabled: e2.target.checked })
44815
45018
  }
44816
45019
  ),
44817
- /* @__PURE__ */ jsx97("span", { className: "squisq-media-edit-stage__label", children: stage.label })
45020
+ /* @__PURE__ */ jsx98("span", { className: "squisq-media-edit-stage__label", children: stage.label })
44818
45021
  ] }),
44819
- /* @__PURE__ */ jsx97(
45022
+ /* @__PURE__ */ jsx98(
44820
45023
  "input",
44821
45024
  {
44822
45025
  id: inputId,
@@ -44832,9 +45035,9 @@ function MediaEditAudioSection({
44832
45035
  onChange: (e2) => setStage(stage.id, { value: stage.toValue(Number(e2.target.value)) })
44833
45036
  }
44834
45037
  ),
44835
- /* @__PURE__ */ jsx97("output", { className: "squisq-media-edit-stage__value", htmlFor: inputId, children: stage.format(s.value) }),
44836
- /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-stage__hint", children: stage.hint }),
44837
- 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(
45038
+ /* @__PURE__ */ jsx98("output", { className: "squisq-media-edit-stage__value", htmlFor: inputId, children: stage.format(s.value) }),
45039
+ /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-stage__hint", children: stage.hint }),
45040
+ stage.id === "loudness" && s.enabled && /* @__PURE__ */ jsx98("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Targets", children: LOUDNESS_PRESETS.map((preset) => /* @__PURE__ */ jsxs79(
44838
45041
  "button",
44839
45042
  {
44840
45043
  type: "button",
@@ -44854,14 +45057,14 @@ function MediaEditAudioSection({
44854
45057
  stage.id
44855
45058
  );
44856
45059
  }) }),
44857
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-preview", "aria-label": "Preview", children: [
44858
- duration != null && windowMax > windowMin && /* @__PURE__ */ jsxs78("label", { className: "squisq-media-edit-preview__from", children: [
44859
- /* @__PURE__ */ jsxs78("span", { children: [
45060
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview", "aria-label": "Preview", children: [
45061
+ duration != null && windowMax > windowMin && /* @__PURE__ */ jsxs79("label", { className: "squisq-media-edit-preview__from", children: [
45062
+ /* @__PURE__ */ jsxs79("span", { children: [
44860
45063
  "Preview from ",
44861
45064
  previewFrom.toFixed(0),
44862
45065
  " s"
44863
45066
  ] }),
44864
- /* @__PURE__ */ jsx97(
45067
+ /* @__PURE__ */ jsx98(
44865
45068
  "input",
44866
45069
  {
44867
45070
  type: "range",
@@ -44873,7 +45076,7 @@ function MediaEditAudioSection({
44873
45076
  }
44874
45077
  )
44875
45078
  ] }),
44876
- /* @__PURE__ */ jsx97("div", { className: "squisq-media-edit-preview__actions", children: /* @__PURE__ */ jsx97(
45079
+ /* @__PURE__ */ jsx98("div", { className: "squisq-media-edit-preview__actions", children: /* @__PURE__ */ jsx98(
44877
45080
  "button",
44878
45081
  {
44879
45082
  type: "button",
@@ -44882,10 +45085,10 @@ function MediaEditAudioSection({
44882
45085
  children: previewing ? "Rendering preview\u2026" : preview ? "Update preview" : "Create preview"
44883
45086
  }
44884
45087
  ) }),
44885
- preview != null && player.duration > 0 && /* @__PURE__ */ jsxs78(Fragment32, { children: [
44886
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-playback", "data-playing": player.playing ?? void 0, children: [
44887
- /* @__PURE__ */ jsx97("span", { className: "squisq-media-edit-playback__label", children: player.playing ? `${player.playing === "original" ? "Original" : "Processed"} from ${Math.round(preview.startSec)} s` : "Stopped" }),
44888
- /* @__PURE__ */ jsx97(
45088
+ preview != null && player.duration > 0 && /* @__PURE__ */ jsxs79(Fragment33, { children: [
45089
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-playback", "data-playing": player.playing ?? void 0, children: [
45090
+ /* @__PURE__ */ jsx98("span", { className: "squisq-media-edit-playback__label", children: player.playing ? `${player.playing === "original" ? "Original" : "Processed"} from ${Math.round(preview.startSec)} s` : "Stopped" }),
45091
+ /* @__PURE__ */ jsx98(
44889
45092
  "input",
44890
45093
  {
44891
45094
  type: "range",
@@ -44899,14 +45102,14 @@ function MediaEditAudioSection({
44899
45102
  onChange: (e2) => player.seek(Number(e2.target.value))
44900
45103
  }
44901
45104
  ),
44902
- /* @__PURE__ */ jsxs78("span", { className: "squisq-media-edit-playback__time", children: [
45105
+ /* @__PURE__ */ jsxs79("span", { className: "squisq-media-edit-playback__time", children: [
44903
45106
  formatClock6(player.position),
44904
45107
  " / ",
44905
45108
  formatClock6(player.duration)
44906
45109
  ] })
44907
45110
  ] }),
44908
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-preview__actions", children: [
44909
- /* @__PURE__ */ jsxs78(
45111
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview__actions", children: [
45112
+ /* @__PURE__ */ jsxs79(
44910
45113
  "button",
44911
45114
  {
44912
45115
  type: "button",
@@ -44914,12 +45117,12 @@ function MediaEditAudioSection({
44914
45117
  disabled: previewing,
44915
45118
  onClick: () => player.play("original"),
44916
45119
  children: [
44917
- /* @__PURE__ */ jsx97(PlayIcon, {}),
45120
+ /* @__PURE__ */ jsx98(PlayIcon, {}),
44918
45121
  "Original"
44919
45122
  ]
44920
45123
  }
44921
45124
  ),
44922
- /* @__PURE__ */ jsxs78(
45125
+ /* @__PURE__ */ jsxs79(
44923
45126
  "button",
44924
45127
  {
44925
45128
  type: "button",
@@ -44927,26 +45130,26 @@ function MediaEditAudioSection({
44927
45130
  disabled: previewing,
44928
45131
  onClick: () => player.play("processed"),
44929
45132
  children: [
44930
- /* @__PURE__ */ jsx97(PlayIcon, {}),
45133
+ /* @__PURE__ */ jsx98(PlayIcon, {}),
44931
45134
  "Processed"
44932
45135
  ]
44933
45136
  }
44934
45137
  ),
44935
- /* @__PURE__ */ jsxs78("button", { type: "button", disabled: !player.playing, onClick: player.stop, children: [
44936
- /* @__PURE__ */ jsx97(StopIcon, {}),
45138
+ /* @__PURE__ */ jsxs79("button", { type: "button", disabled: !player.playing, onClick: player.stop, children: [
45139
+ /* @__PURE__ */ jsx98(StopIcon, {}),
44937
45140
  "Stop"
44938
45141
  ] })
44939
45142
  ] })
44940
45143
  ] }),
44941
- preview != null && previewedFx !== knownFx && /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-note", children: "Settings changed \u2014 update the preview to hear them." }),
44942
- previewError && /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: previewError })
45144
+ preview != null && previewedFx !== knownFx && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note", children: "Settings changed \u2014 update the preview to hear them." }),
45145
+ previewError && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: previewError })
44943
45146
  ] })
44944
45147
  ] });
44945
45148
  }
44946
45149
 
44947
45150
  // src/mediaEdit/MediaEditTimingSection.tsx
44948
- import { useCallback as useCallback60, useEffect as useEffect76, useRef as useRef71, useState as useState87 } from "react";
44949
- import { jsx as jsx98, jsxs as jsxs79 } from "react/jsx-runtime";
45151
+ import { useCallback as useCallback60, useEffect as useEffect78, useRef as useRef72, useState as useState88 } from "react";
45152
+ import { jsx as jsx99, jsxs as jsxs80 } from "react/jsx-runtime";
44950
45153
  var DEFAULT_MAX_PAUSE = 0.8;
44951
45154
  function formatDb(value) {
44952
45155
  if (value === 0) return "0 dB";
@@ -44959,11 +45162,11 @@ function MediaEditTimingSection({
44959
45162
  manager,
44960
45163
  idPrefix
44961
45164
  }) {
44962
- const [maxPause, setMaxPause] = useState87(DEFAULT_MAX_PAUSE);
44963
- const [finding, setFinding] = useState87(false);
44964
- const [error, setError] = useState87(null);
44965
- const abortRef = useRef71(null);
44966
- useEffect76(() => () => abortRef.current?.abort(), []);
45165
+ const [maxPause, setMaxPause] = useState88(DEFAULT_MAX_PAUSE);
45166
+ const [finding, setFinding] = useState88(false);
45167
+ const [error, setError] = useState88(null);
45168
+ const abortRef = useRef72(null);
45169
+ useEffect78(() => () => abortRef.current?.abort(), []);
44967
45170
  const findPauses = useCallback60(async () => {
44968
45171
  abortRef.current?.abort();
44969
45172
  const controller = new AbortController();
@@ -44987,10 +45190,10 @@ function MediaEditTimingSection({
44987
45190
  }
44988
45191
  }, [manager, item.src, maxPause, draft, onChange]);
44989
45192
  const saved = cutSeconds(draft.cuts);
44990
- return /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-section", children: [
44991
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
44992
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-pause`, children: "Shorten pauses longer than" }),
44993
- /* @__PURE__ */ jsx98(
45193
+ return /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-section", children: [
45194
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45195
+ /* @__PURE__ */ jsx99("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-pause`, children: "Shorten pauses longer than" }),
45196
+ /* @__PURE__ */ jsx99(
44994
45197
  "input",
44995
45198
  {
44996
45199
  id: `${idPrefix}-pause`,
@@ -45003,14 +45206,14 @@ function MediaEditTimingSection({
45003
45206
  onChange: (e2) => setMaxPause(Number(e2.target.value))
45004
45207
  }
45005
45208
  ),
45006
- /* @__PURE__ */ jsxs79("output", { htmlFor: `${idPrefix}-pause`, children: [
45209
+ /* @__PURE__ */ jsxs80("output", { htmlFor: `${idPrefix}-pause`, children: [
45007
45210
  maxPause.toFixed(1),
45008
45211
  " s"
45009
45212
  ] })
45010
45213
  ] }),
45011
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview__actions", children: [
45012
- /* @__PURE__ */ jsx98("button", { type: "button", onClick: findPauses, disabled: finding, children: finding ? "Finding pauses\u2026" : "Find pauses" }),
45013
- /* @__PURE__ */ jsx98(
45214
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-preview__actions", children: [
45215
+ /* @__PURE__ */ jsx99("button", { type: "button", onClick: findPauses, disabled: finding, children: finding ? "Finding pauses\u2026" : "Find pauses" }),
45216
+ /* @__PURE__ */ jsx99(
45014
45217
  "button",
45015
45218
  {
45016
45219
  type: "button",
@@ -45020,11 +45223,11 @@ function MediaEditTimingSection({
45020
45223
  }
45021
45224
  )
45022
45225
  ] }),
45023
- /* @__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)}.` }),
45024
- error && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: error }),
45025
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
45026
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-gain`, children: "Volume" }),
45027
- /* @__PURE__ */ jsx98(
45226
+ /* @__PURE__ */ jsx99("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)}.` }),
45227
+ error && /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: error }),
45228
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45229
+ /* @__PURE__ */ jsx99("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-gain`, children: "Volume" }),
45230
+ /* @__PURE__ */ jsx99(
45028
45231
  "input",
45029
45232
  {
45030
45233
  id: `${idPrefix}-gain`,
@@ -45037,11 +45240,11 @@ function MediaEditTimingSection({
45037
45240
  onChange: (e2) => onChange({ ...draft, gain: Number(e2.target.value) })
45038
45241
  }
45039
45242
  ),
45040
- /* @__PURE__ */ jsx98("output", { htmlFor: `${idPrefix}-gain`, children: formatDb(draft.gain) })
45243
+ /* @__PURE__ */ jsx99("output", { htmlFor: `${idPrefix}-gain`, children: formatDb(draft.gain) })
45041
45244
  ] }),
45042
- ["fadeIn", "fadeOut"].map((key) => /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
45043
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-${key}`, children: key === "fadeIn" ? "Fade in" : "Fade out" }),
45044
- /* @__PURE__ */ jsx98(
45245
+ ["fadeIn", "fadeOut"].map((key) => /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45246
+ /* @__PURE__ */ jsx99("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-${key}`, children: key === "fadeIn" ? "Fade in" : "Fade out" }),
45247
+ /* @__PURE__ */ jsx99(
45045
45248
  "input",
45046
45249
  {
45047
45250
  id: `${idPrefix}-${key}`,
@@ -45054,7 +45257,7 @@ function MediaEditTimingSection({
45054
45257
  onChange: (e2) => onChange({ ...draft, [key]: Number(e2.target.value) })
45055
45258
  }
45056
45259
  ),
45057
- /* @__PURE__ */ jsx98("output", { htmlFor: `${idPrefix}-${key}`, children: draft[key] === 0 ? "Off" : `${draft[key].toFixed(1)} s` })
45260
+ /* @__PURE__ */ jsx99("output", { htmlFor: `${idPrefix}-${key}`, children: draft[key] === 0 ? "Off" : `${draft[key].toFixed(1)} s` })
45058
45261
  ] }, key))
45059
45262
  ] });
45060
45263
  }
@@ -45062,11 +45265,11 @@ function MediaEditTimingSection({
45062
45265
  // src/mediaEdit/MediaEditFrameSection.tsx
45063
45266
  import {
45064
45267
  useCallback as useCallback61,
45065
- useRef as useRef72,
45066
- useState as useState88
45268
+ useRef as useRef73,
45269
+ useState as useState89
45067
45270
  } from "react";
45068
45271
  import { normalizeMediaCrop } from "@bendyline/squisq/mediaEdit";
45069
- import { jsx as jsx99, jsxs as jsxs80 } from "react/jsx-runtime";
45272
+ import { jsx as jsx100, jsxs as jsxs81 } from "react/jsx-runtime";
45070
45273
  var FULL = { x: 0, y: 0, w: 1, h: 1 };
45071
45274
  var MIN_EDGE = 0.05;
45072
45275
  var NUDGE = 0.01;
@@ -45089,9 +45292,9 @@ function clampCrop(crop) {
45089
45292
  }
45090
45293
  function MediaEditFrameSection({ item, draft, onChange }) {
45091
45294
  const src = useResolvedMediaSrc(item.src);
45092
- const [frame, setFrame] = useState88(null);
45093
- const [aspect, setAspect] = useState88(null);
45094
- const stageRef = useRef72(null);
45295
+ const [frame, setFrame] = useState89(null);
45296
+ const [aspect, setAspect] = useState89(null);
45297
+ const stageRef = useRef73(null);
45095
45298
  const crop = draft.crop ?? FULL;
45096
45299
  const setCrop = useCallback61(
45097
45300
  (next) => onChange({ ...draft, crop: normalizeMediaCrop(clampCrop(next)) }),
@@ -45146,9 +45349,9 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45146
45349
  );
45147
45350
  };
45148
45351
  const pct = (n) => `${(n * 100).toFixed(2)}%`;
45149
- return /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-section", children: [
45150
- /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Crop aspect", children: [
45151
- ASPECTS.map((option) => /* @__PURE__ */ jsx99(
45352
+ return /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-section", children: [
45353
+ /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Crop aspect", children: [
45354
+ ASPECTS.map((option) => /* @__PURE__ */ jsx100(
45152
45355
  "button",
45153
45356
  {
45154
45357
  type: "button",
@@ -45163,7 +45366,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45163
45366
  },
45164
45367
  option.label
45165
45368
  )),
45166
- /* @__PURE__ */ jsx99(
45369
+ /* @__PURE__ */ jsx100(
45167
45370
  "button",
45168
45371
  {
45169
45372
  type: "button",
@@ -45176,14 +45379,14 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45176
45379
  }
45177
45380
  )
45178
45381
  ] }),
45179
- /* @__PURE__ */ jsxs80(
45382
+ /* @__PURE__ */ jsxs81(
45180
45383
  "div",
45181
45384
  {
45182
45385
  ref: stageRef,
45183
45386
  className: "squisq-media-edit-crop",
45184
45387
  style: frame ? { aspectRatio: `${frame.w} / ${frame.h}` } : void 0,
45185
45388
  children: [
45186
- src && /* @__PURE__ */ jsx99(
45389
+ src && /* @__PURE__ */ jsx100(
45187
45390
  "video",
45188
45391
  {
45189
45392
  src,
@@ -45199,7 +45402,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45199
45402
  }
45200
45403
  }
45201
45404
  ),
45202
- /* @__PURE__ */ jsx99(
45405
+ /* @__PURE__ */ jsx100(
45203
45406
  "div",
45204
45407
  {
45205
45408
  className: "squisq-media-edit-crop__rect",
@@ -45210,7 +45413,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45210
45413
  style: { left: pct(crop.x), top: pct(crop.y), width: pct(crop.w), height: pct(crop.h) },
45211
45414
  onPointerDown: startDrag("move"),
45212
45415
  onKeyDown,
45213
- children: ["nw", "ne", "sw", "se"].map((handle) => /* @__PURE__ */ jsx99(
45416
+ children: ["nw", "ne", "sw", "se"].map((handle) => /* @__PURE__ */ jsx100(
45214
45417
  "span",
45215
45418
  {
45216
45419
  className: `squisq-media-edit-crop__handle squisq-media-edit-crop__handle--${handle}`,
@@ -45223,12 +45426,12 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45223
45426
  ]
45224
45427
  }
45225
45428
  ),
45226
- /* @__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." })
45429
+ /* @__PURE__ */ jsx100("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." })
45227
45430
  ] });
45228
45431
  }
45229
45432
 
45230
45433
  // src/mediaEdit/MediaEditModal.tsx
45231
- import { Fragment as Fragment33, jsx as jsx100, jsxs as jsxs81 } from "react/jsx-runtime";
45434
+ import { Fragment as Fragment34, jsx as jsx101, jsxs as jsxs82 } from "react/jsx-runtime";
45232
45435
  var TABS = [
45233
45436
  { id: "audio", label: "Audio cleanup" },
45234
45437
  { id: "timing", label: "Timing" },
@@ -45250,7 +45453,7 @@ function useRenderStatus(item, manager) {
45250
45453
  }
45251
45454
  var percent = (status) => `${Math.round((status.progress ?? 0) * 100)}%`;
45252
45455
  function RenderStatusBadge({ status }) {
45253
- return /* @__PURE__ */ jsxs81("span", { className: "squisq-media-edit-badge", "data-state": status.state, children: [
45456
+ return /* @__PURE__ */ jsxs82("span", { className: "squisq-media-edit-badge", "data-state": status.state, children: [
45254
45457
  status.state === "ready" && "Processed",
45255
45458
  status.state === "queued" && "Queued",
45256
45459
  status.state === "rendering" && `Processing ${percent(status)}`,
@@ -45263,43 +45466,43 @@ function RenderStatusText({
45263
45466
  }) {
45264
45467
  switch (status.state) {
45265
45468
  case "ready":
45266
- return /* @__PURE__ */ jsx100(Fragment33, { children: "Processed audio is in use." });
45469
+ return /* @__PURE__ */ jsx101(Fragment34, { children: "Processed audio is in use." });
45267
45470
  case "queued":
45268
- return /* @__PURE__ */ jsx100(Fragment33, { children: "Waiting to process\u2026" });
45471
+ return /* @__PURE__ */ jsx101(Fragment34, { children: "Waiting to process\u2026" });
45269
45472
  case "rendering":
45270
- return /* @__PURE__ */ jsxs81(Fragment33, { children: [
45473
+ return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45271
45474
  "Processing\u2026 ",
45272
45475
  percent(status)
45273
45476
  ] });
45274
45477
  case "failed":
45275
- return /* @__PURE__ */ jsxs81(Fragment33, { children: [
45478
+ return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45276
45479
  "Processing failed: ",
45277
45480
  status.error,
45278
45481
  " ",
45279
- /* @__PURE__ */ jsx100("button", { type: "button", onClick: onRetry, children: "Retry" })
45482
+ /* @__PURE__ */ jsx101("button", { type: "button", onClick: onRetry, children: "Retry" })
45280
45483
  ] });
45281
45484
  }
45282
45485
  }
45283
45486
  function MediaEditModal({ target, onClose }) {
45284
45487
  const { doc, markdownSource, setMarkdownSource, mediaEditRenders } = useEditorContext();
45285
- const modalRef = useRef73(null);
45286
- const surfaceRef = useRef73(null);
45287
- const titleId = useId17();
45488
+ const modalRef = useRef74(null);
45489
+ const surfaceRef = useRef74(null);
45490
+ const titleId = useId18();
45288
45491
  useModalDialog({ rootRef: modalRef, dialogRef: surfaceRef, onClose });
45289
45492
  const item = useMemo61(() => doc ? findEditableMedia(doc, target) : null, [doc, target]);
45290
45493
  const companions = useMemo61(() => doc && item ? groupCompanions(doc, item) : [], [doc, item]);
45291
45494
  const renderStatus = useRenderStatus(item, mediaEditRenders);
45292
- const [draft, setDraft] = useState89(() => draftFromEdits(item?.edits));
45495
+ const [draft, setDraft] = useState90(() => draftFromEdits(item?.edits));
45293
45496
  const seedKey = item ? `${item.sourceLine}|${editsSignature(item.edits)}` : null;
45294
- const seededRef = useRef73(null);
45295
- useEffect77(() => {
45497
+ const seededRef = useRef74(null);
45498
+ useEffect79(() => {
45296
45499
  if (seedKey === null || seededRef.current === seedKey) return;
45297
45500
  seededRef.current = seedKey;
45298
45501
  setDraft(draftFromEdits(item?.edits));
45299
45502
  }, [seedKey]);
45300
45503
  const tabs = TABS.filter((t) => t.id !== "frame" || item?.kind === "video");
45301
- const [activeTab, setActiveTab] = useState89("audio");
45302
- const tabRefs = useRef73(/* @__PURE__ */ new Map());
45504
+ const [activeTab, setActiveTab] = useState90("audio");
45505
+ const tabRefs = useRef74(/* @__PURE__ */ new Map());
45303
45506
  const onTabKeyDown = (event, index2) => {
45304
45507
  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;
45305
45508
  if (next == null) return;
@@ -45327,7 +45530,7 @@ function MediaEditModal({ target, onClose }) {
45327
45530
  const tabbed = item != null && mediaEditRenders != null;
45328
45531
  const tabId = (tab) => `${titleId}-tab-${tab}`;
45329
45532
  const panelId = (tab) => `${titleId}-panel-${tab}`;
45330
- return /* @__PURE__ */ jsx100(
45533
+ return /* @__PURE__ */ jsx101(
45331
45534
  "div",
45332
45535
  {
45333
45536
  ref: modalRef,
@@ -45336,7 +45539,7 @@ function MediaEditModal({ target, onClose }) {
45336
45539
  onClick: (e2) => {
45337
45540
  if (e2.target === e2.currentTarget) onClose();
45338
45541
  },
45339
- children: /* @__PURE__ */ jsxs81(
45542
+ children: /* @__PURE__ */ jsxs82(
45340
45543
  "div",
45341
45544
  {
45342
45545
  ref: surfaceRef,
@@ -45345,11 +45548,11 @@ function MediaEditModal({ target, onClose }) {
45345
45548
  "aria-modal": "true",
45346
45549
  "aria-labelledby": titleId,
45347
45550
  children: [
45348
- /* @__PURE__ */ jsxs81("header", { className: "squisq-media-edit-modal__header", children: [
45349
- /* @__PURE__ */ jsx100("span", { id: titleId, className: "squisq-media-edit-modal__title", children: title }),
45350
- /* @__PURE__ */ jsx100("span", { className: "squisq-media-edit-modal__path", children: target.src }),
45351
- renderStatus && /* @__PURE__ */ jsx100(RenderStatusBadge, { status: renderStatus }),
45352
- /* @__PURE__ */ jsx100(
45551
+ /* @__PURE__ */ jsxs82("header", { className: "squisq-media-edit-modal__header", children: [
45552
+ /* @__PURE__ */ jsx101("span", { id: titleId, className: "squisq-media-edit-modal__title", children: title }),
45553
+ /* @__PURE__ */ jsx101("span", { className: "squisq-media-edit-modal__path", children: target.src }),
45554
+ renderStatus && /* @__PURE__ */ jsx101(RenderStatusBadge, { status: renderStatus }),
45555
+ /* @__PURE__ */ jsx101(
45353
45556
  "button",
45354
45557
  {
45355
45558
  type: "button",
@@ -45360,11 +45563,11 @@ function MediaEditModal({ target, onClose }) {
45360
45563
  }
45361
45564
  )
45362
45565
  ] }),
45363
- !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: [
45364
- /* @__PURE__ */ jsx100("div", { className: "squisq-media-edit-tabs", role: "tablist", "aria-label": "Edit sections", children: tabs.map((tab, index2) => {
45566
+ !item ? /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-modal__empty", children: "This clip is no longer in the document." }) : !mediaEditRenders ? /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-modal__empty", children: "Media editing needs a media folder for this document." }) : /* @__PURE__ */ jsxs82(Fragment34, { children: [
45567
+ /* @__PURE__ */ jsx101("div", { className: "squisq-media-edit-tabs", role: "tablist", "aria-label": "Edit sections", children: tabs.map((tab, index2) => {
45365
45568
  const selected = tab.id === activeTab;
45366
45569
  const edited = tabHasEdits(tab.id, draft);
45367
- return /* @__PURE__ */ jsxs81(
45570
+ return /* @__PURE__ */ jsxs82(
45368
45571
  "button",
45369
45572
  {
45370
45573
  ref: (el) => {
@@ -45383,21 +45586,21 @@ function MediaEditModal({ target, onClose }) {
45383
45586
  onKeyDown: (e2) => onTabKeyDown(e2, index2),
45384
45587
  children: [
45385
45588
  tab.label,
45386
- edited && /* @__PURE__ */ jsx100("span", { className: "squisq-sr-only", children: " (edited)" })
45589
+ edited && /* @__PURE__ */ jsx101("span", { className: "squisq-sr-only", children: " (edited)" })
45387
45590
  ]
45388
45591
  },
45389
45592
  tab.id
45390
45593
  );
45391
45594
  }) }),
45392
- /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-modal__body", children: [
45393
- /* @__PURE__ */ jsx100(
45595
+ /* @__PURE__ */ jsxs82("div", { className: "squisq-media-edit-modal__body", children: [
45596
+ /* @__PURE__ */ jsx101(
45394
45597
  "div",
45395
45598
  {
45396
45599
  role: "tabpanel",
45397
45600
  id: panelId("audio"),
45398
45601
  "aria-labelledby": tabId("audio"),
45399
45602
  hidden: activeTab !== "audio",
45400
- children: /* @__PURE__ */ jsx100(
45603
+ children: /* @__PURE__ */ jsx101(
45401
45604
  MediaEditAudioSection,
45402
45605
  {
45403
45606
  item,
@@ -45409,14 +45612,14 @@ function MediaEditModal({ target, onClose }) {
45409
45612
  )
45410
45613
  }
45411
45614
  ),
45412
- /* @__PURE__ */ jsx100(
45615
+ /* @__PURE__ */ jsx101(
45413
45616
  "div",
45414
45617
  {
45415
45618
  role: "tabpanel",
45416
45619
  id: panelId("timing"),
45417
45620
  "aria-labelledby": tabId("timing"),
45418
45621
  hidden: activeTab !== "timing",
45419
- children: /* @__PURE__ */ jsx100(
45622
+ children: /* @__PURE__ */ jsx101(
45420
45623
  MediaEditTimingSection,
45421
45624
  {
45422
45625
  item,
@@ -45428,17 +45631,17 @@ function MediaEditModal({ target, onClose }) {
45428
45631
  )
45429
45632
  }
45430
45633
  ),
45431
- item.kind === "video" && /* @__PURE__ */ jsx100(
45634
+ item.kind === "video" && /* @__PURE__ */ jsx101(
45432
45635
  "div",
45433
45636
  {
45434
45637
  role: "tabpanel",
45435
45638
  id: panelId("frame"),
45436
45639
  "aria-labelledby": tabId("frame"),
45437
45640
  hidden: activeTab !== "frame",
45438
- children: /* @__PURE__ */ jsx100(MediaEditFrameSection, { item, draft, onChange: setDraft })
45641
+ children: /* @__PURE__ */ jsx101(MediaEditFrameSection, { item, draft, onChange: setDraft })
45439
45642
  }
45440
45643
  ),
45441
- companions.length > 0 && /* @__PURE__ */ jsxs81("p", { className: "squisq-media-edit-note", children: [
45644
+ companions.length > 0 && /* @__PURE__ */ jsxs82("p", { className: "squisq-media-edit-note", children: [
45442
45645
  "Cleanup and pause cuts also apply to ",
45443
45646
  companions.length,
45444
45647
  " linked",
@@ -45448,16 +45651,16 @@ function MediaEditModal({ target, onClose }) {
45448
45651
  ] })
45449
45652
  ] })
45450
45653
  ] }),
45451
- /* @__PURE__ */ jsxs81("footer", { className: "squisq-media-edit-modal__footer", children: [
45452
- /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-status", role: "status", "data-state": renderStatus?.state, children: renderStatus && item && mediaEditRenders && /* @__PURE__ */ jsx100(
45654
+ /* @__PURE__ */ jsxs82("footer", { className: "squisq-media-edit-modal__footer", children: [
45655
+ /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-status", role: "status", "data-state": renderStatus?.state, children: renderStatus && item && mediaEditRenders && /* @__PURE__ */ jsx101(
45453
45656
  RenderStatusText,
45454
45657
  {
45455
45658
  status: renderStatus,
45456
45659
  onRetry: () => mediaEditRenders.retry(item.clip)
45457
45660
  }
45458
45661
  ) }),
45459
- /* @__PURE__ */ jsx100("button", { type: "button", onClick: onClose, children: "Cancel" }),
45460
- /* @__PURE__ */ jsx100(
45662
+ /* @__PURE__ */ jsx101("button", { type: "button", onClick: onClose, children: "Cancel" }),
45663
+ /* @__PURE__ */ jsx101(
45461
45664
  "button",
45462
45665
  {
45463
45666
  type: "button",
@@ -45722,7 +45925,7 @@ import {
45722
45925
  createMediaEditRenderManager,
45723
45926
  useProcessedAudio as useProcessedAudio4
45724
45927
  } from "@bendyline/squisq-video-react/media-edit";
45725
- import { Fragment as Fragment34, jsx as jsx101, jsxs as jsxs82 } from "react/jsx-runtime";
45928
+ import { Fragment as Fragment35, jsx as jsx102, jsxs as jsxs83 } from "react/jsx-runtime";
45726
45929
  function EditorShell({
45727
45930
  ariaLabel,
45728
45931
  initialMarkdown = "",
@@ -45828,11 +46031,11 @@ function EditorShell({
45828
46031
  () => mediaEditRenders === void 0 && effectiveMediaProvider ? createMediaEditRenderManager({ mediaProvider: effectiveMediaProvider }) : null,
45829
46032
  [mediaEditRenders, effectiveMediaProvider]
45830
46033
  );
45831
- useEffect78(() => () => ownedMediaEditRenders?.dispose(), [ownedMediaEditRenders]);
46034
+ useEffect80(() => () => ownedMediaEditRenders?.dispose(), [ownedMediaEditRenders]);
45832
46035
  const effectiveMediaEditRenders = mediaEditRenders === void 0 ? ownedMediaEditRenders : mediaEditRenders;
45833
46036
  const filesToggleEnabled = showFilesToggle ?? effectiveMediaProvider !== void 0;
45834
46037
  const effectiveInitialView = hostMode === "chat" || !showPlayTab && initialView === "preview" ? "wysiwyg" : initialView;
45835
- return /* @__PURE__ */ jsx101(MediaContext7.Provider, { value: effectiveMediaProvider ?? null, children: /* @__PURE__ */ jsx101(
46038
+ return /* @__PURE__ */ jsx102(MediaContext7.Provider, { value: effectiveMediaProvider ?? null, children: /* @__PURE__ */ jsx102(
45836
46039
  EditorProvider,
45837
46040
  {
45838
46041
  initialMarkdown,
@@ -45878,7 +46081,7 @@ function EditorShell({
45878
46081
  themeInheritance,
45879
46082
  viewPreferences,
45880
46083
  onViewPreferencesChange,
45881
- children: /* @__PURE__ */ jsx101(ProofingRoot, { children: /* @__PURE__ */ jsx101(ReviewRoot, { providers: reviewProviders, children: /* @__PURE__ */ jsx101(PageTemplateContext.Provider, { value: pageTemplates, children: /* @__PURE__ */ jsx101(
46084
+ children: /* @__PURE__ */ jsx102(ProofingRoot, { children: /* @__PURE__ */ jsx102(ReviewRoot, { providers: reviewProviders, children: /* @__PURE__ */ jsx102(PageTemplateContext.Provider, { value: pageTemplates, children: /* @__PURE__ */ jsx102(
45882
46085
  EditorShellInner,
45883
46086
  {
45884
46087
  ariaLabel: ariaLabel ?? (hostMode === "chat" ? "Message" : fileName ? `Edit ${fileName}` : "Document editor"),
@@ -45944,11 +46147,11 @@ function UseModeToolbarControls({
45944
46147
  summarizationDesigner
45945
46148
  }) {
45946
46149
  const printMode = usePrintMode();
45947
- if (printMode.active) return /* @__PURE__ */ jsx101(PrintPreviewToolbar, {});
45948
- return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45949
- /* @__PURE__ */ jsx101(PreviewToolbarControls, { summarizationDesigner }),
45950
- /* @__PURE__ */ jsx101(PresentationModeControl, {}),
45951
- allowPrint && /* @__PURE__ */ jsx101(PrintModeControl, {})
46150
+ if (printMode.active) return /* @__PURE__ */ jsx102(PrintPreviewToolbar, {});
46151
+ return /* @__PURE__ */ jsxs83(Fragment35, { children: [
46152
+ /* @__PURE__ */ jsx102(PreviewToolbarControls, { summarizationDesigner }),
46153
+ /* @__PURE__ */ jsx102(PresentationModeControl, {}),
46154
+ allowPrint && /* @__PURE__ */ jsx102(PrintModeControl, {})
45952
46155
  ] });
45953
46156
  }
45954
46157
  function UseModeProviders({
@@ -45957,13 +46160,13 @@ function UseModeProviders({
45957
46160
  allowPresentationWindow,
45958
46161
  allowPresentationFullscreen
45959
46162
  }) {
45960
- return /* @__PURE__ */ jsx101(
46163
+ return /* @__PURE__ */ jsx102(
45961
46164
  PresentationModeProvider,
45962
46165
  {
45963
46166
  rootRef,
45964
46167
  allowWindow: allowPresentationWindow,
45965
46168
  allowFullscreen: allowPresentationFullscreen,
45966
- children: /* @__PURE__ */ jsx101(PrintModeProvider, { rootRef, children })
46169
+ children: /* @__PURE__ */ jsx102(PrintModeProvider, { rootRef, children })
45967
46170
  }
45968
46171
  );
45969
46172
  }
@@ -46022,8 +46225,8 @@ function EditorShellInner({
46022
46225
  defaultThemeId,
46023
46226
  defaultThemeLabel
46024
46227
  }) {
46025
- const shellRef = useRef74(null);
46026
- const [uncontrolledNavigationSheet, setUncontrolledNavigationSheet] = useState90(null);
46228
+ const shellRef = useRef75(null);
46229
+ const [uncontrolledNavigationSheet, setUncontrolledNavigationSheet] = useState91(null);
46027
46230
  const navigationSheetPanel = navigationSheet === void 0 ? uncontrolledNavigationSheet : navigationSheet;
46028
46231
  const handleNavigationSheetChange = useCallback63(
46029
46232
  (panel) => {
@@ -46062,8 +46265,8 @@ function EditorShellInner({
46062
46265
  } = useEditorContext();
46063
46266
  const processedAudio = useProcessedAudio4(mediaEditRenders);
46064
46267
  const { docThemes, onDocThemesChange } = useDocCustomThemes();
46065
- const lastEditingView = useRef74(activeView === "raw" ? "raw" : "wysiwyg");
46066
- useEffect78(() => {
46268
+ const lastEditingView = useRef75(activeView === "raw" ? "raw" : "wysiwyg");
46269
+ useEffect80(() => {
46067
46270
  if (activeView !== "preview") lastEditingView.current = activeView;
46068
46271
  }, [activeView]);
46069
46272
  const editingView = activeView === "preview" ? lastEditingView.current : activeView;
@@ -46110,32 +46313,32 @@ function EditorShellInner({
46110
46313
  );
46111
46314
  const timelineClock = useTimelineClock(isTimelineMode ? timelineDuration : 0);
46112
46315
  const hasTimelineVideo = timelineVideoSchedule.length > 0;
46113
- const [timelineVideoVisible, setTimelineVideoVisible] = useState90(false);
46114
- const [timelineCompositionVisible, setTimelineCompositionVisible] = useState90(false);
46316
+ const [timelineVideoVisible, setTimelineVideoVisible] = useState91(false);
46317
+ const [timelineCompositionVisible, setTimelineCompositionVisible] = useState91(false);
46115
46318
  const timelinePreviewCount = Number(timelineVideoVisible) + Number(timelineCompositionVisible);
46116
- const [showFiles, setShowFiles] = useState90(false);
46117
- const [filesFocusPath, setFilesFocusPath] = useState90(null);
46118
- const [mediaRefreshKey, setMediaRefreshKey] = useState90(0);
46119
- const [mediaCount, setMediaCount] = useState90(0);
46120
- const [mediaBinRecorderOpen, setMediaBinRecorderOpen] = useState90(false);
46319
+ const [showFiles, setShowFiles] = useState91(false);
46320
+ const [filesFocusPath, setFilesFocusPath] = useState91(null);
46321
+ const [mediaRefreshKey, setMediaRefreshKey] = useState91(0);
46322
+ const [mediaCount, setMediaCount] = useState91(0);
46323
+ const [mediaBinRecorderOpen, setMediaBinRecorderOpen] = useState91(false);
46121
46324
  const mediaListRefreshKey = mediaRefreshKey + mediaRevision;
46122
46325
  const usedMediaPaths = useMemo62(
46123
46326
  () => collectMediaReferencesFromMarkdown(markdownSource),
46124
46327
  [markdownSource]
46125
46328
  );
46126
- const imageEditFallbackContainerRef = useRef74(null);
46329
+ const imageEditFallbackContainerRef = useRef75(null);
46127
46330
  if (imageEditFallbackContainerRef.current === null) {
46128
46331
  imageEditFallbackContainerRef.current = new MemoryContentContainer2();
46129
46332
  }
46130
46333
  const imageEditFallbackContainer = imageEditFallbackContainerRef.current;
46131
46334
  const isDark = colorScheme === "dark";
46132
- useEffect78(() => {
46335
+ useEffect80(() => {
46133
46336
  if (!isTimelineMode || !hasTimelineVideo) setTimelineVideoVisible(false);
46134
46337
  }, [isTimelineMode, hasTimelineVideo]);
46135
- useEffect78(() => {
46338
+ useEffect80(() => {
46136
46339
  if (!isTimelineMode || !doc?.blocks.length) setTimelineCompositionVisible(false);
46137
46340
  }, [isTimelineMode, doc]);
46138
- useEffect78(() => {
46341
+ useEffect80(() => {
46139
46342
  if (!mediaProvider) {
46140
46343
  setMediaCount(0);
46141
46344
  return;
@@ -46159,7 +46362,7 @@ function EditorShellInner({
46159
46362
  cancelled = true;
46160
46363
  };
46161
46364
  }, [mediaProvider, mediaListRefreshKey]);
46162
- useEffect78(() => {
46365
+ useEffect80(() => {
46163
46366
  if (showFilesWhenNotEmpty && mediaCount > 0) setShowFiles(true);
46164
46367
  }, [mediaCount, showFilesWhenNotEmpty]);
46165
46368
  const handleToggleFiles = useCallback63(() => {
@@ -46178,8 +46381,8 @@ function EditorShellInner({
46178
46381
  },
46179
46382
  [insertionTarget]
46180
46383
  );
46181
- const docBasenameRef = useRef74("document");
46182
- useEffect78(() => {
46384
+ const docBasenameRef = useRef75("document");
46385
+ useEffect80(() => {
46183
46386
  let cancelled = false;
46184
46387
  docBasenameRef.current = "document";
46185
46388
  void resolveDocBasename(workspaceContainer).then((base) => {
@@ -46262,7 +46465,7 @@ function EditorShellInner({
46262
46465
  onDrop: handleFileDrop,
46263
46466
  enabled: !readOnly
46264
46467
  });
46265
- useEffect78(() => {
46468
+ useEffect80(() => {
46266
46469
  onChange?.(markdownSource);
46267
46470
  }, [markdownSource, onChange]);
46268
46471
  const handleShellKeyDown = useCallback63((e2) => {
@@ -46318,7 +46521,7 @@ function EditorShellInner({
46318
46521
  anchor.removeAttribute("data-squisq-link-title");
46319
46522
  }, []);
46320
46523
  const autoGrow = minHeight !== void 0 || maxHeight !== void 0;
46321
- const shell = /* @__PURE__ */ jsxs82(
46524
+ const shell = /* @__PURE__ */ jsxs83(
46322
46525
  "div",
46323
46526
  {
46324
46527
  ref: shellRef,
@@ -46357,7 +46560,7 @@ function EditorShellInner({
46357
46560
  },
46358
46561
  ...containerProps,
46359
46562
  children: [
46360
- /* @__PURE__ */ jsx101(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx101(
46563
+ /* @__PURE__ */ jsx102(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx102(
46361
46564
  PreviewSettingsProvider,
46362
46565
  {
46363
46566
  doc,
@@ -46365,25 +46568,25 @@ function EditorShellInner({
46365
46568
  themeOverride,
46366
46569
  defaultThemeId,
46367
46570
  defaultThemeLabel,
46368
- children: /* @__PURE__ */ jsxs82(
46571
+ children: /* @__PURE__ */ jsxs83(
46369
46572
  UseModeProviders,
46370
46573
  {
46371
46574
  rootRef: shellRef,
46372
46575
  allowPresentationWindow,
46373
46576
  allowPresentationFullscreen,
46374
46577
  children: [
46375
- isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs82("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
46578
+ isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs83("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
46376
46579
  toolbarSlotLeft,
46377
- /* @__PURE__ */ jsx101("div", { style: { flex: 1 } }),
46580
+ /* @__PURE__ */ jsx102("div", { style: { flex: 1 } }),
46378
46581
  toolbarSlotRight
46379
- ] }) : /* @__PURE__ */ jsx101("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx101(
46582
+ ] }) : /* @__PURE__ */ jsx102("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx102(
46380
46583
  Toolbar,
46381
46584
  {
46382
46585
  showFiles,
46383
46586
  fileCount: mediaCount,
46384
46587
  onToggleFiles: !isCodeMode && filesToggleEnabled ? handleToggleFiles : void 0,
46385
46588
  slotLeft: toolbarSlotLeft,
46386
- slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx101(
46589
+ slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx102(
46387
46590
  UseModeToolbarControls,
46388
46591
  {
46389
46592
  allowPrint,
@@ -46400,7 +46603,7 @@ function EditorShellInner({
46400
46603
  findShortcut
46401
46604
  }
46402
46605
  ) }),
46403
- /* @__PURE__ */ jsxs82(
46606
+ /* @__PURE__ */ jsxs83(
46404
46607
  "div",
46405
46608
  {
46406
46609
  className: "squisq-editor-content",
@@ -46414,7 +46617,7 @@ function EditorShellInner({
46414
46617
  display: "flex"
46415
46618
  },
46416
46619
  children: [
46417
- /* @__PURE__ */ jsxs82(
46620
+ /* @__PURE__ */ jsxs83(
46418
46621
  "div",
46419
46622
  {
46420
46623
  className: "squisq-editor-primary",
@@ -46425,7 +46628,7 @@ function EditorShellInner({
46425
46628
  position: "relative"
46426
46629
  },
46427
46630
  children: [
46428
- isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx101(
46631
+ isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx102(
46429
46632
  ImageEditor,
46430
46633
  {
46431
46634
  filesContainer: imageEditorContainer,
@@ -46435,16 +46638,16 @@ function EditorShellInner({
46435
46638
  onExport: onImageExport,
46436
46639
  surface: colorScheme === "dark" ? DARK_SURFACE2 : LIGHT_SURFACE2
46437
46640
  }
46438
- ) : /* @__PURE__ */ jsx101(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
46439
- !isImageMode && editingView === "raw" && /* @__PURE__ */ jsxs82(
46641
+ ) : /* @__PURE__ */ jsx102(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
46642
+ !isImageMode && editingView === "raw" && /* @__PURE__ */ jsxs83(
46440
46643
  "div",
46441
46644
  {
46442
46645
  className: "squisq-editor-with-gutter",
46443
46646
  hidden: isPreview,
46444
46647
  style: isPreview ? { display: "none" } : void 0,
46445
46648
  children: [
46446
- isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx101(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46447
- /* @__PURE__ */ jsx101(
46649
+ isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx102(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46650
+ /* @__PURE__ */ jsx102(
46448
46651
  BlockCardView,
46449
46652
  {
46450
46653
  active: isCardMode,
@@ -46453,7 +46656,7 @@ function EditorShellInner({
46453
46656
  onPrev: prevBlock,
46454
46657
  onNext: nextBlock,
46455
46658
  onAdd: addBlock,
46456
- children: /* @__PURE__ */ jsx101("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx101(
46659
+ children: /* @__PURE__ */ jsx102("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx102(
46457
46660
  RawEditor,
46458
46661
  {
46459
46662
  ariaLabel: `${ariaLabel} \u2014 source`,
@@ -46465,9 +46668,9 @@ function EditorShellInner({
46465
46668
  },
46466
46669
  "raw-frame"
46467
46670
  ),
46468
- isCodeMode && codeContext && /* @__PURE__ */ jsx101(CodeContextZones, { options: codeContext }, "code-context"),
46469
- isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(BlockPreviewPanel, { basePath }, "block-preview"),
46470
- isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(
46671
+ isCodeMode && codeContext && /* @__PURE__ */ jsx102(CodeContextZones, { options: codeContext }, "code-context"),
46672
+ isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(BlockPreviewPanel, { basePath }, "block-preview"),
46673
+ isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(
46471
46674
  InlinePreviewGutter,
46472
46675
  {
46473
46676
  width: inlinePreviewWidth,
@@ -46476,7 +46679,7 @@ function EditorShellInner({
46476
46679
  },
46477
46680
  "inline"
46478
46681
  ),
46479
- isMarkdownMode && /* @__PURE__ */ jsx101(
46682
+ isMarkdownMode && /* @__PURE__ */ jsx102(
46480
46683
  NavigationSheet,
46481
46684
  {
46482
46685
  panel: navigationSheetPanel,
@@ -46491,15 +46694,15 @@ function EditorShellInner({
46491
46694
  },
46492
46695
  "raw-shell"
46493
46696
  ),
46494
- isMarkdownMode && editingView === "wysiwyg" && /* @__PURE__ */ jsxs82(
46697
+ isMarkdownMode && editingView === "wysiwyg" && /* @__PURE__ */ jsxs83(
46495
46698
  "div",
46496
46699
  {
46497
46700
  className: "squisq-editor-with-gutter",
46498
46701
  hidden: isPreview,
46499
46702
  style: isPreview ? { display: "none" } : void 0,
46500
46703
  children: [
46501
- outlineVisible && /* @__PURE__ */ jsx101(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46502
- /* @__PURE__ */ jsx101(
46704
+ outlineVisible && /* @__PURE__ */ jsx102(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46705
+ /* @__PURE__ */ jsx102(
46503
46706
  BlockCardView,
46504
46707
  {
46505
46708
  active: isCardMode,
@@ -46508,7 +46711,7 @@ function EditorShellInner({
46508
46711
  onPrev: prevBlock,
46509
46712
  onNext: nextBlock,
46510
46713
  onAdd: addBlock,
46511
- children: /* @__PURE__ */ jsx101(
46714
+ children: /* @__PURE__ */ jsx102(
46512
46715
  WysiwygEditor,
46513
46716
  {
46514
46717
  ariaLabel,
@@ -46526,8 +46729,8 @@ function EditorShellInner({
46526
46729
  },
46527
46730
  "wysiwyg-frame"
46528
46731
  ),
46529
- isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(BlockPreviewPanel, { basePath }, "block-preview"),
46530
- !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(
46732
+ isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(BlockPreviewPanel, { basePath }, "block-preview"),
46733
+ !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(
46531
46734
  InlinePreviewGutter,
46532
46735
  {
46533
46736
  width: inlinePreviewWidth,
@@ -46536,7 +46739,7 @@ function EditorShellInner({
46536
46739
  },
46537
46740
  "inline"
46538
46741
  ),
46539
- /* @__PURE__ */ jsx101(
46742
+ /* @__PURE__ */ jsx102(
46540
46743
  NavigationSheet,
46541
46744
  {
46542
46745
  panel: navigationSheetPanel,
@@ -46551,7 +46754,7 @@ function EditorShellInner({
46551
46754
  },
46552
46755
  "wysiwyg-shell"
46553
46756
  ),
46554
- isMarkdownMode && isPreview && /* @__PURE__ */ jsx101(
46757
+ isMarkdownMode && isPreview && /* @__PURE__ */ jsx102(
46555
46758
  PreviewPanel,
46556
46759
  {
46557
46760
  basePath,
@@ -46564,7 +46767,7 @@ function EditorShellInner({
46564
46767
  ]
46565
46768
  }
46566
46769
  ),
46567
- isTimelineMode && timelineVideoVisible && /* @__PURE__ */ jsx101(
46770
+ isTimelineMode && timelineVideoVisible && /* @__PURE__ */ jsx102(
46568
46771
  TimelineVideoPanel,
46569
46772
  {
46570
46773
  schedule: timelineVideoSchedule,
@@ -46574,7 +46777,7 @@ function EditorShellInner({
46574
46777
  onClose: () => setTimelineVideoVisible(false)
46575
46778
  }
46576
46779
  ),
46577
- isTimelineMode && timelineCompositionVisible && /* @__PURE__ */ jsx101(
46780
+ isTimelineMode && timelineCompositionVisible && /* @__PURE__ */ jsx102(
46578
46781
  TimelineCompositionPanel,
46579
46782
  {
46580
46783
  doc,
@@ -46584,7 +46787,7 @@ function EditorShellInner({
46584
46787
  onClose: () => setTimelineCompositionVisible(false)
46585
46788
  }
46586
46789
  ),
46587
- isMarkdownMode && showFiles && /* @__PURE__ */ jsx101(
46790
+ isMarkdownMode && showFiles && /* @__PURE__ */ jsx102(
46588
46791
  MediaBin,
46589
46792
  {
46590
46793
  mediaProvider,
@@ -46600,11 +46803,11 @@ function EditorShellInner({
46600
46803
  highlightPath: filesFocusPath
46601
46804
  }
46602
46805
  ),
46603
- isMarkdownMode && /* @__PURE__ */ jsx101(ProofingPanel, {}),
46604
- isMarkdownMode && /* @__PURE__ */ jsx101(ReviewPanel, {}),
46806
+ isMarkdownMode && /* @__PURE__ */ jsx102(ProofingPanel, {}),
46807
+ isMarkdownMode && /* @__PURE__ */ jsx102(ReviewPanel, {}),
46605
46808
  isMarkdownMode && sidePanelSlot,
46606
- isMarkdownMode && /* @__PURE__ */ jsx101(ThemeDesignerDock, {}),
46607
- isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx101(
46809
+ isMarkdownMode && /* @__PURE__ */ jsx102(ThemeDesignerDock, {}),
46810
+ isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx102(
46608
46811
  DropZoneOverlay,
46609
46812
  {
46610
46813
  dragContentType,
@@ -46615,7 +46818,7 @@ function EditorShellInner({
46615
46818
  ]
46616
46819
  }
46617
46820
  ),
46618
- isTimelineMode && /* @__PURE__ */ jsx101(
46821
+ isTimelineMode && /* @__PURE__ */ jsx102(
46619
46822
  TimelineToolbar,
46620
46823
  {
46621
46824
  literalVideoVisible: timelineVideoVisible,
@@ -46626,7 +46829,7 @@ function EditorShellInner({
46626
46829
  onToggleComposition: () => setTimelineCompositionVisible((visible) => !visible)
46627
46830
  }
46628
46831
  ),
46629
- isTimelineMode && /* @__PURE__ */ jsx101(
46832
+ isTimelineMode && /* @__PURE__ */ jsx102(
46630
46833
  TimelineTrack,
46631
46834
  {
46632
46835
  doc: timelineDoc,
@@ -46635,8 +46838,8 @@ function EditorShellInner({
46635
46838
  basePath
46636
46839
  }
46637
46840
  ),
46638
- statusBarVisible && !isImageMode && /* @__PURE__ */ jsx101(StatusBar, { slotRight: statusBarSlotRight }),
46639
- isMarkdownMode && allowRecording && mediaProvider && /* @__PURE__ */ jsx101(
46841
+ statusBarVisible && !isImageMode && /* @__PURE__ */ jsx102(StatusBar, { slotRight: statusBarSlotRight }),
46842
+ isMarkdownMode && allowRecording && mediaProvider && /* @__PURE__ */ jsx102(
46640
46843
  RecorderEntry,
46641
46844
  {
46642
46845
  open: mediaBinRecorderOpen,
@@ -46649,8 +46852,8 @@ function EditorShellInner({
46649
46852
  )
46650
46853
  }
46651
46854
  ) }),
46652
- /* @__PURE__ */ jsx101(TooltipLayer, {}),
46653
- imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx101(
46855
+ /* @__PURE__ */ jsx102(TooltipLayer, {}),
46856
+ imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx102(
46654
46857
  ImageEditModal,
46655
46858
  {
46656
46859
  relativePath: imageEditTarget,
@@ -46666,12 +46869,12 @@ function EditorShellInner({
46666
46869
  shellTheme: colorScheme
46667
46870
  }
46668
46871
  ),
46669
- mediaEditTarget !== null && /* @__PURE__ */ jsx101(MediaEditModal, { target: mediaEditTarget, onClose: closeMediaEdit })
46872
+ mediaEditTarget !== null && /* @__PURE__ */ jsx102(MediaEditModal, { target: mediaEditTarget, onClose: closeMediaEdit })
46670
46873
  ]
46671
46874
  }
46672
46875
  );
46673
- return /* @__PURE__ */ jsxs82(EditorContextMenuProvider, { rootRef: shellRef, readOnly, children: [
46674
- /* @__PURE__ */ jsx101(MediaEditContextMenuItems, {}),
46876
+ return /* @__PURE__ */ jsxs83(EditorContextMenuProvider, { rootRef: shellRef, readOnly, children: [
46877
+ /* @__PURE__ */ jsx102(MediaEditContextMenuItems, {}),
46675
46878
  shell
46676
46879
  ] });
46677
46880
  }