@superdoc-dev/cli 0.8.0-next.19 → 0.8.0-next.20

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 (2) hide show
  1. package/dist/index.js +1774 -260
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -4129,7 +4129,7 @@ More content with **bold** and *italic*.`
4129
4129
  },
4130
4130
  "history.get": {
4131
4131
  memberPath: "history.get",
4132
- description: "Query the current undo/redo history state of the active editor.",
4132
+ description: "Query the current undo/redo history state of the document.",
4133
4133
  expectedResult: "Returns a HistoryState object with undoDepth, redoDepth, canUndo, canRedo, and a list of history-unsafe operations.",
4134
4134
  requiresDocumentContext: true,
4135
4135
  metadata: readOperation({
@@ -4140,7 +4140,7 @@ More content with **bold** and *italic*.`
4140
4140
  },
4141
4141
  "history.undo": {
4142
4142
  memberPath: "history.undo",
4143
- description: "Undo the most recent history-safe mutation in the active editor.",
4143
+ description: "Undo the most recent history-safe mutation in the document.",
4144
4144
  expectedResult: "Returns a HistoryActionResult with noop flag, reason (EMPTY_UNDO_STACK | NO_EFFECT when noop), and revision before/after.",
4145
4145
  requiresDocumentContext: true,
4146
4146
  metadata: mutationOperation({
@@ -4157,7 +4157,7 @@ More content with **bold** and *italic*.`
4157
4157
  },
4158
4158
  "history.redo": {
4159
4159
  memberPath: "history.redo",
4160
- description: "Redo the most recently undone action in the active editor.",
4160
+ description: "Redo the most recently undone action in the document.",
4161
4161
  expectedResult: "Returns a HistoryActionResult with noop flag, reason (EMPTY_REDO_STACK | NO_EFFECT when noop), and revision before/after.",
4162
4162
  requiresDocumentContext: true,
4163
4163
  metadata: mutationOperation({
@@ -65610,7 +65610,7 @@ var init_remark_gfm_BhnWr3yf_es = __esm(() => {
65610
65610
  emptyOptions2 = {};
65611
65611
  });
65612
65612
 
65613
- // ../../packages/superdoc/dist/chunks/SuperConverter-Dn6cDET4.es.js
65613
+ // ../../packages/superdoc/dist/chunks/SuperConverter-2Pu0hMB1.es.js
65614
65614
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
65615
65615
  const fieldValue = extension$1.config[field];
65616
65616
  if (typeof fieldValue === "function")
@@ -117890,7 +117890,7 @@ var isRegExp = (value) => {
117890
117890
  state.kern = kernNode.attributes["w:val"];
117891
117891
  }
117892
117892
  }, SuperConverter;
117893
- var init_SuperConverter_Dn6cDET4_es = __esm(() => {
117893
+ var init_SuperConverter_2Pu0hMB1_es = __esm(() => {
117894
117894
  init_rolldown_runtime_Bg48TavK_es();
117895
117895
  init_jszip_C49i9kUs_es();
117896
117896
  init_xml_js_CqGKpaft_es();
@@ -123804,7 +123804,7 @@ var init_SuperConverter_Dn6cDET4_es = __esm(() => {
123804
123804
  },
123805
123805
  "history.get": {
123806
123806
  memberPath: "history.get",
123807
- description: "Query the current undo/redo history state of the active editor.",
123807
+ description: "Query the current undo/redo history state of the document.",
123808
123808
  expectedResult: "Returns a HistoryState object with undoDepth, redoDepth, canUndo, canRedo, and a list of history-unsafe operations.",
123809
123809
  requiresDocumentContext: true,
123810
123810
  metadata: readOperation2({ idempotency: "idempotent" }),
@@ -123813,7 +123813,7 @@ var init_SuperConverter_Dn6cDET4_es = __esm(() => {
123813
123813
  },
123814
123814
  "history.undo": {
123815
123815
  memberPath: "history.undo",
123816
- description: "Undo the most recent history-safe mutation in the active editor.",
123816
+ description: "Undo the most recent history-safe mutation in the document.",
123817
123817
  expectedResult: "Returns a HistoryActionResult with noop flag, reason (EMPTY_UNDO_STACK | NO_EFFECT when noop), and revision before/after.",
123818
123818
  requiresDocumentContext: true,
123819
123819
  metadata: mutationOperation2({
@@ -123830,7 +123830,7 @@ var init_SuperConverter_Dn6cDET4_es = __esm(() => {
123830
123830
  },
123831
123831
  "history.redo": {
123832
123832
  memberPath: "history.redo",
123833
- description: "Redo the most recently undone action in the active editor.",
123833
+ description: "Redo the most recently undone action in the document.",
123834
123834
  expectedResult: "Returns a HistoryActionResult with noop flag, reason (EMPTY_REDO_STACK | NO_EFFECT when noop), and revision before/after.",
123835
123835
  requiresDocumentContext: true,
123836
123836
  metadata: mutationOperation2({
@@ -155319,7 +155319,7 @@ var init_SuperConverter_Dn6cDET4_es = __esm(() => {
155319
155319
  };
155320
155320
  });
155321
155321
 
155322
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-CQu_F9Mr.es.js
155322
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-sMwtuYL8.es.js
155323
155323
  function parseSizeUnit(val = "0") {
155324
155324
  const length3 = val.toString() || "0";
155325
155325
  const value = Number.parseFloat(length3);
@@ -156919,6 +156919,14 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
156919
156919
  comment: change.comment ?? null
156920
156920
  }) !== false;
156921
156921
  });
156922
+ }, resolveSurfaceFromDocumentId = (documentId) => {
156923
+ if (typeof documentId !== "string" || documentId.length === 0)
156924
+ return "body";
156925
+ if (documentId.startsWith("footnote:") || documentId.startsWith("fn:"))
156926
+ return "note";
156927
+ if (documentId.startsWith("endnote:") || documentId.startsWith("en:"))
156928
+ return "endnote";
156929
+ return "body";
156922
156930
  }, resolveSurface = (activeEditor) => {
156923
156931
  if (activeEditor?.options?.isHeaderOrFooter) {
156924
156932
  const headerFooterType = activeEditor.options?.headerFooterType;
@@ -156927,7 +156935,7 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
156927
156935
  if (headerFooterType === "header")
156928
156936
  return "header";
156929
156937
  }
156930
- return "body";
156938
+ return resolveSurfaceFromDocumentId(activeEditor?.options?.documentId);
156931
156939
  }, resolveSelectionEmpty = (editor) => {
156932
156940
  return editor.state?.selection?.empty ?? true;
156933
156941
  }, createEditorToolbarTarget = (editor) => {
@@ -156941,7 +156949,11 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
156941
156949
  doc: editor.getActiveEditor()?.doc
156942
156950
  };
156943
156951
  }, resolvePresentationEditor = (superdoc) => {
156944
- const documentId = superdoc.activeEditor?.options?.documentId;
156952
+ const activeEditor = superdoc.activeEditor ?? null;
156953
+ const directPresentationEditor = activeEditor?.presentationEditor ?? activeEditor?._presentationEditor ?? null;
156954
+ if (directPresentationEditor)
156955
+ return directPresentationEditor;
156956
+ const documentId = activeEditor?.options?.documentId;
156945
156957
  if (!documentId)
156946
156958
  return null;
156947
156959
  return (superdoc.superdocStore?.documents ?? []).find((doc2) => doc2.getEditor?.()?.options?.documentId === documentId)?.getPresentationEditor?.() ?? null;
@@ -157033,10 +157045,14 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
157033
157045
  presentationEditor.on("headerFooterEditingContext", onChange3);
157034
157046
  presentationEditor.on("headerFooterUpdate", onChange3);
157035
157047
  presentationEditor.on("headerFooterTransaction", onChange3);
157048
+ presentationEditor.on("activeSurfaceChange", onChange3);
157049
+ presentationEditor.on("historyStateChange", onChange3);
157036
157050
  return () => {
157037
157051
  presentationEditor.off?.("headerFooterEditingContext", onChange3);
157038
157052
  presentationEditor.off?.("headerFooterUpdate", onChange3);
157039
157053
  presentationEditor.off?.("headerFooterTransaction", onChange3);
157054
+ presentationEditor.off?.("activeSurfaceChange", onChange3);
157055
+ presentationEditor.off?.("historyStateChange", onChange3);
157040
157056
  };
157041
157057
  }, subscribeToolbarEvents = (options, onChange3) => {
157042
157058
  const { activeEditor: editor, presentationEditor } = resolveToolbarSources(options.superdoc);
@@ -157090,7 +157106,18 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
157090
157106
  return false;
157091
157107
  const result = payload === undefined ? command() : command(payload);
157092
157108
  return Boolean(result);
157109
+ }, readCoordinatorDepths = (context) => {
157110
+ const state = context?.presentationEditor?.getHistoryState?.();
157111
+ if (!state)
157112
+ return null;
157113
+ return {
157114
+ undoDepth: state.undoDepth,
157115
+ redoDepth: state.redoDepth
157116
+ };
157093
157117
  }, getCurrentUndoDepth = (context) => {
157118
+ const coordinatorDepths = readCoordinatorDepths(context);
157119
+ if (coordinatorDepths)
157120
+ return coordinatorDepths.undoDepth;
157094
157121
  const stateEditor = resolveStateEditor(context);
157095
157122
  if (!stateEditor?.state)
157096
157123
  return 0;
@@ -157102,6 +157129,9 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
157102
157129
  return 0;
157103
157130
  }
157104
157131
  }, getCurrentRedoDepth = (context) => {
157132
+ const coordinatorDepths = readCoordinatorDepths(context);
157133
+ if (coordinatorDepths)
157134
+ return coordinatorDepths.redoDepth;
157105
157135
  const stateEditor = resolveStateEditor(context);
157106
157136
  if (!stateEditor?.state)
157107
157137
  return 0;
@@ -157911,8 +157941,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
157911
157941
  }
157912
157942
  };
157913
157943
  };
157914
- var init_create_headless_toolbar_CQu_F9Mr_es = __esm(() => {
157915
- init_SuperConverter_Dn6cDET4_es();
157944
+ var init_create_headless_toolbar_sMwtuYL8_es = __esm(() => {
157945
+ init_SuperConverter_2Pu0hMB1_es();
157916
157946
  init_constants_CGhJRd87_es();
157917
157947
  init_dist_B8HfvhaK_es();
157918
157948
  CSS_DIMENSION_REGEX = /[\d-.]+(\w+)$/;
@@ -187258,7 +187288,7 @@ var require_runtime_core_cjs = __commonJS((exports) => {
187258
187288
  function devtoolsInitApp(app, version4) {
187259
187289
  emit$1("app:init", app, version4, {
187260
187290
  Fragment: Fragment3,
187261
- Text,
187291
+ Text: Text2,
187262
187292
  Comment,
187263
187293
  Static
187264
187294
  });
@@ -188386,7 +188416,7 @@ var require_runtime_core_cjs = __commonJS((exports) => {
188386
188416
  }
188387
188417
  let nextNode = null;
188388
188418
  switch (type) {
188389
- case Text:
188419
+ case Text2:
188390
188420
  if (domType !== 3) {
188391
188421
  if (vnode.children === "") {
188392
188422
  insert(vnode.el = createText(""), parentNode2(node3), node3);
@@ -188581,10 +188611,10 @@ Server rendered element contains more child nodes than client vdom.`);
188581
188611
  let hasWarned2 = false;
188582
188612
  for (let i4 = 0;i4 < l; i4++) {
188583
188613
  const vnode = optimized ? children[i4] : children[i4] = normalizeVNode(children[i4]);
188584
- const isText = vnode.type === Text;
188614
+ const isText = vnode.type === Text2;
188585
188615
  if (node3) {
188586
188616
  if (isText && !optimized) {
188587
- if (i4 + 1 < l && normalizeVNode(children[i4 + 1]).type === Text) {
188617
+ if (i4 + 1 < l && normalizeVNode(children[i4 + 1]).type === Text2) {
188588
188618
  insert(createText(node3.data.slice(vnode.children.length)), container, nextSibling(node3));
188589
188619
  node3.data = vnode.children;
188590
188620
  }
@@ -191418,7 +191448,7 @@ If you want to remount the same app, move your app creation logic into a factory
191418
191448
  }
191419
191449
  const { type, ref: ref3, shapeFlag } = n2;
191420
191450
  switch (type) {
191421
- case Text:
191451
+ case Text2:
191422
191452
  processText(n1, n2, container, anchor);
191423
191453
  break;
191424
191454
  case Comment:
@@ -192425,7 +192455,7 @@ If you want to remount the same app, move your app creation logic into a factory
192425
192455
  if (!shallow3 && c2.patchFlag !== -2)
192426
192456
  traverseStaticChildren(c1, c2);
192427
192457
  }
192428
- if (c2.type === Text) {
192458
+ if (c2.type === Text2) {
192429
192459
  if (c2.patchFlag === -1) {
192430
192460
  c2 = ch2[i4] = cloneIfMounted(c2);
192431
192461
  }
@@ -192902,7 +192932,7 @@ If you want to remount the same app, move your app creation logic into a factory
192902
192932
  return suspensible != null && suspensible !== false;
192903
192933
  }
192904
192934
  var Fragment3 = /* @__PURE__ */ Symbol.for("v-fgt");
192905
- var Text = /* @__PURE__ */ Symbol.for("v-txt");
192935
+ var Text2 = /* @__PURE__ */ Symbol.for("v-txt");
192906
192936
  var Comment = /* @__PURE__ */ Symbol.for("v-cmt");
192907
192937
  var Static = /* @__PURE__ */ Symbol.for("v-stc");
192908
192938
  var blockStack = [];
@@ -193112,7 +193142,7 @@ Component that was made reactive: `, type);
193112
193142
  return cloned;
193113
193143
  }
193114
193144
  function createTextVNode(text4 = " ", flag = 0) {
193115
- return createVNode(Text, null, text4, flag);
193145
+ return createVNode(Text2, null, text4, flag);
193116
193146
  }
193117
193147
  function createStaticVNode(content2, numberOfNodes) {
193118
193148
  const vnode = createVNode(Static, null, content2);
@@ -193130,7 +193160,7 @@ Component that was made reactive: `, type);
193130
193160
  } else if (isVNode(child)) {
193131
193161
  return cloneIfMounted(child);
193132
193162
  } else {
193133
- return createVNode(Text, null, String(child));
193163
+ return createVNode(Text2, null, String(child));
193134
193164
  }
193135
193165
  }
193136
193166
  function cloneIfMounted(child) {
@@ -193901,7 +193931,7 @@ Component that was made reactive: `, type);
193901
193931
  exports.Static = Static;
193902
193932
  exports.Suspense = Suspense;
193903
193933
  exports.Teleport = Teleport;
193904
- exports.Text = Text;
193934
+ exports.Text = Text2;
193905
193935
  exports.assertNumber = assertNumber;
193906
193936
  exports.callWithAsyncErrorHandling = callWithAsyncErrorHandling;
193907
193937
  exports.callWithErrorHandling = callWithErrorHandling;
@@ -206599,7 +206629,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
206599
206629
  init_remark_gfm_BhnWr3yf_es();
206600
206630
  });
206601
206631
 
206602
- // ../../packages/superdoc/dist/chunks/src-CLao-BLx.es.js
206632
+ // ../../packages/superdoc/dist/chunks/src-CjxSHf0p.es.js
206603
206633
  function deleteProps(obj, propOrProps) {
206604
206634
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
206605
206635
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -237366,36 +237396,39 @@ function tablesSetBordersWrapper(editor, input2, options) {
237366
237396
  function tablesSetTableOptionsWrapper(editor, input2, options) {
237367
237397
  return executeTableCommand(editor, "tables.setTableOptions", tablesSetTableOptionsAdapter, input2, options);
237368
237398
  }
237369
- function isCollabHistory(editor) {
237370
- return Boolean(editor.options.collaborationProvider && editor.options.ydoc);
237399
+ function getRootPresentationHistoryOwner(editor) {
237400
+ const withPresentation = editor;
237401
+ const presentationEditor = withPresentation.presentationEditor ?? withPresentation._presentationEditor ?? null;
237402
+ if (!presentationEditor)
237403
+ return null;
237404
+ if (presentationEditor.editor !== editor)
237405
+ return null;
237406
+ return presentationEditor;
237371
237407
  }
237372
- function getUndoDepth(editor) {
237373
- if (!editor.state)
237374
- return 0;
237375
- try {
237376
- if (isCollabHistory(editor))
237377
- return yUndoPluginKey.getState(editor.state)?.undoManager?.undoStack?.length ?? 0;
237378
- return undoDepth(editor.state);
237379
- } catch {
237380
- return 0;
237408
+ function readHistoryDepths(editor) {
237409
+ const presentationOwner = getRootPresentationHistoryOwner(editor);
237410
+ if (presentationOwner) {
237411
+ const state = presentationOwner.getHistoryState();
237412
+ return {
237413
+ undoDepth: state.undoDepth,
237414
+ redoDepth: state.redoDepth
237415
+ };
237381
237416
  }
237417
+ return readEditorHistorySnapshot(editor);
237382
237418
  }
237383
- function getRedoDepth(editor) {
237384
- if (!editor.state)
237385
- return 0;
237386
- try {
237387
- if (isCollabHistory(editor))
237388
- return yUndoPluginKey.getState(editor.state)?.undoManager?.redoStack?.length ?? 0;
237389
- return redoDepth(editor.state);
237390
- } catch {
237391
- return 0;
237392
- }
237419
+ function runHistoryCommand(editor, action) {
237420
+ const presentationOwner = getRootPresentationHistoryOwner(editor);
237421
+ if (presentationOwner)
237422
+ return action === "undo" ? presentationOwner.undo() : presentationOwner.redo();
237423
+ const command$1 = editor.commands?.[action];
237424
+ if (typeof command$1 !== "function")
237425
+ throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", `history.${action} command is not available.`, { reason: "missing_command" });
237426
+ return Boolean(command$1());
237393
237427
  }
237394
237428
  function createHistoryAdapter(editor) {
237395
237429
  return {
237396
237430
  get() {
237397
- const ud = getUndoDepth(editor);
237398
- const rd = getRedoDepth(editor);
237431
+ const { undoDepth: ud, redoDepth: rd } = readHistoryDepths(editor);
237399
237432
  return {
237400
237433
  undoDepth: ud,
237401
237434
  redoDepth: rd,
@@ -237405,10 +237438,8 @@ function createHistoryAdapter(editor) {
237405
237438
  };
237406
237439
  },
237407
237440
  undo() {
237408
- if (typeof editor.commands?.undo !== "function")
237409
- throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", "history.undo command is not available.", { reason: "missing_command" });
237410
237441
  const revBefore = getRevision(editor);
237411
- if (getUndoDepth(editor) === 0)
237442
+ if (readHistoryDepths(editor).undoDepth === 0)
237412
237443
  return {
237413
237444
  noop: true,
237414
237445
  reason: "EMPTY_UNDO_STACK",
@@ -237417,7 +237448,7 @@ function createHistoryAdapter(editor) {
237417
237448
  after: revBefore
237418
237449
  }
237419
237450
  };
237420
- const success = Boolean(editor.commands.undo());
237451
+ const success = runHistoryCommand(editor, "undo");
237421
237452
  const revAfter = getRevision(editor);
237422
237453
  return {
237423
237454
  noop: !success,
@@ -237429,10 +237460,8 @@ function createHistoryAdapter(editor) {
237429
237460
  };
237430
237461
  },
237431
237462
  redo() {
237432
- if (typeof editor.commands?.redo !== "function")
237433
- throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", "history.redo command is not available.", { reason: "missing_command" });
237434
237463
  const revBefore = getRevision(editor);
237435
- if (getRedoDepth(editor) === 0)
237464
+ if (readHistoryDepths(editor).redoDepth === 0)
237436
237465
  return {
237437
237466
  noop: true,
237438
237467
  reason: "EMPTY_REDO_STACK",
@@ -237441,7 +237470,7 @@ function createHistoryAdapter(editor) {
237441
237470
  after: revBefore
237442
237471
  }
237443
237472
  };
237444
- const success = Boolean(editor.commands.redo());
237473
+ const success = runHistoryCommand(editor, "redo");
237445
237474
  const revAfter = getRevision(editor);
237446
237475
  return {
237447
237476
  noop: !success,
@@ -256310,17 +256339,20 @@ function charOffsetToPm(block, line, charOffset, fallbackPmStart) {
256310
256339
  const runs2 = sliceRunsForLine(block, line);
256311
256340
  let cursor = 0;
256312
256341
  let lastPm = fallbackPmStart;
256313
- for (const run2 of runs2) {
256314
- const isTab = isTabRun$1(run2);
256315
- const text5 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" || run2.kind === "math" ? "" : run2.text ?? "";
256316
- const runLength = isTab ? TAB_CHAR_LENGTH : text5.length;
256317
- const runPmStart = typeof run2.pmStart === "number" ? run2.pmStart : null;
256318
- const runPmEnd = typeof run2.pmEnd === "number" ? run2.pmEnd : runPmStart != null ? runPmStart + runLength : null;
256342
+ for (let runIndex = 0;runIndex < runs2.length; runIndex += 1) {
256343
+ const run2 = runs2[runIndex];
256344
+ const runLength = getRunCharacterLength(run2);
256345
+ const runPmStart = resolveRunPmStart(run2, runLength);
256346
+ const runPmEnd = resolveRunPmEnd(run2, runLength, runPmStart);
256319
256347
  if (runPmStart != null)
256320
256348
  lastPm = runPmStart;
256321
256349
  if (safeCharOffset <= cursor + runLength) {
256322
256350
  const offsetInRun = Math.max(0, safeCharOffset - cursor);
256323
- return runPmStart != null ? runPmStart + Math.min(offsetInRun, runLength) : fallbackPmStart + safeCharOffset;
256351
+ if (runPmStart != null)
256352
+ return runPmStart + Math.min(offsetInRun, runLength);
256353
+ if (isVisualOnlyRun(run2))
256354
+ return resolveVisualOnlyRunBoundary(runs2, runIndex, offsetInRun, runLength, lastPm);
256355
+ return fallbackPmStart + safeCharOffset;
256324
256356
  }
256325
256357
  if (runPmEnd != null)
256326
256358
  lastPm = runPmEnd;
@@ -260941,6 +260973,17 @@ function resolveFragment(fragmentEl, viewX, viewY) {
260941
260973
  return null;
260942
260974
  return resolveLineAtX(lineEl, viewX);
260943
260975
  }
260976
+ function resolveTextBoundaryWithinFragmentDom(fragmentEl, clientX, clientY) {
260977
+ if (!fragmentEl.classList?.contains?.(CLASS.fragment))
260978
+ return null;
260979
+ const lineEls = Array.from(fragmentEl.querySelectorAll(`.${CLASS.line}`));
260980
+ if (lineEls.length === 0)
260981
+ return null;
260982
+ const lineEl = findLineAtY(lineEls, clientY);
260983
+ if (!lineEl)
260984
+ return null;
260985
+ return resolveLineTextBoundaryAtX(lineEl, clientX);
260986
+ }
260944
260987
  function resolveLineAtX(lineEl, viewX) {
260945
260988
  const { start: lineStart, end: lineEnd } = readPmRange(lineEl);
260946
260989
  if (!Number.isFinite(lineStart) || !Number.isFinite(lineEnd)) {
@@ -260949,6 +260992,34 @@ function resolveLineAtX(lineEl, viewX) {
260949
260992
  }
260950
260993
  return resolvePositionInLine(lineEl, lineStart, lineEnd, getClickableSpans(lineEl), viewX);
260951
260994
  }
260995
+ function resolveLineTextBoundaryAtX(lineEl, viewX) {
260996
+ const spanEls = getClickableSpans(lineEl);
260997
+ if (spanEls.length === 0)
260998
+ return null;
260999
+ const rtl = isRtlLine(lineEl);
261000
+ const allRects = spanEls.map((el) => el.getBoundingClientRect());
261001
+ const visibleRects = allRects.filter(isVisibleRect);
261002
+ const boundsRects = visibleRects.length > 0 ? visibleRects : allRects;
261003
+ const visualLeft = Math.min(...boundsRects.map((r$1) => r$1.left));
261004
+ const visualRight = Math.max(...boundsRects.map((r$1) => r$1.right));
261005
+ if (viewX <= visualLeft)
261006
+ return resolveElementBoundary(rtl ? spanEls[spanEls.length - 1] : spanEls[0], rtl ? "after" : "before");
261007
+ if (viewX >= visualRight)
261008
+ return resolveElementBoundary(rtl ? spanEls[0] : spanEls[spanEls.length - 1], rtl ? "before" : "after");
261009
+ const targetEl = findSpanAtX(spanEls, viewX);
261010
+ if (!targetEl)
261011
+ return null;
261012
+ const textNode = findFirstTextNode(targetEl);
261013
+ if (!textNode || !textNode.textContent) {
261014
+ const targetRect = targetEl.getBoundingClientRect();
261015
+ const closerToLeft = Math.abs(viewX - targetRect.left) <= Math.abs(viewX - targetRect.right);
261016
+ return resolveElementBoundary(targetEl, rtl ? closerToLeft ? "after" : "before" : closerToLeft ? "before" : "after");
261017
+ }
261018
+ return {
261019
+ node: textNode,
261020
+ offset: findCharIndexAtX(textNode, viewX, rtl)
261021
+ };
261022
+ }
260952
261023
  function resolvePositionInLine(lineEl, lineStart, lineEnd, spanEls, viewX) {
260953
261024
  if (spanEls.length === 0) {
260954
261025
  log2("No spans in line, returning lineStart:", lineStart);
@@ -260984,6 +261055,24 @@ function resolvePositionInLine(lineEl, lineStart, lineEnd, spanEls, viewX) {
260984
261055
  const charIndex = findCharIndexAtX(textNode, viewX, rtl);
260985
261056
  return mapCharIndexToPm(spanStart, spanEnd, rightCaretBoundary, textNode.length, charIndex);
260986
261057
  }
261058
+ function resolveElementBoundary(element3, side) {
261059
+ if (!(element3 instanceof HTMLElement))
261060
+ return null;
261061
+ const textNode = findFirstTextNode(element3);
261062
+ if (!textNode)
261063
+ return null;
261064
+ return {
261065
+ node: textNode,
261066
+ offset: side === "before" ? 0 : textNode.textContent?.length ?? 0
261067
+ };
261068
+ }
261069
+ function findFirstTextNode(element3) {
261070
+ const doc$12 = getNodeDocument(element3);
261071
+ if (!doc$12)
261072
+ return null;
261073
+ const node3 = doc$12.createTreeWalker(element3, NodeFilter.SHOW_TEXT).nextNode();
261074
+ return node3 instanceof Text ? node3 : null;
261075
+ }
260987
261076
  function resolveRightCaretBoundary(spanEls, targetIndex, spanStart, spanEnd) {
260988
261077
  for (let index2 = targetIndex + 1;index2 < spanEls.length; index2 += 1) {
260989
261078
  const { start: nextStart } = readPmRange(spanEls[index2]);
@@ -262560,6 +262649,38 @@ function measureVisibleTextOffset(root3, boundaryNode, boundaryOffset) {
262560
262649
  }
262561
262650
  return total;
262562
262651
  }
262652
+ function measureVisibleTextOffsetInContainers(containers, boundaryNode, boundaryOffset) {
262653
+ const root3 = containers[0];
262654
+ if (!root3 || !boundaryNode)
262655
+ return null;
262656
+ if (!containers.some((container) => boundaryNode === container || container.contains(boundaryNode)))
262657
+ return null;
262658
+ const doc$12 = root3.ownerDocument ?? document;
262659
+ const boundary = doc$12.createRange();
262660
+ try {
262661
+ boundary.setStart(boundaryNode, boundaryOffset);
262662
+ boundary.setEnd(boundaryNode, boundaryOffset);
262663
+ } catch {
262664
+ return null;
262665
+ }
262666
+ const model = collectVisibleTextModel(containers);
262667
+ for (const segment of model.segments) {
262668
+ const textNode = segment.node;
262669
+ const textLength = textNode.textContent?.length ?? 0;
262670
+ if (textLength === 0)
262671
+ continue;
262672
+ const textRange2 = doc$12.createRange();
262673
+ textRange2.selectNodeContents(textNode);
262674
+ if (textRange2.compareBoundaryPoints(Range.END_TO_END, boundary) <= 0)
262675
+ continue;
262676
+ if (textNode === boundaryNode)
262677
+ return segment.startOffset + Math.max(0, Math.min(boundaryOffset, textLength));
262678
+ if (textRange2.compareBoundaryPoints(Range.START_TO_START, boundary) >= 0)
262679
+ return segment.startOffset;
262680
+ return segment.startOffset;
262681
+ }
262682
+ return model.totalLength;
262683
+ }
262563
262684
  function computeCaretRectFromVisibleTextOffset(options, textOffset) {
262564
262685
  const model = collectVisibleTextModel(options.containers);
262565
262686
  if (!model.segments.length)
@@ -265832,28 +265953,6 @@ function ensureEditorFieldAnnotationInteractionStyles(doc$12) {
265832
265953
  doc$12.head?.appendChild(styleEl);
265833
265954
  fieldAnnotationInteractionStylesInjected = true;
265834
265955
  }
265835
- function stripVolatileHistoryAttrs(value) {
265836
- if (Array.isArray(value))
265837
- return value.map((item) => stripVolatileHistoryAttrs(item));
265838
- if (!value || typeof value !== "object")
265839
- return value;
265840
- const result = {};
265841
- for (const [key2, entryValue] of Object.entries(value)) {
265842
- if (VOLATILE_HISTORY_ATTR_KEYS.has(key2))
265843
- continue;
265844
- result[key2] = stripVolatileHistoryAttrs(entryValue);
265845
- }
265846
- return result;
265847
- }
265848
- function docsEqualIgnoringVolatileHistoryAttrs(before2, after2) {
265849
- if (!before2 || !after2)
265850
- return false;
265851
- if (typeof before2.eq === "function" && before2.eq(after2))
265852
- return true;
265853
- const beforeJson = typeof before2.toJSON === "function" ? before2.toJSON() : before2;
265854
- const afterJson = typeof after2.toJSON === "function" ? after2.toJSON() : after2;
265855
- return JSON.stringify(stripVolatileHistoryAttrs(beforeJson)) === JSON.stringify(stripVolatileHistoryAttrs(afterJson));
265856
- }
265857
265956
  function parseRenderedNoteTarget(blockId) {
265858
265957
  if (typeof blockId !== "string" || blockId.length === 0)
265859
265958
  return null;
@@ -268219,7 +268318,7 @@ var Node$13 = class Node$14 {
268219
268318
  const transaction = view.state.tr.setSelection(selection);
268220
268319
  view.dispatch(transaction);
268221
268320
  }
268222
- }, StructuredContentInlineView, STRUCTURED_CONTENT_LOCK_KEY, structuredContentClass = "sd-structured-content", structuredContentInnerClass = "sd-structured-content__content", StructuredContent, StructuredContentBlockView, structuredContentBlockClass = "sd-structured-content-block", structuredContentBlockInnerClass = "sd-structured-content-block__content", StructuredContentBlock, structuredContentHelpers_exports, STRUCTURED_CONTENT_NAMES, findFirstTextNode = (node3) => {
268321
+ }, StructuredContentInlineView, STRUCTURED_CONTENT_LOCK_KEY, structuredContentClass = "sd-structured-content", structuredContentInnerClass = "sd-structured-content__content", StructuredContent, StructuredContentBlockView, structuredContentBlockClass = "sd-structured-content-block", structuredContentBlockInnerClass = "sd-structured-content-block__content", StructuredContentBlock, structuredContentHelpers_exports, STRUCTURED_CONTENT_NAMES, findFirstTextNode$1 = (node3) => {
268223
268322
  let firstTextNode = null;
268224
268323
  node3.descendants((child) => {
268225
268324
  if (child.isText) {
@@ -268475,7 +268574,7 @@ var Node$13 = class Node$14 {
268475
268574
  tr.setDocAttribute("bodySectPr", sectPr);
268476
268575
  tr.setMeta("forceUpdatePagination", true);
268477
268576
  return true;
268478
- }, Document$1, Text$1, OxmlNode, isLinkedParagraphStyleId = (editor, styleId) => {
268577
+ }, Document$1, Text$2, OxmlNode, isLinkedParagraphStyleId = (editor, styleId) => {
268479
268578
  if (!styleId)
268480
268579
  return false;
268481
268580
  const styleDefinition = readTranslatedLinkedStyles(editor)?.styles?.[styleId];
@@ -276414,7 +276513,7 @@ var Node$13 = class Node$14 {
276414
276513
  TableOfContents,
276415
276514
  DocumentIndex,
276416
276515
  Strike,
276417
- Text$1,
276516
+ Text$2,
276418
276517
  TextAlign,
276419
276518
  TextStyle,
276420
276519
  Underline,
@@ -276469,7 +276568,7 @@ var Node$13 = class Node$14 {
276469
276568
  TableOfContents,
276470
276569
  TocPageNumber,
276471
276570
  DocumentIndex,
276472
- Text$1,
276571
+ Text$2,
276473
276572
  TextAlign,
276474
276573
  TextStyle,
276475
276574
  Underline,
@@ -277941,19 +278040,64 @@ var Node$13 = class Node$14 {
277941
278040
  () => commands$1.joinForward(),
277942
278041
  () => commands$1.selectNodeForward()
277943
278042
  ]);
277944
- }, Keymap, handleInsertTextBeforeInput = (view, event) => {
278043
+ }, Keymap, appendStoryInputDebugLog = (entry) => {
278044
+ const debugGlobal = globalThis;
278045
+ if (debugGlobal.__SD_DEBUG_STORY_INPUT__ !== true)
278046
+ return;
278047
+ const existingLog = Array.isArray(debugGlobal.__SD_DEBUG_STORY_INPUT_LOG__) ? debugGlobal.__SD_DEBUG_STORY_INPUT_LOG__ : [];
278048
+ existingLog.push(entry);
278049
+ if (existingLog.length > 200)
278050
+ existingLog.splice(0, existingLog.length - 200);
278051
+ debugGlobal.__SD_DEBUG_STORY_INPUT_LOG__ = existingLog;
278052
+ }, isStorySurfaceEditor = (editor) => {
278053
+ const documentId = editor?.options?.documentId ?? "";
278054
+ return documentId.startsWith("hf:") || documentId.startsWith("fn:") || documentId.startsWith("en:");
278055
+ }, recordStoryInputDebug = (view, event, editor, phase, extra = {}) => {
278056
+ if (!isStorySurfaceEditor(editor))
278057
+ return;
278058
+ let domAnchorPos = null;
278059
+ const domSelection = view?.dom?.ownerDocument?.getSelection?.() ?? null;
278060
+ try {
278061
+ if (view?.dom && domSelection?.anchorNode && view.dom.contains(domSelection.anchorNode))
278062
+ domAnchorPos = view.posAtDOM(domSelection.anchorNode, domSelection.anchorOffset, -1);
278063
+ } catch {
278064
+ domAnchorPos = null;
278065
+ }
278066
+ appendStoryInputDebugLog({
278067
+ phase,
278068
+ documentId: editor?.options?.documentId ?? null,
278069
+ inputType: event?.inputType ?? null,
278070
+ data: event?.data ?? null,
278071
+ cancelable: event?.cancelable ?? null,
278072
+ defaultPrevented: event?.defaultPrevented ?? null,
278073
+ selectionFrom: view?.state?.selection?.from ?? null,
278074
+ selectionTo: view?.state?.selection?.to ?? null,
278075
+ domAnchorPos,
278076
+ ...extra
278077
+ });
278078
+ }, handleInsertTextBeforeInput = (view, event, editor) => {
277945
278079
  const isInsertTextInput = event?.inputType === "insertText";
277946
278080
  const hasTextData = typeof event?.data === "string" && event.data.length > 0;
277947
278081
  const isComposing = event?.isComposing === true;
277948
- if (!isInsertTextInput || !hasTextData || isComposing)
278082
+ recordStoryInputDebug(view, event, editor, "beforeinput:start", {
278083
+ isInsertTextInput,
278084
+ hasTextData,
278085
+ isComposing
278086
+ });
278087
+ if (!isInsertTextInput || !hasTextData || isComposing) {
278088
+ recordStoryInputDebug(view, event, editor, "beforeinput:skip");
277949
278089
  return false;
278090
+ }
277950
278091
  const selection = view.state.selection;
277951
- if (selection.empty)
278092
+ if (selection.empty && !isStorySurfaceEditor(editor)) {
278093
+ recordStoryInputDebug(view, event, editor, "beforeinput:skip-empty-selection");
277952
278094
  return false;
278095
+ }
277953
278096
  const tr = view.state.tr.insertText(event.data, selection.from, selection.to);
277954
278097
  tr.setMeta("inputType", "insertText");
277955
278098
  view.dispatch(tr);
277956
278099
  event.preventDefault();
278100
+ recordStoryInputDebug(view, event, editor, "beforeinput:handled");
277957
278101
  return true;
277958
278102
  }, shouldForceEndStaleComposition = (view, event) => {
277959
278103
  if (!view.composing || event?.isComposing)
@@ -279128,7 +279272,598 @@ var Node$13 = class Node$14 {
279128
279272
  listener(snapshot2);
279129
279273
  } catch {}
279130
279274
  }
279131
- }, EMITTABLE_BLOCK_TYPES, SDT_BLOCK_NODE_NAMES, REQUIRED_COMMANDS, VALID_CAPABILITY_REASON_CODES, REQUIRED_HELPERS, SCHEMA_NODE_GATES, schemaGatedIds, SUPPORTED_NON_UNIFORM_STRATEGIES, SUPPORTED_SET_MARKS, REGEX_MAX_PATTERN_LENGTH = 1024, STYLES_PART = "word/styles.xml", PROPERTIES_KEY_BY_CHANNEL, XML_PATH_BY_CHANNEL2, UNDERLINE_API_TO_STORAGE, UNDERLINE_STORAGE_TO_API, HEX_SUBKEYS_BY_PROPERTY, SUPPORTED_DELETE_NODE_TYPES3, REJECTED_DELETE_NODE_TYPES3, TEXT_PREVIEW_MAX_LENGTH = 80, RANGE_DELETE_SAFE_NODE_TYPES, HEADING_PATTERN, OOXML_DEFAULT_FONT_SIZE_PT = 10, INDENT_PER_LEVEL_TWIPS = 720, HANGING_INDENT_TWIPS = 360, SYMBOL_FONT_NAMES, RFONTS_FAMILY_ATTRS, ORDERED_PRESET_CONFIG, BULLET_PRESET_CONFIG, PRESET_TEMPLATES, LevelFormattingHelpers, PRESET_KIND_MAP, NUMBERING_PART = "word/numbering.xml", DEFAULT_PRESET_FOR_KIND, _setValueDelegate, PREVIEW_TEXT_MAX_LENGTH = 2000, BLOCK_PREVIEW_MAX_LENGTH = 200, EDGE_NODE_TYPES$1, POINTS_TO_PIXELS, POINTS_TO_TWIPS = 20, PIXELS_TO_TWIPS, DEFAULT_TABLE_GRID_WIDTH_TWIPS = 1500, SETTINGS_PART$1 = "word/settings.xml", WORD_DEFAULT_TBL_LOOK, FLAG_TO_OOXML_KEY, INVERTED_FLAGS, XML_KEY_TO_STYLE_OPTION, CLEARED_BORDER_OOXML, TABLE_MARGIN_KEY_GROUPS, TABLE_ADAPTER_DISPATCH, ROW_TARGETED_TABLE_OPS, registered = false, STYLES_PART_ID = "word/styles.xml", stylesPartDescriptor, settingsPartDescriptor, RELS_PART_ID2 = "word/_rels/document.xml.rels", RELS_XMLNS2 = "http://schemas.openxmlformats.org/package/2006/relationships", HEADER_RELATIONSHIP_TYPE$1 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE$1 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", relsPartDescriptor, HISTORY_UNSAFE_OPS, CANONICAL_COMMENT_IGNORED_KEYS, INITIAL_HASH, ROUND_CONSTANTS, V1_COVERAGE, V2_COVERAGE, SNAPSHOT_VERSION_V2 = "sd-diff-snapshot/v2", PAYLOAD_VERSION_V1 = "sd-diff-payload/v1", PAYLOAD_VERSION_V2 = "sd-diff-payload/v2", ENGINE_ID = "super-editor", STAGED_CONVERTER_KEYS, DiffServiceError, DEFAULT_LEVEL = 1, SWITCH_PATTERN, TOC_BOOKMARK_PREFIX = "_Toc", DEFAULT_RIGHT_TAB_POS = 9350, TAB_LEADER_MAP, NO_ENTRIES_PLACEHOLDER, TC_LEVEL_MIN = 1, TC_LEVEL_MAX = 9, ALLOWED_WRAP_ATTRS, WRAP_TYPES_SUPPORTING_SIDE, WRAP_TYPES_SUPPORTING_DISTANCES, RELATIVE_HEIGHT_MIN = 0, RELATIVE_HEIGHT_MAX = 4294967295, FORBIDDEN_RAW_PATCH_NAMES, CONTROL_TYPE_SDT_PR_ELEMENTS, DEFAULT_CHECKBOX_SYMBOL_FONT2 = "MS Gothic", DEFAULT_CHECKBOX_CHECKED_HEX2 = "2612", DEFAULT_CHECKBOX_UNCHECKED_HEX2 = "2610", VARIANT_ORDER, KIND_ORDER, HEADER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", DOCUMENT_RELS_PATH2 = "word/_rels/document.xml.rels", HEADER_FILE_PATTERN2, FOOTER_FILE_PATTERN2, SETTINGS_PART, SPECIAL_NOTE_TYPES, RESTART_POLICY_TO_OOXML, VALID_DISPLAYS, REFERENCE_BLOCK_PREFIX, CAPTION_STYLE_NAMES, CAPTION_PARAGRAPH_STYLE_ID = "Caption", CAPTION_FORMAT_TO_OOXML, DOCUMENT_STAT_FIELD_TYPES, TOA_LEADER_REVERSE_MAP, EDGE_NODE_TYPES, CONTENT_TYPES_PART_ID = "[Content_Types].xml", CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types", contentTypesPartDescriptor, empty_exports, init_empty, CURRENT_APP_VERSION2 = "1.29.0", PIXELS_PER_INCH2 = 96, MAX_HEIGHT_BUFFER_PX = 50, MAX_WIDTH_BUFFER_PX = 20, cloneExtensionInstance = (extension3) => {
279275
+ }, EMITTABLE_BLOCK_TYPES, SDT_BLOCK_NODE_NAMES, REQUIRED_COMMANDS, VALID_CAPABILITY_REASON_CODES, REQUIRED_HELPERS, SCHEMA_NODE_GATES, schemaGatedIds, SUPPORTED_NON_UNIFORM_STRATEGIES, SUPPORTED_SET_MARKS, REGEX_MAX_PATTERN_LENGTH = 1024, STYLES_PART = "word/styles.xml", PROPERTIES_KEY_BY_CHANNEL, XML_PATH_BY_CHANNEL2, UNDERLINE_API_TO_STORAGE, UNDERLINE_STORAGE_TO_API, HEX_SUBKEYS_BY_PROPERTY, SUPPORTED_DELETE_NODE_TYPES3, REJECTED_DELETE_NODE_TYPES3, TEXT_PREVIEW_MAX_LENGTH = 80, RANGE_DELETE_SAFE_NODE_TYPES, HEADING_PATTERN, OOXML_DEFAULT_FONT_SIZE_PT = 10, INDENT_PER_LEVEL_TWIPS = 720, HANGING_INDENT_TWIPS = 360, SYMBOL_FONT_NAMES, RFONTS_FAMILY_ATTRS, ORDERED_PRESET_CONFIG, BULLET_PRESET_CONFIG, PRESET_TEMPLATES, LevelFormattingHelpers, PRESET_KIND_MAP, NUMBERING_PART = "word/numbering.xml", DEFAULT_PRESET_FOR_KIND, _setValueDelegate, PREVIEW_TEXT_MAX_LENGTH = 2000, BLOCK_PREVIEW_MAX_LENGTH = 200, EDGE_NODE_TYPES$1, POINTS_TO_PIXELS, POINTS_TO_TWIPS = 20, PIXELS_TO_TWIPS, DEFAULT_TABLE_GRID_WIDTH_TWIPS = 1500, SETTINGS_PART$1 = "word/settings.xml", WORD_DEFAULT_TBL_LOOK, FLAG_TO_OOXML_KEY, INVERTED_FLAGS, XML_KEY_TO_STYLE_OPTION, CLEARED_BORDER_OOXML, TABLE_MARGIN_KEY_GROUPS, TABLE_ADAPTER_DISPATCH, ROW_TARGETED_TABLE_OPS, registered = false, STYLES_PART_ID = "word/styles.xml", stylesPartDescriptor, settingsPartDescriptor, RELS_PART_ID2 = "word/_rels/document.xml.rels", RELS_XMLNS2 = "http://schemas.openxmlformats.org/package/2006/relationships", HEADER_RELATIONSHIP_TYPE$1 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE$1 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", relsPartDescriptor, BatchHistoryAdapter = class {
279276
+ #done = [];
279277
+ #redone = [];
279278
+ #listeners = /* @__PURE__ */ new Set;
279279
+ record(batch2) {
279280
+ this.#done.push(batch2);
279281
+ this.#redone.length = 0;
279282
+ this.#notify();
279283
+ }
279284
+ getSnapshot() {
279285
+ return {
279286
+ undoDepth: this.#done.length,
279287
+ redoDepth: this.#redone.length
279288
+ };
279289
+ }
279290
+ undo() {
279291
+ const batch2 = this.#done.pop();
279292
+ if (!batch2)
279293
+ return false;
279294
+ try {
279295
+ if (batch2.undo() === false) {
279296
+ this.#done.push(batch2);
279297
+ return false;
279298
+ }
279299
+ } catch {
279300
+ this.#done.push(batch2);
279301
+ return false;
279302
+ }
279303
+ this.#redone.push(batch2);
279304
+ this.#notify();
279305
+ return true;
279306
+ }
279307
+ redo() {
279308
+ const batch2 = this.#redone.pop();
279309
+ if (!batch2)
279310
+ return false;
279311
+ try {
279312
+ if (batch2.redo() === false) {
279313
+ this.#redone.push(batch2);
279314
+ return false;
279315
+ }
279316
+ } catch {
279317
+ this.#redone.push(batch2);
279318
+ return false;
279319
+ }
279320
+ this.#done.push(batch2);
279321
+ this.#notify();
279322
+ return true;
279323
+ }
279324
+ subscribe(onChange$1) {
279325
+ this.#listeners.add(onChange$1);
279326
+ return () => this.#listeners.delete(onChange$1);
279327
+ }
279328
+ #notify() {
279329
+ this.#listeners.forEach((listener) => listener());
279330
+ }
279331
+ }, BATCH_PARTICIPANT_KEY = "internal:batch", DEFAULT_GLOBAL_HISTORY_CAP = 500, stateEquals = (a2, b$1) => a2.canUndo === b$1.canUndo && a2.canRedo === b$1.canRedo && a2.undoDepth === b$1.undoDepth && a2.redoDepth === b$1.redoDepth, DocumentHistoryCoordinator = class {
279332
+ #participants = /* @__PURE__ */ new Map;
279333
+ #doneStack = [];
279334
+ #redoStack = [];
279335
+ #changeListeners = /* @__PURE__ */ new Set;
279336
+ #cueListeners = /* @__PURE__ */ new Set;
279337
+ #purgeListeners = /* @__PURE__ */ new Set;
279338
+ #capacity;
279339
+ #onDiagnostic;
279340
+ #batchAdapter = new BatchHistoryAdapter;
279341
+ #suppressionCount = 0;
279342
+ #seq = 0;
279343
+ #lastEmittedState = {
279344
+ canUndo: false,
279345
+ canRedo: false,
279346
+ undoDepth: 0,
279347
+ redoDepth: 0
279348
+ };
279349
+ #activeReplay = null;
279350
+ #activeSurface = "body";
279351
+ constructor(options = {}) {
279352
+ this.#capacity = Math.max(1, options.capacity ?? DEFAULT_GLOBAL_HISTORY_CAP);
279353
+ this.#onDiagnostic = options.onDiagnostic;
279354
+ this.register({
279355
+ key: BATCH_PARTICIPANT_KEY,
279356
+ surface: "body",
279357
+ adapter: this.#batchAdapter
279358
+ });
279359
+ this.setPinned(BATCH_PARTICIPANT_KEY, true);
279360
+ }
279361
+ withHistoryBatch(batch2) {
279362
+ this.#batchAdapter.record(batch2);
279363
+ }
279364
+ register(participant, options = {}) {
279365
+ const existing = this.#participants.get(participant.key);
279366
+ if (existing)
279367
+ existing.unsubscribe();
279368
+ const lastSnapshot = participant.adapter.getSnapshot();
279369
+ const unsubscribe3 = participant.adapter.subscribe(() => this.#onParticipantTransaction(participant.key));
279370
+ this.#participants.set(participant.key, {
279371
+ participant,
279372
+ lastSnapshot,
279373
+ pinned: existing?.pinned ?? options.pinned ?? false,
279374
+ unsubscribe: unsubscribe3
279375
+ });
279376
+ this.#onDiagnostic?.("unified-history: participant registered", {
279377
+ key: participant.key,
279378
+ surface: participant.surface,
279379
+ snapshot: lastSnapshot,
279380
+ replacedExisting: Boolean(existing)
279381
+ });
279382
+ }
279383
+ unregister(key2) {
279384
+ const record = this.#participants.get(key2);
279385
+ if (!record)
279386
+ return;
279387
+ record.unsubscribe();
279388
+ this.#participants.delete(key2);
279389
+ }
279390
+ purge(key2, reason = "unregister") {
279391
+ const record = this.#participants.get(key2);
279392
+ if (record) {
279393
+ this.#invokeOnInvalidated(record);
279394
+ record.unsubscribe();
279395
+ this.#participants.delete(key2);
279396
+ }
279397
+ this.#removeEntriesForKey(key2);
279398
+ this.#notifyPurge(key2, reason);
279399
+ this.#emitStateIfChanged();
279400
+ }
279401
+ #invokeOnInvalidated(record) {
279402
+ const hook = record.participant.onInvalidated;
279403
+ if (!hook)
279404
+ return;
279405
+ try {
279406
+ hook();
279407
+ } catch (error3) {
279408
+ this.#onDiagnostic?.("unified-history: onInvalidated threw", {
279409
+ key: record.participant.key,
279410
+ error: error3
279411
+ });
279412
+ }
279413
+ }
279414
+ hasParticipant(key2) {
279415
+ return this.#participants.has(key2);
279416
+ }
279417
+ setPinned(key2, pinned) {
279418
+ const record = this.#participants.get(key2);
279419
+ if (!record)
279420
+ return;
279421
+ record.pinned = pinned;
279422
+ }
279423
+ isPinned(key2) {
279424
+ const record = this.#participants.get(key2);
279425
+ return Boolean(record?.pinned);
279426
+ }
279427
+ getReachableKeys() {
279428
+ const keys$1 = /* @__PURE__ */ new Set;
279429
+ for (const entry of this.#doneStack)
279430
+ keys$1.add(entry.participantKey);
279431
+ for (const entry of this.#redoStack)
279432
+ keys$1.add(entry.participantKey);
279433
+ return keys$1;
279434
+ }
279435
+ setActiveSurface(surface) {
279436
+ this.#activeSurface = surface;
279437
+ }
279438
+ getActiveSurface() {
279439
+ return this.#activeSurface;
279440
+ }
279441
+ canUndo() {
279442
+ return this.#findExecutableEntry(this.#doneStack, "undo") !== null;
279443
+ }
279444
+ canRedo() {
279445
+ return this.#findExecutableEntry(this.#redoStack, "redo") !== null;
279446
+ }
279447
+ getState() {
279448
+ return {
279449
+ canUndo: this.canUndo(),
279450
+ canRedo: this.canRedo(),
279451
+ undoDepth: this.#doneStack.length,
279452
+ redoDepth: this.#redoStack.length
279453
+ };
279454
+ }
279455
+ undo() {
279456
+ return this.#replay("undo");
279457
+ }
279458
+ redo() {
279459
+ return this.#replay("redo");
279460
+ }
279461
+ syncParticipant(key2) {
279462
+ this.#onParticipantTransaction(key2);
279463
+ }
279464
+ onChange(listener) {
279465
+ this.#changeListeners.add(listener);
279466
+ return () => this.#changeListeners.delete(listener);
279467
+ }
279468
+ onCue(listener) {
279469
+ this.#cueListeners.add(listener);
279470
+ return () => this.#cueListeners.delete(listener);
279471
+ }
279472
+ onPurge(listener) {
279473
+ this.#purgeListeners.add(listener);
279474
+ return () => this.#purgeListeners.delete(listener);
279475
+ }
279476
+ destroy() {
279477
+ for (const record of this.#participants.values())
279478
+ record.unsubscribe();
279479
+ this.#participants.clear();
279480
+ this.#doneStack.length = 0;
279481
+ this.#redoStack.length = 0;
279482
+ this.#changeListeners.clear();
279483
+ this.#cueListeners.clear();
279484
+ this.#purgeListeners.clear();
279485
+ }
279486
+ #onParticipantTransaction(key2) {
279487
+ const record = this.#participants.get(key2);
279488
+ if (!record)
279489
+ return;
279490
+ const previous3 = record.lastSnapshot;
279491
+ const current = record.participant.adapter.getSnapshot();
279492
+ record.lastSnapshot = current;
279493
+ this.#onDiagnostic?.("unified-history: participant transaction observed", {
279494
+ key: key2,
279495
+ surface: record.participant.surface,
279496
+ previous: previous3,
279497
+ current,
279498
+ suppressionCount: this.#suppressionCount
279499
+ });
279500
+ if (this.#suppressionCount > 0)
279501
+ return;
279502
+ const changeKind = record.participant.adapter.consumePendingChangeKind?.() ?? "unknown";
279503
+ const undoIncreased = current.undoDepth > previous3.undoDepth;
279504
+ const undoDecreased = current.undoDepth < previous3.undoDepth;
279505
+ const redoIncreased = current.redoDepth > previous3.redoDepth;
279506
+ const redoDecreased = current.redoDepth < previous3.redoDepth;
279507
+ if (changeKind === "undo") {
279508
+ this.#mirrorExternalUndo(record.participant, previous3, current);
279509
+ return;
279510
+ }
279511
+ if (changeKind === "redo") {
279512
+ this.#mirrorExternalRedo(record.participant, previous3, current);
279513
+ return;
279514
+ }
279515
+ if (undoIncreased) {
279516
+ this.#recordLocalEdit(record.participant, current.undoDepth - previous3.undoDepth);
279517
+ return;
279518
+ }
279519
+ if (undoDecreased)
279520
+ this.#discardTopEntriesForKey(this.#doneStack, record.participant.key, previous3.undoDepth - current.undoDepth);
279521
+ if (redoIncreased) {
279522
+ this.#appendReplayEntries(this.#redoStack, record.participant, current.redoDepth - previous3.redoDepth);
279523
+ this.#emitStateIfChanged();
279524
+ return;
279525
+ }
279526
+ if (redoDecreased)
279527
+ this.#discardTopEntriesForKey(this.#redoStack, record.participant.key, previous3.redoDepth - current.redoDepth);
279528
+ this.#emitStateIfChanged();
279529
+ }
279530
+ #recordLocalEdit(participant, stepCount) {
279531
+ this.#appendReplayEntries(this.#doneStack, participant, stepCount);
279532
+ if (this.#redoStack.length > 0)
279533
+ this.#redoStack.length = 0;
279534
+ this.#onDiagnostic?.("unified-history: recorded local edit", {
279535
+ key: participant.key,
279536
+ surface: participant.surface,
279537
+ stepCount,
279538
+ state: this.getState()
279539
+ });
279540
+ this.#emitStateIfChanged();
279541
+ }
279542
+ #mirrorExternalUndo(participant, previous3, current) {
279543
+ const stepCount = previous3.undoDepth - current.undoDepth;
279544
+ if (stepCount <= 0)
279545
+ return;
279546
+ const unmatchedSteps = stepCount - this.#moveEntriesBetweenStacks(this.#doneStack, this.#redoStack, participant, stepCount);
279547
+ if (unmatchedSteps > 0)
279548
+ this.#discardTopEntriesForKey(this.#doneStack, participant.key, unmatchedSteps);
279549
+ this.#emitStateIfChanged();
279550
+ }
279551
+ #mirrorExternalRedo(participant, previous3, current) {
279552
+ const stepCount = current.undoDepth - previous3.undoDepth;
279553
+ if (stepCount <= 0)
279554
+ return;
279555
+ const unmatchedSteps = stepCount - this.#moveEntriesBetweenStacks(this.#redoStack, this.#doneStack, participant, stepCount);
279556
+ if (unmatchedSteps > 0)
279557
+ this.#appendReplayEntries(this.#doneStack, participant, unmatchedSteps);
279558
+ this.#emitStateIfChanged();
279559
+ }
279560
+ #findExecutableEntry(stack, action) {
279561
+ for (let i4 = stack.length - 1;i4 >= 0; i4 -= 1) {
279562
+ const entry = stack[i4];
279563
+ const record = this.#participants.get(entry.participantKey);
279564
+ if (!record)
279565
+ continue;
279566
+ const snapshot2 = record.participant.adapter.getSnapshot();
279567
+ if (action === "undo" ? snapshot2.undoDepth > 0 : snapshot2.redoDepth > 0)
279568
+ return {
279569
+ entry,
279570
+ record
279571
+ };
279572
+ }
279573
+ return null;
279574
+ }
279575
+ #replay(action) {
279576
+ const source = action === "undo" ? this.#doneStack : this.#redoStack;
279577
+ const target = action === "undo" ? this.#redoStack : this.#doneStack;
279578
+ const hit = this.#findExecutableEntry(source, action);
279579
+ if (!hit)
279580
+ return false;
279581
+ const { entry, record } = hit;
279582
+ this.#removeEntryExact(source, entry);
279583
+ this.#activeReplay = {
279584
+ action,
279585
+ surface: entry.surface,
279586
+ key: entry.participantKey
279587
+ };
279588
+ this.#suppressionCount += 1;
279589
+ let didRun = false;
279590
+ try {
279591
+ didRun = action === "undo" ? record.participant.adapter.undo() : record.participant.adapter.redo();
279592
+ } catch (error3) {
279593
+ this.#onDiagnostic?.("unified-history: adapter threw during replay", {
279594
+ action,
279595
+ key: entry.participantKey,
279596
+ error: error3
279597
+ });
279598
+ } finally {
279599
+ this.#suppressionCount = Math.max(0, this.#suppressionCount - 1);
279600
+ record.lastSnapshot = record.participant.adapter.getSnapshot();
279601
+ }
279602
+ if (!didRun) {
279603
+ this.#onDiagnostic?.("unified-history: replay produced no local step", {
279604
+ action,
279605
+ key: entry.participantKey
279606
+ });
279607
+ source.push(entry);
279608
+ this.#activeReplay = null;
279609
+ this.#emitStateIfChanged();
279610
+ return false;
279611
+ }
279612
+ target.push({
279613
+ ...entry,
279614
+ seq: ++this.#seq
279615
+ });
279616
+ this.#enforceCapacity();
279617
+ this.#onDiagnostic?.("unified-history: replay applied", {
279618
+ action,
279619
+ key: entry.participantKey,
279620
+ surface: entry.surface,
279621
+ activeSurface: this.#activeSurface,
279622
+ state: this.getState()
279623
+ });
279624
+ this.#emitCueIfCrossSurface(entry);
279625
+ this.#runFlushAfterReplay(record, action);
279626
+ this.#activeReplay = null;
279627
+ this.#emitStateIfChanged();
279628
+ return true;
279629
+ }
279630
+ #runFlushAfterReplay(record, action) {
279631
+ const hook = record.participant.flushAfterReplay;
279632
+ if (!hook)
279633
+ return;
279634
+ try {
279635
+ hook(action);
279636
+ } catch (error3) {
279637
+ this.#onDiagnostic?.("unified-history: flushAfterReplay threw", {
279638
+ key: record.participant.key,
279639
+ action,
279640
+ error: error3
279641
+ });
279642
+ }
279643
+ }
279644
+ #emitCueIfCrossSurface(entry) {
279645
+ const replay = this.#activeReplay;
279646
+ if (!replay)
279647
+ return;
279648
+ if (entry.surface === this.#activeSurface)
279649
+ return;
279650
+ const cue = {
279651
+ action: replay.action,
279652
+ surface: entry.surface,
279653
+ participantKey: entry.participantKey
279654
+ };
279655
+ this.#cueListeners.forEach((listener) => {
279656
+ try {
279657
+ listener(cue);
279658
+ } catch (error3) {
279659
+ this.#onDiagnostic?.("unified-history: cue listener threw", { error: error3 });
279660
+ }
279661
+ });
279662
+ }
279663
+ #removeEntriesForKey(key2) {
279664
+ this.#filterInPlace(this.#doneStack, (entry) => entry.participantKey !== key2);
279665
+ this.#filterInPlace(this.#redoStack, (entry) => entry.participantKey !== key2);
279666
+ }
279667
+ #discardTopEntriesForKey(stack, key2, count2) {
279668
+ return this.#takeTopEntriesForKey(stack, key2, count2).length;
279669
+ }
279670
+ #moveEntriesBetweenStacks(source, target, participant, count2) {
279671
+ const movedEntries = this.#takeTopEntriesForKey(source, participant.key, count2);
279672
+ movedEntries.forEach((entry) => {
279673
+ target.push({
279674
+ ...entry,
279675
+ seq: ++this.#seq
279676
+ });
279677
+ });
279678
+ this.#enforceCapacity();
279679
+ return movedEntries.length;
279680
+ }
279681
+ #takeTopEntriesForKey(stack, key2, count2) {
279682
+ const removed = [];
279683
+ if (count2 <= 0)
279684
+ return removed;
279685
+ for (let i4 = stack.length - 1;i4 >= 0 && removed.length < count2; i4 -= 1) {
279686
+ if (stack[i4].participantKey !== key2)
279687
+ continue;
279688
+ removed.push(stack[i4]);
279689
+ stack.splice(i4, 1);
279690
+ }
279691
+ return removed;
279692
+ }
279693
+ #appendReplayEntries(stack, participant, count2) {
279694
+ for (let i4 = 0;i4 < count2; i4 += 1)
279695
+ stack.push({
279696
+ seq: ++this.#seq,
279697
+ participantKey: participant.key,
279698
+ surface: participant.surface
279699
+ });
279700
+ this.#enforceCapacity();
279701
+ }
279702
+ #removeEntryExact(stack, entry) {
279703
+ for (let i4 = stack.length - 1;i4 >= 0; i4 -= 1)
279704
+ if (stack[i4].seq === entry.seq) {
279705
+ stack.splice(i4, 1);
279706
+ return;
279707
+ }
279708
+ }
279709
+ #enforceCapacity() {
279710
+ while (this.#doneStack.length + this.#redoStack.length > this.#capacity) {
279711
+ const victim = this.#doneStack.length > 0 ? this.#doneStack.shift() : this.#redoStack.shift();
279712
+ if (!victim)
279713
+ break;
279714
+ if (!this.#isKeyReferenced(victim.participantKey))
279715
+ this.#notifyPurge(victim.participantKey, "capacity-eviction");
279716
+ this.#onDiagnostic?.("unified-history: capacity eviction", {
279717
+ key: victim.participantKey,
279718
+ surface: victim.surface
279719
+ });
279720
+ }
279721
+ }
279722
+ #isKeyReferenced(key2) {
279723
+ for (const entry of this.#doneStack)
279724
+ if (entry.participantKey === key2)
279725
+ return true;
279726
+ for (const entry of this.#redoStack)
279727
+ if (entry.participantKey === key2)
279728
+ return true;
279729
+ return false;
279730
+ }
279731
+ #filterInPlace(array, predicate) {
279732
+ let writeIndex = 0;
279733
+ for (let readIndex = 0;readIndex < array.length; readIndex += 1) {
279734
+ const value = array[readIndex];
279735
+ if (predicate(value)) {
279736
+ array[writeIndex] = value;
279737
+ writeIndex += 1;
279738
+ }
279739
+ }
279740
+ array.length = writeIndex;
279741
+ }
279742
+ #emitStateIfChanged() {
279743
+ const next2 = this.getState();
279744
+ if (stateEquals(next2, this.#lastEmittedState))
279745
+ return;
279746
+ this.#lastEmittedState = next2;
279747
+ this.#changeListeners.forEach((listener) => {
279748
+ try {
279749
+ listener();
279750
+ } catch (error3) {
279751
+ this.#onDiagnostic?.("unified-history: change listener threw", { error: error3 });
279752
+ }
279753
+ });
279754
+ }
279755
+ #notifyPurge(key2, reason) {
279756
+ this.#purgeListeners.forEach((listener) => {
279757
+ try {
279758
+ listener({
279759
+ key: key2,
279760
+ reason
279761
+ });
279762
+ } catch (error3) {
279763
+ this.#onDiagnostic?.("unified-history: purge listener threw", { error: error3 });
279764
+ }
279765
+ });
279766
+ }
279767
+ }, isYjsBacked = (editor) => {
279768
+ const opts = editor.options;
279769
+ return Boolean(opts?.collaborationProvider && opts?.ydoc);
279770
+ }, readYjsDepths = (editor) => {
279771
+ if (!editor.state)
279772
+ return {
279773
+ undoDepth: 0,
279774
+ redoDepth: 0
279775
+ };
279776
+ const manager = yUndoPluginKey.getState(editor.state)?.undoManager;
279777
+ return {
279778
+ undoDepth: manager?.undoStack?.length ?? 0,
279779
+ redoDepth: manager?.redoStack?.length ?? 0
279780
+ };
279781
+ }, readPmDepths = (editor) => {
279782
+ if (!editor.state)
279783
+ return {
279784
+ undoDepth: 0,
279785
+ redoDepth: 0
279786
+ };
279787
+ try {
279788
+ return {
279789
+ undoDepth: undoDepth(editor.state),
279790
+ redoDepth: redoDepth(editor.state)
279791
+ };
279792
+ } catch {
279793
+ return {
279794
+ undoDepth: 0,
279795
+ redoDepth: 0
279796
+ };
279797
+ }
279798
+ }, readEditorHistorySnapshot = (editor) => {
279799
+ return isYjsBacked(editor) ? readYjsDepths(editor) : readPmDepths(editor);
279800
+ }, EditorHistorySnapshotAdapter = class {
279801
+ #editor;
279802
+ #collaborative;
279803
+ #pendingChangeKind = "unknown";
279804
+ constructor(editor) {
279805
+ this.#editor = editor;
279806
+ this.#collaborative = isYjsBacked(editor);
279807
+ }
279808
+ getSnapshot() {
279809
+ if (this.#collaborative)
279810
+ return readYjsDepths(this.#editor);
279811
+ return readPmDepths(this.#editor);
279812
+ }
279813
+ undo() {
279814
+ return Boolean(runEditorUndo(this.#editor));
279815
+ }
279816
+ redo() {
279817
+ return Boolean(runEditorRedo(this.#editor));
279818
+ }
279819
+ consumePendingChangeKind() {
279820
+ const changeKind = this.#pendingChangeKind;
279821
+ this.#pendingChangeKind = "unknown";
279822
+ return changeKind;
279823
+ }
279824
+ subscribe(onChange$1) {
279825
+ const editor = this.#editor;
279826
+ if (!editor.on || !editor.off)
279827
+ return () => {};
279828
+ const handleTransaction = (payload) => {
279829
+ this.#pendingChangeKind = classifyTransaction(payload?.transaction);
279830
+ onChange$1();
279831
+ };
279832
+ editor.on("transaction", handleTransaction);
279833
+ return () => editor.off?.("transaction", handleTransaction);
279834
+ }
279835
+ }, classifyTransaction = (transaction) => {
279836
+ const inputType = transaction?.getMeta?.("inputType");
279837
+ if (inputType === "historyUndo")
279838
+ return "undo";
279839
+ if (inputType === "historyRedo")
279840
+ return "redo";
279841
+ if (transaction?.docChanged && transaction.getMeta?.("addToHistory") !== false)
279842
+ return "edit";
279843
+ return "unknown";
279844
+ }, HEADER_FOOTER_KEY_PREFIX = "hf:part:", BODY_PARTICIPANT_KEY, buildHeaderFooterParticipantKey = (refId) => `${HEADER_FOOTER_KEY_PREFIX}${refId}`, createBodyParticipant = (editor) => ({
279845
+ key: BODY_PARTICIPANT_KEY,
279846
+ surface: "body",
279847
+ adapter: new EditorHistorySnapshotAdapter(editor)
279848
+ }), createHeaderFooterParticipant = (editor, descriptor) => ({
279849
+ key: buildHeaderFooterParticipantKey(descriptor.id),
279850
+ surface: descriptor.kind,
279851
+ adapter: new EditorHistorySnapshotAdapter(editor)
279852
+ }), createNoteParticipant = (input2) => {
279853
+ const surface = input2.storyType === "footnote" ? "note" : "endnote";
279854
+ return {
279855
+ key: input2.storyKey,
279856
+ surface,
279857
+ adapter: new EditorHistorySnapshotAdapter(input2.editor),
279858
+ flushAfterReplay: input2.flushAfterReplay,
279859
+ onInvalidated: input2.onInvalidated
279860
+ };
279861
+ }, DEFAULT_CAPACITY2 = 20, DEFAULT_IDLE_TTL_MS, SWEEP_INTERVAL_MS, NoteEditorRegistry, defaultScheduleSweep = (callback, intervalMs) => {
279862
+ if (typeof setInterval !== "function")
279863
+ return () => {};
279864
+ const handle3 = setInterval(callback, intervalMs);
279865
+ return () => clearInterval(handle3);
279866
+ }, HISTORY_UNSAFE_OPS, CANONICAL_COMMENT_IGNORED_KEYS, INITIAL_HASH, ROUND_CONSTANTS, V1_COVERAGE, V2_COVERAGE, SNAPSHOT_VERSION_V2 = "sd-diff-snapshot/v2", PAYLOAD_VERSION_V1 = "sd-diff-payload/v1", PAYLOAD_VERSION_V2 = "sd-diff-payload/v2", ENGINE_ID = "super-editor", STAGED_CONVERTER_KEYS, DiffServiceError, DEFAULT_LEVEL = 1, SWITCH_PATTERN, TOC_BOOKMARK_PREFIX = "_Toc", DEFAULT_RIGHT_TAB_POS = 9350, TAB_LEADER_MAP, NO_ENTRIES_PLACEHOLDER, TC_LEVEL_MIN = 1, TC_LEVEL_MAX = 9, ALLOWED_WRAP_ATTRS, WRAP_TYPES_SUPPORTING_SIDE, WRAP_TYPES_SUPPORTING_DISTANCES, RELATIVE_HEIGHT_MIN = 0, RELATIVE_HEIGHT_MAX = 4294967295, FORBIDDEN_RAW_PATCH_NAMES, CONTROL_TYPE_SDT_PR_ELEMENTS, DEFAULT_CHECKBOX_SYMBOL_FONT2 = "MS Gothic", DEFAULT_CHECKBOX_CHECKED_HEX2 = "2612", DEFAULT_CHECKBOX_UNCHECKED_HEX2 = "2610", VARIANT_ORDER, KIND_ORDER, HEADER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", DOCUMENT_RELS_PATH2 = "word/_rels/document.xml.rels", HEADER_FILE_PATTERN2, FOOTER_FILE_PATTERN2, SETTINGS_PART, SPECIAL_NOTE_TYPES, RESTART_POLICY_TO_OOXML, VALID_DISPLAYS, REFERENCE_BLOCK_PREFIX, CAPTION_STYLE_NAMES, CAPTION_PARAGRAPH_STYLE_ID = "Caption", CAPTION_FORMAT_TO_OOXML, DOCUMENT_STAT_FIELD_TYPES, TOA_LEADER_REVERSE_MAP, EDGE_NODE_TYPES, CONTENT_TYPES_PART_ID = "[Content_Types].xml", CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types", contentTypesPartDescriptor, empty_exports, init_empty, CURRENT_APP_VERSION2 = "1.29.0", PIXELS_PER_INCH2 = 96, MAX_HEIGHT_BUFFER_PX = 50, MAX_WIDTH_BUFFER_PX = 20, cloneExtensionInstance = (extension3) => {
279132
279867
  const extensionLike = extension3;
279133
279868
  const config2 = extensionLike?.config;
279134
279869
  const ExtensionCtor = extensionLike?.constructor;
@@ -279268,6 +280003,28 @@ var Node$13 = class Node$14 {
279268
280003
  return true;
279269
280004
  return false;
279270
280005
  }
280006
+ hasCurrentRanges(state) {
280007
+ this.#refreshEligiblePlugins(state);
280008
+ if (this.#eligiblePlugins.length === 0)
280009
+ return false;
280010
+ const docSize = state.doc.content.size;
280011
+ for (const plugin of this.#eligiblePlugins) {
280012
+ const decorationSet = this.#getDecorationSet(plugin, state);
280013
+ if (decorationSet === DecorationSet.empty)
280014
+ continue;
280015
+ for (const decoration of decorationSet.find(0, docSize)) {
280016
+ if (!this.#isInlineDecoration(decoration))
280017
+ continue;
280018
+ const attrs = this.#extractSafeAttrs(decoration);
280019
+ if (!(attrs.classes.length > 0 || attrs.dataEntries.length > 0 || attrs.styleEntries.length > 0))
280020
+ continue;
280021
+ if (decoration.from >= decoration.to)
280022
+ continue;
280023
+ return true;
280024
+ }
280025
+ }
280026
+ return false;
280027
+ }
279271
280028
  collectDecorationRanges(state) {
279272
280029
  this.#refreshEligiblePlugins(state);
279273
280030
  const ranges = [];
@@ -279823,6 +280580,9 @@ var Node$13 = class Node$14 {
279823
280580
  hasDecorationChanges(editorState) {
279824
280581
  return this.#decorationBridge.hasChanges(editorState);
279825
280582
  }
280583
+ hasCurrentDecorationRanges(editorState) {
280584
+ return this.#decorationBridge.hasCurrentRanges(editorState);
280585
+ }
279826
280586
  collectDecorationRanges(editorState) {
279827
280587
  return this.#decorationBridge.collectDecorationRanges(editorState);
279828
280588
  }
@@ -285417,7 +286177,11 @@ menclose::after {
285417
286177
  if (!layoutDebugEnabled$2)
285418
286178
  return;
285419
286179
  console.log(...args$1);
285420
- }, measurementCanvas = null, measurementCtx = null, TAB_CHAR_LENGTH = 1, getRunCharacterLength = (run2) => {
286180
+ }, measurementCanvas = null, measurementCtx = null, TAB_CHAR_LENGTH = 1, FOOTNOTE_MARKER_DATA_ATTR$1 = "data-sd-footnote-number", getRunDataAttrs = (run2) => {
286181
+ if (!run2 || !("dataAttrs" in run2))
286182
+ return;
286183
+ return run2.dataAttrs;
286184
+ }, getRunCharacterLength = (run2) => {
285421
286185
  if (!run2)
285422
286186
  return 0;
285423
286187
  if (isTabRun$1(run2))
@@ -285425,6 +286189,8 @@ menclose::after {
285425
286189
  if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" || run2.kind === "math")
285426
286190
  return 0;
285427
286191
  return run2.text?.length ?? 0;
286192
+ }, isVisualOnlyRun = (run2) => {
286193
+ return getRunDataAttrs(run2)?.[FOOTNOTE_MARKER_DATA_ATTR$1] === "true";
285428
286194
  }, SPACE_CHARS$1, isTabRun$1 = (run2) => run2?.kind === "tab", isWordChar$3 = (char) => {
285429
286195
  if (!char)
285430
286196
  return false;
@@ -285515,6 +286281,39 @@ menclose::after {
285515
286281
  }),
285516
286282
  totalSpaces
285517
286283
  };
286284
+ }, resolveRunPmStart = (run2, runLength) => {
286285
+ if (!run2)
286286
+ return null;
286287
+ if (typeof run2.pmStart === "number")
286288
+ return run2.pmStart;
286289
+ if (typeof run2.pmEnd === "number")
286290
+ return run2.pmEnd - runLength;
286291
+ return null;
286292
+ }, resolveRunPmEnd = (run2, runLength, runPmStart) => {
286293
+ if (!run2)
286294
+ return null;
286295
+ if (typeof run2.pmEnd === "number")
286296
+ return run2.pmEnd;
286297
+ if (runPmStart != null)
286298
+ return runPmStart + runLength;
286299
+ return null;
286300
+ }, findNextPmBoundary = (runs2, startIndex, fallbackPm) => {
286301
+ for (let runIndex = startIndex;runIndex < runs2.length; runIndex += 1) {
286302
+ const run2 = runs2[runIndex];
286303
+ const runLength = getRunCharacterLength(run2);
286304
+ const nextPmStart = resolveRunPmStart(run2, runLength);
286305
+ if (nextPmStart != null)
286306
+ return nextPmStart;
286307
+ const nextPmEnd = resolveRunPmEnd(run2, runLength, nextPmStart);
286308
+ if (nextPmEnd != null)
286309
+ return nextPmEnd;
286310
+ }
286311
+ return fallbackPm;
286312
+ }, resolveVisualOnlyRunBoundary = (runs2, runIndex, offsetInRun, runLength, previousPmBoundary) => {
286313
+ const nextPmBoundary = findNextPmBoundary(runs2, runIndex + 1, previousPmBoundary);
286314
+ if (runLength <= 0 || previousPmBoundary === nextPmBoundary)
286315
+ return previousPmBoundary;
286316
+ return offsetInRun < runLength / 2 ? previousPmBoundary : nextPmBoundary;
285518
286317
  }, computeLetterSpacingWidth = (run2, precedingChars, runLength) => {
285519
286318
  if (isTabRun$1(run2) || "src" in run2 || run2.kind === "fieldAnnotation" || !("letterSpacing" in run2) || !run2.letterSpacing)
285520
286319
  return 0;
@@ -290309,8 +291108,7 @@ menclose::after {
290309
291108
  handledByDepth = this.#callbacks.selectParagraphAt?.(selectionPos) ?? false;
290310
291109
  else if (clickDepth === 2)
290311
291110
  handledByDepth = this.#callbacks.selectWordAt?.(selectionPos) ?? false;
290312
- if (!(editor.view?.hasFocus?.() ?? false))
290313
- this.#focusEditor();
291111
+ this.#focusEditor();
290314
291112
  if (!handledByDepth)
290315
291113
  try {
290316
291114
  const sdtBlock = clickDepth === 1 ? this.#findStructuredContentBlockAtPos(doc$12, hit.pos) : null;
@@ -290516,9 +291314,7 @@ menclose::after {
290516
291314
  this.#suppressFocusInFromDraggable = false;
290517
291315
  return;
290518
291316
  }
290519
- try {
290520
- this.#deps.getActiveEditor().view?.focus();
290521
- } catch {}
291317
+ this.#focusEditorView(this.#deps.getActiveEditor().view);
290522
291318
  this.#callbacks.scheduleSelectionUpdate?.();
290523
291319
  }
290524
291320
  #handleEditorFocus() {
@@ -291132,7 +291928,7 @@ menclose::after {
291132
291928
  editor.view?.dispatch(tr);
291133
291929
  } catch {}
291134
291930
  editorDom.focus();
291135
- editor?.view?.focus();
291931
+ this.#focusEditorView(editor?.view);
291136
291932
  this.#callbacks.scheduleSelectionUpdate?.();
291137
291933
  }
291138
291934
  #focusEditor() {
@@ -291141,14 +291937,19 @@ menclose::after {
291141
291937
  if (!editorDom)
291142
291938
  return;
291143
291939
  const active = document.activeElement;
291144
- const activeIsEditor = active === editorDom || !!active && editorDom.contains?.(active);
291145
- const hasFocus = typeof view.hasFocus === "function" && view.hasFocus();
291146
- if (activeIsEditor || hasFocus)
291940
+ if (active === editorDom || !!active && editorDom.contains?.(active))
291147
291941
  return;
291148
291942
  if (active instanceof HTMLElement)
291149
291943
  active.blur();
291150
291944
  editorDom.focus();
291151
- view?.focus();
291945
+ this.#focusEditorView(view);
291946
+ }
291947
+ #focusEditorView(view) {
291948
+ if (typeof view?.focus !== "function")
291949
+ return;
291950
+ try {
291951
+ view.focus();
291952
+ } catch {}
291152
291953
  }
291153
291954
  #handleRepeatClickOnActiveComment(event, target, editor) {
291154
291955
  const activeThreadId = getActiveCommentThreadId(editor);
@@ -291343,7 +292144,7 @@ menclose::after {
291343
292144
  if (options?.suppressOriginal)
291344
292145
  this.#suppressOriginalEvent(originalEvent);
291345
292146
  if (options?.focusTarget)
291346
- this.#focusTargetDom(target);
292147
+ this.#focusTargetDom(target, { force: options?.forceFocusTarget ?? false });
291347
292148
  this.#currentTarget = target;
291348
292149
  try {
291349
292150
  if (!target.dispatchEvent(synthetic) || synthetic.defaultPrevented)
@@ -291362,20 +292163,42 @@ menclose::after {
291362
292163
  return null;
291363
292164
  return target;
291364
292165
  }
291365
- #focusTargetDom(target) {
292166
+ #focusTargetDom(target, options) {
292167
+ const forceFocusRestore = options?.force ?? false;
292168
+ const doc$12 = target.ownerDocument ?? document;
292169
+ const selection = doc$12.getSelection?.() ?? null;
292170
+ const selectionInsideTarget = !!selection?.anchorNode && target.contains(selection.anchorNode);
292171
+ if (!forceFocusRestore && selectionInsideTarget)
292172
+ return;
291366
292173
  const targetEditor = this.#getTargetEditor?.() ?? null;
291367
- if ((targetEditor?.view?.dom ?? null) === target && typeof targetEditor?.focus === "function") {
292174
+ const targetEditorDom = targetEditor?.view?.dom ?? null;
292175
+ if (targetEditorDom === target && typeof targetEditor?.focus === "function") {
291368
292176
  targetEditor.focus();
292177
+ this.#syncEditorSelectionToDom(targetEditor);
291369
292178
  return;
291370
292179
  }
291371
- const active = (target.ownerDocument ?? document).activeElement;
291372
- if (active === target || !!active && target.contains(active))
292180
+ const active = doc$12.activeElement;
292181
+ const activeIsTarget = active === target || !!active && target.contains(active);
292182
+ if (!forceFocusRestore && activeIsTarget)
291373
292183
  return;
291374
292184
  try {
291375
292185
  target.focus({ preventScroll: true });
291376
292186
  } catch {
291377
292187
  target.focus();
291378
292188
  }
292189
+ if (targetEditorDom === target)
292190
+ this.#syncEditorSelectionToDom(targetEditor);
292191
+ }
292192
+ #syncEditorSelectionToDom(editor) {
292193
+ const selection = editor?.state?.selection;
292194
+ const transaction = editor?.state?.tr;
292195
+ const dispatch = editor?.view?.dispatch;
292196
+ const setSelection = transaction?.setSelection;
292197
+ if (!selection || !transaction || typeof setSelection !== "function" || typeof dispatch !== "function")
292198
+ return;
292199
+ const selectionTransaction = setSelection.call(transaction, selection);
292200
+ selectionTransaction?.setMeta?.("addToHistory", false);
292201
+ dispatch(selectionTransaction);
291379
292202
  }
291380
292203
  #suppressOriginalEvent(event) {
291381
292204
  event.preventDefault();
@@ -291455,6 +292278,7 @@ menclose::after {
291455
292278
  });
291456
292279
  this.#dispatchToResolvedTarget(event, synthetic, staleOrigin.activeTarget, {
291457
292280
  focusTarget: true,
292281
+ forceFocusTarget: true,
291458
292282
  suppressOriginal: true
291459
292283
  });
291460
292284
  }
@@ -291519,6 +292343,7 @@ menclose::after {
291519
292343
  });
291520
292344
  this.#dispatchToResolvedTarget(event, synthetic, staleOrigin.activeTarget, {
291521
292345
  focusTarget: true,
292346
+ forceFocusTarget: true,
291522
292347
  suppressOriginal: true
291523
292348
  });
291524
292349
  }
@@ -291568,6 +292393,7 @@ menclose::after {
291568
292393
  });
291569
292394
  this.#dispatchToResolvedTarget(event, synthetic, staleOrigin.activeTarget, {
291570
292395
  focusTarget: true,
292396
+ forceFocusTarget: true,
291571
292397
  suppressOriginal: true
291572
292398
  });
291573
292399
  }
@@ -294049,17 +294875,19 @@ menclose::after {
294049
294875
  pointer-events: none;
294050
294876
  z-index: 1000;
294051
294877
  }
294052
- `, fieldAnnotationInteractionStylesInjected = false, VOLATILE_HISTORY_ATTR_KEYS, DOCUMENT_RELS_PART_ID = "word/_rels/document.xml.rels", DEFAULT_PAGE_SIZE, DEFAULT_MARGINS, DEFAULT_PAGE_GAP = 24, DEFAULT_HORIZONTAL_PAGE_GAP = 20, layoutDebugEnabled, perfLog = (...args$1) => {
294878
+ `, fieldAnnotationInteractionStylesInjected = false, INTERNAL_NOTE_COMMIT_SOURCES, isInternalNoteCommitSource = (event) => {
294879
+ return typeof event?.source === "string" && INTERNAL_NOTE_COMMIT_SOURCES.has(event.source);
294880
+ }, DOCUMENT_RELS_PART_ID = "word/_rels/document.xml.rels", DEFAULT_PAGE_SIZE, DEFAULT_MARGINS, DEFAULT_PAGE_GAP = 24, DEFAULT_HORIZONTAL_PAGE_GAP = 20, layoutDebugEnabled, perfLog = (...args$1) => {
294053
294881
  if (!layoutDebugEnabled)
294054
294882
  return;
294055
294883
  console.log(...args$1);
294056
294884
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions;
294057
- var init_src_CLao_BLx_es = __esm(() => {
294885
+ var init_src_CjxSHf0p_es = __esm(() => {
294058
294886
  init_rolldown_runtime_Bg48TavK_es();
294059
- init_SuperConverter_Dn6cDET4_es();
294887
+ init_SuperConverter_2Pu0hMB1_es();
294060
294888
  init_jszip_C49i9kUs_es();
294061
294889
  init_uuid_qzgm05fK_es();
294062
- init_create_headless_toolbar_CQu_F9Mr_es();
294890
+ init_create_headless_toolbar_sMwtuYL8_es();
294063
294891
  init_constants_CGhJRd87_es();
294064
294892
  init_dist_B8HfvhaK_es();
294065
294893
  init_unified_Dsuw2be5_es();
@@ -296162,7 +296990,7 @@ ${err.toString()}`);
296162
296990
  const posTo = pos + node3.nodeSize;
296163
296991
  let content3 = null;
296164
296992
  if (options.text) {
296165
- const firstTextNode = options.keepTextNodeStyles === true ? findFirstTextNode(node3) : null;
296993
+ const firstTextNode = options.keepTextNodeStyles === true ? findFirstTextNode$1(node3) : null;
296166
296994
  const textMarks = firstTextNode ? firstTextNode.marks : [];
296167
296995
  content3 = schema.text(options.text, textMarks);
296168
296996
  }
@@ -296244,7 +297072,7 @@ ${err.toString()}`);
296244
297072
  const { pos, node: node3 } = structuredContent;
296245
297073
  let content3 = null;
296246
297074
  if (options.text) {
296247
- const firstTextNode = options.keepTextNodeStyles === true ? findFirstTextNode(node3) : null;
297075
+ const firstTextNode = options.keepTextNodeStyles === true ? findFirstTextNode$1(node3) : null;
296248
297076
  const textMarks = firstTextNode ? firstTextNode.marks : [];
296249
297077
  content3 = schema.text(options.text, textMarks);
296250
297078
  }
@@ -296618,7 +297446,7 @@ ${err.toString()}`);
296618
297446
  };
296619
297447
  }
296620
297448
  });
