@bendyline/squisq-editor-react 2.11.18 → 2.11.19

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  NarrationStage,
3
3
  useNarrationStage
4
- } from "./chunk-CGENKHWY.js";
4
+ } from "./chunk-ZS6G2P57.js";
5
5
 
6
6
  // src/teleprompter/TeleprompterView.tsx
7
7
  import { jsx } from "react/jsx-runtime";
@@ -70,6 +70,35 @@ var RE_ITALIC_UNDER = /(?<![\p{L}\p{N}_])_(?![\s_])(.+?)(?<![\s_])_(?![\p{L}\p{N
70
70
  var RE_STRIKETHROUGH = /~~(.+?)~~/g;
71
71
  var RE_LEGACY_BOLD_STAR = /\*\*(?![\s*])((?:(?!\*\*).)+?)(?<![\s*])([ \t]+)\*\*(?=$|[^\s*])/g;
72
72
  var RE_LEGACY_ITALIC_STAR = /(?<!\*)\*(?![\s*])([^*]+?)(?<![\s*])([ \t]+)\*(?=$|[^\s*])/g;
73
+ var RE_BOLD_DELIMITER = /\*\*/g;
74
+ var RE_ITALIC_DELIMITER = /\*/g;
75
+ function countEmphasisDelimiters(text, end, delimiter) {
76
+ let count = 0;
77
+ delimiter.lastIndex = 0;
78
+ for (let match = delimiter.exec(text); match && match.index < end; match = delimiter.exec(text)) {
79
+ const before = text[match.index - 1];
80
+ const after = text[match.index + match[0].length];
81
+ if ((before === void 0 || /\s/.test(before)) && (after === void 0 || /\s/.test(after))) {
82
+ continue;
83
+ }
84
+ count++;
85
+ }
86
+ return count;
87
+ }
88
+ function recoverLegacyEmphasis(text, pattern, delimiter, delimiterLength, tag) {
89
+ let output = "";
90
+ let copied = 0;
91
+ pattern.lastIndex = 0;
92
+ for (let match = pattern.exec(text); match; match = pattern.exec(text)) {
93
+ if (countEmphasisDelimiters(text, match.index, delimiter) % 2 === 1) {
94
+ pattern.lastIndex = match.index + delimiterLength;
95
+ continue;
96
+ }
97
+ output += `${text.slice(copied, match.index)}<${tag}>${match[1]}</${tag}>${match[2]}`;
98
+ copied = match.index + match[0].length;
99
+ }
100
+ return output + text.slice(copied);
101
+ }
73
102
  var ESCAPABLE_MD_CHARS = ["*", "_", "~", "\\"];
74
103
  var RE_MD_ESCAPE = /\\([*_~\\])/g;
75
104
  var RE_BACKSLASH_PAIR = /\\([\s\S])/g;
@@ -972,10 +1001,10 @@ function inlineToHtml(text) {
972
1001
  RE_MD_ESCAPE,
973
1002
  (_m, ch) => `\0ESC${ESCAPABLE_MD_CHARS.indexOf(ch)}\0`
974
1003
  );
975
- result = result.replace(RE_LEGACY_BOLD_STAR, "<strong>$1</strong>$2");
1004
+ result = recoverLegacyEmphasis(result, RE_LEGACY_BOLD_STAR, RE_BOLD_DELIMITER, 2, "strong");
976
1005
  result = result.replace(RE_BOLD_STAR, "<strong>$1</strong>");
977
1006
  result = result.replace(RE_BOLD_UNDER, "<strong>$1</strong>");
978
- result = result.replace(RE_LEGACY_ITALIC_STAR, "<em>$1</em>$2");
1007
+ result = recoverLegacyEmphasis(result, RE_LEGACY_ITALIC_STAR, RE_ITALIC_DELIMITER, 1, "em");
979
1008
  result = result.replace(RE_ITALIC_STAR, "<em>$1</em>");
980
1009
  result = result.replace(RE_ITALIC_UNDER, "<em>$1</em>");
981
1010
  result = result.replace(RE_STRIKETHROUGH, "<s>$1</s>");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RecorderModal
3
- } from "./chunk-U6NVT3BY.js";
3
+ } from "./chunk-UFK47ZAI.js";
4
4
 
5
5
  // src/recorder/RecorderButton.tsx
6
6
  import { useCallback, useState } from "react";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MARKDOWN_ESCAPE_ATTR
3
- } from "./chunk-DPAMJV6A.js";
3
+ } from "./chunk-HSWWEWT4.js";
4
4
 
5
5
  // src/MarkdownEscape.ts
6
6
  import { Mark, mergeAttributes } from "@tiptap/core";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-DNEVUOBZ.js";
5
5
  import {
6
6
  markdownToTiptap
7
- } from "./chunk-DPAMJV6A.js";
7
+ } from "./chunk-HSWWEWT4.js";
8
8
 
9
9
  // src/blockRange.ts
10
10
  import { parseMarkdown } from "@bendyline/squisq/markdown";
