superdoc 1.0.2 → 1.0.4

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-CEsyOAkj.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C51KNTCu.es.js → PdfViewer-HJvoIAmw.es.js} +1 -1
  3. package/dist/chunks/{index-Cf7hdzkm.cjs → index-BnbidVv1.cjs} +3 -3
  4. package/dist/chunks/{index-DDZ1ZT8N-DzepXBTN.cjs → index-Bv0DGtbh-K1rWUuu7.cjs} +1 -1
  5. package/dist/chunks/{index-DDZ1ZT8N-MJzqg0qg.es.js → index-Bv0DGtbh-urKMoo8D.es.js} +1 -1
  6. package/dist/chunks/{index-rtbawgUA.es.js → index-Bz20imLv.es.js} +3 -3
  7. package/dist/chunks/{super-editor.es-BijxiFs9.cjs → super-editor.es-DJA6a1gh.cjs} +711 -141
  8. package/dist/chunks/{super-editor.es-DFXddrgb.es.js → super-editor.es-KVC6ktpa.es.js} +711 -141
  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-gJwtBYAj.js} +1 -1
  13. package/dist/super-editor/chunks/{docx-zipper-D8Tzq3RX.js → docx-zipper-W2QGfyJo.js} +1 -1
  14. package/dist/super-editor/chunks/{editor-mgoEnsBi.js → editor-R8q_NUAb.js} +708 -155
  15. package/dist/super-editor/chunks/{index-DDZ1ZT8N.js → index-Bv0DGtbh.js} +1 -1
  16. package/dist/super-editor/chunks/{toolbar-DULgxvjl.js → toolbar-Bh9zkddg.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 +713 -143
  29. package/dist/superdoc.umd.js.map +1 -1
  30. package/package.json +1 -1
@@ -42410,7 +42410,7 @@ const _SuperConverter = class _SuperConverter2 {
42410
42410
  static getStoredSuperdocVersion(docx) {
42411
42411
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42412
42412
  }
42413
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.2") {
42413
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.4") {
42414
42414
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42415
42415
  }
42416
42416
  /**
@@ -60491,7 +60491,7 @@ const isHeadless = (editor) => {
60491
60491
  const shouldSkipNodeView = (editor) => {
60492
60492
  return isHeadless(editor);
60493
60493
  };
60494
- const summaryVersion = "1.0.2";
60494
+ const summaryVersion = "1.0.4";
60495
60495
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
60496
60496
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
60497
60497
  function mapAttributes(attrs) {
@@ -61280,7 +61280,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
61280
61280
  { default: remarkStringify },
61281
61281
  { default: remarkGfm }
61282
61282
  ] = await Promise.all([
61283
- import("./index-DDZ1ZT8N-MJzqg0qg.es.js"),
61283
+ import("./index-Bv0DGtbh-urKMoo8D.es.js"),
61284
61284
  import("./index-DRCvimau-Cw339678.es.js"),
61285
61285
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
61286
61286
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -61485,7 +61485,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
61485
61485
  * Process collaboration migrations
61486
61486
  */
61487
61487
  processCollaborationMigrations() {
61488
- console.debug("[checkVersionMigrations] Current editor version", "1.0.2");
61488
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.4");
61489
61489
  if (!this.options.ydoc) return;
61490
61490
  const metaMap = this.options.ydoc.getMap("meta");
61491
61491
  let docVersion = metaMap.get("version");
@@ -68737,7 +68737,7 @@ function isMinimalWordLayout(value) {
68737
68737
  return true;
68738
68738
  }
68739
68739
  const LIST_MARKER_GAP$2 = 8;
68740
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
68740
+ const DEFAULT_TAB_INTERVAL_PX$2 = 48;
68741
68741
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
68742
68742
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
68743
68743
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -69664,6 +69664,7 @@ const _DomPainter = class _DomPainter2 {
69664
69664
  const block = lookup2.block;
69665
69665
  const measure = lookup2.measure;
69666
69666
  const wordLayout = isMinimalWordLayout(block.attrs?.wordLayout) ? block.attrs.wordLayout : void 0;
69667
+ const alignment2 = block.attrs?.alignment;
69667
69668
  const fragmentEl = this.doc.createElement("div");
69668
69669
  fragmentEl.classList.add(CLASS_NAMES$1.fragment);
69669
69670
  const isTocEntry = block.attrs?.isTocEntry;
@@ -69742,7 +69743,7 @@ const _DomPainter = class _DomPainter2 {
69742
69743
  const textStart = paraIndentLeft + firstLine;
69743
69744
  tabWidth = textStart - currentPos;
69744
69745
  if (tabWidth <= 0) {
69745
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
69746
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
69746
69747
  } else if (tabWidth < LIST_MARKER_GAP$2) {
69747
69748
  tabWidth = LIST_MARKER_GAP$2;
69748
69749
  }
@@ -69769,6 +69770,21 @@ const _DomPainter = class _DomPainter2 {
69769
69770
  let availableWidthOverride = line.maxWidth != null ? Math.min(line.maxWidth, fallbackAvailableWidth) : fallbackAvailableWidth;
69770
69771
  if (index2 === 0 && listFirstLineMarkerTabWidth != null) {
69771
69772
  availableWidthOverride = fragment.width - listFirstLineMarkerTabWidth - Math.max(0, paraIndentRight);
69773
+ if (alignment2 === "justify" || alignment2 === "both") {
69774
+ console.log(
69775
+ "[justify-debug][painter-firstline-available]",
69776
+ JSON.stringify({
69777
+ blockId: block.id,
69778
+ fragmentWidth: fragment.width,
69779
+ markerTabWidth: listFirstLineMarkerTabWidth,
69780
+ paraIndentRight,
69781
+ availableWidthOverride,
69782
+ lineMaxWidth: line.maxWidth ?? null,
69783
+ lineWidth: line.width,
69784
+ lineNaturalWidth: line.naturalWidth ?? null
69785
+ })
69786
+ );
69787
+ }
69772
69788
  }
69773
69789
  const isLastLineOfFragment = index2 === lines.length - 1;
69774
69790
  const isLastLineOfParagraph = isLastLineOfFragment && !fragment.continuesOnNext;
@@ -69894,7 +69910,7 @@ const _DomPainter = class _DomPainter2 {
69894
69910
  const textStart = paraIndentLeft + firstLine;
69895
69911
  tabWidth = textStart - currentPos;
69896
69912
  if (tabWidth <= 0) {
69897
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
69913
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
69898
69914
  } else if (tabWidth < LIST_MARKER_GAP$2) {
69899
69915
  tabWidth = LIST_MARKER_GAP$2;
69900
69916
  }
@@ -71428,6 +71444,23 @@ const _DomPainter = class _DomPainter2 {
71428
71444
  if (spacingPerSpace !== 0) {
71429
71445
  el.style.wordSpacing = `${spacingPerSpace}px`;
71430
71446
  }
71447
+ if (justifyShouldApply && spacingPerSpace < 0) {
71448
+ console.log(
71449
+ "[justify-debug][painter-wordspacing-negative]",
71450
+ JSON.stringify({
71451
+ blockId: block.id,
71452
+ lineIndex: lineIndex ?? null,
71453
+ alignment: alignment2 ?? null,
71454
+ availableWidth,
71455
+ lineWidth,
71456
+ lineMaxWidth: line.maxWidth ?? null,
71457
+ lineNaturalWidth: line.naturalWidth ?? null,
71458
+ spaceCount,
71459
+ hasExplicitPositioning: Boolean(hasExplicitPositioning),
71460
+ skipJustify: Boolean(skipJustify)
71461
+ })
71462
+ );
71463
+ }
71431
71464
  if (hasExplicitPositioning && line.segments) {
71432
71465
  const paraIndent = block.attrs?.indent;
71433
71466
  const indentLeft = paraIndent?.left ?? 0;
@@ -73621,6 +73654,28 @@ let measurementCtx = null;
73621
73654
  const TAB_CHAR_LENGTH = 1;
73622
73655
  const SPACE_CHARS = SPACE_CHARS$1;
73623
73656
  const isTabRun$1 = (run2) => run2?.kind === "tab";
73657
+ const isWordChar$3 = (char) => {
73658
+ if (!char) return false;
73659
+ const code = char.charCodeAt(0);
73660
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
73661
+ };
73662
+ const capitalizeText$2 = (text) => {
73663
+ if (!text) return text;
73664
+ let result = "";
73665
+ for (let i = 0; i < text.length; i += 1) {
73666
+ const prevChar = i > 0 ? text[i - 1] : "";
73667
+ const ch = text[i];
73668
+ result += isWordChar$3(ch) && !isWordChar$3(prevChar) ? ch.toUpperCase() : ch;
73669
+ }
73670
+ return result;
73671
+ };
73672
+ const applyTextTransform$2 = (text, transform) => {
73673
+ if (!text || !transform || transform === "none") return text;
73674
+ if (transform === "uppercase") return text.toUpperCase();
73675
+ if (transform === "lowercase") return text.toLowerCase();
73676
+ if (transform === "capitalize") return capitalizeText$2(text);
73677
+ return text;
73678
+ };
73624
73679
  function getMeasurementContext() {
73625
73680
  if (measurementCtx) return measurementCtx;
73626
73681
  if (typeof document === "undefined") {
@@ -73796,17 +73851,18 @@ function measureCharacterX(block, line, charOffset, availableWidthOverride, alig
73796
73851
  }
73797
73852
  const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73798
73853
  const runLength = text.length;
73854
+ const displayText = applyTextTransform$2(text, run2.textTransform);
73799
73855
  if (currentCharOffset + runLength >= charOffset) {
73800
73856
  const offsetInRun = charOffset - currentCharOffset;
73801
73857
  ctx2.font = getRunFontString(run2);
73802
- const textUpToTarget = text.slice(0, offsetInRun);
73858
+ const textUpToTarget = displayText.slice(0, offsetInRun);
73803
73859
  const measured2 = ctx2.measureText(textUpToTarget);
73804
73860
  const spacingWidth = computeLetterSpacingWidth(run2, offsetInRun, runLength);
73805
- const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(textUpToTarget) : 0;
73861
+ const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(text.slice(0, offsetInRun)) : 0;
73806
73862
  return alignmentOffset + currentX + measured2.width + spacingWidth + justify.extraPerSpace * (spaceTally + spacesInPortion);
73807
73863
  }
73808
73864
  ctx2.font = getRunFontString(run2);
73809
- const measured = ctx2.measureText(text);
73865
+ const measured = ctx2.measureText(displayText);
73810
73866
  const runLetterSpacing = computeLetterSpacingWidth(run2, runLength, runLength);
73811
73867
  const spacesInRun = justify.extraPerSpace !== 0 ? countSpaces(text) : 0;
73812
73868
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -73845,8 +73901,9 @@ function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
73845
73901
  return segmentBaseX + (offsetInSegment >= segmentChars ? segment.width ?? 0 : 0);
73846
73902
  }
73847
73903
  const text = run2.text ?? "";
73848
- const segmentText = text.slice(segment.fromChar, segment.toChar);
73849
- const textUpToTarget = segmentText.slice(0, offsetInSegment);
73904
+ const displayText = applyTextTransform$2(text, run2.textTransform);
73905
+ const displaySegmentText = displayText.slice(segment.fromChar, segment.toChar);
73906
+ const textUpToTarget = displaySegmentText.slice(0, offsetInSegment);
73850
73907
  ctx2.font = getRunFontString(run2);
73851
73908
  const measured = ctx2.measureText(textUpToTarget);
73852
73909
  const spacingWidth = computeLetterSpacingWidth(run2, offsetInSegment, segmentChars);
@@ -73942,12 +73999,13 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73942
73999
  }
73943
74000
  const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73944
74001
  const runLength = text.length;
74002
+ const displayText = applyTextTransform$2(text, run2.textTransform);
73945
74003
  if (runLength === 0) continue;
73946
74004
  ctx2.font = getRunFontString(run2);
73947
74005
  for (let i = 0; i <= runLength; i++) {
73948
- const textUpToChar = text.slice(0, i);
74006
+ const textUpToChar = displayText.slice(0, i);
73949
74007
  const measured2 = ctx2.measureText(textUpToChar);
73950
- const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(textUpToChar) : 0;
74008
+ const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(text.slice(0, i)) : 0;
73951
74009
  const charX = currentX + measured2.width + computeLetterSpacingWidth(run2, i, runLength) + justify.extraPerSpace * (spaceTally + spacesInPortion);
73952
74010
  if (charX >= safeX) {
73953
74011
  if (i === 0) {
@@ -73957,7 +74015,7 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73957
74015
  pmPosition: pmPosition3
73958
74016
  };
73959
74017
  }
73960
- const prevText = text.slice(0, i - 1);
74018
+ const prevText = displayText.slice(0, i - 1);
73961
74019
  const prevMeasured = ctx2.measureText(prevText);
73962
74020
  const prevX = currentX + prevMeasured.width + computeLetterSpacingWidth(run2, i - 1, runLength);
73963
74021
  const distToPrev = Math.abs(safeX - prevX);
@@ -73970,7 +74028,7 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73970
74028
  };
73971
74029
  }
73972
74030
  }
73973
- const measured = ctx2.measureText(text);
74031
+ const measured = ctx2.measureText(displayText);
73974
74032
  const runLetterSpacing = computeLetterSpacingWidth(run2, runLength, runLength);
73975
74033
  const spacesInRun = justify.extraPerSpace > 0 ? countSpaces(text) : 0;
73976
74034
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -74401,6 +74459,83 @@ function findCharIndexAtX(textNode, container, targetX) {
74401
74459
  }
74402
74460
  return index2;
74403
74461
  }
74462
+ const LIST_MARKER_GAP$1 = 8;
74463
+ const MIN_MARKER_GUTTER = 24;
74464
+ const DEFAULT_LIST_INDENT_BASE_PX = 24;
74465
+ const DEFAULT_LIST_INDENT_STEP_PX = 24;
74466
+ const DEFAULT_LIST_HANGING_PX$1 = 18;
74467
+ const SPACE_SUFFIX_GAP_PX = 4;
74468
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74469
+ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
74470
+ const marker = wordLayout?.marker;
74471
+ if (!marker) {
74472
+ const textStartPx = wordLayout?.firstLineIndentMode === true && typeof wordLayout.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
74473
+ return textStartPx;
74474
+ }
74475
+ const markerBoxWidth = typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0;
74476
+ let markerTextWidth = typeof marker.glyphWidthPx === "number" && Number.isFinite(marker.glyphWidthPx) ? marker.glyphWidthPx : void 0;
74477
+ if (markerTextWidth == null && marker.markerText) {
74478
+ markerTextWidth = measureMarkerText(marker.markerText, marker);
74479
+ }
74480
+ if (!Number.isFinite(markerTextWidth) || markerTextWidth < 0) {
74481
+ markerTextWidth = markerBoxWidth;
74482
+ }
74483
+ markerTextWidth = Math.max(0, markerTextWidth);
74484
+ let markerStartPos;
74485
+ if (wordLayout?.firstLineIndentMode === true && Number.isFinite(marker.markerX)) {
74486
+ markerStartPos = marker.markerX;
74487
+ } else {
74488
+ markerStartPos = indentLeft - hanging + firstLine;
74489
+ }
74490
+ if (!Number.isFinite(markerStartPos)) {
74491
+ markerStartPos = 0;
74492
+ }
74493
+ const currentPos = markerStartPos + markerTextWidth;
74494
+ const suffix2 = marker.suffix ?? "tab";
74495
+ if (suffix2 === "space") {
74496
+ return markerStartPos + markerTextWidth + SPACE_SUFFIX_GAP_PX;
74497
+ }
74498
+ if (suffix2 === "nothing") {
74499
+ return markerStartPos + markerTextWidth;
74500
+ }
74501
+ const markerJustification = marker.justification ?? "left";
74502
+ if (markerJustification !== "left") {
74503
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
74504
+ return markerStartPos + markerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
74505
+ }
74506
+ if (wordLayout?.firstLineIndentMode === true) {
74507
+ let targetTabStop;
74508
+ if (Array.isArray(wordLayout.tabsPx)) {
74509
+ for (const tab of wordLayout.tabsPx) {
74510
+ if (typeof tab === "number" && tab > currentPos) {
74511
+ targetTabStop = tab;
74512
+ break;
74513
+ }
74514
+ }
74515
+ }
74516
+ const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
74517
+ let tabWidth2;
74518
+ if (targetTabStop !== void 0) {
74519
+ tabWidth2 = targetTabStop - currentPos;
74520
+ } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
74521
+ tabWidth2 = textStartTarget - currentPos;
74522
+ } else {
74523
+ tabWidth2 = LIST_MARKER_GAP$1;
74524
+ }
74525
+ if (tabWidth2 < LIST_MARKER_GAP$1) {
74526
+ tabWidth2 = LIST_MARKER_GAP$1;
74527
+ }
74528
+ return markerStartPos + markerTextWidth + tabWidth2;
74529
+ }
74530
+ const textStart = indentLeft + firstLine;
74531
+ let tabWidth = textStart - currentPos;
74532
+ if (tabWidth <= 0) {
74533
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
74534
+ } else if (tabWidth < LIST_MARKER_GAP$1) {
74535
+ tabWidth = LIST_MARKER_GAP$1;
74536
+ }
74537
+ return markerStartPos + markerTextWidth + tabWidth;
74538
+ }
74404
74539
  function getWordLayoutConfig(block) {
74405
74540
  if (!block || block.kind !== "paragraph") {
74406
74541
  return void 0;
@@ -74433,9 +74568,16 @@ function calculateTextStartIndent(params2) {
74433
74568
  const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
74434
74569
  let indentAdjust = paraIndentLeft;
74435
74570
  if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
74571
+ const resolvedTextStart = resolveListTextStartPx(
74572
+ wordLayout,
74573
+ paraIndentLeft,
74574
+ Math.max(firstLineIndent, 0),
74575
+ Math.max(hangingIndent, 0),
74576
+ () => markerWidth
74577
+ // Use provided markerWidth since we don't have canvas access here
74578
+ );
74436
74579
  const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
74437
- const markerTextStartX = wordLayout?.marker?.textStartX;
74438
- indentAdjust = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : textStartFallback;
74580
+ indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
74439
74581
  } else if (isFirstLine && !isListItem2) {
74440
74582
  indentAdjust += firstLineOffset;
74441
74583
  }
@@ -74591,7 +74733,10 @@ function getHeaderFooterTypeForSection(pageNumber, sectionIndex, identifier, opt
74591
74733
  }
74592
74734
  function createFloatingObjectManager(columns, margins, pageWidth) {
74593
74735
  const zones = [];
74594
- const marginLeft = Math.max(0, margins?.left ?? 0);
74736
+ let currentColumns = columns;
74737
+ let currentMargins = margins;
74738
+ let currentPageWidth = pageWidth;
74739
+ let marginLeft = Math.max(0, currentMargins?.left ?? 0);
74595
74740
  return {
74596
74741
  registerDrawing(drawingBlock, measure, anchorY, columnIndex, pageNumber) {
74597
74742
  if (!drawingBlock.anchor?.isAnchored) {
@@ -74604,7 +74749,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74604
74749
  }
74605
74750
  const objectWidth = measure.width ?? 0;
74606
74751
  const objectHeight = measure.height ?? 0;
74607
- const x2 = computeAnchorX(anchor, columnIndex, columns, objectWidth, margins, pageWidth);
74752
+ const x2 = computeAnchorX(anchor, columnIndex, currentColumns, objectWidth, currentMargins, currentPageWidth);
74608
74753
  const y2 = anchorY + (anchor.offsetV ?? 0);
74609
74754
  const zone = {
74610
74755
  imageBlockId: drawingBlock.id,
@@ -74638,7 +74783,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74638
74783
  }
74639
74784
  const tableWidth = measure.totalWidth ?? 0;
74640
74785
  const tableHeight = measure.totalHeight ?? 0;
74641
- const x2 = computeTableAnchorX(anchor, columnIndex, columns, tableWidth, margins, pageWidth);
74786
+ const x2 = computeTableAnchorX(anchor, columnIndex, currentColumns, tableWidth, currentMargins, currentPageWidth);
74642
74787
  const y2 = anchorY + (anchor.offsetV ?? 0);
74643
74788
  const zone = {
74644
74789
  imageBlockId: tableBlock.id,
@@ -74686,7 +74831,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74686
74831
  }
74687
74832
  const leftFloats = [];
74688
74833
  const rightFloats = [];
74689
- const columnOrigin = marginLeft + columnIndex * (columns.width + columns.gap);
74834
+ const columnOrigin = marginLeft + columnIndex * (currentColumns.width + currentColumns.gap);
74690
74835
  const columnCenter = columnOrigin + baseWidth / 2;
74691
74836
  for (const zone of wrappingZones) {
74692
74837
  if (zone.wrapMode === "left") {
@@ -74725,6 +74870,22 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74725
74870
  },
74726
74871
  clear() {
74727
74872
  zones.length = 0;
74873
+ },
74874
+ /**
74875
+ * Update layout context used for positioning and wrapping (columns, margins, page width).
74876
+ * This method should be called when the layout configuration changes (e.g., section breaks,
74877
+ * column changes, page size changes) to ensure floating objects are positioned and wrapped
74878
+ * correctly relative to the new layout boundaries.
74879
+ *
74880
+ * @param nextColumns - Column layout configuration (width, gap, count)
74881
+ * @param nextMargins - Optional page margins (left, right) in pixels
74882
+ * @param nextPageWidth - Optional total page width in pixels
74883
+ */
74884
+ setLayoutContext(nextColumns, nextMargins, nextPageWidth) {
74885
+ currentColumns = nextColumns;
74886
+ currentMargins = nextMargins;
74887
+ currentPageWidth = nextPageWidth;
74888
+ marginLeft = Math.max(0, currentMargins?.left ?? 0);
74728
74889
  }
74729
74890
  };
74730
74891
  }
@@ -74824,7 +74985,14 @@ function computeNextSectionPropsAtBreak(blocks) {
74824
74985
  const props = {};
74825
74986
  if (source.kind !== "sectionBreak") return props;
74826
74987
  if (source.margins) {
74827
- props.margins = { header: source.margins.header, footer: source.margins.footer };
74988
+ props.margins = {
74989
+ header: source.margins.header,
74990
+ footer: source.margins.footer,
74991
+ top: source.margins.top,
74992
+ right: source.margins.right,
74993
+ bottom: source.margins.bottom,
74994
+ left: source.margins.left
74995
+ };
74828
74996
  }
74829
74997
  if (source.pageSize) {
74830
74998
  props.pageSize = { w: source.pageSize.w, h: source.pageSize.h };
@@ -74872,20 +75040,36 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
74872
75040
  next.activeOrientation = block.orientation;
74873
75041
  next.pendingOrientation = null;
74874
75042
  }
75043
+ const headerDistance = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
75044
+ const footerDistance = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
75045
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
75046
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
74875
75047
  if (block.margins?.header !== void 0) {
74876
- const headerDistance = Math.max(0, block.margins.header);
74877
75048
  next.activeHeaderDistance = headerDistance;
74878
75049
  next.pendingHeaderDistance = headerDistance;
74879
- next.activeTopMargin = calcRequiredTopMargin(headerDistance, baseMargins.top);
74880
- next.pendingTopMargin = next.activeTopMargin;
74881
75050
  }
74882
75051
  if (block.margins?.footer !== void 0) {
74883
- const footerDistance = Math.max(0, block.margins.footer);
74884
75052
  next.activeFooterDistance = footerDistance;
74885
75053
  next.pendingFooterDistance = footerDistance;
74886
- next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
75054
+ }
75055
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
75056
+ next.activeTopMargin = calcRequiredTopMargin(headerDistance, sectionTop);
75057
+ next.pendingTopMargin = next.activeTopMargin;
75058
+ }
75059
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
75060
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, sectionBottom);
74887
75061
  next.pendingBottomMargin = next.activeBottomMargin;
74888
75062
  }
75063
+ if (block.margins?.left !== void 0) {
75064
+ const leftMargin = Math.max(0, block.margins.left);
75065
+ next.activeLeftMargin = leftMargin;
75066
+ next.pendingLeftMargin = leftMargin;
75067
+ }
75068
+ if (block.margins?.right !== void 0) {
75069
+ const rightMargin = Math.max(0, block.margins.right);
75070
+ next.activeRightMargin = rightMargin;
75071
+ next.pendingRightMargin = rightMargin;
75072
+ }
74889
75073
  if (block.columns) {
74890
75074
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
74891
75075
  next.pendingColumns = null;
@@ -74894,26 +75078,42 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
74894
75078
  }
74895
75079
  const headerPx = block.margins?.header;
74896
75080
  const footerPx = block.margins?.footer;
75081
+ const topPx = block.margins?.top;
75082
+ const bottomPx = block.margins?.bottom;
74897
75083
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
74898
75084
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
75085
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
75086
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
74899
75087
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
74900
75088
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
74901
- if (typeof headerPx === "number") {
74902
- const newHeaderDist = Math.max(0, headerPx);
75089
+ if (typeof headerPx === "number" || typeof topPx === "number") {
75090
+ const newHeaderDist = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
75091
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
74903
75092
  next.pendingHeaderDistance = newHeaderDist;
74904
- next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, baseMargins.top);
75093
+ next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, sectionTop);
74905
75094
  } else {
74906
75095
  next.pendingTopMargin = nextTop;
74907
75096
  next.pendingHeaderDistance = nextHeader;
74908
75097
  }
74909
- if (typeof footerPx === "number") {
74910
- const newFooterDist = Math.max(0, footerPx);
75098
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
75099
+ const newFooterDist = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
75100
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
74911
75101
  next.pendingFooterDistance = newFooterDist;
74912
- next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
75102
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, sectionBottom);
74913
75103
  } else {
74914
75104
  next.pendingBottomMargin = nextBottom;
74915
75105
  next.pendingFooterDistance = nextFooter;
74916
75106
  }
75107
+ if (typeof block.margins?.left === "number") {
75108
+ next.pendingLeftMargin = Math.max(0, block.margins.left);
75109
+ } else {
75110
+ next.pendingLeftMargin = nextLeft;
75111
+ }
75112
+ if (typeof block.margins?.right === "number") {
75113
+ next.pendingRightMargin = Math.max(0, block.margins.right);
75114
+ } else {
75115
+ next.pendingRightMargin = nextRight;
75116
+ }
74917
75117
  if (block.pageSize) {
74918
75118
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
74919
75119
  }
@@ -74973,6 +75173,12 @@ function applyPendingToActive(state2) {
74973
75173
  if (next.pendingBottomMargin != null) {
74974
75174
  next.activeBottomMargin = next.pendingBottomMargin;
74975
75175
  }
75176
+ if (next.pendingLeftMargin != null) {
75177
+ next.activeLeftMargin = next.pendingLeftMargin;
75178
+ }
75179
+ if (next.pendingRightMargin != null) {
75180
+ next.activeRightMargin = next.pendingRightMargin;
75181
+ }
74976
75182
  if (next.pendingHeaderDistance != null) {
74977
75183
  next.activeHeaderDistance = next.pendingHeaderDistance;
74978
75184
  }
@@ -74990,6 +75196,8 @@ function applyPendingToActive(state2) {
74990
75196
  }
74991
75197
  next.pendingTopMargin = null;
74992
75198
  next.pendingBottomMargin = null;
75199
+ next.pendingLeftMargin = null;
75200
+ next.pendingRightMargin = null;
74993
75201
  next.pendingHeaderDistance = null;
74994
75202
  next.pendingFooterDistance = null;
74995
75203
  next.pendingPageSize = null;
@@ -75218,7 +75426,8 @@ function layoutParagraphBlock(ctx2, anchors) {
75218
75426
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
75219
75427
  const firstLineIndent = calculateFirstLineIndent(block, measure);
75220
75428
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
75221
- lines = normalizeLines(newMeasure);
75429
+ const newLines = normalizeLines(newMeasure);
75430
+ lines = newLines;
75222
75431
  didRemeasureForColumnWidth = true;
75223
75432
  }
75224
75433
  let fromLine = 0;
@@ -75300,7 +75509,8 @@ function layoutParagraphBlock(ctx2, anchors) {
75300
75509
  if (narrowestRemeasureWidth < remeasureWidth) {
75301
75510
  const firstLineIndent = calculateFirstLineIndent(block, measure);
75302
75511
  const newMeasure = remeasureParagraph2(block, narrowestRemeasureWidth, firstLineIndent);
75303
- lines = normalizeLines(newMeasure);
75512
+ const newLines = normalizeLines(newMeasure);
75513
+ lines = newLines;
75304
75514
  didRemeasureForFloats = true;
75305
75515
  }
75306
75516
  }
@@ -75644,6 +75854,94 @@ function getCellPadding(cellIdx, blockRow) {
75644
75854
  function getCellTotalLines(cell) {
75645
75855
  return getCellLines(cell).length;
75646
75856
  }
75857
+ function mergePmRange(target, range2) {
75858
+ if (typeof range2.pmStart === "number") {
75859
+ target.pmStart = target.pmStart == null ? range2.pmStart : Math.min(target.pmStart, range2.pmStart);
75860
+ }
75861
+ if (typeof range2.pmEnd === "number") {
75862
+ target.pmEnd = target.pmEnd == null ? range2.pmEnd : Math.max(target.pmEnd, range2.pmEnd);
75863
+ }
75864
+ }
75865
+ function computeCellPmRange(cell, cellMeasure, fromLine, toLine) {
75866
+ const range2 = {};
75867
+ if (!cell || !cellMeasure) return range2;
75868
+ const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
75869
+ const blockMeasures = cellMeasure.blocks ?? (cellMeasure.paragraph ? [cellMeasure.paragraph] : []);
75870
+ const maxBlocks = Math.min(cellBlocks.length, blockMeasures.length);
75871
+ let cumulativeLineCount = 0;
75872
+ for (let i = 0; i < maxBlocks; i++) {
75873
+ const block = cellBlocks[i];
75874
+ const blockMeasure = blockMeasures[i];
75875
+ if (blockMeasure.kind === "paragraph" && block?.kind === "paragraph") {
75876
+ const paraMeasure = blockMeasure;
75877
+ const lines = paraMeasure.lines;
75878
+ const blockLineCount = lines?.length ?? 0;
75879
+ const blockStartGlobal = cumulativeLineCount;
75880
+ const blockEndGlobal = cumulativeLineCount + blockLineCount;
75881
+ const localFrom = Math.max(fromLine, blockStartGlobal) - blockStartGlobal;
75882
+ const localTo = Math.min(toLine, blockEndGlobal) - blockStartGlobal;
75883
+ if (lines && lines.length > 0 && localFrom < localTo) {
75884
+ mergePmRange(range2, computeFragmentPmRange(block, lines, localFrom, localTo));
75885
+ } else {
75886
+ mergePmRange(range2, extractBlockPmRange(block));
75887
+ }
75888
+ cumulativeLineCount += blockLineCount;
75889
+ continue;
75890
+ }
75891
+ mergePmRange(range2, extractBlockPmRange(block));
75892
+ }
75893
+ return range2;
75894
+ }
75895
+ function computeTableFragmentPmRange(block, measure, fromRow, toRow, partialRow) {
75896
+ const range2 = {};
75897
+ for (let rowIndex = fromRow; rowIndex < toRow; rowIndex++) {
75898
+ const row = block.rows[rowIndex];
75899
+ const rowMeasure = measure.rows[rowIndex];
75900
+ if (!row || !rowMeasure) continue;
75901
+ const isPartial = partialRow?.rowIndex === rowIndex;
75902
+ const cellCount = Math.min(row.cells.length, rowMeasure.cells.length);
75903
+ for (let cellIndex = 0; cellIndex < cellCount; cellIndex++) {
75904
+ const cell = row.cells[cellIndex];
75905
+ const cellMeasure = rowMeasure.cells[cellIndex];
75906
+ if (!cell || !cellMeasure) continue;
75907
+ const totalLines = getCellTotalLines(cellMeasure);
75908
+ let fromLine = 0;
75909
+ let toLine = totalLines;
75910
+ if (isPartial) {
75911
+ const hasValidFromLineByCell = partialRow?.fromLineByCell && cellIndex < partialRow.fromLineByCell.length;
75912
+ const hasValidToLineByCell = partialRow?.toLineByCell && cellIndex < partialRow.toLineByCell.length;
75913
+ if (hasValidFromLineByCell) {
75914
+ const rawFrom = partialRow.fromLineByCell[cellIndex];
75915
+ if (typeof rawFrom === "number" && rawFrom >= 0) {
75916
+ fromLine = rawFrom;
75917
+ }
75918
+ }
75919
+ if (hasValidToLineByCell) {
75920
+ const rawTo = partialRow.toLineByCell[cellIndex];
75921
+ if (typeof rawTo === "number") {
75922
+ toLine = rawTo === -1 ? totalLines : rawTo;
75923
+ }
75924
+ }
75925
+ }
75926
+ fromLine = Math.max(0, Math.min(fromLine, totalLines));
75927
+ toLine = Math.max(0, Math.min(toLine, totalLines));
75928
+ if (toLine < fromLine) {
75929
+ toLine = fromLine;
75930
+ }
75931
+ mergePmRange(range2, computeCellPmRange(cell, cellMeasure, fromLine, toLine));
75932
+ }
75933
+ }
75934
+ return range2;
75935
+ }
75936
+ function applyTableFragmentPmRange(fragment, block, measure) {
75937
+ const range2 = computeTableFragmentPmRange(block, measure, fragment.fromRow, fragment.toRow, fragment.partialRow);
75938
+ if (range2.pmStart != null) {
75939
+ fragment.pmStart = range2.pmStart;
75940
+ }
75941
+ if (range2.pmEnd != null) {
75942
+ fragment.pmEnd = range2.pmEnd;
75943
+ }
75944
+ }
75647
75945
  function computePartialRow(rowIndex, blockRow, measure, availableHeight, fromLineByCell) {
75648
75946
  const row = measure.rows[rowIndex];
75649
75947
  if (!row) {
@@ -75788,6 +76086,7 @@ function layoutMonolithicTable(context) {
75788
76086
  height,
75789
76087
  metadata
75790
76088
  };
76089
+ applyTableFragmentPmRange(fragment, context.block, context.measure);
75791
76090
  state2.page.fragments.push(fragment);
75792
76091
  state2.cursorY += height;
75793
76092
  }
@@ -75866,6 +76165,7 @@ function layoutTableBlock({
75866
76165
  height,
75867
76166
  metadata
75868
76167
  };
76168
+ applyTableFragmentPmRange(fragment, block, measure);
75869
76169
  state2.page.fragments.push(fragment);
75870
76170
  state2.cursorY += height;
75871
76171
  return;
@@ -75929,6 +76229,7 @@ function layoutTableBlock({
75929
76229
  partialRow: continuationPartialRow,
75930
76230
  metadata: generateFragmentMetadata(measure)
75931
76231
  };
76232
+ applyTableFragmentPmRange(fragment2, block, measure);
75932
76233
  state2.page.fragments.push(fragment2);
75933
76234
  state2.cursorY += fragmentHeight2;
75934
76235
  }
@@ -75973,6 +76274,7 @@ function layoutTableBlock({
75973
76274
  partialRow: forcedPartialRow,
75974
76275
  metadata: generateFragmentMetadata(measure)
75975
76276
  };
76277
+ applyTableFragmentPmRange(fragment2, block, measure);
75976
76278
  state2.page.fragments.push(fragment2);
75977
76279
  state2.cursorY += fragmentHeight2;
75978
76280
  pendingPartialRow = forcedPartialRow;
@@ -76008,6 +76310,7 @@ function layoutTableBlock({
76008
76310
  partialRow: partialRow || void 0,
76009
76311
  metadata: generateFragmentMetadata(measure)
76010
76312
  };
76313
+ applyTableFragmentPmRange(fragment, block, measure);
76011
76314
  state2.page.fragments.push(fragment);
76012
76315
  state2.cursorY += fragmentHeight;
76013
76316
  if (partialRow && !partialRow.isLastPart) {
@@ -76025,7 +76328,7 @@ function createAnchoredTableFragment(block, measure, x2, y2) {
76025
76328
  columnBoundaries: generateColumnBoundaries(measure),
76026
76329
  coordinateSystem: "fragment"
76027
76330
  };
76028
- return {
76331
+ const fragment = {
76029
76332
  kind: "table",
76030
76333
  blockId: block.id,
76031
76334
  fromRow: 0,
@@ -76036,6 +76339,8 @@ function createAnchoredTableFragment(block, measure, x2, y2) {
76036
76339
  height: measure.totalHeight ?? 0,
76037
76340
  metadata
76038
76341
  };
76342
+ applyTableFragmentPmRange(fragment, block, measure);
76343
+ return fragment;
76039
76344
  }
76040
76345
  function isPageRelativeAnchor(block) {
76041
76346
  const vRelativeFrom = block.anchor?.vRelativeFrom;
@@ -76457,8 +76762,8 @@ function layoutDocument(blocks, measures, options = {}) {
76457
76762
  header: options.margins?.header ?? options.margins?.top ?? DEFAULT_MARGINS$2.top,
76458
76763
  footer: options.margins?.footer ?? options.margins?.bottom ?? DEFAULT_MARGINS$2.bottom
76459
76764
  };
76460
- const contentWidth = pageSize.w - (margins.left + margins.right);
76461
- if (contentWidth <= 0) {
76765
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
76766
+ if (baseContentWidth <= 0) {
76462
76767
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
76463
76768
  }
76464
76769
  const validateContentHeight = (height) => {
@@ -76488,8 +76793,12 @@ function layoutDocument(blocks, measures, options = {}) {
76488
76793
  const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
76489
76794
  let activeTopMargin = effectiveTopMargin;
76490
76795
  let activeBottomMargin = effectiveBottomMargin;
76796
+ let activeLeftMargin = margins.left;
76797
+ let activeRightMargin = margins.right;
76491
76798
  let pendingTopMargin = null;
76492
76799
  let pendingBottomMargin = null;
76800
+ let pendingLeftMargin = null;
76801
+ let pendingRightMargin = null;
76493
76802
  let activeHeaderDistance = margins.header ?? margins.top;
76494
76803
  let pendingHeaderDistance = null;
76495
76804
  let activeFooterDistance = margins.footer ?? margins.bottom;
@@ -76502,10 +76811,11 @@ function layoutDocument(blocks, measures, options = {}) {
76502
76811
  let pendingOrientation = null;
76503
76812
  let activeVAlign = null;
76504
76813
  let pendingVAlign = null;
76814
+ const paginatorMargins = { left: activeLeftMargin, right: activeRightMargin };
76505
76815
  const floatManager = createFloatingObjectManager(
76506
- normalizeColumns(activeColumns, contentWidth),
76507
- { left: margins.left, right: margins.right },
76508
- pageSize.w
76816
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
76817
+ { left: activeLeftMargin, right: activeRightMargin },
76818
+ activePageSize.w
76509
76819
  );
76510
76820
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
76511
76821
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
@@ -76522,22 +76832,38 @@ function layoutDocument(blocks, measures, options = {}) {
76522
76832
  next.activeOrientation = block.orientation;
76523
76833
  next.pendingOrientation = null;
76524
76834
  }
76835
+ const headerDistance2 = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
76836
+ const footerDistance2 = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
76837
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
76838
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
76525
76839
  if (block.margins?.header !== void 0) {
76526
- const headerDist = Math.max(0, block.margins.header);
76527
- next.activeHeaderDistance = headerDist;
76528
- next.pendingHeaderDistance = headerDist;
76529
- const requiredTop = maxHeaderContentHeight > 0 ? headerDist + maxHeaderContentHeight : headerDist;
76530
- next.activeTopMargin = Math.max(baseMargins.top, requiredTop);
76531
- next.pendingTopMargin = next.activeTopMargin;
76840
+ next.activeHeaderDistance = headerDistance2;
76841
+ next.pendingHeaderDistance = headerDistance2;
76532
76842
  }
76533
76843
  if (block.margins?.footer !== void 0) {
76534
- const footerDistance2 = Math.max(0, block.margins.footer);
76535
76844
  next.activeFooterDistance = footerDistance2;
76536
76845
  next.pendingFooterDistance = footerDistance2;
76846
+ }
76847
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
76848
+ const requiredTop = maxHeaderContentHeight > 0 ? headerDistance2 + maxHeaderContentHeight : headerDistance2;
76849
+ next.activeTopMargin = Math.max(sectionTop, requiredTop);
76850
+ next.pendingTopMargin = next.activeTopMargin;
76851
+ }
76852
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
76537
76853
  const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
76538
- next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
76854
+ next.activeBottomMargin = Math.max(sectionBottom, requiredBottom);
76539
76855
  next.pendingBottomMargin = next.activeBottomMargin;
76540
76856
  }
76857
+ if (block.margins?.left !== void 0) {
76858
+ const leftMargin = Math.max(0, block.margins.left);
76859
+ next.activeLeftMargin = leftMargin;
76860
+ next.pendingLeftMargin = leftMargin;
76861
+ }
76862
+ if (block.margins?.right !== void 0) {
76863
+ const rightMargin = Math.max(0, block.margins.right);
76864
+ next.activeRightMargin = rightMargin;
76865
+ next.pendingRightMargin = rightMargin;
76866
+ }
76541
76867
  if (block.columns) {
76542
76868
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
76543
76869
  next.pendingColumns = null;
@@ -76566,27 +76892,35 @@ function layoutDocument(blocks, measures, options = {}) {
76566
76892
  const headerPx = block.margins?.header;
76567
76893
  const footerPx = block.margins?.footer;
76568
76894
  const topPx = block.margins?.top;
76895
+ const bottomPx = block.margins?.bottom;
76896
+ const leftPx = block.margins?.left;
76897
+ const rightPx = block.margins?.right;
76569
76898
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
76570
76899
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
76900
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
76901
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
76571
76902
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
76572
76903
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
76573
76904
  next.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
76574
76905
  next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
76575
76906
  if (typeof headerPx === "number" || typeof topPx === "number") {
76576
- const sectionTop = topPx ?? baseMargins.top;
76907
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
76577
76908
  const sectionHeader = next.pendingHeaderDistance;
76578
76909
  const requiredTop = maxHeaderContentHeight > 0 ? sectionHeader + maxHeaderContentHeight : sectionHeader;
76579
76910
  next.pendingTopMargin = Math.max(sectionTop, requiredTop);
76580
76911
  } else {
76581
76912
  next.pendingTopMargin = nextTop;
76582
76913
  }
76583
- if (typeof footerPx === "number") {
76914
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
76584
76915
  const sectionFooter = next.pendingFooterDistance;
76916
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
76585
76917
  const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
76586
- next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
76918
+ next.pendingBottomMargin = Math.max(sectionBottom, requiredBottom);
76587
76919
  } else {
76588
76920
  next.pendingBottomMargin = nextBottom;
76589
76921
  }
76922
+ next.pendingLeftMargin = typeof leftPx === "number" ? Math.max(0, leftPx) : nextLeft;
76923
+ next.pendingRightMargin = typeof rightPx === "number" ? Math.max(0, rightPx) : nextRight;
76590
76924
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
76591
76925
  if (block.orientation) next.pendingOrientation = block.orientation;
76592
76926
  const sectionType = block.type ?? "continuous";
@@ -76671,7 +77005,7 @@ function layoutDocument(blocks, measures, options = {}) {
76671
77005
  let activeSectionIndex = initialSectionMetadata?.sectionIndex ?? 0;
76672
77006
  let pendingSectionIndex = null;
76673
77007
  const paginator = createPaginator({
76674
- margins: { left: margins.left, right: margins.right },
77008
+ margins: paginatorMargins,
76675
77009
  getActiveTopMargin: () => activeTopMargin,
76676
77010
  getActiveBottomMargin: () => activeBottomMargin,
76677
77011
  getActiveHeaderDistance: () => activeHeaderDistance,
@@ -76686,8 +77020,12 @@ function layoutDocument(blocks, measures, options = {}) {
76686
77020
  const applied = applyPendingToActive({
76687
77021
  activeTopMargin,
76688
77022
  activeBottomMargin,
77023
+ activeLeftMargin,
77024
+ activeRightMargin,
76689
77025
  pendingTopMargin,
76690
77026
  pendingBottomMargin,
77027
+ pendingLeftMargin,
77028
+ pendingRightMargin,
76691
77029
  activeHeaderDistance,
76692
77030
  activeFooterDistance,
76693
77031
  pendingHeaderDistance,
@@ -76702,8 +77040,12 @@ function layoutDocument(blocks, measures, options = {}) {
76702
77040
  });
76703
77041
  activeTopMargin = applied.activeTopMargin;
76704
77042
  activeBottomMargin = applied.activeBottomMargin;
77043
+ activeLeftMargin = applied.activeLeftMargin;
77044
+ activeRightMargin = applied.activeRightMargin;
76705
77045
  pendingTopMargin = applied.pendingTopMargin;
76706
77046
  pendingBottomMargin = applied.pendingBottomMargin;
77047
+ pendingLeftMargin = applied.pendingLeftMargin;
77048
+ pendingRightMargin = applied.pendingRightMargin;
76707
77049
  activeHeaderDistance = applied.activeHeaderDistance;
76708
77050
  activeFooterDistance = applied.activeFooterDistance;
76709
77051
  pendingHeaderDistance = applied.pendingHeaderDistance;
@@ -76715,6 +77057,14 @@ function layoutDocument(blocks, measures, options = {}) {
76715
77057
  activeOrientation = applied.activeOrientation;
76716
77058
  pendingOrientation = applied.pendingOrientation;
76717
77059
  cachedColumnsState.state = null;
77060
+ paginatorMargins.left = activeLeftMargin;
77061
+ paginatorMargins.right = activeRightMargin;
77062
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77063
+ floatManager.setLayoutContext(
77064
+ normalizeColumns(activeColumns, contentWidth),
77065
+ { left: activeLeftMargin, right: activeRightMargin },
77066
+ activePageSize.w
77067
+ );
76718
77068
  if (pendingNumbering) {
76719
77069
  if (pendingNumbering.format) activeNumberFormat = pendingNumbering.format;
76720
77070
  if (typeof pendingNumbering.start === "number" && Number.isFinite(pendingNumbering.start)) {
@@ -76759,7 +77109,7 @@ function layoutDocument(blocks, measures, options = {}) {
76759
77109
  const getActiveColumnsForState = paginator.getActiveColumnsForState;
76760
77110
  let cachedColumnsState = { state: null, constraintIndex: -2, contentWidth: -1, colsConfig: null, normalized: null };
76761
77111
  const getCurrentColumns = () => {
76762
- const currentContentWidth = activePageSize.w - (margins.left + margins.right);
77112
+ const currentContentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
76763
77113
  const state2 = states[states.length - 1] ?? null;
76764
77114
  const colsConfig = state2 ? getActiveColumnsForState(state2) : activeColumns;
76765
77115
  const constraintIndex = state2 ? state2.activeConstraintIndex : -1;
@@ -76792,6 +77142,12 @@ function layoutDocument(blocks, measures, options = {}) {
76792
77142
  layoutLog(` Current page: ${state2.page.number}, cursorY: ${state2.cursorY}`);
76793
77143
  activeColumns = newColumns;
76794
77144
  cachedColumnsState.state = null;
77145
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77146
+ floatManager.setLayoutContext(
77147
+ normalizeColumns(activeColumns, contentWidth),
77148
+ { left: activeLeftMargin, right: activeRightMargin },
77149
+ activePageSize.w
77150
+ );
76795
77151
  };
76796
77152
  const anchoredByParagraph = collectAnchoredDrawings(blocks, measures);
76797
77153
  const anchoredTablesByParagraph = collectAnchoredTables(blocks, measures);
@@ -76823,10 +77179,10 @@ function layoutDocument(blocks, measures, options = {}) {
76823
77179
  if (alignV === "top") {
76824
77180
  anchorY = offsetV;
76825
77181
  } else if (alignV === "bottom") {
76826
- const pageHeight = contentBottom + margins.bottom;
77182
+ const pageHeight = contentBottom + (state2.page.margins?.bottom ?? activeBottomMargin);
76827
77183
  anchorY = pageHeight - imageHeight + offsetV;
76828
77184
  } else if (alignV === "center") {
76829
- const pageHeight = contentBottom + margins.bottom;
77185
+ const pageHeight = contentBottom + (state2.page.margins?.bottom ?? activeBottomMargin);
76830
77186
  anchorY = (pageHeight - imageHeight) / 2 + offsetV;
76831
77187
  } else {
76832
77188
  anchorY = offsetV;
@@ -76837,11 +77193,11 @@ function layoutDocument(blocks, measures, options = {}) {
76837
77193
  const anchorX = entry.block.anchor ? computeAnchorX(
76838
77194
  entry.block.anchor,
76839
77195
  state2.columnIndex,
76840
- normalizeColumns(activeColumns, contentWidth),
77196
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
76841
77197
  entry.measure.width,
76842
- { left: margins.left, right: margins.right },
77198
+ { left: activeLeftMargin, right: activeRightMargin },
76843
77199
  activePageSize.w
76844
- ) : margins.left;
77200
+ ) : activeLeftMargin;
76845
77201
  floatManager.registerDrawing(entry.block, entry.measure, anchorY, state2.columnIndex, state2.page.number);
76846
77202
  preRegisteredPositions.set(entry.block.id, { anchorX, anchorY, pageNumber: state2.page.number });
76847
77203
  }
@@ -76879,8 +77235,12 @@ function layoutDocument(blocks, measures, options = {}) {
76879
77235
  const sectionState = {
76880
77236
  activeTopMargin,
76881
77237
  activeBottomMargin,
77238
+ activeLeftMargin,
77239
+ activeRightMargin,
76882
77240
  pendingTopMargin,
76883
77241
  pendingBottomMargin,
77242
+ pendingLeftMargin,
77243
+ pendingRightMargin,
76884
77244
  activeHeaderDistance,
76885
77245
  activeFooterDistance,
76886
77246
  pendingHeaderDistance,
@@ -76914,8 +77274,12 @@ function layoutDocument(blocks, measures, options = {}) {
76914
77274
  layoutLog(`[Layout] ========== END SECTION BREAK ==========`);
76915
77275
  activeTopMargin = updatedState.activeTopMargin;
76916
77276
  activeBottomMargin = updatedState.activeBottomMargin;
77277
+ activeLeftMargin = updatedState.activeLeftMargin;
77278
+ activeRightMargin = updatedState.activeRightMargin;
76917
77279
  pendingTopMargin = updatedState.pendingTopMargin;
76918
77280
  pendingBottomMargin = updatedState.pendingBottomMargin;
77281
+ pendingLeftMargin = updatedState.pendingLeftMargin;
77282
+ pendingRightMargin = updatedState.pendingRightMargin;
76919
77283
  activeHeaderDistance = updatedState.activeHeaderDistance;
76920
77284
  activeFooterDistance = updatedState.activeFooterDistance;
76921
77285
  pendingHeaderDistance = updatedState.pendingHeaderDistance;
@@ -77053,8 +77417,8 @@ function layoutDocument(blocks, measures, options = {}) {
77053
77417
  pageMargins: {
77054
77418
  top: activeTopMargin,
77055
77419
  bottom: activeBottomMargin,
77056
- left: margins.left,
77057
- right: margins.right
77420
+ left: activeLeftMargin,
77421
+ right: activeRightMargin
77058
77422
  },
77059
77423
  columns: getCurrentColumns(),
77060
77424
  placedAnchoredIds
@@ -77076,9 +77440,9 @@ function layoutDocument(blocks, measures, options = {}) {
77076
77440
  const cols = getCurrentColumns();
77077
77441
  let maxWidth;
77078
77442
  if (relativeFrom === "page") {
77079
- maxWidth = cols.count === 1 ? activePageSize.w - margins.left - margins.right : activePageSize.w;
77443
+ maxWidth = cols.count === 1 ? activePageSize.w - (activeLeftMargin + activeRightMargin) : activePageSize.w;
77080
77444
  } else if (relativeFrom === "margin") {
77081
- maxWidth = activePageSize.w - margins.left - margins.right;
77445
+ maxWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77082
77446
  } else {
77083
77447
  maxWidth = cols.width;
77084
77448
  }
@@ -77238,6 +77602,9 @@ function layoutHeaderFooter(blocks, measures, constraints) {
77238
77602
  if (!Number.isFinite(height) || height <= 0) {
77239
77603
  throw new Error("layoutHeaderFooter: height must be positive");
77240
77604
  }
77605
+ const maxBehindDocOverflow = Math.max(192, height * 4);
77606
+ const minBehindDocY = -maxBehindDocOverflow;
77607
+ const maxBehindDocY = height + maxBehindDocOverflow;
77241
77608
  const marginLeft = constraints.margins?.left ?? 0;
77242
77609
  const transformedBlocks = marginLeft > 0 ? blocks.map((block) => {
77243
77610
  const hasPageRelativeAnchor = (block.kind === "image" || block.kind === "drawing") && block.anchor?.hRelativeFrom === "page" && block.anchor.offsetH != null;
@@ -77268,6 +77635,18 @@ function layoutHeaderFooter(blocks, measures, constraints) {
77268
77635
  if (idx == null) continue;
77269
77636
  const block = blocks[idx];
77270
77637
  const measure = measures[idx];
77638
+ const isAnchoredFragment = (fragment.kind === "image" || fragment.kind === "drawing") && fragment.isAnchored === true;
77639
+ if (isAnchoredFragment) {
77640
+ if (block.kind !== "image" && block.kind !== "drawing") {
77641
+ throw new Error(
77642
+ `Type mismatch: fragment kind is ${fragment.kind} but block kind is ${block.kind} for block ${block.id}`
77643
+ );
77644
+ }
77645
+ const anchoredBlock = block;
77646
+ if (anchoredBlock.anchor?.behindDoc && (fragment.y < minBehindDocY || fragment.y > maxBehindDocY)) {
77647
+ continue;
77648
+ }
77649
+ }
77271
77650
  if (fragment.y < minY) minY = fragment.y;
77272
77651
  let bottom2 = fragment.y;
77273
77652
  if (fragment.kind === "para" && measure?.kind === "paragraph") {
@@ -78265,11 +78644,11 @@ function findWordBoundaries(blocks, pos) {
78265
78644
  if (text.length === 0) return null;
78266
78645
  const clampedPos = Math.max(0, Math.min(localPos, text.length));
78267
78646
  let wordStart = clampedPos;
78268
- while (wordStart > 0 && isWordChar(text[wordStart - 1])) {
78647
+ while (wordStart > 0 && isWordChar$2(text[wordStart - 1])) {
78269
78648
  wordStart--;
78270
78649
  }
78271
78650
  let wordEnd = clampedPos;
78272
- while (wordEnd < text.length && isWordChar(text[wordEnd])) {
78651
+ while (wordEnd < text.length && isWordChar$2(text[wordEnd])) {
78273
78652
  wordEnd++;
78274
78653
  }
78275
78654
  if (wordStart === wordEnd) {
@@ -78332,7 +78711,7 @@ function findBlockAtPosition(blocks, pos) {
78332
78711
  }
78333
78712
  return null;
78334
78713
  }
78335
- function isWordChar(char) {
78714
+ function isWordChar$2(char) {
78336
78715
  return /[\p{L}\p{N}_]/u.test(char);
78337
78716
  }
78338
78717
  function isWhitespace(char) {
@@ -78367,6 +78746,29 @@ function fontString(run2) {
78367
78746
  function runText(run2) {
78368
78747
  return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
78369
78748
  }
78749
+ const isWordChar$1 = (char) => {
78750
+ if (!char) return false;
78751
+ const code = char.charCodeAt(0);
78752
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
78753
+ };
78754
+ const capitalizeText$1 = (text, fullText, startOffset) => {
78755
+ if (!text) return text;
78756
+ const hasFullText = typeof startOffset === "number" && fullText != null;
78757
+ let result = "";
78758
+ for (let i = 0; i < text.length; i += 1) {
78759
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
78760
+ const ch = text[i];
78761
+ result += isWordChar$1(ch) && !isWordChar$1(prevChar) ? ch.toUpperCase() : ch;
78762
+ }
78763
+ return result;
78764
+ };
78765
+ const applyTextTransform$1 = (text, transform, fullText, startOffset) => {
78766
+ if (!text || !transform || transform === "none") return text;
78767
+ if (transform === "uppercase") return text.toUpperCase();
78768
+ if (transform === "lowercase") return text.toLowerCase();
78769
+ if (transform === "capitalize") return capitalizeText$1(text, fullText, startOffset);
78770
+ return text;
78771
+ };
78370
78772
  const DEFAULT_TAB_INTERVAL_TWIPS$1 = 720;
78371
78773
  const TWIPS_PER_INCH$4 = 1440;
78372
78774
  const PX_PER_INCH$3 = 96;
@@ -78375,6 +78777,13 @@ const TAB_EPSILON$1 = 0.1;
78375
78777
  const WIDTH_FUDGE_PX = 0.5;
78376
78778
  const twipsToPx$2 = (twips) => twips / TWIPS_PER_PX$1;
78377
78779
  const pxToTwips$1 = (px) => Math.round(px * TWIPS_PER_PX$1);
78780
+ const markerFontString = (run2) => {
78781
+ const size2 = run2?.fontSize ?? 16;
78782
+ const family = run2?.fontFamily ?? "Arial";
78783
+ const italic = run2?.italic ? "italic " : "";
78784
+ const bold = run2?.bold ? "bold " : "";
78785
+ return `${italic}${bold}${size2}px ${family}`.trim();
78786
+ };
78378
78787
  const buildTabStopsPx$1 = (indent, tabs, tabIntervalTwips) => {
78379
78788
  const paragraphIndentTwips = {
78380
78789
  left: pxToTwips$1(Math.max(0, indent?.left ?? 0)),
@@ -78405,7 +78814,8 @@ const getNextTabStopPx$1 = (currentX, tabStops, startIndex) => {
78405
78814
  };
78406
78815
  function measureRunSliceWidth(run2, fromChar, toChar) {
78407
78816
  const context = getCtx();
78408
- const text = runText(run2).slice(fromChar, toChar);
78817
+ const fullText = runText(run2);
78818
+ const text = applyTextTransform$1(fullText.slice(fromChar, toChar), run2.textTransform, fullText, fromChar);
78409
78819
  if (!context) {
78410
78820
  const textRun = isTextRun$2(run2) ? run2 : null;
78411
78821
  const size2 = textRun?.fontSize ?? 16;
@@ -78451,8 +78861,21 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
78451
78861
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
78452
78862
  const markerTextStartX = wordLayout?.marker?.textStartX;
78453
78863
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
78454
- const treatAsHanging = textStartPx && indentLeft === 0 && indentHanging === 0;
78455
- const firstLineWidth = typeof textStartPx === "number" && textStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - textStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
78864
+ const resolvedTextStartPx = resolveListTextStartPx(
78865
+ wordLayout,
78866
+ indentLeft,
78867
+ indentFirstLine,
78868
+ indentHanging,
78869
+ (markerText, marker) => {
78870
+ const context = getCtx();
78871
+ if (!context) return 0;
78872
+ context.font = markerFontString(marker.run);
78873
+ return context.measureText(markerText).width;
78874
+ }
78875
+ );
78876
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
78877
+ const treatAsHanging = !wordLayout?.marker && effectiveTextStartPx && indentLeft === 0 && indentHanging === 0;
78878
+ const firstLineWidth = typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - effectiveTextStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
78456
78879
  const tabStops = buildTabStopsPx$1(indent, attrs?.tabs, attrs?.tabIntervalTwips);
78457
78880
  let currentRun = 0;
78458
78881
  let currentChar = 0;
@@ -78992,7 +79415,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
78992
79415
  if (dirty.deletedBlockIds.length > 0) {
78993
79416
  measureCache.invalidate(dirty.deletedBlockIds);
78994
79417
  }
78995
- const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options);
79418
+ const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options, nextBlocks);
78996
79419
  if (measurementWidth <= 0 || measurementHeight <= 0) {
78997
79420
  throw new Error("incrementalLayout: invalid measurement constraints resolved from options");
78998
79421
  }
@@ -79261,7 +79684,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
79261
79684
  const DEFAULT_PAGE_SIZE$1 = { w: 612, h: 792 };
79262
79685
  const DEFAULT_MARGINS$1 = { top: 72, right: 72, bottom: 72, left: 72 };
79263
79686
  const normalizeMargin = (value, fallback) => Number.isFinite(value) ? value : fallback;
79264
- function resolveMeasurementConstraints(options) {
79687
+ function resolveMeasurementConstraints(options, blocks) {
79265
79688
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
79266
79689
  const margins = {
79267
79690
  top: normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top),
@@ -79269,23 +79692,41 @@ function resolveMeasurementConstraints(options) {
79269
79692
  bottom: normalizeMargin(options.margins?.bottom, DEFAULT_MARGINS$1.bottom),
79270
79693
  left: normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
79271
79694
  };
79272
- const contentWidth = pageSize.w - (margins.left + margins.right);
79273
- const contentHeight = pageSize.h - (margins.top + margins.bottom);
79274
- const columns = options.columns;
79275
- if (columns && columns.count > 1) {
79695
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
79696
+ const baseContentHeight = pageSize.h - (margins.top + margins.bottom);
79697
+ const computeColumnWidth = (contentWidth, columns) => {
79698
+ if (!columns || columns.count <= 1) return contentWidth;
79276
79699
  const gap = Math.max(0, columns.gap ?? 0);
79277
79700
  const totalGap = gap * (columns.count - 1);
79278
- const columnWidth = (contentWidth - totalGap) / columns.count;
79279
- if (columnWidth > 0) {
79280
- return {
79281
- measurementWidth: columnWidth,
79282
- measurementHeight: contentHeight
79701
+ return (contentWidth - totalGap) / columns.count;
79702
+ };
79703
+ let measurementWidth = computeColumnWidth(baseContentWidth, options.columns);
79704
+ let measurementHeight = baseContentHeight;
79705
+ if (blocks && blocks.length > 0) {
79706
+ for (const block of blocks) {
79707
+ if (block.kind !== "sectionBreak") continue;
79708
+ const sectionPageSize = block.pageSize ?? pageSize;
79709
+ const sectionMargins = {
79710
+ top: normalizeMargin(block.margins?.top, margins.top),
79711
+ right: normalizeMargin(block.margins?.right, margins.right),
79712
+ bottom: normalizeMargin(block.margins?.bottom, margins.bottom),
79713
+ left: normalizeMargin(block.margins?.left, margins.left)
79283
79714
  };
79715
+ const contentWidth = sectionPageSize.w - (sectionMargins.left + sectionMargins.right);
79716
+ const contentHeight = sectionPageSize.h - (sectionMargins.top + sectionMargins.bottom);
79717
+ if (contentWidth <= 0 || contentHeight <= 0) continue;
79718
+ const columnWidth = computeColumnWidth(contentWidth, block.columns ?? options.columns);
79719
+ if (columnWidth > measurementWidth) {
79720
+ measurementWidth = columnWidth;
79721
+ }
79722
+ if (contentHeight > measurementHeight) {
79723
+ measurementHeight = contentHeight;
79724
+ }
79284
79725
  }
79285
79726
  }
79286
79727
  return {
79287
- measurementWidth: contentWidth,
79288
- measurementHeight: contentHeight
79728
+ measurementWidth,
79729
+ measurementHeight
79289
79730
  };
79290
79731
  }
79291
79732
  const serializeHeaderFooterResults = (kind, batch) => {
@@ -81352,6 +81793,7 @@ function isInRegisteredSurface(event) {
81352
81793
  }
81353
81794
  return false;
81354
81795
  }
81796
+ const SLASH_MENU_HANDLED_FLAG = "__sdHandledBySlashMenu";
81355
81797
  class PresentationInputBridge {
81356
81798
  /**
81357
81799
  * Creates a new PresentationInputBridge that forwards user input events from the visible layout
@@ -81565,6 +82007,10 @@ forwardCompositionEvent_fn = function(event) {
81565
82007
  __privateMethod$1(this, _PresentationInputBridge_instances, dispatchToTarget_fn).call(this, event, synthetic);
81566
82008
  };
81567
82009
  forwardContextMenu_fn = function(event) {
82010
+ const handledBySlashMenu = Boolean(event[SLASH_MENU_HANDLED_FLAG]);
82011
+ if (handledBySlashMenu) {
82012
+ return;
82013
+ }
81568
82014
  if (!__privateGet$1(this, _isEditable).call(this)) {
81569
82015
  return;
81570
82016
  }
@@ -84160,11 +84606,27 @@ const collectTrackedChangeFromMarks = (marks) => {
84160
84606
  }, void 0);
84161
84607
  };
84162
84608
  const normalizeUnderlineStyle = (value) => {
84163
- if (value === "none") {
84164
- return void 0;
84609
+ if (value === void 0 || value === null) {
84610
+ return "single";
84165
84611
  }
84166
- if (value === "double" || value === "dotted" || value === "dashed" || value === "wavy") {
84167
- return value;
84612
+ if (typeof value === "boolean") {
84613
+ return value ? "single" : void 0;
84614
+ }
84615
+ if (typeof value === "number") {
84616
+ return value === 0 ? void 0 : "single";
84617
+ }
84618
+ if (typeof value === "string") {
84619
+ const normalized = value.trim().toLowerCase();
84620
+ if (!normalized) {
84621
+ return "single";
84622
+ }
84623
+ if (normalized === "none" || normalized === "0" || normalized === "false" || normalized === "off") {
84624
+ return void 0;
84625
+ }
84626
+ if (normalized === "double" || normalized === "dotted" || normalized === "dashed" || normalized === "wavy") {
84627
+ return normalized;
84628
+ }
84629
+ return "single";
84168
84630
  }
84169
84631
  return "single";
84170
84632
  };
@@ -84316,13 +84778,16 @@ const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG
84316
84778
  break;
84317
84779
  }
84318
84780
  case "underline": {
84319
- const style2 = normalizeUnderlineStyle(mark.attrs?.underlineType);
84781
+ const underlineValue = mark.attrs?.underlineType ?? mark.attrs?.value ?? mark.attrs?.underline ?? mark.attrs?.style;
84782
+ const style2 = normalizeUnderlineStyle(underlineValue);
84320
84783
  if (style2) {
84321
84784
  const underlineColor = resolveColorFromAttributes(mark.attrs ?? {}, themeColors);
84322
84785
  run2.underline = {
84323
84786
  style: style2,
84324
84787
  color: underlineColor ?? run2.underline?.color
84325
84788
  };
84789
+ } else if (underlineValue !== void 0 && underlineValue !== null) {
84790
+ delete run2.underline;
84326
84791
  }
84327
84792
  break;
84328
84793
  }
@@ -85258,8 +85723,8 @@ function buildSdtCacheKey(nodeType, attrs, explicitKey) {
85258
85723
  }
85259
85724
  return void 0;
85260
85725
  }
85261
- const DEFAULT_LIST_HANGING_PX$1 = 18;
85262
- const LIST_MARKER_GAP$1 = 8;
85726
+ const DEFAULT_LIST_HANGING_PX = 18;
85727
+ const LIST_MARKER_GAP = 8;
85263
85728
  const DEFAULT_BULLET_GLYPH = "•";
85264
85729
  const DEFAULT_DECIMAL_PATTERN = "%1.";
85265
85730
  const ASCII_UPPERCASE_A = 65;
@@ -85670,7 +86135,7 @@ function computeWordParagraphLayout(input) {
85670
86135
  let markerBoxWidthPx;
85671
86136
  let markerX;
85672
86137
  if (hasFirstLineIndent) {
85673
- markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP$1 : DEFAULT_LIST_HANGING_PX$1;
86138
+ markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP : DEFAULT_LIST_HANGING_PX;
85674
86139
  markerX = indentLeftPx + (firstLinePx ?? 0);
85675
86140
  layout.textStartPx = markerX + markerBoxWidthPx;
85676
86141
  layout.hangingPx = 0;
@@ -85770,12 +86235,12 @@ const resolveMarkerBoxWidth = (hangingPxRaw, glyphWidthPx) => {
85770
86235
  let markerBox = Math.max(hangingPxRaw || 0, 0);
85771
86236
  if (markerBox <= 0) {
85772
86237
  if (glyphWidthPx != null && glyphWidthPx > 0) {
85773
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
86238
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
85774
86239
  } else {
85775
- markerBox = DEFAULT_LIST_HANGING_PX$1;
86240
+ markerBox = DEFAULT_LIST_HANGING_PX;
85776
86241
  }
85777
- } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP$1 > markerBox) {
85778
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
86242
+ } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP > markerBox) {
86243
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
85779
86244
  }
85780
86245
  return markerBox;
85781
86246
  };
@@ -85795,7 +86260,7 @@ const buildMarkerLayout = ({
85795
86260
  textStartX: textStartPx,
85796
86261
  baselineOffsetPx: markerRun.baselineShift ?? 0,
85797
86262
  // Gutter is the small gap between marker and text, not the full marker box width
85798
- gutterWidthPx: LIST_MARKER_GAP$1,
86263
+ gutterWidthPx: LIST_MARKER_GAP,
85799
86264
  justification: numbering.lvlJc ?? "left",
85800
86265
  suffix: normalizeSuffix$1(numbering.suffix) ?? "tab",
85801
86266
  run: markerRun,
@@ -86487,6 +86952,31 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
86487
86952
  return null;
86488
86953
  }
86489
86954
  };
86955
+ const normalizeWordLayoutForIndent = (wordLayout, paragraphIndent) => {
86956
+ const resolvedIndent = wordLayout.resolvedIndent ?? paragraphIndent ?? {};
86957
+ const indentLeft = isFiniteNumber(resolvedIndent.left) ? resolvedIndent.left : 0;
86958
+ const firstLine = isFiniteNumber(resolvedIndent.firstLine) ? resolvedIndent.firstLine : 0;
86959
+ const hanging = isFiniteNumber(resolvedIndent.hanging) ? resolvedIndent.hanging : 0;
86960
+ const shouldFirstLineIndentMode = firstLine > 0 && !hanging;
86961
+ if (wordLayout.firstLineIndentMode === true && !shouldFirstLineIndentMode) {
86962
+ wordLayout.firstLineIndentMode = false;
86963
+ }
86964
+ if (wordLayout.firstLineIndentMode === true) {
86965
+ if (isFiniteNumber(wordLayout.textStartPx)) {
86966
+ if (wordLayout.marker && (!isFiniteNumber(wordLayout.marker.textStartX) || wordLayout.marker.textStartX !== wordLayout.textStartPx)) {
86967
+ wordLayout.marker.textStartX = wordLayout.textStartPx;
86968
+ }
86969
+ } else if (wordLayout.marker && isFiniteNumber(wordLayout.marker.textStartX)) {
86970
+ wordLayout.textStartPx = wordLayout.marker.textStartX;
86971
+ }
86972
+ } else {
86973
+ wordLayout.textStartPx = indentLeft;
86974
+ if (wordLayout.marker) {
86975
+ wordLayout.marker.textStartX = indentLeft;
86976
+ }
86977
+ }
86978
+ return wordLayout;
86979
+ };
86490
86980
  const computeParagraphAttrs = (para, styleContext, listCounterContext, converterContext, hydrationOverride) => {
86491
86981
  const attrs = para.attrs ?? {};
86492
86982
  const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
@@ -86809,8 +87299,11 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86809
87299
  let wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
86810
87300
  if (!wordLayout && enrichedNumberingProps.resolvedLevelIndent) {
86811
87301
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
86812
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
86813
- if (firstLinePx > 0) {
87302
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
87303
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
87304
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
87305
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
87306
+ if (firstLinePx > 0 && !hangingPx) {
86814
87307
  wordLayout = {
86815
87308
  // Treat as first-line-indent mode: text starts after the marker+firstLine offset.
86816
87309
  firstLineIndentMode: true,
@@ -86818,10 +87311,13 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86818
87311
  };
86819
87312
  }
86820
87313
  }
86821
- if (wordLayout && (!wordLayout.textStartPx || !Number.isFinite(wordLayout.textStartPx)) && enrichedNumberingProps.resolvedLevelIndent) {
87314
+ if (wordLayout && !Number.isFinite(wordLayout.textStartPx) && enrichedNumberingProps.resolvedLevelIndent) {
86822
87315
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
86823
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
86824
- if (firstLinePx > 0) {
87316
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
87317
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
87318
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
87319
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
87320
+ if (firstLinePx > 0 && !hangingPx) {
86825
87321
  wordLayout = {
86826
87322
  ...wordLayout,
86827
87323
  firstLineIndentMode: wordLayout.firstLineIndentMode ?? true,
@@ -86841,6 +87337,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86841
87337
  wordLayout.marker.suffix = listRendering.suffix;
86842
87338
  }
86843
87339
  }
87340
+ wordLayout = normalizeWordLayoutForIndent(wordLayout, paragraphAttrs.indent);
86844
87341
  paragraphAttrs.wordLayout = wordLayout;
86845
87342
  }
86846
87343
  if (enrichedNumberingProps.resolvedLevelIndent) {
@@ -90957,11 +91454,6 @@ function initHeaderFooterRegistry({
90957
91454
  cleanups
90958
91455
  };
90959
91456
  }
90960
- const LIST_MARKER_GAP = 8;
90961
- const MIN_MARKER_GUTTER = 24;
90962
- const DEFAULT_LIST_INDENT_BASE_PX = 24;
90963
- const DEFAULT_LIST_INDENT_STEP_PX = 24;
90964
- const DEFAULT_LIST_HANGING_PX = 18;
90965
91457
  function calculateRotatedBounds(input) {
90966
91458
  const width = Math.max(0, input.width);
90967
91459
  const height = Math.max(0, input.height);
@@ -91225,8 +91717,25 @@ async function measureParagraphBlock(block, maxWidth) {
91225
91717
  const rawTextStartPx = wordLayout?.textStartPx;
91226
91718
  const markerTextStartX = wordLayout?.marker?.textStartX;
91227
91719
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof rawTextStartPx === "number" && Number.isFinite(rawTextStartPx) ? rawTextStartPx : void 0;
91228
- if (typeof textStartPx === "number" && textStartPx > indentLeft) {
91229
- initialAvailableWidth = Math.max(1, maxWidth - textStartPx - indentRight);
91720
+ const resolvedTextStartPx = resolveListTextStartPx(
91721
+ wordLayout,
91722
+ indentLeft,
91723
+ firstLine,
91724
+ hanging,
91725
+ (markerText, marker) => {
91726
+ const markerRun = {
91727
+ fontFamily: toCssFontFamily(marker.run?.fontFamily) ?? marker.run?.fontFamily ?? "Arial",
91728
+ fontSize: marker.run?.fontSize ?? 16,
91729
+ bold: marker.run?.bold ?? false,
91730
+ italic: marker.run?.italic ?? false
91731
+ };
91732
+ const { font: markerFont } = buildFontString(markerRun);
91733
+ return measureText(markerText, markerFont, ctx2);
91734
+ }
91735
+ );
91736
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
91737
+ if (typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft) {
91738
+ initialAvailableWidth = Math.max(1, maxWidth - effectiveTextStartPx - indentRight);
91230
91739
  } else {
91231
91740
  initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset);
91232
91741
  }
@@ -91313,7 +91822,7 @@ async function measureParagraphBlock(block, maxWidth) {
91313
91822
  pendingTabAlignment = null;
91314
91823
  return startX;
91315
91824
  };
91316
- const alignSegmentAtTab = (segmentText, font, runContext) => {
91825
+ const alignSegmentAtTab = (segmentText, font, runContext, segmentStartChar) => {
91317
91826
  if (!pendingTabAlignment || !currentLine) return void 0;
91318
91827
  const { val } = pendingTabAlignment;
91319
91828
  let segmentWidth = 0;
@@ -91322,11 +91831,11 @@ async function measureParagraphBlock(block, maxWidth) {
91322
91831
  const idx = segmentText.indexOf(decimalSeparator);
91323
91832
  if (idx >= 0) {
91324
91833
  const beforeText = segmentText.slice(0, idx);
91325
- beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext) : 0;
91834
+ beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext, segmentStartChar) : 0;
91326
91835
  }
91327
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
91836
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
91328
91837
  } else if (val === "end" || val === "center") {
91329
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
91838
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
91330
91839
  }
91331
91840
  return alignPendingTabForWidth(segmentWidth, beforeDecimalWidth);
91332
91841
  };
@@ -91378,8 +91887,8 @@ async function measureParagraphBlock(block, maxWidth) {
91378
91887
  const { font } = buildFontString(
91379
91888
  lastRun
91380
91889
  );
91381
- const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun);
91382
- const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun) : 0;
91890
+ const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun, sliceStart);
91891
+ const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun, sliceStart) : 0;
91383
91892
  const delta = Math.max(0, fullWidth - keptWidth);
91384
91893
  lineToTrim.width = roundValue(Math.max(0, lineToTrim.width - delta));
91385
91894
  lineToTrim.spaceCount = Math.max(0, lineToTrim.spaceCount - trimCount);
@@ -91590,7 +92099,8 @@ async function measureParagraphBlock(block, maxWidth) {
91590
92099
  continue;
91591
92100
  }
91592
92101
  if (isFieldAnnotationRun(run2)) {
91593
- const displayText = run2.displayLabel || "";
92102
+ const rawDisplayText = run2.displayLabel || "";
92103
+ const displayText = applyTextTransform(rawDisplayText, run2);
91594
92104
  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;
91595
92105
  const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
91596
92106
  const fontWeight = run2.bold ? "bold" : "normal";
@@ -91693,7 +92203,7 @@ async function measureParagraphBlock(block, maxWidth) {
91693
92203
  const spacesLength = segment.length;
91694
92204
  const spacesStartChar = charPosInRun;
91695
92205
  const spacesEndChar = charPosInRun + spacesLength;
91696
- const spacesWidth = measureRunWidth(segment, font, ctx2, run2);
92206
+ const spacesWidth = measureRunWidth(segment, font, ctx2, run2, spacesStartChar);
91697
92207
  if (!currentLine) {
91698
92208
  currentLine = {
91699
92209
  fromRun: runIndex,
@@ -91757,7 +92267,7 @@ async function measureParagraphBlock(block, maxWidth) {
91757
92267
  }
91758
92268
  let segmentStartX;
91759
92269
  if (currentLine && pendingTabAlignment) {
91760
- segmentStartX = alignSegmentAtTab(segment, font, run2);
92270
+ segmentStartX = alignSegmentAtTab(segment, font, run2, charPosInRun);
91761
92271
  if (segmentStartX == null) {
91762
92272
  segmentStartX = currentLine.width;
91763
92273
  }
@@ -91767,7 +92277,7 @@ async function measureParagraphBlock(block, maxWidth) {
91767
92277
  if (word2 === "") {
91768
92278
  const spaceStartChar = charPosInRun;
91769
92279
  const spaceEndChar = charPosInRun + 1;
91770
- const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2);
92280
+ const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2, spaceStartChar);
91771
92281
  if (!currentLine) {
91772
92282
  currentLine = {
91773
92283
  fromRun: runIndex,
@@ -91818,12 +92328,12 @@ async function measureParagraphBlock(block, maxWidth) {
91818
92328
  charPosInRun = spaceEndChar;
91819
92329
  continue;
91820
92330
  }
91821
- const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run2);
91822
- const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
91823
- const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run2) : 0;
91824
- const wordCommitWidth = wordOnlyWidth + spaceWidth;
91825
92331
  const wordStartChar = charPosInRun;
92332
+ const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run2, wordStartChar);
92333
+ const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
91826
92334
  const wordEndNoSpace = charPosInRun + word2.length;
92335
+ const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run2, wordEndNoSpace) : 0;
92336
+ const wordCommitWidth = wordOnlyWidth + spaceWidth;
91827
92337
  const wordEndWithSpace = wordEndNoSpace + (shouldIncludeDelimiterSpace ? 1 : 0);
91828
92338
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
91829
92339
  if (wordOnlyWidth > effectiveMaxWidth && word2.length > 1) {
@@ -91842,7 +92352,7 @@ async function measureParagraphBlock(block, maxWidth) {
91842
92352
  const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
91843
92353
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
91844
92354
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
91845
- const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
92355
+ const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2, wordStartChar);
91846
92356
  let chunkCharOffset = wordStartChar;
91847
92357
  for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
91848
92358
  const chunk = chunks[chunkIndex];
@@ -91966,7 +92476,7 @@ async function measureParagraphBlock(block, maxWidth) {
91966
92476
  if (candidateSpaces > 0) {
91967
92477
  const overflow = totalWidthWithWord - availableWidth;
91968
92478
  if (overflow > 0) {
91969
- const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2) || Math.max(1, boundarySpacing);
92479
+ const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2, wordEndNoSpace) || Math.max(1, boundarySpacing);
91970
92480
  const perSpaceCompression = overflow / candidateSpaces;
91971
92481
  const maxPerSpaceCompression = baseSpaceWidth * 0.25;
91972
92482
  if (perSpaceCompression <= maxPerSpaceCompression) {
@@ -92141,8 +92651,8 @@ async function measureParagraphBlock(block, maxWidth) {
92141
92651
  const { font: markerFont } = buildFontString(markerRun);
92142
92652
  const markerText = wordLayout.marker.markerText ?? "";
92143
92653
  const glyphWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
92144
- const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP;
92145
- const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP);
92654
+ const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP$1;
92655
+ const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP$1);
92146
92656
  markerInfo = {
92147
92657
  markerWidth: markerBoxWidth,
92148
92658
  markerTextWidth: glyphWidth,
@@ -92486,7 +92996,7 @@ async function measureListBlock(block, constraints) {
92486
92996
  markerTextWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
92487
92997
  indentLeft = resolveIndentLeft(item);
92488
92998
  const indentHanging = resolveIndentHanging(item);
92489
- markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP, indentHanging);
92999
+ markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP$1, indentHanging);
92490
93000
  }
92491
93001
  const paragraphWidth = Math.max(1, constraints.maxWidth - indentLeft - markerWidth);
92492
93002
  const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth);
@@ -92512,16 +93022,46 @@ const getPrimaryRun = (paragraph) => {
92512
93022
  fontSize: 16
92513
93023
  };
92514
93024
  };
92515
- const measureRunWidth = (text, font, ctx2, run2) => {
93025
+ const isWordChar = (char) => {
93026
+ if (!char) return false;
93027
+ const code = char.charCodeAt(0);
93028
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
93029
+ };
93030
+ const capitalizeText = (text, fullText, startOffset) => {
93031
+ if (!text) return text;
93032
+ const hasFullText = typeof startOffset === "number" && fullText != null;
93033
+ let result = "";
93034
+ for (let i = 0; i < text.length; i += 1) {
93035
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
93036
+ const ch = text[i];
93037
+ result += isWordChar(ch) && !isWordChar(prevChar) ? ch.toUpperCase() : ch;
93038
+ }
93039
+ return result;
93040
+ };
93041
+ const applyTextTransform = (text, run2, startOffset) => {
93042
+ const transform = run2.textTransform;
93043
+ if (!text || !transform || transform === "none") return text;
93044
+ if (transform === "uppercase") return text.toUpperCase();
93045
+ if (transform === "lowercase") return text.toLowerCase();
93046
+ if (transform === "capitalize") {
93047
+ const fullText = "text" in run2 && typeof run2.text === "string" ? run2.text : text;
93048
+ return capitalizeText(text, fullText, startOffset);
93049
+ }
93050
+ return text;
93051
+ };
93052
+ const measureRunWidth = (text, font, ctx2, run2, startOffset) => {
92516
93053
  const letterSpacing = run2.kind === "text" || run2.kind === void 0 ? run2.letterSpacing || 0 : 0;
92517
- const width = getMeasuredTextWidth(text, font, letterSpacing, ctx2);
93054
+ const displayText = applyTextTransform(text, run2, startOffset);
93055
+ const width = getMeasuredTextWidth(displayText, font, letterSpacing, ctx2);
92518
93056
  return roundValue(width);
92519
93057
  };
92520
- const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2) => {
93058
+ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2, startOffset) => {
92521
93059
  const chunks = [];
93060
+ const baseOffset = typeof startOffset === "number" ? startOffset : 0;
92522
93061
  if (maxWidth <= 0) {
92523
- for (const char of word2) {
92524
- const charWidth = measureRunWidth(char, font, ctx2, run2);
93062
+ for (let i = 0; i < word2.length; i++) {
93063
+ const char = word2[i];
93064
+ const charWidth = measureRunWidth(char, font, ctx2, run2, baseOffset + i);
92525
93065
  chunks.push({ text: char, width: charWidth });
92526
93066
  }
92527
93067
  return chunks;
@@ -92531,11 +93071,11 @@ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2) => {
92531
93071
  for (let i = 0; i < word2.length; i++) {
92532
93072
  const char = word2[i];
92533
93073
  const testChunk = currentChunk + char;
92534
- const testWidth = measureRunWidth(testChunk, font, ctx2, run2);
93074
+ const testWidth = measureRunWidth(testChunk, font, ctx2, run2, baseOffset);
92535
93075
  if (testWidth > maxWidth && currentChunk.length > 0) {
92536
93076
  chunks.push({ text: currentChunk, width: currentWidth });
92537
93077
  currentChunk = char;
92538
- currentWidth = measureRunWidth(char, font, ctx2, run2);
93078
+ currentWidth = measureRunWidth(char, font, ctx2, run2, baseOffset + i);
92539
93079
  } else {
92540
93080
  currentChunk = testChunk;
92541
93081
  currentWidth = testWidth;
@@ -92589,7 +93129,8 @@ const measureDropCap = (ctx2, descriptor, spacing) => {
92589
93129
  italic: run2.italic
92590
93130
  });
92591
93131
  ctx2.font = font;
92592
- const metrics = ctx2.measureText(run2.text);
93132
+ const displayText = applyTextTransform(run2.text, run2);
93133
+ const metrics = ctx2.measureText(displayText);
92593
93134
  const advanceWidth = metrics.width;
92594
93135
  const paintedWidth = (metrics.actualBoundingBoxLeft || 0) + (metrics.actualBoundingBoxRight || 0);
92595
93136
  const textWidth = Math.max(advanceWidth, paintedWidth);
@@ -92615,7 +93156,7 @@ const resolveIndentHanging = (item) => {
92615
93156
  if (indentHanging > 0) {
92616
93157
  return indentHanging;
92617
93158
  }
92618
- return DEFAULT_LIST_HANGING_PX;
93159
+ return DEFAULT_LIST_HANGING_PX$1;
92619
93160
  };
92620
93161
  const buildTabStopsPx = (indent, tabs, tabIntervalTwips) => {
92621
93162
  const paragraphIndentTwips = {
@@ -92821,6 +93362,9 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
92821
93362
  if (event.button !== 0) {
92822
93363
  return;
92823
93364
  }
93365
+ if (event.ctrlKey && navigator.platform.includes("Mac")) {
93366
+ return;
93367
+ }
92824
93368
  __privateSet(this, _pendingMarginClick, null);
92825
93369
  const target = event.target;
92826
93370
  if (target?.closest?.(".superdoc-ruler-handle") != null) {
@@ -98230,6 +98774,8 @@ const SlashMenu = Extension.create({
98230
98774
  const cbRect = containingBlock.getBoundingClientRect();
98231
98775
  left2 -= cbRect.left;
98232
98776
  top2 -= cbRect.top;
98777
+ left2 += containingBlock.scrollLeft || 0;
98778
+ top2 += containingBlock.scrollTop || 0;
98233
98779
  } catch (error) {
98234
98780
  console.warn("SlashMenu: Failed to adjust for containing block", error);
98235
98781
  }
@@ -129568,7 +130114,7 @@ const _sfc_main$8 = {
129568
130114
  if (open) {
129569
130115
  nextTick(() => {
129570
130116
  if (searchInput.value) {
129571
- searchInput.value.focus();
130117
+ searchInput.value.focus({ preventScroll: true });
129572
130118
  }
129573
130119
  });
129574
130120
  }
@@ -129673,15 +130219,31 @@ const _sfc_main$8 = {
129673
130219
  };
129674
130220
  const handleGlobalOutsideClick = (event) => {
129675
130221
  if (isOpen.value && menuRef.value && !menuRef.value.contains(event.target)) {
129676
- moveCursorToMouseEvent(event, props.editor);
130222
+ const isCtrlClickOnMac = event.ctrlKey && isMacOS();
130223
+ const isLeftClick = event.button === 0 && !isCtrlClickOnMac;
130224
+ if (isLeftClick) {
130225
+ moveCursorToMouseEvent(event, props.editor);
130226
+ }
129677
130227
  closeMenu({ restoreCursor: false });
129678
130228
  }
129679
130229
  };
129680
- const handleRightClick = async (event) => {
130230
+ const shouldHandleContextMenu = (event) => {
129681
130231
  const readOnly = !props.editor?.isEditable;
129682
130232
  const contextMenuDisabled = props.editor?.options?.disableContextMenu;
129683
130233
  const bypass = shouldBypassContextMenu(event);
129684
- if (readOnly || contextMenuDisabled || bypass) {
130234
+ return !readOnly && !contextMenuDisabled && !bypass;
130235
+ };
130236
+ const handleRightClickCapture = (event) => {
130237
+ try {
130238
+ if (shouldHandleContextMenu(event)) {
130239
+ event[SLASH_MENU_HANDLED_FLAG] = true;
130240
+ }
130241
+ } catch (error) {
130242
+ console.warn("[SlashMenu] Error in capture phase context menu handler:", error);
130243
+ }
130244
+ };
130245
+ const handleRightClick = async (event) => {
130246
+ if (!shouldHandleContextMenu(event)) {
129685
130247
  return;
129686
130248
  }
129687
130249
  event.preventDefault();
@@ -129792,6 +130354,7 @@ const _sfc_main$8 = {
129792
130354
  props.editor.on("slashMenu:open", slashMenuOpenHandler);
129793
130355
  contextMenuTarget = getEditorSurfaceElement(props.editor);
129794
130356
  if (contextMenuTarget) {
130357
+ contextMenuTarget.addEventListener("contextmenu", handleRightClickCapture, true);
129795
130358
  contextMenuTarget.addEventListener("contextmenu", handleRightClick);
129796
130359
  }
129797
130360
  slashMenuCloseHandler = () => {
@@ -129815,6 +130378,7 @@ const _sfc_main$8 = {
129815
130378
  props.editor.off("slashMenu:close", slashMenuCloseHandler);
129816
130379
  }
129817
130380
  props.editor.off("update", handleEditorUpdate);
130381
+ contextMenuTarget?.removeEventListener("contextmenu", handleRightClickCapture, true);
129818
130382
  contextMenuTarget?.removeEventListener("contextmenu", handleRightClick);
129819
130383
  } catch (error) {
129820
130384
  console.warn("[SlashMenu] Error during cleanup:", error);
@@ -131781,6 +132345,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
131781
132345
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
131782
132346
  });
131783
132347
  const handleMarginClick = (event) => {
132348
+ if (event.button !== 0) {
132349
+ return;
132350
+ }
132351
+ if (event.ctrlKey && isMacOS()) {
132352
+ return;
132353
+ }
131784
132354
  if (event.target.classList.contains("ProseMirror")) return;
131785
132355
  onMarginClickCursorChange(event, activeEditor.value);
131786
132356
  };
@@ -131919,7 +132489,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
131919
132489
  };
131920
132490
  }
131921
132491
  });
131922
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-209a1e8b"]]);
132492
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-c9a3c876"]]);
131923
132493
  const _hoisted_1 = ["innerHTML"];
131924
132494
  const _sfc_main = {
131925
132495
  __name: "SuperInput",