296621
- Text$1 = Node$13.create({
297449
+ Text$2 = Node$13.create({
296622
297450
  name: "text",
296623
297451
  group: "inline",
296624
297452
  inline: true,
@@ -315900,16 +316728,21 @@ function print() { __p += __j.call(arguments, '') }
315900
316728
  editable: () => editor.options.editable,
315901
316729
  handleDOMEvents: {
315902
316730
  beforeinput: (view, event) => {
316731
+ recordStoryInputDebug(view, event, editor, "dom:beforeinput");
315903
316732
  if (!editor.options.editable) {
315904
316733
  event.preventDefault();
315905
316734
  return true;
315906
316735
  }
315907
316736
  if (shouldForceEndStaleComposition(view, event))
315908
316737
  __endComposition(view);
315909
- if (handleInsertTextBeforeInput(view, event))
316738
+ if (handleInsertTextBeforeInput(view, event, editor))
315910
316739
  return true;
315911
316740
  return false;
315912
316741
  },
316742
+ input: (view, event) => {
316743
+ recordStoryInputDebug(view, event, editor, "dom:input");
316744
+ return false;
316745
+ },
315913
316746
  compositionstart: (view, event) => blockWhenNotEditable(view, event),
315914
316747
  compositionupdate: (view, event) => blockWhenNotEditable(view, event),
315915
316748
  compositionend: (view, event) => blockWhenNotEditable(view, event),
@@ -317266,6 +318099,189 @@ function print() { __p += __j.call(arguments, '') }
317266
318099
  syncHeaderFooterCaches(editor, part);
317267
318100
  }
317268
318101
  };
318102
+ BODY_PARTICIPANT_KEY = BODY_STORY_KEY;
318103
+ DEFAULT_IDLE_TTL_MS = 600 * 1000;
318104
+ SWEEP_INTERVAL_MS = 30 * 1000;
318105
+ NoteEditorRegistry = class extends EventEmitter2 {
318106
+ #entries = /* @__PURE__ */ new Map;
318107
+ #capacity;
318108
+ #idleTtlMs;
318109
+ #now;
318110
+ #onBeforeAutoDispose;
318111
+ #scheduleSweep;
318112
+ #cancelSweep = null;
318113
+ constructor(options = {}) {
318114
+ super();
318115
+ this.#capacity = Math.max(1, options.capacity ?? DEFAULT_CAPACITY2);
318116
+ this.#idleTtlMs = Math.max(0, options.idleTtlMs ?? DEFAULT_IDLE_TTL_MS);
318117
+ this.#now = options.now ?? (() => Date.now());
318118
+ this.#onBeforeAutoDispose = options.onBeforeAutoDispose;
318119
+ this.#scheduleSweep = options.scheduleSweep ?? defaultScheduleSweep;
318120
+ }
318121
+ get(storyKey) {
318122
+ const entry = this.#entries.get(storyKey);
318123
+ if (!entry)
318124
+ return null;
318125
+ entry.lastAccessMs = this.#now();
318126
+ return entry.editor;
318127
+ }
318128
+ register(input2) {
318129
+ const existing = this.#entries.get(input2.storyKey);
318130
+ if (existing) {
318131
+ existing.editor = input2.editor;
318132
+ existing.locator = input2.locator;
318133
+ existing.commit = input2.commit ?? null;
318134
+ existing.lastAccessMs = this.#now();
318135
+ return;
318136
+ }
318137
+ const entry = {
318138
+ storyKey: input2.storyKey,
318139
+ locator: input2.locator,
318140
+ editor: input2.editor,
318141
+ commit: input2.commit ?? null,
318142
+ lastAccessMs: this.#now(),
318143
+ pinned: false,
318144
+ disposers: /* @__PURE__ */ new Set
318145
+ };
318146
+ this.#entries.set(input2.storyKey, entry);
318147
+ this.emit("editorCreated", {
318148
+ storyKey: input2.storyKey,
318149
+ editor: input2.editor,
318150
+ locator: input2.locator
318151
+ });
318152
+ this.#syncSweepSchedule();
318153
+ this.#enforceCapacity();
318154
+ }
318155
+ attachDisposer(storyKey, disposer) {
318156
+ const entry = this.#entries.get(storyKey);
318157
+ if (!entry) {
318158
+ disposer();
318159
+ return;
318160
+ }
318161
+ entry.disposers.add(disposer);
318162
+ }
318163
+ setCommitHook(storyKey, commit) {
318164
+ const entry = this.#entries.get(storyKey);
318165
+ if (!entry)
318166
+ return;
318167
+ entry.commit = commit;
318168
+ }
318169
+ getCommitHook(storyKey) {
318170
+ return this.#entries.get(storyKey)?.commit ?? null;
318171
+ }
318172
+ pin(storyKey) {
318173
+ const entry = this.#entries.get(storyKey);
318174
+ if (!entry)
318175
+ return;
318176
+ entry.pinned = true;
318177
+ entry.lastAccessMs = this.#now();
318178
+ this.#syncSweepSchedule();
318179
+ }
318180
+ unpin(storyKey) {
318181
+ const entry = this.#entries.get(storyKey);
318182
+ if (!entry)
318183
+ return;
318184
+ entry.pinned = false;
318185
+ this.#syncSweepSchedule();
318186
+ this.#enforceCapacity();
318187
+ }
318188
+ isPinned(storyKey) {
318189
+ return this.#entries.get(storyKey)?.pinned ?? false;
318190
+ }
318191
+ touch(storyKey) {
318192
+ const entry = this.#entries.get(storyKey);
318193
+ if (!entry)
318194
+ return;
318195
+ entry.lastAccessMs = this.#now();
318196
+ }
318197
+ purge(storyKey, reason = "purge") {
318198
+ const entry = this.#entries.get(storyKey);
318199
+ if (!entry)
318200
+ return;
318201
+ this.#entries.delete(storyKey);
318202
+ this.#syncSweepSchedule();
318203
+ this.#disposeEntry(entry, reason);
318204
+ }
318205
+ get size() {
318206
+ return this.#entries.size;
318207
+ }
318208
+ keys() {
318209
+ return Array.from(this.#entries.keys());
318210
+ }
318211
+ runIdleSweep() {
318212
+ if (this.#idleTtlMs <= 0)
318213
+ return;
318214
+ const cutoff = this.#now() - this.#idleTtlMs;
318215
+ for (const [storyKey, entry] of this.#entries) {
318216
+ if (entry.pinned)
318217
+ continue;
318218
+ if (entry.lastAccessMs > cutoff)
318219
+ continue;
318220
+ this.#entries.delete(storyKey);
318221
+ this.#disposeEntry(entry, "idle");
318222
+ }
318223
+ this.#syncSweepSchedule();
318224
+ }
318225
+ destroy() {
318226
+ this.#cancelSweep?.();
318227
+ this.#cancelSweep = null;
318228
+ for (const entry of this.#entries.values())
318229
+ this.#disposeEntry(entry, "destroy");
318230
+ this.#entries.clear();
318231
+ this.removeAllListeners();
318232
+ }
318233
+ #enforceCapacity() {
318234
+ const unpinned = [];
318235
+ for (const entry of this.#entries.values())
318236
+ if (!entry.pinned)
318237
+ unpinned.push(entry);
318238
+ if (unpinned.length <= this.#capacity)
318239
+ return;
318240
+ unpinned.sort((a2, b$1) => a2.lastAccessMs - b$1.lastAccessMs);
318241
+ const excess = unpinned.length - this.#capacity;
318242
+ for (let i4 = 0;i4 < excess; i4 += 1) {
318243
+ const victim = unpinned[i4];
318244
+ this.#entries.delete(victim.storyKey);
318245
+ this.#disposeEntry(victim, "cap");
318246
+ }
318247
+ this.#syncSweepSchedule();
318248
+ }
318249
+ #syncSweepSchedule() {
318250
+ if (this.#idleTtlMs <= 0) {
318251
+ this.#cancelSweep?.();
318252
+ this.#cancelSweep = null;
318253
+ return;
318254
+ }
318255
+ if (!Array.from(this.#entries.values()).some((entry) => !entry.pinned)) {
318256
+ this.#cancelSweep?.();
318257
+ this.#cancelSweep = null;
318258
+ return;
318259
+ }
318260
+ if (this.#cancelSweep)
318261
+ return;
318262
+ this.#cancelSweep = this.#scheduleSweep(() => this.runIdleSweep(), SWEEP_INTERVAL_MS);
318263
+ }
318264
+ #disposeEntry(entry, reason) {
318265
+ if (reason !== "purge" && reason !== "destroy")
318266
+ this.#onBeforeAutoDispose?.(entry.storyKey);
318267
+ entry.disposers.forEach((disposer) => {
318268
+ try {
318269
+ disposer();
318270
+ } catch (error3) {
318271
+ console.warn("[NoteEditorRegistry] disposer threw:", error3);
318272
+ }
318273
+ });
318274
+ try {
318275
+ entry.editor.destroy?.();
318276
+ } catch (error3) {
318277
+ console.warn("[NoteEditorRegistry] editor.destroy threw:", error3);
318278
+ }
318279
+ this.emit("editorDisposed", {
318280
+ storyKey: entry.storyKey,
318281
+ reason
318282
+ });
318283
+ }
318284
+ };
317269
318285
  HISTORY_UNSAFE_OPS = OPERATION_IDS2.filter((id2) => COMMAND_CATALOG3[id2].historyUnsafe === true);
317270
318286
  CANONICAL_COMMENT_IGNORED_KEYS = COMMENT_ATTRS_DIFF_IGNORED_KEYS.filter((key2) => key2 !== "textJson" && key2 !== "elements" && key2 !== "commentId");
317271
318287
  INITIAL_HASH = [
@@ -324339,6 +325355,7 @@ function print() { __p += __j.call(arguments, '') }
324339
325355
  #cacheHits = 0;
324340
325356
  #cacheMisses = 0;
324341
325357
  #evictions = 0;
325358
+ #pinnedIds = /* @__PURE__ */ new Set;
324342
325359
  constructor(editor) {
324343
325360
  super();
324344
325361
  this.#editor = editor;
@@ -324595,13 +325612,22 @@ function print() { __p += __j.call(arguments, '') }
324595
325612
  } catch (error3) {
324596
325613
  console.warn("[HeaderFooterEditorManager] Cleanup failed for editor:", key2, error3);
324597
325614
  }
324598
- toRemove.push(key2);
325615
+ toRemove.push({
325616
+ key: key2,
325617
+ descriptor: entry.descriptor
325618
+ });
324599
325619
  }
324600
325620
  });
324601
- toRemove.forEach((key2) => this.#editorEntries.delete(key2));
325621
+ toRemove.forEach(({ key: key2, descriptor }) => {
325622
+ this.#editorEntries.delete(key2);
325623
+ this.#pinnedIds.delete(key2);
325624
+ this.emit("editorDisposed", { descriptor });
325625
+ });
324602
325626
  }
324603
325627
  #teardownEditors() {
325628
+ const descriptors2 = [];
324604
325629
  this.#editorEntries.forEach((entry) => {
325630
+ descriptors2.push(entry.descriptor);
324605
325631
  try {
324606
325632
  entry.disposer();
324607
325633
  } catch (error3) {
@@ -324609,6 +325635,10 @@ function print() { __p += __j.call(arguments, '') }
324609
325635
  }
324610
325636
  });
324611
325637
  this.#editorEntries.clear();
325638
+ this.#pinnedIds.clear();
325639
+ descriptors2.forEach((descriptor) => {
325640
+ this.emit("editorDisposed", { descriptor });
325641
+ });
324612
325642
  }
324613
325643
  #createEditorEntry(descriptor, options) {
324614
325644
  const json = this.getDocumentJson(descriptor);
@@ -324700,13 +325730,18 @@ function print() { __p += __j.call(arguments, '') }
324700
325730
  }
324701
325731
  });
