@harbour-enterprises/superdoc 1.0.2 → 1.0.3

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 (30) hide show
  1. package/dist/chunks/{PdfViewer-Dk7wI3bm.cjs → PdfViewer-2wYU1nQs.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C51KNTCu.es.js → PdfViewer-Brf64q-p.es.js} +1 -1
  3. package/dist/chunks/{index-DDZ1ZT8N-DzepXBTN.cjs → index-BFesQTtm-DF8MwT73.cjs} +1 -1
  4. package/dist/chunks/{index-DDZ1ZT8N-MJzqg0qg.es.js → index-BFesQTtm-DNeH374x.es.js} +1 -1
  5. package/dist/chunks/{index-Cf7hdzkm.cjs → index-DeETxTrW.cjs} +3 -3
  6. package/dist/chunks/{index-rtbawgUA.es.js → index-KBIvw6xZ.es.js} +3 -3
  7. package/dist/chunks/{super-editor.es-BijxiFs9.cjs → super-editor.es-C_LoTWvJ.cjs} +687 -136
  8. package/dist/chunks/{super-editor.es-DFXddrgb.es.js → super-editor.es-DWpzsMUa.es.js} +687 -136
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/style.css +6 -6
  11. package/dist/super-editor/ai-writer.es.js +2 -2
  12. package/dist/super-editor/chunks/{converter-VYPiNbpo.js → converter-BhELnOP5.js} +1 -1
  13. package/dist/super-editor/chunks/{docx-zipper-D8Tzq3RX.js → docx-zipper-Bwi8bTEB.js} +1 -1
  14. package/dist/super-editor/chunks/{editor-mgoEnsBi.js → editor-Dyj08tpz.js} +684 -150
  15. package/dist/super-editor/chunks/{index-DDZ1ZT8N.js → index-BFesQTtm.js} +1 -1
  16. package/dist/super-editor/chunks/{toolbar-DULgxvjl.js → toolbar-DRFf1nRv.js} +2 -2
  17. package/dist/super-editor/converter.es.js +1 -1
  18. package/dist/super-editor/docx-zipper.es.js +2 -2
  19. package/dist/super-editor/editor.es.js +3 -3
  20. package/dist/super-editor/file-zipper.es.js +1 -1
  21. package/dist/super-editor/style.css +6 -6
  22. package/dist/super-editor/super-editor.es.js +41 -17
  23. package/dist/super-editor/toolbar.es.js +2 -2
  24. package/dist/super-editor.cjs +1 -1
  25. package/dist/super-editor.es.js +1 -1
  26. package/dist/superdoc.cjs +2 -2
  27. package/dist/superdoc.es.js +2 -2
  28. package/dist/superdoc.umd.js +689 -138
  29. package/dist/superdoc.umd.js.map +1 -1
  30. package/package.json +1 -1
@@ -42427,7 +42427,7 @@ const _SuperConverter = class _SuperConverter2 {
42427
42427
  static getStoredSuperdocVersion(docx) {
42428
42428
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42429
42429
  }
42430
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.2") {
42430
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.3") {
42431
42431
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42432
42432
  }
42433
42433
  /**
@@ -60508,7 +60508,7 @@ const isHeadless = (editor) => {
60508
60508
  const shouldSkipNodeView = (editor) => {
60509
60509
  return isHeadless(editor);
60510
60510
  };
60511
- const summaryVersion = "1.0.2";
60511
+ const summaryVersion = "1.0.3";
60512
60512
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
60513
60513
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
60514
60514
  function mapAttributes(attrs) {
@@ -61297,7 +61297,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
61297
61297
  { default: remarkStringify },
61298
61298
  { default: remarkGfm }
61299
61299
  ] = await Promise.all([
61300
- Promise.resolve().then(() => require("./index-DDZ1ZT8N-DzepXBTN.cjs")),
61300
+ Promise.resolve().then(() => require("./index-BFesQTtm-DF8MwT73.cjs")),
61301
61301
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
61302
61302
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
61303
61303
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -61502,7 +61502,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
61502
61502
  * Process collaboration migrations
61503
61503
  */
