@harbour-enterprises/superdoc 1.0.0-beta.96 → 1.0.0-beta.98

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 (27) hide show
  1. package/dist/chunks/{PdfViewer-Cdp1WJ9e.es.js → PdfViewer-1_KffD-j.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-BGTfnD4T.cjs → PdfViewer-D1Ot32kX.cjs} +1 -1
  3. package/dist/chunks/{index-BV9YtiyI.es.js → index-CP2_WwLA.es.js} +3 -3
  4. package/dist/chunks/{index-C-IS20yQ.cjs → index-CUO7gEi8.cjs} +3 -3
  5. package/dist/chunks/{index-lfdM_gm7-_EQjLyqH.es.js → index-Dg_sTYZK-D20z8mus.es.js} +1 -1
  6. package/dist/chunks/{index-lfdM_gm7-qtx-V4oF.cjs → index-Dg_sTYZK-DYDzxoXL.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-De2XS3A1.es.js → super-editor.es-3dJOUw65.es.js} +281 -201
  8. package/dist/chunks/{super-editor.es-D2zn943K.cjs → super-editor.es-DN_dgBH0.cjs} +281 -201
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-B29ATZFC.js → converter-Oj-eTB79.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-BPktKUBx.js → docx-zipper-Dl188zQ3.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-BRHMYtPA.js → editor-DBXoaaWP.js} +282 -202
  13. package/dist/super-editor/chunks/{index-lfdM_gm7.js → index-Dg_sTYZK.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-CB2cJCLh.js → toolbar-PlGGj0Ew.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/super-editor.es.js +6 -6
  20. package/dist/super-editor/toolbar.es.js +2 -2
  21. package/dist/super-editor.cjs +1 -1
  22. package/dist/super-editor.es.js +1 -1
  23. package/dist/superdoc.cjs +2 -2
  24. package/dist/superdoc.es.js +2 -2
  25. package/dist/superdoc.umd.js +283 -203
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -42404,7 +42404,7 @@ const _SuperConverter = class _SuperConverter2 {
42404
42404
  static getStoredSuperdocVersion(docx) {
42405
42405
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42406
42406
  }
42407
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.96") {
42407
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.98") {
42408
42408
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42409
42409
  }
42410
42410
  /**
@@ -59622,7 +59622,7 @@ const isHeadless = (editor) => {
59622
59622
  const shouldSkipNodeView = (editor) => {
59623
59623
  return isHeadless(editor);
59624
59624
  };
59625
- const summaryVersion = "1.0.0-beta.96";
59625
+ const summaryVersion = "1.0.0-beta.98";
59626
59626
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59627
59627
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59628
59628
  function mapAttributes(attrs) {
@@ -60411,7 +60411,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60411
60411
  { default: remarkStringify },
60412
60412
  { default: remarkGfm }
60413
60413
  ] = await Promise.all([
60414
- import("./index-lfdM_gm7-_EQjLyqH.es.js"),
60414
+ import("./index-Dg_sTYZK-D20z8mus.es.js"),
60415
60415
  import("./index-DRCvimau-Cw339678.es.js"),
60416
60416
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
60417
60417
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -60616,7 +60616,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60616
60616
  * Process collaboration migrations
60617
60617
  */
60618
60618
  processCollaborationMigrations() {
60619
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.96");
60619
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.98");
60620
60620
  if (!this.options.ydoc) return;
60621
60621
  const metaMap = this.options.ydoc.getMap("meta");
60622
60622
  let docVersion = metaMap.get("version");
@@ -62940,12 +62940,12 @@ var SectionType = /* @__PURE__ */ ((SectionType2) => {
62940
62940
  })(SectionType || {});
62941
62941
  const DEFAULT_PARAGRAPH_SECTION_TYPE = "nextPage";
62942
62942
  const DEFAULT_BODY_SECTION_TYPE = "continuous";
62943
- const TWIPS_PER_INCH$3 = 1440;
62944
- const PX_PER_INCH$2 = 96;
62943
+ const TWIPS_PER_INCH$4 = 1440;
62944
+ const PX_PER_INCH$3 = 96;
62945
62945
  const DEFAULT_COLUMN_GAP_INCHES = 0.5;
62946
62946
  function twipsToPixels$1(twips) {
62947
62947
  const n = Number(twips);
62948
- return Number.isFinite(n) ? n / TWIPS_PER_INCH$3 * PX_PER_INCH$2 : void 0;
62948
+ return Number.isFinite(n) ? n / TWIPS_PER_INCH$4 * PX_PER_INCH$3 : void 0;
62949
62949
  }
62950
62950
  function parseColumnCount(rawValue) {
62951
62951
  if (rawValue == null) return 1;
@@ -62955,7 +62955,7 @@ function parseColumnCount(rawValue) {
62955
62955
  function parseColumnGap(gapTwips) {
62956
62956
  if (gapTwips == null) return DEFAULT_COLUMN_GAP_INCHES;
62957
62957
  const gap = Number(gapTwips);
62958
- return Number.isFinite(gap) ? gap / TWIPS_PER_INCH$3 : DEFAULT_COLUMN_GAP_INCHES;
62958
+ return Number.isFinite(gap) ? gap / TWIPS_PER_INCH$4 : DEFAULT_COLUMN_GAP_INCHES;
62959
62959
  }
62960
62960
  function extractNormalizedMargins(attrs) {
62961
62961
  const sectionMargins = attrs.sectionMargins;
@@ -62994,14 +62994,15 @@ function extractPageSizeAndOrientation(elements) {
62994
62994
  return { pageSizePx, orientation };
62995
62995
  }
62996
62996
  function extractFallbackMargins(elements, currentHeader, currentFooter) {
62997
- if (currentHeader !== void 0 && currentFooter !== void 0) {
62998
- return { headerPx: currentHeader, footerPx: currentFooter };
62999
- }
63000
62997
  const pgMar = elements.find((el) => el?.name === "w:pgMar");
63001
62998
  const a = pgMar?.attributes || {};
63002
62999
  return {
63003
63000
  headerPx: currentHeader ?? (a["w:header"] != null ? twipsToPixels$1(a["w:header"]) : void 0),
63004
- footerPx: currentFooter ?? (a["w:footer"] != null ? twipsToPixels$1(a["w:footer"]) : void 0)
63001
+ footerPx: currentFooter ?? (a["w:footer"] != null ? twipsToPixels$1(a["w:footer"]) : void 0),
63002
+ topPx: a["w:top"] != null ? twipsToPixels$1(a["w:top"]) : void 0,
63003
+ rightPx: a["w:right"] != null ? twipsToPixels$1(a["w:right"]) : void 0,
63004
+ bottomPx: a["w:bottom"] != null ? twipsToPixels$1(a["w:bottom"]) : void 0,
63005
+ leftPx: a["w:left"] != null ? twipsToPixels$1(a["w:left"]) : void 0
63005
63006
  };
63006
63007
  }
63007
63008
  function extractHeaderFooterRefs(elements, refName) {
@@ -63039,7 +63040,7 @@ function extractColumns(elements) {
63039
63040
  const gapInches = parseColumnGap(cols.attributes["w:space"]);
63040
63041
  return {
63041
63042
  count,
63042
- gap: gapInches * PX_PER_INCH$2
63043
+ gap: gapInches * PX_PER_INCH$3
63043
63044
  };
63044
63045
  }
63045
63046
  function extractVerticalAlign(elements) {
@@ -63062,7 +63063,10 @@ function extractSectionData(para) {
63062
63063
  const type2 = extractSectionType(sectPrElements);
63063
63064
  const { pageSizePx, orientation } = extractPageSizeAndOrientation(sectPrElements);
63064
63065
  const titlePg = sectPrElements.some((el) => el?.name === "w:titlePg");
63065
- ({ headerPx, footerPx } = extractFallbackMargins(sectPrElements, headerPx, footerPx));
63066
+ const fallbackMargins = extractFallbackMargins(sectPrElements, headerPx, footerPx);
63067
+ headerPx = fallbackMargins.headerPx;
63068
+ footerPx = fallbackMargins.footerPx;
63069
+ const { topPx, rightPx, bottomPx, leftPx } = fallbackMargins;
63066
63070
  const headerRefs = extractHeaderFooterRefs(sectPrElements, "w:headerReference");
63067
63071
  const footerRefs = extractHeaderFooterRefs(sectPrElements, "w:footerReference");
63068
63072
  const numbering = extractPageNumbering(sectPrElements);
@@ -63071,6 +63075,10 @@ function extractSectionData(para) {
63071
63075
  return {
63072
63076
  headerPx,
63073
63077
  footerPx,
63078
+ topPx,
63079
+ rightPx,
63080
+ bottomPx,
63081
+ leftPx,
63074
63082
  type: type2,
63075
63083
  pageSizePx,
63076
63084
  orientation,
@@ -63182,7 +63190,14 @@ function buildSectionRangesFromParagraphs(paragraphs, hasBodySectPr) {
63182
63190
  startParagraphIndex: currentStart,
63183
63191
  endParagraphIndex: item.index,
63184
63192
  sectPr,
63185
- margins: sectionData.headerPx != null || sectionData.footerPx != null ? { header: sectionData.headerPx ?? 0, footer: sectionData.footerPx ?? 0 } : null,
63193
+ margins: sectionData.headerPx != null || sectionData.footerPx != null ? {
63194
+ header: sectionData.headerPx ?? 0,
63195
+ footer: sectionData.footerPx ?? 0,
63196
+ top: sectionData.topPx,
63197
+ right: sectionData.rightPx,
63198
+ bottom: sectionData.bottomPx,
63199
+ left: sectionData.leftPx
63200
+ } : null,
63186
63201
  pageSize: sectionData.pageSizePx ?? null,
63187
63202
  orientation: sectionData.orientation ?? null,
63188
63203
  columns: sectionData.columnsPx ?? null,
@@ -63224,7 +63239,14 @@ function createFinalSectionFromBodySectPr(bodySectPr, currentStart, totalParagra
63224
63239
  startParagraphIndex: currentStart,
63225
63240
  endParagraphIndex: totalParagraphs - 1,
63226
63241
  sectPr: bodySectPr,
63227
- margins: bodySectionData.headerPx != null || bodySectionData.footerPx != null ? { header: bodySectionData.headerPx ?? 0, footer: bodySectionData.footerPx ?? 0 } : null,
63242
+ margins: bodySectionData.headerPx != null || bodySectionData.footerPx != null ? {
63243
+ header: bodySectionData.headerPx ?? 0,
63244
+ footer: bodySectionData.footerPx ?? 0,
63245
+ top: bodySectionData.topPx,
63246
+ right: bodySectionData.rightPx,
63247
+ bottom: bodySectionData.bottomPx,
63248
+ left: bodySectionData.leftPx
63249
+ } : null,
63228
63250
  pageSize: bodySectionData.pageSizePx ?? null,
63229
63251
  orientation: bodySectionData.orientation ?? null,
63230
63252
  columns: bodySectionData.columnsPx ?? null,
@@ -63275,8 +63297,8 @@ function analyzeSectionRanges(doc2, bodySectPr) {
63275
63297
  }
63276
63298
  return ranges;
63277
63299
  }
63278
- const TWIPS_PER_INCH$2 = 1440;
63279
- const PX_PER_INCH$1 = 96;
63300
+ const TWIPS_PER_INCH$3 = 1440;
63301
+ const PX_PER_INCH$2 = 96;
63280
63302
  const PX_PER_PT = 96 / 72;
63281
63303
  SectionType.NEXT_PAGE;
63282
63304
  SectionType.CONTINUOUS;
@@ -63415,7 +63437,7 @@ const applyTrackedChangesModeToRuns = (runs, config2, hyperlinkConfig, applyMark
63415
63437
  }
63416
63438
  return filtered;
63417
63439
  };
63418
- const twipsToPx$1 = (value) => value / TWIPS_PER_INCH$2 * PX_PER_INCH$1;
63440
+ const twipsToPx$2 = (value) => value / TWIPS_PER_INCH$3 * PX_PER_INCH$2;
63419
63441
  const ptToPx = (pt) => {
63420
63442
  if (pt == null || !Number.isFinite(pt)) return void 0;
63421
63443
  return pt * PX_PER_PT;
@@ -64925,8 +64947,8 @@ const normalizeParagraphSpacing = (value) => {
64925
64947
  const beforeAutospacing = toBooleanFlag(source.beforeAutospacing ?? source.beforeAutoSpacing);
64926
64948
  const afterAutospacing = toBooleanFlag(source.afterAutospacing ?? source.afterAutoSpacing);
64927
64949
  const contextualSpacing = toBooleanFlag(source.contextualSpacing);
64928
- const before = beforeRaw != null ? twipsToPx$1(beforeRaw) : pickNumber(source.lineSpaceBefore);
64929
- const after = afterRaw != null ? twipsToPx$1(afterRaw) : pickNumber(source.lineSpaceAfter);
64950
+ const before = beforeRaw != null ? twipsToPx$2(beforeRaw) : pickNumber(source.lineSpaceBefore);
64951
+ const after = afterRaw != null ? twipsToPx$2(afterRaw) : pickNumber(source.lineSpaceAfter);
64930
64952
  const line = normalizeLineValue(lineRaw, lineRule);
64931
64953
  if (before != null) spacing.before = before;
64932
64954
  if (after != null) spacing.after = after;
@@ -64956,9 +64978,9 @@ const normalizeLineValue = (value, lineRule) => {
64956
64978
  if (value > 0 && value <= MAX_AUTO_LINE_MULTIPLIER) {
64957
64979
  return value;
64958
64980
  }
64959
- return twipsToPx$1(value);
64981
+ return twipsToPx$2(value);
64960
64982
  }
64961
- return twipsToPx$1(value);
64983
+ return twipsToPx$2(value);
64962
64984
  };
64963
64985
  const normalizeLineRule = (value) => {
64964
64986
  if (value === "auto" || value === "exact" || value === "atLeast") {
@@ -64995,7 +65017,7 @@ const normalizeParagraphIndent = (value) => {
64995
65017
  if (Math.abs(num) <= TWIPS_THRESHOLD$1) {
64996
65018
  return num;
64997
65019
  }
64998
- return twipsToPx$1(Number(num));
65020
+ return twipsToPx$2(Number(num));
64999
65021
  };
65000
65022
  const left2 = convert(pickNumber(source.left));
65001
65023
  const right2 = convert(pickNumber(source.right));
@@ -65575,9 +65597,9 @@ const buildFontCss = (run2) => {
65575
65597
  const family = run2.fontFamily ?? "Times New Roman";
65576
65598
  return `${style2}${weight}${size2} ${family}`;
65577
65599
  };
65578
- const TWIPS_PER_INCH$1 = 1440;
65600
+ const TWIPS_PER_INCH$2 = 1440;
65579
65601
  const PIXELS_PER_INCH = 96;
65580
- const TWIPS_PER_PIXEL = Math.round(TWIPS_PER_INCH$1 / PIXELS_PER_INCH);
65602
+ const TWIPS_PER_PIXEL = Math.round(TWIPS_PER_INCH$2 / PIXELS_PER_INCH);
65581
65603
  const PIXELS_PER_TWIP = 1 / TWIPS_PER_PIXEL;
65582
65604
  const toFiniteNumber = (value) => {
65583
65605
  if (value == null) return null;
@@ -66601,7 +66623,7 @@ const extractMarkerRun = (lvl) => {
66601
66623
  }
66602
66624
  const spacingTwips = parseNumberAttr(getAttribute(findChild(rPr, "w:spacing"), "w:val"));
66603
66625
  if (spacingTwips != null && Number.isFinite(spacingTwips)) {
66604
- run2.letterSpacing = twipsToPx$1(spacingTwips);
66626
+ run2.letterSpacing = twipsToPx$2(spacingTwips);
66605
66627
  }
66606
66628
  return Object.keys(run2).length ? run2 : void 0;
66607
66629
  };
@@ -66825,10 +66847,19 @@ const buildNumberingPath = (numId, ilvl, counterValue, listCounterContext) => {
66825
66847
  const convertIndentTwipsToPx = (indent) => {
66826
66848
  if (!indent) return void 0;
66827
66849
  const result = {};
66828
- if (isFiniteNumber(indent.left)) result.left = twipsToPx$1(Number(indent.left));
66829
- if (isFiniteNumber(indent.right)) result.right = twipsToPx$1(Number(indent.right));
66830
- if (isFiniteNumber(indent.firstLine)) result.firstLine = twipsToPx$1(Number(indent.firstLine));
66831
- if (isFiniteNumber(indent.hanging)) result.hanging = twipsToPx$1(Number(indent.hanging));
66850
+ const toNum = (v2) => {
66851
+ if (typeof v2 === "string" && v2.trim() !== "" && isFinite(Number(v2))) return Number(v2);
66852
+ if (isFiniteNumber(v2)) return Number(v2);
66853
+ return void 0;
66854
+ };
66855
+ const left2 = toNum(indent.left);
66856
+ const right2 = toNum(indent.right);
66857
+ const firstLine = toNum(indent.firstLine);
66858
+ const hanging = toNum(indent.hanging);
66859
+ if (left2 != null) result.left = twipsToPx$2(left2);
66860
+ if (right2 != null) result.right = twipsToPx$2(right2);
66861
+ if (firstLine != null) result.firstLine = twipsToPx$2(firstLine);
66862
+ if (hanging != null) result.hanging = twipsToPx$2(hanging);
66832
66863
  return Object.keys(result).length > 0 ? result : void 0;
66833
66864
  };
66834
66865
  const toAdapterNumberingProps = (value) => {
@@ -66853,7 +66884,7 @@ const toResolvedTabStops = (tabs) => {
66853
66884
  if (!stop || typeof stop.pos !== "number") continue;
66854
66885
  const alignment2 = normalizeResolvedTabAlignment(stop.val);
66855
66886
  if (!alignment2) continue;
66856
- const position = twipsToPx$1(stop.pos);
66887
+ const position = twipsToPx$2(stop.pos);
66857
66888
  if (!Number.isFinite(position)) continue;
66858
66889
  const resolvedStop = {
66859
66890
  position,
@@ -67294,9 +67325,9 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67294
67325
  const vAnchor = asString2(framePr["w:vAnchor"] ?? framePr.vAnchor);
67295
67326
  if (vAnchor) frame.vAnchor = vAnchor;
67296
67327
  const xTwips = pickNumber(framePr["w:x"] ?? framePr.x);
67297
- if (xTwips != null) frame.x = twipsToPx$1(xTwips);
67328
+ if (xTwips != null) frame.x = twipsToPx$2(xTwips);
67298
67329
  const yTwips = pickNumber(framePr["w:y"] ?? framePr.y);
67299
- if (yTwips != null) frame.y = twipsToPx$1(yTwips);
67330
+ if (yTwips != null) frame.y = twipsToPx$2(yTwips);
67300
67331
  if (Object.keys(frame).length > 0) {
67301
67332
  paragraphAttrs.frame = frame;
67302
67333
  }
@@ -67384,7 +67415,29 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67384
67415
  }
67385
67416
  }
67386
67417
  }
67387
- const wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
67418
+ let wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
67419
+ if (!wordLayout && enrichedNumberingProps.resolvedLevelIndent) {
67420
+ const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
67421
+ const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
67422
+ if (firstLinePx > 0) {
67423
+ wordLayout = {
67424
+ // Treat as first-line-indent mode: text starts after the marker+firstLine offset.
67425
+ firstLineIndentMode: true,
67426
+ textStartPx: firstLinePx
67427
+ };
67428
+ }
67429
+ }
67430
+ if (wordLayout && (!wordLayout.textStartPx || !Number.isFinite(wordLayout.textStartPx)) && enrichedNumberingProps.resolvedLevelIndent) {
67431
+ const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
67432
+ const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
67433
+ if (firstLinePx > 0) {
67434
+ wordLayout = {
67435
+ ...wordLayout,
67436
+ firstLineIndentMode: wordLayout.firstLineIndentMode ?? true,
67437
+ textStartPx: firstLinePx
67438
+ };
67439
+ }
67440
+ }
67388
67441
  if (wordLayout) {
67389
67442
  if (wordLayout.marker) {
67390
67443
  if (listRendering?.markerText) {
@@ -69295,7 +69348,7 @@ const measurementToPx = (value) => {
69295
69348
  const entry = value;
69296
69349
  if (typeof entry.value !== "number") return void 0;
69297
69350
  if (!entry.type || entry.type === "px" || entry.type === "pixel") return entry.value;
69298
- if (entry.type === "dxa") return twipsToPx$1(entry.value);
69351
+ if (entry.type === "dxa") return twipsToPx$2(entry.value);
69299
69352
  return void 0;
69300
69353
  };
69301
69354
  const normalizeTableWidth = (value) => {
@@ -69307,7 +69360,7 @@ const normalizeTableWidth = (value) => {
69307
69360
  return { width: raw, type: measurement.type ?? "px" };
69308
69361
  }
69309
69362
  if (measurement.type === "dxa") {
69310
- return { width: twipsToPx$1(raw), type: "px" };
69363
+ return { width: twipsToPx$2(raw), type: "px" };
69311
69364
  }
69312
69365
  return { width: raw, type: measurement.type };
69313
69366
  };
@@ -69335,13 +69388,13 @@ const extractTableStyleParagraphProps = (styleId, docx) => {
69335
69388
  const line = parseIntSafe$1(attrs["w:line"]);
69336
69389
  const rawLineRule = attrs["w:lineRule"];
69337
69390
  const lineRule = rawLineRule === "auto" || rawLineRule === "exact" || rawLineRule === "atLeast" ? rawLineRule : void 0;
69338
- if (before != null) spacing.before = twipsToPx$1(before);
69339
- if (after != null) spacing.after = twipsToPx$1(after);
69391
+ if (before != null) spacing.before = twipsToPx$2(before);
69392
+ if (after != null) spacing.after = twipsToPx$2(after);
69340
69393
  if (line != null) {
69341
69394
  if (lineRule === "auto") {
69342
69395
  spacing.line = line / 240;
69343
69396
  } else {
69344
- spacing.line = twipsToPx$1(line);
69397
+ spacing.line = twipsToPx$2(line);
69345
69398
  }
69346
69399
  }
69347
69400
  if (lineRule) spacing.lineRule = lineRule;
@@ -69367,7 +69420,7 @@ const normalizeRowHeight = (rowProps) => {
69367
69420
  if (rawValue == null) return void 0;
69368
69421
  const rawRule = heightObj.rule ?? heightObj.hRule;
69369
69422
  const rule = rawRule === "exact" || rawRule === "atLeast" || rawRule === "auto" ? rawRule : "atLeast";
69370
- const valuePx = twipsToPx$1(rawValue);
69423
+ const valuePx = twipsToPx$2(rawValue);
69371
69424
  return {
69372
69425
  value: valuePx,
69373
69426
  rule
@@ -69472,41 +69525,6 @@ const parseTableCell = (args) => {
69472
69525
  }
69473
69526
  }
69474
69527
  }
69475
- try {
69476
- const blockSummaries = blocks.map((b2) => {
69477
- if (b2.kind === "paragraph") {
69478
- const runs = b2.runs ?? [];
69479
- const attrs = b2.attrs ?? {};
69480
- return {
69481
- kind: "paragraph",
69482
- runKinds: runs.map((r2) => r2.kind ?? "text"),
69483
- runCount: runs.length,
69484
- runPreview: runs.map((r2) => {
69485
- const kind = r2.kind ?? "text";
69486
- if (kind === "image") {
69487
- const img = r2;
69488
- return { kind, src: img.src, width: img.width, height: img.height };
69489
- }
69490
- return { kind };
69491
- }),
69492
- hasNumbering: Boolean(attrs.numberingProperties),
69493
- markerText: attrs.wordLayout?.marker?.markerText
69494
- };
69495
- }
69496
- return { kind: b2.kind };
69497
- });
69498
- console.log(
69499
- "[tableNodeToBlock.parseTableCell] cell contents",
69500
- JSON.stringify({
69501
- cellIndex,
69502
- rowIndex,
69503
- cellIdPreview: `cell-${rowIndex}-${cellIndex}`,
69504
- childTypes: cellNode.content.map((c2) => c2?.type),
69505
- blocks: blockSummaries
69506
- })
69507
- );
69508
- } catch {
69509
- }
69510
69528
  if (blocks.length === 0) {
69511
69529
  return null;
69512
69530
  }
@@ -69617,10 +69635,10 @@ function extractFloatingTableAnchorWrap(node) {
69617
69635
  anchor.alignV = floatingProps.tblpYSpec;
69618
69636
  }
69619
69637
  if (floatingProps.tblpX !== void 0) {
69620
- anchor.offsetH = twipsToPx$1(floatingProps.tblpX);
69638
+ anchor.offsetH = twipsToPx$2(floatingProps.tblpX);
69621
69639
  }
69622
69640
  if (floatingProps.tblpY !== void 0) {
69623
- anchor.offsetV = twipsToPx$1(floatingProps.tblpY);
69641
+ anchor.offsetV = twipsToPx$2(floatingProps.tblpY);
69624
69642
  }
69625
69643
  const hasDistances = floatingProps.leftFromText !== void 0 || floatingProps.rightFromText !== void 0 || floatingProps.topFromText !== void 0 || floatingProps.bottomFromText !== void 0;
69626
69644
  const wrap2 = {
@@ -69631,16 +69649,16 @@ function extractFloatingTableAnchorWrap(node) {
69631
69649
  };
69632
69650
  if (hasDistances) {
69633
69651
  if (floatingProps.topFromText !== void 0) {
69634
- wrap2.distTop = twipsToPx$1(floatingProps.topFromText);
69652
+ wrap2.distTop = twipsToPx$2(floatingProps.topFromText);
69635
69653
  }
69636
69654
  if (floatingProps.bottomFromText !== void 0) {
69637
- wrap2.distBottom = twipsToPx$1(floatingProps.bottomFromText);
69655
+ wrap2.distBottom = twipsToPx$2(floatingProps.bottomFromText);
69638
69656
  }
69639
69657
  if (floatingProps.leftFromText !== void 0) {
69640
- wrap2.distLeft = twipsToPx$1(floatingProps.leftFromText);
69658
+ wrap2.distLeft = twipsToPx$2(floatingProps.leftFromText);
69641
69659
  }
69642
69660
  if (floatingProps.rightFromText !== void 0) {
69643
- wrap2.distRight = twipsToPx$1(floatingProps.rightFromText);
69661
+ wrap2.distRight = twipsToPx$2(floatingProps.rightFromText);
69644
69662
  }
69645
69663
  }
69646
69664
  return { anchor, wrap: wrap2 };
@@ -73371,20 +73389,6 @@ const renderTableCell = (deps) => {
73371
73389
  }
73372
73390
  const cellBlocks = cell?.blocks ?? (cell?.paragraph ? [cell.paragraph] : []);
73373
73391
  const blockMeasures = cellMeasure?.blocks ?? (cellMeasure?.paragraph ? [cellMeasure.paragraph] : []);
73374
- try {
73375
- console.log(
73376
- "[DomPainter.renderTableCell] cell render input",
73377
- JSON.stringify({
73378
- cellId: cell?.id,
73379
- blockKinds: cellBlocks.map((b2) => b2.kind),
73380
- measureKinds: blockMeasures.map((m2) => m2.kind),
73381
- width: cellMeasure?.width,
73382
- height: cellMeasure?.height,
73383
- rowHeight
73384
- })
73385
- );
73386
- } catch {
73387
- }
73388
73392
  if (cellBlocks.length > 0 && blockMeasures.length > 0) {
73389
73393
  const content = doc2.createElement("div");
73390
73394
  content.style.position = "relative";
@@ -73417,15 +73421,6 @@ const renderTableCell = (deps) => {
73417
73421
  const blockMeasure = blockMeasures[i];
73418
73422
  const block = cellBlocks[i];
73419
73423
  if (blockMeasure.kind === "image" && block?.kind === "image") {
73420
- console.log(
73421
- "[DomPainter.renderTableCell] rendering image block in cell",
73422
- JSON.stringify({
73423
- cellId: cell?.id,
73424
- blockId: block.id,
73425
- width: blockMeasure.width,
73426
- height: blockMeasure.height
73427
- })
73428
- );
73429
73424
  const imageWrapper = doc2.createElement("div");
73430
73425
  imageWrapper.style.position = "relative";
73431
73426
  imageWrapper.style.width = `${blockMeasure.width}px`;
@@ -73448,16 +73443,6 @@ const renderTableCell = (deps) => {
73448
73443
  continue;
73449
73444
  }
73450
73445
  if (blockMeasure.kind === "drawing" && block?.kind === "drawing") {
73451
- console.log(
73452
- "[DomPainter.renderTableCell] rendering drawing block in cell",
73453
- JSON.stringify({
73454
- cellId: cell?.id,
73455
- blockId: block.id,
73456
- drawingKind: block.drawingKind,
73457
- width: blockMeasure.width,
73458
- height: blockMeasure.height
73459
- })
73460
- );
73461
73446
  const drawingWrapper = doc2.createElement("div");
73462
73447
  drawingWrapper.style.position = "relative";
73463
73448
  drawingWrapper.style.width = `${blockMeasure.width}px`;
@@ -73500,20 +73485,6 @@ const renderTableCell = (deps) => {
73500
73485
  continue;
73501
73486
  }
73502
73487
  if (blockMeasure.kind === "paragraph" && block?.kind === "paragraph") {
73503
- try {
73504
- const runKinds = (block.runs ?? []).map((r2) => r2.kind ?? "text");
73505
- const imageRuns = (block.runs ?? []).filter((r2) => r2.kind === "image").map((r2) => ({ src: r2.src }));
73506
- console.log(
73507
- "[DomPainter.renderTableCell] rendering paragraph block in cell",
73508
- JSON.stringify({
73509
- cellId: cell?.id,
73510
- blockId: block.id,
73511
- runKinds,
73512
- imageRuns
73513
- })
73514
- );
73515
- } catch {
73516
- }
73517
73488
  const paragraphMeasure = blockMeasure;
73518
73489
  const lines = paragraphMeasure.lines;
73519
73490
  const blockLineCount = lines?.length || 0;
@@ -75328,7 +75299,9 @@ const _DomPainter = class _DomPainter2 {
75328
75299
  const isTocEntry = block.attrs?.isTocEntry;
75329
75300
  const hasMarker = !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
75330
75301
  const hasSdtContainer = block.attrs?.sdt?.type === "documentSection" || block.attrs?.sdt?.type === "structuredContent" || block.attrs?.containerSdt?.type === "documentSection" || block.attrs?.containerSdt?.type === "structuredContent";
75331
- const styles = isTocEntry ? { ...fragmentStyles, whiteSpace: "nowrap" } : hasMarker || hasSdtContainer ? { ...fragmentStyles, overflow: "visible" } : fragmentStyles;
75302
+ const paraIndentForOverflow = block.attrs?.indent;
75303
+ const hasNegativeIndent = (paraIndentForOverflow?.left ?? 0) < 0 || (paraIndentForOverflow?.right ?? 0) < 0;
75304
+ const styles = isTocEntry ? { ...fragmentStyles, whiteSpace: "nowrap" } : hasMarker || hasSdtContainer || hasNegativeIndent ? { ...fragmentStyles, overflow: "visible" } : fragmentStyles;
75332
75305
  applyStyles$2(fragmentEl, styles);
75333
75306
  this.applyFragmentFrame(fragmentEl, fragment, context.section);
75334
75307
  if (isTocEntry) {
@@ -75357,6 +75330,8 @@ const _DomPainter = class _DomPainter2 {
75357
75330
  }
75358
75331
  if (fragmentEl.style.paddingLeft) fragmentEl.style.removeProperty("padding-left");
75359
75332
  if (fragmentEl.style.paddingRight) fragmentEl.style.removeProperty("padding-right");
75333
+ if (fragmentEl.style.marginLeft) fragmentEl.style.removeProperty("margin-left");
75334
+ if (fragmentEl.style.marginRight) fragmentEl.style.removeProperty("margin-right");
75360
75335
  if (fragmentEl.style.textIndent) fragmentEl.style.removeProperty("text-indent");
75361
75336
  const paraIndent = block.attrs?.indent;
75362
75337
  const paraIndentLeft = paraIndent?.left ?? 0;
@@ -75385,16 +75360,22 @@ const _DomPainter = class _DomPainter2 {
75385
75360
  if (!isListFirstLine) {
75386
75361
  if (hasExplicitSegmentPositioning) {
75387
75362
  if (isFirstLine && firstLineOffset !== 0) {
75388
- const adjustedPadding = paraIndentLeft + firstLineOffset;
75389
- lineEl.style.paddingLeft = `${adjustedPadding}px`;
75363
+ const effectiveLeftIndent = paraIndentLeft < 0 ? 0 : paraIndentLeft;
75364
+ const adjustedPadding = effectiveLeftIndent + firstLineOffset;
75365
+ if (adjustedPadding > 0) {
75366
+ lineEl.style.paddingLeft = `${adjustedPadding}px`;
75367
+ }
75390
75368
  }
75391
- } else if (paraIndentLeft) {
75369
+ } else if (paraIndentLeft && paraIndentLeft > 0) {
75392
75370
  lineEl.style.paddingLeft = `${paraIndentLeft}px`;
75371
+ } else if (!isFirstLine && paraIndent?.hanging && paraIndent.hanging > 0) {
75372
+ lineEl.style.paddingLeft = `${paraIndent.hanging}px`;
75393
75373
  }
75394
75374
  }
75395
- if (paraIndentRight) {
75375
+ if (paraIndentRight && paraIndentRight > 0) {
75396
75376
  lineEl.style.paddingRight = `${paraIndentRight}px`;
75397
75377
  }
75378
+ const hasNegativeLeftIndent = paraIndentLeft != null && paraIndentLeft < 0;
75398
75379
  if (!fragment.continuesFromPrev && index2 === 0 && firstLineOffset && !isListFirstLine) {
75399
75380
  if (!hasExplicitSegmentPositioning) {
75400
75381
  lineEl.style.textIndent = `${firstLineOffset}px`;
@@ -76813,7 +76794,7 @@ const _DomPainter = class _DomPainter2 {
76813
76794
  }
76814
76795
  const runsForLine = sliceRunsForLine(block, line);
76815
76796
  const trackedConfig = this.resolveTrackedChangesConfig(block);
76816
- const textSlices = runsForLine.length > 0 ? runsForLine.filter((r2) => (r2.kind === "text" || r2.kind === void 0) && "text" in r2 && r2.text != null).map((r2) => r2.text) : gatherTextSlicesForLine(block, line);
76797
+ runsForLine.length > 0 ? runsForLine.filter((r2) => (r2.kind === "text" || r2.kind === void 0) && "text" in r2 && r2.text != null).map((r2) => r2.text) : gatherTextSlicesForLine(block, line);
76817
76798
  if (runsForLine.length === 0) {
76818
76799
  const span = this.doc.createElement("span");
76819
76800
  span.innerHTML = "&nbsp;";
@@ -76860,19 +76841,7 @@ const _DomPainter = class _DomPainter2 {
76860
76841
  });
76861
76842
  }
76862
76843
  const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
76863
- const availableWidth = availableWidthOverride ?? line.maxWidth ?? line.width;
76864
- const shouldJustify = !skipJustify && effectiveAlignment === "justify" && !hasExplicitPositioning;
76865
- if (shouldJustify) {
76866
- const spaceCount = textSlices.reduce(
76867
- (sum, s2) => sum + Array.from(s2).filter((ch) => ch === " " || ch === " ").length,
76868
- 0
76869
- );
76870
- const slack = availableWidth - line.width;
76871
- if (spaceCount > 0 && slack !== 0) {
76872
- const spacingPerSpace = slack / spaceCount;
76873
- el.style.wordSpacing = `${spacingPerSpace}px`;
76874
- }
76875
- }
76844
+ availableWidthOverride ?? line.maxWidth ?? line.width;
76876
76845
  if (hasExplicitPositioning && line.segments) {
76877
76846
  const paraIndent = block.attrs?.indent;
76878
76847
  const indentLeft = paraIndent?.left ?? 0;
@@ -77691,15 +77660,18 @@ const applyParagraphBlockStyles = (element, attrs) => {
77691
77660
  }
77692
77661
  const indent = attrs.indent;
77693
77662
  if (indent) {
77694
- if (indent.left) {
77663
+ if (indent.left && indent.left > 0) {
77695
77664
  element.style.paddingLeft = `${indent.left}px`;
77696
77665
  }
77697
- if (indent.right) {
77666
+ if (indent.right && indent.right > 0) {
77698
77667
  element.style.paddingRight = `${indent.right}px`;
77699
77668
  }
77700
- const textIndent = (indent.firstLine ?? 0) - (indent.hanging ?? 0);
77701
- if (textIndent) {
77702
- element.style.textIndent = `${textIndent}px`;
77669
+ const hasNegativeLeftIndent = indent.left != null && indent.left < 0;
77670
+ if (!hasNegativeLeftIndent) {
77671
+ const textIndent = (indent.firstLine ?? 0) - (indent.hanging ?? 0);
77672
+ if (textIndent) {
77673
+ element.style.textIndent = `${textIndent}px`;
77674
+ }
77703
77675
  }
77704
77676
  }
77705
77677
  applyParagraphBorderStyles(element, attrs.borders);
@@ -79061,20 +79033,6 @@ const asSafeNumber = (value) => {
79061
79033
  }
79062
79034
  return value;
79063
79035
  };
79064
- function calculateFirstLineIndent(block, measure) {
79065
- const wordLayout = block.attrs?.wordLayout;
79066
- if (!wordLayout?.firstLineIndentMode) {
79067
- return 0;
79068
- }
79069
- if (!wordLayout.marker || !measure.marker) {
79070
- return 0;
79071
- }
79072
- const markerWidthRaw = measure.marker.markerWidth ?? wordLayout.marker.markerBoxWidthPx ?? 0;
79073
- const markerWidth = Number.isFinite(markerWidthRaw) && markerWidthRaw >= 0 ? markerWidthRaw : 0;
79074
- const gutterWidthRaw = measure.marker.gutterWidth ?? 0;
79075
- const gutterWidth = Number.isFinite(gutterWidthRaw) && gutterWidthRaw >= 0 ? gutterWidthRaw : 0;
79076
- return markerWidth + gutterWidth;
79077
- }
79078
79036
  function layoutParagraphBlock(ctx2, anchors) {
79079
79037
  const { block, measure, columnWidth, ensurePage, advanceColumn, columnX, floatManager } = ctx2;
79080
79038
  const remeasureParagraph2 = ctx2.remeasureParagraph;
@@ -79196,10 +79154,25 @@ function layoutParagraphBlock(ctx2, anchors) {
79196
79154
  }
79197
79155
  let lines = normalizeLines(measure);
79198
79156
  const measurementWidth = lines[0]?.maxWidth;
79157
+ const paraIndent = block.attrs?.indent;
79158
+ const indentLeft = typeof paraIndent?.left === "number" && Number.isFinite(paraIndent.left) ? paraIndent.left : 0;
79159
+ const indentRight = typeof paraIndent?.right === "number" && Number.isFinite(paraIndent.right) ? paraIndent.right : 0;
79160
+ const negativeLeftIndent = indentLeft < 0 ? indentLeft : 0;
79161
+ const negativeRightIndent = indentRight < 0 ? indentRight : 0;
79162
+ const remeasureWidth = Math.max(1, columnWidth - indentLeft - indentRight);
79199
79163
  let didRemeasureForColumnWidth = false;
79200
- if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > columnWidth) {
79201
- const firstLineIndent = calculateFirstLineIndent(block, measure);
79202
- const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
79164
+ if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
79165
+ let firstLineIndent = 0;
79166
+ const wordLayout = block.attrs?.wordLayout;
79167
+ if (wordLayout?.marker && measure.marker) {
79168
+ const markerJustification = wordLayout.marker.justification ?? "left";
79169
+ if (markerJustification === "left") {
79170
+ const markerWidth = measure.marker.markerWidth ?? 0;
79171
+ const gutterWidth = measure.marker.gutterWidth ?? wordLayout.marker.gutterWidthPx ?? 0;
79172
+ firstLineIndent = markerWidth + gutterWidth;
79173
+ }
79174
+ }
79175
+ const newMeasure = remeasureParagraph2(block, remeasureWidth, firstLineIndent);
79203
79176
  lines = normalizeLines(newMeasure);
79204
79177
  didRemeasureForColumnWidth = true;
79205
79178
  }
@@ -79278,9 +79251,19 @@ function layoutParagraphBlock(ctx2, anchors) {
79278
79251
  }
79279
79252
  tempY += lineHeight2;
79280
79253
  }
79281
- if (narrowestWidth < columnWidth) {
79282
- const firstLineIndent = calculateFirstLineIndent(block, measure);
79283
- const newMeasure = remeasureParagraph2(block, narrowestWidth, firstLineIndent);
79254
+ const narrowestRemeasureWidth = Math.max(1, narrowestWidth - indentLeft - indentRight);
79255
+ if (narrowestRemeasureWidth < remeasureWidth) {
79256
+ let firstLineIndent = 0;
79257
+ const wordLayout = block.attrs?.wordLayout;
79258
+ if (wordLayout?.marker && measure.marker) {
79259
+ const markerJustification = wordLayout.marker.justification ?? "left";
79260
+ if (markerJustification === "left") {
79261
+ const markerWidth = measure.marker.markerWidth ?? 0;
79262
+ const gutterWidth = measure.marker.gutterWidth ?? wordLayout.marker.gutterWidthPx ?? 0;
79263
+ firstLineIndent = markerWidth + gutterWidth;
79264
+ }
79265
+ }
79266
+ const newMeasure = remeasureParagraph2(block, narrowestRemeasureWidth, firstLineIndent);
79284
79267
  lines = normalizeLines(newMeasure);
79285
79268
  didRemeasureForFloats = true;
79286
79269
  }
@@ -79334,14 +79317,16 @@ function layoutParagraphBlock(ctx2, anchors) {
79334
79317
  }
79335
79318
  const slice2 = sliceLines(lines, fromLine, state2.contentBottom - state2.cursorY);
79336
79319
  const fragmentHeight = slice2.height;
79320
+ const adjustedX = columnX(state2.columnIndex) + offsetX + negativeLeftIndent;
79321
+ const adjustedWidth = effectiveColumnWidth - negativeLeftIndent - negativeRightIndent;
79337
79322
  const fragment = {
79338
79323
  kind: "para",
79339
79324
  blockId: block.id,
79340
79325
  fromLine,
79341
79326
  toLine: slice2.toLine,
79342
- x: columnX(state2.columnIndex) + offsetX,
79327
+ x: adjustedX,
79343
79328
  y: state2.cursorY,
79344
- width: effectiveColumnWidth,
79329
+ width: adjustedWidth,
79345
79330
  ...computeFragmentPmRange(block, lines, fromLine, slice2.toLine)
79346
79331
  };
79347
79332
  if (didRemeasureForColumnWidth) {
@@ -82194,7 +82179,13 @@ function getCtx() {
82194
82179
  return ctx$1;
82195
82180
  }
82196
82181
  function isTextRun(run2) {
82197
- return run2.kind === "tab" ? false : true;
82182
+ if (run2.kind === "tab" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation") {
82183
+ return false;
82184
+ }
82185
+ if ("src" in run2) {
82186
+ return false;
82187
+ }
82188
+ return true;
82198
82189
  }
82199
82190
  function fontString(run2) {
82200
82191
  const textRun = isTextRun(run2) ? run2 : null;
@@ -82207,6 +82198,42 @@ function fontString(run2) {
82207
82198
  function runText(run2) {
82208
82199
  return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
82209
82200
  }
82201
+ const DEFAULT_TAB_INTERVAL_TWIPS$1 = 720;
82202
+ const TWIPS_PER_INCH$1 = 1440;
82203
+ const PX_PER_INCH$1 = 96;
82204
+ const TWIPS_PER_PX$1 = TWIPS_PER_INCH$1 / PX_PER_INCH$1;
82205
+ const TAB_EPSILON$1 = 0.1;
82206
+ const WIDTH_FUDGE_PX = 0.5;
82207
+ const twipsToPx$1 = (twips) => twips / TWIPS_PER_PX$1;
82208
+ const pxToTwips$1 = (px) => Math.round(px * TWIPS_PER_PX$1);
82209
+ const buildTabStopsPx$1 = (indent, tabs, tabIntervalTwips) => {
82210
+ const paragraphIndentTwips = {
82211
+ left: pxToTwips$1(Math.max(0, indent?.left ?? 0)),
82212
+ right: pxToTwips$1(Math.max(0, indent?.right ?? 0)),
82213
+ firstLine: pxToTwips$1(Math.max(0, indent?.firstLine ?? 0)),
82214
+ hanging: pxToTwips$1(Math.max(0, indent?.hanging ?? 0))
82215
+ };
82216
+ const stops = computeTabStops$1({
82217
+ explicitStops: tabs ?? [],
82218
+ defaultTabInterval: tabIntervalTwips ?? DEFAULT_TAB_INTERVAL_TWIPS$1,
82219
+ paragraphIndent: paragraphIndentTwips
82220
+ });
82221
+ return stops.map((stop) => ({
82222
+ pos: twipsToPx$1(stop.pos),
82223
+ val: stop.val,
82224
+ leader: stop.leader
82225
+ }));
82226
+ };
82227
+ const getNextTabStopPx$1 = (currentX, tabStops, startIndex) => {
82228
+ let index2 = startIndex;
82229
+ while (index2 < tabStops.length && tabStops[index2].pos <= currentX + TAB_EPSILON$1) {
82230
+ index2 += 1;
82231
+ }
82232
+ if (index2 < tabStops.length) {
82233
+ return { target: tabStops[index2].pos, nextIndex: index2 + 1 };
82234
+ }
82235
+ return { target: currentX + twipsToPx$1(DEFAULT_TAB_INTERVAL_TWIPS$1), nextIndex: index2 };
82236
+ };
82210
82237
  function measureRunSliceWidth(run2, fromChar, toChar) {
82211
82238
  const context = getCtx();
82212
82239
  const text = runText(run2).slice(fromChar, toChar);
@@ -82230,13 +82257,38 @@ function lineHeightForRuns(runs, fromRun, toRun) {
82230
82257
  return maxSize2 * 1.2;
82231
82258
  }
82232
82259
  function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
82260
+ if (!Number.isFinite(maxWidth) || maxWidth <= 0) {
82261
+ throw new Error(`remeasureParagraph: maxWidth must be a positive number, got ${maxWidth}`);
82262
+ }
82263
+ if (!Number.isFinite(firstLineIndent)) {
82264
+ throw new Error(`remeasureParagraph: firstLineIndent must be a finite number, got ${firstLineIndent}`);
82265
+ }
82266
+ if (!block) {
82267
+ throw new Error("remeasureParagraph: block must be defined");
82268
+ }
82269
+ if (!Array.isArray(block.runs)) {
82270
+ throw new Error(`remeasureParagraph: block.runs must be an array, got ${typeof block.runs}`);
82271
+ }
82233
82272
  const runs = block.runs ?? [];
82234
82273
  const lines = [];
82274
+ const attrs = block.attrs;
82275
+ const indent = attrs?.indent;
82276
+ const wordLayout = attrs?.wordLayout;
82277
+ const indentLeft = Math.max(0, indent?.left ?? 0);
82278
+ const indentRight = Math.max(0, indent?.right ?? 0);
82279
+ const indentFirstLine = Math.max(0, indent?.firstLine ?? 0);
82280
+ const indentHanging = Math.max(0, indent?.hanging ?? 0);
82281
+ const rawFirstLineOffset = Math.max(0, firstLineIndent || indentFirstLine - indentHanging);
82282
+ const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
82283
+ const textStartPx = wordLayout?.textStartPx;
82284
+ const treatAsHanging = textStartPx && indentLeft === 0 && indentHanging === 0;
82285
+ const firstLineWidth = typeof textStartPx === "number" && textStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - textStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
82286
+ const tabStops = buildTabStopsPx$1(indent, attrs?.tabs, attrs?.tabIntervalTwips);
82235
82287
  let currentRun = 0;
82236
82288
  let currentChar = 0;
82237
82289
  while (currentRun < runs.length) {
82238
82290
  const isFirstLine = lines.length === 0;
82239
- const effectiveMaxWidth = isFirstLine ? maxWidth - firstLineIndent : maxWidth;
82291
+ const effectiveMaxWidth = Math.max(1, isFirstLine ? firstLineWidth : contentWidth);
82240
82292
  const startRun = currentRun;
82241
82293
  const startChar = currentChar;
82242
82294
  let width = 0;
@@ -82244,13 +82296,26 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
82244
82296
  let lastBreakChar = -1;
82245
82297
  let endRun = currentRun;
82246
82298
  let endChar = currentChar;
82299
+ let tabStopCursor = 0;
82300
+ let didBreakInThisLine = false;
82247
82301
  for (let r2 = currentRun; r2 < runs.length; r2 += 1) {
82248
82302
  const run2 = runs[r2];
82303
+ if (run2.kind === "tab") {
82304
+ const { target, nextIndex } = getNextTabStopPx$1(width, tabStops, tabStopCursor);
82305
+ const tabAdvance = Math.max(0, target - width);
82306
+ width += tabAdvance;
82307
+ tabStopCursor = nextIndex;
82308
+ endRun = r2;
82309
+ endChar = 1;
82310
+ lastBreakRun = r2;
82311
+ lastBreakChar = 1;
82312
+ continue;
82313
+ }
82249
82314
  const text = runText(run2);
82250
82315
  const start2 = r2 === currentRun ? currentChar : 0;
82251
82316
  for (let c2 = start2; c2 < text.length; c2 += 1) {
82252
82317
  const w2 = measureRunSliceWidth(run2, c2, c2 + 1);
82253
- if (width + w2 > effectiveMaxWidth && width > 0) {
82318
+ if (width + w2 > effectiveMaxWidth - WIDTH_FUDGE_PX && width > 0) {
82254
82319
  if (lastBreakRun >= 0) {
82255
82320
  endRun = lastBreakRun;
82256
82321
  endChar = lastBreakChar;
@@ -82258,6 +82323,7 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
82258
82323
  endRun = r2;
82259
82324
  endChar = c2;
82260
82325
  }
82326
+ didBreakInThisLine = true;
82261
82327
  break;
82262
82328
  }
82263
82329
  width += w2;
@@ -82269,9 +82335,7 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
82269
82335
  lastBreakChar = c2 + 1;
82270
82336
  }
82271
82337
  }
82272
- if (endRun !== r2 || endRun === r2 && (r2 === lastBreakRun ? endChar === lastBreakChar : false)) {
82273
- break;
82274
- }
82338
+ if (didBreakInThisLine) break;
82275
82339
  }
82276
82340
  if (startRun === endRun && startChar === endChar) {
82277
82341
  endRun = startRun;
@@ -82285,11 +82349,15 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
82285
82349
  width,
82286
82350
  ascent: 0,
82287
82351
  descent: 0,
82288
- lineHeight: lineHeightForRuns(runs, startRun, endRun)
82352
+ lineHeight: lineHeightForRuns(runs, startRun, endRun),
82353
+ maxWidth: effectiveMaxWidth
82289
82354
  };
82290
82355
  lines.push(line);
82291
82356
  currentRun = endRun;
82292
82357
  currentChar = endChar;
82358
+ if (currentRun >= runs.length) {
82359
+ break;
82360
+ }
82293
82361
  if (currentChar >= runText(runs[currentRun]).length) {
82294
82362
  currentRun += 1;
82295
82363
  currentChar = 0;
@@ -82966,9 +83034,15 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
82966
83034
  }
82967
83035
  const DEFAULT_PAGE_SIZE$1 = { w: 612, h: 792 };
82968
83036
  const DEFAULT_MARGINS$1 = { top: 72, right: 72, bottom: 72, left: 72 };
83037
+ const normalizeMargin = (value, fallback) => Number.isFinite(value) ? value : fallback;
82969
83038
  function resolveMeasurementConstraints(options) {
82970
83039
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
82971
- const margins = options.margins ?? DEFAULT_MARGINS$1;
83040
+ const margins = {
83041
+ top: normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top),
83042
+ right: normalizeMargin(options.margins?.right, DEFAULT_MARGINS$1.right),
83043
+ bottom: normalizeMargin(options.margins?.bottom, DEFAULT_MARGINS$1.bottom),
83044
+ left: normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
83045
+ };
82972
83046
  const contentWidth = pageSize.w - (margins.left + margins.right);
82973
83047
  const contentHeight = pageSize.h - (margins.top + margins.bottom);
82974
83048
  const columns = options.columns;
@@ -84502,12 +84576,12 @@ async function measureBlock(block, constraints) {
84502
84576
  async function measureParagraphBlock(block, maxWidth) {
84503
84577
  const ctx2 = getCanvasContext();
84504
84578
  const wordLayout = block.attrs?.wordLayout;
84505
- const WIDTH_FUDGE_PX = 0.5;
84579
+ const WIDTH_FUDGE_PX2 = 0.5;
84506
84580
  const lines = [];
84507
84581
  const indent = block.attrs?.indent;
84508
84582
  const spacing = block.attrs?.spacing;
84509
- const indentLeft = sanitizePositive(indent?.left);
84510
- const indentRight = sanitizePositive(indent?.right);
84583
+ const indentLeft = sanitizeIndent(indent?.left);
84584
+ const indentRight = sanitizeIndent(indent?.right);
84511
84585
  const firstLine = indent?.firstLine ?? 0;
84512
84586
  const hanging = indent?.hanging ?? 0;
84513
84587
  const isWordLayoutList = Boolean(wordLayout?.marker);
@@ -84516,6 +84590,7 @@ async function measureParagraphBlock(block, maxWidth) {
84516
84590
  const clampedFirstLineOffset = Math.max(0, rawFirstLineOffset);
84517
84591
  const firstLineOffset = isWordLayoutList ? 0 : clampedFirstLineOffset;
84518
84592
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
84593
+ const bodyContentWidth = contentWidth;
84519
84594
  let initialAvailableWidth;
84520
84595
  const textStartPx = wordLayout?.textStartPx;
84521
84596
  if (typeof textStartPx === "number" && textStartPx > indentLeft) {
@@ -84710,7 +84785,7 @@ async function measureParagraphBlock(block, maxWidth) {
84710
84785
  lines.push(emptyLine);
84711
84786
  }
84712
84787
  const hadPreviousLine = lines.length > 0;
84713
- const nextLineMaxWidth = hadPreviousLine ? getEffectiveWidth(contentWidth) : getEffectiveWidth(initialAvailableWidth);
84788
+ const nextLineMaxWidth = hadPreviousLine ? getEffectiveWidth(bodyContentWidth) : getEffectiveWidth(initialAvailableWidth);
84714
84789
  currentLine = {
84715
84790
  fromRun: runIndex,
84716
84791
  fromChar: 0,
@@ -84821,7 +84896,7 @@ async function measureParagraphBlock(block, maxWidth) {
84821
84896
  toChar: 1,
84822
84897
  width: imageWidth,
84823
84898
  maxFontSize: imageHeight,
84824
- maxWidth: getEffectiveWidth(contentWidth),
84899
+ maxWidth: getEffectiveWidth(bodyContentWidth),
84825
84900
  spaceCount: 0,
84826
84901
  segments: [
84827
84902
  {
@@ -84910,7 +84985,7 @@ async function measureParagraphBlock(block, maxWidth) {
84910
84985
  toChar: 1,
84911
84986
  width: annotationWidth,
84912
84987
  maxFontSize: annotationHeight,
84913
- maxWidth: getEffectiveWidth(contentWidth),
84988
+ maxWidth: getEffectiveWidth(bodyContentWidth),
84914
84989
  spaceCount: 0,
84915
84990
  segments: [
84916
84991
  {
@@ -84972,7 +85047,7 @@ async function measureParagraphBlock(block, maxWidth) {
84972
85047
  };
84973
85048
  } else {
84974
85049
  const boundarySpacing = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
84975
- if (currentLine.width + boundarySpacing + spacesWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0) {
85050
+ if (currentLine.width + boundarySpacing + spacesWidth > currentLine.maxWidth - WIDTH_FUDGE_PX2 && currentLine.width > 0) {
84976
85051
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
84977
85052
  const { spaceCount: _sc, ...lineBase } = currentLine;
84978
85053
  const completedLine = {
@@ -84992,7 +85067,7 @@ async function measureParagraphBlock(block, maxWidth) {
84992
85067
  width: spacesWidth,
84993
85068
  maxFontSize: run2.fontSize,
84994
85069
  maxFontInfo: getFontInfoFromRun(run2),
84995
- maxWidth: getEffectiveWidth(contentWidth),
85070
+ maxWidth: getEffectiveWidth(bodyContentWidth),
84996
85071
  segments: [{ runIndex, fromChar: spacesStartChar, toChar: spacesEndChar, width: spacesWidth }],
84997
85072
  spaceCount: spacesLength
84998
85073
  };
@@ -85038,7 +85113,7 @@ async function measureParagraphBlock(block, maxWidth) {
85038
85113
  };
85039
85114
  } else {
85040
85115
  const boundarySpacing2 = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
85041
- if (currentLine.width + boundarySpacing2 + singleSpaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0) {
85116
+ if (currentLine.width + boundarySpacing2 + singleSpaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX2 && currentLine.width > 0) {
85042
85117
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
85043
85118
  const { spaceCount: _sc, ...lineBase } = currentLine;
85044
85119
  const completedLine = { ...lineBase, ...metrics };
@@ -85055,7 +85130,7 @@ async function measureParagraphBlock(block, maxWidth) {
85055
85130
  width: singleSpaceWidth,
85056
85131
  maxFontSize: run2.fontSize,
85057
85132
  maxFontInfo: getFontInfoFromRun(run2),
85058
- maxWidth: getEffectiveWidth(contentWidth),
85133
+ maxWidth: getEffectiveWidth(bodyContentWidth),
85059
85134
  segments: [{ runIndex, fromChar: spaceStartChar, toChar: spaceEndChar, width: singleSpaceWidth }],
85060
85135
  spaceCount: 1
85061
85136
  };
@@ -85096,7 +85171,7 @@ async function measureParagraphBlock(block, maxWidth) {
85096
85171
  const hasTabOnlyLine = currentLine && currentLine.segments.length === 0 && currentLine.width > 0;
85097
85172
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
85098
85173
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
85099
- const chunks = breakWordIntoChunks(word, chunkWidth - WIDTH_FUDGE_PX, font, ctx2, run2);
85174
+ const chunks = breakWordIntoChunks(word, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
85100
85175
  let chunkCharOffset = wordStartChar;
85101
85176
  for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
85102
85177
  const chunk = chunks[chunkIndex];
@@ -85118,7 +85193,7 @@ async function measureParagraphBlock(block, maxWidth) {
85118
85193
  });
85119
85194
  if (isLastChunk) {
85120
85195
  const ls = run2.letterSpacing ?? 0;
85121
- if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX) {
85196
+ if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX2) {
85122
85197
  currentLine.toChar = wordEndWithSpace;
85123
85198
  currentLine.width = roundValue(currentLine.width + spaceWidth + ls);
85124
85199
  charPosInRun = wordEndWithSpace;
@@ -85150,7 +85225,7 @@ async function measureParagraphBlock(block, maxWidth) {
85150
85225
  spaceCount: 0
85151
85226
  };
85152
85227
  const ls = run2.letterSpacing ?? 0;
85153
- if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX) {
85228
+ if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX2) {
85154
85229
  currentLine.toChar = wordEndWithSpace;
85155
85230
  currentLine.width = roundValue(currentLine.width + spaceWidth + ls);
85156
85231
  charPosInRun = wordEndWithSpace;
@@ -85192,7 +85267,7 @@ async function measureParagraphBlock(block, maxWidth) {
85192
85267
  spaceCount: 0
85193
85268
  };
85194
85269
  const ls = run2.letterSpacing ?? 0;
85195
- if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX) {
85270
+ if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX2) {
85196
85271
  currentLine.toChar = wordEndWithSpace;
85197
85272
  currentLine.width = roundValue(currentLine.width + spaceWidth + ls);
85198
85273
  charPosInRun = wordEndWithSpace;
@@ -85207,7 +85282,7 @@ async function measureParagraphBlock(block, maxWidth) {
85207
85282
  const justifyAlignment = block.attrs?.alignment === "justify";
85208
85283
  const totalWidthWithWord = currentLine.width + boundarySpacing + wordCommitWidth + // Safe cast: only TextRuns produce word segments from split(), other run types are handled earlier
85209
85284
  (isLastWord ? 0 : run2.letterSpacing ?? 0);
85210
- const availableWidth = currentLine.maxWidth - WIDTH_FUDGE_PX;
85285
+ const availableWidth = currentLine.maxWidth - WIDTH_FUDGE_PX2;
85211
85286
  let shouldBreak = currentLine.width + boundarySpacing + wordOnlyWidth > availableWidth && currentLine.width > 0 && !isTocEntry;
85212
85287
  let compressedWidth = null;
85213
85288
  if (shouldBreak && justifyAlignment) {
@@ -85248,11 +85323,11 @@ async function measureParagraphBlock(block, maxWidth) {
85248
85323
  width: wordOnlyWidth,
85249
85324
  maxFontSize: run2.fontSize,
85250
85325
  maxFontInfo: getFontInfoFromRun(run2),
85251
- maxWidth: getEffectiveWidth(contentWidth),
85326
+ maxWidth: getEffectiveWidth(bodyContentWidth),
85252
85327
  segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }],
85253
85328
  spaceCount: 0
85254
85329
  };
85255
- if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX) {
85330
+ if (!isLastWord && currentLine.width + spaceWidth <= currentLine.maxWidth - WIDTH_FUDGE_PX2) {
85256
85331
  currentLine.toChar = wordEndWithSpace;
85257
85332
  currentLine.width = roundValue(currentLine.width + spaceWidth + (run2.letterSpacing ?? 0));
85258
85333
  charPosInRun = wordEndWithSpace;
@@ -85262,7 +85337,7 @@ async function measureParagraphBlock(block, maxWidth) {
85262
85337
  }
85263
85338
  } else {
85264
85339
  currentLine.toRun = runIndex;
85265
- if (!isLastWord && currentLine.width + boundarySpacing + wordOnlyWidth + spaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX) {
85340
+ if (!isLastWord && currentLine.width + boundarySpacing + wordOnlyWidth + spaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX2) {
85266
85341
  currentLine.toChar = wordEndNoSpace;
85267
85342
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
85268
85343
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
@@ -85813,6 +85888,7 @@ const resolveLineHeight = (spacing, baseLineHeight) => {
85813
85888
  return Math.max(baseLineHeight, raw);
85814
85889
  };
85815
85890
  const sanitizePositive = (value) => typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
85891
+ const sanitizeIndent = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
85816
85892
  const sanitizeDecimalSeparator = (value) => {
85817
85893
  if (value === ",") return ",";
85818
85894
  return DEFAULT_DECIMAL_SEPARATOR;
@@ -90361,6 +90437,10 @@ resolveLayoutOptions_fn = function(blocks, sectionMetadata) {
90361
90437
  const pageSize = firstSection?.pageSize ?? defaults.pageSize;
90362
90438
  const margins = {
90363
90439
  ...defaults.margins,
90440
+ ...firstSection?.margins?.top != null ? { top: firstSection.margins.top } : {},
90441
+ ...firstSection?.margins?.right != null ? { right: firstSection.margins.right } : {},
90442
+ ...firstSection?.margins?.bottom != null ? { bottom: firstSection.margins.bottom } : {},
90443
+ ...firstSection?.margins?.left != null ? { left: firstSection.margins.left } : {},
90364
90444
  ...firstSection?.margins?.header != null ? { header: firstSection.margins.header } : {},
90365
90445
  ...firstSection?.margins?.footer != null ? { footer: firstSection.margins.footer } : {}
90366
90446
  };