324702
325732
  });
324703
- return {
325733
+ const entry = {
324704
325734
  descriptor,
324705
325735
  editor,
324706
325736
  container,
324707
325737
  disposer,
324708
325738
  ready
324709
325739
  };
325740
+ this.emit("editorCreated", {
325741
+ descriptor,
325742
+ editor
325743
+ });
325744
+ return entry;
324710
325745
  }
324711
325746
  #mountAndUpdateEntry(entry, options) {
324712
325747
  if (entry.container && options?.editorHost && entry.container.parentElement !== options.editorHost)
@@ -324769,21 +325804,56 @@ function print() { __p += __j.call(arguments, '') }
324769
325804
  this.#editorAccessOrder.push(id2);
324770
325805
  }
324771
325806
  #enforceCacheSizeLimit() {
324772
- while (this.#editorAccessOrder.length > this.#maxCachedEditors) {
324773
- const oldestId = this.#editorAccessOrder.shift();
325807
+ const overflow = () => this.#countEvictableEntries() > this.#maxCachedEditors;
325808
+ let guard$1 = this.#editorAccessOrder.length;
325809
+ while (overflow() && guard$1 > 0) {
325810
+ guard$1 -= 1;
325811
+ const oldestId = this.#findOldestEvictableId();
324774
325812
  if (!oldestId)
324775
325813
  break;
324776
- const oldEntry = this.#editorEntries.get(oldestId);
324777
- if (oldEntry) {
324778
- try {
324779
- oldEntry.disposer();
324780
- this.#evictions += 1;
324781
- } catch (error3) {
324782
- console.warn("[HeaderFooterEditorManager] LRU eviction cleanup failed:", error3);
324783
- }
324784
- this.#editorEntries.delete(oldestId);
324785
- }
325814
+ this.#evictById(oldestId);
325815
+ }
325816
+ }
325817
+ #countEvictableEntries() {
325818
+ let count2 = 0;
325819
+ for (const id2 of this.#editorAccessOrder)
325820
+ if (!this.#pinnedIds.has(id2))
325821
+ count2 += 1;
325822
+ return count2;
325823
+ }
325824
+ #findOldestEvictableId() {
325825
+ for (const id2 of this.#editorAccessOrder)
325826
+ if (!this.#pinnedIds.has(id2))
325827
+ return id2;
325828
+ return null;
325829
+ }
325830
+ #evictById(id2) {
325831
+ this.#editorAccessOrder = this.#editorAccessOrder.filter((existingId) => existingId !== id2);
325832
+ const oldEntry = this.#editorEntries.get(id2);
325833
+ if (!oldEntry)
325834
+ return;
325835
+ try {
325836
+ oldEntry.disposer();
325837
+ this.#evictions += 1;
325838
+ } catch (error3) {
325839
+ console.warn("[HeaderFooterEditorManager] LRU eviction cleanup failed:", error3);
324786
325840
  }
325841
+ this.#editorEntries.delete(id2);
325842
+ this.emit("editorDisposed", { descriptor: oldEntry.descriptor });
325843
+ }
325844
+ pin(id2) {
325845
+ if (!id2)
325846
+ return;
325847
+ this.#pinnedIds.add(id2);
325848
+ }
325849
+ unpin(id2) {
325850
+ if (!id2)
325851
+ return;
325852
+ this.#pinnedIds.delete(id2);
325853
+ this.#enforceCacheSizeLimit();
325854
+ }
325855
+ isPinned(id2) {
325856
+ return this.#pinnedIds.has(id2);
324787
325857
  }
324788
325858
  setMaxCachedEditors(max$2) {
324789
325859
  if (max$2 < 1)
@@ -324855,7 +325925,7 @@ function print() { __p += __j.call(arguments, '') }
324855
325925
  after: 12
324856
325926
  }
324857
325927
  };
