kordoc 4.17.0 → 4.17.2

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 (143) hide show
  1. package/README.md +6 -3
  2. package/dist/{-PRAKO6M4.js → -2UA2JHVA.js} +11 -11
  3. package/dist/{chunk-I5DJOP62.js → chunk-2XHXABCX.js} +2 -2
  4. package/dist/{chunk-4XVNQAK5.js → chunk-3N272C5L.js} +244 -115
  5. package/dist/chunk-3N272C5L.js.map +1 -0
  6. package/dist/{chunk-6RGGYQQC.js → chunk-4HRJISJF.js} +3 -3
  7. package/dist/{chunk-WN6OD2CQ.js → chunk-4TSYMJDL.js} +243 -114
  8. package/dist/chunk-4TSYMJDL.js.map +1 -0
  9. package/dist/{chunk-EFO6JZY6.js → chunk-5JZEY5IL.js} +119 -77
  10. package/dist/chunk-5JZEY5IL.js.map +1 -0
  11. package/dist/{chunk-WYON5ANU.cjs → chunk-6DOCSYEM.cjs} +113 -71
  12. package/dist/chunk-6DOCSYEM.cjs.map +1 -0
  13. package/dist/{chunk-BZG7K44Z.js → chunk-6OCKAXIS.js} +2 -2
  14. package/dist/{chunk-ZF6KHPB7.js → chunk-A2W2JQ3S.js} +11 -5
  15. package/dist/chunk-A2W2JQ3S.js.map +1 -0
  16. package/dist/{chunk-N6V7LQBL.js → chunk-C4MVZXB5.js} +2 -2
  17. package/dist/{chunk-4GSF2R7T.js → chunk-FGL4IGOT.js} +4 -4
  18. package/dist/{chunk-R2BUANHQ.cjs → chunk-GPC72VSF.cjs} +6 -6
  19. package/dist/chunk-GPC72VSF.cjs.map +1 -0
  20. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  21. package/dist/{chunk-TDQ6XDB3.js → chunk-GYTL6WT3.js} +3 -3
  22. package/dist/{chunk-O7OUX6NU.cjs → chunk-HAW2VL62.cjs} +12 -12
  23. package/dist/chunk-HAW2VL62.cjs.map +1 -0
  24. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  25. package/dist/{chunk-QJWVMPB6.js → chunk-JY2NBFIG.js} +15 -13
  26. package/dist/chunk-JY2NBFIG.js.map +1 -0
  27. package/dist/{chunk-A55JGNKD.js → chunk-KQIYC2ZU.js} +2 -2
  28. package/dist/{chunk-QNJLLF4J.cjs → chunk-KZVQK5NS.cjs} +11 -5
  29. package/dist/chunk-KZVQK5NS.cjs.map +1 -0
  30. package/dist/{chunk-PHID6WNG.js → chunk-MDCTITUG.js} +2 -2
  31. package/dist/{chunk-2KF5WZCR.js → chunk-O4CB7D2Q.js} +2 -2
  32. package/dist/{chunk-YZ5HHS6A.js → chunk-SDRKHEVT.js} +2 -2
  33. package/dist/{chunk-MJBCXW5R.js → chunk-UX3HHAWH.js} +1 -1
  34. package/dist/{chunk-MJBCXW5R.js.map → chunk-UX3HHAWH.js.map} +1 -1
  35. package/dist/{chunk-K2VYABZ3.js → chunk-VU26WGE5.js} +102 -38
  36. package/dist/chunk-VU26WGE5.js.map +1 -0
  37. package/dist/{chunk-BFT5IM2R.js → chunk-WJLICIYV.js} +2 -2
  38. package/dist/{chunk-5CDUL6PH.js → chunk-WL3BWROT.js} +1 -1
  39. package/dist/{chunk-5CDUL6PH.js.map → chunk-WL3BWROT.js.map} +1 -1
  40. package/dist/{chunk-XEPKOC2O.cjs → chunk-WWMKIHF7.cjs} +344 -215
  41. package/dist/chunk-WWMKIHF7.cjs.map +1 -0
  42. package/dist/{chunk-BLPR4HRF.js → chunk-XZA6X34R.js} +121 -77
  43. package/dist/chunk-XZA6X34R.js.map +1 -0
  44. package/dist/{chunk-ML4NHUR7.js → chunk-YGKC6E6A.js} +11 -5
  45. package/dist/chunk-YGKC6E6A.js.map +1 -0
  46. package/dist/{chunk-AKB72TEH.cjs → chunk-YIANW5QX.cjs} +1 -1
  47. package/dist/chunk-YIANW5QX.cjs.map +1 -0
  48. package/dist/{chunk-WY5JAR4O.js → chunk-ZDX5PIWR.js} +2 -2
  49. package/dist/chunks-EBWJR55V.js +10 -0
  50. package/dist/cli.js +26 -26
  51. package/dist/{formula-ECNOZT36.cjs → formula-5RETDCIC.cjs} +9 -9
  52. package/dist/formula-5RETDCIC.cjs.map +1 -0
  53. package/dist/{formula-7MMFBRGJ.js → formula-MBLN2DG4.js} +4 -4
  54. package/dist/{formula-SHBXRXOJ.js → formula-QZZDW5GW.js} +3 -3
  55. package/dist/{image-ocr-P6ECJCT2.js → image-ocr-CJSO3QSR.js} +8 -8
  56. package/dist/{image-ocr-QCT3A7X5.js → image-ocr-EREKAS47.js} +6 -6
  57. package/dist/{image-ocr-VUDSP2B4.cjs → image-ocr-PSPVRLB5.cjs} +15 -15
  58. package/dist/image-ocr-PSPVRLB5.cjs.map +1 -0
  59. package/dist/index.cjs +688 -622
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +2 -1
  62. package/dist/index.d.ts +2 -1
  63. package/dist/index.js +106 -40
  64. package/dist/index.js.map +1 -1
  65. package/dist/mcp.js +22 -22
  66. package/dist/{model-bundle-OUHGCEZY.js → model-bundle-MA4MMCRJ.js} +5 -5
  67. package/dist/{models-6D6LMOTH.js → models-SEJ7LNSN.js} +5 -5
  68. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  69. package/dist/{parser-ZPRQ3SSU.js → parser-M5WHRX25.js} +41 -23
  70. package/dist/parser-M5WHRX25.js.map +1 -0
  71. package/dist/{parser-RQ4PJRTJ.cjs → parser-QILYPWSI.cjs} +215 -197
  72. package/dist/parser-QILYPWSI.cjs.map +1 -0
  73. package/dist/{parser-CTRB7PKD.js → parser-VH3F4EQU.js} +38 -20
  74. package/dist/parser-VH3F4EQU.js.map +1 -0
  75. package/dist/pdf-ocr-3SZUM3CN.cjs +16 -0
  76. package/dist/pdf-ocr-3SZUM3CN.cjs.map +1 -0
  77. package/dist/pdf-ocr-QB2TB5W5.js +18 -0
  78. package/dist/pdf-ocr-XC33L43D.js +15 -0
  79. package/dist/{profile-io-YZUW6MAN.js → profile-io-5YB627EO.js} +3 -3
  80. package/dist/{rasterize-OUR2QJXX.js → rasterize-V2XHHS2I.js} +3 -3
  81. package/dist/{redact-doc-4OQKG4SM.js → redact-doc-5MK5L5IQ.js} +11 -11
  82. package/dist/{render-XNO6PZJO.js → render-SYZMHYK6.js} +7 -7
  83. package/dist/seal-IPKIQHYB.js +10 -0
  84. package/dist/{setup-UU3EIHNI.js → setup-ZPLJENSK.js} +3 -3
  85. package/dist/visual-RTTGNOAE.js +20 -0
  86. package/dist/{watch-SR6Q5SQN.js → watch-FNWHVKK3.js} +12 -12
  87. package/package.json +1 -1
  88. package/dist/chunk-4XVNQAK5.js.map +0 -1
  89. package/dist/chunk-AKB72TEH.cjs.map +0 -1
  90. package/dist/chunk-BLPR4HRF.js.map +0 -1
  91. package/dist/chunk-EFO6JZY6.js.map +0 -1
  92. package/dist/chunk-K2VYABZ3.js.map +0 -1
  93. package/dist/chunk-ML4NHUR7.js.map +0 -1
  94. package/dist/chunk-O7OUX6NU.cjs.map +0 -1
  95. package/dist/chunk-QJWVMPB6.js.map +0 -1
  96. package/dist/chunk-QNJLLF4J.cjs.map +0 -1
  97. package/dist/chunk-R2BUANHQ.cjs.map +0 -1
  98. package/dist/chunk-WN6OD2CQ.js.map +0 -1
  99. package/dist/chunk-WYON5ANU.cjs.map +0 -1
  100. package/dist/chunk-XEPKOC2O.cjs.map +0 -1
  101. package/dist/chunk-ZF6KHPB7.js.map +0 -1
  102. package/dist/chunks-YBFBLJ4G.js +0 -10
  103. package/dist/formula-ECNOZT36.cjs.map +0 -1
  104. package/dist/image-ocr-VUDSP2B4.cjs.map +0 -1
  105. package/dist/parser-CTRB7PKD.js.map +0 -1
  106. package/dist/parser-RQ4PJRTJ.cjs.map +0 -1
  107. package/dist/parser-ZPRQ3SSU.js.map +0 -1
  108. package/dist/pdf-ocr-462ZFSHX.js +0 -15
  109. package/dist/pdf-ocr-L35FQYGP.js +0 -18
  110. package/dist/pdf-ocr-STK5EQFF.cjs +0 -16
  111. package/dist/pdf-ocr-STK5EQFF.cjs.map +0 -1
  112. package/dist/seal-CJ7C44JN.js +0 -10
  113. package/dist/visual-QRMRFPUK.js +0 -20
  114. /package/dist/{-PRAKO6M4.js.map → -2UA2JHVA.js.map} +0 -0
  115. /package/dist/{chunk-I5DJOP62.js.map → chunk-2XHXABCX.js.map} +0 -0
  116. /package/dist/{chunk-6RGGYQQC.js.map → chunk-4HRJISJF.js.map} +0 -0
  117. /package/dist/{chunk-BZG7K44Z.js.map → chunk-6OCKAXIS.js.map} +0 -0
  118. /package/dist/{chunk-N6V7LQBL.js.map → chunk-C4MVZXB5.js.map} +0 -0
  119. /package/dist/{chunk-4GSF2R7T.js.map → chunk-FGL4IGOT.js.map} +0 -0
  120. /package/dist/{chunk-TDQ6XDB3.js.map → chunk-GYTL6WT3.js.map} +0 -0
  121. /package/dist/{chunk-A55JGNKD.js.map → chunk-KQIYC2ZU.js.map} +0 -0
  122. /package/dist/{chunk-PHID6WNG.js.map → chunk-MDCTITUG.js.map} +0 -0
  123. /package/dist/{chunk-2KF5WZCR.js.map → chunk-O4CB7D2Q.js.map} +0 -0
  124. /package/dist/{chunk-YZ5HHS6A.js.map → chunk-SDRKHEVT.js.map} +0 -0
  125. /package/dist/{chunk-BFT5IM2R.js.map → chunk-WJLICIYV.js.map} +0 -0
  126. /package/dist/{chunk-WY5JAR4O.js.map → chunk-ZDX5PIWR.js.map} +0 -0
  127. /package/dist/{chunks-YBFBLJ4G.js.map → chunks-EBWJR55V.js.map} +0 -0
  128. /package/dist/{formula-7MMFBRGJ.js.map → formula-MBLN2DG4.js.map} +0 -0
  129. /package/dist/{formula-SHBXRXOJ.js.map → formula-QZZDW5GW.js.map} +0 -0
  130. /package/dist/{image-ocr-P6ECJCT2.js.map → image-ocr-CJSO3QSR.js.map} +0 -0
  131. /package/dist/{image-ocr-QCT3A7X5.js.map → image-ocr-EREKAS47.js.map} +0 -0
  132. /package/dist/{model-bundle-OUHGCEZY.js.map → model-bundle-MA4MMCRJ.js.map} +0 -0
  133. /package/dist/{models-6D6LMOTH.js.map → models-SEJ7LNSN.js.map} +0 -0
  134. /package/dist/{pdf-ocr-462ZFSHX.js.map → pdf-ocr-QB2TB5W5.js.map} +0 -0
  135. /package/dist/{pdf-ocr-L35FQYGP.js.map → pdf-ocr-XC33L43D.js.map} +0 -0
  136. /package/dist/{profile-io-YZUW6MAN.js.map → profile-io-5YB627EO.js.map} +0 -0
  137. /package/dist/{rasterize-OUR2QJXX.js.map → rasterize-V2XHHS2I.js.map} +0 -0
  138. /package/dist/{redact-doc-4OQKG4SM.js.map → redact-doc-5MK5L5IQ.js.map} +0 -0
  139. /package/dist/{render-XNO6PZJO.js.map → render-SYZMHYK6.js.map} +0 -0
  140. /package/dist/{seal-CJ7C44JN.js.map → seal-IPKIQHYB.js.map} +0 -0
  141. /package/dist/{setup-UU3EIHNI.js.map → setup-ZPLJENSK.js.map} +0 -0
  142. /package/dist/{visual-QRMRFPUK.js.map → visual-RTTGNOAE.js.map} +0 -0
  143. /package/dist/{watch-SR6Q5SQN.js.map → watch-FNWHVKK3.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -270,7 +270,8 @@ interface ParseOptions {
270
270
  * `images` 는 비고, 블록의 `imageData` 도 떼며, HWP5 `inlineImages` 도 무시한다.
271
271
  * 그림 자리 표시(`![image](…)`)는 마크다운·블록에 그대로 남아 위치는 알 수 있다.
272
272
  * PDF 는 PNG 인코딩을 건너뛴다. 거르는 기준은 같되 메모리 보호용 128MB 누적 상한은 걸리지
273
- * 않아, 그 상한 뒤의 그림도 자리 표시가 남는다.
273
+ * 않아, 그 상한 뒤의 그림도 자리 표시가 남는다. DOCX 는 그림 파트(`word/media`·`word/embeddings`)를
274
+ * 풀지 않고 ZIP 비압축 상한(100MB)에도 세지 않는다 (#108).
274
275
  *
275
276
  * 검색 색인처럼 글자만 필요한 호출자용이다. 그림이 많은 문서는 base64 로 불어난 이미지가
276
277
  * JSON 출력의 대부분을 차지했다 (PDF 실측 200MB → 9.5MB, CPU 시간 30% 감소). 본문 글자와
package/dist/index.d.ts CHANGED
@@ -270,7 +270,8 @@ interface ParseOptions {
270
270
  * `images` 는 비고, 블록의 `imageData` 도 떼며, HWP5 `inlineImages` 도 무시한다.
271
271
  * 그림 자리 표시(`![image](…)`)는 마크다운·블록에 그대로 남아 위치는 알 수 있다.
272
272
  * PDF 는 PNG 인코딩을 건너뛴다. 거르는 기준은 같되 메모리 보호용 128MB 누적 상한은 걸리지
273
- * 않아, 그 상한 뒤의 그림도 자리 표시가 남는다.
273
+ * 않아, 그 상한 뒤의 그림도 자리 표시가 남는다. DOCX 는 그림 파트(`word/media`·`word/embeddings`)를
274
+ * 풀지 않고 ZIP 비압축 상한(100MB)에도 세지 않는다 (#108).
274
275
  *
275
276
  * 검색 색인처럼 글자만 필요한 호출자용이다. 그림이 많은 문서는 base64 로 불어난 이미지가
276
277
  * JSON 출력의 대부분을 차지했다 (PDF 실측 200MB → 9.5MB, CPU 시간 30% 감소). 본문 글자와
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  mapPuaText,
17
17
  markNonLayoutTable,
18
18
  noteSuffix
19
- } from "./chunk-YZ5HHS6A.js";
19
+ } from "./chunk-SDRKHEVT.js";
20
20
  import {
21
21
  parsePageRange
22
22
  } from "./chunk-V4BH5SRQ.js";
@@ -30,7 +30,7 @@ import {
30
30
  tidyScriptTags,
31
31
  unframeLayoutTables,
32
32
  wrapScript
33
- } from "./chunk-MJBCXW5R.js";
33
+ } from "./chunk-UX3HHAWH.js";
34
34
  import {
35
35
  KordocError,
36
36
  OPTIONAL_DEP_INSTALL_HINT,
@@ -47,7 +47,7 @@ import {
47
47
  toArrayBuffer,
48
48
  unescapeHtml,
49
49
  unzipLimitBytes
50
- } from "./chunk-ML4NHUR7.js";
50
+ } from "./chunk-YGKC6E6A.js";
51
51
 
52
52
  // src/plain-markdown.ts
53
53
  function toPlainMarkdown(md2) {
@@ -746,6 +746,7 @@ async function extractHwpxStyles(zip, decompressed) {
746
746
  continue;
747
747
  }
748
748
  }
749
+ if (result.borderEdges.size > 0 && !result.borderEdges.has("0")) result.borderEdges.set("0", { t: false, b: false, l: false, r: false });
749
750
  return result;
750
751
  }
751
752
  function parseCharProperties(doc, map) {
@@ -5657,7 +5658,9 @@ function parseCell(records, lhIdx, end, ctx) {
5657
5658
  if (isHeader) cell2.isHeader = true;
5658
5659
  if (rec.data.length >= 24 && rec.data.readUInt32LE(20) > A4_HEIGHT) cell2.pageSpanning = true;
5659
5660
  if (rec.data.length >= 34) {
5660
- const edges = ctx.docInfo?.borderEdges?.[rec.data.readUInt16LE(32) - 1];
5661
+ const borderFillId = rec.data.readUInt16LE(32);
5662
+ const definitions = ctx.docInfo?.borderEdges;
5663
+ const edges = borderFillId === 0 && definitions?.length ? { t: false, b: false, l: false, r: false } : definitions?.[borderFillId - 1];
5661
5664
  if (edges) cell2.edges = edges;
5662
5665
  }
5663
5666
  return cell2;
@@ -20233,6 +20236,21 @@ var ListCounter = class {
20233
20236
  }
20234
20237
  };
20235
20238
 
20239
+ // src/docx/symbol-font.ts
20240
+ var SYMBOL_LO = " !\u2200#\u2203%&\u220B()\u2217+,\u2212./0123456789:;<=>?\u2245\u0391\u0392\u03A7\u0394\u0395\u03A6\u0393\u0397\u0399\u03D1\u039A\u039B\u039C\u039D\u039F\u03A0\u0398\u03A1\u03A3\u03A4\u03A5\u03C2\u03A9\u039E\u03A8\u0396[\u2234]\u22A5_\0\u03B1\u03B2\u03C7\u03B4\u03B5\u03C6\u03B3\u03B7\u03B9\u03D5\u03BA\u03BB\u03BC\u03BD\u03BF\u03C0\u03B8\u03C1\u03C3\u03C4\u03C5\u03D6\u03C9\u03BE\u03C8\u03B6{|}\u223C";
20241
+ var SYMBOL_HI = "\u20AC\u03D2\u2032\u2264\u2044\u221E\u0192\u2663\u2666\u2665\u2660\u2194\u2190\u2191\u2192\u2193\xB0\xB1\u2033\u2265\xD7\u221D\u2202\u2022\xF7\u2260\u2261\u2248\u2026\u23D0\u23AF\u21B5\u2135\u2111\u211C\u2118\u2297\u2295\u2205\u2229\u222A\u2283\u2287\u2284\u2282\u2286\u2208\u2209\u2220\u2207\xAE\xA9\u2122\u220F\u221A\u22C5\xAC\u2227\u2228\u21D4\u21D0\u21D1\u21D2\u21D3\u25CA\u27E8\xAE\xA9\u2122\u2211\u239B\u239C\u239D\u23A1\u23A2\u23A3\u23A7\u23A8\u23A9\u23AA\0\u27E9\u222B\u2320\u23AE\u2321\u239E\u239F\u23A0\u23A4\u23A5\u23A6\u23AB\u23AC\u23AD";
20242
+ var DINGBAT_FONT_RE = /^\s*(?:wingdings|webdings|marlett|zapf\s*dingbats)/i;
20243
+ function symbolChar(font, char) {
20244
+ const code = parseInt(char ?? "", 16);
20245
+ if (!(code >= 32 && code <= 65535) || DINGBAT_FONT_RE.test(font ?? "")) return "";
20246
+ if (/^\s*symbol\s*$/i.test(font ?? "")) {
20247
+ const lo = code & 255;
20248
+ const c = lo >= 32 && lo <= 126 ? SYMBOL_LO[lo - 32] : lo >= 160 && lo <= 254 ? SYMBOL_HI[lo - 160] : "";
20249
+ return c === "\0" ? "" : c;
20250
+ }
20251
+ return code >= 61440 && code <= 61695 ? "" : String.fromCharCode(code);
20252
+ }
20253
+
20236
20254
  // src/docx/parser.ts
20237
20255
  import { DOMParser as DOMParser3 } from "@xmldom/xmldom";
20238
20256
 
@@ -20240,8 +20258,12 @@ import { DOMParser as DOMParser3 } from "@xmldom/xmldom";
20240
20258
  function runToLatex(r) {
20241
20259
  let out = "";
20242
20260
  for (const t of childrenByLocalName(r, "t")) out += t.textContent ?? "";
20243
- return out;
20261
+ return out.replace(/[#%]/g, "\\$&");
20262
+ }
20263
+ function join(a, b) {
20264
+ return /\\[A-Za-z]+$/.test(a) && /^[A-Za-z]/.test(b) ? a + " " + b : a + b;
20244
20265
  }
20266
+ var EQ_NUMBER_RE = /\s*\\#\s*(?:\\left\((.+)\\right\)|\(([^()]*)\))\s*$/;
20245
20267
  var FUNC_NAMES = /* @__PURE__ */ new Set([
20246
20268
  "sin",
20247
20269
  "cos",
@@ -20361,7 +20383,7 @@ function grp(body) {
20361
20383
  function childrenToLatex(parent) {
20362
20384
  let out = "";
20363
20385
  for (const ch of elementChildren(parent)) {
20364
- out += nodeToLatex(ch);
20386
+ out = join(out, nodeToLatex(ch));
20365
20387
  }
20366
20388
  return out;
20367
20389
  }
@@ -20486,7 +20508,7 @@ function nodeToLatex(el) {
20486
20508
  }
20487
20509
  const items = childrenByLocalName(el, "e").map(childrenToLatex);
20488
20510
  const body = items.join(sep);
20489
- return "\\left" + mapDelim(beg, true) + body + "\\right" + mapDelim(end, false);
20511
+ return join("\\left" + mapDelim(beg, true), body) + "\\right" + mapDelim(end, false);
20490
20512
  }
20491
20513
  // 행렬
20492
20514
  case "m": {
@@ -20555,10 +20577,16 @@ function nodeToLatex(el) {
20555
20577
  // group character (over/underset 비슷)
20556
20578
  case "groupChr":
20557
20579
  return childrenToLatex(findChildByLocalName(el, "e") ?? el);
20558
- // box/borderBox/phantom/eqArr/… 는 자식 본문만 유지
20580
+ // 수식 배열 — 한 줄짜리 끝의 수식 번호 `#(43)` 는 \tag{43} (#106). 여러 줄은 종전대로 이어 붙인다
20581
+ case "eqArr": {
20582
+ const rows = childrenByLocalName(el, "e");
20583
+ const one = rows.length === 1 ? childrenToLatex(rows[0]) : "";
20584
+ const m = one.match(EQ_NUMBER_RE);
20585
+ return m ? one.slice(0, m.index) + " \\tag{" + (m[1] ?? m[2]).trim() + "}" : childrenToLatex(el);
20586
+ }
20587
+ // box/borderBox/phantom/… 는 자식 본문만 유지
20559
20588
  case "borderBox":
20560
20589
  case "phant":
20561
- case "eqArr":
20562
20590
  return childrenToLatex(el);
20563
20591
  // 최상위 컨테이너
20564
20592
  case "oMath":
@@ -20598,6 +20626,7 @@ function isDisplayMath(el) {
20598
20626
 
20599
20627
  // src/docx/parser.ts
20600
20628
  var MAX_DECOMPRESS_SIZE5 = unzipLimitBytes(100 * 1024 * 1024);
20629
+ var MEDIA_PART_RE = /^word\/(?:media|embeddings)\//;
20601
20630
  function matchesLocal(el, localName3) {
20602
20631
  return el.localName === localName3 || (el.tagName?.endsWith(`:${localName3}`) ?? false);
20603
20632
  }
@@ -20615,7 +20644,7 @@ function effectiveChildElements(parent) {
20615
20644
  result.push(...effectiveChildElements(c));
20616
20645
  }
20617
20646
  }
20618
- } else if (matchesLocal(el, "ins") || matchesLocal(el, "smartTag")) {
20647
+ } else if (matchesLocal(el, "ins") || matchesLocal(el, "smartTag") || matchesLocal(el, "dir") || matchesLocal(el, "bdo")) {
20619
20648
  result.push(...effectiveChildElements(el));
20620
20649
  } else {
20621
20650
  result.push(el);
@@ -20823,6 +20852,7 @@ function extractRun(r) {
20823
20852
  if (matchesLocal(el, "t")) text += el.textContent ?? "";
20824
20853
  else if (matchesLocal(el, "br") || matchesLocal(el, "cr")) text += "\n";
20825
20854
  else if (matchesLocal(el, "tab")) text += " ";
20855
+ else if (matchesLocal(el, "sym")) text += symbolChar(getAttr(el, "font"), getAttr(el, "char"));
20826
20856
  }
20827
20857
  let bold = false;
20828
20858
  let italic = false;
@@ -20873,7 +20903,19 @@ function collectInline(p, footnotes, rels) {
20873
20903
  fieldInstr = "";
20874
20904
  fieldDisplay = "";
20875
20905
  };
20906
+ const placedMath = /* @__PURE__ */ new Set();
20907
+ const mathText = (om) => {
20908
+ const latex = ommlElementToLatex(om);
20909
+ return !latex ? "" : isDisplayMath(om) ? " $$" + latex + "$$ " : "$" + latex + "$";
20910
+ };
20876
20911
  for (const el of effectiveChildElements(p)) {
20912
+ if (matchesLocal(el, "oMath") || matchesLocal(el, "oMathPara")) {
20913
+ placedMath.add(el);
20914
+ const m = mathText(el);
20915
+ if (fieldActive && fieldStage === "display") fieldDisplay += m;
20916
+ else parts.push(m);
20917
+ continue;
20918
+ }
20877
20919
  if (matchesLocal(el, "hyperlink")) {
20878
20920
  const rId = getAttr(el, "id");
20879
20921
  const anchor = getAttr(el, "anchor");
@@ -20925,10 +20967,9 @@ function collectInline(p, footnotes, rels) {
20925
20967
  }
20926
20968
  flushField();
20927
20969
  for (const om of collectOmmlRoots(p)) {
20928
- const latex = ommlElementToLatex(om);
20929
- if (!latex) continue;
20930
- if (isDisplayMath(om)) parts.push(" $$" + latex + "$$ ");
20931
- else parts.push(" $" + latex + "$ ");
20970
+ if (placedMath.has(om)) continue;
20971
+ const m = mathText(om);
20972
+ if (m) parts.push(isDisplayMath(om) ? m : " " + m + " ");
20932
20973
  }
20933
20974
  const text = tidyScriptTags(parts.join("")).replace(/[ \t]{2,}/g, " ").trim();
20934
20975
  return { text, bold, italic, footnoteText };
@@ -21080,7 +21121,7 @@ function collectCellText(tc2, styles, numbering, footnotes, rels, depth) {
21080
21121
  }
21081
21122
  return parts;
21082
21123
  }
21083
- async function buildImageMap(zip, rels, doc, warnings) {
21124
+ async function buildImageMap(zip, rels, doc, warnings, readBytes) {
21084
21125
  const imageMap = /* @__PURE__ */ new Map();
21085
21126
  const images = [];
21086
21127
  let imgIdx = 0;
@@ -21101,7 +21142,8 @@ async function buildImageMap(zip, rels, doc, warnings) {
21101
21142
  const imgFile = zip.file(imgPath);
21102
21143
  if (!imgFile) continue;
21103
21144
  try {
21104
- const data = await imgFile.async("uint8array");
21145
+ let data = null;
21146
+ if (readBytes) data = await imgFile.async("uint8array");
21105
21147
  imgIdx++;
21106
21148
  const ext = imgPath.split(".").pop()?.toLowerCase() ?? "png";
21107
21149
  const mimeMap = {
@@ -21117,8 +21159,10 @@ async function buildImageMap(zip, rels, doc, warnings) {
21117
21159
  svg: "image/svg+xml"
21118
21160
  };
21119
21161
  const filename = `image_${String(imgIdx).padStart(3, "0")}.${ext}`;
21120
- const mimeType = mimeMap[ext] ?? detectImageMime(data) ?? "application/octet-stream";
21121
- images.push({ filename, data, mimeType, source: imgPath });
21162
+ if (data) {
21163
+ const mimeType = mimeMap[ext] ?? detectImageMime(data) ?? "application/octet-stream";
21164
+ images.push({ filename, data, mimeType, source: imgPath });
21165
+ }
21122
21166
  imageMap.set(embedId, filename);
21123
21167
  } catch (err) {
21124
21168
  warnings.push({
@@ -21199,7 +21243,8 @@ async function parseHeaderFooterBlocks(zip, doc, rels, kind, styles, numbering,
21199
21243
  return out;
21200
21244
  }
21201
21245
  async function parseDocxDocument(buffer, options) {
21202
- precheckZipSize(buffer, MAX_DECOMPRESS_SIZE5);
21246
+ const readImages = options?.images !== false;
21247
+ precheckZipSize(buffer, MAX_DECOMPRESS_SIZE5, void 0, { re: MEDIA_PART_RE, skip: !readImages });
21203
21248
  const zip = await JSZip5.loadAsync(buffer);
21204
21249
  const warnings = [];
21205
21250
  const docFile = zip.file("word/document.xml");
@@ -21253,7 +21298,7 @@ async function parseDocxDocument(buffer, options) {
21253
21298
  if (body.length === 0) {
21254
21299
  throw new KordocError("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
21255
21300
  }
21256
- const { imageMap, images } = await buildImageMap(zip, rels, doc, warnings);
21301
+ const { imageMap, images } = await buildImageMap(zip, rels, doc, warnings, readImages);
21257
21302
  const linkedImages = /* @__PURE__ */ new Set();
21258
21303
  const blocks = [];
21259
21304
  const bodyEl = body[0];
@@ -25024,11 +25069,10 @@ var FONTS = {
25024
25069
  function hasFontMetrics(face) {
25025
25070
  return !!face && Object.prototype.hasOwnProperty.call(FONTS, face.trim());
25026
25071
  }
25027
- function fontAdvanceEm1000(face, cp) {
25072
+ function fontWidthFn(face) {
25073
+ if (!hasFontMetrics(face)) return null;
25028
25074
  const m = FONTS[face.trim()];
25029
- if (!m) return null;
25030
- if (cp >= 32 && cp <= 126) return m.ascii[cp - 32];
25031
- return m.ex[cp] ?? m.cjk;
25075
+ return (cp) => cp >= 32 && cp <= 126 ? m.ascii[cp - 32] : m.ex[cp] ?? m.cjk;
25032
25076
  }
25033
25077
 
25034
25078
  // src/hwpx/text-metrics.ts
@@ -25218,7 +25262,7 @@ function widthFnOf(faceClass) {
25218
25262
  if (faceClass === "gothic") return gothicWidthEm1000;
25219
25263
  if (faceClass?.startsWith("font:")) {
25220
25264
  const face = faceClass.slice(5);
25221
- return (cp) => fontAdvanceEm1000(face, cp) ?? gothicWidthEm1000(cp);
25265
+ return fontWidthFn(face) ?? gothicWidthEm1000;
25222
25266
  }
25223
25267
  return charWidthEm1000;
25224
25268
  }
@@ -25269,7 +25313,8 @@ function simulateWrap(text, firstWidth, contWidth, height, ratioPct, mode = "kee
25269
25313
  const breakBefore = (unitPos, w) => {
25270
25314
  let bp = unitPos;
25271
25315
  const u = text[unitPos];
25272
- if (u !== void 0 && FORBID_START.has(u) && bp - 1 > lineStart() && text[bp - 1] !== " ") bp--;
25316
+ const prevStart = (end) => end - (end >= 2 && /[\uDC00-\uDFFF]/.test(text[end - 1]) && /[\uD800-\uDBFF]/.test(text[end - 2]) ? 2 : 1);
25317
+ if (u !== void 0 && FORBID_START.has(u) && prevStart(bp) > lineStart() && text[bp - 1] !== " ") bp = prevStart(bp);
25273
25318
  while (bp - 1 > lineStart() && FORBID_END.has(text[bp - 1])) bp--;
25274
25319
  if (bp <= lineStart()) bp = unitPos;
25275
25320
  starts.push(bp);
@@ -25747,28 +25792,49 @@ function fitParagraph(text, font, pt2, firstW, contW, minRatio = 88, orphanRatio
25747
25792
  const ladder = [[100, 0], ...SQUEEZE.filter(([r]) => r >= minRatio)];
25748
25793
  const base = simulateWrap(text, f, c, h, 100, "keep", { faceClass });
25749
25794
  if (base.lines < 2) return null;
25795
+ const wraps = /* @__PURE__ */ new Map([["100:0", base]]);
25796
+ const looseness = /* @__PURE__ */ new Map();
25797
+ const wrap = (r, sp) => {
25798
+ const key = `${r}:${sp}`;
25799
+ let w = wraps.get(key);
25800
+ if (!w) {
25801
+ w = simulateWrap(text, f, c, h, r, "keep", { faceClass, spacingPct: sp });
25802
+ wraps.set(key, w);
25803
+ }
25804
+ return w;
25805
+ };
25806
+ const looseAt = (r, sp, w) => {
25807
+ const key = `${r}:${sp}`;
25808
+ let loose = looseness.get(key);
25809
+ if (loose === void 0) {
25810
+ loose = worstLooseness(text, w.starts, f, c, h, r, sp, faceClass);
25811
+ looseness.set(key, loose);
25812
+ }
25813
+ return loose;
25814
+ };
25750
25815
  if (base.lastLineWidth <= c * PULL_TAIL) {
25751
25816
  let pull = null;
25752
25817
  for (const [r, sp] of ladder) {
25753
25818
  const amt = squeezeOf(r, sp);
25754
25819
  if (amt > PULL_MAX + 1e-9 || pull && amt >= pull.amt - 1e-9) continue;
25755
- const w = simulateWrap(text, f, c, h, r, "keep", { faceClass, spacingPct: sp });
25756
- if (w.lines < base.lines && worstLooseness(text, w.starts, f, c, h, r, sp, faceClass) <= LOOSE_LIMIT) pull = { r, sp, amt };
25820
+ const w = wrap(r, sp);
25821
+ if (w.lines < base.lines && looseAt(r, sp, w) <= LOOSE_LIMIT) pull = { r, sp, amt };
25757
25822
  }
25758
25823
  if (pull) return { ratio: pull.r, spacing: pull.sp };
25759
25824
  }
25760
25825
  let baseLines = 0;
25761
25826
  let best = null;
25762
25827
  for (const [r, sp] of ladder) {
25763
- const w = simulateWrap(text, f, c, h, r, "keep", { faceClass, spacingPct: sp });
25828
+ const w = wrap(r, sp);
25764
25829
  if (!best) {
25765
25830
  if (w.lines < 2) return null;
25766
25831
  baseLines = w.lines;
25767
25832
  }
25768
25833
  if (w.lines > baseLines) continue;
25769
25834
  const orphan = w.lines > 1 && w.lastLineWidth <= contW * orphanRatio;
25770
- const loose = worstLooseness(text, w.starts, f, c, h, r, sp, faceClass);
25835
+ const loose = looseAt(r, sp, w);
25771
25836
  const cost = Math.max(0, loose - LOOSE_LIMIT) + (orphan ? ORPHAN_COST : 0) + squeezeOf(r, sp) * COMPRESS_COST;
25837
+ if (r === 100 && sp === 0 && cost === 0) return null;
25772
25838
  if (!best || cost < best.cost - 1e-9) best = { r, sp, cost };
25773
25839
  }
25774
25840
  return best && (best.r !== 100 || best.sp !== 0) ? { ratio: best.r, spacing: best.sp } : null;
@@ -30472,7 +30538,7 @@ function legalMarkerDepth(marker) {
30472
30538
  return 7;
30473
30539
  }
30474
30540
  function parseLeadingMarker(text, keepMarkers = false) {
30475
- const t = text.replace(/^[\s ]+/, "").replace(/^\*\*([□■ㅇ○◦●❍◎▸※-])\s*(?=\S)/u, "$1 **");
30541
+ const t = text.replace(/^[\s ]+/, "").replace(/^(\*\*|__)([□■ㅇ○◦●❍◎▸※-])\1(?=\s|$)/u, "$2").replace(/^(\*\*|__)([□■ㅇ○◦●❍◎▸※-])\s*(?=\S)/u, "$2 $1");
30476
30542
  const ref = REF_RE.exec(t);
30477
30543
  if (ref) return { kind: "ref", depth: 0, marker: ref[1], rest: t.slice(ref[0].length).trim() };
30478
30544
  if (keepMarkers) {
@@ -30942,7 +31008,7 @@ function chapterLabel(index, style) {
30942
31008
  return style === "roman" ? `${ROMAN[(index - 1) % 12]}.` : `${index}.`;
30943
31009
  }
30944
31010
  function plain2(text) {
30945
- return text.replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/!\[[^\]]*\]\([^)]*\)/g, "");
31011
+ return parseInlineMarkdown(text).map((span2) => span2.text).join("");
30946
31012
  }
30947
31013
  function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
30948
31014
  resetTableIds();
@@ -31678,7 +31744,7 @@ function diffTableCells(a, b) {
31678
31744
  // src/form/templates.ts
31679
31745
  import { existsSync, readFileSync } from "fs";
31680
31746
  import { fileURLToPath } from "url";
31681
- import { dirname, join } from "path";
31747
+ import { dirname, join as join2 } from "path";
31682
31748
  var BUILTIN_TEMPLATES = [
31683
31749
  {
31684
31750
  id: "gian",
@@ -31704,22 +31770,22 @@ function resolveBuiltinTemplate(name) {
31704
31770
  function builtinTemplateDir() {
31705
31771
  const here = dirname(fileURLToPath(import.meta.url));
31706
31772
  const candidates = [
31707
- join(here, "..", "..", "templates"),
31773
+ join2(here, "..", "..", "templates"),
31708
31774
  // src/form/templates.ts → 패키지 루트
31709
- join(here, "..", "templates")
31775
+ join2(here, "..", "templates")
31710
31776
  // dist/*.js (tsup 번들) → 패키지 루트
31711
31777
  ];
31712
31778
  for (const c of candidates) {
31713
- if (existsSync(join(c, BUILTIN_TEMPLATES[0].file))) return c;
31779
+ if (existsSync(join2(c, BUILTIN_TEMPLATES[0].file))) return c;
31714
31780
  }
31715
31781
  throw new KordocError("\uB0B4\uC7A5 templates \uB514\uB809\uD1A0\uB9AC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (\uD328\uD0A4\uC9C0 \uC124\uCE58\uAC00 \uC190\uC0C1\uB418\uC5C8\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4)");
31716
31782
  }
31717
31783
  function readBuiltinTemplate(t) {
31718
- const buf = readFileSync(join(builtinTemplateDir(), t.file));
31784
+ const buf = readFileSync(join2(builtinTemplateDir(), t.file));
31719
31785
  return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
31720
31786
  }
31721
31787
  function readBuiltinTemplateSample(t) {
31722
- return JSON.parse(readFileSync(join(builtinTemplateDir(), t.sampleFile), "utf-8"));
31788
+ return JSON.parse(readFileSync(join2(builtinTemplateDir(), t.sampleFile), "utf-8"));
31723
31789
  }
31724
31790
 
31725
31791
  // src/form/seal.ts
@@ -40663,7 +40729,7 @@ function scriptsOff(r, off) {
40663
40729
  }
40664
40730
  async function parseImage(buffer, options) {
40665
40731
  try {
40666
- const { parseImageDocument } = await import("./image-ocr-QCT3A7X5.js");
40732
+ const { parseImageDocument } = await import("./image-ocr-EREKAS47.js");
40667
40733
  const { blocks, warnings } = await parseImageDocument(buffer, options);
40668
40734
  stripScriptTags({ blocks });
40669
40735
  return {
@@ -40723,7 +40789,7 @@ async function parseHwp(buffer, options) {
40723
40789
  async function parsePdf(buffer, options) {
40724
40790
  let parsePdfDocument;
40725
40791
  try {
40726
- const mod = await import("./parser-CTRB7PKD.js");
40792
+ const mod = await import("./parser-VH3F4EQU.js");
40727
40793
  parsePdfDocument = mod.parsePdfDocument;
40728
40794
  } catch {
40729
40795
  return {