kordoc 3.8.0 → 3.8.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 (30) hide show
  1. package/README.md +6 -1
  2. package/dist/{-ATVQYFSW.js → -LD4BZDDJ.js} +3 -3
  3. package/dist/{chunk-3R3YK7EM.js → chunk-IFYJFWD2.js} +2 -2
  4. package/dist/{chunk-SLKF72QF.js → chunk-KT2BCHXI.js} +690 -671
  5. package/dist/chunk-KT2BCHXI.js.map +1 -0
  6. package/dist/{chunk-ITJIALN5.cjs → chunk-LFCS3UVG.cjs} +2 -2
  7. package/dist/{chunk-ITJIALN5.cjs.map → chunk-LFCS3UVG.cjs.map} +1 -1
  8. package/dist/{chunk-QV25HMU7.js → chunk-PELBIL4K.js} +2 -2
  9. package/dist/cli.js +4 -4
  10. package/dist/index.cjs +1052 -1033
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +689 -670
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp.js +3 -3
  15. package/dist/{parser-7G5F7PT2.js → parser-FFEBMLSH.js} +1830 -1803
  16. package/dist/parser-FFEBMLSH.js.map +1 -0
  17. package/dist/{parser-GUSJH44K.cjs → parser-IXK5V7YG.cjs} +1830 -1803
  18. package/dist/parser-IXK5V7YG.cjs.map +1 -0
  19. package/dist/{parser-DCK42RMA.js → parser-XEDROIM7.js} +1830 -1803
  20. package/dist/parser-XEDROIM7.js.map +1 -0
  21. package/dist/{watch-GVZESOCE.js → watch-MAWCDNFI.js} +3 -3
  22. package/package.json +2 -2
  23. package/dist/chunk-SLKF72QF.js.map +0 -1
  24. package/dist/parser-7G5F7PT2.js.map +0 -1
  25. package/dist/parser-DCK42RMA.js.map +0 -1
  26. package/dist/parser-GUSJH44K.cjs.map +0 -1
  27. /package/dist/{-ATVQYFSW.js.map → -LD4BZDDJ.js.map} +0 -0
  28. /package/dist/{chunk-3R3YK7EM.js.map → chunk-IFYJFWD2.js.map} +0 -0
  29. /package/dist/{chunk-QV25HMU7.js.map → chunk-PELBIL4K.js.map} +0 -0
  30. /package/dist/{watch-GVZESOCE.js.map → watch-MAWCDNFI.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
 
21
21
 
22
- var _chunkITJIALN5cjs = require('./chunk-ITJIALN5.cjs');
22
+ var _chunkLFCS3UVGcjs = require('./chunk-LFCS3UVG.cjs');
23
23
 
24
24
 
25
25
  var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
@@ -283,8 +283,6 @@ async function detectZipFormat(buffer) {
283
283
 
284
284
  // src/hwpx/parser.ts
285
285
 
286
- var _zlib = require('zlib');
287
- var _xmldom = require('@xmldom/xmldom');
288
286
 
289
287
  // src/hwpx/com-fallback.ts
290
288
  var _child_process = require('child_process');
@@ -393,6 +391,245 @@ function comResultToParseResult(pages, pageCount, warnings) {
393
391
  };
394
392
  }
395
393
 
394
+ // src/hwpx/parser-shared.ts
395
+ var _xmldom = require('@xmldom/xmldom');
396
+ var MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024;
397
+ var MAX_ZIP_ENTRIES = 500;
398
+ function clampSpan(val, max) {
399
+ return Math.max(1, Math.min(val, max));
400
+ }
401
+ var MAX_XML_DEPTH = 200;
402
+ function createSectionShared() {
403
+ return { numState: /* @__PURE__ */ new Map(), pageText: { headers: [], footers: [] }, track: { deleteDepth: 0, warned: false } };
404
+ }
405
+ function createXmlParser(warnings) {
406
+ return new (0, _xmldom.DOMParser)({
407
+ onError(level, msg2) {
408
+ if (level === "fatalError") throw new (0, _chunkLFCS3UVGcjs.KordocError)(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
409
+ _optionalChain([warnings, 'optionalAccess', _3 => _3.push, 'call', _4 => _4({ code: "MALFORMED_XML", message: `XML ${level === "warn" ? "\uACBD\uACE0" : "\uC624\uB958"}: ${msg2}` })]);
410
+ }
411
+ });
412
+ }
413
+ function applyPageText(blocks, shared) {
414
+ const { headers, footers } = shared.pageText;
415
+ if (headers.length > 0) {
416
+ blocks.unshift(...headers.map((t) => ({ type: "paragraph", text: t, pageNumber: 1 })));
417
+ }
418
+ if (footers.length > 0) {
419
+ blocks.push(...footers.map((t) => ({ type: "paragraph", text: t })));
420
+ }
421
+ }
422
+ function findChildByLocalName(parent, name) {
423
+ const children = parent.childNodes;
424
+ if (!children) return null;
425
+ for (let i = 0; i < children.length; i++) {
426
+ const ch = children[i];
427
+ if (ch.nodeType !== 1) continue;
428
+ const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
429
+ if (tag === name) return ch;
430
+ }
431
+ return null;
432
+ }
433
+ function extractTextFromNode(node) {
434
+ let result = "";
435
+ const children = node.childNodes;
436
+ if (!children) return result;
437
+ for (let i = 0; i < children.length; i++) {
438
+ const child = children[i];
439
+ if (child.nodeType === 3) result += child.textContent || "";
440
+ else if (child.nodeType === 1) result += extractTextFromNode(child);
441
+ }
442
+ return result.trim();
443
+ }
444
+
445
+ // src/hwpx/styles.ts
446
+ async function extractHwpxStyles(zip, decompressed) {
447
+ const result = {
448
+ charProperties: /* @__PURE__ */ new Map(),
449
+ styles: /* @__PURE__ */ new Map(),
450
+ numberings: /* @__PURE__ */ new Map(),
451
+ bullets: /* @__PURE__ */ new Map(),
452
+ paraHeadings: /* @__PURE__ */ new Map()
453
+ };
454
+ const headerPaths = ["Contents/header.xml", "header.xml", "Contents/head.xml", "head.xml"];
455
+ for (const hp of headerPaths) {
456
+ const hpLower = hp.toLowerCase();
457
+ const file = zip.file(hp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === hpLower) || null;
458
+ if (!file) continue;
459
+ try {
460
+ const xml = await file.async("text");
461
+ if (decompressed) {
462
+ decompressed.total += xml.length * 2;
463
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
464
+ }
465
+ const parser = createXmlParser();
466
+ const doc = parser.parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, xml), "text/xml");
467
+ if (!doc.documentElement) continue;
468
+ parseCharProperties(doc, result.charProperties);
469
+ parseStyleElements(doc, result.styles);
470
+ const domDoc = doc;
471
+ parseNumberings(domDoc, result.numberings);
472
+ parseBullets(domDoc, result.bullets);
473
+ parseParaHeadings(domDoc, result.paraHeadings);
474
+ break;
475
+ } catch (e5) {
476
+ continue;
477
+ }
478
+ }
479
+ return result;
480
+ }
481
+ function parseCharProperties(doc, map) {
482
+ const tagNames = ["hh:charPr", "charPr", "hp:charPr"];
483
+ for (const tagName of tagNames) {
484
+ const elements = doc.getElementsByTagName(tagName);
485
+ for (let i = 0; i < elements.length; i++) {
486
+ const el = elements[i];
487
+ const id = el.getAttribute("id") || el.getAttribute("IDRef") || "";
488
+ if (!id) continue;
489
+ const prop = {};
490
+ const height = el.getAttribute("height");
491
+ if (height) {
492
+ const parsedHeight = parseInt(height, 10);
493
+ if (!isNaN(parsedHeight) && parsedHeight > 0) {
494
+ prop.fontSize = parsedHeight / 100;
495
+ }
496
+ }
497
+ const bold = el.getAttribute("bold");
498
+ if (bold === "true" || bold === "1") prop.bold = true;
499
+ const italic = el.getAttribute("italic");
500
+ if (italic === "true" || italic === "1") prop.italic = true;
501
+ const fontFaces = el.getElementsByTagName("*");
502
+ for (let j = 0; j < fontFaces.length; j++) {
503
+ const ff = fontFaces[j];
504
+ const localTag = (ff.tagName || "").replace(/^[^:]+:/, "");
505
+ if (localTag === "fontface" || localTag === "fontRef") {
506
+ const face = ff.getAttribute("face") || ff.getAttribute("FontFace");
507
+ if (face) {
508
+ prop.fontName = face;
509
+ break;
510
+ }
511
+ }
512
+ }
513
+ map.set(id, prop);
514
+ }
515
+ }
516
+ }
517
+ function parseStyleElements(doc, map) {
518
+ const tagNames = ["hh:style", "style", "hp:style"];
519
+ for (const tagName of tagNames) {
520
+ const elements = doc.getElementsByTagName(tagName);
521
+ for (let i = 0; i < elements.length; i++) {
522
+ const el = elements[i];
523
+ const id = el.getAttribute("id") || el.getAttribute("IDRef") || String(i);
524
+ const name = el.getAttribute("name") || el.getAttribute("engName") || "";
525
+ const charPrId = el.getAttribute("charPrIDRef") || void 0;
526
+ const paraPrId = el.getAttribute("paraPrIDRef") || void 0;
527
+ map.set(id, { name, charPrId, paraPrId });
528
+ }
529
+ }
530
+ }
531
+ function parseNumberings(doc, map) {
532
+ const tagNames = ["hh:numbering", "numbering"];
533
+ for (const tagName of tagNames) {
534
+ const elements = doc.getElementsByTagName(tagName);
535
+ for (let i = 0; i < elements.length; i++) {
536
+ const el = elements[i];
537
+ const id = el.getAttribute("id") || "";
538
+ if (!id) continue;
539
+ const def = { heads: /* @__PURE__ */ new Map() };
540
+ const children = el.childNodes;
541
+ for (let j = 0; j < children.length; j++) {
542
+ const ch = children[j];
543
+ if (ch.nodeType !== 1) continue;
544
+ const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
545
+ if (tag !== "paraHead") continue;
546
+ const level = parseInt(ch.getAttribute("level") || "", 10);
547
+ if (isNaN(level) || level < 1 || level > 10) continue;
548
+ const start = parseInt(ch.getAttribute("start") || "1", 10);
549
+ def.heads.set(level, {
550
+ numFormat: ch.getAttribute("numFormat") || "DIGIT",
551
+ text: ch.textContent || "",
552
+ start: isNaN(start) ? 1 : start
553
+ });
554
+ }
555
+ if (def.heads.size > 0) map.set(id, def);
556
+ }
557
+ if (map.size > 0) break;
558
+ }
559
+ }
560
+ function parseBullets(doc, map) {
561
+ const tagNames = ["hh:bullet", "bullet"];
562
+ for (const tagName of tagNames) {
563
+ const elements = doc.getElementsByTagName(tagName);
564
+ for (let i = 0; i < elements.length; i++) {
565
+ const el = elements[i];
566
+ const id = el.getAttribute("id") || "";
567
+ const char = el.getAttribute("char") || "";
568
+ if (id && char) map.set(id, char);
569
+ }
570
+ if (map.size > 0) break;
571
+ }
572
+ }
573
+ function parseParaHeadings(doc, map) {
574
+ const tagNames = ["hh:paraPr", "paraPr"];
575
+ for (const tagName of tagNames) {
576
+ const elements = doc.getElementsByTagName(tagName);
577
+ for (let i = 0; i < elements.length; i++) {
578
+ const el = elements[i];
579
+ const id = el.getAttribute("id") || "";
580
+ if (!id) continue;
581
+ const heading = findChildByLocalName(el, "heading");
582
+ if (!heading) continue;
583
+ const type = heading.getAttribute("type") || "NONE";
584
+ if (type !== "NUMBER" && type !== "BULLET" && type !== "OUTLINE") continue;
585
+ const level = parseInt(heading.getAttribute("level") || "0", 10);
586
+ map.set(id, {
587
+ type,
588
+ idRef: heading.getAttribute("idRef") || "0",
589
+ level: isNaN(level) ? 0 : Math.max(0, Math.min(level, 9))
590
+ });
591
+ }
592
+ if (map.size > 0) break;
593
+ }
594
+ }
595
+ function detectHwpxHeadings(blocks, styleMap) {
596
+ if (blocks.some((b) => b.type === "heading")) return;
597
+ let baseFontSize = 0;
598
+ const sizeFreq = /* @__PURE__ */ new Map();
599
+ for (const b of blocks) {
600
+ if (_optionalChain([b, 'access', _5 => _5.style, 'optionalAccess', _6 => _6.fontSize])) {
601
+ sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1);
602
+ }
603
+ }
604
+ let maxCount = 0;
605
+ for (const [size, count] of sizeFreq) {
606
+ if (count > maxCount) {
607
+ maxCount = count;
608
+ baseFontSize = size;
609
+ }
610
+ }
611
+ for (const block of blocks) {
612
+ if (block.type !== "paragraph" || !block.text) continue;
613
+ const text = block.text.trim();
614
+ if (text.length === 0 || text.length > 200 || /^\d+$/.test(text)) continue;
615
+ let level = 0;
616
+ if (baseFontSize > 0 && _optionalChain([block, 'access', _7 => _7.style, 'optionalAccess', _8 => _8.fontSize])) {
617
+ const ratio = block.style.fontSize / baseFontSize;
618
+ if (ratio >= _chunkLFCS3UVGcjs.HEADING_RATIO_H1) level = 1;
619
+ else if (ratio >= _chunkLFCS3UVGcjs.HEADING_RATIO_H2) level = 2;
620
+ else if (ratio >= _chunkLFCS3UVGcjs.HEADING_RATIO_H3) level = 3;
621
+ }
622
+ const compactText = text.replace(/\s+/g, "");
623
+ if (/^제\d+[조장절편]/.test(compactText) && text.length <= 50) {
624
+ if (level === 0) level = 3;
625
+ }
626
+ if (level > 0) {
627
+ block.type = "heading";
628
+ block.level = level;
629
+ }
630
+ }
631
+ }
632
+
396
633
  // src/hwpx/equation.ts
397
634
  var CONVERT_MAP = {
398
635
  TIMES: "\\times",
@@ -676,7 +913,7 @@ function findEnclosingBrackets(eqString, startIdx) {
676
913
  try {
677
914
  const [start, end] = findBrackets(eqString, idx, 1);
678
915
  if (start === idx && end > startIdx) return [start, end];
679
- } catch (e5) {
916
+ } catch (e6) {
680
917
  return null;
681
918
  }
682
919
  return null;
@@ -695,7 +932,7 @@ function replaceFrac(eqString) {
695
932
  const beforeFrac = eqString.slice(0, numStart);
696
933
  const afterFrac = eqString.slice(cursor + hmlFrac.length);
697
934
  eqString = beforeFrac + "\\frac" + numerator + afterFrac;
698
- } catch (e6) {
935
+ } catch (e7) {
699
936
  return eqString;
700
937
  }
701
938
  }
@@ -713,7 +950,7 @@ function replaceRootOf(eqString) {
713
950
  const e1 = eqString.slice(elem1[0] + 1, elem1[1] - 1);
714
951
  const e2 = eqString.slice(elem2[0] + 1, elem2[1] - 1);
715
952
  eqString = eqString.slice(0, rootCursor) + "\\sqrt[" + e1 + "]{" + e2 + "}" + eqString.slice(elem2[1] + 1);
716
- } catch (e7) {
953
+ } catch (e8) {
717
954
  return eqString;
718
955
  }
719
956
  }
@@ -745,7 +982,7 @@ function replaceAllMatrix(eqString) {
745
982
  afterMat = input.slice(eEnd);
746
983
  }
747
984
  input = beforeMat + matElem.begin + elem + matElem.end + afterMat;
748
- } catch (e8) {
985
+ } catch (e9) {
749
986
  return input;
750
987
  }
751
988
  }
@@ -769,7 +1006,7 @@ function replaceAllBar(eqString) {
769
1006
  const beforeBar = input.slice(0, replaceStart);
770
1007
  const afterBar = input.slice(replaceEnd);
771
1008
  input = beforeBar + barElem + elem + afterBar;
772
- } catch (e9) {
1009
+ } catch (e10) {
773
1010
  return input;
774
1011
  }
775
1012
  }
@@ -793,7 +1030,7 @@ function replaceAllBrace(eqString) {
793
1030
  const beforeBrace = input.slice(0, cursor);
794
1031
  const afterBrace = input.slice(eEnd2);
795
1032
  input = beforeBrace + braceElem + elem1 + "^" + elem2 + afterBrace;
796
- } catch (e10) {
1033
+ } catch (e11) {
797
1034
  return input;
798
1035
  }
799
1036
  }
@@ -832,173 +1069,7 @@ function hmlToLatex(hmlEqStr) {
832
1069
  return out;
833
1070
  }
834
1071
 