324858
- VOLATILE_HISTORY_ATTR_KEYS = new Set(["sdBlockId", "sdBlockRev"]);
325928
+ INTERNAL_NOTE_COMMIT_SOURCES = new Set(["story-runtime:commit:footnote", "story-runtime:commit:endnote"]);
324859
325929
  DEFAULT_PAGE_SIZE = {
324860
325930
  w: 612,
324861
325931
  h: 792
@@ -324974,8 +326044,11 @@ function print() { __p += __j.call(arguments, '') }
324974
326044
  #storySessionSelectionHandler = null;
324975
326045
  #storySessionTransactionHandler = null;
324976
326046
  #storySessionEditor = null;
324977
- #persistentStorySessionEditors = /* @__PURE__ */ new WeakSet;
324978
- #lastPersistentStoryHistoryEditor = null;
326047
+ #historyCoordinator = null;
326048
+ #noteEditorRegistry = null;
326049
+ #historyCoordinatorCleanup = [];
326050
+ #coordinatorDrivenNotePurges = /* @__PURE__ */ new Set;
326051
+ #lastPublishedActiveSurface = null;
324979
326052
  #activeSurfaceUiEventEditor = null;
324980
326053
  #activeSurfaceUiUpdateHandler = null;
324981
326054
  #activeSurfaceUiContextMenuOpenHandler = null;
@@ -325205,6 +326278,7 @@ function print() { __p += __j.call(arguments, '') }
325205
326278
  this.setContextMenuDisabled(this.#options.disableContextMenu);
325206
326279
  this.#setupHeaderFooterSession();
325207
326280
  this.#setupStorySessionManager();
326281
+ this.#setupUnifiedHistoryCoordinator();
325208
326282
  this.#applyZoom();
325209
326283
  this.#setupEditorListeners();
325210
326284
  this.#initializeEditorInputManager();
@@ -325422,16 +326496,25 @@ function print() { __p += __j.call(arguments, '') }
325422
326496
  return "header";
325423
326497
  if (mode === "footer")
325424
326498
  return "footer";
326499
+ const locator = this.#storySessionManager?.getActiveSession()?.locator;
326500
+ if (locator?.storyType === "footnote")
326501
+ return "note";
326502
+ if (locator?.storyType === "endnote")
326503
+ return "endnote";
325425
326504
  return "body";
325426
326505
  }
325427
326506
  captureCurrentSelectionHandle() {
325428
- const surface = this.#resolveActiveSurface();
326507
+ const surface = this.#resolveSelectionHandleSurface();
325429
326508
  return this.getActiveEditor().captureCurrentSelectionHandle(surface);
325430
326509
  }
325431
326510
  captureEffectiveSelectionHandle() {
325432
- const surface = this.#resolveActiveSurface();
326511
+ const surface = this.#resolveSelectionHandleSurface();
325433
326512
  return this.getActiveEditor().captureEffectiveSelectionHandle(surface);
325434
326513
  }
326514
+ #resolveSelectionHandleSurface() {
326515
+ const surface = this.#resolveActiveSurface();
326516
+ return surface === "header" || surface === "footer" ? surface : "body";
326517
+ }
325435
326518
  resolveSelectionHandle(handle3) {
325436
326519
  const ownerEditor = handle3._owner;
325437
326520
  const range = ownerEditor.resolveSelectionHandle(handle3);
@@ -325458,7 +326541,7 @@ function print() { __p += __j.call(arguments, '') }
325458
326541
  return {
325459
326542
  editor: activeEditor,
325460
326543
  doc: activeEditor.doc,
325461
- surface: this.#resolveActiveSurface(),
326544
+ surface: this.#resolveSelectionHandleSurface(),
325462
326545
  range: activeEditor.getCurrentSelectionRange()
325463
326546
  };
325464
326547
  }
