kordoc 4.9.2 → 4.11.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 (129) hide show
  1. package/README.md +55 -0
  2. package/dist/{-Z4LCTGQR.js → -LFHXUYGZ.js} +9 -9
  3. package/dist/{chunk-PIUPP3FL.js → chunk-3P6XONHY.js} +3 -3
  4. package/dist/{chunk-NOEYLJGJ.js → chunk-476CF3WL.js} +3 -3
  5. package/dist/{chunk-LREEDIEF.js → chunk-4F4PZQTW.js} +2 -2
  6. package/dist/{chunk-VYGNPB2X.js → chunk-7XDCXPWC.js} +52 -8
  7. package/dist/chunk-7XDCXPWC.js.map +1 -0
  8. package/dist/{chunk-NIBRVLGS.js → chunk-B6IA745V.js} +3 -3
  9. package/dist/{chunk-5ZPXRDS2.js → chunk-CF2FQBVN.js} +2 -2
  10. package/dist/{chunk-5ZPXRDS2.js.map → chunk-CF2FQBVN.js.map} +1 -1
  11. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  12. package/dist/{chunk-BAJVZXC7.cjs → chunk-FN6NBZ34.cjs} +3 -3
  13. package/dist/chunk-FN6NBZ34.cjs.map +1 -0
  14. package/dist/{chunk-LUY46O7O.js → chunk-FNNOBF36.js} +52 -8
  15. package/dist/chunk-FNNOBF36.js.map +1 -0
  16. package/dist/{chunk-V3Q6I2AQ.cjs → chunk-FQTPFGVG.cjs} +54 -10
  17. package/dist/chunk-FQTPFGVG.cjs.map +1 -0
  18. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  19. package/dist/{chunk-Y7QB4IB6.js → chunk-HXR7TSXU.js} +2 -2
  20. package/dist/{chunk-KATZTHWA.cjs → chunk-JO3W54E5.cjs} +2 -2
  21. package/dist/chunk-JO3W54E5.cjs.map +1 -0
  22. package/dist/{chunk-OYQL3D4B.js → chunk-LM5A4DOY.js} +2 -2
  23. package/dist/{chunk-JHPEDWJX.js → chunk-LXMQUWGU.js} +3 -3
  24. package/dist/{chunk-TK7WUS47.js → chunk-LYTFBD6P.js} +2 -2
  25. package/dist/{chunk-XINP35F4.js → chunk-N3DLQ2YH.js} +1 -1
  26. package/dist/{chunk-XINP35F4.js.map → chunk-N3DLQ2YH.js.map} +1 -1
  27. package/dist/{chunk-BN33O25L.js → chunk-ONQHGZTS.js} +1 -1
  28. package/dist/{chunk-BN33O25L.js.map → chunk-ONQHGZTS.js.map} +1 -1
  29. package/dist/{chunk-SHBVD23C.cjs → chunk-RSATURJN.cjs} +11 -11
  30. package/dist/chunk-RSATURJN.cjs.map +1 -0
  31. package/dist/{chunk-LKZQ4564.js → chunk-SD3ITJLU.js} +2 -2
  32. package/dist/{chunk-L5CDTOC3.cjs → chunk-T7GRHAIW.cjs} +1 -1
  33. package/dist/chunk-T7GRHAIW.cjs.map +1 -0
  34. package/dist/{chunk-WLZX2HTC.js → chunk-V2TMM6OD.js} +3 -3
  35. package/dist/{chunk-6WYMV73J.js → chunk-W4DVZN5M.js} +229 -19
  36. package/dist/chunk-W4DVZN5M.js.map +1 -0
  37. package/dist/{chunk-LJP3PK2S.js → chunk-W6537QWB.js} +2 -2
  38. package/dist/{chunk-GL6BCNJV.js → chunk-X25PKMMD.js} +3 -3
  39. package/dist/{chunk-NIQ4JCQF.cjs → chunk-YBTTQQBH.cjs} +6 -6
  40. package/dist/chunk-YBTTQQBH.cjs.map +1 -0
  41. package/dist/{chunk-PKCDYIIJ.js → chunk-Z37BVIRF.js} +2 -2
  42. package/dist/{chunk-OOT54JF2.js → chunk-Z6NFU6DA.js} +2 -2
  43. package/dist/{chunk-OOT54JF2.js.map → chunk-Z6NFU6DA.js.map} +1 -1
  44. package/dist/chunks-Y32RX6IF.js +10 -0
  45. package/dist/cli.js +37 -33
  46. package/dist/cli.js.map +1 -1
  47. package/dist/{formula-LFWZG7T7.js → formula-2ORTZGRU.js} +4 -4
  48. package/dist/{formula-JVBJ6QRG.cjs → formula-KFSWOSCF.cjs} +9 -9
  49. package/dist/formula-KFSWOSCF.cjs.map +1 -0
  50. package/dist/{formula-77TJPACH.js → formula-YCFGCLUF.js} +3 -3
  51. package/dist/{image-ocr-6SY623KL.js → image-ocr-2B7NVDRS.js} +8 -8
  52. package/dist/{image-ocr-YZ56O63S.js → image-ocr-JCKC4QWU.js} +6 -6
  53. package/dist/{image-ocr-YTGAUHEP.cjs → image-ocr-ZV4AP2I6.cjs} +12 -12
  54. package/dist/image-ocr-ZV4AP2I6.cjs.map +1 -0
  55. package/dist/index.cjs +411 -202
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +2 -0
  58. package/dist/index.d.ts +2 -0
  59. package/dist/index.js +224 -15
  60. package/dist/index.js.map +1 -1
  61. package/dist/mcp.js +16 -16
  62. package/dist/{model-bundle-W7B3BIYS.js → model-bundle-EX75CSEI.js} +5 -5
  63. package/dist/{models-FUKPEVPE.js → models-KJCNM77P.js} +5 -5
  64. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  65. package/dist/{parser-6UL2HLDH.js → parser-2KFORGOT.js} +7 -7
  66. package/dist/{parser-GDYZDBZI.js → parser-TXBQATM7.js} +7 -7
  67. package/dist/{parser-WIRWVN5E.cjs → parser-WY5PY5V4.cjs} +27 -27
  68. package/dist/parser-WY5PY5V4.cjs.map +1 -0
  69. package/dist/pdf-ocr-GD6KYSH7.js +16 -0
  70. package/dist/pdf-ocr-JXYOCUGR.cjs +14 -0
  71. package/dist/pdf-ocr-JXYOCUGR.cjs.map +1 -0
  72. package/dist/pdf-ocr-MNCYWT4Z.js +13 -0
  73. package/dist/{profile-io-4EE64K6Y.js → profile-io-Z5NKKNGW.js} +3 -3
  74. package/dist/{rasterize-QW7SSKHB.js → rasterize-66QIXE2S.js} +2 -2
  75. package/dist/render-ILBFLY3A.js +10 -0
  76. package/dist/seal-AKUPO4YT.js +10 -0
  77. package/dist/{setup-JS7E2HFM.js → setup-L2LYDZ6N.js} +3 -3
  78. package/dist/{watch-YISVPGW3.js → watch-HJAEDIKZ.js} +10 -10
  79. package/package.json +1 -1
  80. package/dist/chunk-6WYMV73J.js.map +0 -1
  81. package/dist/chunk-BAJVZXC7.cjs.map +0 -1
  82. package/dist/chunk-KATZTHWA.cjs.map +0 -1
  83. package/dist/chunk-L5CDTOC3.cjs.map +0 -1
  84. package/dist/chunk-LUY46O7O.js.map +0 -1
  85. package/dist/chunk-NIQ4JCQF.cjs.map +0 -1
  86. package/dist/chunk-SHBVD23C.cjs.map +0 -1
  87. package/dist/chunk-V3Q6I2AQ.cjs.map +0 -1
  88. package/dist/chunk-VYGNPB2X.js.map +0 -1
  89. package/dist/chunks-TRJGNO4N.js +0 -10
  90. package/dist/formula-JVBJ6QRG.cjs.map +0 -1
  91. package/dist/image-ocr-YTGAUHEP.cjs.map +0 -1
  92. package/dist/parser-WIRWVN5E.cjs.map +0 -1
  93. package/dist/pdf-ocr-O373AAN6.cjs +0 -14
  94. package/dist/pdf-ocr-O373AAN6.cjs.map +0 -1
  95. package/dist/pdf-ocr-OHUAQQMN.js +0 -16
  96. package/dist/pdf-ocr-XTE234WC.js +0 -13
  97. package/dist/render-2NID54BX.js +0 -10
  98. package/dist/seal-PTP4TWYR.js +0 -10
  99. /package/dist/{-Z4LCTGQR.js.map → -LFHXUYGZ.js.map} +0 -0
  100. /package/dist/{chunk-PIUPP3FL.js.map → chunk-3P6XONHY.js.map} +0 -0
  101. /package/dist/{chunk-NOEYLJGJ.js.map → chunk-476CF3WL.js.map} +0 -0
  102. /package/dist/{chunk-LREEDIEF.js.map → chunk-4F4PZQTW.js.map} +0 -0
  103. /package/dist/{chunk-NIBRVLGS.js.map → chunk-B6IA745V.js.map} +0 -0
  104. /package/dist/{chunk-Y7QB4IB6.js.map → chunk-HXR7TSXU.js.map} +0 -0
  105. /package/dist/{chunk-OYQL3D4B.js.map → chunk-LM5A4DOY.js.map} +0 -0
  106. /package/dist/{chunk-JHPEDWJX.js.map → chunk-LXMQUWGU.js.map} +0 -0
  107. /package/dist/{chunk-TK7WUS47.js.map → chunk-LYTFBD6P.js.map} +0 -0
  108. /package/dist/{chunk-LKZQ4564.js.map → chunk-SD3ITJLU.js.map} +0 -0
  109. /package/dist/{chunk-WLZX2HTC.js.map → chunk-V2TMM6OD.js.map} +0 -0
  110. /package/dist/{chunk-LJP3PK2S.js.map → chunk-W6537QWB.js.map} +0 -0
  111. /package/dist/{chunk-GL6BCNJV.js.map → chunk-X25PKMMD.js.map} +0 -0
  112. /package/dist/{chunk-PKCDYIIJ.js.map → chunk-Z37BVIRF.js.map} +0 -0
  113. /package/dist/{chunks-TRJGNO4N.js.map → chunks-Y32RX6IF.js.map} +0 -0
  114. /package/dist/{formula-LFWZG7T7.js.map → formula-2ORTZGRU.js.map} +0 -0
  115. /package/dist/{formula-77TJPACH.js.map → formula-YCFGCLUF.js.map} +0 -0
  116. /package/dist/{image-ocr-6SY623KL.js.map → image-ocr-2B7NVDRS.js.map} +0 -0
  117. /package/dist/{image-ocr-YZ56O63S.js.map → image-ocr-JCKC4QWU.js.map} +0 -0
  118. /package/dist/{model-bundle-W7B3BIYS.js.map → model-bundle-EX75CSEI.js.map} +0 -0
  119. /package/dist/{models-FUKPEVPE.js.map → models-KJCNM77P.js.map} +0 -0
  120. /package/dist/{parser-6UL2HLDH.js.map → parser-2KFORGOT.js.map} +0 -0
  121. /package/dist/{parser-GDYZDBZI.js.map → parser-TXBQATM7.js.map} +0 -0
  122. /package/dist/{pdf-ocr-OHUAQQMN.js.map → pdf-ocr-GD6KYSH7.js.map} +0 -0
  123. /package/dist/{pdf-ocr-XTE234WC.js.map → pdf-ocr-MNCYWT4Z.js.map} +0 -0
  124. /package/dist/{profile-io-4EE64K6Y.js.map → profile-io-Z5NKKNGW.js.map} +0 -0
  125. /package/dist/{rasterize-QW7SSKHB.js.map → rasterize-66QIXE2S.js.map} +0 -0
  126. /package/dist/{render-2NID54BX.js.map → render-ILBFLY3A.js.map} +0 -0
  127. /package/dist/{seal-PTP4TWYR.js.map → seal-AKUPO4YT.js.map} +0 -0
  128. /package/dist/{setup-JS7E2HFM.js.map → setup-L2LYDZ6N.js.map} +0 -0
  129. /package/dist/{watch-YISVPGW3.js.map → watch-HJAEDIKZ.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -329,6 +329,8 @@ interface ExtractedImage {
329
329
  data: Uint8Array;
330
330
  /** MIME 타입 */
331
331
  mimeType: string;
332
+ /** 원본 컨테이너 내 항목명 (HWPX/DOCX ZIP 경로, HWP5 BinData 스토리지명 — PDF 등 합성 이미지는 없음, #70) */
333
+ source?: string;
332
334
  }
333
335
  interface ParseFailure extends ParseResultBase {
334
336
  success: false;
package/dist/index.d.ts CHANGED
@@ -329,6 +329,8 @@ interface ExtractedImage {
329
329
  data: Uint8Array;
330
330
  /** MIME 타입 */
331
331
  mimeType: string;
332
+ /** 원본 컨테이너 내 항목명 (HWPX/DOCX ZIP 경로, HWP5 BinData 스토리지명 — PDF 등 합성 이미지는 없음, #70) */
333
+ source?: string;
332
334
  }
333
335
  interface ParseFailure extends ParseResultBase {
334
336
  success: false;
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  flattenLayoutTables,
9
9
  inlineImagesIntoMarkdown,
10
10
  mapPuaText
11
- } from "./chunk-VYGNPB2X.js";
11
+ } from "./chunk-7XDCXPWC.js";
12
12
  import {
13
13
  parsePageRange
14
14
  } from "./chunk-GE43BE46.js";
@@ -16,7 +16,7 @@ import {
16
16
  HEADING_RATIO_H1,
17
17
  HEADING_RATIO_H2,
18
18
  HEADING_RATIO_H3
19
- } from "./chunk-BN33O25L.js";
19
+ } from "./chunk-ONQHGZTS.js";
20
20
  import {
21
21
  KordocError,
22
22
  VERSION,
@@ -29,7 +29,7 @@ import {
29
29
  sanitizeHref,
30
30
  stripDtd,
31
31
  toArrayBuffer
32
- } from "./chunk-OOT54JF2.js";
32
+ } from "./chunk-Z6NFU6DA.js";
33
33
 
