superdoc 2.29.0-next.9 → 2.29.0

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 (80) hide show
  1. package/dist/chunks/{FindReplaceSurface-BKVHzhQ4.es.js → FindReplaceSurface-B_5ggdWg.es.js} +1 -1
  2. package/dist/chunks/{FindReplaceSurface-BNDrJ6VS.cjs → FindReplaceSurface-fVHxPXtn.cjs} +1 -1
  3. package/dist/chunks/{PasswordPromptSurface-6mF6Azda.es.js → PasswordPromptSurface-CZqhDQQ1.es.js} +1 -1
  4. package/dist/chunks/{PasswordPromptSurface-BNkaztaP.cjs → PasswordPromptSurface-x8GNmMJT.cjs} +1 -1
  5. package/dist/chunks/{PdfViewer-aOWhUVI7.es.js → PdfViewer-CW09MNrB.es.js} +4 -10
  6. package/dist/chunks/{PdfViewer-DmSkZehl.cjs → PdfViewer-CkrAHpC-.cjs} +4 -10
  7. package/dist/chunks/{_plugin-vue_export-helper-6MBoygIY.cjs → _plugin-vue_export-helper-BkbCxNeT.cjs} +31 -7
  8. package/dist/chunks/{_plugin-vue_export-helper-CsJQtMvr.es.js → _plugin-vue_export-helper-DRPRMkeA.es.js} +20 -8
  9. package/dist/chunks/{create-super-doc-ui-Bm5kmx0W.es.js → create-super-doc-ui-Dc8dQAMc.es.js} +83 -114
  10. package/dist/chunks/{create-super-doc-ui-DN70aatf.cjs → create-super-doc-ui-L60GhVAX.cjs} +199 -236
  11. package/dist/collaboration-upgrade-engine.cjs +1 -1
  12. package/dist/collaboration-upgrade-engine.es.js +1 -1
  13. package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
  14. package/dist/public/ui-react.cjs +1 -1
  15. package/dist/public/ui-react.es.js +1 -1
  16. package/dist/public/ui-vue.cjs +1 -1
  17. package/dist/public/ui-vue.es.js +1 -1
  18. package/dist/public/ui.cjs +1 -1
  19. package/dist/public/ui.es.js +1 -1
  20. package/dist/style.css +1 -1
  21. package/dist/style.layered.css +1 -1
  22. package/dist/superdoc/src/components/CommentsLayer/collect-removed-comment-ids.d.ts +11 -1
  23. package/dist/superdoc/src/components/CommentsLayer/collect-tracked-change-thread.d.ts +19 -2
  24. package/dist/superdoc/src/components/CommentsLayer/comment-urls.d.ts +1 -1
  25. package/dist/superdoc/src/components/CommentsLayer/commentsList/super-comments-list.d.ts +23 -20
  26. package/dist/superdoc/src/components/CommentsLayer/helpers.d.ts +1 -4
  27. package/dist/superdoc/src/components/CommentsLayer/tracked-change-threading.d.ts +16 -1
  28. package/dist/superdoc/src/components/Whiteboard/WhiteboardLayer.vue.d.ts +4 -5
  29. package/dist/superdoc/src/components/Whiteboard/WhiteboardPage.vue.d.ts +3 -4
  30. package/dist/superdoc/src/components/Whiteboard/whiteboard-types.d.ts +2 -0
  31. package/dist/superdoc/src/components/surfaces/watermark-surface-runtime.d.ts +7 -7
  32. package/dist/superdoc/src/composables/use-comment-small-screen.d.ts +11 -7
  33. package/dist/superdoc/src/composables/use-compact-comment-popover.d.ts +44 -18
  34. package/dist/superdoc/src/composables/use-find-replace.d.ts +13 -3
  35. package/dist/superdoc/src/composables/use-password-prompt.d.ts +1 -1
  36. package/dist/superdoc/src/composables/use-viewport-fit.d.ts +62 -26
  37. package/dist/superdoc/src/core/SuperDoc.d.ts +3 -3
  38. package/dist/superdoc/src/core/pdf/pdf-adapter.d.ts +6 -2
  39. package/dist/superdoc/src/core/types/index.d.ts +37 -4
  40. package/dist/superdoc/src/core/v2-integration/browser-peer-runtime.d.ts +5 -3
  41. package/dist/superdoc/src/core/v2-integration/cdn-engine-loader.d.ts +3 -13
  42. package/dist/superdoc/src/core/v2-integration/internal-vue-runtime.d.ts +64 -59
  43. package/dist/superdoc/src/helpers/object-guards.d.ts +1 -0
  44. package/dist/superdoc/src/helpers/v2-author-required-rejection.d.ts +8 -11
  45. package/dist/superdoc/src/helpers/v2-bulk-decision-event.d.ts +9 -7
  46. package/dist/superdoc/src/helpers/v2-keyboard-edit-rejection.d.ts +8 -7
  47. package/dist/superdoc/src/helpers/v2-mutation-exception.d.ts +12 -8
  48. package/dist/superdoc/src/helpers/v2-review-target.d.ts +11 -1
  49. package/dist/superdoc/src/helpers/v2-selection-sync.d.ts +40 -14
  50. package/dist/superdoc/src/helpers/v2-typing-mutation-event.d.ts +14 -5
  51. package/dist/superdoc/src/icons.d.ts +11 -19
  52. package/dist/superdoc/src/internal/diagnostics/translate-diagnostic.d.ts +6 -4
  53. package/dist/superdoc/src/internal/toolbar/built-in/PageNumberMenu.vue.d.ts +25 -15
  54. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +3 -1
  55. package/dist/superdoc/src/internal/toolbar/built-in/font-options.d.ts +15 -1
  56. package/dist/superdoc/src/internal/toolbar/built-in/font-typeahead.d.ts +37 -7
  57. package/dist/superdoc/src/internal/toolbar/built-in/format-negation.d.ts +10 -4
  58. package/dist/superdoc/src/internal/toolbar/built-in/general.d.ts +12 -1
  59. package/dist/superdoc/src/internal/toolbar/built-in/helpers.d.ts +9 -4
  60. package/dist/superdoc/src/internal/toolbar/built-in/list-style-buttons.d.ts +2 -2
  61. package/dist/superdoc/src/internal/toolbar/built-in/page-number-feedback.d.ts +4 -5
  62. package/dist/superdoc/src/internal/toolbar/built-in/scroll-helpers.d.ts +3 -4
  63. package/dist/superdoc/src/internal/toolbar/built-in/toolbarIcons.d.ts +78 -145
  64. package/dist/superdoc/src/internal/toolbar/built-in/url-safety.d.ts +11 -3
  65. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +4 -3
  66. package/dist/superdoc/src/internal/toolbar/image-upload.d.ts +29 -39
  67. package/dist/superdoc/src/public/ui/format-painter-helpers.d.ts +2 -8
  68. package/dist/superdoc/src/stores/comments-store.d.ts +7 -7
  69. package/dist/superdoc/src/stores/helpers/comment-document-scope.d.ts +22 -0
  70. package/dist/superdoc/src/stores/helpers/pending-selection-snapshot.d.ts +17 -0
  71. package/dist/superdoc/src/stores/helpers/tracked-change-compaction.d.ts +16 -0
  72. package/dist/superdoc/src/stores/helpers/tracked-change-decision.d.ts +45 -0
  73. package/dist/superdoc/src/stores/superdoc-store.d.ts +21 -21
  74. package/dist/superdoc.cjs +423 -464
  75. package/dist/superdoc.es.js +335 -376
  76. package/dist-cdn/style.layered.css +1 -1
  77. package/dist-cdn/superdoc.min.css +1 -1
  78. package/dist-cdn/superdoc.min.js +41 -41
  79. package/package.json +3 -2
  80. package/dist/superdoc/src/main.d.ts +0 -1
package/dist/superdoc.cjs CHANGED
@@ -1,21 +1,21 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./chunks/rolldown-runtime-74VwNCz7.cjs");
3
+ const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-BkbCxNeT.cjs");
3
4
  const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
4
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-DN70aatf.cjs");
5
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-L60GhVAX.cjs");
5
6
  const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
6
7
  const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
7
- const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-6MBoygIY.cjs");
8
8
  const require_jszip = require("./chunks/jszip-D8mAFF-r.cjs");
9
9
  const require_is_finite_number = require("./chunks/is-finite-number-BEXgTRgc.cjs");
10
10
  const require_constants = require("./chunks/constants-BeeNZoQp.cjs");
11
11
  let superdoc_entry_vue = require("vue");
12
12
  superdoc_entry_vue = require_rolldown_runtime.__toESM(superdoc_entry_vue, 1);
13
13
  let yjs = require("yjs");
14
- //#region src/core/v2-integration/browser-peer-runtime.js
14
+ //#region src/core/v2-integration/browser-peer-runtime.ts
15
15
  var SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY = "__SUPERDOC_V2_BROWSER_RUNTIME__";
16
16
  function readInstalledRuntime(globalObject = globalThis) {
17
- const installed = globalObject[SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY];
18
- return installed && typeof installed === "object" ? installed : null;
17
+ const installed = Reflect.get(globalObject, SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY);
18
+ return require__plugin_vue_export_helper.isPlainObject(installed) ? installed : null;
19
19
  }
20
20
  function installSuperDocV2BrowserRuntime(runtime = {}, globalObject = globalThis) {
21
21
  const installed = readInstalledRuntime(globalObject) ?? {};
@@ -24,7 +24,7 @@ function installSuperDocV2BrowserRuntime(runtime = {}, globalObject = globalThis
24
24
  ...runtime,
25
25
  vue: runtime.vue ?? installed.vue ?? superdoc_entry_vue
26
26
  };
27
- globalObject[SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY] = nextRuntime;
27
+ Reflect.set(globalObject, SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY, nextRuntime);
28
28
  return nextRuntime;
29
29
  }
30
30
  installSuperDocV2BrowserRuntime();
