kordoc 4.4.0 → 4.4.1

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 (82) hide show
  1. package/README.md +9 -3
  2. package/dist/{-R6NUMPRV.js → -7X4H77Z7.js} +8 -8
  3. package/dist/{chunk-YOZ7ZRCD.js → chunk-2352RXHG.js} +8 -8
  4. package/dist/{chunk-SKM6KZUH.cjs → chunk-3DX6VJGH.cjs} +9 -9
  5. package/dist/{chunk-SKM6KZUH.cjs.map → chunk-3DX6VJGH.cjs.map} +1 -1
  6. package/dist/{chunk-GHGZU2LQ.js → chunk-5A2TGIN7.js} +2 -2
  7. package/dist/{chunk-65DYCXGC.js → chunk-5PXCA3DN.js} +3 -3
  8. package/dist/{chunk-H2KMJOB6.cjs → chunk-7BIVNIK5.cjs} +2 -2
  9. package/dist/{chunk-H2KMJOB6.cjs.map → chunk-7BIVNIK5.cjs.map} +1 -1
  10. package/dist/{chunk-HNRULYUH.js → chunk-7MDLAKVO.js} +2 -2
  11. package/dist/{chunk-YVYU267E.js → chunk-AYM6UHFX.js} +2 -2
  12. package/dist/chunk-AYM6UHFX.js.map +1 -0
  13. package/dist/{chunk-AB322K3O.cjs → chunk-FR65WNLF.cjs} +3 -3
  14. package/dist/{chunk-AB322K3O.cjs.map → chunk-FR65WNLF.cjs.map} +1 -1
  15. package/dist/{chunk-UDGPM5R5.cjs → chunk-GC7WBHAN.cjs} +4 -4
  16. package/dist/{chunk-UDGPM5R5.cjs.map → chunk-GC7WBHAN.cjs.map} +1 -1
  17. package/dist/{chunk-W6CUD7V3.js → chunk-HGSO2H44.js} +2 -2
  18. package/dist/{chunk-RZURSA4N.js → chunk-IPOVUGXD.js} +3 -3
  19. package/dist/{chunk-5KLE3U23.js → chunk-JGHQFUKI.js} +2 -2
  20. package/dist/{chunk-V35DRUJC.js → chunk-NUGTEPKT.js} +2 -2
  21. package/dist/{chunk-QXYB74QF.js → chunk-SMPEZINI.js} +2 -2
  22. package/dist/{chunk-ONS7JKVA.js → chunk-T25FBUMN.js} +2 -2
  23. package/dist/{chunk-HFJF477F.js → chunk-TGAWXMXB.js} +2 -2
  24. package/dist/chunk-TGAWXMXB.js.map +1 -0
  25. package/dist/{chunk-XCIC7U6Y.js → chunk-UA53AA7R.js} +2 -2
  26. package/dist/{chunk-P7YPCK7C.js → chunk-WA7XLWZW.js} +2 -2
  27. package/dist/chunks-FMZK4QHL.js +10 -0
  28. package/dist/cli.js +16 -16
  29. package/dist/{image-ocr-U2DRRFL3.js → image-ocr-AHHY42OI.js} +4 -4
  30. package/dist/{image-ocr-XC52AQDV.js → image-ocr-K4XCRBTY.js} +4 -4
  31. package/dist/{image-ocr-F2BQA26V.cjs → image-ocr-VCXLT5Q6.cjs} +10 -10
  32. package/dist/{image-ocr-F2BQA26V.cjs.map → image-ocr-VCXLT5Q6.cjs.map} +1 -1
  33. package/dist/index.cjs +178 -178
  34. package/dist/index.js +4 -4
  35. package/dist/mcp.js +26 -24
  36. package/dist/mcp.js.map +1 -1
  37. package/dist/{parser-FFQN67O6.cjs → parser-ABYM2MVN.cjs} +24 -24
  38. package/dist/{parser-FFQN67O6.cjs.map → parser-ABYM2MVN.cjs.map} +1 -1
  39. package/dist/{parser-ESGFWWCT.js → parser-I3ELUUOG.js} +5 -5
  40. package/dist/{parser-TFPGQWCC.js → parser-IPVY56U3.js} +5 -5
  41. package/dist/pdf-ocr-EL3VSWWY.js +12 -0
  42. package/dist/{pdf-ocr-WE5TMRFU.js → pdf-ocr-FVLKQNAT.js} +4 -4
  43. package/dist/pdf-ocr-VQ3QWXGE.cjs +13 -0
  44. package/dist/{pdf-ocr-UQBZH3HE.cjs.map → pdf-ocr-VQ3QWXGE.cjs.map} +1 -1
  45. package/dist/{profile-io-O6BDCUJN.js → profile-io-YADU6SKH.js} +3 -3
  46. package/dist/{rasterize-V22VCCE7.js → rasterize-YV5VDSQX.js} +2 -2
  47. package/dist/render-K6M3P24X.js +10 -0
  48. package/dist/seal-YW3U5BCY.js +10 -0
  49. package/dist/{watch-HGKBICED.js → watch-5K2ZERXI.js} +8 -8
  50. package/package.json +1 -1
  51. package/dist/chunk-HFJF477F.js.map +0 -1
  52. package/dist/chunk-YVYU267E.js.map +0 -1
  53. package/dist/chunks-QMGCI5DG.js +0 -10
  54. package/dist/pdf-ocr-4R646OO6.js +0 -12
  55. package/dist/pdf-ocr-UQBZH3HE.cjs +0 -13
  56. package/dist/render-3BSVTTZE.js +0 -10
  57. package/dist/seal-6ZSEJVOD.js +0 -10
  58. /package/dist/{-R6NUMPRV.js.map → -7X4H77Z7.js.map} +0 -0
  59. /package/dist/{chunk-YOZ7ZRCD.js.map → chunk-2352RXHG.js.map} +0 -0
  60. /package/dist/{chunk-GHGZU2LQ.js.map → chunk-5A2TGIN7.js.map} +0 -0
  61. /package/dist/{chunk-65DYCXGC.js.map → chunk-5PXCA3DN.js.map} +0 -0
  62. /package/dist/{chunk-HNRULYUH.js.map → chunk-7MDLAKVO.js.map} +0 -0
  63. /package/dist/{chunk-W6CUD7V3.js.map → chunk-HGSO2H44.js.map} +0 -0
  64. /package/dist/{chunk-RZURSA4N.js.map → chunk-IPOVUGXD.js.map} +0 -0
  65. /package/dist/{chunk-5KLE3U23.js.map → chunk-JGHQFUKI.js.map} +0 -0
  66. /package/dist/{chunk-V35DRUJC.js.map → chunk-NUGTEPKT.js.map} +0 -0
  67. /package/dist/{chunk-QXYB74QF.js.map → chunk-SMPEZINI.js.map} +0 -0
  68. /package/dist/{chunk-ONS7JKVA.js.map → chunk-T25FBUMN.js.map} +0 -0
  69. /package/dist/{chunk-XCIC7U6Y.js.map → chunk-UA53AA7R.js.map} +0 -0
  70. /package/dist/{chunk-P7YPCK7C.js.map → chunk-WA7XLWZW.js.map} +0 -0
  71. /package/dist/{chunks-QMGCI5DG.js.map → chunks-FMZK4QHL.js.map} +0 -0
  72. /package/dist/{image-ocr-U2DRRFL3.js.map → image-ocr-AHHY42OI.js.map} +0 -0
  73. /package/dist/{image-ocr-XC52AQDV.js.map → image-ocr-K4XCRBTY.js.map} +0 -0
  74. /package/dist/{parser-ESGFWWCT.js.map → parser-I3ELUUOG.js.map} +0 -0
  75. /package/dist/{parser-TFPGQWCC.js.map → parser-IPVY56U3.js.map} +0 -0
  76. /package/dist/{pdf-ocr-4R646OO6.js.map → pdf-ocr-EL3VSWWY.js.map} +0 -0
  77. /package/dist/{pdf-ocr-WE5TMRFU.js.map → pdf-ocr-FVLKQNAT.js.map} +0 -0
  78. /package/dist/{profile-io-O6BDCUJN.js.map → profile-io-YADU6SKH.js.map} +0 -0
  79. /package/dist/{rasterize-V22VCCE7.js.map → rasterize-YV5VDSQX.js.map} +0 -0
  80. /package/dist/{render-3BSVTTZE.js.map → render-K6M3P24X.js.map} +0 -0
  81. /package/dist/{seal-6ZSEJVOD.js.map → seal-YW3U5BCY.js.map} +0 -0
  82. /package/dist/{watch-HGKBICED.js.map → watch-5K2ZERXI.js.map} +0 -0
