@arbidocs/blocks 0.4.103 → 0.4.105

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 (92) hide show
  1. package/dist/agents/index.cjs +207 -207
  2. package/dist/agents/index.js +2 -2
  3. package/dist/agents/runs/AgentSteps.d.ts +3 -3
  4. package/dist/chat/ModelPicker.d.ts +7 -7
  5. package/dist/chat/index.cjs +65 -65
  6. package/dist/chat/index.js +1 -1
  7. package/dist/{chunk-IF6VAYIA.cjs → chunk-24ND4S6Y.cjs} +8 -8
  8. package/dist/chunk-24ND4S6Y.cjs.map +1 -0
  9. package/dist/{chunk-AOFATOT3.cjs → chunk-2A4MDHJR.cjs} +7 -5
  10. package/dist/chunk-2A4MDHJR.cjs.map +1 -0
  11. package/dist/{chunk-DDYXFALG.cjs → chunk-3PCHGUL5.cjs} +5 -5
  12. package/dist/{chunk-DDYXFALG.cjs.map → chunk-3PCHGUL5.cjs.map} +1 -1
  13. package/dist/{chunk-GQTIAATM.js → chunk-4GFB5U3K.js} +3 -3
  14. package/dist/{chunk-GQTIAATM.js.map → chunk-4GFB5U3K.js.map} +1 -1
  15. package/dist/chunk-5FYU7ZIU.cjs +139 -0
  16. package/dist/chunk-5FYU7ZIU.cjs.map +1 -0
  17. package/dist/{chunk-TFDU2KGS.cjs → chunk-7LLLQUM7.cjs} +5 -5
  18. package/dist/{chunk-TFDU2KGS.cjs.map → chunk-7LLLQUM7.cjs.map} +1 -1
  19. package/dist/{chunk-D3QPYKZG.js → chunk-EPHGD4YV.js} +7 -6
  20. package/dist/chunk-EPHGD4YV.js.map +1 -0
  21. package/dist/chunk-HFZ45FD3.js +133 -0
  22. package/dist/chunk-HFZ45FD3.js.map +1 -0
  23. package/dist/{chunk-5NQIBJPP.js → chunk-IU542FPZ.js} +5 -5
  24. package/dist/{chunk-5NQIBJPP.js.map → chunk-IU542FPZ.js.map} +1 -1
  25. package/dist/{chunk-H6DFXG5N.js → chunk-PIT2YZCK.js} +3 -3
  26. package/dist/{chunk-H6DFXG5N.js.map → chunk-PIT2YZCK.js.map} +1 -1
  27. package/dist/{chunk-Z3G65XHZ.js → chunk-S55VDTX3.js} +3 -3
  28. package/dist/{chunk-Z3G65XHZ.js.map → chunk-S55VDTX3.js.map} +1 -1
  29. package/dist/{chunk-ICBAFX5B.js → chunk-S7RHJI5Q.js} +8 -8
  30. package/dist/chunk-S7RHJI5Q.js.map +1 -0
  31. package/dist/{chunk-LENXDIMY.cjs → chunk-SKSE4OT6.cjs} +22 -22
  32. package/dist/{chunk-LENXDIMY.cjs.map → chunk-SKSE4OT6.cjs.map} +1 -1
  33. package/dist/{chunk-N36PWG7A.cjs → chunk-TP3FAP5J.cjs} +5 -5
  34. package/dist/{chunk-N36PWG7A.cjs.map → chunk-TP3FAP5J.cjs.map} +1 -1
  35. package/dist/{chunk-CVYY4X5R.js → chunk-W2RTZOK3.js} +1232 -193
  36. package/dist/chunk-W2RTZOK3.js.map +1 -0
  37. package/dist/{chunk-O33EBMIX.cjs → chunk-ZWWN4CUL.cjs} +1410 -359
  38. package/dist/chunk-ZWWN4CUL.cjs.map +1 -0
  39. package/dist/connect/docx.cjs +8 -7
  40. package/dist/connect/docx.cjs.map +1 -1
  41. package/dist/connect/docx.js +6 -5
  42. package/dist/connect/docx.js.map +1 -1
  43. package/dist/connect/index.cjs +13 -12
  44. package/dist/connect/index.cjs.map +1 -1
  45. package/dist/connect/index.js +6 -5
  46. package/dist/connect/index.js.map +1 -1
  47. package/dist/docx/LinkHoverCard.d.ts +24 -0
  48. package/dist/docx/NativeDocxEditor.d.ts +6 -0
  49. package/dist/docx/beforeSave.d.ts +9 -0
  50. package/dist/docx/definitions/fragment.d.ts +19 -1
  51. package/dist/docx/definitions/port.d.ts +43 -11
  52. package/dist/docx/index.cjs +85 -36
  53. package/dist/docx/index.cjs.map +1 -1
  54. package/dist/docx/index.d.ts +6 -0
  55. package/dist/docx/index.js +5 -4
  56. package/dist/docx/index.js.map +1 -1
  57. package/dist/docx/references/CrossReferences.d.ts +97 -0
  58. package/dist/docx/references/EditorMenus.d.ts +10 -0
  59. package/dist/docx/references/commands.d.ts +119 -0
  60. package/dist/docx/references/numbering.d.ts +49 -0
  61. package/dist/docx/references/passages.d.ts +32 -0
  62. package/dist/docx/references/port.d.ts +20 -0
  63. package/dist/facts/index.cjs +21 -128
  64. package/dist/facts/index.cjs.map +1 -1
  65. package/dist/facts/index.js +2 -124
  66. package/dist/facts/index.js.map +1 -1
  67. package/dist/index.cjs +342 -342
  68. package/dist/index.js +8 -8
  69. package/dist/settings/Billing.d.ts +1 -1
  70. package/dist/settings/PlanCard.d.ts +2 -2
  71. package/dist/settings/QuotaMeter.d.ts +1 -1
  72. package/dist/settings/{ReferralCredit.d.ts → ReferralReward.d.ts} +15 -15
  73. package/dist/settings/SubscriptionParts.d.ts +3 -3
  74. package/dist/settings/Usage.d.ts +7 -11
  75. package/dist/settings/WelcomeDialog.d.ts +1 -1
  76. package/dist/settings/index.cjs +33 -39
  77. package/dist/settings/index.cjs.map +1 -1
  78. package/dist/settings/index.d.ts +2 -2
  79. package/dist/settings/index.js +31 -36
  80. package/dist/settings/index.js.map +1 -1
  81. package/dist/tags/ooxml.d.ts +4 -0
  82. package/dist/workflow-canvas/index.cjs +9 -9
  83. package/dist/workflow-canvas/index.js +2 -2
  84. package/node_modules/@arbidocs/coedit/package.json +1 -1
  85. package/package.json +4 -4
  86. package/src/docx/README.md +22 -0
  87. package/dist/chunk-AOFATOT3.cjs.map +0 -1
  88. package/dist/chunk-CVYY4X5R.js.map +0 -1
  89. package/dist/chunk-D3QPYKZG.js.map +0 -1
  90. package/dist/chunk-ICBAFX5B.js.map +0 -1
  91. package/dist/chunk-IF6VAYIA.cjs.map +0 -1
  92. package/dist/chunk-O33EBMIX.cjs.map +0 -1
@@ -1,17 +1,19 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkAOFATOT3_cjs = require('./chunk-AOFATOT3.cjs');
4
+ var chunk5FYU7ZIU_cjs = require('./chunk-5FYU7ZIU.cjs');
5
+ var chunk2A4MDHJR_cjs = require('./chunk-2A4MDHJR.cjs');
5
6
  var chunk7UTB4PHM_cjs = require('./chunk-7UTB4PHM.cjs');
6
7
  var fflate = require('fflate');
7
8
  var store = require('@docx-editor.dev/core/store');
8
- var React3 = require('react');
9
+ var React4 = require('react');
9
10
  var react = require('@docx-editor.dev/react');
10
11
  var ui = require('@arbidocs/react/ui');
11
12
  var lucideReact = require('lucide-react');
12
13
  var jsxRuntime = require('react/jsx-runtime');
13
14
  var reactDom = require('react-dom');
14
15
  var template = require('@arbidocs/coedit/template');
16
+ var layout = require('@docx-editor.dev/core/layout');
15
17
  var editor = require('@docx-editor.dev/core/editor');
16
18
  var server = require('react-dom/server');
17
19
  var Y = require('yjs');
@@ -38,7 +40,7 @@ function _interopNamespace(e) {
38
40
  return Object.freeze(n);
39
41
  }
40
42
 
41
- var React3__default = /*#__PURE__*/_interopDefault(React3);
43
+ var React4__default = /*#__PURE__*/_interopDefault(React4);
42
44
  var Y__namespace = /*#__PURE__*/_interopNamespace(Y);
43
45
 