@@ -325467,98 +326550,93 @@ function print() { __p += __j.call(arguments, '') }
325467
326550
  return {
325468
326551
  editor: activeEditor,
325469
326552
  doc: activeEditor.doc,
325470
- surface: this.#resolveActiveSurface(),
326553
+ surface: this.#resolveSelectionHandleSurface(),
325471
326554
  range: activeEditor.getEffectiveSelectionRange()
325472
326555
  };
325473
326556
  }
325474
- #runEditorHistoryCommand(editor, command$1) {
326557
+ #canRunEditorHistoryCommand(editor, command$1) {
325475
326558
  if (!editor)
325476
- return {
325477
- didRun: false,
325478
- didChangeDoc: false
325479
- };
325480
- const beforeDoc = editor.state?.doc ?? null;
326559
+ return false;
325481
326560
  try {
325482
- const didRun = command$1 === "undo" ? runEditorUndo(editor) : runEditorRedo(editor);
325483
- const rawDidChangeDoc = beforeDoc && editor.state?.doc && typeof editor.state.doc.eq === "function" ? !editor.state.doc.eq(beforeDoc) : didRun;
325484
- const didChangeDoc = editor === this.#editor && rawDidChangeDoc && docsEqualIgnoringVolatileHistoryAttrs(beforeDoc, editor.state?.doc) ? false : rawDidChangeDoc;
325485
- if (didRun && this.#persistentStorySessionEditors.has(editor))
325486
- this.#lastPersistentStoryHistoryEditor = editor;
325487
- return {
325488
- didRun,
325489
- didChangeDoc
325490
- };
326561
+ return Boolean(command$1 === "undo" ? runEditorUndo(editor, { allowDispatch: false }) : runEditorRedo(editor, { allowDispatch: false }));
325491
326562
  } catch {
325492
- return {
325493
- didRun: false,
325494
- didChangeDoc: false
325495
- };
326563
+ return false;
325496
326564
  }
325497
326565
  }