package/README.md CHANGED
@@ -73,7 +73,7 @@ MCP 등록 대신 스킬(SKILL.md) 형태로 쓰려면:
73
73
  단순한 텍스트 추출을 넘어, **공문서 처리를 위한 모든 과정**을 자동화합니다.
74
74
 
75
75
  * **📄 어떤 문서든 마크다운으로**: `HWP3` (구버전), `HWP`(5.x), `HWPX`, `HWPML`, `PDF`, `XLS`, `XLSX`, `DOCX` 파일은 물론 `PNG`/`JPG`/`WebP` 이미지(자동 OCR)까지 즉시 `Markdown`으로 변환합니다. AI(LLM)가 문서를 읽고 분석하기 가장 좋은 상태로 만들어줍니다.
76
- * **📊 복잡한 표(Table) 완벽 재현**: 선이 없는 PDF나 복잡하게 병합된 HWP 표도 구조를 분석하여 정확한 마크다운 테이블로 복원합니다. 법령 개정안 PDF의 신구조문대비표도 통째로 살립니다 (v3.16.2).
76
+ * **📊 복잡한 표(Table) 복원 숫자로 잠금**: 병합·중첩 표를 구조 그대로 살립니다. HWPX 코퍼스 291문서 **표 1,673/1,673·셀 27,714/27,714 무손실**(독립 추출기 대조 게이트 1.0), 동일문서 hwpx↔pdf 대조(6쌍 69표)는 **매칭 98.6%·완전일치 65.2%**. 선 없는 PDF 표도 감지해 복원하고, 법령 개정안 PDF의 신구조문대비표도 통째로 살립니다 (v3.16.2).
77
77
  * **🔍 신구대조표 자동 생성**: 두 문서의 차이점을 분석하여 무엇이 바뀌었는지 한눈에 보여줍니다. (HWP와 HWPX 간의 비교도 가능!)