34
34
  // src/index.ts
35
35
  import { readFile } from "fs/promises";
@@ -2927,7 +2927,7 @@ function resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced) {
2927
2927
  const ext = mime.includes("jpeg") ? "jpg" : mime.includes("png") ? "png" : mime.includes("gif") ? "gif" : mime.includes("bmp") ? "bmp" : "bin";
2928
2928
  img = { filename: `image_${String(imageIndex).padStart(3, "0")}.${ext}`, data: new Uint8Array(bin.data), mime };
2929
2929
  resolved.set(storageId, img);
2930
- images.push({ filename: img.filename, data: img.data, mimeType: img.mime });
2930
+ images.push({ filename: img.filename, data: img.data, mimeType: img.mime, source: bin.name });
2931
2931
  renamed.set(storageId, img.filename);
2932
2932
  }
2933
2933
  }
@@ -2951,7 +2951,7 @@ function resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced) {
2951
2951
  const ext = mime.includes("jpeg") ? "jpg" : mime.includes("png") ? "png" : mime.includes("gif") ? "gif" : mime.includes("bmp") ? "bmp" : "bin";
2952
2952
  const filename = `image_${String(imageIndex).padStart(3, "0")}.${ext}`;
2953
2953
  const data = new Uint8Array(bin.data);
2954
- images.push({ filename, data, mimeType: mime });
2954
+ images.push({ filename, data, mimeType: mime, source: bin.name });
2955
2955
  blocks.push({ type: "image", text: filename, imageData: { data, mimeType: mime, filename: bin.name } });
2956
2956
  }
