@stll/folio-react 0.24.2 → 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.
Files changed (44) hide show
  1. package/dist/{CommentsSidebar-Bk5pQ_2C.js → CommentsSidebar-D8sljCtX.js} +1 -1
  2. package/dist/compat/eigenpal.d.ts +1 -1
  3. package/dist/compat/eigenpal.js +1 -1
  4. package/dist/i18n/messages/ar.d.ts +2 -0
  5. package/dist/i18n/messages/ar.js +2 -0
  6. package/dist/i18n/messages/cs.d.ts +2 -0
  7. package/dist/i18n/messages/cs.js +2 -0
  8. package/dist/i18n/messages/de.d.ts +2 -0
  9. package/dist/i18n/messages/de.js +2 -0
  10. package/dist/i18n/messages/en.d.ts +2 -0
  11. package/dist/i18n/messages/en.js +2 -0
  12. package/dist/i18n/messages/es.d.ts +2 -0
  13. package/dist/i18n/messages/es.js +2 -0
  14. package/dist/i18n/messages/et.d.ts +2 -0
  15. package/dist/i18n/messages/et.js +2 -0
  16. package/dist/i18n/messages/fr.d.ts +2 -0
  17. package/dist/i18n/messages/fr.js +2 -0
  18. package/dist/i18n/messages/he.d.ts +2 -0
  19. package/dist/i18n/messages/he.js +2 -0
  20. package/dist/i18n/messages/hi.d.ts +2 -0
  21. package/dist/i18n/messages/hi.js +2 -0
  22. package/dist/i18n/messages/hu.d.ts +2 -0
  23. package/dist/i18n/messages/hu.js +2 -0
  24. package/dist/i18n/messages/locales.d.ts +2 -0
  25. package/dist/i18n/messages/locales.js +2 -0
  26. package/dist/i18n/messages/lt.d.ts +2 -0
  27. package/dist/i18n/messages/lt.js +2 -0
  28. package/dist/i18n/messages/lv.d.ts +2 -0
  29. package/dist/i18n/messages/lv.js +2 -0
  30. package/dist/i18n/messages/pl.d.ts +2 -0
  31. package/dist/i18n/messages/pl.js +2 -0
  32. package/dist/i18n/messages/pt-BR.d.ts +2 -0
  33. package/dist/i18n/messages/pt-BR.js +2 -0
  34. package/dist/i18n/messages/sk.d.ts +2 -0
  35. package/dist/i18n/messages/sk.js +2 -0
  36. package/dist/i18n/messages/tr.d.ts +2 -0
  37. package/dist/i18n/messages/tr.js +2 -0
  38. package/dist/i18n/messages/zh-CN.d.ts +2 -0
  39. package/dist/i18n/messages/zh-CN.js +2 -0
  40. package/dist/index.d.ts +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/{renderAsync-6eWf0MfZ.js → renderAsync-BRxLNRVW.js} +778 -444
  43. package/dist/{renderAsync-BYZY3FVx.d.ts → renderAsync-DMxC2d2H.d.ts} +4 -0
  44. package/package.json +7 -3
@@ -1,12 +1,14 @@
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";
7
8
  import { closeHistory, redo, undo } from "prosemirror-history";
8
9
  import { IntlProvider, useFormatter, useTranslations } from "use-intl";
9
10
  import { FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FolioPendingSuggestionRegistry, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, createFolioAIEditSnapshot, createPendingSuggestionSourceSnapshot, getCommentAnchorsFromDoc, getFolioDocumentOperationIssues, getTrackedChangesFromDoc } from "@stll/folio-core/ai-edits";
11
+ import { resolveCanonicalReviewRange } from "@stll/folio-core/controller/canonicalReview";
10
12
  import { resolveActiveEditorStory } from "@stll/folio-core/controller/activeEditorStory";
11
13
  import { FOLIO_DOCX_SERIALIZATION_MODE, createFolioEditor } from "@stll/folio-core/controller/folioEditor";
12
14
  import { createNoteReferenceFollower, withoutUnreferencedNotes } from "@stll/folio-core/prosemirror/noteReferenceReview";
@@ -23,6 +25,8 @@ import { setContentControlContentBlocksTr } from "@stll/folio-core/prosemirror/c
23
25
  import { CLIPBOARD_READ_ERROR_EVENT, buildPlainTextSlice } from "@stll/folio-core/prosemirror/commands/pastePlainText";
24
26
  import { proseDocToBlocks } from "@stll/folio-core/prosemirror/conversion/fromProseDoc";
25
27
  import { ExtensionManager } from "@stll/folio-core/prosemirror/extensions/ExtensionManager";
28
+ import { executeEditorCommand, executeFirstEditorCommand } from "@stll/folio-core/prosemirror/executeEditorCommand";
29
+ import { insertPageBreak } from "@stll/folio-core/prosemirror/commands/pageBreak";
26
30
  import { clearTrackedChanges, getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges, repackWithEditorSectionRemovals } from "@stll/folio-core/prosemirror/extensions/features/ParagraphChangeTrackerExtension";
27
31
  import { createStarterKit } from "@stll/folio-core/prosemirror/extensions/StarterKit";
28
32
  import { resolveFindMatchRange } from "@stll/folio-core/prosemirror/findReplaceSelection";
@@ -41,8 +45,11 @@ import { onFontsLoaded } from "@stll/folio-core/utils/fontLoader";
41
45
  import { collectHeadings } from "@stll/folio-core/utils/headingCollector";
42
46
  import { formatPx, pixelsToTwips, pointsToHalfPoints, twipsToPixels } from "@stll/folio-core/utils/units";
43
47
  import { HistoryManager, classifyHistoryShortcut } from "@stll/folio-core/managers/HistoryManager";
48
+ import { createCanonicalHeaderFooterOperation, createCanonicalSectionPropertiesOperation, removeCanonicalHeaderFooterOperations } from "@stll/folio-core/controller/canonicalOperations";
49
+ import { CanonicalSaveDiagnosticError, serializeCanonicalSave } from "@stll/folio-core/docx/canonicalSave";
44
50
  import { TableSelectionManager } from "@stll/folio-core/managers/TableSelectionManager";
45
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";
46
53
  import { createPortal } from "react-dom";
47
54
  import { NodeSelection, Selection, TextSelection as TextSelection$1 } from "prosemirror-state";
48
55
  import { CellSelection } from "prosemirror-tables";
@@ -52,6 +59,7 @@ import { createNoteEditorManager } from "@stll/folio-core/controller/noteEditorM
52
59
  import { projectMarkupView, visibleCaretPosition } from "@stll/folio-core/prosemirror/markupViewProjection";
53
60
  import { createFolioAIEditSnapshot as createFolioAIEditSnapshot$1 } from "@stll/folio-core/ai-edits/snapshot";
54
61
  import { createFolioEditorEmitter } from "@stll/folio-core/controller/folioEditorEvents";
62
+ import { CanonicalSessionRefusalError, collectRemoteSelections, createHiddenEditorManager, createHiddenEditorState } from "@stll/folio-core/controller/hiddenEditorManager";
55
63
  import { dispatchEditorTextInput } from "@stll/folio-core/prosemirror/textInput";
56
64
  import { createLatestRequestGate } from "@stll/folio-core/controller/latestRequestGate";
57
65
  import { runLayoutPipeline } from "@stll/folio-core/controller/layoutPipeline";
@@ -59,7 +67,6 @@ import { TRANSACTION_LAYOUT_TIMING, browserClock, createLayoutScheduler } from "
59
67
  import { createLayoutSession } from "@stll/folio-core/controller/layoutSession";
60
68
  import { createHyphenationReadiness } from "@stll/folio-core/controller/hyphenationReadiness";
61
69
  import { readFontSetSignature, waitForInitialLayoutFonts, watchLayoutFontLoads } from "@stll/folio-core/controller/fontReadiness";
62
- import { getFootnoteText } from "@stll/folio-core/docx/footnoteParser";
63
70
  import { convertHeaderFooterPmDocToContent, convertHeaderFooterToContent } from "@stll/folio-core/layout-bridge/convert/headerFooterLayout";
64
71
  import { templatePreviewDirtyRange } from "@stll/folio-core/layout-bridge/convert/templatePreviewFlow";
65
72
  import { clickToPositionDom, getCaretPositionFromDom, getSelectionRectsFromDom } from "@stll/folio-core/layout-bridge/dom/clickToPositionDom";
@@ -91,7 +98,6 @@ import { allowsDirectDrawingEdit } from "@stll/folio-core/docx/imageRawXml";
91
98
  import { commitImageFloatMove, commitImageInlineMove, commitImageResize, isFloatingImage } from "@stll/folio-core/prosemirror/imageCommit";
92
99
  import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts } from "@stll/folio-core/fonts/embeddedFonts";
93
100
  import { panic } from "better-result";
94
- import { collectRemoteSelections, createHiddenEditorManager, createHiddenEditorState } from "@stll/folio-core/controller/hiddenEditorManager";
95
101
  import { loadCollaborationModules } from "@stll/folio-core/controller/collaborationModules";
96
102
  import { createVisualLineState, handleVisualLineKeyDown } from "@stll/folio-core/prosemirror/utils/visualLineNavigation";
97
103
  import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "@stll/folio-core/ai-edits/blockRange";
@@ -339,22 +345,31 @@ const HOST_STYLES = {
339
345
  zIndex: -1,
340
346
  pointerEvents: "none"
341
347
  };