325498
- #runPersistentStoryHistoryCommand(command$1) {
325499
- const editor = this.#lastPersistentStoryHistoryEditor;
325500
- if (!editor || !this.#persistentStorySessionEditors.has(editor))
325501
- return false;
325502
- const handler2 = command$1 === "undo" ? editor.commands?.undo : editor.commands?.redo;
325503
- if (typeof handler2 !== "function")
325504
- return false;
326566
+ canUndo() {
326567
+ if (this.#historyCoordinator)
326568
+ return this.#historyCoordinator.canUndo();
326569
+ return this.#canRunEditorHistoryCommand(this.getActiveEditor(), "undo");
326570
+ }
326571
+ canRedo() {
326572
+ if (this.#historyCoordinator)
326573
+ return this.#historyCoordinator.canRedo();
326574
+ return this.#canRunEditorHistoryCommand(this.getActiveEditor(), "redo");
326575
+ }
326576
+ undo() {
326577
+ if (this.#historyCoordinator) {
326578
+ const result = this.#historyCoordinator.undo();
326579
+ this.#debugUnifiedHistory("undo()", {
326580
+ mode: "coordinator",
326581
+ result,
326582
+ activeSurface: this.#resolveActiveSurface(),
326583
+ state: this.#historyCoordinator.getState()
326584
+ });
326585
+ return result;
326586
+ }
325505
326587
  try {
325506
- const didRun = Boolean(handler2());
325507
- if (didRun)
325508
- this.#lastPersistentStoryHistoryEditor = editor;
325509
- return didRun;
326588
+ const result = Boolean(runEditorUndo(this.getActiveEditor()));
326589
+ this.#debugUnifiedHistory("undo()", {
326590
+ mode: "legacy",
326591
+ result,
326592
+ activeSurface: this.#resolveActiveSurface(),
326593
+ state: readEditorHistorySnapshot(this.getActiveEditor())
326594
+ });
326595
+ return result;
325510
326596
  } catch {
325511
326597
  return false;
325512
326598
  }
325513
326599
  }
325514
- #canRunEditorHistoryCommand(editor, command$1) {
325515
- if (!editor)
325516
- return false;
326600
+ redo() {
326601
+ if (this.#historyCoordinator) {
326602
+ const result = this.#historyCoordinator.redo();
326603
+ this.#debugUnifiedHistory("redo()", {
326604
+ mode: "coordinator",
326605
+ result,
326606
+ activeSurface: this.#resolveActiveSurface(),
326607
+ state: this.#historyCoordinator.getState()
326608
+ });
326609
+ return result;
326610
+ }
325517
326611
  try {
325518
- return Boolean(command$1 === "undo" ? runEditorUndo(editor, { allowDispatch: false }) : runEditorRedo(editor, { allowDispatch: false }));
326612
+ const result = Boolean(runEditorRedo(this.getActiveEditor()));
326613
+ this.#debugUnifiedHistory("redo()", {
326614
+ mode: "legacy",
326615
+ result,
326616
+ activeSurface: this.#resolveActiveSurface(),
326617
+ state: readEditorHistorySnapshot(this.getActiveEditor())
326618
+ });
326619
+ return result;
325519
326620
  } catch {
325520
326621
  return false;
325521
326622
  }
325522
326623
  }