78
78
  * **📝 마크다운을 다시 HWPX로**: AI가 작성한 내용을 다시 보고서 양식(`HWPX`)으로 되돌려줍니다. 이제 복사-붙여넣기 노가다에서 해방되세요.
79
79
  * **🏛️ 정부 표준 공문서 생성 (v4.0)**: 실제 정부 양식 16종 + 실결재 기안문 60건을 전수 디코드·대조해 만든 공문서 엔진. 개조식 보고서(표지·목차 배너·로마숫자 장헤더·쪽번호·결재란), 기안문(별지 제1호서식 두문·결문, "끝." 자동), 공고문·보도자료 프리셋, 항목부호 8단계(1. 가. 1) 가)…) 자동, 공문서 표기법 검수 13룰(`kordoc lint`)까지 — 한글 COM 실렌더로 조판까지 실측 검증했습니다.
@@ -86,13 +86,19 @@ MCP 등록 대신 스킬(SKILL.md) 형태로 쓰려면:
86
86
 
87
87
  ---
88
88
 
89
+ ## v4.4.1 변경사항
90
+
91
+ - **🖼️ MCP 이미지 입력 수리**: `parse_document` 등 파싱 도구가 PNG/JPG/WebP를 확장자 단계에서 거부하던 것(CLI는 정상, MCP만 차단)을 해제 — 스크린샷·스캔 이미지를 MCP로도 바로 변환합니다.
92
+ - **📏 내장 OCR 정확도 첫 실측** (`bench/ocr-accuracy.mjs` 신설): 코퍼스 PDF 41문서 82페이지, 클린 텍스트층 대조 — 문자 recall 90.0%(글꼴 미렌더 1건 제외 94.0%)·precision 95.1%, 한글 음절 recall median 99.9%, 0.96s/페이지. 스캔 표 구조는 매칭 63%·cellF1 0.50로 아직 약한 지점입니다. 정답이 클린 렌더라 실스캔 노이즈는 미반영(상한치).
93
+
89
94
  ## v4.4.0 변경사항