342
- const HiddenHeaderFooterPMs = memo(forwardRef(function HiddenHeaderFooterPMs({ document, styles, theme, onTransaction }, ref) {
348
+ const HiddenHeaderFooterPMs = memo(forwardRef(function HiddenHeaderFooterPMs({ document, styles, theme, onTransaction, experimentalSession, getCanonicalApi, onSessionRefusal }, ref) {
343
349
  const hostRef = useRef(null);
344
350
  const documentRef = useRef(document);
345
351
  const stylesRef = useRef(styles);
346
352
  const themeRef = useRef(theme);
347
353
  const onTransactionRef = useRef(onTransaction);
354
+ const canonicalApiRef = useRef(getCanonicalApi);
355
+ const sessionRef = useRef(experimentalSession);
356
+ const refusalRef = useRef(onSessionRefusal);
348
357
  documentRef.current = document;
349
358
  stylesRef.current = styles;
350
359
  themeRef.current = theme;
351
360
  onTransactionRef.current = onTransaction;
361
+ canonicalApiRef.current = getCanonicalApi;
362
+ sessionRef.current = experimentalSession;
363
+ refusalRef.current = onSessionRefusal;
352
364
  const managerRef = useRef(null);
353
365
  managerRef.current ??= createHeaderFooterEditorManager({
354
366
  getHost: () => hostRef.current,
355
367
  getDocument: () => documentRef.current,
356
368
  getStyles: () => stylesRef.current,
357
369
  getTheme: () => themeRef.current,
370
+ getCanonicalApi: () => canonicalApiRef.current?.() ?? null,
371
+ getExperimentalSession: () => sessionRef.current,
372
+ onSessionRefusal: (reason, gap) => refusalRef.current?.(reason, gap),
358
373
  onTransaction: ({ rId, kind, view, docChanged, selectionChanged }) => {
359
374
  onTransactionRef.current?.(rId, kind, view, docChanged, selectionChanged);
360
375
  }
@@ -420,13 +435,16 @@ const hostStyle = {
420
435
  };
421
436
  const EMPTY_PLUGINS$1 = [];
422
437
  const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
423
- const $ = c(51);
424
- const { document, onActiveChange, onDocumentChange, onStoryChange, plugins, styles, suggestionAuthor, suggestionModeActive, theme } = t0;
438
+ const $ = c(57);
439
+ const { document, experimentalSession, getCanonicalApi, onSessionRefusal, onActiveChange, onDocumentChange, onStoryChange, plugins, styles, suggestionAuthor, suggestionModeActive, theme } = t0;
425
440
  const t = useTranslations("folio");
426
441
  const resolvedPlugins = plugins ?? EMPTY_PLUGINS$1;
427
442
  const isSuggestionModeActive = suggestionModeActive ?? false;
428
443
  const hostRef = useRef(null);
429
444
  const documentRef = useRef(document);
445
+ const canonicalApiRef = useRef(getCanonicalApi);
446
+ const sessionRef = useRef(experimentalSession);
447
+ const refusalRef = useRef(onSessionRefusal);
430
448
  const stylesRef = useRef(styles);
431
449
  const themeRef = useRef(theme);
432
450
  const pluginsRef = useRef(resolvedPlugins);
@@ -438,9 +456,12 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
438
456
  const footnotes = document?.package.footnotes;
439
457
  const endnotes = document?.package.endnotes;
440
458
  let t1;
441
- if ($[0] !== active || $[1] !== document || $[2] !== onActiveChange || $[3] !== onDocumentChange || $[4] !== onStoryChange || $[5] !== resolvedPlugins || $[6] !== styles || $[7] !== theme) {
459
+ if ($[0] !== active || $[1] !== document || $[2] !== experimentalSession || $[3] !== getCanonicalApi || $[4] !== onActiveChange || $[5] !== onDocumentChange || $[6] !== onSessionRefusal || $[7] !== onStoryChange || $[8] !== resolvedPlugins || $[9] !== styles || $[10] !== theme) {
442
460
  t1 = () => {
443
461
  documentRef.current = document;
462
+ canonicalApiRef.current = getCanonicalApi;
463
+ sessionRef.current = experimentalSession;
464
+ refusalRef.current = onSessionRefusal;
444
465
  stylesRef.current = styles;
445
466
  themeRef.current = theme;
446
467
  pluginsRef.current = resolvedPlugins;
@@ -453,9 +474,15 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
453
474
  getPlugins: () => pluginsRef.current,
454
475
  getStyles: () => stylesRef.current,
455
476
  getTheme: () => themeRef.current,
477
+ getCanonicalApi: () => canonicalApiRef.current?.() ?? null,
478
+ getExperimentalSession: () => sessionRef.current,
479
+ onSessionRefusal: (reason, gap) => refusalRef.current?.(reason, gap),
456
480
  onTransaction: (t2) => {
457
481
  const { docChanged, selectionChanged, view } = t2;
458
- if (docChanged) {
482
+ if (docChanged) if (usesCanonicalSession(sessionRef.current, CANONICAL_GAP.secondaryStories)) {
483
+ const canonical = canonicalApiRef.current?.()?.getCanonicalDocument();
484
+ if (canonical) onDocumentChangeRef.current(canonical);
485
+ } else {
459
486
  const current = documentRef.current;
460
487
  if (current) onDocumentChangeRef.current(managerRef.current?.snapshotDocument(current) ?? current);
461
488
  }
@@ -471,44 +498,53 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
471
498
  };
472
499
  $[0] = active;
473
500
  $[1] = document;
474
- $[2] = onActiveChange;
475
- $[3] = onDocumentChange;
476
- $[4] = onStoryChange;
477
- $[5] = resolvedPlugins;
478
- $[6] = styles;
479
- $[7] = theme;
480
- $[8] = t1;
481
- } else t1 = $[8];
501
+ $[2] = experimentalSession;
502
+ $[3] = getCanonicalApi;
503
+ $[4] = onActiveChange;
504
+ $[5] = onDocumentChange;
505
+ $[6] = onSessionRefusal;
506
+ $[7] = onStoryChange;
507
+ $[8] = resolvedPlugins;
508
+ $[9] = styles;
509
+ $[10] = theme;
510
+ $[11] = t1;
511
+ } else t1 = $[11];
482
512
  let t2;
483
- if ($[9] !== active || $[10] !== document || $[11] !== endnotes || $[12] !== footnotes || $[13] !== onActiveChange || $[14] !== onDocumentChange || $[15] !== onStoryChange || $[16] !== resolvedPlugins || $[17] !== styles || $[18] !== theme) {
513
+ if ($[12] !== active || $[13] !== document || $[14] !== endnotes || $[15] !== experimentalSession || $[16] !== footnotes || $[17] !== getCanonicalApi || $[18] !== onActiveChange || $[19] !== onDocumentChange || $[20] !== onSessionRefusal || $[21] !== onStoryChange || $[22] !== resolvedPlugins || $[23] !== styles || $[24] !== theme) {
484
514
  t2 = [
485
515
  active,
486
516
  document,
487
517
  endnotes,
518
+ experimentalSession,
488
519
  footnotes,
520
+ getCanonicalApi,
489
521
  onActiveChange,
490
522
  onDocumentChange,
523
+ onSessionRefusal,
491
524
  onStoryChange,
492
525
  resolvedPlugins,
493
526
  styles,
494
527
  theme
495
528
  ];
496
- $[9] = active;
497
- $[10] = document;
498
- $[11] = endnotes;
499
- $[12] = footnotes;
500
- $[13] = onActiveChange;
501
- $[14] = onDocumentChange;
502
- $[15] = onStoryChange;
503
- $[16] = resolvedPlugins;
504
- $[17] = styles;
505
- $[18] = theme;
506
- $[19] = t2;
507
- } else t2 = $[19];
529
+ $[12] = active;
530
+ $[13] = document;
531
+ $[14] = endnotes;
532
+ $[15] = experimentalSession;
533
+ $[16] = footnotes;
534
+ $[17] = getCanonicalApi;
535
+ $[18] = onActiveChange;
536
+ $[19] = onDocumentChange;
537
+ $[20] = onSessionRefusal;
538
+ $[21] = onStoryChange;
539
+ $[22] = resolvedPlugins;
540
+ $[23] = styles;
541
+ $[24] = theme;
542
+ $[25] = t2;
543
+ } else t2 = $[25];
508
544
  useEffect(t1, t2);
509
545
  let t3;
510
546
  let t4;
511
- if ($[20] !== isSuggestionModeActive || $[21] !== suggestionAuthor) {
547
+ if ($[26] !== isSuggestionModeActive || $[27] !== suggestionAuthor) {
512
548
  t3 = () => {
513
549
  const manager_0 = managerRef.current;
514
550
  if (!manager_0) return;
@@ -518,41 +554,41 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
518
554
  }
519
555
  };
520
556
  t4 = [isSuggestionModeActive, suggestionAuthor];
521
- $[20] = isSuggestionModeActive;
522
- $[21] = suggestionAuthor;
523
- $[22] = t3;
524
- $[23] = t4;
557
+ $[26] = isSuggestionModeActive;
558
+ $[27] = suggestionAuthor;
559
+ $[28] = t3;
560
+ $[29] = t4;
525
561
  } else {
526
- t3 = $[22];
527
- t4 = $[23];
562
+ t3 = $[28];
563
+ t4 = $[29];
528
564
  }
529
565
  useEffect(t3, t4);
530
566
  let t5;
531
567
  let t6;
532
- if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
568
+ if ($[30] === Symbol.for("react.memo_cache_sentinel")) {
533
569
  t5 = () => () => {
534
570
  managerRef.current?.destroy();
535
571
  };
536
572
  t6 = [];
537
- $[24] = t5;
538
- $[25] = t6;
573
+ $[30] = t5;
574
+ $[31] = t6;
539
575
  } else {
540
- t5 = $[24];
541
- t6 = $[25];
576
+ t5 = $[30];
577
+ t6 = $[31];
542
578
  }
543
579
  useEffect(t5, t6);
544
580
  let t7;
545
- if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
581
+ if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
546
582
  t7 = () => {
547
583
  managerRef.current?.activate(null);
548
584
  setActive(null);
549
585
  onActiveChangeRef.current(null);
550
586
  };
551
- $[26] = t7;
552
- } else t7 = $[26];
587
+ $[32] = t7;
588
+ } else t7 = $[32];
553
589
  const closeEditor = t7;
554
590
  let t8;
555
- if ($[27] !== isSuggestionModeActive || $[28] !== suggestionAuthor) {
591
+ if ($[33] !== isSuggestionModeActive || $[34] !== suggestionAuthor) {
556
592
  t8 = () => ({
557
593
  close: closeEditor,
558
594
  getActiveView: () => {
@@ -569,63 +605,63 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
569
605
  },
570
606
  snapshotDocument: (current_0) => managerRef.current?.snapshotDocument(current_0) ?? current_0
571
607
  });
572
- $[27] = isSuggestionModeActive;
573
- $[28] = suggestionAuthor;
574
- $[29] = t8;
575
- } else t8 = $[29];
608
+ $[33] = isSuggestionModeActive;
609
+ $[34] = suggestionAuthor;
610
+ $[35] = t8;
611
+ } else t8 = $[35];
576
612
  useImperativeHandle(ref, t8);
577
613
  let t9;
578
- if ($[30] !== active || $[31] !== t) {
614
+ if ($[36] !== active || $[37] !== t) {
579
615
  t9 = active ? t(active.kind === "footnote" ? "dialogs.footnoteProperties.footnotes" : "dialogs.footnoteProperties.endnotes") : "";
580
- $[30] = active;
581
- $[31] = t;
582
- $[32] = t9;
583
- } else t9 = $[32];
616
+ $[36] = active;
617
+ $[37] = t;
618
+ $[38] = t9;
619
+ } else t9 = $[38];
584
620
  const title = t9;
585
621
  const t10 = active ? "block" : "none";
586
622
  let t11;
587
- if ($[33] !== t10) {
623
+ if ($[39] !== t10) {
588
624
  t11 = {
589
625
  ...panelStyle,
590
626
  display: t10
591
627
  };
592
- $[33] = t10;
593
- $[34] = t11;
594
- } else t11 = $[34];
628
+ $[39] = t10;
629
+ $[40] = t11;
630
+ } else t11 = $[40];
595
631
  let t12;
596
- if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
632
+ if ($[41] === Symbol.for("react.memo_cache_sentinel")) {
597
633
  t12 = (event) => {
598
634
  if (event.key !== "Escape") return;
599
635
  event.preventDefault();
600
636
  event.stopPropagation();
601
637
  closeEditor();
602
638
  };
603
- $[35] = t12;
604
- } else t12 = $[35];
639
+ $[41] = t12;
640
+ } else t12 = $[41];
605
641
  let t13;
606
- if ($[36] !== title) {
642
+ if ($[42] !== title) {
607
643
  t13 = /* @__PURE__ */ jsx("span", { children: title });
608
- $[36] = title;
609
- $[37] = t13;
610
- } else t13 = $[37];
644
+ $[42] = title;
645
+ $[43] = t13;
646
+ } else t13 = $[43];
611
647
  let t14;
612
- if ($[38] !== t) {
648
+ if ($[44] !== t) {
613
649
  t14 = t("common.closeDialog");
614
- $[38] = t;
615
- $[39] = t14;
616
- } else t14 = $[39];
650
+ $[44] = t;
651
+ $[45] = t14;
652
+ } else t14 = $[45];
617
653
  let t15;
618
- if ($[40] === Symbol.for("react.memo_cache_sentinel")) {
654
+ if ($[46] === Symbol.for("react.memo_cache_sentinel")) {
619
655
  t15 = {
620
656
  border: 0,
621
657
  background: "transparent",
622
658
  color: "inherit",
623
659
  cursor: "pointer"
624
660
  };
625
- $[40] = t15;
626
- } else t15 = $[40];
661
+ $[46] = t15;
662
+ } else t15 = $[46];
627
663
  let t16;
628
- if ($[41] !== t14) {
664
+ if ($[47] !== t14) {
629
665
  t16 = /* @__PURE__ */ jsx("button", {
630
666
  type: "button",
631
667
  "aria-label": t14,
@@ -633,40 +669,40 @@ const NoteStoryEditor = forwardRef(function NoteStoryEditor(t0, ref) {
633
669
  style: t15,
634
670
  children: "×"
635
671
  });
636
- $[41] = t14;
637
- $[42] = t16;
638
- } else t16 = $[42];
672
+ $[47] = t14;
673
+ $[48] = t16;
674
+ } else t16 = $[48];
639
675
  let t17;
640
- if ($[43] !== t13 || $[44] !== t16) {
676
+ if ($[49] !== t13 || $[50] !== t16) {
641
677
  t17 = /* @__PURE__ */ jsxs("div", {
642
678
  style: headerStyle,
643
679
  children: [t13, t16]
644
680
  });
645
- $[43] = t13;
646
- $[44] = t16;
647
- $[45] = t17;
648
- } else t17 = $[45];
681
+ $[49] = t13;
682
+ $[50] = t16;
683
+ $[51] = t17;
684
+ } else t17 = $[51];
649
685
  let t18;
650
- if ($[46] === Symbol.for("react.memo_cache_sentinel")) {
686
+ if ($[52] === Symbol.for("react.memo_cache_sentinel")) {
651
687
  t18 = /* @__PURE__ */ jsx("div", {
652
688
  ref: hostRef,
653
689
  style: hostStyle
654
690
  });
655
- $[46] = t18;
656
- } else t18 = $[46];
691
+ $[52] = t18;
692
+ } else t18 = $[52];
657
693
  let t19;
658
- if ($[47] !== t11 || $[48] !== t17 || $[49] !== title) {
694
+ if ($[53] !== t11 || $[54] !== t17 || $[55] !== title) {
659
695
  t19 = /* @__PURE__ */ jsxs("aside", {
660
696
  style: t11,
661
697
  "aria-label": title,
662
698
  onKeyDown: t12,
663
699
  children: [t17, t18]
664
700
  });
665
- $[47] = t11;
666
- $[48] = t17;
667
- $[49] = title;
668
- $[50] = t19;
669
- } else t19 = $[50];
701
+ $[53] = t11;
702
+ $[54] = t17;
703
+ $[55] = title;
704
+ $[56] = t19;
705
+ } else t19 = $[56];
670
706
  return t19;
671
707
  });
672
708
  NoteStoryEditor.displayName = "NoteStoryEditor";
@@ -1218,12 +1254,16 @@ const HIDDEN_HOST_STYLES = {
1218
1254
  * HiddenProseMirror - Off-screen ProseMirror editor for keyboard input
1219
1255
  */
1220
1256
  const HiddenProseMirror = forwardRef((props, ref) => {
1221
- const { document, documentIdentity, styles, theme: _theme, widthPx = 612, readOnly = false, onTransaction, onSelectionChange, externalPlugins = EMPTY_EXTERNAL_PLUGINS, collaboration, extensionManager, onEditorViewReady, onEditorViewDestroy, onKeyDown, onCopy, onCut, onPaste, onReadOnlyEditAttempt, onRemoteSelectionsChange, precomputedInitialState } = props;
1257
+ const { document, documentIdentity, experimentalSession, suggestionModeActive = false, suggestionAuthor = "User", onSessionRefusal, styles, theme: _theme, widthPx = 612, readOnly = false, onTransaction, onSelectionChange, externalPlugins = EMPTY_EXTERNAL_PLUGINS, collaboration, extensionManager, onEditorViewReady, onEditorViewDestroy, onKeyDown, onCopy, onCut, onPaste, onReadOnlyEditAttempt, onRemoteSelectionsChange, precomputedInitialState } = props;
1222
1258
  const [collaborationModules, setCollaborationModules] = useState(null);
1223
1259
  const [collaborationModulesError, setCollaborationModulesError] = useState(null);
1224
1260
  const hasCollaboration = collaboration !== void 0;
1225
1261
  const hostRef = useRef(null);
1226
1262
  const readOnlyRef = useRef(readOnly);
1263
+ const experimentalSessionRef = useRef(experimentalSession);
1264
+ const suggestionModeActiveRef = useRef(suggestionModeActive);
1265
+ const suggestionAuthorRef = useRef(suggestionAuthor);
1266
+ const onSessionRefusalRef = useRef(onSessionRefusal);
1227
1267
  const documentRef = useRef(document);
1228
1268
  const documentIdentityRef = useRef(documentIdentity);
1229
1269
  const stylesRef = useRef(styles);
@@ -1243,6 +1283,10 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1243
1283
  const onReadOnlyEditAttemptRef = useRef(onReadOnlyEditAttempt);
1244
1284
  const onRemoteSelectionsChangeRef = useRef(onRemoteSelectionsChange);
1245
1285
  readOnlyRef.current = readOnly;
1286
+ experimentalSessionRef.current = experimentalSession;
1287
+ suggestionModeActiveRef.current = suggestionModeActive;
1288
+ suggestionAuthorRef.current = suggestionAuthor;
1289
+ onSessionRefusalRef.current = onSessionRefusal;
1246
1290
  stylesRef.current = styles;
1247
1291
  extensionManagerRef.current = extensionManager;
1248
1292
  externalPluginsRef.current = externalPlugins;
@@ -1272,6 +1316,10 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1272
1316
  getCollaborationModules: () => collaborationModulesRef.current,
1273
1317
  getPrecomputedInitialState: () => precomputedInitialStateRef.current,
1274
1318
  getReadOnly: () => readOnlyRef.current,
1319
+ getExperimentalSession: () => experimentalSessionRef.current,
1320
+ getEditingMode: () => suggestionModeActiveRef.current ? "suggesting" : "editing",
1321
+ getSuggestionAuthor: () => suggestionAuthorRef.current,
1322
+ onSessionRefusal: (reason, gap) => onSessionRefusalRef.current?.(reason, gap),
1275
1323
  getDocumentIdentity: () => documentIdentityRef.current,
1276
1324
  getDocumentContext: () => documentRef.current,
1277
1325
  onTransaction: (update) => onTransactionRef.current?.(update),
@@ -1331,13 +1379,19 @@ const HiddenProseMirror = forwardRef((props, ref) => {
1331
1379
  }, []);
1332
1380
  useLayoutEffect(() => {
1333
1381
  managerRef.current?.retryViewCreation();
1334
- }, [collaboration, collaborationModules]);
1382
+ }, [
1383
+ collaboration,
1384
+ collaborationModules,
1385
+ experimentalSession
1386
+ ]);
1335
1387
  useEffect(() => () => destroyView(), [destroyView]);
1336
1388
  useEffect(() => {
1337
1389
  managerRef.current?.syncExternalDocument();
1338
1390
  }, [
1339
1391
  document,
1340
1392
  documentIdentity,
1393
+ experimentalSession,
1394
+ suggestionModeActive,
1341
1395
  styles,
1342
1396
  extensionManager,
1343
1397
  externalPlugins,
@@ -2819,7 +2873,7 @@ function buildFootnoteRenderItems(pageFootnoteMap, footnoteContentMap, doc) {
2819
2873
  * PagedEditor - Main paginated editing component.
2820
2874
  */
2821
2875
  const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2822
- const { document, documentIO, documentIdentity, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, pageRenderer, markupView, showMarginGuides = false, marginGuideColor, onDocumentChange, onReadOnlyEditAttempt, onCopy, onCut, onPaste, onSelectionChange, onSelectionTextChange, onEditorViewReady, externalPlugins = EMPTY_PLUGINS, showTemplateDirectives = true, collaboration, extensionManager, suggestionModeActive = false, suggestionAuthor, onActiveNoteStoryChange, onHeaderFooterDoubleClick, hfEditMode, activeHeaderFooterRId, onBodyClick, className, style, pageEndGutter = 0, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, onError, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
2876
+ const { document, documentIO, documentIdentity, experimentalSession, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, pageRenderer, markupView, showMarginGuides = false, marginGuideColor, onDocumentChange, onReadOnlyEditAttempt, onCopy, onCut, onPaste, onSelectionChange, onSelectionTextChange, onEditorViewReady, externalPlugins = EMPTY_PLUGINS, showTemplateDirectives = true, collaboration, extensionManager, suggestionModeActive = false, suggestionAuthor, onActiveNoteStoryChange, onHeaderFooterDoubleClick, hfEditMode, activeHeaderFooterRId, onBodyClick, className, style, pageEndGutter = 0, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, onError, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
2823
2877
  const getScrollContainer = useCallback(() => {
2824
2878
  if (scrollContainerRefProp && typeof scrollContainerRefProp === "object") return getEditorScrollRoot(scrollContainerRefProp.current);
2825
2879
  return getEditorScrollRoot(containerRef.current);
@@ -2837,16 +2891,19 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2837
2891
  const hiddenPMRef = useRef(null);
2838
2892
  const hfPMsRef = useRef(null);
2839
2893
  const noteEditorRef = useRef(null);
2894
+ const activeNoteStoryRef = useRef(null);
2840
2895
  const [noteStoryActive, setNoteStoryActive] = useState(false);
2841
2896
  const painterRef = useRef(null);
2842
2897
  const noteStoryPlugins = useMemo(() => externalPlugins.filter(({ spec }) => spec.key === suggestionModeKey), [externalPlugins]);
2843
2898
  const handleActiveNoteStoryChange = useCallback((story) => {
2899
+ activeNoteStoryRef.current = story;
2844
2900
  setNoteStoryActive(story !== null);
2845
2901
  onActiveNoteStoryChange?.(story);
2846
2902
  }, [onActiveNoteStoryChange]);
2847
2903
  useEffect(() => {
2848
- if (readOnly) noteEditorRef.current?.close();
2849
- }, [readOnly]);
2904
+ if (readOnly || usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) noteEditorRef.current?.close();
2905
+ }, [experimentalSession, readOnly]);
2906
+ const getCanonicalApi = useCallback(() => hiddenPMRef.current, []);
2850
2907
  const { handlePMKeyDown } = useVisualLineNavigation({ pagesContainerRef });
2851
2908
  const handleHiddenEditorKeyDown = useCallback((view, event) => {
2852
2909
  if (getTemplateSlashMenu(view.state).active) return false;
@@ -2866,6 +2923,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2866
2923
  onDocumentChangeRef.current = onDocumentChange;
2867
2924
  onTotalPagesChangeRef.current = onTotalPagesChange;
2868
2925
  onErrorRef.current = onError;
2926
+ const handleSessionRefusal = useCallback((message, gap) => {
2927
+ onErrorRef.current?.(new CanonicalSessionRefusalError({
2928
+ gap,
2929
+ message
2930
+ }));
2931
+ }, []);
2869
2932
  const [layout, setLayout] = useState(null);
2870
2933
  const layoutRef = useRef(layout);
2871
2934
  layoutRef.current = layout;
@@ -2987,12 +3050,18 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2987
3050
  queuedInputBeforeHiddenEditorRef.current = [];
2988
3051
  for (const input of queuedInput) {
2989
3052
  if (input.type === "text") {
2990
- dispatchEditorTextInput(view_0, input.text);
3053
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) view_0.dom.dispatchEvent(new InputEvent("beforeinput", {
3054
+ inputType: "insertText",
3055
+ data: input.text,
3056
+ cancelable: true,
3057
+ bubbles: true
3058
+ }));
3059
+ else dispatchEditorTextInput(view_0, input.text);
2991
3060
  continue;
2992
3061
  }
2993
3062
  replayDeferredKeyDown(view_0, input.eventInit);
2994
3063
  }
2995
- }, []);
3064
+ }, [experimentalSession]);
2996
3065
  useEffect(() => {
2997
3066
  if (collaboration !== void 0) ensureHiddenEditorView();
2998
3067
  }, [collaboration, ensureHiddenEditorView]);
@@ -3211,6 +3280,18 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3211
3280
  folioEditor,
3212
3281
  hfEditMode
3213
3282
  ]);
3283
+ const getCanonicalActiveStory = useCallback(() => {
3284
+ const note = activeNoteStoryRef.current;
3285
+ if (note) return {
3286
+ kind: note.kind,
3287
+ id: note.noteId
3288
+ };
3289
+ if (hfEditMode && activeHeaderFooterRId) return {
3290
+ kind: hfEditMode,
3291
+ rId: activeHeaderFooterRId
3292
+ };
3293
+ return "main";
3294
+ }, [hfEditMode, activeHeaderFooterRId]);
3214
3295
  const paintSettingsInitializedRef = useRef(false);
3215
3296
  useEffect(() => {
3216
3297
  if (!paintSettingsInitializedRef.current) {
@@ -3243,12 +3324,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3243
3324
  }
3244
3325
  let newDoc = hiddenPMRef.current?.getDocument();
3245
3326
  const body = hiddenPMRef.current?.getState()?.doc;
3246
- if (newDoc && body) newDoc = noteFollower.reconcile(newDoc, body);
3327
+ if (newDoc && body && !usesCanonicalSession(experimentalSession, CANONICAL_GAP.save)) newDoc = noteFollower.reconcile(newDoc, body);
3247
3328
  if (newDoc) {
3248
- onDocumentChangeRef.current?.(newDoc);
3249
- folioEmitterRef.current.emit("docChange", 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);
3250
3331
  }
3251
- }, [noteFollower]);
3332
+ }, [experimentalSession, noteFollower]);
3252
3333
  const scheduleDocumentChangeNotification = useCallback(() => {
3253
3334
  if (documentChangeNotifyTimerRef.current !== null) window.clearTimeout(documentChangeNotifyTimerRef.current);
3254
3335
  documentChangeNotifyTimerRef.current = window.setTimeout(() => {
@@ -3853,6 +3934,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3853
3934
  if (docChanged_0) {
3854
3935
  if (!hiddenPMRef.current?.getState() && !precomputedInitialStateRef.current) ensureHiddenEditorView({ sync: true });
3855
3936
  scheduleLayout();
3937
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) scheduleDocumentChangeNotification();
3856
3938
  }
3857
3939
  if (docChanged_0 || selectionChanged) {
3858
3940
  const { from: from_1, to: to_1 } = view_3.state.selection;
@@ -3870,7 +3952,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3870
3952
  to: to_1
3871
3953
  });
3872
3954
  }
3873
- }, [scheduleLayout, ensureHiddenEditorView]);
3955
+ }, [
3956
+ scheduleLayout,
3957
+ ensureHiddenEditorView,
3958
+ experimentalSession,
3959
+ scheduleDocumentChangeNotification
3960
+ ]);
3874
3961
  const handleNoteStoryTransaction = useCallback((view_4, docChanged_1, selectionChanged_0) => {
3875
3962
  if (docChanged_1) scheduleLayout();
3876
3963
  if (docChanged_1 || selectionChanged_0) {
@@ -3883,9 +3970,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3883
3970
  }
3884
3971
  }, [scheduleLayout]);
3885
3972
  const handleNoteDocumentChange = useCallback((updated) => {
3886
- onDocumentChangeRef.current?.(updated);
3887
- folioEmitterRef.current.emit("docChange", updated);
3888
- }, []);
3973
+ onDocumentChangeRef.current?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(updated) : updated);
3974
+ folioEmitterRef.current.emit("docChange", usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(updated) : updated);
3975
+ }, [experimentalSession]);
3889
3976
  useEffect(() => {
3890
3977
  if (!hfEditMode) setHfCaretSelection(null);
3891
3978
  dragAnchorRef.current = null;
@@ -4750,6 +4837,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4750
4837
  if (story_0) {
4751
4838
  e_3.preventDefault();
4752
4839
  e_3.stopPropagation();
4840
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
4841
+ handleSessionRefusal("Footnote and endnote editing is unavailable in this session.", CANONICAL_GAP.secondaryStories);
4842
+ return;
4843
+ }
4753
4844
  noteEditorRef.current?.open(story_0);
4754
4845
  return;
4755
4846
  }
@@ -4893,7 +4984,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4893
4984
  }
