@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,15 +1,17 @@
1
1
  "use client";
2
- import { stylesXml, definitionBookmark, groupDefinitions, definitionLabels, filterTermGroups, esc, docxPackage, documentXml, definitionIdOfBookmark, compareTerms, parseDefinition } from './chunk-D3QPYKZG.js';
2
+ import { FactPassageItem } from './chunk-HFZ45FD3.js';
3
+ import { stylesXml, definitionBookmark, groupDefinitions, definitionLabels, filterTermGroups, esc, hyperlinkRelationship, docxPackage, documentXml, definitionIdOfBookmark, compareTerms, parseDefinition } from './chunk-EPHGD4YV.js';
3
4
  import { filterMentionCandidates, MentionMenu, findMentionQuery, listOptionId, extractMentions, useListKeyNav } from './chunk-AA3PT6KR.js';
4
5
  import { unzipSync, strFromU8, strToU8, zipSync } from 'fflate';
5
6
  import { collectReviewItems, revisionItemsOf } from '@docx-editor.dev/core/store';
6
- import React3, { createContext, useContext, useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo, useSyncExternalStore } from 'react';
7
+ import React4, { createContext, useContext, useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo, useSyncExternalStore } from 'react';
7
8
  import { useDocxEditor, ReviewRailContext, useEditorSnapshot, useEditorState, useChromeTranslate, DocxEditor, createFontSource, useParagraphStyle, normalizeImageBytes, usePageSetup, useEditorCommand } from '@docx-editor.dev/react';
8
- import { AiMarkdown, Dialog, DialogContent, DialogHeader, DialogTitle, cn, splitMarkdownBlocks } from '@arbidocs/react/ui';
9
- import { MessageSquarePlus, MessageSquare, PencilLine, ChevronLeft, ChevronRight, X, ChevronUp, ChevronDown, CheckCheck, RotateCcw, CircleCheck, Trash2, Check, SendHorizontal, Loader2, Sparkles, Type, Pilcrow, UsersRound, RefreshCw, WifiOff, Download, Save, Ellipsis, BookA, Blocks, Superscript, NotebookText, Columns2, Settings2, BetweenHorizontalStart, BetweenHorizontalEnd, BetweenVerticalStart, BetweenVerticalEnd, Merge, Split, Heading, AlignVerticalJustifyStart, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, RotateCw, FlipHorizontal2, FlipVertical2, Scaling, RectangleVertical, RectangleHorizontal, FileText, SeparatorHorizontal, Captions } from 'lucide-react';
9
+ import { AiMarkdown, Dialog, DialogContent, DialogHeader, DialogTitle, cn, DialogDescription, Button, DialogFooter, Tabs, TabsList, TabsTrigger, TabsContent, Input, splitMarkdownBlocks } from '@arbidocs/react/ui';
10
+ import { MessageSquarePlus, MessageSquare, PencilLine, ChevronLeft, ChevronRight, X, ChevronUp, ChevronDown, CheckCheck, RotateCcw, CircleCheck, Trash2, Check, SendHorizontal, Loader2, Sparkles, Type, Pilcrow, UsersRound, RefreshCw, WifiOff, Download, Save, Ellipsis, BookA, Blocks, Link2, Superscript, NotebookText, RefreshCcw, Columns2, Settings2, BetweenHorizontalStart, BetweenHorizontalEnd, BetweenVerticalStart, BetweenVerticalEnd, Merge, Split, Heading, AlignVerticalJustifyStart, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, RotateCw, FlipHorizontal2, FlipVertical2, Scaling, RectangleVertical, RectangleHorizontal, FileText, SeparatorHorizontal, Captions } from 'lucide-react';
10
11
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
11
12
  import { createPortal } from 'react-dom';
12
13
  import { defaultLegalTemplate, listBuildingBlocks, attachedTemplateOf, linkedLevelStyles, styleDivergence, buildingBlockFragment, fragmentClipboardHtml, trackInsertion, newFromTemplate } from '@arbidocs/coedit/template';
14
+ import { resolveNumberingLevel, resolveStoryListItems, buildStyleCascadeTable, withNumberingStyleLinks, buildNumberingIndex } from '@docx-editor.dev/core/layout';
13
15
  import { executeImageCommand } from '@docx-editor.dev/core/editor';
14
16
  import { renderToStaticMarkup } from 'react-dom/server';
15
17
  import * as Y from 'yjs';
