reamkit 1.32.0 → 1.33.0

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 (157) hide show
  1. package/README.md +5 -4
  2. package/dist/esm/core/bidi/algorithm.js +2 -2
  3. package/dist/esm/core/bidi/char-types.js +1 -1
  4. package/dist/esm/core/bidi/index.js +3 -3
  5. package/dist/esm/core/bytes.js +1 -1
  6. package/dist/esm/core/converter/facade.js +3 -2
  7. package/dist/esm/core/converter/ream.js +12 -5
  8. package/dist/esm/core/crypto/asn1.js +2 -2
  9. package/dist/esm/core/crypto/cms.js +5 -3
  10. package/dist/esm/core/crypto/index.js +2 -1
  11. package/dist/esm/core/crypto/offcrypto.js +64 -19
  12. package/dist/esm/core/crypto/primitives.js +16 -16
  13. package/dist/esm/core/document-model/index.d.ts +1 -1
  14. package/dist/esm/core/document-model/types.d.ts +174 -2
  15. package/dist/esm/core/drawingml/chart-geometry.d.ts +45 -17
  16. package/dist/esm/core/drawingml/chart-geometry.js +1090 -257
  17. package/dist/esm/core/drawingml/chart-parser.d.ts +24 -1
  18. package/dist/esm/core/drawingml/chart-parser.js +334 -41
  19. package/dist/esm/core/drawingml/chart-text.d.ts +41 -0
  20. package/dist/esm/core/drawingml/chart-text.js +93 -0
  21. package/dist/esm/core/drawingml/colors.js +5 -5
  22. package/dist/esm/core/drawingml/diagram/layout-engine.js +1 -4
  23. package/dist/esm/core/drawingml/diagram/run.js +2 -1
  24. package/dist/esm/core/drawingml/preset-geometry.js +4 -6
  25. package/dist/esm/core/drawingml/shape-render.js +1 -1
  26. package/dist/esm/core/drawingml/text-warp.js +4 -16
  27. package/dist/esm/core/drawingml/theme-parser.js +14 -8
  28. package/dist/esm/core/font/arabic-joining.js +2 -2
  29. package/dist/esm/core/font/binary-reader.js +2 -0
  30. package/dist/esm/core/font/font-registry.js +1 -0
  31. package/dist/esm/core/font/ligatures.js +1 -1
  32. package/dist/esm/core/font/opentype-layout.js +11 -5
  33. package/dist/esm/core/font/ttf-build.js +6 -10
  34. package/dist/esm/core/font/ttf-parser.js +2 -1
  35. package/dist/esm/core/font/ttf-subset.js +8 -8
  36. package/dist/esm/core/fonts/families.js +1 -1
  37. package/dist/esm/core/fonts/remote-fonts.js +4 -4
  38. package/dist/esm/core/hyphenation/index.js +1 -1
  39. package/dist/esm/core/images.js +8 -8
  40. package/dist/esm/core/ir/loss.js +1 -0
  41. package/dist/esm/core/line-breaker/cjk.js +1 -1
  42. package/dist/esm/core/line-breaker/index.js +4 -3
  43. package/dist/esm/core/links.js +1 -1
  44. package/dist/esm/core/lzw.js +1 -1
  45. package/dist/esm/core/metafile/blit.js +1 -1
  46. package/dist/esm/core/metafile/emf.js +5 -7
  47. package/dist/esm/core/metafile/picture.js +1 -1
  48. package/dist/esm/core/metafile/symbol-fonts.js +7 -7
  49. package/dist/esm/core/metafile/wmf.js +5 -7
  50. package/dist/esm/core/number-format.d.ts +40 -15
  51. package/dist/esm/core/number-format.js +284 -79
  52. package/dist/esm/core/numbering/index.js +3 -2
  53. package/dist/esm/core/ole/cfb.js +4 -4
  54. package/dist/esm/core/ole/escher-blip.js +1 -1
  55. package/dist/esm/core/opc/index.js +5 -4
  56. package/dist/esm/core/opc/package.js +3 -1
  57. package/dist/esm/core/opc/tag-scan.d.ts +15 -0
  58. package/dist/esm/core/opc/tag-scan.js +41 -0
  59. package/dist/esm/core/opc/xml-entities.js +40 -3
  60. package/dist/esm/core/outline.js +1 -1
  61. package/dist/esm/core/png-encode.js +3 -3
  62. package/dist/esm/core/po-helpers.js +1 -1
  63. package/dist/esm/core/spreadsheet-model/types.d.ts +6 -0
  64. package/dist/esm/core/style-cascade/index.js +4 -3
  65. package/dist/esm/core/tiff.js +3 -1
  66. package/dist/esm/excel/activex-parser.js +1 -1
  67. package/dist/esm/excel/conditional-format.js +7 -7
  68. package/dist/esm/excel/formula/functions.js +45 -18
  69. package/dist/esm/excel/formula/index.js +3 -3
  70. package/dist/esm/excel/formula/lexer.js +2 -2
  71. package/dist/esm/excel/formula/parser.js +4 -3
  72. package/dist/esm/excel/formula/value.js +1 -1
  73. package/dist/esm/excel/index.js +7 -6
  74. package/dist/esm/excel/print-model.js +18 -7
  75. package/dist/esm/excel/printer-settings.js +6 -7
  76. package/dist/esm/excel/rich-value.js +1 -1
  77. package/dist/esm/excel/sheet-shape-parser.js +4 -2
  78. package/dist/esm/excel/sheet-to-flow.js +13 -11
  79. package/dist/esm/excel/styles-parser.js +5 -3
  80. package/dist/esm/excel/tint.js +5 -5
  81. package/dist/esm/excel/vml-drawing.js +3 -3
  82. package/dist/esm/excel/worksheet-parser.js +5 -5
  83. package/dist/esm/excel/xls/biff-chart.js +1 -3
  84. package/dist/esm/excel/xls/biff-reader.js +10 -11
  85. package/dist/esm/excel/xls/xls-reader.js +1 -1
  86. package/dist/esm/excel/xlsx-reader.js +56 -9
  87. package/dist/esm/excel/xlsx-to-pdf.js +1 -1
  88. package/dist/esm/excel/xlsx-writer.js +2 -2
  89. package/dist/esm/html/html-writer.js +18 -10
  90. package/dist/esm/layout/line-paint.js +1 -1
  91. package/dist/esm/layout/math-layout.js +5 -8
  92. package/dist/esm/layout/styled-layout.js +104 -32
  93. package/dist/esm/layout/turned-section.js +2 -2
  94. package/dist/esm/markdown/markdown-writer.js +59 -8
  95. package/dist/esm/pdf/encryption.js +9 -9
  96. package/dist/esm/pdf/icc-profile.js +2 -2
  97. package/dist/esm/pdf/index.js +3 -2
  98. package/dist/esm/pdf/objects.js +7 -0
  99. package/dist/esm/pdf/serialize.js +1 -1
  100. package/dist/esm/pdf/struct-tree.js +3 -1
  101. package/dist/esm/pdf/styled-page-emitter.js +23 -15
  102. package/dist/esm/pdf/styled-page-renderer.js +9 -5
  103. package/dist/esm/pdf-reader/annot-draw.js +5 -5
  104. package/dist/esm/pdf-reader/annots.js +3 -1
  105. package/dist/esm/pdf-reader/ccitt.js +2 -1
  106. package/dist/esm/pdf-reader/cff-outline.js +1 -4
  107. package/dist/esm/pdf-reader/content.js +13 -15
  108. package/dist/esm/pdf-reader/decrypt.js +5 -4
  109. package/dist/esm/pdf-reader/document.js +6 -2
  110. package/dist/esm/pdf-reader/encodings.js +1 -1
  111. package/dist/esm/pdf-reader/flow-build.js +4 -6
  112. package/dist/esm/pdf-reader/font.js +4 -4
  113. package/dist/esm/pdf-reader/function.js +8 -7
  114. package/dist/esm/pdf-reader/icc.js +1 -1
  115. package/dist/esm/pdf-reader/images.js +1 -1
  116. package/dist/esm/pdf-reader/jbig2.js +36 -38
  117. package/dist/esm/pdf-reader/jpeg.js +14 -13
  118. package/dist/esm/pdf-reader/layout.js +13 -10
  119. package/dist/esm/pdf-reader/lexer.js +2 -1
  120. package/dist/esm/pdf-reader/math-rows.js +2 -2
  121. package/dist/esm/pdf-reader/optional-content.js +1 -1
  122. package/dist/esm/pdf-reader/page-numbers.js +1 -1
  123. package/dist/esm/pdf-reader/pattern-tint.js +1 -2
  124. package/dist/esm/pdf-reader/reader.js +2 -2
  125. package/dist/esm/pdf-reader/struct-tree.js +1 -1
  126. package/dist/esm/pdf-reader/tagged.js +3 -2
  127. package/dist/esm/pdf-reader/text.js +2 -2
  128. package/dist/esm/pdf-reader/type1-outline.js +1 -3
  129. package/dist/esm/pptx/embedded-fonts.js +3 -5
  130. package/dist/esm/pptx/placeholder-cascade.js +1 -1
  131. package/dist/esm/pptx/ppt/ppt-reader.js +5 -4
  132. package/dist/esm/pptx/ppt/ppt-text.js +9 -10
  133. package/dist/esm/pptx/pptx-reader.js +6 -5
  134. package/dist/esm/pptx/preset-table-styles.js +1 -1
  135. package/dist/esm/pptx/slide-parser.js +6 -4
  136. package/dist/esm/pptx/sp-helpers.js +1 -1
  137. package/dist/esm/pptx/table-style.js +2 -1
  138. package/dist/esm/svg/svg-writer.js +1 -1
  139. package/dist/esm/word/doc/doc-reader.js +2 -2
  140. package/dist/esm/word/doc/doc-text.js +20 -22
  141. package/dist/esm/word/document-parser.js +27 -22
  142. package/dist/esm/word/docx-reader.js +15 -10
  143. package/dist/esm/word/docx-to-pdf.js +6 -6
  144. package/dist/esm/word/docx-writer.js +10 -6
  145. package/dist/esm/word/drawing-parser.js +18 -18
  146. package/dist/esm/word/font-table.js +90 -11
  147. package/dist/esm/word/index.js +6 -5
  148. package/dist/esm/word/numbering-parser.js +5 -4
  149. package/dist/esm/word/omml-parser.js +1 -1
  150. package/dist/esm/word/paragraph-properties.js +11 -10
  151. package/dist/esm/word/run-properties.js +4 -4
  152. package/dist/esm/word/settings-parser.js +2 -1
  153. package/dist/esm/word/shading.js +1 -1
  154. package/dist/esm/word/styles-parser.js +5 -4
  155. package/dist/esm/word/table-parser.js +4 -4
  156. package/dist/esm/word/theme-fonts.js +1 -1
  157. package/package.json +10 -4