4894
4985
  }
4895
4986
  }, [
4987
+ experimentalSession,
4896
4988
  getPositionFromMouse,
4989
+ handleSessionRefusal,
4897
4990
  onHeaderFooterDoubleClick,
4898
4991
  onHyperlinkClick,
4899
4992
  readOnly
@@ -5401,6 +5494,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5401
5494
  getDocument() {
5402
5495
  if (documentChangeNotifyTimerRef.current !== null) flushDocumentChangeNotification();
5403
5496
  const editorDocument = folioEditor.getDocument();
5497
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return editorDocument;
5404
5498
  const current_0 = editorDocument ? noteFollower.withPending(editorDocument) : null;
5405
5499
  return current_0 ? noteEditorRef.current?.snapshotDocument(current_0) ?? current_0 : null;
5406
5500
  },
@@ -5411,12 +5505,14 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5411
5505
  return folioEditor.getView();
5412
5506
  },
5413
5507
  getActiveView() {
5508
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return folioEditor.getView();
5414
5509
  return getActiveEditorStory().view;
5415
5510
  },
5416
5511
  closeNoteStory() {
5417
5512
  noteEditorRef.current?.close();
5418
5513
  },
5419
5514
  getHfView(rId_0) {
5515
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return null;
5420
5516
  return hfPMsRef.current?.getView(rId_0) ?? null;
5421
5517
  },
5422
5518
  ensureView(options_4) {
@@ -5442,22 +5538,34 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5442
5538
  undo() {
5443
5539
  const target_5 = getActiveEditorStory();
5444
5540
  if (target_5.type === "none") return false;
5445
- return target_5.type === "body" ? hiddenPMRef.current?.undo() ?? false : undo(target_5.view.state, target_5.view.dispatch);
5541
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return hiddenPMRef.current?.applyCanonicalStoryHistory({
5542
+ view: target_5.view,
5543
+ story: getCanonicalActiveStory(),
5544
+ direction: "undo"
5545
+ }) ?? false;
5546
+ if (target_5.type === "body") return hiddenPMRef.current?.undo() ?? false;
5547
+ return undo(target_5.view.state, target_5.view.dispatch);
5446
5548
  },
5447
5549
  redo() {
5448
5550
  const target_6 = getActiveEditorStory();
5449
5551
  if (target_6.type === "none") return false;
5450
- return target_6.type === "body" ? hiddenPMRef.current?.redo() ?? false : redo(target_6.view.state, target_6.view.dispatch);
5552
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return hiddenPMRef.current?.applyCanonicalStoryHistory({
5553
+ view: target_6.view,
5554
+ story: getCanonicalActiveStory(),
5555
+ direction: "redo"
5556
+ }) ?? false;
5557
+ if (target_6.type === "body") return hiddenPMRef.current?.redo() ?? false;
5558
+ return redo(target_6.view.state, target_6.view.dispatch);
5451
5559
  },
5452
5560
  canUndo() {
5453
5561
  const target_7 = getActiveEditorStory();
5454
5562
  if (target_7.type === "none") return false;
5455
- return 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);
5456
5564
  },
5457
5565
  canRedo() {
5458
5566
  const target_8 = getActiveEditorStory();
5459
5567
  if (target_8.type === "none") return false;
5460
- return 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);
5461
5569
  },
5462
5570
  setSelection(anchor_3, head_1) {
5463
5571
  folioEditor.setSelection(anchor_3, head_1);
@@ -5541,6 +5649,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5541
5649
  flushDocumentChangeNotification,
5542
5650
  folioEditor,
5543
5651
  getActiveEditorStory,
5652
+ getCanonicalActiveStory,
5544
5653
  noteFollower,
5545
5654
  getScrollContainer,
5546
5655
  refreshBodyImeCaretAnchor,
@@ -5614,6 +5723,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5614
5723
  ref: hfPMsRef,
5615
5724
  document,
5616
5725
  onTransaction: handleHfPmTransaction,
5726
+ getCanonicalApi,
5727
+ onSessionRefusal: handleSessionRefusal,
5728
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
5617
5729
  ...styles !== void 0 ? { styles } : {},
5618
5730
  ..._theme !== void 0 ? { theme: _theme } : {}
5619
5731
  }),
@@ -5621,6 +5733,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5621
5733
  ref: noteEditorRef,
5622
5734
  document,
5623
5735
  onActiveChange: handleActiveNoteStoryChange,
5736
+ getCanonicalApi,
5737
+ onSessionRefusal: handleSessionRefusal,
5738
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
5624
5739
  onDocumentChange: handleNoteDocumentChange,
5625
5740
  onStoryChange: handleNoteStoryTransaction,
5626
5741
  plugins: noteStoryPlugins,
@@ -5633,6 +5748,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5633
5748
  ref: hiddenPMRef,
5634
5749
  document,
5635
5750
  documentIdentity,
5751
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
5752
+ onSessionRefusal: handleSessionRefusal,
5753
+ ...suggestionAuthor !== void 0 ? { suggestionAuthor } : {},
5754
+ suggestionModeActive,
5636
5755
  widthPx: contentWidth,
5637
5756
  precomputedInitialState: validPrecomputedInitialState,
5638
5757
  readOnly,