61504
61504
  processCollaborationMigrations() {
61505
- console.debug("[checkVersionMigrations] Current editor version", "1.0.2");
61505
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.3");
61506
61506
  if (!this.options.ydoc) return;
61507
61507
  const metaMap = this.options.ydoc.getMap("meta");
61508
61508
  let docVersion = metaMap.get("version");
@@ -68754,7 +68754,7 @@ function isMinimalWordLayout(value) {
68754
68754
  return true;
68755
68755
  }
68756
68756
  const LIST_MARKER_GAP$2 = 8;
68757
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
68757
+ const DEFAULT_TAB_INTERVAL_PX$2 = 48;
68758
68758
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
68759
68759
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
68760
68760
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -69681,6 +69681,7 @@ const _DomPainter = class _DomPainter2 {
69681
69681
  const block = lookup2.block;
69682
69682
  const measure = lookup2.measure;
69683
69683
  const wordLayout = isMinimalWordLayout(block.attrs?.wordLayout) ? block.attrs.wordLayout : void 0;
69684
+ const alignment2 = block.attrs?.alignment;
69684
69685
  const fragmentEl = this.doc.createElement("div");
69685
69686
  fragmentEl.classList.add(CLASS_NAMES$1.fragment);
69686
69687
  const isTocEntry = block.attrs?.isTocEntry;
@@ -69759,7 +69760,7 @@ const _DomPainter = class _DomPainter2 {
69759
69760
  const textStart = paraIndentLeft + firstLine;
69760
69761
  tabWidth = textStart - currentPos;
69761
69762
  if (tabWidth <= 0) {
69762
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
69763
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
69763
69764
  } else if (tabWidth < LIST_MARKER_GAP$2) {
69764
69765
  tabWidth = LIST_MARKER_GAP$2;
69765
69766
  }
@@ -69786,6 +69787,21 @@ const _DomPainter = class _DomPainter2 {
69786
69787
  let availableWidthOverride = line.maxWidth != null ? Math.min(line.maxWidth, fallbackAvailableWidth) : fallbackAvailableWidth;
69787
69788
  if (index2 === 0 && listFirstLineMarkerTabWidth != null) {
69788
69789
  availableWidthOverride = fragment.width - listFirstLineMarkerTabWidth - Math.max(0, paraIndentRight);
69790
+ if (alignment2 === "justify" || alignment2 === "both") {
69791
+ console.log(
69792
+ "[justify-debug][painter-firstline-available]",
69793
+ JSON.stringify({
69794
+ blockId: block.id,
69795
+ fragmentWidth: fragment.width,
69796
+ markerTabWidth: listFirstLineMarkerTabWidth,
69797
+ paraIndentRight,
69798
+ availableWidthOverride,
69799
+ lineMaxWidth: line.maxWidth ?? null,
69800
+ lineWidth: line.width,
69801
+ lineNaturalWidth: line.naturalWidth ?? null
69802
+ })
69803
+ );
69804
+ }
69789
69805
  }
69790
69806
  const isLastLineOfFragment = index2 === lines.length - 1;
69791
69807
  const isLastLineOfParagraph = isLastLineOfFragment && !fragment.continuesOnNext;
@@ -69911,7 +69927,7 @@ const _DomPainter = class _DomPainter2 {
69911
69927
  const textStart = paraIndentLeft + firstLine;
69912
69928
  tabWidth = textStart - currentPos;
69913
69929
  if (tabWidth <= 0) {
69914
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
69930
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
69915
69931
  } else if (tabWidth < LIST_MARKER_GAP$2) {
69916
69932
  tabWidth = LIST_MARKER_GAP$2;
69917
69933
  }
@@ -71445,6 +71461,23 @@ const _DomPainter = class _DomPainter2 {
71445
71461
  if (spacingPerSpace !== 0) {
71446
71462
  el.style.wordSpacing = `${spacingPerSpace}px`;
71447
71463
  }
71464
+ if (justifyShouldApply && spacingPerSpace < 0) {
71465
+ console.log(
71466
+ "[justify-debug][painter-wordspacing-negative]",
71467
+ JSON.stringify({
71468
+ blockId: block.id,
71469
+ lineIndex: lineIndex ?? null,
71470
+ alignment: alignment2 ?? null,
71471
+ availableWidth,
71472
+ lineWidth,
71473
+ lineMaxWidth: line.maxWidth ?? null,
71474
+ lineNaturalWidth: line.naturalWidth ?? null,
71475
+ spaceCount,
71476
+ hasExplicitPositioning: Boolean(hasExplicitPositioning),
71477
+ skipJustify: Boolean(skipJustify)
71478
+ })
71479
+ );
71480
+ }
71448
71481
  if (hasExplicitPositioning && line.segments) {
71449
71482
  const paraIndent = block.attrs?.indent;
71450
71483
  const indentLeft = paraIndent?.left ?? 0;
@@ -73638,6 +73671,28 @@ let measurementCtx = null;
73638
73671
  const TAB_CHAR_LENGTH = 1;
73639
73672
  const SPACE_CHARS = SPACE_CHARS$1;
73640
73673
  const isTabRun$1 = (run2) => run2?.kind === "tab";
73674
+ const isWordChar$3 = (char) => {
73675
+ if (!char) return false;
73676
+ const code = char.charCodeAt(0);
73677
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
73678
+ };
73679
+ const capitalizeText$2 = (text) => {
73680
+ if (!text) return text;
73681
+ let result = "";
73682
+ for (let i = 0; i < text.length; i += 1) {
73683
+ const prevChar = i > 0 ? text[i - 1] : "";
73684
+ const ch = text[i];
73685
+ result += isWordChar$3(ch) && !isWordChar$3(prevChar) ? ch.toUpperCase() : ch;
73686
+ }
73687
+ return result;
73688
+ };
73689
+ const applyTextTransform$2 = (text, transform) => {
73690
+ if (!text || !transform || transform === "none") return text;
73691
+ if (transform === "uppercase") return text.toUpperCase();
73692
+ if (transform === "lowercase") return text.toLowerCase();
73693
+ if (transform === "capitalize") return capitalizeText$2(text);
73694
+ return text;
73695
+ };
73641
73696
  function getMeasurementContext() {
73642
73697
  if (measurementCtx) return measurementCtx;
73643
73698
  if (typeof document === "undefined") {
@@ -73813,17 +73868,18 @@ function measureCharacterX(block, line, charOffset, availableWidthOverride, alig
73813
73868
  }
73814
73869
  const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73815
73870
  const runLength = text.length;
73871
+ const displayText = applyTextTransform$2(text, run2.textTransform);
73816
73872
  if (currentCharOffset + runLength >= charOffset) {
73817
73873
  const offsetInRun = charOffset - currentCharOffset;
73818
73874
  ctx2.font = getRunFontString(run2);
73819
- const textUpToTarget = text.slice(0, offsetInRun);
73875
+ const textUpToTarget = displayText.slice(0, offsetInRun);
73820
73876
  const measured2 = ctx2.measureText(textUpToTarget);
73821
73877
  const spacingWidth = computeLetterSpacingWidth(run2, offsetInRun, runLength);
73822
- const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(textUpToTarget) : 0;
73878
+ const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(text.slice(0, offsetInRun)) : 0;
73823
73879
  return alignmentOffset + currentX + measured2.width + spacingWidth + justify.extraPerSpace * (spaceTally + spacesInPortion);
73824
73880
  }
73825
73881
  ctx2.font = getRunFontString(run2);
73826
- const measured = ctx2.measureText(text);
73882
+ const measured = ctx2.measureText(displayText);
73827
73883
  const runLetterSpacing = computeLetterSpacingWidth(run2, runLength, runLength);
73828
73884
  const spacesInRun = justify.extraPerSpace !== 0 ? countSpaces(text) : 0;
73829
73885
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -73862,8 +73918,9 @@ function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
73862
73918
  return segmentBaseX + (offsetInSegment >= segmentChars ? segment.width ?? 0 : 0);
73863
73919
  }
73864
73920
  const text = run2.text ?? "";
73865
- const segmentText = text.slice(segment.fromChar, segment.toChar);
73866
- const textUpToTarget = segmentText.slice(0, offsetInSegment);
73921
+ const displayText = applyTextTransform$2(text, run2.textTransform);
73922
+ const displaySegmentText = displayText.slice(segment.fromChar, segment.toChar);
73923
+ const textUpToTarget = displaySegmentText.slice(0, offsetInSegment);
73867
73924
  ctx2.font = getRunFontString(run2);
73868
73925
  const measured = ctx2.measureText(textUpToTarget);
73869
73926
  const spacingWidth = computeLetterSpacingWidth(run2, offsetInSegment, segmentChars);
@@ -73959,12 +74016,13 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73959
74016
  }
73960
74017
  const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73961
74018
  const runLength = text.length;
74019
+ const displayText = applyTextTransform$2(text, run2.textTransform);
73962
74020
  if (runLength === 0) continue;
73963
74021
  ctx2.font = getRunFontString(run2);
73964
74022
  for (let i = 0; i <= runLength; i++) {
73965
- const textUpToChar = text.slice(0, i);
74023
+ const textUpToChar = displayText.slice(0, i);
73966
74024
  const measured2 = ctx2.measureText(textUpToChar);
73967
- const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(textUpToChar) : 0;
74025
+ const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(text.slice(0, i)) : 0;
73968
74026
  const charX = currentX + measured2.width + computeLetterSpacingWidth(run2, i, runLength) + justify.extraPerSpace * (spaceTally + spacesInPortion);
73969
74027
  if (charX >= safeX) {
73970
74028
  if (i === 0) {
@@ -73974,7 +74032,7 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73974
74032
  pmPosition: pmPosition3
73975
74033
  };
73976
74034
  }
73977
- const prevText = text.slice(0, i - 1);
74035
+ const prevText = displayText.slice(0, i - 1);
73978
74036
  const prevMeasured = ctx2.measureText(prevText);
73979
74037
  const prevX = currentX + prevMeasured.width + computeLetterSpacingWidth(run2, i - 1, runLength);
73980
74038
  const distToPrev = Math.abs(safeX - prevX);
@@ -73987,7 +74045,7 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73987
74045
  };
73988
74046
  }
73989
74047
  }
73990
- const measured = ctx2.measureText(text);
74048
+ const measured = ctx2.measureText(displayText);
73991
74049
  const runLetterSpacing = computeLetterSpacingWidth(run2, runLength, runLength);
73992
74050
  const spacesInRun = justify.extraPerSpace > 0 ? countSpaces(text) : 0;
73993
74051
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -74418,6 +74476,83 @@ function findCharIndexAtX(textNode, container, targetX) {
74418
74476
  }
74419
74477
  return index2;
74420
74478
  }
74479
+ const LIST_MARKER_GAP$1 = 8;
74480
+ const MIN_MARKER_GUTTER = 24;
74481
+ const DEFAULT_LIST_INDENT_BASE_PX = 24;
74482
+ const DEFAULT_LIST_INDENT_STEP_PX = 24;
74483
+ const DEFAULT_LIST_HANGING_PX$1 = 18;
74484
+ const SPACE_SUFFIX_GAP_PX = 4;
74485
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74486
+ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
74487
+ const marker = wordLayout?.marker;
74488
+ if (!marker) {
74489
+ const textStartPx = wordLayout?.firstLineIndentMode === true && typeof wordLayout.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
74490
+ return textStartPx;
74491
+ }
74492
+ const markerBoxWidth = typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0;
74493
+ let markerTextWidth = typeof marker.glyphWidthPx === "number" && Number.isFinite(marker.glyphWidthPx) ? marker.glyphWidthPx : void 0;
74494
+ if (markerTextWidth == null && marker.markerText) {
74495
+ markerTextWidth = measureMarkerText(marker.markerText, marker);
74496
+ }
74497
+ if (!Number.isFinite(markerTextWidth) || markerTextWidth < 0) {
74498
+ markerTextWidth = markerBoxWidth;
74499
+ }
74500
+ markerTextWidth = Math.max(0, markerTextWidth);
74501
+ let markerStartPos;
74502
+ if (wordLayout?.firstLineIndentMode === true && Number.isFinite(marker.markerX)) {
74503
+ markerStartPos = marker.markerX;
74504
+ } else {
74505
+ markerStartPos = indentLeft - hanging + firstLine;
74506
+ }
74507
+ if (!Number.isFinite(markerStartPos)) {
74508
+ markerStartPos = 0;
74509
+ }
74510
+ const currentPos = markerStartPos + markerTextWidth;
74511
+ const suffix2 = marker.suffix ?? "tab";
74512
+ if (suffix2 === "space") {
74513
+ return markerStartPos + markerTextWidth + SPACE_SUFFIX_GAP_PX;
74514
+ }
74515
+ if (suffix2 === "nothing") {
74516
+ return markerStartPos + markerTextWidth;
74517
+ }
74518
+ const markerJustification = marker.justification ?? "left";
74519
+ if (markerJustification !== "left") {
74520
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
74521
+ return markerStartPos + markerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
74522
+ }
74523
+ if (wordLayout?.firstLineIndentMode === true) {
74524
+ let targetTabStop;
74525
+ if (Array.isArray(wordLayout.tabsPx)) {
74526
+ for (const tab of wordLayout.tabsPx) {
74527
+ if (typeof tab === "number" && tab > currentPos) {
74528
+ targetTabStop = tab;
74529
+ break;
74530
+ }
74531
+ }
74532
+ }
74533
+ const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
74534
+ let tabWidth2;
74535
+ if (targetTabStop !== void 0) {
74536
+ tabWidth2 = targetTabStop - currentPos;
74537
+ } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
74538
+ tabWidth2 = textStartTarget - currentPos;
74539
+ } else {
74540
+ tabWidth2 = LIST_MARKER_GAP$1;
74541
+ }
74542
+ if (tabWidth2 < LIST_MARKER_GAP$1) {
74543
+ tabWidth2 = LIST_MARKER_GAP$1;
74544
+ }
74545
+ return markerStartPos + markerTextWidth + tabWidth2;
74546
+ }
74547
+ const textStart = indentLeft + firstLine;
74548
+ let tabWidth = textStart - currentPos;
74549
+ if (tabWidth <= 0) {
74550
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
74551
+ } else if (tabWidth < LIST_MARKER_GAP$1) {
74552
+ tabWidth = LIST_MARKER_GAP$1;
74553
+ }
74554
+ return markerStartPos + markerTextWidth + tabWidth;
74555
+ }
74421
74556
  function getWordLayoutConfig(block) {
74422
74557
  if (!block || block.kind !== "paragraph") {
74423
74558
  return void 0;
@@ -74450,9 +74585,16 @@ function calculateTextStartIndent(params2) {
74450
74585
  const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
74451
74586
  let indentAdjust = paraIndentLeft;
74452
74587
  if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
74588
+ const resolvedTextStart = resolveListTextStartPx(
74589
+ wordLayout,
74590
+ paraIndentLeft,
74591
+ Math.max(firstLineIndent, 0),
74592
+ Math.max(hangingIndent, 0),
74593
+ () => markerWidth
74594
+ // Use provided markerWidth since we don't have canvas access here
74595
+ );
74453
74596
  const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
74454
- const markerTextStartX = wordLayout?.marker?.textStartX;
74455
- indentAdjust = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : textStartFallback;
74597
+ indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
74456
74598
  } else if (isFirstLine && !isListItem2) {
74457
74599
  indentAdjust += firstLineOffset;
74458
74600
  }
@@ -74608,7 +74750,10 @@ function getHeaderFooterTypeForSection(pageNumber, sectionIndex, identifier, opt
74608
74750
  }
74609
74751
  function createFloatingObjectManager(columns, margins, pageWidth) {
74610
74752
  const zones = [];
74611
- const marginLeft = Math.max(0, margins?.left ?? 0);
74753
+ let currentColumns = columns;
74754
+ let currentMargins = margins;
74755
+ let currentPageWidth = pageWidth;
74756
+ let marginLeft = Math.max(0, currentMargins?.left ?? 0);
74612
74757
  return {
74613
74758
  registerDrawing(drawingBlock, measure, anchorY, columnIndex, pageNumber) {
74614
74759
  if (!drawingBlock.anchor?.isAnchored) {
@@ -74621,7 +74766,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74621
74766
  }
74622
74767
  const objectWidth = measure.width ?? 0;
74623
74768
  const objectHeight = measure.height ?? 0;
74624
- const x2 = computeAnchorX(anchor, columnIndex, columns, objectWidth, margins, pageWidth);
74769
+ const x2 = computeAnchorX(anchor, columnIndex, currentColumns, objectWidth, currentMargins, currentPageWidth);
74625
74770
  const y2 = anchorY + (anchor.offsetV ?? 0);
74626
74771
  const zone = {
74627
74772
  imageBlockId: drawingBlock.id,
@@ -74655,7 +74800,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74655
74800
  }
74656
74801
  const tableWidth = measure.totalWidth ?? 0;
74657
74802
  const tableHeight = measure.totalHeight ?? 0;
74658
- const x2 = computeTableAnchorX(anchor, columnIndex, columns, tableWidth, margins, pageWidth);
74803
+ const x2 = computeTableAnchorX(anchor, columnIndex, currentColumns, tableWidth, currentMargins, currentPageWidth);
74659
74804
  const y2 = anchorY + (anchor.offsetV ?? 0);
74660
74805
  const zone = {
74661
74806
  imageBlockId: tableBlock.id,
@@ -74703,7 +74848,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74703
74848
  }
74704
74849
  const leftFloats = [];
74705
74850
  const rightFloats = [];
74706
- const columnOrigin = marginLeft + columnIndex * (columns.width + columns.gap);
74851
+ const columnOrigin = marginLeft + columnIndex * (currentColumns.width + currentColumns.gap);
74707
74852
  const columnCenter = columnOrigin + baseWidth / 2;
74708
74853
  for (const zone of wrappingZones) {
74709
74854
  if (zone.wrapMode === "left") {
@@ -74742,6 +74887,22 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74742
74887
  },
74743
74888
  clear() {
74744
74889
  zones.length = 0;
74890
+ },
74891
+ /**
74892
+ * Update layout context used for positioning and wrapping (columns, margins, page width).
74893
+ * This method should be called when the layout configuration changes (e.g., section breaks,
74894
+ * column changes, page size changes) to ensure floating objects are positioned and wrapped
74895
+ * correctly relative to the new layout boundaries.
74896
+ *
74897
+ * @param nextColumns - Column layout configuration (width, gap, count)
74898
+ * @param nextMargins - Optional page margins (left, right) in pixels
74899
+ * @param nextPageWidth - Optional total page width in pixels
74900
+ */
74901
+ setLayoutContext(nextColumns, nextMargins, nextPageWidth) {
74902
+ currentColumns = nextColumns;
74903
+ currentMargins = nextMargins;
74904
+ currentPageWidth = nextPageWidth;
74905
+ marginLeft = Math.max(0, currentMargins?.left ?? 0);
74745
74906
  }
74746
74907
  };
74747
74908
  }
@@ -74841,7 +75002,14 @@ function computeNextSectionPropsAtBreak(blocks) {
74841
75002
  const props = {};
74842
75003
  if (source.kind !== "sectionBreak") return props;
74843
75004
  if (source.margins) {
74844
- props.margins = { header: source.margins.header, footer: source.margins.footer };
75005
+ props.margins = {
75006
+ header: source.margins.header,
75007
+ footer: source.margins.footer,
75008
+ top: source.margins.top,
75009
+ right: source.margins.right,
75010
+ bottom: source.margins.bottom,
75011
+ left: source.margins.left
75012
+ };
74845
75013
  }
74846
75014
  if (source.pageSize) {
74847
75015
  props.pageSize = { w: source.pageSize.w, h: source.pageSize.h };
@@ -74889,20 +75057,36 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
74889
75057
  next.activeOrientation = block.orientation;
74890
75058
  next.pendingOrientation = null;
74891
75059
  }
75060
+ const headerDistance = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
75061
+ const footerDistance = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
75062
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
75063
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
74892
75064
  if (block.margins?.header !== void 0) {
74893
- const headerDistance = Math.max(0, block.margins.header);
74894
75065
  next.activeHeaderDistance = headerDistance;
74895
75066
  next.pendingHeaderDistance = headerDistance;
74896
- next.activeTopMargin = calcRequiredTopMargin(headerDistance, baseMargins.top);
74897
- next.pendingTopMargin = next.activeTopMargin;
74898
75067
  }
74899
75068
  if (block.margins?.footer !== void 0) {
74900
- const footerDistance = Math.max(0, block.margins.footer);
74901
75069
  next.activeFooterDistance = footerDistance;
74902
75070
  next.pendingFooterDistance = footerDistance;
74903
- next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
75071
+ }
75072
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
75073
+ next.activeTopMargin = calcRequiredTopMargin(headerDistance, sectionTop);
75074
+ next.pendingTopMargin = next.activeTopMargin;
75075
+ }
75076
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
75077
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, sectionBottom);
74904
75078
  next.pendingBottomMargin = next.activeBottomMargin;
74905
75079
  }
75080
+ if (block.margins?.left !== void 0) {
75081
+ const leftMargin = Math.max(0, block.margins.left);
75082
+ next.activeLeftMargin = leftMargin;
75083
+ next.pendingLeftMargin = leftMargin;
75084
+ }
75085
+ if (block.margins?.right !== void 0) {
75086
+ const rightMargin = Math.max(0, block.margins.right);
75087
+ next.activeRightMargin = rightMargin;
75088
+ next.pendingRightMargin = rightMargin;
75089
+ }
74906
75090
  if (block.columns) {
74907
75091
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
74908
75092
  next.pendingColumns = null;
@@ -74911,26 +75095,42 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
74911
75095
  }
74912
75096
  const headerPx = block.margins?.header;
74913
75097
  const footerPx = block.margins?.footer;
75098
+ const topPx = block.margins?.top;
75099
+ const bottomPx = block.margins?.bottom;
74914
75100
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
74915
75101
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
75102
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
75103
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
74916
75104
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
74917
75105
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
74918
- if (typeof headerPx === "number") {
74919
- const newHeaderDist = Math.max(0, headerPx);
75106
+ if (typeof headerPx === "number" || typeof topPx === "number") {
75107
+ const newHeaderDist = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
75108
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
74920
75109
  next.pendingHeaderDistance = newHeaderDist;
74921
- next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, baseMargins.top);
75110
+ next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, sectionTop);
74922
75111
  } else {
74923
75112
  next.pendingTopMargin = nextTop;
74924
75113
  next.pendingHeaderDistance = nextHeader;
74925
75114
  }
74926
- if (typeof footerPx === "number") {
74927
- const newFooterDist = Math.max(0, footerPx);
75115
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
75116
+ const newFooterDist = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
75117
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
74928
75118
  next.pendingFooterDistance = newFooterDist;
74929
- next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
75119
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, sectionBottom);
74930
75120
  } else {
74931
75121
  next.pendingBottomMargin = nextBottom;
74932
75122
  next.pendingFooterDistance = nextFooter;
74933
75123
  }
75124
+ if (typeof block.margins?.left === "number") {
75125
+ next.pendingLeftMargin = Math.max(0, block.margins.left);
75126
+ } else {
75127
+ next.pendingLeftMargin = nextLeft;
75128
+ }
75129
+ if (typeof block.margins?.right === "number") {
75130
+ next.pendingRightMargin = Math.max(0, block.margins.right);
75131
+ } else {
75132
+ next.pendingRightMargin = nextRight;
75133
+ }
74934
75134
  if (block.pageSize) {
74935
75135
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
74936
75136
  }
@@ -74990,6 +75190,12 @@ function applyPendingToActive(state2) {
74990
75190
  if (next.pendingBottomMargin != null) {
74991
75191
  next.activeBottomMargin = next.pendingBottomMargin;
74992
75192
  }
75193
+ if (next.pendingLeftMargin != null) {
75194
+ next.activeLeftMargin = next.pendingLeftMargin;
75195
+ }
75196
+ if (next.pendingRightMargin != null) {
75197
+ next.activeRightMargin = next.pendingRightMargin;
75198
+ }
74993
75199
  if (next.pendingHeaderDistance != null) {
74994
75200
  next.activeHeaderDistance = next.pendingHeaderDistance;
74995
75201
  }
@@ -75007,6 +75213,8 @@ function applyPendingToActive(state2) {
75007
75213
  }
75008
75214
  next.pendingTopMargin = null;
75009
75215
  next.pendingBottomMargin = null;
75216
+ next.pendingLeftMargin = null;
75217
+ next.pendingRightMargin = null;
75010
75218
  next.pendingHeaderDistance = null;
75011
75219
  next.pendingFooterDistance = null;
75012
75220
  next.pendingPageSize = null;
@@ -75235,7 +75443,8 @@ function layoutParagraphBlock(ctx2, anchors) {
75235
75443
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
75236
75444
  const firstLineIndent = calculateFirstLineIndent(block, measure);
75237
75445
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
75238
- lines = normalizeLines(newMeasure);
75446
+ const newLines = normalizeLines(newMeasure);
75447
+ lines = newLines;
75239
75448
  didRemeasureForColumnWidth = true;
75240
75449
  }
75241
75450
  let fromLine = 0;
@@ -75317,7 +75526,8 @@ function layoutParagraphBlock(ctx2, anchors) {
75317
75526
  if (narrowestRemeasureWidth < remeasureWidth) {
75318
75527
  const firstLineIndent = calculateFirstLineIndent(block, measure);
75319
75528
  const newMeasure = remeasureParagraph2(block, narrowestRemeasureWidth, firstLineIndent);
75320
- lines = normalizeLines(newMeasure);
75529
+ const newLines = normalizeLines(newMeasure);
75530
+ lines = newLines;
75321
75531
  didRemeasureForFloats = true;
75322
75532
  }
75323
75533
  }
@@ -75661,6 +75871,94 @@ function getCellPadding(cellIdx, blockRow) {
75661
75871
  function getCellTotalLines(cell) {
75662
75872
  return getCellLines(cell).length;
75663
75873
  }
75874
+ function mergePmRange(target, range2) {
75875
+ if (typeof range2.pmStart === "number") {
75876
+ target.pmStart = target.pmStart == null ? range2.pmStart : Math.min(target.pmStart, range2.pmStart);
75877
+ }
75878
+ if (typeof range2.pmEnd === "number") {
75879
+ target.pmEnd = target.pmEnd == null ? range2.pmEnd : Math.max(target.pmEnd, range2.pmEnd);
75880
+ }
75881
+ }
75882
+ function computeCellPmRange(cell, cellMeasure, fromLine, toLine) {
75883
+ const range2 = {};
75884
+ if (!cell || !cellMeasure) return range2;
75885
+ const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
75886
+ const blockMeasures = cellMeasure.blocks ?? (cellMeasure.paragraph ? [cellMeasure.paragraph] : []);
75887
+ const maxBlocks = Math.min(cellBlocks.length, blockMeasures.length);
75888
+ let cumulativeLineCount = 0;
75889
+ for (let i = 0; i < maxBlocks; i++) {
75890
+ const block = cellBlocks[i];
75891
+ const blockMeasure = blockMeasures[i];
75892
+ if (blockMeasure.kind === "paragraph" && block?.kind === "paragraph") {
75893
+ const paraMeasure = blockMeasure;
75894
+ const lines = paraMeasure.lines;
75895
+ const blockLineCount = lines?.length ?? 0;
75896
+ const blockStartGlobal = cumulativeLineCount;
75897
+ const blockEndGlobal = cumulativeLineCount + blockLineCount;
75898
+ const localFrom = Math.max(fromLine, blockStartGlobal) - blockStartGlobal;
75899
+ const localTo = Math.min(toLine, blockEndGlobal) - blockStartGlobal;
75900
+ if (lines && lines.length > 0 && localFrom < localTo) {
75901
+ mergePmRange(range2, computeFragmentPmRange(block, lines, localFrom, localTo));
75902
+ } else {
75903
+ mergePmRange(range2, extractBlockPmRange(block));
75904
+ }
75905
+ cumulativeLineCount += blockLineCount;
75906
+ continue;
75907
+ }
75908
+ mergePmRange(range2, extractBlockPmRange(block));
75909
+ }
75910
+ return range2;
75911
+ }
75912
+ function computeTableFragmentPmRange(block, measure, fromRow, toRow, partialRow) {
75913
+ const range2 = {};
75914
+ for (let rowIndex = fromRow; rowIndex < toRow; rowIndex++) {
75915
+ const row = block.rows[rowIndex];
75916
+ const rowMeasure = measure.rows[rowIndex];
75917
+ if (!row || !rowMeasure) continue;
75918
+ const isPartial = partialRow?.rowIndex === rowIndex;
75919
+ const cellCount = Math.min(row.cells.length, rowMeasure.cells.length);
75920
+ for (let cellIndex = 0; cellIndex < cellCount; cellIndex++) {
75921
+ const cell = row.cells[cellIndex];
75922
+ const cellMeasure = rowMeasure.cells[cellIndex];
75923
+ if (!cell || !cellMeasure) continue;
75924
+ const totalLines = getCellTotalLines(cellMeasure);
75925
+ let fromLine = 0;
75926
+ let toLine = totalLines;
75927
+ if (isPartial) {
75928
+ const hasValidFromLineByCell = partialRow?.fromLineByCell && cellIndex < partialRow.fromLineByCell.length;
75929
+ const hasValidToLineByCell = partialRow?.toLineByCell && cellIndex < partialRow.toLineByCell.length;
75930
+ if (hasValidFromLineByCell) {
75931
+ const rawFrom = partialRow.fromLineByCell[cellIndex];
75932
+ if (typeof rawFrom === "number" && rawFrom >= 0) {
75933
+ fromLine = rawFrom;
75934
+ }
75935
+ }
75936
+ if (hasValidToLineByCell) {
75937
+ const rawTo = partialRow.toLineByCell[cellIndex];
75938
+ if (typeof rawTo === "number") {
75939
+ toLine = rawTo === -1 ? totalLines : rawTo;
75940
+ }
75941
+ }
75942
+ }
75943
+ fromLine = Math.max(0, Math.min(fromLine, totalLines));
75944
+ toLine = Math.max(0, Math.min(toLine, totalLines));
75945
+ if (toLine < fromLine) {
75946
+ toLine = fromLine;
75947
+ }
75948
+ mergePmRange(range2, computeCellPmRange(cell, cellMeasure, fromLine, toLine));
75949
+ }
75950
+ }
75951
+ return range2;
75952
+ }
75953
+ function applyTableFragmentPmRange(fragment, block, measure) {
75954
+ const range2 = computeTableFragmentPmRange(block, measure, fragment.fromRow, fragment.toRow, fragment.partialRow);
75955
+ if (range2.pmStart != null) {
75956
+ fragment.pmStart = range2.pmStart;
75957
+ }
75958
+ if (range2.pmEnd != null) {
75959
+ fragment.pmEnd = range2.pmEnd;
75960
+ }
75961
+ }
75664
75962
  function computePartialRow(rowIndex, blockRow, measure, availableHeight, fromLineByCell) {
75665
75963
  const row = measure.rows[rowIndex];
75666
75964
  if (!row) {
@@ -75805,6 +76103,7 @@ function layoutMonolithicTable(context) {
75805
76103
  height,
75806
76104
  metadata
75807
76105
  };
76106
+ applyTableFragmentPmRange(fragment, context.block, context.measure);
75808
76107
  state2.page.fragments.push(fragment);
75809
76108
  state2.cursorY += height;
75810
76109
  }
@@ -75883,6 +76182,7 @@ function layoutTableBlock({
75883
76182
  height,
75884
76183
  metadata
75885
76184
  };
76185
+ applyTableFragmentPmRange(fragment, block, measure);
75886
76186
  state2.page.fragments.push(fragment);
75887
76187
  state2.cursorY += height;
75888
76188
  return;
@@ -75946,6 +76246,7 @@ function layoutTableBlock({
75946
76246
  partialRow: continuationPartialRow,
75947
76247
  metadata: generateFragmentMetadata(measure)
75948
76248
  };
76249
+ applyTableFragmentPmRange(fragment2, block, measure);
75949
76250
  state2.page.fragments.push(fragment2);
75950
76251
  state2.cursorY += fragmentHeight2;
75951
76252
  }
@@ -75990,6 +76291,7 @@ function layoutTableBlock({
75990
76291
  partialRow: forcedPartialRow,
75991
76292
  metadata: generateFragmentMetadata(measure)
75992
76293
  };
76294
+ applyTableFragmentPmRange(fragment2, block, measure);
75993
76295
  state2.page.fragments.push(fragment2);
75994
76296
  state2.cursorY += fragmentHeight2;
75995
76297
  pendingPartialRow = forcedPartialRow;
@@ -76025,6 +76327,7 @@ function layoutTableBlock({
76025
76327
  partialRow: partialRow || void 0,
76026
76328
  metadata: generateFragmentMetadata(measure)
76027
76329
  };
76330
+ applyTableFragmentPmRange(fragment, block, measure);
76028
76331
  state2.page.fragments.push(fragment);
76029
76332
  state2.cursorY += fragmentHeight;
76030
76333
  if (partialRow && !partialRow.isLastPart) {
@@ -76042,7 +76345,7 @@ function createAnchoredTableFragment(block, measure, x2, y2) {
76042
76345
  columnBoundaries: generateColumnBoundaries(measure),
76043
76346
  coordinateSystem: "fragment"
76044
76347
  };
76045
- return {
76348
+ const fragment = {
76046
76349
  kind: "table",
76047
76350
  blockId: block.id,
76048
76351
  fromRow: 0,
@@ -76053,6 +76356,8 @@ function createAnchoredTableFragment(block, measure, x2, y2) {
76053
76356
  height: measure.totalHeight ?? 0,
76054
76357
  metadata
76055
76358
  };
76359
+ applyTableFragmentPmRange(fragment, block, measure);
76360
+ return fragment;
76056
76361
  }
76057
76362
  function isPageRelativeAnchor(block) {
76058
76363
  const vRelativeFrom = block.anchor?.vRelativeFrom;
@@ -76474,8 +76779,8 @@ function layoutDocument(blocks, measures, options = {}) {
76474
76779
  header: options.margins?.header ?? options.margins?.top ?? DEFAULT_MARGINS$2.top,
76475
76780
  footer: options.margins?.footer ?? options.margins?.bottom ?? DEFAULT_MARGINS$2.bottom
76476
76781
  };
76477
- const contentWidth = pageSize.w - (margins.left + margins.right);
76478
- if (contentWidth <= 0) {
76782
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
76783
+ if (baseContentWidth <= 0) {
76479
76784
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
76480
76785
  }
76481
76786
  const validateContentHeight = (height) => {
@@ -76505,8 +76810,12 @@ function layoutDocument(blocks, measures, options = {}) {
76505
76810
  const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
76506
76811
  let activeTopMargin = effectiveTopMargin;
76507
76812
  let activeBottomMargin = effectiveBottomMargin;
76813
+ let activeLeftMargin = margins.left;
76814
+ let activeRightMargin = margins.right;
76508
76815
  let pendingTopMargin = null;
76509
76816
  let pendingBottomMargin = null;
76817
+ let pendingLeftMargin = null;
76818
+ let pendingRightMargin = null;
76510
76819
  let activeHeaderDistance = margins.header ?? margins.top;
76511
76820
  let pendingHeaderDistance = null;
76512
76821
  let activeFooterDistance = margins.footer ?? margins.bottom;
@@ -76519,10 +76828,11 @@ function layoutDocument(blocks, measures, options = {}) {
76519
76828
  let pendingOrientation = null;
76520
76829
  let activeVAlign = null;
76521
76830
  let pendingVAlign = null;
76831
+ const paginatorMargins = { left: activeLeftMargin, right: activeRightMargin };
76522
76832
  const floatManager = createFloatingObjectManager(
76523
- normalizeColumns(activeColumns, contentWidth),
76524
- { left: margins.left, right: margins.right },
76525
- pageSize.w
76833
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
76834
+ { left: activeLeftMargin, right: activeRightMargin },
76835
+ activePageSize.w
76526
76836
  );
76527
76837
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
76528
76838
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
@@ -76539,22 +76849,38 @@ function layoutDocument(blocks, measures, options = {}) {
76539
76849
  next.activeOrientation = block.orientation;
76540
76850
  next.pendingOrientation = null;
76541
76851
  }
76852
+ const headerDistance2 = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
76853
+ const footerDistance2 = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
76854
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
76855
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
76542
76856
  if (block.margins?.header !== void 0) {
76543
- const headerDist = Math.max(0, block.margins.header);
76544
- next.activeHeaderDistance = headerDist;
76545
- next.pendingHeaderDistance = headerDist;
76546
- const requiredTop = maxHeaderContentHeight > 0 ? headerDist + maxHeaderContentHeight : headerDist;
76547
- next.activeTopMargin = Math.max(baseMargins.top, requiredTop);
76548
- next.pendingTopMargin = next.activeTopMargin;
76857
+ next.activeHeaderDistance = headerDistance2;
76858
+ next.pendingHeaderDistance = headerDistance2;
76549
76859
  }
76550
76860
  if (block.margins?.footer !== void 0) {
76551
- const footerDistance2 = Math.max(0, block.margins.footer);
76552
76861
  next.activeFooterDistance = footerDistance2;
76553
76862
  next.pendingFooterDistance = footerDistance2;
76863
+ }
76864
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
76865
+ const requiredTop = maxHeaderContentHeight > 0 ? headerDistance2 + maxHeaderContentHeight : headerDistance2;
76866
+ next.activeTopMargin = Math.max(sectionTop, requiredTop);
76867
+ next.pendingTopMargin = next.activeTopMargin;
76868
+ }
76869
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
76554
76870
  const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
76555
- next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
76871
+ next.activeBottomMargin = Math.max(sectionBottom, requiredBottom);
76556
76872
  next.pendingBottomMargin = next.activeBottomMargin;
76557
76873
  }
76874
+ if (block.margins?.left !== void 0) {
76875
+ const leftMargin = Math.max(0, block.margins.left);
76876
+ next.activeLeftMargin = leftMargin;
76877
+ next.pendingLeftMargin = leftMargin;
76878
+ }
76879
+ if (block.margins?.right !== void 0) {
76880
+ const rightMargin = Math.max(0, block.margins.right);
76881
+ next.activeRightMargin = rightMargin;
76882
+ next.pendingRightMargin = rightMargin;
76883
+ }
76558
76884
  if (block.columns) {
76559
76885
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
76560
76886
  next.pendingColumns = null;
@@ -76583,27 +76909,35 @@ function layoutDocument(blocks, measures, options = {}) {
76583
76909
  const headerPx = block.margins?.header;
76584
76910
  const footerPx = block.margins?.footer;
76585
76911
  const topPx = block.margins?.top;
76912
+ const bottomPx = block.margins?.bottom;
76913
+ const leftPx = block.margins?.left;
76914
+ const rightPx = block.margins?.right;
76586
76915
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
76587
76916
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
76917
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
76918
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
76588
76919
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
76589
76920
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
76590
76921
  next.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
76591
76922
  next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
76592
76923
  if (typeof headerPx === "number" || typeof topPx === "number") {
76593
- const sectionTop = topPx ?? baseMargins.top;
76924
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
76594
76925
  const sectionHeader = next.pendingHeaderDistance;
76595
76926
  const requiredTop = maxHeaderContentHeight > 0 ? sectionHeader + maxHeaderContentHeight : sectionHeader;
76596
76927
  next.pendingTopMargin = Math.max(sectionTop, requiredTop);
76597
76928
  } else {
76598
76929
  next.pendingTopMargin = nextTop;
76599
76930
  }
76600
- if (typeof footerPx === "number") {
76931
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
76601
76932
  const sectionFooter = next.pendingFooterDistance;
76933
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
76602
76934
  const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
76603
- next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
76935
+ next.pendingBottomMargin = Math.max(sectionBottom, requiredBottom);
76604
76936
  } else {
76605
76937
  next.pendingBottomMargin = nextBottom;
76606
76938
  }
76939
+ next.pendingLeftMargin = typeof leftPx === "number" ? Math.max(0, leftPx) : nextLeft;
76940
+ next.pendingRightMargin = typeof rightPx === "number" ? Math.max(0, rightPx) : nextRight;
76607
76941
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
76608
76942
  if (block.orientation) next.pendingOrientation = block.orientation;
76609
76943
  const sectionType = block.type ?? "continuous";
@@ -76688,7 +77022,7 @@ function layoutDocument(blocks, measures, options = {}) {
76688
77022
  let activeSectionIndex = initialSectionMetadata?.sectionIndex ?? 0;
76689
77023
  let pendingSectionIndex = null;
76690
77024
  const paginator = createPaginator({
76691
- margins: { left: margins.left, right: margins.right },
77025
+ margins: paginatorMargins,
76692
77026
  getActiveTopMargin: () => activeTopMargin,
76693
77027
  getActiveBottomMargin: () => activeBottomMargin,
76694
77028
  getActiveHeaderDistance: () => activeHeaderDistance,
@@ -76703,8 +77037,12 @@ function layoutDocument(blocks, measures, options = {}) {
76703
77037
  const applied = applyPendingToActive({
76704
77038
  activeTopMargin,
76705
77039
  activeBottomMargin,
77040
+ activeLeftMargin,
77041
+ activeRightMargin,
76706
77042
  pendingTopMargin,
76707
77043
  pendingBottomMargin,
77044
+ pendingLeftMargin,
77045
+ pendingRightMargin,
76708
77046
  activeHeaderDistance,
76709
77047
  activeFooterDistance,
76710
77048
  pendingHeaderDistance,
@@ -76719,8 +77057,12 @@ function layoutDocument(blocks, measures, options = {}) {
76719
77057
  });
76720
77058
  activeTopMargin = applied.activeTopMargin;
76721
77059
  activeBottomMargin = applied.activeBottomMargin;
77060
+ activeLeftMargin = applied.activeLeftMargin;
77061
+ activeRightMargin = applied.activeRightMargin;
76722
77062
  pendingTopMargin = applied.pendingTopMargin;
76723
77063
  pendingBottomMargin = applied.pendingBottomMargin;
77064
+ pendingLeftMargin = applied.pendingLeftMargin;
77065
+ pendingRightMargin = applied.pendingRightMargin;
76724
77066
  activeHeaderDistance = applied.activeHeaderDistance;
76725
77067
  activeFooterDistance = applied.activeFooterDistance;
76726
77068
  pendingHeaderDistance = applied.pendingHeaderDistance;
@@ -76732,6 +77074,14 @@ function layoutDocument(blocks, measures, options = {}) {
76732
77074
  activeOrientation = applied.activeOrientation;
76733
77075
  pendingOrientation = applied.pendingOrientation;
76734
77076
  cachedColumnsState.state = null;
77077
+ paginatorMargins.left = activeLeftMargin;
77078
+ paginatorMargins.right = activeRightMargin;
77079
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77080
+ floatManager.setLayoutContext(
77081
+ normalizeColumns(activeColumns, contentWidth),
77082
+ { left: activeLeftMargin, right: activeRightMargin },
77083
+ activePageSize.w
77084
+ );
76735
77085
  if (pendingNumbering) {
76736
77086
  if (pendingNumbering.format) activeNumberFormat = pendingNumbering.format;
76737
77087
  if (typeof pendingNumbering.start === "number" && Number.isFinite(pendingNumbering.start)) {
@@ -76776,7 +77126,7 @@ function layoutDocument(blocks, measures, options = {}) {
76776
77126
  const getActiveColumnsForState = paginator.getActiveColumnsForState;
76777
77127
  let cachedColumnsState = { state: null, constraintIndex: -2, contentWidth: -1, colsConfig: null, normalized: null };
76778
77128
  const getCurrentColumns = () => {
76779
- const currentContentWidth = activePageSize.w - (margins.left + margins.right);
77129
+ const currentContentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
76780
77130
  const state2 = states[states.length - 1] ?? null;
76781
77131
  const colsConfig = state2 ? getActiveColumnsForState(state2) : activeColumns;
76782
77132
  const constraintIndex = state2 ? state2.activeConstraintIndex : -1;
@@ -76809,6 +77159,12 @@ function layoutDocument(blocks, measures, options = {}) {
76809
77159
  layoutLog(` Current page: ${state2.page.number}, cursorY: ${state2.cursorY}`);
76810
77160
  activeColumns = newColumns;
76811
77161
  cachedColumnsState.state = null;
77162
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77163
+ floatManager.setLayoutContext(
77164
+ normalizeColumns(activeColumns, contentWidth),
77165
+ { left: activeLeftMargin, right: activeRightMargin },
77166
+ activePageSize.w
77167
+ );
76812
77168
  };
76813
77169
  const anchoredByParagraph = collectAnchoredDrawings(blocks, measures);
76814
77170
  const anchoredTablesByParagraph = collectAnchoredTables(blocks, measures);
@@ -76840,10 +77196,10 @@ function layoutDocument(blocks, measures, options = {}) {
76840
77196
  if (alignV === "top") {
76841
77197
  anchorY = offsetV;
76842
77198
  } else if (alignV === "bottom") {
76843
- const pageHeight = contentBottom + margins.bottom;
77199
+ const pageHeight = contentBottom + (state2.page.margins?.bottom ?? activeBottomMargin);
76844
77200
  anchorY = pageHeight - imageHeight + offsetV;
76845
77201
  } else if (alignV === "center") {
76846
- const pageHeight = contentBottom + margins.bottom;
77202
+ const pageHeight = contentBottom + (state2.page.margins?.bottom ?? activeBottomMargin);
76847
77203
  anchorY = (pageHeight - imageHeight) / 2 + offsetV;
76848
77204
  } else {
76849
77205
  anchorY = offsetV;
@@ -76854,11 +77210,11 @@ function layoutDocument(blocks, measures, options = {}) {
76854
77210
  const anchorX = entry.block.anchor ? computeAnchorX(
76855
77211
  entry.block.anchor,
76856
77212
  state2.columnIndex,
76857
- normalizeColumns(activeColumns, contentWidth),
77213
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
76858
77214
  entry.measure.width,
76859
- { left: margins.left, right: margins.right },
77215
+ { left: activeLeftMargin, right: activeRightMargin },
76860
77216
  activePageSize.w
76861
- ) : margins.left;
77217
+ ) : activeLeftMargin;
76862
77218
  floatManager.registerDrawing(entry.block, entry.measure, anchorY, state2.columnIndex, state2.page.number);
76863
77219
  preRegisteredPositions.set(entry.block.id, { anchorX, anchorY, pageNumber: state2.page.number });
76864
77220
  }
@@ -76896,8 +77252,12 @@ function layoutDocument(blocks, measures, options = {}) {
76896
77252
  const sectionState = {
76897
77253
  activeTopMargin,
76898
77254
  activeBottomMargin,
77255
+ activeLeftMargin,
77256
+ activeRightMargin,
76899
77257
  pendingTopMargin,
76900
77258
  pendingBottomMargin,
77259
+ pendingLeftMargin,
77260
+ pendingRightMargin,
76901
77261
  activeHeaderDistance,
76902
77262
  activeFooterDistance,
76903
77263
  pendingHeaderDistance,
@@ -76931,8 +77291,12 @@ function layoutDocument(blocks, measures, options = {}) {
76931
77291
  layoutLog(`[Layout] ========== END SECTION BREAK ==========`);
76932
77292
  activeTopMargin = updatedState.activeTopMargin;
76933
77293
  activeBottomMargin = updatedState.activeBottomMargin;
77294
+ activeLeftMargin = updatedState.activeLeftMargin;
77295
+ activeRightMargin = updatedState.activeRightMargin;
76934
77296
  pendingTopMargin = updatedState.pendingTopMargin;
76935
77297
  pendingBottomMargin = updatedState.pendingBottomMargin;
77298
+ pendingLeftMargin = updatedState.pendingLeftMargin;
77299
+ pendingRightMargin = updatedState.pendingRightMargin;
76936
77300
  activeHeaderDistance = updatedState.activeHeaderDistance;
76937
77301
  activeFooterDistance = updatedState.activeFooterDistance;
76938
77302
  pendingHeaderDistance = updatedState.pendingHeaderDistance;
@@ -77070,8 +77434,8 @@ function layoutDocument(blocks, measures, options = {}) {
77070
77434
  pageMargins: {
77071
77435
  top: activeTopMargin,
77072
77436
  bottom: activeBottomMargin,
77073
- left: margins.left,
77074
- right: margins.right
77437
+ left: activeLeftMargin,
77438
+ right: activeRightMargin
77075
77439
  },
77076
77440
  columns: getCurrentColumns(),
77077
77441
  placedAnchoredIds
@@ -77093,9 +77457,9 @@ function layoutDocument(blocks, measures, options = {}) {
77093
77457
  const cols = getCurrentColumns();
77094
77458
  let maxWidth;
77095
77459
  if (relativeFrom === "page") {
77096
- maxWidth = cols.count === 1 ? activePageSize.w - margins.left - margins.right : activePageSize.w;
77460
+ maxWidth = cols.count === 1 ? activePageSize.w - (activeLeftMargin + activeRightMargin) : activePageSize.w;
77097
77461
  } else if (relativeFrom === "margin") {
77098
- maxWidth = activePageSize.w - margins.left - margins.right;
77462
+ maxWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77099
77463
  } else {
77100
77464
  maxWidth = cols.width;
77101
77465
  }
@@ -77255,6 +77619,9 @@ function layoutHeaderFooter(blocks, measures, constraints) {
77255
77619
  if (!Number.isFinite(height) || height <= 0) {
77256
77620
  throw new Error("layoutHeaderFooter: height must be positive");
77257
77621
  }
77622
+ const maxBehindDocOverflow = Math.max(192, height * 4);
77623
+ const minBehindDocY = -maxBehindDocOverflow;
77624
+ const maxBehindDocY = height + maxBehindDocOverflow;
77258
77625
  const marginLeft = constraints.margins?.left ?? 0;
77259
77626
  const transformedBlocks = marginLeft > 0 ? blocks.map((block) => {
77260
77627
  const hasPageRelativeAnchor = (block.kind === "image" || block.kind === "drawing") && block.anchor?.hRelativeFrom === "page" && block.anchor.offsetH != null;
@@ -77285,6 +77652,18 @@ function layoutHeaderFooter(blocks, measures, constraints) {
77285
77652
  if (idx == null) continue;
77286
77653
  const block = blocks[idx];
77287
77654
  const measure = measures[idx];
77655
+ const isAnchoredFragment = (fragment.kind === "image" || fragment.kind === "drawing") && fragment.isAnchored === true;
77656
+ if (isAnchoredFragment) {
77657
+ if (block.kind !== "image" && block.kind !== "drawing") {
77658
+ throw new Error(
77659
+ `Type mismatch: fragment kind is ${fragment.kind} but block kind is ${block.kind} for block ${block.id}`
77660
+ );
77661
+ }
77662
+ const anchoredBlock = block;
77663
+ if (anchoredBlock.anchor?.behindDoc && (fragment.y < minBehindDocY || fragment.y > maxBehindDocY)) {
77664
+ continue;
77665
+ }
77666
+ }
77288
77667
  if (fragment.y < minY) minY = fragment.y;
77289
77668
  let bottom2 = fragment.y;
77290
77669
  if (fragment.kind === "para" && measure?.kind === "paragraph") {
@@ -78282,11 +78661,11 @@ function findWordBoundaries(blocks, pos) {
78282
78661
  if (text.length === 0) return null;
78283
78662
  const clampedPos = Math.max(0, Math.min(localPos, text.length));
78284
78663
  let wordStart = clampedPos;
78285
- while (wordStart > 0 && isWordChar(text[wordStart - 1])) {
78664
+ while (wordStart > 0 && isWordChar$2(text[wordStart - 1])) {
78286
78665
  wordStart--;
78287
78666
  }
78288
78667
  let wordEnd = clampedPos;
78289
- while (wordEnd < text.length && isWordChar(text[wordEnd])) {
78668
+ while (wordEnd < text.length && isWordChar$2(text[wordEnd])) {
78290
78669
  wordEnd++;
78291
78670
  }
78292
78671
  if (wordStart === wordEnd) {
@@ -78349,7 +78728,7 @@ function findBlockAtPosition(blocks, pos) {
78349
78728
  }
78350
78729
  return null;
78351
78730
  }
78352
- function isWordChar(char) {
78731
+ function isWordChar$2(char) {
78353
78732
  return /[\p{L}\p{N}_]/u.test(char);
78354
78733
  }
78355
78734
  function isWhitespace(char) {
@@ -78384,6 +78763,29 @@ function fontString(run2) {
78384
78763
  function runText(run2) {
78385
78764
  return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
78386
78765
  }
78766
+ const isWordChar$1 = (char) => {
78767
+ if (!char) return false;
78768
+ const code = char.charCodeAt(0);
78769
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
78770
+ };
78771
+ const capitalizeText$1 = (text, fullText, startOffset) => {
78772
+ if (!text) return text;
78773
+ const hasFullText = typeof startOffset === "number" && fullText != null;
78774
+ let result = "";
78775
+ for (let i = 0; i < text.length; i += 1) {
78776
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
78777
+ const ch = text[i];
78778
+ result += isWordChar$1(ch) && !isWordChar$1(prevChar) ? ch.toUpperCase() : ch;
78779
+ }
78780
+ return result;
78781
+ };
78782
+ const applyTextTransform$1 = (text, transform, fullText, startOffset) => {
78783
+ if (!text || !transform || transform === "none") return text;
78784
+ if (transform === "uppercase") return text.toUpperCase();
78785
+ if (transform === "lowercase") return text.toLowerCase();
78786
+ if (transform === "capitalize") return capitalizeText$1(text, fullText, startOffset);
78787
+ return text;
78788
+ };
78387
78789
  const DEFAULT_TAB_INTERVAL_TWIPS$1 = 720;
78388
78790
  const TWIPS_PER_INCH$4 = 1440;
78389
78791
  const PX_PER_INCH$3 = 96;
@@ -78392,6 +78794,13 @@ const TAB_EPSILON$1 = 0.1;
78392
78794
  const WIDTH_FUDGE_PX = 0.5;
78393
78795
  const twipsToPx$2 = (twips) => twips / TWIPS_PER_PX$1;
78394
78796
  const pxToTwips$1 = (px) => Math.round(px * TWIPS_PER_PX$1);
78797
+ const markerFontString = (run2) => {
78798
+ const size2 = run2?.fontSize ?? 16;
78799
+ const family = run2?.fontFamily ?? "Arial";
78800
+ const italic = run2?.italic ? "italic " : "";
78801
+ const bold = run2?.bold ? "bold " : "";
78802
+ return `${italic}${bold}${size2}px ${family}`.trim();
78803
+ };
78395
78804
  const buildTabStopsPx$1 = (indent, tabs, tabIntervalTwips) => {
78396
78805
  const paragraphIndentTwips = {
78397
78806
  left: pxToTwips$1(Math.max(0, indent?.left ?? 0)),
@@ -78422,7 +78831,8 @@ const getNextTabStopPx$1 = (currentX, tabStops, startIndex) => {
78422
78831
  };
78423
78832
  function measureRunSliceWidth(run2, fromChar, toChar) {
78424
78833
  const context = getCtx();
78425
- const text = runText(run2).slice(fromChar, toChar);
78834
+ const fullText = runText(run2);
78835
+ const text = applyTextTransform$1(fullText.slice(fromChar, toChar), run2.textTransform, fullText, fromChar);
78426
78836
  if (!context) {
78427
78837
  const textRun = isTextRun$2(run2) ? run2 : null;
78428
78838
  const size2 = textRun?.fontSize ?? 16;
@@ -78468,8 +78878,21 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
78468
78878
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
78469
78879
  const markerTextStartX = wordLayout?.marker?.textStartX;
78470
78880
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
78471
- const treatAsHanging = textStartPx && indentLeft === 0 && indentHanging === 0;
78472
- const firstLineWidth = typeof textStartPx === "number" && textStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - textStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
78881
+ const resolvedTextStartPx = resolveListTextStartPx(
78882
+ wordLayout,
78883
+ indentLeft,
78884
+ indentFirstLine,
78885
+ indentHanging,
78886
+ (markerText, marker) => {
78887
+ const context = getCtx();
78888
+ if (!context) return 0;
78889
+ context.font = markerFontString(marker.run);
78890
+ return context.measureText(markerText).width;
78891
+ }
78892
+ );
78893
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
78894
+ const treatAsHanging = !wordLayout?.marker && effectiveTextStartPx && indentLeft === 0 && indentHanging === 0;
78895
+ const firstLineWidth = typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - effectiveTextStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
78473
78896
  const tabStops = buildTabStopsPx$1(indent, attrs?.tabs, attrs?.tabIntervalTwips);
78474
78897
  let currentRun = 0;
78475
78898
  let currentChar = 0;
@@ -79009,7 +79432,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
79009
79432
  if (dirty.deletedBlockIds.length > 0) {
79010
79433
  measureCache.invalidate(dirty.deletedBlockIds);
79011
79434
  }
79012
- const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options);
79435
+ const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options, nextBlocks);
79013
79436
  if (measurementWidth <= 0 || measurementHeight <= 0) {
79014
79437
  throw new Error("incrementalLayout: invalid measurement constraints resolved from options");
79015
79438
  }
@@ -79278,7 +79701,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
79278
79701
  const DEFAULT_PAGE_SIZE$1 = { w: 612, h: 792 };
79279
79702
  const DEFAULT_MARGINS$1 = { top: 72, right: 72, bottom: 72, left: 72 };
79280
79703
  const normalizeMargin = (value, fallback) => Number.isFinite(value) ? value : fallback;
79281
- function resolveMeasurementConstraints(options) {
79704
+ function resolveMeasurementConstraints(options, blocks) {
79282
79705
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
79283
79706
  const margins = {
79284
79707
  top: normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top),
@@ -79286,23 +79709,41 @@ function resolveMeasurementConstraints(options) {
79286
79709
  bottom: normalizeMargin(options.margins?.bottom, DEFAULT_MARGINS$1.bottom),
79287
79710
  left: normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
79288
79711
  };
79289
- const contentWidth = pageSize.w - (margins.left + margins.right);
79290
- const contentHeight = pageSize.h - (margins.top + margins.bottom);
79291
- const columns = options.columns;
79292
- if (columns && columns.count > 1) {
79712
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
79713
+ const baseContentHeight = pageSize.h - (margins.top + margins.bottom);
79714
+ const computeColumnWidth = (contentWidth, columns) => {
79715
+ if (!columns || columns.count <= 1) return contentWidth;
79293
79716
  const gap = Math.max(0, columns.gap ?? 0);
79294
79717
  const totalGap = gap * (columns.count - 1);
79295
- const columnWidth = (contentWidth - totalGap) / columns.count;
79296
- if (columnWidth > 0) {
79297
- return {
79298
- measurementWidth: columnWidth,
79299
- measurementHeight: contentHeight
79718
+ return (contentWidth - totalGap) / columns.count;
79719
+ };
79720
+ let measurementWidth = computeColumnWidth(baseContentWidth, options.columns);
79721
+ let measurementHeight = baseContentHeight;
79722
+ if (blocks && blocks.length > 0) {
79723
+ for (const block of blocks) {
79724
+ if (block.kind !== "sectionBreak") continue;
79725
+ const sectionPageSize = block.pageSize ?? pageSize;
79726
+ const sectionMargins = {
79727
+ top: normalizeMargin(block.margins?.top, margins.top),
79728
+ right: normalizeMargin(block.margins?.right, margins.right),
79729
+ bottom: normalizeMargin(block.margins?.bottom, margins.bottom),
79730
+ left: normalizeMargin(block.margins?.left, margins.left)
79300
79731
  };
79732
+ const contentWidth = sectionPageSize.w - (sectionMargins.left + sectionMargins.right);
79733
+ const contentHeight = sectionPageSize.h - (sectionMargins.top + sectionMargins.bottom);
79734
+ if (contentWidth <= 0 || contentHeight <= 0) continue;
79735
+ const columnWidth = computeColumnWidth(contentWidth, block.columns ?? options.columns);
79736
+ if (columnWidth > measurementWidth) {
79737
+ measurementWidth = columnWidth;
79738
+ }
79739
+ if (contentHeight > measurementHeight) {
79740
+ measurementHeight = contentHeight;
79741
+ }
79301
79742
  }
79302
79743
  }
79303
79744
  return {
79304
- measurementWidth: contentWidth,
79305
- measurementHeight: contentHeight
79745
+ measurementWidth,
79746
+ measurementHeight
79306
79747
  };
79307
79748
  }
79308
79749
  const serializeHeaderFooterResults = (kind, batch) => {
@@ -81369,6 +81810,7 @@ function isInRegisteredSurface(event) {
81369
81810
  }
81370
81811
  return false;
81371
81812
  }
81813
+ const SLASH_MENU_HANDLED_FLAG = "__sdHandledBySlashMenu";
81372
81814
  class PresentationInputBridge {
81373
81815
  /**
81374
81816
  * Creates a new PresentationInputBridge that forwards user input events from the visible layout
@@ -81582,6 +82024,10 @@ forwardCompositionEvent_fn = function(event) {
81582
82024
  __privateMethod$1(this, _PresentationInputBridge_instances, dispatchToTarget_fn).call(this, event, synthetic);
81583
82025
  };
81584
82026
  forwardContextMenu_fn = function(event) {
82027
+ const handledBySlashMenu = Boolean(event[SLASH_MENU_HANDLED_FLAG]);
82028
+ if (handledBySlashMenu) {
82029
+ return;
82030
+ }
81585
82031
  if (!__privateGet$1(this, _isEditable).call(this)) {
81586
82032
  return;
81587
82033
  }
@@ -85275,8 +85721,8 @@ function buildSdtCacheKey(nodeType, attrs, explicitKey) {
85275
85721
  }
85276
85722
  return void 0;
85277
85723
  }
85278
- const DEFAULT_LIST_HANGING_PX$1 = 18;
85279
- const LIST_MARKER_GAP$1 = 8;
85724
+ const DEFAULT_LIST_HANGING_PX = 18;
85725
+ const LIST_MARKER_GAP = 8;
85280
85726
  const DEFAULT_BULLET_GLYPH = "•";
85281
85727
  const DEFAULT_DECIMAL_PATTERN = "%1.";
85282
85728
  const ASCII_UPPERCASE_A = 65;
@@ -85687,7 +86133,7 @@ function computeWordParagraphLayout(input) {
85687
86133
  let markerBoxWidthPx;
85688
86134
  let markerX;
85689
86135
  if (hasFirstLineIndent) {
85690
- markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP$1 : DEFAULT_LIST_HANGING_PX$1;
86136
+ markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP : DEFAULT_LIST_HANGING_PX;
85691
86137
  markerX = indentLeftPx + (firstLinePx ?? 0);
85692
86138
  layout.textStartPx = markerX + markerBoxWidthPx;
85693
86139
  layout.hangingPx = 0;
@@ -85787,12 +86233,12 @@ const resolveMarkerBoxWidth = (hangingPxRaw, glyphWidthPx) => {
85787
86233
  let markerBox = Math.max(hangingPxRaw || 0, 0);
85788
86234
  if (markerBox <= 0) {
85789
86235
  if (glyphWidthPx != null && glyphWidthPx > 0) {
85790
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
86236
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
85791
86237
  } else {
85792
- markerBox = DEFAULT_LIST_HANGING_PX$1;
86238
+ markerBox = DEFAULT_LIST_HANGING_PX;
85793
86239
  }
85794
- } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP$1 > markerBox) {
85795
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
86240
+ } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP > markerBox) {
86241
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
85796
86242
  }
85797
86243
  return markerBox;
85798
86244
  };
@@ -85812,7 +86258,7 @@ const buildMarkerLayout = ({
85812
86258
  textStartX: textStartPx,
85813
86259
  baselineOffsetPx: markerRun.baselineShift ?? 0,
85814
86260
  // Gutter is the small gap between marker and text, not the full marker box width
85815
- gutterWidthPx: LIST_MARKER_GAP$1,
86261
+ gutterWidthPx: LIST_MARKER_GAP,
85816
86262
  justification: numbering.lvlJc ?? "left",
85817
86263
  suffix: normalizeSuffix$1(numbering.suffix) ?? "tab",
85818
86264
  run: markerRun,
@@ -86504,6 +86950,31 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
86504
86950
  return null;
86505
86951
  }
86506
86952
  };
86953
+ const normalizeWordLayoutForIndent = (wordLayout, paragraphIndent) => {
86954
+ const resolvedIndent = wordLayout.resolvedIndent ?? paragraphIndent ?? {};
86955
+ const indentLeft = isFiniteNumber(resolvedIndent.left) ? resolvedIndent.left : 0;
86956
+ const firstLine = isFiniteNumber(resolvedIndent.firstLine) ? resolvedIndent.firstLine : 0;
86957
+ const hanging = isFiniteNumber(resolvedIndent.hanging) ? resolvedIndent.hanging : 0;
86958
+ const shouldFirstLineIndentMode = firstLine > 0 && !hanging;
86959
+ if (wordLayout.firstLineIndentMode === true && !shouldFirstLineIndentMode) {
86960
+ wordLayout.firstLineIndentMode = false;
86961
+ }
86962
+ if (wordLayout.firstLineIndentMode === true) {
86963
+ if (isFiniteNumber(wordLayout.textStartPx)) {
86964
+ if (wordLayout.marker && (!isFiniteNumber(wordLayout.marker.textStartX) || wordLayout.marker.textStartX !== wordLayout.textStartPx)) {
86965
+ wordLayout.marker.textStartX = wordLayout.textStartPx;
86966
+ }
86967
+ } else if (wordLayout.marker && isFiniteNumber(wordLayout.marker.textStartX)) {
86968
+ wordLayout.textStartPx = wordLayout.marker.textStartX;
86969
+ }
86970
+ } else {
86971
+ wordLayout.textStartPx = indentLeft;
86972
+ if (wordLayout.marker) {
86973
+ wordLayout.marker.textStartX = indentLeft;
86974
+ }
86975
+ }
86976
+ return wordLayout;
86977
+ };
86507
86978
  const computeParagraphAttrs = (para, styleContext, listCounterContext, converterContext, hydrationOverride) => {
86508
86979
  const attrs = para.attrs ?? {};
86509
86980
  const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
@@ -86826,8 +87297,11 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86826
87297
  let wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
86827
87298
  if (!wordLayout && enrichedNumberingProps.resolvedLevelIndent) {
86828
87299
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
86829
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
86830
- if (firstLinePx > 0) {
87300
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
87301
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
87302
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
87303
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
87304
+ if (firstLinePx > 0 && !hangingPx) {
86831
87305
  wordLayout = {
86832
87306
  // Treat as first-line-indent mode: text starts after the marker+firstLine offset.
86833
87307
  firstLineIndentMode: true,
@@ -86835,10 +87309,13 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86835
87309
  };
86836
87310
  }
86837
87311
  }
86838
- if (wordLayout && (!wordLayout.textStartPx || !Number.isFinite(wordLayout.textStartPx)) && enrichedNumberingProps.resolvedLevelIndent) {
87312
+ if (wordLayout && !Number.isFinite(wordLayout.textStartPx) && enrichedNumberingProps.resolvedLevelIndent) {
86839
87313
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
86840
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
86841
- if (firstLinePx > 0) {
87314
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
87315
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
87316
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
87317
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
87318
+ if (firstLinePx > 0 && !hangingPx) {
86842
87319
  wordLayout = {
86843
87320
  ...wordLayout,
86844
87321
  firstLineIndentMode: wordLayout.firstLineIndentMode ?? true,
@@ -86858,6 +87335,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86858
87335
  wordLayout.marker.suffix = listRendering.suffix;
86859
87336
  }
86860
87337
  }
87338
+ wordLayout = normalizeWordLayoutForIndent(wordLayout, paragraphAttrs.indent);
86861
87339
  paragraphAttrs.wordLayout = wordLayout;
86862
87340
  }
86863
87341
  if (enrichedNumberingProps.resolvedLevelIndent) {
@@ -90974,11 +91452,6 @@ function initHeaderFooterRegistry({
90974
91452
  cleanups
90975
91453
  };
90976
91454
  }
90977
- const LIST_MARKER_GAP = 8;
90978
- const MIN_MARKER_GUTTER = 24;
90979
- const DEFAULT_LIST_INDENT_BASE_PX = 24;
90980
- const DEFAULT_LIST_INDENT_STEP_PX = 24;
90981
- const DEFAULT_LIST_HANGING_PX = 18;
90982
91455
  function calculateRotatedBounds(input) {
90983
91456
  const width = Math.max(0, input.width);
90984
91457
  const height = Math.max(0, input.height);
@@ -91242,8 +91715,25 @@ async function measureParagraphBlock(block, maxWidth) {
91242
91715
  const rawTextStartPx = wordLayout?.textStartPx;
91243
91716
  const markerTextStartX = wordLayout?.marker?.textStartX;
91244
91717
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof rawTextStartPx === "number" && Number.isFinite(rawTextStartPx) ? rawTextStartPx : void 0;
91245
- if (typeof textStartPx === "number" && textStartPx > indentLeft) {
91246
- initialAvailableWidth = Math.max(1, maxWidth - textStartPx - indentRight);
91718
+ const resolvedTextStartPx = resolveListTextStartPx(
91719
+ wordLayout,
91720
+ indentLeft,
91721
+ firstLine,
91722
+ hanging,
91723
+ (markerText, marker) => {
91724
+ const markerRun = {
91725
+ fontFamily: toCssFontFamily(marker.run?.fontFamily) ?? marker.run?.fontFamily ?? "Arial",
91726
+ fontSize: marker.run?.fontSize ?? 16,
91727
+ bold: marker.run?.bold ?? false,
91728
+ italic: marker.run?.italic ?? false
91729
+ };
91730
+ const { font: markerFont } = buildFontString(markerRun);
91731
+ return measureText(markerText, markerFont, ctx2);
91732
+ }
91733
+ );
91734
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
91735
+ if (typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft) {
91736
+ initialAvailableWidth = Math.max(1, maxWidth - effectiveTextStartPx - indentRight);
91247
91737
  } else {
91248
91738
  initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset);
91249
91739
  }
@@ -91330,7 +91820,7 @@ async function measureParagraphBlock(block, maxWidth) {
91330
91820
  pendingTabAlignment = null;
91331
91821
  return startX;
91332
91822
  };
91333
- const alignSegmentAtTab = (segmentText, font, runContext) => {
91823
+ const alignSegmentAtTab = (segmentText, font, runContext, segmentStartChar) => {
91334
91824
  if (!pendingTabAlignment || !currentLine) return void 0;
91335
91825
  const { val } = pendingTabAlignment;
91336
91826
  let segmentWidth = 0;
@@ -91339,11 +91829,11 @@ async function measureParagraphBlock(block, maxWidth) {
91339
91829
  const idx = segmentText.indexOf(decimalSeparator);
91340
91830
  if (idx >= 0) {
91341
91831
  const beforeText = segmentText.slice(0, idx);
91342
- beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext) : 0;
91832
+ beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext, segmentStartChar) : 0;
91343
91833
  }
91344
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
91834
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
91345
91835
  } else if (val === "end" || val === "center") {
91346
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
91836
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
91347
91837
  }
91348
91838
  return alignPendingTabForWidth(segmentWidth, beforeDecimalWidth);
91349
91839
  };
@@ -91395,8 +91885,8 @@ async function measureParagraphBlock(block, maxWidth) {
91395
91885
  const { font } = buildFontString(
91396
91886
  lastRun
91397
91887
  );
91398
- const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun);
91399
- const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun) : 0;
91888
+ const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun, sliceStart);
91889
+ const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun, sliceStart) : 0;
91400
91890
  const delta = Math.max(0, fullWidth - keptWidth);
91401
91891
  lineToTrim.width = roundValue(Math.max(0, lineToTrim.width - delta));
91402
91892
  lineToTrim.spaceCount = Math.max(0, lineToTrim.spaceCount - trimCount);
@@ -91607,7 +92097,8 @@ async function measureParagraphBlock(block, maxWidth) {
91607
92097
  continue;
91608
92098
  }
91609
92099
  if (isFieldAnnotationRun(run2)) {
91610
- const displayText = run2.displayLabel || "";
92100
+ const rawDisplayText = run2.displayLabel || "";
92101
+ const displayText = applyTextTransform(rawDisplayText, run2);
91611
92102
  const annotationFontSize = typeof run2.fontSize === "number" ? run2.fontSize : typeof run2.fontSize === "string" ? parseFloat(run2.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE : DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
91612
92103
  const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
91613
92104
  const fontWeight = run2.bold ? "bold" : "normal";
@@ -91710,7 +92201,7 @@ async function measureParagraphBlock(block, maxWidth) {
91710
92201
  const spacesLength = segment.length;
91711
92202
  const spacesStartChar = charPosInRun;
91712
92203
  const spacesEndChar = charPosInRun + spacesLength;
91713
- const spacesWidth = measureRunWidth(segment, font, ctx2, run2);
92204
+ const spacesWidth = measureRunWidth(segment, font, ctx2, run2, spacesStartChar);
91714
92205
  if (!currentLine) {
91715
92206
  currentLine = {
91716
92207
  fromRun: runIndex,
@@ -91774,7 +92265,7 @@ async function measureParagraphBlock(block, maxWidth) {
91774
92265
  }
91775
92266
  let segmentStartX;
91776
92267
  if (currentLine && pendingTabAlignment) {
91777
- segmentStartX = alignSegmentAtTab(segment, font, run2);
92268
+ segmentStartX = alignSegmentAtTab(segment, font, run2, charPosInRun);
91778
92269
  if (segmentStartX == null) {
91779
92270
  segmentStartX = currentLine.width;
91780
92271
  }
@@ -91784,7 +92275,7 @@ async function measureParagraphBlock(block, maxWidth) {
91784
92275
  if (word2 === "") {
91785
92276
  const spaceStartChar = charPosInRun;
91786
92277
  const spaceEndChar = charPosInRun + 1;
91787
- const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2);
92278
+ const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2, spaceStartChar);
91788
92279
  if (!currentLine) {
91789
92280
  currentLine = {
91790
92281
  fromRun: runIndex,
@@ -91835,12 +92326,12 @@ async function measureParagraphBlock(block, maxWidth) {
91835
92326
  charPosInRun = spaceEndChar;
91836
92327
  continue;
91837
92328
  }
91838
- const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run2);
91839
- const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
91840
- const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run2) : 0;
91841
- const wordCommitWidth = wordOnlyWidth + spaceWidth;
91842
92329
  const wordStartChar = charPosInRun;
92330
+ const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run2, wordStartChar);
92331
+ const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
91843
92332
  const wordEndNoSpace = charPosInRun + word2.length;
92333
+ const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run2, wordEndNoSpace) : 0;
92334
+ const wordCommitWidth = wordOnlyWidth + spaceWidth;
91844
92335
  const wordEndWithSpace = wordEndNoSpace + (shouldIncludeDelimiterSpace ? 1 : 0);
91845
92336
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
91846
92337
  if (wordOnlyWidth > effectiveMaxWidth && word2.length > 1) {
@@ -91859,7 +92350,7 @@ async function measureParagraphBlock(block, maxWidth) {
91859
92350
  const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
91860
92351
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
91861
92352
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
91862
- const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
92353
+ const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2, wordStartChar);
91863
92354
  let chunkCharOffset = wordStartChar;
91864
92355
  for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
91865
92356
  const chunk = chunks[chunkIndex];
@@ -91983,7 +92474,7 @@ async function measureParagraphBlock(block, maxWidth) {
91983
92474
  if (candidateSpaces > 0) {
91984
92475
  const overflow = totalWidthWithWord - availableWidth;
91985
92476
  if (overflow > 0) {
91986
- const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2) || Math.max(1, boundarySpacing);
92477
+ const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2, wordEndNoSpace) || Math.max(1, boundarySpacing);
91987
92478
  const perSpaceCompression = overflow / candidateSpaces;
91988
92479
  const maxPerSpaceCompression = baseSpaceWidth * 0.25;
91989
92480
  if (perSpaceCompression <= maxPerSpaceCompression) {
@@ -92158,8 +92649,8 @@ async function measureParagraphBlock(block, maxWidth) {
92158
92649
  const { font: markerFont } = buildFontString(markerRun);
92159
92650
  const markerText = wordLayout.marker.markerText ?? "";
92160
92651
  const glyphWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
92161
- const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP;
92162
- const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP);
92652
+ const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP$1;
92653
+ const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP$1);
92163
92654
  markerInfo = {
92164
92655
  markerWidth: markerBoxWidth,
92165
92656
  markerTextWidth: glyphWidth,
@@ -92503,7 +92994,7 @@ async function measureListBlock(block, constraints) {
92503
92994
  markerTextWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
92504
92995
  indentLeft = resolveIndentLeft(item);
92505
92996
  const indentHanging = resolveIndentHanging(item);
92506
- markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP, indentHanging);
92997
+ markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP$1, indentHanging);
92507
92998
  }
92508
92999
  const paragraphWidth = Math.max(1, constraints.maxWidth - indentLeft - markerWidth);
92509
93000
  const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth);
@@ -92529,16 +93020,46 @@ const getPrimaryRun = (paragraph) => {
92529
93020
  fontSize: 16
92530
93021
  };
92531
93022
  };
92532
- const measureRunWidth = (text, font, ctx2, run2) => {
93023
+ const isWordChar = (char) => {
93024
+ if (!char) return false;
93025
+ const code = char.charCodeAt(0);
93026
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
93027
+ };
93028
+ const capitalizeText = (text, fullText, startOffset) => {
93029
+ if (!text) return text;
93030
+ const hasFullText = typeof startOffset === "number" && fullText != null;
93031
+ let result = "";
93032
+ for (let i = 0; i < text.length; i += 1) {
93033
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
93034
+ const ch = text[i];
93035
+ result += isWordChar(ch) && !isWordChar(prevChar) ? ch.toUpperCase() : ch;
93036
+ }
93037
+ return result;
93038
+ };
93039
+ const applyTextTransform = (text, run2, startOffset) => {
93040
+ const transform = run2.textTransform;
93041
+ if (!text || !transform || transform === "none") return text;
93042
+ if (transform === "uppercase") return text.toUpperCase();
93043
+ if (transform === "lowercase") return text.toLowerCase();
93044
+ if (transform === "capitalize") {
93045
+ const fullText = "text" in run2 && typeof run2.text === "string" ? run2.text : text;
93046
+ return capitalizeText(text, fullText, startOffset);
93047
+ }
93048
+ return text;
93049
+ };
93050
+ const measureRunWidth = (text, font, ctx2, run2, startOffset) => {
92533
93051
  const letterSpacing = run2.kind === "text" || run2.kind === void 0 ? run2.letterSpacing || 0 : 0;
92534
- const width = getMeasuredTextWidth(text, font, letterSpacing, ctx2);
93052
+ const displayText = applyTextTransform(text, run2, startOffset);
93053
+ const width = getMeasuredTextWidth(displayText, font, letterSpacing, ctx2);
92535
93054
  return roundValue(width);
92536
93055
  };
92537
- const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2) => {
93056
+ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2, startOffset) => {
92538
93057
  const chunks = [];
93058
+ const baseOffset = typeof startOffset === "number" ? startOffset : 0;
92539
93059
  if (maxWidth <= 0) {
92540
- for (const char of word2) {
92541
- const charWidth = measureRunWidth(char, font, ctx2, run2);
93060
+ for (let i = 0; i < word2.length; i++) {
93061
+ const char = word2[i];
93062
+ const charWidth = measureRunWidth(char, font, ctx2, run2, baseOffset + i);
92542
93063
  chunks.push({ text: char, width: charWidth });
92543
93064
  }
92544
93065
  return chunks;
@@ -92548,11 +93069,11 @@ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2) => {
92548
93069
  for (let i = 0; i < word2.length; i++) {
92549
93070
  const char = word2[i];
92550
93071
  const testChunk = currentChunk + char;
92551
- const testWidth = measureRunWidth(testChunk, font, ctx2, run2);
93072
+ const testWidth = measureRunWidth(testChunk, font, ctx2, run2, baseOffset);
92552
93073
  if (testWidth > maxWidth && currentChunk.length > 0) {
92553
93074
  chunks.push({ text: currentChunk, width: currentWidth });
92554
93075
  currentChunk = char;
92555
- currentWidth = measureRunWidth(char, font, ctx2, run2);
93076
+ currentWidth = measureRunWidth(char, font, ctx2, run2, baseOffset + i);
92556
93077
  } else {
92557
93078
  currentChunk = testChunk;
92558
93079
  currentWidth = testWidth;
@@ -92606,7 +93127,8 @@ const measureDropCap = (ctx2, descriptor, spacing) => {
92606
93127
  italic: run2.italic
92607
93128
  });
92608
93129
  ctx2.font = font;
92609
- const metrics = ctx2.measureText(run2.text);
93130
+ const displayText = applyTextTransform(run2.text, run2);
93131
+ const metrics = ctx2.measureText(displayText);
92610
93132
  const advanceWidth = metrics.width;
92611
93133
  const paintedWidth = (metrics.actualBoundingBoxLeft || 0) + (metrics.actualBoundingBoxRight || 0);
92612
93134
  const textWidth = Math.max(advanceWidth, paintedWidth);
@@ -92632,7 +93154,7 @@ const resolveIndentHanging = (item) => {
92632
93154
  if (indentHanging > 0) {
92633
93155
  return indentHanging;
92634
93156
  }
92635
- return DEFAULT_LIST_HANGING_PX;
93157
+ return DEFAULT_LIST_HANGING_PX$1;
92636
93158
  };
92637
93159
  const buildTabStopsPx = (indent, tabs, tabIntervalTwips) => {
92638
93160
  const paragraphIndentTwips = {
@@ -92838,6 +93360,9 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
92838
93360
  if (event.button !== 0) {
92839
93361
  return;
92840
93362
  }
93363
+ if (event.ctrlKey && navigator.platform.includes("Mac")) {
93364
+ return;
93365
+ }
92841
93366
  __privateSet(this, _pendingMarginClick, null);
92842
93367
  const target = event.target;
92843
93368
  if (target?.closest?.(".superdoc-ruler-handle") != null) {
@@ -98247,6 +98772,8 @@ const SlashMenu = Extension.create({
98247
98772
  const cbRect = containingBlock.getBoundingClientRect();
98248
98773
  left2 -= cbRect.left;
98249
98774
  top2 -= cbRect.top;
98775
+ left2 += containingBlock.scrollLeft || 0;
98776
+ top2 += containingBlock.scrollTop || 0;
98250
98777
  } catch (error) {
98251
98778
  console.warn("SlashMenu: Failed to adjust for containing block", error);
98252
98779
  }
@@ -129585,7 +130112,7 @@ const _sfc_main$8 = {
129585
130112
  if (open) {
129586
130113
  vue.nextTick(() => {
129587
130114
  if (searchInput.value) {
129588
- searchInput.value.focus();
130115
+ searchInput.value.focus({ preventScroll: true });
129589
130116
  }
129590
130117
  });
129591
130118
  }
@@ -129690,15 +130217,31 @@ const _sfc_main$8 = {
129690
130217
  };
129691
130218
  const handleGlobalOutsideClick = (event) => {
129692
130219
  if (isOpen.value && menuRef.value && !menuRef.value.contains(event.target)) {
129693
- moveCursorToMouseEvent(event, props.editor);
130220
+ const isCtrlClickOnMac = event.ctrlKey && isMacOS();
130221
+ const isLeftClick = event.button === 0 && !isCtrlClickOnMac;
130222
+ if (isLeftClick) {
130223
+ moveCursorToMouseEvent(event, props.editor);
130224
+ }
129694
130225
  closeMenu({ restoreCursor: false });
129695
130226
  }
129696
130227
  };
129697
- const handleRightClick = async (event) => {
130228
+ const shouldHandleContextMenu = (event) => {
129698
130229
  const readOnly = !props.editor?.isEditable;
129699
130230
  const contextMenuDisabled = props.editor?.options?.disableContextMenu;
129700
130231
  const bypass = shouldBypassContextMenu(event);
129701
- if (readOnly || contextMenuDisabled || bypass) {
130232
+ return !readOnly && !contextMenuDisabled && !bypass;
130233
+ };
130234
+ const handleRightClickCapture = (event) => {
130235
+ try {
130236
+ if (shouldHandleContextMenu(event)) {
130237
+ event[SLASH_MENU_HANDLED_FLAG] = true;
130238
+ }
130239
+ } catch (error) {
130240
+ console.warn("[SlashMenu] Error in capture phase context menu handler:", error);
130241
+ }
130242
+ };
130243
+ const handleRightClick = async (event) => {
130244
+ if (!shouldHandleContextMenu(event)) {
129702
130245
  return;
129703
130246
  }
129704
130247
  event.preventDefault();
@@ -129809,6 +130352,7 @@ const _sfc_main$8 = {
129809
130352
  props.editor.on("slashMenu:open", slashMenuOpenHandler);
129810
130353
  contextMenuTarget = getEditorSurfaceElement(props.editor);
129811
130354
  if (contextMenuTarget) {
130355
+ contextMenuTarget.addEventListener("contextmenu", handleRightClickCapture, true);
129812
130356
  contextMenuTarget.addEventListener("contextmenu", handleRightClick);
129813
130357
  }
129814
130358
  slashMenuCloseHandler = () => {
@@ -129832,6 +130376,7 @@ const _sfc_main$8 = {
129832
130376
  props.editor.off("slashMenu:close", slashMenuCloseHandler);
129833
130377
  }
129834
130378
  props.editor.off("update", handleEditorUpdate);
130379
+ contextMenuTarget?.removeEventListener("contextmenu", handleRightClickCapture, true);
129835
130380
  contextMenuTarget?.removeEventListener("contextmenu", handleRightClick);
129836
130381
  } catch (error) {
129837
130382
  console.warn("[SlashMenu] Error during cleanup:", error);
@@ -131798,6 +132343,12 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
131798
132343
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
131799
132344
  });
131800
132345
  const handleMarginClick = (event) => {
132346
+ if (event.button !== 0) {
132347
+ return;
132348
+ }
132349
+ if (event.ctrlKey && isMacOS()) {
132350
+ return;
132351
+ }
131801
132352
  if (event.target.classList.contains("ProseMirror")) return;
131802
132353
  onMarginClickCursorChange(event, activeEditor.value);
131803
132354
  };
@@ -131936,7 +132487,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
131936
132487
  };
131937
132488
  }
131938
132489
  });
131939
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-209a1e8b"]]);
132490
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-c9a3c876"]]);
131940
132491
  const _hoisted_1 = ["innerHTML"];
131941
132492
  const _sfc_main = {
131942
132493
  __name: "SuperInput",