@@ -259,7 +259,7 @@ var v_click_outside_default = {
259
259
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
260
260
  function getSuperdocVersion() {
261
261
  try {
262
- return "2.29.0-next.9";
262
+ return "2.29.0";
263
263
  } catch {
264
264
  return "unknown";
265
265
  }
@@ -5842,7 +5842,7 @@ function useCheckboxField(field) {
5842
5842
  //#region src/core/collaboration/collaboration-comments.ts
5843
5843
  var readComment = (event) => {
5844
5844
  const { comment } = event;
5845
- if (!require_create_super_doc_ui.isPlainObject(comment)) throw new TypeError("Collaboration comment events require a comment object");
5845
+ if (!require__plugin_vue_export_helper.isPlainObject(comment)) throw new TypeError("Collaboration comment events require a comment object");
5846
5846
  return comment;
5847
5847
  };
5848
5848
  var addYComment = (yArray, ydoc, event, user) => {
@@ -5870,12 +5870,12 @@ var deleteYComment = (yArray, ydoc, event, user) => {
5870
5870
  }, { user });
5871
5871
  };
5872
5872
  var getCommentIndex = (yArray, comment) => {
5873
- return yArray.toJSON().findIndex((c) => require_create_super_doc_ui.isPlainObject(c) && c.commentId === comment.commentId);
5873
+ return yArray.toJSON().findIndex((c) => require__plugin_vue_export_helper.isPlainObject(c) && c.commentId === comment.commentId);
5874
5874
  };
5875
5875
  //#endregion
5876
5876
  //#region src/core/collaboration/helpers.ts
5877
5877
  var isPropertyBag = (value) => typeof value === "object" && value !== null || typeof value === "function";
5878
- var readCommentsStore = (superdoc) => superdoc["commentsStore"];
5878
+ var readCommentsStore$1 = (superdoc) => superdoc["commentsStore"];
5879
5879
  var isV2ReviewRuntimeActive = (superdoc) => superdoc.activeEditor?.editorVersion === 2 || superdoc.editorVersion === 2;
5880
5880
  var commentKey = (comment) => {
5881
5881
  const key = comment.commentId ?? comment.importedId;
@@ -5894,7 +5894,7 @@ var preserveLocalV2TrackedChangeRows = (superdoc, commentsStore, incomingComment
5894
5894
  };
5895
5895
  var loadCommentsFromYdoc = (superdoc) => {
5896
5896
  if (!superdoc?.ydoc) return false;
5897
- const commentsStore = readCommentsStore(superdoc);
5897
+ const commentsStore = readCommentsStore$1(superdoc);
5898
5898
  if (!commentsStore) return false;
5899
5899
  const comments = superdoc.ydoc.getArray("comments").toJSON();
5900
5900
  const seenCommentIdByKey = /* @__PURE__ */ new Map();
@@ -5940,7 +5940,7 @@ var initCollaborationComments = (superdoc) => {
5940
5940
  const updateCommentsStore = () => loadCommentsFromYdoc(superdoc);
5941
5941
  const onSuperDocYdocSynced = () => {
5942
5942
  if (!updateCommentsStore()) setTimeout(updateCommentsStore, 0);
5943
- const commentsStore = readCommentsStore(superdoc);
5943
+ const commentsStore = readCommentsStore$1(superdoc);
5944
5944
  if (commentsStore) commentsStore.hasSyncedCollaborationComments = true;
5945
5945
  const currentProvider = superdoc.provider;
5946
5946
  if (!currentProvider) throw new TypeError("initCollaborationComments requires superdoc.provider");
@@ -5952,7 +5952,7 @@ var initCollaborationComments = (superdoc) => {
5952
5952
  provider.on("synced", onSuperDocYdocSynced);
5953
5953
  if (!updateCommentsStore()) setTimeout(updateCommentsStore, 0);
5954
5954
  commentsArray.observe((event) => {
5955
- if (!readCommentsStore(superdoc)) return;
5955
+ if (!readCommentsStore$1(superdoc)) return;
5956
5956
  const currentUser = superdoc.config.user;
5957
5957
  const origin = event?.transaction?.origin;
5958
5958
  const originUser = isPropertyBag(origin) ? origin.user : null;
@@ -6810,7 +6810,7 @@ var groupRectsByPage = (rects) => {
6810
6810
  }));
6811
6811
  };
6812
6812
  var readStoryType = (story) => {
6813
- return require_create_super_doc_ui.isPlainObject(story) ? story.storyType : void 0;
6813
+ return require__plugin_vue_export_helper.isPlainObject(story) ? story.storyType : void 0;
6814
6814
  };
6815
6815
  var isRepeatedHeaderFooterTrackedChange = (comment, positionEntry) => {
6816
6816
  if (!comment?.trackedChange) return false;
@@ -6891,23 +6891,76 @@ var buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fall
6891
6891
  })];
6892
6892
  };
6893
6893
  //#endregion
6894
- //#region src/components/CommentsLayer/tracked-change-threading.js
6894
+ //#region src/stores/helpers/comment-document-scope.ts
6895
+ var getCommentDocumentId = (comment) => {
6896
+ if (!comment) return null;
6897
+ if (comment.fileId != null) return String(comment.fileId);
6898
+ if (comment.documentId != null) return String(comment.documentId);
6899
+ if (comment.selection?.documentId != null) return String(comment.selection.documentId);
6900
+ return null;
6901
+ };
6902
+ var createCommentDocumentScope = (readOpenDocuments) => {
6903
+ const getOpenDocuments = () => {
6904
+ const source = readOpenDocuments();
6905
+ const docs = Array.isArray(source) ? source : source?.value;
6906
+ return Array.isArray(docs) ? docs : [];
6907
+ };
6908
+ const getSingleOpenDocumentId = () => {
6909
+ const docs = getOpenDocuments();
6910
+ if (docs.length !== 1) return null;
6911
+ return docs[0]?.id != null ? String(docs[0].id) : null;
6912
+ };
6913
+ const belongsToDocument = (comment, activeDocumentId, options = {}) => {
6914
+ const { allowSingleDocumentMismatch = false } = options;
6915
+ if (!activeDocumentId) return false;
6916
+ const commentDocumentId = getCommentDocumentId(comment);
6917
+ if (commentDocumentId) {
6918
+ if (commentDocumentId === activeDocumentId) return true;
6919
+ const singleOpenDocumentId = getSingleOpenDocumentId();
6920
+ return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
6921
+ }
6922
+ return getSingleOpenDocumentId() === activeDocumentId;
6923
+ };
6924
+ const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
6925
+ return {
6926
+ belongsToDocument,
6927
+ belongsToTrackedChangeSyncDocument
6928
+ };
6929
+ };
6930
+ //#endregion
6931
+ //#region src/stores/helpers/pending-selection-snapshot.ts
6932
+ var isThenable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
6933
+ var getPendingSelectionSnapshot = (superdoc, activeSelection) => {
6934
+ if (activeSelection?.source !== "document-editor") return null;
6935
+ const selectionDocumentId = activeSelection?.documentId ?? null;
6936
+ const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
6937
+ if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
6938
+ let currentSelection;
6939
+ try {
6940
+ currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
6941
+ } catch {
6942
+ return null;
6943
+ }
6944
+ if (typeof currentSelection !== "function") return null;
6945
+ try {
6946
+ const snapshot = currentSelection();
6947
+ return isThenable(snapshot) ? Promise.resolve(snapshot).catch(() => null) : snapshot;
6948
+ } catch {
6949
+ return null;
6950
+ }
6951
+ };
6952
+ //#endregion
6953
+ //#region src/components/CommentsLayer/tracked-change-threading.ts
6895
6954
  /**
6896
6955
  * Legacy comment payloads predate explicit tracked-change thread provenance.
6897
6956
  * These fields distinguish a true legacy review child from a v2 comment whose
6898
6957
  * anchor merely overlaps tracked content.
6899
- *
6900
- * @param {Record<string, any> | null | undefined} comment
6901
- * @returns {boolean}
6902
6958
  */
6903
6959
  var hasLegacyTrackedChangeThreadSignal = (comment) => Boolean(comment?.trackedChangeLink) || Boolean(comment?.trackedChangeType) || Boolean(comment?.trackedChangeDisplayType) || Boolean(comment?.trackedChangeText) || Boolean(comment?.deletedText) || comment?.trackedChange === true;
6904
6960
  /**
6905
6961
  * Resolve explicit thread provenance first, then the guarded legacy fallback.
6906
6962
  * Spatial-only v2 comments carry neither the explicit field nor a legacy
6907
6963
  * review signal and therefore remain standalone.
6908
- *
6909
- * @param {Record<string, any> | null | undefined} comment
6910
- * @returns {string | number | null}
6911
6964
  */
6912
6965
  var trackedChangeThreadParentIdForComment$1 = (comment) => {
6913
6966
  if (comment?.trackedChangeThreadParentId != null) return comment.trackedChangeThreadParentId;
@@ -7096,7 +7149,7 @@ async function loadDefaultV2IntegrationOrFallback() {
7096
7149
  }
7097
7150
  var V2_BODY_TRACKED_CHANGE_ANCHOR_PREFIX = "tc::body::";
7098
7151
  function isV2SyntheticTrackedChangeRow(row) {
7099
- if (!require_create_super_doc_ui.isPlainObject(row) || row.trackedChange !== true) return false;
7152
+ if (!require__plugin_vue_export_helper.isPlainObject(row) || row.trackedChange !== true) return false;
7100
7153
  const anchorKey = row.trackedChangeAnchorKey;
7101
7154
  return typeof anchorKey === "string" && anchorKey.startsWith(V2_BODY_TRACKED_CHANGE_ANCHOR_PREFIX);
7102
7155
  }
@@ -7160,7 +7213,7 @@ function createStubV2Integration() {
7160
7213
  }
7161
7214
  function adoptEngineIntegration(engineIntegration) {
7162
7215
  const stub = createStubV2Integration();
7163
- if (!require_create_super_doc_ui.isPlainObject(engineIntegration) || !engineIntegration.EditorComponent) return stub;
7216
+ if (!require__plugin_vue_export_helper.isPlainObject(engineIntegration) || !engineIntegration.EditorComponent) return stub;
7164
7217
  const engine = engineIntegration;
7165
7218
  return {
7166
7219
  version: typeof engine.version === "number" ? engine.version : stub.version,
@@ -7186,7 +7239,6 @@ function createDefaultV2Integration() {
7186
7239
  //#region src/helpers/interaction-trace.ts
7187
7240
  var isStartSpan = (value) => typeof value === "function";
7188
7241
  var isEndSpan = (value) => typeof value === "function";
7189
- var isThenable$3 = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
7190
7242
  function safeTraceCollector() {
7191
7243
  try {
7192
7244
  const collector = Reflect.get(globalThis, "__superdocInteractionTrace");
@@ -7217,7 +7269,7 @@ function withInteractionSpan(stage, branch, meta, fn) {
7217
7269
  if (!span) return fn();
7218
7270
  try {
7219
7271
  const result = fn();
7220
- if (isThenable$3(result)) return result.then((value) => {
7272
+ if (require__plugin_vue_export_helper.isThenable(result)) return result.then((value) => {
7221
7273
  endInteractionSpan(span);
7222
7274
  return value;
7223
7275
  }, (error) => {
@@ -7232,6 +7284,81 @@ function withInteractionSpan(stage, branch, meta, fn) {
7232
7284
  }
7233
7285
  }
7234
7286
  //#endregion
7287
+ //#region src/stores/helpers/tracked-change-decision.ts
7288
+ var normalizeTrackedChangeDecisionType = (value) => {
7289
+ const lower = typeof value === "string" ? value.toLowerCase() : "";
7290
+ if (!lower) return null;
7291
+ if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
7292
+ if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
7293
+ return lower;
7294
+ };
7295
+ var trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
7296
+ const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
7297
+ if (!normalizedDecision) return false;
7298
+ const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
7299
+ return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
7300
+ };
7301
+ var collectTrackedChangeDecisionIdsWithAliases = (comment, aliasIds) => {
7302
+ const trackedChangeIds = new Set(aliasIds);
7303
+ if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
7304
+ const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
7305
+ if (anchorKey) {
7306
+ trackedChangeIds.add(anchorKey);
7307
+ if (anchorKey.startsWith("tc::")) {
7308
+ const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
7309
+ if (rawId) trackedChangeIds.add(rawId);
7310
+ }
7311
+ }
7312
+ return trackedChangeIds;
7313
+ };
7314
+ var collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
7315
+ const record = receipt && typeof receipt === "object" ? receipt : null;
7316
+ if (!record?.success) return /* @__PURE__ */ new Set();
7317
+ const ids = /* @__PURE__ */ new Set();
7318
+ const collect = (entry) => {
7319
+ const ref = entry && typeof entry === "object" ? entry : null;
7320
+ if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
7321
+ if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
7322
+ };
7323
+ if (Array.isArray(record.removed)) record.removed.forEach(collect);
7324
+ if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
7325
+ return ids;
7326
+ };
7327
+ var collectReliableDecidedTrackedChangeIds = (outcome) => {
7328
+ const ids = /* @__PURE__ */ new Set();
7329
+ if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
7330
+ if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
7331
+ if (id != null && String(id).length > 0) ids.add(String(id));
7332
+ });
7333
+ collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
7334
+ return ids;
7335
+ };
7336
+ var clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
7337
+ if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
7338
+ try {
7339
+ adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
7340
+ } catch {}
7341
+ };
7342
+ var waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
7343
+ const readiness = superdoc?.activeEditor?.documentMutationReadiness;
7344
+ if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
7345
+ try {
7346
+ await readiness.whenPainted(receipt);
7347
+ const requestFrame = globalThis.requestAnimationFrame;
7348
+ if (typeof requestFrame === "function") await new Promise((resolve) => {
7349
+ let settled = false;
7350
+ const finish = () => {
7351
+ if (settled) return;
7352
+ settled = true;
7353
+ clearTimeout(fallback);
7354
+ resolve();
7355
+ };
7356
+ const fallback = setTimeout(finish, 250);
7357
+ requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
7358
+ });
7359
+ } catch {}
7360
+ };
7361
+ //#endregion
7235
7362
  //#region src/stores/helpers/comment-draft-text.ts
7236
7363
  var COMMENT_DRAFT_BR_TAG = /<br(?:\s[^>]*)?\s*\/?>/gi;
7237
7364
  var COMMENT_DRAFT_BLOCK_BOUNDARY = /(?:<\/(?:p|div|li|blockquote|pre|h[1-6])\s*>\s*)+(?:<(?:p|div|li|blockquote|pre|h[1-6])(?:\s[^>]*)?\s*\/?>)+/gi;
@@ -7276,12 +7403,12 @@ var BODY_TRACKED_CHANGE_STORY = {
7276
7403
  };
7277
7404
  var normalizeCommentId = (id) => id === void 0 || id === null ? null : String(id);
7278
7405
  var isNonEmptyString$2 = (value) => Boolean(value);
7279
- var trackedChangeFields = (comment) => require_create_super_doc_ui.isPlainObject(comment) && comment.trackedChange ? comment : null;
7406
+ var trackedChangeFields = (comment) => require__plugin_vue_export_helper.isPlainObject(comment) && comment.trackedChange ? comment : null;
7280
7407
  var makeTrackedChangeAnchorKey = ({ storyKey, rawId }) => `tc::${storyKey}::${rawId}`;
7281
7408
  var isBodyTrackedChangeComment = (comment) => {
7282
7409
  const fields = trackedChangeFields(comment);
7283
7410
  if (!fields) return false;
7284
- const storyType = require_create_super_doc_ui.isPlainObject(fields.trackedChangeStory) ? fields.trackedChangeStory.storyType : void 0;
7411
+ const storyType = require__plugin_vue_export_helper.isPlainObject(fields.trackedChangeStory) ? fields.trackedChangeStory.storyType : void 0;
7285
7412
  if (storyType == null || storyType === "body") return true;
7286
7413
  const anchorKey = fields.trackedChangeAnchorKey;
7287
7414
  return typeof anchorKey === "string" && anchorKey.startsWith("tc::body::");
@@ -7324,7 +7451,7 @@ var getTrackedChangeStoryKey = (comment) => {
7324
7451
  const anchorParts = parseTrackedChangeAnchorKey(fields.trackedChangeAnchorKey);
7325
7452
  if (anchorParts) return anchorParts.storyKey;
7326
7453
  const story = fields.trackedChangeStory;
7327
- if (!require_create_super_doc_ui.isPlainObject(story)) return null;
7454
+ if (!require__plugin_vue_export_helper.isPlainObject(story)) return null;
7328
7455
  switch (story.storyType) {
7329
7456
  case "body": return "body";
7330
7457
  case "headerFooterPart": return storyIdKey("hf", story.refId);
@@ -7345,7 +7472,7 @@ var trackedChangeStoryKeysAreCompatible = (leftStoryKey, rightStoryKey) => {
7345
7472
  return !left || !right || left === right;
7346
7473
  };
7347
7474
  var positionEntryMatchesTrackedChangeStory = (entry, comment) => {
7348
- return trackedChangeStoryKeysAreCompatible(normalizeTrackedChangeStoryKey(getTrackedChangeStoryKey(comment)), normalizeTrackedChangeStoryKey(normalizeCommentId(require_create_super_doc_ui.isPlainObject(entry) ? entry.storyKey : null)));
7475
+ return trackedChangeStoryKeysAreCompatible(normalizeTrackedChangeStoryKey(getTrackedChangeStoryKey(comment)), normalizeTrackedChangeStoryKey(normalizeCommentId(require__plugin_vue_export_helper.isPlainObject(entry) ? entry.storyKey : null)));
7349
7476
  };
7350
7477
  var buildTrackedChangeImportedPositionId = (id) => {
7351
7478
  const normalizedId = normalizeCommentId(id);
@@ -7542,7 +7669,7 @@ var createCommentIdentity = ({ getComments, getReviewDirectory, getPositions })
7542
7669
  };
7543
7670
  //#endregion
7544
7671
  //#region src/stores/helpers/tracked-change-row-values.ts
7545
- var isObjectOrArray = (value) => require_create_super_doc_ui.isPlainObject(value) || Array.isArray(value);
7672
+ var isObjectOrArray = (value) => require__plugin_vue_export_helper.isPlainObject(value) || Array.isArray(value);
7546
7673
  var stringOrEmpty = (value) => typeof value === "string" ? value : "";
7547
7674
  var shallowEqual = (a, b) => {
7548
7675
  if (Object.is(a, b)) return true;
@@ -7604,6 +7731,82 @@ var cloneV2TrackedChangeStory = (story) => {
7604
7731
  };
7605
7732
  };
7606
7733
  //#endregion
7734
+ //#region src/stores/helpers/tracked-change-compaction.ts
7735
+ var isPresentId = (id) => Boolean(id);
7736
+ var getBodyTrackedChangeIdentityIds = (comment) => {
7737
+ return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
7738
+ comment.importedId,
7739
+ comment.trackedChangeAnchorKey,
7740
+ ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
7741
+ ] : []].map((id) => normalizeCommentId(id)).filter(isPresentId);
7742
+ };
7743
+ var groupBodyTrackedChangeCommentsByIdentity = (comments) => {
7744
+ const parents = comments.map((_, index) => index);
7745
+ const findRoot = (index) => {
7746
+ let root = index;
7747
+ while (parents[root] !== root) root = parents[root];
7748
+ while (parents[index] !== index) {
7749
+ const next = parents[index];
7750
+ parents[index] = root;
7751
+ index = next;
7752
+ }
7753
+ return root;
7754
+ };
7755
+ const join = (left, right) => {
7756
+ const leftRoot = findRoot(left);
7757
+ const rightRoot = findRoot(right);
7758
+ if (leftRoot === rightRoot) return;
7759
+ parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
7760
+ };
7761
+ const identityOwner = /* @__PURE__ */ new Map();
7762
+ comments.forEach((comment, index) => {
7763
+ getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
7764
+ const owner = identityOwner.get(identityId);
7765
+ if (owner === void 0) identityOwner.set(identityId, index);
7766
+ else join(index, owner);
7767
+ });
7768
+ });
7769
+ const groups = /* @__PURE__ */ new Map();
7770
+ comments.forEach((comment, index) => {
7771
+ const root = findRoot(index);
7772
+ const group = groups.get(root) ?? [];
7773
+ group.push(comment);
7774
+ groups.set(root, group);
7775
+ });
7776
+ return groups;
7777
+ };
7778
+ var mergeDuplicateBodyTrackedChangeComments = (groups) => {
7779
+ const duplicates = /* @__PURE__ */ new Map();
7780
+ groups.forEach(([survivor, ...duplicateRows]) => {
7781
+ if (!survivor || duplicateRows.length === 0) return;
7782
+ const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
7783
+ if (survivor.resolvedTime == null && resolvedDuplicate) {
7784
+ survivor.resolvedTime = resolvedDuplicate.resolvedTime;
7785
+ survivor.resolvedById = resolvedDuplicate.resolvedById;
7786
+ survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
7787
+ survivor.resolvedByName = resolvedDuplicate.resolvedByName;
7788
+ survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
7789
+ }
7790
+ survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
7791
+ comment.commentId,
7792
+ comment.importedId,
7793
+ comment.trackedChangeCanonicalId,
7794
+ ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
7795
+ ])]);
7796
+ duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
7797
+ });
7798
+ return duplicates;
7799
+ };
7800
+ var createDroppedCommentIdMap = (duplicates) => {
7801
+ const droppedCommentIds = /* @__PURE__ */ new Map();
7802
+ duplicates.forEach((survivor, duplicate) => {
7803
+ const fromId = normalizeCommentId(duplicate.commentId);
7804
+ const toId = normalizeCommentId(survivor.commentId);
7805
+ if (fromId && toId) droppedCommentIds.set(fromId, toId);
7806
+ });
7807
+ return droppedCommentIds;
7808
+ };
7809
+ //#endregion
7607
7810
  //#region src/stores/comments-store.js
7608
7811
  var useCommentsStore = defineStore("comments", () => {
7609
7812
  const superdocStore = useSuperdocStore();
@@ -8082,25 +8285,6 @@ var useCommentsStore = defineStore("comments", () => {
8082
8285
  delete debounceTimers[commentId];
8083
8286
  }, delay);
8084
8287
  };
8085
- const getPendingSelectionSnapshot = (superdoc, activeSelection) => {
8086
- if (activeSelection?.source !== "document-editor") return null;
8087
- const selectionDocumentId = activeSelection?.documentId ?? null;
8088
- const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
8089
- if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
8090
- let currentSelection;
8091
- try {
8092
- currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
8093
- } catch {
8094
- return null;
8095
- }
8096
- if (typeof currentSelection !== "function") return null;
8097
- try {
8098
- const snapshot = currentSelection();
8099
- return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8100
- } catch {
8101
- return null;
8102
- }
8103
- };
8104
8288
  const showAddComment = (superdoc, targetClientY = null) => {
8105
8289
  const request = ++pendingCommentRequest;
8106
8290
  const editor = superdoc?.activeEditor;
@@ -9624,122 +9808,7 @@ var useCommentsStore = defineStore("comments", () => {
9624
9808
  const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
9625
9809
  if (activeCommentId && removedAliasIds.has(activeCommentId)) clearActiveCommentSelection();
9626
9810
  }
9627
- const getCommentDocumentId = (comment) => {
9628
- if (!comment) return null;
9629
- if (comment.fileId != null) return String(comment.fileId);
9630
- if (comment.documentId != null) return String(comment.documentId);
9631
- if (comment.selection?.documentId != null) return String(comment.selection.documentId);
9632
- return null;
9633
- };
9634
- const getOpenDocuments = () => {
9635
- const docs = Array.isArray(superdocStore.documents) ? superdocStore.documents : superdocStore.documents?.value;
9636
- return Array.isArray(docs) ? docs : [];
9637
- };
9638
- const getSingleOpenDocumentId = () => {
9639
- const docs = getOpenDocuments();
9640
- if (docs.length !== 1) return null;
9641
- return docs[0]?.id != null ? String(docs[0].id) : null;
9642
- };
9643
- const belongsToDocument = (comment, activeDocumentId, options = {}) => {
9644
- const { allowSingleDocumentMismatch = false } = options;
9645
- if (!activeDocumentId) return false;
9646
- const commentDocumentId = getCommentDocumentId(comment);
9647
- if (commentDocumentId) {
9648
- if (commentDocumentId === activeDocumentId) return true;
9649
- const singleOpenDocumentId = getSingleOpenDocumentId();
9650
- return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
9651
- }
9652
- return getSingleOpenDocumentId() === activeDocumentId;
9653
- };
9654
- const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => {
9655
- return belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
9656
- };
9657
- const normalizeTrackedChangeDecisionType = (value) => {
9658
- const lower = typeof value === "string" ? value.toLowerCase() : "";
9659
- if (!lower) return null;
9660
- if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
9661
- if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
9662
- return lower;
9663
- };
9664
- const trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
9665
- const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
9666
- if (!normalizedDecision) return false;
9667
- const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
9668
- return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
9669
- };
9670
- const getBodyTrackedChangeIdentityIds = (comment) => {
9671
- return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
9672
- comment.importedId,
9673
- comment.trackedChangeAnchorKey,
9674
- ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
9675
- ] : []].map((id) => normalizeCommentId(id)).filter(Boolean);
9676
- };
9677
- const groupBodyTrackedChangeCommentsByIdentity = (comments) => {
9678
- const parents = comments.map((_, index) => index);
9679
- const findRoot = (index) => {
9680
- let root = index;
9681
- while (parents[root] !== root) root = parents[root];
9682
- while (parents[index] !== index) {
9683
- const next = parents[index];
9684
- parents[index] = root;
9685
- index = next;
9686
- }
9687
- return root;
9688
- };
9689
- const join = (left, right) => {
9690
- const leftRoot = findRoot(left);
9691
- const rightRoot = findRoot(right);
9692
- if (leftRoot === rightRoot) return;
9693
- parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
9694
- };
9695
- const identityOwner = /* @__PURE__ */ new Map();
9696
- comments.forEach((comment, index) => {
9697
- getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
9698
- const owner = identityOwner.get(identityId);
9699
- if (owner === void 0) identityOwner.set(identityId, index);
9700
- else join(index, owner);
9701
- });
9702
- });
9703
- const groups = /* @__PURE__ */ new Map();
9704
- comments.forEach((comment, index) => {
9705
- const root = findRoot(index);
9706
- const group = groups.get(root) ?? [];
9707
- group.push(comment);
9708
- groups.set(root, group);
9709
- });
9710
- return groups;
9711
- };
9712
- const mergeDuplicateBodyTrackedChangeComments = (groups) => {
9713
- const duplicates = /* @__PURE__ */ new Map();
9714
- groups.forEach(([survivor, ...duplicateRows]) => {
9715
- if (!survivor || duplicateRows.length === 0) return;
9716
- const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
9717
- if (survivor.resolvedTime == null && resolvedDuplicate) {
9718
- survivor.resolvedTime = resolvedDuplicate.resolvedTime;
9719
- survivor.resolvedById = resolvedDuplicate.resolvedById;
9720
- survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
9721
- survivor.resolvedByName = resolvedDuplicate.resolvedByName;
9722
- survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
9723
- }
9724
- survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
9725
- comment.commentId,
9726
- comment.importedId,
9727
- comment.trackedChangeCanonicalId,
9728
- ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
9729
- ])]);
9730
- duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
9731
- });
9732
- return duplicates;
9733
- };
9734
- const createDroppedCommentIdMap = (duplicates) => {
9735
- const droppedCommentIds = /* @__PURE__ */ new Map();
9736
- duplicates.forEach((survivor, duplicate) => {
9737
- const fromId = normalizeCommentId(duplicate.commentId);
9738
- const toId = normalizeCommentId(survivor.commentId);
9739
- if (fromId && toId) droppedCommentIds.set(fromId, toId);
9740
- });
9741
- return droppedCommentIds;
9742
- };
9811
+ const { belongsToDocument, belongsToTrackedChangeSyncDocument } = createCommentDocumentScope(() => superdocStore.documents);
9743
9812
  const remapTrackedChangeReferences = (droppedCommentIds, activeDocumentId) => {
9744
9813
  const remapSelection = (selection) => {
9745
9814
  const selectedId = normalizeCommentId(selection.value);
@@ -9765,9 +9834,7 @@ var useCommentsStore = defineStore("comments", () => {
9765
9834
  });
9766
9835
  };
9767
9836
  const compactDuplicateBodyTrackedChangeComments = (activeDocumentId) => {
9768
- const candidates = commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId));
9769
- const groups = groupBodyTrackedChangeCommentsByIdentity(candidates);
9770
- const duplicates = mergeDuplicateBodyTrackedChangeComments(groups);
9837
+ const duplicates = mergeDuplicateBodyTrackedChangeComments(groupBodyTrackedChangeCommentsByIdentity(commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId))));
9771
9838
  if (!duplicates.size) return 0;
