@extend-ai/react-docx 0.7.0 → 0.7.2

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.
package/dist/index.cjs CHANGED
@@ -549,7 +549,13 @@ async function defaultWasmSource() {
549
549
  const fs = await nodeFsPromises();
550
550
  return fs.readFile(wasmUrl);
551
551
  }
552
- return wasmUrl;
552
+ const response = await fetch(wasmUrl);
553
+ if (!response.ok) {
554
+ throw new Error(
555
+ `react-docx: failed to load the bundled WebAssembly binary from ${wasmUrl.href} (${response.status} ${response.statusText}). If your bundler did not emit this asset, import @extend-ai/react-docx/docx_wasm_bg.wasm?url and pass it to setWasmSource() before importing a document.`
556
+ );
557
+ }
558
+ return response;
553
559
  }
554
560
  async function initWasm(source) {
555
561
  if (!initPromise) {
@@ -1185,7 +1191,7 @@ __export(index_exports, {
1185
1191
  defaultStarterModel: () => defaultStarterModel,
1186
1192
  duplicateParagraph: () => duplicateParagraph,
1187
1193
  getPart: () => getPart,
1188
- initWasm: () => initWasm,
1194
+ initWasm: () => initWasm2,
1189
1195
  insertParagraph: () => insertParagraph,
1190
1196
  layoutDocument: () => layoutDocument,
1191
1197
  modelToDocumentXml: () => modelToDocumentXml,
@@ -1227,7 +1233,7 @@ __export(index_exports, {
1227
1233
  setParagraphHeading: () => setParagraphHeading,
1228
1234
  setRunColor: () => setRunColor,
1229
1235
  setRunHighlight: () => setRunHighlight,
1230
- setWasmSource: () => setWasmSource,
1236
+ setWasmSource: () => setWasmSource2,
1231
1237
  splitParagraphChildrenAtTextOffsets: () => splitParagraphChildrenAtTextOffsets,
1232
1238
  toggleRunStyleFlag: () => toggleRunStyleFlag,
1233
1239
  updateParagraphText: () => updateParagraphText,
@@ -1479,6 +1485,60 @@ function layoutDocument(model, options = {}) {
1479
1485
 
1480
1486
  // src/docx-import.ts
1481
1487
  init_cjs_shims();
1488
+
1489
+ // src/wasm-source.ts
1490
+ init_cjs_shims();
1491
+ init_src();
1492
+ var hasConfiguredWasmSource = false;
1493
+ var configuredWorkerWasmSource;
1494
+ function bufferSourceToArrayBuffer(source) {
1495
+ if (source instanceof ArrayBuffer) {
1496
+ return source.slice(0);
1497
+ }
1498
+ const bytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
1499
+ const copy = new Uint8Array(bytes);
1500
+ return copy.buffer;
1501
+ }
1502
+ function sourceToWorkerSource(source) {
1503
+ if (typeof source === "string") {
1504
+ return source;
1505
+ }
1506
+ if (typeof URL !== "undefined" && source instanceof URL) {
1507
+ return source.href;
1508
+ }
1509
+ if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {
1510
+ return bufferSourceToArrayBuffer(source);
1511
+ }
1512
+ if (typeof WebAssembly !== "undefined" && source instanceof WebAssembly.Module) {
1513
+ return source;
1514
+ }
1515
+ if (typeof Request !== "undefined" && source instanceof Request) {
1516
+ return source.url;
1517
+ }
1518
+ return void 0;
1519
+ }
1520
+ function rememberWorkerWasmSource(source) {
1521
+ hasConfiguredWasmSource = true;
1522
+ configuredWorkerWasmSource = sourceToWorkerSource(source);
1523
+ }
1524
+ function setWasmSource2(source) {
1525
+ setWasmSource(source);
1526
+ rememberWorkerWasmSource(source);
1527
+ }
1528
+ function initWasm2(source) {
1529
+ if (source !== void 0) {
1530
+ rememberWorkerWasmSource(source);
1531
+ }
1532
+ return initWasm(source);
1533
+ }
1534
+ function canUseConfiguredWasmSourceInWorker() {
1535
+ return !hasConfiguredWasmSource || configuredWorkerWasmSource !== void 0;
1536
+ }
1537
+ function getConfiguredWorkerWasmSource() {
1538
+ return configuredWorkerWasmSource;
1539
+ }
1540
+
1541
+ // src/docx-import.ts
1482
1542
  var nextImportWorkerRequestId = 1;
1483
1543
  function createAbortError() {
1484
1544
  if (typeof DOMException !== "undefined") {
@@ -1497,7 +1557,7 @@ function errorFromWorkerResponse(response) {
1497
1557
  return error;
1498
1558
  }
1499
1559
  function canUseDocxImportWorker(options) {
1500
- return options.useWorker !== false && typeof Worker !== "undefined";
1560
+ return options.useWorker !== false && typeof Worker !== "undefined" && canUseConfiguredWasmSourceInWorker();
1501
1561
  }
1502
1562
  function createDocxImportWorker() {
1503
1563
  return new Worker(new URL("./docx-import-worker.js", importMetaUrl), {
@@ -1606,7 +1666,8 @@ async function importDocxBuffer(buffer, options = {}) {
1606
1666
  const request = {
1607
1667
  id: requestId,
1608
1668
  type: "import-docx",
1609
- buffer
1669
+ buffer,
1670
+ wasmSource: getConfiguredWorkerWasmSource()
1610
1671
  };
1611
1672
  const transfer = options.transferBuffer ? [buffer] : [];
1612
1673
  worker.postMessage(request, transfer);
@@ -1668,6 +1729,18 @@ function readStringAttribute(tagXml, attribute) {
1668
1729
  }
1669
1730
  return tagXml.match(new RegExp(`${attribute}="([^"]+)"`, "i"))?.[1];
1670
1731
  }
1732
+ function resolvePageSizeForOrientation(params) {
1733
+ const normalizedOrientation = params.orientation?.trim().toLowerCase();
1734
+ const widthPx = Math.max(1, params.widthPx);
1735
+ const heightPx = Math.max(1, params.heightPx);
1736
+ if (normalizedOrientation === "landscape" && widthPx < heightPx) {
1737
+ return { widthPx: heightPx, heightPx: widthPx };
1738
+ }
1739
+ if (normalizedOrientation === "portrait" && widthPx > heightPx) {
1740
+ return { widthPx: heightPx, heightPx: widthPx };
1741
+ }
1742
+ return { widthPx, heightPx };
1743
+ }
1671
1744
  function normalizeHexColor(value) {
1672
1745
  if (!value) {
1673
1746
  return void 0;
@@ -1753,8 +1826,13 @@ function parseSectionLayout(sectionPropertiesXml) {
1753
1826
  const pageSizeTag = sectionPropertiesXml.match(/<w:pgSz\b[^>]*>/i)?.[0];
1754
1827
  const pageMarginTag = sectionPropertiesXml.match(/<w:pgMar\b[^>]*>/i)?.[0];
1755
1828
  const docGridTag = sectionPropertiesXml.match(/<w:docGrid\b[^>]*\/?>/i)?.[0];
1756
- const pageWidthPx = twipsToPixels(readTwipsAttribute(pageSizeTag, "w:w")) ?? DEFAULT_DOCUMENT_LAYOUT.pageWidthPx;
1757
- const pageHeightPx = twipsToPixels(readTwipsAttribute(pageSizeTag, "w:h")) ?? DEFAULT_DOCUMENT_LAYOUT.pageHeightPx;
1829
+ const rawPageWidthPx = twipsToPixels(readTwipsAttribute(pageSizeTag, "w:w")) ?? DEFAULT_DOCUMENT_LAYOUT.pageWidthPx;
1830
+ const rawPageHeightPx = twipsToPixels(readTwipsAttribute(pageSizeTag, "w:h")) ?? DEFAULT_DOCUMENT_LAYOUT.pageHeightPx;
1831
+ const pageSize = resolvePageSizeForOrientation({
1832
+ widthPx: rawPageWidthPx,
1833
+ heightPx: rawPageHeightPx,
1834
+ orientation: readStringAttribute(pageSizeTag, "w:orient")
1835
+ });
1758
1836
  const topMarginPx = twipsToPixels(readTwipsAttribute(pageMarginTag, "w:top")) ?? DEFAULT_DOCUMENT_LAYOUT.marginsPx.top;
1759
1837
  const rightMarginPx = twipsToPixels(readTwipsAttribute(pageMarginTag, "w:right")) ?? DEFAULT_DOCUMENT_LAYOUT.marginsPx.right;
1760
1838
  const bottomMarginPx = twipsToPixels(readTwipsAttribute(pageMarginTag, "w:bottom")) ?? DEFAULT_DOCUMENT_LAYOUT.marginsPx.bottom;
@@ -1764,8 +1842,8 @@ function parseSectionLayout(sectionPropertiesXml) {
1764
1842
  const docGridType = readStringAttribute(docGridTag, "w:type")?.toLowerCase();
1765
1843
  const docGridLinePitchPx = docGridType === "lines" || docGridType === "linesandchars" || docGridType === "snaptochars" ? twipsToPixels(readTwipsAttribute(docGridTag, "w:linePitch")) ?? DEFAULT_DOCUMENT_LAYOUT.docGridLinePitchPx : DEFAULT_DOCUMENT_LAYOUT.docGridLinePitchPx;
1766
1844
  return {
1767
- pageWidthPx,
1768
- pageHeightPx,
1845
+ pageWidthPx: pageSize.widthPx,
1846
+ pageHeightPx: pageSize.heightPx,
1769
1847
  marginsPx: {
1770
1848
  top: topMarginPx,
1771
1849
  right: rightMarginPx,
@@ -4474,6 +4552,26 @@ function getDownscaledThumbnailImageDataUri(src) {
4474
4552
  downscaledThumbnailImageCache.set(src, pending);
4475
4553
  return pending;
4476
4554
  }
4555
+ var THUMBNAIL_DECODED_IMAGE_CACHE_MAX_ENTRIES = 48;
4556
+ var decodedThumbnailImageCache = /* @__PURE__ */ new Map();
4557
+ function getDecodedThumbnailImage(src) {
4558
+ const cached = decodedThumbnailImageCache.get(src);
4559
+ if (cached) {
4560
+ decodedThumbnailImageCache.delete(src);
4561
+ decodedThumbnailImageCache.set(src, cached);
4562
+ return cached;
4563
+ }
4564
+ const pending = loadThumbnailImage(src).catch(() => void 0);
4565
+ decodedThumbnailImageCache.set(src, pending);
4566
+ while (decodedThumbnailImageCache.size > THUMBNAIL_DECODED_IMAGE_CACHE_MAX_ENTRIES) {
4567
+ const oldestKey = decodedThumbnailImageCache.keys().next().value;
4568
+ if (oldestKey === void 0) {
4569
+ break;
4570
+ }
4571
+ decodedThumbnailImageCache.delete(oldestKey);
4572
+ }
4573
+ return pending;
4574
+ }
4477
4575
  function directThumbnailPositivePx(value, fallback = 1) {
4478
4576
  return Number.isFinite(value) && value > 0 ? Math.max(1, Number(value)) : fallback;
4479
4577
  }
@@ -4729,6 +4827,32 @@ function drawDirectThumbnailImagePlaceholder(context, image, hairlineSourcePx) {
4729
4827
  context.lineWidth = hairlineSourcePx;
4730
4828
  context.strokeRect(xPx, yPx, widthPx, heightPx);
4731
4829
  }
4830
+ function drawDirectThumbnailImage(context, image, decoded, hairlineSourcePx) {
4831
+ const xPx = Math.round(image.xPx);
4832
+ const yPx = Math.round(image.yPx);
4833
+ const widthPx = Math.max(1, Math.round(image.widthPx));
4834
+ const heightPx = Math.max(1, Math.round(image.heightPx));
4835
+ if (decoded && decoded.naturalWidth > 0 && decoded.naturalHeight > 0) {
4836
+ try {
4837
+ context.drawImage(decoded, xPx, yPx, widthPx, heightPx);
4838
+ return;
4839
+ } catch {
4840
+ }
4841
+ }
4842
+ setCanvasFillStyle(
4843
+ context,
4844
+ image.backgroundColor,
4845
+ THUMBNAIL_DIRECT_IMAGE_BACKGROUND
4846
+ );
4847
+ context.fillRect(xPx, yPx, widthPx, heightPx);
4848
+ setCanvasStrokeStyle(
4849
+ context,
4850
+ image.borderColor,
4851
+ THUMBNAIL_DIRECT_TABLE_BORDER_COLOR
4852
+ );
4853
+ context.lineWidth = hairlineSourcePx;
4854
+ context.strokeRect(xPx, yPx, widthPx, heightPx);
4855
+ }
4732
4856
  function drawDirectThumbnailTable(context, table, hairlineSourcePx) {
4733
4857
  const tableXPx = Math.round(table.xPx);
4734
4858
  const tableYPx = Math.round(table.yPx);
@@ -4768,7 +4892,7 @@ function drawDirectThumbnailTable(context, table, hairlineSourcePx) {
4768
4892
  });
4769
4893
  context.restore();
4770
4894
  }
4771
- function renderDocxThumbnailSnapshotSurface(params) {
4895
+ async function renderDocxThumbnailSnapshotSurface(params) {
4772
4896
  if (typeof document === "undefined") {
4773
4897
  throw new Error("DOCX thumbnails require a browser environment.");
4774
4898
  }
@@ -4783,6 +4907,21 @@ function renderDocxThumbnailSnapshotSurface(params) {
4783
4907
  if (!context) {
4784
4908
  throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
4785
4909
  }
4910
+ const elements = params.snapshot.elements.slice(0, THUMBNAIL_DIRECT_MAX_ELEMENTS);
4911
+ const decodedImagesBySrc = /* @__PURE__ */ new Map();
4912
+ const imageSrcs = /* @__PURE__ */ new Set();
4913
+ for (const element of elements) {
4914
+ if (element.kind === "image" && element.src) {
4915
+ imageSrcs.add(element.src);
4916
+ }
4917
+ }
4918
+ if (imageSrcs.size > 0) {
4919
+ await Promise.all(
4920
+ Array.from(imageSrcs, async (src) => {
4921
+ decodedImagesBySrc.set(src, await getDecodedThumbnailImage(src));
4922
+ })
4923
+ );
4924
+ }
4786
4925
  const scaleX = pixelWidthPx / sourceWidthPx;
4787
4926
  const scaleY = pixelHeightPx / sourceHeightPx;
4788
4927
  const hairlineSourcePx = Math.max(0.75, 1 / Math.max(scaleX, scaleY));
@@ -4795,7 +4934,7 @@ function renderDocxThumbnailSnapshotSurface(params) {
4795
4934
  "#ffffff"
4796
4935
  );
4797
4936
  context.fillRect(0, 0, sourceWidthPx, sourceHeightPx);
4798
- params.snapshot.elements.slice(0, THUMBNAIL_DIRECT_MAX_ELEMENTS).forEach((element) => {
4937
+ elements.forEach((element) => {
4799
4938
  switch (element.kind) {
4800
4939
  case "paragraph":
4801
4940
  drawDirectThumbnailParagraph(context, element);
@@ -4807,6 +4946,14 @@ function renderDocxThumbnailSnapshotSurface(params) {
4807
4946
  hairlineSourcePx
4808
4947
  );
4809
4948
  break;
4949
+ case "image":
4950
+ drawDirectThumbnailImage(
4951
+ context,
4952
+ element,
4953
+ decodedImagesBySrc.get(element.src),
4954
+ hairlineSourcePx
4955
+ );
4956
+ break;
4810
4957
  case "table":
4811
4958
  drawDirectThumbnailTable(context, element, hairlineSourcePx);
4812
4959
  break;
@@ -5687,10 +5834,11 @@ var BASE_DOC_STYLE = {
5687
5834
  transition: "box-shadow 0.2s ease"
5688
5835
  };
5689
5836
  var TRACKED_CHANGE_GUTTER_WIDTH_PX = 300;
5690
- var TRACKED_CHANGE_GUTTER_CARD_LEFT_PX = 28;
5691
- var TRACKED_CHANGE_GUTTER_CARD_RIGHT_PX = 10;
5692
- var TRACKED_CHANGE_GUTTER_CARD_GAP_PX = 8;
5693
- var TRACKED_CHANGE_GUTTER_CARD_MIN_HEIGHT_PX = 52;
5837
+ var TRACKED_CHANGE_GUTTER_CARD_LEFT_PX = 14;
5838
+ var TRACKED_CHANGE_GUTTER_CARD_RIGHT_PX = 12;
5839
+ var TRACKED_CHANGE_GUTTER_CARD_GAP_PX = 4;
5840
+ var TRACKED_CHANGE_GUTTER_CARD_MIN_HEIGHT_PX = 30;
5841
+ var TRACKED_CHANGE_GUTTER_BEND_OFFSET_PX = 8;
5694
5842
  var INITIAL_PAGINATION_STABILITY_IDLE_MS = 240;
5695
5843
  function scheduleDomWrite(callback) {
5696
5844
  if (typeof window !== "undefined" && typeof window.requestAnimationFrame === "function") {
@@ -14103,9 +14251,10 @@ function trackedInlineStyle(baseStyle, change) {
14103
14251
  return baseStyle;
14104
14252
  }
14105
14253
  if (change.kind === "insertion" || change.kind === "move-to") {
14254
+ const accentColor = change.kind === "move-to" ? "#70ad47" : "#dc2626";
14106
14255
  return {
14107
14256
  ...baseStyle,
14108
- color: "#2563eb",
14257
+ color: accentColor,
14109
14258
  textDecoration: mergeTextDecorations(
14110
14259
  baseStyle.textDecoration,
14111
14260
  "underline"
@@ -15730,11 +15879,22 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
15730
15879
  if (!commentIds || commentIds.length === 0) {
15731
15880
  return void 0;
15732
15881
  }
15733
- const accent = commentAccentColor(documentTheme);
15734
- return {
15735
- backgroundColor: documentTheme === "dark" ? "rgba(251, 191, 36, 0.24)" : "rgba(251, 191, 36, 0.3)",
15736
- borderBottom: `2px solid ${accent}`
15737
- };
15882
+ return commentHighlightStyle(documentTheme, commentIds[0]);
15883
+ };
15884
+ const currentAnnotationAttributes = (trackedInlineChange) => {
15885
+ const attributes = {};
15886
+ if (trackedInlineChange) {
15887
+ attributes["data-docx-tracked-change"] = trackedInlineChange.kind;
15888
+ attributes["data-docx-tracked-change-id"] = trackedInlineChange.id;
15889
+ }
15890
+ const commentIds = commentMarkup?.commentIdsByVisibleChildIndex[trackedVisibleChildCursor];
15891
+ if (commentIds && commentIds.length > 0) {
15892
+ attributes["data-docx-comment-ids"] = commentIds.join(" ");
15893
+ if (commentIds.length === 1) {
15894
+ attributes["data-docx-comment-id"] = String(commentIds[0]);
15895
+ }
15896
+ }
15897
+ return attributes;
15738
15898
  };
15739
15899
  const consumeTrackedVisibleChild = (child) => {
15740
15900
  if (!trackedMarkup && !commentMarkup) {
@@ -15768,11 +15928,11 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
15768
15928
  fallbackTabWidthPx,
15769
15929
  checkboxChoiceRow
15770
15930
  );
15771
- const appendPlainTextWithSoftBreakControl = (target, keySeed, text, style, measureStyle) => {
15931
+ const appendPlainTextWithSoftBreakControl = (target, keySeed, text, style, measureStyle, spanAttributes) => {
15772
15932
  const shouldControlSoftBreakStretch = paragraph.style?.align === "justify" && text.includes("\n");
15773
15933
  if (!shouldControlSoftBreakStretch) {
15774
15934
  target.push(
15775
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style, children: text }, keySeed)
15935
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...spanAttributes, style, children: text }, keySeed)
15776
15936
  );
15777
15937
  trackTextAdvance(text, measureStyle);
15778
15938
  return;
@@ -15788,6 +15948,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
15788
15948
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
15789
15949
  "span",
15790
15950
  {
15951
+ ...spanAttributes,
15791
15952
  style: isLastSegment ? {
15792
15953
  ...style,
15793
15954
  display: "inline-block",
@@ -15938,6 +16099,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
15938
16099
  " "
15939
16100
  );
15940
16101
  const text = textOverride ?? textValue;
16102
+ const annotationAttributes2 = currentAnnotationAttributes(trackedInlineChange);
15941
16103
  if (child.link) {
15942
16104
  const linkHref = child.link;
15943
16105
  const isInternalLink = linkHref.startsWith("#");
@@ -15945,6 +16107,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
15945
16107
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
15946
16108
  "a",
15947
16109
  {
16110
+ ...annotationAttributes2,
15948
16111
  href: linkHref,
15949
16112
  target: isInternalLink ? void 0 : "_blank",
15950
16113
  rel: isInternalLink ? void 0 : "noreferrer noopener",
@@ -15981,12 +16144,20 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
15981
16144
  };
15982
16145
  if (text === " " && !useTabLeaderLayout && !useAnchoredTabLayout) {
15983
16146
  target.push(
15984
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: tabTextStyle(child.style, trackedStyle), children: "\xA0" }, key)
16147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
16148
+ "span",
16149
+ {
16150
+ ...annotationAttributes2,
16151
+ style: tabTextStyle(child.style, trackedStyle),
16152
+ children: "\xA0"
16153
+ },
16154
+ key
16155
+ )
15985
16156
  );
15986
16157
  return;
15987
16158
  }
15988
16159
  target.push(
15989
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: trackedStyle, children: text }, key)
16160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...annotationAttributes2, style: trackedStyle, children: text }, key)
15990
16161
  );
15991
16162
  trackTextAdvance(text, child.style);
15992
16163
  return;
@@ -16055,7 +16226,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
16055
16226
  const sectionImageCursor = sectionImageLocation && !sectionImageInteraction?.isReadOnly && !behavesAsDecorativeBehindTextBackground && (isWrappedFloatingImage || isAbsoluteFloatingImage) ? "move" : void 0;
16056
16227
  const isCenteredStandaloneInlineImage = !isWrappedFloatingImage && !isAbsoluteFloatingImage && paragraph.style?.align === "center" && paragraph.children.length === 1 && paragraph.children[0]?.type === "image";
16057
16228
  const trackedImageStyle = trackedInlineChange?.kind === "insertion" || trackedInlineChange?.kind === "move-to" ? {
16058
- outline: "2px solid rgba(37, 99, 235, 0.35)",
16229
+ outline: trackedInlineChange.kind === "move-to" ? "2px solid rgba(112, 173, 71, 0.35)" : "2px solid rgba(220, 38, 38, 0.3)",
16059
16230
  outlineOffset: 1
16060
16231
  } : void 0;
16061
16232
  const renderableImageSrc = syntheticTextBoxSvg(
@@ -16241,6 +16412,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
16241
16412
  ),
16242
16413
  ...currentCommentHighlightStyle()
16243
16414
  };
16415
+ const annotationAttributes = currentAnnotationAttributes(trackedInlineChange);
16244
16416
  const noteLabel = noteMarkerLabel(
16245
16417
  child.noteReference,
16246
16418
  safeNoteMarkerIndexes.footnote,
@@ -16251,6 +16423,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
16251
16423
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
16252
16424
  "span",
16253
16425
  {
16426
+ ...annotationAttributes,
16254
16427
  style: {
16255
16428
  ...textStyle,
16256
16429
  verticalAlign: "super",
@@ -16266,7 +16439,15 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
16266
16439
  }
16267
16440
  if ((textOverride ?? child.text) === " " && !useTabLeaderLayout && !useAnchoredTabLayout) {
16268
16441
  target.push(
16269
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: tabTextStyle(child.style, textStyle), children: "\xA0" }, key)
16442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
16443
+ "span",
16444
+ {
16445
+ ...annotationAttributes,
16446
+ style: tabTextStyle(child.style, textStyle),
16447
+ children: "\xA0"
16448
+ },
16449
+ key
16450
+ )
16270
16451
  );
16271
16452
  return;
16272
16453
  }
@@ -16277,6 +16458,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
16277
16458
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
16278
16459
  "a",
16279
16460
  {
16461
+ ...annotationAttributes,
16280
16462
  href: linkHref,
16281
16463
  target: isInternalLink ? void 0 : "_blank",
16282
16464
  rel: isInternalLink ? void 0 : "noreferrer noopener",
@@ -16309,7 +16491,8 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
16309
16491
  key,
16310
16492
  textOverride ?? child.text,
16311
16493
  textStyle,
16312
- child.style
16494
+ child.style,
16495
+ annotationAttributes
16313
16496
  );
16314
16497
  };
16315
16498
  const anchoredTabZoneStyle = {
@@ -19020,6 +19203,7 @@ function collectTrackedChangesFromModel(model) {
19020
19203
  trackedMarkup.changes.forEach((change, changeIndex) => {
19021
19204
  trackedChanges.push({
19022
19205
  id: `${paragraphLocationKey(location)}:${change.id}:${changeIndex}`,
19206
+ inlineAnchorId: change.id,
19023
19207
  kind: change.kind,
19024
19208
  author: change.author,
19025
19209
  date: change.date,
@@ -19198,13 +19382,42 @@ function collectCommentsFromModel(model) {
19198
19382
  });
19199
19383
  return comments;
19200
19384
  }
19201
- function commentAccentColor(documentTheme) {
19202
- return documentTheme === "dark" ? "#fbbf24" : "#d97706";
19385
+ function hexColorWithAlpha(color, alpha) {
19386
+ const normalized = color.trim().replace(/^#/, "");
19387
+ if (!/^[\da-f]{6}$/i.test(normalized)) {
19388
+ return color;
19389
+ }
19390
+ const red = Number.parseInt(normalized.slice(0, 2), 16);
19391
+ const green = Number.parseInt(normalized.slice(2, 4), 16);
19392
+ const blue = Number.parseInt(normalized.slice(4, 6), 16);
19393
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
19394
+ }
19395
+ function commentAccentColor(documentTheme, commentId) {
19396
+ const lightPalette = ["#5b9bd5", "#d65f5f", "#8f6ac8", "#70ad47", "#d9872b"];
19397
+ const darkPalette = ["#7dd3fc", "#fca5a5", "#c4b5fd", "#86efac", "#fdba74"];
19398
+ if (Number.isFinite(commentId)) {
19399
+ const palette = documentTheme === "dark" ? darkPalette : lightPalette;
19400
+ return palette[Math.abs(Math.round(commentId)) % palette.length];
19401
+ }
19402
+ return documentTheme === "dark" ? darkPalette[0] : lightPalette[0];
19403
+ }
19404
+ function commentHighlightStyle(documentTheme, commentId) {
19405
+ const accent = commentAccentColor(documentTheme, commentId);
19406
+ return {
19407
+ backgroundColor: hexColorWithAlpha(
19408
+ accent,
19409
+ documentTheme === "dark" ? 0.3 : 0.22
19410
+ ),
19411
+ boxShadow: `inset 0 -1px 0 ${hexColorWithAlpha(
19412
+ accent,
19413
+ documentTheme === "dark" ? 0.7 : 0.48
19414
+ )}`
19415
+ };
19203
19416
  }
19204
19417
  function estimateCommentCardHeight(comment) {
19205
19418
  const snippet = comment.text || "Comment";
19206
- const lines = Math.max(1, Math.ceil(snippet.length / 30));
19207
- return Math.max(TRACKED_CHANGE_GUTTER_CARD_MIN_HEIGHT_PX, 34 + lines * 14);
19419
+ const lines = Math.min(2, Math.max(1, Math.ceil(snippet.length / 42)));
19420
+ return Math.max(TRACKED_CHANGE_GUTTER_CARD_MIN_HEIGHT_PX, 24 + lines * 11);
19208
19421
  }
19209
19422
  function trackedChangeKindLabel(kind) {
19210
19423
  switch (kind) {
@@ -19226,16 +19439,16 @@ function trackedChangeKindLabel(kind) {
19226
19439
  }
19227
19440
  function trackedChangeAccentColor(kind, documentTheme) {
19228
19441
  const palette = documentTheme === "dark" ? {
19229
- insertion: "#60a5fa",
19442
+ insertion: "#f87171",
19230
19443
  deletion: "#f87171",
19231
- moveFrom: "#fbbf24",
19232
- moveTo: "#22d3ee",
19444
+ moveFrom: "#86efac",
19445
+ moveTo: "#86efac",
19233
19446
  format: "#c084fc"
19234
19447
  } : {
19235
- insertion: "#2563eb",
19448
+ insertion: "#dc2626",
19236
19449
  deletion: "#dc2626",
19237
- moveFrom: "#d97706",
19238
- moveTo: "#0891b2",
19450
+ moveFrom: "#70ad47",
19451
+ moveTo: "#70ad47",
19239
19452
  format: "#7c3aed"
19240
19453
  };
19241
19454
  switch (kind) {
@@ -19254,6 +19467,9 @@ function trackedChangeAccentColor(kind, documentTheme) {
19254
19467
  return palette.format;
19255
19468
  }
19256
19469
  }
19470
+ function trackedChangeUsesGutterBalloon(change) {
19471
+ return change.kind !== "insertion" && change.kind !== "move-to";
19472
+ }
19257
19473
  function gutterAnnotationSortTuple(location) {
19258
19474
  if (location.kind === "paragraph") {
19259
19475
  return [location.nodeIndex, 0, 0, 0];
@@ -19334,10 +19550,92 @@ function elementRectWithinContainer(element, container) {
19334
19550
  height: elementRect.height / scaleY
19335
19551
  };
19336
19552
  }
19553
+ function findFirstElementWithSpaceSeparatedDataValue(rootElement, attributeName, value) {
19554
+ const candidateElements = [];
19555
+ if (rootElement.hasAttribute(attributeName)) {
19556
+ candidateElements.push(rootElement);
19557
+ }
19558
+ candidateElements.push(
19559
+ ...rootElement.querySelectorAll(
19560
+ `[${attributeName}]`
19561
+ )
19562
+ );
19563
+ for (const candidate of candidateElements) {
19564
+ const rawValue = candidate.getAttribute(attributeName);
19565
+ if (!rawValue) {
19566
+ continue;
19567
+ }
19568
+ if (rawValue.split(/\s+/).includes(value)) {
19569
+ return candidate;
19570
+ }
19571
+ }
19572
+ return void 0;
19573
+ }
19574
+ function findGutterAnnotationScopeElementInPage(pageElement, annotation) {
19575
+ return findTrackedChangeAnchorElementInPage(pageElement, annotation.location);
19576
+ }
19577
+ function findGutterAnnotationDataAnchorInPage(pageElement, annotation, attributeName, value) {
19578
+ const scopedRoot = findGutterAnnotationScopeElementInPage(
19579
+ pageElement,
19580
+ annotation
19581
+ );
19582
+ if (scopedRoot) {
19583
+ const scopedAnchor = findFirstElementWithSpaceSeparatedDataValue(
19584
+ scopedRoot,
19585
+ attributeName,
19586
+ value
19587
+ );
19588
+ if (scopedAnchor) {
19589
+ return scopedAnchor;
19590
+ }
19591
+ }
19592
+ return findFirstElementWithSpaceSeparatedDataValue(
19593
+ pageElement,
19594
+ attributeName,
19595
+ value
19596
+ );
19597
+ }
19598
+ function findGutterAnnotationAnchorElementInPage(pageElement, annotation) {
19599
+ if (annotation.trackedChange) {
19600
+ const trackedAnchor = findGutterAnnotationDataAnchorInPage(
19601
+ pageElement,
19602
+ annotation,
19603
+ "data-docx-tracked-change-id",
19604
+ annotation.trackedChange.id
19605
+ );
19606
+ if (trackedAnchor) {
19607
+ return trackedAnchor;
19608
+ }
19609
+ const inlineAnchorId = annotation.trackedChange.inlineAnchorId;
19610
+ if (inlineAnchorId && inlineAnchorId !== annotation.trackedChange.id) {
19611
+ const inlineTrackedAnchor = findGutterAnnotationDataAnchorInPage(
19612
+ pageElement,
19613
+ annotation,
19614
+ "data-docx-tracked-change-id",
19615
+ inlineAnchorId
19616
+ );
19617
+ if (inlineTrackedAnchor) {
19618
+ return inlineTrackedAnchor;
19619
+ }
19620
+ }
19621
+ }
19622
+ if (annotation.comment) {
19623
+ const commentAnchor = findGutterAnnotationDataAnchorInPage(
19624
+ pageElement,
19625
+ annotation,
19626
+ "data-docx-comment-ids",
19627
+ String(annotation.comment.commentId)
19628
+ );
19629
+ if (commentAnchor) {
19630
+ return commentAnchor;
19631
+ }
19632
+ }
19633
+ return findTrackedChangeAnchorElementInPage(pageElement, annotation.location);
19634
+ }
19337
19635
  function estimateTrackedChangeCardHeight(change) {
19338
19636
  const snippet = normalizeTrackedChangeSnippet(change.text) ?? trackedChangeKindLabel(change.kind);
19339
- const lines = Math.max(1, Math.ceil(snippet.length / 30));
19340
- return Math.max(TRACKED_CHANGE_GUTTER_CARD_MIN_HEIGHT_PX, 34 + lines * 14);
19637
+ const lines = Math.min(2, Math.max(1, Math.ceil(snippet.length / 42)));
19638
+ return Math.max(TRACKED_CHANGE_GUTTER_CARD_MIN_HEIGHT_PX, 22 + lines * 11);
19341
19639
  }
19342
19640
  function layoutTrackedChangesForPage(annotations, anchorByChangeId, cardHeightsByChangeId, pageWidthPx, pageHeightPx) {
19343
19641
  if (annotations.length === 0) {
@@ -19377,11 +19675,21 @@ function layoutTrackedChangesForPage(annotations, anchorByChangeId, cardHeightsB
19377
19675
  heightPx
19378
19676
  };
19379
19677
  });
19380
- withAnchors.sort((left, right) => left.anchorY - right.anchorY);
19678
+ withAnchors.sort((left, right) => {
19679
+ const yDelta = left.anchorY - right.anchorY;
19680
+ if (Math.abs(yDelta) > 2) {
19681
+ return yDelta;
19682
+ }
19683
+ const xDelta = left.anchorX - right.anchorX;
19684
+ if (xDelta !== 0) {
19685
+ return xDelta;
19686
+ }
19687
+ return left.annotation.id.localeCompare(right.annotation.id);
19688
+ });
19381
19689
  const minTopPx = 8;
19382
19690
  let cursorTopPx = minTopPx;
19383
19691
  withAnchors.forEach((entry) => {
19384
- const desiredTop = entry.anchorY - Math.round(entry.heightPx / 2);
19692
+ const desiredTop = entry.anchorY - 8;
19385
19693
  entry.top = Math.max(desiredTop, cursorTopPx);
19386
19694
  cursorTopPx = entry.top + entry.heightPx + TRACKED_CHANGE_GUTTER_CARD_GAP_PX;
19387
19695
  });
@@ -24263,7 +24571,7 @@ function docxThumbnailTextRunsFromParagraph(paragraph, documentTheme, maxChars =
24263
24571
  return;
24264
24572
  }
24265
24573
  const style = child.type === "text" || child.type === "form-field" ? child.style : void 0;
24266
- const text = child.type === "text" ? child.text : child.type === "form-field" ? formFieldDisplayValue2(child) : child.type === "image" ? child.alt || "[image]" : "";
24574
+ const text = child.type === "text" ? child.text : child.type === "form-field" ? formFieldDisplayValue2(child) : "";
24267
24575
  appendDocxThumbnailTextRun(
24268
24576
  runs,
24269
24577
  {
@@ -24354,13 +24662,29 @@ function buildDocxThumbnailParagraphElements(params) {
24354
24662
  (widthPx - 4) / imageWidthPx,
24355
24663
  (bodyHeightPx - 4) / imageHeightPx
24356
24664
  );
24357
- elements.push({
24358
- kind: "image-placeholder",
24359
- xPx: xPx + 2,
24360
- yPx: bodyYPx + 2,
24361
- widthPx: Math.max(12, imageWidthPx * scale),
24362
- heightPx: Math.max(12, imageHeightPx * scale)
24363
- });
24665
+ const elementXPx = xPx + 2;
24666
+ const elementYPx = bodyYPx + 2;
24667
+ const elementWidthPx = Math.max(12, imageWidthPx * scale);
24668
+ const elementHeightPx = Math.max(12, imageHeightPx * scale);
24669
+ const renderableSrc = resolveRenderableImageSource(imageRun);
24670
+ if (renderableSrc) {
24671
+ elements.push({
24672
+ kind: "image",
24673
+ xPx: elementXPx,
24674
+ yPx: elementYPx,
24675
+ widthPx: elementWidthPx,
24676
+ heightPx: elementHeightPx,
24677
+ src: renderableSrc
24678
+ });
24679
+ } else {
24680
+ elements.push({
24681
+ kind: "image-placeholder",
24682
+ xPx: elementXPx,
24683
+ yPx: elementYPx,
24684
+ widthPx: elementWidthPx,
24685
+ heightPx: elementHeightPx
24686
+ });
24687
+ }
24364
24688
  });
24365
24689
  }
24366
24690
  return elements;
@@ -24459,6 +24783,24 @@ function buildDocxThumbnailTableElement(params) {
24459
24783
  cells
24460
24784
  };
24461
24785
  }
24786
+ function docxThumbnailNodeRequiresDomRaster(node) {
24787
+ if (!node) {
24788
+ return false;
24789
+ }
24790
+ if (node.type === "paragraph") {
24791
+ return node.children.some((child) => child.type === "image");
24792
+ }
24793
+ return node.rows.some(
24794
+ (row) => row.cells.some(
24795
+ (cell) => cell.nodes.some((cellNode) => docxThumbnailNodeRequiresDomRaster(cellNode))
24796
+ )
24797
+ );
24798
+ }
24799
+ function docxThumbnailPageRequiresDomRaster(model, pageSegments) {
24800
+ return pageSegments.some(
24801
+ (segment) => docxThumbnailNodeRequiresDomRaster(model.nodes[segment.nodeIndex])
24802
+ );
24803
+ }
24462
24804
  function buildDocxPageThumbnailRenderSnapshotEntries(params) {
24463
24805
  const {
24464
24806
  model,
@@ -24471,6 +24813,9 @@ function buildDocxPageThumbnailRenderSnapshotEntries(params) {
24471
24813
  numberingDefinitions
24472
24814
  } = params;
24473
24815
  return pageNodeSegmentsByPage.map((pageSegments, pageIndex) => {
24816
+ if (docxThumbnailPageRequiresDomRaster(model, pageSegments)) {
24817
+ return void 0;
24818
+ }
24474
24819
  const key = `${contentKeysByPage[pageIndex] ?? ""}|theme:${documentTheme}`;
24475
24820
  let cachedSnapshot;
24476
24821
  return {
@@ -24917,7 +25262,7 @@ function useDocxPageThumbnails(editor, options = {}) {
24917
25262
  if (!surface) {
24918
25263
  const thumbnailSnapshot = thumbnailSnapshotEntry?.getSnapshot();
24919
25264
  if (thumbnailSnapshot) {
24920
- surface = renderDocxThumbnailSnapshotSurface({
25265
+ surface = await renderDocxThumbnailSnapshotSurface({
24921
25266
  snapshot: thumbnailSnapshot,
24922
25267
  widthPx: resolution.widthPx,
24923
25268
  heightPx: resolution.heightPx,
@@ -28527,6 +28872,9 @@ function DocxEditorViewer({
28527
28872
  };
28528
28873
  if (trackedChangesEnabled) {
28529
28874
  editor.trackedChanges.forEach((change) => {
28875
+ if (!trackedChangeUsesGutterBalloon(change)) {
28876
+ return;
28877
+ }
28530
28878
  placeAnnotation({
28531
28879
  id: change.id,
28532
28880
  location: change.location,
@@ -28577,45 +28925,45 @@ function DocxEditorViewer({
28577
28925
  );
28578
28926
  return;
28579
28927
  }
28580
- const nextAnchorMaps = trackedChangesByPage.map((annotations, pageIndex) => {
28581
- const pageElement = pageElementsRef.current.get(pageIndex);
28582
- const anchorsByChangeId = /* @__PURE__ */ new Map();
28583
- if (!pageElement || annotations.length === 0) {
28928
+ const nextAnchorMaps = trackedChangesByPage.map(
28929
+ (annotations, pageIndex) => {
28930
+ const pageElement = pageElementsRef.current.get(pageIndex);
28931
+ const anchorsByChangeId = /* @__PURE__ */ new Map();
28932
+ if (!pageElement || annotations.length === 0) {
28933
+ return anchorsByChangeId;
28934
+ }
28935
+ const pageHeightPx = Math.max(1, pageElement.offsetHeight);
28936
+ const pageWidthPx = Math.max(1, pageElement.offsetWidth);
28937
+ annotations.forEach((annotation) => {
28938
+ const anchorElement = findGutterAnnotationAnchorElementInPage(
28939
+ pageElement,
28940
+ annotation
28941
+ );
28942
+ if (!anchorElement) {
28943
+ return;
28944
+ }
28945
+ const anchorRect = elementRectWithinContainer(
28946
+ anchorElement,
28947
+ pageElement
28948
+ );
28949
+ if (!anchorRect) {
28950
+ return;
28951
+ }
28952
+ const anchorY = clampNumber(
28953
+ Math.round(anchorRect.top + anchorRect.height / 2),
28954
+ 10,
28955
+ Math.max(10, pageHeightPx - 10)
28956
+ );
28957
+ const anchorX = clampNumber(
28958
+ Math.round(anchorRect.right),
28959
+ 10,
28960
+ Math.max(10, pageWidthPx - 10)
28961
+ );
28962
+ anchorsByChangeId.set(annotation.id, { x: anchorX, y: anchorY });
28963
+ });
28584
28964
  return anchorsByChangeId;
28585
28965
  }
28586
- const pageHeightPx = Math.max(1, pageElement.offsetHeight);
28587
- const pageWidthPx = Math.max(1, pageElement.offsetWidth);
28588
- annotations.forEach((annotation) => {
28589
- const anchorElement = findTrackedChangeAnchorElementInPage(
28590
- pageElement,
28591
- annotation.location
28592
- );
28593
- if (!anchorElement) {
28594
- return;
28595
- }
28596
- const anchorRect = elementRectWithinContainer(
28597
- anchorElement,
28598
- pageElement
28599
- );
28600
- if (!anchorRect) {
28601
- return;
28602
- }
28603
- const anchorY = clampNumber(
28604
- Math.round(anchorRect.top + anchorRect.height / 2),
28605
- 10,
28606
- Math.max(10, pageHeightPx - 10)
28607
- );
28608
- const anchorX = clampNumber(
28609
- Math.round(
28610
- anchorRect.left + Math.min(24, Math.max(8, anchorRect.width * 0.2))
28611
- ),
28612
- 10,
28613
- Math.max(10, pageWidthPx - 10)
28614
- );
28615
- anchorsByChangeId.set(annotation.id, { x: anchorX, y: anchorY });
28616
- });
28617
- return anchorsByChangeId;
28618
- });
28966
+ );
28619
28967
  setTrackedChangeAnchorByPage(nextAnchorMaps);
28620
28968
  }, [
28621
28969
  trackedChangesByPage,
@@ -42466,6 +42814,7 @@ ${currentText.slice(end)}`;
42466
42814
  });
42467
42815
  const headerFooterBodyDimmed = pageHeaderFooterEditActive;
42468
42816
  const documentPageBackgroundColor = editor.model.metadata.documentBackgroundColor;
42817
+ const resolvedPageSurfaceBackgroundColor = pageBackgroundColor ?? documentPageBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor;
42469
42818
  const pageBorders = parseSectionPageBorders(
42470
42819
  pageInfo?.section.sectionPropertiesXml ?? editor.model.metadata.sectionPropertiesXml
42471
42820
  );
@@ -42488,7 +42837,7 @@ ${currentText.slice(end)}`;
42488
42837
  width: pageLayout.pageWidthPx,
42489
42838
  height: pageLayout.pageHeightPx,
42490
42839
  minHeight: pageLayout.pageHeightPx,
42491
- backgroundColor: pageBackgroundColor ?? documentPageBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor,
42840
+ backgroundColor: resolvedPageSurfaceBackgroundColor,
42492
42841
  position: "relative",
42493
42842
  ...pageMarginPaddingStyle(pageLayout.marginsPx)
42494
42843
  };
@@ -43590,6 +43939,7 @@ ${currentText.slice(end)}`;
43590
43939
  top: 0,
43591
43940
  width: TRACKED_CHANGE_GUTTER_WIDTH_PX,
43592
43941
  height: pageLayout.pageHeightPx,
43942
+ backgroundColor: resolvedPageSurfaceBackgroundColor,
43593
43943
  pointerEvents: "none",
43594
43944
  overflow: "visible"
43595
43945
  },
@@ -43620,14 +43970,14 @@ ${currentText.slice(end)}`;
43620
43970
  overflow: "visible"
43621
43971
  },
43622
43972
  children: pageTrackedChanges.map((entry) => {
43623
- const accentColor = entry.annotation.trackedChange ? trackedChangeAccentColor(
43624
- entry.annotation.trackedChange.kind,
43973
+ const trackedChange = entry.annotation.trackedChange;
43974
+ const comment = entry.annotation.comment;
43975
+ const accentColor = trackedChange ? trackedChangeAccentColor(
43976
+ trackedChange.kind,
43625
43977
  editor.documentTheme
43626
- ) : commentAccentColor(editor.documentTheme);
43627
- const cardCenterY = clampNumber(
43628
- Math.round(entry.top + entry.heightPx / 2),
43629
- 8,
43630
- Math.max(8, pageLayout.pageHeightPx - 8)
43978
+ ) : commentAccentColor(
43979
+ editor.documentTheme,
43980
+ comment?.commentId
43631
43981
  );
43632
43982
  const anchorY = clampNumber(
43633
43983
  Math.round(entry.anchorY),
@@ -43639,48 +43989,50 @@ ${currentText.slice(end)}`;
43639
43989
  8,
43640
43990
  Math.max(8, pageLayout.pageWidthPx - 8)
43641
43991
  );
43642
- const cardLeadX = pageLayout.pageWidthPx + TRACKED_CHANGE_GUTTER_CARD_LEFT_PX - 6;
43643
- const bendX = clampNumber(
43644
- Math.round((anchorX + cardLeadX) / 2),
43645
- anchorX + 8,
43646
- Math.max(anchorX + 8, cardLeadX - 8)
43992
+ const cardAttachX = pageLayout.pageWidthPx + TRACKED_CHANGE_GUTTER_CARD_LEFT_PX;
43993
+ const gutterBendX = pageLayout.pageWidthPx + TRACKED_CHANGE_GUTTER_BEND_OFFSET_PX;
43994
+ const cardCenterY = clampNumber(
43995
+ Math.round(entry.top + entry.heightPx / 2),
43996
+ 8,
43997
+ Math.max(8, pageLayout.pageHeightPx - 8)
43998
+ );
43999
+ const connectorPath = Math.abs(cardCenterY - anchorY) <= 2 ? `M ${anchorX} ${anchorY} H ${cardAttachX}` : `M ${anchorX} ${anchorY} H ${gutterBendX} V ${cardCenterY} H ${cardAttachX}`;
44000
+ const revisionBarX = clampNumber(
44001
+ Math.round(pageLayout.marginsPx.left - 20),
44002
+ 8,
44003
+ Math.max(8, pageLayout.pageWidthPx - 8)
43647
44004
  );
43648
44005
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
43649
44006
  "g",
43650
44007
  {
43651
44008
  children: [
44009
+ trackedChange ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44010
+ "line",
44011
+ {
44012
+ x1: revisionBarX,
44013
+ y1: Math.max(8, anchorY - 16),
44014
+ x2: revisionBarX,
44015
+ y2: Math.min(
44016
+ pageLayout.pageHeightPx - 8,
44017
+ anchorY + 16
44018
+ ),
44019
+ stroke: editor.documentTheme === "dark" ? "#94a3b8" : "#9ca3af",
44020
+ strokeWidth: 1.25,
44021
+ strokeLinecap: "square"
44022
+ }
44023
+ ) : null,
43652
44024
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43653
44025
  "path",
43654
44026
  {
43655
- d: `M ${anchorX} ${anchorY} L ${bendX} ${anchorY} L ${cardLeadX} ${cardCenterY}`,
44027
+ d: connectorPath,
43656
44028
  stroke: accentColor,
43657
- strokeWidth: 1.75,
43658
- strokeOpacity: 1,
43659
- strokeDasharray: "5 4",
44029
+ strokeWidth: 1.15,
44030
+ strokeOpacity: 0.78,
44031
+ strokeDasharray: "2 3",
43660
44032
  strokeLinejoin: "round",
43661
44033
  strokeLinecap: "round",
43662
44034
  fill: "none"
43663
44035
  }
43664
- ),
43665
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43666
- "circle",
43667
- {
43668
- cx: anchorX,
43669
- cy: anchorY,
43670
- r: 2.2,
43671
- fill: accentColor,
43672
- stroke: editor.documentTheme === "dark" ? "#020617" : "#ffffff",
43673
- strokeWidth: 1
43674
- }
43675
- ),
43676
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43677
- "circle",
43678
- {
43679
- cx: cardLeadX,
43680
- cy: cardCenterY,
43681
- r: 1.8,
43682
- fill: accentColor
43683
- }
43684
44036
  )
43685
44037
  ]
43686
44038
  },
@@ -43711,7 +44063,10 @@ ${currentText.slice(end)}`;
43711
44063
  const accentColor = trackedChange ? trackedChangeAccentColor(
43712
44064
  trackedChange.kind,
43713
44065
  editor.documentTheme
43714
- ) : commentAccentColor(editor.documentTheme);
44066
+ ) : commentAccentColor(
44067
+ editor.documentTheme,
44068
+ comment?.commentId
44069
+ );
43715
44070
  const formattedDate = formatTrackedChangeDate(
43716
44071
  trackedChange?.date ?? comment?.date
43717
44072
  );
@@ -43738,15 +44093,15 @@ ${currentText.slice(end)}`;
43738
44093
  {
43739
44094
  style: {
43740
44095
  ...cardStyle,
43741
- padding: "6px 8px",
44096
+ padding: "4px 6px",
43742
44097
  boxSizing: "border-box",
43743
- borderLeft: `2px solid ${accentColor}`,
43744
- borderTop: `1px solid ${editor.documentTheme === "dark" ? "rgba(148, 163, 184, 0.28)" : "rgba(15, 23, 42, 0.12)"}`,
43745
- borderRight: `1px solid ${editor.documentTheme === "dark" ? "rgba(148, 163, 184, 0.28)" : "rgba(15, 23, 42, 0.12)"}`,
43746
- borderBottom: `1px solid ${editor.documentTheme === "dark" ? "rgba(148, 163, 184, 0.28)" : "rgba(15, 23, 42, 0.12)"}`,
43747
- backgroundColor: editor.documentTheme === "dark" ? "rgba(2, 6, 23, 0.96)" : "rgba(255, 255, 255, 0.96)",
44098
+ borderLeft: `1.5px solid ${accentColor}`,
44099
+ borderTop: `1px solid ${editor.documentTheme === "dark" ? "rgba(148, 163, 184, 0.18)" : "rgba(15, 23, 42, 0.08)"}`,
44100
+ borderRight: `1px solid ${editor.documentTheme === "dark" ? "rgba(148, 163, 184, 0.18)" : "rgba(15, 23, 42, 0.08)"}`,
44101
+ borderBottom: `1px solid ${editor.documentTheme === "dark" ? "rgba(148, 163, 184, 0.18)" : "rgba(15, 23, 42, 0.08)"}`,
44102
+ backgroundColor: editor.documentTheme === "dark" ? "rgba(15, 23, 42, 0.92)" : "rgba(255, 255, 255, 0.72)",
43748
44103
  color: editor.documentTheme === "dark" ? "#f3f4f6" : "#111827",
43749
- boxShadow: editor.documentTheme === "dark" ? "0 2px 6px rgba(2, 6, 23, 0.55)" : "0 1px 2px rgba(15, 23, 42, 0.14)"
44104
+ boxShadow: editor.documentTheme === "dark" ? "0 1px 2px rgba(2, 6, 23, 0.45)" : "0 1px 1px rgba(15, 23, 42, 0.08)"
43750
44105
  },
43751
44106
  children: [
43752
44107
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -43764,9 +44119,9 @@ ${currentText.slice(end)}`;
43764
44119
  {
43765
44120
  style: {
43766
44121
  margin: 0,
43767
- fontSize: 12,
44122
+ fontSize: 10,
43768
44123
  fontWeight: 700,
43769
- lineHeight: 1.25
44124
+ lineHeight: 1.2
43770
44125
  },
43771
44126
  children: (trackedChange?.author ?? comment?.author)?.trim() || "Unknown author"
43772
44127
  }
@@ -43776,8 +44131,8 @@ ${currentText.slice(end)}`;
43776
44131
  {
43777
44132
  style: {
43778
44133
  margin: 0,
43779
- fontSize: 11,
43780
- lineHeight: 1.2,
44134
+ fontSize: 9,
44135
+ lineHeight: 1.15,
43781
44136
  color: editor.documentTheme === "dark" ? "#94a3b8" : "#6b7280",
43782
44137
  whiteSpace: "nowrap"
43783
44138
  },
@@ -43792,8 +44147,8 @@ ${currentText.slice(end)}`;
43792
44147
  {
43793
44148
  style: {
43794
44149
  margin: "2px 0 0",
43795
- fontSize: 11,
43796
- lineHeight: 1.3,
44150
+ fontSize: 9,
44151
+ lineHeight: 1.25,
43797
44152
  fontStyle: "italic",
43798
44153
  color: editor.documentTheme === "dark" ? "#94a3b8" : "#6b7280"
43799
44154
  },
@@ -43809,8 +44164,8 @@ ${currentText.slice(end)}`;
43809
44164
  {
43810
44165
  style: {
43811
44166
  margin: "2px 0 0",
43812
- fontSize: 12,
43813
- lineHeight: 1.35
44167
+ fontSize: 10,
44168
+ lineHeight: 1.25
43814
44169
  },
43815
44170
  children: [
43816
44171
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("strong", { children: [
@@ -43847,6 +44202,9 @@ ${currentText.slice(end)}`;
43847
44202
  "div",
43848
44203
  {
43849
44204
  "data-docx-gutter-annotation": trackedChange ? "tracked-change" : "comment",
44205
+ "data-docx-gutter-annotation-id": entry.annotation.id,
44206
+ "data-docx-gutter-anchor-x": Math.round(entry.anchorX),
44207
+ "data-docx-gutter-anchor-y": Math.round(entry.anchorY),
43850
44208
  ref: (element) => {
43851
44209
  const elementKey = `${pageIndex}:${entry.annotation.id}`;
43852
44210
  if (element) {
@@ -45732,7 +46090,6 @@ function buildLayoutSnapshot(model, options = {}) {
45732
46090
  }
45733
46091
 
45734
46092
  // src/index.tsx
45735
- init_src();
45736
46093
  var import_jsx_runtime2 = require("react/jsx-runtime");
45737
46094
  var HIGHLIGHT_TO_CSS2 = {
45738
46095
  yellow: "#fff59d",