@@ -10060,16 +10179,17 @@ function useContextMenu(t0) {
10060
10179
  * callbacks each render.
10061
10180
  */
10062
10181
  const useDocumentLoader = (t0) => {
10063
- const $ = c(22);
10064
- const { documentBuffer, initialDocument, password, history, onError, onCompatibilityChange, onReset, setDocumentLoadState } = t0;
10182
+ const $ = c(28);
10183
+ const { documentBuffer, initialDocument, password, experimentalSession, history, onError, onCompatibilityChange, onReset, setDocumentLoadState } = t0;
10065
10184
  const originalBufferRef = useRef(null);
10066
10185
  const originalBufferIdentityRef = useRef(null);
10067
10186
  const [loadedDocumentIdentity, setLoadedDocumentIdentity] = useState("0");
10068
10187
  let t1;
10069
- if ($[0] !== history || $[1] !== onCompatibilityChange || $[2] !== onError || $[3] !== onReset || $[4] !== setDocumentLoadState) {
10188
+ if ($[0] !== experimentalSession || $[1] !== history || $[2] !== onCompatibilityChange || $[3] !== onError || $[4] !== onReset || $[5] !== setDocumentLoadState) {
10070
10189
  t1 = () => {
10071
10190
  const instance = new DocumentLoaderManager({
10072
10191
  history,
10192
+ getExperimentalSession: () => experimentalSession,
10073
10193
  onError,
10074
10194
  onCompatibilityChange,
10075
10195
  onReset,
@@ -10085,17 +10205,19 @@ const useDocumentLoader = (t0) => {
10085
10205
  }
10086
10206
  };
10087
10207
  };
10088
- $[0] = history;
10089
- $[1] = onCompatibilityChange;
10090
- $[2] = onError;
10091
- $[3] = onReset;
10092
- $[4] = setDocumentLoadState;
10093
- $[5] = t1;
10094
- } else t1 = $[5];
10208
+ $[0] = experimentalSession;
10209
+ $[1] = history;
10210
+ $[2] = onCompatibilityChange;
10211
+ $[3] = onError;
10212
+ $[4] = onReset;
10213
+ $[5] = setDocumentLoadState;
10214
+ $[6] = t1;
10215
+ } else t1 = $[6];
10095
10216
  const [t2] = useState(t1);
10096
10217
  const { manager, api } = t2;
10097
10218
  manager.setCallbacks({
10098
10219
  history,
10220
+ getExperimentalSession: () => experimentalSession,
10099
10221
  onError,
10100
10222
  onCompatibilityChange,
10101
10223
  onReset,
@@ -10103,8 +10225,7 @@ const useDocumentLoader = (t0) => {
10103
10225
  setLoadedDocumentIdentity
10104
10226
  });
10105
10227
  let t3;
10106
- let t4;
10107
- if ($[6] !== api || $[7] !== documentBuffer || $[8] !== initialDocument || $[9] !== password) {
10228
+ if ($[7] !== api || $[8] !== documentBuffer || $[9] !== initialDocument || $[10] !== password) {
10108
10229
  t3 = () => {
10109
10230
  const source = getDocumentLoadSource({
10110
10231
  documentBuffer,
@@ -10117,26 +10238,32 @@ const useDocumentLoader = (t0) => {
10117
10238
  }
10118
10239
  api.loadBuffer(source.buffer, { password });
10119
10240
  };
10241
+ $[7] = api;
10242
+ $[8] = documentBuffer;
10243
+ $[9] = initialDocument;
10244
+ $[10] = password;
10245
+ $[11] = t3;
10246
+ } else t3 = $[11];
10247
+ let t4;
10248
+ if ($[12] !== api || $[13] !== documentBuffer || $[14] !== experimentalSession || $[15] !== initialDocument || $[16] !== password) {
10120
10249
  t4 = [
10121
10250
  documentBuffer,
10122
10251
  initialDocument,
10123
10252
  password,
10253
+ experimentalSession,
10124
10254
  api
10125
10255
  ];
10126
- $[6] = api;
10127
- $[7] = documentBuffer;
10128
- $[8] = initialDocument;
10129
- $[9] = password;
10130
- $[10] = t3;
10131
- $[11] = t4;
10132
- } else {
10133
- t3 = $[10];
10134
- t4 = $[11];
10135
- }
10256
+ $[12] = api;
10257
+ $[13] = documentBuffer;
10258
+ $[14] = experimentalSession;
10259
+ $[15] = initialDocument;
10260
+ $[16] = password;
10261
+ $[17] = t4;
10262
+ } else t4 = $[17];
10136
10263
  useEffect(t3, t4);
10137
10264
  let t5;
10138
10265
  let t6;
10139
- if ($[12] !== documentBuffer || $[13] !== history.state || $[14] !== loadedDocumentIdentity) {
10266
+ if ($[18] !== documentBuffer || $[19] !== history.state || $[20] !== loadedDocumentIdentity) {
10140
10267
  t5 = () => {
10141
10268
  if (originalBufferIdentityRef.current === loadedDocumentIdentity) return;
10142
10269
  originalBufferIdentityRef.current = loadedDocumentIdentity;
@@ -10151,18 +10278,18 @@ const useDocumentLoader = (t0) => {
10151
10278
  documentBuffer,
10152
10279
  loadedDocumentIdentity
10153
10280
  ];
10154
- $[12] = documentBuffer;
10155
- $[13] = history.state;
10156
- $[14] = loadedDocumentIdentity;
10157
- $[15] = t5;
10158
- $[16] = t6;
10281
+ $[18] = documentBuffer;
10282
+ $[19] = history.state;
10283
+ $[20] = loadedDocumentIdentity;
10284
+ $[21] = t5;
10285
+ $[22] = t6;
10159
10286
  } else {
10160
- t5 = $[15];
10161
- t6 = $[16];
10287
+ t5 = $[21];
10288
+ t6 = $[22];
10162
10289
  }
10163
10290
  useEffect(t5, t6);
10164
10291
  let t7;
10165
- if ($[17] !== api.loadBuffer || $[18] !== api.loadParsedDocument || $[19] !== api.resetForNewDocument || $[20] !== loadedDocumentIdentity) {
10292
+ if ($[23] !== api.loadBuffer || $[24] !== api.loadParsedDocument || $[25] !== api.resetForNewDocument || $[26] !== loadedDocumentIdentity) {
10166
10293
  t7 = {
10167
10294
  loadBuffer: api.loadBuffer,
10168
10295
  loadParsedDocument: api.loadParsedDocument,
@@ -10170,12 +10297,12 @@ const useDocumentLoader = (t0) => {
10170
10297
  originalBufferRef,
10171
10298
  loadedDocumentIdentity
10172
10299
  };
10173
- $[17] = api.loadBuffer;
10174
- $[18] = api.loadParsedDocument;
10175
- $[19] = api.resetForNewDocument;
10176
- $[20] = loadedDocumentIdentity;
10177
- $[21] = t7;
10178
- } else t7 = $[21];
10300
+ $[23] = api.loadBuffer;
10301
+ $[24] = api.loadParsedDocument;
10302
+ $[25] = api.resetForNewDocument;
10303
+ $[26] = loadedDocumentIdentity;
10304
+ $[27] = t7;
10305
+ } else t7 = $[27];
10179
10306
  return t7;
10180
10307
  };
10181
10308
  //#endregion
@@ -10458,7 +10585,7 @@ const saveAndCloseHeaderFooterEdit = ({ activeRId, document, editPosition, isFir
10458
10585
  if (newDocument) pushDocument(newDocument);
10459
10586
  setEditPosition(null);
10460
10587
  };
10461
- const useHeaderFooterEditor = ({ history, pushDocument, getHfView }) => {
10588
+ const useHeaderFooterEditor = ({ history, pushDocument, getHfView, getCanonicalApi, experimentalSession }) => {
10462
10589
  const [hfEditPosition, setHfEditPosition] = useState(null);
10463
10590
  const [hfEditIsFirstPage, setHfEditIsFirstPage] = useState(false);
10464
10591
  const rawResolution = useMemo(() => resolveHeaderFooterContent(history.state?.package), [history.state]);
@@ -10476,6 +10603,19 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView }) => {
10476
10603
  setHfEditPosition(position);
10477
10604
  return;
10478
10605
  }
10606
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10607
+ const api = getCanonicalApi?.();
10608
+ api?.ensureView();
10609
+ const canonical = api?.getCanonicalDocument();
10610
+ if (!canonical || !api) return;
10611
+ const operation = createCanonicalHeaderFooterOperation({
10612
+ document: canonical,
10613
+ position,
10614
+ referenceType: isFirstPage ? "first" : "default"
10615
+ });
10616
+ if (api.applyCanonicalOperations([operation])) setHfEditPosition(position);
10617
+ return;
10618
+ }
10479
10619
  if (!history.state) return;
10480
10620
  const newDoc = createEmptyHeaderFooter(history.state, position, isFirstPage);
10481
10621
  if (!newDoc) return;
@@ -10488,9 +10628,15 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView }) => {
10488
10628
  firstPageFooterContent,
10489
10629
  hasTitlePg,
10490
10630
  history,
10491
- pushDocument
10631
+ pushDocument,
10632
+ getCanonicalApi,
10633
+ experimentalSession
10492
10634
  ]);
10493
10635
  const handleHeaderFooterSave = useCallback(() => {
10636
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10637
+ setHfEditPosition(null);
10638
+ return;
10639
+ }
10494
10640
  if (!hfEditPosition || !history.state?.package) {
10495
10641
  setHfEditPosition(null);
10496
10642
  return;
@@ -10512,7 +10658,8 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView }) => {
10512
10658
  resolution,
10513
10659
  history,
10514
10660
  pushDocument,
10515
- getHfView
10661
+ getHfView,
10662
+ experimentalSession
10516
10663
  ]);
10517
10664
  return {
10518
10665
  hfEditPosition,
@@ -10540,6 +10687,17 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView }) => {
10540
10687
  return;
10541
10688
  }
10542
10689
  const activeRId_0 = pickActiveHeaderFooterRId(resolution, hfEditPosition, hfEditIsFirstPage);
10690
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.secondaryStories)) {
10691
+ const api_0 = getCanonicalApi?.();
10692
+ const canonical_0 = api_0?.getCanonicalDocument();
10693
+ if (api_0 && canonical_0 && activeRId_0) api_0.applyCanonicalOperations(removeCanonicalHeaderFooterOperations({
10694
+ document: canonical_0,
10695
+ position: hfEditPosition,
10696
+ rId: activeRId_0
10697
+ }));
10698
+ setHfEditPosition(null);
10699
+ return;
10700
+ }
10543
10701
  if (activeRId_0) pushDocument(removeHeaderFooter({
10544
10702
  document: history.state,
10545
10703
  position: hfEditPosition,
@@ -10551,7 +10709,9 @@ const useHeaderFooterEditor = ({ history, pushDocument, getHfView }) => {
10551
10709
  hfEditIsFirstPage,
10552
10710
  resolution,
10553
10711
  history,
10554
- pushDocument
10712
+ pushDocument,
10713
+ getCanonicalApi,
10714
+ experimentalSession
10555
10715
  ])
10556
10716
  };
10557
10717
  };
@@ -12793,7 +12953,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12793
12953
  */
12794
12954
  /** No headings to track while the outline is not shown. */
12795
12955
  const NO_HEADINGS = [];
12796
- const CommentsSidebar = lazy(() => import("./CommentsSidebar-Bk5pQ_2C.js").then((m) => ({ default: m.CommentsSidebar })));
12956
+ const CommentsSidebar = lazy(() => import("./CommentsSidebar-D8sljCtX.js").then((m) => ({ default: m.CommentsSidebar })));
12797
12957
  const TextContextMenu = lazy(() => import("./TextContextMenu-Bqth8itn.js").then((m) => ({ default: m.TextContextMenu })));
12798
12958
  const loadAttemptSelectiveSave = async () => {
12799
12959
  const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
@@ -12864,7 +13024,7 @@ function areActiveTrackedChangesEqual(a, b) {
12864
13024
  /**
12865
13025
  * DocxEditor - Complete DOCX editor component
12866
13026
  */
12867
- const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, pageRenderer, showMarginGuides = false, marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, keyboardShortcuts = "document", hostShortcuts: hostShortcutsProp, readOnly: readOnlyProp = false, autoOpenReviewSidebar = true, components, toolbarExtra, className = "", style, placeholder, loadingIndicator, preserveDocumentWhileLoading = false, initialScrollTop, onScrollTopChange, showOutline: showOutlineProp = true, onPrint, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onCopy, onCut, onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, plugins, featureFlags, onSelectiveSaveTripwire }, ref) {
13027
+ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, document: initialDocument, onSave, author = "User", onChange, onSelectionChange, onSelectionTextChange, onError, onFontsLoaded: onFontsLoadedCallback, fontFamilies, fonts, theme, showToolbar = true, showZoomControl = true, showReviewControls = true, showHeaderFooterEditing = true, pageRenderer, showMarginGuides = false, marginGuideColor, showRuler: showRulerProp = false, rulerUnit = "inch", initialZoom = 1, enableWheelZoom = true, keyboardShortcuts = "document", hostShortcuts: hostShortcutsProp, readOnly: readOnlyProp = false, autoOpenReviewSidebar = true, components, toolbarExtra, className = "", style, placeholder, loadingIndicator, preserveDocumentWhileLoading = false, initialScrollTop, onScrollTopChange, showOutline: showOutlineProp = true, onPrint, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onCopy, onCut, onPaste, mode: modeProp, onModeChange, onReadonlyEditAttempt, onCompatibilityChange, onEditorViewReady, onAnonymizationMatchesChange, onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq, showTemplateDirectives = false, onSlashMenuChange, onSlashMenuKeyAction, customContextMenuItems, onCustomContextAction, comments: commentsProp, onCommentsChange, collaboration, plugins, featureFlags, experimentalSession, onSelectiveSaveTripwire }, ref) {
12868
13028
  const t = useTranslations("folio");
12869
13029
  useEffect(() => {
12870
13030
  const onClipboardReadError = () => {
@@ -12903,11 +13063,28 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12903
13063
  const [, setTrackedChanges] = useState([]);
12904
13064
  const trackedChangesRef = useRef([]);
12905
13065
  const [anchorPositions, setAnchorPositions] = useState(EMPTY_ANCHOR_POSITIONS);
12906
- const { editingMode, readOnly, trackChangesOn, toggleTrackChanges, displayMode, setDisplayMode } = useEditorMode({
13066
+ const { editingMode, readOnly, trackChangesOn, toggleTrackChanges: toggleTrackChangesUnrestricted, displayMode, setDisplayMode } = useEditorMode({
12907
13067
  modeProp,
12908
13068
  onModeChange,
12909
13069
  readOnlyProp
12910
13070
  });
13071
+ const toggleTrackChanges = useCallback(() => {
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
+ });
13077
+ toast(error.message);
13078
+ onError?.(error);
13079
+ return;
13080
+ }
13081
+ toggleTrackChangesUnrestricted();
13082
+ }, [
13083
+ experimentalSession,
13084
+ trackChangesOn,
13085
+ onError,
13086
+ toggleTrackChangesUnrestricted
13087
+ ]);
12911
13088
  const extractTrackedChangesTimerRef = useRef(null);
12912
13089
  const collectHeadingsTimerRef = useRef(null);
12913
13090
  const extractTrackedChanges = useCallback(() => {
@@ -12956,8 +13133,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12956
13133
  const history = useDocumentHistory(initialDocument || null, {
12957
13134
  maxEntries: 100,
12958
13135
  groupingInterval: 500,
12959
- enableKeyboardShortcuts: historyShortcuts === "editor"
13136
+ enableKeyboardShortcuts: historyShortcuts === "editor" && !usesCanonicalSession(experimentalSession, CANONICAL_GAP.history)
12960
13137
  });
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
+ });
13144
+ toast(error_0.message);
13145
+ onError?.(error_0);
13146
+ return true;
13147
+ }, [experimentalSession, onError]);
12961
13148
  const extensionManager = useMemo(() => {
12962
13149
  const mgr = new ExtensionManager(createStarterKit({ historyShortcuts }));
12963
13150
  mgr.buildSchema();
@@ -13177,6 +13364,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13177
13364
  canUndo: false
13178
13365
  });
13179
13366
  const [activeNoteStory, setActiveNoteStory] = useState(null);
13367
+ const canEditHeaderFooter = showHeaderFooterEditing;
13368
+ const getCanonicalApi = useCallback(() => pagedEditorRef.current?.getEditor() ?? null, []);
13180
13369
  const pushDocument = useCallback((document) => {
13181
13370
  history.push(document);
13182
13371
  return document;
@@ -13192,6 +13381,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13192
13381
  const { hfEditPosition, setHfEditPosition, hfEditIsFirstPage, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, activeHeaderRId, activeFooterRId, activeFirstHeaderRId, activeFirstFooterRId, effectiveSectionProperties, handleHeaderFooterDoubleClick, handleBodyClick, handleRemoveHeaderFooter } = useHeaderFooterEditor({
13193
13382
  history,
13194
13383
  pushDocument,
13384
+ getCanonicalApi,
13385
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
13195
13386
  getHfView: (rId) => pagedEditorRef.current?.getHfView(rId) ?? null
13196
13387
  });
13197
13388
  let activeHfRId = hfEditIsFirstPage ? activeFirstFooterRId : activeFooterRId;
@@ -13224,19 +13415,27 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13224
13415
  else pagedEditorRef.current?.focus();
13225
13416
  }, [getActiveEditorStory]);
13226
13417
  const undoActiveEditor = useCallback(() => {
13227
- if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.undo();
13418
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.undo();
13228
13419
  else {
13229
13420
  pagedEditorRef.current?.undo();
13230
13421
  requestAnimationFrame(refreshBodyHistoryAvailability);
13231
13422
  }
13232
- }, [getActiveEditorStory, refreshBodyHistoryAvailability]);
13423
+ }, [
13424
+ getActiveEditorStory,
13425
+ refreshBodyHistoryAvailability,
13426
+ experimentalSession
13427
+ ]);
13233
13428
  const redoActiveEditor = useCallback(() => {
13234
- if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.redo();
13429
+ if (!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) && getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) hfEditorRef.current.redo();
13235
13430
  else {
13236
13431
  pagedEditorRef.current?.redo();
13237
13432
  requestAnimationFrame(refreshBodyHistoryAvailability);
13238
13433
  }
13239
- }, [getActiveEditorStory, refreshBodyHistoryAvailability]);
13434
+ }, [
13435
+ getActiveEditorStory,
13436
+ refreshBodyHistoryAvailability,
13437
+ experimentalSession
13438
+ ]);
13240
13439
  const handleActiveNoteStoryChange = useCallback((story) => {
13241
13440
  setActiveNoteStory(story);
13242
13441
  if (story && hfEditPosition) handleBodyClick();
@@ -13260,6 +13459,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13260
13459
  documentBuffer: documentBuffer ?? null,
13261
13460
  initialDocument: initialDocument ?? null,
13262
13461
  password,
13462
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
13263
13463
  history,
13264
13464
  onError,
13265
13465
  onCompatibilityChange,
@@ -13373,7 +13573,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13373
13573
  }
13374
13574
  };