2957
2957
  }
@@ -3088,7 +3088,7 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUn
3088
3088
  const mimeType = imageExtToMime(ext);
3089
3089
  imageIndex++;
3090
3090
  const filename2 = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
3091
- img = { filename: filename2, data, mimeType };
3091
+ img = { filename: filename2, data, mimeType, source: path };
3092
3092
  images.push(img);
3093
3093
  usedPaths.add(path);
3094
3094
  break;
@@ -3127,7 +3127,7 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings, sweepUn
3127
3127
  }
3128
3128
  imageIndex++;
3129
3129
  const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
3130
- const img = { filename, data, mimeType };
3130
+ const img = { filename, data, mimeType, source: file.name };
3131
3131
  images.push(img);
3132
3132
  blocks.push({ type: "image", text: filename, imageData: { data, mimeType, filename: file.name } });
3133
3133
  } catch (err) {
@@ -17383,9 +17383,15 @@ var ARAEA_JAMO = 4510;
17383
17383
  function decodeAraeaSyllable(ch) {
17384
17384
  if (ch < 32768) return null;
17385
17385
  if ((ch >> 5 & 31) !== JUNG_ARAEA) return null;
17386
- const cho = CHO_MAP[ch >> 10 & 31];
17386
+ const choIdx = ch >> 10 & 31;
17387
+ const cho = CHO_MAP[choIdx];
17387
17388
  const jong = JONG_MAP[ch & 31];
17388
- if (cho === -1 || jong === -1) return null;
17389
+ if (jong === -1) return null;
17390
+ if (cho === -1) {
17391
+ if (choIdx !== 1) return null;
17392
+ const bare = String.fromCodePoint(ARAEA_JAMO);
17393
+ return jong === 0 ? bare : bare + String.fromCodePoint(4519 + jong);
17394
+ }
17389
17395
  const out = String.fromCodePoint(4352 + cho) + String.fromCodePoint(ARAEA_JAMO);
17390
17396
  return jong === 0 ? out : out + String.fromCodePoint(4519 + jong);
17391
17397
  }
@@ -17413,7 +17419,44 @@ function decodeJohab(ch) {
17413
17419
  }
17414
17420
  return decodeHwp3Extra(ch);
17415
17421
  }