@@ -2141,6 +2141,7 @@ function EditorProvider({
2141
2141
  sceneTextChannel,
2142
2142
  workspaceContainer,
2143
2143
  versioning,
2144
+ versioningAutoSaves: versioningAutoSaveIdleMs > 0,
2144
2145
  saveVersion,
2145
2146
  mediaProvider,
2146
2147
  mediaEditRenders,
@@ -2222,6 +2223,7 @@ function EditorProvider({
2222
2223
  sceneTextChannel,
2223
2224
  workspaceContainer,
2224
2225
  versioning,
2226
+ versioningAutoSaveIdleMs,
2225
2227
  saveVersion,
2226
2228
  mediaProvider,
2227
2229
  mediaEditRenders,
@@ -20,7 +20,7 @@ import {
20
20
  timingPathFor,
21
21
  useNarrationStage,
22
22
  useStreamPreview
23
- } from "./chunk-CGENKHWY.js";
23
+ } from "./chunk-ZS6G2P57.js";
24
24
  import {
25
25
  buildFilename,
26
26
  requestMicStream,
@@ -2612,6 +2612,7 @@ function RecorderModal({
2612
2612
  const narrationRecording = narrationOn && Boolean(narration?.recording);
2613
2613
  const expanded = isExpandedPanel(panelMode);
2614
2614
  const [narrationRequesting, setNarrationRequesting] = useState3(false);
2615
+ const [countingIn, setCountingIn] = useState3(false);
2615
2616
  const [narrationPreview, setNarrationPreview] = useState3(null);
2616
2617
  const [deviceSettings, setDeviceSettings] = useState3(() => ({
2617
2618
  ...DEFAULT_RECORDER_DEVICE_SETTINGS,
@@ -2927,17 +2928,27 @@ function RecorderModal({
2927
2928
  } catch {
2928
2929
  }
2929
2930
  }, [recorder]);
2930
- const handleStart = useCallback4(() => {
2931
+ const handleStart = useCallback4(async () => {
2931
2932
  setSaveError(null);
2932
2933
  dualSaveProgressRef.current = {};
2934
+ if (narrationOn) {
2935
+ setCountingIn(true);
2936
+ const rolled = await stageRef.current.controller.countIn();
2937
+ setCountingIn(false);
2938
+ if (!rolled) return;
2939
+ }
2933
2940
  recorder.start();
2934
2941
  const blockId = slideDeckRef.current[slideIndexRef.current]?.blockId;
2935
2942
  setAdvanceLog(blockId ? recordSlideShown(EMPTY_ADVANCE_LOG, blockId, 0) : EMPTY_ADVANCE_LOG);
2936
- }, [recorder]);
2943
+ }, [narrationOn, recorder]);
2937
2944
  const handleStop = useCallback4(async () => {
2938
2945
  setSaveError(null);
2946
+ if (countingIn) {
2947
+ stageRef.current.controller.pause();
2948
+ return;
2949
+ }
2939
2950
  await recorder.stop();
2940
- }, [recorder]);
2951
+ }, [countingIn, recorder]);
2941
2952
  const writeSlideTimingSidecar = useCallback4(
2942
2953
  async (mediaRelativePath, durationSec) => {
2943
2954
  const doc = slides?.doc;
@@ -3130,8 +3141,8 @@ function RecorderModal({
3130
3141
  );
3131
3142
  const isAudioOnly = recordedMediaKind(source, recorder.stream, recorder.mimeType) === "audio";
3132
3143
  const showPreview = recorder.state !== "idle" && recorder.state !== "error";
3133
- const canRecord = recorder.state === "ready";
3134
- const canStop = recorder.state === "recording";
3144
+ const canRecord = recorder.state === "ready" && !countingIn;
3145
+ const canStop = recorder.state === "recording" || countingIn;
3135
3146
  const canSave = recorder.state === "stopped" && recorder.blob !== null;
3136
3147
  const isBusy = recorder.state === "requesting" || recorder.state === "stopping" || isSaving;
3137
3148
  const slidesTimingCapture = slidesOn && slidesCaptureTimings;
@@ -3185,7 +3196,7 @@ function RecorderModal({
3185
3196
  sourceText
3186
3197
  ]);
3187
3198
  const slideCoverageWarning = slideCoverage ? unshownSlidesWarning(slideCoverage.total, slideCoverage.unshown) : null;
3188
- const togglesLocked = recorder.state === "recording" || recorder.state === "requesting" || recorder.state === "stopping" || canSave;
3199
+ const togglesLocked = countingIn || recorder.state === "recording" || recorder.state === "requesting" || recorder.state === "stopping" || canSave;
3189
3200
  const toggleLockReason = canSave ? "Save or discard this recording before changing sources" : void 0;
3190
3201
  const systemAudioHasCompanion = micOn || cameraOn || screenOn;
3191
3202
  const simpleToggleProps = (key) => {
@@ -3680,24 +3691,33 @@ function RecorderModal({
3680
3691
  children: recorder.state === "requesting" ? "Requesting\u2026" : "Start preview"
3681
3692
  }
3682
3693
  ),
3683
- canRecord && /* @__PURE__ */ jsxs5("button", { type: "button", style: btnRecord, onClick: handleStart, disabled: isBusy, children: [
3684
- /* @__PURE__ */ jsx6(
3685
- "span",
3686
- {
3687
- className: "squisq-recorder-record-dot",
3688
- style: recordDotFrameStyle,
3689
- "aria-hidden": "true",
3690
- children: /* @__PURE__ */ jsx6(
3694
+ canRecord && /* @__PURE__ */ jsxs5(
3695
+ "button",
3696
+ {
3697
+ type: "button",
3698
+ style: btnRecord,
3699
+ onClick: () => void handleStart(),
3700
+ disabled: isBusy,
3701
+ children: [
3702
+ /* @__PURE__ */ jsx6(
3691
3703
  "span",
3692
3704
  {
3693
- className: "squisq-recorder-record-dot-center",
3694
- style: recordDotStyle
3705
+ className: "squisq-recorder-record-dot",
3706
+ style: recordDotFrameStyle,
3707
+ "aria-hidden": "true",
3708
+ children: /* @__PURE__ */ jsx6(
3709
+ "span",
3710
+ {
3711
+ className: "squisq-recorder-record-dot-center",
3712
+ style: recordDotStyle
3713
+ }
3714
+ )
3695
3715
  }
3696
- )
3697
- }
3698
- ),
3699
- "Record"
3700
- ] }),
3716
+ ),
3717
+ "Record"
3718
+ ]
3719
+ }
3720
+ ),
3701
3721
  canStop && /* @__PURE__ */ jsx6("button", { type: "button", style: btnDanger, onClick: handleStop, disabled: isBusy, children: "Stop" }),
3702
3722
  canSave && /* @__PURE__ */ jsxs5(Fragment3, { children: [
3703
3723
  /* @__PURE__ */ jsx6(
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  MarkdownEscape
3
- } from "./chunk-2XXBDECJ.js";
3
+ } from "./chunk-OCQEWWHI.js";
4
4
  import {
5
5
  markdownToTiptap,
6
6
  tiptapToMarkdown
7
- } from "./chunk-DPAMJV6A.js";
7
+ } from "./chunk-HSWWEWT4.js";
8
8
 
9
9
  // src/jsonEditor/JsonEditorContext.tsx
10
10
  import { createContext, useContext, useEffect, useMemo } from "react";
@@ -429,6 +429,7 @@ function useTeleprompter(opts) {
429
429
  const levelRef = useRef2(0);
430
430
  const voiceRef = useRef2(false);
431
431
  const countdownTimerRef = useRef2(null);
432
+ const countInWaitersRef = useRef2([]);
432
433
  scriptRef.current = script;
433
434
  prefsRef.current = prefs;
434
435
  transportRef.current = transport;
@@ -453,13 +454,19 @@ function useTeleprompter(opts) {
453
454
  const notifyTick = useCallback2(() => {
454
455
  for (const cb of tickSubsRef.current) cb(wordPosRef.current);
455
456
  }, []);
457
+ const settleCountIn = useCallback2((rolled) => {
458
+ const waiters = countInWaitersRef.current;
459
+ countInWaitersRef.current = [];
460
+ for (const resolve of waiters) resolve(rolled);
461
+ }, []);
456
462
  const clearCountdown = useCallback2(() => {
457
463
  if (countdownTimerRef.current !== null) {
458
464
  clearInterval(countdownTimerRef.current);
459
465
  countdownTimerRef.current = null;
460
466
  }
461
467
  setCountdownRemaining(null);
462
- }, []);
468
+ settleCountIn(false);
469
+ }, [settleCountIn]);
463
470
  const finish = useCallback2(() => {
464
471
  setTransport("finished");
465
472
  transportRef.current = "finished";
@@ -533,13 +540,14 @@ function useTeleprompter(opts) {
533
540
  return () => cancelAnimationFrame(raf);
534
541
  }, [transport, mic.status, finish, notifyTick, publish]);
535
542
  const beginRolling = useCallback2(() => {
543
+ settleCountIn(true);
536
544
  clearCountdown();
537
545
  if (sessionRef.current) {
538
546
  sessionRef.current = reanchorSession(sessionRef.current, wordPosRef.current);
539
547
  }
540
548
  setTransport("rolling");
541
549
  transportRef.current = "rolling";
542
- }, [clearCountdown]);
550
+ }, [clearCountdown, settleCountIn]);
543
551
  const play = useCallback2(() => {
544
552
  if (transportRef.current === "rolling" || transportRef.current === "countdown") return;
545
553
  if (transportRef.current === "finished") {
@@ -564,6 +572,14 @@ function useTeleprompter(opts) {
564
572
  beginRolling();
565
573
  }
566
574
  }, [beginRolling, mic, publish]);
575
+ const countIn = useCallback2(() => {
576
+ if (transportRef.current === "rolling") return Promise.resolve(true);
577
+ const rolled = new Promise((resolve) => {
578
+ countInWaitersRef.current.push(resolve);
579
+ });
580
+ play();
581
+ return rolled;
582
+ }, [play]);
567
583
  const pause = useCallback2(() => {
568
584
  if (transportRef.current === "countdown") {
569
585
  clearCountdown();
@@ -699,6 +715,7 @@ function useTeleprompter(opts) {
699
715
  prefs,
700
716
  setPrefs,
701
717
  play,
718
+ countIn,
702
719
  pause,
703
720
  restart,
704
721
  nudge,
@@ -1450,6 +1467,11 @@ function useNarrationRecorder(options) {
1450
1467
  cameraMime = videoFormat.mimeType;
1451
1468
  cameraExt = videoFormat.extension;
1452
1469
  }
1470
+ if (opts.countIn) {
1471
+ setCameraStream(camera);
1472
+ if (!await opts.countIn()) throw new StartAborted();
1473
+ if (superseded()) throw new StartAborted();
1474
+ }
1453
1475
  const capture = {
1454
1476
  audioRecorder,
1455
1477
  audioChunks: [],
@@ -1527,6 +1549,7 @@ function useNarrationRecorder(options) {
1527
1549
  if (!capture) {
1528
1550
  if (startingRef.current) {
1529
1551
  cancelPendingStart();
1552
+ optionsRef.current.onRecordingStop?.();
1530
1553
  setState("idle");
1531
1554
  }
1532
1555
  return;
@@ -1826,7 +1849,8 @@ function useNarrationStage(opts) {
1826
1849
  maxRecordingBytes: opts.maxRecordingBytes,
1827
1850
  audioRecorderOptions: opts.audioRecorderOptions,
1828
1851
  cameraRecorderOptions: opts.cameraRecorderOptions,
1829
- onRecordingStart: () => controllerRef.current.play(),
1852
+ // The take starts when the countdown ends, with the prompter already rolling.
1853
+ countIn: () => controllerRef.current.countIn(),
1830
1854
  onRecordingStop: () => controllerRef.current.pause()
1831
1855
  });
1832
1856
  const recorderRef = useRef5(recorder);
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CodeContext, E as EditorHostMode, S as SceneTextChannel, a as CalcEngineFactory, b as CsvSourceMeta, X as XlsxSourceMeta, F as FormulaEditRecord } from './shell-Cb0P_ln8.js';
2
- export { A as ApplySourceEditsOptions, B as BlockInsertionBuilder, c as BlockInsertionContext, d as BlockPlacement, e as BlockRange, f as BlockSlice, g as BlockTagVisibility, h as CodeContextSection, i as CoverImageSaveOutput, D as DashboardImageSaveOutput, j as DocumentLinkCandidate, k as DocumentLinkProvider, l as EditorActions, m as EditorColorScheme, n as EditorContextMenuContext, o as EditorContextMenuItem, p as EditorContextMenuItemVisibility, q as EditorContextMenuProvider, r as EditorContextMenuProviderProps, s as EditorContextValue, t as EditorMode, u as EditorProvider, v as EditorProviderProps, w as EditorSelectionInfo, x as EditorShell, y as EditorShellProps, z as EditorState, G as EditorView, H as FormulaSessionOptions, I as ImageDisplayMode, J as IngestedSidecar, K as InsertBlockOptions, L as LayoutMode, M as MentionCandidate, N as MentionProvider, O as OutlineBlock, P as OutlineInsertion, Q as PreviewPanel, R as PreviewPanelProps, T as RawEditor, U as RawEditorProps, V as ThemeInheritance, W as ViewPreferences, Y as WriteCanvasSettings, Z as WysiwygEditor, _ as WysiwygEditorProps, $ as XLSX_LOCKED_REASON, a0 as XlsxFormulaSession, a1 as applySourceEditsToText, a2 as blockInsertionPoint, a3 as createXlsxFormulaSession, a4 as getBlockSlices, a5 as headingDepthForInsertion, a6 as ingestSidecarBytes, a7 as joinBlockAt, a8 as lineToOffset, a9 as minimalReplaceEdit, aa as normalizeSourceEdits, ab as offsetToLine, ac as resolveOutlineInsertion, ad as sliceIndexAtOffset, ae as sourceOutline, af as spliceBlock, ag as useEditorContext, ah as useEditorContextMenuItems } from './shell-Cb0P_ln8.js';
1
+ import { C as CodeContext, E as EditorHostMode, S as SceneTextChannel, a as CalcEngineFactory, b as CsvSourceMeta, X as XlsxSourceMeta, F as FormulaEditRecord } from './shell-Cje1A3zN.js';
2
+ export { A as ApplySourceEditsOptions, B as BlockInsertionBuilder, c as BlockInsertionContext, d as BlockPlacement, e as BlockRange, f as BlockSlice, g as BlockTagVisibility, h as CodeContextSection, i as CoverImageSaveOutput, D as DashboardImageSaveOutput, j as DocumentLinkCandidate, k as DocumentLinkProvider, l as EditorActions, m as EditorColorScheme, n as EditorContextMenuContext, o as EditorContextMenuItem, p as EditorContextMenuItemVisibility, q as EditorContextMenuProvider, r as EditorContextMenuProviderProps, s as EditorContextValue, t as EditorMode, u as EditorProvider, v as EditorProviderProps, w as EditorSelectionInfo, x as EditorShell, y as EditorShellProps, z as EditorState, G as EditorView, H as FormulaSessionOptions, I as ImageDisplayMode, J as IngestedSidecar, K as InsertBlockOptions, L as LayoutMode, M as MentionCandidate, N as MentionProvider, O as OutlineBlock, P as OutlineInsertion, Q as PreviewPanel, R as PreviewPanelProps, T as RawEditor, U as RawEditorProps, V as ThemeInheritance, W as ViewPreferences, Y as WriteCanvasSettings, Z as WysiwygEditor, _ as WysiwygEditorProps, $ as XLSX_LOCKED_REASON, a0 as XlsxFormulaSession, a1 as applySourceEditsToText, a2 as blockInsertionPoint, a3 as createXlsxFormulaSession, a4 as getBlockSlices, a5 as headingDepthForInsertion, a6 as ingestSidecarBytes, a7 as joinBlockAt, a8 as lineToOffset, a9 as minimalReplaceEdit, aa as normalizeSourceEdits, ab as offsetToLine, ac as resolveOutlineInsertion, ad as sliceIndexAtOffset, ae as sourceOutline, af as spliceBlock, ag as useEditorContext, ah as useEditorContextMenuItems } from './shell-Cje1A3zN.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties, ReactElement } from 'react';
@@ -27,9 +27,9 @@ import { FenceRendererMap } from '@bendyline/squisq/fence';
27
27
  import { TableViewState } from '@bendyline/squisq/table';
28
28
  import { EditJournal } from '@bendyline/squisq-grid-react';
29
29
  export { JsonEditor, JsonEditorProps } from './json-editor/index.js';
30
- export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, r as RecorderNarrationOptions, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, x as RecorderSlidesOptions, S as ScreenStreamHandle, y as ScreenStreamOptions, z as SlideTimingSaveResult, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from './recorder-CRsw0eC7.js';
31
- import { R as RecorderState } from './useNarrationStage-vKtk6H-V.js';
32
- export { C as CanvasSink, a as CaptureKind, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, c as FloatingWindowHandle, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, g as NarrationStageHandle, h as NarrationTake, P as PrompterTransport, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, m as ResolvedFormat, T as TeleprompterController, n as TeleprompterPrefs, o as TeleprompterRecordingDeps, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, q as UseNarrationStageOptions, r as buildFilename, s as createFloatingWindowManager, t as detectFloatTiers, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, z as useFloatingWindow, A as useMediaRecorder, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from './useNarrationStage-vKtk6H-V.js';
30
+ export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, r as RecorderNarrationOptions, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, x as RecorderSlidesOptions, S as ScreenStreamHandle, y as ScreenStreamOptions, z as SlideTimingSaveResult, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from './recorder-DKN3vZPi.js';
31
+ import { R as RecorderState } from './useNarrationStage-CB8dynUg.js';
32
+ export { C as CanvasSink, a as CaptureKind, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, c as FloatingWindowHandle, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, g as NarrationStageHandle, h as NarrationTake, P as PrompterTransport, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, m as ResolvedFormat, T as TeleprompterController, n as TeleprompterPrefs, o as TeleprompterRecordingDeps, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, q as UseNarrationStageOptions, r as buildFilename, s as createFloatingWindowManager, t as detectFloatTiers, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, z as useFloatingWindow, A as useMediaRecorder, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from './useNarrationStage-CB8dynUg.js';
33
33
  export { EYE_LINE_FRACTION, ExecuteNarrationSaveDeps, NarrationSavePlan, NarrationSavePlanArgs, NarrationSaveProgress, NarrationSaveResult, NarrationStage, NarrationStageProps, PCM_WORKLET_NAME, PCM_WORKLET_SOURCE, TELEPROMPTER_CSS, TeleprompterControls, TeleprompterControlsProps, TeleprompterSurface, TeleprompterSurfaceProps, TeleprompterView, TeleprompterViewProps, TokenLineMap, buildNarrationSavePlan, cameraVideoLine, ensureTeleprompterStyles, executeNarrationSave, insertNarrationPreamble, measureTokenLines, narrationAnnotationLine, prompterVarsFromTheme, registerPcmWorklet, stepScroll, targetOffsetFor } from './teleprompter/index.js';
34
34
  export { H as HarperProofingConfig, a as ProofingCapability, b as ProofingDocumentRef, c as ProofingIgnoreStore, d as ProofingLanguage, e as ProofingLintOptions, P as ProofingProvider, f as ProofingProviderFactory } from './types-De4z-gGb.js';
35
35
  export { createHarperProofingProvider } from './proofing/index.js';
@@ -1339,10 +1339,6 @@ interface StatusBarProps {
1339
1339
  /** Host-supplied status content rendered at the right edge. */
1340
1340
  slotRight?: ReactNode;
1341
1341
  }
1342
- /**
1343
- * Status bar displaying document statistics: character count, word count,
1344
- * block count, parse errors, and optional host status.
1345
- */
1346
1342
  declare function StatusBar({ className, slotRight }: StatusBarProps): react_jsx_runtime.JSX.Element;
1347
1343
 
1348
1344
  /**
package/dist/index.js CHANGED
@@ -221,7 +221,7 @@ import {
221
221
  validateMermaidSource,
222
222
  viewStateFromBinding,
223
223
  writeHeadingViewState
224
- } from "./chunk-GIXXD2O3.js";
224
+ } from "./chunk-5EB3BGPE.js";
225
225
  import {
226
226
  EditorProvider,
227
227
  applySourceEditsToText,
@@ -241,7 +241,7 @@ import {
241
241
  spliceBlock,
242
242
  useBlockNavigator,
243
243
  useEditorContext
244
- } from "./chunk-45NQUR62.js";
244
+ } from "./chunk-TZX7RKZV.js";
245
245
  import {
246
246
  SPEECH_INPUT_SAMPLE_RATE,
247
247
  isSpeechInputProviderFactory,
@@ -250,14 +250,14 @@ import {
250
250
  import "./chunk-V4NBQF5C.js";
251
251
  import {
252
252
  JsonEditor
253
- } from "./chunk-UBFNLWCN.js";
253
+ } from "./chunk-V2OLZOYJ.js";
254
254
  import {
255
255
  MarkdownEscape
256
- } from "./chunk-2XXBDECJ.js";
256
+ } from "./chunk-OCQEWWHI.js";
257
257
  import {
258
258
  markdownToTiptap,
259
259
  tiptapToMarkdown
260
- } from "./chunk-DPAMJV6A.js";
260
+ } from "./chunk-HSWWEWT4.js";
261
261
  import {
262
262
  ImageEditor,
263
263
  ImageViewer,
@@ -267,7 +267,7 @@ import {
267
267
  } from "./chunk-K4Z2GIX4.js";
268
268
  import {
269
269
  RecorderButton
270
- } from "./chunk-WKZLBGPX.js";
270
+ } from "./chunk-LR6Q2MK4.js";
271
271
  import {
272
272
  RecorderDeviceQuickPicks,
273
273
  RecorderDeviceSettingsPanel,
@@ -292,7 +292,7 @@ import {
292
292
  unshownSlidesWarning,
293
293
  useMediaDevices,
294
294
  useMediaRecorder
295
- } from "./chunk-U6NVT3BY.js";
295
+ } from "./chunk-UFK47ZAI.js";
296
296
  import {
297
297
  DEFAULT_RECORDER_DEVICE_SETTINGS,
298
298
  buildRecorderAudioConstraints,
@@ -304,7 +304,7 @@ import {
304
304
  import "./chunk-GS7QWYFT.js";
305
305
  import {
306
306
  TeleprompterView
307
- } from "./chunk-H7YTL6SL.js";
307
+ } from "./chunk-DJS5I5NO.js";
308
308
  import {
309
309
  DEFAULT_TELEPROMPTER_PREFS,
310
310
  EYE_LINE_FRACTION,
@@ -338,7 +338,7 @@ import {
338
338
  useStreamPreview,
339
339
  useTeleprompter,
340
340
  vadConfigForSensitivity
341
- } from "./chunk-CGENKHWY.js";
341
+ } from "./chunk-ZS6G2P57.js";
342
342
  import {
343
343
  buildFilename,
344
344
  requestMicStream,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  JsonEditor
3
- } from "../chunk-UBFNLWCN.js";
4
- import "../chunk-2XXBDECJ.js";
5
- import "../chunk-DPAMJV6A.js";
3
+ } from "../chunk-V2OLZOYJ.js";
4
+ import "../chunk-OCQEWWHI.js";
5
+ import "../chunk-HSWWEWT4.js";
6
6
  export {
7
7
  JsonEditor
8
8
  };
@@ -1,5 +1,5 @@
1
- export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, S as ScreenStreamHandle, y as ScreenStreamOptions, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from '../recorder-CRsw0eC7.js';
2
- export { a as CaptureKind, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, R as RecorderState, m as ResolvedFormat, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, r as buildFilename, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, A as useMediaRecorder } from '../useNarrationStage-vKtk6H-V.js';
1
+ export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, S as ScreenStreamHandle, y as ScreenStreamOptions, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from '../recorder-DKN3vZPi.js';
2
+ export { a as CaptureKind, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, R as RecorderState, m as ResolvedFormat, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, r as buildFilename, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, A as useMediaRecorder } from '../useNarrationStage-CB8dynUg.js';
3
3
  import 'react/jsx-runtime';
4
4
  import '@bendyline/squisq/schemas';
5
5
  import '@bendyline/squisq/storage';
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RecorderButton
3
- } from "../chunk-WKZLBGPX.js";
3
+ } from "../chunk-LR6Q2MK4.js";
4
4
  import {
5
5
  RecorderDeviceQuickPicks,
6
6
  RecorderDeviceSettingsPanel,
@@ -14,7 +14,7 @@ import {
14
14
  requestScreenStream,
15
15
  useMediaDevices,
16
16
  useMediaRecorder
17
- } from "../chunk-U6NVT3BY.js";
17
+ } from "../chunk-UFK47ZAI.js";
18
18
  import {
19
19
  DEFAULT_RECORDER_DEVICE_SETTINGS,
20
20
  buildRecorderAudioConstraints,
@@ -30,7 +30,7 @@ import {
30
30
  requestCameraStream,
31
31
  timingPathFor,
32
32
  useStreamPreview
33
- } from "../chunk-CGENKHWY.js";
33
+ } from "../chunk-ZS6G2P57.js";
34
34
  import {
35
35
  buildFilename,
36
36
  requestMicStream,
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { Doc, Theme, ViewportConfig, MediaProvider } from '@bendyline/squisq/schemas';
3
3
  import { ContentContainer } from '@bendyline/squisq/storage';
4
- import { l as RecorderSource, o as TeleprompterRecordingDeps, S as ScreenCaptureRegion } from './useNarrationStage-vKtk6H-V.js';
4
+ import { l as RecorderSource, o as TeleprompterRecordingDeps, S as ScreenCaptureRegion } from './useNarrationStage-CB8dynUg.js';
5
5
  import { CSSProperties, RefObject } from 'react';
6
6
 
7
7
  type RecordedMediaKind = 'audio' | 'video';
@@ -19,9 +19,9 @@ import {
19
19
  updateReviewDecorations,
20
20
  useReview,
21
21
  useReviewState
22
- } from "../chunk-45NQUR62.js";
22
+ } from "../chunk-TZX7RKZV.js";
23
23
  import "../chunk-DNEVUOBZ.js";
24
- import "../chunk-DPAMJV6A.js";
24
+ import "../chunk-HSWWEWT4.js";
25
25
 
26
26
  // src/review/proofingAdapter.ts
27
27
  import {
@@ -1,4 +1,4 @@
1
- export { g as BlockTagVisibility, j as DocumentLinkCandidate, k as DocumentLinkProvider, l as EditorActions, m as EditorColorScheme, n as EditorContextMenuContext, o as EditorContextMenuItem, p as EditorContextMenuItemVisibility, q as EditorContextMenuProvider, r as EditorContextMenuProviderProps, s as EditorContextValue, E as EditorHostMode, t as EditorMode, u as EditorProvider, v as EditorProviderProps, x as EditorShell, y as EditorShellProps, z as EditorState, G as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, N as MentionProvider, Q as PreviewPanel, R as PreviewPanelProps, T as RawEditor, U as RawEditorProps, V as ThemeInheritance, W as ViewPreferences, Z as WysiwygEditor, _ as WysiwygEditorProps, ag as useEditorContext, ah as useEditorContextMenuItems } from '../shell-Cb0P_ln8.js';
1
+ export { g as BlockTagVisibility, j as DocumentLinkCandidate, k as DocumentLinkProvider, l as EditorActions, m as EditorColorScheme, n as EditorContextMenuContext, o as EditorContextMenuItem, p as EditorContextMenuItemVisibility, q as EditorContextMenuProvider, r as EditorContextMenuProviderProps, s as EditorContextValue, E as EditorHostMode, t as EditorMode, u as EditorProvider, v as EditorProviderProps, x as EditorShell, y as EditorShellProps, z as EditorState, G as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, N as MentionProvider, Q as PreviewPanel, R as PreviewPanelProps, T as RawEditor, U as RawEditorProps, V as ThemeInheritance, W as ViewPreferences, Z as WysiwygEditor, _ as WysiwygEditorProps, ag as useEditorContext, ah as useEditorContextMenuItems } from '../shell-Cje1A3zN.js';
2
2
  import 'react/jsx-runtime';
3
3
  import '@bendyline/squisq/table';
4
4
  import '@bendyline/squisq-calc';
@@ -5,21 +5,21 @@ import {
5
5
  RawEditor,
6
6
  WysiwygEditor,
7
7
  useEditorContextMenuItems
8
- } from "../chunk-GIXXD2O3.js";
8
+ } from "../chunk-5EB3BGPE.js";
9
9
  import {
10
10
  EditorProvider,
11
11
  useEditorContext
12
- } from "../chunk-45NQUR62.js";
12
+ } from "../chunk-TZX7RKZV.js";
13
13
  import "../chunk-DNEVUOBZ.js";
14
14
  import "../chunk-V4NBQF5C.js";
15
- import "../chunk-2XXBDECJ.js";
16
- import "../chunk-DPAMJV6A.js";
15
+ import "../chunk-OCQEWWHI.js";
16
+ import "../chunk-HSWWEWT4.js";
17
17
  import "../chunk-K4Z2GIX4.js";
18
- import "../chunk-U6NVT3BY.js";
18
+ import "../chunk-UFK47ZAI.js";
19
19
  import "../chunk-LRZJD5YD.js";
20
20
  import "../chunk-GS7QWYFT.js";
21
- import "../chunk-H7YTL6SL.js";
22
- import "../chunk-CGENKHWY.js";
21
+ import "../chunk-DJS5I5NO.js";
22
+ import "../chunk-ZS6G2P57.js";
23
23
  import "../chunk-DNJ6HOES.js";
24
24
  export {
25
25
  EditorContextMenuProvider,
@@ -735,6 +735,12 @@ interface EditorContextValue extends EditorState, EditorActions {
735
735
  * reads it from here.
736
736
  */
737
737
  versioning: DocumentVersionManager | null;
738
+ /**
739
+ * Whether versions are also saved automatically after an idle pause
740
+ * (`versioningAutoSaveIdleMs` above zero), so the version-history panel
741
+ * only promises automatic saves when the host has them on.
742
+ */
743
+ versioningAutoSaves: boolean;
738
744
  /**
739
745
  * Stamp a new snapshot of the current document. No-op (returns
740
746
  * `unchanged`) when content matches the latest version. Always safe
@@ -7866,8 +7866,9 @@
7866
7866
  .squisq-toolbar-contextual--clipped {
7867
7867
  visibility: hidden;
7868
7868
  }
7869
- .squisq-toolbar-button--overflowed {
7870
- visibility: hidden;
7869
+ .squisq-toolbar-button.squisq-toolbar-button--overflowed,
7870
+ .squisq-toolbar-group.squisq-toolbar-group--collapsed {
7871
+ display: none;
7871
7872
  }
7872
7873
  .squisq-toolbar-view-tab {
7873
7874
  padding: 8px 14px 4px;
@@ -9259,6 +9260,18 @@
9259
9260
  color: var(--squisq-text-muted);
9260
9261
  flex-shrink: 0;
9261
9262
  gap: 12px;
9263
+ container: squisq-status-bar / inline-size;
9264
+ }
9265
+ @container squisq-status-bar (max-width: 520px) {
9266
+ .squisq-status-chars,
9267
+ .squisq-status-lines {
9268
+ display: none;
9269
+ }
9270
+ }
9271
+ @container squisq-status-bar (max-width: 300px) {
9272
+ .squisq-status-blocks {
9273
+ display: none;
9274
+ }
9262
9275
  }
9263
9276
  .squisq-status-item {
9264
9277
  white-space: nowrap;
@@ -11448,7 +11461,8 @@
11448
11461
  color: var(--squisq-danger-strong);
11449
11462
  background: var(--squisq-danger-soft);
11450
11463
  }
11451
- .squisq-version-history-empty {
11464
+ .squisq-version-history-empty,
11465
+ .squisq-version-history-note {
11452
11466
  padding: 16px 12px;
11453
11467
  font-size: 12px;
11454
11468
  color: var(--squisq-text-muted);
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { Doc, Theme, MediaProvider } from '@bendyline/squisq/schemas';
3
3
  import { ContentContainer } from '@bendyline/squisq/storage';
4
- import { o as TeleprompterRecordingDeps, g as NarrationStageHandle, T as TeleprompterController, c as FloatingWindowHandle } from '../useNarrationStage-vKtk6H-V.js';
5
- export { C as CanvasSink, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, h as NarrationTake, P as PrompterTransport, J as TELEPROMPTER_PREF_LIMITS, n as TeleprompterPrefs, q as UseNarrationStageOptions, s as createFloatingWindowManager, t as detectFloatTiers, K as normalizeTeleprompterPrefs, z as useFloatingWindow, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from '../useNarrationStage-vKtk6H-V.js';
4
+ import { o as TeleprompterRecordingDeps, g as NarrationStageHandle, T as TeleprompterController, c as FloatingWindowHandle } from '../useNarrationStage-CB8dynUg.js';
5
+ export { C as CanvasSink, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, h as NarrationTake, P as PrompterTransport, J as TELEPROMPTER_PREF_LIMITS, n as TeleprompterPrefs, q as UseNarrationStageOptions, s as createFloatingWindowManager, t as detectFloatTiers, K as normalizeTeleprompterPrefs, z as useFloatingWindow, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from '../useNarrationStage-CB8dynUg.js';
6
6
  import { NarrationTimingJsonV3, NarrationScript, NarrationAlignment, NarrationTimingGenerator } from '@bendyline/squisq/narration';
7
7
  import { ReactNode } from 'react';
8
8
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TeleprompterView
3
- } from "../chunk-H7YTL6SL.js";
3
+ } from "../chunk-DJS5I5NO.js";
4
4
  import {
5
5
  DEFAULT_TELEPROMPTER_PREFS,
6
6
  EYE_LINE_FRACTION,
@@ -31,7 +31,7 @@ import {
31
31
  useNarrationStage,
32
32
  useTeleprompter,
33
33
  vadConfigForSensitivity
34
- } from "../chunk-CGENKHWY.js";
34
+ } from "../chunk-ZS6G2P57.js";
35
35
  import "../chunk-DNJ6HOES.js";
36
36
  export {
37
37
  DEFAULT_TELEPROMPTER_PREFS,