9772
9839
  commentsList.value = commentsList.value.filter((comment) => !duplicates.has(comment));
9773
9840
  remapTrackedChangeReferences(createDroppedCommentIdMap(duplicates), activeDocumentId);
@@ -9908,19 +9975,7 @@ var useCommentsStore = defineStore("comments", () => {
9908
9975
  });
9909
9976
  return resolvedCount;
9910
9977
  };
9911
- const collectTrackedChangeDecisionIds = (comment) => {
9912
- const trackedChangeIds = new Set(getCommentAliasIds(comment));
9913
- if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
9914
- const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
9915
- if (anchorKey) {
9916
- trackedChangeIds.add(anchorKey);
9917
- if (anchorKey.startsWith("tc::")) {
9918
- const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
9919
- if (rawId) trackedChangeIds.add(rawId);
9920
- }
9921
- }
9922
- return trackedChangeIds;
9923
- };
9978
+ const collectTrackedChangeDecisionIds = (comment) => collectTrackedChangeDecisionIdsWithAliases(comment, getCommentAliasIds(comment));
9924
9979
  const getTrackedChangeDecisionLinks = (comment) => {
9925
9980
  const linked = [];
9926
9981
  const seen = /* @__PURE__ */ new Set();
@@ -9931,28 +9986,6 @@ var useCommentsStore = defineStore("comments", () => {
9931
9986
  }
9932
9987
  return linked;
9933
9988
  };
9934
- const collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
9935
- const record = receipt && typeof receipt === "object" ? receipt : null;
9936
- if (!record?.success) return /* @__PURE__ */ new Set();
9937
- const ids = /* @__PURE__ */ new Set();
9938
- const collect = (entry) => {
9939
- const ref = entry && typeof entry === "object" ? entry : null;
9940
- if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
9941
- if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
9942
- };
9943
- if (Array.isArray(record.removed)) record.removed.forEach(collect);
9944
- if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
9945
- return ids;
9946
- };
9947
- const collectReliableDecidedTrackedChangeIds = (outcome) => {
9948
- const ids = /* @__PURE__ */ new Set();
9949
- if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
9950
- if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
9951
- if (id != null && String(id).length > 0) ids.add(String(id));
9952
- });
9953
- collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
9954
- return ids;
9955
- };
9956
9989
  const detachLinkedCommentsForTrackedChangeDecision = ({ comment, decision } = {}) => {
9957
9990
  if (!comment?.trackedChange) return 0;
9958
9991
  if (!trackedChangeDecisionKeepsCommentAnchor({
@@ -10128,31 +10161,6 @@ var useCommentsStore = defineStore("comments", () => {
10128
10161
  removedIds
10129
10162
  };
10130
10163
  };
10131
- const clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
10132
- if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
10133
- try {
10134
- adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
10135
- } catch {}
10136
- };
10137
- const waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
10138
- const readiness = superdoc?.activeEditor?.documentMutationReadiness;
10139
- if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
10140
- try {
10141
- await readiness.whenPainted(receipt);
10142
- const requestFrame = globalThis.requestAnimationFrame;
10143
- if (typeof requestFrame === "function") await new Promise((resolve) => {
10144
- let settled = false;
10145
- const finish = () => {
10146
- if (settled) return;
10147
- settled = true;
10148
- clearTimeout(fallback);
10149
- resolve();
10150
- };
10151
- const fallback = setTimeout(finish, 250);
10152
- requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
10153
- });
10154
- } catch {}
10155
- };
10156
10164
  /**
10157
10165
  * Accept or reject the tracked change behind a sidebar row.
10158
10166
  *
@@ -10713,7 +10721,7 @@ var ellipsis_vertical_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\"
10713
10721
  //#region ../../shared/common/icons/rotate-left-solid.svg?raw
10714
10722
  var rotate_left_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M48.5 224L40 224c-13.3 0-24-10.7-24-24L16 72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8L48.5 224z\"/></svg>";
10715
10723
  //#endregion
10716
- //#region src/icons.js
10724
+ //#region src/icons.ts
10717
10725
  var superdocIcons = {
10718
10726
  comment: comment_solid_default,
10719
10727
  caretDown: caret_down_solid_default,
@@ -10798,8 +10806,8 @@ var scrollThreadAnchorToFocusTarget = (presentation, primaryThreadId, fallbackTh
10798
10806
  var DEFAULT_UI_FONT_FAMILY$1 = "Arial, Helvetica, sans-serif";
10799
10807
  function configuredUiFontFamily(proxy) {
10800
10808
  const superdoc = proxy ? Reflect.get(proxy, "$superdoc") : void 0;
10801
- const config = require_create_super_doc_ui.isPlainObject(superdoc) ? superdoc.config : void 0;
10802
- return require_create_super_doc_ui.isPlainObject(config) ? config.uiDisplayFallbackFont : void 0;
10809
+ const config = require__plugin_vue_export_helper.isPlainObject(superdoc) ? superdoc.config : void 0;
10810
+ return require__plugin_vue_export_helper.isPlainObject(config) ? config.uiDisplayFallbackFont : void 0;
10803
10811
  }
10804
10812
  /**
10805
10813
  * Vue composable that returns the computed UI font-family for SuperDoc surfaces.
@@ -11077,12 +11085,9 @@ var InternalDropdown_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
11077
11085
  //#region src/components/CommentsLayer/InternalDropdown.vue
11078
11086
  var InternalDropdown_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(InternalDropdown_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-026f5d66"]]);
11079
11087
  //#endregion
11080
- //#region src/components/CommentsLayer/helpers.js
11088
+ //#region src/components/CommentsLayer/helpers.ts
11081
11089
  /**
11082
11090
  * Comments helper to format dates from timestamp
11083
- *
11084
- * @param {Number} timestamp The timestamp to format
11085
- * @returns {String} The formatted date
11086
11091
  */
11087
11092
  function formatDate(timestamp) {
11088
11093
  const date = new Date(timestamp);
@@ -11683,7 +11688,7 @@ var CommentInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ req
11683
11688
  //#region src/components/CommentsLayer/CommentInput.vue
11684
11689
  var CommentInput_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(CommentInput_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-aa97de44"]]);
11685
11690
  //#endregion
11686
- //#region src/internal/toolbar/built-in/url-safety.js
11691
+ //#region src/internal/toolbar/built-in/url-safety.ts
11687
11692
  /**
11688
11693
  * Minimal href sanitizer for the built-in link popover.
11689
11694
  *
@@ -11699,8 +11704,6 @@ var DANGEROUS_SCHEME = /^(javascript|data|vbscript):/i;
11699
11704
  var HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
11700
11705
  /**
11701
11706
  * Validate and normalize an href. Returns `{ href }` for safe values, or `null`.
11702
- * @param {string} value
11703
- * @returns {{ href: string }|null}
11704
11707
  */
11705
11708
  function sanitizeHref(value) {
11706
11709
  if (typeof value !== "string") return null;
@@ -11712,7 +11715,7 @@ function sanitizeHref(value) {
11712
11715
  return { href: trimmed };
11713
11716
  }
11714
11717
  //#endregion
11715
- //#region src/components/CommentsLayer/comment-urls.js
11718
+ //#region src/components/CommentsLayer/comment-urls.ts
11716
11719
  function isAbsoluteWebUrl(value) {
11717
11720
  if (!/^https?:\/\/[^\s/?#\\]+/i.test(value) || /[\s\\]/u.test(value)) return false;
11718
11721
  try {
@@ -11736,7 +11739,7 @@ function trimUrlPunctuation(value) {
11736
11739
  for (const character of value) {
11737
11740
  const close = closingDelimiter[character];
11738
11741
  if (close) balance[close] += 1;
11739
- else if (Object.hasOwn(balance, character)) balance[character] -= 1;
11742
+ else if (Object.prototype.hasOwnProperty.call(balance, character)) balance[character] -= 1;
11740
11743
  }
11741
11744
  let end = value.length;
11742
11745
  while (end > 0) {
@@ -11760,17 +11763,18 @@ function renderCommentHtml(value) {
11760
11763
  if (typeof document === "undefined") return value;
11761
11764
  const template = document.createElement("template");
11762
11765
  template.innerHTML = value;
11763
- for (const link of template.content.querySelectorAll("a")) {
11764
- const safe = sanitizeHref(link.getAttribute("href"));
11766
+ for (const link of Array.from(template.content.querySelectorAll("a"))) {
11767
+ const rawHref = link.getAttribute("href");
11768
+ const safe = rawHref === null ? null : sanitizeHref(rawHref);
11765
11769
  if (safe && (isAbsoluteWebUrl(safe.href) || /^(mailto|tel):\S+$/i.test(safe.href))) configureLink(link, safe.href);
11766
- else link.replaceWith(...link.childNodes);
11770
+ else link.replaceWith(...Array.from(link.childNodes));
11767
11771
  }
11768
11772
  const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_TEXT);
11769
11773
  const textNodes = [];
11770
- while (walker.nextNode()) textNodes.push(walker.currentNode);
11774
+ while (walker.nextNode()) if (walker.currentNode instanceof Text) textNodes.push(walker.currentNode);
11771
11775
  for (const node of textNodes) {
11772
11776
  if (node.parentElement?.closest("a, script, style, textarea, code, pre")) continue;
11773
- const text = node.textContent;
11777
+ const text = node.data;
11774
11778
  const fragment = document.createDocumentFragment();
11775
11779
  let end = 0;
11776
11780
  for (const match of text.matchAll(/(^|[\s([{])(https?:\/\/[^\s<>"']+)/gi)) {
@@ -13454,21 +13458,25 @@ var commentsList_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ req
13454
13458
  //#region src/components/CommentsLayer/commentsList/commentsList.vue
13455
13459
  var commentsList_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(commentsList_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-8eca48e1"]]);
13456
13460
  //#endregion
13457
- //#region src/components/CommentsLayer/commentsList/super-comments-list.js
13461
+ //#region src/components/CommentsLayer/commentsList/super-comments-list.ts
13462
+ var isReviewDirectoryStore = (value) => require__plugin_vue_export_helper.isPlainObject(value) && typeof value.setReviewDirectoryFromV2 === "function" && typeof value.clearReviewDirectory === "function";
13463
+ var readCommentsStore = (superdoc) => {
13464
+ const store = superdoc?.["commentsStore"];
13465
+ return isReviewDirectoryStore(store) ? store : void 0;
13466
+ };
13458
13467
  /**
13459
13468
  * Comments list renderer (not floating comments)
13460
13469
  *
13461
13470
  * This renders a list of comments into an element, connected to main SuperDoc instance
13462
13471
  */
13463
13472
  var SuperComments = class extends require_eventemitter3.import_eventemitter3.default {
13464
- element;
13465
- config = {
13466
- comments: [],
13467
- element: null,
13468
- commentsStore: null
13469
- };
13470
13473
  constructor(options, superdoc) {
13471
13474
  super();
13475
+ this.config = {
13476
+ comments: [],
13477
+ element: null,
13478
+ commentsStore: null
13479
+ };
13472
13480
  this.config = {
13473
13481
  ...this.config,
13474
13482
  ...options
@@ -13489,7 +13497,7 @@ var SuperComments = class extends require_eventemitter3.import_eventemitter3.def
13489
13497
  this.open();
13490
13498
  }
13491
13499
  syncDirectory() {
13492
- const store = this.superdoc?.commentsStore;
13500
+ const store = readCommentsStore(this.superdoc);
13493
13501
  if (!store) return;
13494
13502
  const comments = this.directorySnapshots.comments;
13495
13503
  const trackChanges = this.directorySnapshots.trackChanges;
@@ -13507,12 +13515,14 @@ var SuperComments = class extends require_eventemitter3.import_eventemitter3.def
13507
13515
  const acceptDirectorySnapshot = (snapshot) => {
13508
13516
  if (generation !== this.directoryGeneration) return;
13509
13517
  if ((snapshot?.listStatus ?? snapshot?.status) !== "ready") {
13510
- if (this.superdoc?.commentsStore) this.superdoc.commentsStore.isReviewDirectoryLoading = true;
13518
+ const store = readCommentsStore(this.superdoc);
13519
+ if (store) store.isReviewDirectoryLoading = true;
13511
13520
  return;
13512
13521
  }
13513
13522
  const items = Array.isArray(snapshot.items) ? snapshot.items : [];
13514
13523
  if (this.directoryItemRefs[family] === items) {
13515
- if (this.superdoc?.commentsStore) this.superdoc.commentsStore.isReviewDirectoryLoading = this.directorySnapshots.comments == null || this.directorySnapshots.trackChanges == null;
13524
+ const store = readCommentsStore(this.superdoc);
13525
+ if (store) store.isReviewDirectoryLoading = this.directorySnapshots.comments == null || this.directorySnapshots.trackChanges == null;
13516
13526
  return;
13517
13527
  }
13518
13528
  this.directoryItemRefs[family] = items;
@@ -13529,15 +13539,16 @@ var SuperComments = class extends require_eventemitter3.import_eventemitter3.def
13529
13539
  };
13530
13540
  const ui = this.superdoc?.ui;
13531
13541
  if (!ui) return;
13532
- if (this.superdoc?.commentsStore) {
13533
- this.superdoc.commentsStore.isReviewDirectoryActive = true;
13534
- this.superdoc.commentsStore.isReviewDirectoryLoading = true;
13542
+ const store = readCommentsStore(this.superdoc);
13543
+ if (store) {
13544
+ store.isReviewDirectoryActive = true;
13545
+ store.isReviewDirectoryLoading = true;
13535
13546
  }
13536
13547
  this.stopDirectoryObservers = [subscribe(ui.comments, "comments"), subscribe(ui.trackChanges, "trackChanges")];
13537
13548
  }
13538
13549
  createVueApp() {
13539
13550
  this.app = require__plugin_vue_export_helper.createApp(commentsList_default);
13540
- const parentProvides = this.superdoc?.app?._context?.provides;
13551
+ const parentProvides = this.superdoc?.["app"]?._context?.provides;
13541
13552
  if (parentProvides && this.app?._context?.provides) Object.setPrototypeOf(this.app._context.provides, parentProvides);
13542
13553
  if (this.superdoc?.pinia) {
13543
13554
  setActivePinia(this.superdoc.pinia);
@@ -13561,10 +13572,11 @@ var SuperComments = class extends require_eventemitter3.import_eventemitter3.def
13561
13572
  comments: null,
13562
13573
  trackChanges: null
13563
13574
  };
13564
- if (this.superdoc?.commentsStore) {
13565
- this.superdoc.commentsStore.clearReviewDirectory();
13566
- this.superdoc.commentsStore.isReviewDirectoryActive = false;
13567
- this.superdoc.commentsStore.isReviewDirectoryLoading = false;
13575
+ const store = readCommentsStore(this.superdoc);
13576
+ if (store) {
13577
+ store.clearReviewDirectory();
13578
+ store.isReviewDirectoryActive = false;
13579
+ store.isReviewDirectoryLoading = false;
13568
13580
  }
13569
13581
  if (this.app) {
13570
13582
  this.app.unmount();
@@ -13578,7 +13590,7 @@ var SuperComments = class extends require_eventemitter3.import_eventemitter3.def
13578
13590
  }
13579
13591
  };
13580
13592
  //#endregion
13581
- //#region src/composables/use-viewport-fit.js
13593
+ //#region src/composables/use-viewport-fit.ts
13582
13594
  var CSS_PX_PER_INCH = 96;
13583
13595
  var SIDEBAR_SELECTOR = ".superdoc__right-sidebar";
13584
13596
  var PDF_PAGE_SELECTOR = ".sd-pdf-viewer-page";
@@ -13683,7 +13695,7 @@ function useViewportFit({ getSuperdoc, superdocContainerWidth, isReady, activeZo
13683
13695
  const root = superdocRoot.value;
13684
13696
  if (!root?.querySelectorAll) return null;
13685
13697
  let widest = 0;
13686
- for (const page of root.querySelectorAll(PDF_PAGE_SELECTOR)) {
13698
+ for (const page of Array.from(root.querySelectorAll(PDF_PAGE_SELECTOR))) {
13687
13699
  const measured = Number(page.clientWidth) || Number(page.getBoundingClientRect?.().width) || 0;
13688
13700
  let scaleFactor = NaN;
13689
13701
  if (typeof window !== "undefined" && typeof window.getComputedStyle === "function") scaleFactor = Number.parseFloat(window.getComputedStyle(page).getPropertyValue("--scale-factor"));
@@ -15493,7 +15505,7 @@ var WhiteboardPage_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ r
15493
15505
  });
15494
15506
  //#endregion
15495
15507
  //#region src/components/Whiteboard/WhiteboardPage.vue
15496
- var WhiteboardPage_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(WhiteboardPage_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-f730b33d"]]);
15508
+ var WhiteboardPage_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(WhiteboardPage_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-fdae8749"]]);
15497
15509
  //#endregion
15498
15510
  //#region src/components/Whiteboard/WhiteboardLayer.vue?vue&type=script&setup=true&lang.ts
15499
15511
  var WhiteboardLayer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
@@ -15567,16 +15579,11 @@ var WhiteboardLayer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
15567
15579
  });
15568
15580
  //#endregion
15569
15581
  //#region src/components/Whiteboard/WhiteboardLayer.vue
15570
- var WhiteboardLayer_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(WhiteboardLayer_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-980e1f94"]]);
15582
+ var WhiteboardLayer_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(WhiteboardLayer_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-800e1970"]]);
15571
15583
  //#endregion
15572
- //#region src/components/CommentsLayer/collect-removed-comment-ids.js
15584
+ //#region src/components/CommentsLayer/collect-removed-comment-ids.ts
15573
15585
  /**
15574
15586
  * Expand deleted comment ids through comment and tracked-change descendants.
15575
- *
15576
- * @param {ReadonlyArray<Record<string, any>>} comments
15577
- * @param {ReadonlyArray<string>} targetIds
15578
- * @param {(comment: Record<string, any>) => boolean} [isInScope]
15579
- * @returns {Set<string>}
15580
15587
  */
15581
15588
  var collectRemovedCommentIds = (comments, targetIds, isInScope = () => true) => {
15582
15589
  const targets = new Set(targetIds.map(String));
@@ -15638,7 +15645,7 @@ function isActiveTrackedChangeContextMenuTarget(target) {
15638
15645
  function normalizeCommentsUiConfig(commentsConfig) {
15639
15646
  if (!commentsConfig || typeof commentsConfig !== "object") return commentsConfig;
15640
15647
  const normalized = { ...commentsConfig };
15641
- const responsive = require_create_super_doc_ui.isPlainObject(commentsConfig.responsive) ? commentsConfig.responsive : {};
15648
+ const responsive = require__plugin_vue_export_helper.isPlainObject(commentsConfig.responsive) ? commentsConfig.responsive : {};
15642
15649
  const layout = firstDefined$1(commentsConfig.layout, commentsConfig.displayMode);
15643
15650
  const target = normalizeResponsiveTarget(firstDefined$1(responsive.target, commentsConfig.compactMeasurementSelector));
15644
15651
  const breakpoint = firstDefined$1(responsive.breakpoint, commentsConfig.compactBreakpointPx);
@@ -15659,7 +15666,7 @@ function normalizeCommentsUiConfig(commentsConfig) {
15659
15666
  return normalized;
15660
15667
  }
15661
15668
  //#endregion
15662
- //#region src/composables/use-comment-small-screen.js
15669
+ //#region src/composables/use-comment-small-screen.ts
15663
15670
  var SUPERDOC_DOCUMENT_SELECTOR = ".superdoc__document";
15664
15671
  var isValidCompactBreakpoint = (value) => {
15665
15672
  return require_is_finite_number.isFiniteNumber(value) && value >= 0;
@@ -15739,10 +15746,11 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
15739
15746
  }
15740
15747
  documentWidthTargets = nextTargets;
15741
15748
  if (!nextTargets.length) return;
15742
- documentWidthResizeObserver = new ResizeObserverClass(() => {
15749
+ const observer = new ResizeObserverClass(() => {
15743
15750
  recalculateCompactCommentsMode();
15744
15751
  });
15745
- nextTargets.forEach((el) => documentWidthResizeObserver.observe(el));
15752
+ documentWidthResizeObserver = observer;
15753
+ nextTargets.forEach((el) => observer.observe(el));
15746
15754
  };
15747
15755
  const getMeasuredDocumentWidth = () => {
15748
15756
  ensureDocumentWidthObserver();
@@ -15798,7 +15806,7 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
15798
15806
  };
15799
15807
  }
15800
15808
  //#endregion
15801
- //#region src/composables/use-compact-comment-popover.js
15809
+ //#region src/composables/use-compact-comment-popover.ts
15802
15810
  var POPOVER_WIDTH_PX = 320;
15803
15811
  var SAFE_MARGIN_PX = 12;
15804
15812
  var MIN_BOTTOM_SPACE_PX = 220;
@@ -15828,7 +15836,7 @@ var resolveInteractionAnchor = (lastClickAnchor) => {
15828
15836
  var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) => {
15829
15837
  if (Boolean(pendingComment?.value && comment?.commentId === pendingComment.value?.commentId)) {
15830
15838
  const nodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
15831
- for (const node of nodes) {
15839
+ for (const node of Array.from(nodes)) {
15832
15840
  if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes("pending")) continue;
15833
15841
  if (typeof node.getBoundingClientRect !== "function") continue;
15834
15842
  return node.getBoundingClientRect();
@@ -15838,7 +15846,7 @@ var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) =>
15838
15846
  if (!anchorId) return null;
15839
15847
  const safeId = String(anchorId);
15840
15848
  const highlightNodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
15841
- for (const node of highlightNodes) {
15849
+ for (const node of Array.from(highlightNodes)) {
15842
15850
  if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes(safeId)) continue;
15843
15851
  if (typeof node.getBoundingClientRect !== "function") continue;
15844
15852
  return node.getBoundingClientRect();
@@ -15923,9 +15931,10 @@ function useCompactCommentPopover({ activeComment, pendingComment, activeCompact
15923
15931
  };
15924
15932
  const trackCompactPopoverClickAnchor = (e) => {
15925
15933
  const root = superdocRoot.value;
15926
- if (!root || !layers.value?.contains(e.target)) return;
15927
- const anchorElement = (typeof document.elementsFromPoint === "function" ? document.elementsFromPoint(e.clientX, e.clientY) : []).find((node) => node?.nodeType === 1 && root.contains(node) && node.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor"))?.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") ?? (e.target?.nodeType === 1 ? e.target.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") : null);
15928
- if (clearCompactPopoverIfPdfClickedOutside(root, e.target, anchorElement)) return;
15934
+ const target = e.target instanceof Node ? e.target : null;
15935
+ if (!root || !layers.value?.contains(target)) return;
15936
+ const anchorElement = (typeof document.elementsFromPoint === "function" ? document.elementsFromPoint(e.clientX, e.clientY) : []).find((node) => node?.nodeType === 1 && root.contains(node) && node.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor"))?.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") ?? (target instanceof Element ? target.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") : null);
15937
+ if (clearCompactPopoverIfPdfClickedOutside(root, target, anchorElement)) return;
15929
15938
  if (e.button !== 0 || e.pointerType !== "mouse") return;
15930
15939
  const anchorRect = anchorElement && typeof anchorElement.getBoundingClientRect === "function" ? anchorElement.getBoundingClientRect() : null;
15931
15940
  if (!anchorRect) return;
@@ -16128,10 +16137,10 @@ function mergeCommentsConfig(config, presentation) {
16128
16137
  * existing UI suppression rules keep their current behavior.
16129
16138
  */
16130
16139
  function normalizeHyperlinksConfig(config = {}) {
16131
- const canonical = require_create_super_doc_ui.isPlainObject(config.hyperlinks) ? config.hyperlinks : {};
16140
+ const canonical = require__plugin_vue_export_helper.isPlainObject(config.hyperlinks) ? config.hyperlinks : {};
16132
16141
  const hasCanonicalHandler = typeof canonical.onActivate === "function";
16133
- const ui = require_create_super_doc_ui.isPlainObject(config.ui) ? config.ui : {};
16134
- const legacyUi = require_create_super_doc_ui.isPlainObject(ui.linkPopover) ? ui.linkPopover : {};
16142
+ const ui = require__plugin_vue_export_helper.isPlainObject(config.ui) ? config.ui : {};
16143
+ const legacyUi = require__plugin_vue_export_helper.isPlainObject(ui.linkPopover) ? ui.linkPopover : {};
16135
16144
  const allActivationDisabled = config.hyperlinks === false;
16136
16145
  const builtInEditorDisabled = config.ui === false || ui.linkPopover === false;
16137
16146
  const selectedHandler = [
@@ -16159,7 +16168,7 @@ function normalizeHyperlinksConfig(config = {}) {
16159
16168
  };
16160
16169
  }
16161
16170
  //#endregion
16162
- //#region src/helpers/v2-review-target.js
16171
+ //#region src/helpers/v2-review-target.ts
16163
16172
  /**
16164
16173
  * Resolve the comments-store identity for a document-origin v2 review target.
16165
16174
  * Painted review carriers can become interactive before the asynchronous row
@@ -16175,15 +16184,16 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
16175
16184
  return commentId != null ? String(commentId) : null;
16176
16185
  }
16177
16186
  //#endregion
16178
- //#region src/helpers/v2-mutation-exception.js
16187
+ //#region src/helpers/v2-mutation-exception.ts
16179
16188
  var FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
16180
16189
  var DIAGNOSTIC_CODE = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
16181
16190
  var COMMAND_KIND = /^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/;
16182
16191
  function createV2MutationRejectionCause(event) {
16183
- if (!event || typeof event !== "object") return {};
16184
- const reason = event.reason ?? (event.failureSource === "receipt" ? event.failure?.code : void 0);
16192
+ if (!require__plugin_vue_export_helper.isPlainObject(event)) return {};
16193
+ const failure = require__plugin_vue_export_helper.isPlainObject(event.failure) ? event.failure : void 0;
16194
+ const reason = event.reason ?? (event.failureSource === "receipt" ? failure?.code : void 0);
16185
16195
  return {
16186
- ...FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
16196
+ ...typeof event.failureSource === "string" && FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
16187
16197
  ...typeof reason === "string" && DIAGNOSTIC_CODE.test(reason) ? { reason } : {},
16188
16198
  ...typeof event.inputKind === "string" && DIAGNOSTIC_CODE.test(event.inputKind) ? { inputKind: event.inputKind } : {},
16189
16199
  ...typeof event.editableCommandKind === "string" && event.editableCommandKind.length <= 128 && COMMAND_KIND.test(event.editableCommandKind) ? { editableCommandKind: event.editableCommandKind } : {}
@@ -16211,7 +16221,7 @@ function createV2MutationRejectionNotificationGate(matches) {
16211
16221
  };
16212
16222
  }
16213
16223
  //#endregion
16214
- //#region src/helpers/v2-author-required-rejection.js
16224
+ //#region src/helpers/v2-author-required-rejection.ts
16215
16225
  var NO_AUTHOR_SIGNAL = "no-author-configured";
16216
16226
  /** Stable, non-terminal exception code surfaced to consumers. */
16217
16227
  var V2_AUTHOR_REQUIRED_CODE = "author-required";
@@ -16223,15 +16233,11 @@ var V2_AUTHOR_REQUIRED_MESSAGE = "This edit needs an author identity. Set `user.
16223
16233
  function messageHasNoAuthorSignal(message) {
16224
16234
  return typeof message === "string" && message.includes(NO_AUTHOR_SIGNAL);
16225
16235
  }
16226
- /**
16227
- * @param {any} event - a `v2-host-event` payload.
16228
- * @returns {boolean} true when the rejection means the session needs an author.
16229
- */
16230
16236
  function isV2AuthorRequiredRejection(event) {
16231
- if (!event || event.type !== "mutation:rejected") return false;
16237
+ if (!require__plugin_vue_export_helper.isPlainObject(event) || event.type !== "mutation:rejected") return false;
16232
16238
  if (event.failureSource === "receipt") {
16233
16239
  const failure = event.failure;
16234
- if (!failure) return false;
16240
+ if (!require__plugin_vue_export_helper.isPlainObject(failure)) return false;
16235
16241
  return failure.code === "PRECONDITION_FAILED" && messageHasNoAuthorSignal(failure.message);
16236
16242
  }
16237
16243
  if (event.failureSource === "shell") {
@@ -16244,7 +16250,7 @@ function createV2AuthorRequiredNotificationGate() {
16244
16250
  return createV2MutationRejectionNotificationGate(isV2AuthorRequiredRejection);
16245
16251
  }
16246
16252
  //#endregion
16247
- //#region src/helpers/v2-bulk-decision-event.js
16253
+ //#region src/helpers/v2-bulk-decision-event.ts
16248
16254
  function toV2BulkDecisionEvent(documentId, fact) {
16249
16255
  if (fact?.schemaVersion !== 1 || fact.decision !== "accept" && fact.decision !== "reject") return null;
16250
16256
  return {
@@ -16256,7 +16262,7 @@ function toV2BulkDecisionEvent(documentId, fact) {
16256
16262
  };
16257
16263
  }
16258
16264
  //#endregion
16259
- //#region src/helpers/v2-keyboard-edit-rejection.js
16265
+ //#region src/helpers/v2-keyboard-edit-rejection.ts
16260
16266
  var EDIT_INPUT_KINDS = /* @__PURE__ */ new Set([
16261
16267
  "keydown",
16262
16268
  "beforeinput",
@@ -16306,7 +16312,7 @@ var EDIT_FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
16306
16312
  var V2_EDIT_REJECTED_CODE = "edit-rejected";
16307
16313
  var V2_EDIT_REJECTED_MESSAGE = "This edit couldn’t be completed. Adjust the selection and try again.";
16308
16314
  function isV2KeyboardEditRejection(event) {
16309
- return Boolean(event && event.type === "mutation:rejected" && event.origin === "document-surface" && EDIT_FAILURE_SOURCES.has(event.failureSource) && EDIT_INPUT_KINDS.has(event.inputKind) && (EDIT_COMMAND_KINDS.has(event.editableCommandKind) || event.editableCommandKind == null && EDIT_INPUT_WITHOUT_COMMAND_KINDS.has(event.inputKind)));
16315
+ return require__plugin_vue_export_helper.isPlainObject(event) && event.type === "mutation:rejected" && event.origin === "document-surface" && EDIT_FAILURE_SOURCES.has(event.failureSource) && EDIT_INPUT_KINDS.has(event.inputKind) && (EDIT_COMMAND_KINDS.has(event.editableCommandKind) || event.editableCommandKind == null && EDIT_INPUT_WITHOUT_COMMAND_KINDS.has(event.inputKind));
16310
16316
  }
16311
16317
  function createV2KeyboardEditRejectionException(documentId, event) {
16312
16318
  return {
@@ -16320,24 +16326,17 @@ function createV2KeyboardEditRejectionNotificationGate() {
16320
16326
  return createV2MutationRejectionNotificationGate(isV2KeyboardEditRejection);
16321
16327
  }
16322
16328
  //#endregion
16323
- //#region src/helpers/v2-selection-sync.js
16329
+ //#region src/helpers/v2-selection-sync.ts
16324
16330
  /**
16325
16331
  * A logical v2 selection snapshot represents a non-empty range when its anchor
16326
16332
  * and focus point at different block positions. Mirrors the range check the v2
16327
16333
  * shell uses when it emits `v2-selection-changed`.
16328
- *
16329
- * @param {{ anchor?: { blockId?: unknown, blockOffset?: unknown }, focus?: { blockId?: unknown, blockOffset?: unknown } } | null | undefined} snapshot
16330
- * @returns {boolean}
16331
16334
  */
16332
16335
  var isV2RangeSnapshot = (snapshot) => Boolean(snapshot?.anchor && snapshot?.focus && (snapshot.anchor.blockId !== snapshot.focus.blockId || snapshot.anchor.blockOffset !== snapshot.focus.blockOffset));
16333
16336
  /**
16334
16337
  * Detect a real browser text selection whose endpoints are outside the active
16335
16338
  * v2 mount. Editable host selections can have no native DOM range, so an
16336
16339
  * absent range must not count as an outside selection.
16337
- *
16338
- * @param {Selection | null | undefined} selection
16339
- * @param {Node | null | undefined} root
16340
- * @returns {boolean}
16341
16340
  */
16342
16341
  var hasOutsideV2DomRangeSelection = (selection, root) => {
16343
16342
  if (!selection || selection.rangeCount < 1 || selection.isCollapsed || !root) return false;
@@ -16353,10 +16352,6 @@ var hasOutsideV2DomRangeSelection = (selection, root) => {
16353
16352
  * host snapshot rather than clobber the selection the host just published.
16354
16353
  * Only editable modes use the host snapshot. Viewing mode keeps native DOM
16355
16354
  * selection, and unknown modes should not preserve stale host state.
16356
- *
16357
- * @param {string | null | undefined} documentMode
16358
- * @param {unknown} hostSnapshot
16359
- * @returns {boolean}
16360
16355
  */
16361
16356
  var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
16362
16357
  if (documentMode !== "editing" && documentMode !== "suggesting") return false;
@@ -16367,10 +16362,6 @@ var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
16367
16362
  * rebuilt. Keep an already-positioned comment affordance during that gap when
16368
16363
  * the host still owns a range; otherwise the button unmounts and remounts on
16369
16364
  * consecutive paint frames, making it blink and intercepting its own click.
16370
- *
16371
- * @param {boolean} hasHostRange
16372
- * @param {{ source?: unknown } | null | undefined} selectionPosition
16373
- * @returns {boolean}
16374
16365
  */
16375
16366
  var shouldRetainV2FloatingSelection = (hasHostRange, selectionPosition) => hasHostRange === true && selectionPosition?.source === "document-editor";
16376
16367
  //#endregion
@@ -16562,7 +16553,7 @@ function usePasswordPrompt({ getSurfaceManager, getPasswordPromptConfig, onUnhan
16562
16553
  })
16563
16554
  });
16564
16555
  } else {
16565
- const mod = await Promise.resolve().then(() => require("./chunks/PasswordPromptSurface-BNkaztaP.cjs"));
16556
+ const mod = await Promise.resolve().then(() => require("./chunks/PasswordPromptSurface-x8GNmMJT.cjs"));
16566
16557
  const surfaceId = `password-prompt-${doc.id}`;
16567
16558
  handle = manager.open({
16568
16559
  id: surfaceId,
@@ -16664,9 +16655,6 @@ function createReplaceContinuation(session, { getCurrentSession, applySlice, onS
16664
16655
  }
16665
16656
  //#endregion
16666
16657
  //#region src/composables/use-find-replace.ts
16667
- function isThenable$2(value) {
16668
- return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
16669
- }
16670
16658
  var DEFAULT_TEXTS = {
16671
16659
  findPlaceholder: "Find",
16672
16660
  findAriaLabel: "Find text",
@@ -16841,7 +16829,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
16841
16829
  try {
16842
16830
  result = search.replace(replaceText.value);
16843
16831
  } catch {}
16844
- if (isThenable$2(result)) Promise.resolve(result).then(finish, finish);
16832
+ if (require__plugin_vue_export_helper.isThenable(result)) Promise.resolve(result).then(finish, finish);
16845
16833
  else finish();
16846
16834
  }
16847
16835
  function replaceAll() {
@@ -16863,7 +16851,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
16863
16851
  try {
16864
16852
  result = search.replaceAll(replaceText.value);
16865
16853
  } catch {}
16866
- if (isThenable$2(result)) Promise.resolve(result).then(finish, finish);
16854
+ if (require__plugin_vue_export_helper.isThenable(result)) Promise.resolve(result).then(finish, finish);
16867
16855
  else finish();
16868
16856
  }
16869
16857
  function syncFromSearchSession() {
@@ -17225,7 +17213,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17225
17213
  } else {
17226
17214
  let FindReplaceSurface;
17227
17215
  try {
17228
- FindReplaceSurface = (await Promise.resolve().then(() => require("./chunks/FindReplaceSurface-BNDrJ6VS.cjs"))).default;
17216
+ FindReplaceSurface = (await Promise.resolve().then(() => require("./chunks/FindReplaceSurface-fVHxPXtn.cjs"))).default;
17229
17217
  } catch {
17230
17218
  opening = false;
17231
17219
  return;
@@ -17492,7 +17480,7 @@ var plus_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0
17492
17480
  //#region ../../shared/common/icons/trash-can-solid.svg?raw
17493
17481
  var trash_can_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M135.2 17.7C140.6 6.8 151.7 0 163.8 0L284.2 0c12.1 0 23.2 6.8 28.6 17.7L320 32l96 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 96C14.3 96 0 81.7 0 64S14.3 32 32 32l96 0 7.2-14.3zM32 128l384 0 0 320c0 35.3-28.7 64-64 64L96 512c-35.3 0-64-28.7-64-64l0-320zm96 64c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16z\"/></svg>";
17494
17482
  //#endregion
17495
- //#region src/internal/toolbar/built-in/toolbarIcons.js
17483
+ //#region src/internal/toolbar/built-in/toolbarIcons.ts
17496
17484
  var toolbarIcons = {
17497
17485
  undo: rotate_left_solid_default,
17498
17486
  redo: rotate_right_solid_default,
@@ -17902,7 +17890,7 @@ var LinkInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ requir
17902
17890
  //#region src/internal/toolbar/built-in/LinkInput.vue
17903
17891
  var LinkInput_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(LinkInput_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-172107e4"]]);
17904
17892
  //#endregion
17905
- //#region src/internal/toolbar/built-in/scroll-helpers.js
17893
+ //#region src/internal/toolbar/built-in/scroll-helpers.ts
17906
17894
  function getScrollableParent(element) {
17907
17895
  let currentElement = element;
17908
17896
  while (currentElement) {
@@ -17935,26 +17923,25 @@ function scrollToElement(targetElement, options = {
17935
17923
  var FLOATING_SURFACE_ID = "link-popover";
17936
17924
  var RECENT_OUTSIDE_CLOSE_MS = 500;
17937
17925
  var MAX_ANCHOR_NAVIGATION_STEPS = 4;
17938
- var isThenable$1 = (value) => Boolean(value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function");
17939
17926
  function isLinkPopoverDocumentApi(value) {
17940
- return require_create_super_doc_ui.isPlainObject(value) || typeof value === "function";
17927
+ return require__plugin_vue_export_helper.isPlainObject(value) || typeof value === "function";
17941
17928
  }
17942
17929
  function linkPopoverDocumentApi(editor) {
17943
17930
  const doc = editor?.doc;
17944
17931
  return isLinkPopoverDocumentApi(doc) ? doc : null;
17945
17932
  }
17946
17933
  function isLinkNavigationHost(value) {
17947
- return require_create_super_doc_ui.isPlainObject(value) || typeof value === "function";
17934
+ return require__plugin_vue_export_helper.isPlainObject(value) || typeof value === "function";
17948
17935
  }
17949
17936
  function isHyperlinkTarget(value) {
17950
- if (!require_create_super_doc_ui.isPlainObject(value) || value.kind !== "inline" || value.nodeType !== "hyperlink") return false;
17951
- const anchor = require_create_super_doc_ui.isPlainObject(value.anchor) ? value.anchor : null;
17952
- const start = anchor && require_create_super_doc_ui.isPlainObject(anchor.start) ? anchor.start : null;
17953
- const end = anchor && require_create_super_doc_ui.isPlainObject(anchor.end) ? anchor.end : null;
17937
+ if (!require__plugin_vue_export_helper.isPlainObject(value) || value.kind !== "inline" || value.nodeType !== "hyperlink") return false;
17938
+ const anchor = require__plugin_vue_export_helper.isPlainObject(value.anchor) ? value.anchor : null;
17939
+ const start = anchor && require__plugin_vue_export_helper.isPlainObject(anchor.start) ? anchor.start : null;
17940
+ const end = anchor && require__plugin_vue_export_helper.isPlainObject(anchor.end) ? anchor.end : null;
17954
17941
  return typeof start?.blockId === "string" && typeof start.offset === "number" && typeof end?.blockId === "string" && typeof end.offset === "number";
17955
17942
  }
17956
17943
  function isValidResolution(value) {
17957
- if (!require_create_super_doc_ui.isPlainObject(value)) return false;
17944
+ if (!require__plugin_vue_export_helper.isPlainObject(value)) return false;
17958
17945
  if (value.type === "default" || value.type === "suppress" || value.type === "none") return true;
17959
17946
  if (value.type === "custom") return value.component != null;
17960
17947
  if (value.type === "external") return typeof value.render === "function";
@@ -17991,8 +17978,8 @@ function readPaintedSourceRef(element) {
17991
17978
  if (!encoded) return null;
17992
17979
  try {
17993
17980
  const parsed = JSON.parse(encoded);
17994
- const sourceRef = require_create_super_doc_ui.isPlainObject(parsed) ? parsed.sourceRef : void 0;
17995
- if (!require_create_super_doc_ui.isPlainObject(sourceRef)) return null;
17981
+ const sourceRef = require__plugin_vue_export_helper.isPlainObject(parsed) ? parsed.sourceRef : void 0;
17982
+ if (!require__plugin_vue_export_helper.isPlainObject(sourceRef)) return null;
17996
17983
  const partUri = typeof sourceRef.partUri === "string" ? sourceRef.partUri : void 0;
17997
17984
  const xpathLikePath = typeof sourceRef.xpathLikePath === "string" ? sourceRef.xpathLikePath : void 0;
17998
17985
  return partUri || xpathLikePath ? {
@@ -18580,7 +18567,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
18580
18567
  const fallbackResolution = () => usesOnActivate ? { type: "suppress" } : { type: "default" };
18581
18568
  try {
18582
18569
  const resolution = handler(ctx);
18583
- if (isThenable$1(resolution)) {
18570
+ if (require__plugin_vue_export_helper.isThenable(resolution)) {
18584
18571
  Promise.resolve(resolution).catch(() => void 0);
18585
18572
  emitException({
18586
18573
  error: /* @__PURE__ */ new Error(usesOnActivate ? "hyperlinks.onActivate must return synchronously; Promises are not supported." : "The hyperlink activation handler must return synchronously."),
@@ -19373,10 +19360,10 @@ function isPromiseLike(value) {
19373
19360
  return Boolean(value && typeof value === "object" && typeof value.then === "function");
19374
19361
  }
19375
19362
  function isTextTarget(value) {
19376
- return require_create_super_doc_ui.isPlainObject(value) && value.kind === "text" && Array.isArray(value.segments) && value.segments.length > 0;
19363
+ return require__plugin_vue_export_helper.isPlainObject(value) && value.kind === "text" && Array.isArray(value.segments) && value.segments.length > 0;
19377
19364
  }
19378
19365
  function isHeaderFooterStory(story) {
19379
- return require_create_super_doc_ui.isPlainObject(story) && story.kind === "story" && (story.storyType === "headerFooterSlot" || story.storyType === "headerFooterPart");
19366
+ return require__plugin_vue_export_helper.isPlainObject(story) && story.kind === "story" && (story.storyType === "headerFooterSlot" || story.storyType === "headerFooterPart");
19380
19367
  }
19381
19368
  function resolveCurrentHeaderFooterTextTarget(doc) {
19382
19369
  if (!isFn(doc.selection?.current)) return {
@@ -19396,7 +19383,7 @@ function resolveCurrentHeaderFooterTextTarget(doc) {
19396
19383
  handled: false,
19397
19384
  reason: "page-field-selection-async"
19398
19385
  };
19399
- if (!require_create_super_doc_ui.isPlainObject(currentSelection) || !isTextTarget(currentSelection.target)) return {
19386
+ if (!require__plugin_vue_export_helper.isPlainObject(currentSelection) || !isTextTarget(currentSelection.target)) return {
19400
19387
  handled: false,
19401
19388
  reason: "page-field-selection-unavailable"
19402
19389
  };
@@ -19494,7 +19481,7 @@ function createV2SessionShortcutRoutes(deps) {
19494
19481
  mode: "raw"
19495
19482
  });
19496
19483
  if (isPromiseLike(result)) result.catch(() => {});
19497
- else if (require_create_super_doc_ui.isPlainObject(result) && result.success === false) return {
19484
+ else if (require__plugin_vue_export_helper.isPlainObject(result) && result.success === false) return {
19498
19485
  handled: false,
19499
19486
  reason: "page-field-insert-failed"
19500
19487
  };
@@ -20511,7 +20498,7 @@ var SuperDoc_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require
20511
20498
  __name: "SuperDoc",
20512
20499
  emits: ["selection-update"],
20513
20500
  setup(__props, { emit: __emit }) {
20514
- const PdfViewer = require__plugin_vue_export_helper.defineAsyncComponent(() => Promise.resolve().then(() => require("./chunks/PdfViewer-DmSkZehl.cjs")));
20501
+ const PdfViewer = require__plugin_vue_export_helper.defineAsyncComponent(() => Promise.resolve().then(() => require("./chunks/PdfViewer-CkrAHpC-.cjs")));
20515
20502
  const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
20516
20503
  const resolveDocumentV2Collaboration = (doc) => {
20517
20504
  const rawConfig = doc?.v2Collaboration;
@@ -21314,7 +21301,7 @@ var SuperDoc_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require
21314
21301
  let v2SelectionToolbarRafHandle = 0;
21315
21302
  let v2SelectionToolbarTimeoutHandle = 0;
21316
21303
  let v2DomSelectionRafHandle = 0;
21317
- const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null } = {}) => {
21304
+ const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null, isRemote = false } = {}) => {
21318
21305
  const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21319
21306
  const effectiveEditor = editor ?? sourceEditor ?? activeEditor ?? void 0;
21320
21307
  return {
@@ -21322,7 +21309,8 @@ var SuperDoc_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require
21322
21309
  sourceEditor: sourceEditor ?? effectiveEditor,
21323
21310
  surface,
21324
21311
  headerId,
21325
- sectionType
21312
+ sectionType,
21313
+ isRemote
21326
21314
  };
21327
21315
  };
21328
21316
  const emitV2EditorUpdate = (payload = {}) => {
@@ -21716,6 +21704,7 @@ var SuperDoc_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require
21716
21704
  v2ReviewWindowController.invalidate("collaboration:remote-review-changed");
21717
21705
  v2ReviewWindowController.refreshCommittedWindow("collaboration:remote-review-changed");
21718
21706
  }
21707
+ emitV2EditorUpdate({ isRemote: true });
21719
21708
  return;
21720
21709
  }
21721
21710
  if (event.type === "source:complete") {
@@ -23131,7 +23120,7 @@ var SuperDoc_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require
23131
23120
  });
23132
23121
  //#endregion
23133
23122
  //#region src/SuperDoc.vue
23134
- var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(SuperDoc_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-26bcc2bd"]]);
23123
+ var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(SuperDoc_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-d2540ad3"]]);
23135
23124
  //#endregion
23136
23125
  //#region src/core/create-app.ts
23137
23126
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -32546,7 +32535,7 @@ function checkDefaultFill(config) {
32546
32535
  if (!config.fillLinearGradientColorStops && !config.fillRadialGradientColorStops && !config.fillPatternImage) config.fill = config.fill || "black";
32547
32536
  return config;
32548
32537
  }
32549
- var Text = class extends Shape {
32538
+ var Text$1 = class extends Shape {
32550
32539
  constructor(config) {
32551
32540
  super(checkDefaultFill(config));
32552
32541
  this._partialTextX = 0;
@@ -32808,10 +32797,10 @@ var Text = class extends Shape {
32808
32797
  return super._useBufferCanvas();
32809
32798
  }
32810
32799
  };
32811
- Text.prototype._fillFunc = _fillFunc$1;
32812
- Text.prototype._strokeFunc = _strokeFunc$1;
32813
- Text.prototype.className = TEXT_UPPER;
32814
- Text.prototype._attrsAffectingSize = [
32800
+ Text$1.prototype._fillFunc = _fillFunc$1;
32801
+ Text$1.prototype._strokeFunc = _strokeFunc$1;
32802
+ Text$1.prototype.className = TEXT_UPPER;
32803
+ Text$1.prototype._attrsAffectingSize = [
32815
32804
  "text",
32816
32805
  "fontSize",
32817
32806
  "padding",
@@ -32819,25 +32808,25 @@ Text.prototype._attrsAffectingSize = [
32819
32808
  "lineHeight",
32820
32809
  "letterSpacing"
32821
32810
  ];
32822
- _registerNode(Text);
32823
- Factory.overWriteSetter(Text, "width", getNumberOrAutoValidator());
32824
- Factory.overWriteSetter(Text, "height", getNumberOrAutoValidator());
32825
- Factory.addGetterSetter(Text, "direction", INHERIT);
32826
- Factory.addGetterSetter(Text, "fontFamily", "Arial");
32827
- Factory.addGetterSetter(Text, "fontSize", 12, getNumberValidator());
32828
- Factory.addGetterSetter(Text, "fontStyle", NORMAL$1);
32829
- Factory.addGetterSetter(Text, "fontVariant", NORMAL$1);
32830
- Factory.addGetterSetter(Text, "padding", 0, getNumberValidator());
32831
- Factory.addGetterSetter(Text, "align", LEFT);
32832
- Factory.addGetterSetter(Text, "verticalAlign", TOP);
32833
- Factory.addGetterSetter(Text, "lineHeight", 1, getNumberValidator());
32834
- Factory.addGetterSetter(Text, "wrap", WORD);
32835
- Factory.addGetterSetter(Text, "ellipsis", false, getBooleanValidator());
32836
- Factory.addGetterSetter(Text, "letterSpacing", 0, getNumberValidator());
32837
- Factory.addGetterSetter(Text, "text", "", getStringValidator());
32838
- Factory.addGetterSetter(Text, "textDecoration", "");
32839
- Factory.addGetterSetter(Text, "underlineOffset", void 0, getNumberValidator());
32840
- Factory.addGetterSetter(Text, "charRenderFunc", void 0);
32811
+ _registerNode(Text$1);
32812
+ Factory.overWriteSetter(Text$1, "width", getNumberOrAutoValidator());
32813
+ Factory.overWriteSetter(Text$1, "height", getNumberOrAutoValidator());
32814
+ Factory.addGetterSetter(Text$1, "direction", INHERIT);
32815
+ Factory.addGetterSetter(Text$1, "fontFamily", "Arial");
32816
+ Factory.addGetterSetter(Text$1, "fontSize", 12, getNumberValidator());
32817
+ Factory.addGetterSetter(Text$1, "fontStyle", NORMAL$1);
32818
+ Factory.addGetterSetter(Text$1, "fontVariant", NORMAL$1);
32819
+ Factory.addGetterSetter(Text$1, "padding", 0, getNumberValidator());
32820
+ Factory.addGetterSetter(Text$1, "align", LEFT);
32821
+ Factory.addGetterSetter(Text$1, "verticalAlign", TOP);
32822
+ Factory.addGetterSetter(Text$1, "lineHeight", 1, getNumberValidator());
32823
+ Factory.addGetterSetter(Text$1, "wrap", WORD);
32824
+ Factory.addGetterSetter(Text$1, "ellipsis", false, getBooleanValidator());
32825
+ Factory.addGetterSetter(Text$1, "letterSpacing", 0, getNumberValidator());
32826
+ Factory.addGetterSetter(Text$1, "text", "", getStringValidator());
32827
+ Factory.addGetterSetter(Text$1, "textDecoration", "");
32828
+ Factory.addGetterSetter(Text$1, "underlineOffset", void 0, getNumberValidator());
32829
+ Factory.addGetterSetter(Text$1, "charRenderFunc", void 0);
32841
32830
  //#endregion
32842
32831
  //#region ../../node_modules/.pnpm/konva@10.2.5/node_modules/konva/lib/shapes/TextPath.js
32843
32832
  var EMPTY_STRING = "";
@@ -32943,10 +32932,10 @@ var TextPath = class extends Shape {
32943
32932
  return this.textHeight;
32944
32933
  }
32945
32934
  setText(text) {
32946
- return Text.prototype.setText.call(this, text);
32935
+ return Text$1.prototype.setText.call(this, text);
32947
32936
  }
32948
32937
  _getContextFont() {
32949
- return Text.prototype._getContextFont.call(this);
32938
+ return Text$1.prototype._getContextFont.call(this);
32950
32939
  }
32951
32940
  _getTextSize(text) {
32952
32941
  const _context = this.dummyCanvas.getContext("2d");
@@ -35486,7 +35475,7 @@ var lib_default = Konva$1.Util._assign(Konva$1, {
35486
35475
  Ring,
35487
35476
  Sprite,
35488
35477
  Star,
35489
- Text,
35478
+ Text: Text$1,
35490
35479
  TextPath,
35491
35480
  Transformer,
35492
35481
  Wedge,
@@ -35951,7 +35940,7 @@ var TOOLBAR_ITEM_ALIASES = Object.freeze({
35951
35940
  * historical default rather than inheriting from its siblings.
35952
35941
  */
35953
35942
  var isUnknownArray = (value) => Array.isArray(value);
35954
- var isOptionsBag = (value) => require_create_super_doc_ui.isPlainObject(value);
35943
+ var isOptionsBag = (value) => require__plugin_vue_export_helper.isPlainObject(value);
35955
35944
  var hasSelectHandler = (item) => typeof item.onSelect === "function";
35956
35945
  /** Surfaces that render when the consumer says nothing at all. */
35957
35946
  var HISTORICAL_DEFAULTS = Object.freeze({
@@ -36080,7 +36069,7 @@ var SEARCH_STRING_KEYS = Object.freeze({
36080
36069
  invalidPattern: "invalidPatternLabel"
36081
36070
  });
36082
36071
  function normalizeSearchStrings(strings) {
36083
- if (!require_create_super_doc_ui.isPlainObject(strings)) return {};
36072
+ if (!require__plugin_vue_export_helper.isPlainObject(strings)) return {};
36084
36073
  return Object.fromEntries(Object.entries(strings).filter(([key, value]) => SEARCH_STRING_KEYS[key] !== void 0 && value !== void 0).map(([key, value]) => [SEARCH_STRING_KEYS[key], value]));
36085
36074
  }
36086
36075
  function normalizeSearchOptions(options) {
@@ -36174,7 +36163,7 @@ function mapToolbarKey(key, aliases) {
36174
36163
  return aliases[String(key)] ?? key;
36175
36164
  }
36176
36165
  function mapToolbarRecord(record, aliases) {
36177
- if (!require_create_super_doc_ui.isPlainObject(record)) return void 0;
36166
+ if (!require__plugin_vue_export_helper.isPlainObject(record)) return void 0;
36178
36167
  const entries = Object.entries(record);
36179
36168
  const passthroughEntries = entries.filter(([key]) => aliases[key] === void 0);
36180
36169
  const aliasedEntries = entries.filter(([key]) => aliases[key] !== void 0);
@@ -36185,14 +36174,14 @@ function mapToolbarItems(items) {
36185
36174
  return items.map((item) => mapToolbarKey(item, TOOLBAR_ITEM_ALIASES));
36186
36175
  }
36187
36176
  function mapToolbarRegions(regions) {
36188
- if (!require_create_super_doc_ui.isPlainObject(regions)) return regions;
36177
+ if (!require__plugin_vue_export_helper.isPlainObject(regions)) return regions;
36189
36178
  return Object.fromEntries(Object.entries(regions).map(([region, items]) => [region, mapToolbarItems(items)]));
36190
36179
  }
36191
36180
  function addCustomItemRegions(regions, customItems) {
36192
- if (!require_create_super_doc_ui.isPlainObject(regions) || !isUnknownArray(customItems)) return regions;
36181
+ if (!require__plugin_vue_export_helper.isPlainObject(regions) || !isUnknownArray(customItems)) return regions;
36193
36182
  const result = { ...regions };
36194
36183
  for (const item of customItems) {
36195
- if (!require_create_super_doc_ui.isPlainObject(item)) continue;
36184
+ if (!require__plugin_vue_export_helper.isPlainObject(item)) continue;
36196
36185
  const region = item.region ?? "center";
36197
36186
  if (result[region] === void 0) result[region] = [];
36198
36187
  }
@@ -36205,7 +36194,7 @@ var TOOLBAR_OPTIONAL_ITEM_REGIONS = Object.freeze({
36205
36194
  "table-of-contents": "center"
36206
36195
  });
36207
36196
  function addIncludedToolbarItems(regions, includeItems) {
36208
- if (!require_create_super_doc_ui.isPlainObject(regions) || !isUnknownArray(includeItems)) return regions;
36197
+ if (!require__plugin_vue_export_helper.isPlainObject(regions) || !isUnknownArray(includeItems)) return regions;
36209
36198
  const result = Object.fromEntries(Object.entries(regions).map(([region, items]) => [region, isUnknownArray(items) ? [...items] : items]));
36210
36199
  const configuredItems = new Set(Object.values(result).flatMap((items) => isUnknownArray(items) ? items : []).map((item) => mapToolbarKey(item, TOOLBAR_ITEM_ALIASES)));
36211
36200
  for (const item of includeItems) {
@@ -36225,7 +36214,7 @@ function extendToolbarRegions(regions, options) {
36225
36214
  function mapToolbarFontOptions(options) {
36226
36215
  if (!isUnknownArray(options)) return options;
36227
36216
  return options.map((option) => {
36228
- if (!require_create_super_doc_ui.isPlainObject(option)) return option;
36217
+ if (!require__plugin_vue_export_helper.isPlainObject(option)) return option;
36229
36218
  const { value, label, previewFamily } = option;
36230
36219
  return {
36231
36220
  key: value,
@@ -36238,7 +36227,7 @@ function mapToolbarFontOptions(options) {
36238
36227
  function mapToolbarCustomItems(items) {
36239
36228
  if (!isUnknownArray(items)) return items;
36240
36229
  return items.map((item) => {
36241
- if (!require_create_super_doc_ui.isPlainObject(item) || typeof item.id !== "string") return item;
36230
+ if (!require__plugin_vue_export_helper.isPlainObject(item) || typeof item.id !== "string") return item;
36242
36231
  const size = item.size ?? "default";
36243
36232
  const layoutWidth = item.type === "separator" ? void 0 : CUSTOM_TOOLBAR_ITEM_WIDTHS[String(size)];
36244
36233
  const style = item.style;
@@ -36266,7 +36255,7 @@ function mapToolbarCustomItems(items) {
36266
36255
  }
36267
36256
  if (item.type === "dropdown" && isUnknownArray(item.options)) {
36268
36257
  mapped.options = item.options.map((option) => {
36269
- if (!require_create_super_doc_ui.isPlainObject(option)) return option;
36258
+ if (!require__plugin_vue_export_helper.isPlainObject(option)) return option;
36270
36259
  return {
36271
36260
  ...option,
36272
36261
  key: option.value ?? option.id,
@@ -36288,14 +36277,14 @@ function mapToolbarCustomItems(items) {
36288
36277
  }
36289
36278
  function normalizeToolbarOptions(options) {
36290
36279
  const normalized = { ...options };
36291
- const configuredItems = firstDefined(options.items, require_create_super_doc_ui.isPlainObject(options.groups) ? options.groups : void 0);
36292
- const items = require_create_super_doc_ui.isPlainObject(options.items) && Object.keys(options.items).length === 0 ? { center: [] } : configuredItems;
36280
+ const configuredItems = firstDefined(options.items, require__plugin_vue_export_helper.isPlainObject(options.groups) ? options.groups : void 0);
36281
+ const items = require__plugin_vue_export_helper.isPlainObject(options.items) && Object.keys(options.items).length === 0 ? { center: [] } : configuredItems;
36293
36282
  const groupedItems = extendToolbarRegions(items, options);
36294
36283
  const groups = groupedItems === void 0 ? options.groups : mapToolbarRegions(groupedItems);
36295
36284
  const icons = mapToolbarRecord(options.icons, TOOLBAR_ICON_ALIASES);
36296
36285
  const texts = mergeDefined(mapToolbarRecord(options.texts, {}), mapToolbarRecord(options.strings, TOOLBAR_STRING_ALIASES));
36297
36286
  const includeItems = isUnknownArray(options.includeItems) ? new Set(options.includeItems) : null;
36298
- const itemIds = require_create_super_doc_ui.isPlainObject(items) ? new Set(Object.values(items).flatMap((regionItems) => isUnknownArray(regionItems) ? regionItems : [])) : /* @__PURE__ */ new Set();
36287
+ const itemIds = require__plugin_vue_export_helper.isPlainObject(items) ? new Set(Object.values(items).flatMap((regionItems) => isUnknownArray(regionItems) ? regionItems : [])) : /* @__PURE__ */ new Set();
36299
36288
  delete normalized.items;
36300
36289
  delete normalized.includeItems;
36301
36290
  delete normalized.overflow;
@@ -36324,7 +36313,7 @@ function normalizeToolbarOptions(options) {
36324
36313
  function normalizeUiConfig(config = {}) {
36325
36314
  const raw = config.ui;
36326
36315
  const allDisabled = raw === false;
36327
- const ui = require_create_super_doc_ui.isPlainObject(raw) ? raw : void 0;
36316
+ const ui = require__plugin_vue_export_helper.isPlainObject(raw) ? raw : void 0;
36328
36317
  const enabled = (key) => !allDisabled && resolveSurface(ui, key);
36329
36318
  const explicit = (key) => {
36330
36319
  if (allDisabled) return false;
@@ -36338,16 +36327,16 @@ function normalizeUiConfig(config = {}) {
36338
36327
  const legacyContentControlsChrome = config.modules?.contentControls?.chrome === "none" ? void 0 : config.modules?.contentControls?.chrome;
36339
36328
  const rawToolbarOptions = options("toolbar");
36340
36329
  const toolbarOptions = normalizeToolbarOptions(rawToolbarOptions);
36341
- const hasCanonicalToolbarItems = require_create_super_doc_ui.isPlainObject(rawToolbarOptions.items);
36330
+ const hasCanonicalToolbarItems = require__plugin_vue_export_helper.isPlainObject(rawToolbarOptions.items);
36342
36331
  const legacyToolbar = config.modules?.toolbar;
36343
- const legacyToolbarOptions = require_create_super_doc_ui.isPlainObject(legacyToolbar) ? legacyToolbar : {};
36332
+ const legacyToolbarOptions = require__plugin_vue_export_helper.isPlainObject(legacyToolbar) ? legacyToolbar : {};
36344
36333
  const legacyContextMenuRaw = config.modules?.contextMenu ?? config.modules?.slashMenu;
36345
- const legacyContextMenu = require_create_super_doc_ui.isPlainObject(legacyContextMenuRaw) ? legacyContextMenuRaw : {};
36334
+ const legacyContextMenu = require__plugin_vue_export_helper.isPlainObject(legacyContextMenuRaw) ? legacyContextMenuRaw : {};
36346
36335
  const legacySearchRaw = config.modules?.surfaces?.findReplace;
36347
- const legacySearch = normalizeSearchOptions(require_create_super_doc_ui.isPlainObject(legacySearchRaw) ? legacySearchRaw : {});
36348
- const legacyToolbarGroups = require_create_super_doc_ui.isPlainObject(legacyToolbarOptions.groups) ? mapToolbarRegions(extendToolbarRegions(legacyToolbarOptions.groups, rawToolbarOptions)) : legacyToolbarOptions.groups;
36336
+ const legacySearch = normalizeSearchOptions(require__plugin_vue_export_helper.isPlainObject(legacySearchRaw) ? legacySearchRaw : {});
36337
+ const legacyToolbarGroups = require__plugin_vue_export_helper.isPlainObject(legacyToolbarOptions.groups) ? mapToolbarRegions(extendToolbarRegions(legacyToolbarOptions.groups, rawToolbarOptions)) : legacyToolbarOptions.groups;
36349
36338
  const groupCandidates = [toolbarOptions.groups, legacyToolbarGroups];
36350
- const composedGroups = groupCandidates.find(require_create_super_doc_ui.isPlainObject);
36339
+ const composedGroups = groupCandidates.find(require__plugin_vue_export_helper.isPlainObject);
36351
36340
  const orderedGroups = groupCandidates.find(isUnknownArray);
36352
36341
  const selectedGroups = hasCanonicalToolbarItems ? Object.keys(toolbarOptions.groups ?? {}) : firstDefined(orderedGroups, legacyToolbarOptions.toolbarGroups, config.toolbarGroups);
36353
36342
  const selection = isUnknownArray(selectedGroups) ? selectedGroups.map(String) : null;
@@ -36425,10 +36414,10 @@ var isCommentInteractionLevel = (value) => value === "read" || value === "write"
36425
36414
  * resolve and reopen actions.
36426
36415
  */
36427
36416
  function normalizeInteractionConfig(config = {}) {
36428
- const interaction = require_create_super_doc_ui.isPlainObject(config.interaction) ? config.interaction : {};
36429
- const interactionComments = require_create_super_doc_ui.isPlainObject(interaction.comments) ? interaction.comments : {};
36430
- const interactionTrackedChanges = require_create_super_doc_ui.isPlainObject(interaction.trackedChanges) ? interaction.trackedChanges : {};
36431
- const legacyComments = require_create_super_doc_ui.isPlainObject(config.modules?.comments) ? config.modules.comments : {};
36417
+ const interaction = require__plugin_vue_export_helper.isPlainObject(config.interaction) ? config.interaction : {};
36418
+ const interactionComments = require__plugin_vue_export_helper.isPlainObject(interaction.comments) ? interaction.comments : {};
36419
+ const interactionTrackedChanges = require__plugin_vue_export_helper.isPlainObject(interaction.trackedChanges) ? interaction.trackedChanges : {};
36420
+ const legacyComments = require__plugin_vue_export_helper.isPlainObject(config.modules?.comments) ? config.modules.comments : {};
36432
36421
  const legacyReadOnly = (interactionComments.readOnly ?? legacyComments.readOnly ?? false) === true;
36433
36422
  const legacyAllowResolve = (interactionComments.allowResolve ?? legacyComments.allowResolve ?? true) !== false;
36434
36423
  const canonicalLevel = interactionComments.level;
@@ -36472,8 +36461,8 @@ function normalizeInteractionConfig(config = {}) {
36472
36461
  * is a function or `null` once a non-function value has been rejected.
36473
36462
  */
36474
36463
  function normalizeSurfacesConfig(config = {}) {
36475
- const next = require_create_super_doc_ui.isPlainObject(config.surfaces) ? config.surfaces : {};
36476
- const legacy = require_create_super_doc_ui.isPlainObject(config.modules?.surfaces) ? config.modules.surfaces : {};
36464
+ const next = require__plugin_vue_export_helper.isPlainObject(config.surfaces) ? config.surfaces : {};
36465
+ const legacy = require__plugin_vue_export_helper.isPlainObject(config.modules?.surfaces) ? config.modules.surfaces : {};
36477
36466
  const resolver = next.resolver === void 0 ? legacy.resolver : next.resolver;
36478
36467
  return {
36479
36468
  resolver: typeof resolver === "function" ? resolver : null,
@@ -37010,23 +36999,21 @@ function resolveBuiltInItemCommandId(name) {
37010
36999
  return resolveToolbarCommandId(name) ?? UNCATALOGED_ITEM_COMMAND_IDS[name] ?? null;
37011
37000
  }
37012
37001
  //#endregion
37013
- //#region src/internal/toolbar/built-in/helpers.js
37002
+ //#region src/internal/toolbar/built-in/helpers.ts
37014
37003
  var sanitizeNumber = (value, defaultNumber) => {
37015
- let sanitized = value.replace(/[^0-9.]/g, "");
37016
- sanitized = parseFloat(sanitized);
37017
- if (isNaN(sanitized)) sanitized = defaultNumber;
37018
- sanitized = parseFloat(sanitized);
37019
- return sanitized;
37020
- };
37021
- var throttle = (func, wait, options) => {
37022
- let timeout, args, result;
37004
+ const parsed = parseFloat(String(value ?? "").replace(/[^0-9.]/g, ""));
37005
+ return isNaN(parsed) ? defaultNumber : parsed;
37006
+ };
37007
+ var throttle = (func, wait, options = {}) => {
37008
+ let timeout;
37009
+ let args;
37010
+ let result;
37023
37011
  let previous = 0;
37024
- if (!options) options = {};
37025
37012
  const later = () => {
37026
37013
  previous = options.leading === false ? 0 : Date.now();
37027
- timeout = null;
37028
- result = func(...args);
37029
- if (!timeout) args = null;
37014
+ timeout = void 0;
37015
+ if (args) result = func(...args);
37016
+ if (!timeout) args = void 0;
37030
37017
  };
37031
37018
  const throttled = (...callArgs) => {
37032
37019
  const _now = Date.now();
@@ -37036,18 +37023,18 @@ var throttle = (func, wait, options) => {
37036
37023
  if (remaining <= 0 || remaining > wait) {
37037
37024
  if (timeout) {
37038
37025
  clearTimeout(timeout);
37039
- timeout = null;
37026
+ timeout = void 0;
37040
37027
  }
37041
37028
  previous = _now;
37042
37029
  result = func(...callArgs);
37043
- if (!timeout) args = null;
37030
+ if (!timeout) args = void 0;
37044
37031
  } else if (!timeout && options.trailing !== false) timeout = setTimeout(later, remaining);
37045
37032
  return result;
37046
37033
  };
37047
37034
  throttled.cancel = function() {
37048
37035
  clearTimeout(timeout);
37049
37036
  previous = 0;
37050
- timeout = args = null;
37037
+ timeout = args = void 0;
37051
37038
  };
37052
37039
  return throttled;
37053
37040
  };
@@ -37953,24 +37940,11 @@ var OverflowMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ req
37953
37940
  //#region src/internal/toolbar/built-in/OverflowMenu.vue
37954
37941
  var OverflowMenu_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(OverflowMenu_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-d2e189fd"]]);
37955
37942
  //#endregion
37956
- //#region src/internal/toolbar/built-in/font-typeahead.js
37957
- /**
37958
- * Pure typeahead/autocomplete helpers for the font comboboxes (family + size).
37959
- *
37960
- * Matching is case-insensitive prefix matching on the logical font labels.
37961
- * Space is a normal query character, so the query is never split on spaces;
37962
- * only the outer whitespace is ignored when comparing.
37963
- *
37964
- * These functions hold no Vue or DOM state so CI can unit-test them in isolation.
37965
- */
37943
+ //#region src/internal/toolbar/built-in/font-typeahead.ts
37966
37944
  var normalize = (value) => String(value ?? "").trim().toLowerCase();
37967
37945
  /**
37968
37946
  * Index of the first label that starts with `query` (case-insensitive).
37969
- * An empty/whitespace query never matches.
37970
- *
37971
- * @param {string} query
37972
- * @param {ReadonlyArray<string>} labels
37973
- * @returns {number} matching index or -1
37947
+ * An empty/whitespace query never matches. Returns the matching index or -1.
37974
37948
  */
37975
37949
  var findPrefixMatchIndex = (query, labels) => {
37976
37950
  const q = normalize(query);
@@ -37984,12 +37958,7 @@ var findPrefixMatchIndex = (query, labels) => {
37984
37958
  * When `autocomplete` is true and a prefix match exists that is longer than the
37985
37959
  * typed query, the completion is shown with the suffix selected so the next
37986
37960
  * keystroke replaces it. When false (deletion) or no match exists, the raw
37987
- * query is shown with the caret at its end.
37988
- *
37989
- * @param {string} query - the user-typed portion
37990
- * @param {ReadonlyArray<string>} labels
37991
- * @param {{ autocomplete?: boolean }} [options]
37992
- * @returns {{ matchIndex: number, display: string, selectionStart: number, selectionEnd: number }}
37961
+ * query is shown with the caret at its end. `query` is the user-typed portion.
37993
37962
  */
37994
37963
  var computeTypeahead = (query, labels, { autocomplete = true } = {}) => {
37995
37964
  const typed = String(query ?? "");
@@ -38041,9 +38010,6 @@ var MAX_FONT_SIZE = 1638;
38041
38010
  * the nearest half point (DOCX/Word support half points such as 10.5), and clamps
38042
38011
  * to the supported range. Returns '' when nothing usable was typed, including
38043
38012
  * negative or sub-minimum values.
38044
- *
38045
- * @param {string} value
38046
- * @returns {string} point size (whole or half), or '' when empty/invalid
38047
38013
  */
38048
38014
  var normalizeCustomFontSize = (value) => {
38049
38015
  const cleaned = String(value ?? "").replace(/[^0-9.-]/g, "");
@@ -39738,7 +39704,7 @@ var Toolbar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require_
39738
39704
  //#region src/internal/toolbar/built-in/Toolbar.vue
39739
39705
  var Toolbar_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(Toolbar_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-bce7c04a"]]);
39740
39706
  //#endregion
39741
- //#region src/internal/toolbar/built-in/font-options.js
39707
+ //#region src/internal/toolbar/built-in/font-options.ts
39742
39708
  /**
39743
39709
  * Normalize a font dropdown option so each row renders in its own typeface.
39744
39710
  *
@@ -40096,7 +40062,7 @@ var StyleButtonsList_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
40096
40062
  //#region src/internal/toolbar/built-in/StyleButtonsList.vue
40097
40063
  var StyleButtonsList_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(StyleButtonsList_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-539d0995"]]);
40098
40064
  //#endregion
40099
- //#region src/internal/toolbar/built-in/list-style-buttons.js
40065
+ //#region src/internal/toolbar/built-in/list-style-buttons.ts
40100
40066
  var bulletStyleButtons = [
40101
40067
  {
40102
40068
  key: "disc",
@@ -40429,13 +40395,13 @@ var AIWriter_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require
40429
40395
  });
40430
40396
  function extractGeneratedText(payload) {
40431
40397
  if (typeof payload === "string") return payload;
40432
- if (!require_create_super_doc_ui.isPlainObject(payload)) return "";
40398
+ if (!require__plugin_vue_export_helper.isPlainObject(payload)) return "";
40433
40399
  const customPrompt = payload.custom_prompt;
40434
40400
  if (Array.isArray(customPrompt)) {
40435
40401
  const first = customPrompt[0];
40436
- if (require_create_super_doc_ui.isPlainObject(first) && typeof first.value === "string") return first.value;
40402
+ if (require__plugin_vue_export_helper.isPlainObject(first) && typeof first.value === "string") return first.value;
40437
40403
  }
40438
- if (require_create_super_doc_ui.isPlainObject(customPrompt) && typeof customPrompt.value === "string") return customPrompt.value;
40404
+ if (require__plugin_vue_export_helper.isPlainObject(customPrompt) && typeof customPrompt.value === "string") return customPrompt.value;
40439
40405
  if (typeof payload.value === "string") return payload.value;
40440
40406
  if (typeof payload.text === "string") return payload.text;
40441
40407
  return "";
@@ -41314,7 +41280,7 @@ var PageNumberMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ r
41314
41280
  }
41315
41281
  function failureDetails(result) {
41316
41282
  if (typeof result !== "object" || result === null || result.success) return null;
41317
- return require_create_super_doc_ui.isPlainObject(result.failure?.details) ? result.failure.details : null;
41283
+ return require__plugin_vue_export_helper.isPlainObject(result.failure?.details) ? result.failure.details : null;
41318
41284
  }
41319
41285
  function failureMessage(result, action) {
41320
41286
  const details = failureDetails(result);
@@ -41426,7 +41392,7 @@ var PageNumberMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ r
41426
41392
  onClick: ($event) => selectTile(tile),
41427
41393
  onDblclick: applyPageNumbers,
41428
41394
  onKeydown: onTileKeydown
41429
- }, [(require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = require__plugin_vue_export_helper.createStaticVNode("<rect class=\"sd-page-number-menu__sheet\" x=\"0.75\" y=\"0.75\" width=\"34.5\" height=\"44.5\" rx=\"2.5\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"14\" width=\"22\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"19\" width=\"18\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"24\" width=\"22\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"29\" width=\"14\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect>", 5)), require__plugin_vue_export_helper.createElementVNode("rect", {
41395
+ }, [(require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = require__plugin_vue_export_helper.createStaticVNode("<rect class=\"sd-page-number-menu__sheet\" x=\"0.75\" y=\"0.75\" width=\"34.5\" height=\"44.5\" rx=\"2.5\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"14\" width=\"22\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"19\" width=\"18\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"24\" width=\"22\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"29\" width=\"14\" height=\"2\" rx=\"1\" data-v-e3105afd></rect>", 5)), require__plugin_vue_export_helper.createElementVNode("rect", {
41430
41396
  class: "sd-page-number-menu__chip",
41431
41397
  x: CHIP_X[tile.alignment],
41432
41398
  y: CHIP_Y[tile.position],
@@ -41509,23 +41475,21 @@ var PageNumberMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ r
41509
41475
  });
41510
41476
  //#endregion
41511
41477
  //#region src/internal/toolbar/built-in/PageNumberMenu.vue
41512
- var PageNumberMenu_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(PageNumberMenu_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-a6c124c0"]]);
41478
+ var PageNumberMenu_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(PageNumberMenu_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-e3105afd"]]);
41513
41479
  //#endregion
41514
- //#region src/internal/toolbar/built-in/page-number-feedback.js
41480
+ //#region src/internal/toolbar/built-in/page-number-feedback.ts
41515
41481
  var FLASH_CLASS = "sd-page-number-flash";
41516
41482
  var FLASH_MS = 1400;
41517
41483
  var nextFrame = (view) => new Promise((resolve) => {
41518
- if (typeof view?.requestAnimationFrame === "function") view.requestAnimationFrame(() => resolve());
41484
+ if (typeof view.requestAnimationFrame === "function") view.requestAnimationFrame(() => resolve());
41519
41485
  else setTimeout(resolve, 16);
41520
41486
  });
41521
41487
  /**
41522
41488
  * Briefly highlight the painted header or footer regions that are on screen,
41523
41489
  * so the user sees where page numbers landed without the caret leaving the
41524
41490
  * body. Regions are read after the repaint that follows the mutation; nothing
41525
- * happens when none is visible or the host is unavailable.
41526
- *
41527
- * @param {HTMLElement | null | undefined} host Document viewport host element.
41528
- * @param {'header' | 'footer'} kind
41491
+ * happens when none is visible or the host is unavailable. `host` is the
41492
+ * document viewport host element.
41529
41493
  */
41530
41494
  async function flashPageNumberRegions(host, kind) {
41531
41495
  const view = host?.ownerDocument?.defaultView;
@@ -41533,7 +41497,7 @@ async function flashPageNumberRegions(host, kind) {
41533
41497
  await nextFrame(view);
41534
41498
  await nextFrame(view);
41535
41499
  const viewportHeight = view.innerHeight;
41536
- const regions = [...host.querySelectorAll(`[data-sd-headerfooter-kind="${kind}"]`)].filter((region) => {
41500
+ const regions = Array.from(host.querySelectorAll(`[data-sd-headerfooter-kind="${kind}"]`)).filter((region) => {
41537
41501
  const rect = region.getBoundingClientRect();
41538
41502
  return rect.height > 0 && rect.bottom > 0 && rect.top < viewportHeight;
41539
41503
  });
@@ -41711,7 +41675,7 @@ function currentSelectionSnapshot(superToolbar) {
41711
41675
  return superToolbar.ui?.selection?.get?.() ?? superToolbar.ui?.selection?.current?.() ?? null;
41712
41676
  }
41713
41677
  function readMember(value, key) {
41714
- return require_create_super_doc_ui.isPlainObject(value) ? value[key] : void 0;
41678
+ return require__plugin_vue_export_helper.isPlainObject(value) ? value[key] : void 0;
41715
41679
  }
41716
41680
  function configuredAiModule(superToolbar) {
41717
41681
  return readMember(readMember(readMember(readMember(superToolbar.config, "superdoc"), "config"), "modules"), "ai");
@@ -42881,7 +42845,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
42881
42845
  };
42882
42846
  };
42883
42847
  //#endregion
42884
- //#region src/internal/toolbar/built-in/general.js
42848
+ //#region src/internal/toolbar/built-in/general.ts
42885
42849
  /**
42886
42850
  * Minimal DOM helpers for the built-in toolbar shell.
42887
42851
  *
@@ -42892,8 +42856,6 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
42892
42856
  */
42893
42857
  /**
42894
42858
  * Resolve a toolbar mount target from a selector string or element id.
42895
- * @param {string|HTMLElement|null|undefined} selector
42896
- * @returns {HTMLElement|null}
42897
42859
  */
42898
42860
  var findElementBySelector = (selector) => {
42899
42861
  if (!selector) return null;
@@ -42933,9 +42895,6 @@ function toSelectedValue(value) {
42933
42895
  function nonEmptyString(value) {
42934
42896
  return typeof value === "string" && value ? value : void 0;
42935
42897
  }
42936
- function isThenable(value) {
42937
- return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
42938
- }
42939
42898
  function isToolbarCommandCallback(value) {
42940
42899
  return typeof value === "function";
42941
42900
  }
@@ -42958,7 +42917,7 @@ function executeCommand(ui, commandId, argument, options = {}) {
42958
42917
  if (!options.reportUnhandled || settled !== false) return;
42959
42918
  options.onError?.(/* @__PURE__ */ new Error(`[superdoc toolbar] Command "${commandId}" did not run. Check that it is enabled and has the required input.`));
42960
42919
  };
42961
- if (isThenable(result)) Promise.resolve(result).then((settled) => {
42920
+ if (require__plugin_vue_export_helper.isThenable(result)) Promise.resolve(result).then((settled) => {
42962
42921
  reportFailure(settled);
42963
42922
  options.onSettled?.();
42964
42923
  }, (error) => {
@@ -43310,7 +43269,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
43310
43269
  argument: payload.argument,
43311
43270
  option: payload.option
43312
43271
  });
43313
- if (isThenable(result)) return Promise.resolve(result).catch((error) => {
43272
+ if (require__plugin_vue_export_helper.isThenable(result)) return Promise.resolve(result).catch((error) => {
43314
43273
  this.#emitCommandException(error, config.name);
43315
43274
  return false;
43316
43275
  });
@@ -43787,7 +43746,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
43787
43746
  ui: this.ui,
43788
43747
  superdoc: this.superdoc
43789
43748
  });
43790
- if (isThenable(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
43749
+ if (require__plugin_vue_export_helper.isThenable(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
43791
43750
  }
43792
43751
  this.updateToolbarState();
43793
43752
  return;
@@ -44357,7 +44316,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
44357
44316
  }
44358
44317
  this.userColorMap = /* @__PURE__ */ new Map();
44359
44318
  this.colorIndex = 0;
44360
- this.version = "2.29.0-next.9";
44319
+ this.version = "2.29.0";
44361
44320
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
44362
44321
  this.superdocId = config.superdocId || require_uuid.v4();
44363
44322
  this.colors = this.config.colors ?? [];