@@ -896,7 +898,7 @@ function DocxCommentActivity() {
896
898
  const thread = review.items.filter(
897
899
  (entry) => entry.kind === "comment" && (entry.item.id === commentId || entry.parentId === commentId)
898
900
  );
899
- const statuses = Object.entries(activity).filter(([, run]) => run.commentId === commentId);
901
+ const statuses = Object.entries(activity).filter(([, run2]) => run2.commentId === commentId);
900
902
  const labels = {
901
903
  delivering: "Delivering mention\u2026",
902
904
  queued: "Queued\u2026",
@@ -908,18 +910,18 @@ function DocxCommentActivity() {
908
910
  unknown: "Status unavailable"
909
911
  };
910
912
  return /* @__PURE__ */ jsxs("div", { className: "native-docx-comment-extra", "data-review-selectable": "", children: [
911
- statuses.map(([id, run]) => /* @__PURE__ */ jsxs(
913
+ statuses.map(([id, run2]) => /* @__PURE__ */ jsxs(
912
914
  "div",
913
915
  {
914
916
  role: "status",
915
917
  "data-testid": "docx-comment-agent-status",
916
- "data-status": run.status,
918
+ "data-status": run2.status,
917
919
  className: "native-docx-comment-activity",
918
920
  children: [
919
- ["delivering", "queued", "in_progress"].includes(run.status) && /* @__PURE__ */ jsx("span", { className: "native-docx-agent-spinner", "aria-hidden": "true" }),
920
- run.label,
921
+ ["delivering", "queued", "in_progress"].includes(run2.status) && /* @__PURE__ */ jsx("span", { className: "native-docx-agent-spinner", "aria-hidden": "true" }),
922
+ run2.label,
921
923
  ": ",
922
- labels[run.status]
924
+ labels[run2.status]
923
925
  ]
924
926
  },
925
927
  id
@@ -947,10 +949,10 @@ function DocxCommentActivity() {
947
949
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: entry.author || "Reviewer" }),
948
950
  /* @__PURE__ */ jsx("div", { "data-testid": "docx-full-comment-text", children: /* @__PURE__ */ jsx(AiMarkdown, { allowHtml: false, children: commentText(entry) }) })
949
951
  ] }, entry.key)),
950
- statuses.map(([id, run]) => /* @__PURE__ */ jsxs("p", { role: "status", className: "text-sm", children: [
951
- run.label,
952
+ statuses.map(([id, run2]) => /* @__PURE__ */ jsxs("p", { role: "status", className: "text-sm", children: [
953
+ run2.label,
952
954
  ": ",
953
- labels[run.status]
955
+ labels[run2.status]
954
956
  ] }, id))
955
957
  ]
956
958
  }
@@ -1262,9 +1264,19 @@ function DocxMentions({
1262
1264
  ) });
1263
1265
  }
1264
1266
  var DEFINED_TERM_STYLE = "DefinedTerm";
1265
- var FRAGMENT_STYLES = stylesXml(
1267
+ var CROSS_REFERENCE_STYLE = "CrossReference";
1268
+ var BROKEN_CROSS_REFERENCE_STYLE = "CrossReferenceBroken";
1269
+ var CHARACTER_STYLES = {
1270
+ [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>`,
1271
+ [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>`,
1272
+ [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>`
1273
+ };
1274
+ function stylesUsed(body) {
1275
+ return [...new Set([...body.matchAll(/<w:rStyle w:val="([^"]+)"/g)].map((m) => m[1]))];
1276
+ }
1277
+ var fragmentStyles = (ids) => stylesXml(
1266
1278
  "",
1267
- `<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>`
1279
+ `<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("")}`
1268
1280
  );
1269
1281
  var textRun = (text, props = "") => `<w:r>${props ? `<w:rPr>${props}</w:rPr>` : ""}<w:t xml:space="preserve">${esc(text)}</w:t></w:r>`;
1270
1282
  function definitionTooltip(definition) {
@@ -1292,11 +1304,16 @@ function base64(bytes) {
1292
1304
  binary += String.fromCharCode(...bytes.subarray(i, i + 32768));
1293
1305
  return btoa(binary);
1294
1306
  }
1295
- function fragmentHtml(body, covered2, revision) {
1307
+ function fragmentHtml(body, covered2, {
1308
+ revision,
1309
+ relationships,
1310
+ styles = stylesUsed(body)
1311
+ } = {}) {
1296
1312
  const untracked = docxPackage({
1297
1313
  document: documentXml(body),
1298
- styles: FRAGMENT_STYLES,
1299
- title: "Defined terms"
1314
+ styles: fragmentStyles(styles),
1315
+ title: "Defined terms",
1316
+ relationships
1300
1317
  });
1301
1318
  const bytes = revision ? trackInsertion(untracked, revision, covered2) : untracked;
1302
1319
  return `<div data-docx-fragment="${base64(bytes)}" data-docx-fragment-end="${covered2 ? "covered" : "open"}"></div>`;
@@ -1395,9 +1412,93 @@ function definitionOfAnchor(anchor, definitions) {
1395
1412
  const id = definitionIdOfBookmark(anchor.replace(/^#/, ""));
1396
1413
  return id ? definitions.get(id) : void 0;
1397
1414
  }
1415
+ function LinkHoverCard({
1416
+ root,
1417
+ matches,
1418
+ resolve,
1419
+ onFirstHover,
1420
+ testId
1421
+ }) {
1422
+ const [card, setCard] = useState(null);
1423
+ const hovered = useRef(false);
1424
+ const latest = useRef({ matches, onFirstHover });
1425
+ latest.current = { matches, onFirstHover };
1426
+ useEffect(() => {
1427
+ if (!root) return;
1428
+ const over = (event) => {
1429
+ const link = event.target?.closest?.(
1430
+ "a.docx-hyperlink"
1431
+ );
1432
+ const href = link?.getAttribute("href") ?? "";
1433
+ if (!link || !href || !latest.current.matches(href, link)) return;
1434
+ if (!hovered.current) {
1435
+ hovered.current = true;
1436
+ latest.current.onFirstHover?.();
1437
+ }
1438
+ const title = link.getAttribute("title");
1439
+ if (title) {
1440
+ link.dataset.hoverTitle = title;
1441
+ link.removeAttribute("title");
1442
+ }
1443
+ const rect = link.getBoundingClientRect();
1444
+ setCard({
1445
+ left: rect.left,
1446
+ top: rect.bottom + 6,
1447
+ href,
1448
+ fallback: link.dataset.hoverTitle ?? ""
1449
+ });
1450
+ };
1451
+ const out = (event) => {
1452
+ const link = event.target?.closest?.("a.docx-hyperlink");
1453
+ if (link && !link.contains(event.relatedTarget)) setCard(null);
1454
+ };
1455
+ const hide = () => setCard(null);
1456
+ root.addEventListener("mouseover", over);
1457
+ root.addEventListener("mouseout", out);
1458
+ window.addEventListener("keydown", hide, true);
1459
+ window.addEventListener("pointerdown", hide, true);
1460
+ window.addEventListener("scroll", hide, true);
1461
+ return () => {
1462
+ root.removeEventListener("mouseover", over);
1463
+ root.removeEventListener("mouseout", out);
1464
+ window.removeEventListener("keydown", hide, true);
1465
+ window.removeEventListener("pointerdown", hide, true);
1466
+ window.removeEventListener("scroll", hide, true);
1467
+ };
1468
+ }, [root]);
1469
+ if (!card) return null;
1470
+ const content = resolve(card.href);
1471
+ if (!content && !card.fallback) return null;
1472
+ return createPortal(
1473
+ /* @__PURE__ */ jsx(
1474
+ "div",
1475
+ {
1476
+ role: "tooltip",
1477
+ className: "native-docx-link-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
1478
+ style: {
1479
+ position: "fixed",
1480
+ left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
1481
+ top: card.top,
1482
+ width: 340,
1483
+ zIndex: 1e3,
1484
+ pointerEvents: "none"
1485
+ },
1486
+ "data-testid": testId,
1487
+ children: content ? /* @__PURE__ */ jsxs(Fragment, { children: [
1488
+ content.title && /* @__PURE__ */ jsx("p", { className: "font-medium", children: content.title }),
1489
+ /* @__PURE__ */ jsx("p", { className: content.title ? "mt-1 text-muted-foreground" : void 0, children: content.body }),
1490
+ content.footer && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: content.footer })
1491
+ ] }) : /* @__PURE__ */ jsx("p", { children: card.fallback })
1492
+ }
1493
+ ),
1494
+ document.body
1495
+ );
1496
+ }
1398
1497
 
1399
1498
  // src/docx/definitions/port.ts
1499
+ var WATCHED_STYLES = /* @__PURE__ */ new Set([BROKEN_CROSS_REFERENCE_STYLE]);
1400
1500
  var attr = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
1501
+ var FIELD_ATOM = "\uFFFC";
1401
1502
  var HEADING_STYLE = /^(heading|berschrift|titre|t[ií]tulo|titolo|kop)\s*\d/i;
1402
1503
  function readParagraphs(root) {
1403
1504
  const out = [];
@@ -1424,8 +1525,44 @@ function readParagraph(node, topLevel, bookmarks) {
1424
1525
  const links = [];
1425
1526
  let styleId;
1426
1527
  let outline = false;
1528
+ let fieldDepth = 0;
1529
+ const marks = [];
1530
+ let runStyle;
1531
+ const fields = [];
1532
+ let current = null;
1533
+ const field = (c) => {
1534
+ const type = attr(c, "fldCharType");
1535
+ if (type === "begin") {
1536
+ if (fieldDepth === 0) {
1537
+ current = { offset: text.length, instruction: "", result: "", inResult: false };
1538
+ text += FIELD_ATOM;
1539
+ }
1540
+ fieldDepth++;
1541
+ } else if (type === "separate" && fieldDepth === 1 && current) current.inResult = true;
1542
+ else if (type === "end") {
1543
+ fieldDepth = Math.max(0, fieldDepth - 1);
1544
+ if (fieldDepth === 0 && current) {
1545
+ const { offset, instruction, result } = current;
1546
+ fields.push({ offset, instruction: instruction.trim(), result });
1547
+ current = null;
1548
+ }
1549
+ }
1550
+ };
1427
1551
  const walk = (n, link) => {
1428
1552
  for (const c of n.children ?? []) {
1553
+ if (c.localName === "fldChar") {
1554
+ field(c);
1555
+ continue;
1556
+ }
1557
+ if (c.localName === "fldSimple") {
1558
+ if (fieldDepth === 0) text += FIELD_ATOM;
1559
+ continue;
1560
+ }
1561
+ if (c.localName === "instrText") {
1562
+ if (fieldDepth === 1 && current)
1563
+ current.instruction += (c.children ?? []).map((t) => t.value ?? "").join("");
1564
+ continue;
1565
+ }
1429
1566
  if (c.kind === "paragraphProperties" || c.localName === "pPr") {
1430
1567
  for (const p of c.children ?? []) {
1431
1568
  if (p.localName === "pStyle") styleId = attr(p, "val");
@@ -1434,6 +1571,14 @@ function readParagraph(node, topLevel, bookmarks) {
1434
1571
  continue;
1435
1572
  }
1436
1573
  if (c.localName === "delText" || c.localName === "del" || c.localName === "rPr") continue;
1574
+ if (c.localName === "r") {
1575
+ const rStyle = c.children?.find((x) => x.localName === "rPr")?.children?.find((x) => x.localName === "rStyle");
1576
+ const watched = rStyle && attr(rStyle, "val");
1577
+ runStyle = watched && WATCHED_STYLES.has(watched) ? watched : void 0;
1578
+ walk(c, link);
1579
+ runStyle = void 0;
1580
+ continue;
1581
+ }
1437
1582
  if (c.localName === "bookmarkStart") {
1438
1583
  const name = attr(c, "name");
1439
1584
  if (name) bookmarks.push(name);
@@ -1447,11 +1592,22 @@ function readParagraph(node, topLevel, bookmarks) {
1447
1592
  continue;
1448
1593
  }
1449
1594
  if (c.kind === "textValue") {
1595
+ if (fieldDepth > 0) {
1596
+ const open = current;
1597
+ if (fieldDepth === 1 && open?.inResult) open.result += c.value ?? "";
1598
+ continue;
1599
+ }
1600
+ if (runStyle && c.value) {
1601
+ const last = marks[marks.length - 1];
1602
+ if (last && last.styleId === runStyle && last.offset + last.text.length === text.length)
1603
+ last.text += c.value;
1604
+ else marks.push({ styleId: runStyle, offset: text.length, text: c.value });
1605
+ }
1450
1606
  text += c.value ?? "";
1451
1607
  if (link) link.text += c.value ?? "";
1452
1608
  continue;
1453
1609
  }
1454
- if (c.localName === "tab") text += " ";
1610
+ if (c.localName === "tab" && fieldDepth === 0) text += " ";
1455
1611
  walk(c, link);
1456
1612
  }
1457
1613
  };
@@ -1463,9 +1619,20 @@ function readParagraph(node, topLevel, bookmarks) {
1463
1619
  styleId,
1464
1620
  topLevel,
1465
1621
  bookmarks,
1466
- links
1622
+ links,
1623
+ ...fields.length ? { fields } : {},
1624
+ ...marks.length ? { marks } : {}
1467
1625
  };
1468
1626
  }
1627
+ function documentStyleIds(root) {
1628
+ const ids = /* @__PURE__ */ new Set();
1629
+ for (const style of root?.children ?? [])
1630
+ if (style.localName === "style") {
1631
+ const id = attr(style, "styleId");
1632
+ if (id) ids.add(id);
1633
+ }
1634
+ return ids;
1635
+ }
1469
1636
  function editorPort(editor, revision) {
1470
1637
  const surface = () => {
1471
1638
  const s = editor.surface;
@@ -1485,8 +1652,17 @@ function editorPort(editor, revision) {
1485
1652
  surface().setSelection({ anchor: from, head: to });
1486
1653
  surface().deleteSelection();
1487
1654
  },
1488
- paste: (body, text, covered2) => editor.exec({ type: "paste", text, html: fragmentHtml(body, covered2, revision) }).ok,
1489
- splitParagraph: () => surface().splitParagraph()
1655
+ paste: (body, text, covered2, relationships) => {
1656
+ const defined = documentStyleIds(surface().session.stylesRoot());
1657
+ const styles = stylesUsed(body).filter((id) => !defined.has(id));
1658
+ return editor.exec({
1659
+ type: "paste",
1660
+ text,
1661
+ html: fragmentHtml(body, covered2, { revision, relationships, styles })
1662
+ }).ok;
1663
+ },
1664
+ splitParagraph: () => surface().splitParagraph(),
1665
+ typeText: (text) => surface().insertPlainText(text)
1490
1666
  };
1491
1667
  }
1492
1668
  function withDirectEditing(editor, fn) {
@@ -1499,34 +1675,68 @@ function withDirectEditing(editor, fn) {
1499
1675
  if (mode === "suggesting") editor.setEditingMode("suggesting");
1500
1676
  }
1501
1677
  }
1502
- function holdCaret(editor, timeoutMs = 5e3) {
1678
+ function holdCaret(editor, { settleMs = 600, maxMs = 2e3 } = {}) {
1503
1679
  const surface = editor.surface;
1504
1680
  const selection = surface?.state().selection;
1505
1681
  if (!surface || !selection) return;
1506
- const { paragraphId, offset } = selection.head;
1507
- const paraId = surface.session.paraIdOf(paragraphId);
1682
+ const { offset } = selection.head;
1683
+ const paraId = surface.session.paraIdOf(selection.head.paragraphId);
1508
1684
  if (!paraId) return;
1685
+ let typed = "";
1509
1686
  let done = false;
1687
+ let settle;
1510
1688
  const stop = () => {
1511
1689
  done = true;
1512
1690
  offChange();
1513
- offSelection();
1514
- clearTimeout(timer);
1691
+ clearTimeout(settle);
1692
+ clearTimeout(limit);
1693
+ window.removeEventListener("keydown", key, true);
1694
+ window.removeEventListener("pointerdown", click, true);
1515
1695
  };
1516
- const restore = () => {
1696
+ const finish = () => {
1517
1697
  if (done) return;
1518
- const now = surface.state().selection;
1519
- const node = surface.session.nodeIdOf(paraId);
1520
- if (!now || !node) return;
1521
- if (now.head.offset !== offset || now.head.paragraphId !== paragraphId) return stop();
1522
- if (node === paragraphId) return;
1523
1698
  stop();
1699
+ const node = surface.session.nodeIdOf(paraId);
1700
+ if (!node) return;
1524
1701
  const point = { paragraphId: node, offset };
1525
1702
  surface.setSelection({ anchor: point, head: point });
1703
+ if (typed) surface.insertPlainText(typed);
1704
+ };
1705
+ const key = (event) => {
1706
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
1707
+ event.preventDefault();
1708
+ event.stopPropagation();
1709
+ typed += event.key;
1710
+ return;
1711
+ }
1712
+ finish();
1713
+ };
1714
+ const click = () => {
1715
+ if (typed) finish();
1716
+ else stop();
1717
+ };
1718
+ const quiet = () => {
1719
+ clearTimeout(settle);
1720
+ settle = setTimeout(finish, settleMs);
1526
1721
  };
1527
- const offChange = editor.on("change", restore);
1528
- const offSelection = editor.on("selectionChange", restore);
1529
- const timer = setTimeout(stop, timeoutMs);
1722
+ const offChange = editor.on("change", quiet);
1723
+ window.addEventListener("keydown", key, true);
1724
+ window.addEventListener("pointerdown", click, true);
1725
+ settle = setTimeout(finish, settleMs);
1726
+ const limit = setTimeout(finish, maxMs);
1727
+ }
1728
+ function preservingCaret(editor, fn) {
1729
+ const surface = editor.surface;
1730
+ const before = surface?.state().selection?.head;
1731
+ const paraId = before && surface?.session.paraIdOf(before.paragraphId);
1732
+ const result = fn();
1733
+ const node = paraId && surface?.session.nodeIdOf(paraId);
1734
+ if (before && node) {
1735
+ const point = { paragraphId: node, offset: before.offset };
1736
+ surface.setSelection({ anchor: point, head: point });
1737
+ holdCaret(editor);
1738
+ }
1739
+ return result;
1530
1740
  }
1531
1741
 
1532
1742
  // src/docx/structural/trackedOrNoted.ts
@@ -1690,19 +1900,26 @@ function DefinedTermsProvider({
1690
1900
  },
1691
1901
  [notify]
1692
1902
  );
1693
- const run = useCallback(
1903
+ const run2 = useCallback(
1694
1904
  (fn) => editor ? attempt(() => withDirectEditing(editor, fn)) : void 0,
1695
1905
  [editor, attempt]
1696
1906
  );
1907
+ const typedTrigger = (port) => {
1908
+ if (picker?.mode !== "typing") return 0;
1909
+ const caret = port.caret();
1910
+ const paragraph = caret && port.paragraphs().find((p) => p.id === caret.paragraphId);
1911
+ const match = paragraph && TRIGGER_QUERY.exec(paragraph.text.slice(0, caret.offset));
1912
+ return match ? DEFINED_TERM_TRIGGER.length + match[1].length : 0;
1913
+ };
1697
1914
  const pick = useCallback(
1698
1915
  (row) => {
1699
1916
  if (!editor || !picker || !row) return;
1700
1917
  const port = editorPort(editor);
1701
- const placed = run(() => {
1918
+ const placed = run2(() => {
1702
1919
  if (picker.mode === "search" && picker.caret) port.setCaret(picker.caret);
1703
1920
  const caret = port.caret();
1704
1921
  if (!caret) throw new Error("Place the cursor where the term should go.");
1705
- const typed = picker.mode === "typing" ? DEFINED_TERM_TRIGGER.length + picker.query.length : 0;
1922
+ const typed = typedTrigger(port);
1706
1923
  if (typed) port.deleteRange({ ...caret, offset: Math.max(0, caret.offset - typed) }, caret);
1707
1924
  return true;
1708
1925
  });
@@ -1718,7 +1935,7 @@ function DefinedTermsProvider({
1718
1935
  if (result?.addedDefinition)
1719
1936
  notify?.(`\u201C${row.definition.term}\u201D added to the Definitions section.`, "success");
1720
1937
  },
1721
- [editor, picker, run, attempt, track, notify]
1938
+ [editor, picker, run2, attempt, track, notify]
1722
1939
  );
1723
1940
  const openPicker = useCallback(
1724
1941
  (anchor) => {
@@ -1797,11 +2014,16 @@ function DefinedTermsProvider({
1797
2014
  /* @__PURE__ */ jsx("span", { ref: marker, hidden: true }),
1798
2015
  children,
1799
2016
  load && /* @__PURE__ */ jsx(
1800
- DefinedTermHover,
2017
+ LinkHoverCard,
1801
2018
  {
1802
2019
  root: viewer,
1803
- resolve: (anchor) => definitionOfAnchor(anchor, byId),
1804
- onFirstHover: firstHover
2020
+ matches: (href) => href.startsWith("#_dt_"),
2021
+ resolve: (href) => {
2022
+ const definition = definitionOfAnchor(href, byId);
2023
+ return definition ? { title: definition.term, body: definition.meaning, footer: sourceOf(definition) } : null;
2024
+ },
2025
+ onFirstHover: firstHover,
2026
+ testId: "docx-defined-term-card"
1805
2027
  }
1806
2028
  ),
1807
2029
  picker && createPortal(
@@ -1843,7 +2065,7 @@ function DefinedTermMenu({
1843
2065
  onClose,
1844
2066
  labels: l
1845
2067
  }) {
1846
- const listboxId = React3.useId();
2068
+ const listboxId = React4.useId();
1847
2069
  const element = useRef(null);
1848
2070
  const search = picker.mode === "search";
1849
2071
  useEffect(() => {
@@ -1954,83 +2176,6 @@ function DefinedTermMenu({
1954
2176
  }
1955
2177
  );
1956
2178
  }
1957
- function DefinedTermHover({
1958
- root,
1959
- resolve,
1960
- onFirstHover
1961
- }) {
1962
- const [card, setCard] = useState(null);
1963
- const hovered = useRef(false);
1964
- useEffect(() => {
1965
- if (!root) return;
1966
- const over = (event) => {
1967
- const link = event.target?.closest?.(
1968
- 'a.docx-hyperlink[data-docx-link-kind="internal"]'
1969
- );
1970
- const href = link?.getAttribute("href") ?? "";
1971
- if (!link || !href.startsWith("#_dt_")) return;
1972
- if (!hovered.current) {
1973
- hovered.current = true;
1974
- onFirstHover();
1975
- }
1976
- const title = link.getAttribute("title");
1977
- if (title) {
1978
- link.dataset.definition = title;
1979
- link.removeAttribute("title");
1980
- }
1981
- const rect = link.getBoundingClientRect();
1982
- setCard({
1983
- left: rect.left,
1984
- top: rect.bottom + 6,
1985
- anchor: href.slice(1),
1986
- fallback: link.dataset.definition ?? ""
1987
- });
1988
- };
1989
- const out = (event) => {
1990
- const link = event.target?.closest?.("a.docx-hyperlink");
1991
- if (link && !link.contains(event.relatedTarget)) setCard(null);
1992
- };
1993
- root.addEventListener("mouseover", over);
1994
- root.addEventListener("mouseout", out);
1995
- const hide = () => setCard(null);
1996
- window.addEventListener("keydown", hide, true);
1997
- window.addEventListener("pointerdown", hide, true);
1998
- window.addEventListener("scroll", hide, true);
1999
- return () => {
2000
- root.removeEventListener("mouseover", over);
2001
- root.removeEventListener("mouseout", out);
2002
- window.removeEventListener("keydown", hide, true);
2003
- window.removeEventListener("pointerdown", hide, true);
2004
- window.removeEventListener("scroll", hide, true);
2005
- };
2006
- }, [root, onFirstHover]);
2007
- if (!card) return null;
2008
- const definition = resolve(card.anchor);
2009
- return createPortal(
2010
- /* @__PURE__ */ jsx(
2011
- "div",
2012
- {
2013
- role: "tooltip",
2014
- className: "native-docx-term-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
2015
- style: {
2016
- position: "fixed",
2017
- left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
2018
- top: card.top,
2019
- width: 340,
2020
- zIndex: 1e3,
2021
- pointerEvents: "none"
2022
- },
2023
- "data-testid": "docx-defined-term-card",
2024
- children: definition ? /* @__PURE__ */ jsxs(Fragment, { children: [
2025
- /* @__PURE__ */ jsx("p", { className: "font-medium", children: definition.term }),
2026
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-muted-foreground", children: definition.meaning }),
2027
- sourceOf(definition) && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: sourceOf(definition) })
2028
- ] }) : /* @__PURE__ */ jsx("p", { children: card.fallback })
2029
- }
2030
- ),
2031
- document.body
2032
- );
2033
- }
2034
2179
  var BUILTIN_TEMPLATE_NAME = "ARBI legal template";
2035
2180
  var templateFileName = (t) => /\.(dotx|dotm|docx|docm)$/i.test(t.name) ? t.name : `${t.name}.dotx`;
2036
2181
  var builtin;
@@ -2163,6 +2308,825 @@ function HouseTemplateProvider({
2163
2308
  );
2164
2309
  return /* @__PURE__ */ jsx(HouseTemplateContext.Provider, { value: enabled ? value : null, children });
2165
2310
  }
2311
+
2312
+ // src/docx/references/numbering.ts
2313
+ var numbers = (level) => !!level && level.numFmt !== "bullet" && level.numFmt !== "none" && (level.lvlText ?? level.markerText ?? "").length > 0;
2314
+ function paragraphNumber(order, items, levelOf, paragraphId) {
2315
+ const item = items.get(paragraphId);
2316
+ if (!item || !numbers(item)) return null;
2317
+ const at = order.indexOf(paragraphId);
2318
+ const markerAt = (ilvl) => {
2319
+ if (ilvl === item.ilvl) return item.markerText;
2320
+ for (let i = at - 1; i >= 0; i--) {
2321
+ const other = items.get(order[i]);
2322
+ if (other && other.numId === item.numId && other.ilvl === ilvl) return other.markerText;
2323
+ }
2324
+ return null;
2325
+ };
2326
+ const chain = [];
2327
+ const texts = [];
2328
+ for (let u = item.ilvl; u >= 0; u--) {
2329
+ const level = levelOf(item.numId, u);
2330
+ if (!level || !numbers(level)) continue;
2331
+ if (u !== item.ilvl && texts.some((t) => t.includes(`%${u + 1}`))) continue;
2332
+ chain.push(u);
2333
+ texts.push(level.lvlText);
2334
+ }
2335
+ const value = chain.reverse().map((u) => markerAt(u) ?? "").join("");
2336
+ if (!value) return null;
2337
+ return value.length > 1 && value.endsWith(".") ? value.slice(0, -1) : value;
2338
+ }
2339
+ function listTargets(paragraphs, items, levelOf) {
2340
+ const order = paragraphs.map((p) => p.id);
2341
+ const out = [];
2342
+ for (const p of paragraphs) {
2343
+ const text = p.text.replace(//g, "").trim();
2344
+ if (!text) continue;
2345
+ const number = paragraphNumber(order, items, levelOf, p.id);
2346
+ const item = items.get(p.id);
2347
+ if (number !== null)
2348
+ out.push({
2349
+ paragraphId: p.id,
2350
+ kind: "numbered",
2351
+ number,
2352
+ marker: item?.markerText ?? "",
2353
+ text,
2354
+ heading: p.heading,
2355
+ level: item?.ilvl ?? 0
2356
+ });
2357
+ else if (p.heading)
2358
+ out.push({
2359
+ paragraphId: p.id,
2360
+ kind: "heading",
2361
+ number: null,
2362
+ marker: "",
2363
+ text,
2364
+ heading: true,
2365
+ level: 0
2366
+ });
2367
+ }
2368
+ return out;
2369
+ }
2370
+ function filterTargets(targets, query) {
2371
+ const q = query.trim().toLowerCase();
2372
+ if (!q) return [...targets];
2373
+ return targets.filter(
2374
+ (t) => (t.number ?? "").toLowerCase().startsWith(q) || t.text.toLowerCase().includes(q)
2375
+ );
2376
+ }
2377
+
2378
+ // src/docx/references/commands.ts
2379
+ var REF_BOOKMARK_PREFIX = "_Ref";
2380
+ function newRefBookmark(taken, random = Math.random) {
2381
+ for (; ; ) {
2382
+ const name = `${REF_BOOKMARK_PREFIX}${String(Math.floor(random() * 9e8) + 1e8)}`;
2383
+ if (!taken.has(name)) return name;
2384
+ }
2385
+ }
2386
+ var styled = (style) => style ? `<w:rPr><w:rStyle w:val="${style}"/></w:rPr>` : "";
2387
+ var run = (text, style) => `<w:r>${styled(style)}<w:t xml:space="preserve">${esc(text)}</w:t></w:r>`;
2388
+ function refFieldXml(instruction, cached) {
2389
+ const r = (inner) => `<w:r>${styled(CROSS_REFERENCE_STYLE)}${inner}</w:r>`;
2390
+ return `${r('<w:fldChar w:fldCharType="begin"/>')}${r(
2391
+ `<w:instrText xml:space="preserve"> ${esc(instruction)} </w:instrText>`
2392
+ )}${r('<w:fldChar w:fldCharType="separate"/>')}${run(cached, CROSS_REFERENCE_STYLE)}${r(
2393
+ '<w:fldChar w:fldCharType="end"/>'
2394
+ )}`;
2395
+ }
2396
+ var refTooltip = (value, mode) => mode === "number" ? `Cross-reference to clause ${value}` : `Cross-reference to \u201C${value}\u201D`;
2397
+ function crossReferenceXml(bookmark, mode, value) {
2398
+ return `<w:hyperlink w:anchor="${esc(bookmark)}" w:tooltip="${esc(
2399
+ refTooltip(value, mode)
2400
+ )}" w:history="1">${refFieldXml(refInstruction(bookmark, mode), value)}</w:hyperlink>`;
2401
+ }
2402
+ var refInstruction = (bookmark, mode) => mode === "number" ? `REF ${bookmark} \\r \\h` : `REF ${bookmark} \\h`;
2403
+ var refResult = (target, mode) => mode === "number" && target.number ? target.number : target.text;
2404
+ var allBookmarks = (port) => new Set(port.paragraphs().flatMap((p) => p.bookmarks));
2405
+ function ensureTargetBookmark(port, target, mode) {
2406
+ const paragraph = port.paragraphs().find((p) => p.id === target.paragraphId);
2407
+ if (!paragraph) throw new Error("That clause is no longer in the document.");
2408
+ const existing = paragraph.bookmarks.find((b) => b.startsWith(REF_BOOKMARK_PREFIX));
2409
+ if (existing && mode === "number") return existing;
2410
+ const name = newRefBookmark(allBookmarks(port));
2411
+ const start = `<w:bookmarkStart w:id="0" w:name="${name}"/>`;
2412
+ const end = '<w:bookmarkEnd w:id="0"/>';
2413
+ if (mode === "number") {
2414
+ port.setCaret({ paragraphId: paragraph.id, offset: 0 });
2415
+ if (!port.paste(`<w:p>${start}${end}</w:p>`, "", false))
2416
+ throw new Error("The cross-reference target could not be marked.");
2417
+ return name;
2418
+ }
2419
+ const runs = port.runsXml(paragraph.id);
2420
+ if (!runs) throw new Error("This heading cannot be referred to by its text; use its number.");
2421
+ port.deleteRange(
2422
+ { paragraphId: paragraph.id, offset: 0 },
2423
+ { paragraphId: paragraph.id, offset: paragraph.text.length }
2424
+ );
2425
+ if (!port.paste(`<w:p>${start}${runs}${end}</w:p>`, paragraph.text, false))
2426
+ throw new Error("The cross-reference target could not be marked.");
2427
+ return name;
2428
+ }
2429
+ function pastePoint(port, caret) {
2430
+ const paragraph = port.paragraphs().find((p) => p.id === caret.paragraphId);
2431
+ if (paragraph?.text[caret.offset - 1] !== FIELD_ATOM) return caret;
2432
+ port.setCaret(caret);
2433
+ port.typeText(" ");
2434
+ return { paragraphId: caret.paragraphId, offset: caret.offset + 1 };
2435
+ }
2436
+ function markCrossReferenceTarget(port, target, mode) {
2437
+ if (mode === "number" && !target.number) mode = "text";
2438
+ const bookmark = ensureTargetBookmark(port, target, mode);
2439
+ return { bookmark, mode, value: refResult(target, mode) };
2440
+ }
2441
+ function insertCrossReferenceField(port, { bookmark, mode, value }, caret) {
2442
+ caret = pastePoint(port, caret);
2443
+ port.setCaret(caret);
2444
+ if (!port.paste(`<w:p>${crossReferenceXml(bookmark, mode, value)}</w:p>`, value, false))
2445
+ throw new Error("The cross-reference could not be inserted.");
2446
+ port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + 1 });
2447
+ return { bookmark };
2448
+ }
2449
+ function insertCrossReference(port, target, mode, caret) {
2450
+ return insertCrossReferenceField(port, markCrossReferenceTarget(port, target, mode), caret);
2451
+ }
2452
+ var documentReferenceTooltip = (text, appName = "ARBI") => `Cross-reference: ${text} \u2014 opens in ${appName}`;
2453
+ function insertDocumentReference(port, reference, caret) {
2454
+ const text = reference.text.trim();
2455
+ if (!text) throw new Error("Enter the reference text.");
2456
+ const tooltip = documentReferenceTooltip(text, reference.appName).slice(0, 255);
2457
+ caret = pastePoint(port, caret);
2458
+ port.setCaret(caret);
2459
+ const link = `<w:p><w:hyperlink r:id="rIdRef1"${tooltip ? ` w:tooltip="${esc(tooltip)}"` : ""} w:history="1">${run(text, CROSS_REFERENCE_STYLE)}</w:hyperlink></w:p>`;
2460
+ if (!port.paste(link, text, false, hyperlinkRelationship("rIdRef1", reference.url)))
2461
+ throw new Error("The reference could not be inserted.");
2462
+ port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + text.length });
2463
+ }
2464
+ var REF_FIELD = /^REF\s+(\S+)((?:\s+\\[A-Za-z*]+(?:\s+MERGEFORMAT)?)*)\s*$/i;
2465
+ function staleCrossReferences(port) {
2466
+ const paragraphs = port.paragraphs();
2467
+ if (!paragraphs.some((p) => p.fields?.length)) return [];
2468
+ const items = port.listItems();
2469
+ const order = paragraphs.map((p) => p.id);
2470
+ const owner = /* @__PURE__ */ new Map();
2471
+ for (const p of paragraphs) for (const b of p.bookmarks) if (!owner.has(b)) owner.set(b, p.id);
2472
+ const out = [];
2473
+ for (const p of paragraphs)
2474
+ for (const field of p.fields ?? []) {
2475
+ const match = REF_FIELD.exec(field.instruction);
2476
+ if (!match || !match[1].startsWith(REF_BOOKMARK_PREFIX)) continue;
2477
+ const switches = match[2].toLowerCase();
2478
+ const mode = /\\[rwn]\b/.test(switches) ? "number" : "text";
2479
+ const target = owner.get(match[1]);
2480
+ const base = {
2481
+ paragraphId: p.id,
2482
+ offset: field.offset,
2483
+ instruction: field.instruction,
2484
+ cached: field.result,
2485
+ bookmark: match[1],
2486
+ mode
2487
+ };
2488
+ if (!target) {
2489
+ out.push({ ...base, value: null });
2490
+ continue;
2491
+ }
2492
+ 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();
2493
+ if (value && value !== field.result.trim()) out.push({ ...base, value });
2494
+ }
2495
+ return out;
2496
+ }
2497
+ function brokenCrossReferences(port) {
2498
+ return port.paragraphs().flatMap(
2499
+ (p) => (p.marks ?? []).filter((m) => m.styleId === BROKEN_CROSS_REFERENCE_STYLE).map((m) => ({ paragraphId: p.id, offset: m.offset, text: m.text }))
2500
+ );
2501
+ }
2502
+ function refreshCrossReferences(port) {
2503
+ const stale = staleCrossReferences(port).sort(
2504
+ (a, b) => a.paragraphId === b.paragraphId ? b.offset - a.offset : 0
2505
+ );
2506
+ let refreshed = 0;
2507
+ for (const ref of stale) {
2508
+ const paragraph = port.paragraphs().find((p) => p.id === ref.paragraphId);
2509
+ if (!paragraph || paragraph.text[ref.offset - 1] === FIELD_ATOM) continue;
2510
+ const at = { paragraphId: ref.paragraphId, offset: ref.offset };
2511
+ port.deleteRange(at, { paragraphId: ref.paragraphId, offset: ref.offset + 1 });
2512
+ port.setCaret(at);
2513
+ const text = ref.value ?? (ref.cached.trim() || ref.bookmark);
2514
+ const body = ref.value === null ? run(text, BROKEN_CROSS_REFERENCE_STYLE) : crossReferenceXml(ref.bookmark, ref.mode, ref.value);
2515
+ if (port.paste(`<w:p>${body}</w:p>`, text, false) && ref.value !== null) refreshed++;
2516
+ }
2517
+ return { refreshed, broken: brokenCrossReferences(port) };
2518
+ }
2519
+
2520
+ // src/docx/references/passages.ts
2521
+ function shortTitle(title) {
2522
+ const base = title.replace(/\.[A-Za-z0-9]{1,5}$/, "").trim();
2523
+ const defined = /\(\s*(?:the\s+)?["“'‘]([^"”'’]{1,30})["”'’]\s*\)/i.exec(base);
2524
+ return defined ? defined[1] : base;
2525
+ }
2526
+ function passageClause(text) {
2527
+ const first = text.trim().split("\n")[0] ?? "";
2528
+ const match = /^(?:#+\s*)?(?:\*\*)?(?:clause|section|article)?\s*(\d+(?:\.\d+)*)[.)]?(?:\*\*)?\s+\S/i.exec(
2529
+ first
2530
+ );
2531
+ return match ? match[1] : null;
2532
+ }
2533
+ function referenceText(title, passage) {
2534
+ const name = shortTitle(title);
2535
+ const clause = passageClause(passage.text);
2536
+ if (clause) return `${name}, clause ${clause}`;
2537
+ if (passage.page) return `${name}, p. ${passage.page}`;
2538
+ return name;
2539
+ }
2540
+ function passageExcerpt(text, max = 280) {
2541
+ const plain = text.replace(/[#*_`>|]+/g, " ").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\s+/g, " ").trim();
2542
+ return plain.length > max ? `${plain.slice(0, max - 1)}\u2026` : plain;
2543
+ }
2544
+ function filterPassages(passages, query) {
2545
+ const q = query.trim().toLowerCase();
2546
+ return q ? passages.filter((p) => p.text.toLowerCase().includes(q)) : [...passages];
2547
+ }
2548
+ var RUN_PARTS = /* @__PURE__ */ new Set(["rPr", "t", "tab", "br", "lastRenderedPageBreak"]);
2549
+ var SKIPPED = /* @__PURE__ */ new Set(["pPr", "bookmarkStart", "bookmarkEnd", "proofErr", "permStart", "permEnd"]);
2550
+ function serialize(node) {
2551
+ if (node.kind === "textValue") return esc(node.value ?? "");
2552
+ const name = `${node.prefix ?? "w"}:${node.localName}`;
2553
+ const attrs = (node.attributes ?? []).map((a) => ` ${a.prefix ? `${a.prefix}:` : ""}${a.localName}="${esc(a.value)}"`).join("");
2554
+ const children = (node.children ?? []).map((c) => serialize(c)).join("");
2555
+ return children ? `<${name}${attrs}>${children}</${name}>` : `<${name}${attrs}/>`;
2556
+ }
2557
+ function paragraphRunsXml(paragraph) {
2558
+ const runs = [];
2559
+ for (const child of paragraph.children ?? []) {
2560
+ if (child.localName && SKIPPED.has(child.localName)) continue;
2561
+ if (child.localName !== "r") return null;
2562
+ if ((child.children ?? []).some((c) => !c.localName || !RUN_PARTS.has(c.localName))) return null;
2563
+ runs.push(serialize(child));
2564
+ }
2565
+ return runs.length ? runs.join("") : null;
2566
+ }
2567
+ function findNode2(node, id) {
2568
+ if (node.id === id) return node;
2569
+ for (const child of node.children ?? []) {
2570
+ const found = findNode2(child, id);
2571
+ if (found) return found;
2572
+ }
2573
+ return void 0;
2574
+ }
2575
+ function referencesPort(editor, revision) {
2576
+ const base = editorPort(editor, revision);
2577
+ const session = () => {
2578
+ const s = editor.surface?.session;
2579
+ if (!s) throw new Error("The document is not open.");
2580
+ return s;
2581
+ };
2582
+ const root = () => session().part().root;
2583
+ let numbering;
2584
+ let cascade;
2585
+ const index = () => {
2586
+ if (!numbering) {
2587
+ const s = session();
2588
+ cascade = buildStyleCascadeTable(s.stylesRoot(), void 0, s.settingsRoot());
2589
+ numbering = withNumberingStyleLinks(buildNumberingIndex(s.numberingRoot()), cascade);
2590
+ }
2591
+ return numbering;
2592
+ };
2593
+ return {
2594
+ ...base,
2595
+ listItems: () => {
2596
+ const body = root().children?.find((n) => n.kind === "body");
2597
+ const items = resolveStoryListItems(
2598
+ body?.children ?? [],
2599
+ index(),
2600
+ cascade
2601
+ );
2602
+ const out = /* @__PURE__ */ new Map();
2603
+ for (const [id, item] of items)
2604
+ out.set(id, {
2605
+ numId: item.numId,
2606
+ ilvl: item.ilvl,
2607
+ markerText: item.markerText,
2608
+ numFmt: item.numFmt
2609
+ });
2610
+ return out;
2611
+ },
2612
+ levelOf: (numId, ilvl) => {
2613
+ const level = resolveNumberingLevel(index(), numId, ilvl)?.level;
2614
+ return level ? { lvlText: level.lvlText, numFmt: level.numFmt } : null;
2615
+ },
2616
+ runsXml: (paragraphId) => {
2617
+ const node = findNode2(root(), paragraphId);
2618
+ return node ? paragraphRunsXml(node) : null;
2619
+ }
2620
+ };
2621
+ }
2622
+
2623
+ // src/docx/beforeSave.ts
2624
+ var hooks = /* @__PURE__ */ new WeakMap();
2625
+ function onBeforeSave(editor, fn) {
2626
+ let set = hooks.get(editor);
2627
+ if (!set) hooks.set(editor, set = /* @__PURE__ */ new Set());
2628
+ set.add(fn);
2629
+ return () => set.delete(fn);
2630
+ }
2631
+ function runBeforeSave(editor) {
2632
+ if (!editor) return;
2633
+ for (const fn of hooks.get(editor) ?? [])
2634
+ try {
2635
+ fn();
2636
+ } catch {
2637
+ }
2638
+ }
2639
+ var DEFAULT_CROSS_REFERENCES_LABELS = {
2640
+ insert: "Insert cross-reference",
2641
+ title: "Insert cross-reference",
2642
+ description: "Refer to a clause of this document, or to a passage of another document.",
2643
+ thisDocument: "This document",
2644
+ otherDocument: "Another document",
2645
+ filterTargets: "Find a clause or heading",
2646
+ noTargets: "This document has no numbered clauses or headings yet.",
2647
+ number: "Paragraph number",
2648
+ text: "Heading text",
2649
+ insertAs: "Insert",
2650
+ chooseDocument: "Choose a document",
2651
+ filterPassages: "Find a passage",
2652
+ loadingPassages: "Loading passages\u2026",
2653
+ noPassages: "No passage matches.",
2654
+ referenceText: "Reference text",
2655
+ insertButton: "Insert",
2656
+ cancel: "Cancel",
2657
+ clause: (number) => `Clause ${number}`,
2658
+ heading: "Heading",
2659
+ update: "Update cross-references",
2660
+ updated: "Cross-references updated",
2661
+ updateSummary: (refreshed) => refreshed ? `${refreshed} cross-reference${refreshed === 1 ? "" : "s"} brought up to date.` : "Every cross-reference is up to date.",
2662
+ brokenTitle: "Broken cross-references",
2663
+ brokenNone: "No cross-reference points at a deleted target.",
2664
+ brokenHelp: "Their target was deleted: the last text is kept and marked. Insert the reference again to repair it.",
2665
+ brokenCard: "Broken cross-reference",
2666
+ brokenCardBody: "Its target was deleted. Update cross-references to mark it.",
2667
+ show: "Show",
2668
+ close: "Close"
2669
+ };
2670
+ var CrossReferencesContext = createContext(null);
2671
+ var useCrossReferences = () => useContext(CrossReferencesContext);
2672
+ function CrossReferencesProvider({
2673
+ children,
2674
+ editable,
2675
+ references,
2676
+ documentId,
2677
+ notify,
2678
+ labels
2679
+ }) {
2680
+ const editor = useDocxEditor();
2681
+ const track = useTrackedOrNoted();
2682
+ const l = useMemo(() => ({ ...DEFAULT_CROSS_REFERENCES_LABELS, ...labels }), [labels]);
2683
+ const [dialog, setDialog] = useState(
2684
+ null
2685
+ );
2686
+ const marker = useRef(null);
2687
+ const [viewer, setViewer] = useState(null);
2688
+ useEffect(() => setViewer(marker.current?.closest(".native-docx-viewer") ?? null), []);
2689
+ const openDialog = useCallback(() => {
2690
+ if (!editor || !editable) return;
2691
+ try {
2692
+ const port = referencesPort(editor);
2693
+ const caret = port.caret();
2694
+ if (!caret) return notify?.("Place the cursor where the reference should go.", "error");
2695
+ setDialog({ caret, targets: listTargets(port.paragraphs(), port.listItems(), port.levelOf) });
2696
+ } catch (error) {
2697
+ notify?.(error instanceof Error ? error.message : "Could not read the document.", "error");
2698
+ }
2699
+ }, [editor, editable, notify]);
2700
+ const run2 = useCallback(
2701
+ (label, prepare, insert) => {
2702
+ if (!editor) return;
2703
+ try {
2704
+ const prepared = withDirectEditing(editor, prepare);
2705
+ if (dialog) referencesPort(editor).setCaret(dialog.caret);
2706
+ track({ label, insert: (revision) => insert(prepared, revision), inserted: () => true });
2707
+ setDialog(null);
2708
+ editor.surface?.focus();
2709
+ holdCaret(editor);
2710
+ } catch (error) {
2711
+ notify?.(
2712
+ error instanceof Error ? error.message : "Could not insert the reference.",
2713
+ "error"
2714
+ );
2715
+ }
2716
+ },
2717
+ [editor, dialog, track, notify]
2718
+ );
2719
+ useEffect(() => {
2720
+ if (!editor || !editable) return;
2721
+ const refresh = () => {
2722
+ try {
2723
+ const port = referencesPort(editor);
2724
+ if (!port.paragraphs().some((p) => p.fields?.length)) return;
2725
+ preservingCaret(editor, () => withDirectEditing(editor, () => refreshCrossReferences(port)));
2726
+ } catch {
2727
+ }
2728
+ };
2729
+ const off = onBeforeSave(editor, refresh);
2730
+ const timer = setTimeout(refresh, 1500);
2731
+ return () => {
2732
+ off();
2733
+ clearTimeout(timer);
2734
+ };
2735
+ }, [editor, editable]);
2736
+ const [report, setReport] = useState(null);
2737
+ const update = useCallback(() => {
2738
+ if (!editor || !editable) return;
2739
+ try {
2740
+ const result = preservingCaret(
2741
+ editor,
2742
+ () => withDirectEditing(editor, () => refreshCrossReferences(referencesPort(editor)))
2743
+ );
2744
+ setReport(result);
2745
+ } catch (error) {
2746
+ notify?.(
2747
+ error instanceof Error ? error.message : "Could not update cross-references.",
2748
+ "error"
2749
+ );
2750
+ }
2751
+ }, [editor, editable, notify]);
2752
+ const [passages, setPassages] = useState({});
2753
+ const loadPassages = useCallback(
2754
+ (id) => {
2755
+ if (!references || passages[id]) return;
2756
+ setPassages((p) => ({ ...p, [id]: "loading" }));
2757
+ references.passages(id).then((list) => setPassages((p) => ({ ...p, [id]: list }))).catch(() => setPassages((p) => ({ ...p, [id]: [] })));
2758
+ },
2759
+ [references, passages]
2760
+ );
2761
+ useEffect(() => {
2762
+ if (!viewer || !references) return;
2763
+ const targetOf = (event) => {
2764
+ const link = event.target?.closest?.(
2765
+ 'a.docx-hyperlink[data-docx-link-kind="external"]'
2766
+ );
2767
+ if (!link || !viewer.contains(link)) return null;
2768
+ const mouse = event;
2769
+ if (mouse.button !== 0 || mouse.ctrlKey || mouse.metaKey || mouse.shiftKey) return null;
2770
+ return references.targetOf(link.getAttribute("href") ?? "");
2771
+ };
2772
+ const take = (event) => {
2773
+ const target = targetOf(event);
2774
+ if (!target) return;
2775
+ event.preventDefault();
2776
+ event.stopPropagation();
2777
+ if (event.type === "click") references.open(target);
2778
+ };
2779
+ const types = ["pointerdown", "mousedown", "pointerup", "mouseup", "click"];
2780
+ for (const type of types) window.addEventListener(type, take, true);
2781
+ return () => {
2782
+ for (const type of types) window.removeEventListener(type, take, true);
2783
+ };
2784
+ }, [viewer, references]);
2785
+ const value = useMemo(
2786
+ () => editable ? { openDialog, update, labels: l } : null,
2787
+ [editable, openDialog, update, l]
2788
+ );
2789
+ const resolveInternal = (href) => {
2790
+ if (!editor) return null;
2791
+ const name = href.replace(/^#/, "");
2792
+ try {
2793
+ const port = referencesPort(editor);
2794
+ const paragraphs = port.paragraphs();
2795
+ const target = paragraphs.find((p) => p.bookmarks.includes(name));
2796
+ if (!target) return { title: l.brokenCard, body: l.brokenCardBody };
2797
+ const number = paragraphNumber(
2798
+ paragraphs.map((p) => p.id),
2799
+ port.listItems(),
2800
+ port.levelOf,
2801
+ target.id
2802
+ );
2803
+ return {
2804
+ title: number ? l.clause(number) : l.heading,
2805
+ body: passageExcerpt(target.text.replace(//g, ""))
2806
+ };
2807
+ } catch {
2808
+ return null;
2809
+ }
2810
+ };
2811
+ return /* @__PURE__ */ jsxs(CrossReferencesContext.Provider, { value, children: [
2812
+ /* @__PURE__ */ jsx("span", { ref: marker, hidden: true }),
2813
+ children,
2814
+ /* @__PURE__ */ jsx(
2815
+ LinkHoverCard,
2816
+ {
2817
+ root: viewer,
2818
+ matches: (href) => href.startsWith(`#${REF_BOOKMARK_PREFIX}`),
2819
+ resolve: resolveInternal,
2820
+ testId: "docx-cross-reference-card"
2821
+ }
2822
+ ),
2823
+ references && /* @__PURE__ */ jsx(
2824
+ LinkHoverCard,
2825
+ {
2826
+ root: viewer,
2827
+ matches: (href) => !!references.targetOf(href),
2828
+ resolve: (href) => {
2829
+ const target = references.targetOf(href);
2830
+ if (!target) return null;
2831
+ const list = passages[target.documentId];
2832
+ if (!list) loadPassages(target.documentId);
2833
+ const passage = Array.isArray(list) ? list.find((p) => p.chunkId === target.chunkId) : void 0;
2834
+ return passage ? {
2835
+ body: passageExcerpt(passage.text),
2836
+ footer: passage.page ? `p. ${passage.page}` : void 0
2837
+ } : null;
2838
+ },
2839
+ testId: "docx-cross-reference-card"
2840
+ }
2841
+ ),
2842
+ dialog && /* @__PURE__ */ jsx(
2843
+ CrossReferenceDialog,
2844
+ {
2845
+ targets: dialog.targets,
2846
+ references,
2847
+ documentId,
2848
+ passages,
2849
+ loadPassages,
2850
+ labels: l,
2851
+ onCancel: () => setDialog(null),
2852
+ onClosed: () => editor?.surface?.focus(),
2853
+ onInsertTarget: (target, mode) => run2(
2854
+ `Inserted cross-reference: ${refResult(target, mode)}`,
2855
+ () => markCrossReferenceTarget(referencesPort(editor), target, mode),
2856
+ (marked, revision) => insertCrossReferenceField(referencesPort(editor, revision), marked, dialog.caret)
2857
+ ),
2858
+ onInsertPassage: (target, text) => run2(
2859
+ `Inserted cross-reference: ${text}`,
2860
+ () => void 0,
2861
+ (_, revision) => insertDocumentReference(
2862
+ referencesPort(editor, revision),
2863
+ { text, url: references.linkFor(target), appName: references.appName },
2864
+ dialog.caret
2865
+ )
2866
+ )
2867
+ }
2868
+ ),
2869
+ /* @__PURE__ */ jsx(Dialog, { open: !!report, onOpenChange: (open) => !open && setReport(null), children: /* @__PURE__ */ jsxs(
2870
+ DialogContent,
2871
+ {
2872
+ className: "max-h-[85dvh] overflow-y-auto",
2873
+ "data-testid": "docx-cross-references-report",
2874
+ children: [
2875
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2876
+ /* @__PURE__ */ jsx(DialogTitle, { children: l.updated }),
2877
+ /* @__PURE__ */ jsx(DialogDescription, { children: report && l.updateSummary(report.refreshed) })
2878
+ ] }),
2879
+ report && /* @__PURE__ */ jsxs("section", { className: "space-y-1 text-sm", children: [
2880
+ /* @__PURE__ */ jsx("h3", { className: "font-medium", children: l.brokenTitle }),
2881
+ report.broken.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
2882
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: l.brokenHelp }),
2883
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1", "data-testid": "docx-cross-references-broken", children: report.broken.map((b) => /* @__PURE__ */ jsxs(
2884
+ "li",
2885
+ {
2886
+ className: "flex items-center justify-between gap-2",
2887
+ children: [
2888
+ /* @__PURE__ */ jsx("span", { className: "text-red-text", children: b.text }),
2889
+ /* @__PURE__ */ jsx(
2890
+ Button,
2891
+ {
2892
+ size: "sm",
2893
+ variant: "ghost",
2894
+ onClick: () => {
2895
+ const point = { paragraphId: b.paragraphId, offset: b.offset };
2896
+ editor?.surface?.setSelection({ anchor: point, head: point });
2897
+ editor?.surface?.revealParagraph(b.paragraphId);
2898
+ setReport(null);
2899
+ },
2900
+ children: l.show
2901
+ }
2902
+ )
2903
+ ]
2904
+ },
2905
+ `${b.paragraphId}:${b.offset}`
2906
+ )) })
2907
+ ] }) : /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: l.brokenNone })
2908
+ ] }),
2909
+ /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setReport(null), children: l.close }) })
2910
+ ]
2911
+ }
2912
+ ) })
2913
+ ] });
2914
+ }
2915
+ function CrossReferenceDialog({
2916
+ targets,
2917
+ references,
2918
+ documentId,
2919
+ passages,
2920
+ loadPassages,
2921
+ labels,
2922
+ onCancel,
2923
+ onInsertTarget,
2924
+ onInsertPassage,
2925
+ onClosed
2926
+ }) {
2927
+ const l = { ...DEFAULT_CROSS_REFERENCES_LABELS, ...labels };
2928
+ const [tab, setTab] = useState("this");
2929
+ const [query, setQuery] = useState("");
2930
+ const [chosen, setChosen] = useState(null);
2931
+ const [mode, setMode] = useState("number");
2932
+ const shown = useMemo(() => filterTargets(targets, query), [targets, query]);
2933
+ const effectiveMode = chosen?.number ? mode : "text";
2934
+ const [documents, setDocuments] = useState(null);
2935
+ const [docId, setDocId] = useState(null);
2936
+ const [passageQuery, setPassageQuery] = useState("");
2937
+ const [passage, setPassage] = useState(null);
2938
+ const [text, setText] = useState("");
2939
+ useEffect(() => {
2940
+ if (tab !== "other" || !references || documents) return;
2941
+ references.documents().then((list2) => setDocuments(list2.filter((d) => d.id !== documentId))).catch(() => setDocuments([]));
2942
+ }, [tab, references, documents, documentId]);
2943
+ const chooseDocument = (id) => {
2944
+ setDocId(id);
2945
+ setPassage(null);
2946
+ setText("");
2947
+ loadPassages(id);
2948
+ };
2949
+ const title = documents?.find((d) => d.id === docId)?.title ?? "";
2950
+ const list = docId ? passages[docId] : void 0;
2951
+ const shownPassages = Array.isArray(list) ? filterPassages(list, passageQuery) : [];
2952
+ const canInsert = tab === "this" ? !!chosen : !!(docId && passage && text.trim());
2953
+ const insert = () => {
2954
+ if (tab === "this" && chosen) onInsertTarget(chosen, effectiveMode);
2955
+ if (tab === "other" && docId && passage)
2956
+ onInsertPassage(
2957
+ { documentId: docId, chunkId: passage.chunkId, page: passage.page ?? null },
2958
+ text
2959
+ );
2960
+ };
2961
+ return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => !open && onCancel(), children: /* @__PURE__ */ jsxs(
2962
+ DialogContent,
2963
+ {
2964
+ className: "max-h-[85dvh] overflow-y-auto",
2965
+ "data-testid": "docx-cross-reference-dialog",
2966
+ onCloseAutoFocus: (event) => {
2967
+ if (!onClosed) return;
2968
+ event.preventDefault();
2969
+ onClosed();
2970
+ },
2971
+ children: [
2972
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2973
+ /* @__PURE__ */ jsx(DialogTitle, { children: l.title }),
2974
+ /* @__PURE__ */ jsx(DialogDescription, { children: l.description })
2975
+ ] }),
2976
+ /* @__PURE__ */ jsxs(Tabs, { value: tab, onValueChange: (v) => setTab(v), children: [
2977
+ /* @__PURE__ */ jsxs(TabsList, { children: [
2978
+ /* @__PURE__ */ jsx(TabsTrigger, { value: "this", "data-testid": "docx-cross-reference-this", children: l.thisDocument }),
2979
+ references && /* @__PURE__ */ jsx(TabsTrigger, { value: "other", "data-testid": "docx-cross-reference-other", children: l.otherDocument })
2980
+ ] }),
2981
+ /* @__PURE__ */ jsxs(TabsContent, { value: "this", className: "space-y-3", children: [
2982
+ /* @__PURE__ */ jsx(
2983
+ Input,
2984
+ {
2985
+ value: query,
2986
+ placeholder: l.filterTargets,
2987
+ "aria-label": l.filterTargets,
2988
+ onChange: (e) => setQuery(e.target.value),
2989
+ "data-testid": "docx-cross-reference-filter"
2990
+ }
2991
+ ),
2992
+ /* @__PURE__ */ jsxs(
2993
+ "div",
2994
+ {
2995
+ role: "listbox",
2996
+ "aria-label": l.filterTargets,
2997
+ className: "max-h-64 space-y-0.5 overflow-y-auto rounded-md border border-border p-1",
2998
+ children: [
2999
+ shown.length === 0 && /* @__PURE__ */ jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.noTargets }),
3000
+ shown.map((t) => /* @__PURE__ */ jsxs(
3001
+ "button",
3002
+ {
3003
+ type: "button",
3004
+ role: "option",
3005
+ "aria-selected": chosen?.paragraphId === t.paragraphId,
3006
+ "data-testid": "docx-cross-reference-target",
3007
+ onClick: () => setChosen(t),
3008
+ onDoubleClick: () => onInsertTarget(t, t.number ? mode : "text"),
3009
+ className: cn(
3010
+ "flex w-full items-baseline gap-2 rounded px-2 py-1 text-left text-sm",
3011
+ chosen?.paragraphId === t.paragraphId ? "bg-accent" : "hover:bg-accent/50"
3012
+ ),
3013
+ style: { paddingLeft: 8 + t.level * 16 },
3014
+ children: [
3015
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: t.marker || l.heading }),
3016
+ /* @__PURE__ */ jsx("span", { className: cn("truncate", t.heading && "font-medium"), children: t.text })
3017
+ ]
3018
+ },
3019
+ t.paragraphId
3020
+ ))
3021
+ ]
3022
+ }
3023
+ ),
3024
+ chosen && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
3025
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: l.insertAs }),
3026
+ chosen.number && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1", children: [
3027
+ /* @__PURE__ */ jsx(
3028
+ "input",
3029
+ {
3030
+ type: "radio",
3031
+ name: "cross-reference-mode",
3032
+ checked: effectiveMode === "number",
3033
+ onChange: () => setMode("number")
3034
+ }
3035
+ ),
3036
+ l.number
3037
+ ] }),
3038
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1", children: [
3039
+ /* @__PURE__ */ jsx(
3040
+ "input",
3041
+ {
3042
+ type: "radio",
3043
+ name: "cross-reference-mode",
3044
+ checked: effectiveMode === "text",
3045
+ onChange: () => setMode("text")
3046
+ }
3047
+ ),
3048
+ l.text
3049
+ ] }),
3050
+ /* @__PURE__ */ jsx(
3051
+ "span",
3052
+ {
3053
+ className: "ml-auto rounded bg-muted px-2 py-0.5",
3054
+ "data-testid": "docx-cross-reference-preview",
3055
+ children: refResult(chosen, effectiveMode)
3056
+ }
3057
+ )
3058
+ ] })
3059
+ ] }),
3060
+ references && /* @__PURE__ */ jsxs(TabsContent, { value: "other", className: "space-y-3", children: [
3061
+ references.renderDocumentPicker ? references.renderDocumentPicker(chooseDocument, docId) : /* @__PURE__ */ jsxs(
3062
+ "select",
3063
+ {
3064
+ className: "h-9 w-full rounded-md border border-border bg-background px-2 text-sm",
3065
+ "aria-label": l.chooseDocument,
3066
+ value: docId ?? "",
3067
+ onChange: (e) => e.target.value && chooseDocument(e.target.value),
3068
+ "data-testid": "docx-cross-reference-document",
3069
+ children: [
3070
+ /* @__PURE__ */ jsx("option", { value: "", children: l.chooseDocument }),
3071
+ (documents ?? []).map((d) => /* @__PURE__ */ jsx("option", { value: d.id, children: d.title }, d.id))
3072
+ ]
3073
+ }
3074
+ ),
3075
+ docId && /* @__PURE__ */ jsxs(Fragment, { children: [
3076
+ /* @__PURE__ */ jsx(
3077
+ Input,
3078
+ {
3079
+ value: passageQuery,
3080
+ placeholder: l.filterPassages,
3081
+ "aria-label": l.filterPassages,
3082
+ onChange: (e) => setPassageQuery(e.target.value),
3083
+ "data-testid": "docx-cross-reference-passage-filter"
3084
+ }
3085
+ ),
3086
+ /* @__PURE__ */ jsx(
3087
+ "div",
3088
+ {
3089
+ className: "max-h-64 space-y-1 overflow-y-auto",
3090
+ "data-testid": "docx-cross-reference-passages",
3091
+ children: list === "loading" || list === void 0 ? /* @__PURE__ */ jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.loadingPassages }) : shownPassages.length === 0 ? /* @__PURE__ */ jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.noPassages }) : shownPassages.map((p, i) => /* @__PURE__ */ jsx(
3092
+ FactPassageItem,
3093
+ {
3094
+ index: i,
3095
+ page: p.page,
3096
+ excerpt: passageExcerpt(p.text, 200),
3097
+ isViewing: passage?.chunkId === p.chunkId,
3098
+ onSelect: () => {
3099
+ setPassage(p);
3100
+ setText(referenceText(title, p));
3101
+ },
3102
+ testId: "docx-cross-reference-passage"
3103
+ },
3104
+ p.chunkId
3105
+ ))
3106
+ }
3107
+ ),
3108
+ passage && /* @__PURE__ */ jsxs("label", { className: "block space-y-1 text-sm", children: [
3109
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: l.referenceText }),
3110
+ /* @__PURE__ */ jsx(
3111
+ Input,
3112
+ {
3113
+ value: text,
3114
+ onChange: (e) => setText(e.target.value),
3115
+ "data-testid": "docx-cross-reference-text"
3116
+ }
3117
+ )
3118
+ ] })
3119
+ ] })
3120
+ ] })
3121
+ ] }),
3122
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
3123
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onCancel, children: l.cancel }),
3124
+ /* @__PURE__ */ jsx(Button, { disabled: !canInsert, onClick: insert, "data-testid": "docx-cross-reference-insert", children: l.insertButton })
3125
+ ] })
3126
+ ]
3127
+ }
3128
+ ) });
3129
+ }
2166
3130
  function RibbonMenu({
2167
3131
  label,
2168
3132
  icon,
@@ -2301,7 +3265,7 @@ function GenerateImageButton({ generation }) {
2301
3265
  });
2302
3266
  const editable = useEditorState((snapshot) => snapshot.editable);
2303
3267
  const generating = useSyncExternalStore(subscribe, () => running > 0);
2304
- async function run() {
3268
+ async function run2() {
2305
3269
  if (!editor || !prompt.trim() || busy) return;
2306
3270
  const caret = rememberCaret(editor);
2307
3271
  const controller = new AbortController();
@@ -2347,7 +3311,7 @@ function GenerateImageButton({ generation }) {
2347
3311
  className: "native-docx-form native-docx-generate-image",
2348
3312
  onSubmit: (event) => {
2349
3313
  event.preventDefault();
2350
- void run();
3314
+ void run2();
2351
3315
  },
2352
3316
  children: [
2353
3317
  /* @__PURE__ */ jsxs("label", { children: [
@@ -2363,7 +3327,7 @@ function GenerateImageButton({ generation }) {
2363
3327
  "data-testid": "docx-generate-image-prompt",
2364
3328
  onChange: (event) => setPrompt(event.target.value),
2365
3329
  onKeyDown: (event) => {
2366
- if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) void run();
3330
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) void run2();
2367
3331
  }
2368
3332
  }
2369
3333
  )
@@ -3003,6 +3967,65 @@ function WordShortcuts({ scope }) {
3003
3967
  }, [scope]);
3004
3968
  return null;
3005
3969
  }
3970
+ function CrossReferenceButton() {
3971
+ const references = useCrossReferences();
3972
+ if (!references) return null;
3973
+ return /* @__PURE__ */ jsx(
3974
+ "button",
3975
+ {
3976
+ type: "button",
3977
+ className: "native-docx-ribbon-trigger",
3978
+ "aria-label": references.labels.insert,
3979
+ title: references.labels.insert,
3980
+ "data-testid": "docx-insert-cross-reference",
3981
+ onMouseDown: (event) => event.preventDefault(),
3982
+ onClick: () => references.openDialog(),
3983
+ children: /* @__PURE__ */ jsx(Link2, { size: 16 })
3984
+ }
3985
+ );
3986
+ }
3987
+ function UpdateCrossReferencesButton() {
3988
+ const references = useCrossReferences();
3989
+ if (!references) return null;
3990
+ return /* @__PURE__ */ jsx(
3991
+ "button",
3992
+ {
3993
+ type: "button",
3994
+ className: "native-docx-ribbon-trigger",
3995
+ "aria-label": references.labels.update,
3996
+ title: references.labels.update,
3997
+ "data-testid": "docx-update-cross-references",
3998
+ onMouseDown: (event) => event.preventDefault(),
3999
+ onClick: () => references.update(),
4000
+ children: /* @__PURE__ */ jsx(RefreshCcw, { size: 16 })
4001
+ }
4002
+ );
4003
+ }
4004
+ function DocxContextMenuExtras() {
4005
+ const terms = useDefinedTerms();
4006
+ const references = useCrossReferences();
4007
+ if (!terms && !references) return null;
4008
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4009
+ /* @__PURE__ */ jsx(DocxEditor.ContextMenu.Separator, {}),
4010
+ terms && /* @__PURE__ */ jsx(
4011
+ DocxEditor.ContextMenu.Item,
4012
+ {
4013
+ label: "Insert defined term",
4014
+ icon: /* @__PURE__ */ jsx(BookA, { size: 14 }),
4015
+ shortcut: "@@",
4016
+ onSelect: () => terms.openPicker()
4017
+ }
4018
+ ),
4019
+ references && /* @__PURE__ */ jsx(
4020
+ DocxEditor.ContextMenu.Item,
4021
+ {
4022
+ label: references.labels.insert,
4023
+ icon: /* @__PURE__ */ jsx(Link2, { size: 14 }),
4024
+ onSelect: () => references.openDialog()
4025
+ }
4026
+ )
4027
+ ] });
4028
+ }
3006
4029
 