13375
13575
  pushDocument(documentWithComments);
13376
- onChange?.(documentWithComments);
13576
+ onChange?.(usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? cloneDocumentWithParagraphPropertySources(documentWithComments) : documentWithComments);
13377
13577
  if (showOutlineRef.current) {
13378
13578
  if (collectHeadingsTimerRef.current) clearTimeout(collectHeadingsTimerRef.current);
13379
13579
  collectHeadingsTimerRef.current = setTimeout(() => {
@@ -13394,10 +13594,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13394
13594
  pushDocument,
13395
13595
  extractTrackedChanges,
13396
13596
  refreshBodyHistoryAvailability,
13397
- commentsRef
13597
+ commentsRef,
13598
+ experimentalSession
13398
13599
  ]);
13399
13600
  const buildCurrentDocument = useCallback(() => {
13400
13601
  if (!history.state) return null;
13602
+ const canonical = pagedEditorRef.current?.getEditor().getCanonicalDocument();
13603
+ if (canonical) return canonical;
13604
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return null;
13401
13605
  let doc_0 = cloneDocumentWithParagraphPropertySources(history.state);
13402
13606
  const pmDoc = pagedEditorRef.current?.getDocument();
13403
13607
  if (pmDoc) {
@@ -13422,8 +13626,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13422
13626
  const referencedCommentIds = collectCommentIdsFromSources(doc_0.package.document.content, doc_0.package.headers, doc_0.package.footers, doc_0.package.footnotes, doc_0.package.endnotes);
13423
13627
  doc_0.package.document.comments = pruneOrphanedComments(commentsRef.current, referencedCommentIds);
13424
13628
  return doc_0;
13425
- }, [history.state, commentsRef]);
13629
+ }, [
13630
+ history.state,
13631
+ commentsRef,
13632
+ experimentalSession
13633
+ ]);
13426
13634
  const replaceComments = useCallback((nextComments) => {
13635
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
13636
+ refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.");
13637
+ return;
13638
+ }
13427
13639
  commentsDirtyRef.current = true;
13428
13640
  setComments(nextComments);
13429
13641
  const currentDocument = buildCurrentDocument();
@@ -13432,7 +13644,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13432
13644
  }, [
13433
13645
  buildCurrentDocument,
13434
13646
  commentsDirtyRef,
13647
+ experimentalSession,
13435
13648
  onChange,
13649
+ refuseCanonicalModelEdit,
13436
13650
  setComments
13437
13651
  ]);
13438
13652
  const updateComments = useCallback((updater) => {
@@ -13685,6 +13899,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13685
13899
  roots: shortcutRoots
13686
13900
  });
13687
13901
  const handleApplyFootnoteProperties = useCallback((footnotePr, endnotePr) => {
13902
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
13903
+ const api = getCanonicalApi();
13904
+ api?.ensureView();
13905
+ const canonical_0 = api?.getCanonicalDocument();
13906
+ if (!canonical_0 || !api?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_0, {
13907
+ footnotePr,
13908
+ endnotePr
13909
+ })])) refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "Section property changes could not be applied.");
13910
+ return;
13911
+ }
13688
13912
  if (!history.state?.package) return;
13689
13913
  const newDoc = {
13690
13914
  ...history.state.package.document,
@@ -13701,7 +13925,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13701
13925
  document: newDoc
13702
13926
  }
13703
13927
  });
13704
- }, [history, pushDocument]);
13928
+ }, [
13929
+ history,
13930
+ pushDocument,
13931
+ experimentalSession,
13932
+ getCanonicalApi,
13933
+ refuseCanonicalModelEdit
13934
+ ]);
13705
13935
  const handleTableAction = useCallback((action_0) => {
13706
13936
  const view_9 = getActiveEditorView();
13707
13937
  if (!view_9) return;
@@ -13896,92 +14126,95 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13896
14126
  const tr = view_10.state.tr.setSelection(TextSelection.create(view_10.state.doc, savedSelection.from, savedSelection.to));
13897
14127
  view_10.dispatch(tr);
13898
14128
  } catch {}
13899
- const commandState = view_10.state;
13900
14129
  if (action_1 === "bold") {
13901
- toggleBold(commandState, view_10.dispatch);
14130
+ executeEditorCommand(view_10, toggleBold);
13902
14131
  return;
13903
14132
  }
13904
14133
  if (action_1 === "italic") {
13905
- toggleItalic(commandState, view_10.dispatch);
14134
+ executeEditorCommand(view_10, toggleItalic);
13906
14135
  return;
13907
14136
  }
13908
14137
  if (action_1 === "underline") {
13909
- toggleUnderline(commandState, view_10.dispatch);
14138
+ executeEditorCommand(view_10, toggleUnderline);
13910
14139
  return;
13911
14140
  }
13912
14141
  if (action_1 === "strikethrough") {
13913
- toggleStrike(commandState, view_10.dispatch);
14142
+ executeEditorCommand(view_10, toggleStrike);
13914
14143
  return;
13915
14144
  }
13916
14145
  if (action_1 === "superscript") {
13917
- toggleSuperscript(commandState, view_10.dispatch);
14146
+ executeEditorCommand(view_10, toggleSuperscript);
13918
14147
  return;
13919
14148
  }
13920
14149
  if (action_1 === "subscript") {
13921
- toggleSubscript(commandState, view_10.dispatch);
14150
+ executeEditorCommand(view_10, toggleSubscript);
13922
14151
  return;
13923
14152
  }
13924
14153
  if (action_1 === "bulletList") {
13925
- toggleBulletList(commandState, view_10.dispatch);
14154
+ executeEditorCommand(view_10, toggleBulletList);
13926
14155
  return;
13927
14156
  }
13928
14157
  if (action_1 === "numberedList") {
13929
- toggleNumberedList(commandState, view_10.dispatch);
14158
+ executeEditorCommand(view_10, toggleNumberedList);
13930
14159
  return;
13931
14160
  }
13932
14161
  if (action_1 === "indent") {
13933
- if (!increaseListLevel(commandState, view_10.dispatch)) increaseIndent()(commandState, view_10.dispatch);
14162
+ executeFirstEditorCommand(view_10, [increaseListLevel, increaseIndent()]);
13934
14163
  return;
13935
14164
  }
13936
14165
  if (action_1 === "outdent") {
13937
- if (!decreaseListLevel(commandState, view_10.dispatch)) decreaseIndent()(commandState, view_10.dispatch);
14166
+ executeFirstEditorCommand(view_10, [decreaseListLevel, decreaseIndent()]);
13938
14167
  return;
13939
14168
  }
13940
14169
  if (action_1 === "clearFormatting") {
13941
- clearFormatting(commandState, view_10.dispatch);
14170
+ executeEditorCommand(view_10, clearFormatting);
13942
14171
  return;
13943
14172
  }
13944
14173
  if (action_1 === "setRtl") {
13945
- setRtl(commandState, view_10.dispatch);
14174
+ executeEditorCommand(view_10, setRtl);
13946
14175
  return;
13947
14176
  }
13948
14177
  if (action_1 === "setLtr") {
13949
- setLtr(commandState, view_10.dispatch);
14178
+ executeEditorCommand(view_10, setLtr);
14179
+ return;
14180
+ }
14181
+ if (action_1 === "insertPageBreak") {
14182
+ executeEditorCommand(view_10, insertPageBreak);
13950
14183
  return;
13951
14184
  }
13952
14185
  if (typeof action_1 === "object") switch (action_1.type) {
13953
14186
  case "alignment":
13954
- setAlignment(action_1.value)(commandState, view_10.dispatch);
14187
+ executeEditorCommand(view_10, setAlignment(action_1.value));
13955
14188
  break;
13956
14189
  case "toggleDirection":
13957
- toggleBidi(commandState, view_10.dispatch);
14190
+ executeEditorCommand(view_10, toggleBidi);
13958
14191
  break;
13959
14192
  case "textColor": {
13960
14193
  const colorVal_0 = action_1.value;
13961
- if (typeof colorVal_0 === "string") setTextColor({ rgb: colorVal_0.replace("#", "") })(commandState, view_10.dispatch);
13962
- else if (colorVal_0.auto) clearTextColor(commandState, view_10.dispatch);
14194
+ if (typeof colorVal_0 === "string") executeEditorCommand(view_10, setTextColor({ rgb: colorVal_0.replace("#", "") }));
14195
+ else if (colorVal_0.auto) executeEditorCommand(view_10, clearTextColor);
13963
14196
  else {
13964
14197
  const themeColor = typeof colorVal_0.themeColor === "string" ? colorVal_0.themeColor : void 0;
13965
- setTextColor({
14198
+ executeEditorCommand(view_10, setTextColor({
13966
14199
  ...colorVal_0.rgb === void 0 ? {} : { rgb: colorVal_0.rgb },
13967
14200
  ...themeColor ? { themeColor } : {},
13968
14201
  ...colorVal_0.themeTint === void 0 ? {} : { themeTint: colorVal_0.themeTint },
13969
14202
  ...colorVal_0.themeShade === void 0 ? {} : { themeShade: colorVal_0.themeShade }
13970
- })(commandState, view_10.dispatch);
14203
+ }));
13971
14204
  }
13972
14205
  break;
13973
14206
  }
13974
14207
  case "highlightColor":
13975
- setHighlight((action_1.value ? mapHexToHighlightName(action_1.value) : "") || action_1.value)(commandState, view_10.dispatch);
14208
+ executeEditorCommand(view_10, setHighlight((action_1.value ? mapHexToHighlightName(action_1.value) : "") || action_1.value));
13976
14209
  break;
13977
14210
  case "fontSize":
13978
- setFontSize(pointsToHalfPoints(action_1.value))(commandState, view_10.dispatch);
14211
+ executeEditorCommand(view_10, setFontSize(pointsToHalfPoints(action_1.value)));
13979
14212
  break;
13980
14213
  case "fontFamily":
13981
- setFontFamily(action_1.value)(commandState, view_10.dispatch);
14214
+ executeEditorCommand(view_10, setFontFamily(action_1.value));
13982
14215
  break;
13983
14216
  case "lineSpacing":
13984
- setLineSpacing(action_1.value)(commandState, view_10.dispatch);
14217
+ executeEditorCommand(view_10, setLineSpacing(action_1.value));
13985
14218
  break;
13986
14219
  case "applyStyle": {
13987
14220
  const currentDoc_0 = historyStateRef.current;
@@ -13994,8 +14227,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13994
14227
  const styleName = styleResolver_0.getStyle(action_1.value)?.name;
13995
14228
  if (styleName) styleAttrs.styleName = styleName;
13996
14229
  styleAttrs.numbering = currentDoc_0?.package.numbering ? getCachedNumberingMap(currentDoc_0.package.numbering) : null;
13997
- applyStyle(action_1.value, styleAttrs)(commandState, view_10.dispatch);
13998
- } else applyStyle(action_1.value)(commandState, view_10.dispatch);
14230
+ executeEditorCommand(view_10, applyStyle(action_1.value, styleAttrs));
14231
+ } else executeEditorCommand(view_10, applyStyle(action_1.value));
13999
14232
  break;
14000
14233
  }
14001
14234
  default: break;
@@ -14310,13 +14543,21 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14310
14543
  case "acceptChange": {
14311
14544
  const { from: from_4, to: to_4 } = view_13.state.selection;
14312
14545
  const range_1 = findChangeAtPosition(view_13.state, from_4, to_4);
14313
- acceptChange(range_1.from, range_1.to)(view_13.state, view_13.dispatch);
14546
+ if (resolveCanonicalReviewRange({
14547
+ editor: pagedEditorRef.current?.getEditor(),
14548
+ ...range_1,
14549
+ resolution: "accept"
14550
+ }) === null) acceptChange(range_1.from, range_1.to)(view_13.state, view_13.dispatch);
14314
14551
  break;
14315
14552
  }
14316
14553
  case "rejectChange": {
14317
14554
  const { from: from_3, to: to_3 } = view_13.state.selection;
14318
14555
  const range_0 = findChangeAtPosition(view_13.state, from_3, to_3);
14319
- rejectChange(range_0.from, range_0.to)(view_13.state, view_13.dispatch);
14556
+ if (resolveCanonicalReviewRange({
14557
+ editor: pagedEditorRef.current?.getEditor(),
14558
+ ...range_0,
14559
+ resolution: "reject"
14560
+ }) === null) rejectChange(range_0.from, range_0.to)(view_13.state, view_13.dispatch);
14320
14561
  break;
14321
14562
  }