325523
- #canRunPersistentStoryHistoryCommand(command$1) {
325524
- const editor = this.#lastPersistentStoryHistoryEditor;
325525
- if (!editor || !this.#persistentStorySessionEditors.has(editor))
325526
- return false;
325527
- return this.#canRunEditorHistoryCommand(editor, command$1);
325528
- }
325529
- canUndo() {
325530
- const editor = this.getActiveEditor();
325531
- if (this.#canRunEditorHistoryCommand(editor, "undo"))
325532
- return true;
325533
- if (editor === this.#editor)
325534
- return this.#canRunPersistentStoryHistoryCommand("undo");
325535
- return false;
325536
- }
325537
- canRedo() {
325538
- const editor = this.getActiveEditor();
325539
- if (this.#canRunEditorHistoryCommand(editor, "redo"))
325540
- return true;
325541
- if (editor === this.#editor)
325542
- return this.#canRunPersistentStoryHistoryCommand("redo");
325543
- return false;
326624
+ getHistoryState() {
326625
+ if (this.#historyCoordinator)
326626
+ return this.#historyCoordinator.getState();
326627
+ const activeEditorSnapshot = readEditorHistorySnapshot(this.getActiveEditor());
326628
+ return {
326629
+ canUndo: this.canUndo(),
326630
+ canRedo: this.canRedo(),
326631
+ undoDepth: activeEditorSnapshot.undoDepth,
326632
+ redoDepth: activeEditorSnapshot.redoDepth
326633
+ };
325544
326634
  }
325545
- undo() {
325546
- const editor = this.getActiveEditor();
325547
- const { didRun, didChangeDoc } = this.#runEditorHistoryCommand(editor, "undo");
325548
- if (didRun && (editor !== this.#editor || didChangeDoc))
325549
- return true;
325550
- if (editor === this.#editor)
325551
- return this.#runPersistentStoryHistoryCommand("undo");
325552
- return false;
326635
+ get historyCoordinator() {
326636
+ return this.#historyCoordinator;
325553
326637
  }
325554
- redo() {
325555
- const editor = this.getActiveEditor();
325556
- const { didRun, didChangeDoc } = this.#runEditorHistoryCommand(editor, "redo");
325557
- if (didRun && (editor !== this.#editor || didChangeDoc))
325558
- return true;
325559
- if (editor === this.#editor)
325560
- return this.#runPersistentStoryHistoryCommand("redo");
325561
- return false;
326638
+ recordHistoryBatch(batch2) {
326639
+ this.#historyCoordinator?.withHistoryBatch(batch2);
325562
326640
  }
325563
326641
  dispatchInActiveEditor(callback) {
325564
326642
  callback(this.getActiveEditor());
@@ -326219,7 +327297,15 @@ function print() { __p += __j.call(arguments, '') }
326219
327297
  return null;
326220
327298
  const noteContext = this.#buildActiveNoteLayoutContext();
326221
327299
  if (noteContext) {
326222
- const rawHit$1 = this.#resolveNoteDomHit(noteContext, clientX, clientY) ?? clickToPositionGeometry(this.#layoutState.layout, noteContext.blocks, noteContext.measures, normalized, { geometryHelper: this.#pageGeometryHelper ?? undefined });
327300
+ const geometryHit = clickToPositionGeometry(this.#layoutState.layout, noteContext.blocks, noteContext.measures, normalized, { geometryHelper: this.#pageGeometryHelper ?? undefined });
327301
+ const domHit = this.#resolveNoteDomHit(noteContext, clientX, clientY);
327302
+ this.#recordNoteHitDebug({
327303
+ clientX,
327304
+ clientY,
327305
+ geometryPos: geometryHit?.pos ?? null,
327306
+ domPos: domHit?.pos ?? null
327307
+ });
327308
+ const rawHit$1 = domHit ?? geometryHit;
326223
327309
  if (!rawHit$1)
326224
327310
  return null;
326225
327311
  const doc$2 = this.getActiveEditor().state?.doc;
@@ -326840,6 +327926,9 @@ function print() { __p += __j.call(arguments, '') }
326840
327926
  PresentationEditor2.#instances.delete(this.#registryKey);
326841
327927
  this.#registryKey = null;
326842
327928
  }
327929
+ safeCleanup(() => {
327930
+ this.#teardownUnifiedHistoryCoordinator();
327931
+ }, "Unified history coordinator");
326843
327932
  safeCleanup(() => {
326844
327933
  this.#headerFooterSession?.destroy();
326845
327934
  this.#headerFooterSession = null;
@@ -326982,6 +328071,11 @@ function print() { __p += __j.call(arguments, '') }
326982
328071
  console.warn("[PresentationEditor] Decoration sync failed:", error3);
326983
328072
  }
326984
328073
  }
328074
+ #shouldRestoreEmptyDecorationsAfterTransaction(transaction, state) {
328075
+ if (transaction)
328076
+ return transaction.docChanged === true;
328077
+ return this.#postPaintPipeline.hasCurrentDecorationRanges(state);
328078
+ }
326985
328079
  #scheduleDecorationSync() {
326986
328080
  if (this.#renderScheduled || this.#isRerendering)
326987
328081
  return;
@@ -327040,7 +328134,7 @@ function print() { __p += __j.call(arguments, '') }
327040
328134
  const state = this.#editor?.view?.state;
327041
328135
  const decorationChanged = state && this.#postPaintPipeline.hasDecorationChanges(state);
327042
328136
  if (decorationChanged) {
327043
- const restoreEmpty = tr ? tr.docChanged === true : false;
328137
+ const restoreEmpty = this.#shouldRestoreEmptyDecorationsAfterTransaction(tr, state);
327044
328138
  this.#postPaintPipeline.syncDecorations(state, this.#domPositionIndex, { restoreEmptyDecorations: restoreEmpty });
327045
328139
  } else
327046
328140
  this.#scheduleDecorationSync();
@@ -327087,11 +328181,13 @@ function print() { __p += __j.call(arguments, '') }
327087
328181
  handler: handleStylesDefaultsChanged
327088
328182
  });
327089
328183
  this.#syncActiveSurfaceUiEventBridge(this.#editor);
327090
- const handleNotesPartChanged = () => {
328184
+ const handleNotesPartChanged = (event) => {
327091
328185
  this.#flowBlockCache.setHasExternalChanges(true);
327092
328186
  this.#pendingDocChange = true;
327093
328187
  this.#selectionSync.onLayoutStart();
327094
328188
  this.#scheduleRerender();
328189
+ if (!isInternalNoteCommitSource(event))
328190
+ this.#purgeAllNoteParticipantsOnExternalInvalidation();
327095
328191
  };
327096
328192
  this.#editor.on("notes-part-changed", handleNotesPartChanged);
327097
328193
  this.#editorListeners.push({
@@ -327101,14 +328197,18 @@ function print() { __p += __j.call(arguments, '') }
327101
328197
  const handlePartChanged = (event) => {
327102
328198
  if (!event?.parts?.length)
327103
328199
  return;
328200
+ const isInternalHeaderFooterSync = event.source === SOURCE_HEADER_FOOTER_LOCAL;
327104
328201
  const headerFooterStructureChanged = event.parts.some((part) => part.partId === DOCUMENT_RELS_PART_ID);
327105
328202
  const changedHeaderFooterRefIds = Array.from(new Set(event.parts.filter((part) => isHeaderFooterPartId(part.partId)).map((part) => part.sectionId).filter((refId) => typeof refId === "string" && refId.length > 0)));
327106
328203
  if (!headerFooterStructureChanged && changedHeaderFooterRefIds.length === 0)
327107
328204
  return;
327108
328205
  if (headerFooterStructureChanged)
327109
328206
  this.#headerFooterSession?.refreshStructure();
327110
- if (changedHeaderFooterRefIds.length > 0)
328207
+ if (changedHeaderFooterRefIds.length > 0) {
327111
328208
  this.#headerFooterSession?.invalidateLayoutForRefs(changedHeaderFooterRefIds);
328209
+ if (!isInternalHeaderFooterSync)
328210
+ this.#purgeHeaderFooterParticipantsOnExternalInvalidation(changedHeaderFooterRefIds);
328211
+ }
327112
328212
  this.#pendingDocChange = true;
327113
328213
  this.#selectionSync.onLayoutStart();
327114
328214
  this.#scheduleRerender();
@@ -327418,6 +328518,7 @@ function print() { __p += __j.call(arguments, '') }
327418
328518
  this.#scheduleA11ySelectionAnnouncement({ immediate: true });
327419
328519
  }
327420
328520
  this.#syncActiveSurfaceUiEventBridge();
328521
+ this.#publishActiveSurfaceChange();
327421
328522
  },
327422
328523
  onEditBlocked: (reason) => {
327423
328524
  this.emit("headerFooterEditBlocked", { reason });
@@ -327532,8 +328633,7 @@ function print() { __p += __j.call(arguments, '') }
327532
328633
  const transactionHandler = ({ transaction }) => {
327533
328634
  if (!transaction?.docChanged)
327534
328635
  return;
327535
- if (this.#persistentStorySessionEditors.has(session.editor))
327536
- this.#lastPersistentStoryHistoryEditor = session.editor;
328636
+ this.#syncActiveStorySessionHistoryTransaction(session);
327537
328637
  if (session.kind === "note") {
327538
328638
  this.#invalidateTrackedChangesForStory(session.locator);
327539
328639
  this.#pendingDocChange = true;
@@ -327550,6 +328650,26 @@ function print() { __p += __j.call(arguments, '') }
327550
328650
  this.#scheduleA11ySelectionAnnouncement({ immediate: true });
327551
328651
  this.#syncActiveSurfaceUiEventBridge();
327552
328652
  }
328653
+ #resolveStorySessionHistoryParticipantKey(session) {
328654
+ const locator = session.locator;
328655
+ if (locator.kind !== "story")
328656
+ return null;
328657
+ if (locator.storyType === "headerFooterPart")
328658
+ return buildHeaderFooterParticipantKey(locator.refId);
328659
+ if (locator.storyType === "footnote" || locator.storyType === "endnote")
328660
+ return buildStoryKey(locator);
328661
+ return null;
328662
+ }
328663
+ #syncActiveStorySessionHistoryTransaction(session) {
328664
+ const participantKey = this.#resolveStorySessionHistoryParticipantKey(session);
328665
+ if (!participantKey)
328666
+ return;
328667
+ this.#debugUnifiedHistory("Reconciling active story-session history transaction.", {
328668
+ participantKey,
328669
+ sessionKind: session.kind
328670
+ });
328671
+ this.#historyCoordinator?.syncParticipant(participantKey);
328672
+ }
327553
328673
  #syncActiveStorySessionDocumentMode(session) {
327554
328674
  if (!session || session.kind !== "note")
327555
328675
  return;
@@ -327560,6 +328680,24 @@ function print() { __p += __j.call(arguments, '') }
327560
328680
  session.editor.setEditable?.(this.#documentMode !== "viewing");
327561
328681
  session.editor.setOptions?.({ documentMode: this.#documentMode });
327562
328682
  }
328683
+ #syncActiveStorySessionHistoryParticipant(session) {
328684
+ const coordinator = this.#historyCoordinator;
328685
+ if (!coordinator || !session)
328686
+ return;
328687
+ const locator = session.locator;
328688
+ if (session.kind !== "headerFooter" || locator.kind !== "story" || locator.storyType !== "headerFooterPart")
328689
+ return;
328690
+ const surfaceKind = session.editor.options.headerFooterType === "footer" ? "footer" : "header";
328691
+ this.#debugUnifiedHistory("Syncing active header/footer session editor into coordinator.", {
328692
+ refId: locator.refId,
328693
+ surface: surfaceKind
328694
+ });
328695
+ coordinator.register(createHeaderFooterParticipant(session.editor, {
328696
+ id: locator.refId,
328697
+ kind: surfaceKind
328698
+ }));
328699
+ this.#syncUnifiedHistoryParticipantPins();
328700
+ }
327563
328701
  #invalidateTrackedChangesForStory(locator) {
327564
328702
  try {
327565
328703
  getTrackedChangeIndex(this.#editor).invalidate(locator);
@@ -327573,55 +328711,322 @@ function print() { __p += __j.call(arguments, '') }
327573
328711
  getMountContainer: () => {
327574
328712
  return this.#visibleHost?.ownerDocument?.body ?? this.#visibleHost ?? null;
327575
328713
  },
327576
- editorFactory: ({ runtime, hostElement, activationOptions }) => {
327577
- const editorContext = activationOptions.editorContext ?? {};
327578
- if (runtime.kind === "headerFooter" && runtime.locator.storyType === "headerFooterPart") {
327579
- const descriptor = this.#headerFooterSession?.manager?.getDescriptorById(runtime.locator.refId) ?? null;
327580
- const persisted = descriptor ? this.#headerFooterSession?.manager?.ensureEditorSync(descriptor, {
327581
- editorHost: hostElement,
327582
- availableWidth: editorContext.availableWidth,
327583
- availableHeight: editorContext.availableHeight,
327584
- currentPageNumber: editorContext.currentPageNumber,
327585
- totalPageCount: editorContext.totalPageCount
327586
- }) ?? null : null;
327587
- if (persisted) {
327588
- this.#persistentStorySessionEditors.add(persisted);
327589
- return { editor: persisted };
327590
- }
327591
- }
327592
- const pmJson = runtime.editor.getJSON();
327593
- const fresh = createStoryEditor(this.#editor, pmJson, {
327594
- documentId: runtime.storyKey,
327595
- isHeaderOrFooter: runtime.kind === "headerFooter",
327596
- headless: false,
327597
- element: hostElement,
327598
- currentPageNumber: editorContext.currentPageNumber,
327599
- totalPageCount: editorContext.totalPageCount
327600
- });
327601
- return {
327602
- editor: fresh,
327603
- dispose: () => {
327604
- try {
327605
- fresh.destroy();
327606
- } catch {}
327607
- }
327608
- };
327609
- },
328714
+ editorFactory: (input2) => this.#createStorySessionEditor(input2),
327610
328715
  onActiveSessionChanged: () => {
327611
328716
  const activeSession = this.#storySessionManager?.getActiveSession() ?? null;
327612
328717
  if (activeSession?.hostWrapper)
327613
328718
  this.#wrapOffscreenEditorFocus(activeSession.editor);
328719
+ this.#syncActiveStorySessionHistoryParticipant(activeSession);
327614
328720
  this.#syncActiveStorySessionDocumentMode(activeSession);
327615
328721
  this.#syncStorySessionEventBridge(activeSession);
327616
328722
  this.#syncActiveSurfaceUiEventBridge();
328723
+ this.#publishActiveSurfaceChange();
327617
328724
  this.#inputBridge?.notifyTargetChanged();
327618
328725
  }
327619
328726
  });
327620
328727
  return this.#storySessionManager;
327621
328728
  }
328729
+ #createStorySessionEditor(input2) {
328730
+ const { runtime, hostElement, activationOptions } = input2;
328731
+ const editorContext = activationOptions.editorContext ?? {};
328732
+ if (runtime.kind === "headerFooter" && runtime.locator.storyType === "headerFooterPart") {
328733
+ const descriptor = this.#headerFooterSession?.manager?.getDescriptorById(runtime.locator.refId) ?? null;
328734
+ const persisted = descriptor ? this.#headerFooterSession?.manager?.ensureEditorSync(descriptor, {
328735
+ editorHost: hostElement,
328736
+ availableWidth: editorContext.availableWidth,
328737
+ availableHeight: editorContext.availableHeight,
328738
+ currentPageNumber: editorContext.currentPageNumber,
328739
+ totalPageCount: editorContext.totalPageCount
328740
+ }) ?? null : null;
328741
+ if (persisted)
328742
+ return { editor: persisted };
328743
+ }
328744
+ if (runtime.kind === "note" && this.#noteEditorRegistry)
328745
+ return this.#createNoteSessionEditor(input2);
328746
+ return this.#createFreshStorySessionEditor(input2);
328747
+ }
328748
+ #createFreshStorySessionEditor(input2) {
328749
+ const { runtime, hostElement, activationOptions } = input2;
328750
+ const editorContext = activationOptions.editorContext ?? {};
328751
+ const pmJson = runtime.editor.getJSON();
328752
+ const fresh = createStoryEditor(this.#editor, pmJson, {
328753
+ documentId: runtime.storyKey,
328754
+ isHeaderOrFooter: runtime.kind === "headerFooter",
328755
+ headless: false,
328756
+ element: hostElement,
328757
+ currentPageNumber: editorContext.currentPageNumber,
328758
+ totalPageCount: editorContext.totalPageCount
328759
+ });
328760
+ return {
328761
+ editor: fresh,
328762
+ dispose: () => {
328763
+ try {
328764
+ fresh.destroy();
328765
+ } catch {}
328766
+ }
328767
+ };
328768
+ }
328769
+ #createNoteSessionEditor(input2) {
328770
+ const registry$1 = this.#noteEditorRegistry;
328771
+ if (!registry$1)
328772
+ return this.#createFreshStorySessionEditor(input2);
328773
+ const { runtime, hostElement } = input2;
328774
+ const locator = runtime.locator;
328775
+ if (locator.storyType !== "footnote" && locator.storyType !== "endnote")
328776
+ return this.#createFreshStorySessionEditor(input2);
328777
+ const commitHook = runtime.commitEditor ?? null;
328778
+ const existing = registry$1.get(runtime.storyKey);
328779
+ if (existing) {
328780
+ if (commitHook)
328781
+ registry$1.setCommitHook(runtime.storyKey, commitHook);
328782
+ this.#remountStorySessionEditor(existing, hostElement);
328783
+ registry$1.touch(runtime.storyKey);
328784
+ return { editor: existing };
328785
+ }
328786
+ const fresh = this.#createFreshStorySessionEditor(input2);
328787
+ registry$1.register({
328788
+ storyKey: runtime.storyKey,
328789
+ locator,
328790
+ editor: fresh.editor,
328791
+ commit: commitHook
328792
+ });
328793
+ if (fresh.dispose)
328794
+ registry$1.attachDisposer(runtime.storyKey, fresh.dispose);
328795
+ return { editor: fresh.editor };
328796
+ }
328797
+ #remountStorySessionEditor(editor, hostElement) {
328798
+ editor.setOptions({ element: hostElement });
328799
+ editor.unmount?.();
328800
+ editor.mount?.(hostElement);
328801
+ }
327622
328802
  #setupStorySessionManager() {
327623
328803
  this.#ensureStorySessionManager();
327624
328804
  }