835
- // src/hwpx/parser.ts
836
- var MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024;
837
- var MAX_ZIP_ENTRIES = 500;
838
- function clampSpan(val, max) {
839
- return Math.max(1, Math.min(val, max));
840
- }
841
- var MAX_XML_DEPTH = 200;
842
- function createSectionShared() {
843
- return { numState: /* @__PURE__ */ new Map(), pageText: { headers: [], footers: [] }, track: { deleteDepth: 0, warned: false } };
844
- }
845
- function createXmlParser(warnings) {
846
- return new (0, _xmldom.DOMParser)({
847
- onError(level, msg2) {
848
- if (level === "fatalError") throw new (0, _chunkITJIALN5cjs.KordocError)(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
849
- _optionalChain([warnings, 'optionalAccess', _3 => _3.push, 'call', _4 => _4({ code: "MALFORMED_XML", message: `XML ${level === "warn" ? "\uACBD\uACE0" : "\uC624\uB958"}: ${msg2}` })]);
850
- }
851
- });
852
- }
853
- async function extractHwpxStyles(zip, decompressed) {
854
- const result = {
855
- charProperties: /* @__PURE__ */ new Map(),
856
- styles: /* @__PURE__ */ new Map(),
857
- numberings: /* @__PURE__ */ new Map(),
858
- bullets: /* @__PURE__ */ new Map(),
859
- paraHeadings: /* @__PURE__ */ new Map()
860
- };
861
- const headerPaths = ["Contents/header.xml", "header.xml", "Contents/head.xml", "head.xml"];
862
- for (const hp of headerPaths) {
863
- const hpLower = hp.toLowerCase();
864
- const file = zip.file(hp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === hpLower) || null;
865
- if (!file) continue;
866
- try {
867
- const xml = await file.async("text");
868
- if (decompressed) {
869
- decompressed.total += xml.length * 2;
870
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
871
- }
872
- const parser = createXmlParser();
873
- const doc = parser.parseFromString(_chunkITJIALN5cjs.stripDtd.call(void 0, xml), "text/xml");
874
- if (!doc.documentElement) continue;
875
- parseCharProperties(doc, result.charProperties);
876
- parseStyleElements(doc, result.styles);
877
- const domDoc = doc;
878
- parseNumberings(domDoc, result.numberings);
879
- parseBullets(domDoc, result.bullets);
880
- parseParaHeadings(domDoc, result.paraHeadings);
881
- break;
882
- } catch (e11) {
883
- continue;
884
- }
885
- }
886
- return result;
887
- }
888
- function parseCharProperties(doc, map) {
889
- const tagNames = ["hh:charPr", "charPr", "hp:charPr"];
890
- for (const tagName of tagNames) {
891
- const elements = doc.getElementsByTagName(tagName);
892
- for (let i = 0; i < elements.length; i++) {
893
- const el = elements[i];
894
- const id = el.getAttribute("id") || el.getAttribute("IDRef") || "";
895
- if (!id) continue;
896
- const prop = {};
897
- const height = el.getAttribute("height");
898
- if (height) {
899
- const parsedHeight = parseInt(height, 10);
900
- if (!isNaN(parsedHeight) && parsedHeight > 0) {
901
- prop.fontSize = parsedHeight / 100;
902
- }
903
- }
904
- const bold = el.getAttribute("bold");
905
- if (bold === "true" || bold === "1") prop.bold = true;
906
- const italic = el.getAttribute("italic");
907
- if (italic === "true" || italic === "1") prop.italic = true;
908
- const fontFaces = el.getElementsByTagName("*");
909
- for (let j = 0; j < fontFaces.length; j++) {
910
- const ff = fontFaces[j];
911
- const localTag = (ff.tagName || "").replace(/^[^:]+:/, "");
912
- if (localTag === "fontface" || localTag === "fontRef") {
913
- const face = ff.getAttribute("face") || ff.getAttribute("FontFace");
914
- if (face) {
915
- prop.fontName = face;
916
- break;
917
- }
918
- }
919
- }
920
- map.set(id, prop);
921
- }
922
- }
923
- }
924
- function parseStyleElements(doc, map) {
925
- const tagNames = ["hh:style", "style", "hp:style"];
926
- for (const tagName of tagNames) {
927
- const elements = doc.getElementsByTagName(tagName);
928
- for (let i = 0; i < elements.length; i++) {
929
- const el = elements[i];
930
- const id = el.getAttribute("id") || el.getAttribute("IDRef") || String(i);
931
- const name = el.getAttribute("name") || el.getAttribute("engName") || "";
932
- const charPrId = el.getAttribute("charPrIDRef") || void 0;
933
- const paraPrId = el.getAttribute("paraPrIDRef") || void 0;
934
- map.set(id, { name, charPrId, paraPrId });
935
- }
936
- }
937
- }
938
- function parseNumberings(doc, map) {
939
- const tagNames = ["hh:numbering", "numbering"];
940
- for (const tagName of tagNames) {
941
- const elements = doc.getElementsByTagName(tagName);
942
- for (let i = 0; i < elements.length; i++) {
943
- const el = elements[i];
944
- const id = el.getAttribute("id") || "";
945
- if (!id) continue;
946
- const def = { heads: /* @__PURE__ */ new Map() };
947
- const children = el.childNodes;
948
- for (let j = 0; j < children.length; j++) {
949
- const ch = children[j];
950
- if (ch.nodeType !== 1) continue;
951
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
952
- if (tag !== "paraHead") continue;
953
- const level = parseInt(ch.getAttribute("level") || "", 10);
954
- if (isNaN(level) || level < 1 || level > 10) continue;
955
- const start = parseInt(ch.getAttribute("start") || "1", 10);
956
- def.heads.set(level, {
957
- numFormat: ch.getAttribute("numFormat") || "DIGIT",
958
- text: ch.textContent || "",
959
- start: isNaN(start) ? 1 : start
960
- });
961
- }
962
- if (def.heads.size > 0) map.set(id, def);
963
- }
964
- if (map.size > 0) break;
965
- }
966
- }
967
- function parseBullets(doc, map) {
968
- const tagNames = ["hh:bullet", "bullet"];
969
- for (const tagName of tagNames) {
970
- const elements = doc.getElementsByTagName(tagName);
971
- for (let i = 0; i < elements.length; i++) {
972
- const el = elements[i];
973
- const id = el.getAttribute("id") || "";
974
- const char = el.getAttribute("char") || "";
975
- if (id && char) map.set(id, char);
976
- }
977
- if (map.size > 0) break;
978
- }
979
- }
980
- function parseParaHeadings(doc, map) {
981
- const tagNames = ["hh:paraPr", "paraPr"];
982
- for (const tagName of tagNames) {
983
- const elements = doc.getElementsByTagName(tagName);
984
- for (let i = 0; i < elements.length; i++) {
985
- const el = elements[i];
986
- const id = el.getAttribute("id") || "";
987
- if (!id) continue;
988
- const heading = findChildByLocalName(el, "heading");
989
- if (!heading) continue;
990
- const type = heading.getAttribute("type") || "NONE";
991
- if (type !== "NUMBER" && type !== "BULLET" && type !== "OUTLINE") continue;
992
- const level = parseInt(heading.getAttribute("level") || "0", 10);
993
- map.set(id, {
994
- type,
995
- idRef: heading.getAttribute("idRef") || "0",
996
- level: isNaN(level) ? 0 : Math.max(0, Math.min(level, 9))
997
- });
998
- }
999
- if (map.size > 0) break;
1000
- }
1001
- }
1072
+ // src/hwpx/para-heading.ts
1002
1073
  var HANGUL_SYLLABLE_SEQ = "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC\uC544\uC790\uCC28\uCE74\uD0C0\uD30C\uD558";
1003
1074
  var HANGUL_JAMO_SEQ = "\u3131\u3134\u3137\u3139\u3141\u3142\u3145\u3147\u3148\u314A\u314B\u314C\u314D\u314E";
1004
1075
  function toRoman(n) {
@@ -1080,783 +1151,423 @@ function resolveParaHeading(paraEl, ctx) {
1080
1151
  ctx.shared.numState.set(numId, counters);
1081
1152
  }
1082
1153
  const head = numDef.heads.get(level);
1083
- counters[level] = counters[level] === 0 ? _nullishCoalesce(_optionalChain([head, 'optionalAccess', _5 => _5.start]), () => ( 1)) : counters[level] + 1;
1154
+ counters[level] = counters[level] === 0 ? _nullishCoalesce(_optionalChain([head, 'optionalAccess', _9 => _9.start]), () => ( 1)) : counters[level] + 1;
1084
1155
  for (let l = level + 1; l <= 10; l++) counters[l] = 0;
1085
- const fmtText = _optionalChain([head, 'optionalAccess', _6 => _6.text, 'optionalAccess', _7 => _7.trim, 'call', _8 => _8()]) || `^${level}.`;
1156
+ const fmtText = _optionalChain([head, 'optionalAccess', _10 => _10.text, 'optionalAccess', _11 => _11.trim, 'call', _12 => _12()]) || `^${level}.`;
1086
1157
  const prefix = fmtText.replace(/\^(10|[1-9])/g, (_, d) => {
1087
1158
  const lv = parseInt(d, 10);
1088
1159
  const refHead = numDef.heads.get(lv);
1089
- const n = counters[lv] || _optionalChain([refHead, 'optionalAccess', _9 => _9.start]) || 1;
1090
- return formatHeadNumber(n, _optionalChain([refHead, 'optionalAccess', _10 => _10.numFormat]) || "DIGIT");
1160
+ const n = counters[lv] || _optionalChain([refHead, 'optionalAccess', _13 => _13.start]) || 1;
1161
+ return formatHeadNumber(n, _optionalChain([refHead, 'optionalAccess', _14 => _14.numFormat]) || "DIGIT");
1091
1162
  });
1092
1163
  return { prefix, headingLevel };
1093
1164
  }
1094
- async function parseHwpxDocument(buffer, options) {
1095
- _chunkITJIALN5cjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
1096
- let zip;
1097
- try {
1098
- zip = await _jszip2.default.loadAsync(buffer);
1099
- } catch (e12) {
1100
- return extractFromBrokenZip(buffer);
1101
- }
1102
- const actualEntryCount = Object.keys(zip.files).length;
1103
- if (actualEntryCount > MAX_ZIP_ENTRIES) {
1104
- throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP \uC5D4\uD2B8\uB9AC \uC218 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1105
- }
1106
- const manifestFile = zip.file("META-INF/manifest.xml");
1107
- if (manifestFile) {
1108
- const manifestXml = await manifestFile.async("text");
1109
- if (isEncryptedHwpx(manifestXml)) {
1110
- if (isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _11 => _11.filePath])) {
1111
- const { pages, pageCount, warnings: warnings2 } = extractTextViaCom(options.filePath);
1112
- if (pages.some((p) => p && p.trim().length > 0)) {
1113
- return comResultToParseResult(pages, pageCount, warnings2);
1165
+
1166
+ // src/hwpx/table-build.ts
1167
+ function buildTableWithCellMeta(state) {
1168
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, state.rows);
1169
+ if (state.caption) table.caption = state.caption;
1170
+ const anchors = [];
1171
+ {
1172
+ const covered = /* @__PURE__ */ new Set();
1173
+ for (let r = 0; r < table.rows; r++) {
1174
+ for (let c = 0; c < table.cols; c++) {
1175
+ if (covered.has(`${r},${c}`)) continue;
1176
+ const cell = _optionalChain([table, 'access', _15 => _15.cells, 'access', _16 => _16[r], 'optionalAccess', _17 => _17[c]]);
1177
+ if (!cell) continue;
1178
+ for (let dr = 0; dr < cell.rowSpan; dr++) {
1179
+ for (let dc = 0; dc < cell.colSpan; dc++) {
1180
+ if (dr === 0 && dc === 0) continue;
1181
+ if (r + dr < table.rows && c + dc < table.cols) covered.add(`${r + dr},${c + dc}`);
1182
+ }
1114
1183
  }
1184
+ anchors.push(cell);
1185
+ c += cell.colSpan - 1;
1115
1186
  }
1116
- throw new (0, _chunkITJIALN5cjs.KordocError)("DRM \uC554\uD638\uD654\uB41C HWPX \uD30C\uC77C\uC785\uB2C8\uB2E4. Windows + \uD55C\uCEF4 \uC624\uD53C\uC2A4 \uC124\uCE58 \uC2DC \uC790\uB3D9 \uCD94\uCD9C\uB429\uB2C8\uB2E4.");
1117
1187
  }
1118
1188
  }
1119
- const decompressed = { total: 0 };
1120
- const metadata = {};
1121
- await extractHwpxMetadata(zip, metadata, decompressed);
1122
- const styleMap = await extractHwpxStyles(zip, decompressed);
1123
- const warnings = [];
1124
- const sectionPaths = await resolveSectionPaths(zip);
1125
- if (sectionPaths.length === 0) throw new (0, _chunkITJIALN5cjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1126
- metadata.pageCount = sectionPaths.length;
1127
- const pageFilter = _optionalChain([options, 'optionalAccess', _12 => _12.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sectionPaths.length) : null;
1128
- const totalTarget = pageFilter ? pageFilter.size : sectionPaths.length;
1129
- const blocks = [];
1130
- const shared = createSectionShared();
1131
- let parsedSections = 0;
1132
- for (let si = 0; si < sectionPaths.length; si++) {
1133
- if (pageFilter && !pageFilter.has(si + 1)) continue;
1134
- const file = zip.file(sectionPaths[si]);
1135
- if (!file) continue;
1136
- try {
1137
- const xml = await file.async("text");
1138
- decompressed.total += xml.length * 2;
1139
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1140
- blocks.push(...parseSectionXml(xml, styleMap, warnings, si + 1, shared));
1141
- parsedSections++;
1142
- _optionalChain([options, 'optionalAccess', _13 => _13.onProgress, 'optionalCall', _14 => _14(parsedSections, totalTarget)]);
1143
- } catch (secErr) {
1144
- if (secErr instanceof _chunkITJIALN5cjs.KordocError) throw secErr;
1145
- warnings.push({ page: si + 1, message: `\uC139\uC158 ${si + 1} \uD30C\uC2F1 \uC2E4\uD328: ${secErr instanceof Error ? secErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
1189
+ const srcCount = state.rows.reduce((s, r) => s + r.length, 0);
1190
+ const ordinalReliable = anchors.length === srcCount;
1191
+ const claimed = /* @__PURE__ */ new Set();
1192
+ let flatIdx = -1;
1193
+ for (const row of state.rows) {
1194
+ for (const src of row) {
1195
+ flatIdx++;
1196
+ const needsBlocks = src.hasStructure && src.blocks && src.blocks.length > 0;
1197
+ if (!needsBlocks && !src.isHeader) continue;
1198
+ let target;
1199
+ const trimmed = src.text.trim();
1200
+ if (src.rowAddr !== void 0 && src.colAddr !== void 0) {
1201
+ const cand = _optionalChain([table, 'access', _18 => _18.cells, 'access', _19 => _19[src.rowAddr], 'optionalAccess', _20 => _20[src.colAddr]]);
1202
+ if (cand && cand.text === trimmed && !claimed.has(cand)) target = cand;
1203
+ }
1204
+ if (!target) {
1205
+ outer: for (const irRow of table.cells) {
1206
+ for (const cand of irRow) {
1207
+ if (!claimed.has(cand) && cand.text === trimmed && cand.colSpan === src.colSpan && cand.rowSpan === src.rowSpan) {
1208
+ target = cand;
1209
+ break outer;
1210
+ }
1211
+ }
1212
+ }
1213
+ }
1214
+ if (!target && ordinalReliable) {
1215
+ const cand = anchors[flatIdx];
1216
+ if (cand && !claimed.has(cand)) target = cand;
1217
+ }
1218
+ if (!target) continue;
1219
+ claimed.add(target);
1220
+ if (needsBlocks) target.blocks = src.blocks;
1221
+ if (src.isHeader) target.isHeader = true;
1146
1222
  }
1147
1223
  }
1148
- applyPageText(blocks, shared);
1149
- const images = await extractImagesFromZip(zip, blocks, decompressed, warnings);
1150
- detectHwpxHeadings(blocks, styleMap);
1151
- const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
1152
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks);
1153
- return { markdown, blocks, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
1224
+ return table;
1154
1225
  }
1155
- function applyPageText(blocks, shared) {
1156
- const { headers, footers } = shared.pageText;
1157
- if (headers.length > 0) {
1158
- blocks.unshift(...headers.map((t) => ({ type: "paragraph", text: t, pageNumber: 1 })));
1226
+ function completeTable(newTable, tableStack, blocks, ctx) {
1227
+ const parentTable = tableStack.length > 0 ? tableStack.pop() : null;
1228
+ if (newTable.rows.length === 0) {
1229
+ if (newTable.caption) blocks.push({ type: "paragraph", text: newTable.caption, pageNumber: ctx.sectionNum });
1230
+ return parentTable;
1159
1231
  }
1160
- if (footers.length > 0) {
1161
- blocks.push(...footers.map((t) => ({ type: "paragraph", text: t })));
1232
+ const ir = buildTableWithCellMeta(newTable);
1233
+ const block = { type: "table", table: ir, pageNumber: ctx.sectionNum };
1234
+ if (_optionalChain([parentTable, 'optionalAccess', _21 => _21.cell])) {
1235
+ const cell = parentTable.cell;
1236
+ (cell.blocks ??= []).push(block);
1237
+ cell.hasStructure = true;
1238
+ let flat = _chunkLFCS3UVGcjs.convertTableToText.call(void 0, newTable.rows);
1239
+ if (newTable.caption) flat = newTable.caption + (flat ? "\n" + flat : "");
1240
+ if (flat) cell.text += (cell.text ? "\n" : "") + flat;
1241
+ } else {
1242
+ blocks.push(block);
1162
1243
  }
1244
+ return parentTable;
1163
1245
  }
1164
- function imageExtToMime(ext) {
1165
- switch (ext.toLowerCase()) {
1166
- case "jpg":
1167
- case "jpeg":
1168
- return "image/jpeg";
1169
- case "png":
1170
- return "image/png";
1171
- case "gif":
1172
- return "image/gif";
1173
- case "bmp":
1174
- return "image/bmp";
1175
- case "tif":
1176
- case "tiff":
1177
- return "image/tiff";
1178
- case "wmf":
1179
- return "image/wmf";
1180
- case "emf":
1181
- return "image/emf";
1182
- case "svg":
1183
- return "image/svg+xml";
1184
- default:
1185
- return "application/octet-stream";
1246
+
1247
+ // src/hwpx/section-walker.ts
1248
+ function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1249
+ const parser = createXmlParser(warnings);
1250
+ const doc = parser.parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, xml), "text/xml");
1251
+ if (!doc.documentElement) return [];
1252
+ const ctx = { styleMap, warnings, sectionNum, shared: _nullishCoalesce(shared, () => ( createSectionShared())) };
1253
+ ctx.shared.track.deleteDepth = 0;
1254
+ for (const tagName of ["hp:secPr", "secPr"]) {
1255
+ const els = doc.getElementsByTagName(tagName);
1256
+ if (els.length > 0) {
1257
+ const v = els[0].getAttribute("outlineShapeIDRef");
1258
+ if (v) ctx.outlineNumId = v;
1259
+ break;
1260
+ }
1186
1261
  }
1262
+ const blocks = [];
1263
+ walkSection(doc.documentElement, blocks, null, [], ctx);
1264
+ return blocks;
1187
1265
  }
1188
- function mimeToExt(mime) {
1189
- if (mime.includes("jpeg")) return "jpg";
1190
- if (mime.includes("png")) return "png";
1191
- if (mime.includes("gif")) return "gif";
1192
- if (mime.includes("bmp")) return "bmp";
1193
- if (mime.includes("tiff")) return "tif";
1194
- if (mime.includes("wmf")) return "wmf";
1195
- if (mime.includes("emf")) return "emf";
1196
- if (mime.includes("svg")) return "svg";
1197
- return "bin";
1198
- }
1199
- function collectImageBlocks(blocks, out, ownerCell, depth = 0) {
1200
- if (depth > MAX_XML_DEPTH) return;
1201
- for (const block of blocks) {
1202
- if (block.type === "image") {
1203
- out.push({ block, ownerCell });
1204
- } else if (block.type === "table" && block.table) {
1205
- for (const row of block.table.cells) {
1206
- for (const cell of row) {
1207
- if (_optionalChain([cell, 'access', _15 => _15.blocks, 'optionalAccess', _16 => _16.length])) collectImageBlocks(cell.blocks, out, cell, depth + 1);
1208
- }
1209
- }
1266
+ function extractImageRef(el) {
1267
+ const children = el.childNodes;
1268
+ if (!children) return null;
1269
+ for (let i = 0; i < children.length; i++) {
1270
+ const child = children[i];
1271
+ if (child.nodeType !== 1) continue;
1272
+ const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1273
+ if (tag === "imgRect" || tag === "img" || tag === "imgClip") {
1274
+ const ref = child.getAttribute("binaryItemIDRef") || child.getAttribute("href") || "";
1275
+ if (ref) return ref;
1210
1276
  }
1277
+ const nested = extractImageRef(child);
1278
+ if (nested) return nested;
1211
1279
  }
1280
+ const directRef = el.getAttribute("binaryItemIDRef") || "";
1281
+ if (directRef) return directRef;
1282
+ return null;
1212
1283
  }
1213
- async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
1214
- const images = [];
1215
- let imageIndex = 0;
1216
- const imageBlocks = [];
1217
- collectImageBlocks(blocks, imageBlocks);
1218
- const resolved = /* @__PURE__ */ new Map();
1219
- for (const { block, ownerCell } of imageBlocks) {
1220
- if (block.type !== "image" || !block.text) continue;
1221
- const ref = block.text;
1222
- let img = resolved.get(ref);
1223
- if (img === void 0) {
1224
- img = null;
1225
- const candidates = [
1226
- `BinData/${ref}`,
1227
- `Contents/BinData/${ref}`,
1228
- ref
1229
- // 절대 경로일 수도 있음
1230
- ];
1231
- let resolvedPath = null;
1232
- if (!ref.includes(".")) {
1233
- const prefixes = [`BinData/${ref}`, `Contents/BinData/${ref}`];
1234
- for (const prefix of prefixes) {
1235
- const match = zip.file(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.[a-zA-Z0-9]+$`));
1236
- if (match.length > 0) {
1237
- resolvedPath = match[0].name;
1238
- break;
1284
+ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1285
+ if (depth > MAX_XML_DEPTH) return;
1286
+ const children = node.childNodes;
1287
+ if (!children) return;
1288
+ for (let i = 0; i < children.length; i++) {
1289
+ const el = children[i];
1290
+ if (el.nodeType !== 1) continue;
1291
+ const tag = el.tagName || el.localName || "";
1292
+ const localTag = tag.replace(/^[^:]+:/, "");
1293
+ switch (localTag) {
1294
+ case "tbl": {
1295
+ if (tableCtx) tableStack.push(tableCtx);
1296
+ const newTable = { rows: [], currentRow: [], cell: null };
1297
+ walkSection(el, blocks, newTable, tableStack, ctx, depth + 1);
1298
+ tableCtx = completeTable(newTable, tableStack, blocks, ctx);
1299
+ break;
1300
+ }
1301
+ // 표/도표 캡션 — IRTable.caption으로 보존 (v3.0, 기존 무음 드롭 수정)
1302
+ case "caption":
1303
+ if (tableCtx) {
1304
+ const capText = collectSubListText(el, ctx);
1305
+ if (capText) tableCtx.caption = (tableCtx.caption ? tableCtx.caption + "\n" : "") + capText;
1306
+ }
1307
+ break;
1308
+ case "tr":
1309
+ if (tableCtx) {
1310
+ tableCtx.currentRow = [];
1311
+ walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1312
+ if (tableCtx.currentRow.length > 0) tableCtx.rows.push(tableCtx.currentRow);
1313
+ tableCtx.currentRow = [];
1314
+ }
1315
+ break;
1316
+ case "tc":
1317
+ if (tableCtx) {
1318
+ tableCtx.cell = { text: "", colSpan: 1, rowSpan: 1 };
1319
+ if (el.getAttribute("header") === "1" || el.getAttribute("header") === "true") tableCtx.cell.isHeader = true;
1320
+ walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1321
+ if (tableCtx.cell) {
1322
+ tableCtx.currentRow.push(tableCtx.cell);
1323
+ tableCtx.cell = null;
1324
+ }
1325
+ }
1326
+ break;
1327
+ case "cellAddr":
1328
+ if (_optionalChain([tableCtx, 'optionalAccess', _22 => _22.cell])) {
1329
+ const ca = parseInt(el.getAttribute("colAddr") || "", 10);
1330
+ const ra = parseInt(el.getAttribute("rowAddr") || "", 10);
1331
+ if (!isNaN(ca)) tableCtx.cell.colAddr = ca;
1332
+ if (!isNaN(ra)) tableCtx.cell.rowAddr = ra;
1333
+ }
1334
+ break;
1335
+ case "cellSpan":
1336
+ if (_optionalChain([tableCtx, 'optionalAccess', _23 => _23.cell])) {
1337
+ const rawCs = parseInt(el.getAttribute("colSpan") || "1", 10);
1338
+ const cs = isNaN(rawCs) ? 1 : rawCs;
1339
+ const rawRs = parseInt(el.getAttribute("rowSpan") || "1", 10);
1340
+ const rs = isNaN(rawRs) ? 1 : rawRs;
1341
+ tableCtx.cell.colSpan = clampSpan(cs, _chunkLFCS3UVGcjs.MAX_COLS);
1342
+ tableCtx.cell.rowSpan = clampSpan(rs, _chunkLFCS3UVGcjs.MAX_ROWS);
1343
+ }
1344
+ break;
1345
+ case "p": {
1346
+ const { text: rawText, href, footnote, style } = extractParagraphInfo(el, ctx.styleMap, ctx);
1347
+ let text = rawText;
1348
+ let headingLevel;
1349
+ if (text) {
1350
+ const ph = resolveParaHeading(el, ctx);
1351
+ if (_optionalChain([ph, 'optionalAccess', _24 => _24.prefix])) text = ph.prefix + " " + text;
1352
+ headingLevel = _optionalChain([ph, 'optionalAccess', _25 => _25.headingLevel]);
1353
+ }
1354
+ if (text) {
1355
+ if (_optionalChain([tableCtx, 'optionalAccess', _26 => _26.cell])) {
1356
+ const cell = tableCtx.cell;
1357
+ if (footnote) text += ` (\uC8FC: ${footnote})`;
1358
+ cell.text += (cell.text ? "\n" : "") + text;
1359
+ (cell.blocks ??= []).push({ type: "paragraph", text, pageNumber: ctx.sectionNum });
1360
+ } else if (!tableCtx) {
1361
+ const block = { type: headingLevel ? "heading" : "paragraph", text, pageNumber: ctx.sectionNum };
1362
+ if (headingLevel) block.level = headingLevel;
1363
+ if (style) block.style = style;
1364
+ if (href) block.href = href;
1365
+ if (footnote) block.footnoteText = footnote;
1366
+ blocks.push(block);
1367
+ } else {
1368
+ blocks.push({ type: "paragraph", text, pageNumber: ctx.sectionNum });
1239
1369
  }
1240
1370
  }
1371
+ tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1372
+ break;
1241
1373
  }
1242
- const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates;
1243
- for (const path of allCandidates) {
1244
- if (_chunkITJIALN5cjs.isPathTraversal.call(void 0, path)) continue;
1245
- const file = zip.file(path);
1246
- if (!file) continue;
1247
- try {
1248
- const data = await file.async("uint8array");
1249
- decompressed.total += data.length;
1250
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1251
- const ext = path.includes(".") ? path.split(".").pop() || "png" : "png";
1252
- const mimeType = imageExtToMime(ext);
1253
- imageIndex++;
1254
- const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
1255
- img = { filename, data, mimeType };
1256
- images.push(img);
1257
- break;
1258
- } catch (err) {
1259
- if (err instanceof _chunkITJIALN5cjs.KordocError) throw err;
1374
+ // 이미지/그림/글상자 이미지·텍스트·캡션 병행 추출
1375
+ case "pic":
1376
+ case "shape":
1377
+ case "drawingObject": {
1378
+ if (_optionalChain([tableCtx, 'optionalAccess', _27 => _27.cell])) {
1379
+ const sink = [];
1380
+ handleShape(el, sink, ctx);
1381
+ mergeBlocksIntoCell(tableCtx.cell, sink);
1382
+ } else {
1383
+ handleShape(el, blocks, ctx);
1260
1384
  }
1385
+ break;
1261
1386
  }
1262
- if (!img) _optionalChain([warnings, 'optionalAccess', _17 => _17.push, 'call', _18 => _18({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" })]);
1263
- resolved.set(ref, img);
1264
- }
1265
- if (!img) {
1266
- block.type = "paragraph";
1267
- block.text = `[\uC774\uBBF8\uC9C0: ${ref}]`;
1268
- if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `[\uC774\uBBF8\uC9C0: ${ref}]`);
1269
- continue;
1270
- }
1271
- block.text = img.filename;
1272
- block.imageData = { data: img.data, mimeType: img.mimeType, filename: ref };
1273
- if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `![image](${img.filename})`);
1274
- }
1275
- return images;
1276
- }
1277
- async function extractHwpxMetadata(zip, metadata, decompressed) {
1278
- try {
1279
- const metaPaths = ["meta.xml", "META-INF/meta.xml", "docProps/core.xml"];
1280
- for (const mp of metaPaths) {
1281
- const file = zip.file(mp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === mp.toLowerCase()) || null;
1282
- if (!file) continue;
1283
- const xml = await file.async("text");
1284
- if (decompressed) {
1285
- decompressed.total += xml.length * 2;
1286
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1387
+ // 메모 본문 혼입 차단 (v3.0)
1388
+ case "memogroup":
1389
+ case "memo": {
1390
+ if (ctx.warnings && extractTextFromNode(el)) {
1391
+ ctx.warnings.push({ page: ctx.sectionNum, message: "\uBA54\uBAA8 \uD14D\uC2A4\uD2B8 \uBCF8\uBB38 \uC81C\uC678: memogroup", code: "HIDDEN_TEXT_FILTERED" });
1392
+ }
1393
+ break;
1287
1394
  }
1288
- parseDublinCoreMetadata(xml, metadata);
1289
- if (metadata.title || metadata.author) return;
1395
+ default:
1396
+ walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1397
+ break;
1290
1398
  }
1291
- } catch (e13) {
1292
1399
  }
1293
1400
  }
1294
- function parseDublinCoreMetadata(xml, metadata) {
1295
- const parser = createXmlParser();
1296
- const doc = parser.parseFromString(_chunkITJIALN5cjs.stripDtd.call(void 0, xml), "text/xml");
1297
- if (!doc.documentElement) return;
1298
- const getText = (tagNames) => {
1299
- for (const tag of tagNames) {
1300
- const els = doc.getElementsByTagName(tag);
1301
- if (els.length > 0) {
1302
- const text = _optionalChain([els, 'access', _19 => _19[0], 'access', _20 => _20.textContent, 'optionalAccess', _21 => _21.trim, 'call', _22 => _22()]);
1303
- if (text) return text;
1304
- }
1305
- }
1306
- return void 0;
1307
- };
1308
- metadata.title = metadata.title || getText(["dc:title", "title"]);
1309
- metadata.author = metadata.author || getText(["dc:creator", "creator", "cp:lastModifiedBy"]);
1310
- metadata.description = metadata.description || getText(["dc:description", "description", "dc:subject", "subject"]);
1311
- metadata.createdAt = metadata.createdAt || getText(["dcterms:created", "meta:creation-date"]);
1312
- metadata.modifiedAt = metadata.modifiedAt || getText(["dcterms:modified", "meta:date"]);
1313
- const keywords = getText(["dc:keyword", "cp:keywords", "meta:keyword"]);
1314
- if (keywords && !metadata.keywords) {
1315
- metadata.keywords = keywords.split(/[,;]/).map((k) => k.trim()).filter(Boolean);
1401
+ function handleShape(el, sink, ctx) {
1402
+ const imgRef = extractImageRef(el);
1403
+ const drawTextChild = findDescendant(el, "drawText");
1404
+ if (imgRef) {
1405
+ const block = { type: "image", text: imgRef, pageNumber: ctx.sectionNum };
1406
+ const alt = userShapeComment(el);
1407
+ if (alt) block.footnoteText = alt;
1408
+ sink.push(block);
1409
+ }
1410
+ if (drawTextChild) {
1411
+ extractDrawTextBlocks(drawTextChild, sink, ctx);
1412
+ }
1413
+ const capEl = findChildByLocalName(el, "caption");
1414
+ if (capEl) {
1415
+ const capText = collectSubListText(capEl, ctx);
1416
+ if (capText) sink.push({ type: "paragraph", text: capText, pageNumber: ctx.sectionNum });
1417
+ }
1418
+ if (!imgRef && !drawTextChild && ctx.warnings && ctx.sectionNum) {
1419
+ const localTag = (el.tagName || el.localName || "").replace(/^[^:]+:/, "");
1420
+ ctx.warnings.push({ page: ctx.sectionNum, message: `\uC2A4\uD0B5\uB41C \uC694\uC18C: ${localTag}`, code: "SKIPPED_IMAGE" });
1316
1421
  }
1317
1422
  }
1318
- function extractFromBrokenZip(buffer) {
1319
- const data = new Uint8Array(buffer);
1320
- const view = new DataView(buffer);
1321
- let pos = 0;
1322
- const blocks = [];
1323
- const warnings = [
1324
- { code: "BROKEN_ZIP_RECOVERY", message: "\uC190\uC0C1\uB41C ZIP \uAD6C\uC870 \u2014 Local File Header \uAE30\uBC18 \uBCF5\uAD6C \uBAA8\uB4DC" }
1325
- ];
1326
- let totalDecompressed = 0;
1327
- let entryCount = 0;
1328
- let sectionNum = 0;
1329
- const shared = createSectionShared();
1330
- while (pos < data.length - 30) {
1331
- if (data[pos] !== 80 || data[pos + 1] !== 75 || data[pos + 2] !== 3 || data[pos + 3] !== 4) {
1332
- pos++;
1333
- while (pos < data.length - 30) {
1334
- if (data[pos] === 80 && data[pos + 1] === 75 && data[pos + 2] === 3 && data[pos + 3] === 4) break;
1335
- pos++;
1423
+ function userShapeComment(el) {
1424
+ const commentEl = findChildByLocalName(el, "shapeComment");
1425
+ if (!commentEl) return void 0;
1426
+ const text = extractTextFromNode(commentEl);
1427
+ if (!text) return void 0;
1428
+ if (/^그림입니다/.test(text)) return void 0;
1429
+ if (/^(?:모서리가 둥근 |둥근 )?[^\n]{1,20}입니다\.?$/.test(text)) return void 0;
1430
+ return text;
1431
+ }
1432
+ function mergeBlocksIntoCell(cell, sink) {
1433
+ for (const b of sink) {
1434
+ if ((b.type === "paragraph" || b.type === "heading") && b.text) {
1435
+ cell.text += (cell.text ? "\n" : "") + b.text;
1436
+ (cell.blocks ??= []).push(b);
1437
+ } else if (b.type === "image" || b.type === "table") {
1438
+ if (b.type === "image" && b.text) {
1439
+ cell.text += (cell.text ? "\n" : "") + `![image](${b.text})`;
1336
1440
  }
1337
- continue;
1338
- }
1339
- if (++entryCount > MAX_ZIP_ENTRIES) break;
1340
- const method = view.getUint16(pos + 8, true);
1341
- const compSize = view.getUint32(pos + 18, true);
1342
- const nameLen = view.getUint16(pos + 26, true);
1343
- const extraLen = view.getUint16(pos + 28, true);
1344
- if (nameLen > 1024 || extraLen > 65535) {
1345
- pos += 30 + nameLen + extraLen;
1346
- continue;
1347
- }
1348
- const fileStart = pos + 30 + nameLen + extraLen;
1349
- if (fileStart + compSize > data.length) break;
1350
- if (compSize === 0 && method !== 0) {
1351
- pos = fileStart;
1352
- continue;
1441
+ ;
1442
+ (cell.blocks ??= []).push(b);
1443
+ cell.hasStructure = true;
1353
1444
  }
1354
- const nameBytes = data.slice(pos + 30, pos + 30 + nameLen);
1355
- const name = new TextDecoder().decode(nameBytes);
1356
- if (_chunkITJIALN5cjs.isPathTraversal.call(void 0, name)) {
1357
- pos = fileStart + compSize;
1445
+ }
1446
+ }
1447
+ function collectSubListText(el, ctx, depth = 0) {
1448
+ if (depth > 10) return "";
1449
+ const parts = [];
1450
+ const children = el.childNodes;
1451
+ if (!children) return "";
1452
+ for (let i = 0; i < children.length; i++) {
1453
+ const ch = children[i];
1454
+ if (ch.nodeType !== 1) continue;
1455
+ const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
1456
+ if (tag === "p" || tag === "para") {
1457
+ const t = extractParagraphInfo(ch, ctx.styleMap, ctx).text;
1458
+ if (t) parts.push(t);
1459
+ } else if (tag === "tbl") {
1358
1460
  continue;
1461
+ } else {
1462
+ const t = collectSubListText(ch, ctx, depth + 1);
1463
+ if (t) parts.push(t);
1359
1464
  }
1360
- const fileData = data.slice(fileStart, fileStart + compSize);
1361
- pos = fileStart + compSize;
1362
- if (!name.toLowerCase().includes("section") || !name.endsWith(".xml")) continue;
1363
- try {
1364
- let content;
1365
- if (method === 0) {
1366
- content = new TextDecoder().decode(fileData);
1367
- } else if (method === 8) {
1368
- const decompressed = _zlib.inflateRawSync.call(void 0, Buffer.from(fileData), { maxOutputLength: MAX_DECOMPRESS_SIZE });
1369
- content = new TextDecoder().decode(decompressed);
1370
- } else {
1371
- continue;
1465
+ }
1466
+ return parts.join("\n").trim();
1467
+ }
1468
+ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1469
+ if (depth > MAX_XML_DEPTH) return tableCtx;
1470
+ const children = node.childNodes;
1471
+ if (!children) return tableCtx;
1472
+ const walkChildren = (parent, d) => {
1473
+ if (d > MAX_XML_DEPTH) return;
1474
+ const kids2 = parent.childNodes;
1475
+ if (!kids2) return;
1476
+ for (let i = 0; i < kids2.length; i++) {
1477
+ const el = kids2[i];
1478
+ if (el.nodeType !== 1) continue;
1479
+ const tag = el.tagName || el.localName || "";
1480
+ const localTag = tag.replace(/^[^:]+:/, "");
1481
+ if (localTag === "tbl") {
1482
+ if (tableCtx) tableStack.push(tableCtx);
1483
+ const newTable = { rows: [], currentRow: [], cell: null };
1484
+ walkSection(el, blocks, newTable, tableStack, ctx, d + 1);
1485
+ tableCtx = completeTable(newTable, tableStack, blocks, ctx);
1486
+ } else if (localTag === "pic" || localTag === "shape" || localTag === "drawingObject") {
1487
+ if (_optionalChain([tableCtx, 'optionalAccess', _28 => _28.cell])) {
1488
+ const sink = [];
1489
+ handleShape(el, sink, ctx);
1490
+ mergeBlocksIntoCell(tableCtx.cell, sink);
1491
+ } else {
1492
+ handleShape(el, blocks, ctx);
1493
+ }
1494
+ } else if (localTag === "drawText") {
1495
+ if (_optionalChain([tableCtx, 'optionalAccess', _29 => _29.cell])) {
1496
+ const sink = [];
1497
+ extractDrawTextBlocks(el, sink, ctx);
1498
+ mergeBlocksIntoCell(tableCtx.cell, sink);
1499
+ } else {
1500
+ extractDrawTextBlocks(el, blocks, ctx);
1501
+ }
1502
+ } else if (localTag === "r" || localTag === "run" || localTag === "ctrl" || localTag === "rect" || localTag === "ellipse" || localTag === "polygon" || localTag === "line" || localTag === "arc" || localTag === "curve" || localTag === "connectLine" || localTag === "container") {
1503
+ walkChildren(el, d + 1);
1372
1504
  }
1373
- totalDecompressed += content.length * 2;
1374
- if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunkITJIALN5cjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
1375
- sectionNum++;
1376
- blocks.push(...parseSectionXml(content, void 0, warnings, sectionNum, shared));
1377
- } catch (e14) {
1378
- continue;
1379
1505
  }
1380
- }
1381
- if (blocks.length === 0) throw new (0, _chunkITJIALN5cjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1382
- applyPageText(blocks, shared);
1383
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks);
1384
- return { markdown, blocks, warnings: warnings.length > 0 ? warnings : void 0 };
1506
+ };
1507
+ walkChildren(node, depth);
1508
+ return tableCtx;
1385
1509
  }
1386
- async function resolveSectionPaths(zip) {
1387
- const manifestPaths = ["Contents/content.hpf", "content.hpf"];
1388
- for (const mp of manifestPaths) {
1389
- const mpLower = mp.toLowerCase();
1390
- const file = zip.file(mp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === mpLower) || null;
1391
- if (!file) continue;
1392
- const xml = await file.async("text");
1393
- const paths = parseSectionPathsFromManifest(xml);
1394
- if (paths.length > 0) return paths;
1510
+ function findDescendant(node, targetTag, depth = 0) {
1511
+ if (depth > 5) return null;
1512
+ const children = node.childNodes;
1513
+ if (!children) return null;
1514
+ for (let i = 0; i < children.length; i++) {
1515
+ const child = children[i];
1516
+ if (child.nodeType !== 1) continue;
1517
+ const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1518
+ if (tag === targetTag) return child;
1519
+ const found = findDescendant(child, targetTag, depth + 1);
1520
+ if (found) return found;
1395
1521
  }
1396
- const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/);
1397
- return sectionFiles.map((f) => f.name).sort(_chunkITJIALN5cjs.compareSectionPaths);
1522
+ return null;
1398
1523
  }
1399
- function parseSectionPathsFromManifest(xml) {
1400
- const parser = createXmlParser();
1401
- const doc = parser.parseFromString(_chunkITJIALN5cjs.stripDtd.call(void 0, xml), "text/xml");
1402
- const items = doc.getElementsByTagName("opf:item");
1403
- const spine = doc.getElementsByTagName("opf:itemref");
1404
- const idToHref = /* @__PURE__ */ new Map();
1405
- for (let i = 0; i < items.length; i++) {
1406
- const item = items[i];
1407
- const id = item.getAttribute("id") || "";
1408
- const href = _chunkITJIALN5cjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
1409
- if (id && href) idToHref.set(id, href);
1410
- }
1411
- if (spine.length > 0) {
1412
- const ordered = [];
1413
- for (let i = 0; i < spine.length; i++) {
1414
- const href = idToHref.get(spine[i].getAttribute("idref") || "");
1415
- if (href) ordered.push(href);
1524
+ function extractDrawTextBlocks(drawTextNode, blocks, ctx) {
1525
+ const children = drawTextNode.childNodes;
1526
+ if (!children) return;
1527
+ for (let i = 0; i < children.length; i++) {
1528
+ const child = children[i];
1529
+ if (child.nodeType !== 1) continue;
1530
+ const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1531
+ if (tag === "subList" || tag === "p" || tag === "para") {
1532
+ if (tag === "subList") {
1533
+ extractDrawTextBlocks(child, blocks, ctx);
1534
+ } else {
1535
+ const info = extractParagraphInfo(child, ctx.styleMap, ctx);
1536
+ let text = info.text.trim();
1537
+ if (text) {
1538
+ const ph = resolveParaHeading(child, ctx);
1539
+ if (_optionalChain([ph, 'optionalAccess', _30 => _30.prefix])) text = ph.prefix + " " + text;
1540
+ const block = { type: "paragraph", text, style: _nullishCoalesce(info.style, () => ( void 0)), pageNumber: ctx.sectionNum };
1541
+ if (info.href) block.href = info.href;
1542
+ if (info.footnote) block.footnoteText = info.footnote;
1543
+ blocks.push(block);
1544
+ }
1545
+ walkParagraphChildren(child, blocks, null, [], ctx);
1546
+ }
1416
1547
  }
1417
- if (ordered.length > 0) return ordered;
1418
1548
  }
1419
- return Array.from(idToHref.values()).sort(_chunkITJIALN5cjs.compareSectionPaths);
1420
1549
  }
1421
- function detectHwpxHeadings(blocks, styleMap) {
1422
- if (blocks.some((b) => b.type === "heading")) return;
1423
- let baseFontSize = 0;
1424
- const sizeFreq = /* @__PURE__ */ new Map();
1425
- for (const b of blocks) {
1426
- if (_optionalChain([b, 'access', _23 => _23.style, 'optionalAccess', _24 => _24.fontSize])) {
1427
- sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1);
1428
- }
1429
- }
1430
- let maxCount = 0;
1431
- for (const [size, count] of sizeFreq) {
1432
- if (count > maxCount) {
1433
- maxCount = count;
1434
- baseFontSize = size;
1435
- }
1436
- }
1437
- for (const block of blocks) {
1438
- if (block.type !== "paragraph" || !block.text) continue;
1439
- const text = block.text.trim();
1440
- if (text.length === 0 || text.length > 200 || /^\d+$/.test(text)) continue;
1441
- let level = 0;
1442
- if (baseFontSize > 0 && _optionalChain([block, 'access', _25 => _25.style, 'optionalAccess', _26 => _26.fontSize])) {
1443
- const ratio = block.style.fontSize / baseFontSize;
1444
- if (ratio >= _chunkITJIALN5cjs.HEADING_RATIO_H1) level = 1;
1445
- else if (ratio >= _chunkITJIALN5cjs.HEADING_RATIO_H2) level = 2;
1446
- else if (ratio >= _chunkITJIALN5cjs.HEADING_RATIO_H3) level = 3;
1447
- }
1448
- const compactText = text.replace(/\s+/g, "");
1449
- if (/^제\d+[조장절편]/.test(compactText) && text.length <= 50) {
1450
- if (level === 0) level = 3;
1451
- }
1452
- if (level > 0) {
1453
- block.type = "heading";
1454
- block.level = level;
1455
- }
1456
- }
1457
- }
1458
- function buildTableWithCellMeta(state) {
1459
- const table = _chunkITJIALN5cjs.buildTable.call(void 0, state.rows);
1460
- if (state.caption) table.caption = state.caption;
1461
- const anchors = [];
1462
- {
1463
- const covered = /* @__PURE__ */ new Set();
1464
- for (let r = 0; r < table.rows; r++) {
1465
- for (let c = 0; c < table.cols; c++) {
1466
- if (covered.has(`${r},${c}`)) continue;
1467
- const cell = _optionalChain([table, 'access', _27 => _27.cells, 'access', _28 => _28[r], 'optionalAccess', _29 => _29[c]]);
1468
- if (!cell) continue;
1469
- for (let dr = 0; dr < cell.rowSpan; dr++) {
1470
- for (let dc = 0; dc < cell.colSpan; dc++) {
1471
- if (dr === 0 && dc === 0) continue;
1472
- if (r + dr < table.rows && c + dc < table.cols) covered.add(`${r + dr},${c + dc}`);
1473
- }
1474
- }
1475
- anchors.push(cell);
1476
- c += cell.colSpan - 1;
1477
- }
1478
- }
1479
- }
1480
- const srcCount = state.rows.reduce((s, r) => s + r.length, 0);
1481
- const ordinalReliable = anchors.length === srcCount;
1482
- const claimed = /* @__PURE__ */ new Set();
1483
- let flatIdx = -1;
1484
- for (const row of state.rows) {
1485
- for (const src of row) {
1486
- flatIdx++;
1487
- const needsBlocks = src.hasStructure && src.blocks && src.blocks.length > 0;
1488
- if (!needsBlocks && !src.isHeader) continue;
1489
- let target;
1490
- const trimmed = src.text.trim();
1491
- if (src.rowAddr !== void 0 && src.colAddr !== void 0) {
1492
- const cand = _optionalChain([table, 'access', _30 => _30.cells, 'access', _31 => _31[src.rowAddr], 'optionalAccess', _32 => _32[src.colAddr]]);
1493
- if (cand && cand.text === trimmed && !claimed.has(cand)) target = cand;
1494
- }
1495
- if (!target) {
1496
- outer: for (const irRow of table.cells) {
1497
- for (const cand of irRow) {
1498
- if (!claimed.has(cand) && cand.text === trimmed && cand.colSpan === src.colSpan && cand.rowSpan === src.rowSpan) {
1499
- target = cand;
1500
- break outer;
1501
- }
1502
- }
1503
- }
1504
- }
1505
- if (!target && ordinalReliable) {
1506
- const cand = anchors[flatIdx];
1507
- if (cand && !claimed.has(cand)) target = cand;
1508
- }
1509
- if (!target) continue;
1510
- claimed.add(target);
1511
- if (needsBlocks) target.blocks = src.blocks;
1512
- if (src.isHeader) target.isHeader = true;
1513
- }
1514
- }
1515
- return table;
1516
- }
1517
- function completeTable(newTable, tableStack, blocks, ctx) {
1518
- const parentTable = tableStack.length > 0 ? tableStack.pop() : null;
1519
- if (newTable.rows.length === 0) {
1520
- if (newTable.caption) blocks.push({ type: "paragraph", text: newTable.caption, pageNumber: ctx.sectionNum });
1521
- return parentTable;
1522
- }
1523
- const ir = buildTableWithCellMeta(newTable);
1524
- const block = { type: "table", table: ir, pageNumber: ctx.sectionNum };
1525
- if (_optionalChain([parentTable, 'optionalAccess', _33 => _33.cell])) {
1526
- const cell = parentTable.cell;
1527
- (cell.blocks ??= []).push(block);
1528
- cell.hasStructure = true;
1529
- let flat = _chunkITJIALN5cjs.convertTableToText.call(void 0, newTable.rows);
1530
- if (newTable.caption) flat = newTable.caption + (flat ? "\n" + flat : "");
1531
- if (flat) cell.text += (cell.text ? "\n" : "") + flat;
1532
- } else {
1533
- blocks.push(block);
1534
- }
1535
- return parentTable;
1536
- }
1537
- function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1538
- const parser = createXmlParser(warnings);
1539
- const doc = parser.parseFromString(_chunkITJIALN5cjs.stripDtd.call(void 0, xml), "text/xml");
1540
- if (!doc.documentElement) return [];
1541
- const ctx = { styleMap, warnings, sectionNum, shared: _nullishCoalesce(shared, () => ( createSectionShared())) };
1542
- ctx.shared.track.deleteDepth = 0;
1543
- for (const tagName of ["hp:secPr", "secPr"]) {
1544
- const els = doc.getElementsByTagName(tagName);
1545
- if (els.length > 0) {
1546
- const v = els[0].getAttribute("outlineShapeIDRef");
1547
- if (v) ctx.outlineNumId = v;
1548
- break;
1549
- }
1550
- }
1551
- const blocks = [];
1552
- walkSection(doc.documentElement, blocks, null, [], ctx);
1553
- return blocks;
1554
- }
1555
- function extractImageRef(el) {
1556
- const children = el.childNodes;
1557
- if (!children) return null;
1558
- for (let i = 0; i < children.length; i++) {
1559
- const child = children[i];
1560
- if (child.nodeType !== 1) continue;
1561
- const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1562
- if (tag === "imgRect" || tag === "img" || tag === "imgClip") {
1563
- const ref = child.getAttribute("binaryItemIDRef") || child.getAttribute("href") || "";
1564
- if (ref) return ref;
1565
- }
1566
- const nested = extractImageRef(child);
1567
- if (nested) return nested;
1568
- }
1569
- const directRef = el.getAttribute("binaryItemIDRef") || "";
1570
- if (directRef) return directRef;
1571
- return null;
1572
- }
1573
- function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1574
- if (depth > MAX_XML_DEPTH) return;
1575
- const children = node.childNodes;
1576
- if (!children) return;
1577
- for (let i = 0; i < children.length; i++) {
1578
- const el = children[i];
1579
- if (el.nodeType !== 1) continue;
1580
- const tag = el.tagName || el.localName || "";
1581
- const localTag = tag.replace(/^[^:]+:/, "");
1582
- switch (localTag) {
1583
- case "tbl": {
1584
- if (tableCtx) tableStack.push(tableCtx);
1585
- const newTable = { rows: [], currentRow: [], cell: null };
1586
- walkSection(el, blocks, newTable, tableStack, ctx, depth + 1);
1587
- tableCtx = completeTable(newTable, tableStack, blocks, ctx);
1588
- break;
1589
- }
1590
- // 표/도표 캡션 — IRTable.caption으로 보존 (v3.0, 기존 무음 드롭 수정)
1591
- case "caption":
1592
- if (tableCtx) {
1593
- const capText = collectSubListText(el, ctx);
1594
- if (capText) tableCtx.caption = (tableCtx.caption ? tableCtx.caption + "\n" : "") + capText;
1595
- }
1596
- break;
1597
- case "tr":
1598
- if (tableCtx) {
1599
- tableCtx.currentRow = [];
1600
- walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1601
- if (tableCtx.currentRow.length > 0) tableCtx.rows.push(tableCtx.currentRow);
1602
- tableCtx.currentRow = [];
1603
- }
1604
- break;
1605
- case "tc":
1606
- if (tableCtx) {
1607
- tableCtx.cell = { text: "", colSpan: 1, rowSpan: 1 };
1608
- if (el.getAttribute("header") === "1" || el.getAttribute("header") === "true") tableCtx.cell.isHeader = true;
1609
- walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1610
- if (tableCtx.cell) {
1611
- tableCtx.currentRow.push(tableCtx.cell);
1612
- tableCtx.cell = null;
1613
- }
1614
- }
1615
- break;
1616
- case "cellAddr":
1617
- if (_optionalChain([tableCtx, 'optionalAccess', _34 => _34.cell])) {
1618
- const ca = parseInt(el.getAttribute("colAddr") || "", 10);
1619
- const ra = parseInt(el.getAttribute("rowAddr") || "", 10);
1620
- if (!isNaN(ca)) tableCtx.cell.colAddr = ca;
1621
- if (!isNaN(ra)) tableCtx.cell.rowAddr = ra;
1622
- }
1623
- break;
1624
- case "cellSpan":
1625
- if (_optionalChain([tableCtx, 'optionalAccess', _35 => _35.cell])) {
1626
- const rawCs = parseInt(el.getAttribute("colSpan") || "1", 10);
1627
- const cs = isNaN(rawCs) ? 1 : rawCs;
1628
- const rawRs = parseInt(el.getAttribute("rowSpan") || "1", 10);
1629
- const rs = isNaN(rawRs) ? 1 : rawRs;
1630
- tableCtx.cell.colSpan = clampSpan(cs, _chunkITJIALN5cjs.MAX_COLS);
1631
- tableCtx.cell.rowSpan = clampSpan(rs, _chunkITJIALN5cjs.MAX_ROWS);
1632
- }
1633
- break;
1634
- case "p": {
1635
- const { text: rawText, href, footnote, style } = extractParagraphInfo(el, ctx.styleMap, ctx);
1636
- let text = rawText;
1637
- let headingLevel;
1638
- if (text) {
1639
- const ph = resolveParaHeading(el, ctx);
1640
- if (_optionalChain([ph, 'optionalAccess', _36 => _36.prefix])) text = ph.prefix + " " + text;
1641
- headingLevel = _optionalChain([ph, 'optionalAccess', _37 => _37.headingLevel]);
1642
- }
1643
- if (text) {
1644
- if (_optionalChain([tableCtx, 'optionalAccess', _38 => _38.cell])) {
1645
- const cell = tableCtx.cell;
1646
- if (footnote) text += ` (\uC8FC: ${footnote})`;
1647
- cell.text += (cell.text ? "\n" : "") + text;
1648
- (cell.blocks ??= []).push({ type: "paragraph", text, pageNumber: ctx.sectionNum });
1649
- } else if (!tableCtx) {
1650
- const block = { type: headingLevel ? "heading" : "paragraph", text, pageNumber: ctx.sectionNum };
1651
- if (headingLevel) block.level = headingLevel;
1652
- if (style) block.style = style;
1653
- if (href) block.href = href;
1654
- if (footnote) block.footnoteText = footnote;
1655
- blocks.push(block);
1656
- } else {
1657
- blocks.push({ type: "paragraph", text, pageNumber: ctx.sectionNum });
1658
- }
1659
- }
1660
- tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1661
- break;
1662
- }
1663
- // 이미지/그림/글상자 — 이미지·텍스트·캡션 병행 추출
1664
- case "pic":
1665
- case "shape":
1666
- case "drawingObject": {
1667
- if (_optionalChain([tableCtx, 'optionalAccess', _39 => _39.cell])) {
1668
- const sink = [];
1669
- handleShape(el, sink, ctx);
1670
- mergeBlocksIntoCell(tableCtx.cell, sink);
1671
- } else {
1672
- handleShape(el, blocks, ctx);
1673
- }
1674
- break;
1675
- }
1676
- // 메모 — 본문 혼입 차단 (v3.0)
1677
- case "memogroup":
1678
- case "memo": {
1679
- if (ctx.warnings && extractTextFromNode(el)) {
1680
- ctx.warnings.push({ page: ctx.sectionNum, message: "\uBA54\uBAA8 \uD14D\uC2A4\uD2B8 \uBCF8\uBB38 \uC81C\uC678: memogroup", code: "HIDDEN_TEXT_FILTERED" });
1681
- }
1682
- break;
1683
- }
1684
- default:
1685
- walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1);
1686
- break;
1687
- }
1688
- }
1689
- }
1690
- function handleShape(el, sink, ctx) {
1691
- const imgRef = extractImageRef(el);
1692
- const drawTextChild = findDescendant(el, "drawText");
1693
- if (imgRef) {
1694
- const block = { type: "image", text: imgRef, pageNumber: ctx.sectionNum };
1695
- const alt = userShapeComment(el);
1696
- if (alt) block.footnoteText = alt;
1697
- sink.push(block);
1698
- }
1699
- if (drawTextChild) {
1700
- extractDrawTextBlocks(drawTextChild, sink, ctx);
1701
- }
1702
- const capEl = findChildByLocalName(el, "caption");
1703
- if (capEl) {
1704
- const capText = collectSubListText(capEl, ctx);
1705
- if (capText) sink.push({ type: "paragraph", text: capText, pageNumber: ctx.sectionNum });
1706
- }
1707
- if (!imgRef && !drawTextChild && ctx.warnings && ctx.sectionNum) {
1708
- const localTag = (el.tagName || el.localName || "").replace(/^[^:]+:/, "");
1709
- ctx.warnings.push({ page: ctx.sectionNum, message: `\uC2A4\uD0B5\uB41C \uC694\uC18C: ${localTag}`, code: "SKIPPED_IMAGE" });
1710
- }
1711
- }
1712
- function userShapeComment(el) {
1713
- const commentEl = findChildByLocalName(el, "shapeComment");
1714
- if (!commentEl) return void 0;
1715
- const text = extractTextFromNode(commentEl);
1716
- if (!text) return void 0;
1717
- if (/^그림입니다/.test(text)) return void 0;
1718
- if (/^(?:모서리가 둥근 |둥근 )?[^\n]{1,20}입니다\.?$/.test(text)) return void 0;
1719
- return text;
1720
- }
1721
- function mergeBlocksIntoCell(cell, sink) {
1722
- for (const b of sink) {
1723
- if ((b.type === "paragraph" || b.type === "heading") && b.text) {
1724
- cell.text += (cell.text ? "\n" : "") + b.text;
1725
- (cell.blocks ??= []).push(b);
1726
- } else if (b.type === "image" || b.type === "table") {
1727
- if (b.type === "image" && b.text) {
1728
- cell.text += (cell.text ? "\n" : "") + `![image](${b.text})`;
1729
- }
1730
- ;
1731
- (cell.blocks ??= []).push(b);
1732
- cell.hasStructure = true;
1733
- }
1734
- }
1735
- }
1736
- function collectSubListText(el, ctx, depth = 0) {
1737
- if (depth > 10) return "";
1738
- const parts = [];
1739
- const children = el.childNodes;
1740
- if (!children) return "";
1741
- for (let i = 0; i < children.length; i++) {
1742
- const ch = children[i];
1743
- if (ch.nodeType !== 1) continue;
1744
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
1745
- if (tag === "p" || tag === "para") {
1746
- const t = extractParagraphInfo(ch, ctx.styleMap, ctx).text;
1747
- if (t) parts.push(t);
1748
- } else if (tag === "tbl") {
1749
- continue;
1750
- } else {
1751
- const t = collectSubListText(ch, ctx, depth + 1);
1752
- if (t) parts.push(t);
1753
- }
1754
- }
1755
- return parts.join("\n").trim();
1756
- }
1757
- function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1758
- if (depth > MAX_XML_DEPTH) return tableCtx;
1759
- const children = node.childNodes;
1760
- if (!children) return tableCtx;
1761
- const walkChildren = (parent, d) => {
1762
- if (d > MAX_XML_DEPTH) return;
1763
- const kids2 = parent.childNodes;
1764
- if (!kids2) return;
1765
- for (let i = 0; i < kids2.length; i++) {
1766
- const el = kids2[i];
1767
- if (el.nodeType !== 1) continue;
1768
- const tag = el.tagName || el.localName || "";
1769
- const localTag = tag.replace(/^[^:]+:/, "");
1770
- if (localTag === "tbl") {
1771
- if (tableCtx) tableStack.push(tableCtx);
1772
- const newTable = { rows: [], currentRow: [], cell: null };
1773
- walkSection(el, blocks, newTable, tableStack, ctx, d + 1);
1774
- tableCtx = completeTable(newTable, tableStack, blocks, ctx);
1775
- } else if (localTag === "pic" || localTag === "shape" || localTag === "drawingObject") {
1776
- if (_optionalChain([tableCtx, 'optionalAccess', _40 => _40.cell])) {
1777
- const sink = [];
1778
- handleShape(el, sink, ctx);
1779
- mergeBlocksIntoCell(tableCtx.cell, sink);
1780
- } else {
1781
- handleShape(el, blocks, ctx);
1782
- }
1783
- } else if (localTag === "drawText") {
1784
- if (_optionalChain([tableCtx, 'optionalAccess', _41 => _41.cell])) {
1785
- const sink = [];
1786
- extractDrawTextBlocks(el, sink, ctx);
1787
- mergeBlocksIntoCell(tableCtx.cell, sink);
1788
- } else {
1789
- extractDrawTextBlocks(el, blocks, ctx);
1790
- }
1791
- } else if (localTag === "r" || localTag === "run" || localTag === "ctrl" || localTag === "rect" || localTag === "ellipse" || localTag === "polygon" || localTag === "line" || localTag === "arc" || localTag === "curve" || localTag === "connectLine" || localTag === "container") {
1792
- walkChildren(el, d + 1);
1793
- }
1794
- }
1795
- };
1796
- walkChildren(node, depth);
1797
- return tableCtx;
1798
- }
1799
- function findDescendant(node, targetTag, depth = 0) {
1800
- if (depth > 5) return null;
1801
- const children = node.childNodes;
1802
- if (!children) return null;
1803
- for (let i = 0; i < children.length; i++) {
1804
- const child = children[i];
1805
- if (child.nodeType !== 1) continue;
1806
- const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1807
- if (tag === targetTag) return child;
1808
- const found = findDescendant(child, targetTag, depth + 1);
1809
- if (found) return found;
1810
- }
1811
- return null;
1812
- }
1813
- function extractDrawTextBlocks(drawTextNode, blocks, ctx) {
1814
- const children = drawTextNode.childNodes;
1815
- if (!children) return;
1816
- for (let i = 0; i < children.length; i++) {
1817
- const child = children[i];
1818
- if (child.nodeType !== 1) continue;
1819
- const tag = (child.tagName || child.localName || "").replace(/^[^:]+:/, "");
1820
- if (tag === "subList" || tag === "p" || tag === "para") {
1821
- if (tag === "subList") {
1822
- extractDrawTextBlocks(child, blocks, ctx);
1823
- } else {
1824
- const info = extractParagraphInfo(child, ctx.styleMap, ctx);
1825
- let text = info.text.trim();
1826
- if (text) {
1827
- const ph = resolveParaHeading(child, ctx);
1828
- if (_optionalChain([ph, 'optionalAccess', _42 => _42.prefix])) text = ph.prefix + " " + text;
1829
- const block = { type: "paragraph", text, style: _nullishCoalesce(info.style, () => ( void 0)), pageNumber: ctx.sectionNum };
1830
- if (info.href) block.href = info.href;
1831
- if (info.footnote) block.footnoteText = info.footnote;
1832
- blocks.push(block);
1833
- }
1834
- walkParagraphChildren(child, blocks, null, [], ctx);
1835
- }
1836
- }
1837
- }
1838
- }
1839
- function extractHyperlinkHref(fieldBegin) {
1840
- if ((fieldBegin.getAttribute("type") || "").toUpperCase() !== "HYPERLINK") return void 0;
1841
- const params = findChildByLocalName(fieldBegin, "parameters");
1842
- if (!params) return void 0;
1843
- const children = params.childNodes;
1844
- if (!children) return void 0;
1845
- for (let i = 0; i < children.length; i++) {
1846
- const ch = children[i];
1847
- if (ch.nodeType !== 1) continue;
1848
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
1849
- if (tag !== "stringParam" || ch.getAttribute("name") !== "Path") continue;
1850
- let url = (ch.textContent || "").trim();
1851
- if (!url) continue;
1852
- url = url.replace(/^https?:\/\/(?=https?:\/\/)/i, "");
1853
- const safe = _chunkITJIALN5cjs.sanitizeHref.call(void 0, url);
1854
- if (safe) return safe;
1550
+ function extractHyperlinkHref(fieldBegin) {
1551
+ if ((fieldBegin.getAttribute("type") || "").toUpperCase() !== "HYPERLINK") return void 0;
1552
+ const params = findChildByLocalName(fieldBegin, "parameters");
1553
+ if (!params) return void 0;
1554
+ const children = params.childNodes;
1555
+ if (!children) return void 0;
1556
+ for (let i = 0; i < children.length; i++) {
1557
+ const ch = children[i];
1558
+ if (ch.nodeType !== 1) continue;
1559
+ const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
1560
+ if (tag !== "stringParam" || ch.getAttribute("name") !== "Path") continue;
1561
+ let url = (ch.textContent || "").trim();
1562
+ if (!url) continue;
1563
+ url = url.replace(/^https?:\/\/(?=https?:\/\/)/i, "");
1564
+ const safe = _chunkLFCS3UVGcjs.sanitizeHref.call(void 0, url);
1565
+ if (safe) return safe;
1855
1566
  }
1856
1567
  return void 0;
1857
1568
  }
1858
1569
  function isInDeletedRange(ctx) {
1859
- return (_nullishCoalesce(_optionalChain([ctx, 'optionalAccess', _43 => _43.shared, 'access', _44 => _44.track, 'access', _45 => _45.deleteDepth]), () => ( 0))) > 0;
1570
+ return (_nullishCoalesce(_optionalChain([ctx, 'optionalAccess', _31 => _31.shared, 'access', _32 => _32.track, 'access', _33 => _33.deleteDepth]), () => ( 0))) > 0;
1860
1571
  }
1861
1572
  function extractParagraphInfo(para, styleMap, ctx) {
1862
1573
  let text = "";
@@ -1910,7 +1621,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1910
1621
  // 삽입분은 최종본에 포함
1911
1622
  // 숨은 설명 — 본문 혼입 차단
1912
1623
  case "hiddenComment": {
1913
- if (_optionalChain([ctx, 'optionalAccess', _46 => _46.warnings]) && extractTextFromNode(k)) {
1624
+ if (_optionalChain([ctx, 'optionalAccess', _34 => _34.warnings]) && extractTextFromNode(k)) {
1914
1625
  ctx.warnings.push({ page: ctx.sectionNum, message: "\uC228\uC740 \uC124\uBA85 \uD14D\uC2A4\uD2B8 \uC81C\uC678: hiddenComment", code: "HIDDEN_TEXT_FILTERED" });
1915
1626
  }
1916
1627
  break;
@@ -1927,7 +1638,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1927
1638
  break;
1928
1639
  // 미지원 요소 — 텍스트를 가졌으면 무음 손실 대신 경고
1929
1640
  default: {
1930
- if (_optionalChain([ctx, 'optionalAccess', _47 => _47.warnings]) && extractTextFromNode(k)) {
1641
+ if (_optionalChain([ctx, 'optionalAccess', _35 => _35.warnings]) && extractTextFromNode(k)) {
1931
1642
  ctx.warnings.push({ page: ctx.sectionNum, message: `\uBBF8\uC9C0\uC6D0 \uC81C\uC5B4 \uC694\uC18C\uC758 \uD14D\uC2A4\uD2B8 \uC190\uC2E4: ${ktag}`, code: "UNSUPPORTED_ELEMENT" });
1932
1643
  }
1933
1644
  }
@@ -1944,7 +1655,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1944
1655
  if (isInDeletedRange(ctx)) {
1945
1656
  if (t && ctx && !ctx.shared.track.warned) {
1946
1657
  ctx.shared.track.warned = true;
1947
- _optionalChain([ctx, 'access', _48 => _48.warnings, 'optionalAccess', _49 => _49.push, 'call', _50 => _50({ page: ctx.sectionNum, message: "\uBCC0\uACBD\uCD94\uC801 \uC0AD\uC81C \uD14D\uC2A4\uD2B8 \uCD9C\uB825 \uC81C\uC678", code: "HIDDEN_TEXT_FILTERED" })]);
1658
+ _optionalChain([ctx, 'access', _36 => _36.warnings, 'optionalAccess', _37 => _37.push, 'call', _38 => _38({ page: ctx.sectionNum, message: "\uBCC0\uACBD\uCD94\uC801 \uC0AD\uC81C \uD14D\uC2A4\uD2B8 \uCD9C\uB825 \uC81C\uC678", code: "HIDDEN_TEXT_FILTERED" })]);
1948
1659
  }
1949
1660
  } else {
1950
1661
  text += t;
@@ -1985,7 +1696,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1985
1696
  case "hyperlink": {
1986
1697
  const url = child.getAttribute("url") || child.getAttribute("href") || "";
1987
1698
  if (url) {
1988
- const safe = _chunkITJIALN5cjs.sanitizeHref.call(void 0, url);
1699
+ const safe = _chunkLFCS3UVGcjs.sanitizeHref.call(void 0, url);
1989
1700
  if (safe) href = safe;
1990
1701
  }
1991
1702
  walk(child);
@@ -2050,66 +1761,374 @@ function extractParagraphInfo(para, styleMap, ctx) {
2050
1761
  try {
2051
1762
  const latex = hmlToLatex(raw).trim();
2052
1763
  if (latex) text += " $" + latex + "$ ";
2053
- } catch (e15) {
1764
+ } catch (e12) {
2054
1765
  }
2055
1766
  }
2056
- break;
1767
+ break;
1768
+ }
1769
+ // run 요소에서 charPrIDRef 추출
1770
+ case "r": {
1771
+ const runCharPr = child.getAttribute("charPrIDRef");
1772
+ if (runCharPr && !charPrId) charPrId = runCharPr;
1773
+ walk(child);
1774
+ break;
1775
+ }
1776
+ default:
1777
+ walk(child);
1778
+ break;
1779
+ }
1780
+ }
1781
+ };
1782
+ walk(para);
1783
+ const leaderIdx = text.indexOf("");
1784
+ if (leaderIdx >= 0) text = text.substring(0, leaderIdx);
1785
+ let cleanText = text.replace(/[ \t]+/g, " ").trim();
1786
+ if (/^그림입니다\.?\s*원본\s*그림의\s*(이름|크기)/.test(cleanText)) cleanText = "";
1787
+ cleanText = cleanText.replace(/그림입니다\.?\s*원본\s*그림의\s*(이름|크기)[^\n]*(\n[^\n]*원본\s*그림의\s*(이름|크기)[^\n]*)*/g, "").trim();
1788
+ cleanText = cleanText.replace(/(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\s?개체|묶음\s?개체|글상자|표|그림|OLE\s?개체)\s?입니다\.?/g, "").trim();
1789
+ let style;
1790
+ if (styleMap && charPrId) {
1791
+ const charProp = styleMap.charProperties.get(charPrId);
1792
+ if (charProp) {
1793
+ style = {};
1794
+ if (charProp.fontSize) style.fontSize = charProp.fontSize;
1795
+ if (charProp.bold) style.bold = true;
1796
+ if (charProp.italic) style.italic = true;
1797
+ if (charProp.fontName) style.fontName = charProp.fontName;
1798
+ if (!style.fontSize && !style.bold && !style.italic) style = void 0;
1799
+ }
1800
+ }
1801
+ return { text: cleanText, href, footnote, style };
1802
+ }
1803
+
1804
+ // src/hwpx/images.ts
1805
+ function imageExtToMime(ext) {
1806
+ switch (ext.toLowerCase()) {
1807
+ case "jpg":
1808
+ case "jpeg":
1809
+ return "image/jpeg";
1810
+ case "png":
1811
+ return "image/png";
1812
+ case "gif":
1813
+ return "image/gif";
1814
+ case "bmp":
1815
+ return "image/bmp";
1816
+ case "tif":
1817
+ case "tiff":
1818
+ return "image/tiff";
1819
+ case "wmf":
1820
+ return "image/wmf";
1821
+ case "emf":
1822
+ return "image/emf";
1823
+ case "svg":
1824
+ return "image/svg+xml";
1825
+ default:
1826
+ return "application/octet-stream";
1827
+ }
1828
+ }
1829
+ function mimeToExt(mime) {
1830
+ if (mime.includes("jpeg")) return "jpg";
1831
+ if (mime.includes("png")) return "png";
1832
+ if (mime.includes("gif")) return "gif";
1833
+ if (mime.includes("bmp")) return "bmp";
1834
+ if (mime.includes("tiff")) return "tif";
1835
+ if (mime.includes("wmf")) return "wmf";
1836
+ if (mime.includes("emf")) return "emf";
1837
+ if (mime.includes("svg")) return "svg";
1838
+ return "bin";
1839
+ }
1840
+ function collectImageBlocks(blocks, out, ownerCell, depth = 0) {
1841
+ if (depth > MAX_XML_DEPTH) return;
1842
+ for (const block of blocks) {
1843
+ if (block.type === "image") {
1844
+ out.push({ block, ownerCell });
1845
+ } else if (block.type === "table" && block.table) {
1846
+ for (const row of block.table.cells) {
1847
+ for (const cell of row) {
1848
+ if (_optionalChain([cell, 'access', _39 => _39.blocks, 'optionalAccess', _40 => _40.length])) collectImageBlocks(cell.blocks, out, cell, depth + 1);
1849
+ }
1850
+ }
1851
+ }
1852
+ }
1853
+ }
1854
+ async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
1855
+ const images = [];
1856
+ let imageIndex = 0;
1857
+ const imageBlocks = [];
1858
+ collectImageBlocks(blocks, imageBlocks);
1859
+ const resolved = /* @__PURE__ */ new Map();
1860
+ for (const { block, ownerCell } of imageBlocks) {
1861
+ if (block.type !== "image" || !block.text) continue;
1862
+ const ref = block.text;
1863
+ let img = resolved.get(ref);
1864
+ if (img === void 0) {
1865
+ img = null;
1866
+ const candidates = [
1867
+ `BinData/${ref}`,
1868
+ `Contents/BinData/${ref}`,
1869
+ ref
1870
+ // 절대 경로일 수도 있음
1871
+ ];
1872
+ let resolvedPath = null;
1873
+ if (!ref.includes(".")) {
1874
+ const prefixes = [`BinData/${ref}`, `Contents/BinData/${ref}`];
1875
+ for (const prefix of prefixes) {
1876
+ const match = zip.file(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.[a-zA-Z0-9]+$`));
1877
+ if (match.length > 0) {
1878
+ resolvedPath = match[0].name;
1879
+ break;
1880
+ }
2057
1881
  }
2058
- // run 요소에서 charPrIDRef 추출
2059
- case "r": {
2060
- const runCharPr = child.getAttribute("charPrIDRef");
2061
- if (runCharPr && !charPrId) charPrId = runCharPr;
2062
- walk(child);
1882
+ }
1883
+ const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates;
1884
+ for (const path of allCandidates) {
1885
+ if (_chunkLFCS3UVGcjs.isPathTraversal.call(void 0, path)) continue;
1886
+ const file = zip.file(path);
1887
+ if (!file) continue;
1888
+ try {
1889
+ const data = await file.async("uint8array");
1890
+ decompressed.total += data.length;
1891
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1892
+ const ext = path.includes(".") ? path.split(".").pop() || "png" : "png";
1893
+ const mimeType = imageExtToMime(ext);
1894
+ imageIndex++;
1895
+ const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
1896
+ img = { filename, data, mimeType };
1897
+ images.push(img);
2063
1898
  break;
1899
+ } catch (err) {
1900
+ if (err instanceof _chunkLFCS3UVGcjs.KordocError) throw err;
2064
1901
  }
2065
- default:
2066
- walk(child);
2067
- break;
2068
1902
  }
1903
+ if (!img) _optionalChain([warnings, 'optionalAccess', _41 => _41.push, 'call', _42 => _42({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" })]);
1904
+ resolved.set(ref, img);
2069
1905
  }
2070
- };
2071
- walk(para);
2072
- const leaderIdx = text.indexOf("");
2073
- if (leaderIdx >= 0) text = text.substring(0, leaderIdx);
2074
- let cleanText = text.replace(/[ \t]+/g, " ").trim();
2075
- if (/^그림입니다\.?\s*원본\s*그림의\s*(이름|크기)/.test(cleanText)) cleanText = "";
2076
- cleanText = cleanText.replace(/그림입니다\.?\s*원본\s*그림의\s*(이름|크기)[^\n]*(\n[^\n]*원본\s*그림의\s*(이름|크기)[^\n]*)*/g, "").trim();
2077
- cleanText = cleanText.replace(/(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\s?개체|묶음\s?개체|글상자|표|그림|OLE\s?개체)\s?입니다\.?/g, "").trim();
2078
- let style;
2079
- if (styleMap && charPrId) {
2080
- const charProp = styleMap.charProperties.get(charPrId);
2081
- if (charProp) {
2082
- style = {};
2083
- if (charProp.fontSize) style.fontSize = charProp.fontSize;
2084
- if (charProp.bold) style.bold = true;
2085
- if (charProp.italic) style.italic = true;
2086
- if (charProp.fontName) style.fontName = charProp.fontName;
2087
- if (!style.fontSize && !style.bold && !style.italic) style = void 0;
1906
+ if (!img) {
1907
+ block.type = "paragraph";
1908
+ block.text = `[\uC774\uBBF8\uC9C0: ${ref}]`;
1909
+ if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `[\uC774\uBBF8\uC9C0: ${ref}]`);
1910
+ continue;
2088
1911
  }
1912
+ block.text = img.filename;
1913
+ block.imageData = { data: img.data, mimeType: img.mimeType, filename: ref };
1914
+ if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `![image](${img.filename})`);
2089
1915
  }
2090
- return { text: cleanText, href, footnote, style };
1916
+ return images;
2091
1917
  }
2092
- function findChildByLocalName(parent, name) {
2093
- const children = parent.childNodes;
2094
- if (!children) return null;
2095
- for (let i = 0; i < children.length; i++) {
2096
- const ch = children[i];
2097
- if (ch.nodeType !== 1) continue;
2098
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
2099
- if (tag === name) return ch;
1918
+
1919
+ // src/hwpx/metadata.ts
1920
+
1921
+
1922
+ // src/hwpx/zip-sections.ts
1923
+ var _zlib = require('zlib');
1924
+ function extractFromBrokenZip(buffer) {
1925
+ const data = new Uint8Array(buffer);
1926
+ const view = new DataView(buffer);
1927
+ let pos = 0;
1928
+ const blocks = [];
1929
+ const warnings = [
1930
+ { code: "BROKEN_ZIP_RECOVERY", message: "\uC190\uC0C1\uB41C ZIP \uAD6C\uC870 \u2014 Local File Header \uAE30\uBC18 \uBCF5\uAD6C \uBAA8\uB4DC" }
1931
+ ];
1932
+ let totalDecompressed = 0;
1933
+ let entryCount = 0;
1934
+ let sectionNum = 0;
1935
+ const shared = createSectionShared();
1936
+ while (pos < data.length - 30) {
1937
+ if (data[pos] !== 80 || data[pos + 1] !== 75 || data[pos + 2] !== 3 || data[pos + 3] !== 4) {
1938
+ pos++;
1939
+ while (pos < data.length - 30) {
1940
+ if (data[pos] === 80 && data[pos + 1] === 75 && data[pos + 2] === 3 && data[pos + 3] === 4) break;
1941
+ pos++;
1942
+ }
1943
+ continue;
1944
+ }
1945
+ if (++entryCount > MAX_ZIP_ENTRIES) break;
1946
+ const method = view.getUint16(pos + 8, true);
1947
+ const compSize = view.getUint32(pos + 18, true);
1948
+ const nameLen = view.getUint16(pos + 26, true);
1949
+ const extraLen = view.getUint16(pos + 28, true);
1950
+ if (nameLen > 1024 || extraLen > 65535) {
1951
+ pos += 30 + nameLen + extraLen;
1952
+ continue;
1953
+ }
1954
+ const fileStart = pos + 30 + nameLen + extraLen;
1955
+ if (fileStart + compSize > data.length) break;
1956
+ if (compSize === 0 && method !== 0) {
1957
+ pos = fileStart;
1958
+ continue;
1959
+ }
1960
+ const nameBytes = data.slice(pos + 30, pos + 30 + nameLen);
1961
+ const name = new TextDecoder().decode(nameBytes);
1962
+ if (_chunkLFCS3UVGcjs.isPathTraversal.call(void 0, name)) {
1963
+ pos = fileStart + compSize;
1964
+ continue;
1965
+ }
1966
+ const fileData = data.slice(fileStart, fileStart + compSize);
1967
+ pos = fileStart + compSize;
1968
+ if (!name.toLowerCase().includes("section") || !name.endsWith(".xml")) continue;
1969
+ try {
1970
+ let content;
1971
+ if (method === 0) {
1972
+ content = new TextDecoder().decode(fileData);
1973
+ } else if (method === 8) {
1974
+ const decompressed = _zlib.inflateRawSync.call(void 0, Buffer.from(fileData), { maxOutputLength: MAX_DECOMPRESS_SIZE });
1975
+ content = new TextDecoder().decode(decompressed);
1976
+ } else {
1977
+ continue;
1978
+ }
1979
+ totalDecompressed += content.length * 2;
1980
+ if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
1981
+ sectionNum++;
1982
+ blocks.push(...parseSectionXml(content, void 0, warnings, sectionNum, shared));
1983
+ } catch (e13) {
1984
+ continue;
1985
+ }
2100
1986
  }
2101
- return null;
1987
+ if (blocks.length === 0) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1988
+ applyPageText(blocks, shared);
1989
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
1990
+ return { markdown, blocks, warnings: warnings.length > 0 ? warnings : void 0 };
2102
1991
  }
2103
- function extractTextFromNode(node) {
2104
- let result = "";
2105
- const children = node.childNodes;
2106
- if (!children) return result;
2107
- for (let i = 0; i < children.length; i++) {
2108
- const child = children[i];
2109
- if (child.nodeType === 3) result += child.textContent || "";
2110
- else if (child.nodeType === 1) result += extractTextFromNode(child);
1992
+ async function resolveSectionPaths(zip) {
1993
+ const manifestPaths = ["Contents/content.hpf", "content.hpf"];
1994
+ for (const mp of manifestPaths) {
1995
+ const mpLower = mp.toLowerCase();
1996
+ const file = zip.file(mp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === mpLower) || null;
1997
+ if (!file) continue;
1998
+ const xml = await file.async("text");
1999
+ const paths = parseSectionPathsFromManifest(xml);
2000
+ if (paths.length > 0) return paths;
2111
2001
  }
2112
- return result.trim();
2002
+ const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/);
2003
+ return sectionFiles.map((f) => f.name).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
2004
+ }
2005
+ function parseSectionPathsFromManifest(xml) {
2006
+ const parser = createXmlParser();
2007
+ const doc = parser.parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, xml), "text/xml");
2008
+ const items = doc.getElementsByTagName("opf:item");
2009
+ const spine = doc.getElementsByTagName("opf:itemref");
2010
+ const idToHref = /* @__PURE__ */ new Map();
2011
+ for (let i = 0; i < items.length; i++) {
2012
+ const item = items[i];
2013
+ const id = item.getAttribute("id") || "";
2014
+ const href = _chunkLFCS3UVGcjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
2015
+ if (id && href) idToHref.set(id, href);
2016
+ }
2017
+ if (spine.length > 0) {
2018
+ const ordered = [];
2019
+ for (let i = 0; i < spine.length; i++) {
2020
+ const href = idToHref.get(spine[i].getAttribute("idref") || "");
2021
+ if (href) ordered.push(href);
2022
+ }
2023
+ if (ordered.length > 0) return ordered;
2024
+ }
2025
+ return Array.from(idToHref.values()).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
2026
+ }
2027
+
2028
+ // src/hwpx/metadata.ts
2029
+ async function extractHwpxMetadata(zip, metadata, decompressed) {
2030
+ try {
2031
+ const metaPaths = ["meta.xml", "META-INF/meta.xml", "docProps/core.xml"];
2032
+ for (const mp of metaPaths) {
2033
+ const file = zip.file(mp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === mp.toLowerCase()) || null;
2034
+ if (!file) continue;
2035
+ const xml = await file.async("text");
2036
+ if (decompressed) {
2037
+ decompressed.total += xml.length * 2;
2038
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2039
+ }
2040
+ parseDublinCoreMetadata(xml, metadata);
2041
+ if (metadata.title || metadata.author) return;
2042
+ }
2043
+ } catch (e14) {
2044
+ }
2045
+ }
2046
+ function parseDublinCoreMetadata(xml, metadata) {
2047
+ const parser = createXmlParser();
2048
+ const doc = parser.parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, xml), "text/xml");
2049
+ if (!doc.documentElement) return;
2050
+ const getText = (tagNames) => {
2051
+ for (const tag of tagNames) {
2052
+ const els = doc.getElementsByTagName(tag);
2053
+ if (els.length > 0) {
2054
+ const text = _optionalChain([els, 'access', _43 => _43[0], 'access', _44 => _44.textContent, 'optionalAccess', _45 => _45.trim, 'call', _46 => _46()]);
2055
+ if (text) return text;
2056
+ }
2057
+ }
2058
+ return void 0;
2059
+ };
2060
+ metadata.title = metadata.title || getText(["dc:title", "title"]);
2061
+ metadata.author = metadata.author || getText(["dc:creator", "creator", "cp:lastModifiedBy"]);
2062
+ metadata.description = metadata.description || getText(["dc:description", "description", "dc:subject", "subject"]);
2063
+ metadata.createdAt = metadata.createdAt || getText(["dcterms:created", "meta:creation-date"]);
2064
+ metadata.modifiedAt = metadata.modifiedAt || getText(["dcterms:modified", "meta:date"]);
2065
+ const keywords = getText(["dc:keyword", "cp:keywords", "meta:keyword"]);
2066
+ if (keywords && !metadata.keywords) {
2067
+ metadata.keywords = keywords.split(/[,;]/).map((k) => k.trim()).filter(Boolean);
2068
+ }
2069
+ }
2070
+
2071
+ // src/hwpx/parser.ts
2072
+ async function parseHwpxDocument(buffer, options) {
2073
+ _chunkLFCS3UVGcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
2074
+ let zip;
2075
+ try {
2076
+ zip = await _jszip2.default.loadAsync(buffer);
2077
+ } catch (e15) {
2078
+ return extractFromBrokenZip(buffer);
2079
+ }
2080
+ const actualEntryCount = Object.keys(zip.files).length;
2081
+ if (actualEntryCount > MAX_ZIP_ENTRIES) {
2082
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP \uC5D4\uD2B8\uB9AC \uC218 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2083
+ }
2084
+ const manifestFile = zip.file("META-INF/manifest.xml");
2085
+ if (manifestFile) {
2086
+ const manifestXml = await manifestFile.async("text");
2087
+ if (isEncryptedHwpx(manifestXml)) {
2088
+ if (isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _47 => _47.filePath])) {
2089
+ const { pages, pageCount, warnings: warnings2 } = extractTextViaCom(options.filePath);
2090
+ if (pages.some((p) => p && p.trim().length > 0)) {
2091
+ return comResultToParseResult(pages, pageCount, warnings2);
2092
+ }
2093
+ }
2094
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("DRM \uC554\uD638\uD654\uB41C HWPX \uD30C\uC77C\uC785\uB2C8\uB2E4. Windows + \uD55C\uCEF4 \uC624\uD53C\uC2A4 \uC124\uCE58 \uC2DC \uC790\uB3D9 \uCD94\uCD9C\uB429\uB2C8\uB2E4.");
2095
+ }
2096
+ }
2097
+ const decompressed = { total: 0 };
2098
+ const metadata = {};
2099
+ await extractHwpxMetadata(zip, metadata, decompressed);
2100
+ const styleMap = await extractHwpxStyles(zip, decompressed);
2101
+ const warnings = [];
2102
+ const sectionPaths = await resolveSectionPaths(zip);
2103
+ if (sectionPaths.length === 0) throw new (0, _chunkLFCS3UVGcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
2104
+ metadata.pageCount = sectionPaths.length;
2105
+ const pageFilter = _optionalChain([options, 'optionalAccess', _48 => _48.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sectionPaths.length) : null;
2106
+ const totalTarget = pageFilter ? pageFilter.size : sectionPaths.length;
2107
+ const blocks = [];
2108
+ const shared = createSectionShared();
2109
+ let parsedSections = 0;
2110
+ for (let si = 0; si < sectionPaths.length; si++) {
2111
+ if (pageFilter && !pageFilter.has(si + 1)) continue;
2112
+ const file = zip.file(sectionPaths[si]);
2113
+ if (!file) continue;
2114
+ try {
2115
+ const xml = await file.async("text");
2116
+ decompressed.total += xml.length * 2;
2117
+ if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
2118
+ blocks.push(...parseSectionXml(xml, styleMap, warnings, si + 1, shared));
2119
+ parsedSections++;
2120
+ _optionalChain([options, 'optionalAccess', _49 => _49.onProgress, 'optionalCall', _50 => _50(parsedSections, totalTarget)]);
2121
+ } catch (secErr) {
2122
+ if (secErr instanceof _chunkLFCS3UVGcjs.KordocError) throw secErr;
2123
+ warnings.push({ page: si + 1, message: `\uC139\uC158 ${si + 1} \uD30C\uC2F1 \uC2E4\uD328: ${secErr instanceof Error ? secErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
2124
+ }
2125
+ }
2126
+ applyPageText(blocks, shared);
2127
+ const images = await extractImagesFromZip(zip, blocks, decompressed, warnings);
2128
+ detectHwpxHeadings(blocks, styleMap);
2129
+ const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
2130
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
2131
+ return { markdown, blocks, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
2113
2132
  }
2114
2133
 
2115
2134
  // src/hwp5/record.ts
@@ -2175,7 +2194,7 @@ function decompressStream(data) {
2175
2194
  return _zlib.inflateRawSync.call(void 0, data, opts);
2176
2195
  }
2177
2196
  function parseFileHeader(data) {
2178
- if (data.length < 40) throw new (0, _chunkITJIALN5cjs.KordocError)("FileHeader\uAC00 \uB108\uBB34 \uC9E7\uC2B5\uB2C8\uB2E4 (\uCD5C\uC18C 40\uBC14\uC774\uD2B8)");
2197
+ if (data.length < 40) throw new (0, _chunkLFCS3UVGcjs.KordocError)("FileHeader\uAC00 \uB108\uBB34 \uC9E7\uC2B5\uB2C8\uB2E4 (\uCD5C\uC18C 40\uBC14\uC774\uD2B8)");
2179
2198
  const sig = data.subarray(0, 32).toString("utf8").replace(/\0+$/, "");
2180
2199
  return {
2181
2200
  signature: sig,
@@ -3709,7 +3728,7 @@ function parseHwp5Document(buffer, options) {
3709
3728
  lenientCfb = parseLenientCfb(buffer);
3710
3729
  warnings.push({ message: "\uC190\uC0C1\uB41C CFB \uCEE8\uD14C\uC774\uB108 \u2014 lenient \uBAA8\uB4DC\uB85C \uBCF5\uAD6C", code: "LENIENT_CFB_RECOVERY" });
3711
3730
  } catch (e21) {
3712
- throw new (0, _chunkITJIALN5cjs.KordocError)("CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328 (strict \uBC0F lenient \uBAA8\uB450)");
3731
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328 (strict \uBC0F lenient \uBAA8\uB450)");
3713
3732
  }
3714
3733
  }
3715
3734
  const findStream = (path) => {
@@ -3720,11 +3739,11 @@ function parseHwp5Document(buffer, options) {
3720
3739
  return lenientCfb.findStream(path);
3721
3740
  };
3722
3741
  const headerData = findStream("/FileHeader");
3723
- if (!headerData) throw new (0, _chunkITJIALN5cjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
3742
+ if (!headerData) throw new (0, _chunkLFCS3UVGcjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
3724
3743
  const header = parseFileHeader(headerData);
3725
- if (header.signature !== "HWP Document File") throw new (0, _chunkITJIALN5cjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
3726
- if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunkITJIALN5cjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3727
- if (header.flags & FLAG_DRM) throw new (0, _chunkITJIALN5cjs.KordocError)("DRM \uBCF4\uD638\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3744
+ if (header.signature !== "HWP Document File") throw new (0, _chunkLFCS3UVGcjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
3745
+ if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3746
+ if (header.flags & FLAG_DRM) throw new (0, _chunkLFCS3UVGcjs.KordocError)("DRM \uBCF4\uD638\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3728
3747
  const compressed = (header.flags & FLAG_COMPRESSED) !== 0;
3729
3748
  const distribution = (header.flags & FLAG_DISTRIBUTION) !== 0;
3730
3749
  const metadata = {
@@ -3733,7 +3752,7 @@ function parseHwp5Document(buffer, options) {
3733
3752
  if (cfb) extractHwp5Metadata(cfb, metadata);
3734
3753
  const docInfo = cfb ? parseDocInfoStream(cfb, compressed) : parseDocInfoFromStream(findStream("/DocInfo"), compressed);
3735
3754
  const sections = distribution ? cfb ? findViewTextSections(cfb, compressed) : findViewTextSectionsLenient(lenientCfb, compressed) : cfb ? findSections(cfb) : findSectionsLenient(lenientCfb, compressed);
3736
- if (sections.length === 0) throw new (0, _chunkITJIALN5cjs.KordocError)("\uC139\uC158 \uC2A4\uD2B8\uB9BC\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3755
+ if (sections.length === 0) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uC139\uC158 \uC2A4\uD2B8\uB9BC\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
3737
3756
  metadata.pageCount = sections.length;
3738
3757
  const pageFilter = _optionalChain([options, 'optionalAccess', _54 => _54.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sections.length) : null;
3739
3758
  const totalTarget = pageFilter ? pageFilter.size : sections.length;
@@ -3747,25 +3766,25 @@ function parseHwp5Document(buffer, options) {
3747
3766
  const sectionData = sections[si];
3748
3767
  const data = !distribution && compressed ? decompressStream(Buffer.from(sectionData)) : Buffer.from(sectionData);
3749
3768
  totalDecompressed += data.length;
3750
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkITJIALN5cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3769
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3751
3770
  const records = readRecords(data);
3752
3771
  const sectionBlocks = parseSection(records, docInfo, warnings, si + 1, doc);
3753
3772
  bodyBlocks.push(...sectionBlocks);
3754
3773
  parsedSections++;
3755
3774
  _optionalChain([options, 'optionalAccess', _55 => _55.onProgress, 'optionalCall', _56 => _56(parsedSections, totalTarget)]);
3756
3775
  } catch (secErr) {
3757
- if (secErr instanceof _chunkITJIALN5cjs.KordocError) throw secErr;
3776
+ if (secErr instanceof _chunkLFCS3UVGcjs.KordocError) throw secErr;
3758
3777
  warnings.push({ page: si + 1, message: `\uC139\uC158 ${si + 1} \uD30C\uC2F1 \uC2E4\uD328: ${secErr instanceof Error ? secErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
3759
3778
  }
3760
3779
  }
3761
3780
  const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
3762
3781
  const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings);
3763
- const flatBlocks = _chunkITJIALN5cjs.flattenLayoutTables.call(void 0, blocks);
3782
+ const flatBlocks = _chunkLFCS3UVGcjs.flattenLayoutTables.call(void 0, blocks);
3764
3783
  if (docInfo) {
3765
3784
  detectHwp5Headings(flatBlocks, docInfo);
3766
3785
  }
3767
3786
  const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
3768
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, flatBlocks);
3787
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, flatBlocks);
3769
3788
  return { markdown, blocks: flatBlocks, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
3770
3789
  }
3771
3790
  function parseDocInfoStream(cfb, compressed) {
@@ -3825,9 +3844,9 @@ function detectHwp5Headings(blocks, docInfo) {
3825
3844
  let level = 0;
3826
3845
  if (_optionalChain([block, 'access', _61 => _61.style, 'optionalAccess', _62 => _62.fontSize]) && baseFontSize > 0) {
3827
3846
  const ratio = block.style.fontSize / baseFontSize;
3828
- if (ratio >= _chunkITJIALN5cjs.HEADING_RATIO_H1) level = 1;
3829
- else if (ratio >= _chunkITJIALN5cjs.HEADING_RATIO_H2) level = 2;
3830
- else if (ratio >= _chunkITJIALN5cjs.HEADING_RATIO_H3) level = 3;
3847
+ if (ratio >= _chunkLFCS3UVGcjs.HEADING_RATIO_H1) level = 1;
3848
+ else if (ratio >= _chunkLFCS3UVGcjs.HEADING_RATIO_H2) level = 2;
3849
+ else if (ratio >= _chunkLFCS3UVGcjs.HEADING_RATIO_H3) level = 3;
3831
3850
  }
3832
3851
  if (/^제\d+[장절편]\s/.test(text) && text.length <= 50) {
3833
3852
  if (level === 0) level = 2;
@@ -3912,7 +3931,7 @@ function findSectionsLenient(lcfb, compressed) {
3912
3931
  if (!raw) break;
3913
3932
  const content = compressed ? decompressStream(raw) : raw;
3914
3933
  totalDecompressed += content.length;
3915
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkITJIALN5cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3934
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3916
3935
  sections.push({ idx: i, content });
3917
3936
  }
3918
3937
  if (sections.length === 0) {
@@ -3924,7 +3943,7 @@ function findSectionsLenient(lcfb, compressed) {
3924
3943
  if (raw) {
3925
3944
  const content = compressed ? decompressStream(raw) : raw;
3926
3945
  totalDecompressed += content.length;
3927
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkITJIALN5cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3946
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3928
3947
  sections.push({ idx, content });
3929
3948
  }
3930
3949
  }
@@ -3941,7 +3960,7 @@ function findViewTextSectionsLenient(lcfb, compressed) {
3941
3960
  try {
3942
3961
  const content = decryptViewText(raw, compressed);
3943
3962
  totalDecompressed += content.length;
3944
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkITJIALN5cjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3963
+ if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
3945
3964
  sections.push({ idx: i, content });
3946
3965
  } catch (e26) {
3947
3966
  break;
@@ -4044,7 +4063,7 @@ function parseParagraph(records, start, end, ctx) {
4044
4063
  const ctrl = ctrls[r.ctrlIdx];
4045
4064
  if (!_optionalChain([ctrl, 'optionalAccess', _69 => _69.href]) || r.end <= r.start) continue;
4046
4065
  if (applied.some(([s, e]) => r.start < e && r.end > s)) continue;
4047
- const href = _chunkITJIALN5cjs.sanitizeHref.call(void 0, ctrl.href);
4066
+ const href = _chunkLFCS3UVGcjs.sanitizeHref.call(void 0, ctrl.href);
4048
4067
  if (!href) continue;
4049
4068
  const anchor = text.slice(r.start, r.end);
4050
4069
  if (!anchor.trim()) continue;
@@ -4277,8 +4296,8 @@ function parseTableControl(ctrl, records, ctx) {
4277
4296
  let tableIdx = -1;
4278
4297
  for (let i2 = childStart; i2 < childEnd; i2++) {
4279
4298
  if (records[i2].tagId === TAG_TABLE && records[i2].data.length >= 8) {
4280
- rows = Math.min(records[i2].data.readUInt16LE(4), _chunkITJIALN5cjs.MAX_ROWS);
4281
- cols = Math.min(records[i2].data.readUInt16LE(6), _chunkITJIALN5cjs.MAX_COLS);
4299
+ rows = Math.min(records[i2].data.readUInt16LE(4), _chunkLFCS3UVGcjs.MAX_ROWS);
4300
+ cols = Math.min(records[i2].data.readUInt16LE(6), _chunkLFCS3UVGcjs.MAX_COLS);
4282
4301
  tableIdx = i2;
4283
4302
  break;
4284
4303
  }
@@ -4327,7 +4346,7 @@ function parseTableControl(ctrl, records, ctx) {
4327
4346
  return table2;
4328
4347
  }
4329
4348
  const cellRows = arrangeCells(rows, cols, cells);
4330
- const table = _chunkITJIALN5cjs.buildTable.call(void 0, cellRows);
4349
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
4331
4350
  if (caption && table.rows > 0) table.caption = caption;
4332
4351
  return table.rows > 0 ? table : null;
4333
4352
  }
@@ -4344,8 +4363,8 @@ function parseCell(records, lhIdx, end, ctx) {
4344
4363
  rowAddr = rec.data.readUInt16LE(10);
4345
4364
  const cs = rec.data.readUInt16LE(12);
4346
4365
  const rs = rec.data.readUInt16LE(14);
4347
- if (cs > 0) colSpan = Math.min(cs, _chunkITJIALN5cjs.MAX_COLS);
4348
- if (rs > 0) rowSpan = Math.min(rs, _chunkITJIALN5cjs.MAX_ROWS);
4366
+ if (cs > 0) colSpan = Math.min(cs, _chunkLFCS3UVGcjs.MAX_COLS);
4367
+ if (rs > 0) rowSpan = Math.min(rs, _chunkLFCS3UVGcjs.MAX_ROWS);
4349
4368
  }
4350
4369
  const blocks = ctx.depth < MAX_NEST_DEPTH ? parseParagraphList(records, lhIdx + 1, end, { ...ctx, depth: ctx.depth + 1 }) : [];
4351
4370
  const parts = [];
@@ -4355,7 +4374,7 @@ function parseCell(records, lhIdx, end, ctx) {
4355
4374
  parts.push(`![image](hwp5bin:${b.text})`);
4356
4375
  hasStructure = true;
4357
4376
  } else if (b.type === "table" && b.table) {
4358
- const flat = _chunkITJIALN5cjs.convertTableToText.call(void 0, b.table.cells);
4377
+ const flat = _chunkLFCS3UVGcjs.convertTableToText.call(void 0, b.table.cells);
4359
4378
  if (flat) parts.push(flat);
4360
4379
  hasStructure = true;
4361
4380
  } else if (b.text) {
@@ -16789,7 +16808,7 @@ function getTextContent(el) {
16789
16808
  return _nullishCoalesce(_optionalChain([el, 'access', _82 => _82.textContent, 'optionalAccess', _83 => _83.trim, 'call', _84 => _84()]), () => ( ""));
16790
16809
  }
16791
16810
  function parseXml(text) {
16792
- return new (0, _xmldom.DOMParser)().parseFromString(_chunkITJIALN5cjs.stripDtd.call(void 0, text), "text/xml");
16811
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, text), "text/xml");
16793
16812
  }
16794
16813
  function parseSharedStrings(xml) {
16795
16814
  const doc = parseXml(xml);
@@ -16933,7 +16952,7 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
16933
16952
  cellRows.push(row);
16934
16953
  }
16935
16954
  if (cellRows.length > 0) {
16936
- const table = _chunkITJIALN5cjs.buildTable.call(void 0, cellRows);
16955
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
16937
16956
  if (table.rows > 0) {
16938
16957
  blocks.push({ type: "table", table, pageNumber: sheetIndex + 1 });
16939
16958
  }
@@ -16941,12 +16960,12 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
16941
16960
  return blocks;
16942
16961
  }
16943
16962
  async function parseXlsxDocument(buffer, options) {
16944
- _chunkITJIALN5cjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
16963
+ _chunkLFCS3UVGcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
16945
16964
  const zip = await _jszip2.default.loadAsync(buffer);
16946
16965
  const warnings = [];
16947
16966
  const workbookFile = zip.file("xl/workbook.xml");
16948
16967
  if (!workbookFile) {
16949
- throw new (0, _chunkITJIALN5cjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 XLSX \uD30C\uC77C: xl/workbook.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
16968
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 XLSX \uD30C\uC77C: xl/workbook.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
16950
16969
  }
16951
16970
  let sharedStrings = [];
16952
16971
  const ssFile = zip.file("xl/sharedStrings.xml");
@@ -16955,7 +16974,7 @@ async function parseXlsxDocument(buffer, options) {
16955
16974
  }
16956
16975
  const sheets = parseWorkbook(await workbookFile.async("text"));
16957
16976
  if (sheets.length === 0) {
16958
- throw new (0, _chunkITJIALN5cjs.KordocError)("XLSX \uD30C\uC77C\uC5D0 \uC2DC\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
16977
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("XLSX \uD30C\uC77C\uC5D0 \uC2DC\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
16959
16978
  }
16960
16979
  let relsMap = /* @__PURE__ */ new Map();
16961
16980
  const relsFile = zip.file("xl/_rels/workbook.xml.rels");
@@ -17027,7 +17046,7 @@ async function parseXlsxDocument(buffer, options) {
17027
17046
  } catch (e27) {
17028
17047
  }
17029
17048
  }
17030
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks);
17049
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
17031
17050
  return { markdown, blocks, metadata, warnings: warnings.length > 0 ? warnings : void 0 };
17032
17051
  }
17033
17052
 
@@ -17434,11 +17453,11 @@ function processGlobals(records) {
17434
17453
  let encrypted = false;
17435
17454
  const firstBof = records[0];
17436
17455
  if (!firstBof || firstBof.opcode !== OP_BOF) {
17437
- throw new (0, _chunkITJIALN5cjs.KordocError)("XLS: \uCCAB \uB808\uCF54\uB4DC\uAC00 BOF\uAC00 \uC544\uB2D8");
17456
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("XLS: \uCCAB \uB808\uCF54\uB4DC\uAC00 BOF\uAC00 \uC544\uB2D8");
17438
17457
  }
17439
17458
  const bof = decodeBof(firstBof.data);
17440
17459
  if (!bof || bof.dt !== DT_GLOBALS) {
17441
- throw new (0, _chunkITJIALN5cjs.KordocError)("XLS: Globals \uC11C\uBE0C\uC2A4\uD2B8\uB9BC BOF \uB204\uB77D");
17460
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("XLS: Globals \uC11C\uBE0C\uC2A4\uD2B8\uB9BC BOF \uB204\uB77D");
17442
17461
  }
17443
17462
  let i = 1;
17444
17463
  while (i < records.length) {
@@ -17553,7 +17572,7 @@ function sheetToBlocks2(sheetName, sheet, sheetIndex) {
17553
17572
  cellRows.push(row);
17554
17573
  }
17555
17574
  if (cellRows.length > 0) {
17556
- const table = _chunkITJIALN5cjs.buildTable.call(void 0, cellRows);
17575
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
17557
17576
  if (table.rows > 0) {
17558
17577
  blocks.push({ type: "table", table, pageNumber: sheetIndex + 1 });
17559
17578
  }
@@ -17566,21 +17585,21 @@ async function parseXlsDocument(buffer, options) {
17566
17585
  try {
17567
17586
  cfb = parseLenientCfb(buf);
17568
17587
  } catch (e) {
17569
- throw new (0, _chunkITJIALN5cjs.KordocError)(
17588
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
17570
17589
  `XLS: OLE2 \uC2DC\uADF8\uB2C8\uCC98 \uAC80\uC99D \uC2E4\uD328 \u2014 ${e instanceof Error ? e.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`
17571
17590
  );
17572
17591
  }
17573
17592
  const wb = _nullishCoalesce(cfb.findStream("/Workbook"), () => ( cfb.findStream("/Book")));
17574
17593
  if (!wb) {
17575
- throw new (0, _chunkITJIALN5cjs.KordocError)("XLS: Workbook \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC74C (BIFF5 \uB610\uB294 \uBE44\uD45C\uC900 \uD30C\uC77C)");
17594
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("XLS: Workbook \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC74C (BIFF5 \uB610\uB294 \uBE44\uD45C\uC900 \uD30C\uC77C)");
17576
17595
  }
17577
17596
  const records = readRecords2(wb);
17578
17597
  if (records.length === 0) {
17579
- throw new (0, _chunkITJIALN5cjs.KordocError)("XLS: \uC2DC\uADF8\uB2C8\uCC98 \uB808\uCF54\uB4DC\uAC00 \uC5C6\uC74C (Workbook \uC2A4\uD2B8\uB9BC \uC190\uC0C1)");
17598
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("XLS: \uC2DC\uADF8\uB2C8\uCC98 \uB808\uCF54\uB4DC\uAC00 \uC5C6\uC74C (Workbook \uC2A4\uD2B8\uB9BC \uC190\uC0C1)");
17580
17599
  }
17581
17600
  const firstBof = decodeBof(records[0].data);
17582
17601
  if (firstBof && firstBof.vers !== 1536) {
17583
- throw new (0, _chunkITJIALN5cjs.KordocError)(
17602
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
17584
17603
  `XLS: BIFF8(0x0600)\uB9CC \uC9C0\uC6D0 \u2014 \uBCF8 \uD30C\uC77C\uC740 0x${firstBof.vers.toString(16)}`
17585
17604
  );
17586
17605
  }
@@ -17640,7 +17659,7 @@ async function parseXlsDocument(buffer, options) {
17640
17659
  pageCount: totalSheets
17641
17660
  };
17642
17661
  return {
17643
- markdown: _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, allBlocks),
17662
+ markdown: _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, allBlocks),
17644
17663
  blocks: allBlocks,
17645
17664
  metadata,
17646
17665
  warnings: warnings.length > 0 ? warnings : void 0
@@ -18078,7 +18097,7 @@ function getAttr(el, localName2) {
18078
18097
  return null;
18079
18098
  }
18080
18099
  function parseXml2(text) {
18081
- return new (0, _xmldom.DOMParser)().parseFromString(_chunkITJIALN5cjs.stripDtd.call(void 0, text), "text/xml");
18100
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, text), "text/xml");
18082
18101
  }
18083
18102
  function parseStyles(xml) {
18084
18103
  const doc = parseXml2(xml);
@@ -18401,12 +18420,12 @@ async function extractImages(zip, rels, doc, warnings) {
18401
18420
  return { blocks, images };
18402
18421
  }
18403
18422
  async function parseDocxDocument(buffer, options) {
18404
- _chunkITJIALN5cjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
18423
+ _chunkLFCS3UVGcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
18405
18424
  const zip = await _jszip2.default.loadAsync(buffer);
18406
18425
  const warnings = [];
18407
18426
  const docFile = zip.file("word/document.xml");
18408
18427
  if (!docFile) {
18409
- throw new (0, _chunkITJIALN5cjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DOCX \uD30C\uC77C: word/document.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
18428
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DOCX \uD30C\uC77C: word/document.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
18410
18429
  }
18411
18430
  let rels = /* @__PURE__ */ new Map();
18412
18431
  const relsFile = zip.file("word/_rels/document.xml.rels");
@@ -18453,7 +18472,7 @@ async function parseDocxDocument(buffer, options) {
18453
18472
  const doc = parseXml2(docXml);
18454
18473
  const body = findElements(doc, "body");
18455
18474
  if (body.length === 0) {
18456
- throw new (0, _chunkITJIALN5cjs.KordocError)("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
18475
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("DOCX \uBCF8\uBB38(w:body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
18457
18476
  }
18458
18477
  const blocks = [];
18459
18478
  const bodyEl = body[0];
@@ -18494,7 +18513,7 @@ async function parseDocxDocument(buffer, options) {
18494
18513
  }
18495
18514
  }
18496
18515
  const outline = blocks.filter((b) => b.type === "heading").map((b) => ({ level: _nullishCoalesce(b.level, () => ( 2)), text: _nullishCoalesce(b.text, () => ( "")) }));
18497
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks);
18516
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
18498
18517
  return {
18499
18518
  markdown,
18500
18519
  blocks,
@@ -18517,7 +18536,7 @@ function parseHwpmlDocument(buffer, options) {
18517
18536
  }
18518
18537
  const text = new TextDecoder("utf-8").decode(buffer).replace(/^\uFEFF/, "");
18519
18538
  const normalized = text.replace(/&nbsp;/g, "&#160;");
18520
- const xml = _chunkITJIALN5cjs.stripDtd.call(void 0, normalized);
18539
+ const xml = _chunkLFCS3UVGcjs.stripDtd.call(void 0, normalized);
18521
18540
  const warnings = [];
18522
18541
  const parser = new (0, _xmldom.DOMParser)({
18523
18542
  onError: (_level, msg2) => {
@@ -18557,7 +18576,7 @@ function parseHwpmlDocument(buffer, options) {
18557
18576
  parseSection2(el, blocks, paraShapeMap, sectionIdx, warnings);
18558
18577
  }
18559
18578
  const outline = blocks.filter((b) => b.type === "heading" && b.text).map((b) => ({ level: _nullishCoalesce(b.level, () => ( 1)), text: b.text, pageNumber: b.pageNumber }));
18560
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks);
18579
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
18561
18580
  return {
18562
18581
  markdown,
18563
18582
  blocks,
@@ -18699,7 +18718,7 @@ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings) {
18699
18718
  const cellRows = grid.map(
18700
18719
  (row) => row.map((cell) => _nullishCoalesce(cell, () => ( { text: "", colSpan: 1, rowSpan: 1 })))
18701
18720
  );
18702
- const table = _chunkITJIALN5cjs.buildTable.call(void 0, cellRows);
18721
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
18703
18722
  blocks.push({ type: "table", table, pageNumber: sectionNum });
18704
18723
  }
18705
18724
  function extractCellText(cellEl) {
@@ -19872,19 +19891,19 @@ function parseCentralDirectory(buf) {
19872
19891
  }
19873
19892
  }
19874
19893
  }
19875
- if (eocdOffset < 0) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP EOCD\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
19894
+ if (eocdOffset < 0) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP EOCD\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
19876
19895
  const totalEntries = view.getUint16(eocdOffset + 10, true);
19877
19896
  const cdSize = view.getUint32(eocdOffset + 12, true);
19878
19897
  const cdOffset = view.getUint32(eocdOffset + 16, true);
19879
- if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19898
+ if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19880
19899
  if (eocdOffset >= 20 && view.getUint32(eocdOffset - 20, true) === ZIP64_EOCD_LOC_SIG) {
19881
- throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19900
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19882
19901
  }
19883
19902
  const decoder = new TextDecoder("utf-8");
19884
19903
  const entries = [];
19885
19904
  let pos = cdOffset;
19886
19905
  for (let i = 0; i < totalEntries; i++) {
19887
- if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
19906
+ if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
19888
19907
  const flags = view.getUint16(pos + 8, true);
19889
19908
  const method = view.getUint16(pos + 10, true);
19890
19909
  const crc = view.getUint32(pos + 16, true);
@@ -19895,7 +19914,7 @@ function parseCentralDirectory(buf) {
19895
19914
  const commentLen = view.getUint16(pos + 32, true);
19896
19915
  const localOffset = view.getUint32(pos + 42, true);
19897
19916
  if (compSize === 4294967295 || uncompSize === 4294967295 || localOffset === 4294967295) {
19898
- throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19917
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP64\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
19899
19918
  }
19900
19919
  const name = decoder.decode(buf.subarray(pos + 46, pos + 46 + nameLen));
19901
19920
  const cdEnd = pos + 46 + nameLen + extraLen + commentLen;
@@ -19924,7 +19943,7 @@ function patchZipEntries(original, replacements) {
19924
19943
  const { entries, cdOffset, eocdOffset } = parseCentralDirectory(original);
19925
19944
  const view = new DataView(original.buffer, original.byteOffset, original.byteLength);
19926
19945
  for (const name of replacements.keys()) {
19927
- if (!entries.some((e) => e.name === name)) throw new (0, _chunkITJIALN5cjs.KordocError)(`ZIP\uC5D0 \uC5C6\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
19946
+ if (!entries.some((e) => e.name === name)) throw new (0, _chunkLFCS3UVGcjs.KordocError)(`ZIP\uC5D0 \uC5C6\uB294 \uC5D4\uD2B8\uB9AC: ${name}`);
19928
19947
  }
19929
19948
  const byLocal = [...entries].sort((a, b) => a.localOffset - b.localOffset);
19930
19949
  const segments = [];
@@ -19942,7 +19961,7 @@ function patchZipEntries(original, replacements) {
19942
19961
  offset += seg.length;
19943
19962
  continue;
19944
19963
  }
19945
- if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunkITJIALN5cjs.KordocError)("ZIP \uB85C\uCEEC \uD5E4\uB354 \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
19964
+ if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP \uB85C\uCEEC \uD5E4\uB354 \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
19946
19965
  const nameLen = view.getUint16(e.localOffset + 26, true);
19947
19966
  const extraLen = view.getUint16(e.localOffset + 28, true);
19948
19967
  const headerLen = 30 + nameLen + extraLen;
@@ -19997,7 +20016,7 @@ async function fillHwpx(hwpxBuffer, values) {
19997
20016
  const zip = await _jszip2.default.loadAsync(hwpxBuffer);
19998
20017
  const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort();
19999
20018
  if (sectionPaths.length === 0) {
20000
- throw new (0, _chunkITJIALN5cjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
20019
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)("HWPX\uC5D0\uC11C \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
20001
20020
  }
20002
20021
  const normalizedValues = normalizeValues(values);
20003
20022
  const cursor = new ValueCursor(normalizedValues);
@@ -20783,7 +20802,7 @@ function escapeGfm(text) {
20783
20802
  }
20784
20803
  var HWP_SHAPE_ALT_TEXT_RE = /(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|이등변 삼각형|직각 삼각형|선|직선|곡선|화살표|굵은 화살표|이중 화살표|오각형|육각형|팔각형|별|[4-8]점별|십자|십자형|구름|구름형|마름모|도넛|평행사변형|사다리꼴|부채꼴|호|반원|물결|번개|하트|빗금|블록 화살표|수식|표|그림|개체|그리기\s?개체|묶음\s?개체|글상자|수식\s?개체|OLE\s?개체)\s?입니다\.?/g;
20785
20804
  function sanitizeText(text) {
20786
- let result = _chunkITJIALN5cjs.mapPuaText.call(void 0, text).replace(/[\u{F0000}-\u{FFFFD}]/gu, "").replace(HWP_SHAPE_ALT_TEXT_RE, "").replace(/ +/g, " ").trim();
20805
+ let result = _chunkLFCS3UVGcjs.mapPuaText.call(void 0, text).replace(/[\u{F0000}-\u{FFFFD}]/gu, "").replace(HWP_SHAPE_ALT_TEXT_RE, "").replace(/ +/g, " ").trim();
20787
20806
  if (result.length <= 30 && result.includes(" ")) {
20788
20807
  const tokens = result.split(" ");
20789
20808
  const koreanSingleCharCount = tokens.filter((t) => t.length === 1 && /[가-힯ㄱ-ㆎ]/.test(t)).length;
@@ -22501,7 +22520,7 @@ async function resolveSectionEntryNames(zip) {
22501
22520
  const paths = sectionPathsFromManifest(xml).filter((p) => zip.file(p) !== null);
22502
22521
  if (paths.length > 0) return paths;
22503
22522
  }
22504
- return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunkITJIALN5cjs.compareSectionPaths);
22523
+ return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
22505
22524
  }
22506
22525
  function sectionPathsFromManifest(xml) {
22507
22526
  const attr = (tag, name) => {
@@ -22511,7 +22530,7 @@ function sectionPathsFromManifest(xml) {
22511
22530
  const idToHref = /* @__PURE__ */ new Map();
22512
22531
  for (const m of xml.matchAll(/<opf:item(\s(?:"[^"]*"|'[^']*'|[^>"'])*?)\/?>/g)) {
22513
22532
  const id = attr(m[1], "id");
22514
- const href = _chunkITJIALN5cjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
22533
+ const href = _chunkLFCS3UVGcjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
22515
22534
  if (id && href) idToHref.set(id, href);
22516
22535
  }
22517
22536
  const ordered = [];
@@ -22520,7 +22539,7 @@ function sectionPathsFromManifest(xml) {
22520
22539
  if (href) ordered.push(href);
22521
22540
  }
22522
22541
  if (ordered.length > 0) return ordered;
22523
- return Array.from(idToHref.values()).sort(_chunkITJIALN5cjs.compareSectionPaths);
22542
+ return Array.from(idToHref.values()).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
22524
22543
  }
22525
22544
 
22526
22545
  // src/roundtrip/patcher.ts
@@ -22631,9 +22650,9 @@ function buildOrigUnits(blocks) {
22631
22650
  if (block.type === "paragraph" && block.text && /^\[별표\s*\d+/.test(sanitizeText(block.text))) {
22632
22651
  const next = blocks[i + 1];
22633
22652
  if (_optionalChain([next, 'optionalAccess', _220 => _220.type]) === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
22634
- chunk = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
22653
+ chunk = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
22635
22654
  } else {
22636
- chunk = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, [block]);
22655
+ chunk = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, [block]);
22637
22656
  }
22638
22657
  if (chunk) {
22639
22658
  const subUnits = splitMarkdownUnits(chunk);
@@ -24331,13 +24350,13 @@ async function htmlToPdf(html, options) {
24331
24350
  try {
24332
24351
  puppeteer = await Promise.resolve().then(() => _interopRequireWildcard(require("puppeteer-core")));
24333
24352
  } catch (e30) {
24334
- throw new (0, _chunkITJIALN5cjs.KordocError)(
24353
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
24335
24354
  "PDF \uC0DD\uC131\uC5D0 puppeteer-core\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC124\uCE58: npm install puppeteer-core"
24336
24355
  );
24337
24356
  }
24338
24357
  const executablePath = _nullishCoalesce(process.env.PUPPETEER_EXECUTABLE_PATH, () => ( findChromiumPath()));
24339
24358
  if (!executablePath) {
24340
- throw new (0, _chunkITJIALN5cjs.KordocError)(
24359
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
24341
24360
  "Chromium \uC2E4\uD589 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. PUPPETEER_EXECUTABLE_PATH \uD658\uACBD\uBCC0\uC218\uB97C \uC124\uC815\uD558\uC138\uC694."
24342
24361
  );
24343
24362
  }
@@ -24396,7 +24415,7 @@ async function markdownToPdf(markdown, options) {
24396
24415
  return htmlToPdf(html, options);
24397
24416
  }
24398
24417
  async function blocksToPdf(blocks, options) {
24399
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, blocks);
24418
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
24400
24419
  return markdownToPdf(markdown, options);
24401
24420
  }
24402
24421
 
@@ -24407,13 +24426,13 @@ async function parse(input, options) {
24407
24426
  if (typeof input === "string") {
24408
24427
  try {
24409
24428
  const buf = await _promises.readFile.call(void 0, input);
24410
- buffer = _chunkITJIALN5cjs.toArrayBuffer.call(void 0, buf);
24429
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, buf);
24411
24430
  } catch (err) {
24412
24431
  const msg2 = err instanceof Error && "code" in err && err.code === "ENOENT" ? `\uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input}` : `\uD30C\uC77C \uC77D\uAE30 \uC2E4\uD328: ${input}`;
24413
24432
  return { success: false, fileType: "unknown", error: msg2, code: "PARSE_ERROR" };
24414
24433
  }
24415
24434
  } else if (Buffer.isBuffer(input)) {
24416
- buffer = _chunkITJIALN5cjs.toArrayBuffer.call(void 0, input);
24435
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, input);
24417
24436
  } else {
24418
24437
  buffer = input;
24419
24438
  }
@@ -24448,7 +24467,7 @@ async function parseHwp3(buffer, options) {
24448
24467
  const { markdown, blocks, metadata, outline, warnings } = parseHwp3Document(buffer, options);
24449
24468
  return { success: true, fileType: "hwp3", markdown, blocks, metadata, outline, warnings };
24450
24469
  } catch (err) {
24451
- return { success: false, fileType: "hwp3", error: err instanceof Error ? err.message : "HWP3 \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24470
+ return { success: false, fileType: "hwp3", error: err instanceof Error ? err.message : "HWP3 \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24452
24471
  }
24453
24472
  }
24454
24473
  async function parseHwpx(buffer, options) {
@@ -24456,7 +24475,7 @@ async function parseHwpx(buffer, options) {
24456
24475
  const { markdown, blocks, metadata, outline, warnings, images } = await parseHwpxDocument(buffer, options);
24457
24476
  return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _280 => _280.length]) ? images : void 0 };
24458
24477
  } catch (err) {
24459
- return { success: false, fileType: "hwpx", error: err instanceof Error ? err.message : "HWPX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24478
+ return { success: false, fileType: "hwpx", error: err instanceof Error ? err.message : "HWPX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24460
24479
  }
24461
24480
  }
24462
24481
  async function parseHwp(buffer, options) {
@@ -24481,13 +24500,13 @@ async function parseHwp(buffer, options) {
24481
24500
  }
24482
24501
  return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _282 => _282.length]) ? images : void 0 };
24483
24502
  } catch (err) {
24484
- return { success: false, fileType: "hwp", error: err instanceof Error ? err.message : "HWP \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24503
+ return { success: false, fileType: "hwp", error: err instanceof Error ? err.message : "HWP \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24485
24504
  }
24486
24505
  }
24487
24506
  async function parsePdf(buffer, options) {
24488
24507
  let parsePdfDocument;
24489
24508
  try {
24490
- const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-GUSJH44K.cjs")));
24509
+ const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-IXK5V7YG.cjs")));
24491
24510
  parsePdfDocument = mod.parsePdfDocument;
24492
24511
  } catch (e32) {
24493
24512
  return {
@@ -24502,7 +24521,7 @@ async function parsePdf(buffer, options) {
24502
24521
  return { success: true, fileType: "pdf", markdown, blocks, metadata, outline, warnings, isImageBased, pageQuality, qualitySummary };
24503
24522
  } catch (err) {
24504
24523
  const isImageBased = err instanceof Error && "isImageBased" in err ? true : void 0;
24505
- return { success: false, fileType: "pdf", error: err instanceof Error ? err.message : "PDF \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err), isImageBased };
24524
+ return { success: false, fileType: "pdf", error: err instanceof Error ? err.message : "PDF \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err), isImageBased };
24506
24525
  }
24507
24526
  }
24508
24527
  async function parseXlsx(buffer, options) {
@@ -24510,7 +24529,7 @@ async function parseXlsx(buffer, options) {
24510
24529
  const { markdown, blocks, metadata, warnings } = await parseXlsxDocument(buffer, options);
24511
24530
  return { success: true, fileType: "xlsx", markdown, blocks, metadata, warnings };
24512
24531
  } catch (err) {
24513
- return { success: false, fileType: "xlsx", error: err instanceof Error ? err.message : "XLSX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24532
+ return { success: false, fileType: "xlsx", error: err instanceof Error ? err.message : "XLSX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24514
24533
  }
24515
24534
  }
24516
24535
  async function parseXls(buffer, options) {
@@ -24518,7 +24537,7 @@ async function parseXls(buffer, options) {
24518
24537
  const { markdown, blocks, metadata, warnings } = await parseXlsDocument(buffer, options);
24519
24538
  return { success: true, fileType: "xls", markdown, blocks, metadata, warnings };
24520
24539
  } catch (err) {
24521
- return { success: false, fileType: "xls", error: err instanceof Error ? err.message : "XLS \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24540
+ return { success: false, fileType: "xls", error: err instanceof Error ? err.message : "XLS \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24522
24541
  }
24523
24542
  }
24524
24543
  async function parseDocx(buffer, options) {
@@ -24526,7 +24545,7 @@ async function parseDocx(buffer, options) {
24526
24545
  const { markdown, blocks, metadata, outline, warnings, images } = await parseDocxDocument(buffer, options);
24527
24546
  return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _283 => _283.length]) ? images : void 0 };
24528
24547
  } catch (err) {
24529
- return { success: false, fileType: "docx", error: err instanceof Error ? err.message : "DOCX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24548
+ return { success: false, fileType: "docx", error: err instanceof Error ? err.message : "DOCX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24530
24549
  }
24531
24550
  }
24532
24551
  async function parseHwpml(buffer, options) {
@@ -24534,16 +24553,16 @@ async function parseHwpml(buffer, options) {
24534
24553
  const { markdown, blocks, metadata, outline, warnings } = parseHwpmlDocument(buffer, options);
24535
24554
  return { success: true, fileType: "hwpml", markdown, blocks, metadata, outline, warnings };
24536
24555
  } catch (err) {
24537
- return { success: false, fileType: "hwpml", error: err instanceof Error ? err.message : "HWPML \uD30C\uC2F1 \uC2E4\uD328", code: _chunkITJIALN5cjs.classifyError.call(void 0, err) };
24556
+ return { success: false, fileType: "hwpml", error: err instanceof Error ? err.message : "HWPML \uD30C\uC2F1 \uC2E4\uD328", code: _chunkLFCS3UVGcjs.classifyError.call(void 0, err) };
24538
24557
  }
24539
24558
  }
24540
24559
  async function fillForm(input, values, outputFormat = "markdown") {
24541
24560
  let buffer;
24542
24561
  if (typeof input === "string") {
24543
24562
  const buf = await _promises.readFile.call(void 0, input);
24544
- buffer = _chunkITJIALN5cjs.toArrayBuffer.call(void 0, buf);
24563
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, buf);
24545
24564
  } else if (Buffer.isBuffer(input)) {
24546
- buffer = _chunkITJIALN5cjs.toArrayBuffer.call(void 0, input);
24565
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, input);
24547
24566
  } else {
24548
24567
  buffer = input;
24549
24568
  }
@@ -24569,7 +24588,7 @@ async function fillForm(input, values, outputFormat = "markdown") {
24569
24588
  throw new Error(`\uC11C\uC2DD \uD30C\uC2F1 \uC2E4\uD328: ${parsed.error}`);
24570
24589
  }
24571
24590
  const fill = fillFormFields(parsed.blocks, values);
24572
- const markdown = _chunkITJIALN5cjs.blocksToMarkdown.call(void 0, fill.blocks);
24591
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, fill.blocks);
24573
24592
  if (outputFormat === "hwpx") {
24574
24593
  const hwpxBuffer = await markdownToHwpx(markdown);
24575
24594
  return { output: hwpxBuffer, format: "hwpx", fill };
@@ -24627,5 +24646,5 @@ async function fillForm(input, values, outputFormat = "markdown") {
24627
24646
 
24628
24647
 
24629
24648
 
24630
- exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunkITJIALN5cjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToMarkdown = _chunkITJIALN5cjs.blocksToMarkdown; exports.blocksToPdf = blocksToPdf; exports.buildParagraphSplices = buildParagraphSplices; exports.buildRangeSplices = buildRangeSplices; exports.charWidthEm1000 = charWidthEm1000; exports.compare = compare; exports.detectFormat = detectFormat; exports.detectOle2Format = detectOle2Format; exports.detectZipFormat = detectZipFormat; exports.diffBlocks = diffBlocks; exports.extractFormFields = extractFormFields; exports.extractFormSchema = extractFormSchema; exports.fillForm = fillForm; exports.fillFormFields = fillFormFields; exports.fillHwpx = fillHwpx; exports.fitRatioForFewerLines = fitRatioForFewerLines; exports.inferFieldType = inferFieldType; exports.isHwpxFile = isHwpxFile; exports.isLabelCell = isLabelCell; exports.isOldHwpFile = isOldHwpFile; exports.isPdfFile = isPdfFile; exports.isZipFile = isZipFile; exports.markdownToHwpx = markdownToHwpx; exports.markdownToPdf = markdownToPdf; exports.measureTextWidth = measureTextWidth; exports.normalizeGongmunPreset = normalizeGongmunPreset; exports.openHwpxDocument = openHwpxDocument; exports.parse = parse; exports.parseDocx = parseDocx; exports.parseHwp = parseHwp; exports.parseHwp3 = parseHwp3; exports.parseHwpml = parseHwpml; exports.parseHwpx = parseHwpx; exports.parsePdf = parsePdf; exports.parseXls = parseXls; exports.parseXlsx = parseXlsx; exports.patchHwp = patchHwp; exports.patchHwpx = patchHwpx; exports.patchHwpxBlocks = patchHwpxBlocks; exports.renderHtml = renderHtml; exports.scanSectionXml = scanSectionXml; exports.simulateWrap = simulateWrap; exports.simulateWrapKeepWord = simulateWrapKeepWord;
24649
+ exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunkLFCS3UVGcjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToMarkdown = _chunkLFCS3UVGcjs.blocksToMarkdown; exports.blocksToPdf = blocksToPdf; exports.buildParagraphSplices = buildParagraphSplices; exports.buildRangeSplices = buildRangeSplices; exports.charWidthEm1000 = charWidthEm1000; exports.compare = compare; exports.detectFormat = detectFormat; exports.detectOle2Format = detectOle2Format; exports.detectZipFormat = detectZipFormat; exports.diffBlocks = diffBlocks; exports.extractFormFields = extractFormFields; exports.extractFormSchema = extractFormSchema; exports.fillForm = fillForm; exports.fillFormFields = fillFormFields; exports.fillHwpx = fillHwpx; exports.fitRatioForFewerLines = fitRatioForFewerLines; exports.inferFieldType = inferFieldType; exports.isHwpxFile = isHwpxFile; exports.isLabelCell = isLabelCell; exports.isOldHwpFile = isOldHwpFile; exports.isPdfFile = isPdfFile; exports.isZipFile = isZipFile; exports.markdownToHwpx = markdownToHwpx; exports.markdownToPdf = markdownToPdf; exports.measureTextWidth = measureTextWidth; exports.normalizeGongmunPreset = normalizeGongmunPreset; exports.openHwpxDocument = openHwpxDocument; exports.parse = parse; exports.parseDocx = parseDocx; exports.parseHwp = parseHwp; exports.parseHwp3 = parseHwp3; exports.parseHwpml = parseHwpml; exports.parseHwpx = parseHwpx; exports.parsePdf = parsePdf; exports.parseXls = parseXls; exports.parseXlsx = parseXlsx; exports.patchHwp = patchHwp; exports.patchHwpx = patchHwpx; exports.patchHwpxBlocks = patchHwpxBlocks; exports.renderHtml = renderHtml; exports.scanSectionXml = scanSectionXml; exports.simulateWrap = simulateWrap; exports.simulateWrapKeepWord = simulateWrapKeepWord;
24631
24650
  //# sourceMappingURL=index.cjs.map