14322
14563
  case "restartNumbering":
@@ -14348,6 +14589,14 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14348
14589
  t
14349
14590
  ]);
14350
14591
  const handlePageSetupApply = useCallback((props) => {
14592
+ if (readOnly) return;
14593
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) {
14594
+ const api_0 = getCanonicalApi();
14595
+ api_0?.ensureView();
14596
+ const canonical_1 = api_0?.getCanonicalDocument();
14597
+ if (!canonical_1 || !api_0?.applyCanonicalOperations([createCanonicalSectionPropertiesOperation(canonical_1, props)])) refuseCanonicalModelEdit(CANONICAL_GAP.sectionProperties, "Section property changes could not be applied.");
14598
+ return;
14599
+ }
14351
14600
  if (!history.state || readOnly) return;
14352
14601
  const newDoc_0 = {
14353
14602
  ...history.state,
@@ -14366,7 +14615,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14366
14615
  }, [
14367
14616
  history.state,
14368
14617
  readOnly,
14369
- handleDocumentChange
14618
+ handleDocumentChange,
14619
+ experimentalSession,
14620
+ getCanonicalApi,
14621
+ refuseCanonicalModelEdit
14370
14622
  ]);
14371
14623
  const handleLeftMarginChange = useCallback((twips) => handlePageSetupApply({ marginLeft: twips }), [handlePageSetupApply]);
14372
14624
  const handleRightMarginChange = useCallback((twips_0) => handlePageSetupApply({ marginRight: twips_0 }), [handlePageSetupApply]);
@@ -14397,55 +14649,76 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14397
14649
  let tripwireResult = null;
14398
14650
  let savedBuffer = null;
14399
14651
  try {
14400
- const view_18 = pagedEditorRef.current?.getView();
14401
- const editorState = view_18?.state;
14402
- const baselineBuffer = originalBufferRef.current;
14403
- const current = buildCurrentDocument();
14404
- const doc_1 = current ? withoutUnreferencedNotes(current) : null;
14405
- if (!doc_1) return null;
14406
- const { resolveSelectiveSaveFlags } = await import("@stll/folio-core/docx/selectiveSaveFlags");
14407
- const flags = resolveSelectiveSaveFlags(featureFlags);
14408
- const useSelectiveForSave = flags.selectiveSave && options?.mode !== FOLIO_DOCX_SERIALIZATION_MODE.full;
14409
- const shouldAttemptSelective = useSelectiveForSave || flags.selectiveSaveTripwire;
14410
- let selectiveBuffer = null;
14411
- if (shouldAttemptSelective && editorState && baselineBuffer) selectiveBuffer = await (await loadAttemptSelectiveSave())(doc_1, baselineBuffer, {
14412
- changedParaIds: getChangedParagraphIds(editorState),
14413
- structuralChange: hasStructuralChanges(editorState),
14414
- hasUntrackedChanges: hasUntrackedChanges(editorState),
14415
- maxBytes: flags.selectiveSaveMaxBytes
14416
- });
14417
- let buffer = useSelectiveForSave ? selectiveBuffer : null;
14418
- let fullBuffer = null;
14419
- const repackSourceDoc = baselineBuffer ? {
14420
- ...doc_1,
14421
- originalBuffer: baselineBuffer
14422
- } : doc_1;
14423
- const repackFull = async () => {
14424
- const repackDocx = await loadRepackDocx();
14425
- const repack = () => repackDocx(repackSourceDoc);
14426
- return editorState ? repackWithEditorSectionRemovals({
14427
- state: editorState,
14428
- document: repackSourceDoc,
14429
- repack
14430
- }) : repack();
14431
- };
14432
- if (!buffer) {
14433
- fullBuffer = await repackFull();
14434
- buffer = fullBuffer;
14435
- } else if (flags.selectiveSaveTripwire) try {
14436
- fullBuffer = await repackFull();
14437
- } catch {}
14438
- if (flags.selectiveSaveTripwire && fullBuffer && onSelectiveSaveTripwire) try {
14439
- const { compareSelectiveVsFull } = await import("@stll/folio-core/docx/selectiveSaveTripwire");
14440
- tripwireResult = await compareSelectiveVsFull(selectiveBuffer, fullBuffer);
14441
- } catch {}
14442
- if (view_18 && pagedEditorRef.current?.getView() === view_18 && view_18.state.doc === editorState?.doc) {
14443
- originalBufferRef.current = buffer;
14444
- view_18.dispatch(clearTrackedChanges(view_18.state));
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
14661
+ });
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;
14445
14719
  }
14446
- savedBuffer = buffer;
14447
- } catch (error) {
14448
- onError?.(error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to save document"));
14720
+ } catch (error_1) {
14721
+ onError?.(error_1 instanceof Error ? error_1 : /* @__PURE__ */ new Error("Failed to save document"));
14449
14722
  return null;
14450
14723
  }
14451
14724
  if (tripwireResult && onSelectiveSaveTripwire) onSelectiveSaveTripwire(tripwireResult);
@@ -14455,12 +14728,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14455
14728
  onError,
14456
14729
  originalBufferRef,
14457
14730
  featureFlags,
14458
- onSelectiveSaveTripwire
14731
+ onSelectiveSaveTripwire,
14732
+ experimentalSession
14459
14733
  ]);
14460
14734
  const handleSave = useCallback(async (options_0) => {
14461
- const editor_1 = pagedEditorRef.current?.getEditor();
14735
+ const editor_2 = pagedEditorRef.current?.getEditor();
14462
14736
  const serializationOptions = { mode: options_0?.selective === false ? FOLIO_DOCX_SERIALIZATION_MODE.full : FOLIO_DOCX_SERIALIZATION_MODE.preferSelective };
14463
- 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);
14464
14738
  if (!buffer_0) return null;
14465
14739
  commentsDirtyRef.current = false;
14466
14740
  onSave?.(buffer_0);
@@ -14479,15 +14753,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14479
14753
  loadParsedDocument,
14480
14754
  serializeCurrentDocx
14481
14755
  ]);