@@ -98,7 +98,7 @@ var WORD_LINE_METRICS = (() => {
98
98
  0,
99
99
  432
100
100
  ];
101
- return new Map([
101
+ return /* @__PURE__ */ new Map([
102
102
  ["calibri", [
103
103
  1950,
104
104
  0,
@@ -670,7 +670,7 @@ function layoutStyledDocument(body, options) {
670
670
  const commentNums = noteAssigned.comments;
671
671
  const threadDepth = (id) => {
672
672
  let depth = 0;
673
- const seen = new Set([id]);
673
+ const seen = /* @__PURE__ */ new Set([id]);
674
674
  let cur = options.comments?.get(id)?.parentId;
675
675
  while (cur !== void 0 && commentNums.has(cur) && !seen.has(cur)) {
676
676
  depth++;
@@ -926,6 +926,7 @@ function balancedColumnHeight(bandHeightPt, colCount, roomPt) {
926
926
  * between takes its share of both sides. Elsewhere the two add up.
927
927
  */
928
928
  var SpacingStack = class {
929
+ collapse;
929
930
  /** The space after the last block, which a paragraph right below may share. */
930
931
  shared = 0;
931
932
  constructor(collapse) {
@@ -1822,7 +1823,7 @@ function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorCh
1822
1823
  seq++;
1823
1824
  continue;
1824
1825
  }
1825
- const line = makeChartLabelLine(prim.text, font, sizePt, textHex ?? prim.colorHex);
1826
+ const line = makeChartLabelLine(prim.text, { font }, sizePt, textHex ?? prim.colorHex);
1826
1827
  const shift = prim.alignH === "center" ? -line.contentWidthPt / 2 : prim.alignH === "right" ? -line.contentWidthPt : 0;
1827
1828
  const baselineY = mapY(prim.y) - (prim.alignBaseline ? 0 : sizePt * .8);
1828
1829
  texts.push({
@@ -1854,8 +1855,8 @@ function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight
1854
1855
  }
1855
1856
  const chart = options.charts?.get(block.chartRelId);
1856
1857
  const { variant } = options.registry.resolveByStyle(false, false);
1857
- const font = fontResources.get(variant);
1858
- const layout = chart && font ? buildChartLayout(chart, widthPt, heightPt, font) : {
1858
+ const faceFor = chart ? chartFaceResolver(options, fontResources, fontResources.get(variant)) : void 0;
1859
+ const layout = chart && faceFor ? buildChartLayout(chart, widthPt, heightPt, faceFor) : {
1859
1860
  shapes: [],
1860
1861
  texts: []
1861
1862
  };
@@ -1882,8 +1883,54 @@ function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight
1882
1883
  ...block.float ? { float: block.float } : {}
1883
1884
  };
1884
1885
  }
1885
- function buildChartLayout(chart, widthPt, heightPt, font) {
1886
- const measure = (text, sizePt) => font.measure.textWidthPt(text, sizePt);
1886
+ /**
1887
+ * Where a chart's text finds its face: the family and weight the chart sets it
1888
+ * in, resolved as a run's are (runFontKeyAndParsed), and the document's base
1889
+ * face for text that names none — which is all of a chart's text unless its
1890
+ * reader resolved the chart's own (Chart.text).
1891
+ */
1892
+ function chartFaceResolver(options, fontResources, base) {
1893
+ const fallback = base ?? fontResources.values().next().value;
1894
+ if (!fallback) return void 0;
1895
+ return (font) => {
1896
+ if (!font || font.family === void 0 && !font.bold && !font.italic) return { font: fallback };
1897
+ const { fontKey, synthetic } = runFontKeyAndParsed(options, font.family, font.bold === true, font.italic === true);
1898
+ const resource = fontResources.get(fontKey);
1899
+ return resource ? {
1900
+ font: resource,
1901
+ ...synthetic ? { synthetic } : {}
1902
+ } : { font: fallback };
1903
+ };
1904
+ }
1905
+ /**
1906
+ * The faces a chart's text is drawn in, one per distinct family and weight;
1907
+ * `undefined` stands for the document's base face, which text naming none is
1908
+ * drawn in.
1909
+ */
1910
+ function chartFonts(chart) {
1911
+ if (!chart.text) return [void 0];
1912
+ const seen = /* @__PURE__ */ new Map();
1913
+ let base = false;
1914
+ for (const style of Object.values(chart.text)) {
1915
+ if (!style) continue;
1916
+ if (style.family === void 0 && !style.bold && !style.italic) {
1917
+ base = true;
1918
+ continue;
1919
+ }
1920
+ const font = {
1921
+ ...style.family !== void 0 ? { family: style.family } : {},
1922
+ ...style.bold ? { bold: true } : {},
1923
+ ...style.italic ? { italic: true } : {}
1924
+ };
1925
+ seen.set(`${font.family ?? ""}|${font.bold === true}|${font.italic === true}`, font);
1926
+ }
1927
+ return base ? [void 0, ...seen.values()] : [...seen.values()];
1928
+ }
1929
+ function buildChartLayout(chart, widthPt, heightPt, faceFor) {
1930
+ const measure = (text, sizePt, font) => {
1931
+ const face = faceFor(font);
1932
+ return face.font.measure.textWidthPt(text, sizePt) * (face.synthetic?.widthScale ?? 1);
1933
+ };
1887
1934
  const scene = buildChartScene(chart, widthPt, heightPt, measure);
1888
1935
  if (!scene) return {
1889
1936
  shapes: [{
@@ -1898,6 +1945,7 @@ function buildChartLayout(chart, widthPt, heightPt, font) {
1898
1945
  const shapes = [];
1899
1946
  if (scene.background) shapes.push(rectPrim(scene.background));
1900
1947
  if (scene.plotBackground) shapes.push(rectPrim(scene.plotBackground));
1948
+ for (const w of scene.walls ?? []) shapes.push(polygonPrim(w));
1901
1949
  for (const g of scene.gridlines ?? []) shapes.push(polylinePrim(g));
1902
1950
  for (const pg of scene.polygons ?? []) shapes.push(polygonPrim(pg));
1903
1951
  for (const r of scene.rects) shapes.push(rectPrim(r));
@@ -1905,7 +1953,7 @@ function buildChartLayout(chart, widthPt, heightPt, font) {
1905
1953
  for (const w of scene.wedges) shapes.push(wedgePrim(w));
1906
1954
  return {
1907
1955
  shapes,
1908
- texts: scene.labels.map((l) => labelPrim(l, font))
1956
+ texts: scene.labels.map((l) => labelPrim(l, faceFor(l)))
1909
1957
  };
1910
1958
  }
1911
1959
  function rectAtPath(x, y, w, h) {
@@ -2061,7 +2109,7 @@ function polygonPrim(p) {
2061
2109
  b.close();
2062
2110
  return {
2063
2111
  paths: [b.build()],
2064
- fillColorHex: p.fillHex,
2112
+ ...p.fillHex ? { fillColorHex: p.fillHex } : {},
2065
2113
  ...p.strokeHex ? { stroke: {
2066
2114
  colorHex: p.strokeHex,
2067
2115
  widthPt: p.widthPt ?? 1
@@ -2079,8 +2127,8 @@ function wedgePrim(w) {
2079
2127
  } } : {}
2080
2128
  };
2081
2129
  }
2082
- function labelPrim(l, font) {
2083
- const line = makeChartLabelLine(l.text, font, l.sizePt, l.colorHex);
2130
+ function labelPrim(l, face) {
2131
+ const line = makeChartLabelLine(l.text, face, l.sizePt, l.colorHex);
2084
2132
  const w = line.contentWidthPt;
2085
2133
  const shift = l.align === "center" ? -w / 2 : l.align === "right" ? -w : 0;
2086
2134
  if (l.rotationDeg) return {
@@ -2095,8 +2143,9 @@ function labelPrim(l, font) {
2095
2143
  y: l.y
2096
2144
  };
2097
2145
  }
2098
- function makeChartLabelLine(text, font, sizePt, colorHex) {
2099
- const widthPt = font.measure.textWidthPt(text, sizePt);
2146
+ function makeChartLabelLine(text, face, sizePt, colorHex) {
2147
+ const { font, synthetic } = face;
2148
+ const widthPt = font.measure.textWidthPt(text, sizePt) * (synthetic?.widthScale ?? 1);
2100
2149
  return {
2101
2150
  tokens: [{
2102
2151
  kind: "text",
@@ -2110,7 +2159,8 @@ function makeChartLabelLine(text, font, sizePt, colorHex) {
2110
2159
  font,
2111
2160
  fontSizePt: sizePt,
2112
2161
  widthPt,
2113
- bidiLevel: 0
2162
+ bidiLevel: 0,
2163
+ ...synthetic ? { synthetic } : {}
2114
2164
  }],
2115
2165
  contentWidthPt: widthPt,
2116
2166
  maxFontSizePt: sizePt,
@@ -2862,7 +2912,8 @@ function runFontKeyAndParsed(options, ascii, bold, italic) {
2862
2912
  function fallbackFaceKey(options, cp, bold, italic) {
2863
2913
  const byFamily = options.registriesByFamily;
2864
2914
  if (!byFamily || byFamily.size === 0) return void 0;
2865
- const script = scriptForCodepoint(cp, byFamily.has("jp") ? "jp" : byFamily.has("kr") ? "kr" : "sc");
2915
+ const hanFace = byFamily.has("jp") ? "jp" : byFamily.has("kr") ? "kr" : "sc";
2916
+ const script = scriptForCodepoint(cp, hanFace);
2866
2917
  const order = script ? [script] : [];
2867
2918
  for (const key of byFamily.keys()) if (key !== script) order.push(key);
2868
2919
  for (const key of order) {
@@ -3156,17 +3207,26 @@ function collectFontResources(body, headersFooters, options, imageResources) {
3156
3207
  else {
3157
3208
  const chart = options.charts?.get(el.chart.chartRelId);
3158
3209
  if (chart) {
3159
- const reg = options.registry.resolveByStyle(false, false);
3160
- let bucket = used.get(reg.variant);
3161
- if (!bucket) {
3162
- bucket = {
3163
- parsed: reg.parsed,
3164
- gids: /* @__PURE__ */ new Set()
3165
- };
3166
- used.set(reg.variant, bucket);
3167
- }
3210
+ const buckets = chartFonts(chart).map((font) => {
3211
+ const face = font === void 0 ? (() => {
3212
+ const reg = options.registry.resolveByStyle(false, false);
3213
+ return {
3214
+ fontKey: reg.variant,
3215
+ parsed: reg.parsed
3216
+ };
3217
+ })() : runFontKeyAndParsed(options, font.family, font.bold === true, font.italic === true);
3218
+ let bucket = used.get(face.fontKey);
3219
+ if (!bucket) {
3220
+ bucket = {
3221
+ parsed: face.parsed,
3222
+ gids: /* @__PURE__ */ new Set()
3223
+ };
3224
+ used.set(face.fontKey, bucket);
3225
+ }
3226
+ return bucket;
3227
+ });
3168
3228
  const add = (s) => {
3169
- for (const ch of s) bucket.gids.add(reg.parsed.glyphForCodepoint(ch.codePointAt(0)));
3229
+ for (const bucket of buckets) for (const ch of s) bucket.gids.add(bucket.parsed.glyphForCodepoint(ch.codePointAt(0)));
3170
3230
  };
3171
3231
  if (chart.title) add(chart.title);
3172
3232
  for (const c of chart.categories) add(c);
@@ -3174,7 +3234,7 @@ function collectFontResources(body, headersFooters, options, imageResources) {
3174
3234
  if (chart.catAxisTitle) add(chart.catAxisTitle);
3175
3235
  if (chart.valAxisTitle) add(chart.valAxisTitle);
3176
3236
  for (const sr of chart.series) for (const label of sr.pointLabels ?? []) add(label.text);
3177
- add("0123456789.,-%() ");
3237
+ add("0123456789.,-+E%() ");
3178
3238
  if (chart.numberFormat) add(chart.numberFormat);
3179
3239
  }
3180
3240
  }
@@ -3766,7 +3826,7 @@ function paragraphMaxWidth(p, contentWidth, firstLine) {
3766
3826
  const firstLineExtra = firstLine ? p.indentFirstLine : 0;
3767
3827
  return Math.max(1, contentWidth - indentLeft - indentRight - firstLineExtra);
3768
3828
  }
3769
- var HYPHENS = new Set([
3829
+ var HYPHENS = /* @__PURE__ */ new Set([
3770
3830
  45,
3771
3831
  8208,
3772
3832
  8211,
@@ -3960,7 +4020,7 @@ function paragraphItemStream(tokens, hyphenator, maxLineWidthPt) {
3960
4020
  }
3961
4021
  /** Word's own default when a document names none (§17.15.1.25): half an inch. */
3962
4022
  var DEFAULT_TAB_STOP_PT = 36;
3963
- var TAB_LEADER_CHARS = new Map([
4023
+ var TAB_LEADER_CHARS = /* @__PURE__ */ new Map([
3964
4024
  ["dot", "."],
3965
4025
  ["hyphen", "-"],
3966
4026
  ["underscore", "_"],
@@ -5116,6 +5176,11 @@ function listItemParagraphNode(builder, stack, list, wantLbl) {
5116
5176
  * bodies move unchanged.
5117
5177
  */
5118
5178
  var PageAssembler = class PageAssembler {
5179
+ sectionCtxs;
5180
+ builder;
5181
+ notes;
5182
+ bookmarkPositions;
5183
+ backgroundImage;
5119
5184
  /**
5120
5185
  * @param sectionCtxs The per-section render contexts, in order; assembly
5121
5186
  * starts on the first section's first page.
@@ -5892,6 +5957,9 @@ var PageAssembler = class PageAssembler {
5892
5957
  * every page that repeats them — which is what Excel prints.
5893
5958
  */
5894
5959
  var SheetView = class {
5960
+ overlay;
5961
+ tableX;
5962
+ builder;
5895
5963
  runs = [];
5896
5964
  figures = /* @__PURE__ */ new Map();
5897
5965
  /**
@@ -6518,13 +6586,15 @@ function emitRowChunk(out, row, marginLeft, cursorY, pageHeight, colCount, cellS
6518
6586
  if (cell.icon && cell.mergeRole !== "middle" && cell.mergeRole !== "end") {
6519
6587
  const iconSize = Math.min(CF_ICON_SIZE_PT, Math.max(0, row.heightPt - 1));
6520
6588
  if (iconSize > 0) {
6589
+ const iconX = cellX + (CF_ICON_GUTTER_PT - iconSize) / 2;
6590
+ const iconBottomYUp = rowBottom + (row.heightPt - iconSize) / 2;
6521
6591
  const iconTransform = flipTransform([
6522
6592
  1,
6523
6593
  0,
6524
6594
  0,
6525
6595
  1,
6526
- cellX + (CF_ICON_GUTTER_PT - iconSize) / 2,
6527
- rowBottom + (row.heightPt - iconSize) / 2
6596
+ iconX,
6597
+ iconBottomYUp
6528
6598
  ], pageHeight);
6529
6599
  for (const prim of buildCellIconShape(cell.icon, iconSize)) out.push({
6530
6600
  type: "shape",
@@ -6540,13 +6610,15 @@ function emitRowChunk(out, row, marginLeft, cursorY, pageHeight, colCount, cellS
6540
6610
  if (cell.dropdown && cell.mergeRole !== "middle" && cell.mergeRole !== "end") {
6541
6611
  const btn = Math.min(DROPDOWN_BUTTON_PT, Math.max(0, row.heightPt - 2));
6542
6612
  if (btn > 1) {
6613
+ const btnX = cellX + cell.widthPt - btn - 1.5;
6614
+ const btnBottomYUp = rowBottom + (row.heightPt - btn) / 2;
6543
6615
  const btnTransform = flipTransform([
6544
6616
  1,
6545
6617
  0,
6546
6618
  0,
6547
6619
  1,
6548
- cellX + cell.widthPt - btn - 1.5,
6549
- rowBottom + (row.heightPt - btn) / 2
6620
+ btnX,
6621
+ btnBottomYUp
6550
6622
  ], pageHeight);
6551
6623
  for (const prim of buildDropdownPrims(btn)) out.push({
6552
6624
  type: "shape",
@@ -1,7 +1,7 @@
1
1
  import { pt } from "../core/ir/units.js";
2
2
  //#region src/layout/turned-section.ts
3
3
  /** A quarter turn in the 1/60000° a DrawingML rotation is stated in (§20.1.7.6). */
4
- var QUARTER_60K = 90 * 6e4;
4
+ var QUARTER_60K = 54e5;
5
5
  /**
6
6
  * One item of a turned section's body, carried from the frame the text reads
7
7
  * in onto the sheet: a point `(x, y)` of the frame (top-left origin, y down)
@@ -161,7 +161,7 @@ function floatIntoFrame(el, sheet) {
161
161
  }
162
162
  /** A clockwise turn with a quarter taken off, kept in the one full turn. */
163
163
  function backedOff(rotation60k) {
164
- const full = 360 * 6e4;
164
+ const full = 216e5;
165
165
  return (((rotation60k ?? 0) - QUARTER_60K) % full + full) % full;
166
166
  }
167
167
  /**
@@ -51,7 +51,7 @@ function writeMarkdown(flow, options = {}) {
51
51
  var markdownWriter = {
52
52
  id: "md",
53
53
  consumes: "flow",
54
- supports: new Set([
54
+ supports: /* @__PURE__ */ new Set([
55
55
  FEATURES.text,
56
56
  FEATURES.lists,
57
57
  FEATURES.tables,
@@ -82,9 +82,29 @@ function lose(ctx, severity, feature, detail) {
82
82
  */
83
83
  function joinBlocks(blocks) {
84
84
  const body = blocks.map(trimHardBreaks).filter((b) => b.length > 0).join("\n\n");
85
- return body.length > 0 ? `${body.replace(/[ \t]+$/gm, "")}\n` : "";
85
+ return body.length > 0 ? `${trimLineEnds(body)}\n` : "";
86
86
  }
87
87
  /**
88
+ * The text without the spaces and tabs that end its lines — what
89
+ * `/[ \t]+$/gm` leaves, a line ending wherever `$` does under `m`: at LF, CR,
90
+ * U+2028, U+2029 and the end of the text. The expression retries every blank
91
+ * of a long run that something else follows, and is quadratic on it; this is
92
+ * one pass.
93
+ */
94
+ function trimLineEnds(text) {
95
+ const out = [];
96
+ let start = 0;
97
+ for (let i = 0; i <= text.length; i++) {
98
+ if (i < text.length && !isLineEnd(text.charCodeAt(i))) continue;
99
+ let end = i;
100
+ while (end > start && (text[end - 1] === " " || text[end - 1] === " ")) end--;
101
+ out.push(text.slice(start, end), text.slice(i, i + 1));
102
+ start = i + 1;
103
+ }
104
+ return out.join("");
105
+ }
106
+ var isLineEnd = (c) => c === 10 || c === 13 || c === 8232 || c === 8233;
107
+ /**
88
108
  * Drop a hard break sitting at either end of a block: at the end there is no
89
109
  * next line to break to, at the start no previous one, and either way the
90
110
  * backslash is left standing in the text as itself. Only a break is taken —
@@ -218,7 +238,7 @@ function emitListItem(out, resolved, marker, inline, ctx) {
218
238
  top.markerWidth = bullet.length + 1;
219
239
  const pad = " ".repeat(top.indent);
220
240
  const cont = " ".repeat(top.indent + top.markerWidth);
221
- const line = `${pad}${bullet} ${inline.replaceAll("\\\n", `\\\n${cont}`)}`.replace(/\s+$/, "");
241
+ const line = `${pad}${bullet} ${inline.replaceAll("\\\n", `\\\n${cont}`)}`.trimEnd();
222
242
  if (wasOpen && out.length > 0) out[out.length - 1] += `\n${line}`;
223
243
  else out.push(line);
224
244
  }
@@ -232,9 +252,24 @@ function listBullet(marker, numId, ilvl, counter, ctx) {
232
252
  const level = numberingLevel(numId, ilvl, ctx.numbering);
233
253
  if (!(level ? level.format !== "bullet" && level.format !== "none" : /\d/.test(marker))) return "-";
234
254
  if (level && level.format !== "decimal" && level.format !== "decimalZero") lose(ctx, "degraded", FEATURES.lists, `${level.format} list markers render as decimal`);
235
- const digits = /(\d+)\D*$/.exec(marker);
236
- if (marker.replace(/\D+/g, "").length > (digits?.[1]?.length ?? 0)) lose(ctx, "degraded", FEATURES.lists, "multi-level list marker flattened to one number");
237
- return `${digits ? Number(digits[1]) : counter}.`;
255
+ const digits = lastNumber(marker);
256
+ if (marker.replace(/\D+/g, "").length > (digits?.length ?? 0)) lose(ctx, "degraded", FEATURES.lists, "multi-level list marker flattened to one number");
257
+ return `${digits !== void 0 ? Number(digits) : counter}.`;
258
+ }
259
+ /**
260
+ * The last run of digits in a marker — what `/(\d+)\D*$/` matched, read back
261
+ * from the end: that expression tried every digit of a long run as its start.
262
+ * The template the marker comes from is the file's, so the run can be any
263
+ * length, and every item of the list reads it.
264
+ */
265
+ function lastNumber(marker) {
266
+ const isDigit = (i) => /\d/.test(marker[i] ?? "");
267
+ let end = marker.length;
268
+ while (end > 0 && !isDigit(end - 1)) end--;
269
+ if (end === 0) return void 0;
270
+ let start = end - 1;
271
+ while (start > 0 && isDigit(start - 1)) start--;
272
+ return marker.slice(start, end);
238
273
  }
239
274
  function numberingLevel(numId, ilvl, numbering) {
240
275
  if (!numbering) return void 0;
@@ -366,7 +401,7 @@ function destination(url) {
366
401
  * paragraph it belongs to — the same shape GFM's own heading anchors take.
367
402
  */
368
403
  function bookmarkSlug(name) {
369
- const slug = name.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "");
404
+ const slug = name.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((word) => word.length > 0).join("-");
370
405
  return slug.length > 0 ? slug : "bookmark";
371
406
  }
372
407
  /** The bookmark names some run actually links to — the only ones worth an anchor. */
@@ -684,7 +719,7 @@ var SPAN_EDGE = String.raw`(?:\\\n|\s)`;
684
719
  function applyMarks(text, marks, ctx, before, after) {
685
720
  const escaped = escapeInline(text);
686
721
  const lead = new RegExp(`^${SPAN_EDGE}*`).exec(escaped)?.[0] ?? "";
687
- const trail = new RegExp(`${SPAN_EDGE}*$`).exec(escaped)?.[0] ?? "";
722
+ const trail = trailingEdge(escaped);
688
723
  const core = escaped.slice(lead.length, escaped.length - trail.length);
689
724
  if (core.length === 0) return escaped;
690
725
  const outerBefore = lead.length > 0 ? lead[lead.length - 1] : before;
@@ -718,6 +753,22 @@ function applyMarks(text, marks, ctx, before, after) {
718
753
  }
719
754
  return `${lead}${linkify(out, marks, ctx)}${trail}`;
720
755
  }
756
+ /**
757
+ * The whitespace and hard breaks the escaped text ends in — what
758
+ * `${SPAN_EDGE}*$` matches, read back from the end instead. Tried from the
759
+ * front, that expression rescans a long run of whitespace from each of its
760
+ * characters whenever something other than the end follows the run, and is
761
+ * quadratic on it.
762
+ */
763
+ function trailingEdge(escaped) {
764
+ let from = escaped.length;
765
+ while (from > 0) {
766
+ const c = escaped[from - 1];
767
+ if (c === "\\" ? escaped[from] !== "\n" : !/\s/u.test(c)) break;
768
+ from--;
769
+ }
770
+ return escaped.slice(from);
771
+ }
721
772
  var isSpace = (c) => c === "" || /\s/u.test(c);
722
773
  var isPunct = (c) => /[\p{P}\p{S}]/u.test(c);
723
774
  /** §6.2 — the delimiter run is left-flanking, so it can open emphasis. */
@@ -82,20 +82,20 @@ async function hardHash(password, salt, userData) {
82
82
  async function preparePdfEncryption(options) {
83
83
  const user = passwordBytes(options.userPassword ?? "");
84
84
  const owner = passwordBytes(options.ownerPassword ?? options.userPassword ?? "");
85
- const fileKey = new Uint8Array(32);
85
+ const fileKey = /* @__PURE__ */ new Uint8Array(32);
86
86
  globalThis.crypto.getRandomValues(fileKey);
87
- const salts = new Uint8Array(36);
87
+ const salts = /* @__PURE__ */ new Uint8Array(36);
88
88
  globalThis.crypto.getRandomValues(salts);
89
89
  const uvs = salts.slice(0, 8);
90
90
  const uks = salts.slice(8, 16);
91
91
  const ovs = salts.slice(16, 24);
92
92
  const oks = salts.slice(24, 32);
93
- const U = concat(await hardHash(user, uvs, new Uint8Array(0)), uvs, uks);
94
- const UE = await aesCbcNoPad(await hardHash(user, uks, new Uint8Array(0)), new Uint8Array(16), fileKey);
93
+ const U = concat(await hardHash(user, uvs, /* @__PURE__ */ new Uint8Array(0)), uvs, uks);
94
+ const UE = await aesCbcNoPad(await hardHash(user, uks, /* @__PURE__ */ new Uint8Array(0)), /* @__PURE__ */ new Uint8Array(16), fileKey);
95
95
  const O = concat(await hardHash(owner, ovs, U), ovs, oks);
96
- const OE = await aesCbcNoPad(await hardHash(owner, oks, U), new Uint8Array(16), fileKey);
96
+ const OE = await aesCbcNoPad(await hardHash(owner, oks, U), /* @__PURE__ */ new Uint8Array(16), fileKey);
97
97
  const p = permissionBits(options.permissions);
98
- const permsPlain = new Uint8Array(16);
98
+ const permsPlain = /* @__PURE__ */ new Uint8Array(16);
99
99
  new DataView(permsPlain.buffer).setInt32(0, p, true);
100
100
  permsPlain.set([
101
101
  255,
@@ -110,7 +110,7 @@ async function preparePdfEncryption(options) {
110
110
  98
111
111
  ], 8);
112
112
  permsPlain.set(salts.slice(32, 36), 12);
113
- const perms = await aesCbcNoPad(fileKey, new Uint8Array(16), permsPlain);
113
+ const perms = await aesCbcNoPad(fileKey, /* @__PURE__ */ new Uint8Array(16), permsPlain);
114
114
  return {
115
115
  fileKey,
116
116
  encryptDict: dict({
@@ -136,7 +136,7 @@ async function preparePdfEncryption(options) {
136
136
  };
137
137
  }
138
138
  async function encryptBytes(fileKey, data) {
139
- const iv = new Uint8Array(16);
139
+ const iv = /* @__PURE__ */ new Uint8Array(16);
140
140
  globalThis.crypto.getRandomValues(iv);
141
141
  const k = await subtle.importKey("raw", fileKey, "AES-CBC", false, ["encrypt"]);
142
142
  return concat(iv, new Uint8Array(await subtle.encrypt({
@@ -177,4 +177,4 @@ async function encryptObjectGraph(value, fileKey) {
177
177
  return value;
178
178
  }
179
179
  //#endregion
180
- export { encryptObjectGraph, preparePdfEncryption };
180
+ export { encryptObjectGraph, hardHash, permissionBits, preparePdfEncryption };
@@ -53,7 +53,7 @@ function buildText(text) {
53
53
  return buf;
54
54
  }
55
55
  function buildXYZ(x, y, z) {
56
- const buf = new Uint8Array(20);
56
+ const buf = /* @__PURE__ */ new Uint8Array(20);
57
57
  const view = new DataView(buf.buffer);
58
58
  writeU32BE(view, 0, tag("XYZ "));
59
59
  writeU32BE(view, 4, 0);
@@ -159,7 +159,7 @@ function buildSrgbIccProfile() {
159
159
  view.setInt32(72, s15Fixed16(D50.y), false);
160
160
  view.setInt32(76, s15Fixed16(D50.z), false);
161
161
  writeU32BE(view, headerSize, tagCount);
162
- let p = headerSize + 4;
162
+ let p = 132;
163
163
  for (const e of entries) {
164
164
  const off = blockOffsets.get(e.data);
165
165
  writeU32BE(view, p, tag(e.sig));
@@ -2,5 +2,6 @@ import "./cid-font.js";
2
2
  import "./text-page-renderer.js";
3
3
  import "../core/images.js";
4
4
  import "./image-xobject.js";
5
- import "./signature.js";
6
- import "./styled-page-renderer.js";
5
+ import { signPdf } from "./signature.js";
6
+ import { renderStyledPdf, renderStyledPdfEncrypted } from "./styled-page-renderer.js";
7
+ export { renderStyledPdf, renderStyledPdfEncrypted, signPdf };
@@ -4,6 +4,7 @@ import { zlibSync } from "fflate";
4
4
  var PDF_NULL = Symbol("PDF_NULL");
5
5
  /** A PDF name object (§7.3.5), e.g. `/Type` — the leading slash is added on serialization. */
6
6
  var PdfName = class {
7
+ value;
7
8
  /** @param value The name's text, without the leading `/`. */
8
9
  constructor(value) {
9
10
  this.value = value;
@@ -11,6 +12,8 @@ var PdfName = class {
11
12
  };
12
13
  /** An indirect reference (§7.3.10), written `id gen R`. */
13
14
  var PdfRef = class {
15
+ id;
16
+ generation;
14
17
  /**
15
18
  * @param id The referenced object number.
16
19
  * @param generation The generation number (0 for freshly written objects).
@@ -22,6 +25,8 @@ var PdfRef = class {
22
25
  };
23
26
  /** A PDF stream object (§7.3.8): a dictionary plus its raw byte payload. */
24
27
  var PdfStream = class {
28
+ dict;
29
+ data;
25
30
  /**
26
31
  * @param dict The stream dictionary (`/Length` is filled in on serialization).
27
32
  * @param data The raw stream bytes.
@@ -37,6 +42,7 @@ var PdfStream = class {
37
42
  * UTF-16BE with a leading BOM, the PDF-standard form for Unicode strings.
38
43
  */
39
44
  var PdfHexString = class {
45
+ bytes;
40
46
  /** @param bytes The raw bytes to emit as hex. */
41
47
  constructor(bytes) {
42
48
  this.bytes = bytes;
@@ -48,6 +54,7 @@ var PdfHexString = class {
48
54
  * place after the byte offsets are known (ISO 32000 §12.8.1).
49
55
  */
50
56
  var PdfRawToken = class {
57
+ token;
51
58
  /** @param token The literal text to emit unchanged. */
52
59
  constructor(token) {
53
60
  this.token = token;
@@ -69,4 +69,4 @@ function serializeStreamObject(id, generation, s) {
69
69
  return out;
70
70
  }
71
71
  //#endregion
72
- export { serializeIndirectObject };
72
+ export { serializeIndirectObject, serializeValue };
@@ -2,6 +2,8 @@ import { PDF_NULL, dict, name, unicodeString } from "./objects.js";
2
2
  //#region src/pdf/struct-tree.ts
3
3
  /** One node in the logical structure tree: a {@link StructType} plus its children, marked-content and attributes. */
4
4
  var StructNode = class {
5
+ id;
6
+ type;
5
7
  children = [];
6
8
  mcrefs = [];
7
9
  /**
@@ -182,4 +184,4 @@ var StructTreeBuilder = class {
182
184
  }
183
185
  };
184
186
  //#endregion
185
- export { StructTreeBuilder };
187
+ export { StructNode, StructTreeBuilder };
@@ -348,7 +348,7 @@ function assembleStyledPdf(laid, options, doc) {
348
348
  });
349
349
  if (pageRefs.length === 0) {
350
350
  const fallback = sectionCtxs[0] ?? defaultPageCtx();
351
- const contentsRef = doc.add(stream({}, new Uint8Array(0)));
351
+ const contentsRef = doc.add(stream({}, /* @__PURE__ */ new Uint8Array(0)));
352
352
  const fallbackDict = dict({
353
353
  Type: name("Page"),
354
354
  Parent: ref(pagesRef.id),
@@ -372,17 +372,23 @@ function assembleStyledPdf(laid, options, doc) {
372
372
  Type: name("Catalog"),
373
373
  Pages: ref(pagesRef.id)
374
374
  };
375
- if (pdfaProfile) catalogEntries["OutputIntents"] = [ref(doc.add(dict({
376
- Type: name("OutputIntent"),
377
- S: name("GTS_PDFA1"),
378
- OutputConditionIdentifier: "sRGB",
379
- Info: "sRGB IEC61966-2.1",
380
- DestOutputProfile: ref(pdfaIccRef.id)
381
- })).id)];
382
- if (pdfaProfile || options.pdfUA) catalogEntries["Metadata"] = ref(doc.add(stream({
383
- Type: name("Metadata"),
384
- Subtype: name("XML")
385
- }, buildXmpPacket(xmpFromInfo(docInfo, pdfaProfile, options.pdfUA === true)))).id);
375
+ if (pdfaProfile) {
376
+ const outputIntentRef = doc.add(dict({
377
+ Type: name("OutputIntent"),
378
+ S: name("GTS_PDFA1"),
379
+ OutputConditionIdentifier: "sRGB",
380
+ Info: "sRGB IEC61966-2.1",
381
+ DestOutputProfile: ref(pdfaIccRef.id)
382
+ }));
383
+ catalogEntries["OutputIntents"] = [ref(outputIntentRef.id)];
384
+ }
385
+ if (pdfaProfile || options.pdfUA) {
386
+ const xmpRef = doc.add(stream({
387
+ Type: name("Metadata"),
388
+ Subtype: name("XML")
389
+ }, buildXmpPacket(xmpFromInfo(docInfo, pdfaProfile, options.pdfUA === true))));
390
+ catalogEntries["Metadata"] = ref(xmpRef.id);
391
+ }
386
392
  if (tagged && structBuilder) {
387
393
  const structRootRef = structBuilder.emit(doc, pageRefs);
388
394
  catalogEntries["MarkInfo"] = dict({ Marked: true });
@@ -399,7 +405,8 @@ function assembleStyledPdf(laid, options, doc) {
399
405
  const sorted = [...embedded].sort((a, b) => a.file.name < b.file.name ? -1 : a.file.name > b.file.name ? 1 : 0);
400
406
  const names = [];
401
407
  for (const e of sorted) names.push(e.file.name, ref(e.ref.id));
402
- namesTreeEntries["EmbeddedFiles"] = ref(doc.add(dict({ Names: names })).id);
408
+ const embeddedFilesRef = doc.add(dict({ Names: names }));
409
+ namesTreeEntries["EmbeddedFiles"] = ref(embeddedFilesRef.id);
403
410
  }
404
411
  const bookmarkDests = laid.pdf.bookmarks;
405
412
  const destNames = [...referencedAnchors].filter((n) => bookmarkDests.has(n)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
@@ -415,7 +422,8 @@ function assembleStyledPdf(laid, options, doc) {
415
422
  pos.yTopPt
416
423
  ]);
417
424
  }
418
- namesTreeEntries["Dests"] = ref(doc.add(dict({ Names: names })).id);
425
+ const destsRef = doc.add(dict({ Names: names }));
426
+ namesTreeEntries["Dests"] = ref(destsRef.id);
419
427
  }
420
428
  if (Object.keys(namesTreeEntries).length > 0) catalogEntries["Names"] = dict(namesTreeEntries);
421
429
  if (options.signaturePlaceholder && firstPageDict) {
@@ -655,7 +663,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
655
663
  const commands = page.commands;
656
664
  const links = [];
657
665
  if (commands.length === 0) return {
658
- content: new Uint8Array(0),
666
+ content: /* @__PURE__ */ new Uint8Array(0),
659
667
  links
660
668
  };
661
669
  const H = page.height;
@@ -1,6 +1,6 @@
1
1
  import { PdfDocument } from "./writer.js";
2
- import "../layout/page-doc.js";
3
- import { layoutStyledDocument } from "../layout/styled-layout.js";
2
+ import { pageItemBounds, pageLayers, paintPlan } from "../layout/page-doc.js";
3
+ import { GLUE_SHRINK_RATIO, layoutStyledDocument } from "../layout/styled-layout.js";
4
4
  import { emitStyledPdf, emitStyledPdfEncrypted } from "./styled-page-emitter.js";
5
5
  //#region src/pdf/styled-page-renderer.ts
6
6
  /**
@@ -12,7 +12,9 @@ import { emitStyledPdf, emitStyledPdfEncrypted } from "./styled-page-emitter.js"
12
12
  */
13
13
  function renderStyledPdf(body, options) {
14
14
  if (options.encrypt) throw new Error("PDF encryption requires the async conversion path (WebCrypto)");
15
- return emitStyledPdf(layoutStyledDocument(body, options), options, new PdfDocument());
15
+ const laid = layoutStyledDocument(body, options);
16
+ const doc = new PdfDocument();
17
+ return emitStyledPdf(laid, options, doc);
16
18
  }
17
19
  /**
18
20
  * The encrypting variant of {@link renderStyledPdf} (ISO 32000 §7.6; async
@@ -37,7 +39,9 @@ async function renderStyledPdfEncrypted(body, options) {
37
39
  contentAccessibility: true
38
40
  }
39
41
  } : encrypt;
40
- return emitStyledPdfEncrypted(layoutStyledDocument(body, options), options, new PdfDocument(), effective);
42
+ const laid = layoutStyledDocument(body, options);
43
+ const doc = new PdfDocument();
44
+ return emitStyledPdfEncrypted(laid, options, doc, effective);
41
45
  }
42
46
  //#endregion
43
- export { renderStyledPdf, renderStyledPdfEncrypted };
47
+ export { GLUE_SHRINK_RATIO, layoutStyledDocument, pageItemBounds, pageLayers, paintPlan, renderStyledPdf, renderStyledPdfEncrypted };