kordoc 4.24.2 → 4.24.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +13 -11
  2. package/dist/{-SRNEV7LS.js → -WND2HWVH.js} +11 -11
  3. package/dist/{chunk-NJ5RUDCW.js → chunk-3LSHLWTX.js} +3 -3
  4. package/dist/{chunk-WDSTW3BD.js → chunk-44E52JJ7.js} +2 -2
  5. package/dist/{chunk-R2GIGE5H.js → chunk-47MTLP4U.js} +2 -2
  6. package/dist/{chunk-NMFFIUI6.js → chunk-4XVL3OBP.js} +2 -2
  7. package/dist/{chunk-C6ZVB547.js → chunk-5AHG3XY3.js} +11 -11
  8. package/dist/{chunk-PNSALBXH.cjs → chunk-6A4KYMQR.cjs} +2 -2
  9. package/dist/{chunk-PNSALBXH.cjs.map → chunk-6A4KYMQR.cjs.map} +1 -1
  10. package/dist/{chunk-LMEF7FN5.js → chunk-6CPBNK5O.js} +2 -2
  11. package/dist/{chunk-MHNJOJQV.js → chunk-A5JDO52L.js} +4 -4
  12. package/dist/{chunk-M46PB75E.js → chunk-AKIJTKEA.js} +2 -2
  13. package/dist/{chunk-IGG63DFK.cjs → chunk-BODFTRWA.cjs} +3 -3
  14. package/dist/{chunk-IGG63DFK.cjs.map → chunk-BODFTRWA.cjs.map} +1 -1
  15. package/dist/{chunk-VPSF5LEM.js → chunk-BYYZUFPC.js} +11 -8
  16. package/dist/chunk-BYYZUFPC.js.map +1 -0
  17. package/dist/{chunk-E6VBLBOO.js → chunk-D4YWVZHD.js} +2 -2
  18. package/dist/{chunk-E7B5CXYI.js → chunk-DTADAHJD.js} +2 -2
  19. package/dist/{chunk-JMOAMKAR.js → chunk-E7N6BUJT.js} +12 -9
  20. package/dist/chunk-E7N6BUJT.js.map +1 -0
  21. package/dist/{chunk-WJAFE3Z6.js → chunk-FK3JPTHI.js} +2 -2
  22. package/dist/{chunk-W24TJJNN.js → chunk-GGVHKYKZ.js} +2 -2
  23. package/dist/{chunk-RIRPLFPN.js → chunk-JHUW5PKO.js} +8 -7
  24. package/dist/chunk-JHUW5PKO.js.map +1 -0
  25. package/dist/{chunk-HLTPMSYW.cjs → chunk-KFQNG2EA.cjs} +3 -3
  26. package/dist/{chunk-HLTPMSYW.cjs.map → chunk-KFQNG2EA.cjs.map} +1 -1
  27. package/dist/{chunk-4745MFQU.js → chunk-LBOXKGAH.js} +3 -3
  28. package/dist/{chunk-UNICY546.cjs → chunk-LJ7U7MFN.cjs} +31 -28
  29. package/dist/chunk-LJ7U7MFN.cjs.map +1 -0
  30. package/dist/{chunk-3HN65YAL.js → chunk-MC4DPT4I.js} +2 -2
  31. package/dist/{chunk-TDMBTG7U.js → chunk-MMPBJGWQ.js} +2 -2
  32. package/dist/{chunk-4XC4O7FJ.js → chunk-QTJTBCTZ.js} +4 -4
  33. package/dist/{chunk-JFUUFJZW.cjs → chunk-TPKP3WQU.cjs} +6 -6
  34. package/dist/{chunk-JFUUFJZW.cjs.map → chunk-TPKP3WQU.cjs.map} +1 -1
  35. package/dist/{chunk-TW3V6FSH.js → chunk-VBY3JQL2.js} +2 -2
  36. package/dist/{chunk-7NTMM6PO.js → chunk-WMDGGQXJ.js} +2 -2
  37. package/dist/{chunk-PNX5FYHC.cjs → chunk-WN5X4DT3.cjs} +24 -24
  38. package/dist/{chunk-PNX5FYHC.cjs.map → chunk-WN5X4DT3.cjs.map} +1 -1
  39. package/dist/{chunk-KUC5I5MB.js → chunk-YBCW544D.js} +2 -2
  40. package/dist/{chunk-DHMBPMKC.js → chunk-YEYNBH5W.js} +244 -31
  41. package/dist/chunk-YEYNBH5W.js.map +1 -0
  42. package/dist/chunks-2UDUNVGQ.js +10 -0
  43. package/dist/cli.js +30 -30
  44. package/dist/{formula-HK2MNZ3Q.cjs → formula-6DJAY3KI.cjs} +9 -9
  45. package/dist/{formula-HK2MNZ3Q.cjs.map → formula-6DJAY3KI.cjs.map} +1 -1
  46. package/dist/{formula-U2LZ67KI.js → formula-MPBZ7OMN.js} +3 -3
  47. package/dist/{formula-DSB574H7.js → formula-NA3LD35B.js} +4 -4
  48. package/dist/{image-ocr-3QB2HLSI.js → image-ocr-6TGDXUAS.js} +9 -9
  49. package/dist/{image-ocr-QNIMVE5A.cjs → image-ocr-REM4LZKX.cjs} +17 -17
  50. package/dist/{image-ocr-QNIMVE5A.cjs.map → image-ocr-REM4LZKX.cjs.map} +1 -1
  51. package/dist/{image-ocr-J54Q3YWP.js → image-ocr-THA5BASF.js} +6 -6
  52. package/dist/index.cjs +870 -656
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.js +250 -36
  55. package/dist/index.js.map +1 -1
  56. package/dist/mcp.js +23 -23
  57. package/dist/{model-bundle-CGWU4ALC.js → model-bundle-3YDTJ6EQ.js} +5 -5
  58. package/dist/{models-A3TF3BDV.js → models-M7AX7VIN.js} +5 -5
  59. package/dist/{parse-worker-v2-MNUD4WAR.js → parse-worker-v2-3ZMFWDFW.js} +12 -12
  60. package/dist/{parser-RPAHN3OR.cjs → parser-GIDYL5LH.cjs} +163 -159
  61. package/dist/parser-GIDYL5LH.cjs.map +1 -0
  62. package/dist/{parser-OBGWEWSU.js → parser-MNNJSFEZ.js} +15 -11
  63. package/dist/parser-MNNJSFEZ.js.map +1 -0
  64. package/dist/{parser-C3ARF26I.js → parser-TD4VZDGY.js} +18 -14
  65. package/dist/parser-TD4VZDGY.js.map +1 -0
  66. package/dist/{pdf-ocr-K53REDNY.js → pdf-ocr-5HEVZKG5.js} +6 -6
  67. package/dist/{pdf-ocr-ENLVEEYL.js → pdf-ocr-6BAOQ6CY.js} +9 -9
  68. package/dist/pdf-ocr-NOSNTEDS.cjs +31 -0
  69. package/dist/{pdf-ocr-GA5QJFNK.cjs.map → pdf-ocr-NOSNTEDS.cjs.map} +1 -1
  70. package/dist/{profile-io-ZGFEO7CB.js → profile-io-H4WQIGN6.js} +3 -3
  71. package/dist/{rasterize-QMC2SAUT.js → rasterize-EOPWJWBO.js} +3 -3
  72. package/dist/{redact-doc-JH6RZZBE.js → redact-doc-BBZVAA3I.js} +11 -11
  73. package/dist/{render-ZGKQLKPJ.js → render-ZZ4CGJ6J.js} +7 -7
  74. package/dist/seal-RRYFKTEQ.js +10 -0
  75. package/dist/{setup-LAQGCYQ2.js → setup-UIPKBNLA.js} +3 -3
  76. package/dist/visual-DLLRTF6C.js +21 -0
  77. package/dist/{watch-7YPB4TKC.js → watch-OXQ6O5HD.js} +12 -12
  78. package/package.json +1 -1
  79. package/dist/chunk-DHMBPMKC.js.map +0 -1
  80. package/dist/chunk-JMOAMKAR.js.map +0 -1
  81. package/dist/chunk-RIRPLFPN.js.map +0 -1
  82. package/dist/chunk-UNICY546.cjs.map +0 -1
  83. package/dist/chunk-VPSF5LEM.js.map +0 -1
  84. package/dist/chunks-AL4P5TO5.js +0 -10
  85. package/dist/parser-C3ARF26I.js.map +0 -1
  86. package/dist/parser-OBGWEWSU.js.map +0 -1
  87. package/dist/parser-RPAHN3OR.cjs.map +0 -1
  88. package/dist/pdf-ocr-GA5QJFNK.cjs +0 -31
  89. package/dist/seal-KMGYTJAV.js +0 -10
  90. package/dist/visual-4OYJFGXL.js +0 -21
  91. /package/dist/{-SRNEV7LS.js.map → -WND2HWVH.js.map} +0 -0
  92. /package/dist/{chunk-NJ5RUDCW.js.map → chunk-3LSHLWTX.js.map} +0 -0
  93. /package/dist/{chunk-WDSTW3BD.js.map → chunk-44E52JJ7.js.map} +0 -0
  94. /package/dist/{chunk-R2GIGE5H.js.map → chunk-47MTLP4U.js.map} +0 -0
  95. /package/dist/{chunk-NMFFIUI6.js.map → chunk-4XVL3OBP.js.map} +0 -0
  96. /package/dist/{chunk-C6ZVB547.js.map → chunk-5AHG3XY3.js.map} +0 -0
  97. /package/dist/{chunk-LMEF7FN5.js.map → chunk-6CPBNK5O.js.map} +0 -0
  98. /package/dist/{chunk-MHNJOJQV.js.map → chunk-A5JDO52L.js.map} +0 -0
  99. /package/dist/{chunk-M46PB75E.js.map → chunk-AKIJTKEA.js.map} +0 -0
  100. /package/dist/{chunk-E6VBLBOO.js.map → chunk-D4YWVZHD.js.map} +0 -0
  101. /package/dist/{chunk-E7B5CXYI.js.map → chunk-DTADAHJD.js.map} +0 -0
  102. /package/dist/{chunk-WJAFE3Z6.js.map → chunk-FK3JPTHI.js.map} +0 -0
  103. /package/dist/{chunk-W24TJJNN.js.map → chunk-GGVHKYKZ.js.map} +0 -0
  104. /package/dist/{chunk-4745MFQU.js.map → chunk-LBOXKGAH.js.map} +0 -0
  105. /package/dist/{chunk-3HN65YAL.js.map → chunk-MC4DPT4I.js.map} +0 -0
  106. /package/dist/{chunk-TDMBTG7U.js.map → chunk-MMPBJGWQ.js.map} +0 -0
  107. /package/dist/{chunk-4XC4O7FJ.js.map → chunk-QTJTBCTZ.js.map} +0 -0
  108. /package/dist/{chunk-TW3V6FSH.js.map → chunk-VBY3JQL2.js.map} +0 -0
  109. /package/dist/{chunk-7NTMM6PO.js.map → chunk-WMDGGQXJ.js.map} +0 -0
  110. /package/dist/{chunk-KUC5I5MB.js.map → chunk-YBCW544D.js.map} +0 -0
  111. /package/dist/{chunks-AL4P5TO5.js.map → chunks-2UDUNVGQ.js.map} +0 -0
  112. /package/dist/{formula-U2LZ67KI.js.map → formula-MPBZ7OMN.js.map} +0 -0
  113. /package/dist/{formula-DSB574H7.js.map → formula-NA3LD35B.js.map} +0 -0
  114. /package/dist/{image-ocr-3QB2HLSI.js.map → image-ocr-6TGDXUAS.js.map} +0 -0
  115. /package/dist/{image-ocr-J54Q3YWP.js.map → image-ocr-THA5BASF.js.map} +0 -0
  116. /package/dist/{model-bundle-CGWU4ALC.js.map → model-bundle-3YDTJ6EQ.js.map} +0 -0
  117. /package/dist/{models-A3TF3BDV.js.map → models-M7AX7VIN.js.map} +0 -0
  118. /package/dist/{parse-worker-v2-MNUD4WAR.js.map → parse-worker-v2-3ZMFWDFW.js.map} +0 -0
  119. /package/dist/{pdf-ocr-ENLVEEYL.js.map → pdf-ocr-5HEVZKG5.js.map} +0 -0
  120. /package/dist/{pdf-ocr-K53REDNY.js.map → pdf-ocr-6BAOQ6CY.js.map} +0 -0
  121. /package/dist/{profile-io-ZGFEO7CB.js.map → profile-io-H4WQIGN6.js.map} +0 -0
  122. /package/dist/{rasterize-QMC2SAUT.js.map → rasterize-EOPWJWBO.js.map} +0 -0
  123. /package/dist/{redact-doc-JH6RZZBE.js.map → redact-doc-BBZVAA3I.js.map} +0 -0
  124. /package/dist/{render-ZGKQLKPJ.js.map → render-ZZ4CGJ6J.js.map} +0 -0
  125. /package/dist/{seal-KMGYTJAV.js.map → seal-RRYFKTEQ.js.map} +0 -0
  126. /package/dist/{setup-LAQGCYQ2.js.map → setup-UIPKBNLA.js.map} +0 -0
  127. /package/dist/{visual-4OYJFGXL.js.map → visual-DLLRTF6C.js.map} +0 -0
  128. /package/dist/{watch-7YPB4TKC.js.map → watch-OXQ6O5HD.js.map} +0 -0
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  blocksToPages,
3
3
  bmpToPng,