14482
- const handleEditorError = useCallback((error_0) => {
14483
- onError?.(error_0);
14756
+ const handleEditorError = useCallback((error_2) => {
14757
+ if (CanonicalSessionRefusalError.is(error_2)) toast(error_2.message);
14758
+ onError?.(error_2);
14484
14759
  }, [onError]);
14485
14760
  useImperativeHandle(ref, () => ({
14486
14761
  getDocument: () => buildCurrentDocument(),
14487
14762
  hasPendingChanges: () => {
14488
- const view_19 = pagedEditorRef.current?.getView();
14489
- if (!view_19) return false;
14490
- 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);
14491
14766
  },
14492
14767
  getEditorRef: () => pagedEditorRef.current,
14493
14768
  getEditor: () => pagedEditorRef.current?.getEditor() ?? null,
@@ -14513,9 +14788,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14513
14788
  },
14514
14789
  loadDocument: (document_0) => {
14515
14790
  pendingSuggestionRegistryRef.current.clear();
14516
- const editor_2 = pagedEditorRef.current?.getEditor();
14517
- if (editor_2) {
14518
- editor_2.loadDocument(document_0);
14791
+ const editor_3 = pagedEditorRef.current?.getEditor();
14792
+ if (editor_3) {
14793
+ editor_3.loadDocument(document_0);
14519
14794
  return;
14520
14795
  }
14521
14796
  loadParsedDocument(document_0);
@@ -14528,13 +14803,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14528
14803
  pagedEditorRef.current?.ensureView(options_2);
14529
14804
  },
14530
14805
  createAIEditSnapshot: () => {
14531
- const view_20 = pagedEditorRef.current?.getView();
14532
- 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;
14533
14808
  },
14534
- applyDocumentOperations: ({ snapshot, batch, author: operationAuthor = author }) => {
14809
+ applyDocumentOperations: ({ snapshot: snapshot_0, batch, author: operationAuthor = author }) => {
14535
14810
  assertSupportedFolioDocumentOperationVersion(batch.version);
14536
- const view_21 = pagedEditorRef.current?.getView();
14537
- if (!view_21) {
14811
+ const view_22 = pagedEditorRef.current?.getView();
14812
+ if (!view_22) {
14538
14813
  let status = "committed";
14539
14814
  if (batch.dryRun === true) status = "previewed";
14540
14815
  else if (batch.atomic === true) status = "rejected";
@@ -14552,21 +14827,27 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14552
14827
  undoHandle: null
14553
14828
  };
14554
14829
  }
14830
+ const canonical_2 = getCanonicalApi()?.applyCanonicalDocumentOperations({
14831
+ snapshot: snapshot_0,
14832
+ batch,
14833
+ author: operationAuthor
14834
+ });
14835
+ if (canonical_2) return canonical_2;
14555
14836
  const existingUndoEntry = documentOperationUndoEntriesRef.current.at(-1);
14556
- 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;
14557
14838
  const commentsBefore = commentsRef.current;
14558
14839
  const createdComments = [];
14559
14840
  const operationView = {
14560
- state: view_21.state,
14841
+ state: view_22.state,
14561
14842
  dispatch: (transaction) => {
14562
- view_21.dispatch(closeHistory(transaction));
14563
- operationView.state = view_21.state;
14843
+ view_22.dispatch(closeHistory(transaction));
14844
+ operationView.state = view_22.state;
14564
14845
  }
14565
14846
  };
14566
- const activeSuggestionIds = new Set(getSuggestions(view_21.state).map((s_0) => s_0.suggestionId));
14567
- const result = applyFolioDocumentOperations({
14847
+ const activeSuggestionIds = new Set(getSuggestions(view_22.state).map((s_0) => s_0.suggestionId));
14848
+ const result_0 = applyFolioDocumentOperations({
14568
14849
  view: operationView,
14569
- snapshot,
14850
+ snapshot: snapshot_0,
14570
14851
  batch,
14571
14852
  author: operationAuthor,
14572
14853
  createCommentId: (text_3) => {
@@ -14579,25 +14860,27 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14579
14860
  id: `react-${String(documentOperationUndoHandleCursor++)}`
14580
14861
  })
14581
14862
  });
14582
- if (batch.mode === "suggested" && result.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
14583
- snapshot,
14863
+ if (batch.mode === "suggested" && result_0.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
14864
+ snapshot: snapshot_0,
14584
14865
  story: { type: "main" },
14585
14866
  operations: batch.operations,
14586
- applied: result.applied,
14867
+ applied: result_0.applied,
14587
14868
  author: operationAuthor,
14588
14869
  activeSuggestionIds
14589
14870
  });
14590
- const batchComments = appliedOperationComments(createdComments, result.applied);
14871
+ const batchComments = appliedOperationComments(createdComments, result_0.applied);
14591
14872
  if (batchComments.length > 0) updateComments((currentComments_0) => [...currentComments_0, ...batchComments]);
14592
- if (result.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
14593
- undoHandle: result.undoHandle,
14594
- afterState: view_21.state,
14873
+ if (result_0.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
14874
+ undoHandle: result_0.undoHandle,
14875
+ afterState: view_22.state,
14595
14876
  commentsBefore,
14596
14877
  commentsAfter: commentsRef.current
14597
14878
  });
14598
- return result;
14879
+ return result_0;
14599
14880
  },
14600
14881
  undoDocumentOperations: (undoHandle) => {
14882
+ const canonical_3 = getCanonicalApi()?.undoCanonicalDocumentOperations(undoHandle);
14883
+ if (canonical_3) return canonical_3;
14601
14884
  const entries = documentOperationUndoEntriesRef.current;
14602
14885
  const entryIndex = entries.findIndex((entry_2) => entry_2.undoHandle.type === undoHandle.type && entry_2.undoHandle.id === undoHandle.id);
14603
14886
  if (entryIndex === -1) return {
@@ -14611,18 +14894,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14611
14894
  reason: "notLatest"
14612
14895
  };
14613
14896
  const entry_3 = entries.at(-1);
14614
- const view_22 = pagedEditorRef.current?.getView();
14615
- if (!entry_3 || !view_22) return {
14897
+ const view_23 = pagedEditorRef.current?.getView();
14898
+ if (!entry_3 || !view_23) return {
14616
14899
  status: "rejected",
14617
14900
  undoHandle,
14618
14901
  reason: "unknownHandle"
14619
14902
  };
14620
- 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 {
14621
14904
  status: "rejected",
14622
14905
  undoHandle,
14623
14906
  reason: "documentChanged"
14624
14907
  };
14625
- if (!undo(view_22.state, view_22.dispatch)) return {
14908
+ if (!undo(view_23.state, view_23.dispatch)) return {
14626
14909
  status: "rejected",
14627
14910
  undoHandle,
14628
14911
  reason: "documentChanged"
@@ -14635,20 +14918,30 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14635
14918
  undoHandle
14636
14919
  };
14637
14920
  },
14638
- applyAIEditOperations: ({ snapshot: snapshot_0, operations, mode = "tracked-changes", author: operationAuthor_0 = author }) => {
14639
- const view_23 = pagedEditorRef.current?.getView();
14640
- 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 {
14641
14924
  applied: [],
14642
14925
  skipped: operations.map((operation_0) => ({
14643
14926
  id: operation_0.id,
14644
14927
  reason: "unsupportedBlock"
14645
14928
  }))
14646
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;
14647
14940
  const createdComments_0 = [];
14648
- 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));
14649
14942
  const { applied: applied_0, skipped: skipped_0 } = applyFolioDocumentOperations({
14650
- view: view_23,
14651
- snapshot: snapshot_0,
14943
+ view: view_24,
14944
+ snapshot: snapshot_1,
14652
14945
  batch: {
14653
14946
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
14654
14947
  operations,
@@ -14664,7 +14957,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14664
14957
  const batchComments_0 = appliedOperationComments(createdComments_0, applied_0);
14665
14958
  if (batchComments_0.length > 0) updateComments((currentComments_1) => [...currentComments_1, ...batchComments_0]);
14666
14959
  if (mode === "suggested") pendingSuggestionRegistryRef.current.recordApplied({
14667
- snapshot: snapshot_0,
14960
+ snapshot: snapshot_1,
14668
14961
  story: { type: "main" },
14669
14962
  operations,
14670
14963
  applied: applied_0,
@@ -14677,67 +14970,71 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14677
14970
  };
14678
14971
  },
14679
14972
  acceptAIEditOperation: (revisionId) => {
14680
- const view_24 = pagedEditorRef.current?.getView();
14681
- if (!view_24) return false;
14682
- return acceptAIEditRevision(revisionId)(view_24.state, view_24.dispatch);
14683
- },
14684
- rejectAIEditOperation: (revisionId_0) => {
14685
14973
  const view_25 = pagedEditorRef.current?.getView();
14686
14974
  if (!view_25) return false;
14687
- return rejectAIEditRevision(revisionId_0)(view_25.state, view_25.dispatch);
14975
+ const editor_4 = pagedEditorRef.current?.getEditor();
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);
14688
14985
  },
14689
14986
  undo: () => {
14690
- if (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();
14691
14988
  const undone = pagedEditorRef.current?.undo() ?? false;
14692
14989
  requestAnimationFrame(refreshBodyHistoryAvailability);
14693
14990
  return undone;
14694
14991
  },
14695
14992
  redo: () => {
14696
- if (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();
14697
14994
  const redone = pagedEditorRef.current?.redo() ?? false;
14698
14995
  requestAnimationFrame(refreshBodyHistoryAvailability);
14699
14996
  return redone;
14700
14997
  },
14701
14998
  scrollToAIEditOperation: (revisionId_1) => {
14702
- const view_26 = pagedEditorRef.current?.getView();
14703
- if (!view_26) return false;
14704
- 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);
14705
15002
  if (!range_2) return false;
14706
- const { from: from_8, to: to_8 } = clampRangeToDocSize(view_26.state.doc.content.size, range_2);
14707
- const $from = view_26.state.doc.resolve(from_8);
14708
- const $to = view_26.state.doc.resolve(to_8);
14709
- 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)));
14710
15007
  requestAnimationFrame(() => {
14711
15008
  pagedEditorRef.current?.scrollToPosition(from_8);
14712
15009
  });
14713
15010
  return true;
14714
15011
  },
14715
- scrollToBlock: (blockId, snapshot_1) => {
14716
- const view_27 = pagedEditorRef.current?.getView();
14717
- if (!view_27) return false;
15012
+ scrollToBlock: (blockId, snapshot_2) => {
15013
+ const view_28 = pagedEditorRef.current?.getView();
15014
+ if (!view_28) return false;
14718
15015
  const range_3 = resolveFolioAIBlockRange({
14719
15016
  blockId,
14720
- doc: view_27.state.doc,
14721
- snapshot: snapshot_1
15017
+ doc: view_28.state.doc,
15018
+ snapshot: snapshot_2
14722
15019
  });
14723
15020
  if (range_3 === null) return false;
14724
15021
  const { from: from_9, to: to_9 } = range_3;
14725
- const $from_0 = view_27.state.doc.resolve(from_9);
14726
- const $to_0 = view_27.state.doc.resolve(to_9);
14727
- 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)));
14728
15025
  requestAnimationFrame(() => {
14729
15026
  pagedEditorRef.current?.scrollToPosition(from_9);
14730
15027
  });
14731
15028
  return true;
14732
15029
  },
14733
- highlightPassage: ({ blockId: blockId_0, text: text_5, snapshot: snapshot_2 }) => {
14734
- const view_28 = pagedEditorRef.current?.getView();
14735
- 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";
14736
15033
  const passageRange = resolvePassageRange({
14737
15034
  blockId: blockId_0,
14738
15035
  text: text_5,
14739
- doc: view_28.state.doc,
14740
- snapshot: snapshot_2
15036
+ doc: view_29.state.doc,
15037
+ snapshot: snapshot_3
14741
15038
  });
14742
15039
  if (passageRange !== null) {
14743
15040
  pagedEditorRef.current?.setPassageHighlight(passageRange);
@@ -14749,16 +15046,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14749
15046
  pagedEditorRef.current?.setPassageHighlight(null);
14750
15047
  const blockRange = resolveFolioAIBlockRange({
14751
15048
  blockId: blockId_0,
14752
- doc: view_28.state.doc,
14753
- snapshot: snapshot_2
15049
+ doc: view_29.state.doc,
15050
+ snapshot: snapshot_3
14754
15051
  });
14755
15052
  if (blockRange === null) return "none";
14756
15053
  const paraId_0 = getFolioParaIdFromBlockId(blockId_0);
14757
15054
  if (paraId_0 !== null && pagedEditorRef.current?.scrollToParaId(paraId_0, { highlight: {} })) return "block";
14758
15055
  const { from: from_10, to: to_10 } = blockRange;
14759
- const $from_1 = view_28.state.doc.resolve(from_10);
14760
- const $to_1 = view_28.state.doc.resolve(to_10);
14761
- 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)));
14762
15059
  requestAnimationFrame(() => {
14763
15060
  pagedEditorRef.current?.scrollToPosition(from_10);
14764
15061
  });
@@ -14767,60 +15064,70 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14767
15064
  clearPassageHighlight: () => {
14768
15065
  pagedEditorRef.current?.setPassageHighlight(null);
14769
15066
  },
14770
- showInDocument: (target_1, snapshot_3) => {
14771
- const view_29 = pagedEditorRef.current?.getView();
14772
- if (!view_29) return false;
15067
+ showInDocument: (target_1, snapshot_4) => {
15068
+ const view_30 = pagedEditorRef.current?.getView();
15069
+ if (!view_30) return false;
14773
15070
  const range_4 = target_1.type === "textRange" ? resolveFolioAITextRange({
14774
15071
  range: target_1,
14775
- doc: view_29.state.doc,
14776
- snapshot: snapshot_3
15072
+ doc: view_30.state.doc,
15073
+ snapshot: snapshot_4
14777
15074
  }) : resolveFolioAIBlockRange({
14778
15075
  blockId: target_1.blockId,
14779
- doc: view_29.state.doc,
14780
- snapshot: snapshot_3
15076
+ doc: view_30.state.doc,
15077
+ snapshot: snapshot_4
14781
15078
  });
14782
15079
  if (range_4 === null) return false;
14783
15080
  const { from: from_11, to: to_11 } = range_4;
14784
- const $from_2 = view_29.state.doc.resolve(from_11);
14785
- const $to_2 = view_29.state.doc.resolve(to_11);
14786
- 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)));
14787
15084
  requestAnimationFrame(() => {
14788
15085
  pagedEditorRef.current?.scrollToPosition(from_11);
14789
15086
  });
14790
15087
  return true;
14791
15088
  },
14792
15089
  getSuggestions: () => {
14793
- const view_30 = pagedEditorRef.current?.getView();
14794
- return view_30 ? getSuggestions(view_30.state) : [];
15090
+ const view_31 = pagedEditorRef.current?.getView();
15091
+ return view_31 ? getSuggestions(view_31.state) : [];
14795
15092
  },
14796
15093
  exportPendingSuggestions: () => {
14797
- const view_31 = pagedEditorRef.current?.getView();
14798
- 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) : []);
14799
15096
  return pendingSuggestionRegistryRef.current.exportPendingSuggestions({
14800
15097
  activeSuggestionIds: activeIds,
14801
- 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
14802
15099
  });
14803
15100
  },
14804
15101
  loadPendingSuggestions: (records) => pendingSuggestionRegistryRef.current.loadPendingSuggestions({
14805
15102
  records,
14806
15103
  snapshotForStory: (story_1) => {
14807
- const view_32 = pagedEditorRef.current?.getView();
14808
- return story_1.type === "main" && view_32 ? createFolioAIEditSnapshot(view_32.state.doc) : null;
14809
- },
14810
- sourceSnapshotForStory: (story_2, commentIds_0) => {
14811
15104
  const view_33 = pagedEditorRef.current?.getView();
14812
- 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;
14813
15106
  },
14814
- apply: (record, snapshot_4) => {
15107
+ sourceSnapshotForStory: (story_2, commentIds_0) => {
14815
15108
  const view_34 = pagedEditorRef.current?.getView();
14816
- 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 {
14817
15114
  applied: [],
14818
15115
  skipped: []
14819
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;
14820
15127
  const createdComments_1 = [];
14821
- const result_0 = applyFolioDocumentOperations({
14822
- view: view_34,
14823
- snapshot: snapshot_4,
15128
+ const result_1 = applyFolioDocumentOperations({
15129
+ view: view_35,
15130
+ snapshot: snapshot_5,
14824
15131
  batch: {
14825
15132
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
14826
15133
  operations: [record.operation],
@@ -14833,78 +15140,78 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14833
15140
  return comment_1.id;
14834
15141
  }
14835
15142
  });
14836
- const appliedComments = appliedOperationComments(createdComments_1, result_0.applied);
15143
+ const appliedComments = appliedOperationComments(createdComments_1, result_1.applied);
14837
15144
  if (appliedComments.length > 0) updateComments((currentComments_2) => [...currentComments_2, ...appliedComments]);
14838
15145
  return {
14839
- applied: result_0.applied,
14840
- skipped: result_0.skipped
15146
+ applied: result_1.applied,
15147
+ skipped: result_1.skipped
14841
15148
  };
14842
15149
  },
14843
15150
  activeSuggestionIds: () => {
14844
- const view_35 = pagedEditorRef.current?.getView();
14845
- 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) : []);
14846
15153
  }
14847
15154
  }),
14848
15155
  acceptSuggestion: (suggestionId, options_3) => {
14849
- const view_36 = pagedEditorRef.current?.getView();
14850
- if (!view_36) return {
15156
+ const view_37 = pagedEditorRef.current?.getView();
15157
+ if (!view_37) return {
14851
15158
  accepted: false,
14852
15159
  appliedAs: null
14853
15160
  };
14854
- const appliedAs = getSuggestions(view_36.state).find((s_4) => s_4.suggestionId === suggestionId)?.appliedAs ?? null;
14855
- 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);
14856
15163
  return {
14857
15164
  accepted,
14858
15165
  appliedAs: accepted ? appliedAs : null
14859
15166
  };
14860
15167
  },
14861
15168
  rejectSuggestion: (suggestionId_0) => {
14862
- const view_37 = pagedEditorRef.current?.getView();
14863
- if (!view_37) return false;
14864
- return rejectSuggestion(suggestionId_0)(view_37.state, view_37.dispatch);
14865
- },
14866
- scrollToSuggestion: (suggestionId_1) => {
14867
15169
  const view_38 = pagedEditorRef.current?.getView();
14868
15170
  if (!view_38) return false;
14869
- 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);
14870
15177
  if (!range_5) return false;
14871
- const { from: from_12, to: to_12 } = clampRangeToDocSize(view_38.state.doc.content.size, range_5);
14872
- const $from_3 = view_38.state.doc.resolve(from_12);
14873
- const $to_3 = view_38.state.doc.resolve(to_12);
14874
- 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)));
14875
15182
  requestAnimationFrame(() => {
14876
15183
  pagedEditorRef.current?.scrollToPosition(from_12);
14877
15184
  });
14878
15185
  return true;
14879
15186
  },
14880
15187
  getTrackedChanges: () => {
14881
- const view_39 = pagedEditorRef.current?.getView();
14882
- return view_39 ? getTrackedChangesFromDoc(view_39.state.doc) : [];
14883
- },
14884
- getCommentAnchors: () => {
14885
15188
  const view_40 = pagedEditorRef.current?.getView();
14886
- return view_40 ? getCommentAnchorsFromDoc(view_40.state.doc) : [];
15189
+ return view_40 ? getTrackedChangesFromDoc(view_40.state.doc) : [];
14887
15190
  },
14888
- getSelectionText: () => {
15191
+ getCommentAnchors: () => {
14889
15192
  const view_41 = pagedEditorRef.current?.getView();
14890
- return view_41 ? getSelectedText(view_41.state) : "";
15193
+ return view_41 ? getCommentAnchorsFromDoc(view_41.state.doc) : [];
14891
15194
  },
14892
- getPageText: (page_1) => {
15195
+ getSelectionText: () => {
14893
15196
  const view_42 = pagedEditorRef.current?.getView();
14894
- if (!view_42) return null;
14895
- return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_42.state.doc, page_1);
15197
+ return view_42 ? getSelectedText(view_42.state) : "";
14896
15198
  },
14897
- getTargetPage: (target_2, snapshot_5) => {
15199
+ getPageText: (page_1) => {
14898
15200
  const view_43 = pagedEditorRef.current?.getView();
14899
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;
14900
15207
  const range_6 = target_2.type === "textRange" ? resolveFolioAITextRange({
14901
15208
  range: target_2,
14902
- doc: view_43.state.doc,
14903
- snapshot: snapshot_5
15209
+ doc: view_44.state.doc,
15210
+ snapshot: snapshot_6
14904
15211
  }) : resolveFolioAIBlockRange({
14905
15212
  blockId: target_2.blockId,
14906
- doc: view_43.state.doc,
14907
- snapshot: snapshot_5
15213
+ doc: view_44.state.doc,
15214
+ snapshot: snapshot_6
14908
15215
  });
14909
15216
  if (range_6 === null) return null;
14910
15217
  return pagedEditorRef.current?.getPageNumberForPmPos(range_6.from) ?? null;
@@ -14914,49 +15221,49 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14914
15221
  getScrollRoot: () => pagedEditorRef.current?.getScrollRoot() ?? null,
14915
15222
  onLayoutChange: (listener) => pagedEditorRef.current?.onLayoutChange(listener) ?? (() => {}),
14916
15223
  getContentControls: (filter = {}) => {
14917
- const view_44 = pagedEditorRef.current?.getView();
14918
- if (!view_44) return [];
14919
- 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) => ({
14920
15227
  properties: blockSdtAttrsToSdtProperties(match_0.node),
14921
15228
  path: match_0.path,
14922
15229
  pmPos: match_0.pos
14923
15230
  }));
14924
15231
  },
14925
15232
  scrollToContentControl: (filter_0) => {
14926
- const view_45 = pagedEditorRef.current?.getView();
14927
- if (!view_45) return false;
14928
- 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);
14929
15236
  if (!match_1) return false;
14930
15237
  const inside = match_1.pos + 1;
14931
- const $pos = view_45.state.doc.resolve(inside);
14932
- 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)));
14933
15240
  requestAnimationFrame(() => {
14934
15241
  pagedEditorRef.current?.scrollToPosition(inside);
14935
15242
  });
14936
15243
  return true;
14937
15244
  },
14938
15245
  setContentControlContent: (filter_1, input, options_4 = {}) => {
14939
- const view_46 = pagedEditorRef.current?.getView();
14940
- if (!view_46) return false;
14941
- 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);
14942
15249
  if (!tr_0) return false;
14943
- view_46.dispatch(tr_0);
15250
+ view_47.dispatch(tr_0);
14944
15251
  return true;
14945
15252
  },
14946
15253
  setContentControlValue: (filter_2, input_0, options_5 = {}) => {
14947
- const view_47 = pagedEditorRef.current?.getView();
14948
- if (!view_47) return false;
14949
- 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);
14950
15257
  if (!tr_1) return false;
14951
- view_47.dispatch(tr_1);
15258
+ view_48.dispatch(tr_1);
14952
15259
  return true;
14953
15260
  },
14954
15261
  removeContentControl: (filter_3, options_6 = {}) => {
14955
- const view_48 = pagedEditorRef.current?.getView();
14956
- if (!view_48) return false;
14957
- 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);
14958
15265
  if (!tr_2) return false;
14959
- view_48.dispatch(tr_2);
15266
+ view_49.dispatch(tr_2);
14960
15267
  return true;
14961
15268
  }
14962
15269
  }), [
@@ -14977,7 +15284,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14977
15284
  commentsRef,
14978
15285
  commentsDirtyRef,
14979
15286
  getActiveEditorStory,
14980
- refreshBodyHistoryAvailability
15287
+ refreshBodyHistoryAvailability,
15288
+ experimentalSession
14981
15289
  ]);
14982
15290
  const getHfTargetElement = useCallback((pos_0) => {
14983
15291
  const pagesContainer = containerRef.current?.querySelector(".paged-editor__pages");
@@ -14990,6 +15298,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14990
15298
  label: t(DISPLAY_MODE_LABEL_KEYS[mode_0])
14991
15299
  })), [t]);