44
46
  function normalizeDocxExport(data) {
@@ -134,10 +136,10 @@ function useReview() {
134
136
  const editor = react.useDocxEditor();
135
137
  const version = react.useEditorSnapshot(editor);
136
138
  const revision = editor?.getReviewRevision() ?? 0;
137
- const items = React3.useMemo(() => editor ? editor.getReviewItems() : NONE, [editor, revision]);
139
+ const items = React4.useMemo(() => editor ? editor.getReviewItems() : NONE, [editor, revision]);
138
140
  const paneOpen = editor?.isReviewPaneOpen() ?? false;
139
141
  const activeKey = items.find((item) => item.isActive)?.key ?? null;
140
- return React3.useMemo(
142
+ return React4.useMemo(
141
143
  () => ({
142
144
  ready: editor !== null,
143
145
  items,
@@ -159,9 +161,9 @@ function useReview() {
159
161
  [editor, items, activeKey, paneOpen, version]
160
162
  );
161
163
  }
162
- var ReviewItemContext = React3.createContext(null);
164
+ var ReviewItemContext = React4.createContext(null);
163
165
  function useReviewItem() {
164
- return React3.useContext(ReviewItemContext);
166
+ return React4.useContext(ReviewItemContext);
165
167
  }
166
168
 
167
169
  // src/docx/review/commentText.ts
@@ -287,7 +289,7 @@ function ReplyForm({
287
289
  review,
288
290
  onDismiss
289
291
  }) {
290
- const [text, setText] = React3.useState("");
292
+ const [text, setText] = React4.useState("");
291
293
  return /* @__PURE__ */ jsxRuntime.jsxs(
292
294
  "form",
293
295
  {
@@ -458,9 +460,9 @@ function Draft({
458
460
  onCancel,
459
461
  formRef
460
462
  }) {
461
- const [text, setText] = React3.useState("");
462
- const input = React3.useRef(null);
463
- React3.useEffect(() => input.current?.focus(), []);
463
+ const [text, setText] = React4.useState("");
464
+ const input = React4.useRef(null);
465
+ React4.useEffect(() => input.current?.focus(), []);
464
466
  return /* @__PURE__ */ jsxRuntime.jsxs(
465
467
  "form",
466
468
  {
@@ -510,11 +512,11 @@ function Draft({
510
512
  );
511
513
  }
512
514
  function useScrollArea(anchor, ready) {
513
- const [area, setArea] = React3.useState({
515
+ const [area, setArea] = React4.useState({
514
516
  element: null,
515
517
  width: 0
516
518
  });
517
- React3.useLayoutEffect(() => {
519
+ React4.useLayoutEffect(() => {
518
520
  const element = anchor.current?.closest(".docx-editor__scroll-container") ?? null;
519
521
  const measure = () => setArea(
520
522
  (previous) => previous.element === element && previous.width === (element?.clientWidth ?? 0) ? previous : { element, width: element?.clientWidth ?? 0 }
@@ -531,26 +533,26 @@ function DocxEditorReviewRail({
531
533
  children
532
534
  }) {
533
535
  const editor = react.useDocxEditor();
534
- const registry = React3.useContext(react.ReviewRailContext);
536
+ const registry = React4.useContext(react.ReviewRailContext);
535
537
  const review = useReview();
536
- const [draft, setDraft] = React3.useState(null);
537
- const [tops, setTops] = React3.useState({});
538
- const [showResolved, setShowResolved] = React3.useState(true);
539
- const elements = React3.useRef(/* @__PURE__ */ new Map());
540
- const anchor = React3.useRef(null);
541
- const toolbar = React3.useRef(null);
538
+ const [draft, setDraft] = React4.useState(null);
539
+ const [tops, setTops] = React4.useState({});
540
+ const [showResolved, setShowResolved] = React4.useState(true);
541
+ const elements = React4.useRef(/* @__PURE__ */ new Map());
542
+ const anchor = React4.useRef(null);
543
+ const toolbar = React4.useRef(null);
542
544
  const area = useScrollArea(anchor, review.ready);
543
545
  const layout = area.width === 0 || area.width >= REVIEW_MARGIN_MIN_WIDTH ? "margin" : "compact";
544
- const openDraft = React3.useCallback(() => {
546
+ const openDraft = React4.useCallback(() => {
545
547
  const placement = editor?.getSelectionPlacement();
546
548
  if (!placement) return;
547
549
  review.setPaneOpen(true);
548
550
  setDraft({ anchorY: placement.anchorY });
549
551
  }, [editor, review.setPaneOpen]);
550
- React3.useEffect(() => registry?.register(), [registry]);
551
- React3.useEffect(() => registry?.registerCommentDraft(openDraft), [registry, openDraft]);
552
- const shownLayout = React3.useRef(null);
553
- React3.useEffect(() => {
552
+ React4.useEffect(() => registry?.register(), [registry]);
553
+ React4.useEffect(() => registry?.registerCommentDraft(openDraft), [registry, openDraft]);
554
+ const shownLayout = React4.useRef(null);
555
+ React4.useEffect(() => {
554
556
  if (!review.ready || area.width === 0 || shownLayout.current === layout) return;
555
557
  editor?.setReviewPaneOptions({ opening: layout === "margin" ? "auto" : "manual" });
556
558
  const deepLinked = shownLayout.current === null && review.activeKey !== null;
@@ -566,7 +568,7 @@ function DocxEditorReviewRail({
566
568
  const changes = review.items.filter((entry) => entry.kind === "revision").length;
567
569
  const comments = top.filter((entry) => entry.kind === "comment").length;
568
570
  const hasResolved = review.items.some((entry) => entry.kind === "comment" && entry.resolved);
569
- const repliesOf = React3.useCallback(
571
+ const repliesOf = React4.useCallback(
570
572
  (entry) => review.items.filter(
571
573
  (other) => other.kind === "comment" && (other.parentId === entry.id || other.parentRevisionId === entry.id)
572
574
  ),
@@ -574,19 +576,19 @@ function DocxEditorReviewRail({
574
576
  );
575
577
  const column = layout === "margin" && review.paneOpen && (top.length > 0 || draft !== null);
576
578
  const bubbleOpen = layout === "compact" && (review.paneOpen || draft !== null);
577
- React3.useEffect(() => {
579
+ React4.useEffect(() => {
578
580
  const element = area.element;
579
581
  if (!element) return;
580
582
  if (column) element.setAttribute("data-review-margin", "");
581
583
  else element.removeAttribute("data-review-margin");
582
584
  return () => element.removeAttribute("data-review-margin");
583
585
  }, [area.element, column]);
584
- const dismiss = React3.useCallback(() => {
586
+ const dismiss = React4.useCallback(() => {
585
587
  setDraft(null);
586
588
  if (layout === "compact") review.setPaneOpen(false);
587
589
  else review.setActive(null);
588
590
  }, [layout, review.setPaneOpen, review.setActive]);
589
- React3.useEffect(() => {
591
+ React4.useEffect(() => {
590
592
  const element = area.element;
591
593
  if (!element || !bubbleOpen) return;
592
594
  const close = (event) => {
@@ -611,7 +613,7 @@ function DocxEditorReviewRail({
611
613
  document2.removeEventListener("keydown", escape);
612
614
  };
613
615
  }, [area.element, bubbleOpen, dismiss]);
614
- React3.useLayoutEffect(() => {
616
+ React4.useLayoutEffect(() => {
615
617
  if (!column) return;
616
618
  const next = {};
617
619
  let floor = (toolbar.current?.offsetHeight ?? 0) + CARD_GAP;
@@ -910,18 +912,18 @@ function mentionCandidates(mentions) {
910
912
  function mentionedDocxRecipients(text, mentions) {
911
913
  return chunk7UTB4PHM_cjs.extractMentions(text, mentionCandidates(mentions)).map((person) => person.id);
912
914
  }
913
- var ActivityContext = React3.createContext({});
915
+ var ActivityContext = React4.createContext({});
914
916
  function DocxCommentActivity() {
915
917
  const item = useReviewItem();
916
918
  const review = useReview();
917
- const activity = React3.useContext(ActivityContext);
918
- const [reading, setReading] = React3.useState(false);
919
+ const activity = React4.useContext(ActivityContext);
920
+ const [reading, setReading] = React4.useState(false);
919
921
  if (!item || item.kind !== "comment") return null;
920
922
  const commentId = item.parentId || item.item.id;
921
923
  const thread = review.items.filter(
922
924
  (entry) => entry.kind === "comment" && (entry.item.id === commentId || entry.parentId === commentId)
923
925
  );
924
- const statuses = Object.entries(activity).filter(([, run]) => run.commentId === commentId);
926
+ const statuses = Object.entries(activity).filter(([, run2]) => run2.commentId === commentId);
925
927
  const labels = {
926
928
  delivering: "Delivering mention\u2026",
927
929
  queued: "Queued\u2026",
@@ -933,18 +935,18 @@ function DocxCommentActivity() {
933
935
  unknown: "Status unavailable"
934
936
  };
935
937
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "native-docx-comment-extra", "data-review-selectable": "", children: [
936
- statuses.map(([id, run]) => /* @__PURE__ */ jsxRuntime.jsxs(
938
+ statuses.map(([id, run2]) => /* @__PURE__ */ jsxRuntime.jsxs(
937
939
  "div",
938
940
  {
939
941
  role: "status",
940
942
  "data-testid": "docx-comment-agent-status",
941
- "data-status": run.status,
943
+ "data-status": run2.status,
942
944
  className: "native-docx-comment-activity",
943
945
  children: [
944
- ["delivering", "queued", "in_progress"].includes(run.status) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "native-docx-agent-spinner", "aria-hidden": "true" }),
945
- run.label,
946
+ ["delivering", "queued", "in_progress"].includes(run2.status) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "native-docx-agent-spinner", "aria-hidden": "true" }),
947
+ run2.label,
946
948
  ": ",
947
- labels[run.status]
949
+ labels[run2.status]
948
950
  ]
949
951
  },
950
952
  id
@@ -972,10 +974,10 @@ function DocxCommentActivity() {
972
974
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: entry.author || "Reviewer" }),
973
975
  /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "docx-full-comment-text", children: /* @__PURE__ */ jsxRuntime.jsx(ui.AiMarkdown, { allowHtml: false, children: commentText(entry) }) })
974
976
  ] }, entry.key)),
975
- statuses.map(([id, run]) => /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "text-sm", children: [
976
- run.label,
977
+ statuses.map(([id, run2]) => /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "text-sm", children: [
978
+ run2.label,
977
979
  ": ",
978
- labels[run.status]
980
+ labels[run2.status]
979
981
  ] }, id))
980
982
  ]
981
983
  }
@@ -991,10 +993,10 @@ function DocxMentions({
991
993
  notify
992
994
  }) {
993
995
  const review = useReview();
994
- const [activity, setActivity] = React3.useState({});
995
- const root = React3.useRef(null);
996
- const [composers, setComposers] = React3.useState([]);
997
- React3.useEffect(() => {
996
+ const [activity, setActivity] = React4.useState({});
997
+ const root = React4.useRef(null);
998
+ const [composers, setComposers] = React4.useState([]);
999
+ React4.useEffect(() => {
998
1000
  const element = root.current;
999
1001
  if (!element || !requestAgent) return;
1000
1002
  const discover = () => {
@@ -1020,15 +1022,15 @@ function DocxMentions({
1020
1022
  field.setSelectionRange(value.length, value.length);
1021
1023
  setSuggestions(null);
1022
1024
  };
1023
- const alive = React3.useRef(true);
1024
- React3.useEffect(() => {
1025
+ const alive = React4.useRef(true);
1026
+ React4.useEffect(() => {
1025
1027
  alive.current = true;
1026
1028
  return () => {
1027
1029
  alive.current = false;
1028
1030
  };
1029
1031
  }, []);
1030
- const activated = React3.useRef(void 0);
1031
- React3.useEffect(() => {
1032
+ const activated = React4.useRef(void 0);
1033
+ React4.useEffect(() => {
1032
1034
  if (!initialCommentId || activated.current === initialCommentId || !review.ready) return;
1033
1035
  const target = review.items.find(
1034
1036
  (item) => item.kind === "comment" && item.item.id === initialCommentId
@@ -1037,16 +1039,16 @@ function DocxMentions({
1037
1039
  review.setPaneOpen(true);
1038
1040
  if (review.setActive(target.key)) activated.current = initialCommentId;
1039
1041
  }, [initialCommentId, review]);
1040
- const input = React3.useRef(null);
1041
- const replyTarget = React3.useRef(null);
1042
- const pending = React3.useRef(null);
1043
- const [suggestions, setSuggestions] = React3.useState(null);
1044
- const [selected, setSelected] = React3.useState(0);
1042
+ const input = React4.useRef(null);
1043
+ const replyTarget = React4.useRef(null);
1044
+ const pending = React4.useRef(null);
1045
+ const [suggestions, setSuggestions] = React4.useState(null);
1046
+ const [selected, setSelected] = React4.useState(0);
1045
1047
  const candidates = chunk7UTB4PHM_cjs.filterMentionCandidates(
1046
1048
  mentionCandidates(mentions),
1047
1049
  suggestions?.query || ""
1048
1050
  ).slice(0, 8);
1049
- React3.useEffect(() => {
1051
+ React4.useEffect(() => {
1050
1052
  const submission = pending.current;
1051
1053
  if (!submission || !requestAgent) return;
1052
1054
  const created = review.items.find(
@@ -1287,26 +1289,36 @@ function DocxMentions({
1287
1289
  ) });
1288
1290
  }
1289
1291
  var DEFINED_TERM_STYLE = "DefinedTerm";
1290
- var FRAGMENT_STYLES = chunkAOFATOT3_cjs.stylesXml(
1292
+ var CROSS_REFERENCE_STYLE = "CrossReference";
1293
+ var BROKEN_CROSS_REFERENCE_STYLE = "CrossReferenceBroken";
1294
+ var CHARACTER_STYLES = {
1295
+ [DEFINED_TERM_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${DEFINED_TERM_STYLE}"><w:name w:val="Defined Term"/><w:rPr><w:u w:val="dotted" w:color="7F7F7F"/></w:rPr></w:style>`,
1296
+ [CROSS_REFERENCE_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${CROSS_REFERENCE_STYLE}"><w:name w:val="Cross Reference"/><w:rPr><w:color w:val="1F4E79"/><w:u w:val="dotted" w:color="8EA9C1"/></w:rPr></w:style>`,
1297
+ [BROKEN_CROSS_REFERENCE_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${BROKEN_CROSS_REFERENCE_STYLE}"><w:name w:val="Cross Reference Broken"/><w:basedOn w:val="${CROSS_REFERENCE_STYLE}"/><w:rPr><w:color w:val="C00000"/><w:u w:val="wave" w:color="C00000"/></w:rPr></w:style>`
1298
+ };
1299
+ function stylesUsed(body) {
1300
+ return [...new Set([...body.matchAll(/<w:rStyle w:val="([^"]+)"/g)].map((m) => m[1]))];
1301
+ }
1302
+ var fragmentStyles = (ids) => chunk2A4MDHJR_cjs.stylesXml(
1291
1303
  "",
1292
- `<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="character" w:customStyle="1" w:styleId="${DEFINED_TERM_STYLE}"><w:name w:val="Defined Term"/><w:rPr><w:u w:val="dotted" w:color="7F7F7F"/></w:rPr></w:style>`
1304
+ `<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style>${ids.map((id) => CHARACTER_STYLES[id] ?? "").join("")}`
1293
1305
  );
1294
- var textRun = (text, props = "") => `<w:r>${props ? `<w:rPr>${props}</w:rPr>` : ""}<w:t xml:space="preserve">${chunkAOFATOT3_cjs.esc(text)}</w:t></w:r>`;
1306
+ var textRun = (text, props = "") => `<w:r>${props ? `<w:rPr>${props}</w:rPr>` : ""}<w:t xml:space="preserve">${chunk2A4MDHJR_cjs.esc(text)}</w:t></w:r>`;
1295
1307
  function definitionTooltip(definition) {
1296
1308
  const line = `\u201C${definition.term}\u201D${definition.rest}`.replace(/\s+/g, " ").trim();
1297
1309
  return line.length > 255 ? `${line.slice(0, 254)}\u2026` : line;
1298
1310
  }
1299
1311
  function definitionParagraphXml(definition, bookmark, id = 0) {
1300
- return `<w:p><w:bookmarkStart w:id="${id}" w:name="${chunkAOFATOT3_cjs.esc(bookmark)}"/>${textRun("\u201C")}${textRun(
1312
+ return `<w:p><w:bookmarkStart w:id="${id}" w:name="${chunk2A4MDHJR_cjs.esc(bookmark)}"/>${textRun("\u201C")}${textRun(
1301
1313
  definition.term,
1302
1314
  "<w:b/>"
1303
1315
  )}${textRun("\u201D")}<w:bookmarkEnd w:id="${id}"/>${textRun(definition.rest)}</w:p>`;
1304
1316
  }
1305
1317
  function headingParagraphXml(text, styleId) {
1306
- return styleId ? `<w:p><w:pPr><w:pStyle w:val="${chunkAOFATOT3_cjs.esc(styleId)}"/></w:pPr>${textRun(text)}</w:p>` : `<w:p><w:pPr><w:keepNext/></w:pPr>${textRun(text, "<w:b/>")}</w:p>`;
1318
+ return styleId ? `<w:p><w:pPr><w:pStyle w:val="${chunk2A4MDHJR_cjs.esc(styleId)}"/></w:pPr>${textRun(text)}</w:p>` : `<w:p><w:pPr><w:keepNext/></w:pPr>${textRun(text, "<w:b/>")}</w:p>`;
1307
1319
  }
1308
1320
  function termLinkXml(term, bookmark, tooltip) {
1309
- return `<w:p><w:hyperlink w:anchor="${chunkAOFATOT3_cjs.esc(bookmark)}" w:tooltip="${chunkAOFATOT3_cjs.esc(tooltip)}" w:history="1">${textRun(
1321
+ return `<w:p><w:hyperlink w:anchor="${chunk2A4MDHJR_cjs.esc(bookmark)}" w:tooltip="${chunk2A4MDHJR_cjs.esc(tooltip)}" w:history="1">${textRun(
1310
1322
  term,
1311
1323
  `<w:rStyle w:val="${DEFINED_TERM_STYLE}"/>`
1312
1324
  )}</w:hyperlink></w:p>`;
@@ -1317,11 +1329,16 @@ function base64(bytes) {
1317
1329
  binary += String.fromCharCode(...bytes.subarray(i, i + 32768));
1318
1330
  return btoa(binary);
1319
1331
  }
1320
- function fragmentHtml(body, covered2, revision) {
1321
- const untracked = chunkAOFATOT3_cjs.docxPackage({
1322
- document: chunkAOFATOT3_cjs.documentXml(body),
1323
- styles: FRAGMENT_STYLES,
1324
- title: "Defined terms"
1332
+ function fragmentHtml(body, covered2, {
1333
+ revision,
1334
+ relationships,
1335
+ styles = stylesUsed(body)
1336
+ } = {}) {
1337
+ const untracked = chunk2A4MDHJR_cjs.docxPackage({
1338
+ document: chunk2A4MDHJR_cjs.documentXml(body),
1339
+ styles: fragmentStyles(styles),
1340
+ title: "Defined terms",
1341
+ relationships
1325
1342
  });
1326
1343
  const bytes = revision ? template.trackInsertion(untracked, revision, covered2) : untracked;
1327
1344
  return `<div data-docx-fragment="${base64(bytes)}" data-docx-fragment-end="${covered2 ? "covered" : "open"}"></div>`;
@@ -1343,14 +1360,14 @@ function findDefinitionsSection(paragraphs) {
1343
1360
  while (end < paragraphs.length && paragraphs[end].topLevel && !paragraphs[end].heading) end++;
1344
1361
  return { title, start: title + 1, end };
1345
1362
  }
1346
- var termOf = (paragraph) => chunkAOFATOT3_cjs.parseDefinition(paragraph.text)?.term ?? null;
1363
+ var termOf = (paragraph) => chunk2A4MDHJR_cjs.parseDefinition(paragraph.text)?.term ?? null;
1347
1364
  function insertionIndex(paragraphs, section, term, skip = /* @__PURE__ */ new Set()) {
1348
1365
  let afterLast = section.start;
1349
1366
  for (let i = section.start; i < section.end; i++) {
1350
1367
  if (skip.has(paragraphs[i].id)) continue;
1351
1368
  const other = termOf(paragraphs[i]);
1352
1369
  if (other === null) continue;
1353
- if (chunkAOFATOT3_cjs.compareTerms(other, term) > 0) return i;
1370
+ if (chunk2A4MDHJR_cjs.compareTerms(other, term) > 0) return i;
1354
1371
  afterLast = i + 1;
1355
1372
  }
1356
1373
  return afterLast;
@@ -1377,7 +1394,7 @@ function insertParagraphs(port, index, body, count, keep) {
1377
1394
  function addDefinition(port, definition, keep) {
1378
1395
  const paragraphs = port.paragraphs();
1379
1396
  const section = findDefinitionsSection(paragraphs);
1380
- const paragraph = definitionParagraphXml(definition, chunkAOFATOT3_cjs.definitionBookmark(definition.id));
1397
+ const paragraph = definitionParagraphXml(definition, chunk2A4MDHJR_cjs.definitionBookmark(definition.id));
1381
1398
  if (section)
1382
1399
  return insertParagraphs(
1383
1400
  port,
@@ -1403,7 +1420,7 @@ function insertDefinedTerm(port, definition, options = {}) {
1403
1420
  caret = { paragraphId: start.paragraphId, offset: Math.max(0, start.offset - options.replace) };
1404
1421
  port.deleteRange(caret, start);
1405
1422
  }
1406
- const bookmark = chunkAOFATOT3_cjs.definitionBookmark(definition.id);
1423
+ const bookmark = chunk2A4MDHJR_cjs.definitionBookmark(definition.id);
1407
1424
  const addedDefinition = !hasBookmark(port.paragraphs(), bookmark);
1408
1425
  if (addedDefinition) caret = addDefinition(port, definition, caret) ?? caret;
1409
1426
  port.setCaret(caret);
@@ -1417,12 +1434,96 @@ function insertDefinedTerm(port, definition, options = {}) {
1417
1434
  return { addedDefinition };
1418
1435
  }
1419
1436
  function definitionOfAnchor(anchor, definitions) {
1420
- const id = chunkAOFATOT3_cjs.definitionIdOfBookmark(anchor.replace(/^#/, ""));
1437
+ const id = chunk2A4MDHJR_cjs.definitionIdOfBookmark(anchor.replace(/^#/, ""));
1421
1438
  return id ? definitions.get(id) : void 0;
1422
1439
  }
1440
+ function LinkHoverCard({
1441
+ root,
1442
+ matches,
1443
+ resolve,
1444
+ onFirstHover,
1445
+ testId
1446
+ }) {
1447
+ const [card, setCard] = React4.useState(null);
1448
+ const hovered = React4.useRef(false);
1449
+ const latest = React4.useRef({ matches, onFirstHover });
1450
+ latest.current = { matches, onFirstHover };
1451
+ React4.useEffect(() => {
1452
+ if (!root) return;
1453
+ const over = (event) => {
1454
+ const link = event.target?.closest?.(
1455
+ "a.docx-hyperlink"
1456
+ );
1457
+ const href = link?.getAttribute("href") ?? "";
1458
+ if (!link || !href || !latest.current.matches(href, link)) return;
1459
+ if (!hovered.current) {
1460
+ hovered.current = true;
1461
+ latest.current.onFirstHover?.();
1462
+ }
1463
+ const title = link.getAttribute("title");
1464
+ if (title) {
1465
+ link.dataset.hoverTitle = title;
1466
+ link.removeAttribute("title");
1467
+ }
1468
+ const rect = link.getBoundingClientRect();
1469
+ setCard({
1470
+ left: rect.left,
1471
+ top: rect.bottom + 6,
1472
+ href,
1473
+ fallback: link.dataset.hoverTitle ?? ""
1474
+ });
1475
+ };
1476
+ const out = (event) => {
1477
+ const link = event.target?.closest?.("a.docx-hyperlink");
1478
+ if (link && !link.contains(event.relatedTarget)) setCard(null);
1479
+ };
1480
+ const hide = () => setCard(null);
1481
+ root.addEventListener("mouseover", over);
1482
+ root.addEventListener("mouseout", out);
1483
+ window.addEventListener("keydown", hide, true);
1484
+ window.addEventListener("pointerdown", hide, true);
1485
+ window.addEventListener("scroll", hide, true);
1486
+ return () => {
1487
+ root.removeEventListener("mouseover", over);
1488
+ root.removeEventListener("mouseout", out);
1489
+ window.removeEventListener("keydown", hide, true);
1490
+ window.removeEventListener("pointerdown", hide, true);
1491
+ window.removeEventListener("scroll", hide, true);
1492
+ };
1493
+ }, [root]);
1494
+ if (!card) return null;
1495
+ const content = resolve(card.href);
1496
+ if (!content && !card.fallback) return null;
1497
+ return reactDom.createPortal(
1498
+ /* @__PURE__ */ jsxRuntime.jsx(
1499
+ "div",
1500
+ {
1501
+ role: "tooltip",
1502
+ className: "native-docx-link-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
1503
+ style: {
1504
+ position: "fixed",
1505
+ left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
1506
+ top: card.top,
1507
+ width: 340,
1508
+ zIndex: 1e3,
1509
+ pointerEvents: "none"
1510
+ },
1511
+ "data-testid": testId,
1512
+ children: content ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1513
+ content.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: content.title }),
1514
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: content.title ? "mt-1 text-muted-foreground" : void 0, children: content.body }),
1515
+ content.footer && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: content.footer })
1516
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: card.fallback })
1517
+ }
1518
+ ),
1519
+ document.body
1520
+ );
1521
+ }
1423
1522
 
1424
1523
  // src/docx/definitions/port.ts
1524
+ var WATCHED_STYLES = /* @__PURE__ */ new Set([BROKEN_CROSS_REFERENCE_STYLE]);
1425
1525
  var attr = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
1526
+ var FIELD_ATOM = "\uFFFC";
1426
1527
  var HEADING_STYLE = /^(heading|berschrift|titre|t[ií]tulo|titolo|kop)\s*\d/i;
1427
1528
  function readParagraphs(root) {
1428
1529
  const out = [];
@@ -1449,8 +1550,44 @@ function readParagraph(node, topLevel, bookmarks) {
1449
1550
  const links = [];
1450
1551
  let styleId;
1451
1552
  let outline = false;
1553
+ let fieldDepth = 0;
1554
+ const marks = [];
1555
+ let runStyle;
1556
+ const fields = [];
1557
+ let current = null;
1558
+ const field = (c) => {
1559
+ const type = attr(c, "fldCharType");
1560
+ if (type === "begin") {
1561
+ if (fieldDepth === 0) {
1562
+ current = { offset: text.length, instruction: "", result: "", inResult: false };
1563
+ text += FIELD_ATOM;
1564
+ }
1565
+ fieldDepth++;
1566
+ } else if (type === "separate" && fieldDepth === 1 && current) current.inResult = true;
1567
+ else if (type === "end") {
1568
+ fieldDepth = Math.max(0, fieldDepth - 1);
1569
+ if (fieldDepth === 0 && current) {
1570
+ const { offset, instruction, result } = current;
1571
+ fields.push({ offset, instruction: instruction.trim(), result });
1572
+ current = null;
1573
+ }
1574
+ }
1575
+ };
1452
1576
  const walk = (n, link) => {
1453
1577
  for (const c of n.children ?? []) {
1578
+ if (c.localName === "fldChar") {
1579
+ field(c);
1580
+ continue;
1581
+ }
1582
+ if (c.localName === "fldSimple") {
1583
+ if (fieldDepth === 0) text += FIELD_ATOM;
1584
+ continue;
1585
+ }
1586
+ if (c.localName === "instrText") {
1587
+ if (fieldDepth === 1 && current)
1588
+ current.instruction += (c.children ?? []).map((t) => t.value ?? "").join("");
1589
+ continue;
1590
+ }
1454
1591
  if (c.kind === "paragraphProperties" || c.localName === "pPr") {
1455
1592
  for (const p of c.children ?? []) {
1456
1593
  if (p.localName === "pStyle") styleId = attr(p, "val");
@@ -1459,6 +1596,14 @@ function readParagraph(node, topLevel, bookmarks) {
1459
1596
  continue;
1460
1597
  }
1461
1598
  if (c.localName === "delText" || c.localName === "del" || c.localName === "rPr") continue;
1599
+ if (c.localName === "r") {
1600
+ const rStyle = c.children?.find((x) => x.localName === "rPr")?.children?.find((x) => x.localName === "rStyle");
1601
+ const watched = rStyle && attr(rStyle, "val");
1602
+ runStyle = watched && WATCHED_STYLES.has(watched) ? watched : void 0;
1603
+ walk(c, link);
1604
+ runStyle = void 0;
1605
+ continue;
1606
+ }
1462
1607
  if (c.localName === "bookmarkStart") {
1463
1608
  const name = attr(c, "name");
1464
1609
  if (name) bookmarks.push(name);
@@ -1472,11 +1617,22 @@ function readParagraph(node, topLevel, bookmarks) {
1472
1617
  continue;
1473
1618
  }
1474
1619
  if (c.kind === "textValue") {
1620
+ if (fieldDepth > 0) {
1621
+ const open = current;
1622
+ if (fieldDepth === 1 && open?.inResult) open.result += c.value ?? "";
1623
+ continue;
1624
+ }
1625
+ if (runStyle && c.value) {
1626
+ const last = marks[marks.length - 1];
1627
+ if (last && last.styleId === runStyle && last.offset + last.text.length === text.length)
1628
+ last.text += c.value;
1629
+ else marks.push({ styleId: runStyle, offset: text.length, text: c.value });
1630
+ }
1475
1631
  text += c.value ?? "";
1476
1632
  if (link) link.text += c.value ?? "";
1477
1633
  continue;
1478
1634
  }
1479
- if (c.localName === "tab") text += " ";
1635
+ if (c.localName === "tab" && fieldDepth === 0) text += " ";
1480
1636
  walk(c, link);
1481
1637
  }
1482
1638
  };
@@ -1488,9 +1644,20 @@ function readParagraph(node, topLevel, bookmarks) {
1488
1644
  styleId,
1489
1645
  topLevel,
1490
1646
  bookmarks,
1491
- links
1647
+ links,
1648
+ ...fields.length ? { fields } : {},
1649
+ ...marks.length ? { marks } : {}
1492
1650
  };
1493
1651
  }
1652
+ function documentStyleIds(root) {
1653
+ const ids = /* @__PURE__ */ new Set();
1654
+ for (const style of root?.children ?? [])
1655
+ if (style.localName === "style") {
1656
+ const id = attr(style, "styleId");
1657
+ if (id) ids.add(id);
1658
+ }
1659
+ return ids;
1660
+ }
1494
1661
  function editorPort(editor, revision) {
1495
1662
  const surface = () => {
1496
1663
  const s = editor.surface;
@@ -1510,8 +1677,17 @@ function editorPort(editor, revision) {
1510
1677
  surface().setSelection({ anchor: from, head: to });
1511
1678
  surface().deleteSelection();
1512
1679
  },
1513
- paste: (body, text, covered2) => editor.exec({ type: "paste", text, html: fragmentHtml(body, covered2, revision) }).ok,
1514
- splitParagraph: () => surface().splitParagraph()
1680
+ paste: (body, text, covered2, relationships) => {
1681
+ const defined = documentStyleIds(surface().session.stylesRoot());
1682
+ const styles = stylesUsed(body).filter((id) => !defined.has(id));
1683
+ return editor.exec({
1684
+ type: "paste",
1685
+ text,
1686
+ html: fragmentHtml(body, covered2, { revision, relationships, styles })
1687
+ }).ok;
1688
+ },
1689
+ splitParagraph: () => surface().splitParagraph(),
1690
+ typeText: (text) => surface().insertPlainText(text)
1515
1691
  };
1516
1692
  }
1517
1693
  function withDirectEditing(editor, fn) {
@@ -1524,34 +1700,68 @@ function withDirectEditing(editor, fn) {
1524
1700
  if (mode === "suggesting") editor.setEditingMode("suggesting");
1525
1701
  }
1526
1702
  }
1527
- function holdCaret(editor, timeoutMs = 5e3) {
1703
+ function holdCaret(editor, { settleMs = 600, maxMs = 2e3 } = {}) {
1528
1704
  const surface = editor.surface;
1529
1705
  const selection = surface?.state().selection;
1530
1706
  if (!surface || !selection) return;
1531
- const { paragraphId, offset } = selection.head;
1532
- const paraId = surface.session.paraIdOf(paragraphId);
1707
+ const { offset } = selection.head;
1708
+ const paraId = surface.session.paraIdOf(selection.head.paragraphId);
1533
1709
  if (!paraId) return;
1710
+ let typed = "";
1534
1711
  let done = false;
1712
+ let settle;
1535
1713
  const stop = () => {
1536
1714
  done = true;
1537
1715
  offChange();
1538
- offSelection();
1539
- clearTimeout(timer);
1716
+ clearTimeout(settle);
1717
+ clearTimeout(limit);
1718
+ window.removeEventListener("keydown", key, true);
1719
+ window.removeEventListener("pointerdown", click, true);
1540
1720
  };
1541
- const restore = () => {
1721
+ const finish = () => {
1542
1722
  if (done) return;
1543
- const now = surface.state().selection;
1544
- const node = surface.session.nodeIdOf(paraId);
1545
- if (!now || !node) return;
1546
- if (now.head.offset !== offset || now.head.paragraphId !== paragraphId) return stop();
1547
- if (node === paragraphId) return;
1548
1723
  stop();
1724
+ const node = surface.session.nodeIdOf(paraId);
1725
+ if (!node) return;
1549
1726
  const point = { paragraphId: node, offset };
1550
1727
  surface.setSelection({ anchor: point, head: point });
1728
+ if (typed) surface.insertPlainText(typed);
1729
+ };
1730
+ const key = (event) => {
1731
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
1732
+ event.preventDefault();
1733
+ event.stopPropagation();
1734
+ typed += event.key;
1735
+ return;
1736
+ }
1737
+ finish();
1738
+ };
1739
+ const click = () => {
1740
+ if (typed) finish();
1741
+ else stop();
1742
+ };
1743
+ const quiet = () => {
1744
+ clearTimeout(settle);
1745
+ settle = setTimeout(finish, settleMs);
1551
1746
  };
1552
- const offChange = editor.on("change", restore);
1553
- const offSelection = editor.on("selectionChange", restore);
1554
- const timer = setTimeout(stop, timeoutMs);
1747
+ const offChange = editor.on("change", quiet);
1748
+ window.addEventListener("keydown", key, true);
1749
+ window.addEventListener("pointerdown", click, true);
1750
+ settle = setTimeout(finish, settleMs);
1751
+ const limit = setTimeout(finish, maxMs);
1752
+ }
1753
+ function preservingCaret(editor, fn) {
1754
+ const surface = editor.surface;
1755
+ const before = surface?.state().selection?.head;
1756
+ const paraId = before && surface?.session.paraIdOf(before.paragraphId);
1757
+ const result = fn();
1758
+ const node = paraId && surface?.session.nodeIdOf(paraId);
1759
+ if (before && node) {
1760
+ const point = { paragraphId: node, offset: before.offset };
1761
+ surface.setSelection({ anchor: point, head: point });
1762
+ holdCaret(editor);
1763
+ }
1764
+ return result;
1555
1765
  }
1556
1766
 
1557
1767
  // src/docx/structural/trackedOrNoted.ts
@@ -1608,11 +1818,11 @@ function structuralPort(editor) {
1608
1818
  }
1609
1819
  };
1610
1820
  }
1611
- var DocxAuthorContext = React3.createContext("You");
1821
+ var DocxAuthorContext = React4.createContext("You");
1612
1822
  function useTrackedOrNoted() {
1613
1823
  const editor = react.useDocxEditor();
1614
- const author = React3.useContext(DocxAuthorContext);
1615
- return React3.useCallback(
1824
+ const author = React4.useContext(DocxAuthorContext);
1825
+ return React4.useCallback(
1616
1826
  (spec) => editor ? trackedOrNoted(structuralPort(editor), { ...spec, author }) : void 0,
1617
1827
  [editor, author]
1618
1828
  );
@@ -1632,8 +1842,8 @@ var DEFAULT_DEFINED_TERMS_LABELS = {
1632
1842
  preferred: "Preferred",
1633
1843
  alsoIn: (source) => `Also defined${source ? ` in ${source}` : ""}`
1634
1844
  };
1635
- var DefinedTermsContext = React3.createContext(null);
1636
- var useDefinedTerms = () => React3.useContext(DefinedTermsContext);
1845
+ var DefinedTermsContext = React4.createContext(null);
1846
+ var useDefinedTerms = () => React4.useContext(DefinedTermsContext);
1637
1847
  function rowsOf(groups) {
1638
1848
  return groups.flatMap(
1639
1849
  (group) => group.definitions.map((definition, i) => ({ group, definition, variant: i > 0 }))
@@ -1649,16 +1859,16 @@ function DefinedTermsProvider({
1649
1859
  }) {
1650
1860
  const editor = react.useDocxEditor();
1651
1861
  const track = useTrackedOrNoted();
1652
- const l = React3.useMemo(() => ({ ...DEFAULT_DEFINED_TERMS_LABELS, ...labels }), [labels]);
1653
- const [sources, setSources] = React3.useState(null);
1654
- const loadedAt = React3.useRef(0);
1655
- const loading = React3.useRef(null);
1656
- const [labelId, setLabelId] = React3.useState(null);
1657
- const [picker, setPicker] = React3.useState(null);
1658
- const [selected, setSelected] = React3.useState(0);
1659
- const marker = React3.useRef(null);
1660
- const dismissedAt = React3.useRef(null);
1661
- const refresh = React3.useCallback(
1862
+ const l = React4.useMemo(() => ({ ...DEFAULT_DEFINED_TERMS_LABELS, ...labels }), [labels]);
1863
+ const [sources, setSources] = React4.useState(null);
1864
+ const loadedAt = React4.useRef(0);
1865
+ const loading = React4.useRef(null);
1866
+ const [labelId, setLabelId] = React4.useState(null);
1867
+ const [picker, setPicker] = React4.useState(null);
1868
+ const [selected, setSelected] = React4.useState(0);
1869
+ const marker = React4.useRef(null);
1870
+ const dismissedAt = React4.useRef(null);
1871
+ const refresh = React4.useCallback(
1662
1872
  (force = false) => {
1663
1873
  if (!load) return Promise.resolve([]);
1664
1874
  if (!force && sources && Date.now() - loadedAt.current < STALE_AFTER_MS)
@@ -1682,29 +1892,29 @@ function DefinedTermsProvider({
1682
1892
  },
1683
1893
  [load, sources, notify]
1684
1894
  );
1685
- const all = React3.useMemo(() => chunkAOFATOT3_cjs.groupDefinitions(sources ?? []).groups, [sources]);
1686
- const byId = React3.useMemo(
1895
+ const all = React4.useMemo(() => chunk2A4MDHJR_cjs.groupDefinitions(sources ?? []).groups, [sources]);
1896
+ const byId = React4.useMemo(
1687
1897
  () => new Map(all.flatMap((g) => g.definitions).map((d) => [d.id, d])),
1688
1898
  [all]
1689
1899
  );
1690
- const agreements = React3.useMemo(() => chunkAOFATOT3_cjs.definitionLabels(sources ?? []), [sources]);
1691
- const groups = React3.useMemo(
1692
- () => picker ? chunkAOFATOT3_cjs.filterTermGroups(chunkAOFATOT3_cjs.groupDefinitions(sources ?? [], { labelId }).groups, picker.query).slice(
1900
+ const agreements = React4.useMemo(() => chunk2A4MDHJR_cjs.definitionLabels(sources ?? []), [sources]);
1901
+ const groups = React4.useMemo(
1902
+ () => picker ? chunk2A4MDHJR_cjs.filterTermGroups(chunk2A4MDHJR_cjs.groupDefinitions(sources ?? [], { labelId }).groups, picker.query).slice(
1693
1903
  0,
1694
1904
  MAX_GROUPS
1695
1905
  ) : [],
1696
1906
  [sources, labelId, picker]
1697
1907
  );
1698
- const rows = React3.useMemo(() => rowsOf(groups), [groups]);
1699
- React3.useEffect(() => setSelected(0), [picker?.query, labelId]);
1908
+ const rows = React4.useMemo(() => rowsOf(groups), [groups]);
1909
+ React4.useEffect(() => setSelected(0), [picker?.query, labelId]);
1700
1910
  const container = () => marker.current?.closest(".native-docx-viewer") ?? document.body;
1701
- const [viewer, setViewer] = React3.useState(null);
1702
- React3.useEffect(() => setViewer(container()), []);
1703
- const refreshRef = React3.useRef(refresh);
1911
+ const [viewer, setViewer] = React4.useState(null);
1912
+ React4.useEffect(() => setViewer(container()), []);
1913
+ const refreshRef = React4.useRef(refresh);
1704
1914
  refreshRef.current = refresh;
1705
- const firstHover = React3.useCallback(() => void refreshRef.current(), []);
1915
+ const firstHover = React4.useCallback(() => void refreshRef.current(), []);
1706
1916
  const caretRect = () => container().querySelector(".docx-editor-one-surface__caret")?.getBoundingClientRect();
1707
- const attempt = React3.useCallback(
1917
+ const attempt = React4.useCallback(
1708
1918
  (fn) => {
1709
1919
  try {
1710
1920
  return fn();
@@ -1715,19 +1925,26 @@ function DefinedTermsProvider({
1715
1925
  },
1716
1926
  [notify]
1717
1927
  );
1718
- const run = React3.useCallback(
1928
+ const run2 = React4.useCallback(
1719
1929
  (fn) => editor ? attempt(() => withDirectEditing(editor, fn)) : void 0,
1720
1930
  [editor, attempt]
1721
1931
  );
1722
- const pick = React3.useCallback(
1932
+ const typedTrigger = (port) => {
1933
+ if (picker?.mode !== "typing") return 0;
1934
+ const caret = port.caret();
1935
+ const paragraph = caret && port.paragraphs().find((p) => p.id === caret.paragraphId);
1936
+ const match = paragraph && TRIGGER_QUERY.exec(paragraph.text.slice(0, caret.offset));
1937
+ return match ? DEFINED_TERM_TRIGGER.length + match[1].length : 0;
1938
+ };
1939
+ const pick = React4.useCallback(
1723
1940
  (row) => {
1724
1941
  if (!editor || !picker || !row) return;
1725
1942
  const port = editorPort(editor);
1726
- const placed = run(() => {
1943
+ const placed = run2(() => {
1727
1944
  if (picker.mode === "search" && picker.caret) port.setCaret(picker.caret);
1728
1945
  const caret = port.caret();
1729
1946
  if (!caret) throw new Error("Place the cursor where the term should go.");
1730
- const typed = picker.mode === "typing" ? DEFINED_TERM_TRIGGER.length + picker.query.length : 0;
1947
+ const typed = typedTrigger(port);
1731
1948
  if (typed) port.deleteRange({ ...caret, offset: Math.max(0, caret.offset - typed) }, caret);
1732
1949
  return true;
1733
1950
  });
@@ -1743,9 +1960,9 @@ function DefinedTermsProvider({
1743
1960
  if (result?.addedDefinition)
1744
1961
  notify?.(`\u201C${row.definition.term}\u201D added to the Definitions section.`, "success");
1745
1962
  },
1746
- [editor, picker, run, attempt, track, notify]
1963
+ [editor, picker, run2, attempt, track, notify]
1747
1964
  );
1748
- const openPicker = React3.useCallback(
1965
+ const openPicker = React4.useCallback(
1749
1966
  (anchor) => {
1750
1967
  if (!editor || !editable) return;
1751
1968
  const caret = editorPort(editor).caret();
@@ -1762,7 +1979,7 @@ function DefinedTermsProvider({
1762
1979
  // eslint-disable-next-line react-hooks/exhaustive-deps
1763
1980
  [editor, editable, refresh]
1764
1981
  );
1765
- React3.useEffect(() => {
1982
+ React4.useEffect(() => {
1766
1983
  if (!editor || !editable || !load) return;
1767
1984
  let frame = 0;
1768
1985
  const check = () => {
@@ -1797,7 +2014,7 @@ function DefinedTermsProvider({
1797
2014
  offSelection();
1798
2015
  };
1799
2016
  }, [editor, editable, load, refresh]);
1800
- React3.useEffect(() => {
2017
+ React4.useEffect(() => {
1801
2018
  if (picker?.mode !== "typing") return;
1802
2019
  const keys = (event) => {
1803
2020
  if (event.key === "Escape") {
@@ -1814,7 +2031,7 @@ function DefinedTermsProvider({
1814
2031
  window.addEventListener("keydown", keys, true);
1815
2032
  return () => window.removeEventListener("keydown", keys, true);
1816
2033
  }, [picker, rows, selected, pick]);
1817
- const value = React3.useMemo(
2034
+ const value = React4.useMemo(
1818
2035
  () => load && editable ? { openPicker, labels: l } : null,
1819
2036
  [load, editable, openPicker, l]
1820
2037
  );
@@ -1822,11 +2039,16 @@ function DefinedTermsProvider({
1822
2039
  /* @__PURE__ */ jsxRuntime.jsx("span", { ref: marker, hidden: true }),
1823
2040
  children,
1824
2041
  load && /* @__PURE__ */ jsxRuntime.jsx(
1825
- DefinedTermHover,
2042
+ LinkHoverCard,
1826
2043
  {
1827
2044
  root: viewer,
1828
- resolve: (anchor) => definitionOfAnchor(anchor, byId),
1829
- onFirstHover: firstHover
2045
+ matches: (href) => href.startsWith("#_dt_"),
2046
+ resolve: (href) => {
2047
+ const definition = definitionOfAnchor(href, byId);
2048
+ return definition ? { title: definition.term, body: definition.meaning, footer: sourceOf(definition) } : null;
2049
+ },
2050
+ onFirstHover: firstHover,
2051
+ testId: "docx-defined-term-card"
1830
2052
  }
1831
2053
  ),
1832
2054
  picker && reactDom.createPortal(
@@ -1868,17 +2090,17 @@ function DefinedTermMenu({
1868
2090
  onClose,
1869
2091
  labels: l
1870
2092
  }) {
1871
- const listboxId = React3__default.default.useId();
1872
- const element = React3.useRef(null);
2093
+ const listboxId = React4__default.default.useId();
2094
+ const element = React4.useRef(null);
1873
2095
  const search = picker.mode === "search";
1874
- React3.useEffect(() => {
2096
+ React4.useEffect(() => {
1875
2097
  const dismiss = (event) => {
1876
2098
  if (!element.current?.contains(event.target)) onClose();
1877
2099
  };
1878
2100
  document.addEventListener("pointerdown", dismiss);
1879
2101
  return () => document.removeEventListener("pointerdown", dismiss);
1880
2102
  }, [onClose]);
1881
- React3.useEffect(() => {
2103
+ React4.useEffect(() => {
1882
2104
  element.current?.querySelector(`[data-index="${selected}"]`)?.scrollIntoView?.({ block: "nearest" });
1883
2105
  }, [selected]);
1884
2106
  const left = Math.max(8, Math.min(picker.left, window.innerWidth - 368));
@@ -1979,83 +2201,6 @@ function DefinedTermMenu({
1979
2201
  }
1980
2202
  );
1981
2203
  }
1982
- function DefinedTermHover({
1983
- root,
1984
- resolve,
1985
- onFirstHover
1986
- }) {
1987
- const [card, setCard] = React3.useState(null);
1988
- const hovered = React3.useRef(false);
1989
- React3.useEffect(() => {
1990
- if (!root) return;
1991
- const over = (event) => {
1992
- const link = event.target?.closest?.(
1993
- 'a.docx-hyperlink[data-docx-link-kind="internal"]'
1994
- );
1995
- const href = link?.getAttribute("href") ?? "";
1996
- if (!link || !href.startsWith("#_dt_")) return;
1997
- if (!hovered.current) {
1998
- hovered.current = true;
1999
- onFirstHover();
2000
- }
2001
- const title = link.getAttribute("title");
2002
- if (title) {
2003
- link.dataset.definition = title;
2004
- link.removeAttribute("title");
2005
- }
2006
- const rect = link.getBoundingClientRect();
2007
- setCard({
2008
- left: rect.left,
2009
- top: rect.bottom + 6,
2010
- anchor: href.slice(1),
2011
- fallback: link.dataset.definition ?? ""
2012
- });
2013
- };
2014
- const out = (event) => {
2015
- const link = event.target?.closest?.("a.docx-hyperlink");
2016
- if (link && !link.contains(event.relatedTarget)) setCard(null);
2017
- };
2018
- root.addEventListener("mouseover", over);
2019
- root.addEventListener("mouseout", out);
2020
- const hide = () => setCard(null);
2021
- window.addEventListener("keydown", hide, true);
2022
- window.addEventListener("pointerdown", hide, true);
2023
- window.addEventListener("scroll", hide, true);
2024
- return () => {
2025
- root.removeEventListener("mouseover", over);
2026
- root.removeEventListener("mouseout", out);
2027
- window.removeEventListener("keydown", hide, true);
2028
- window.removeEventListener("pointerdown", hide, true);
2029
- window.removeEventListener("scroll", hide, true);
2030
- };
2031
- }, [root, onFirstHover]);
2032
- if (!card) return null;
2033
- const definition = resolve(card.anchor);
2034
- return reactDom.createPortal(
2035
- /* @__PURE__ */ jsxRuntime.jsx(
2036
- "div",
2037
- {
2038
- role: "tooltip",
2039
- className: "native-docx-term-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
2040
- style: {
2041
- position: "fixed",
2042
- left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
2043
- top: card.top,
2044
- width: 340,
2045
- zIndex: 1e3,
2046
- pointerEvents: "none"
2047
- },
2048
- "data-testid": "docx-defined-term-card",
2049
- children: definition ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2050
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: definition.term }),
2051
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-muted-foreground", children: definition.meaning }),
2052
- sourceOf(definition) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: sourceOf(definition) })
2053
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: card.fallback })
2054
- }
2055
- ),
2056
- document.body
2057
- );
2058
- }
2059
2204
  var BUILTIN_TEMPLATE_NAME = "ARBI legal template";
2060
2205
  var templateFileName = (t) => /\.(dotx|dotm|docx|docm)$/i.test(t.name) ? t.name : `${t.name}.dotx`;
2061
2206
  var builtin;
@@ -2071,8 +2216,8 @@ async function resolveHouseTemplate(host) {
2071
2216
  return builtinHouseTemplate();
2072
2217
  }
2073
2218
  }
2074
- var HouseTemplateContext = React3.createContext(null);
2075
- var useHouseTemplate = () => React3.useContext(HouseTemplateContext);
2219
+ var HouseTemplateContext = React4.createContext(null);
2220
+ var useHouseTemplate = () => React4.useContext(HouseTemplateContext);
2076
2221
  function HouseTemplateProvider({
2077
2222
  host,
2078
2223
  documentId,
@@ -2083,26 +2228,26 @@ function HouseTemplateProvider({
2083
2228
  }) {
2084
2229
  const editor = react.useDocxEditor();
2085
2230
  const track = useTrackedOrNoted();
2086
- const [template$1, setTemplate] = React3.useState(builtinHouseTemplate);
2087
- const [divergence, setDivergence] = React3.useState(null);
2088
- const [basedOnTemplate, setBasedOnTemplate] = React3.useState(false);
2089
- const [levels, setLevels] = React3.useState({});
2090
- const [generation, setGeneration] = React3.useState(0);
2091
- React3.useEffect(() => {
2231
+ const [template$1, setTemplate] = React4.useState(builtinHouseTemplate);
2232
+ const [divergence, setDivergence] = React4.useState(null);
2233
+ const [basedOnTemplate, setBasedOnTemplate] = React4.useState(false);
2234
+ const [levels, setLevels] = React4.useState({});
2235
+ const [generation, setGeneration] = React4.useState(0);
2236
+ React4.useEffect(() => {
2092
2237
  let live = true;
2093
2238
  void resolveHouseTemplate(host).then((t) => live && setTemplate(t));
2094
2239
  return () => {
2095
2240
  live = false;
2096
2241
  };
2097
2242
  }, [host]);
2098
- const blocks = React3.useMemo(() => {
2243
+ const blocks = React4.useMemo(() => {
2099
2244
  try {
2100
2245
  return template.listBuildingBlocks(template$1.bytes);
2101
2246
  } catch {
2102
2247
  return [];
2103
2248
  }
2104
2249
  }, [template$1]);
2105
- React3.useEffect(() => {
2250
+ React4.useEffect(() => {
2106
2251
  if (!editor || !enabled) return;
2107
2252
  let live = true;
2108
2253
  void editor.save().then((saved) => {
@@ -2116,8 +2261,8 @@ function HouseTemplateProvider({
2116
2261
  live = false;
2117
2262
  };
2118
2263
  }, [editor, template$1, generation, enabled]);
2119
- const refresh = React3.useCallback(() => setGeneration((g) => g + 1), []);
2120
- const insertBlock = React3.useCallback(
2264
+ const refresh = React4.useCallback(() => setGeneration((g) => g + 1), []);
2265
+ const insertBlock = React4.useCallback(
2121
2266
  (name) => {
2122
2267
  if (!editor || !editable) return false;
2123
2268
  const fragment = template.buildingBlockFragment(template$1.bytes, name);
@@ -2147,7 +2292,7 @@ function HouseTemplateProvider({
2147
2292
  },
2148
2293
  [editor, editable, template$1, notify, refresh, track]
2149
2294
  );
2150
- const setAsHouseTemplate = React3.useMemo(
2295
+ const setAsHouseTemplate = React4.useMemo(
2151
2296
  () => host?.setFromDocument && documentId ? async () => {
2152
2297
  try {
2153
2298
  await host.setFromDocument(documentId);
@@ -2162,7 +2307,7 @@ function HouseTemplateProvider({
2162
2307
  } : void 0,
2163
2308
  [host, documentId, notify]
2164
2309
  );
2165
- const value = React3.useMemo(
2310
+ const value = React4.useMemo(
2166
2311
  () => ({
2167
2312
  template: template$1,
2168
2313
  blocks,
@@ -2188,6 +2333,825 @@ function HouseTemplateProvider({
2188
2333
  );
2189
2334
  return /* @__PURE__ */ jsxRuntime.jsx(HouseTemplateContext.Provider, { value: enabled ? value : null, children });
2190
2335
  }
2336
+
2337
+ // src/docx/references/numbering.ts
2338
+ var numbers = (level) => !!level && level.numFmt !== "bullet" && level.numFmt !== "none" && (level.lvlText ?? level.markerText ?? "").length > 0;
2339
+ function paragraphNumber(order, items, levelOf, paragraphId) {
2340
+ const item = items.get(paragraphId);
2341
+ if (!item || !numbers(item)) return null;
2342
+ const at = order.indexOf(paragraphId);
2343
+ const markerAt = (ilvl) => {
2344
+ if (ilvl === item.ilvl) return item.markerText;
2345
+ for (let i = at - 1; i >= 0; i--) {
2346
+ const other = items.get(order[i]);
2347
+ if (other && other.numId === item.numId && other.ilvl === ilvl) return other.markerText;
2348
+ }
2349
+ return null;
2350
+ };
2351
+ const chain = [];
2352
+ const texts = [];
2353
+ for (let u = item.ilvl; u >= 0; u--) {
2354
+ const level = levelOf(item.numId, u);
2355
+ if (!level || !numbers(level)) continue;
2356
+ if (u !== item.ilvl && texts.some((t) => t.includes(`%${u + 1}`))) continue;
2357
+ chain.push(u);
2358
+ texts.push(level.lvlText);
2359
+ }
2360
+ const value = chain.reverse().map((u) => markerAt(u) ?? "").join("");
2361
+ if (!value) return null;
2362
+ return value.length > 1 && value.endsWith(".") ? value.slice(0, -1) : value;
2363
+ }
2364
+ function listTargets(paragraphs, items, levelOf) {
2365
+ const order = paragraphs.map((p) => p.id);
2366
+ const out = [];
2367
+ for (const p of paragraphs) {
2368
+ const text = p.text.replace(//g, "").trim();
2369
+ if (!text) continue;
2370
+ const number = paragraphNumber(order, items, levelOf, p.id);
2371
+ const item = items.get(p.id);
2372
+ if (number !== null)
2373
+ out.push({
2374
+ paragraphId: p.id,
2375
+ kind: "numbered",
2376
+ number,
2377
+ marker: item?.markerText ?? "",
2378
+ text,
2379
+ heading: p.heading,
2380
+ level: item?.ilvl ?? 0
2381
+ });
2382
+ else if (p.heading)
2383
+ out.push({
2384
+ paragraphId: p.id,
2385
+ kind: "heading",
2386
+ number: null,
2387
+ marker: "",
2388
+ text,
2389
+ heading: true,
2390
+ level: 0
2391
+ });
2392
+ }
2393
+ return out;
2394
+ }
2395
+ function filterTargets(targets, query) {
2396
+ const q = query.trim().toLowerCase();
2397
+ if (!q) return [...targets];
2398
+ return targets.filter(
2399
+ (t) => (t.number ?? "").toLowerCase().startsWith(q) || t.text.toLowerCase().includes(q)
2400
+ );
2401
+ }
2402
+
2403
+ // src/docx/references/commands.ts
2404
+ var REF_BOOKMARK_PREFIX = "_Ref";
2405
+ function newRefBookmark(taken, random = Math.random) {
2406
+ for (; ; ) {
2407
+ const name = `${REF_BOOKMARK_PREFIX}${String(Math.floor(random() * 9e8) + 1e8)}`;
2408
+ if (!taken.has(name)) return name;
2409
+ }
2410
+ }
2411
+ var styled = (style) => style ? `<w:rPr><w:rStyle w:val="${style}"/></w:rPr>` : "";
2412
+ var run = (text, style) => `<w:r>${styled(style)}<w:t xml:space="preserve">${chunk2A4MDHJR_cjs.esc(text)}</w:t></w:r>`;
2413
+ function refFieldXml(instruction, cached) {
2414
+ const r = (inner) => `<w:r>${styled(CROSS_REFERENCE_STYLE)}${inner}</w:r>`;
2415
+ return `${r('<w:fldChar w:fldCharType="begin"/>')}${r(
2416
+ `<w:instrText xml:space="preserve"> ${chunk2A4MDHJR_cjs.esc(instruction)} </w:instrText>`
2417
+ )}${r('<w:fldChar w:fldCharType="separate"/>')}${run(cached, CROSS_REFERENCE_STYLE)}${r(
2418
+ '<w:fldChar w:fldCharType="end"/>'
2419
+ )}`;
2420
+ }
2421
+ var refTooltip = (value, mode) => mode === "number" ? `Cross-reference to clause ${value}` : `Cross-reference to \u201C${value}\u201D`;
2422
+ function crossReferenceXml(bookmark, mode, value) {
2423
+ return `<w:hyperlink w:anchor="${chunk2A4MDHJR_cjs.esc(bookmark)}" w:tooltip="${chunk2A4MDHJR_cjs.esc(
2424
+ refTooltip(value, mode)
2425
+ )}" w:history="1">${refFieldXml(refInstruction(bookmark, mode), value)}</w:hyperlink>`;
2426
+ }
2427
+ var refInstruction = (bookmark, mode) => mode === "number" ? `REF ${bookmark} \\r \\h` : `REF ${bookmark} \\h`;
2428
+ var refResult = (target, mode) => mode === "number" && target.number ? target.number : target.text;
2429
+ var allBookmarks = (port) => new Set(port.paragraphs().flatMap((p) => p.bookmarks));
2430
+ function ensureTargetBookmark(port, target, mode) {
2431
+ const paragraph = port.paragraphs().find((p) => p.id === target.paragraphId);
2432
+ if (!paragraph) throw new Error("That clause is no longer in the document.");
2433
+ const existing = paragraph.bookmarks.find((b) => b.startsWith(REF_BOOKMARK_PREFIX));
2434
+ if (existing && mode === "number") return existing;
2435
+ const name = newRefBookmark(allBookmarks(port));
2436
+ const start = `<w:bookmarkStart w:id="0" w:name="${name}"/>`;
2437
+ const end = '<w:bookmarkEnd w:id="0"/>';
2438
+ if (mode === "number") {
2439
+ port.setCaret({ paragraphId: paragraph.id, offset: 0 });
2440
+ if (!port.paste(`<w:p>${start}${end}</w:p>`, "", false))
2441
+ throw new Error("The cross-reference target could not be marked.");
2442
+ return name;
2443
+ }
2444
+ const runs = port.runsXml(paragraph.id);
2445
+ if (!runs) throw new Error("This heading cannot be referred to by its text; use its number.");
2446
+ port.deleteRange(
2447
+ { paragraphId: paragraph.id, offset: 0 },
2448
+ { paragraphId: paragraph.id, offset: paragraph.text.length }
2449
+ );
2450
+ if (!port.paste(`<w:p>${start}${runs}${end}</w:p>`, paragraph.text, false))
2451
+ throw new Error("The cross-reference target could not be marked.");
2452
+ return name;
2453
+ }
2454
+ function pastePoint(port, caret) {
2455
+ const paragraph = port.paragraphs().find((p) => p.id === caret.paragraphId);
2456
+ if (paragraph?.text[caret.offset - 1] !== FIELD_ATOM) return caret;
2457
+ port.setCaret(caret);
2458
+ port.typeText(" ");
2459
+ return { paragraphId: caret.paragraphId, offset: caret.offset + 1 };
2460
+ }
2461
+ function markCrossReferenceTarget(port, target, mode) {
2462
+ if (mode === "number" && !target.number) mode = "text";
2463
+ const bookmark = ensureTargetBookmark(port, target, mode);
2464
+ return { bookmark, mode, value: refResult(target, mode) };
2465
+ }
2466
+ function insertCrossReferenceField(port, { bookmark, mode, value }, caret) {
2467
+ caret = pastePoint(port, caret);
2468
+ port.setCaret(caret);
2469
+ if (!port.paste(`<w:p>${crossReferenceXml(bookmark, mode, value)}</w:p>`, value, false))
2470
+ throw new Error("The cross-reference could not be inserted.");
2471
+ port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + 1 });
2472
+ return { bookmark };
2473
+ }
2474
+ function insertCrossReference(port, target, mode, caret) {
2475
+ return insertCrossReferenceField(port, markCrossReferenceTarget(port, target, mode), caret);
2476
+ }
2477
+ var documentReferenceTooltip = (text, appName = "ARBI") => `Cross-reference: ${text} \u2014 opens in ${appName}`;
2478
+ function insertDocumentReference(port, reference, caret) {
2479
+ const text = reference.text.trim();
2480
+ if (!text) throw new Error("Enter the reference text.");
2481
+ const tooltip = documentReferenceTooltip(text, reference.appName).slice(0, 255);
2482
+ caret = pastePoint(port, caret);
2483
+ port.setCaret(caret);
2484
+ const link = `<w:p><w:hyperlink r:id="rIdRef1"${tooltip ? ` w:tooltip="${chunk2A4MDHJR_cjs.esc(tooltip)}"` : ""} w:history="1">${run(text, CROSS_REFERENCE_STYLE)}</w:hyperlink></w:p>`;
2485
+ if (!port.paste(link, text, false, chunk2A4MDHJR_cjs.hyperlinkRelationship("rIdRef1", reference.url)))
2486
+ throw new Error("The reference could not be inserted.");
2487
+ port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + text.length });
2488
+ }
2489
+ var REF_FIELD = /^REF\s+(\S+)((?:\s+\\[A-Za-z*]+(?:\s+MERGEFORMAT)?)*)\s*$/i;
2490
+ function staleCrossReferences(port) {
2491
+ const paragraphs = port.paragraphs();
2492
+ if (!paragraphs.some((p) => p.fields?.length)) return [];
2493
+ const items = port.listItems();
2494
+ const order = paragraphs.map((p) => p.id);
2495
+ const owner = /* @__PURE__ */ new Map();
2496
+ for (const p of paragraphs) for (const b of p.bookmarks) if (!owner.has(b)) owner.set(b, p.id);
2497
+ const out = [];
2498
+ for (const p of paragraphs)
2499
+ for (const field of p.fields ?? []) {
2500
+ const match = REF_FIELD.exec(field.instruction);
2501
+ if (!match || !match[1].startsWith(REF_BOOKMARK_PREFIX)) continue;
2502
+ const switches = match[2].toLowerCase();
2503
+ const mode = /\\[rwn]\b/.test(switches) ? "number" : "text";
2504
+ const target = owner.get(match[1]);
2505
+ const base = {
2506
+ paragraphId: p.id,
2507
+ offset: field.offset,
2508
+ instruction: field.instruction,
2509
+ cached: field.result,
2510
+ bookmark: match[1],
2511
+ mode
2512
+ };
2513
+ if (!target) {
2514
+ out.push({ ...base, value: null });
2515
+ continue;
2516
+ }
2517
+ const value = /\\[rwn]\b/.test(switches) ? switches.includes("\\r") ? paragraphNumber(order, items, port.levelOf, target) : null : (paragraphs.find((x) => x.id === target)?.text ?? "").replace(//g, "").trim();
2518
+ if (value && value !== field.result.trim()) out.push({ ...base, value });
2519
+ }
2520
+ return out;
2521
+ }
2522
+ function brokenCrossReferences(port) {
2523
+ return port.paragraphs().flatMap(
2524
+ (p) => (p.marks ?? []).filter((m) => m.styleId === BROKEN_CROSS_REFERENCE_STYLE).map((m) => ({ paragraphId: p.id, offset: m.offset, text: m.text }))
2525
+ );
2526
+ }
2527
+ function refreshCrossReferences(port) {
2528
+ const stale = staleCrossReferences(port).sort(
2529
+ (a, b) => a.paragraphId === b.paragraphId ? b.offset - a.offset : 0
2530
+ );
2531
+ let refreshed = 0;
2532
+ for (const ref of stale) {
2533
+ const paragraph = port.paragraphs().find((p) => p.id === ref.paragraphId);
2534
+ if (!paragraph || paragraph.text[ref.offset - 1] === FIELD_ATOM) continue;
2535
+ const at = { paragraphId: ref.paragraphId, offset: ref.offset };
2536
+ port.deleteRange(at, { paragraphId: ref.paragraphId, offset: ref.offset + 1 });
2537
+ port.setCaret(at);
2538
+ const text = ref.value ?? (ref.cached.trim() || ref.bookmark);
2539
+ const body = ref.value === null ? run(text, BROKEN_CROSS_REFERENCE_STYLE) : crossReferenceXml(ref.bookmark, ref.mode, ref.value);
2540
+ if (port.paste(`<w:p>${body}</w:p>`, text, false) && ref.value !== null) refreshed++;
2541
+ }
2542
+ return { refreshed, broken: brokenCrossReferences(port) };
2543
+ }
2544
+
2545
+ // src/docx/references/passages.ts
2546
+ function shortTitle(title) {
2547
+ const base = title.replace(/\.[A-Za-z0-9]{1,5}$/, "").trim();
2548
+ const defined = /\(\s*(?:the\s+)?["“'‘]([^"”'’]{1,30})["”'’]\s*\)/i.exec(base);
2549
+ return defined ? defined[1] : base;
2550
+ }
2551
+ function passageClause(text) {
2552
+ const first = text.trim().split("\n")[0] ?? "";
2553
+ const match = /^(?:#+\s*)?(?:\*\*)?(?:clause|section|article)?\s*(\d+(?:\.\d+)*)[.)]?(?:\*\*)?\s+\S/i.exec(
2554
+ first
2555
+ );
2556
+ return match ? match[1] : null;
2557
+ }
2558
+ function referenceText(title, passage) {
2559
+ const name = shortTitle(title);
2560
+ const clause = passageClause(passage.text);
2561
+ if (clause) return `${name}, clause ${clause}`;
2562
+ if (passage.page) return `${name}, p. ${passage.page}`;
2563
+ return name;
2564
+ }
2565
+ function passageExcerpt(text, max = 280) {
2566
+ const plain = text.replace(/[#*_`>|]+/g, " ").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\s+/g, " ").trim();
2567
+ return plain.length > max ? `${plain.slice(0, max - 1)}\u2026` : plain;
2568
+ }
2569
+ function filterPassages(passages, query) {
2570
+ const q = query.trim().toLowerCase();
2571
+ return q ? passages.filter((p) => p.text.toLowerCase().includes(q)) : [...passages];
2572
+ }
2573
+ var RUN_PARTS = /* @__PURE__ */ new Set(["rPr", "t", "tab", "br", "lastRenderedPageBreak"]);
2574
+ var SKIPPED = /* @__PURE__ */ new Set(["pPr", "bookmarkStart", "bookmarkEnd", "proofErr", "permStart", "permEnd"]);
2575
+ function serialize(node) {
2576
+ if (node.kind === "textValue") return chunk2A4MDHJR_cjs.esc(node.value ?? "");
2577
+ const name = `${node.prefix ?? "w"}:${node.localName}`;
2578
+ const attrs = (node.attributes ?? []).map((a) => ` ${a.prefix ? `${a.prefix}:` : ""}${a.localName}="${chunk2A4MDHJR_cjs.esc(a.value)}"`).join("");
2579
+ const children = (node.children ?? []).map((c) => serialize(c)).join("");
2580
+ return children ? `<${name}${attrs}>${children}</${name}>` : `<${name}${attrs}/>`;
2581
+ }
2582
+ function paragraphRunsXml(paragraph) {
2583
+ const runs = [];
2584
+ for (const child of paragraph.children ?? []) {
2585
+ if (child.localName && SKIPPED.has(child.localName)) continue;
2586
+ if (child.localName !== "r") return null;
2587
+ if ((child.children ?? []).some((c) => !c.localName || !RUN_PARTS.has(c.localName))) return null;
2588
+ runs.push(serialize(child));
2589
+ }
2590
+ return runs.length ? runs.join("") : null;
2591
+ }
2592
+ function findNode2(node, id) {
2593
+ if (node.id === id) return node;
2594
+ for (const child of node.children ?? []) {
2595
+ const found = findNode2(child, id);
2596
+ if (found) return found;
2597
+ }
2598
+ return void 0;
2599
+ }
2600
+ function referencesPort(editor, revision) {
2601
+ const base = editorPort(editor, revision);
2602
+ const session = () => {
2603
+ const s = editor.surface?.session;
2604
+ if (!s) throw new Error("The document is not open.");
2605
+ return s;
2606
+ };
2607
+ const root = () => session().part().root;
2608
+ let numbering;
2609
+ let cascade;
2610
+ const index = () => {
2611
+ if (!numbering) {
2612
+ const s = session();
2613
+ cascade = layout.buildStyleCascadeTable(s.stylesRoot(), void 0, s.settingsRoot());
2614
+ numbering = layout.withNumberingStyleLinks(layout.buildNumberingIndex(s.numberingRoot()), cascade);
2615
+ }
2616
+ return numbering;
2617
+ };
2618
+ return {
2619
+ ...base,
2620
+ listItems: () => {
2621
+ const body = root().children?.find((n) => n.kind === "body");
2622
+ const items = layout.resolveStoryListItems(
2623
+ body?.children ?? [],
2624
+ index(),
2625
+ cascade
2626
+ );
2627
+ const out = /* @__PURE__ */ new Map();
2628
+ for (const [id, item] of items)
2629
+ out.set(id, {
2630
+ numId: item.numId,
2631
+ ilvl: item.ilvl,
2632
+ markerText: item.markerText,
2633
+ numFmt: item.numFmt
2634
+ });
2635
+ return out;
2636
+ },
2637
+ levelOf: (numId, ilvl) => {
2638
+ const level = layout.resolveNumberingLevel(index(), numId, ilvl)?.level;
2639
+ return level ? { lvlText: level.lvlText, numFmt: level.numFmt } : null;
2640
+ },
2641
+ runsXml: (paragraphId) => {
2642
+ const node = findNode2(root(), paragraphId);
2643
+ return node ? paragraphRunsXml(node) : null;
2644
+ }
2645
+ };
2646
+ }
2647
+
2648
+ // src/docx/beforeSave.ts
2649
+ var hooks = /* @__PURE__ */ new WeakMap();
2650
+ function onBeforeSave(editor, fn) {
2651
+ let set = hooks.get(editor);
2652
+ if (!set) hooks.set(editor, set = /* @__PURE__ */ new Set());
2653
+ set.add(fn);
2654
+ return () => set.delete(fn);
2655
+ }
2656
+ function runBeforeSave(editor) {
2657
+ if (!editor) return;
2658
+ for (const fn of hooks.get(editor) ?? [])
2659
+ try {
2660
+ fn();
2661
+ } catch {
2662
+ }
2663
+ }
2664
+ var DEFAULT_CROSS_REFERENCES_LABELS = {
2665
+ insert: "Insert cross-reference",
2666
+ title: "Insert cross-reference",
2667
+ description: "Refer to a clause of this document, or to a passage of another document.",
2668
+ thisDocument: "This document",
2669
+ otherDocument: "Another document",
2670
+ filterTargets: "Find a clause or heading",
2671
+ noTargets: "This document has no numbered clauses or headings yet.",
2672
+ number: "Paragraph number",
2673
+ text: "Heading text",
2674
+ insertAs: "Insert",
2675
+ chooseDocument: "Choose a document",
2676
+ filterPassages: "Find a passage",
2677
+ loadingPassages: "Loading passages\u2026",
2678
+ noPassages: "No passage matches.",
2679
+ referenceText: "Reference text",
2680
+ insertButton: "Insert",
2681
+ cancel: "Cancel",
2682
+ clause: (number) => `Clause ${number}`,
2683
+ heading: "Heading",
2684
+ update: "Update cross-references",
2685
+ updated: "Cross-references updated",
2686
+ updateSummary: (refreshed) => refreshed ? `${refreshed} cross-reference${refreshed === 1 ? "" : "s"} brought up to date.` : "Every cross-reference is up to date.",
2687
+ brokenTitle: "Broken cross-references",
2688
+ brokenNone: "No cross-reference points at a deleted target.",
2689
+ brokenHelp: "Their target was deleted: the last text is kept and marked. Insert the reference again to repair it.",
2690
+ brokenCard: "Broken cross-reference",
2691
+ brokenCardBody: "Its target was deleted. Update cross-references to mark it.",
2692
+ show: "Show",
2693
+ close: "Close"
2694
+ };
2695
+ var CrossReferencesContext = React4.createContext(null);
2696
+ var useCrossReferences = () => React4.useContext(CrossReferencesContext);
2697
+ function CrossReferencesProvider({
2698
+ children,
2699
+ editable,
2700
+ references,
2701
+ documentId,
2702
+ notify,
2703
+ labels
2704
+ }) {
2705
+ const editor = react.useDocxEditor();
2706
+ const track = useTrackedOrNoted();
2707
+ const l = React4.useMemo(() => ({ ...DEFAULT_CROSS_REFERENCES_LABELS, ...labels }), [labels]);
2708
+ const [dialog, setDialog] = React4.useState(
2709
+ null
2710
+ );
2711
+ const marker = React4.useRef(null);
2712
+ const [viewer, setViewer] = React4.useState(null);
2713
+ React4.useEffect(() => setViewer(marker.current?.closest(".native-docx-viewer") ?? null), []);
2714
+ const openDialog = React4.useCallback(() => {
2715
+ if (!editor || !editable) return;
2716
+ try {
2717
+ const port = referencesPort(editor);
2718
+ const caret = port.caret();
2719
+ if (!caret) return notify?.("Place the cursor where the reference should go.", "error");
2720
+ setDialog({ caret, targets: listTargets(port.paragraphs(), port.listItems(), port.levelOf) });
2721
+ } catch (error) {
2722
+ notify?.(error instanceof Error ? error.message : "Could not read the document.", "error");
2723
+ }
2724
+ }, [editor, editable, notify]);
2725
+ const run2 = React4.useCallback(
2726
+ (label, prepare, insert) => {
2727
+ if (!editor) return;
2728
+ try {
2729
+ const prepared = withDirectEditing(editor, prepare);
2730
+ if (dialog) referencesPort(editor).setCaret(dialog.caret);
2731
+ track({ label, insert: (revision) => insert(prepared, revision), inserted: () => true });
2732
+ setDialog(null);
2733
+ editor.surface?.focus();
2734
+ holdCaret(editor);
2735
+ } catch (error) {
2736
+ notify?.(
2737
+ error instanceof Error ? error.message : "Could not insert the reference.",
2738
+ "error"
2739
+ );
2740
+ }
2741
+ },
2742
+ [editor, dialog, track, notify]
2743
+ );
2744
+ React4.useEffect(() => {
2745
+ if (!editor || !editable) return;
2746
+ const refresh = () => {
2747
+ try {
2748
+ const port = referencesPort(editor);
2749
+ if (!port.paragraphs().some((p) => p.fields?.length)) return;
2750
+ preservingCaret(editor, () => withDirectEditing(editor, () => refreshCrossReferences(port)));
2751
+ } catch {
2752
+ }
2753
+ };
2754
+ const off = onBeforeSave(editor, refresh);
2755
+ const timer = setTimeout(refresh, 1500);
2756
+ return () => {
2757
+ off();
2758
+ clearTimeout(timer);
2759
+ };
2760
+ }, [editor, editable]);
2761
+ const [report, setReport] = React4.useState(null);
2762
+ const update = React4.useCallback(() => {
2763
+ if (!editor || !editable) return;
2764
+ try {
2765
+ const result = preservingCaret(
2766
+ editor,
2767
+ () => withDirectEditing(editor, () => refreshCrossReferences(referencesPort(editor)))
2768
+ );
2769
+ setReport(result);
2770
+ } catch (error) {
2771
+ notify?.(
2772
+ error instanceof Error ? error.message : "Could not update cross-references.",
2773
+ "error"
2774
+ );
2775
+ }
2776
+ }, [editor, editable, notify]);
2777
+ const [passages, setPassages] = React4.useState({});
2778
+ const loadPassages = React4.useCallback(
2779
+ (id) => {
2780
+ if (!references || passages[id]) return;
2781
+ setPassages((p) => ({ ...p, [id]: "loading" }));
2782
+ references.passages(id).then((list) => setPassages((p) => ({ ...p, [id]: list }))).catch(() => setPassages((p) => ({ ...p, [id]: [] })));
2783
+ },
2784
+ [references, passages]
2785
+ );
2786
+ React4.useEffect(() => {
2787
+ if (!viewer || !references) return;
2788
+ const targetOf = (event) => {
2789
+ const link = event.target?.closest?.(
2790
+ 'a.docx-hyperlink[data-docx-link-kind="external"]'
2791
+ );
2792
+ if (!link || !viewer.contains(link)) return null;
2793
+ const mouse = event;
2794
+ if (mouse.button !== 0 || mouse.ctrlKey || mouse.metaKey || mouse.shiftKey) return null;
2795
+ return references.targetOf(link.getAttribute("href") ?? "");
2796
+ };
2797
+ const take = (event) => {
2798
+ const target = targetOf(event);
2799
+ if (!target) return;
2800
+ event.preventDefault();
2801
+ event.stopPropagation();
2802
+ if (event.type === "click") references.open(target);
2803
+ };
2804
+ const types = ["pointerdown", "mousedown", "pointerup", "mouseup", "click"];
2805
+ for (const type of types) window.addEventListener(type, take, true);
2806
+ return () => {
2807
+ for (const type of types) window.removeEventListener(type, take, true);
2808
+ };
2809
+ }, [viewer, references]);
2810
+ const value = React4.useMemo(
2811
+ () => editable ? { openDialog, update, labels: l } : null,
2812
+ [editable, openDialog, update, l]
2813
+ );
2814
+ const resolveInternal = (href) => {
2815
+ if (!editor) return null;
2816
+ const name = href.replace(/^#/, "");
2817
+ try {
2818
+ const port = referencesPort(editor);
2819
+ const paragraphs = port.paragraphs();
2820
+ const target = paragraphs.find((p) => p.bookmarks.includes(name));
2821
+ if (!target) return { title: l.brokenCard, body: l.brokenCardBody };
2822
+ const number = paragraphNumber(
2823
+ paragraphs.map((p) => p.id),
2824
+ port.listItems(),
2825
+ port.levelOf,
2826
+ target.id
2827
+ );
2828
+ return {
2829
+ title: number ? l.clause(number) : l.heading,
2830
+ body: passageExcerpt(target.text.replace(//g, ""))
2831
+ };
2832
+ } catch {
2833
+ return null;
2834
+ }
2835
+ };
2836
+ return /* @__PURE__ */ jsxRuntime.jsxs(CrossReferencesContext.Provider, { value, children: [
2837
+ /* @__PURE__ */ jsxRuntime.jsx("span", { ref: marker, hidden: true }),
2838
+ children,
2839
+ /* @__PURE__ */ jsxRuntime.jsx(
2840
+ LinkHoverCard,
2841
+ {
2842
+ root: viewer,
2843
+ matches: (href) => href.startsWith(`#${REF_BOOKMARK_PREFIX}`),
2844
+ resolve: resolveInternal,
2845
+ testId: "docx-cross-reference-card"
2846
+ }
2847
+ ),
2848
+ references && /* @__PURE__ */ jsxRuntime.jsx(
2849
+ LinkHoverCard,
2850
+ {
2851
+ root: viewer,
2852
+ matches: (href) => !!references.targetOf(href),
2853
+ resolve: (href) => {
2854
+ const target = references.targetOf(href);
2855
+ if (!target) return null;
2856
+ const list = passages[target.documentId];
2857
+ if (!list) loadPassages(target.documentId);
2858
+ const passage = Array.isArray(list) ? list.find((p) => p.chunkId === target.chunkId) : void 0;
2859
+ return passage ? {
2860
+ body: passageExcerpt(passage.text),
2861
+ footer: passage.page ? `p. ${passage.page}` : void 0
2862
+ } : null;
2863
+ },
2864
+ testId: "docx-cross-reference-card"
2865
+ }
2866
+ ),
2867
+ dialog && /* @__PURE__ */ jsxRuntime.jsx(
2868
+ CrossReferenceDialog,
2869
+ {
2870
+ targets: dialog.targets,
2871
+ references,
2872
+ documentId,
2873
+ passages,
2874
+ loadPassages,
2875
+ labels: l,
2876
+ onCancel: () => setDialog(null),
2877
+ onClosed: () => editor?.surface?.focus(),
2878
+ onInsertTarget: (target, mode) => run2(
2879
+ `Inserted cross-reference: ${refResult(target, mode)}`,
2880
+ () => markCrossReferenceTarget(referencesPort(editor), target, mode),
2881
+ (marked, revision) => insertCrossReferenceField(referencesPort(editor, revision), marked, dialog.caret)
2882
+ ),
2883
+ onInsertPassage: (target, text) => run2(
2884
+ `Inserted cross-reference: ${text}`,
2885
+ () => void 0,
2886
+ (_, revision) => insertDocumentReference(
2887
+ referencesPort(editor, revision),
2888
+ { text, url: references.linkFor(target), appName: references.appName },
2889
+ dialog.caret
2890
+ )
2891
+ )
2892
+ }
2893
+ ),
2894
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: !!report, onOpenChange: (open) => !open && setReport(null), children: /* @__PURE__ */ jsxRuntime.jsxs(
2895
+ ui.DialogContent,
2896
+ {
2897
+ className: "max-h-[85dvh] overflow-y-auto",
2898
+ "data-testid": "docx-cross-references-report",
2899
+ children: [
2900
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
2901
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: l.updated }),
2902
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: report && l.updateSummary(report.refreshed) })
2903
+ ] }),
2904
+ report && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-1 text-sm", children: [
2905
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-medium", children: l.brokenTitle }),
2906
+ report.broken.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2907
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: l.brokenHelp }),
2908
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", "data-testid": "docx-cross-references-broken", children: report.broken.map((b) => /* @__PURE__ */ jsxRuntime.jsxs(
2909
+ "li",
2910
+ {
2911
+ className: "flex items-center justify-between gap-2",
2912
+ children: [
2913
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-text", children: b.text }),
2914
+ /* @__PURE__ */ jsxRuntime.jsx(
2915
+ ui.Button,
2916
+ {
2917
+ size: "sm",
2918
+ variant: "ghost",
2919
+ onClick: () => {
2920
+ const point = { paragraphId: b.paragraphId, offset: b.offset };
2921
+ editor?.surface?.setSelection({ anchor: point, head: point });
2922
+ editor?.surface?.revealParagraph(b.paragraphId);
2923
+ setReport(null);
2924
+ },
2925
+ children: l.show
2926
+ }
2927
+ )
2928
+ ]
2929
+ },
2930
+ `${b.paragraphId}:${b.offset}`
2931
+ )) })
2932
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: l.brokenNone })
2933
+ ] }),
2934
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", onClick: () => setReport(null), children: l.close }) })
2935
+ ]
2936
+ }
2937
+ ) })
2938
+ ] });
2939
+ }
2940
+ function CrossReferenceDialog({
2941
+ targets,
2942
+ references,
2943
+ documentId,
2944
+ passages,
2945
+ loadPassages,
2946
+ labels,
2947
+ onCancel,
2948
+ onInsertTarget,
2949
+ onInsertPassage,
2950
+ onClosed
2951
+ }) {
2952
+ const l = { ...DEFAULT_CROSS_REFERENCES_LABELS, ...labels };
2953
+ const [tab, setTab] = React4.useState("this");
2954
+ const [query, setQuery] = React4.useState("");
2955
+ const [chosen, setChosen] = React4.useState(null);
2956
+ const [mode, setMode] = React4.useState("number");
2957
+ const shown = React4.useMemo(() => filterTargets(targets, query), [targets, query]);
2958
+ const effectiveMode = chosen?.number ? mode : "text";
2959
+ const [documents, setDocuments] = React4.useState(null);
2960
+ const [docId, setDocId] = React4.useState(null);
2961
+ const [passageQuery, setPassageQuery] = React4.useState("");
2962
+ const [passage, setPassage] = React4.useState(null);
2963
+ const [text, setText] = React4.useState("");
2964
+ React4.useEffect(() => {
2965
+ if (tab !== "other" || !references || documents) return;
2966
+ references.documents().then((list2) => setDocuments(list2.filter((d) => d.id !== documentId))).catch(() => setDocuments([]));
2967
+ }, [tab, references, documents, documentId]);
2968
+ const chooseDocument = (id) => {
2969
+ setDocId(id);
2970
+ setPassage(null);
2971
+ setText("");
2972
+ loadPassages(id);
2973
+ };
2974
+ const title = documents?.find((d) => d.id === docId)?.title ?? "";
2975
+ const list = docId ? passages[docId] : void 0;
2976
+ const shownPassages = Array.isArray(list) ? filterPassages(list, passageQuery) : [];
2977
+ const canInsert = tab === "this" ? !!chosen : !!(docId && passage && text.trim());
2978
+ const insert = () => {
2979
+ if (tab === "this" && chosen) onInsertTarget(chosen, effectiveMode);
2980
+ if (tab === "other" && docId && passage)
2981
+ onInsertPassage(
2982
+ { documentId: docId, chunkId: passage.chunkId, page: passage.page ?? null },
2983
+ text
2984
+ );
2985
+ };
2986
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: true, onOpenChange: (open) => !open && onCancel(), children: /* @__PURE__ */ jsxRuntime.jsxs(
2987
+ ui.DialogContent,
2988
+ {
2989
+ className: "max-h-[85dvh] overflow-y-auto",
2990
+ "data-testid": "docx-cross-reference-dialog",
2991
+ onCloseAutoFocus: (event) => {
2992
+ if (!onClosed) return;
2993
+ event.preventDefault();
2994
+ onClosed();
2995
+ },
2996
+ children: [
2997
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
2998
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: l.title }),
2999
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: l.description })
3000
+ ] }),
3001
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: tab, onValueChange: (v) => setTab(v), children: [
3002
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.TabsList, { children: [
3003
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "this", "data-testid": "docx-cross-reference-this", children: l.thisDocument }),
3004
+ references && /* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "other", "data-testid": "docx-cross-reference-other", children: l.otherDocument })
3005
+ ] }),
3006
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "this", className: "space-y-3", children: [
3007
+ /* @__PURE__ */ jsxRuntime.jsx(
3008
+ ui.Input,
3009
+ {
3010
+ value: query,
3011
+ placeholder: l.filterTargets,
3012
+ "aria-label": l.filterTargets,
3013
+ onChange: (e) => setQuery(e.target.value),
3014
+ "data-testid": "docx-cross-reference-filter"
3015
+ }
3016
+ ),
3017
+ /* @__PURE__ */ jsxRuntime.jsxs(
3018
+ "div",
3019
+ {
3020
+ role: "listbox",
3021
+ "aria-label": l.filterTargets,
3022
+ className: "max-h-64 space-y-0.5 overflow-y-auto rounded-md border border-border p-1",
3023
+ children: [
3024
+ shown.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.noTargets }),
3025
+ shown.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
3026
+ "button",
3027
+ {
3028
+ type: "button",
3029
+ role: "option",
3030
+ "aria-selected": chosen?.paragraphId === t.paragraphId,
3031
+ "data-testid": "docx-cross-reference-target",
3032
+ onClick: () => setChosen(t),
3033
+ onDoubleClick: () => onInsertTarget(t, t.number ? mode : "text"),
3034
+ className: ui.cn(
3035
+ "flex w-full items-baseline gap-2 rounded px-2 py-1 text-left text-sm",
3036
+ chosen?.paragraphId === t.paragraphId ? "bg-accent" : "hover:bg-accent/50"
3037
+ ),
3038
+ style: { paddingLeft: 8 + t.level * 16 },
3039
+ children: [
3040
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: t.marker || l.heading }),
3041
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.cn("truncate", t.heading && "font-medium"), children: t.text })
3042
+ ]
3043
+ },
3044
+ t.paragraphId
3045
+ ))
3046
+ ]
3047
+ }
3048
+ ),
3049
+ chosen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
3050
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: l.insertAs }),
3051
+ chosen.number && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [
3052
+ /* @__PURE__ */ jsxRuntime.jsx(
3053
+ "input",
3054
+ {
3055
+ type: "radio",
3056
+ name: "cross-reference-mode",
3057
+ checked: effectiveMode === "number",
3058
+ onChange: () => setMode("number")
3059
+ }
3060
+ ),
3061
+ l.number
3062
+ ] }),
3063
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [
3064
+ /* @__PURE__ */ jsxRuntime.jsx(
3065
+ "input",
3066
+ {
3067
+ type: "radio",
3068
+ name: "cross-reference-mode",
3069
+ checked: effectiveMode === "text",
3070
+ onChange: () => setMode("text")
3071
+ }
3072
+ ),
3073
+ l.text
3074
+ ] }),
3075
+ /* @__PURE__ */ jsxRuntime.jsx(
3076
+ "span",
3077
+ {
3078
+ className: "ml-auto rounded bg-muted px-2 py-0.5",
3079
+ "data-testid": "docx-cross-reference-preview",
3080
+ children: refResult(chosen, effectiveMode)
3081
+ }
3082
+ )
3083
+ ] })
3084
+ ] }),
3085
+ references && /* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "other", className: "space-y-3", children: [
3086
+ references.renderDocumentPicker ? references.renderDocumentPicker(chooseDocument, docId) : /* @__PURE__ */ jsxRuntime.jsxs(
3087
+ "select",
3088
+ {
3089
+ className: "h-9 w-full rounded-md border border-border bg-background px-2 text-sm",
3090
+ "aria-label": l.chooseDocument,
3091
+ value: docId ?? "",
3092
+ onChange: (e) => e.target.value && chooseDocument(e.target.value),
3093
+ "data-testid": "docx-cross-reference-document",
3094
+ children: [
3095
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: l.chooseDocument }),
3096
+ (documents ?? []).map((d) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: d.id, children: d.title }, d.id))
3097
+ ]
3098
+ }
3099
+ ),
3100
+ docId && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3101
+ /* @__PURE__ */ jsxRuntime.jsx(
3102
+ ui.Input,
3103
+ {
3104
+ value: passageQuery,
3105
+ placeholder: l.filterPassages,
3106
+ "aria-label": l.filterPassages,
3107
+ onChange: (e) => setPassageQuery(e.target.value),
3108
+ "data-testid": "docx-cross-reference-passage-filter"
3109
+ }
3110
+ ),
3111
+ /* @__PURE__ */ jsxRuntime.jsx(
3112
+ "div",
3113
+ {
3114
+ className: "max-h-64 space-y-1 overflow-y-auto",
3115
+ "data-testid": "docx-cross-reference-passages",
3116
+ children: list === "loading" || list === void 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.loadingPassages }) : shownPassages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.noPassages }) : shownPassages.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
3117
+ chunk5FYU7ZIU_cjs.FactPassageItem,
3118
+ {
3119
+ index: i,
3120
+ page: p.page,
3121
+ excerpt: passageExcerpt(p.text, 200),
3122
+ isViewing: passage?.chunkId === p.chunkId,
3123
+ onSelect: () => {
3124
+ setPassage(p);
3125
+ setText(referenceText(title, p));
3126
+ },
3127
+ testId: "docx-cross-reference-passage"
3128
+ },
3129
+ p.chunkId
3130
+ ))
3131
+ }
3132
+ ),
3133
+ passage && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block space-y-1 text-sm", children: [
3134
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: l.referenceText }),
3135
+ /* @__PURE__ */ jsxRuntime.jsx(
3136
+ ui.Input,
3137
+ {
3138
+ value: text,
3139
+ onChange: (e) => setText(e.target.value),
3140
+ "data-testid": "docx-cross-reference-text"
3141
+ }
3142
+ )
3143
+ ] })
3144
+ ] })
3145
+ ] })
3146
+ ] }),
3147
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogFooter, { children: [
3148
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", onClick: onCancel, children: l.cancel }),
3149
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { disabled: !canInsert, onClick: insert, "data-testid": "docx-cross-reference-insert", children: l.insertButton })
3150
+ ] })
3151
+ ]
3152
+ }
3153
+ ) });
3154
+ }
2191
3155
  function RibbonMenu({
2192
3156
  label,
2193
3157
  icon,
@@ -2198,9 +3162,9 @@ function RibbonMenu({
2198
3162
  keepMounted = false,
2199
3163
  popoverClassName
2200
3164
  }) {
2201
- const [open, setOpen] = React3.useState(false);
2202
- const element = React3.useRef(null);
2203
- React3.useEffect(() => {
3165
+ const [open, setOpen] = React4.useState(false);
3166
+ const element = React4.useRef(null);
3167
+ React4.useEffect(() => {
2204
3168
  if (!open) return;
2205
3169
  const dismiss = (event) => {
2206
3170
  if (!element.current?.contains(event.target)) setOpen(false);
@@ -2309,7 +3273,7 @@ var AUTO = "";
2309
3273
  function useGenerateImageTarget() {
2310
3274
  const editor = react.useDocxEditor();
2311
3275
  const loaded2 = react.useEditorState((snapshot) => !snapshot.isLoading);
2312
- React3.useEffect(() => {
3276
+ React4.useEffect(() => {
2313
3277
  if (!editor || !loaded2) return;
2314
3278
  mounted.push(editor);
2315
3279
  return () => void mounted.splice(mounted.indexOf(editor), 1);
@@ -2317,16 +3281,16 @@ function useGenerateImageTarget() {
2317
3281
  }
2318
3282
  function GenerateImageButton({ generation }) {
2319
3283
  const editor = react.useDocxEditor();
2320
- const [prompt, setPrompt] = React3.useState("");
2321
- const [aspectRatio, setAspectRatio] = React3.useState(AUTO);
2322
- const [busy, setBusy] = React3.useState(false);
2323
- const [error, setError] = React3.useState("");
2324
- const abort = React3.useRef(null);
2325
- const close = React3.useRef(() => {
3284
+ const [prompt, setPrompt] = React4.useState("");
3285
+ const [aspectRatio, setAspectRatio] = React4.useState(AUTO);
3286
+ const [busy, setBusy] = React4.useState(false);
3287
+ const [error, setError] = React4.useState("");
3288
+ const abort = React4.useRef(null);
3289
+ const close = React4.useRef(() => {
2326
3290
  });
2327
3291
  const editable = react.useEditorState((snapshot) => snapshot.editable);
2328
- const generating = React3.useSyncExternalStore(subscribe, () => running > 0);
2329
- async function run() {
3292
+ const generating = React4.useSyncExternalStore(subscribe, () => running > 0);
3293
+ async function run2() {
2330
3294
  if (!editor || !prompt.trim() || busy) return;
2331
3295
  const caret = rememberCaret(editor);
2332
3296
  const controller = new AbortController();
@@ -2372,7 +3336,7 @@ function GenerateImageButton({ generation }) {
2372
3336
  className: "native-docx-form native-docx-generate-image",
2373
3337
  onSubmit: (event) => {
2374
3338
  event.preventDefault();
2375
- void run();
3339
+ void run2();
2376
3340
  },
2377
3341
  children: [
2378
3342
  /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
@@ -2388,7 +3352,7 @@ function GenerateImageButton({ generation }) {
2388
3352
  "data-testid": "docx-generate-image-prompt",
2389
3353
  onChange: (event) => setPrompt(event.target.value),
2390
3354
  onKeyDown: (event) => {
2391
- if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) void run();
3355
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) void run2();
2392
3356
  }
2393
3357
  }
2394
3358
  )
@@ -2528,18 +3492,18 @@ function planOverflow(items, available, moreWidth) {
2528
3492
  }
2529
3493
  return collapsed;
2530
3494
  }
2531
- var Overflow = React3.createContext(null);
3495
+ var Overflow = React4.createContext(null);
2532
3496
  var MORE_WIDTH = 32;
2533
3497
  var sameSet = (a, b) => a.size === b.size && [...a].every((id) => b.has(id));
2534
3498
  function RibbonOverflow({ tab, children }) {
2535
- const row = React3.useRef(null);
2536
- const items = React3.useRef(/* @__PURE__ */ new Map());
2537
- const widths = React3.useRef(/* @__PURE__ */ new Map());
2538
- const [version, setVersion] = React3.useState(0);
2539
- const [collapsed, setCollapsed] = React3.useState(() => /* @__PURE__ */ new Set());
2540
- const [slots, setSlots] = React3.useState({});
2541
- const [menu, setMenu] = React3.useState([]);
2542
- const register = React3.useCallback((id, item) => {
3499
+ const row = React4.useRef(null);
3500
+ const items = React4.useRef(/* @__PURE__ */ new Map());
3501
+ const widths = React4.useRef(/* @__PURE__ */ new Map());
3502
+ const [version, setVersion] = React4.useState(0);
3503
+ const [collapsed, setCollapsed] = React4.useState(() => /* @__PURE__ */ new Set());
3504
+ const [slots, setSlots] = React4.useState({});
3505
+ const [menu, setMenu] = React4.useState([]);
3506
+ const register = React4.useCallback((id, item) => {
2543
3507
  items.current.set(id, item);
2544
3508
  setVersion((v) => v + 1);
2545
3509
  return () => {
@@ -2547,7 +3511,7 @@ function RibbonOverflow({ tab, children }) {
2547
3511
  setVersion((v) => v + 1);
2548
3512
  };
2549
3513
  }, []);
2550
- const plan = React3.useCallback(() => {
3514
+ const plan = React4.useCallback(() => {
2551
3515
  const element = row.current;
2552
3516
  if (!element) return;
2553
3517
  const gap = parseFloat(getComputedStyle(element).columnGap) || 0;
@@ -2567,8 +3531,8 @@ function RibbonOverflow({ tab, children }) {
2567
3531
  (current) => current.length === entries.length && current.every((entry, i) => entry.id === entries[i].id && entry.label === entries[i].label) ? current : entries
2568
3532
  );
2569
3533
  }, []);
2570
- React3.useLayoutEffect(plan, [plan, version, tab, collapsed]);
2571
- React3.useLayoutEffect(() => {
3534
+ React4.useLayoutEffect(plan, [plan, version, tab, collapsed]);
3535
+ React4.useLayoutEffect(() => {
2572
3536
  const element = row.current;
2573
3537
  if (!element) return;
2574
3538
  const observer = new ResizeObserver(() => plan());
@@ -2576,7 +3540,7 @@ function RibbonOverflow({ tab, children }) {
2576
3540
  for (const item of items.current.values()) observer.observe(item.element);
2577
3541
  return () => observer.disconnect();
2578
3542
  }, [plan, version]);
2579
- const slotRef = React3.useCallback(
3543
+ const slotRef = React4.useCallback(
2580
3544
  (id) => (node) => setSlots((current) => {
2581
3545
  if (node ? current[id] === node : !(id in current)) return current;
2582
3546
  const next = { ...current };
@@ -2586,7 +3550,7 @@ function RibbonOverflow({ tab, children }) {
2586
3550
  }),
2587
3551
  []
2588
3552
  );
2589
- const context = React3.useMemo(() => ({ collapsed, slots, register }), [collapsed, slots, register]);
3553
+ const context = React4.useMemo(() => ({ collapsed, slots, register }), [collapsed, slots, register]);
2590
3554
  const shown = menu.filter((entry) => collapsed.has(entry.id));
2591
3555
  return /* @__PURE__ */ jsxRuntime.jsx(Overflow.Provider, { value: context, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "native-docx-ribbon-row", ref: row, "data-testid": "docx-ribbon-row", children: [
2592
3556
  children,
@@ -2610,16 +3574,16 @@ function MoreRows({
2610
3574
  slotRef,
2611
3575
  close
2612
3576
  }) {
2613
- const refs = React3.useRef(/* @__PURE__ */ new Map());
3577
+ const refs = React4.useRef(/* @__PURE__ */ new Map());
2614
3578
  const refFor = (id) => {
2615
3579
  let ref = refs.current.get(id);
2616
3580
  if (!ref) refs.current.set(id, ref = slotRef(id));
2617
3581
  return ref;
2618
3582
  };
2619
- const list = React3.useRef(null);
2620
- const latest = React3.useRef(close);
3583
+ const list = React4.useRef(null);
3584
+ const latest = React4.useRef(close);
2621
3585
  latest.current = close;
2622
- React3.useEffect(() => {
3586
+ React4.useEffect(() => {
2623
3587
  const element = list.current;
2624
3588
  if (!element) return;
2625
3589
  const onClick = (event) => {
@@ -2649,10 +3613,10 @@ function RibbonItem({
2649
3613
  priority = 0,
2650
3614
  children
2651
3615
  }) {
2652
- const context = React3.useContext(Overflow);
2653
- const element = React3.useRef(null);
3616
+ const context = React4.useContext(Overflow);
3617
+ const element = React4.useRef(null);
2654
3618
  const register = context?.register;
2655
- React3.useLayoutEffect(() => {
3619
+ React4.useLayoutEffect(() => {
2656
3620
  if (!register || !element.current) return;
2657
3621
  return register(id, { label, priority, element: element.current });
2658
3622
  }, [register, id, label, priority]);
@@ -2734,14 +3698,14 @@ function Gallery({ close }) {
2734
3698
  const changed = new Set(
2735
3699
  house?.basedOnTemplate ? house.divergence?.styles.filter((s) => s.kind === "changed").map((s) => s.styleId) : []
2736
3700
  );
2737
- const [query, setQuery] = React3.useState("");
2738
- const quick = React3.useMemo(
3701
+ const [query, setQuery] = React4.useState("");
3702
+ const quick = React4.useMemo(
2739
3703
  () => QUICK_STYLES.map((name) => findStyle(options, name)).filter(
2740
3704
  (o) => !!o
2741
3705
  ),
2742
3706
  [options]
2743
3707
  );
2744
- const shown = React3.useMemo(() => {
3708
+ const shown = React4.useMemo(() => {
2745
3709
  const q = query.trim().toLowerCase();
2746
3710
  return q ? options.filter(
2747
3711
  (o) => o.name.toLowerCase().includes(q) || o.styleId.toLowerCase().includes(q)
@@ -2988,9 +3952,9 @@ function WordShortcuts({ scope }) {
2988
3952
  const styles = react.useParagraphStyle();
2989
3953
  const editor = react.useDocxEditor();
2990
3954
  const levels = useHouseTemplate()?.levels;
2991
- const latest = React3.useRef({ footnote, endnote, styles, editor, levels });
3955
+ const latest = React4.useRef({ footnote, endnote, styles, editor, levels });
2992
3956
  latest.current = { footnote, endnote, styles, editor, levels };
2993
- React3.useEffect(() => {
3957
+ React4.useEffect(() => {
2994
3958
  const element = scope.current;
2995
3959
  if (!element) return;
2996
3960
  const onKeyDown = (event) => {
@@ -3028,6 +3992,65 @@ function WordShortcuts({ scope }) {
3028
3992
  }, [scope]);
3029
3993
  return null;
3030
3994
  }
3995
+ function CrossReferenceButton() {
3996
+ const references = useCrossReferences();
3997
+ if (!references) return null;
3998
+ return /* @__PURE__ */ jsxRuntime.jsx(
3999
+ "button",
4000
+ {
4001
+ type: "button",
4002
+ className: "native-docx-ribbon-trigger",
4003
+ "aria-label": references.labels.insert,
4004
+ title: references.labels.insert,
4005
+ "data-testid": "docx-insert-cross-reference",
4006
+ onMouseDown: (event) => event.preventDefault(),
4007
+ onClick: () => references.openDialog(),
4008
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { size: 16 })
4009
+ }
4010
+ );
4011
+ }
4012
+ function UpdateCrossReferencesButton() {
4013
+ const references = useCrossReferences();
4014
+ if (!references) return null;
4015
+ return /* @__PURE__ */ jsxRuntime.jsx(
4016
+ "button",
4017
+ {
4018
+ type: "button",
4019
+ className: "native-docx-ribbon-trigger",
4020
+ "aria-label": references.labels.update,
4021
+ title: references.labels.update,
4022
+ "data-testid": "docx-update-cross-references",
4023
+ onMouseDown: (event) => event.preventDefault(),
4024
+ onClick: () => references.update(),
4025
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcw, { size: 16 })
4026
+ }
4027
+ );
4028
+ }
4029
+ function DocxContextMenuExtras() {
4030
+ const terms = useDefinedTerms();
4031
+ const references = useCrossReferences();
4032
+ if (!terms && !references) return null;
4033
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4034
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.ContextMenu.Separator, {}),
4035
+ terms && /* @__PURE__ */ jsxRuntime.jsx(
4036
+ react.DocxEditor.ContextMenu.Item,
4037
+ {
4038
+ label: "Insert defined term",
4039
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookA, { size: 14 }),
4040
+ shortcut: "@@",
4041
+ onSelect: () => terms.openPicker()
4042
+ }
4043
+ ),
4044
+ references && /* @__PURE__ */ jsxRuntime.jsx(
4045
+ react.DocxEditor.ContextMenu.Item,
4046
+ {
4047
+ label: references.labels.insert,
4048
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { size: 14 }),
4049
+ onSelect: () => references.openDialog()
4050
+ }
4051
+ )
4052
+ ] });
4053
+ }
3031
4054
 
3032
4055
  // src/docx/layout/presets.ts
3033
4056
  var TWIPS_PER_INCH = 1440;
@@ -3240,7 +4263,7 @@ function Breaks() {
3240
4263
  }
3241
4264
  function LayoutButtons() {
3242
4265
  const { pageSetup, apply } = react.usePageSetup();
3243
- const [dialog, setDialog] = React3.useState(false);
4266
+ const [dialog, setDialog] = React4.useState(false);
3244
4267
  const props = { setup: pageSetup, apply, openDialog: () => setDialog(true) };
3245
4268
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3246
4269
  /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-margins", label: "Margins", children: /* @__PURE__ */ jsxRuntime.jsx(Margins, { ...props }) }),
@@ -3434,7 +4457,7 @@ function TableButtons() {
3434
4457
  ] });
3435
4458
  }
3436
4459
  var CAPTION_LABELS = ["Figure", "Table", "Equation"];
3437
- var CAPTION_STYLES = chunkAOFATOT3_cjs.stylesXml(
4460
+ var CAPTION_STYLES = chunk2A4MDHJR_cjs.stylesXml(
3438
4461
  "",
3439
4462
  '<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="paragraph" w:styleId="Caption"><w:name w:val="caption"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="35"/><w:unhideWhenUsed/><w:qFormat/><w:pPr><w:spacing w:after="200" w:line="240" w:lineRule="auto"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val="44546A"/><w:sz w:val="18"/><w:szCs w:val="18"/></w:rPr></w:style>'
3440
4463
  );
@@ -3462,9 +4485,9 @@ function countSeqFields(root, label, throughId) {
3462
4485
  return count;
3463
4486
  }
3464
4487
  function captionParagraphXml(label, number, text) {
3465
- const run = (value) => `<w:r><w:t xml:space="preserve">${chunkAOFATOT3_cjs.esc(value)}</w:t></w:r>`;
4488
+ const run2 = (value) => `<w:r><w:t xml:space="preserve">${chunk2A4MDHJR_cjs.esc(value)}</w:t></w:r>`;
3466
4489
  const rest = text.trim() ? `: ${text.trim()}` : "";
3467
- return `<w:p><w:pPr><w:pStyle w:val="Caption"/></w:pPr>${run(`${label} `)}<w:fldSimple w:instr=" SEQ ${chunkAOFATOT3_cjs.esc(label)} \\* ARABIC "><w:r><w:t>${number}</w:t></w:r></w:fldSimple>${rest ? run(rest) : ""}</w:p>`;
4490
+ return `<w:p><w:pPr><w:pStyle w:val="Caption"/></w:pPr>${run2(`${label} `)}<w:fldSimple w:instr=" SEQ ${chunk2A4MDHJR_cjs.esc(label)} \\* ARABIC "><w:r><w:t>${number}</w:t></w:r></w:fldSimple>${rest ? run2(rest) : ""}</w:p>`;
3468
4491
  }
3469
4492
  function base642(bytes) {
3470
4493
  let binary = "";
@@ -3473,8 +4496,8 @@ function base642(bytes) {
3473
4496
  return btoa(binary);
3474
4497
  }
3475
4498
  function captionFragmentHtml(label, number, text, revision) {
3476
- const untracked = chunkAOFATOT3_cjs.docxPackage({
3477
- document: chunkAOFATOT3_cjs.documentXml(captionParagraphXml(label, number, text)),
4499
+ const untracked = chunk2A4MDHJR_cjs.docxPackage({
4500
+ document: chunk2A4MDHJR_cjs.documentXml(captionParagraphXml(label, number, text)),
3478
4501
  styles: CAPTION_STYLES,
3479
4502
  title: "Caption"
3480
4503
  });
@@ -3547,9 +4570,9 @@ function insertCaption(editor, label, text, track) {
3547
4570
  function CaptionButton({ defaultLabel = "Figure" }) {
3548
4571
  const editor = react.useDocxEditor();
3549
4572
  const track = useTrackedOrNoted();
3550
- const [label, setLabel] = React3.useState(defaultLabel);
3551
- const [text, setText] = React3.useState("");
3552
- const [error, setError] = React3.useState("");
4573
+ const [label, setLabel] = React4.useState(defaultLabel);
4574
+ const [text, setText] = React4.useState("");
4575
+ const [error, setError] = React4.useState("");
3553
4576
  return /* @__PURE__ */ jsxRuntime.jsx(RibbonMenu, { label: "Insert caption", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Captions, { size: 16 }), testId: "docx-insert-caption", children: (close) => /* @__PURE__ */ jsxRuntime.jsxs(
3554
4577
  "form",
3555
4578
  {
@@ -3668,9 +4691,9 @@ function tableCells(root, paragraphId) {
3668
4691
  }
3669
4692
  function TableTabKeys({ scope }) {
3670
4693
  const editor = react.useDocxEditor();
3671
- const latest = React3.useRef(editor);
4694
+ const latest = React4.useRef(editor);
3672
4695
  latest.current = editor;
3673
- React3.useEffect(() => {
4696
+ React4.useEffect(() => {
3674
4697
  const element = scope.current;
3675
4698
  if (!element) return;
3676
4699
  const onKeyDown = (event) => {
@@ -3816,7 +4839,7 @@ function covered(room, vector, receipt) {
3816
4839
  }
3817
4840
  return true;
3818
4841
  }
3819
- var EditorBoundary = class extends React3__default.default.Component {
4842
+ var EditorBoundary = class extends React4__default.default.Component {
3820
4843
  state = {};
3821
4844
  static getDerivedStateFromError(error) {
3822
4845
  return { error };
@@ -3829,8 +4852,8 @@ var EditorBoundary = class extends React3__default.default.Component {
3829
4852
  }
3830
4853
  };
3831
4854
  function DocxParticipants({ session }) {
3832
- const [people, setPeople] = React3.useState([]);
3833
- React3.useEffect(() => {
4855
+ const [people, setPeople] = React4.useState([]);
4856
+ React4.useEffect(() => {
3834
4857
  if (!session) return;
3835
4858
  setPeople(session.participants());
3836
4859
  return session.subscribeParticipants(setPeople);
@@ -3859,7 +4882,7 @@ function DocxRibbon({
3859
4882
  badge,
3860
4883
  imageGeneration
3861
4884
  }) {
3862
- const [selected, setTab] = React3.useState("Home");
4885
+ const [selected, setTab] = React4.useState("Home");
3863
4886
  const contextual = useContextualTabs(selected);
3864
4887
  useGenerateImageTarget();
3865
4888
  const tab = contextual.shown;
@@ -3908,11 +4931,16 @@ function DocxRibbon({
3908
4931
  /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-page-break", label: "Page break", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Button, { slotId: "insert.pageBreak" }) }),
3909
4932
  /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-link", label: "Link", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Link, {}) }),
3910
4933
  /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-defined-term", label: "Defined term", children: /* @__PURE__ */ jsxRuntime.jsx(DefinedTermButtons, {}) }),
3911
- /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-quick-parts", label: "Quick Parts", children: /* @__PURE__ */ jsxRuntime.jsx(QuickParts, {}) })
4934
+ /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-quick-parts", label: "Quick Parts", children: /* @__PURE__ */ jsxRuntime.jsx(QuickParts, {}) }),
4935
+ /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsxRuntime.jsx(CrossReferenceButton, {}) })
3912
4936
  ] }),
3913
4937
  /* @__PURE__ */ jsxRuntime.jsx(LayoutTabContent, { tab }),
3914
4938
  tab === "Design" && /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "design-house-template", label: "House template", children: /* @__PURE__ */ jsxRuntime.jsx(HouseTemplatePanel, {}) }),
3915
- tab === "References" && /* @__PURE__ */ jsxRuntime.jsx(NoteButtons, {}),
4939
+ tab === "References" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4940
+ /* @__PURE__ */ jsxRuntime.jsx(NoteButtons, {}),
4941
+ /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "references-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsxRuntime.jsx(CrossReferenceButton, {}) }),
4942
+ /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "references-update-cross-references", label: "Update cross-references", children: /* @__PURE__ */ jsxRuntime.jsx(UpdateCrossReferencesButton, {}) })
4943
+ ] }),
3916
4944
  tab === "Review" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3917
4945
  /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "review-editing-mode", label: "Editing mode", priority: 10, children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.EditingMode, {}) }),
3918
4946
  /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "review-comments", label: "Comments", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Comments, {}) }),
@@ -3935,18 +4963,18 @@ function NativeDocxEditor({
3935
4963
  stream,
3936
4964
  adapter
3937
4965
  }) {
3938
- const [ready, setReady] = React3.useState(), [error, setError] = React3.useState(""), [retry, setRetry] = React3.useState(0);
3939
- const [status, setStatus] = React3.useState("Connecting\u2026"), [dirty, setDirty] = React3.useState(false), [saving, setSaving] = React3.useState(false), [offline, setOffline] = React3.useState(false);
3940
- const revision = React3.useRef(0);
3941
- const stageRef = React3.useRef(null), fitCleanup = React3.useRef(void 0);
3942
- const ref = React3.useRef(null), dirtyRef = React3.useRef(false), draftTimer = React3.useRef(void 0);
4966
+ const [ready, setReady] = React4.useState(), [error, setError] = React4.useState(""), [retry, setRetry] = React4.useState(0);
4967
+ const [status, setStatus] = React4.useState("Connecting\u2026"), [dirty, setDirty] = React4.useState(false), [saving, setSaving] = React4.useState(false), [offline, setOffline] = React4.useState(false);
4968
+ const revision = React4.useRef(0);
4969
+ const stageRef = React4.useRef(null), fitCleanup = React4.useRef(void 0);
4970
+ const ref = React4.useRef(null), dirtyRef = React4.useRef(false), draftTimer = React4.useRef(void 0);
3943
4971
  const isDraft = draftContent !== void 0;
3944
- const streamRef = React3.useRef(stream);
4972
+ const streamRef = React4.useRef(stream);
3945
4973
  streamRef.current = stream;
3946
- const streamWriter = React3.useRef(null);
3947
- const streamFinished = React3.useRef(false);
3948
- const streamTimer = React3.useRef(void 0);
3949
- const [streamAttempt, setStreamAttempt] = React3.useState(0);
4974
+ const streamWriter = React4.useRef(null);
4975
+ const streamFinished = React4.useRef(false);
4976
+ const streamTimer = React4.useRef(void 0);
4977
+ const [streamAttempt, setStreamAttempt] = React4.useState(0);
3950
4978
  function updateStream() {
3951
4979
  const current = streamRef.current;
3952
4980
  if (!current || !streamWriter.current || streamFinished.current) return;
@@ -3962,7 +4990,7 @@ function NativeDocxEditor({
3962
4990
  );
3963
4991
  }
3964
4992
  }
3965
- React3.useEffect(() => {
4993
+ React4.useEffect(() => {
3966
4994
  if (!streamRef.current) return;
3967
4995
  if (!streamRef.current.busy) {
3968
4996
  clearTimeout(streamTimer.current);
@@ -3975,8 +5003,8 @@ function NativeDocxEditor({
3975
5003
  }, 120);
3976
5004
  }
3977
5005
  }, [stream?.content, stream?.busy, stream?.error, streamAttempt]);
3978
- React3.useEffect(() => () => clearTimeout(streamTimer.current), []);
3979
- React3.useEffect(() => {
5006
+ React4.useEffect(() => () => clearTimeout(streamTimer.current), []);
5007
+ React4.useEffect(() => {
3980
5008
  let cancelled = false;
3981
5009
  let room;
3982
5010
  const cleanups = [];
@@ -4104,7 +5132,7 @@ function NativeDocxEditor({
4104
5132
  room?.destroy();
4105
5133
  };
4106
5134
  }, [documentId, isDraft, snapshot, retry]);
4107
- React3.useEffect(() => {
5135
+ React4.useEffect(() => {
4108
5136
  adapter.onDirtyChange?.(dirty);
4109
5137
  const beforeUnload = (e) => {
4110
5138
  if (dirtyRef.current) e.preventDefault();
@@ -4116,6 +5144,7 @@ function NativeDocxEditor({
4116
5144
  };
4117
5145
  }, [dirty]);
4118
5146
  async function exportDocument() {
5147
+ runBeforeSave(ref.current);
4119
5148
  const data = await ref.current?.save();
4120
5149
  if (!data) return;
4121
5150
  const url = URL.createObjectURL(
@@ -4129,7 +5158,7 @@ function NativeDocxEditor({
4129
5158
  a.click();
4130
5159
  setTimeout(() => URL.revokeObjectURL(url), 5e3);
4131
5160
  }
4132
- React3.useLayoutEffect(() => {
5161
+ React4.useLayoutEffect(() => {
4133
5162
  const editor = ref.current;
4134
5163
  return () => {
4135
5164
  if (isDraft && editor && dirtyRef.current)
@@ -4142,6 +5171,7 @@ function NativeDocxEditor({
4142
5171
  async function saveVersion() {
4143
5172
  if (!ready || saving || stream) return;
4144
5173
  setSaving(true);
5174
+ runBeforeSave(ref.current);
4145
5175
  const atRevision = revision.current;
4146
5176
  try {
4147
5177
  const result = isDraft ? await (async () => {
@@ -4265,7 +5295,7 @@ function NativeDocxEditor({
4265
5295
  load: adapter.definitions,
4266
5296
  editable: !stream && !snapshot && ready.canEdit,
4267
5297
  notify: adapter.notify,
4268
- children: /* @__PURE__ */ jsxRuntime.jsxs(
5298
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4269
5299
  HouseTemplateProvider,
4270
5300
  {
4271
5301
  enabled: !stream,
@@ -4273,67 +5303,76 @@ function NativeDocxEditor({
4273
5303
  documentId: isDraft || snapshot ? void 0 : documentId,
4274
5304
  editable: !stream && !snapshot && ready.canEdit,
4275
5305
  notify: adapter.notify,
4276
- children: [
4277
- /* @__PURE__ */ jsxRuntime.jsx(
4278
- react.DocxEditor.RevisionMarkup,
4279
- {
4280
- insertions: { mark: "underline", color: "blue" },
4281
- deletions: { mark: "strikethrough", color: "red" },
4282
- movedFrom: { mark: "doubleStrikethrough", color: "green" },
4283
- movedTo: { mark: "doubleUnderline", color: "green" },
4284
- trackMoves: true
4285
- }
4286
- ),
4287
- !stream && /* @__PURE__ */ jsxRuntime.jsx(
4288
- DocxRibbon,
4289
- {
4290
- onSave: () => void saveVersion(),
4291
- imageGeneration: adapter.imageGeneration && {
4292
- notify: adapter.notify,
4293
- ...adapter.imageGeneration
4294
- },
4295
- badge: (
4296
- // Says the document is shared live, in place of a title row above the ribbon.
4297
- ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
5306
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
5307
+ CrossReferencesProvider,
5308
+ {
5309
+ editable: !stream && !snapshot && ready.canEdit,
5310
+ references: adapter.references,
5311
+ documentId,
5312
+ notify: adapter.notify,
5313
+ children: [
5314
+ /* @__PURE__ */ jsxRuntime.jsx(
5315
+ react.DocxEditor.RevisionMarkup,
5316
+ {
5317
+ insertions: { mark: "underline", color: "blue" },
5318
+ deletions: { mark: "strikethrough", color: "red" },
5319
+ movedFrom: { mark: "doubleStrikethrough", color: "green" },
5320
+ movedTo: { mark: "doubleUnderline", color: "green" },
5321
+ trackMoves: true
5322
+ }
5323
+ ),
5324
+ !stream && /* @__PURE__ */ jsxRuntime.jsx(
5325
+ DocxRibbon,
5326
+ {
5327
+ onSave: () => void saveVersion(),
5328
+ imageGeneration: adapter.imageGeneration && {
5329
+ notify: adapter.notify,
5330
+ ...adapter.imageGeneration
5331
+ },
5332
+ badge: (
5333
+ // Says the document is shared live, in place of a title row above the ribbon.
5334
+ ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
5335
+ )
5336
+ }
5337
+ ),
5338
+ !stream && /* @__PURE__ */ jsxRuntime.jsx(WordShortcuts, { scope: stageRef }),
5339
+ !stream && /* @__PURE__ */ jsxRuntime.jsx(TableTabKeys, { scope: stageRef }),
5340
+ /* @__PURE__ */ jsxRuntime.jsxs(
5341
+ "div",
5342
+ {
5343
+ className: "native-docx-stage",
5344
+ ref: stageRef,
5345
+ onMouseDownCapture: (event) => {
5346
+ if (event.button === 2 && ref.current?.getSelectionPlacement())
5347
+ event.preventDefault();
5348
+ },
5349
+ children: [
5350
+ /* @__PURE__ */ jsxRuntime.jsxs(react.DocxEditor.Viewport, { className: "native-docx-viewport", children: [
5351
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Content, {}),
5352
+ /* @__PURE__ */ jsxRuntime.jsx(
5353
+ DocxMentions,
5354
+ {
5355
+ initialCommentId,
5356
+ mentions: adapter.mentions,
5357
+ notify: adapter.notify,
5358
+ getAgentStatus: adapter.getAgentStatus,
5359
+ requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
5360
+ children: /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(DocxCommentActivity, {}) }) })
5361
+ }
5362
+ ),
5363
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HeaderFooterChrome, {}),
5364
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.NotesChrome, {}),
5365
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Equation, {}),
5366
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HyperLink, {}),
5367
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.ContextMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(DocxContextMenuExtras, {}) })
5368
+ ] }),
5369
+ /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.PageNumber, {})
5370
+ ]
5371
+ }
4298
5372
  )
4299
- }
4300
- ),
4301
- !stream && /* @__PURE__ */ jsxRuntime.jsx(WordShortcuts, { scope: stageRef }),
4302
- !stream && /* @__PURE__ */ jsxRuntime.jsx(TableTabKeys, { scope: stageRef }),
4303
- /* @__PURE__ */ jsxRuntime.jsxs(
4304
- "div",
4305
- {
4306
- className: "native-docx-stage",
4307
- ref: stageRef,
4308
- onMouseDownCapture: (event) => {
4309
- if (event.button === 2 && ref.current?.getSelectionPlacement())
4310
- event.preventDefault();
4311
- },
4312
- children: [
4313
- /* @__PURE__ */ jsxRuntime.jsxs(react.DocxEditor.Viewport, { className: "native-docx-viewport", children: [
4314
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Content, {}),
4315
- /* @__PURE__ */ jsxRuntime.jsx(
4316
- DocxMentions,
4317
- {
4318
- initialCommentId,
4319
- mentions: adapter.mentions,
4320
- notify: adapter.notify,
4321
- getAgentStatus: adapter.getAgentStatus,
4322
- requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
4323
- children: /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(DocxCommentActivity, {}) }) })
4324
- }
4325
- ),
4326
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HeaderFooterChrome, {}),
4327
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.NotesChrome, {}),
4328
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Equation, {}),
4329
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HyperLink, {}),
4330
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.ContextMenu, {})
4331
- ] }),
4332
- /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.PageNumber, {})
4333
- ]
4334
- }
4335
- )
4336
- ]
5373
+ ]
5374
+ }
5375
+ )
4337
5376
  }
4338
5377
  )
4339
5378
  }
@@ -4433,6 +5472,9 @@ async function loadFonts(baseUrl) {
4433
5472
  }
4434
5473
 
4435
5474
  exports.BUILTIN_TEMPLATE_NAME = BUILTIN_TEMPLATE_NAME;
5475
+ exports.CrossReferenceDialog = CrossReferenceDialog;
5476
+ exports.CrossReferencesProvider = CrossReferencesProvider;
5477
+ exports.DEFAULT_CROSS_REFERENCES_LABELS = DEFAULT_CROSS_REFERENCES_LABELS;
4436
5478
  exports.DEFAULT_DEFINED_TERMS_LABELS = DEFAULT_DEFINED_TERMS_LABELS;
4437
5479
  exports.DEFINED_TERM_TRIGGER = DEFINED_TERM_TRIGGER;
4438
5480
  exports.DefinedTermsProvider = DefinedTermsProvider;
@@ -4444,24 +5486,33 @@ exports.DocxParticipants = DocxParticipants;
4444
5486
  exports.DocxRibbon = DocxRibbon;
4445
5487
  exports.GenerateImageButton = GenerateImageButton;
4446
5488
  exports.HouseTemplateProvider = HouseTemplateProvider;
5489
+ exports.LinkHoverCard = LinkHoverCard;
4447
5490
  exports.NativeDocxEditor = NativeDocxEditor;
4448
5491
  exports.builtinHouseTemplate = builtinHouseTemplate;
4449
5492
  exports.contentPath = contentPath;
4450
5493
  exports.editorPort = editorPort;
4451
5494
  exports.findDefinitionsSection = findDefinitionsSection;
5495
+ exports.insertCrossReference = insertCrossReference;
4452
5496
  exports.insertDefinedTerm = insertDefinedTerm;
5497
+ exports.insertDocumentReference = insertDocumentReference;
5498
+ exports.listTargets = listTargets;
4453
5499
  exports.loadDocxFonts = loadDocxFonts;
4454
5500
  exports.normalizeDocxExport = normalizeDocxExport;
5501
+ exports.paragraphNumber = paragraphNumber;
5502
+ exports.referenceText = referenceText;
5503
+ exports.referencesPort = referencesPort;
4455
5504
  exports.resolveHouseTemplate = resolveHouseTemplate;
4456
5505
  exports.reviewModule = reviewModule;
5506
+ exports.shortTitle = shortTitle;
4457
5507
  exports.structuralPort = structuralPort;
4458
5508
  exports.templateFileName = templateFileName;
4459
5509
  exports.trackedOrNoted = trackedOrNoted;
5510
+ exports.useCrossReferences = useCrossReferences;
4460
5511
  exports.useDefinedTerms = useDefinedTerms;
4461
5512
  exports.useHouseTemplate = useHouseTemplate;
4462
5513
  exports.useReview = useReview;
4463
5514
  exports.useReviewItem = useReviewItem;
4464
5515
  exports.useTrackedOrNoted = useTrackedOrNoted;
4465
5516
  exports.withDirectEditing = withDirectEditing;
4466
- //# sourceMappingURL=chunk-O33EBMIX.cjs.map
4467
- //# sourceMappingURL=chunk-O33EBMIX.cjs.map
5517
+ //# sourceMappingURL=chunk-ZWWN4CUL.cjs.map
5518
+ //# sourceMappingURL=chunk-ZWWN4CUL.cjs.map