90
95
 
91
96
  - **🔑 비밀번호 문서 열기 (#59)**: 열기 암호가 걸린 **HWPX·HWP3·HWP5** 문서를 `--password`(CLI) / `password`(API·MCP)로 엽니다. 세 포맷의 암호화 방식이 각각 다릅니다 — HWPX는 ODF 표준(AES-256-CBC + PBKDF2), HWP3는 단일 DES-ECB, HWP5는 EncryptVersion 4의 비트 단위 CFB. 틀린 비밀번호는 성공으로 위장하지 않고 `ENCRYPTED`로 실패합니다. (한컴 DRM 문서보안은 별개라 해당 없음, @jangster77 제보)
92
97
  - **🩹 HWP3 본문 대량 유실 수리**: 그림 뒤에 오는 캡션 문단 리스트를 읽지 않아 그림 하나당 43바이트씩 스트림이 어긋났고, 어긋난 자리가 "문단 끝" 표식으로 읽히면 **경고 없이** 나머지를 통째로 버렸습니다. 945KB 문서가 0자로 나오던 수준입니다(rhwp 대조 실측 6종 복구, 최대 100만 자). 표 셀 상한 256도 실존 문서(367셀)를 죽여 잔여 스트림 기준으로 교체했습니다.
93
98
  - **🔤 CDATA 텍스트 소실 수리**: `<hp:t><![CDATA[본문]]></hp:t>` 로 저장된 텍스트를 경고 없이 버리던 결함 — 공용 XML 헬퍼에 있어 HWPX·HWPML·DOCX 세 포맷에 걸쳐 있었습니다.
94
99
  - **🔣 사라지던 글자 복원**: 한컴 검증 PUA 11종(결재란 `(인)`, 편람 글머리표, 사각 안 숫자 ①~⑳ 등)과 HWP3 johab 매핑 2종(표 셀 글머리표 ▸, 머리말 회사명) — 매핑에 없는 코드는 삭제되는 구조라 누락이 곧 글자 증발이었습니다.
95
- - **🐛 외**: 동명 누름틀이 여러 곳에 있는 서식에서 `require_unique`가 곳도 채우지 않던 것, 수식 토큰이 `constructor`·`toString`이면 출력이 오염되던 프로토타입 체인 결함.
100
+ - **ᄒᆞᆫ HWP3 아래아(옛한글) 복원**: 완성형에 대응 음절이 없어 통째로 빠지던 아래아 음절('ᄒᆞᆫ글 97' 등)을 한컴 HWP5/HWPX 변환본과 같은 자모열(초성+ᆞ+종성)로 보존합니다.
101
+ - **🐛 그 외**: 동명 누름틀이 여러 곳에 있는 서식에서 `require_unique`가 한 곳도 채우지 않던 것, 수식 토큰이 `constructor`·`toString`이면 출력이 오염되던 프로토타입 체인 결함, 빈 셀 채우기가 엔티티(`&#32;`) 원문을 지우던 것(fail-closed 통일), fill 계열 ZIP 폭탄 가드, CLI `--format json`의 실패 JSON 출력(원인 코드 포함). npm 배포본에 NOTICE·THIRD_PARTY 라이선스 고지도 포함됩니다.
96
102
 
97
103
  ## v4.3.0 변경사항
98
104
 
@@ -377,7 +383,7 @@ MCP 등록 대신 스킬(SKILL.md) 형태로 쓰려면:
377
383
 
378
384
  ## v2.9.0 변경사항
379
385
 
380
- - **📊 PDF 텍스트 품질 신호 + OCR 필요 판정** — PDF는 텍스트층이 있어도 ToUnicode/CMap 이 깨져 한글이 깨진 글리프로 떨어지거나 NUL 등 제어문자가 섞이는 경우가 많습니다. `parsePdf` 결과에 페이지별 품질 신호(`pageQuality`)와 문서 요약(`qualitySummary`)을 추가 — `needsOcr`/`ocrReason` 으로 OCR 큐 자동 라우팅이 가능. kordoc OCR 기본 탑재하지 않고 **신호만** 노출합니다. 전국 지자체 주요업무계획 PDF 190건(45,399쪽) 대량 처리 중 도출. (아래 [PDF 텍스트 품질 신호](#pdf-텍스트-품질-신호-v290) 참고)
386
+ - **📊 PDF 텍스트 품질 신호 + OCR 필요 판정** — PDF는 텍스트층이 있어도 ToUnicode/CMap 이 깨져 한글이 깨진 글리프로 떨어지거나 NUL 등 제어문자가 섞이는 경우가 많습니다. `parsePdf` 결과에 페이지별 품질 신호(`pageQuality`)와 문서 요약(`qualitySummary`)을 추가 — `needsOcr`/`ocrReason` 으로 OCR 큐 자동 라우팅이 가능. (당시에는 신호만 노출 — **v4.2.0부터 내장 OCR 탑재**, 신호가 내장 OCR의 자동 발동 조건으로 쓰입니다.) 전국 지자체 주요업무계획 PDF 190건(45,399쪽) 대량 처리 중 도출. (아래 [PDF 텍스트 품질 신호](#pdf-텍스트-품질-신호-v290) 참고)
381
387
 
382
388
  ## v2.8.0 변경사항
383
389
 
@@ -52,7 +52,7 @@ import {
52
52
  resolveBuiltinTemplate,
53
53
  unknownFontWarnings,
54
54
  validateHwpx
55
- } from "./chunk-YOZ7ZRCD.js";
55
+ } from "./chunk-2352RXHG.js";
56
56
  import "./chunk-7FCNOKOR.js";
57
57
  import "./chunk-A73RMJ6B.js";
58
58
  import "./chunk-MOL7MDBG.js";
@@ -62,7 +62,7 @@ import {
62
62
  buildRangeSplices,
63
63
  placeSealHwpx,
64
64
  scanSectionXml
65
- } from "./chunk-RZURSA4N.js";
65
+ } from "./chunk-IPOVUGXD.js";
66
66
  import {
67
67
  DEFAULT_REDACT_RULES,
68
68
  redactMarkdown,
@@ -70,10 +70,10 @@ import {
70
70
  } from "./chunk-DZIXKL7E.js";
71
71
  import {
72
72
  blocksToChunks
73
- } from "./chunk-HNRULYUH.js";
73
+ } from "./chunk-7MDLAKVO.js";
74
74
  import {
75
75
  blocksToMarkdown
76
- } from "./chunk-QXYB74QF.js";
76
+ } from "./chunk-SMPEZINI.js";
77
77
  import {
78
78
  SPACE_EM_FIXED,
79
79
  SPACE_EM_FONT,
@@ -83,11 +83,11 @@ import {
83
83
  renderHwpxToSvg,
84
84
  simulateWrap,
85
85
  simulateWrapKeepWord
86
- } from "./chunk-65DYCXGC.js";
87
- import "./chunk-5KLE3U23.js";
86
+ } from "./chunk-5PXCA3DN.js";
87
+ import "./chunk-JGHQFUKI.js";
88
88
  import {
89
89
  VERSION
90
- } from "./chunk-P7YPCK7C.js";
90
+ } from "./chunk-WA7XLWZW.js";
91
91
  export {
92
92
  BUILTIN_TEMPLATES,
93
93
  DEFAULT_REDACT_RULES,
@@ -161,4 +161,4 @@ export {
161
161
  unknownFontWarnings,
162
162
  validateHwpx
163
163
  };
164
- //# sourceMappingURL=-R6NUMPRV.js.map
164
+ //# sourceMappingURL=-7X4H77Z7.js.map
@@ -22,7 +22,7 @@ import {
22
22
  paraTextPureT,
23
23
  patchZipEntries,
24
24
  scanSectionXml
25
- } from "./chunk-RZURSA4N.js";
25
+ } from "./chunk-IPOVUGXD.js";
26
26
  import {
27
27
  MAX_COLS,
28
28
  MAX_ROWS,
@@ -32,14 +32,14 @@ import {
32
32
  dedupeRunningHeaders,
33
33
  flattenLayoutTables,
34
34
  mapPuaText
35
- } from "./chunk-QXYB74QF.js";
35
+ } from "./chunk-SMPEZINI.js";
36
36
  import {
37
37
  SPACE_EM_FIXED,
38
38
  charWidthEm1000,
39
39
  fitRatioForFewerLines,
40
40
  measureTextWidth,
41
41
  simulateWrap
42
- } from "./chunk-65DYCXGC.js";
42
+ } from "./chunk-5PXCA3DN.js";
43
43
  import {
44
44
  MAX_DECOMPRESS_SIZE,
45
45
  MAX_XML_DEPTH,
@@ -55,7 +55,7 @@ import {
55
55
  findChildByLocalName,
56
56
  localName,
57
57
  rawTextContent
58
- } from "./chunk-5KLE3U23.js";
58
+ } from "./chunk-JGHQFUKI.js";
59
59
  import {
60
60
  KordocError,
61
61
  classifyError,
@@ -67,7 +67,7 @@ import {
67
67
  sanitizeHref,
68
68
  stripDtd,
69
69
  toArrayBuffer
70
- } from "./chunk-P7YPCK7C.js";
70
+ } from "./chunk-WA7XLWZW.js";
71
71
 