14992
15300
  const activeHistoryAvailability = (() => {
15301
+ if (usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting)) return {
15302
+ canRedo: pagedEditorRef.current?.canRedo() ?? false,
15303
+ canUndo: pagedEditorRef.current?.canUndo() ?? false
15304
+ };
14993
15305
  if (activeNoteStory) return {
14994
15306
  canRedo: pagedEditorRef.current?.canRedo() ?? false,
14995
15307
  canUndo: pagedEditorRef.current?.canUndo() ?? false
@@ -15041,39 +15353,47 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15041
15353
  if (isDisplayMode(value)) setDisplayMode(value);
15042
15354
  }, [setDisplayMode]);
15043
15355
  const handleAcceptActiveChange = useCallback(() => {
15044
- const view_49 = pagedEditorRef.current?.getView();
15045
- if (!view_49) return;
15046
- const { from: from_13, to: to_13 } = view_49.state.selection;
15047
- const range_7 = findChangeAtPosition(view_49.state, from_13, to_13);
15048
- acceptChange(range_7.from, range_7.to)(view_49.state, view_49.dispatch);
15049
- }, []);
15050
- const handleRejectActiveChange = useCallback(() => {
15051
15356
  const view_50 = pagedEditorRef.current?.getView();
15052
15357
  if (!view_50) return;
15053
- const { from: from_14, to: to_14 } = view_50.state.selection;
15054
- const range_8 = findChangeAtPosition(view_50.state, from_14, to_14);
15055
- rejectChange(range_8.from, range_8.to)(view_50.state, view_50.dispatch);
15358
+ const { from: from_13, to: to_13 } = view_50.state.selection;
15359
+ const range_7 = findChangeAtPosition(view_50.state, from_13, to_13);
15360
+ if (resolveCanonicalReviewRange({
15361
+ editor: pagedEditorRef.current?.getEditor(),
15362
+ ...range_7,
15363
+ resolution: "accept"
15364
+ }) === null) acceptChange(range_7.from, range_7.to)(view_50.state, view_50.dispatch);
15056
15365
  }, []);
15057
- const handlePreviousChange = useCallback(() => {
15366
+ const handleRejectActiveChange = useCallback(() => {
15058
15367
  const view_51 = pagedEditorRef.current?.getView();
15059
15368
  if (!view_51) return;
15060
- const { from: from_15 } = view_51.state.selection;
15061
- const change = findPreviousChange(view_51.state, from_15);
15369
+ const { from: from_14, to: to_14 } = view_51.state.selection;
15370
+ const range_8 = findChangeAtPosition(view_51.state, from_14, to_14);
15371
+ if (resolveCanonicalReviewRange({
15372
+ editor: pagedEditorRef.current?.getEditor(),
15373
+ ...range_8,
15374
+ resolution: "reject"
15375
+ }) === null) rejectChange(range_8.from, range_8.to)(view_51.state, view_51.dispatch);
15376
+ }, []);
15377
+ const handlePreviousChange = useCallback(() => {
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);
15062
15382
  if (!change) return;
15063
- view_51.dispatch(view_51.state.tr.setSelection(TextSelection.create(view_51.state.doc, change.from, change.to)));
15064
- 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();
15065
15385
  requestAnimationFrame(() => {
15066
15386
  pagedEditorRef.current?.scrollToPosition(change.from);
15067
15387
  });
15068
15388
  }, []);
15069
15389
  const handleNextChange = useCallback(() => {
15070
- const view_52 = pagedEditorRef.current?.getView();
15071
- if (!view_52) return;
15072
- const { to: to_15 } = view_52.state.selection;
15073
- 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);
15074
15394
  if (!change_0) return;
15075
- view_52.dispatch(view_52.state.tr.setSelection(TextSelection.create(view_52.state.doc, change_0.from, change_0.to)));
15076
- 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();
15077
15397
  requestAnimationFrame(() => {
15078
15398
  pagedEditorRef.current?.scrollToPosition(change_0.from);
15079
15399
  });
@@ -15243,39 +15563,45 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15243
15563
  requestAnimationFrame(syncCommentHighlightStyles);
15244
15564
  }, [onScrollTopChange, syncCommentHighlightStyles]);
15245
15565
  const handlePagedSelectionChange = useCallback((_from, _to) => {
15246
- const view_53 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
15247
- 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);
15248
15568
  }, [getActiveEditorView, handleSelectionChange]);
15249
15569
  const handleTotalPagesChange = useCallback((totalPages) => {
15250
15570
  setScrollPageInfo((previous) => updateScrollPageTotal(previous, totalPages));
15251
15571
  }, [setScrollPageInfo]);
15252
15572
  const handleCommentClick = useCallback((id) => setActiveCommentId(id), [setActiveCommentId]);
15253
15573
  const handleCommentResolve = useCallback((id_0) => {
15574
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15254
15575
  updateComments((previous_0) => previous_0.map((comment_2) => comment_2.id === id_0 ? {
15255
15576
  ...comment_2,
15256
15577
  done: true
15257
15578
  } : comment_2));
15258
- }, [updateComments]);
15579
+ }, [refuseCanonicalModelEdit, updateComments]);
15259
15580
  const handleCommentDelete = useCallback((id_1) => {
15581
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15260
15582
  updateComments((previous_1) => previous_1.filter((comment_3) => comment_3.id !== id_1 && comment_3.parentId !== id_1));
15261
15583
  if (activeCommentId === id_1) setActiveCommentId(null);
15262
15584
  }, [
15263
15585
  activeCommentId,
15586
+ refuseCanonicalModelEdit,
15264
15587
  setActiveCommentId,
15265
15588
  updateComments
15266
15589
  ]);
15267
15590
  const handleCommentReply = useCallback((id_2, text_6) => {
15591
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15268
15592
  updateComments((previous_2) => [...previous_2, createComment(text_6, author, id_2)]);
15269
15593
  }, [
15270
15594
  author,
15271
15595
  createComment,
15596
+ refuseCanonicalModelEdit,
15272
15597
  updateComments
15273
15598
  ]);
15274
15599
  const handleAddComment = useCallback((addText) => {
15600
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return false;
15275
15601
  const comment_4 = createComment(addText, author);
15276
- const view_54 = pagedEditorRef.current?.getView();
15277
- if (!view_54 || !commentSelectionRange) return false;
15278
- 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;
15279
15605
  const commentAuthor_2 = getCommentAuthorKey(comment_4.author);
15280
15606
  setVisibleCommentAuthors((current_0) => {
15281
15607
  if (current_0 === null) return null;
@@ -15298,6 +15624,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15298
15624
  author,
15299
15625
  commentSelectionRange,
15300
15626
  createComment,
15627
+ refuseCanonicalModelEdit,
15301
15628
  setActiveCommentId,
15302
15629
  setAddCommentYPosition,
15303
15630
  setCommentSelectionRange,
@@ -15307,15 +15634,17 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15307
15634
  updateComments
15308
15635
  ]);
15309
15636
  const handleTrackedChangeReply = useCallback((revisionId_2, text_7) => {
15637
+ if (refuseCanonicalModelEdit(CANONICAL_GAP.comments, "Comment changes are unavailable in this session.")) return;
15310
15638
  updateComments((previous_4) => [...previous_4, createComment(text_7, author, revisionId_2)]);
15311
15639
  }, [
15312
15640
  author,
15313
15641
  createComment,
15642
+ refuseCanonicalModelEdit,
15314
15643
  updateComments
15315
15644
  ]);
15316
15645
  const handleCancelAddComment = useCallback(() => {
15317
- const view_55 = pagedEditorRef.current?.getView();
15318
- if (view_55 && commentSelectionRange) removePendingCommentMarkRange(view_55, commentSelectionRange);
15646
+ const view_56 = pagedEditorRef.current?.getView();
15647
+ if (view_56 && commentSelectionRange) removePendingCommentMarkRange(view_56, commentSelectionRange);
15319
15648
  setIsAddingComment(false);
15320
15649
  setCommentSelectionRange(null);
15321
15650
  setAddCommentYPosition(null);
@@ -15331,19 +15660,23 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15331
15660
  })?.revisionId ?? null;
15332
15661
  }, []);
15333
15662
  const handleSidebarAcceptChange = useCallback((from_17, to_17) => {
15334
- const view_56 = pagedEditorRef.current?.getView();
15335
- if (!view_56) return;
15663
+ const view_57 = pagedEditorRef.current?.getView();
15664
+ if (!view_57) return;
15336
15665
  const revisionId_3 = resolveSidebarChangeRevisionId(from_17, to_17);
15337
15666
  if (revisionId_3 === null) return;
15338
- 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);
15339
15670
  extractTrackedChanges();
15340
15671
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
15341
15672
  const handleSidebarRejectChange = useCallback((from_18, to_18) => {
15342
- const view_57 = pagedEditorRef.current?.getView();
15343
- if (!view_57) return;
15673
+ const view_58 = pagedEditorRef.current?.getView();
15674
+ if (!view_58) return;
15344
15675
  const revisionId_4 = resolveSidebarChangeRevisionId(from_18, to_18);
15345
15676
  if (revisionId_4 === null) return;
15346
- 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);
15347
15680
  extractTrackedChanges();
15348
15681
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
15349
15682
  const commentsPageWidth = history.state?.package.document.finalSectionProperties?.pageWidth;
@@ -15486,8 +15819,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15486
15819
  }, [readOnly]);
15487
15820
  const closeTableProperties = useCallback(() => setTablePropsOpen(false), []);
15488
15821
  const applyTableProperties = useCallback((props_0) => {
15489
- const view_58 = getActiveEditorView();
15490
- 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);
15491
15824
  }, [getActiveEditorView]);
15492
15825
  const closeImagePosition = useCallback(() => setImagePositionOpen(false), [setImagePositionOpen]);
15493
15826
  const closeImageProperties = useCallback(() => setImagePropsOpen(false), [setImagePropsOpen]);
@@ -15495,8 +15828,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15495
15828
  const closeFootnoteProperties = useCallback(() => setFootnotePropsOpen(false), []);
15496
15829
  const closeInsertSymbol = useCallback(() => setShowInsertSymbol(false), []);
15497
15830
  const insertSymbol = useCallback((symbol) => {
15498
- const view_59 = getActiveEditorView();
15499
- 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());
15500
15833
  }, [getActiveEditorView]);
15501
15834
  const imagePropertiesCurrentData = useMemo(() => buildImagePropertiesData(state.pmImageContext), [state.pmImageContext]);
15502
15835
  const currentFindResult = findResultRef.current;
@@ -15579,8 +15912,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15579
15912
  ]);
15580
15913
  const closeNumberingValueDialog = useCallback(() => setNumberingValueDialogOpen(false), []);
15581
15914
  const applyNumberingValue = useCallback((value_0) => {
15582
- const view_60 = getActiveEditorView();
15583
- 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);
15584
15917
  }, [getActiveEditorView]);
15585
15918
  const numberingValueDialog = useMemo(() => ({
15586
15919
  isOpen: numberingValueDialogOpen,
@@ -15662,7 +15995,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15662
15995
  onError: handleEditorError,
15663
15996
  children: /* @__PURE__ */ jsxs("div", {
15664
15997
  ref: containerRef,
15665
- className: `folio-root folio-editor${displayMode !== "all-markup" ? ` folio-root--${displayMode}` : ""}${showHeaderFooterEditing ? "" : " folio-no-hf-edit"} ${className}`,
15998
+ className: `folio-root folio-editor${displayMode !== "all-markup" ? ` folio-root--${displayMode}` : ""}${canEditHeaderFooter ? "" : " folio-no-hf-edit"} ${className}`,
15666
15999
  style: containerStyle,
15667
16000
  "data-testid": "folio-editor",
15668
16001
  "data-folio-format-painter": formatPainterMode !== "off" ? "armed" : void 0,
@@ -15832,9 +16165,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15832
16165
  firstPageHeaderContentRId: activeFirstHeaderRId,
15833
16166
  firstPageFooterContentRId: activeFirstFooterRId,
15834
16167
  ...history.state.package.styles ? { styles: history.state.package.styles } : {},
15835
- onHeaderFooterDoubleClick: showHeaderFooterEditing ? handleHeaderFooterStoryOpen : void 0,
15836
- hfEditMode: hfEditPosition,
15837
- activeHeaderFooterRId: activeHfRId,
16168
+ onHeaderFooterDoubleClick: handleHeaderFooterStoryOpen,
16169
+ hfEditMode: canEditHeaderFooter ? hfEditPosition : null,
16170
+ activeHeaderFooterRId: canEditHeaderFooter ? activeHfRId : null,
15838
16171
  onBodyClick: handleBodyClick,
15839
16172
  onActiveNoteStoryChange: handleActiveNoteStoryChange,
15840
16173
  zoom,
@@ -15842,6 +16175,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15842
16175
  showMarginGuides,
15843
16176
  ...marginGuideColor !== void 0 ? { marginGuideColor } : {},
15844
16177
  readOnly,
16178
+ ...!usesCanonicalSession(experimentalSession, CANONICAL_GAP.authorityRouting) ? {} : { experimentalSession },
15845
16179
  onDocumentChange: handleDocumentChange,
15846
16180
  extensionManager,
15847
16181
  suggestionModeActive: editingMode === "suggesting",
@@ -15878,8 +16212,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15878
16212
  onMouseDown: (e_1) => {
15879
16213
  e_1.preventDefault();
15880
16214
  e_1.stopPropagation();
15881
- const view_61 = pagedEditorRef.current?.getView();
15882
- if (!view_61) {
16215
+ const view_62 = pagedEditorRef.current?.getView();
16216
+ if (!view_62) {
15883
16217
  setFloatingCommentBtn(null);
15884
16218
  return;
15885
16219
  }
@@ -15887,9 +16221,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15887
16221
  from: floatingCommentBtn.from,
15888
16222
  to: floatingCommentBtn.to
15889
16223
  };
15890
- const currentSelection = view_61.state.selection;
16224
+ const currentSelection = view_62.state.selection;
15891
16225
  const safeRange = resolveCommentCreationRange({
15892
- docSize: view_61.state.doc.content.size,
16226
+ docSize: view_62.state.doc.content.size,
15893
16227
  capturedRange,
15894
16228
  currentRange: {
15895
16229
  from: currentSelection.from,
@@ -15903,7 +16237,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15903
16237
  return;
15904
16238
  }
15905
16239
  setCommentSelectionRange(safeRange);
15906
- if (!applyCommentMarkRange(view_61, safeRange, -1, { selectEnd: true })) {
16240
+ if (!applyCommentMarkRange(view_62, safeRange, -1, { selectEnd: true })) {
15907
16241
  setCommentSelectionRange(null);
15908
16242
  setFloatingCommentBtn(null);
15909
16243
  return;
@@ -15950,7 +16284,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15950
16284
  children: /* @__PURE__ */ jsx(SquarePenIcon, { size: 16 })
15951
16285
  })
15952
16286
  }),
15953
- hfEditPosition && (() => {
16287
+ canEditHeaderFooter && hfEditPosition && (() => {
15954
16288
  if (!(() => {
15955
16289
  if (hfEditIsFirstPage) return (() => {
15956
16290
  if (hfEditPosition === "header") return firstPageHeaderContent;