17422
+ var eucKrDecoder;
17423
+ function kscChar(row, cell2) {
17424
+ if (eucKrDecoder === void 0) {
17425
+ try {
17426
+ eucKrDecoder = new TextDecoder("euc-kr", { fatal: false });
17427
+ } catch {
17428
+ eucKrDecoder = null;
17429
+ }
17430
+ }
17431
+ if (!eucKrDecoder) return null;
17432
+ if (row < 161 || row > 254 || cell2 < 161 || cell2 > 254) return null;
17433
+ const text = eucKrDecoder.decode(Uint8Array.of(row, cell2));
17434
+ if (text.length !== 1) return null;
17435
+ const cp = text.codePointAt(0);
17436
+ if (cp === 65533) return null;
17437
+ return hancomVariant(cp);
17438
+ }
17439
+ function hancomVariant(cp) {
17440
+ if (cp === 8764) return 65374;
17441
+ if (cp === 8857) return 9673;
17442
+ return cp;
17443
+ }
17444
+ function decodeHwp3KscSymbol(ch) {
17445
+ if (ch < 13313) return null;
17446
+ const idx = ch - 13313;
17447
+ const row = 161 + Math.floor(idx / 96);
17448
+ if (row > 172) return null;
17449
+ return kscChar(row, 161 + idx % 96);
17450
+ }
17451
+ function decodeHwp3KscHanja(ch) {
17452
+ if (ch < 16384) return null;
17453
+ const idx = ch - 16384;
17454
+ const row = 202 + Math.floor(idx / 94);
17455
+ if (row > 253) return null;
17456
+ return kscChar(row, 161 + idx % 94);
17457
+ }
17416
17458
  function decodeHwp3Extra(ch) {
17459
+ if (ch >= 160 && ch <= 255) return ch;
17417
17460
  if (ch >= 13712 && ch <= 13721) return 8544 + (ch - 13712);
17418
17461
  if (ch >= 14055 && ch <= 14064) return 9312 + (ch - 14055);
17419
17462
  if (ch >= 14272 && ch <= 14277) return "\uD55C\uAE00\uACFC\uCEF4\uD4E8\uD130".codePointAt(ch - 14272);
@@ -17427,6 +17470,28 @@ function decodeHwp3Extra(ch) {
17427
17470
  case 12316:
17428
17471
  return 9473;
17429
17472
  // ━ 굵은 가로선 (rhwp: U+F080F, 표시값 직행)
17473
+ // 텍스트 다이어그램 괘선 조각 — 한컴은 U+F0806~F0810 으로 보존하고 rhwp 검증표가
17474
+ // ┌┬┐└┘│ 로 편다. HWP3 코드는 그 PUA 에서 상수 오프셋(0xC07F3)만큼 떨어져 있고
17475
+ // (0x301C→F080F 가 이미 그 관계), hwp3-sample11 ↔ 변환본 개수도 그대로 맞는다
17476
+ // (0x3013×3↔┌, 0x3014×1↔┬, 0x3015×10↔┐, 0x3019×6↔└, 0x301B×9↔┘, 0x301D×17↔│).
17477
+ case 12307:
17478
+ return 9484;
17479
+ // ┌
17480
+ case 12308:
17481
+ return 9516;
17482
+ // ┬
17483
+ case 12309:
17484
+ return 9488;
17485
+ // ┐
17486
+ case 12313:
17487
+ return 9492;
17488
+ // └
17489
+ case 12315:
17490
+ return 9496;
17491
+ // ┘
17492
+ case 12317:
17493
+ return 9474;
17494
+ // │
17430
17495
  case 12349:
17431
17496
  return 9632;
17432
17497
  // ■ (rhwp: U+F0827, 표시값 직행)
@@ -17454,8 +17519,119 @@ function decodeHwp3Extra(ch) {
17454
17519
  case 12135:
17455
17520
  return 9656;
17456
17521
  // ▸ 표 셀 글머리표 (rhwp 16db8260 — HWP5 변환본·한컴 PDF 대조)
17522
+ // 아래 항등 코드들은 rhwp #5860 실측표(한글 2022 오라클 위치 정렬) 이식.
17523
+ // 같은 0x20xx 대에 항등과 비항등이 섞여 있어 구간 통과는 하지 않는다.
17524
+ case 8208:
17525
+ return 8208;
17526
+ // ‐
17527
+ case 8211:
17528
+ return 8211;
17529
+ // –
17530
+ case 8451:
17531
+ return 8451;
17532
+ // ℃
17533
+ case 8467:
17534
+ return 8467;
17535
+ // ℓ
17536
+ case 8592:
17537
+ return 8592;
17538
+ // ←
17539
+ case 8594:
17540
+ return 8594;
17541
+ // →
17542
+ case 8595:
17543
+ return 8595;
17544
+ // ↓
17545
+ case 8729:
17546
+ return 8729;
17547
+ // ∙ (sample11 실측 11건)
17548
+ case 8901:
17549
+ return 8901;
17550
+ // ⋅
17551
+ case 8251:
17552
+ return 8251;
17553
+ // ※ — 한자를 완성형 좌표로 담으면서 ※ 만 유니코드 값으로 담은 문서가 있다
17554
+ // 비항등 — 유니코드로 읽으면 ⁚·․·⁘ 같은 다른 글자가 된다 (rhwp #5860)
17555
+ case 8228:
17556
+ return 12539;
17557
+ // ・
17558
+ case 8280:
17559
+ return 9651;
17560
+ // △
17561
+ case 8282:
17562
+ return 9675;
17563
+ // ○
17564
+ case 12040:
17565
+ return 9642;
17566
+ // ▪
17567
+ case 12049:
17568
+ return 9702;
17569
+ // ◦ (sample16 실측 332건)
17570
+ case 12052:
17571
+ return 9702;
17572
+ // ◦
17573
+ case 12631:
17574
+ return 8231;
17575
+ // ‧
17576
+ case 1152:
17577
+ return 720;
17578
+ // ː
17579
+ case 7982:
17580
+ return 12398;
17581
+ // の
17582
+ case 12976:
17583
+ return 65392;
17584
+ // ー (반각)
17585
+ case 12391:
17586
+ return 8216;
17587
+ // ‘
17588
+ case 12392:
17589
+ return 8217;
17590
+ // ’
17591
+ case 12443:
17592
+ return 65378;
17593
+ // 「
17594
+ case 12445:
17595
+ return 65379;
17596
+ // 」
17597
+ case 131:
17598
+ return 8216;
17599
+ // ‘ — 큰따옴표(0x0081/0x0082) 바로 다음 코드 (sample11/14 실측 18건)
17600
+ case 132:
17601
+ return 8217;
17602
+ // ’
17603
+ // 아래 셋은 rhwp 표에 없는 값 — kordoc 이 rhwp 샘플 ↔ 한컴 변환본 문맥 정렬로 실측했다.
17604
+ case 8226:
17605
+ return 8226;
17606
+ // • hwp3-sample 글머리표 4건 (항등)
17607
+ case 12055:
17608
+ return 8226;
17609
+ // • hwp3-sample10 글머리표 3건
17610
+ case 12038:
17611
+ return 9632;
17612
+ // ■ hwp3-sample10 "제목차례" 좌우 장식 2건
17613
+ // 관인·서명란 도장 기호. rhwp 는 U+F012B 로 보존하고 렌더러가 `(인)` 으로 편다 —
17614
+ // kordoc 도 PUA 를 그대로 내보내면 shared/pua.ts 의 검증표가 같은 문자열로 편다.
17615
+ case 11214:
17616
+ return 983339;
17617
+ // ═ 겹줄. rhwp 는 0x3048 을 U+F0832(렌더 표시값 `═`)로 보존한다. 0x37ED 는 기호
17618
+ // 규칙으로는 가타카나 `ネ` 가 되는 사적 graphic 코드로, sample10(42건)·sample11(12건)
17619
+ // 두 문서에서 한컴 변환본의 `═` 개수와 정확히 일치해 표시값 직행으로 싣는다.
17620
+ case 12360:
17621
+ return 9552;
17622
+ case 14317:
17623
+ return 9552;
17624
+ // 사적 원문자·괄호문자 계열. 사적 코드는 일반식이 없어 실측 문서에서 연속으로
17625
+ // 확인된 구간만 싣는다 (sample11 ↔ hwp3-sample11-hwpx 문맥 정렬).
17626
+ // 0x2E01~0x2E07 → ①~⑦ 7코드 연속 일치, 0x2C21~0x2C26 → ⓐ~ⓕ (ⓒ~ⓕ 개수 일치),
17627
+ // 0x2C40~0x2C42 → ㉠~㉢
17457
17628
  default:
17458
- return JOHAB_UNMAPPED;
17629
+ if (ch >= 11777 && ch <= 11783) return 9312 + (ch - 11777);
17630
+ if (ch === 11776) return 9450;
17631
+ if (ch >= 11786 && ch <= 11794) return 9312 + (ch - 11786);
17632
+ if (ch >= 11297 && ch <= 11302) return 9424 + (ch - 11297);
17633
+ if (ch >= 11328 && ch <= 11330) return 12896 + (ch - 11328);
17634
+ return decodeHwp3KscSymbol(ch) ?? decodeHwp3KscHanja(ch) ?? JOHAB_UNMAPPED;
17459
17635
  }
17460
17636
  }
17461
17637
  function decodeHcharString(bytes) {
@@ -19790,10 +19966,14 @@ async function buildImageMap(zip, rels, doc, warnings) {
19790
19966
  gif: "image/gif",
19791
19967
  bmp: "image/bmp",
19792
19968
  wmf: "image/wmf",
19793
- emf: "image/emf"
19969
+ emf: "image/emf",
19970
+ tif: "image/tiff",
19971
+ tiff: "image/tiff",
19972
+ svg: "image/svg+xml"
19794
19973
  };
19795
19974
  const filename = `image_${String(imgIdx).padStart(3, "0")}.${ext}`;
19796
- images.push({ filename, data, mimeType: mimeMap[ext] ?? "image/png" });
19975
+ const mimeType = mimeMap[ext] ?? detectImageMime(data) ?? "application/octet-stream";
19976
+ images.push({ filename, data, mimeType, source: imgPath });
19797
19977
  imageMap.set(embedId, filename);
19798
19978
  } catch (err) {
19799
19979
  warnings.push({
@@ -29530,7 +29710,7 @@ async function patchHwp(original, editedMarkdown, options) {
29530
29710
  for (let i = 0; i < scans.length; i++) {
29531
29711
  if (scans[i].repl.size === 0 && scans[i].inserts.size === 0) continue;
29532
29712
  const newStream = serializeRecords(scans[i].records, scans[i].repl, scans[i].inserts);
29533
- const content = compressed ? deflateRawSync2(newStream) : newStream;
29713
+ const content = compressed ? compressWithTail(newStream) : newStream;
29534
29714
  out = replaceOleStream(out, sectionPaths[i], content);
29535
29715
  }
29536
29716
  data = new Uint8Array(out);
@@ -30013,6 +30193,26 @@ function rebuildCharShape(csData, coreStartUnit) {
30013
30193
  });
30014
30194
  return { buf, count: kept.length };
30015
30195
  }
30196
+ var CRC_TABLE2 = (() => {
30197
+ const t = new Uint32Array(256);
30198
+ for (let n = 0; n < 256; n++) {
30199
+ let c = n;
30200
+ for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
30201
+ t[n] = c >>> 0;
30202
+ }
30203
+ return t;
30204
+ })();
30205
+ function crc322(buf) {
30206
+ let c = 4294967295;
30207
+ for (let i = 0; i < buf.length; i++) c = CRC_TABLE2[(c ^ buf[i]) & 255] ^ c >>> 8;
30208
+ return (c ^ 4294967295) >>> 0;
30209
+ }
30210
+ function compressWithTail(raw) {
30211
+ const tail = Buffer.alloc(8);
30212
+ tail.writeUInt32LE(crc322(raw), 0);
30213
+ tail.writeUInt32LE(raw.length >>> 0, 4);
30214
+ return Buffer.concat([deflateRawSync2(raw), tail]);
30215
+ }
30016
30216
  function synthesizeLineSegs(lineSegData, newRaw, startUnits) {
30017
30217
  if (lineSegData.length < 36) return null;
30018
30218
  const seg0 = lineSegData.subarray(0, 36);
@@ -30090,6 +30290,15 @@ function stageParaPatch(scan, para2, newPlain, skip) {
30090
30290
  scan.repl.set(para2.lineSegIdx, synth.buf);
30091
30291
  newHeader.writeUInt16LE(synth.count, 16);
30092
30292
  }
30293
+ } else {
30294
+ const lineSegData = records[para2.lineSegIdx].data;
30295
+ const segCount = Math.floor(lineSegData.length / 36);
30296
+ let keep = 1;
30297
+ while (keep < segCount && lineSegData.readUInt32LE(keep * 36) < nChars) keep++;
30298
+ if (keep < segCount) {
30299
+ scan.repl.set(para2.lineSegIdx, Buffer.from(lineSegData.subarray(0, keep * 36)));
30300
+ newHeader.writeUInt16LE(keep, 16);
30301
+ }
30093
30302
  }
30094
30303
  scan.repl.set(para2.headerIdx, newHeader);
30095
30304
  return 1;
@@ -31959,7 +32168,7 @@ async function dispatch(format, buffer, opts) {
31959
32168
  }
31960
32169
  async function parseImage(buffer, options) {
31961
32170
  try {
31962
- const { parseImageDocument } = await import("./image-ocr-YZ56O63S.js");
32171
+ const { parseImageDocument } = await import("./image-ocr-JCKC4QWU.js");
31963
32172
  const { blocks, warnings } = await parseImageDocument(buffer, options);
31964
32173
  return {
31965
32174
  success: true,
@@ -32018,7 +32227,7 @@ async function parseHwp(buffer, options) {
32018
32227
  async function parsePdf(buffer, options) {
32019
32228
  let parsePdfDocument;
32020
32229
  try {
32021
- const mod = await import("./parser-6UL2HLDH.js");
32230
+ const mod = await import("./parser-2KFORGOT.js");
32022
32231
  parsePdfDocument = mod.parsePdfDocument;
32023
32232
  } catch {
32024
32233
  return {