3007
4030
  // src/docx/layout/presets.ts
3008
4031
  var TWIPS_PER_INCH = 1440;
@@ -3437,9 +4460,9 @@ function countSeqFields(root, label, throughId) {
3437
4460
  return count;
3438
4461
  }
3439
4462
  function captionParagraphXml(label, number, text) {
3440
- const run = (value) => `<w:r><w:t xml:space="preserve">${esc(value)}</w:t></w:r>`;
4463
+ const run2 = (value) => `<w:r><w:t xml:space="preserve">${esc(value)}</w:t></w:r>`;
3441
4464
  const rest = text.trim() ? `: ${text.trim()}` : "";
3442
- return `<w:p><w:pPr><w:pStyle w:val="Caption"/></w:pPr>${run(`${label} `)}<w:fldSimple w:instr=" SEQ ${esc(label)} \\* ARABIC "><w:r><w:t>${number}</w:t></w:r></w:fldSimple>${rest ? run(rest) : ""}</w:p>`;
4465
+ return `<w:p><w:pPr><w:pStyle w:val="Caption"/></w:pPr>${run2(`${label} `)}<w:fldSimple w:instr=" SEQ ${esc(label)} \\* ARABIC "><w:r><w:t>${number}</w:t></w:r></w:fldSimple>${rest ? run2(rest) : ""}</w:p>`;
3443
4466
  }