4
4
  inlineImagesIntoMarkdown
5
- } from "./chunk-3HN65YAL.js";
5
+ } from "./chunk-MC4DPT4I.js";
6
6
  import {
7
7
  parsePageRange
8
8
  } from "./chunk-V4BH5SRQ.js";
@@ -43,7 +43,7 @@ import {
43
43
  validateOcrOptions,
44
44
  visibleText,
45
45
  wrapScript
46
- } from "./chunk-TW3V6FSH.js";
46
+ } from "./chunk-VBY3JQL2.js";
47
47
  import {
48
48
  KordocError,
49
49
  OPTIONAL_DEP_INSTALL_HINT,
@@ -61,7 +61,7 @@ import {
61
61
  toArrayBuffer,
62
62
  unescapeHtml,
63
63
  unzipLimitBytes
64
- } from "./chunk-WJAFE3Z6.js";
64
+ } from "./chunk-FK3JPTHI.js";
65
65
 
66
66
  // src/plain-markdown.ts
67
67
  function toPlainMarkdown(md2) {
@@ -24620,7 +24620,7 @@ var MIN_SIDE = 24;
24620
24620
  async function ocrEmbeddedImages(blocks, options, warnings) {
24621
24621
  const ocr = options?.ocr;
24622
24622
  if (ocr !== true && ocr !== "force" && typeof ocr !== "function") return false;
24623
- const { parseImageDocument } = await import("./image-ocr-J54Q3YWP.js");
24623
+ const { parseImageDocument } = await import("./image-ocr-THA5BASF.js");
24624
24624
  let inserted = false, unreadable = 0;
24625
24625
  let failed = null;
24626
24626
  const walk = async (list, depth) => {
@@ -44217,7 +44217,7 @@ function hwpFaceToCssStack(face) {
44217
44217
  const head = FONT_ALIASES[trimmed] ?? cssQuote(trimmed);
44218
44218
  return `${head},${generic}`;
44219
44219
  }
44220
- function collectHangulFonts(root, lang = "HANGUL", hftIds) {
44220
+ function collectHangulFonts(root, lang = "HANGUL", hftIds, substKoPub = false) {
44221
44221
  const map = /* @__PURE__ */ new Map();
44222
44222
  const findFaces = (el, depth) => {
44223
44223
  if (depth > 24) return null;
@@ -44253,7 +44253,7 @@ function collectHangulFonts(root, lang = "HANGUL", hftIds) {
44253
44253
  const id = e.getAttribute("id");
44254
44254
  let face = e.getAttribute("face");
44255
44255
  let type = e.getAttribute("type");
44256
- if (face && type === "TTF" && /^한양/.test(face)) {
44256
+ if (face && type === "TTF" && (/^한양/.test(face) || substKoPub && /^KoPub/.test(face))) {
44257
44257
  const sub = Array.from(e.childNodes).find((c) => c.nodeType === 1 && (c.tagName || "").replace(/^[^:]+:/, "") === "substFont");
44258
44258
  const sf = sub?.getAttribute("face");
44259
44259
  if (sf) {
@@ -44344,10 +44344,11 @@ function parseRenderStyles(headXml, opts) {
44344
44344
  const hv = Number.parseFloat(root.getAttribute("version") ?? "");
44345
44345
  const oldUnit = Number.isFinite(hv) && hv < 1.4;
44346
44346
  const hftHangul = /* @__PURE__ */ new Set(), hftLatin = /* @__PURE__ */ new Set();
44347
- const hangulFonts = collectHangulFonts(root, "HANGUL", hftHangul);
44348
- const latinFonts = collectHangulFonts(root, "LATIN", hftLatin);
44347
+ const sk = !!opts?.substKoPub;
44348
+ const hangulFonts = collectHangulFonts(root, "HANGUL", hftHangul, sk);
44349
+ const latinFonts = collectHangulFonts(root, "LATIN", hftLatin, sk);
44349
44350
  const hftHanja = /* @__PURE__ */ new Set(), hftJapanese = /* @__PURE__ */ new Set(), hftSymbol = /* @__PURE__ */ new Set();
44350
- const langFonts = { hanja: [collectHangulFonts(root, "HANJA", hftHanja), hftHanja], japanese: [collectHangulFonts(root, "JAPANESE", hftJapanese), hftJapanese], symbol: [collectHangulFonts(root, "SYMBOL", hftSymbol), hftSymbol] };
44351
+ const langFonts = { hanja: [collectHangulFonts(root, "HANJA", hftHanja, sk), hftHanja], japanese: [collectHangulFonts(root, "JAPANESE", hftJapanese, sk), hftJapanese], symbol: [collectHangulFonts(root, "SYMBOL", hftSymbol, sk), hftSymbol] };
44351
44352
  const autoTabPr = /* @__PURE__ */ new Set();
44352
44353
  const paraTabRef = /* @__PURE__ */ new Map();
44353
44354
  const paraBullet = /* @__PURE__ */ new Map();
@@ -52495,6 +52496,12 @@ function solveRowHeights(cells, rowCount, maxTotal = Number.POSITIVE_INFINITY, s
52495
52496
  for (const r of missing) h[r] = each;
52496
52497
  return true;
52497
52498
  };
52499
+ for (let r = 0; r < rowCount; r++) {
52500
+ if (h[r] !== 0) continue;
52501
+ let need = 0;
52502
+ for (const { c, rows } of spans) if (rows[rows.length - 1] === r && rows.slice(0, -1).every((q) => h[q] > 0)) need = Math.max(need, c.height - rows.slice(0, -1).reduce((t, q) => t + h[q], 0));
52503
+ if (need > 0) h[r] = need;
52504
+ }
52498
52505
  for (let again = true; again; ) {
52499
52506
  again = false;
52500
52507
  for (let k = 0; k < spans.length; k++) if (!done.has(k) && solve(k, true)) again = true;
@@ -52511,7 +52518,8 @@ function solveRowHeights(cells, rowCount, maxTotal = Number.POSITIVE_INFINITY, s
52511
52518
  }
52512
52519
  const last = rowCount - 1, over = total - maxTotal;
52513
52520
  const lastCells = cells.filter((c) => c.rowAddr + c.rowSpan - 1 === last);
52514
- if (shrinkLast && over > 0 && last >= 0 && lastCells.length && lastCells.every((c) => c.rowSpan === 1 && c.contentH != null && c.contentH <= h[last] - over)) h[last] -= over;
52521
+ const spanH = (c) => h.slice(c.rowAddr, c.rowAddr + c.rowSpan).reduce((t, x) => t + x, 0);
52522
+ if (shrinkLast && over > 0 && last >= 0 && lastCells.length && lastCells.every((c) => c.contentH != null && c.contentH <= (c.rowSpan === 1 ? h[last] : spanH(c)) - over)) h[last] -= over;
52515
52523
  return h;
52516
52524
  }
52517
52525
 
@@ -52779,7 +52787,7 @@ function cellContentExtent(cell2, memo) {
52779
52787
  const pushed = baseV - (Math.max(0, vo) + num2(om, "top") + o.height + num2(om, "bottom"));
52780
52788
  const anchor = pushed >= (paraStart > 0 ? paraStart - 100 : -100) ? pushed : baseV - (memo?.paraGeom?.get(p.getAttribute("paraPrIDRef") ?? "")?.spaceBefore ?? 0);
52781
52789
  const oh = o.tag === "tbl" ? Math.max(o.height, measureTableHeight(o.el, memo)) : o.height;
52782
- ext = Math.max(ext, anchor + num2(om, "top") + Math.max(0, vo) + oh);
52790
+ ext = Math.max(ext, anchor + num2(om, "top") + Math.max(0, vo) + oh + num2(om, "bottom"));
52783
52791
  }
52784
52792
  }
52785
52793
  memo?.cell.set(cell2.el, ext);
@@ -52846,7 +52854,7 @@ function measureTableRowHeights(tbl2, memo) {
52846
52854
  const rows = solveRowHeights(
52847
52855
  // 여러 행 칸은 내용(+ 칸 여백)이 저장 높이보다 크면 내용 높이로 — 솔버가 모자란 만큼 그 칸 마지막 행을 키운다
52848
52856
  // (같은 판 PDF: 두 줄 든 2행 병합 칸 내용 2882 > 저장 2564 → 둘째 행이 318 자라고 첫 행은 그대로)
52849
- cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: (c.rs > 1 ? Math.max(c.h, cellContentExtent(c, memo) + c.marginT + c.marginB) : c.h) - sp * (c.rs - 1), contentH: c.rs === 1 ? cellContentExtent(c, memo) + c.marginT + c.marginB : void 0 })),
52857
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: (c.rs > 1 ? Math.max(c.h, cellContentExtent(c, memo) + c.marginT + c.marginB) : c.h) - sp * (c.rs - 1), contentH: cellContentExtent(c, memo) + c.marginT + c.marginB })),
52850
52858
  nRows,
52851
52859
  num2(findChildByLocalName(tbl2, "sz"), "height") - (sp > 0 ? sp * (nRows + 1) : 0) || Number.POSITIVE_INFINITY,
52852
52860
  !inCell(tbl2) && !cells.some((c) => c.ra + c.rs === nRows && splitSaved(c))
@@ -52973,6 +52981,7 @@ function splitTableRows(tbl2, top, lim, bodyH, styles, notes) {
52973
52981
  const fl = () => notes && nN > 0 ? Math.min(floor, bodyH - notes.area((moved ? 0 : notes.n0) + nN, (moved ? 0 : notes.s0) + nS)) : floor;
52974
52982
  const sp = num2(tbl2, "cellSpacing");
52975
52983
  const cells = mode === "CELL" ? collectCells(tbl2) : [];
52984
+ const tableCells = mode === "TABLE" ? collectCells(tbl2) : [];
52976
52985
  const record = mode === "CELL" ? /* @__PURE__ */ new Map() : void 0;
52977
52986
  const carries = /* @__PURE__ */ new Map();
52978
52987
  for (let r = 0; r < rows.length; r++) {
@@ -53001,7 +53010,20 @@ function splitTableRows(tbl2, top, lim, bodyH, styles, notes) {
53001
53010
  y += h;
53002
53011
  continue;
53003
53012
  }
53004
- if (y + h + outB > fl() && !(moved && y === outT + headH)) {
53013
+ let need = h;
53014
+ if (!tableCells.some((c) => c.ra < r && c.ra + c.rs > r)) {
53015
+ let end = r + 1;
53016
+ for (let grown = true; grown; ) {
53017
+ grown = false;
53018
+ for (const c of tableCells) if (c.ra >= r && c.ra < end && c.ra + c.rs > end) {
53019
+ end = c.ra + c.rs;
53020
+ grown = true;
53021
+ }
53022
+ }
53023
+ const groupH = rows.slice(r, end).reduce((a, b) => a + b, 0);
53024
+ if (end > r + 1 && groupH <= bodyH - outT - outB - headH) need = groupH;
53025
+ }
53026
+ if (y + need + outB > fl() && !(moved && y === outT + headH)) {
53005
53027
  if (!moved && r === 0) splitWhole = true;
53006
53028
  y = outT + headH;
53007
53029
  floor = bodyH;
@@ -54381,6 +54403,53 @@ function flowEndNotes(root, bodyH) {
54381
54403
  });
54382
54404
  }
54383
54405
 
54406
+ // src/render/font-env.ts
54407
+ function hasKoPubSubst(headXml) {
54408
+ return /<hh:font\b[^>]*\bface="KoPub[^"]*"[^>]*\btype="TTF"[^>]*>\s*<hh:substFont\b/.test(headXml);
54409
+ }
54410
+ function lineStarts(root) {
54411
+ const out = [];
54412
+ for (const p of Array.from(root.getElementsByTagName("hp:p"))) {
54413
+ const lsa = elements(p).find((e) => ln(e) === "linesegarray");
54414
+ const segs = lsa ? elements(lsa).filter((e) => ln(e) === "lineseg") : [];
54415
+ out.push(segs.length >= 2 ? segs.map((s) => s.getAttribute("textpos") ?? "0").join(",") : null);
54416
+ }
54417
+ return out;
54418
+ }
54419
+ function matchCount(xml, saved, styles) {
54420
+ const root = createXmlParser().parseFromString(xml, "text/xml").documentElement;
54421
+ const pagePr = root.getElementsByTagName("hp:pagePr")[0];
54422
+ if (!pagePr) return 0;
54423
+ const margin = pagePr.getElementsByTagName("hp:margin")[0];
54424
+ let PW = num2(pagePr, "width", 59528), PH = num2(pagePr, "height", 84188);
54425
+ if (pagePr.getAttribute("landscape") === "NARROWLY" && PW < PH) [PW, PH] = [PH, PW];
54426
+ const gutterTB = pagePr.getAttribute("gutterType") === "TOP_BOTTOM", gutter = num2(margin ?? null, "gutter", 0);
54427
+ const BODY_W = PW - num2(margin ?? null, "left", 8504) - num2(margin ?? null, "right", 8504) - (gutterTB ? 0 : gutter);
54428
+ const BODY_H = PH - num2(margin ?? null, "top", 5668) - num2(margin ?? null, "header", 0) - num2(margin ?? null, "bottom", 4252) - num2(margin ?? null, "footer", 0) - (gutterTB ? gutter : 0);
54429
+ for (const p of Array.from(root.getElementsByTagName("hp:p"))) {
54430
+ const lsa = elements(p).find((e) => ln(e) === "linesegarray");
54431
+ if (lsa) p.removeChild(lsa);
54432
+ }
54433
+ reflowSection(root, styles, { BODY_W, BODY_H });
54434
+ const got = lineStarts(root);
54435
+ let n = 0;
54436
+ saved.forEach((s, i) => {
54437
+ if (s !== null && s === got[i]) n++;
54438
+ });
54439
+ return n;
54440
+ }
54441
+ function kopubSubstituted(secXmls, base, alt2) {
54442
+ let a = 0, b = 0, seen = 0;
54443
+ for (const xml of secXmls) {
54444
+ const saved = lineStarts(createXmlParser().parseFromString(xml, "text/xml").documentElement);
54445
+ a += matchCount(xml, saved, base);
54446
+ b += matchCount(xml, saved, alt2);
54447
+ seen += saved.filter((x) => x !== null).length;
54448
+ if (seen >= 60) break;
54449
+ }
54450
+ return b >= a + 5 && b > a * 1.1;
54451
+ }
54452
+
54384
54453
  // src/render/scene.ts
54385
54454
  function regionId(type, seq) {
54386
54455
  return `${type}-${String(seq).padStart(6, "0")}`;
@@ -54609,6 +54678,26 @@ function cellLineBoxes(c) {
54609
54678
  function cellLines(c) {
54610
54679
  return cellLineBoxes(c).map((b) => [b.top, b.bottom]);
54611
54680
  }
54681
+ function spanPartRows(cells, rowY) {
54682
+ const out = /* @__PURE__ */ new Set();
54683
+ for (const c of cells) {
54684
+ if (c.rs < 2) continue;
54685
+ const bs = cellLineBoxes(c);
54686
+ const parts = bs.length ? bs[bs.length - 1].part : 0;
54687
+ let s = c.ra;
54688
+ for (let k = 0; k < parts; k++) {
54689
+ const inK = bs.filter((b) => b.part === k);
54690
+ if (!inK.length) break;
54691
+ const ext = Math.max(...inK.map((b) => b.bottom)) - inK[0].origin + c.marginT + c.marginB;
54692
+ let r = s + 1;
54693
+ while (r < c.ra + c.rs && rowY[r] - rowY[s] < ext - 100) r++;
54694
+ if (r >= c.ra + c.rs) break;
54695
+ out.add(r);
54696
+ s = r;
54697
+ }
54698
+ }
54699
+ return out;
54700
+ }
54612
54701
  function planTableRows(tbl2, cells, rowH, ty, MT, BODY_H, slack = 0, floatSpan, nested = false, contMT = MT) {
54613
54702
  if (nested) slack = 0;
54614
54703
  const nRows = rowH.length;
@@ -54641,9 +54730,15 @@ function planTableRows(tbl2, cells, rowH, ty, MT, BODY_H, slack = 0, floatSpan,
54641
54730
  const out = [];
54642
54731
  const flows = (findChildByLocalName(tbl2, "pos")?.getAttribute("vertRelTo") ?? "PARA") === "PARA";
54643
54732
  let page = 0, y = ty, first = !flows || ty - MT < 2e3;
54733
+ const spanStarts = cellSplit ? spanPartRows(cells, rowY) : /* @__PURE__ */ new Set();
54644
54734
  for (let r = 0; r < nRows; r++) {
54645
54735
  let h = rowH[r];
54646
54736
  const pieces = [];
54737
+ if (!first && r >= hdrRows && spanStarts.has(r)) {
54738
+ page++;
54739
+ y = contTop;
54740
+ first = true;
54741
+ }
54647
54742
  const rowCells = cells.filter((c) => c.ra === r && c.rs === 1);
54648
54743
  const splittable = cellSplit && r >= hdrRows && rowCells.length > 0;
54649
54744
  const stack = splittable && rowCells.length === 1 ? stackedFloats(rowCells[0]) : [];
@@ -54782,11 +54877,11 @@ function planTableRows(tbl2, cells, rowH, ty, MT, BODY_H, slack = 0, floatSpan,
54782
54877
  continue;
54783
54878
  }
54784
54879
  }
54785
- if (splittable && y + h > pageBottom) {
54880
+ if (splittable && y + h + outB > pageBottom) {
54786
54881
  const from = /* @__PURE__ */ new Map();
54787
54882
  const lines = new Map(rowCells.map((c) => [c.el, cellLines(c)]));
54788
- while (y + h > pageBottom && BODY_H > rowY[hdrRows]) {
54789
- const avail = pageBottom - y;
54883
+ while (y + h + outB > pageBottom && BODY_H > rowY[hdrRows]) {
54884
+ const avail = pageBottom - y - outB;
54790
54885
  let rem = 0, placed = false, allFit = true, blocked = false;
54791
54886
  const cuts = [];
54792
54887
  for (const c of rowCells) {
@@ -54858,6 +54953,21 @@ function planTableRows(tbl2, cells, rowH, ty, MT, BODY_H, slack = 0, floatSpan,
54858
54953
  page++;
54859
54954
  y = contTop;
54860
54955
  first = true;
54956
+ } else if (!first && tbl2.getAttribute("pageBreak") === "TABLE" && r >= hdrRows && !cells.some((c) => c.ra < r && c.ra + c.rs > r)) {
54957
+ let end = r + 1;
54958
+ for (let grown = true; grown; ) {
54959
+ grown = false;
54960
+ for (const c of cells) if (c.ra >= r && c.ra < end && c.ra + c.rs > end) {
54961
+ end = c.ra + c.rs;
54962
+ grown = true;
54963
+ }
54964
+ }
54965
+ const groupH = rowY[Math.min(end, nRows)] - rowY[r];
54966
+ if (end > r + 1 && y + groupH + outB > pageBottom && groupH <= pageBottom - contTop) {
54967
+ page++;
54968
+ y = contTop;
54969
+ first = true;
54970
+ }
54861
54971
  }
54862
54972
  out.push([{ page, y, h }]);
54863
54973
  y += h;
@@ -54900,12 +55010,27 @@ function renderingMatrix(el) {
54900
55010
  const info = findChildByLocalName(el, "renderingInfo");
54901
55011
  if (!info) return null;
54902
55012
  let m = null;
55013
+ let pendingS = null;
55014
+ const apply = (n) => {
55015
+ m = m ? mulAffine(m, n) : n;
55016
+ };
54903
55017
  for (const c of elements(info)) {
54904
55018
  const tag = ln(c);
54905
55019
  if (tag !== "transMatrix" && tag !== "scaMatrix" && tag !== "rotMatrix") continue;
54906
55020
  const n = [num2(c, "e1", 1), num2(c, "e4"), num2(c, "e2"), num2(c, "e5", 1), num2(c, "e3"), num2(c, "e6")];
54907
- m = m ? mulAffine(m, n) : n;
55021
+ if (tag === "scaMatrix") {
55022
+ if (pendingS) apply(pendingS);
55023
+ pendingS = n;
55024
+ continue;
55025
+ }
55026
+ if (tag === "rotMatrix" && pendingS) {
55027
+ apply(mulAffine(n, pendingS));
55028
+ pendingS = null;
55029
+ continue;
55030
+ }
55031
+ apply(n);
54908
55032
  }
55033
+ if (pendingS) apply(pendingS);
54909
55034
  return m;
54910
55035
  }
54911
55036
  function objectGeometry(el, x, y, w, h, boxW = w, boxH = h) {
@@ -55012,7 +55137,7 @@ function linePushedBy(o, lineV, paraTop) {
55012
55137
  const raw = num2(pos, "vertOffset"), vo = (pos?.getAttribute("vertRelTo") ?? "PARA") === "PARA" ? Math.max(0, raw >= 2 ** 31 ? raw - 2 ** 32 : raw) : 0;
55013
55138
  return Math.abs(lineV - (vo + num2(om, "top") + o.height + num2(om, "bottom")) - paraTop) <= 10;
55014
55139
  }
55015
- function anchorObject(o, ox, oy, baseV, areaW, ctx, anchorLineV, stayLine = false, paraStartV, lineH, lineSB = 0) {
55140
+ function anchorObject(o, ox, oy, baseV, areaW, ctx, anchorLineV, stayLine = false, paraStartV, lineH, lineSB = 0, anchorAt = "end") {
55016
55141
  const { PW, PH, ML, MT, BODY_W, BODY_H } = ctx.geom;
55017
55142
  const pos = findChildByLocalName(o.el, "pos");
55018
55143
  const om = findChildByLocalName(o.el, "outMargin");
@@ -55040,8 +55165,9 @@ function anchorObject(o, ox, oy, baseV, areaW, ctx, anchorLineV, stayLine = fals
55040
55165
  y = oy + anchor + omT + vo;
55041
55166
  } else {
55042
55167
  const origin = vrel === "PARA" && wrap === "SQUARE" ? paraStartV ?? baseV : baseV;
55043
- const later = vrel === "PARA" && wrap === "SQUARE" && anchorLineV !== void 0 && anchorLineV > baseV;
55044
- y = later ? oy + anchorLineV + vo + omT : oy + Math.max(origin + vo, wrap === "SQUARE" && anchorLineV !== void 0 ? anchorLineV : -Infinity) + omT;
55168
+ const later = vrel === "PARA" && wrap === "SQUARE" && anchorAt === "end" && anchorLineV !== void 0 && anchorLineV > baseV;
55169
+ const midLater = vrel === "PARA" && wrap === "SQUARE" && anchorAt === "top" && anchorLineV !== void 0 && anchorLineV > baseV;
55170
+ y = later ? oy + anchorLineV + vo + omT : oy + Math.max(origin + vo, wrap === "SQUARE" && !midLater && anchorLineV !== void 0 ? anchorLineV : -Infinity) + omT;
55045
55171
  }
55046
55172
  let x;
55047
55173
  const omL = num2(om, "left"), omR = num2(om, "right");
@@ -55364,30 +55490,53 @@ function planLines(m, styles, numText = "") {
55364
55490
  }
55365
55491
  }
55366
55492
  const stretch = align === "JUSTIFY" || align === "DISTRIBUTE" || align === "DISTRIBUTE_SPACE";
55367
- let spaceAdd = 0, spaceFrom = fixedTo;
55493
+ let spaceAdd = 0, spaceFrom = fixedTo, charAdd = 0;
55494
+ const squeeze = (spFrom) => {
55495
+ const short = nat.text - lastSp - avail;
55496
+ let nSp = 0, cap = 0, nG = 0;
55497
+ for (let k = spFrom; k < textEnd; k++) {
55498
+ const c = m.chars[k];
55499
+ if (c.ch === " ") {
55500
+ nSp++;
55501
+ cap += charW(c, styles, m.chars[k - 1]) * 0.2;
55502
+ } else if (c.ch && !c.tab) nG++;
55503
+ }
55504
+ if (nSp > 0) {
55505
+ spaceAdd = -Math.min(short, cap) / nSp;
55506
+ spaceFrom = spFrom;
55507
+ }
55508
+ if (short > cap && nG > 0) charAdd = -(short - (nSp > 0 ? cap : 0)) / nG;
55509
+ };
55368
55510
  if (nat.text > 0 && stretch && (!isLast || align === "DISTRIBUTE" || align === "DISTRIBUTE_SPACE")) {
55369
55511
  let nSp = 0, spFrom = fixedTo;
55370
- while (spFrom < textEnd && (m.chars[spFrom].ch === " " || m.chars[spFrom].ch === "")) spFrom++;
55512
+ while (spFrom < textEnd && (m.chars[spFrom].ch === " " || m.chars[spFrom].ch === "") && !m.chars[spFrom].ctrl) spFrom++;
55371
55513
  for (let k = spFrom; k < textEnd; k++) if (m.chars[k].ch === " ") nSp++;
55372
55514
  if (nSp > 0 && align !== "DISTRIBUTE") {
55373
55515
  spaceAdd = (avail - nat.text + lastSp) / nSp;
55374
55516
  spaceFrom = spFrom;
55517
+ if (spaceAdd < 0) squeeze(spFrom);
55375
55518
  } else scale2 = avail > 0 ? avail / nat.text : 1;
55376
55519
  } else if (nat.text + nat.obj > 0 && (isLast || !stretch)) {
55377
55520
  const w = nat.text + nat.obj - lastSp;
55378
55521
  if (align === "CENTER") xoff = Math.max(0, (lineW - w) / 2);
55379
55522
  else if (align === "RIGHT") xoff = Math.max(0, lineW - w);
55380
55523
  }
55524
+ if (spaceAdd === 0 && charAdd === 0 && scale2 === 1 && nat.text - lastSp > avail) {
55525
+ let spFrom = fixedTo;
55526
+ while (spFrom < textEnd && (m.chars[spFrom].ch === " " || m.chars[spFrom].ch === "") && !m.chars[spFrom].ctrl) spFrom++;
55527
+ squeeze(spFrom);
55528
+ }
55381
55529
  if (!Number.isFinite(scale2) || scale2 <= 0) scale2 = 1;
55382
55530
  scale2 = Math.min(4, Math.max(0.25, scale2));
55383
- plans.push({ seg, xoff: xoff + lead, scale: scale2, spaceAdd, spFrom: spaceFrom, start, end, tabs, fixedTo, textEnd, ...i === 0 && bu ? { bullet: { ch: bu.ch, w: bulletW, prId: bu.charPrId ?? firstPr } } : {} });
55531
+ plans.push({ seg, xoff: xoff + lead, scale: scale2, spaceAdd, spFrom: spaceFrom, ...charAdd ? { charAdd } : {}, start, end, tabs, fixedTo, textEnd, ...i === 0 && bu ? { bullet: { ch: bu.ch, w: bulletW, prId: bu.charPrId ?? firstPr } } : {} });
55384
55532
  }
55385
55533
  return plans;
55386
55534
  }
55387
55535
  function advanceTo(m, styles, plan, upto) {
55388
55536
  let x = 0;
55389
55537
  for (let i = plan.start; i < upto && i < m.chars.length; i++) {
55390
- x += m.chars[i].tab ? plan.tabs.get(i) ?? 0 : charW(m.chars[i], styles, m.chars[i - 1]) * (i < plan.fixedTo ? 1 : plan.scale) + (i >= plan.spFrom && i < plan.textEnd && m.chars[i].ch === " " ? plan.spaceAdd : 0);
55538
+ const c = m.chars[i], inStretch = i >= plan.spFrom && i < plan.textEnd;
55539
+ x += c.tab ? plan.tabs.get(i) ?? 0 : charW(c, styles, m.chars[i - 1]) * (i < plan.fixedTo ? 1 : plan.scale) + (inStretch && c.ch === " " ? plan.spaceAdd : 0) + (inStretch && plan.charAdd && c.ch && c.ch !== " " ? plan.charAdd : 0);
55391
55540
  }
55392
55541
  for (const o of m.objs) if (o.inline && o.index >= plan.start && o.index < upto) x += o.omL + o.width + o.omR;
55393
55542
  return x;
@@ -55505,7 +55654,7 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55505
55654
  return n;
55506
55655
  };
55507
55656
  const renderSeg = (text, cx, hit) => {
55508
- const sw = measure(text) * scale2 + (plan.spaceAdd && i >= plan.fixedTo ? plan.spaceAdd * spacesIn(text) : 0);
55657
+ const sw = measure(text) * scale2 + (plan.spaceAdd && i >= plan.fixedTo ? plan.spaceAdd * spacesIn(text) : 0) + (plan.charAdd && i >= plan.fixedTo ? plan.charAdd * [...text].filter((ch) => ch !== " ").length : 0);
55509
55658
  if (st.shade) emit(ctx, `<rect x="${pt2(cx)}" y="${pt2(glyphY(st.height) - Math.round(st.height * 0.85))}" width="${pt2(sw)}" height="${pt2(st.height)}" fill="${escapeXml7(st.shade)}"/>`);
55510
55659
  if (hit) {
55511
55660
  emit(ctx, `<rect x="${pt2(cx)}" y="${pt2(oy + seg.vertpos)}" width="${pt2(sw)}" height="${pt2(seg.textheight)}" fill="#ffd54f" fill-opacity="0.45"/>`);
@@ -55571,7 +55720,8 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55571
55720
  const plan = plans[planIdx];
55572
55721
  if (segPages && segPages[planIdx] !== void 0) ctx.page = segPages[planIdx];
55573
55722
  const x = ox + plan.seg.horzpos + plan.xoff + advanceTo(m, ctx.styles, plan, o.index) + o.omL;
55574
- const eqAsc = o.tag === "equation" && Number(o.el.getAttribute("baseLine")) > 0 ? Math.round(o.height * Number(o.el.getAttribute("baseLine")) / 100) : o.tag === "pic" ? Math.round(o.height * 0.85) : o.height;
55723
+ const shadowed = o.tag === "pic" && !!findChildByLocalName(findChildByLocalName(o.el, "effects") ?? o.el, "shadow") && plan.seg.textheight > o.height && Math.abs(plan.seg.baseline - Math.round(plan.seg.textheight * 0.85)) <= 2;
55724
+ const eqAsc = o.tag === "equation" && Number(o.el.getAttribute("baseLine")) > 0 ? Math.round(o.height * Number(o.el.getAttribute("baseLine")) / 100) : shadowed ? Math.round(plan.seg.textheight * 0.85) : o.tag === "pic" ? Math.round(o.height * 0.85) : o.height;
55575
55725
  const iom = findChildByLocalName(o.el, "outMargin"), iomT = num2(iom, "top"), iomB = num2(iom, "bottom");
55576
55726
  const yTop = oy + plan.seg.vertpos + Math.max(iomT, plan.seg.baseline - eqAsc - iomB - captionExtra(o.el));
55577
55727
  drawObject(o, x, yTop, baseV, areaW, ctx, depth);
@@ -55585,10 +55735,16 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55585
55735
  }
55586
55736
  let anchorLineV;
55587
55737
  let anchorLineH = 0;
55588
- for (const pl of plans) if (pl.start <= o.index) {
55589
- anchorLineV = pl.seg.vertpos;
55590
- anchorLineH = pl.seg.textheight;
55591
- }
55738
+ let anchorSeg;
55739
+ let anchorK = -1;
55740
+ plans.forEach((pl, k) => {
55741
+ if (pl.start <= o.index) {
55742
+ anchorLineV = pl.seg.vertpos;
55743
+ anchorLineH = pl.seg.textheight;
55744
+ anchorSeg = pl.seg;
55745
+ anchorK = k;
55746
+ }
55747
+ });
55592
55748
  let objBaseV = baseV;
55593
55749
  const pTop = depth === 0 ? ctx.paraTops?.get(p) : void 0;
55594
55750
  const wrapA = o.el.getAttribute("textWrap") ?? "TOP_AND_BOTTOM";
@@ -55598,14 +55754,40 @@ function drawPara(p, ox, oy, areaW, ctx, depth, segPages) {
55598
55754
  if (baseV > start + 100) {
55599
55755
  objBaseV = start;
55600
55756
  if (anchorLineV === baseV) anchorLineV = start;
55757
+ } else if (depth > 0 && start > top0 && Math.abs(baseV - start) <= 100) {
55758
+ objBaseV = top0;
55759
+ if (anchorLineV === baseV) anchorLineV = top0;
55601
55760
  }
55602
55761
  }
55603
55762
  const tbFloats = m.objs.filter((q) => !q.inline && (q.el.getAttribute("textWrap") ?? "TOP_AND_BOTTOM") === "TOP_AND_BOTTOM" && (findChildByLocalName(q.el, "pos")?.getAttribute("vertRelTo") ?? "PARA") === "PARA").length;
55604
55763
  let stay = tbFloats < 2 && !m.objs.some((q) => q.inline) && !m.chars.some((c) => c.ch !== "" && !c.nb && c.ch.trim() !== "");
55605
55764
  const sbA = m.paraPrId != null ? ctx.styles.paraGeom.get(m.paraPrId)?.spaceBefore ?? 0 : 0;
55606
55765
  if (stay && wrapA === "TOP_AND_BOTTOM" && linePushedBy(o, anchorLineV ?? baseV, pTop ?? (depth > 0 ? cellParaTop(p, ctx.styles.paraGeom) : void 0))) stay = false;
55766
+ let carried;
55767
+ if (segPages && anchorK > 0 && segPages[anchorK] !== segPages[0] && segPages[anchorK - 1] === segPages[0] && wrapA === "TOP_AND_BOTTOM" && (findChildByLocalName(o.el, "pos")?.getAttribute("vertRelTo") ?? "PARA") === "PARA") {
55768
+ const s0 = plans[anchorK - 1].seg;
55769
+ carried = s0.vertpos + s0.textheight + (s0.spacing ?? 0);
55770
+ }
55607
55771
  const firstLine = anchorLineV === void 0 || anchorLineV === baseV;
55608
- let { x, y } = anchorObject(o, ax, oy, objBaseV, aw, ctx, anchorLineV, stay ? sbA : false, (firstLine || wrapA === "SQUARE") && pTop !== void 0 && pTop < baseV ? pTop : void 0, anchorLineH, firstLine ? sbA : 0);
55772
+ let { x, y } = anchorObject(
55773
+ o,
55774
+ ax,
55775
+ oy,
55776
+ objBaseV,
55777
+ aw,
55778
+ ctx,
55779
+ anchorLineV,
55780
+ stay ? sbA : false,
55781
+ (firstLine || wrapA === "SQUARE") && pTop !== void 0 && pTop < baseV ? pTop : void 0,
55782
+ anchorLineH,
55783
+ firstLine ? sbA : 0,
55784
+ // 문단 중간 글자 앵커인데 첫 줄부터 앵커 줄만큼 좁게 저장됐으면 개체는 문단 위에 있다(같은 판 한컴 PDF: 둘째 줄 앵커 사진, 네 줄 모두 34602)
55785
+ m.chars.slice(o.index).some((c) => c.ch.trim() !== "") && !!anchorSeg && plans.length > 0 && plans[0].seg !== anchorSeg && Math.abs(plans[0].seg.horzsize - anchorSeg.horzsize) <= 100 && anchorSeg.horzpos + anchorSeg.horzsize < aw - 1e3 ? "top" : m.chars.slice(o.index).some((c) => c.ch.trim() !== "") ? "mid" : "end"
55786
+ );
55787
+ if (carried !== void 0) {
55788
+ const posC = findChildByLocalName(o.el, "pos"), rawC = num2(posC, "vertOffset");
55789
+ y = oy + carried + num2(findChildByLocalName(o.el, "outMargin"), "top") + Math.max(0, rawC >= 2 ** 31 ? rawC - 2 ** 32 : rawC);
55790
+ }
55609
55791
  let stackTop = depth === 0 ? pTop ?? 0 : cellParaTop(p, ctx.styles.paraGeom);
55610
55792
  if (tbFloats >= 2 && wrapA === "TOP_AND_BOTTOM" && stackTop !== void 0) {
55611
55793
  if (!tbStack) {
@@ -55860,10 +56042,28 @@ function drawTable(tbl2, tx, ty, ctx, depth) {
55860
56042
  pcs.forEach((pc, k) => geom.push({ c, page: startPage + pc.page, ...xw(c), y: pc.y, h: pc.h, pieces: k === 0 ? pcs : [] }));
55861
56043
  continue;
55862
56044
  }
56045
+ if (c.rs > 1) {
56046
+ const span2 = plan.slice(c.ra, Math.min(c.ra + c.rs, nRows)).flat();
56047
+ const pages = [...new Set(span2.map((pc) => pc.page))];
56048
+ if (pages.length > 1) {
56049
+ const bs = cellLineBoxes(c);
56050
+ const partTop = (k) => bs.find((b) => b.part === k);
56051
+ const groups = pages.map((pg, k) => {
56052
+ const on = span2.filter((pc) => pc.page === pg);
56053
+ const y0 = Math.min(...on.map((pc) => pc.y)), y1 = Math.max(...on.map((pc) => pc.y + pc.h));
56054
+ const from = k === 0 ? 0 : partTop(k)?.origin ?? Number.POSITIVE_INFINITY;
56055
+ const to = k === pages.length - 1 ? Number.POSITIVE_INFINITY : partTop(k + 1)?.top ?? Number.POSITIVE_INFINITY;
56056
+ return { page: pg, y: y0, h: y1 - y0, range: /* @__PURE__ */ new Map([[c.el, [from, to]]]) };
56057
+ });
56058
+ groups.forEach((pc, k) => geom.push({ c, page: startPage + pc.page, ...xw(c), y: pc.y, h: pc.h, pieces: k === 0 ? groups : [] }));
56059
+ continue;
56060
+ }
56061
+ }
55863
56062
  const h = c.rs === 1 ? pcs[0].h : rowY[Math.min(c.ra + c.rs, nRows)] - rowY[c.ra];
55864
56063
  geom.push({ c, page: startPage + pcs[0].page, ...xw(c), y: pcs[0].y, h });
55865
56064
  }
55866
- for (const page of contPages) for (const c of cells) if (c.ra < hdrRows) geom.push({ c, page, ...xw(c), y: ctx.geom.MT + num2(findChildByLocalName(tbl2, "outMargin"), "top") + rowY[c.ra], h: rowY[Math.min(c.ra + c.rs, nRows)] - rowY[c.ra] });
56065
+ const contBase = depth !== 1 && ctx.splitContMT !== void 0 ? ctx.splitContMT : ctx.geom.MT;
56066
+ for (const page of contPages) for (const c of cells) if (c.ra < hdrRows) geom.push({ c, page, ...xw(c), y: contBase + num2(findChildByLocalName(tbl2, "outMargin"), "top") + rowY[c.ra], h: rowY[Math.min(c.ra + c.rs, nRows)] - rowY[c.ra] });
55867
56067
  for (const g3 of geom) {
55868
56068
  ctx.page = g3.page;
55869
56069
  const bf = g3.c.bfId != null ? ctx.styles.borderFill.get(g3.c.bfId) : void 0;
@@ -55908,7 +56108,7 @@ function drawTable(tbl2, tx, ty, ctx, depth) {
55908
56108
  });
55909
56109
  ctx.splitCell = splitHere;
55910
56110
  const contMTSaved = ctx.splitContMT;
55911
- ctx.splitContMT = ctx.geom.MT + num2(findChildByLocalName(tbl2, "outMargin"), "top") + rowY[hdrRows] + c.marginT;
56111
+ ctx.splitContMT = (depth > 1 && contMTSaved !== void 0 ? contMTSaved : ctx.geom.MT) + num2(findChildByLocalName(tbl2, "outMargin"), "top") + rowY[hdrRows] + c.marginT;
55912
56112
  drawPara(p, g3.x + c.marginL, base, g3.w - c.marginL - c.marginR, ctx, depth + 1, pages);
55913
56113
  ctx.splitContMT = contMTSaved;
55914
56114
  ctx.splitCell = false;
@@ -56496,7 +56696,8 @@ async function renderHwpxInternal(input, options) {
56496
56696
  const verFile = zip.file("version.xml");
56497
56697
  const verXml = verFile ? await readZipEntry(verFile, "text") : void 0;
56498
56698
  const appMajor = hwpxAppMajor(verXml), appBuild = hwpxAppBuild(verXml);
56499
- const styles = headFile ? parseRenderStyles(await readZipEntry(headFile, "text"), { appMajor, appBuild }) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
56699
+ const headXml = headFile ? await readZipEntry(headFile, "text") : void 0;
56700
+ let styles = headXml ? parseRenderStyles(headXml, { appMajor, appBuild }) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), paraGeom: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
56500
56701
  if (!headFile) warnings.push("header.xml \uC5C6\uC74C \u2014 \uAE30\uBCF8 \uC2A4\uD0C0\uC77C\uB85C \uB80C\uB354");
56501
56702
  const secXmls = [];
56502
56703
  for (const f of secFiles) {
@@ -56504,6 +56705,10 @@ async function renderHwpxInternal(input, options) {
56504
56705
  if (xml.length > MAX_DECOMPRESS_SIZE) throw new KordocError("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
56505
56706
  secXmls.push(xml);
56506
56707
  }
56708
+ if (headXml && hasKoPubSubst(headXml)) {
56709
+ const alt2 = parseRenderStyles(headXml, { appMajor, appBuild, substKoPub: true });
56710
+ if (kopubSubstituted(secXmls, styles, alt2)) styles = alt2;
56711
+ }
56507
56712
  const masterPages = /* @__PURE__ */ new Map();
56508
56713
  const masterXmls = [];
56509
56714
  for (const file of zip.file(/Contents\/masterpage[^/]*\.xml$/i)) {
@@ -56555,6 +56760,7 @@ async function renderHwpxInternal(input, options) {
56555
56760
  }
56556
56761
  const roots = [];
56557
56762
  let noCacheSkipped = false;
56763
+ const lastParity = /* @__PURE__ */ new Map();
56558
56764
  for (let si = 0; si < secXmls.length; si++) {
56559
56765
  const secXml = secXmls[si];
56560
56766
  const hasCache = /<(?:[A-Za-z][\w.-]*:)?linesegarray[\s/>]/.test(secXml);
@@ -56571,6 +56777,14 @@ async function renderHwpxInternal(input, options) {
56571
56777
  }
56572
56778
  const secPr = findFirst(root, "secPr");
56573
56779
  const referenced = secPr ? elements(secPr).filter((el) => ln(el) === "masterPage").map((el) => masterPages.get(el.getAttribute("idRef") || "")).filter((el) => !!el) : [];
56780
+ const typeOf = (m) => m.getAttribute("type") || "BOTH";
56781
+ const has3 = (t) => referenced.some((m) => typeOf(m) === t);
56782
+ if (!has3("BOTH")) for (const [t, other] of [["EVEN", "ODD"], ["ODD", "EVEN"]]) {
56783
+ const prev = lastParity.get(t);
56784
+ if (prev && !has3(t) && has3(other)) referenced.unshift(prev);
56785
+ }
56786
+ for (const m of referenced) if (typeOf(m) === "EVEN" || typeOf(m) === "ODD") lastParity.set(typeOf(m), m);
56787
+ if (has3("BOTH")) lastParity.clear();
56574
56788
  roots.push({ root, index: si, masterPages: referenced, hasDeletionMarkers: secXml.includes("deleteBegin") || secXml.includes("deleteEnd") });
56575
56789
  }
56576
56790
  if (roots.length === 0) {
@@ -57605,7 +57819,7 @@ function scriptsOff(r, off) {
57605
57819
  }
57606
57820
  async function parseImage(buffer, options) {
57607
57821
  try {
57608
- const { parseImageDocument } = await import("./image-ocr-J54Q3YWP.js");
57822
+ const { parseImageDocument } = await import("./image-ocr-THA5BASF.js");
57609
57823
  const { blocks, warnings, lines } = await parseImageDocument(buffer, options);
57610
57824
  stripScriptTags({ blocks });
57611
57825
  return {
@@ -57669,7 +57883,7 @@ async function parseHwp(buffer, options) {
57669
57883
  async function parsePdf(buffer, options) {
57670
57884
  let parsePdfDocument;
57671
57885
  try {
57672
- const mod = await import("./parser-OBGWEWSU.js");
57886
+ const mod = await import("./parser-MNNJSFEZ.js");
57673
57887
  parsePdfDocument = mod.parsePdfDocument;
57674
57888
  } catch {
57675
57889
  return {