328805
+ #isUnifiedHistoryEnabled() {
328806
+ return this.#options.experimental?.unifiedHistory !== false;
328807
+ }
328808
+ #isUnifiedHistoryDebugEnabled() {
328809
+ if (this.#options.isDebug)
328810
+ return true;
328811
+ return globalThis.__SD_DEBUG_UNIFIED_HISTORY__ === true;
328812
+ }
328813
+ #debugUnifiedHistory(message, detail) {
328814
+ if (!this.#isUnifiedHistoryDebugEnabled())
328815
+ return;
328816
+ if (detail && Object.keys(detail).length > 0) {
328817
+ console.debug("[PresentationEditor][UnifiedHistory]", message, detail);
328818
+ return;
328819
+ }
328820
+ console.debug("[PresentationEditor][UnifiedHistory]", message);
328821
+ }
328822
+ #recordNoteHitDebug(entry) {
328823
+ const debugGlobal = globalThis;
328824
+ if (debugGlobal.__SD_DEBUG_NOTE_HIT__ !== true)
328825
+ return;
328826
+ const existingLog = Array.isArray(debugGlobal.__SD_DEBUG_NOTE_HIT_LOG__) ? debugGlobal.__SD_DEBUG_NOTE_HIT_LOG__ : [];
328827
+ existingLog.push(entry);
328828
+ if (existingLog.length > 100)
328829
+ existingLog.splice(0, existingLog.length - 100);
328830
+ debugGlobal.__SD_DEBUG_NOTE_HIT_LOG__ = existingLog;
328831
+ }
328832
+ #setupUnifiedHistoryCoordinator() {
328833
+ if (!this.#isUnifiedHistoryEnabled()) {
328834
+ this.#debugUnifiedHistory("Coordinator disabled by configuration.", { documentId: this.#options.documentId ?? null });
328835
+ return;
328836
+ }
328837
+ const coordinator = new DocumentHistoryCoordinator({ onDiagnostic: (message, detail) => this.#debugUnifiedHistory(message, detail) });
328838
+ this.#historyCoordinator = coordinator;
328839
+ this.#debugUnifiedHistory("Coordinator enabled.", { documentId: this.#options.documentId ?? null });
328840
+ const registry$1 = new NoteEditorRegistry({ onBeforeAutoDispose: (storyKey) => coordinator.purge(storyKey, "capacity-eviction") });
328841
+ this.#noteEditorRegistry = registry$1;
328842
+ coordinator.register(createBodyParticipant(this.#editor));
328843
+ const unbindChange = coordinator.onChange(() => {
328844
+ this.#syncUnifiedHistoryParticipantPins();
328845
+ this.#debugUnifiedHistory("Coordinator state changed.", {
328846
+ state: coordinator.getState(),
328847
+ reachableKeys: Array.from(coordinator.getReachableKeys())
328848
+ });
328849
+ this.emit("historyStateChange", coordinator.getState());
328850
+ });
328851
+ const unbindPurge = coordinator.onPurge(() => {
328852
+ this.#syncUnifiedHistoryParticipantPins();
328853
+ });
328854
+ const unbindCue = coordinator.onCue((event) => {
328855
+ this.#announce(this.#formatUnifiedHistoryCue(event));
328856
+ this.emit("unifiedHistoryCue", event);
328857
+ });
328858
+ this.#historyCoordinatorCleanup.push(unbindChange, unbindPurge, unbindCue);
328859
+ this.#bindHeaderFooterParticipants(coordinator);
328860
+ this.#bindNoteParticipants(coordinator, registry$1);
328861
+ this.#syncUnifiedHistoryParticipantPins();
328862
+ this.#publishActiveSurfaceChange(true);
328863
+ }
328864
+ #bindNoteParticipants(coordinator, registry$1) {
328865
+ const handleCreated = (payload) => {
328866
+ this.#debugUnifiedHistory("Registering note participant.", {
328867
+ storyKey: payload.storyKey,
328868
+ storyType: payload.locator.storyType
328869
+ });
328870
+ const participant = createNoteParticipant({
328871
+ storyKey: payload.storyKey,
328872
+ storyType: payload.locator.storyType,
328873
+ editor: payload.editor,
328874
+ flushAfterReplay: () => this.#flushNoteAfterReplay(payload.storyKey, payload.editor),
328875
+ onInvalidated: () => this.#purgeNoteRegistryEntry(registry$1, payload.storyKey)
328876
+ });
328877
+ coordinator.register(participant);
328878
+ this.#syncUnifiedHistoryParticipantPins();
328879
+ };
328880
+ const handleDisposed = (payload) => {
328881
+ if (this.#coordinatorDrivenNotePurges.has(payload.storyKey))
328882
+ return;
328883
+ this.#debugUnifiedHistory("Disposing note participant.", { storyKey: payload.storyKey });
328884
+ if (coordinator.hasParticipant(payload.storyKey))
328885
+ coordinator.purge(payload.storyKey, "destroyed");
328886
+ this.#syncUnifiedHistoryParticipantPins();
328887
+ };
328888
+ registry$1.on("editorCreated", handleCreated);
328889
+ registry$1.on("editorDisposed", handleDisposed);
328890
+ this.#historyCoordinatorCleanup.push(() => registry$1.off("editorCreated", handleCreated), () => registry$1.off("editorDisposed", handleDisposed));
328891
+ }
328892
+ #flushNoteAfterReplay(storyKey, noteEditor) {
328893
+ const commitHook = this.#noteEditorRegistry?.getCommitHook(storyKey);
328894
+ if (commitHook)
328895
+ try {
328896
+ commitHook(this.#editor, noteEditor);
328897
+ } catch (error3) {
328898
+ console.warn("[PresentationEditor] Note commit after replay failed:", error3);
328899
+ }
328900
+ this.#pendingDocChange = true;
328901
+ this.#scheduleRerender();
328902
+ }
328903
+ #bindHeaderFooterParticipants(coordinator) {
328904
+ const manager = this.#headerFooterSession?.manager;
328905
+ if (!manager)
328906
+ return;
328907
+ const handleCreated = (payload) => {
328908
+ this.#debugUnifiedHistory("Registering header/footer participant.", {
328909
+ refId: payload.descriptor.id,
328910
+ surface: payload.descriptor.kind
328911
+ });
328912
+ const participant = createHeaderFooterParticipant(payload.editor, payload.descriptor);
328913
+ coordinator.register(participant);
328914
+ this.#syncUnifiedHistoryParticipantPins();
328915
+ };
328916
+ const handleDisposed = (payload) => {
328917
+ const key2 = buildHeaderFooterParticipantKey(payload.descriptor.id);
328918
+ this.#debugUnifiedHistory("Disposing header/footer participant.", {
328919
+ refId: payload.descriptor.id,
328920
+ participantKey: key2
328921
+ });
328922
+ coordinator.purge(key2, "destroyed");
328923
+ this.#syncUnifiedHistoryParticipantPins();
328924
+ };
328925
+ manager.on("editorCreated", handleCreated);
328926
+ manager.on("editorDisposed", handleDisposed);
328927
+ this.#historyCoordinatorCleanup.push(() => manager.off?.("editorCreated", handleCreated), () => manager.off?.("editorDisposed", handleDisposed));
328928
+ }
328929
+ #purgeNoteRegistryEntry(registry$1, storyKey) {
328930
+ if (this.#coordinatorDrivenNotePurges.has(storyKey))
328931
+ return;
328932
+ this.#coordinatorDrivenNotePurges.add(storyKey);
328933
+ try {
328934
+ registry$1.purge(storyKey, "purge");
328935
+ } finally {
328936
+ this.#coordinatorDrivenNotePurges.delete(storyKey);
328937
+ }
328938
+ }
328939
+ #syncUnifiedHistoryParticipantPins() {
328940
+ const coordinator = this.#historyCoordinator;
328941
+ if (!coordinator)
328942
+ return;
328943
+ const reachableKeys = coordinator.getReachableKeys();
328944
+ const headerFooterManager = this.#headerFooterSession?.manager;
328945
+ const noteRegistry = this.#noteEditorRegistry;
328946
+ if (headerFooterManager && typeof headerFooterManager.getDescriptors === "function")
328947
+ headerFooterManager.getDescriptors().forEach((descriptor) => {
328948
+ const participantKey = buildHeaderFooterParticipantKey(descriptor.id);
328949
+ if (!coordinator.hasParticipant(participantKey))
328950
+ return;
328951
+ const shouldPin = reachableKeys.has(participantKey);
328952
+ coordinator.setPinned(participantKey, shouldPin);
328953
+ if (shouldPin) {
328954
+ headerFooterManager.pin?.(descriptor.id);
328955
+ return;
328956
+ }
328957
+ headerFooterManager.unpin?.(descriptor.id);
328958
+ });
328959
+ if (!noteRegistry)
328960
+ return;
328961
+ noteRegistry.keys().forEach((storyKey) => {
328962
+ if (!coordinator.hasParticipant(storyKey))
328963
+ return;
328964
+ const shouldPin = reachableKeys.has(storyKey);
328965
+ coordinator.setPinned(storyKey, shouldPin);
328966
+ if (shouldPin) {
328967
+ noteRegistry.pin(storyKey);
328968
+ return;
328969
+ }
328970
+ noteRegistry.unpin(storyKey);
328971
+ });
328972
+ }
328973
+ #publishActiveSurfaceChange(force = false) {
328974
+ const surface = this.#resolveActiveSurface();
328975
+ this.#historyCoordinator?.setActiveSurface(surface);
328976
+ if (!force && surface === this.#lastPublishedActiveSurface)
328977
+ return;
328978
+ this.#lastPublishedActiveSurface = surface;
328979
+ this.#debugUnifiedHistory("Active surface changed.", { surface });
328980
+ this.emit("activeSurfaceChange", { surface });
328981
+ }
328982
+ #formatUnifiedHistoryCue(event) {
328983
+ const action = event.action === "undo" ? "Undid" : "Redid";
328984
+ switch (event.surface) {
328985
+ case "header":
328986
+ return `${action} change in Header.`;
328987
+ case "footer":
328988
+ return `${action} change in Footer.`;
328989
+ case "note":
328990
+ return `${action} change in Footnote.`;
328991
+ case "endnote":
328992
+ return `${action} change in Endnote.`;
328993
+ default:
328994
+ return `${action} change in Document.`;
328995
+ }
328996
+ }
328997
+ #purgeHeaderFooterParticipantsOnExternalInvalidation(refIds) {
328998
+ const coordinator = this.#historyCoordinator;
328999
+ if (!coordinator)
329000
+ return;
329001
+ refIds.forEach((refId) => {
329002
+ coordinator.purge(buildHeaderFooterParticipantKey(refId), "external-invalidation");
329003
+ });
329004
+ }
329005
+ #purgeAllNoteParticipantsOnExternalInvalidation() {
329006
+ const coordinator = this.#historyCoordinator;
329007
+ const registry$1 = this.#noteEditorRegistry;
329008
+ if (!coordinator || !registry$1)
329009
+ return;
329010
+ registry$1.keys().forEach((storyKey) => {
329011
+ coordinator.purge(storyKey, "external-invalidation");
329012
+ });
329013
+ }
329014
+ #teardownUnifiedHistoryCoordinator() {
329015
+ this.#historyCoordinatorCleanup.forEach((cleanup) => {
329016
+ try {
329017
+ cleanup();
329018
+ } catch (error3) {
329019
+ console.warn("[PresentationEditor] Unified history cleanup failed:", error3);
329020
+ }
329021
+ });
329022
+ this.#historyCoordinatorCleanup.length = 0;
329023
+ this.#historyCoordinator?.destroy();
329024
+ this.#historyCoordinator = null;
329025
+ this.#noteEditorRegistry?.destroy();
329026
+ this.#noteEditorRegistry = null;
329027
+ this.#coordinatorDrivenNotePurges.clear();
329028
+ this.#lastPublishedActiveSurface = null;
329029
+ }
327625
329030
  #hitTestTable(normalizedX, normalizedY) {
327626
329031
  const configuredPageHeight = (this.#layoutOptions.pageSize ?? DEFAULT_PAGE_SIZE).h;
327627
329032
  return hitTestTable(this.#layoutState.layout, this.#layoutState.blocks, this.#layoutState.measures, normalizedX, normalizedY, configuredPageHeight, this.#getEffectivePageGap(), this.#pageGeometryHelper);
@@ -328817,6 +330222,12 @@ function print() { __p += __j.call(arguments, '') }
328817
330222
  noteId: session.locator.noteId
328818
330223
  });
328819
330224
  }
330225
+ #toStoryNoteVisibleTextOffset(_noteFragments, renderedTextOffset) {
330226
+ return Math.max(0, renderedTextOffset);
330227
+ }
330228
+ #toRenderedNoteVisibleTextOffset(_noteFragments, storyTextOffset) {
330229
+ return Math.max(0, storyTextOffset);
330230
+ }
328820
330231
  #collectNoteBlockIds(context) {
328821
330232
  return new Set(context.blocks.map((block) => typeof block?.id === "string" ? block.id : null).filter((blockId) => !!blockId));
328822
330233
  }
@@ -328839,6 +330250,77 @@ function print() { __p += __j.call(arguments, '') }
328839
330250
  return [];
328840
330251
  return Array.from(this.#viewportHost.querySelectorAll("[data-block-id]")).filter((element3) => noteBlockIds.has(element3.getAttribute("data-block-id") ?? ""));
328841
330252
  }
330253
+ #measureRenderedNoteVisibleTextOffset(context, clientX, clientY) {
330254
+ const noteBlockIds = this.#collectNoteBlockIds(context);
330255
+ const noteFragments = this.#getRenderedNoteFragmentElements(noteBlockIds);
330256
+ if (!noteFragments.length)
330257
+ return null;
330258
+ const fragmentHit = this.#findRenderedNoteFragmentAtPoint(noteBlockIds, clientX, clientY);
330259
+ if (!fragmentHit)
330260
+ return null;
330261
+ const boundary = resolveTextBoundaryWithinFragmentDom(fragmentHit.fragmentElement, clientX, clientY);
330262
+ if (!boundary)
330263
+ return null;
330264
+ const renderedTextOffset = measureVisibleTextOffsetInContainers(noteFragments, boundary.node, boundary.offset);
330265
+ if (renderedTextOffset == null)
330266
+ return null;
330267
+ return this.#toStoryNoteVisibleTextOffset(noteFragments, renderedTextOffset);
330268
+ }
330269
+ #resolveActiveEditorPosFromVisibleTextOffset(textOffset) {
330270
+ if (!Number.isFinite(textOffset))
330271
+ return null;
330272
+ const docSize = this.getActiveEditor()?.state?.doc?.content.size;
330273
+ if (!Number.isFinite(docSize))
330274
+ return null;
330275
+ const targetOffset = Math.max(0, textOffset);
330276
+ const visibleOffsetCache = /* @__PURE__ */ new Map;
330277
+ const readVisibleOffset = (pos) => {
330278
+ if (!visibleOffsetCache.has(pos))
330279
+ visibleOffsetCache.set(pos, this.#measureActiveEditorVisibleTextOffset(pos));
330280
+ return visibleOffsetCache.get(pos) ?? null;
330281
+ };
330282
+ const resolveLastPosAtOrBeforeOffset = () => {
330283
+ let low = 0;
330284
+ let high = docSize;
330285
+ let bestPos = null;
330286
+ while (low <= high) {
330287
+ const mid = Math.floor((low + high) / 2);
330288
+ const visibleOffset = readVisibleOffset(mid);
330289
+ if (visibleOffset == null) {
330290
+ high = mid - 1;
330291
+ continue;
330292
+ }
330293
+ if (visibleOffset <= targetOffset) {
330294
+ bestPos = mid;
330295
+ low = mid + 1;
330296
+ continue;
330297
+ }
330298
+ high = mid - 1;
330299
+ }
330300
+ return bestPos;
330301
+ };
330302
+ const resolveFirstPosAtOrAfterOffset = () => {
330303
+ let low = 0;
330304
+ let high = docSize;
330305
+ let bestPos = null;
330306
+ while (low <= high) {
330307
+ const mid = Math.floor((low + high) / 2);
330308
+ const visibleOffset = readVisibleOffset(mid);
330309
+ if (visibleOffset == null) {
330310
+ high = mid - 1;
330311
+ continue;
330312
+ }
330313
+ if (visibleOffset >= targetOffset) {
330314
+ bestPos = mid;
330315
+ high = mid - 1;
330316
+ continue;
330317
+ }
330318
+ low = mid + 1;
330319
+ }
330320
+ return bestPos;
330321
+ };
330322
+ return targetOffset === 0 ? resolveLastPosAtOrBeforeOffset() : resolveFirstPosAtOrAfterOffset();
330323
+ }
328842
330324
  #findRenderedNoteFragmentAtPoint(noteBlockIds, clientX, clientY) {
328843
330325
  const doc$12 = this.#viewportHost.ownerDocument ?? document;
328844
330326
  const elementsFromPoint = typeof doc$12.elementsFromPoint === "function" ? doc$12.elementsFromPoint.bind(doc$12) : null;
@@ -328879,6 +330361,32 @@ function print() { __p += __j.call(arguments, '') }
328879
330361
  const fragmentHit = this.#findRenderedNoteFragmentAtPoint(noteBlockIds, clientX, clientY);
328880
330362
  if (!fragmentHit)
328881
330363
  return null;
330364
+ const bridgedTextOffset = this.#measureRenderedNoteVisibleTextOffset(context, clientX, clientY);
330365
+ const bridgedPos = bridgedTextOffset == null ? null : this.#resolveActiveEditorPosFromVisibleTextOffset(bridgedTextOffset);
330366
+ if (bridgedTextOffset != null && bridgedPos != null)
330367
+ this.#recordNoteHitDebug({
330368
+ bridgedTextOffset,
330369
+ bridgedPos,
330370
+ bridgedVisibleOffsets: [
330371
+ bridgedPos - 2,
330372
+ bridgedPos - 1,
330373
+ bridgedPos,
330374
+ bridgedPos + 1,
330375
+ bridgedPos + 2
330376
+ ].filter((pos$1) => pos$1 >= 0).map((pos$1) => ({
330377
+ pos: pos$1,
330378
+ visibleOffset: this.#measureActiveEditorVisibleTextOffset(pos$1)
330379
+ }))
330380
+ });
330381
+ if (bridgedPos != null)
330382
+ return {
330383
+ pos: bridgedPos,
330384
+ layoutEpoch: readLayoutEpochFromDom(fragmentHit.fragmentElement, clientX, clientY) ?? layout.layoutEpoch ?? 0,
330385
+ blockId: fragmentHit.fragmentElement.getAttribute("data-block-id") ?? "",
330386
+ pageIndex: fragmentHit.pageIndex,
330387
+ column: 0,
330388
+ lineIndex: -1
330389
+ };
328882
330390
  const pos = resolvePositionWithinFragmentDom(fragmentHit.fragmentElement, clientX, clientY);
328883
330391
  if (pos == null)
328884
330392
  return null;
@@ -329503,12 +331011,14 @@ function print() { __p += __j.call(arguments, '') }
329503
331011
  const noteFragments = this.#getRenderedNoteFragmentElements(this.#collectNoteBlockIds(context));
329504
331012
  if (!noteFragments.length)
329505
331013
  return null;
331014
+ const renderedStartOffset = this.#toRenderedNoteVisibleTextOffset(noteFragments, startOffset);
331015
+ const renderedEndOffset = this.#toRenderedNoteVisibleTextOffset(noteFragments, endOffset);
329506
331016
  return computeSelectionRectsFromVisibleTextOffsets({
329507
331017
  containers: noteFragments,
329508
331018
  zoom: this.#layoutOptions.zoom ?? 1,
329509
331019
  pageHeight: this.#getBodyPageHeight(),
329510
331020
  pageGap: layout.pageGap ?? this.#getEffectivePageGap()
329511
- }, startOffset, endOffset);
331021
+ }, renderedStartOffset, renderedEndOffset);
329512
331022
  }
329513
331023
  #computeNoteSelectionRects(from$1, to) {
329514
331024
  const context = this.#buildActiveNoteLayoutContext();
@@ -329530,12 +331040,16 @@ function print() { __p += __j.call(arguments, '') }
329530
331040
  const textOffset = this.#measureActiveEditorVisibleTextOffset(pos);
329531
331041
  if (textOffset == null)
329532
331042
  return null;
331043
+ const noteFragments = this.#getRenderedNoteFragmentElements(noteBlockIds);
331044
+ if (!noteFragments.length)
331045
+ return null;
331046
+ const renderedTextOffset = this.#toRenderedNoteVisibleTextOffset(noteFragments, textOffset);
329533
331047
  return computeCaretRectFromVisibleTextOffset({
329534
- containers: this.#getRenderedNoteFragmentElements(noteBlockIds),
331048
+ containers: noteFragments,
329535
331049
  zoom: this.#layoutOptions.zoom ?? 1,
329536
331050
  pageHeight: this.#getBodyPageHeight(),
329537
331051
  pageGap: layout.pageGap ?? this.#getEffectivePageGap()
329538
- }, textOffset);
331052
+ }, renderedTextOffset);
329539
331053
  }
329540
331054
  #computeNoteCaretRect(pos) {
329541
331055
  const context = this.#buildActiveNoteLayoutContext();
@@ -330234,11 +331748,11 @@ var init_zipper_DbkgrypV_es = __esm(() => {
330234
331748
 
330235
331749
  // ../../packages/superdoc/dist/super-editor.es.js
330236
331750
  var init_super_editor_es = __esm(() => {
330237
- init_src_CLao_BLx_es();
330238
- init_SuperConverter_Dn6cDET4_es();
331751
+ init_src_CjxSHf0p_es();
331752
+ init_SuperConverter_2Pu0hMB1_es();
330239
331753
  init_jszip_C49i9kUs_es();
330240
331754
  init_xml_js_CqGKpaft_es();
330241
- init_create_headless_toolbar_CQu_F9Mr_es();
331755
+ init_create_headless_toolbar_sMwtuYL8_es();
330242
331756
  init_constants_CGhJRd87_es();
330243
331757
  init_dist_B8HfvhaK_es();
330244
331758
  init_unified_Dsuw2be5_es();
@@ -363442,13 +364956,13 @@ var init_XMLDocument = __esm(() => {
363442
364956
  });
363443
364957
 
363444
364958
  // ../../node_modules/.pnpm/happy-dom@20.4.0/node_modules/happy-dom/lib/nodes/text/Text.js
363445
- var Text;
364959
+ var Text2;
363446
364960
  var init_Text = __esm(() => {
363447
364961
  init_PropertySymbol();
363448
364962
  init_CharacterData();
363449
364963
  init_DOMExceptionNameEnum();
363450
364964
  init_NodeTypeEnum();
363451
- Text = class Text extends CharacterData {
364965
+ Text2 = class Text2 extends CharacterData {
363452
364966
  [nodeType] = NodeTypeEnum_default.textNode;
363453
364967
  [textAreaNode] = null;
363454
364968
  [styleNode] = null;
@@ -366798,10 +368312,10 @@ class WindowContextClassExtender {
366798
368312
  DocumentFragment2.prototype[window2] = window3;
366799
368313
  window3.DocumentFragment = DocumentFragment2;
366800
368314
 
366801
- class Text2 extends Text {
368315
+ class Text3 extends Text2 {
366802
368316
  }
366803
- Text2.prototype[window2] = window3;
366804
- window3.Text = Text2;
368317
+ Text3.prototype[window2] = window3;
368318
+ window3.Text = Text3;
366805
368319
 
366806
368320
  class Comment2 extends Comment {
366807
368321
  }