3444
4467
  function base642(bytes) {
3445
4468
  let binary = "";
@@ -3791,7 +4814,7 @@ function covered(room, vector, receipt) {
3791
4814
  }
3792
4815
  return true;
3793
4816
  }
3794
- var EditorBoundary = class extends React3.Component {
4817
+ var EditorBoundary = class extends React4.Component {
3795
4818
  state = {};
3796
4819
  static getDerivedStateFromError(error) {
3797
4820
  return { error };
@@ -3883,11 +4906,16 @@ function DocxRibbon({
3883
4906
  /* @__PURE__ */ jsx(RibbonItem, { id: "insert-page-break", label: "Page break", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Button, { slotId: "insert.pageBreak" }) }),
3884
4907
  /* @__PURE__ */ jsx(RibbonItem, { id: "insert-link", label: "Link", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Link, {}) }),
3885
4908
  /* @__PURE__ */ jsx(RibbonItem, { id: "insert-defined-term", label: "Defined term", children: /* @__PURE__ */ jsx(DefinedTermButtons, {}) }),
3886
- /* @__PURE__ */ jsx(RibbonItem, { id: "insert-quick-parts", label: "Quick Parts", children: /* @__PURE__ */ jsx(QuickParts, {}) })
4909
+ /* @__PURE__ */ jsx(RibbonItem, { id: "insert-quick-parts", label: "Quick Parts", children: /* @__PURE__ */ jsx(QuickParts, {}) }),
4910
+ /* @__PURE__ */ jsx(RibbonItem, { id: "insert-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsx(CrossReferenceButton, {}) })
3887
4911
  ] }),
3888
4912
  /* @__PURE__ */ jsx(LayoutTabContent, { tab }),
3889
4913
  tab === "Design" && /* @__PURE__ */ jsx(RibbonItem, { id: "design-house-template", label: "House template", children: /* @__PURE__ */ jsx(HouseTemplatePanel, {}) }),
3890
- tab === "References" && /* @__PURE__ */ jsx(NoteButtons, {}),
4914
+ tab === "References" && /* @__PURE__ */ jsxs(Fragment, { children: [
4915
+ /* @__PURE__ */ jsx(NoteButtons, {}),
4916
+ /* @__PURE__ */ jsx(RibbonItem, { id: "references-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsx(CrossReferenceButton, {}) }),
4917
+ /* @__PURE__ */ jsx(RibbonItem, { id: "references-update-cross-references", label: "Update cross-references", children: /* @__PURE__ */ jsx(UpdateCrossReferencesButton, {}) })
4918
+ ] }),
3891
4919
  tab === "Review" && /* @__PURE__ */ jsxs(Fragment, { children: [
3892
4920
  /* @__PURE__ */ jsx(RibbonItem, { id: "review-editing-mode", label: "Editing mode", priority: 10, children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.EditingMode, {}) }),
3893
4921
  /* @__PURE__ */ jsx(RibbonItem, { id: "review-comments", label: "Comments", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Comments, {}) }),
@@ -4091,6 +5119,7 @@ function NativeDocxEditor({
4091
5119
  };
4092
5120
  }, [dirty]);
4093
5121
  async function exportDocument() {
5122
+ runBeforeSave(ref.current);
4094
5123
  const data = await ref.current?.save();
4095
5124
  if (!data) return;
4096
5125
  const url = URL.createObjectURL(
@@ -4117,6 +5146,7 @@ function NativeDocxEditor({
4117
5146
  async function saveVersion() {
4118
5147
  if (!ready || saving || stream) return;
4119
5148
  setSaving(true);
5149
+ runBeforeSave(ref.current);
4120
5150
  const atRevision = revision.current;
4121
5151
  try {
4122
5152
  const result = isDraft ? await (async () => {
@@ -4240,7 +5270,7 @@ function NativeDocxEditor({
4240
5270
  load: adapter.definitions,
4241
5271
  editable: !stream && !snapshot && ready.canEdit,
4242
5272
  notify: adapter.notify,
4243
- children: /* @__PURE__ */ jsxs(
5273
+ children: /* @__PURE__ */ jsx(
4244
5274
  HouseTemplateProvider,
4245
5275
  {
4246
5276
  enabled: !stream,
@@ -4248,67 +5278,76 @@ function NativeDocxEditor({
4248
5278
  documentId: isDraft || snapshot ? void 0 : documentId,
4249
5279
  editable: !stream && !snapshot && ready.canEdit,
4250
5280
  notify: adapter.notify,
4251
- children: [
4252
- /* @__PURE__ */ jsx(
4253
- DocxEditor.RevisionMarkup,
4254
- {
4255
- insertions: { mark: "underline", color: "blue" },
4256
- deletions: { mark: "strikethrough", color: "red" },
4257
- movedFrom: { mark: "doubleStrikethrough", color: "green" },
4258
- movedTo: { mark: "doubleUnderline", color: "green" },
4259
- trackMoves: true
4260
- }
4261
- ),
4262
- !stream && /* @__PURE__ */ jsx(
4263
- DocxRibbon,
4264
- {
4265
- onSave: () => void saveVersion(),
4266
- imageGeneration: adapter.imageGeneration && {
4267
- notify: adapter.notify,
4268
- ...adapter.imageGeneration
4269
- },
4270
- badge: (
4271
- // Says the document is shared live, in place of a title row above the ribbon.
4272
- ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
5281
+ children: /* @__PURE__ */ jsxs(
5282
+ CrossReferencesProvider,
5283
+ {
5284
+ editable: !stream && !snapshot && ready.canEdit,
5285
+ references: adapter.references,
5286
+ documentId,
5287
+ notify: adapter.notify,
5288
+ children: [
5289
+ /* @__PURE__ */ jsx(
5290
+ DocxEditor.RevisionMarkup,
5291
+ {
5292
+ insertions: { mark: "underline", color: "blue" },
5293
+ deletions: { mark: "strikethrough", color: "red" },
5294
+ movedFrom: { mark: "doubleStrikethrough", color: "green" },
5295
+ movedTo: { mark: "doubleUnderline", color: "green" },
5296
+ trackMoves: true
5297
+ }
5298
+ ),
5299
+ !stream && /* @__PURE__ */ jsx(
5300
+ DocxRibbon,
5301
+ {
5302
+ onSave: () => void saveVersion(),
5303
+ imageGeneration: adapter.imageGeneration && {
5304
+ notify: adapter.notify,
5305
+ ...adapter.imageGeneration
5306
+ },
5307
+ badge: (
5308
+ // Says the document is shared live, in place of a title row above the ribbon.
5309
+ ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
5310
+ )
5311
+ }
5312
+ ),
5313
+ !stream && /* @__PURE__ */ jsx(WordShortcuts, { scope: stageRef }),
5314
+ !stream && /* @__PURE__ */ jsx(TableTabKeys, { scope: stageRef }),
5315
+ /* @__PURE__ */ jsxs(
5316
+ "div",
5317
+ {
5318
+ className: "native-docx-stage",
5319
+ ref: stageRef,
5320
+ onMouseDownCapture: (event) => {
5321
+ if (event.button === 2 && ref.current?.getSelectionPlacement())
5322
+ event.preventDefault();
5323
+ },
5324
+ children: [
5325
+ /* @__PURE__ */ jsxs(DocxEditor.Viewport, { className: "native-docx-viewport", children: [
5326
+ /* @__PURE__ */ jsx(DocxEditor.Content, {}),
5327
+ /* @__PURE__ */ jsx(
5328
+ DocxMentions,
5329
+ {
5330
+ initialCommentId,
5331
+ mentions: adapter.mentions,
5332
+ notify: adapter.notify,
5333
+ getAgentStatus: adapter.getAgentStatus,
5334
+ requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
5335
+ children: /* @__PURE__ */ jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsx(DocxCommentActivity, {}) }) })
5336
+ }
5337
+ ),
5338
+ /* @__PURE__ */ jsx(DocxEditor.HeaderFooterChrome, {}),
5339
+ /* @__PURE__ */ jsx(DocxEditor.NotesChrome, {}),
5340
+ /* @__PURE__ */ jsx(DocxEditor.Equation, {}),
5341
+ /* @__PURE__ */ jsx(DocxEditor.HyperLink, {}),
5342
+ /* @__PURE__ */ jsx(DocxEditor.ContextMenu, { children: /* @__PURE__ */ jsx(DocxContextMenuExtras, {}) })
5343
+ ] }),
5344
+ /* @__PURE__ */ jsx(DocxEditor.PageNumber, {})
5345
+ ]
5346
+ }
4273
5347
  )
4274
- }
4275
- ),
4276
- !stream && /* @__PURE__ */ jsx(WordShortcuts, { scope: stageRef }),
4277
- !stream && /* @__PURE__ */ jsx(TableTabKeys, { scope: stageRef }),
4278
- /* @__PURE__ */ jsxs(
4279
- "div",
4280
- {
4281
- className: "native-docx-stage",
4282
- ref: stageRef,
4283
- onMouseDownCapture: (event) => {
4284
- if (event.button === 2 && ref.current?.getSelectionPlacement())
4285
- event.preventDefault();
4286
- },
4287
- children: [
4288
- /* @__PURE__ */ jsxs(DocxEditor.Viewport, { className: "native-docx-viewport", children: [
4289
- /* @__PURE__ */ jsx(DocxEditor.Content, {}),
4290
- /* @__PURE__ */ jsx(
4291
- DocxMentions,
4292
- {
4293
- initialCommentId,
4294
- mentions: adapter.mentions,
4295
- notify: adapter.notify,
4296
- getAgentStatus: adapter.getAgentStatus,
4297
- requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
4298
- children: /* @__PURE__ */ jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsx(DocxCommentActivity, {}) }) })
4299
- }
4300
- ),
4301
- /* @__PURE__ */ jsx(DocxEditor.HeaderFooterChrome, {}),
4302
- /* @__PURE__ */ jsx(DocxEditor.NotesChrome, {}),
4303
- /* @__PURE__ */ jsx(DocxEditor.Equation, {}),
4304
- /* @__PURE__ */ jsx(DocxEditor.HyperLink, {}),
4305
- /* @__PURE__ */ jsx(DocxEditor.ContextMenu, {})
4306
- ] }),
4307
- /* @__PURE__ */ jsx(DocxEditor.PageNumber, {})
4308
- ]
4309
- }
4310
- )
4311
- ]
5348
+ ]
5349
+ }
5350
+ )
4312
5351
  }
4313
5352
  )
4314
5353
  }
@@ -4407,6 +5446,6 @@ async function loadFonts(baseUrl) {
4407
5446
  };
4408
5447
  }
4409
5448
 
4410
- export { BUILTIN_TEMPLATE_NAME, DEFAULT_DEFINED_TERMS_LABELS, DEFINED_TERM_TRIGGER, DefinedTermsProvider, DocxAuthorContext, DocxCommentActivity, DocxEditorReview, DocxMentions, DocxParticipants, DocxRibbon, GenerateImageButton, HouseTemplateProvider, NativeDocxEditor, builtinHouseTemplate, contentPath, editorPort, findDefinitionsSection, insertDefinedTerm, loadDocxFonts, normalizeDocxExport, resolveHouseTemplate, reviewModule, structuralPort, templateFileName, trackedOrNoted, useDefinedTerms, useHouseTemplate, useReview, useReviewItem, useTrackedOrNoted, withDirectEditing };
4411
- //# sourceMappingURL=chunk-CVYY4X5R.js.map
4412
- //# sourceMappingURL=chunk-CVYY4X5R.js.map
5449
+ export { BUILTIN_TEMPLATE_NAME, CrossReferenceDialog, CrossReferencesProvider, DEFAULT_CROSS_REFERENCES_LABELS, DEFAULT_DEFINED_TERMS_LABELS, DEFINED_TERM_TRIGGER, DefinedTermsProvider, DocxAuthorContext, DocxCommentActivity, DocxEditorReview, DocxMentions, DocxParticipants, DocxRibbon, GenerateImageButton, HouseTemplateProvider, LinkHoverCard, NativeDocxEditor, builtinHouseTemplate, contentPath, editorPort, findDefinitionsSection, insertCrossReference, insertDefinedTerm, insertDocumentReference, listTargets, loadDocxFonts, normalizeDocxExport, paragraphNumber, referenceText, referencesPort, resolveHouseTemplate, reviewModule, shortTitle, structuralPort, templateFileName, trackedOrNoted, useCrossReferences, useDefinedTerms, useHouseTemplate, useReview, useReviewItem, useTrackedOrNoted, withDirectEditing };
5450
+ //# sourceMappingURL=chunk-W2RTZOK3.js.map
5451
+ //# sourceMappingURL=chunk-W2RTZOK3.js.map