72
72
  // src/index.ts
73
73
  import { readFile } from "fs/promises";
@@ -28327,7 +28327,7 @@ async function parse(input, options) {
28327
28327
  }
28328
28328
  async function parseImage(buffer, options) {
28329
28329
  try {
28330
- const { parseImageDocument } = await import("./image-ocr-XC52AQDV.js");
28330
+ const { parseImageDocument } = await import("./image-ocr-K4XCRBTY.js");
28331
28331
  const { blocks, warnings } = await parseImageDocument(buffer, options);
28332
28332
  return {
28333
28333
  success: true,
@@ -28386,7 +28386,7 @@ async function parseHwp(buffer, options) {
28386
28386
  async function parsePdf(buffer, options) {
28387
28387
  let parsePdfDocument;
28388
28388
  try {
28389
- const mod = await import("./parser-ESGFWWCT.js");
28389
+ const mod = await import("./parser-I3ELUUOG.js");
28390
28390
  parsePdfDocument = mod.parsePdfDocument;
28391
28391
  } catch {
28392
28392
  return {
@@ -28532,4 +28532,4 @@ export {
28532
28532
  parseHwpml,
28533
28533
  fillForm
28534
28534
  };
28535
- //# sourceMappingURL=chunk-YOZ7ZRCD.js.map
28535
+ //# sourceMappingURL=chunk-2352RXHG.js.map
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkH2KMJOB6cjs = require('./chunk-H2KMJOB6.cjs');
7
+ var _chunk7BIVNIK5cjs = require('./chunk-7BIVNIK5.cjs');
8
8
 
9
9
  // src/pdf/image-regions.ts
10
10
  var _pdfmjs = require('pdfjs-dist/legacy/build/pdf.mjs');
@@ -1567,9 +1567,9 @@ function detectHeadings(blocks, medianFontSize) {
1567
1567
  if (/^\d+$/.test(text)) continue;
1568
1568
  const ratio = block.style.fontSize / medianFontSize;
1569
1569
  let level = 0;
1570
- if (ratio >= _chunkH2KMJOB6cjs.HEADING_RATIO_H1) level = 1;
1571
- else if (ratio >= _chunkH2KMJOB6cjs.HEADING_RATIO_H2) level = 2;
1572
- else if (ratio >= _chunkH2KMJOB6cjs.HEADING_RATIO_H3) level = 3;
1570
+ if (ratio >= _chunk7BIVNIK5cjs.HEADING_RATIO_H1) level = 1;
1571
+ else if (ratio >= _chunk7BIVNIK5cjs.HEADING_RATIO_H2) level = 2;
1572
+ else if (ratio >= _chunk7BIVNIK5cjs.HEADING_RATIO_H3) level = 3;
1573
1573
  if (level > 0) {
1574
1574
  block.type = "heading";
1575
1575
  block.level = level;
@@ -2689,14 +2689,14 @@ function isProseSpread(items) {
2689
2689
  for (let i = 1; i < sorted.length; i++) {
2690
2690
  gaps.push(sorted[i].x - (sorted[i - 1].x + sorted[i - 1].w));
2691
2691
  }
2692
- const maxGap = _chunkH2KMJOB6cjs.safeMax.call(void 0, gaps);
2692
+ const maxGap = _chunk7BIVNIK5cjs.safeMax.call(void 0, gaps);
2693
2693
  const avgLen = items.reduce((s, i) => s + i.text.length, 0) / items.length;
2694
2694
  return maxGap < 40 && avgLen < 5;
2695
2695
  }
2696
2696
  function detectColumns(yLines) {
2697
2697
  const allItems = yLines.flat();
2698
2698
  if (allItems.length === 0) return null;
2699
- const pageWidth = _chunkH2KMJOB6cjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkH2KMJOB6cjs.safeMin.call(void 0, allItems.map((i) => i.x));
2699
+ const pageWidth = _chunk7BIVNIK5cjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunk7BIVNIK5cjs.safeMin.call(void 0, allItems.map((i) => i.x));
2700
2700
  if (pageWidth < 100) return null;
2701
2701
  let bigoLineIdx = -1;
2702
2702
  for (let i = 0; i < yLines.length; i++) {
@@ -3144,7 +3144,7 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
3144
3144
  let finalTextBlocks = [];
3145
3145
  if (remaining.length > 0) {
3146
3146
  const allY = remaining.map((i) => i.y);
3147
- const pageH = _chunkH2KMJOB6cjs.safeMax.call(void 0, allY) - _chunkH2KMJOB6cjs.safeMin.call(void 0, allY);
3147
+ const pageH = _chunk7BIVNIK5cjs.safeMax.call(void 0, allY) - _chunk7BIVNIK5cjs.safeMin.call(void 0, allY);
3148
3148
  const groups = xyCutOrder(remaining, Math.max(15, pageH * 0.03));
3149
3149
  const textBlocks = [];
3150
3150
  for (const group of groups) {
@@ -3332,7 +3332,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false) {
3332
3332
  blocks.push({ type: "paragraph", text: tableText, pageNumber: pageNum, bbox, style: dominantStyle(items) });
3333
3333
  } else {
3334
3334
  const allY = items.map((i) => i.y);
3335
- const pageHeight = _chunkH2KMJOB6cjs.safeMax.call(void 0, allY) - _chunkH2KMJOB6cjs.safeMin.call(void 0, allY);
3335
+ const pageHeight = _chunk7BIVNIK5cjs.safeMax.call(void 0, allY) - _chunk7BIVNIK5cjs.safeMin.call(void 0, allY);
3336
3336
  const gapThreshold = Math.max(15, pageHeight * 0.03);
3337
3337
  const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
3338
3338
  for (const group of orderedGroups) {
@@ -3371,4 +3371,4 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false) {
3371
3371
 
3372
3372
 
3373
3373
  exports.extractImageRegions = extractImageRegions; exports.filterHiddenText = filterHiddenText; exports.collapseEvenSpacing = collapseEvenSpacing; exports.normalizeItems = normalizeItems; exports.computeMedianFontSizeFromFreq = computeMedianFontSizeFromFreq; exports.detectHeadings = detectHeadings; exports.detectMarkerHeadings = detectMarkerHeadings; exports.detectTableCaptions = detectTableCaptions; exports.detectKoreanListBlocks = detectKoreanListBlocks; exports.removeHeaderFooterBlocks = removeHeaderFooterBlocks; exports.extractPageBlocksWithLines = extractPageBlocksWithLines; exports.mergeCrossPageTables = mergeCrossPageTables;
3374
- //# sourceMappingURL=chunk-SKM6KZUH.cjs.map
3374
+ //# sourceMappingURL=chunk-3DX6VJGH.cjs.map