@stll/folio-react 0.25.0 → 0.25.1

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,6 +1,7 @@
1
1
  import { i as cn, n as FolioUIProvider, r as useFolioUI, t as DEFAULT_COMPONENTS } from "./folio-ui-DO95voaI.js";
2
2
  import { t as messages_exports } from "./messages.js";
3
3
  import { c } from "react-compiler-runtime";
4
+ import { CANONICAL_GAP, canonicalRefusalMessage, usesCanonicalSession } from "@stll/folio-core/types/canonicalCapabilities";
4
5
  import * as React$1 from "react";
5
6
  import React, { Component, Suspense, cloneElement, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
7
  import { AlertCircleIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, BaselineIcon, BoldIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ClipboardCopyIcon, EyeIcon, FileIcon, GlobeIcon, ImageIcon, IndentDecreaseIcon, IndentIncreaseIcon, InfoIcon, ItalicIcon, LinkIcon, ListIcon, ListOrderedIcon, ListTreeIcon, MessageSquareTextIcon, MoreHorizontalIcon, OmegaIcon, PaintbrushIcon, PanelLeftOpenIcon, PenLineIcon, PencilIcon, PilcrowIcon, Redo2Icon, RulerIcon, SeparatorHorizontalIcon, SquarePenIcon, StickyNoteIcon, TableIcon, TableOfContentsIcon, TypeIcon, UnderlineIcon, Undo2Icon, UnlinkIcon, XIcon } from "lucide-react";
@@ -45,9 +46,10 @@ import { collectHeadings } from "@stll/folio-core/utils/headingCollector";
45
46
  import { formatPx, pixelsToTwips, pointsToHalfPoints, twipsToPixels } from "@stll/folio-core/utils/units";
46
47
  import { HistoryManager, classifyHistoryShortcut } from "@stll/folio-core/managers/HistoryManager";
47
48
  import { createCanonicalHeaderFooterOperation, createCanonicalSectionPropertiesOperation, removeCanonicalHeaderFooterOperations } from "@stll/folio-core/controller/canonicalOperations";
48
- import { repackWithCanonicalStoryRemovals } from "@stll/folio-core/docx/canonicalStoryRepack";
49
+ import { CanonicalSaveDiagnosticError, serializeCanonicalSave } from "@stll/folio-core/docx/canonicalSave";
49
50
  import { TableSelectionManager } from "@stll/folio-core/managers/TableSelectionManager";
50
51
  import { DEFAULT_PAGE_HEIGHT_PX, getMargins, getPageSize, twipsToPixels as twipsToPixels$1 } from "@stll/folio-core/paged-layout/sectionGeometry";
52
+ import { getFootnoteText } from "@stll/folio-core/docx/storyPlainText";
51
53
  import { createPortal } from "react-dom";
52
54
  import { NodeSelection, Selection, TextSelection as TextSelection$1 } from "prosemirror-state";
53
55
  import { CellSelection } from "prosemirror-tables";
@@ -65,7 +67,6 @@ import { TRANSACTION_LAYOUT_TIMING, browserClock, createLayoutScheduler } from "
65
67
  import { createLayoutSession } from "@stll/folio-core/controller/layoutSession";
66
68
  import { createHyphenationReadiness } from "@stll/folio-core/controller/hyphenationReadiness";
67
69
  import { readFontSetSignature, waitForInitialLayoutFonts, watchLayoutFontLoads } from "@stll/folio-core/controller/fontReadiness";
68
- import { getFootnoteText } from "@stll/folio-core/docx/footnoteParser";
69
70
  import { convertHeaderFooterPmDocToContent, convertHeaderFooterToContent } from "@stll/folio-core/layout-bridge/convert/headerFooterLayout";
70
71
  import { templatePreviewDirtyRange } from "@stll/folio-core/layout-bridge/convert/templatePreviewFlow";
71
72
  import { clickToPositionDom, getCaretPositionFromDom, getSelectionRectsFromDom } from "@stll/folio-core/layout-bridge/dom/clickToPositionDom";
@@ -368,7 +369,7 @@ const HiddenHeaderFooterPMs = memo(forwardRef(function HiddenHeaderFooterPMs({ d
368
369
  getTheme: () => themeRef.current,
369
370
  getCanonicalApi: () => canonicalApiRef.current?.() ?? null,
370
371
  getExperimentalSession: () => sessionRef.current,
371
- onSessionRefusal: (reason) => refusalRef.current?.(reason),
372
+ onSessionRefusal: (reason, gap) => refusalRef.current?.(reason, gap),
372
373
  onTransaction: ({ rId, kind, view, docChanged, selectionChanged }) => {
373
374
  onTransactionRef.current?.(rId, kind, view, docChanged, selectionChanged);
374
375
  }
@@ -475,10 +476,10 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
475
476
  getTheme: () => themeRef.current,
476
477
  getCanonicalApi: () => canonicalApiRef.current?.() ?? null,
477
478
  getExperimentalSession: () => sessionRef.current,
478
- onSessionRefusal: (reason) => refusalRef.current?.(reason),
479
+ onSessionRefusal: (reason, gap) => refusalRef.current?.(reason, gap),
479
480
  onTransaction: (t2) => {
480
481
  const { docChanged, selectionChanged, view } = t2;
481
- if (docChanged) if (sessionRef.current === "canonical") {
482
+ if (docChanged) if (usesCanonicalSession(sessionRef.current, CANONICAL_GAP.secondaryStories)) {
482
483
  const canonical = canonicalApiRef.current?.()?.getCanonicalDocument();
483
484
  if (canonical) onDocumentChangeRef.current(canonical);
484
485
  } else {
@@ -1318,7 +1319,7 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1318
1319
  getExperimentalSession: () => experimentalSessionRef.current,
1319
1320
  getEditingMode: () => suggestionModeActiveRef.current ? "suggesting" : "editing",
1320
1321
  getSuggestionAuthor: () => suggestionAuthorRef.current,
1321
- onSessionRefusal: (reason) => onSessionRefusalRef.current?.(reason),
1322
+ onSessionRefusal: (reason, gap) => onSessionRefusalRef.current?.(reason, gap),
1322
1323
  getDocumentIdentity: () => documentIdentityRef.current,
1323
1324
  getDocumentContext: () => documentRef.current,
1324
1325
  onTransaction: (update) => onTransactionRef.current?.(update),
@@ -2900,7 +2901,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2900
2901
  onActiveNoteStoryChange?.(story);
2901
2902
  }, [onActiveNoteStoryChange]);
2902
2903
  useEffect(() => {
2903
- if (readOnly || experimentalSession === "canonical") noteEditorRef.current?.close();
2904
+ if (readOnly || usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) noteEditorRef.current?.close();
2904
2905
  }, [experimentalSession, readOnly]);
2905
2906
  const getCanonicalApi = useCallback(() => hiddenPMRef.current, []);
2906
2907
  const { handlePMKeyDown } = useVisualLineNavigation({ pagesContainerRef });
@@ -2922,8 +2923,11 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2922
2923
  onDocumentChangeRef.current = onDocumentChange;
2923
2924
  onTotalPagesChangeRef.current = onTotalPagesChange;
2924
2925
  onErrorRef.current = onError;
2925
- const handleSessionRefusal = useCallback((message) => {
2926
- onErrorRef.current?.(new CanonicalSessionRefusalError({ message }));
2926
+ const handleSessionRefusal = useCallback((message, gap) => {
2927
+ onErrorRef.current?.(new CanonicalSessionRefusalError({
2928
+ gap,
2929
+ message
2930
+ }));
2927
2931
  }, []);
2928
2932
  const [layout, setLayout] = useState(null);
2929
2933
  const layoutRef = useRef(layout);
@@ -3046,7 +3050,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3046
3050
  queuedInputBeforeHiddenEditorRef.current = [];
3047
3051
  for (const input of queuedInput) {
3048
3052
  if (input.type === "text") {
3049
- if (experimentalSession === "canonical") view_0.dom.dispatchEvent(new InputEvent("beforeinput", {
3053
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) view_0.dom.dispatchEvent(new InputEvent("beforeinput", {
3050
3054
  inputType: "insertText",
3051
3055
  data: input.text,
3052
3056
  cancelable: true,
@@ -3320,10 +3324,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3320
3324
  }
3321
3325
  let newDoc = hiddenPMRef.current?.getDocument();
3322
3326
  const body = hiddenPMRef.current?.getState()?.doc;
3323
- if (newDoc && body && experimentalSession !== "canonical") newDoc = noteFollower.reconcile(newDoc, body);
3327
+ if (newDoc && body && !usesCanonicalSession(experimentalSession, CANONICAL_GAP.save)) newDoc = noteFollower.reconcile(newDoc, body);
3324
3328
  if (newDoc) {
3325
- onDocumentChangeRef.current?.(experimentalSession === "canonical" ? cloneDocumentWithParagraphPropertySources(newDoc) : newDoc);
3326
- folioEmitterRef.current.emit("docChange", experimentalSession === "canonical" ? cloneDocumentWithParagraphPropertySources(newDoc) : newDoc);
3329
+ onDocumentChangeRef.current?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.save) ? cloneDocumentWithParagraphPropertySources(newDoc) : newDoc);
3330
+ folioEmitterRef.current.emit("docChange", usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(newDoc) : newDoc);
3327
3331
  }
3328
3332
  }, [experimentalSession, noteFollower]);
3329
3333
  const scheduleDocumentChangeNotification = useCallback(() => {
@@ -3930,7 +3934,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3930
3934
  if (docChanged_0) {
3931
3935
  if (!hiddenPMRef.current?.getState() && !precomputedInitialStateRef.current) ensureHiddenEditorView({ sync: true });
3932
3936
  scheduleLayout();
3933
- if (experimentalSession === "canonical") scheduleDocumentChangeNotification();
3937
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) scheduleDocumentChangeNotification();
3934
3938
  }
3935
3939
  if (docChanged_0 || selectionChanged) {
3936
3940
  const { from: from_1, to: to_1 } = view_3.state.selection;
@@ -3966,8 +3970,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3966
3970
  }
3967
3971
  }, [scheduleLayout]);
3968
3972
  const handleNoteDocumentChange = useCallback((updated) => {
3969
- onDocumentChangeRef.current?.(experimentalSession === "canonical" ? cloneDocumentWithParagraphPropertySources(updated) : updated);
3970
- folioEmitterRef.current.emit("docChange", experimentalSession === "canonical" ? cloneDocumentWithParagraphPropertySources(updated) : updated);
3973
+ onDocumentChangeRef.current?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(updated) : updated);
3974
+ folioEmitterRef.current.emit("docChange", usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(updated) : updated);
3971
3975
  }, [experimentalSession]);
3972
3976
  useEffect(() => {
3973
3977
  if (!hfEditMode) setHfCaretSelection(null);
@@ -4833,8 +4837,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4833
4837
  if (story_0) {
4834
4838
  e_3.preventDefault();
4835
4839
  e_3.stopPropagation();
4836
- if (experimentalSession === "canonical") {
4837
- handleSessionRefusal("Footnote and endnote editing is unavailable in this session.");
4840
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
4841
+ handleSessionRefusal("Footnote and endnote editing is unavailable in this session.", CANONICAL_GAP.secondaryStories);
4838
4842
  return;
4839
4843
  }
4840
4844
  noteEditorRef.current?.open(story_0);
@@ -5490,7 +5494,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5490
5494
  getDocument() {
5491
5495
  if (documentChangeNotifyTimerRef.current !== null) flushDocumentChangeNotification();
5492
5496
  const editorDocument = folioEditor.getDocument();
5493
- if (experimentalSession === "canonical") return editorDocument;
5497
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return editorDocument;
5494
5498
  const current_0 = editorDocument ? noteFollower.withPending(editorDocument) : null;
5495
5499
  return current_0 ? noteEditorRef.current?.snapshotDocument(current_0) ?? current_0 : null;
5496
5500
  },
@@ -5501,14 +5505,14 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5501
5505
  return folioEditor.getView();
5502
5506
  },
5503
5507
  getActiveView() {
5504
- if (experimentalSession === "canonical") return folioEditor.getView();
5508
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return folioEditor.getView();
5505
5509
  return getActiveEditorStory().view;
5506
5510
  },
5507
5511
  closeNoteStory() {
5508
5512
  noteEditorRef.current?.close();
5509
5513
  },
5510
5514
  getHfView(rId_0) {
5511
- if (experimentalSession === "canonical") return null;
5515
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return null;
5512
5516
  return hfPMsRef.current?.getView(rId_0) ?? null;
5513
5517
  },
5514
5518
  ensureView(options_4) {
@@ -5534,7 +5538,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5534
5538
  undo() {
5535
5539
  const target_5 = getActiveEditorStory();
5536
5540
  if (target_5.type === "none") return false;
5537
- if (experimentalSession === "canonical") return hiddenPMRef.current?.applyCanonicalStoryHistory({
5541
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return hiddenPMRef.current?.applyCanonicalStoryHistory({
5538
5542
  view: target_5.view,
5539
5543
  story: getCanonicalActiveStory(),
5540
5544
  direction: "undo"
@@ -5545,7 +5549,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5545
5549
  redo() {
5546
5550
  const target_6 = getActiveEditorStory();
5547
5551
  if (target_6.type === "none") return false;
5548
- if (experimentalSession === "canonical") return hiddenPMRef.current?.applyCanonicalStoryHistory({
5552
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return hiddenPMRef.current?.applyCanonicalStoryHistory({
5549
5553
  view: target_6.view,
5550
5554
  story: getCanonicalActiveStory(),
5551
5555
  direction: "redo"
@@ -5556,12 +5560,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5556
5560
  canUndo() {
5557
5561
  const target_7 = getActiveEditorStory();
5558
5562
  if (target_7.type === "none") return false;
5559
- return experimentalSession === "canonical" || target_7.type === "body" ? hiddenPMRef.current?.canUndo() ?? false : undo(target_7.view.state);
5563
+ return usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) || target_7.type === "body" ? hiddenPMRef.current?.canUndo() ?? false : undo(target_7.view.state);
5560
5564
  },
5561
5565
  canRedo() {
5562
5566
  const target_8 = getActiveEditorStory();
5563
5567
  if (target_8.type === "none") return false;
5564
- return experimentalSession === "canonical" || target_8.type === "body" ? hiddenPMRef.current?.canRedo() ?? false : redo(target_8.view.state);
5568
+ return usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) || target_8.type === "body" ? hiddenPMRef.current?.canRedo() ?? false : redo(target_8.view.state);
5565
5569
  },
5566
5570
  setSelection(anchor_3, head_1) {
5567
5571
  folioEditor.setSelection(anchor_3, head_1);
@@ -5721,7 +5725,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5721
5725
  onTransaction: handleHfPmTransaction,
5722
5726
  getCanonicalApi,
5723
5727
  onSessionRefusal: handleSessionRefusal,
5724
- ...experimentalSession === void 0 ? {} : { experimentalSession },
5728
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
5725
5729
  ...styles !== void 0 ? { styles } : {},
5726
5730
  ..._theme !== void 0 ? { theme: _theme } : {}
5727
5731
  }),
@@ -5731,7 +5735,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5731
5735
  onActiveChange: handleActiveNoteStoryChange,
5732
5736
  getCanonicalApi,
5733
5737
  onSessionRefusal: handleSessionRefusal,
5734
- ...experimentalSession === void 0 ? {} : { experimentalSession },
5738
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
5735
5739
  onDocumentChange: handleNoteDocumentChange,
5736
5740
  onStoryChange: handleNoteStoryTransaction,
5737
5741
  plugins: noteStoryPlugins,
@@ -5744,7 +5748,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5744
5748
  ref: hiddenPMRef,
5745
5749
  document,
5746
5750
  documentIdentity,
5747
- ...experimentalSession === void 0 ? {} : { experimentalSession },
5751
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
5748
5752
  onSessionRefusal: handleSessionRefusal,
5749
5753
  ...suggestionAuthor !== void 0 ? { suggestionAuthor } : {},
5750
5754
  suggestionModeActive,
@@ -10599,7 +10603,7 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalA
10599
10603
  setHfEditPosition(position);
10600
10604
  return;
10601
10605
  }
10602
- if (experimentalSession === "canonical") {
10606
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10603
10607
  const api = getCanonicalApi?.();
10604
10608
  api?.ensureView();
10605
10609
  const canonical = api?.getCanonicalDocument();
@@ -10629,7 +10633,7 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalA
10629
10633
  experimentalSession
10630
10634
  ]);
10631
10635
  const handleHeaderFooterSave = useCallback(() => {
10632
- if (experimentalSession === "canonical") {
10636
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10633
10637
  setHfEditPosition(null);
10634
10638
  return;
10635
10639
  }
@@ -10683,7 +10687,7 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalA
10683
10687
  return;
10684
10688
  }
10685
10689
  const activeRId_0 = pickActiveHeaderFooterRId(resolution, hfEditPosition, hfEditIsFirstPage);
10686
- if (experimentalSession === "canonical") {
10690
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10687
10691
  const api_0 = getCanonicalApi?.();
10688
10692
  const canonical_0 = api_0?.getCanonicalDocument();
10689
10693
  if (api_0 && canonical_0 && activeRId_0) api_0.applyCanonicalOperations(removeCanonicalHeaderFooterOperations({
@@ -12949,7 +12953,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12949
12953
  */
12950
12954
  /** No headings to track while the outline is not shown. */
12951
12955
  const NO_HEADINGS = [];
12952
- const CommentsSidebar = lazy(() => import("./CommentsSidebar-D9vMIMl7.js").then((m) => ({ default: m.CommentsSidebar })));
12956
+ const CommentsSidebar = lazy(() => import("./CommentsSidebar-D8sljCtX.js").then((m) => ({ default: m.CommentsSidebar })));
12953
12957
  const TextContextMenu = lazy(() => import("./TextContextMenu-Bqth8itn.js").then((m) => ({ default: m.TextContextMenu })));
12954
12958
  const loadAttemptSelectiveSave = async () => {
12955
12959
  const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
@@ -13065,8 +13069,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13065
13069
  readOnlyProp
13066
13070
  });
13067
13071
  const toggleTrackChanges = useCallback(() => {
13068
- if (experimentalSession === "canonical" && !trackChangesOn) {
13069
- const error = new CanonicalSessionRefusalError({ message: "Canonical sessions do not support suggesting mode." });
13072
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.suggesting) && !trackChangesOn) {
13073
+ const error = new CanonicalSessionRefusalError({
13074
+ gap: CANONICAL_GAP.suggesting,
13075
+ message: canonicalRefusalMessage(CANONICAL_GAP.suggesting, "Canonical sessions do not support suggesting mode.")
13076
+ });
13070
13077
  toast(error.message);
13071
13078
  onError?.(error);
13072
13079
  return;
@@ -13126,11 +13133,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13126
13133
  const history = useDocumentHistory(initialDocument || null, {
13127
13134
  maxEntries: 100,
13128
13135
  groupingInterval: 500,
13129
- enableKeyboardShortcuts: historyShortcuts === "editor" && experimentalSession !== "canonical"
13136
+ enableKeyboardShortcuts: historyShortcuts === "editor" && !usesCanonicalSession(experimentalSession, CANONICAL_GAP.history)
13130
13137
  });
13131
- const refuseCanonicalModelEdit = useCallback((message) => {
13132
- if (experimentalSession !== "canonical") return false;
13133
- const error_0 = new CanonicalSessionRefusalError({ message });
13138
+ const refuseCanonicalModelEdit = useCallback((gap, message) => {
13139
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return false;
13140
+ const error_0 = new CanonicalSessionRefusalError({
13141
+ gap,
13142
+ message: canonicalRefusalMessage(gap, message)
13143
+ });
13134
13144
  toast(error_0.message);
13135
13145
  onError?.(error_0);
13136
13146
  return true;
@@ -13372,7 +13382,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13372
13382
  history,
13373
13383
  pushDocument,
13374
13384
  getCanonicalApi,
13375
- ...experimentalSession === void 0 ? {} : { experimentalSession },
13385
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
13376
13386
  getHfView: (rId) => pagedEditorRef.current?.getHfView(rId) ?? null
13377
13387
  });
13378
13388
  let activeHfRId = hfEditIsFirstPage ? activeFirstFooterRId : activeFooterRId;
@@ -13405,7 +13415,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13405
13415
  else pagedEditorRef.current?.focus();
13406
13416
  }, [getActiveEditorStory]);
13407
13417
  const undoActiveEditor = useCallback(() => {
13408
- if (experimentalSession !== "canonical" && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.undo();
13418
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.undo();
13409
13419
  else {
13410
13420
  pagedEditorRef.current?.undo();
13411
13421
  requestAnimationFrame(refreshBodyHistoryAvailability);
@@ -13416,7 +13426,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13416
13426
  experimentalSession
13417
13427
  ]);
13418
13428
  const redoActiveEditor = useCallback(() => {
13419
- if (experimentalSession !== "canonical" && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.redo();
13429
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.redo();
13420
13430
  else {
13421
13431
  pagedEditorRef.current?.redo();
13422
13432
  requestAnimationFrame(refreshBodyHistoryAvailability);
@@ -13449,7 +13459,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13449
13459
  documentBuffer: documentBuffer ?? null,
13450
13460
  initialDocument: initialDocument ?? null,
13451
13461
  password,
13452
- ...experimentalSession === void 0 ? {} : { experimentalSession },
13462
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
13453
13463
  history,
13454
13464
  onError,
13455
13465
  onCompatibilityChange,
@@ -13563,7 +13573,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13563
13573
  }
13564
13574
  };
13565
13575
  pushDocument(documentWithComments);
13566
- onChange?.(experimentalSession === "canonical" ? cloneDocumentWithParagraphPropertySources(documentWithComments) : documentWithComments);
13576
+ onChange?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(documentWithComments) : documentWithComments);
13567
13577
  if (showOutlineRef.current) {
13568
13578
  if (collectHeadingsTimerRef.current) clearTimeout(collectHeadingsTimerRef.current);
13569
13579
  collectHeadingsTimerRef.current = setTimeout(() => {
@@ -13591,7 +13601,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13591
13601
  if (!history.state) return null;
13592
13602
  const canonical = pagedEditorRef.current?.getEditor().getCanonicalDocument();
13593
13603
  if (canonical) return canonical;
13594
- if (experimentalSession === "canonical") return null;
13604
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return null;
13595
13605
  let doc_0 = cloneDocumentWithParagraphPropertySources(history.state);
13596
13606
  const pmDoc = pagedEditorRef.current?.getDocument();
13597
13607
  if (pmDoc) {
@@ -13622,8 +13632,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13622
13632
  experimentalSession
13623
13633
  ]);
13624
13634
  const replaceComments = useCallback((nextComments) => {
13625
- if (experimentalSession === "canonical") {
13626
- refuseCanonicalModelEdit("Comment changes are unavailable in this session.");
13635
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
13636
+ refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.");
13627
13637
  return;
13628
13638
  }
13629
13639
  commentsDirtyRef.current = true;
@@ -13889,14 +13899,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13889
13899
  roots: shortcutRoots
13890
13900
  });
13891
13901
  const handleApplyFootnoteProperties = useCallback((footnotePr, endnotePr) => {
13892
- if (experimentalSession === "canonical") {
13902
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
13893
13903
  const api = getCanonicalApi();
13894
13904
  api?.ensureView();
13895
13905
  const canonical_0 = api?.getCanonicalDocument();
13896
13906
  if (!canonical_0 || !api?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_0, {
13897
13907
  footnotePr,
13898
13908
  endnotePr
13899
- })])) refuseCanonicalModelEdit("Section property changes could not be applied.");
13909
+ })])) refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "Section property changes could not be applied.");
13900
13910
  return;
13901
13911
  }
13902
13912
  if (!history.state?.package) return;
@@ -14580,11 +14590,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14580
14590
  ]);
14581
14591
  const handlePageSetupApply = useCallback((props) => {
14582
14592
  if (readOnly) return;
14583
- if (experimentalSession === "canonical") {
14593
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
14584
14594
  const api_0 = getCanonicalApi();
14585
14595
  api_0?.ensureView();
14586
14596
  const canonical_1 = api_0?.getCanonicalDocument();
14587
- if (!canonical_1 || !api_0?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_1, props)])) refuseCanonicalModelEdit("Section property changes could not be applied.");
14597
+ if (!canonical_1 || !api_0?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_1, props)])) refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "Section property changes could not be applied.");
14588
14598
  return;
14589
14599
  }
14590
14600
  if (!history.state || readOnly) return;
@@ -14639,57 +14649,74 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14639
14649
  let tripwireResult = null;
14640
14650
  let savedBuffer = null;
14641
14651
  try {
14642
- const view_18 = pagedEditorRef.current?.getView();
14643
- const editorState = view_18?.state;
14644
- const baselineBuffer = originalBufferRef.current;
14645
- const current = buildCurrentDocument();
14646
- const doc_1 = current ? withoutUnreferencedNotes(current) : null;
14647
- if (!doc_1) return null;
14648
- const { resolveSelectiveSaveFlags } = await import("@stll/folio-core/docx/selectiveSaveFlags");
14649
- const flags = resolveSelectiveSaveFlags(featureFlags);
14650
- const useSelectiveForSave = flags.selectiveSave && options?.mode !== FOLIO_DOCX_SERIALIZATION_MODE.full;
14651
- const shouldAttemptSelective = useSelectiveForSave || flags.selectiveSaveTripwire;
14652
- let selectiveBuffer = null;
14653
- if (shouldAttemptSelective && editorState && baselineBuffer) selectiveBuffer = await (await loadAttemptSelectiveSave())(doc_1, baselineBuffer, {
14654
- changedParaIds: getChangedParagraphIds(editorState),
14655
- structuralChange: hasStructuralChanges(editorState),
14656
- hasUntrackedChanges: hasUntrackedChanges(editorState),
14657
- maxBytes: flags.selectiveSaveMaxBytes
14658
- });
14659
- let buffer = useSelectiveForSave ? selectiveBuffer : null;
14660
- let fullBuffer = null;
14661
- const repackSourceDoc = baselineBuffer ? {
14662
- ...doc_1,
14663
- originalBuffer: baselineBuffer
14664
- } : doc_1;
14665
- const repackFull = async () => {
14666
- const repackDocx = await loadRepackDocx();
14667
- const repack = () => repackDocx(repackSourceDoc);
14668
- if (experimentalSession === "canonical") return repackWithCanonicalStoryRemovals({
14669
- document: repackSourceDoc,
14670
- repack
14652
+ const editor_1 = pagedEditorRef.current?.getEditor();
14653
+ const snapshot = editor_1?.captureCanonicalSave();
14654
+ if (snapshot && editor_1) {
14655
+ const view_18 = editor_1.getView();
14656
+ const editorState = view_18?.state;
14657
+ const result = await serializeCanonicalSave({
14658
+ snapshot,
14659
+ options,
14660
+ featureFlags
14671
14661
  });
14672
- return editorState ? repackWithEditorSectionRemovals({
14673
- state: editorState,
14674
- document: repackSourceDoc,
14675
- repack
14676
- }) : repack();
14677
- };
14678
- if (!buffer) {
14679
- fullBuffer = await repackFull();
14680
- buffer = fullBuffer;
14681
- } else if (flags.selectiveSaveTripwire) try {
14682
- fullBuffer = await repackFull();
14683
- } catch {}
14684
- if (flags.selectiveSaveTripwire && fullBuffer && onSelectiveSaveTripwire) try {
14685
- const { compareSelectiveVsFull } = await import("@stll/folio-core/docx/selectiveSaveTripwire");
14686
- tripwireResult = await compareSelectiveVsFull(selectiveBuffer, fullBuffer);
14687
- } catch {}
14688
- if (view_18 && pagedEditorRef.current?.getView() === view_18 && view_18.state.doc === editorState?.doc) {
14689
- originalBufferRef.current = buffer;
14690
- view_18.dispatch(clearTrackedChanges(view_18.state));
14662
+ for (const diagnostic of result.diagnostics) if (!options?.onDiagnostic) onError?.(new CanonicalSaveDiagnosticError({
14663
+ gap: CANONICAL_GAP.save,
14664
+ diagnostic,
14665
+ message: `Canonical save used a fidelity fallback: ${diagnostic.type} (${diagnostic.part}).`
14666
+ }));
14667
+ tripwireResult = result.tripwireResult;
14668
+ if (view_18 && pagedEditorRef.current?.getEditor() === editor_1 && editor_1.getView() === view_18 && view_18.state.doc === editorState?.doc && editor_1.isCanonicalSaveCurrent(snapshot.version)) view_18.dispatch(clearTrackedChanges(view_18.state));
14669
+ savedBuffer = result.buffer;
14670
+ } else {
14671
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.save)) return null;
14672
+ const view_19 = pagedEditorRef.current?.getView();
14673
+ const editorState_0 = view_19?.state;
14674
+ const baselineBuffer = originalBufferRef.current;
14675
+ const current = buildCurrentDocument();
14676
+ const doc_1 = current ? withoutUnreferencedNotes(current) : null;
14677
+ if (!doc_1) return null;
14678
+ const { resolveSelectiveSaveFlags } = await import("@stll/folio-core/docx/selectiveSaveFlags");
14679
+ const flags = resolveSelectiveSaveFlags(featureFlags);
14680
+ const useSelectiveForSave = flags.selectiveSave && options?.mode !== FOLIO_DOCX_SERIALIZATION_MODE.full;
14681
+ const shouldAttemptSelective = useSelectiveForSave || flags.selectiveSaveTripwire;
14682
+ let selectiveBuffer = null;
14683
+ if (shouldAttemptSelective && editorState_0 && baselineBuffer) selectiveBuffer = await (await loadAttemptSelectiveSave())(doc_1, baselineBuffer, {
14684
+ changedParaIds: getChangedParagraphIds(editorState_0),
14685
+ structuralChange: hasStructuralChanges(editorState_0),
14686
+ hasUntrackedChanges: hasUntrackedChanges(editorState_0),
14687
+ maxBytes: flags.selectiveSaveMaxBytes
14688
+ });
14689
+ let buffer = useSelectiveForSave ? selectiveBuffer : null;
14690
+ let fullBuffer = null;
14691
+ const repackSourceDoc = baselineBuffer ? {
14692
+ ...doc_1,
14693
+ originalBuffer: baselineBuffer
14694
+ } : doc_1;
14695
+ const repackFull = async () => {
14696
+ const repackDocx = await loadRepackDocx();
14697
+ const repack = () => repackDocx(repackSourceDoc);
14698
+ return editorState_0 ? repackWithEditorSectionRemovals({
14699
+ state: editorState_0,
14700
+ document: repackSourceDoc,
14701
+ repack
14702
+ }) : repack();
14703
+ };
14704
+ if (!buffer) {
14705
+ fullBuffer = await repackFull();
14706
+ buffer = fullBuffer;
14707
+ } else if (flags.selectiveSaveTripwire) try {
14708
+ fullBuffer = await repackFull();
14709
+ } catch {}
14710
+ if (flags.selectiveSaveTripwire && fullBuffer && onSelectiveSaveTripwire) try {
14711
+ const { compareSelectiveVsFull } = await import("@stll/folio-core/docx/selectiveSaveTripwire");
14712
+ tripwireResult = await compareSelectiveVsFull(selectiveBuffer, fullBuffer);
14713
+ } catch {}
14714
+ if (view_19 && pagedEditorRef.current?.getView() === view_19 && view_19.state.doc === editorState_0?.doc) {
14715
+ originalBufferRef.current = buffer;
14716
+ view_19.dispatch(clearTrackedChanges(view_19.state));
14717
+ }
14718
+ savedBuffer = buffer;
14691
14719
  }
14692
- savedBuffer = buffer;
14693
14720
  } catch (error_1) {
14694
14721
  onError?.(error_1 instanceof Error ? error_1 : /* @__PURE__ */ new Error("Failed to save document"));
14695
14722
  return null;
@@ -14701,12 +14728,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14701
14728
  onError,
14702
14729
  originalBufferRef,
14703
14730
  featureFlags,
14704
- onSelectiveSaveTripwire
14731
+ onSelectiveSaveTripwire,
14732
+ experimentalSession
14705
14733
  ]);
14706
14734
  const handleSave = useCallback(async (options_0) => {
14707
- const editor_1 = pagedEditorRef.current?.getEditor();
14735
+ const editor_2 = pagedEditorRef.current?.getEditor();
14708
14736
  const serializationOptions = { mode: options_0?.selective === false ? FOLIO_DOCX_SERIALIZATION_MODE.full : FOLIO_DOCX_SERIALIZATION_MODE.preferSelective };
14709
- const buffer_0 = editor_1 ? await editor_1.getDocx(serializationOptions) : await serializeCurrentDocx(serializationOptions);
14737
+ const buffer_0 = editor_2 ? await editor_2.getDocx(serializationOptions) : await serializeCurrentDocx(serializationOptions);
14710
14738
  if (!buffer_0) return null;
14711
14739
  commentsDirtyRef.current = false;
14712
14740
  onSave?.(buffer_0);
@@ -14732,9 +14760,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14732
14760
  useImperativeHandle(ref, () => ({
14733
14761
  getDocument: () => buildCurrentDocument(),
14734
14762
  hasPendingChanges: () => {
14735
- const view_19 = pagedEditorRef.current?.getView();
14736
- if (!view_19) return false;
14737
- return commentsDirtyRef.current || getChangedParagraphIds(view_19.state).size > 0 || hasStructuralChanges(view_19.state) || hasUntrackedChanges(view_19.state);
14763
+ const view_20 = pagedEditorRef.current?.getView();
14764
+ if (!view_20) return false;
14765
+ return commentsDirtyRef.current || getChangedParagraphIds(view_20.state).size > 0 || hasStructuralChanges(view_20.state) || hasUntrackedChanges(view_20.state);
14738
14766
  },
14739
14767
  getEditorRef: () => pagedEditorRef.current,
14740
14768
  getEditor: () => pagedEditorRef.current?.getEditor() ?? null,
@@ -14760,9 +14788,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14760
14788
  },
14761
14789
  loadDocument: (document_0) => {
14762
14790
  pendingSuggestionRegistryRef.current.clear();
14763
- const editor_2 = pagedEditorRef.current?.getEditor();
14764
- if (editor_2) {
14765
- editor_2.loadDocument(document_0);
14791
+ const editor_3 = pagedEditorRef.current?.getEditor();
14792
+ if (editor_3) {
14793
+ editor_3.loadDocument(document_0);
14766
14794
  return;
14767
14795
  }
14768
14796
  loadParsedDocument(document_0);
@@ -14775,13 +14803,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14775
14803
  pagedEditorRef.current?.ensureView(options_2);
14776
14804
  },
14777
14805
  createAIEditSnapshot: () => {
14778
- const view_20 = pagedEditorRef.current?.getView();
14779
- return view_20 ? createFolioAIEditSnapshot(view_20.state.doc) : null;
14806
+ const view_21 = pagedEditorRef.current?.getView();
14807
+ return view_21 ? createFolioAIEditSnapshot(view_21.state.doc) : null;
14780
14808
  },
14781
- applyDocumentOperations: ({ snapshot, batch, author: operationAuthor = author }) => {
14809
+ applyDocumentOperations: ({ snapshot: snapshot_0, batch, author: operationAuthor = author }) => {
14782
14810
  assertSupportedFolioDocumentOperationVersion(batch.version);
14783
- const view_21 = pagedEditorRef.current?.getView();
14784
- if (!view_21) {
14811
+ const view_22 = pagedEditorRef.current?.getView();
14812
+ if (!view_22) {
14785
14813
  let status = "committed";
14786
14814
  if (batch.dryRun === true) status = "previewed";
14787
14815
  else if (batch.atomic === true) status = "rejected";
@@ -14799,21 +14827,27 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14799
14827
  undoHandle: null
14800
14828
  };
14801
14829
  }
14830
+ const canonical_2 = getCanonicalApi()?.applyCanonicalDocumentOperations({
14831
+ snapshot: snapshot_0,
14832
+ batch,
14833
+ author: operationAuthor
14834
+ });
14835
+ if (canonical_2) return canonical_2;
14802
14836
  const existingUndoEntry = documentOperationUndoEntriesRef.current.at(-1);
14803
- if (existingUndoEntry && (!view_21.state.doc.eq(existingUndoEntry.afterState.doc) || commentsRef.current !== existingUndoEntry.commentsAfter)) documentOperationUndoEntriesRef.current.length = 0;
14837
+ if (existingUndoEntry && (!view_22.state.doc.eq(existingUndoEntry.afterState.doc) || commentsRef.current !== existingUndoEntry.commentsAfter)) documentOperationUndoEntriesRef.current.length = 0;
14804
14838
  const commentsBefore = commentsRef.current;
14805
14839
  const createdComments = [];
14806
14840
  const operationView = {
14807
- state: view_21.state,
14841
+ state: view_22.state,
14808
14842
  dispatch: (transaction) => {
14809
- view_21.dispatch(closeHistory(transaction));
14810
- operationView.state = view_21.state;
14843
+ view_22.dispatch(closeHistory(transaction));
14844
+ operationView.state = view_22.state;
14811
14845
  }
14812
14846
  };
14813
- const activeSuggestionIds = new Set(getSuggestions(view_21.state).map((s_0) => s_0.suggestionId));
14814
- const result = applyFolioDocumentOperations({
14847
+ const activeSuggestionIds = new Set(getSuggestions(view_22.state).map((s_0) => s_0.suggestionId));
14848
+ const result_0 = applyFolioDocumentOperations({
14815
14849
  view: operationView,
14816
- snapshot,
14850
+ snapshot: snapshot_0,
14817
14851
  batch,
14818
14852
  author: operationAuthor,
14819
14853
  createCommentId: (text_3) => {
@@ -14826,25 +14860,27 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14826
14860
  id: `react-${String(documentOperationUndoHandleCursor++)}`
14827
14861
  })
14828
14862
  });
14829
- if (batch.mode === "suggested" && result.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
14830
- snapshot,
14863
+ if (batch.mode === "suggested" && result_0.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
14864
+ snapshot: snapshot_0,
14831
14865
  story: { type: "main" },
14832
14866
  operations: batch.operations,
14833
- applied: result.applied,
14867
+ applied: result_0.applied,
14834
14868
  author: operationAuthor,
14835
14869
  activeSuggestionIds
14836
14870
  });
14837
- const batchComments = appliedOperationComments(createdComments, result.applied);
14871
+ const batchComments = appliedOperationComments(createdComments, result_0.applied);
14838
14872
  if (batchComments.length > 0) updateComments((currentComments_0) => [...currentComments_0, ...batchComments]);
14839
- if (result.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
14840
- undoHandle: result.undoHandle,
14841
- afterState: view_21.state,
14873
+ if (result_0.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
14874
+ undoHandle: result_0.undoHandle,
14875
+ afterState: view_22.state,
14842
14876
  commentsBefore,
14843
14877
  commentsAfter: commentsRef.current
14844
14878
  });
14845
- return result;
14879
+ return result_0;
14846
14880
  },
14847
14881
  undoDocumentOperations: (undoHandle) => {
14882
+ const canonical_3 = getCanonicalApi()?.undoCanonicalDocumentOperations(undoHandle);
14883
+ if (canonical_3) return canonical_3;
14848
14884
  const entries = documentOperationUndoEntriesRef.current;
14849
14885
  const entryIndex = entries.findIndex((entry_2) => entry_2.undoHandle.type === undoHandle.type && entry_2.undoHandle.id === undoHandle.id);
14850
14886
  if (entryIndex === -1) return {
@@ -14858,18 +14894,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14858
14894
  reason: "notLatest"
14859
14895
  };
14860
14896
  const entry_3 = entries.at(-1);
14861
- const view_22 = pagedEditorRef.current?.getView();
14862
- if (!entry_3 || !view_22) return {
14897
+ const view_23 = pagedEditorRef.current?.getView();
14898
+ if (!entry_3 || !view_23) return {
14863
14899
  status: "rejected",
14864
14900
  undoHandle,
14865
14901
  reason: "unknownHandle"
14866
14902
  };
14867
- if (!view_22.state.doc.eq(entry_3.afterState.doc) || commentsRef.current !== entry_3.commentsAfter) return {
14903
+ if (!view_23.state.doc.eq(entry_3.afterState.doc) || commentsRef.current !== entry_3.commentsAfter) return {
14868
14904
  status: "rejected",
14869
14905
  undoHandle,
14870
14906
  reason: "documentChanged"
14871
14907
  };
14872
- if (!undo(view_22.state, view_22.dispatch)) return {
14908
+ if (!undo(view_23.state, view_23.dispatch)) return {
14873
14909
  status: "rejected",
14874
14910
  undoHandle,
14875
14911
  reason: "documentChanged"
@@ -14882,20 +14918,30 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14882
14918
  undoHandle
14883
14919
  };
14884
14920
  },
14885
- applyAIEditOperations: ({ snapshot: snapshot_0, operations, mode = "tracked-changes", author: operationAuthor_0 = author }) => {
14886
- const view_23 = pagedEditorRef.current?.getView();
14887
- if (!view_23) return {
14921
+ applyAIEditOperations: ({ snapshot: snapshot_1, operations, mode = "tracked-changes", author: operationAuthor_0 = author }) => {
14922
+ const view_24 = pagedEditorRef.current?.getView();
14923
+ if (!view_24) return {
14888
14924
  applied: [],
14889
14925
  skipped: operations.map((operation_0) => ({
14890
14926
  id: operation_0.id,
14891
14927
  reason: "unsupportedBlock"
14892
14928
  }))
14893
14929
  };
14930
+ const canonical_4 = getCanonicalApi()?.applyCanonicalDocumentOperations({
14931
+ snapshot: snapshot_1,
14932
+ batch: {
14933
+ version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
14934
+ operations,
14935
+ mode
14936
+ },
14937
+ author: operationAuthor_0
14938
+ });
14939
+ if (canonical_4) return canonical_4;
14894
14940
  const createdComments_0 = [];
14895
- const activeSuggestionIds_0 = new Set(getSuggestions(view_23.state).map((s_1) => s_1.suggestionId));
14941
+ const activeSuggestionIds_0 = new Set(getSuggestions(view_24.state).map((s_1) => s_1.suggestionId));
14896
14942
  const { applied: applied_0, skipped: skipped_0 } = applyFolioDocumentOperations({
14897
- view: view_23,
14898
- snapshot: snapshot_0,
14943
+ view: view_24,
14944
+ snapshot: snapshot_1,
14899
14945
  batch: {
14900
14946
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
14901
14947
  operations,
@@ -14911,7 +14957,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14911
14957
  const batchComments_0 = appliedOperationComments(createdComments_0, applied_0);
14912
14958
  if (batchComments_0.length > 0) updateComments((currentComments_1) => [...currentComments_1, ...batchComments_0]);
14913
14959
  if (mode === "suggested") pendingSuggestionRegistryRef.current.recordApplied({
14914
- snapshot: snapshot_0,
14960
+ snapshot: snapshot_1,
14915
14961
  story: { type: "main" },
14916
14962
  operations,
14917
14963
  applied: applied_0,
@@ -14924,71 +14970,71 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14924
14970
  };
14925
14971
  },
14926
14972
  acceptAIEditOperation: (revisionId) => {
14927
- const view_24 = pagedEditorRef.current?.getView();
14928
- if (!view_24) return false;
14929
- const editor_3 = pagedEditorRef.current?.getEditor();
14930
- if (editor_3?.getCanonicalDocument()) return editor_3.resolveCanonicalRevisions(typeof revisionId === "number" ? [revisionId] : revisionId, "accept");
14931
- return acceptAIEditRevision(revisionId)(view_24.state, view_24.dispatch);
14932
- },
14933
- rejectAIEditOperation: (revisionId_0) => {
14934
14973
  const view_25 = pagedEditorRef.current?.getView();
14935
14974
  if (!view_25) return false;
14936
14975
  const editor_4 = pagedEditorRef.current?.getEditor();
14937
- if (editor_4?.getCanonicalDocument()) return editor_4.resolveCanonicalRevisions(typeof revisionId_0 === "number" ? [revisionId_0] : revisionId_0, "reject");
14938
- return rejectAIEditRevision(revisionId_0)(view_25.state, view_25.dispatch);
14976
+ if (editor_4?.getCanonicalDocument()) return editor_4.resolveCanonicalRevisions(typeof revisionId === "number" ? [revisionId] : revisionId, "accept");
14977
+ return acceptAIEditRevision(revisionId)(view_25.state, view_25.dispatch);
14978
+ },
14979
+ rejectAIEditOperation: (revisionId_0) => {
14980
+ const view_26 = pagedEditorRef.current?.getView();
14981
+ if (!view_26) return false;
14982
+ const editor_5 = pagedEditorRef.current?.getEditor();
14983
+ if (editor_5?.getCanonicalDocument()) return editor_5.resolveCanonicalRevisions(typeof revisionId_0 === "number" ? [revisionId_0] : revisionId_0, "reject");
14984
+ return rejectAIEditRevision(revisionId_0)(view_26.state, view_26.dispatch);
14939
14985
  },
14940
14986
  undo: () => {
14941
- if (experimentalSession !== "canonical" && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.undo();
14987
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.undo();
14942
14988
  const undone = pagedEditorRef.current?.undo() ?? false;
14943
14989
  requestAnimationFrame(refreshBodyHistoryAvailability);
14944
14990
  return undone;
14945
14991
  },
14946
14992
  redo: () => {
14947
- if (experimentalSession !== "canonical" && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.redo();
14993
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.redo();
14948
14994
  const redone = pagedEditorRef.current?.redo() ?? false;
14949
14995
  requestAnimationFrame(refreshBodyHistoryAvailability);
14950
14996
  return redone;
14951
14997
  },
14952
14998
  scrollToAIEditOperation: (revisionId_1) => {
14953
- const view_26 = pagedEditorRef.current?.getView();
14954
- if (!view_26) return false;
14955
- const range_2 = findAIEditRevisionRange(view_26.state, revisionId_1);
14999
+ const view_27 = pagedEditorRef.current?.getView();
15000
+ if (!view_27) return false;
15001
+ const range_2 = findAIEditRevisionRange(view_27.state, revisionId_1);
14956
15002
  if (!range_2) return false;
14957
- const { from: from_8, to: to_8 } = clampRangeToDocSize(view_26.state.doc.content.size, range_2);
14958
- const $from = view_26.state.doc.resolve(from_8);
14959
- const $to = view_26.state.doc.resolve(to_8);
14960
- view_26.dispatch(view_26.state.tr.setSelection(TextSelection.between($from, $to)));
15003
+ const { from: from_8, to: to_8 } = clampRangeToDocSize(view_27.state.doc.content.size, range_2);
15004
+ const $from = view_27.state.doc.resolve(from_8);
15005
+ const $to = view_27.state.doc.resolve(to_8);
15006
+ view_27.dispatch(view_27.state.tr.setSelection(TextSelection.between($from, $to)));
14961
15007
  requestAnimationFrame(() => {
14962
15008
  pagedEditorRef.current?.scrollToPosition(from_8);
14963
15009
  });
14964
15010
  return true;
14965
15011
  },
14966
- scrollToBlock: (blockId, snapshot_1) => {
14967
- const view_27 = pagedEditorRef.current?.getView();
14968
- if (!view_27) return false;
15012
+ scrollToBlock: (blockId, snapshot_2) => {
15013
+ const view_28 = pagedEditorRef.current?.getView();
15014
+ if (!view_28) return false;
14969
15015
  const range_3 = resolveFolioAIBlockRange({
14970
15016
  blockId,
14971
- doc: view_27.state.doc,
14972
- snapshot: snapshot_1
15017
+ doc: view_28.state.doc,
15018
+ snapshot: snapshot_2
14973
15019
  });
14974
15020
  if (range_3 === null) return false;
14975
15021
  const { from: from_9, to: to_9 } = range_3;
14976
- const $from_0 = view_27.state.doc.resolve(from_9);
14977
- const $to_0 = view_27.state.doc.resolve(to_9);
14978
- view_27.dispatch(view_27.state.tr.setSelection(TextSelection.between($from_0, $to_0)));
15022
+ const $from_0 = view_28.state.doc.resolve(from_9);
15023
+ const $to_0 = view_28.state.doc.resolve(to_9);
15024
+ view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from_0, $to_0)));
14979
15025
  requestAnimationFrame(() => {
14980
15026
  pagedEditorRef.current?.scrollToPosition(from_9);
14981
15027
  });
14982
15028
  return true;
14983
15029
  },
14984
- highlightPassage: ({ blockId: blockId_0, text: text_5, snapshot: snapshot_2 }) => {
14985
- const view_28 = pagedEditorRef.current?.getView();
14986
- if (!view_28) return "none";
15030
+ highlightPassage: ({ blockId: blockId_0, text: text_5, snapshot: snapshot_3 }) => {
15031
+ const view_29 = pagedEditorRef.current?.getView();
15032
+ if (!view_29) return "none";
14987
15033
  const passageRange = resolvePassageRange({
14988
15034
  blockId: blockId_0,
14989
15035
  text: text_5,
14990
- doc: view_28.state.doc,
14991
- snapshot: snapshot_2
15036
+ doc: view_29.state.doc,
15037
+ snapshot: snapshot_3
14992
15038
  });
14993
15039
  if (passageRange !== null) {
14994
15040
  pagedEditorRef.current?.setPassageHighlight(passageRange);
@@ -15000,16 +15046,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15000
15046
  pagedEditorRef.current?.setPassageHighlight(null);
15001
15047
  const blockRange = resolveFolioAIBlockRange({
15002
15048
  blockId: blockId_0,
15003
- doc: view_28.state.doc,
15004
- snapshot: snapshot_2
15049
+ doc: view_29.state.doc,
15050
+ snapshot: snapshot_3
15005
15051
  });
15006
15052
  if (blockRange === null) return "none";
15007
15053
  const paraId_0 = getFolioParaIdFromBlockId(blockId_0);
15008
15054
  if (paraId_0 !== null && pagedEditorRef.current?.scrollToParaId(paraId_0, { highlight: {} })) return "block";
15009
15055
  const { from: from_10, to: to_10 } = blockRange;
15010
- const $from_1 = view_28.state.doc.resolve(from_10);
15011
- const $to_1 = view_28.state.doc.resolve(to_10);
15012
- view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
15056
+ const $from_1 = view_29.state.doc.resolve(from_10);
15057
+ const $to_1 = view_29.state.doc.resolve(to_10);
15058
+ view_29.dispatch(view_29.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
15013
15059
  requestAnimationFrame(() => {
15014
15060
  pagedEditorRef.current?.scrollToPosition(from_10);
15015
15061
  });
@@ -15018,60 +15064,70 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15018
15064
  clearPassageHighlight: () => {
15019
15065
  pagedEditorRef.current?.setPassageHighlight(null);
15020
15066
  },
15021
- showInDocument: (target_1, snapshot_3) => {
15022
- const view_29 = pagedEditorRef.current?.getView();
15023
- if (!view_29) return false;
15067
+ showInDocument: (target_1, snapshot_4) => {
15068
+ const view_30 = pagedEditorRef.current?.getView();
15069
+ if (!view_30) return false;
15024
15070
  const range_4 = target_1.type === "textRange" ? resolveFolioAITextRange({
15025
15071
  range: target_1,
15026
- doc: view_29.state.doc,
15027
- snapshot: snapshot_3
15072
+ doc: view_30.state.doc,
15073
+ snapshot: snapshot_4
15028
15074
  }) : resolveFolioAIBlockRange({
15029
15075
  blockId: target_1.blockId,
15030
- doc: view_29.state.doc,
15031
- snapshot: snapshot_3
15076
+ doc: view_30.state.doc,
15077
+ snapshot: snapshot_4
15032
15078
  });
15033
15079
  if (range_4 === null) return false;
15034
15080
  const { from: from_11, to: to_11 } = range_4;
15035
- const $from_2 = view_29.state.doc.resolve(from_11);
15036
- const $to_2 = view_29.state.doc.resolve(to_11);
15037
- view_29.dispatch(view_29.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
15081
+ const $from_2 = view_30.state.doc.resolve(from_11);
15082
+ const $to_2 = view_30.state.doc.resolve(to_11);
15083
+ view_30.dispatch(view_30.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
15038
15084
  requestAnimationFrame(() => {
15039
15085
  pagedEditorRef.current?.scrollToPosition(from_11);
15040
15086
  });
15041
15087
  return true;
15042
15088
  },
15043
15089
  getSuggestions: () => {
15044
- const view_30 = pagedEditorRef.current?.getView();
15045
- return view_30 ? getSuggestions(view_30.state) : [];
15090
+ const view_31 = pagedEditorRef.current?.getView();
15091
+ return view_31 ? getSuggestions(view_31.state) : [];
15046
15092
  },
15047
15093
  exportPendingSuggestions: () => {
15048
- const view_31 = pagedEditorRef.current?.getView();
15049
- const activeIds = new Set(view_31 ? getSuggestions(view_31.state).map((s_2) => s_2.suggestionId) : []);
15094
+ const view_32 = pagedEditorRef.current?.getView();
15095
+ const activeIds = new Set(view_32 ? getSuggestions(view_32.state).map((s_2) => s_2.suggestionId) : []);
15050
15096
  return pendingSuggestionRegistryRef.current.exportPendingSuggestions({
15051
15097
  activeSuggestionIds: activeIds,
15052
- snapshotForStory: (story_0, commentIds) => story_0.type === "main" && view_31 ? createPendingSuggestionSourceSnapshot(view_31.state, commentIds) : null
15098
+ snapshotForStory: (story_0, commentIds) => story_0.type === "main" && view_32 ? createPendingSuggestionSourceSnapshot(view_32.state, commentIds) : null
15053
15099
  });
15054
15100
  },
15055
15101
  loadPendingSuggestions: (records) => pendingSuggestionRegistryRef.current.loadPendingSuggestions({
15056
15102
  records,
15057
15103
  snapshotForStory: (story_1) => {
15058
- const view_32 = pagedEditorRef.current?.getView();
15059
- return story_1.type === "main" && view_32 ? createFolioAIEditSnapshot(view_32.state.doc) : null;
15060
- },
15061
- sourceSnapshotForStory: (story_2, commentIds_0) => {
15062
15104
  const view_33 = pagedEditorRef.current?.getView();
15063
- return story_2.type === "main" && view_33 ? createPendingSuggestionSourceSnapshot(view_33.state, commentIds_0) : null;
15105
+ return story_1.type === "main" && view_33 ? createFolioAIEditSnapshot(view_33.state.doc) : null;
15064
15106
  },
15065
- apply: (record, snapshot_4) => {
15107
+ sourceSnapshotForStory: (story_2, commentIds_0) => {
15066
15108
  const view_34 = pagedEditorRef.current?.getView();
15067
- if (!view_34) return {
15109
+ return story_2.type === "main" && view_34 ? createPendingSuggestionSourceSnapshot(view_34.state, commentIds_0) : null;
15110
+ },
15111
+ apply: (record, snapshot_5) => {
15112
+ const view_35 = pagedEditorRef.current?.getView();
15113
+ if (!view_35) return {
15068
15114
  applied: [],
15069
15115
  skipped: []
15070
15116
  };
15117
+ const canonical_5 = getCanonicalApi()?.applyCanonicalDocumentOperations({
15118
+ snapshot: snapshot_5,
15119
+ batch: {
15120
+ version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
15121
+ operations: [record.operation],
15122
+ mode: "suggested"
15123
+ },
15124
+ author: record.author
15125
+ });
15126
+ if (canonical_5) return canonical_5;
15071
15127
  const createdComments_1 = [];
15072
- const result_0 = applyFolioDocumentOperations({
15073
- view: view_34,
15074
- snapshot: snapshot_4,
15128
+ const result_1 = applyFolioDocumentOperations({
15129
+ view: view_35,
15130
+ snapshot: snapshot_5,
15075
15131
  batch: {
15076
15132
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
15077
15133
  operations: [record.operation],
@@ -15084,78 +15140,78 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15084
15140
  return comment_1.id;
15085
15141
  }
15086
15142
  });
15087
- const appliedComments = appliedOperationComments(createdComments_1, result_0.applied);
15143
+ const appliedComments = appliedOperationComments(createdComments_1, result_1.applied);
15088
15144
  if (appliedComments.length > 0) updateComments((currentComments_2) => [...currentComments_2, ...appliedComments]);
15089
15145
  return {
15090
- applied: result_0.applied,
15091
- skipped: result_0.skipped
15146
+ applied: result_1.applied,
15147
+ skipped: result_1.skipped
15092
15148
  };
15093
15149
  },
15094
15150
  activeSuggestionIds: () => {
15095
- const view_35 = pagedEditorRef.current?.getView();
15096
- return new Set(view_35 ? getSuggestions(view_35.state).map((s_3) => s_3.suggestionId) : []);
15151
+ const view_36 = pagedEditorRef.current?.getView();
15152
+ return new Set(view_36 ? getSuggestions(view_36.state).map((s_3) => s_3.suggestionId) : []);
15097
15153
  }
15098
15154
  }),
15099
15155
  acceptSuggestion: (suggestionId, options_3) => {
15100
- const view_36 = pagedEditorRef.current?.getView();
15101
- if (!view_36) return {
15156
+ const view_37 = pagedEditorRef.current?.getView();
15157
+ if (!view_37) return {
15102
15158
  accepted: false,
15103
15159
  appliedAs: null
15104
15160
  };
15105
- const appliedAs = getSuggestions(view_36.state).find((s_4) => s_4.suggestionId === suggestionId)?.appliedAs ?? null;
15106
- const accepted = acceptSuggestion(suggestionId, { author: options_3?.author ?? author })(view_36.state, view_36.dispatch);
15161
+ const appliedAs = getSuggestions(view_37.state).find((s_4) => s_4.suggestionId === suggestionId)?.appliedAs ?? null;
15162
+ const accepted = acceptSuggestion(suggestionId, { author: options_3?.author ?? author })(view_37.state, view_37.dispatch);
15107
15163
  return {
15108
15164
  accepted,
15109
15165
  appliedAs: accepted ? appliedAs : null
15110
15166
  };
15111
15167
  },
15112
15168
  rejectSuggestion: (suggestionId_0) => {
15113
- const view_37 = pagedEditorRef.current?.getView();
15114
- if (!view_37) return false;
15115
- return rejectSuggestion(suggestionId_0)(view_37.state, view_37.dispatch);
15116
- },
15117
- scrollToSuggestion: (suggestionId_1) => {
15118
15169
  const view_38 = pagedEditorRef.current?.getView();
15119
15170
  if (!view_38) return false;
15120
- const range_5 = findSuggestionRange(view_38.state, suggestionId_1);
15171
+ return rejectSuggestion(suggestionId_0)(view_38.state, view_38.dispatch);
15172
+ },
15173
+ scrollToSuggestion: (suggestionId_1) => {
15174
+ const view_39 = pagedEditorRef.current?.getView();
15175
+ if (!view_39) return false;
15176
+ const range_5 = findSuggestionRange(view_39.state, suggestionId_1);
15121
15177
  if (!range_5) return false;
15122
- const { from: from_12, to: to_12 } = clampRangeToDocSize(view_38.state.doc.content.size, range_5);
15123
- const $from_3 = view_38.state.doc.resolve(from_12);
15124
- const $to_3 = view_38.state.doc.resolve(to_12);
15125
- view_38.dispatch(view_38.state.tr.setSelection(TextSelection.between($from_3, $to_3)));
15178
+ const { from: from_12, to: to_12 } = clampRangeToDocSize(view_39.state.doc.content.size, range_5);
15179
+ const $from_3 = view_39.state.doc.resolve(from_12);
15180
+ const $to_3 = view_39.state.doc.resolve(to_12);
15181
+ view_39.dispatch(view_39.state.tr.setSelection(TextSelection.between($from_3, $to_3)));
15126
15182
  requestAnimationFrame(() => {
15127
15183
  pagedEditorRef.current?.scrollToPosition(from_12);
15128
15184
  });
15129
15185
  return true;
15130
15186
  },
15131
15187
  getTrackedChanges: () => {
15132
- const view_39 = pagedEditorRef.current?.getView();
15133
- return view_39 ? getTrackedChangesFromDoc(view_39.state.doc) : [];
15134
- },
15135
- getCommentAnchors: () => {
15136
15188
  const view_40 = pagedEditorRef.current?.getView();
15137
- return view_40 ? getCommentAnchorsFromDoc(view_40.state.doc) : [];
15189
+ return view_40 ? getTrackedChangesFromDoc(view_40.state.doc) : [];
15138
15190
  },
15139
- getSelectionText: () => {
15191
+ getCommentAnchors: () => {
15140
15192
  const view_41 = pagedEditorRef.current?.getView();
15141
- return view_41 ? getSelectedText(view_41.state) : "";
15193
+ return view_41 ? getCommentAnchorsFromDoc(view_41.state.doc) : [];
15142
15194
  },
15143
- getPageText: (page_1) => {
15195
+ getSelectionText: () => {
15144
15196
  const view_42 = pagedEditorRef.current?.getView();
15145
- if (!view_42) return null;
15146
- return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_42.state.doc, page_1);
15197
+ return view_42 ? getSelectedText(view_42.state) : "";
15147
15198
  },
15148
- getTargetPage: (target_2, snapshot_5) => {
15199
+ getPageText: (page_1) => {
15149
15200
  const view_43 = pagedEditorRef.current?.getView();
15150
15201
  if (!view_43) return null;
15202
+ return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_43.state.doc, page_1);
15203
+ },
15204
+ getTargetPage: (target_2, snapshot_6) => {
15205
+ const view_44 = pagedEditorRef.current?.getView();
15206
+ if (!view_44) return null;
15151
15207
  const range_6 = target_2.type === "textRange" ? resolveFolioAITextRange({
15152
15208
  range: target_2,
15153
- doc: view_43.state.doc,
15154
- snapshot: snapshot_5
15209
+ doc: view_44.state.doc,
15210
+ snapshot: snapshot_6
15155
15211
  }) : resolveFolioAIBlockRange({
15156
15212
  blockId: target_2.blockId,
15157
- doc: view_43.state.doc,
15158
- snapshot: snapshot_5
15213
+ doc: view_44.state.doc,
15214
+ snapshot: snapshot_6
15159
15215
  });
15160
15216
  if (range_6 === null) return null;
15161
15217
  return pagedEditorRef.current?.getPageNumberForPmPos(range_6.from) ?? null;
@@ -15165,49 +15221,49 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15165
15221
  getScrollRoot: () => pagedEditorRef.current?.getScrollRoot() ?? null,
15166
15222
  onLayoutChange: (listener) => pagedEditorRef.current?.onLayoutChange(listener) ?? (() => {}),
15167
15223
  getContentControls: (filter = {}) => {
15168
- const view_44 = pagedEditorRef.current?.getView();
15169
- if (!view_44) return [];
15170
- return findBlockSdtMatches(view_44.state.doc, filter).map((match_0) => ({
15224
+ const view_45 = pagedEditorRef.current?.getView();
15225
+ if (!view_45) return [];
15226
+ return findBlockSdtMatches(view_45.state.doc, filter).map((match_0) => ({
15171
15227
  properties: blockSdtAttrsToSdtProperties(match_0.node),
15172
15228
  path: match_0.path,
15173
15229
  pmPos: match_0.pos
15174
15230
  }));
15175
15231
  },
15176
15232
  scrollToContentControl: (filter_0) => {
15177
- const view_45 = pagedEditorRef.current?.getView();
15178
- if (!view_45) return false;
15179
- const match_1 = findBlockSdtMatch(view_45.state.doc, filter_0);
15233
+ const view_46 = pagedEditorRef.current?.getView();
15234
+ if (!view_46) return false;
15235
+ const match_1 = findBlockSdtMatch(view_46.state.doc, filter_0);
15180
15236
  if (!match_1) return false;
15181
15237
  const inside = match_1.pos + 1;
15182
- const $pos = view_45.state.doc.resolve(inside);
15183
- view_45.dispatch(view_45.state.tr.setSelection(TextSelection.near($pos)));
15238
+ const $pos = view_46.state.doc.resolve(inside);
15239
+ view_46.dispatch(view_46.state.tr.setSelection(TextSelection.near($pos)));
15184
15240
  requestAnimationFrame(() => {
15185
15241
  pagedEditorRef.current?.scrollToPosition(inside);
15186
15242
  });
15187
15243
  return true;
15188
15244
  },
15189
15245
  setContentControlContent: (filter_1, input, options_4 = {}) => {
15190
- const view_46 = pagedEditorRef.current?.getView();
15191
- if (!view_46) return false;
15192
- const tr_0 = typeof input === "string" ? setContentControlContentTr(view_46.state, filter_1, input, options_4) : setContentControlContentBlocksTr(view_46.state, filter_1, input, options_4);
15246
+ const view_47 = pagedEditorRef.current?.getView();
15247
+ if (!view_47) return false;
15248
+ const tr_0 = typeof input === "string" ? setContentControlContentTr(view_47.state, filter_1, input, options_4) : setContentControlContentBlocksTr(view_47.state, filter_1, input, options_4);
15193
15249
  if (!tr_0) return false;
15194
- view_46.dispatch(tr_0);
15250
+ view_47.dispatch(tr_0);
15195
15251
  return true;
15196
15252
  },
15197
15253
  setContentControlValue: (filter_2, input_0, options_5 = {}) => {
15198
- const view_47 = pagedEditorRef.current?.getView();
15199
- if (!view_47) return false;
15200
- const tr_1 = setContentControlValueTr(view_47.state, filter_2, input_0, options_5);
15254
+ const view_48 = pagedEditorRef.current?.getView();
15255
+ if (!view_48) return false;
15256
+ const tr_1 = setContentControlValueTr(view_48.state, filter_2, input_0, options_5);
15201
15257
  if (!tr_1) return false;
15202
- view_47.dispatch(tr_1);
15258
+ view_48.dispatch(tr_1);
15203
15259
  return true;
15204
15260
  },
15205
15261
  removeContentControl: (filter_3, options_6 = {}) => {
15206
- const view_48 = pagedEditorRef.current?.getView();
15207
- if (!view_48) return false;
15208
- const tr_2 = removeContentControlTr(view_48.state, filter_3, options_6);
15262
+ const view_49 = pagedEditorRef.current?.getView();
15263
+ if (!view_49) return false;
15264
+ const tr_2 = removeContentControlTr(view_49.state, filter_3, options_6);
15209
15265
  if (!tr_2) return false;
15210
- view_48.dispatch(tr_2);
15266
+ view_49.dispatch(tr_2);
15211
15267
  return true;
15212
15268
  }
15213
15269
  }), [
@@ -15242,7 +15298,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15242
15298
  label: t(DISPLAY_MODE_LABEL_KEYS[mode_0])
15243
15299
  })), [t]);
15244
15300
  const activeHistoryAvailability = (() => {
15245
- if (experimentalSession === "canonical") return {
15301
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return {
15246
15302
  canRedo: pagedEditorRef.current?.canRedo() ?? false,
15247
15303
  canUndo: pagedEditorRef.current?.canUndo() ?? false
15248
15304
  };
@@ -15297,47 +15353,47 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15297
15353
  if (isDisplayMode(value)) setDisplayMode(value);
15298
15354
  }, [setDisplayMode]);
15299
15355
  const handleAcceptActiveChange = useCallback(() => {
15300
- const view_49 = pagedEditorRef.current?.getView();
15301
- if (!view_49) return;
15302
- const { from: from_13, to: to_13 } = view_49.state.selection;
15303
- const range_7 = findChangeAtPosition(view_49.state, from_13, to_13);
15356
+ const view_50 = pagedEditorRef.current?.getView();
15357
+ if (!view_50) return;
15358
+ const { from: from_13, to: to_13 } = view_50.state.selection;
15359
+ const range_7 = findChangeAtPosition(view_50.state, from_13, to_13);
15304
15360
  if (resolveCanonicalReviewRange({
15305
15361
  editor: pagedEditorRef.current?.getEditor(),
15306
15362
  ...range_7,
15307
15363
  resolution: "accept"
15308
- }) === null) acceptChange(range_7.from, range_7.to)(view_49.state, view_49.dispatch);
15364
+ }) === null) acceptChange(range_7.from, range_7.to)(view_50.state, view_50.dispatch);
15309
15365
  }, []);
15310
15366
  const handleRejectActiveChange = useCallback(() => {
15311
- const view_50 = pagedEditorRef.current?.getView();
15312
- if (!view_50) return;
15313
- const { from: from_14, to: to_14 } = view_50.state.selection;
15314
- const range_8 = findChangeAtPosition(view_50.state, from_14, to_14);
15367
+ const view_51 = pagedEditorRef.current?.getView();
15368
+ if (!view_51) return;
15369
+ const { from: from_14, to: to_14 } = view_51.state.selection;
15370
+ const range_8 = findChangeAtPosition(view_51.state, from_14, to_14);
15315
15371
  if (resolveCanonicalReviewRange({
15316
15372
  editor: pagedEditorRef.current?.getEditor(),
15317
15373
  ...range_8,
15318
15374
  resolution: "reject"
15319
- }) === null) rejectChange(range_8.from, range_8.to)(view_50.state, view_50.dispatch);
15375
+ }) === null) rejectChange(range_8.from, range_8.to)(view_51.state, view_51.dispatch);
15320
15376
  }, []);
15321
15377
  const handlePreviousChange = useCallback(() => {
15322
- const view_51 = pagedEditorRef.current?.getView();
15323
- if (!view_51) return;
15324
- const { from: from_15 } = view_51.state.selection;
15325
- const change = findPreviousChange(view_51.state, from_15);
15378
+ const view_52 = pagedEditorRef.current?.getView();
15379
+ if (!view_52) return;
15380
+ const { from: from_15 } = view_52.state.selection;
15381
+ const change = findPreviousChange(view_52.state, from_15);
15326
15382
  if (!change) return;
15327
- view_51.dispatch(view_51.state.tr.setSelection(TextSelection.create(view_51.state.doc, change.from, change.to)));
15328
- view_51.focus();
15383
+ view_52.dispatch(view_52.state.tr.setSelection(TextSelection.create(view_52.state.doc, change.from, change.to)));
15384
+ view_52.focus();
15329
15385
  requestAnimationFrame(() => {
15330
15386
  pagedEditorRef.current?.scrollToPosition(change.from);
15331
15387
  });
15332
15388
  }, []);
15333
15389
  const handleNextChange = useCallback(() => {
15334
- const view_52 = pagedEditorRef.current?.getView();
15335
- if (!view_52) return;
15336
- const { to: to_15 } = view_52.state.selection;
15337
- const change_0 = findNextChange(view_52.state, to_15);
15390
+ const view_53 = pagedEditorRef.current?.getView();
15391
+ if (!view_53) return;
15392
+ const { to: to_15 } = view_53.state.selection;
15393
+ const change_0 = findNextChange(view_53.state, to_15);
15338
15394
  if (!change_0) return;
15339
- view_52.dispatch(view_52.state.tr.setSelection(TextSelection.create(view_52.state.doc, change_0.from, change_0.to)));
15340
- view_52.focus();
15395
+ view_53.dispatch(view_53.state.tr.setSelection(TextSelection.create(view_53.state.doc, change_0.from, change_0.to)));
15396
+ view_53.focus();
15341
15397
  requestAnimationFrame(() => {
15342
15398
  pagedEditorRef.current?.scrollToPosition(change_0.from);
15343
15399
  });
@@ -15507,22 +15563,22 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15507
15563
  requestAnimationFrame(syncCommentHighlightStyles);
15508
15564
  }, [onScrollTopChange, syncCommentHighlightStyles]);
15509
15565
  const handlePagedSelectionChange = useCallback((_from, _to) => {
15510
- const view_53 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
15511
- handleSelectionChange(view_53 ? extractSelectionState(view_53.state) : null);
15566
+ const view_54 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
15567
+ handleSelectionChange(view_54 ? extractSelectionState(view_54.state) : null);
15512
15568
  }, [getActiveEditorView, handleSelectionChange]);
15513
15569
  const handleTotalPagesChange = useCallback((totalPages) => {
15514
15570
  setScrollPageInfo((previous) => updateScrollPageTotal(previous, totalPages));
15515
15571
  }, [setScrollPageInfo]);
15516
15572
  const handleCommentClick = useCallback((id) => setActiveCommentId(id), [setActiveCommentId]);
15517
15573
  const handleCommentResolve = useCallback((id_0) => {
15518
- if (refuseCanonicalModelEdit("Comment changes are unavailable in this session.")) return;
15574
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15519
15575
  updateComments((previous_0) => previous_0.map((comment_2) => comment_2.id === id_0 ? {
15520
15576
  ...comment_2,
15521
15577
  done: true
15522
15578
  } : comment_2));
15523
15579
  }, [refuseCanonicalModelEdit, updateComments]);
15524
15580
  const handleCommentDelete = useCallback((id_1) => {
15525
- if (refuseCanonicalModelEdit("Comment changes are unavailable in this session.")) return;
15581
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15526
15582
  updateComments((previous_1) => previous_1.filter((comment_3) => comment_3.id !== id_1 && comment_3.parentId !== id_1));
15527
15583
  if (activeCommentId === id_1) setActiveCommentId(null);
15528
15584
  }, [
@@ -15532,7 +15588,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15532
15588
  updateComments
15533
15589
  ]);
15534
15590
  const handleCommentReply = useCallback((id_2, text_6) => {
15535
- if (refuseCanonicalModelEdit("Comment changes are unavailable in this session.")) return;
15591
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15536
15592
  updateComments((previous_2) => [...previous_2, createComment(text_6, author, id_2)]);
15537
15593
  }, [
15538
15594
  author,
@@ -15541,11 +15597,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15541
15597
  updateComments
15542
15598
  ]);
15543
15599
  const handleAddComment = useCallback((addText) => {
15544
- if (refuseCanonicalModelEdit("Comment changes are unavailable in this session.")) return false;
15600
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return false;
15545
15601
  const comment_4 = createComment(addText, author);
15546
- const view_54 = pagedEditorRef.current?.getView();
15547
- if (!view_54 || !commentSelectionRange) return false;
15548
- if (!applyCommentMarkRange(view_54, commentSelectionRange, comment_4.id, { replacePending: true })) return false;
15602
+ const view_55 = pagedEditorRef.current?.getView();
15603
+ if (!view_55 || !commentSelectionRange) return false;
15604
+ if (!applyCommentMarkRange(view_55, commentSelectionRange, comment_4.id, { replacePending: true })) return false;
15549
15605
  const commentAuthor_2 = getCommentAuthorKey(comment_4.author);
15550
15606
  setVisibleCommentAuthors((current_0) => {
15551
15607
  if (current_0 === null) return null;
@@ -15578,7 +15634,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15578
15634
  updateComments
15579
15635
  ]);
15580
15636
  const handleTrackedChangeReply = useCallback((revisionId_2, text_7) => {
15581
- if (refuseCanonicalModelEdit("Comment changes are unavailable in this session.")) return;
15637
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15582
15638
  updateComments((previous_4) => [...previous_4, createComment(text_7, author, revisionId_2)]);
15583
15639
  }, [
15584
15640
  author,
@@ -15587,8 +15643,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15587
15643
  updateComments
15588
15644
  ]);
15589
15645
  const handleCancelAddComment = useCallback(() => {
15590
- const view_55 = pagedEditorRef.current?.getView();
15591
- if (view_55 && commentSelectionRange) removePendingCommentMarkRange(view_55, commentSelectionRange);
15646
+ const view_56 = pagedEditorRef.current?.getView();
15647
+ if (view_56 && commentSelectionRange) removePendingCommentMarkRange(view_56, commentSelectionRange);
15592
15648
  setIsAddingComment(false);
15593
15649
  setCommentSelectionRange(null);
15594
15650
  setAddCommentYPosition(null);
@@ -15604,23 +15660,23 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15604
15660
  })?.revisionId ?? null;
15605
15661
  }, []);
15606
15662
  const handleSidebarAcceptChange = useCallback((from_17, to_17) => {
15607
- const view_56 = pagedEditorRef.current?.getView();
15608
- if (!view_56) return;
15663
+ const view_57 = pagedEditorRef.current?.getView();
15664
+ if (!view_57) return;
15609
15665
  const revisionId_3 = resolveSidebarChangeRevisionId(from_17, to_17);
15610
15666
  if (revisionId_3 === null) return;
15611
- const editor_5 = pagedEditorRef.current?.getEditor();
15612
- if (editor_5?.getCanonicalDocument()) editor_5.resolveCanonicalRevisions([revisionId_3], "accept");
15613
- else acceptAIEditRevision(revisionId_3)(view_56.state, view_56.dispatch);
15667
+ const editor_6 = pagedEditorRef.current?.getEditor();
15668
+ if (editor_6?.getCanonicalDocument()) editor_6.resolveCanonicalRevisions([revisionId_3], "accept");
15669
+ else acceptAIEditRevision(revisionId_3)(view_57.state, view_57.dispatch);
15614
15670
  extractTrackedChanges();
15615
15671
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
15616
15672
  const handleSidebarRejectChange = useCallback((from_18, to_18) => {
15617
- const view_57 = pagedEditorRef.current?.getView();
15618
- if (!view_57) return;
15673
+ const view_58 = pagedEditorRef.current?.getView();
15674
+ if (!view_58) return;
15619
15675
  const revisionId_4 = resolveSidebarChangeRevisionId(from_18, to_18);
15620
15676
  if (revisionId_4 === null) return;
15621
- const editor_6 = pagedEditorRef.current?.getEditor();
15622
- if (editor_6?.getCanonicalDocument()) editor_6.resolveCanonicalRevisions([revisionId_4], "reject");
15623
- else rejectAIEditRevision(revisionId_4)(view_57.state, view_57.dispatch);
15677
+ const editor_7 = pagedEditorRef.current?.getEditor();
15678
+ if (editor_7?.getCanonicalDocument()) editor_7.resolveCanonicalRevisions([revisionId_4], "reject");
15679
+ else rejectAIEditRevision(revisionId_4)(view_58.state, view_58.dispatch);
15624
15680
  extractTrackedChanges();
15625
15681
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
15626
15682
  const commentsPageWidth = history.state?.package.document.finalSectionProperties?.pageWidth;
@@ -15763,8 +15819,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15763
15819
  }, [readOnly]);
15764
15820
  const closeTableProperties = useCallback(() => setTablePropsOpen(false), []);
15765
15821
  const applyTableProperties = useCallback((props_0) => {
15766
- const view_58 = getActiveEditorView();
15767
- if (view_58) setTableProperties(props_0)(view_58.state, view_58.dispatch);
15822
+ const view_59 = getActiveEditorView();
15823
+ if (view_59) setTableProperties(props_0)(view_59.state, view_59.dispatch);
15768
15824
  }, [getActiveEditorView]);
15769
15825
  const closeImagePosition = useCallback(() => setImagePositionOpen(false), [setImagePositionOpen]);
15770
15826
  const closeImageProperties = useCallback(() => setImagePropsOpen(false), [setImagePropsOpen]);
@@ -15772,8 +15828,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15772
15828
  const closeFootnoteProperties = useCallback(() => setFootnotePropsOpen(false), []);
15773
15829
  const closeInsertSymbol = useCallback(() => setShowInsertSymbol(false), []);
15774
15830
  const insertSymbol = useCallback((symbol) => {
15775
- const view_59 = getActiveEditorView();
15776
- if (view_59) view_59.dispatch(view_59.state.tr.insertText(symbol).scrollIntoView());
15831
+ const view_60 = getActiveEditorView();
15832
+ if (view_60) view_60.dispatch(view_60.state.tr.insertText(symbol).scrollIntoView());
15777
15833
  }, [getActiveEditorView]);
15778
15834
  const imagePropertiesCurrentData = useMemo(() => buildImagePropertiesData(state.pmImageContext), [state.pmImageContext]);
15779
15835
  const currentFindResult = findResultRef.current;
@@ -15856,8 +15912,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15856
15912
  ]);
15857
15913
  const closeNumberingValueDialog = useCallback(() => setNumberingValueDialogOpen(false), []);
15858
15914
  const applyNumberingValue = useCallback((value_0) => {
15859
- const view_60 = getActiveEditorView();
15860
- if (view_60) setNumberingValue(value_0)(view_60.state, view_60.dispatch);
15915
+ const view_61 = getActiveEditorView();
15916
+ if (view_61) setNumberingValue(value_0)(view_61.state, view_61.dispatch);
15861
15917
  }, [getActiveEditorView]);
15862
15918
  const numberingValueDialog = useMemo(() => ({
15863
15919
  isOpen: numberingValueDialogOpen,
@@ -16119,7 +16175,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16119
16175
  showMarginGuides,
16120
16176
  ...marginGuideColor !== void 0 ? { marginGuideColor } : {},
16121
16177
  readOnly,
16122
- ...experimentalSession === void 0 ? {} : { experimentalSession },
16178
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
16123
16179
  onDocumentChange: handleDocumentChange,
16124
16180
  extensionManager,
16125
16181
  suggestionModeActive: editingMode === "suggesting",
@@ -16156,8 +16212,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16156
16212
  onMouseDown: (e_1) => {
16157
16213
  e_1.preventDefault();
16158
16214
  e_1.stopPropagation();
16159
- const view_61 = pagedEditorRef.current?.getView();
16160
- if (!view_61) {
16215
+ const view_62 = pagedEditorRef.current?.getView();
16216
+ if (!view_62) {
16161
16217
  setFloatingCommentBtn(null);
16162
16218
  return;
16163
16219
  }
@@ -16165,9 +16221,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16165
16221
  from: floatingCommentBtn.from,
16166
16222
  to: floatingCommentBtn.to
16167
16223
  };
16168
- const currentSelection = view_61.state.selection;
16224
+ const currentSelection = view_62.state.selection;
16169
16225
  const safeRange = resolveCommentCreationRange({
16170
- docSize: view_61.state.doc.content.size,
16226
+ docSize: view_62.state.doc.content.size,
16171
16227
  capturedRange,
16172
16228
  currentRange: {
16173
16229
  from: currentSelection.from,
@@ -16181,7 +16237,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
16181
16237
  return;
16182
16238
  }
16183
16239
  setCommentSelectionRange(safeRange);
16184
- if (!applyCommentMarkRange(view_61, safeRange, -1, { selectEnd: true })) {
16240
+ if (!applyCommentMarkRange(view_62, safeRange, -1, { selectEnd: true })) {
16185
16241
  setCommentSelectionRange(null);
16186
16242
  setFloatingCommentBtn(null);
16187
16243
  return;