kordoc 3.7.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 +14 -2
  2. package/dist/{-7UC4ZWBS.js → -LD4BZDDJ.js} +3 -3
  3. package/dist/{chunk-IJJMVTU5.js → chunk-IFYJFWD2.js} +2 -2
  4. package/dist/{chunk-NXRABCWW.js → chunk-KT2BCHXI.js} +803 -703
  5. package/dist/chunk-KT2BCHXI.js.map +1 -0
  6. package/dist/{chunk-QZCP3UWU.cjs → chunk-LFCS3UVG.cjs} +2 -2
  7. package/dist/{chunk-QZCP3UWU.cjs.map → chunk-LFCS3UVG.cjs.map} +1 -1
  8. package/dist/{chunk-MEVKYW55.js → chunk-PELBIL4K.js} +2 -2
  9. package/dist/cli.js +4 -4
  10. package/dist/index.cjs +968 -868
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +802 -702
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp.js +3 -3
  15. package/dist/{parser-DR5CTZ74.js → parser-FFEBMLSH.js} +1830 -1803
  16. package/dist/parser-FFEBMLSH.js.map +1 -0
  17. package/dist/{parser-RFLPUZ7P.cjs → parser-IXK5V7YG.cjs} +1830 -1803
  18. package/dist/parser-IXK5V7YG.cjs.map +1 -0
  19. package/dist/{parser-ZHJFQR44.js → parser-XEDROIM7.js} +1830 -1803
  20. package/dist/parser-XEDROIM7.js.map +1 -0
  21. package/dist/{watch-UIX447QV.js → watch-MAWCDNFI.js} +3 -3
  22. package/package.json +2 -2
  23. package/dist/chunk-NXRABCWW.js.map +0 -1
  24. package/dist/parser-DR5CTZ74.js.map +0 -1
  25. package/dist/parser-RFLPUZ7P.cjs.map +0 -1
  26. package/dist/parser-ZHJFQR44.js.map +0 -1
  27. /package/dist/{-7UC4ZWBS.js.map → -LD4BZDDJ.js.map} +0 -0
  28. /package/dist/{chunk-IJJMVTU5.js.map → chunk-IFYJFWD2.js.map} +0 -0
  29. /package/dist/{chunk-MEVKYW55.js.map → chunk-PELBIL4K.js.map} +0 -0
  30. /package/dist/{watch-UIX447QV.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 _chunkQZCP3UWUcjs = require('./chunk-QZCP3UWU.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
  }
@@ -802,656 +1039,133 @@ function replaceAllBrace(eqString) {
802
1039
  for (const [braceKey, braceElem] of Object.entries(BRACE_CONVERT_MAP)) {
803
1040
  eqString = replaceBrace(eqString, braceKey, braceElem);
804
1041
  }
805
- return eqString;
806
- }
807
- function replaceBracket(strList) {
808
- for (let i = 0; i < strList.length; i++) {
809
- if (strList[i] === "{" && i > 0 && strList[i - 1] === "\\left") strList[i] = "\\{";
810
- if (strList[i] === "}" && i > 0 && strList[i - 1] === "\\right") strList[i] = "\\}";
811
- }
812
- return strList;
813
- }
814
- function hmlToLatex(hmlEqStr) {
815
- if (!hmlEqStr) return "";
816
- let s = hmlEqStr.replace(/`/g, " ");
817
- s = s.replace(/\{/g, " { ").replace(/\}/g, " } ").replace(/&/g, " & ");
818
- let tokens = s.split(" ");
819
- for (let i = 0; i < tokens.length; i++) {
820
- const t = tokens[i];
821
- if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t];
822
- else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t];
823
- }
824
- tokens = tokens.filter((tok) => tok.length !== 0);
825
- tokens = replaceBracket(tokens);
826
- let out = tokens.join(" ");
827
- out = replaceFrac(out);
828
- out = replaceRootOf(out);
829
- out = replaceAllMatrix(out);
830
- out = replaceAllBar(out);
831
- out = replaceAllBrace(out);
832
- return out;
833
- }
834
-
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, _chunkQZCP3UWUcjs.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, _chunkQZCP3UWUcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
871
- }
872
- const parser = createXmlParser();
873
- const doc = parser.parseFromString(_chunkQZCP3UWUcjs.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
- }
1002
- var HANGUL_SYLLABLE_SEQ = "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC\uC544\uC790\uCC28\uCE74\uD0C0\uD30C\uD558";
1003
- var HANGUL_JAMO_SEQ = "\u3131\u3134\u3137\u3139\u3141\u3142\u3145\u3147\u3148\u314A\u314B\u314C\u314D\u314E";
1004
- function toRoman(n) {
1005
- if (n <= 0 || n >= 4e3) return String(n);
1006
- const table = [
1007
- [1e3, "M"],
1008
- [900, "CM"],
1009
- [500, "D"],
1010
- [400, "CD"],
1011
- [100, "C"],
1012
- [90, "XC"],
1013
- [50, "L"],
1014
- [40, "XL"],
1015
- [10, "X"],
1016
- [9, "IX"],
1017
- [5, "V"],
1018
- [4, "IV"],
1019
- [1, "I"]
1020
- ];
1021
- let out = "";
1022
- for (const [v, s] of table) {
1023
- while (n >= v) {
1024
- out += s;
1025
- n -= v;
1026
- }
1027
- }
1028
- return out;
1029
- }
1030
- function formatHeadNumber(n, numFormat) {
1031
- if (n <= 0) n = 1;
1032
- switch (numFormat) {
1033
- case "DIGIT":
1034
- return String(n);
1035
- case "CIRCLED_DIGIT":
1036
- return n <= 20 ? String.fromCodePoint(9312 + n - 1) : `(${n})`;
1037
- case "HANGUL_SYLLABLE":
1038
- return HANGUL_SYLLABLE_SEQ[(n - 1) % HANGUL_SYLLABLE_SEQ.length];
1039
- case "CIRCLED_HANGUL_SYLLABLE":
1040
- return n <= 14 ? String.fromCodePoint(12910 + n - 1) : HANGUL_SYLLABLE_SEQ[(n - 1) % 14];
1041
- case "HANGUL_JAMO":
1042
- return HANGUL_JAMO_SEQ[(n - 1) % HANGUL_JAMO_SEQ.length];
1043
- case "CIRCLED_HANGUL_JAMO":
1044
- return n <= 14 ? String.fromCodePoint(12896 + n - 1) : HANGUL_JAMO_SEQ[(n - 1) % 14];
1045
- case "LATIN_CAPITAL":
1046
- return String.fromCharCode(65 + (n - 1) % 26);
1047
- case "LATIN_SMALL":
1048
- return String.fromCharCode(97 + (n - 1) % 26);
1049
- case "CIRCLED_LATIN_CAPITAL":
1050
- return n <= 26 ? String.fromCodePoint(9398 + n - 1) : String.fromCharCode(65 + (n - 1) % 26);
1051
- case "CIRCLED_LATIN_SMALL":
1052
- return n <= 26 ? String.fromCodePoint(9424 + n - 1) : String.fromCharCode(97 + (n - 1) % 26);
1053
- case "ROMAN_CAPITAL":
1054
- return toRoman(n);
1055
- case "ROMAN_SMALL":
1056
- return toRoman(n).toLowerCase();
1057
- default:
1058
- return String(n);
1059
- }
1060
- }
1061
- function resolveParaHeading(paraEl, ctx) {
1062
- const sm = ctx.styleMap;
1063
- if (!sm) return null;
1064
- const prId = paraEl.getAttribute("paraPrIDRef");
1065
- if (!prId) return null;
1066
- const ref = sm.paraHeadings.get(prId);
1067
- if (!ref) return null;
1068
- if (ref.type === "BULLET") {
1069
- const char = sm.bullets.get(ref.idRef);
1070
- return char ? { prefix: char } : null;
1071
- }
1072
- const numId = ref.type === "OUTLINE" ? ctx.outlineNumId || "1" : ref.idRef;
1073
- const level = Math.min(ref.level + 1, 10);
1074
- const headingLevel = ref.type === "OUTLINE" ? Math.min(ref.level + 1, 6) : void 0;
1075
- const numDef = sm.numberings.get(numId);
1076
- if (!numDef) return headingLevel ? { headingLevel } : null;
1077
- let counters = ctx.shared.numState.get(numId);
1078
- if (!counters) {
1079
- counters = new Array(11).fill(0);
1080
- ctx.shared.numState.set(numId, counters);
1081
- }
1082
- const head = numDef.heads.get(level);
1083
- counters[level] = counters[level] === 0 ? _nullishCoalesce(_optionalChain([head, 'optionalAccess', _5 => _5.start]), () => ( 1)) : counters[level] + 1;
1084
- 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}.`;
1086
- const prefix = fmtText.replace(/\^(10|[1-9])/g, (_, d) => {
1087
- const lv = parseInt(d, 10);
1088
- 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");
1091
- });
1092
- return { prefix, headingLevel };
1093
- }
1094
- async function parseHwpxDocument(buffer, options) {
1095
- _chunkQZCP3UWUcjs.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, _chunkQZCP3UWUcjs.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);
1114
- }
1115
- }
1116
- throw new (0, _chunkQZCP3UWUcjs.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
- }
1118
- }
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, _chunkQZCP3UWUcjs.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, _chunkQZCP3UWUcjs.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 _chunkQZCP3UWUcjs.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" });
1146
- }
1147
- }
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 = _chunkQZCP3UWUcjs.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 };
1154
- }
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 })));
1159
- }
1160
- if (footers.length > 0) {
1161
- blocks.push(...footers.map((t) => ({ type: "paragraph", text: t })));
1162
- }
1163
- }
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";
1186
- }
1187
- }
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
- }
1210
- }
1211
- }
1212
- }
1213
- async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
1214
- const images = [];
1215
- let imageIndex = 0;
1216
- const imageBlocks = [];
1217
- collectImageBlocks(blocks, imageBlocks);
1218
- for (const { block, ownerCell } of imageBlocks) {
1219
- if (block.type !== "image" || !block.text) continue;
1220
- const ref = block.text;
1221
- const candidates = [
1222
- `BinData/${ref}`,
1223
- `Contents/BinData/${ref}`,
1224
- ref
1225
- // 절대 경로일 수도 있음
1226
- ];
1227
- let resolvedPath = null;
1228
- if (!ref.includes(".")) {
1229
- const prefixes = [`BinData/${ref}`, `Contents/BinData/${ref}`];
1230
- for (const prefix of prefixes) {
1231
- const match = zip.file(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.[a-zA-Z0-9]+$`));
1232
- if (match.length > 0) {
1233
- resolvedPath = match[0].name;
1234
- break;
1235
- }
1236
- }
1237
- }
1238
- let found = false;
1239
- const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates;
1240
- for (const path of allCandidates) {
1241
- if (_chunkQZCP3UWUcjs.isPathTraversal.call(void 0, path)) continue;
1242
- const file = zip.file(path);
1243
- if (!file) continue;
1244
- try {
1245
- const data = await file.async("uint8array");
1246
- decompressed.total += data.length;
1247
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkQZCP3UWUcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1248
- const actualPath = path;
1249
- const ext = actualPath.includes(".") ? actualPath.split(".").pop() || "png" : "png";
1250
- const mimeType = imageExtToMime(ext);
1251
- imageIndex++;
1252
- const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
1253
- images.push({ filename, data, mimeType });
1254
- block.text = filename;
1255
- block.imageData = { data, mimeType, filename: ref };
1256
- if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `![image](${filename})`);
1257
- found = true;
1258
- break;
1259
- } catch (err) {
1260
- if (err instanceof _chunkQZCP3UWUcjs.KordocError) throw err;
1261
- }
1262
- }
1263
- if (!found) {
1264
- _optionalChain([warnings, 'optionalAccess', _17 => _17.push, 'call', _18 => _18({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" })]);
1265
- block.type = "paragraph";
1266
- block.text = `[\uC774\uBBF8\uC9C0: ${ref}]`;
1267
- if (ownerCell) ownerCell.text = ownerCell.text.replace(`![image](${ref})`, `[\uC774\uBBF8\uC9C0: ${ref}]`);
1268
- }
1269
- }
1270
- return images;
1271
- }
1272
- async function extractHwpxMetadata(zip, metadata, decompressed) {
1273
- try {
1274
- const metaPaths = ["meta.xml", "META-INF/meta.xml", "docProps/core.xml"];
1275
- for (const mp of metaPaths) {
1276
- const file = zip.file(mp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === mp.toLowerCase()) || null;
1277
- if (!file) continue;
1278
- const xml = await file.async("text");
1279
- if (decompressed) {
1280
- decompressed.total += xml.length * 2;
1281
- if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new (0, _chunkQZCP3UWUcjs.KordocError)("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
1282
- }
1283
- parseDublinCoreMetadata(xml, metadata);
1284
- if (metadata.title || metadata.author) return;
1285
- }
1286
- } catch (e13) {
1287
- }
1288
- }
1289
- function parseDublinCoreMetadata(xml, metadata) {
1290
- const parser = createXmlParser();
1291
- const doc = parser.parseFromString(_chunkQZCP3UWUcjs.stripDtd.call(void 0, xml), "text/xml");
1292
- if (!doc.documentElement) return;
1293
- const getText = (tagNames) => {
1294
- for (const tag of tagNames) {
1295
- const els = doc.getElementsByTagName(tag);
1296
- if (els.length > 0) {
1297
- const text = _optionalChain([els, 'access', _19 => _19[0], 'access', _20 => _20.textContent, 'optionalAccess', _21 => _21.trim, 'call', _22 => _22()]);
1298
- if (text) return text;
1299
- }
1300
- }
1301
- return void 0;
1302
- };
1303
- metadata.title = metadata.title || getText(["dc:title", "title"]);
1304
- metadata.author = metadata.author || getText(["dc:creator", "creator", "cp:lastModifiedBy"]);
1305
- metadata.description = metadata.description || getText(["dc:description", "description", "dc:subject", "subject"]);
1306
- metadata.createdAt = metadata.createdAt || getText(["dcterms:created", "meta:creation-date"]);
1307
- metadata.modifiedAt = metadata.modifiedAt || getText(["dcterms:modified", "meta:date"]);
1308
- const keywords = getText(["dc:keyword", "cp:keywords", "meta:keyword"]);
1309
- if (keywords && !metadata.keywords) {
1310
- metadata.keywords = keywords.split(/[,;]/).map((k) => k.trim()).filter(Boolean);
1311
- }
1312
- }
1313
- function extractFromBrokenZip(buffer) {
1314
- const data = new Uint8Array(buffer);
1315
- const view = new DataView(buffer);
1316
- let pos = 0;
1317
- const blocks = [];
1318
- const warnings = [
1319
- { code: "BROKEN_ZIP_RECOVERY", message: "\uC190\uC0C1\uB41C ZIP \uAD6C\uC870 \u2014 Local File Header \uAE30\uBC18 \uBCF5\uAD6C \uBAA8\uB4DC" }
1320
- ];
1321
- let totalDecompressed = 0;
1322
- let entryCount = 0;
1323
- let sectionNum = 0;
1324
- const shared = createSectionShared();
1325
- while (pos < data.length - 30) {
1326
- if (data[pos] !== 80 || data[pos + 1] !== 75 || data[pos + 2] !== 3 || data[pos + 3] !== 4) {
1327
- pos++;
1328
- while (pos < data.length - 30) {
1329
- if (data[pos] === 80 && data[pos + 1] === 75 && data[pos + 2] === 3 && data[pos + 3] === 4) break;
1330
- pos++;
1331
- }
1332
- continue;
1333
- }
1334
- if (++entryCount > MAX_ZIP_ENTRIES) break;
1335
- const method = view.getUint16(pos + 8, true);
1336
- const compSize = view.getUint32(pos + 18, true);
1337
- const nameLen = view.getUint16(pos + 26, true);
1338
- const extraLen = view.getUint16(pos + 28, true);
1339
- if (nameLen > 1024 || extraLen > 65535) {
1340
- pos += 30 + nameLen + extraLen;
1341
- continue;
1342
- }
1343
- const fileStart = pos + 30 + nameLen + extraLen;
1344
- if (fileStart + compSize > data.length) break;
1345
- if (compSize === 0 && method !== 0) {
1346
- pos = fileStart;
1347
- continue;
1348
- }
1349
- const nameBytes = data.slice(pos + 30, pos + 30 + nameLen);
1350
- const name = new TextDecoder().decode(nameBytes);
1351
- if (_chunkQZCP3UWUcjs.isPathTraversal.call(void 0, name)) {
1352
- pos = fileStart + compSize;
1353
- continue;
1354
- }
1355
- const fileData = data.slice(fileStart, fileStart + compSize);
1356
- pos = fileStart + compSize;
1357
- if (!name.toLowerCase().includes("section") || !name.endsWith(".xml")) continue;
1358
- try {
1359
- let content;
1360
- if (method === 0) {
1361
- content = new TextDecoder().decode(fileData);
1362
- } else if (method === 8) {
1363
- const decompressed = _zlib.inflateRawSync.call(void 0, Buffer.from(fileData), { maxOutputLength: MAX_DECOMPRESS_SIZE });
1364
- content = new TextDecoder().decode(decompressed);
1365
- } else {
1366
- continue;
1367
- }
1368
- totalDecompressed += content.length * 2;
1369
- if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new (0, _chunkQZCP3UWUcjs.KordocError)("\uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC");
1370
- sectionNum++;
1371
- blocks.push(...parseSectionXml(content, void 0, warnings, sectionNum, shared));
1372
- } catch (e14) {
1373
- continue;
1374
- }
1375
- }
1376
- if (blocks.length === 0) throw new (0, _chunkQZCP3UWUcjs.KordocError)("\uC190\uC0C1\uB41C HWPX\uC5D0\uC11C \uC139\uC158 \uB370\uC774\uD130\uB97C \uBCF5\uAD6C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1377
- applyPageText(blocks, shared);
1378
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, blocks);
1379
- return { markdown, blocks, warnings: warnings.length > 0 ? warnings : void 0 };
1380
- }
1381
- async function resolveSectionPaths(zip) {
1382
- const manifestPaths = ["Contents/content.hpf", "content.hpf"];
1383
- for (const mp of manifestPaths) {
1384
- const mpLower = mp.toLowerCase();
1385
- const file = zip.file(mp) || Object.values(zip.files).find((f) => f.name.toLowerCase() === mpLower) || null;
1386
- if (!file) continue;
1387
- const xml = await file.async("text");
1388
- const paths = parseSectionPathsFromManifest(xml);
1389
- if (paths.length > 0) return paths;
1390
- }
1391
- const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/);
1392
- return sectionFiles.map((f) => f.name).sort(_chunkQZCP3UWUcjs.compareSectionPaths);
1042
+ return eqString;
1393
1043
  }
1394
- function parseSectionPathsFromManifest(xml) {
1395
- const parser = createXmlParser();
1396
- const doc = parser.parseFromString(_chunkQZCP3UWUcjs.stripDtd.call(void 0, xml), "text/xml");
1397
- const items = doc.getElementsByTagName("opf:item");
1398
- const spine = doc.getElementsByTagName("opf:itemref");
1399
- const idToHref = /* @__PURE__ */ new Map();
1400
- for (let i = 0; i < items.length; i++) {
1401
- const item = items[i];
1402
- const id = item.getAttribute("id") || "";
1403
- const href = _chunkQZCP3UWUcjs.normalizeSectionHref.call(void 0, item.getAttribute("href") || "");
1404
- if (id && href) idToHref.set(id, href);
1044
+ function replaceBracket(strList) {
1045
+ for (let i = 0; i < strList.length; i++) {
1046
+ if (strList[i] === "{" && i > 0 && strList[i - 1] === "\\left") strList[i] = "\\{";
1047
+ if (strList[i] === "}" && i > 0 && strList[i - 1] === "\\right") strList[i] = "\\}";
1405
1048
  }
1406
- if (spine.length > 0) {
1407
- const ordered = [];
1408
- for (let i = 0; i < spine.length; i++) {
1409
- const href = idToHref.get(spine[i].getAttribute("idref") || "");
1410
- if (href) ordered.push(href);
1411
- }
1412
- if (ordered.length > 0) return ordered;
1049
+ return strList;
1050
+ }
1051
+ function hmlToLatex(hmlEqStr) {
1052
+ if (!hmlEqStr) return "";
1053
+ let s = hmlEqStr.replace(/`/g, " ");
1054
+ s = s.replace(/\{/g, " { ").replace(/\}/g, " } ").replace(/&/g, " & ");
1055
+ let tokens = s.split(" ");
1056
+ for (let i = 0; i < tokens.length; i++) {
1057
+ const t = tokens[i];
1058
+ if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t];
1059
+ else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t];
1413
1060
  }
1414
- return Array.from(idToHref.values()).sort(_chunkQZCP3UWUcjs.compareSectionPaths);
1061
+ tokens = tokens.filter((tok) => tok.length !== 0);
1062
+ tokens = replaceBracket(tokens);
1063
+ let out = tokens.join(" ");
1064
+ out = replaceFrac(out);
1065
+ out = replaceRootOf(out);
1066
+ out = replaceAllMatrix(out);
1067
+ out = replaceAllBar(out);
1068
+ out = replaceAllBrace(out);
1069
+ return out;
1415
1070
  }
1416
- function detectHwpxHeadings(blocks, styleMap) {
1417
- if (blocks.some((b) => b.type === "heading")) return;
1418
- let baseFontSize = 0;
1419
- const sizeFreq = /* @__PURE__ */ new Map();
1420
- for (const b of blocks) {
1421
- if (_optionalChain([b, 'access', _23 => _23.style, 'optionalAccess', _24 => _24.fontSize])) {
1422
- sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1);
1071
+
1072
+ // src/hwpx/para-heading.ts
1073
+ var HANGUL_SYLLABLE_SEQ = "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC\uC544\uC790\uCC28\uCE74\uD0C0\uD30C\uD558";
1074
+ var HANGUL_JAMO_SEQ = "\u3131\u3134\u3137\u3139\u3141\u3142\u3145\u3147\u3148\u314A\u314B\u314C\u314D\u314E";
1075
+ function toRoman(n) {
1076
+ if (n <= 0 || n >= 4e3) return String(n);
1077
+ const table = [
1078
+ [1e3, "M"],
1079
+ [900, "CM"],
1080
+ [500, "D"],
1081
+ [400, "CD"],
1082
+ [100, "C"],
1083
+ [90, "XC"],
1084
+ [50, "L"],
1085
+ [40, "XL"],
1086
+ [10, "X"],
1087
+ [9, "IX"],
1088
+ [5, "V"],
1089
+ [4, "IV"],
1090
+ [1, "I"]
1091
+ ];
1092
+ let out = "";
1093
+ for (const [v, s] of table) {
1094
+ while (n >= v) {
1095
+ out += s;
1096
+ n -= v;
1423
1097
  }
1424
1098
  }
1425
- let maxCount = 0;
1426
- for (const [size, count] of sizeFreq) {
1427
- if (count > maxCount) {
1428
- maxCount = count;
1429
- baseFontSize = size;
1430
- }
1099
+ return out;
1100
+ }
1101
+ function formatHeadNumber(n, numFormat) {
1102
+ if (n <= 0) n = 1;
1103
+ switch (numFormat) {
1104
+ case "DIGIT":
1105
+ return String(n);
1106
+ case "CIRCLED_DIGIT":
1107
+ return n <= 20 ? String.fromCodePoint(9312 + n - 1) : `(${n})`;
1108
+ case "HANGUL_SYLLABLE":
1109
+ return HANGUL_SYLLABLE_SEQ[(n - 1) % HANGUL_SYLLABLE_SEQ.length];
1110
+ case "CIRCLED_HANGUL_SYLLABLE":
1111
+ return n <= 14 ? String.fromCodePoint(12910 + n - 1) : HANGUL_SYLLABLE_SEQ[(n - 1) % 14];
1112
+ case "HANGUL_JAMO":
1113
+ return HANGUL_JAMO_SEQ[(n - 1) % HANGUL_JAMO_SEQ.length];
1114
+ case "CIRCLED_HANGUL_JAMO":
1115
+ return n <= 14 ? String.fromCodePoint(12896 + n - 1) : HANGUL_JAMO_SEQ[(n - 1) % 14];
1116
+ case "LATIN_CAPITAL":
1117
+ return String.fromCharCode(65 + (n - 1) % 26);
1118
+ case "LATIN_SMALL":
1119
+ return String.fromCharCode(97 + (n - 1) % 26);
1120
+ case "CIRCLED_LATIN_CAPITAL":
1121
+ return n <= 26 ? String.fromCodePoint(9398 + n - 1) : String.fromCharCode(65 + (n - 1) % 26);
1122
+ case "CIRCLED_LATIN_SMALL":
1123
+ return n <= 26 ? String.fromCodePoint(9424 + n - 1) : String.fromCharCode(97 + (n - 1) % 26);
1124
+ case "ROMAN_CAPITAL":
1125
+ return toRoman(n);
1126
+ case "ROMAN_SMALL":
1127
+ return toRoman(n).toLowerCase();
1128
+ default:
1129
+ return String(n);
1431
1130
  }
1432
- for (const block of blocks) {
1433
- if (block.type !== "paragraph" || !block.text) continue;
1434
- const text = block.text.trim();
1435
- if (text.length === 0 || text.length > 200 || /^\d+$/.test(text)) continue;
1436
- let level = 0;
1437
- if (baseFontSize > 0 && _optionalChain([block, 'access', _25 => _25.style, 'optionalAccess', _26 => _26.fontSize])) {
1438
- const ratio = block.style.fontSize / baseFontSize;
1439
- if (ratio >= _chunkQZCP3UWUcjs.HEADING_RATIO_H1) level = 1;
1440
- else if (ratio >= _chunkQZCP3UWUcjs.HEADING_RATIO_H2) level = 2;
1441
- else if (ratio >= _chunkQZCP3UWUcjs.HEADING_RATIO_H3) level = 3;
1442
- }
1443
- const compactText = text.replace(/\s+/g, "");
1444
- if (/^제\d+[조장절편]/.test(compactText) && text.length <= 50) {
1445
- if (level === 0) level = 3;
1446
- }
1447
- if (level > 0) {
1448
- block.type = "heading";
1449
- block.level = level;
1450
- }
1131
+ }
1132
+ function resolveParaHeading(paraEl, ctx) {
1133
+ const sm = ctx.styleMap;
1134
+ if (!sm) return null;
1135
+ const prId = paraEl.getAttribute("paraPrIDRef");
1136
+ if (!prId) return null;
1137
+ const ref = sm.paraHeadings.get(prId);
1138
+ if (!ref) return null;
1139
+ if (ref.type === "BULLET") {
1140
+ const char = sm.bullets.get(ref.idRef);
1141
+ return char ? { prefix: char } : null;
1142
+ }
1143
+ const numId = ref.type === "OUTLINE" ? ctx.outlineNumId || "1" : ref.idRef;
1144
+ const level = Math.min(ref.level + 1, 10);
1145
+ const headingLevel = ref.type === "OUTLINE" ? Math.min(ref.level + 1, 6) : void 0;
1146
+ const numDef = sm.numberings.get(numId);
1147
+ if (!numDef) return headingLevel ? { headingLevel } : null;
1148
+ let counters = ctx.shared.numState.get(numId);
1149
+ if (!counters) {
1150
+ counters = new Array(11).fill(0);
1151
+ ctx.shared.numState.set(numId, counters);
1451
1152
  }
1153
+ const head = numDef.heads.get(level);
1154
+ counters[level] = counters[level] === 0 ? _nullishCoalesce(_optionalChain([head, 'optionalAccess', _9 => _9.start]), () => ( 1)) : counters[level] + 1;
1155
+ for (let l = level + 1; l <= 10; l++) counters[l] = 0;
1156
+ const fmtText = _optionalChain([head, 'optionalAccess', _10 => _10.text, 'optionalAccess', _11 => _11.trim, 'call', _12 => _12()]) || `^${level}.`;
1157
+ const prefix = fmtText.replace(/\^(10|[1-9])/g, (_, d) => {
1158
+ const lv = parseInt(d, 10);
1159
+ const refHead = numDef.heads.get(lv);
1160
+ const n = counters[lv] || _optionalChain([refHead, 'optionalAccess', _13 => _13.start]) || 1;
1161
+ return formatHeadNumber(n, _optionalChain([refHead, 'optionalAccess', _14 => _14.numFormat]) || "DIGIT");
1162
+ });
1163
+ return { prefix, headingLevel };
1452
1164
  }
1165
+
1166
+ // src/hwpx/table-build.ts
1453
1167
  function buildTableWithCellMeta(state) {
1454
- const table = _chunkQZCP3UWUcjs.buildTable.call(void 0, state.rows);
1168
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, state.rows);
1455
1169
  if (state.caption) table.caption = state.caption;
1456
1170
  const anchors = [];
1457
1171
  {
@@ -1459,7 +1173,7 @@ function buildTableWithCellMeta(state) {
1459
1173
  for (let r = 0; r < table.rows; r++) {
1460
1174
  for (let c = 0; c < table.cols; c++) {
1461
1175
  if (covered.has(`${r},${c}`)) continue;
1462
- const cell = _optionalChain([table, 'access', _27 => _27.cells, 'access', _28 => _28[r], 'optionalAccess', _29 => _29[c]]);
1176
+ const cell = _optionalChain([table, 'access', _15 => _15.cells, 'access', _16 => _16[r], 'optionalAccess', _17 => _17[c]]);
1463
1177
  if (!cell) continue;
1464
1178
  for (let dr = 0; dr < cell.rowSpan; dr++) {
1465
1179
  for (let dc = 0; dc < cell.colSpan; dc++) {
@@ -1484,7 +1198,7 @@ function buildTableWithCellMeta(state) {
1484
1198
  let target;
1485
1199
  const trimmed = src.text.trim();
1486
1200
  if (src.rowAddr !== void 0 && src.colAddr !== void 0) {
1487
- const cand = _optionalChain([table, 'access', _30 => _30.cells, 'access', _31 => _31[src.rowAddr], 'optionalAccess', _32 => _32[src.colAddr]]);
1201
+ const cand = _optionalChain([table, 'access', _18 => _18.cells, 'access', _19 => _19[src.rowAddr], 'optionalAccess', _20 => _20[src.colAddr]]);
1488
1202
  if (cand && cand.text === trimmed && !claimed.has(cand)) target = cand;
1489
1203
  }
1490
1204
  if (!target) {
@@ -1517,11 +1231,11 @@ function completeTable(newTable, tableStack, blocks, ctx) {
1517
1231
  }
1518
1232
  const ir = buildTableWithCellMeta(newTable);
1519
1233
  const block = { type: "table", table: ir, pageNumber: ctx.sectionNum };
1520
- if (_optionalChain([parentTable, 'optionalAccess', _33 => _33.cell])) {
1234
+ if (_optionalChain([parentTable, 'optionalAccess', _21 => _21.cell])) {
1521
1235
  const cell = parentTable.cell;
1522
1236
  (cell.blocks ??= []).push(block);
1523
1237
  cell.hasStructure = true;
1524
- let flat = _chunkQZCP3UWUcjs.convertTableToText.call(void 0, newTable.rows);
1238
+ let flat = _chunkLFCS3UVGcjs.convertTableToText.call(void 0, newTable.rows);
1525
1239
  if (newTable.caption) flat = newTable.caption + (flat ? "\n" + flat : "");
1526
1240
  if (flat) cell.text += (cell.text ? "\n" : "") + flat;
1527
1241
  } else {
@@ -1529,9 +1243,11 @@ function completeTable(newTable, tableStack, blocks, ctx) {
1529
1243
  }
1530
1244
  return parentTable;
1531
1245
  }
1246
+
1247
+ // src/hwpx/section-walker.ts
1532
1248
  function parseSectionXml(xml, styleMap, warnings, sectionNum, shared) {
1533
1249
  const parser = createXmlParser(warnings);
1534
- const doc = parser.parseFromString(_chunkQZCP3UWUcjs.stripDtd.call(void 0, xml), "text/xml");
1250
+ const doc = parser.parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, xml), "text/xml");
1535
1251
  if (!doc.documentElement) return [];
1536
1252
  const ctx = { styleMap, warnings, sectionNum, shared: _nullishCoalesce(shared, () => ( createSectionShared())) };
1537
1253
  ctx.shared.track.deleteDepth = 0;
@@ -1609,7 +1325,7 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1609
1325
  }
1610
1326
  break;
1611
1327
  case "cellAddr":
1612
- if (_optionalChain([tableCtx, 'optionalAccess', _34 => _34.cell])) {
1328
+ if (_optionalChain([tableCtx, 'optionalAccess', _22 => _22.cell])) {
1613
1329
  const ca = parseInt(el.getAttribute("colAddr") || "", 10);
1614
1330
  const ra = parseInt(el.getAttribute("rowAddr") || "", 10);
1615
1331
  if (!isNaN(ca)) tableCtx.cell.colAddr = ca;
@@ -1617,13 +1333,13 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1617
1333
  }
1618
1334
  break;
1619
1335
  case "cellSpan":
1620
- if (_optionalChain([tableCtx, 'optionalAccess', _35 => _35.cell])) {
1336
+ if (_optionalChain([tableCtx, 'optionalAccess', _23 => _23.cell])) {
1621
1337
  const rawCs = parseInt(el.getAttribute("colSpan") || "1", 10);
1622
1338
  const cs = isNaN(rawCs) ? 1 : rawCs;
1623
1339
  const rawRs = parseInt(el.getAttribute("rowSpan") || "1", 10);
1624
1340
  const rs = isNaN(rawRs) ? 1 : rawRs;
1625
- tableCtx.cell.colSpan = clampSpan(cs, _chunkQZCP3UWUcjs.MAX_COLS);
1626
- tableCtx.cell.rowSpan = clampSpan(rs, _chunkQZCP3UWUcjs.MAX_ROWS);
1341
+ tableCtx.cell.colSpan = clampSpan(cs, _chunkLFCS3UVGcjs.MAX_COLS);
1342
+ tableCtx.cell.rowSpan = clampSpan(rs, _chunkLFCS3UVGcjs.MAX_ROWS);
1627
1343
  }
1628
1344
  break;
1629
1345
  case "p": {
@@ -1632,11 +1348,11 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1632
1348
  let headingLevel;
1633
1349
  if (text) {
1634
1350
  const ph = resolveParaHeading(el, ctx);
1635
- if (_optionalChain([ph, 'optionalAccess', _36 => _36.prefix])) text = ph.prefix + " " + text;
1636
- headingLevel = _optionalChain([ph, 'optionalAccess', _37 => _37.headingLevel]);
1351
+ if (_optionalChain([ph, 'optionalAccess', _24 => _24.prefix])) text = ph.prefix + " " + text;
1352
+ headingLevel = _optionalChain([ph, 'optionalAccess', _25 => _25.headingLevel]);
1637
1353
  }
1638
1354
  if (text) {
1639
- if (_optionalChain([tableCtx, 'optionalAccess', _38 => _38.cell])) {
1355
+ if (_optionalChain([tableCtx, 'optionalAccess', _26 => _26.cell])) {
1640
1356
  const cell = tableCtx.cell;
1641
1357
  if (footnote) text += ` (\uC8FC: ${footnote})`;
1642
1358
  cell.text += (cell.text ? "\n" : "") + text;
@@ -1659,7 +1375,7 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1659
1375
  case "pic":
1660
1376
  case "shape":
1661
1377
  case "drawingObject": {
1662
- if (_optionalChain([tableCtx, 'optionalAccess', _39 => _39.cell])) {
1378
+ if (_optionalChain([tableCtx, 'optionalAccess', _27 => _27.cell])) {
1663
1379
  const sink = [];
1664
1380
  handleShape(el, sink, ctx);
1665
1381
  mergeBlocksIntoCell(tableCtx.cell, sink);
@@ -1768,7 +1484,7 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
1768
1484
  walkSection(el, blocks, newTable, tableStack, ctx, d + 1);
1769
1485
  tableCtx = completeTable(newTable, tableStack, blocks, ctx);
1770
1486
  } else if (localTag === "pic" || localTag === "shape" || localTag === "drawingObject") {
1771
- if (_optionalChain([tableCtx, 'optionalAccess', _40 => _40.cell])) {
1487
+ if (_optionalChain([tableCtx, 'optionalAccess', _28 => _28.cell])) {
1772
1488
  const sink = [];
1773
1489
  handleShape(el, sink, ctx);
1774
1490
  mergeBlocksIntoCell(tableCtx.cell, sink);
@@ -1776,7 +1492,7 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
1776
1492
  handleShape(el, blocks, ctx);
1777
1493
  }
1778
1494
  } else if (localTag === "drawText") {
1779
- if (_optionalChain([tableCtx, 'optionalAccess', _41 => _41.cell])) {
1495
+ if (_optionalChain([tableCtx, 'optionalAccess', _29 => _29.cell])) {
1780
1496
  const sink = [];
1781
1497
  extractDrawTextBlocks(el, sink, ctx);
1782
1498
  mergeBlocksIntoCell(tableCtx.cell, sink);
@@ -1820,7 +1536,7 @@ function extractDrawTextBlocks(drawTextNode, blocks, ctx) {
1820
1536
  let text = info.text.trim();
1821
1537
  if (text) {
1822
1538
  const ph = resolveParaHeading(child, ctx);
1823
- if (_optionalChain([ph, 'optionalAccess', _42 => _42.prefix])) text = ph.prefix + " " + text;
1539
+ if (_optionalChain([ph, 'optionalAccess', _30 => _30.prefix])) text = ph.prefix + " " + text;
1824
1540
  const block = { type: "paragraph", text, style: _nullishCoalesce(info.style, () => ( void 0)), pageNumber: ctx.sectionNum };
1825
1541
  if (info.href) block.href = info.href;
1826
1542
  if (info.footnote) block.footnoteText = info.footnote;
@@ -1845,13 +1561,13 @@ function extractHyperlinkHref(fieldBegin) {
1845
1561
  let url = (ch.textContent || "").trim();
1846
1562
  if (!url) continue;
1847
1563
  url = url.replace(/^https?:\/\/(?=https?:\/\/)/i, "");
1848
- const safe = _chunkQZCP3UWUcjs.sanitizeHref.call(void 0, url);
1564
+ const safe = _chunkLFCS3UVGcjs.sanitizeHref.call(void 0, url);
1849
1565
  if (safe) return safe;
1850
1566
  }
1851
1567
  return void 0;
1852
1568
  }
1853
1569
  function isInDeletedRange(ctx) {
1854
- 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;
1855
1571
  }
1856
1572
  function extractParagraphInfo(para, styleMap, ctx) {
1857
1573
  let text = "";
@@ -1905,7 +1621,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1905
1621
  // 삽입분은 최종본에 포함
1906
1622
  // 숨은 설명 — 본문 혼입 차단
1907
1623
  case "hiddenComment": {
1908
- if (_optionalChain([ctx, 'optionalAccess', _46 => _46.warnings]) && extractTextFromNode(k)) {
1624
+ if (_optionalChain([ctx, 'optionalAccess', _34 => _34.warnings]) && extractTextFromNode(k)) {
1909
1625
  ctx.warnings.push({ page: ctx.sectionNum, message: "\uC228\uC740 \uC124\uBA85 \uD14D\uC2A4\uD2B8 \uC81C\uC678: hiddenComment", code: "HIDDEN_TEXT_FILTERED" });
1910
1626
  }
1911
1627
  break;
@@ -1922,7 +1638,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1922
1638
  break;
1923
1639
  // 미지원 요소 — 텍스트를 가졌으면 무음 손실 대신 경고
1924
1640
  default: {
1925
- if (_optionalChain([ctx, 'optionalAccess', _47 => _47.warnings]) && extractTextFromNode(k)) {
1641
+ if (_optionalChain([ctx, 'optionalAccess', _35 => _35.warnings]) && extractTextFromNode(k)) {
1926
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" });
1927
1643
  }
1928
1644
  }
@@ -1939,7 +1655,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1939
1655
  if (isInDeletedRange(ctx)) {
1940
1656
  if (t && ctx && !ctx.shared.track.warned) {
1941
1657
  ctx.shared.track.warned = true;
1942
- _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" })]);
1943
1659
  }
1944
1660
  } else {
1945
1661
  text += t;
@@ -1980,7 +1696,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
1980
1696
  case "hyperlink": {
1981
1697
  const url = child.getAttribute("url") || child.getAttribute("href") || "";
1982
1698
  if (url) {
1983
- const safe = _chunkQZCP3UWUcjs.sanitizeHref.call(void 0, url);
1699
+ const safe = _chunkLFCS3UVGcjs.sanitizeHref.call(void 0, url);
1984
1700
  if (safe) href = safe;
1985
1701
  }
1986
1702
  walk(child);
@@ -2045,7 +1761,7 @@ function extractParagraphInfo(para, styleMap, ctx) {
2045
1761
  try {
2046
1762
  const latex = hmlToLatex(raw).trim();
2047
1763
  if (latex) text += " $" + latex + "$ ";
2048
- } catch (e15) {
1764
+ } catch (e12) {
2049
1765
  }
2050
1766
  }
2051
1767
  break;
@@ -2062,49 +1778,357 @@ function extractParagraphInfo(para, styleMap, ctx) {
2062
1778
  break;
2063
1779
  }
2064
1780
  }
2065
- };
2066
- walk(para);
2067
- const leaderIdx = text.indexOf("");
2068
- if (leaderIdx >= 0) text = text.substring(0, leaderIdx);
2069
- let cleanText = text.replace(/[ \t]+/g, " ").trim();
2070
- if (/^그림입니다\.?\s*원본\s*그림의\s*(이름|크기)/.test(cleanText)) cleanText = "";
2071
- cleanText = cleanText.replace(/그림입니다\.?\s*원본\s*그림의\s*(이름|크기)[^\n]*(\n[^\n]*원본\s*그림의\s*(이름|크기)[^\n]*)*/g, "").trim();
2072
- cleanText = cleanText.replace(/(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\s?개체|묶음\s?개체|글상자|표|그림|OLE\s?개체)\s?입니다\.?/g, "").trim();
2073
- let style;
2074
- if (styleMap && charPrId) {
2075
- const charProp = styleMap.charProperties.get(charPrId);
2076
- if (charProp) {
2077
- style = {};
2078
- if (charProp.fontSize) style.fontSize = charProp.fontSize;
2079
- if (charProp.bold) style.bold = true;
2080
- if (charProp.italic) style.italic = true;
2081
- if (charProp.fontName) style.fontName = charProp.fontName;
2082
- if (!style.fontSize && !style.bold && !style.italic) style = void 0;
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
+ }
1881
+ }
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);
1898
+ break;
1899
+ } catch (err) {
1900
+ if (err instanceof _chunkLFCS3UVGcjs.KordocError) throw err;
1901
+ }
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);
1905
+ }
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;
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})`);
1915
+ }
1916
+ return images;
1917
+ }
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;
2083
1985
  }
2084
1986
  }
2085
- return { text: cleanText, href, footnote, style };
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 };
2086
1991
  }
2087
- function findChildByLocalName(parent, name) {
2088
- const children = parent.childNodes;
2089
- if (!children) return null;
2090
- for (let i = 0; i < children.length; i++) {
2091
- const ch = children[i];
2092
- if (ch.nodeType !== 1) continue;
2093
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
2094
- if (tag === name) return ch;
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;
2095
2001
  }
2096
- return null;
2002
+ const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/);
2003
+ return sectionFiles.map((f) => f.name).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
2097
2004
  }
2098
- function extractTextFromNode(node) {
2099
- let result = "";
2100
- const children = node.childNodes;
2101
- if (!children) return result;
2102
- for (let i = 0; i < children.length; i++) {
2103
- const child = children[i];
2104
- if (child.nodeType === 3) result += child.textContent || "";
2105
- else if (child.nodeType === 1) result += extractTextFromNode(child);
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);
2106
2016
  }
2107
- return result.trim();
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 };
2108
2132
  }
2109
2133
 
2110
2134
  // src/hwp5/record.ts
@@ -2170,7 +2194,7 @@ function decompressStream(data) {
2170
2194
  return _zlib.inflateRawSync.call(void 0, data, opts);
2171
2195
  }
2172
2196
  function parseFileHeader(data) {
2173
- if (data.length < 40) throw new (0, _chunkQZCP3UWUcjs.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)");
2174
2198
  const sig = data.subarray(0, 32).toString("utf8").replace(/\0+$/, "");
2175
2199
  return {
2176
2200
  signature: sig,
@@ -2631,32 +2655,42 @@ function resolveImageBlocks(binDataMap, blocks, warnings) {
2631
2655
  if (imageBlocks.length === 0) return [];
2632
2656
  const images = [];
2633
2657
  const renamed = /* @__PURE__ */ new Map();
2658
+ const resolved = /* @__PURE__ */ new Map();
2634
2659
  let imageIndex = 0;
2635
2660
  for (const block of imageBlocks) {
2636
2661
  if (!block.text) continue;
2637
2662
  const storageId = parseInt(block.text, 10);
2638
2663
  if (isNaN(storageId)) continue;
2639
- const bin = binDataMap.get(storageId);
2640
- if (!bin) {
2641
- warnings.push({ page: block.pageNumber, message: `BinData ${storageId} \uC5C6\uC74C`, code: "SKIPPED_IMAGE" });
2642
- block.type = "paragraph";
2643
- block.text = `[\uC774\uBBF8\uC9C0: BinData ${storageId}]`;
2644
- continue;
2664
+ let img = resolved.get(storageId);
2665
+ if (img === void 0) {
2666
+ const bin = binDataMap.get(storageId);
2667
+ if (!bin) {
2668
+ warnings.push({ page: block.pageNumber, message: `BinData ${storageId} \uC5C6\uC74C`, code: "SKIPPED_IMAGE" });
2669
+ resolved.set(storageId, null);
2670
+ } else {
2671
+ const mime = detectImageMime(bin.data);
2672
+ if (!mime) {
2673
+ warnings.push({ page: block.pageNumber, message: `BinData ${storageId}: \uC54C \uC218 \uC5C6\uB294 \uC774\uBBF8\uC9C0 \uD615\uC2DD`, code: "SKIPPED_IMAGE" });
2674
+ resolved.set(storageId, null);
2675
+ } else {
2676
+ imageIndex++;
2677
+ const ext = mime.includes("jpeg") ? "jpg" : mime.includes("png") ? "png" : mime.includes("gif") ? "gif" : mime.includes("bmp") ? "bmp" : "bin";
2678
+ img = { filename: `image_${String(imageIndex).padStart(3, "0")}.${ext}`, data: new Uint8Array(bin.data), mime };
2679
+ resolved.set(storageId, img);
2680
+ images.push({ filename: img.filename, data: img.data, mimeType: img.mime });
2681
+ renamed.set(storageId, img.filename);
2682
+ }
2683
+ }
2684
+ img = resolved.get(storageId);
2645
2685
  }
2646
- const mime = detectImageMime(bin.data);
2647
- if (!mime) {
2648
- warnings.push({ page: block.pageNumber, message: `BinData ${storageId}: \uC54C \uC218 \uC5C6\uB294 \uC774\uBBF8\uC9C0 \uD615\uC2DD`, code: "SKIPPED_IMAGE" });
2686
+ if (!img) {
2687
+ const bin = binDataMap.get(storageId);
2649
2688
  block.type = "paragraph";
2650
- block.text = `[\uC774\uBBF8\uC9C0: ${bin.name}]`;
2689
+ block.text = bin ? `[\uC774\uBBF8\uC9C0: ${bin.name}]` : `[\uC774\uBBF8\uC9C0: BinData ${storageId}]`;
2651
2690
  continue;
2652
2691
  }
2653
- imageIndex++;
2654
- const ext = mime.includes("jpeg") ? "jpg" : mime.includes("png") ? "png" : mime.includes("gif") ? "gif" : mime.includes("bmp") ? "bmp" : "bin";
2655
- const filename = `image_${String(imageIndex).padStart(3, "0")}.${ext}`;
2656
- images.push({ filename, data: new Uint8Array(bin.data), mimeType: mime });
2657
- renamed.set(storageId, filename);
2658
- block.text = filename;
2659
- block.imageData = { data: new Uint8Array(bin.data), mimeType: mime, filename: bin.name };
2692
+ block.text = img.filename;
2693
+ block.imageData = { data: img.data, mimeType: img.mime, filename: binDataMap.get(storageId).name };
2660
2694
  }
2661
2695
  resolveCellImageSentinels(blocks, renamed);
2662
2696
  return images;
@@ -3694,7 +3728,7 @@ function parseHwp5Document(buffer, options) {
3694
3728
  lenientCfb = parseLenientCfb(buffer);
3695
3729
  warnings.push({ message: "\uC190\uC0C1\uB41C CFB \uCEE8\uD14C\uC774\uB108 \u2014 lenient \uBAA8\uB4DC\uB85C \uBCF5\uAD6C", code: "LENIENT_CFB_RECOVERY" });
3696
3730
  } catch (e21) {
3697
- throw new (0, _chunkQZCP3UWUcjs.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)");
3698
3732
  }
3699
3733
  }
3700
3734
  const findStream = (path) => {
@@ -3705,11 +3739,11 @@ function parseHwp5Document(buffer, options) {
3705
3739
  return lenientCfb.findStream(path);
3706
3740
  };
3707
3741
  const headerData = findStream("/FileHeader");
3708
- if (!headerData) throw new (0, _chunkQZCP3UWUcjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
3742
+ if (!headerData) throw new (0, _chunkLFCS3UVGcjs.KordocError)("FileHeader \uC2A4\uD2B8\uB9BC \uC5C6\uC74C");
3709
3743
  const header = parseFileHeader(headerData);
3710
- if (header.signature !== "HWP Document File") throw new (0, _chunkQZCP3UWUcjs.KordocError)("HWP \uC2DC\uADF8\uB2C8\uCC98 \uBD88\uC77C\uCE58");
3711
- if (header.flags & FLAG_ENCRYPTED) throw new (0, _chunkQZCP3UWUcjs.KordocError)("\uC554\uD638\uD654\uB41C HWP\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
3712
- if (header.flags & FLAG_DRM) throw new (0, _chunkQZCP3UWUcjs.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");
3713
3747
  const compressed = (header.flags & FLAG_COMPRESSED) !== 0;
3714
3748
  const distribution = (header.flags & FLAG_DISTRIBUTION) !== 0;
3715
3749
  const metadata = {
@@ -3718,7 +3752,7 @@ function parseHwp5Document(buffer, options) {
3718
3752
  if (cfb) extractHwp5Metadata(cfb, metadata);
3719
3753
  const docInfo = cfb ? parseDocInfoStream(cfb, compressed) : parseDocInfoFromStream(findStream("/DocInfo"), compressed);
3720
3754
  const sections = distribution ? cfb ? findViewTextSections(cfb, compressed) : findViewTextSectionsLenient(lenientCfb, compressed) : cfb ? findSections(cfb) : findSectionsLenient(lenientCfb, compressed);
3721
- if (sections.length === 0) throw new (0, _chunkQZCP3UWUcjs.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");
3722
3756
  metadata.pageCount = sections.length;
3723
3757
  const pageFilter = _optionalChain([options, 'optionalAccess', _54 => _54.pages]) ? _chunkDCZVOIEOcjs.parsePageRange.call(void 0, options.pages, sections.length) : null;
3724
3758
  const totalTarget = pageFilter ? pageFilter.size : sections.length;
@@ -3732,25 +3766,25 @@ function parseHwp5Document(buffer, options) {
3732
3766
  const sectionData = sections[si];
3733
3767
  const data = !distribution && compressed ? decompressStream(Buffer.from(sectionData)) : Buffer.from(sectionData);
3734
3768
  totalDecompressed += data.length;
3735
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkQZCP3UWUcjs.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)");
3736
3770
  const records = readRecords(data);
3737
3771
  const sectionBlocks = parseSection(records, docInfo, warnings, si + 1, doc);
3738
3772
  bodyBlocks.push(...sectionBlocks);
3739
3773
  parsedSections++;
3740
3774
  _optionalChain([options, 'optionalAccess', _55 => _55.onProgress, 'optionalCall', _56 => _56(parsedSections, totalTarget)]);
3741
3775
  } catch (secErr) {
3742
- if (secErr instanceof _chunkQZCP3UWUcjs.KordocError) throw secErr;
3776
+ if (secErr instanceof _chunkLFCS3UVGcjs.KordocError) throw secErr;
3743
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" });
3744
3778
  }
3745
3779
  }
3746
3780
  const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
3747
3781
  const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings);
3748
- const flatBlocks = _chunkQZCP3UWUcjs.flattenLayoutTables.call(void 0, blocks);
3782
+ const flatBlocks = _chunkLFCS3UVGcjs.flattenLayoutTables.call(void 0, blocks);
3749
3783
  if (docInfo) {
3750
3784
  detectHwp5Headings(flatBlocks, docInfo);
3751
3785
  }
3752
3786
  const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
3753
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, flatBlocks);
3787
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, flatBlocks);
3754
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 };
3755
3789
  }
3756
3790
  function parseDocInfoStream(cfb, compressed) {
@@ -3810,9 +3844,9 @@ function detectHwp5Headings(blocks, docInfo) {
3810
3844
  let level = 0;
3811
3845
  if (_optionalChain([block, 'access', _61 => _61.style, 'optionalAccess', _62 => _62.fontSize]) && baseFontSize > 0) {
3812
3846
  const ratio = block.style.fontSize / baseFontSize;
3813
- if (ratio >= _chunkQZCP3UWUcjs.HEADING_RATIO_H1) level = 1;
3814
- else if (ratio >= _chunkQZCP3UWUcjs.HEADING_RATIO_H2) level = 2;
3815
- else if (ratio >= _chunkQZCP3UWUcjs.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;
3816
3850
  }
3817
3851
  if (/^제\d+[장절편]\s/.test(text) && text.length <= 50) {
3818
3852
  if (level === 0) level = 2;
@@ -3897,7 +3931,7 @@ function findSectionsLenient(lcfb, compressed) {
3897
3931
  if (!raw) break;
3898
3932
  const content = compressed ? decompressStream(raw) : raw;
3899
3933
  totalDecompressed += content.length;
3900
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkQZCP3UWUcjs.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)");
3901
3935
  sections.push({ idx: i, content });
3902
3936
  }
3903
3937
  if (sections.length === 0) {
@@ -3909,7 +3943,7 @@ function findSectionsLenient(lcfb, compressed) {
3909
3943
  if (raw) {
3910
3944
  const content = compressed ? decompressStream(raw) : raw;
3911
3945
  totalDecompressed += content.length;
3912
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkQZCP3UWUcjs.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)");
3913
3947
  sections.push({ idx, content });
3914
3948
  }
3915
3949
  }
@@ -3926,7 +3960,7 @@ function findViewTextSectionsLenient(lcfb, compressed) {
3926
3960
  try {
3927
3961
  const content = decryptViewText(raw, compressed);
3928
3962
  totalDecompressed += content.length;
3929
- if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new (0, _chunkQZCP3UWUcjs.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)");
3930
3964
  sections.push({ idx: i, content });
3931
3965
  } catch (e26) {
3932
3966
  break;
@@ -4029,7 +4063,7 @@ function parseParagraph(records, start, end, ctx) {
4029
4063
  const ctrl = ctrls[r.ctrlIdx];
4030
4064
  if (!_optionalChain([ctrl, 'optionalAccess', _69 => _69.href]) || r.end <= r.start) continue;
4031
4065
  if (applied.some(([s, e]) => r.start < e && r.end > s)) continue;
4032
- const href = _chunkQZCP3UWUcjs.sanitizeHref.call(void 0, ctrl.href);
4066
+ const href = _chunkLFCS3UVGcjs.sanitizeHref.call(void 0, ctrl.href);
4033
4067
  if (!href) continue;
4034
4068
  const anchor = text.slice(r.start, r.end);
4035
4069
  if (!anchor.trim()) continue;
@@ -4262,8 +4296,8 @@ function parseTableControl(ctrl, records, ctx) {
4262
4296
  let tableIdx = -1;
4263
4297
  for (let i2 = childStart; i2 < childEnd; i2++) {
4264
4298
  if (records[i2].tagId === TAG_TABLE && records[i2].data.length >= 8) {
4265
- rows = Math.min(records[i2].data.readUInt16LE(4), _chunkQZCP3UWUcjs.MAX_ROWS);
4266
- cols = Math.min(records[i2].data.readUInt16LE(6), _chunkQZCP3UWUcjs.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);
4267
4301
  tableIdx = i2;
4268
4302
  break;
4269
4303
  }
@@ -4312,7 +4346,7 @@ function parseTableControl(ctrl, records, ctx) {
4312
4346
  return table2;
4313
4347
  }
4314
4348
  const cellRows = arrangeCells(rows, cols, cells);
4315
- const table = _chunkQZCP3UWUcjs.buildTable.call(void 0, cellRows);
4349
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
4316
4350
  if (caption && table.rows > 0) table.caption = caption;
4317
4351
  return table.rows > 0 ? table : null;
4318
4352
  }
@@ -4329,8 +4363,8 @@ function parseCell(records, lhIdx, end, ctx) {
4329
4363
  rowAddr = rec.data.readUInt16LE(10);
4330
4364
  const cs = rec.data.readUInt16LE(12);
4331
4365
  const rs = rec.data.readUInt16LE(14);
4332
- if (cs > 0) colSpan = Math.min(cs, _chunkQZCP3UWUcjs.MAX_COLS);
4333
- if (rs > 0) rowSpan = Math.min(rs, _chunkQZCP3UWUcjs.MAX_ROWS);
4366
+ if (cs > 0) colSpan = Math.min(cs, _chunkLFCS3UVGcjs.MAX_COLS);
4367
+ if (rs > 0) rowSpan = Math.min(rs, _chunkLFCS3UVGcjs.MAX_ROWS);
4334
4368
  }
4335
4369
  const blocks = ctx.depth < MAX_NEST_DEPTH ? parseParagraphList(records, lhIdx + 1, end, { ...ctx, depth: ctx.depth + 1 }) : [];
4336
4370
  const parts = [];
@@ -4340,7 +4374,7 @@ function parseCell(records, lhIdx, end, ctx) {
4340
4374
  parts.push(`![image](hwp5bin:${b.text})`);
4341
4375
  hasStructure = true;
4342
4376
  } else if (b.type === "table" && b.table) {
4343
- const flat = _chunkQZCP3UWUcjs.convertTableToText.call(void 0, b.table.cells);
4377
+ const flat = _chunkLFCS3UVGcjs.convertTableToText.call(void 0, b.table.cells);
4344
4378
  if (flat) parts.push(flat);
4345
4379
  hasStructure = true;
4346
4380
  } else if (b.text) {
@@ -16774,7 +16808,7 @@ function getTextContent(el) {
16774
16808
  return _nullishCoalesce(_optionalChain([el, 'access', _82 => _82.textContent, 'optionalAccess', _83 => _83.trim, 'call', _84 => _84()]), () => ( ""));
16775
16809
  }
16776
16810
  function parseXml(text) {
16777
- return new (0, _xmldom.DOMParser)().parseFromString(_chunkQZCP3UWUcjs.stripDtd.call(void 0, text), "text/xml");
16811
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, text), "text/xml");
16778
16812
  }
16779
16813
  function parseSharedStrings(xml) {
16780
16814
  const doc = parseXml(xml);
@@ -16918,7 +16952,7 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
16918
16952
  cellRows.push(row);
16919
16953
  }
16920
16954
  if (cellRows.length > 0) {
16921
- const table = _chunkQZCP3UWUcjs.buildTable.call(void 0, cellRows);
16955
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
16922
16956
  if (table.rows > 0) {
16923
16957
  blocks.push({ type: "table", table, pageNumber: sheetIndex + 1 });
16924
16958
  }
@@ -16926,12 +16960,12 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
16926
16960
  return blocks;
16927
16961
  }
16928
16962
  async function parseXlsxDocument(buffer, options) {
16929
- _chunkQZCP3UWUcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
16963
+ _chunkLFCS3UVGcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE3);
16930
16964
  const zip = await _jszip2.default.loadAsync(buffer);
16931
16965
  const warnings = [];
16932
16966
  const workbookFile = zip.file("xl/workbook.xml");
16933
16967
  if (!workbookFile) {
16934
- throw new (0, _chunkQZCP3UWUcjs.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");
16935
16969
  }
16936
16970
  let sharedStrings = [];
16937
16971
  const ssFile = zip.file("xl/sharedStrings.xml");
@@ -16940,7 +16974,7 @@ async function parseXlsxDocument(buffer, options) {
16940
16974
  }
16941
16975
  const sheets = parseWorkbook(await workbookFile.async("text"));
16942
16976
  if (sheets.length === 0) {
16943
- throw new (0, _chunkQZCP3UWUcjs.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");
16944
16978
  }
16945
16979
  let relsMap = /* @__PURE__ */ new Map();
16946
16980
  const relsFile = zip.file("xl/_rels/workbook.xml.rels");
@@ -17012,7 +17046,7 @@ async function parseXlsxDocument(buffer, options) {
17012
17046
  } catch (e27) {
17013
17047
  }
17014
17048
  }
17015
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, blocks);
17049
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
17016
17050
  return { markdown, blocks, metadata, warnings: warnings.length > 0 ? warnings : void 0 };
17017
17051
  }
17018
17052
 
@@ -17419,11 +17453,11 @@ function processGlobals(records) {
17419
17453
  let encrypted = false;
17420
17454
  const firstBof = records[0];
17421
17455
  if (!firstBof || firstBof.opcode !== OP_BOF) {
17422
- throw new (0, _chunkQZCP3UWUcjs.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");
17423
17457
  }
17424
17458
  const bof = decodeBof(firstBof.data);
17425
17459
  if (!bof || bof.dt !== DT_GLOBALS) {
17426
- throw new (0, _chunkQZCP3UWUcjs.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");
17427
17461
  }
17428
17462
  let i = 1;
17429
17463
  while (i < records.length) {
@@ -17538,7 +17572,7 @@ function sheetToBlocks2(sheetName, sheet, sheetIndex) {
17538
17572
  cellRows.push(row);
17539
17573
  }
17540
17574
  if (cellRows.length > 0) {
17541
- const table = _chunkQZCP3UWUcjs.buildTable.call(void 0, cellRows);
17575
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
17542
17576
  if (table.rows > 0) {
17543
17577
  blocks.push({ type: "table", table, pageNumber: sheetIndex + 1 });
17544
17578
  }
@@ -17551,21 +17585,21 @@ async function parseXlsDocument(buffer, options) {
17551
17585
  try {
17552
17586
  cfb = parseLenientCfb(buf);
17553
17587
  } catch (e) {
17554
- throw new (0, _chunkQZCP3UWUcjs.KordocError)(
17588
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
17555
17589
  `XLS: OLE2 \uC2DC\uADF8\uB2C8\uCC98 \uAC80\uC99D \uC2E4\uD328 \u2014 ${e instanceof Error ? e.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`
17556
17590
  );
17557
17591
  }
17558
17592
  const wb = _nullishCoalesce(cfb.findStream("/Workbook"), () => ( cfb.findStream("/Book")));
17559
17593
  if (!wb) {
17560
- throw new (0, _chunkQZCP3UWUcjs.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)");
17561
17595
  }
17562
17596
  const records = readRecords2(wb);
17563
17597
  if (records.length === 0) {
17564
- throw new (0, _chunkQZCP3UWUcjs.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)");
17565
17599
  }
17566
17600
  const firstBof = decodeBof(records[0].data);
17567
17601
  if (firstBof && firstBof.vers !== 1536) {
17568
- throw new (0, _chunkQZCP3UWUcjs.KordocError)(
17602
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
17569
17603
  `XLS: BIFF8(0x0600)\uB9CC \uC9C0\uC6D0 \u2014 \uBCF8 \uD30C\uC77C\uC740 0x${firstBof.vers.toString(16)}`
17570
17604
  );
17571
17605
  }
@@ -17625,7 +17659,7 @@ async function parseXlsDocument(buffer, options) {
17625
17659
  pageCount: totalSheets
17626
17660
  };
17627
17661
  return {
17628
- markdown: _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, allBlocks),
17662
+ markdown: _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, allBlocks),
17629
17663
  blocks: allBlocks,
17630
17664
  metadata,
17631
17665
  warnings: warnings.length > 0 ? warnings : void 0
@@ -18063,7 +18097,7 @@ function getAttr(el, localName2) {
18063
18097
  return null;
18064
18098
  }
18065
18099
  function parseXml2(text) {
18066
- return new (0, _xmldom.DOMParser)().parseFromString(_chunkQZCP3UWUcjs.stripDtd.call(void 0, text), "text/xml");
18100
+ return new (0, _xmldom.DOMParser)().parseFromString(_chunkLFCS3UVGcjs.stripDtd.call(void 0, text), "text/xml");
18067
18101
  }
18068
18102
  function parseStyles(xml) {
18069
18103
  const doc = parseXml2(xml);
@@ -18344,7 +18378,7 @@ function parseTable(tbl, styles, numbering, footnotes, rels) {
18344
18378
  };
18345
18379
  return { type: "table", table };
18346
18380
  }
18347
- async function extractImages(zip, rels, doc) {
18381
+ async function extractImages(zip, rels, doc, warnings) {
18348
18382
  const blocks = [];
18349
18383
  const images = [];
18350
18384
  const drawingElements = findElements(doc.documentElement, "drawing");
@@ -18375,19 +18409,23 @@ async function extractImages(zip, rels, doc) {
18375
18409
  const filename = `image_${String(imgIdx).padStart(3, "0")}.${ext}`;
18376
18410
  images.push({ filename, data, mimeType: _nullishCoalesce(mimeMap[ext], () => ( "image/png")) });
18377
18411
  blocks.push({ type: "image", text: filename });
18378
- } catch (e28) {
18412
+ } catch (err) {
18413
+ warnings.push({
18414
+ code: "SKIPPED_IMAGE",
18415
+ message: `DOCX \uC774\uBBF8\uC9C0 \uCD94\uCD9C \uC2E4\uD328 (${imgPath}): ${err instanceof Error ? err.message : String(err)}`
18416
+ });
18379
18417
  }
18380
18418
  }
18381
18419
  }
18382
18420
  return { blocks, images };
18383
18421
  }
18384
18422
  async function parseDocxDocument(buffer, options) {
18385
- _chunkQZCP3UWUcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
18423
+ _chunkLFCS3UVGcjs.precheckZipSize.call(void 0, buffer, MAX_DECOMPRESS_SIZE4);
18386
18424
  const zip = await _jszip2.default.loadAsync(buffer);
18387
18425
  const warnings = [];
18388
18426
  const docFile = zip.file("word/document.xml");
18389
18427
  if (!docFile) {
18390
- throw new (0, _chunkQZCP3UWUcjs.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");
18391
18429
  }
18392
18430
  let rels = /* @__PURE__ */ new Map();
18393
18431
  const relsFile = zip.file("word/_rels/document.xml.rels");
@@ -18399,7 +18437,11 @@ async function parseDocxDocument(buffer, options) {
18399
18437
  if (stylesFile) {
18400
18438
  try {
18401
18439
  styles = parseStyles(await stylesFile.async("text"));
18402
- } catch (e29) {
18440
+ } catch (err) {
18441
+ warnings.push({
18442
+ code: "PARTIAL_PARSE",
18443
+ message: `DOCX \uC2A4\uD0C0\uC77C(styles.xml) \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uAE30\uBCF8 \uC2A4\uD0C0\uC77C\uB85C \uACC4\uC18D: ${err instanceof Error ? err.message : String(err)}`
18444
+ });
18403
18445
  }
18404
18446
  }
18405
18447
  let numbering = /* @__PURE__ */ new Map();
@@ -18407,7 +18449,11 @@ async function parseDocxDocument(buffer, options) {
18407
18449
  if (numFile) {
18408
18450
  try {
18409
18451
  numbering = parseNumbering(await numFile.async("text"));
18410
- } catch (e30) {
18452
+ } catch (err) {
18453
+ warnings.push({
18454
+ code: "PARTIAL_PARSE",
18455
+ message: `DOCX \uBC88\uD638\uB9E4\uAE30\uAE30(numbering.xml) \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uBAA9\uB85D \uBC88\uD638 \uC0DD\uB7B5: ${err instanceof Error ? err.message : String(err)}`
18456
+ });
18411
18457
  }
18412
18458
  }
18413
18459
  let footnotes = /* @__PURE__ */ new Map();
@@ -18415,14 +18461,18 @@ async function parseDocxDocument(buffer, options) {
18415
18461
  if (fnFile) {
18416
18462
  try {
18417
18463
  footnotes = parseFootnotes(await fnFile.async("text"));
18418
- } catch (e31) {
18464
+ } catch (err) {
18465
+ warnings.push({
18466
+ code: "PARTIAL_PARSE",
18467
+ message: `DOCX \uAC01\uC8FC(footnotes.xml) \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uAC01\uC8FC \uC0DD\uB7B5: ${err instanceof Error ? err.message : String(err)}`
18468
+ });
18419
18469
  }
18420
18470
  }
18421
18471
  const docXml = await docFile.async("text");
18422
18472
  const doc = parseXml2(docXml);
18423
18473
  const body = findElements(doc, "body");
18424
18474
  if (body.length === 0) {
18425
- throw new (0, _chunkQZCP3UWUcjs.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");
18426
18476
  }
18427
18477
  const blocks = [];
18428
18478
  const bodyEl = body[0];
@@ -18437,7 +18487,7 @@ async function parseDocxDocument(buffer, options) {
18437
18487
  if (block) blocks.push(block);
18438
18488
  }
18439
18489
  }
18440
- const { blocks: imgBlocks, images } = await extractImages(zip, rels, doc);
18490
+ const { blocks: imgBlocks, images } = await extractImages(zip, rels, doc, warnings);
18441
18491
  const metadata = {};
18442
18492
  const coreFile = zip.file("docProps/core.xml");
18443
18493
  if (coreFile) {
@@ -18455,11 +18505,15 @@ async function parseDocxDocument(buffer, options) {
18455
18505
  if (created) metadata.createdAt = created;
18456
18506
  const modified = getFirst("dcterms:modified");
18457
18507
  if (modified) metadata.modifiedAt = modified;
18458
- } catch (e32) {
18508
+ } catch (err) {
18509
+ warnings.push({
18510
+ code: "PARTIAL_PARSE",
18511
+ message: `DOCX \uBA54\uD0C0\uB370\uC774\uD130(core.xml) \uD30C\uC2F1 \uC2E4\uD328: ${err instanceof Error ? err.message : String(err)}`
18512
+ });
18459
18513
  }
18460
18514
  }
18461
18515
  const outline = blocks.filter((b) => b.type === "heading").map((b) => ({ level: _nullishCoalesce(b.level, () => ( 2)), text: _nullishCoalesce(b.text, () => ( "")) }));
18462
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, blocks);
18516
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
18463
18517
  return {
18464
18518
  markdown,
18465
18519
  blocks,
@@ -18482,7 +18536,7 @@ function parseHwpmlDocument(buffer, options) {
18482
18536
  }
18483
18537
  const text = new TextDecoder("utf-8").decode(buffer).replace(/^\uFEFF/, "");
18484
18538
  const normalized = text.replace(/&nbsp;/g, "&#160;");
18485
- const xml = _chunkQZCP3UWUcjs.stripDtd.call(void 0, normalized);
18539
+ const xml = _chunkLFCS3UVGcjs.stripDtd.call(void 0, normalized);
18486
18540
  const warnings = [];
18487
18541
  const parser = new (0, _xmldom.DOMParser)({
18488
18542
  onError: (_level, msg2) => {
@@ -18522,7 +18576,7 @@ function parseHwpmlDocument(buffer, options) {
18522
18576
  parseSection2(el, blocks, paraShapeMap, sectionIdx, warnings);
18523
18577
  }
18524
18578
  const outline = blocks.filter((b) => b.type === "heading" && b.text).map((b) => ({ level: _nullishCoalesce(b.level, () => ( 1)), text: b.text, pageNumber: b.pageNumber }));
18525
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, blocks);
18579
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
18526
18580
  return {
18527
18581
  markdown,
18528
18582
  blocks,
@@ -18664,7 +18718,7 @@ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings) {
18664
18718
  const cellRows = grid.map(
18665
18719
  (row) => row.map((cell) => _nullishCoalesce(cell, () => ( { text: "", colSpan: 1, rowSpan: 1 })))
18666
18720
  );
18667
- const table = _chunkQZCP3UWUcjs.buildTable.call(void 0, cellRows);
18721
+ const table = _chunkLFCS3UVGcjs.buildTable.call(void 0, cellRows);
18668
18722
  blocks.push({ type: "table", table, pageNumber: sectionNum });
18669
18723
  }
18670
18724
  function extractCellText(cellEl) {
@@ -19308,7 +19362,7 @@ function decodeXmlEntities(text) {
19308
19362
  try {
19309
19363
  const code = ent[1] === "x" || ent[1] === "X" ? parseInt(ent.slice(2), 16) : parseInt(ent.slice(1), 10);
19310
19364
  if (!isNaN(code) && code >= 0 && code <= 1114111) return String.fromCodePoint(code);
19311
- } catch (e33) {
19365
+ } catch (e28) {
19312
19366
  }
19313
19367
  return m;
19314
19368
  });
@@ -19837,19 +19891,19 @@ function parseCentralDirectory(buf) {
19837
19891
  }
19838
19892
  }
19839
19893
  }
19840
- if (eocdOffset < 0) throw new (0, _chunkQZCP3UWUcjs.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");
19841
19895
  const totalEntries = view.getUint16(eocdOffset + 10, true);
19842
19896
  const cdSize = view.getUint32(eocdOffset + 12, true);
19843
19897
  const cdOffset = view.getUint32(eocdOffset + 16, true);
19844
- if (cdOffset === 4294967295 || totalEntries === 65535) throw new (0, _chunkQZCP3UWUcjs.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");
19845
19899
  if (eocdOffset >= 20 && view.getUint32(eocdOffset - 20, true) === ZIP64_EOCD_LOC_SIG) {
19846
- throw new (0, _chunkQZCP3UWUcjs.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");
19847
19901
  }
19848
19902
  const decoder = new TextDecoder("utf-8");
19849
19903
  const entries = [];
19850
19904
  let pos = cdOffset;
19851
19905
  for (let i = 0; i < totalEntries; i++) {
19852
- if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunkQZCP3UWUcjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
19906
+ if (view.getUint32(pos, true) !== CD_SIG) throw new (0, _chunkLFCS3UVGcjs.KordocError)("ZIP Central Directory \uC190\uC0C1");
19853
19907
  const flags = view.getUint16(pos + 8, true);
19854
19908
  const method = view.getUint16(pos + 10, true);
19855
19909
  const crc = view.getUint32(pos + 16, true);
@@ -19860,7 +19914,7 @@ function parseCentralDirectory(buf) {
19860
19914
  const commentLen = view.getUint16(pos + 32, true);
19861
19915
  const localOffset = view.getUint32(pos + 42, true);
19862
19916
  if (compSize === 4294967295 || uncompSize === 4294967295 || localOffset === 4294967295) {
19863
- throw new (0, _chunkQZCP3UWUcjs.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");
19864
19918
  }
19865
19919
  const name = decoder.decode(buf.subarray(pos + 46, pos + 46 + nameLen));
19866
19920
  const cdEnd = pos + 46 + nameLen + extraLen + commentLen;
@@ -19889,7 +19943,7 @@ function patchZipEntries(original, replacements) {
19889
19943
  const { entries, cdOffset, eocdOffset } = parseCentralDirectory(original);
19890
19944
  const view = new DataView(original.buffer, original.byteOffset, original.byteLength);
19891
19945
  for (const name of replacements.keys()) {
19892
- if (!entries.some((e) => e.name === name)) throw new (0, _chunkQZCP3UWUcjs.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}`);
19893
19947
  }
19894
19948
  const byLocal = [...entries].sort((a, b) => a.localOffset - b.localOffset);
19895
19949
  const segments = [];
@@ -19907,7 +19961,7 @@ function patchZipEntries(original, replacements) {
19907
19961
  offset += seg.length;
19908
19962
  continue;
19909
19963
  }
19910
- if (view.getUint32(e.localOffset, true) !== LOCAL_SIG) throw new (0, _chunkQZCP3UWUcjs.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");
19911
19965
  const nameLen = view.getUint16(e.localOffset + 26, true);
19912
19966
  const extraLen = view.getUint16(e.localOffset + 28, true);
19913
19967
  const headerLen = 30 + nameLen + extraLen;
@@ -19962,7 +20016,7 @@ async function fillHwpx(hwpxBuffer, values) {
19962
20016
  const zip = await _jszip2.default.loadAsync(hwpxBuffer);
19963
20017
  const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort();
19964
20018
  if (sectionPaths.length === 0) {
19965
- throw new (0, _chunkQZCP3UWUcjs.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");
19966
20020
  }
19967
20021
  const normalizedValues = normalizeValues(values);
19968
20022
  const cursor = new ValueCursor(normalizedValues);
@@ -20748,7 +20802,7 @@ function escapeGfm(text) {
20748
20802
  }
20749
20803
  var HWP_SHAPE_ALT_TEXT_RE = /(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|이등변 삼각형|직각 삼각형|선|직선|곡선|화살표|굵은 화살표|이중 화살표|오각형|육각형|팔각형|별|[4-8]점별|십자|십자형|구름|구름형|마름모|도넛|평행사변형|사다리꼴|부채꼴|호|반원|물결|번개|하트|빗금|블록 화살표|수식|표|그림|개체|그리기\s?개체|묶음\s?개체|글상자|수식\s?개체|OLE\s?개체)\s?입니다\.?/g;
20750
20804
  function sanitizeText(text) {
20751
- let result = _chunkQZCP3UWUcjs.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();
20752
20806
  if (result.length <= 30 && result.includes(" ")) {
20753
20807
  const tokens = result.split(" ");
20754
20808
  const koreanSingleCharCount = tokens.filter((t) => t.length === 1 && /[가-힯ㄱ-ㆎ]/.test(t)).length;
@@ -21580,9 +21634,22 @@ function precomputeGongmunList(blocks, gongmun) {
21580
21634
  continue;
21581
21635
  }
21582
21636
  const run = [];
21583
- while (i < blocks.length && blocks[i].type === "list_item") {
21584
- run.push(i);
21585
- i++;
21637
+ while (i < blocks.length) {
21638
+ const t = blocks[i].type;
21639
+ if (t === "list_item") {
21640
+ run.push(i);
21641
+ i++;
21642
+ continue;
21643
+ }
21644
+ if (t === "table" || t === "html_table") {
21645
+ let j = i + 1;
21646
+ while (j < blocks.length && (blocks[j].type === "table" || blocks[j].type === "html_table")) j++;
21647
+ if (j < blocks.length && blocks[j].type === "list_item") {
21648
+ i = j;
21649
+ continue;
21650
+ }
21651
+ }
21652
+ break;
21586
21653
  }
21587
21654
  const depths = run.map((bi) => Math.min(Math.max(blocks[bi].indent || 0, 0), GONGMUN_LIST_LEVELS - 1));
21588
21655
  const suppress = gongmun.numbering === "standard" ? computeSuppression(depths) : depths.map(() => false);
@@ -22453,7 +22520,7 @@ async function resolveSectionEntryNames(zip) {
22453
22520
  const paths = sectionPathsFromManifest(xml).filter((p) => zip.file(p) !== null);
22454
22521
  if (paths.length > 0) return paths;
22455
22522
  }
22456
- return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunkQZCP3UWUcjs.compareSectionPaths);
22523
+ return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
22457
22524
  }
22458
22525
  function sectionPathsFromManifest(xml) {
22459
22526
  const attr = (tag, name) => {
@@ -22463,7 +22530,7 @@ function sectionPathsFromManifest(xml) {
22463
22530
  const idToHref = /* @__PURE__ */ new Map();
22464
22531
  for (const m of xml.matchAll(/<opf:item(\s(?:"[^"]*"|'[^']*'|[^>"'])*?)\/?>/g)) {
22465
22532
  const id = attr(m[1], "id");
22466
- const href = _chunkQZCP3UWUcjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
22533
+ const href = _chunkLFCS3UVGcjs.normalizeSectionHref.call(void 0, attr(m[1], "href"));
22467
22534
  if (id && href) idToHref.set(id, href);
22468
22535
  }
22469
22536
  const ordered = [];
@@ -22472,7 +22539,7 @@ function sectionPathsFromManifest(xml) {
22472
22539
  if (href) ordered.push(href);
22473
22540
  }
22474
22541
  if (ordered.length > 0) return ordered;
22475
- return Array.from(idToHref.values()).sort(_chunkQZCP3UWUcjs.compareSectionPaths);
22542
+ return Array.from(idToHref.values()).sort(_chunkLFCS3UVGcjs.compareSectionPaths);
22476
22543
  }
22477
22544
 
22478
22545
  // src/roundtrip/patcher.ts
@@ -22489,7 +22556,7 @@ async function patchHwpx(original, editedMarkdown, options) {
22489
22556
  let zip;
22490
22557
  try {
22491
22558
  zip = await _jszip2.default.loadAsync(original);
22492
- } catch (e34) {
22559
+ } catch (e29) {
22493
22560
  return { success: false, applied: 0, skipped, error: "ZIP \uB85C\uB4DC \uC2E4\uD328" };
22494
22561
  }
22495
22562
  const sectionPaths = await resolveSectionEntryNames(zip);
@@ -22583,9 +22650,9 @@ function buildOrigUnits(blocks) {
22583
22650
  if (block.type === "paragraph" && block.text && /^\[별표\s*\d+/.test(sanitizeText(block.text))) {
22584
22651
  const next = blocks[i + 1];
22585
22652
  if (_optionalChain([next, 'optionalAccess', _220 => _220.type]) === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
22586
- chunk = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
22653
+ chunk = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks.slice(i, i + consume));
22587
22654
  } else {
22588
- chunk = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, [block]);
22655
+ chunk = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, [block]);
22589
22656
  }
22590
22657
  if (chunk) {
22591
22658
  const subUnits = splitMarkdownUnits(chunk);
@@ -23151,21 +23218,24 @@ function readRecordsStrict(stream) {
23151
23218
  }
23152
23219
  return recs;
23153
23220
  }
23154
- function serializeRecords(recs, repl) {
23221
+ function serializeRecords(recs, repl, inserts) {
23155
23222
  const parts = [];
23156
- for (let i = 0; i < recs.length; i++) {
23157
- const data = _nullishCoalesce(_optionalChain([repl, 'optionalAccess', _231 => _231.get, 'call', _232 => _232(i)]), () => ( recs[i].data));
23223
+ const push = (tagId, level, data) => {
23158
23224
  const ext = data.length >= 4095;
23159
23225
  const header = Buffer.alloc(ext ? 8 : 4);
23160
- header.writeUInt32LE((recs[i].tagId & 1023 | (recs[i].level & 1023) << 10 | (ext ? 4095 : data.length) << 20) >>> 0, 0);
23226
+ header.writeUInt32LE((tagId & 1023 | (level & 1023) << 10 | (ext ? 4095 : data.length) << 20) >>> 0, 0);
23161
23227
  if (ext) header.writeUInt32LE(data.length, 4);
23162
23228
  parts.push(header, data);
23229
+ };
23230
+ for (let i = 0; i < recs.length; i++) {
23231
+ for (const ins of _nullishCoalesce(_optionalChain([inserts, 'optionalAccess', _231 => _231.get, 'call', _232 => _232(i)]), () => ( []))) push(ins.tagId, ins.level, ins.data);
23232
+ push(recs[i].tagId, recs[i].level, _nullishCoalesce(_optionalChain([repl, 'optionalAccess', _233 => _233.get, 'call', _234 => _234(i)]), () => ( recs[i].data)));
23163
23233
  }
23164
23234
  return Buffer.concat(parts);
23165
23235
  }
23166
23236
  function scanSection(stream, sectionIndex, compressed) {
23167
23237
  const records = readRecordsStrict(stream);
23168
- if (!records) return { records: [], safe: false, paras: [], tables: [], compressed, repl: /* @__PURE__ */ new Map() };
23238
+ if (!records) return { records: [], safe: false, paras: [], tables: [], compressed, repl: /* @__PURE__ */ new Map(), inserts: /* @__PURE__ */ new Map() };
23169
23239
  const safe = serializeRecords(records).equals(stream);
23170
23240
  const parent = new Int32Array(records.length).fill(-1);
23171
23241
  const stack = [];
@@ -23264,7 +23334,7 @@ function scanSection(stream, sectionIndex, compressed) {
23264
23334
  }
23265
23335
  tables.push({ sectionIndex, rows, cols, cells });
23266
23336
  }
23267
- return { records, safe, paras, tables, compressed, repl: /* @__PURE__ */ new Map() };
23337
+ return { records, safe, paras, tables, compressed, repl: /* @__PURE__ */ new Map(), inserts: /* @__PURE__ */ new Map() };
23268
23338
  }
23269
23339
  async function patchHwp(original, editedMarkdown, options) {
23270
23340
  const skipped = [];
@@ -23277,7 +23347,7 @@ async function patchHwp(original, editedMarkdown, options) {
23277
23347
  return fail(`CFB \uCEE8\uD14C\uC774\uB108 \uD30C\uC2F1 \uC2E4\uD328: ${msg(err)}`);
23278
23348
  }
23279
23349
  const fhEntry = CFB2.find(cfb, "/FileHeader");
23280
- if (!_optionalChain([fhEntry, 'optionalAccess', _233 => _233.content])) return fail("FileHeader \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 HWP 5.x \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4");
23350
+ if (!_optionalChain([fhEntry, 'optionalAccess', _235 => _235.content])) return fail("FileHeader \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 HWP 5.x \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4");
23281
23351
  let flags;
23282
23352
  try {
23283
23353
  flags = parseFileHeader(Buffer.from(fhEntry.content)).flags;
@@ -23299,7 +23369,7 @@ async function patchHwp(original, editedMarkdown, options) {
23299
23369
  const scans = [];
23300
23370
  for (let i = 0; i < sectionPaths.length; i++) {
23301
23371
  const entry = CFB2.find(cfb, sectionPaths[i]);
23302
- if (!_optionalChain([entry, 'optionalAccess', _234 => _234.content])) return fail(`\uC139\uC158 \uC2A4\uD2B8\uB9BC \uC77D\uAE30 \uC2E4\uD328: ${sectionPaths[i]}`);
23372
+ if (!_optionalChain([entry, 'optionalAccess', _236 => _236.content])) return fail(`\uC139\uC158 \uC2A4\uD2B8\uB9BC \uC77D\uAE30 \uC2E4\uD328: ${sectionPaths[i]}`);
23303
23373
  let stream;
23304
23374
  try {
23305
23375
  stream = compressed ? decompressStream(Buffer.from(entry.content)) : Buffer.from(entry.content);
@@ -23332,15 +23402,15 @@ async function patchHwp(original, editedMarkdown, options) {
23332
23402
  }
23333
23403
  }
23334
23404
  let data;
23335
- const dirty = scans.some((s) => s.repl.size > 0);
23405
+ const dirty = scans.some((s) => s.repl.size > 0 || s.inserts.size > 0);
23336
23406
  if (!dirty) {
23337
23407
  data = new Uint8Array(original);
23338
23408
  } else {
23339
23409
  try {
23340
23410
  let out = originalBuf;
23341
23411
  for (let i = 0; i < scans.length; i++) {
23342
- if (scans[i].repl.size === 0) continue;
23343
- const newStream = serializeRecords(scans[i].records, scans[i].repl);
23412
+ if (scans[i].repl.size === 0 && scans[i].inserts.size === 0) continue;
23413
+ const newStream = serializeRecords(scans[i].records, scans[i].repl, scans[i].inserts);
23344
23414
  const content = compressed ? _zlib.deflateRawSync.call(void 0, newStream) : newStream;
23345
23415
  out = replaceOleStream(out, sectionPaths[i], content);
23346
23416
  }
@@ -23350,7 +23420,7 @@ async function patchHwp(original, editedMarkdown, options) {
23350
23420
  }
23351
23421
  }
23352
23422
  let verification;
23353
- if (_optionalChain([options, 'optionalAccess', _235 => _235.verify]) !== false) {
23423
+ if (_optionalChain([options, 'optionalAccess', _237 => _237.verify]) !== false) {
23354
23424
  try {
23355
23425
  const reparsed = parseHwp5Document(Buffer.from(data));
23356
23426
  verification = diffUnitLists(splitMarkdownUnits(reparsed.markdown), editedUnits);
@@ -23439,7 +23509,7 @@ function tableContentScore(irTable, scanTable) {
23439
23509
  for (const [key, scanCell] of scanTable.cells) {
23440
23510
  const comma = key.indexOf(",");
23441
23511
  const r = Number(key.slice(0, comma)), c = Number(key.slice(comma + 1));
23442
- const irCell = _optionalChain([irTable, 'access', _236 => _236.cells, 'access', _237 => _237[r], 'optionalAccess', _238 => _238[c]]);
23512
+ const irCell = _optionalChain([irTable, 'access', _238 => _238.cells, 'access', _239 => _239[r], 'optionalAccess', _240 => _240[c]]);
23443
23513
  if (!irCell) continue;
23444
23514
  const a = normForMatch(scanCell.paras.map((p) => p.rawText).join(" "));
23445
23515
  const b = normForMatch(stripCellTokens(irCell.text));
@@ -23475,7 +23545,7 @@ function handleModified(orig, edited, ctx) {
23475
23545
  }
23476
23546
  function patchParagraph(block, orig, edited, ctx, skip) {
23477
23547
  const mapping = ctx.paraMap.get(orig.blockIdx);
23478
- if (!_optionalChain([mapping, 'optionalAccess', _239 => _239.para])) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED\uC774\uAC70\uB098 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)");
23548
+ if (!_optionalChain([mapping, 'optionalAccess', _241 => _241.para])) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED\uC774\uAC70\uB098 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)");
23479
23549
  if (block.text && block.text.includes("\n")) {
23480
23550
  return skip("\uBB38\uB2E8 \uB0B4 \uAC15\uC81C \uC904\uBC14\uAFC8 \uD3EC\uD568 \u2014 \uC218\uC815 \uC2DC \uC904\uBC14\uAFC8 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0 (v1)");
23481
23551
  }
@@ -23651,7 +23721,7 @@ function applyCellEdit5(table, scanTable, gridR, gridC, newLines, ctx, before, a
23651
23721
  };
23652
23722
  const cell = scanTable.cells.get(`${gridR},${gridC}`);
23653
23723
  if (!cell) return skip("\uC140 \uC88C\uD45C \uB9E4\uD551 \uC2E4\uD328 (\uBCD1\uD569 \uC601\uC5ED\uC758 \uBE48 \uCE78\uC774\uAC70\uB098 \uC88C\uD45C \uBD88\uC77C\uCE58)");
23654
- const irCell = _optionalChain([table, 'access', _240 => _240.cells, 'access', _241 => _241[gridR], 'optionalAccess', _242 => _242[gridC]]);
23724
+ const irCell = _optionalChain([table, 'access', _242 => _242.cells, 'access', _243 => _243[gridR], 'optionalAccess', _244 => _244[gridC]]);
23655
23725
  const scanJoined = cell.paras.map((p) => p.rawText).filter((t) => normForMatch(t)).join("\n");
23656
23726
  if (irCell && normForMatch(scanJoined) !== normForMatch(stripCellTokens(irCell.text))) {
23657
23727
  if (normForMatch(irCell.text) !== "" || normForMatch(scanJoined) !== "") {
@@ -23668,24 +23738,25 @@ function applyCellEdit5(table, scanTable, gridR, gridC, newLines, ctx, before, a
23668
23738
  }
23669
23739
  const unstable = newLines.find((l) => sanitizeText(l) !== l);
23670
23740
  if (unstable !== void 0) return skip("\uACF5\uBC31 \uC815\uADDC\uD654 \uBD88\uC548\uC815 \uD14D\uC2A4\uD2B8 \u2014 \uD328\uCE58 \uC2DC \uC6D0\uBB38 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0");
23671
- if (nonEmpty.length === 0) return skip("\uBE48 \uC140 \uD14D\uC2A4\uD2B8 \uCC44\uC6B0\uAE30\uB294 HWP5 \uBBF8\uC9C0\uC6D0 (v1) \u2014 \uBB38\uB2E8 \uC0DD\uC131 \uD544\uC694");
23741
+ const targets = nonEmpty.length > 0 ? nonEmpty : cell.paras;
23742
+ if (targets.length === 0) return skip("\uC140\uC5D0 \uBB38\uB2E8\uC774 \uC5C6\uC74C \u2014 \uBBF8\uC9C0\uC6D0");
23672
23743
  const assigned = [];
23673
- for (let i = 0; i < nonEmpty.length; i++) {
23744
+ for (let i = 0; i < targets.length; i++) {
23674
23745
  if (i < newLines.length) {
23675
- assigned.push(i === nonEmpty.length - 1 && newLines.length > nonEmpty.length ? newLines.slice(i).join(" ") : newLines[i]);
23746
+ assigned.push(i === targets.length - 1 && newLines.length > targets.length ? newLines.slice(i).join(" ") : newLines[i]);
23676
23747
  } else {
23677
23748
  assigned.push("");
23678
23749
  }
23679
23750
  }
23680
- if (newLines.length > nonEmpty.length) {
23751
+ if (newLines.length > targets.length) {
23681
23752
  ctx.skipped.push({ reason: "\uC140 \uB0B4 \uC904 \uCD94\uAC00\uB294 \uBB38\uB2E8 \uC0DD\uC131 \uBBF8\uC9C0\uC6D0 \u2014 \uB9C8\uC9C0\uB9C9 \uBB38\uB2E8\uC5D0 \uBCD1\uD569 \uC801\uC6A9", after: summarize(after), partial: true });
23682
23753
  } else if (newLines.length < nonEmpty.length && nonEmpty.length > 1) {
23683
23754
  ctx.skipped.push({ reason: "\uC140 \uB0B4 \uC904 \uC0AD\uC81C\uB294 \uBB38\uB2E8 \uC81C\uAC70 \uBBF8\uC9C0\uC6D0 \u2014 \uBE48 \uBB38\uB2E8 \uC794\uC874(\uBDF0\uC5B4\uC5D0 \uBE48 \uC904 \uD45C\uC2DC \uAC00\uB2A5)", before: summarize(before), after: summarize(after), partial: true });
23684
23755
  }
23685
23756
  let staged = 0;
23686
- for (let i = 0; i < nonEmpty.length; i++) {
23687
- if (assigned[i] === nonEmpty[i].rawText || normForMatch(assigned[i]) === normForMatch(nonEmpty[i].rawText)) continue;
23688
- staged += stageParaPatch(ctx.scans[nonEmpty[i].sectionIndex], nonEmpty[i], assigned[i], skip);
23757
+ for (let i = 0; i < targets.length; i++) {
23758
+ if (assigned[i] === targets[i].rawText || normForMatch(assigned[i]) === normForMatch(targets[i].rawText)) continue;
23759
+ staged += stageParaPatch(ctx.scans[targets[i].sectionIndex], targets[i], assigned[i], skip);
23689
23760
  }
23690
23761
  return staged > 0 ? 1 : 0;
23691
23762
  }
@@ -23755,7 +23826,21 @@ function splitParaText(data) {
23755
23826
  if (firstP < 0) firstP = k;
23756
23827
  lastP = k;
23757
23828
  }
23758
- if (firstP < 0) return null;
23829
+ if (firstP < 0) {
23830
+ if (toks.some((t) => t.visible)) return null;
23831
+ let cut = data.length;
23832
+ for (const t of toks) if (data.readUInt16LE(t.start) === 13) {
23833
+ cut = t.start;
23834
+ break;
23835
+ }
23836
+ return {
23837
+ prefix: data.subarray(0, cut),
23838
+ prefixUnits: cut / 2,
23839
+ core: "",
23840
+ suffix: data.subarray(cut),
23841
+ suffixUnits: (data.length - cut) / 2
23842
+ };
23843
+ }
23759
23844
  for (let k = firstP; k <= lastP; k++) if (!toks[k].plain) return null;
23760
23845
  for (let k = 0; k < firstP; k++) if (toks[k].visible) return null;
23761
23846
  for (let k = lastP + 1; k < toks.length; k++) if (toks[k].visible) return null;
@@ -23788,7 +23873,6 @@ function rebuildCharShape(csData, coreStartUnit) {
23788
23873
  }
23789
23874
  function stageParaPatch(scan, para, newPlain, skip) {
23790
23875
  if (!scan.safe) return skip("\uC139\uC158 \uB808\uCF54\uB4DC \uC7AC\uC9C1\uB82C\uD654 \uBD88\uC77C\uCE58 \u2014 \uC548\uC804\uC744 \uC704\uD574 \uC774 \uC139\uC158\uC740 \uBBF8\uC9C0\uC6D0");
23791
- if (para.textIdx === -1) return skip("\uBE48 \uBB38\uB2E8 \uD14D\uC2A4\uD2B8 \uCD94\uAC00\uB294 \uBBF8\uC9C0\uC6D0 (v1)");
23792
23876
  if (para.textIdx === -2) return skip("\uBCF5\uC218 PARA_TEXT \uB808\uCF54\uB4DC \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)");
23793
23877
  if (para.rangeTagCount > 0) return skip("\uBC94\uC704 \uD0DC\uADF8(\uD615\uAD11\uD39C/\uAD50\uC815\uBD80\uD638) \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)");
23794
23878
  if (para.charShapeIdx < 0 || para.lineSegIdx < 0) return skip("\uBB38\uB2E8 \uB808\uCF54\uB4DC \uAD6C\uC131 \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
@@ -23796,11 +23880,27 @@ function stageParaPatch(scan, para, newPlain, skip) {
23796
23880
  if (/[\u0000-\u001f]/.test(newPlain)) return skip("\uC0C8 \uD14D\uC2A4\uD2B8\uC5D0 \uC81C\uC5B4\uBB38\uC790 \uD3EC\uD568 \u2014 \uBBF8\uC9C0\uC6D0");
23797
23881
  const records = scan.records;
23798
23882
  const headerRec = records[para.headerIdx];
23799
- const textRec = records[para.textIdx];
23800
23883
  const charShapeRec = records[para.charShapeIdx];
23801
23884
  if (charShapeRec.data.length < 8) {
23802
23885
  return skip("CHAR_SHAPE \uB808\uCF54\uB4DC \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
23803
23886
  }
23887
+ if (para.textIdx === -1) {
23888
+ const nCharsLow = para.nCharsRaw & 2147483647;
23889
+ if (nCharsLow > 1) return skip("PARA_TEXT \uC5C6\uB294 \uBB38\uB2E8\uC758 nChars \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
23890
+ const paraEnd = nCharsLow === 1 ? Buffer.from([13, 0]) : Buffer.alloc(0);
23891
+ const at = para.headerIdx + 1;
23892
+ const list = _nullishCoalesce(scan.inserts.get(at), () => ( []));
23893
+ list.push({ tagId: TAG_PARA_TEXT, level: headerRec.level + 1, data: Buffer.concat([Buffer.from(newPlain, "utf16le"), paraEnd]) });
23894
+ scan.inserts.set(at, list);
23895
+ const newHeader2 = Buffer.from(headerRec.data);
23896
+ newHeader2.writeUInt32LE((para.nCharsRaw & 2147483648 | newPlain.length + nCharsLow) >>> 0, 0);
23897
+ const cs2 = rebuildCharShape(charShapeRec.data, 0);
23898
+ scan.repl.set(para.charShapeIdx, cs2.buf);
23899
+ newHeader2.writeUInt16LE(cs2.count, 12);
23900
+ scan.repl.set(para.headerIdx, newHeader2);
23901
+ return 1;
23902
+ }
23903
+ const textRec = records[para.textIdx];
23804
23904
  const seg = splitParaText(textRec.data);
23805
23905
  if (!seg) {
23806
23906
  return skip(para.ctrlMask !== 0 ? "\uCEE8\uD2B8\uB864 \uBB38\uC790(\uD0ED/\uD544\uB4DC/\uD2B9\uC218\uACF5\uBC31 \uB4F1 \uD14D\uC2A4\uD2B8 \uC911\uAC04) \uD3EC\uD568 \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)" : "PARA_TEXT \uC7AC\uAD6C\uC131 \uBD88\uC77C\uCE58 \u2014 \uC6D0\uBB38 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0");
@@ -23896,7 +23996,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
23896
23996
  const block = st.blocks[blockIndex];
23897
23997
  if (!block) return void 0;
23898
23998
  if (block.type === "paragraph" || block.type === "heading") {
23899
- const para = _optionalChain([st, 'access', _243 => _243.paraMap, 'access', _244 => _244.get, 'call', _245 => _245(blockIndex), 'optionalAccess', _246 => _246.para]);
23999
+ const para = _optionalChain([st, 'access', _245 => _245.paraMap, 'access', _246 => _246.get, 'call', _247 => _247(blockIndex), 'optionalAccess', _248 => _248.para]);
23900
24000
  if (!para) return void 0;
23901
24001
  return { kind: "paragraph", sectionIndex: para.sectionIndex, xmlStart: para.start };
23902
24002
  }
@@ -23921,7 +24021,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
23921
24021
  if (block.text && block.text.includes("\n")) {
23922
24022
  return { capability: "locked", reason: "\uBB38\uB2E8 \uB0B4 \uAC15\uC81C \uC904\uBC14\uAFC8 \uD3EC\uD568 \u2014 \uC218\uC815 \uC2DC \uC904\uBC14\uAFC8 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0 (v1)" };
23923
24023
  }
23924
- if (!_optionalChain([st, 'access', _247 => _247.paraMap, 'access', _248 => _248.get, 'call', _249 => _249(blockIndex), 'optionalAccess', _250 => _250.para])) {
24024
+ if (!_optionalChain([st, 'access', _249 => _249.paraMap, 'access', _250 => _250.get, 'call', _251 => _251(blockIndex), 'optionalAccess', _252 => _252.para])) {
23925
24025
  return { capability: "locked", reason: "\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED\uC774\uAC70\uB098 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)" };
23926
24026
  }
23927
24027
  return { capability: "text" };
@@ -23987,7 +24087,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
23987
24087
  continue;
23988
24088
  }
23989
24089
  if (block.type === "table" && block.table) {
23990
- if (!_optionalChain([edit, 'access', _251 => _251.cells, 'optionalAccess', _252 => _252.length])) {
24090
+ if (!_optionalChain([edit, 'access', _253 => _253.cells, 'optionalAccess', _254 => _254.length])) {
23991
24091
  skipped.push({ reason: "\uD45C \uBE14\uB85D\uC5D0\uB294 cells \uD3B8\uC9D1\uB9CC \uC9C0\uC6D0", before: summarize(_nullishCoalesce(block.table.caption, () => ( "(\uD45C)"))) });
23992
24092
  continue;
23993
24093
  }
@@ -24007,7 +24107,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
24007
24107
  skipped.push({ reason: "\uAC19\uC740 \uC140\uC5D0 \uC911\uBCF5 \uD3B8\uC9D1 \u2014 \uBA3C\uC800 \uC801\uC6A9\uB41C \uD3B8\uC9D1 \uC720\uC9C0", after: summarize(cellEdit.text) });
24008
24108
  continue;
24009
24109
  }
24010
- const irCell = _optionalChain([block, 'access', _253 => _253.table, 'access', _254 => _254.cells, 'access', _255 => _255[cellEdit.row], 'optionalAccess', _256 => _256[cellEdit.col]]);
24110
+ const irCell = _optionalChain([block, 'access', _255 => _255.table, 'access', _256 => _256.cells, 'access', _257 => _257[cellEdit.row], 'optionalAccess', _258 => _258[cellEdit.col]]);
24011
24111
  if (!irCell) {
24012
24112
  skipped.push({ reason: `\uC140 \uC88C\uD45C \uBC94\uC704 \uBC16: ${cellEdit.row},${cellEdit.col}`, after: summarize(cellEdit.text) });
24013
24113
  continue;
@@ -24063,7 +24163,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
24063
24163
  }
24064
24164
  if (replacements.size === 0) {
24065
24165
  let changes2;
24066
- if (_optionalChain([options, 'optionalAccess', _257 => _257.verify]) !== false) {
24166
+ if (_optionalChain([options, 'optionalAccess', _259 => _259.verify]) !== false) {
24067
24167
  const units = splitMarkdownUnits(st.markdown);
24068
24168
  changes2 = diffUnitLists(units, units);
24069
24169
  }
@@ -24084,7 +24184,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
24084
24184
  }
24085
24185
  this.state = newState;
24086
24186
  let changes;
24087
- if (_optionalChain([options, 'optionalAccess', _258 => _258.verify]) !== false) {
24187
+ if (_optionalChain([options, 'optionalAccess', _260 => _260.verify]) !== false) {
24088
24188
  changes = diffUnitLists(splitMarkdownUnits(beforeMarkdown), splitMarkdownUnits(newState.markdown));
24089
24189
  }
24090
24190
  return { success: true, data: new Uint8Array(data), applied, skipped, changes };
@@ -24104,7 +24204,7 @@ var HwpxSession = (_class5 = class _HwpxSession {
24104
24204
  return skip("\uBB38\uB2E8 \uB0B4 \uAC15\uC81C \uC904\uBC14\uAFC8 \uD3EC\uD568 \u2014 \uC218\uC815 \uC2DC \uC904\uBC14\uAFC8 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0 (v1)");
24105
24205
  }
24106
24206
  const mapping = st.paraMap.get(blockIndex);
24107
- if (!_optionalChain([mapping, 'optionalAccess', _259 => _259.para])) {
24207
+ if (!_optionalChain([mapping, 'optionalAccess', _261 => _261.para])) {
24108
24208
  return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED\uC774\uAC70\uB098 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)");
24109
24209
  }
24110
24210
  let newPlain = newTextRaw.split("\n").map((l) => l.trim()).filter(Boolean).join(" ");
@@ -24124,14 +24224,14 @@ var HwpxSession = (_class5 = class _HwpxSession {
24124
24224
  if (sanitizeText(newPlain) !== newPlain) {
24125
24225
  return skip("\uACF5\uBC31 \uC815\uADDC\uD654 \uBD88\uC548\uC815 \uD14D\uC2A4\uD2B8 \u2014 \uD328\uCE58 \uC2DC \uC6D0\uBB38 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0");
24126
24226
  }
24127
- const splices = buildParagraphSplices(mapping.para, newPlain, _optionalChain([st, 'access', _260 => _260.scans, 'access', _261 => _261[mapping.para.sectionIndex], 'optionalAccess', _262 => _262.xml]));
24227
+ const splices = buildParagraphSplices(mapping.para, newPlain, _optionalChain([st, 'access', _262 => _262.scans, 'access', _263 => _263[mapping.para.sectionIndex], 'optionalAccess', _264 => _264.xml]));
24128
24228
  if (splices === null) return skip("\uBB38\uB2E8\uC5D0 \uD14D\uC2A4\uD2B8 \uB178\uB4DC\uB97C \uB9CC\uB4E4 \uC218 \uC5C6\uC74C");
24129
24229
  sectionSplices[mapping.para.sectionIndex].push(...splices);
24130
24230
  return 1;
24131
24231
  }
24132
24232
  }, _class5);
24133
24233
  function cellStaticCheck(table, scanTable, r, c) {
24134
- const irCell = _optionalChain([table, 'access', _263 => _263.cells, 'access', _264 => _264[r], 'optionalAccess', _265 => _265[c]]);
24234
+ const irCell = _optionalChain([table, 'access', _265 => _265.cells, 'access', _266 => _266[r], 'optionalAccess', _267 => _267[c]]);
24135
24235
  if (!irCell) return { editable: false, reason: "\uC140 \uC88C\uD45C \uBC94\uC704 \uBC16" };
24136
24236
  const cell = scanTable.cellByAnchor.get(`${r},${c}`);
24137
24237
  if (!cell) return { editable: false, reason: "\uBCD1\uD569 \uC601\uC5ED\uC758 \uBE48 \uCE78\uC774\uAC70\uB098 \uC88C\uD45C \uBD88\uC77C\uCE58" };
@@ -24215,11 +24315,11 @@ var md = new (0, _markdownit2.default)({
24215
24315
  breaks: false
24216
24316
  });
24217
24317
  function renderHtml(markdown, options) {
24218
- const preset = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _266 => _266.preset]), () => ( "default"));
24219
- const css = PRESETS[preset] + (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _267 => _267.extraCss]), () => ( "")));
24318
+ const preset = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _268 => _268.preset]), () => ( "default"));
24319
+ const css = PRESETS[preset] + (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _269 => _269.extraCss]), () => ( "")));
24220
24320
  const body = md.render(markdown);
24221
- const watermark = _optionalChain([options, 'optionalAccess', _268 => _268.watermark]) ? `<div class="watermark">${escapeHtml(options.watermark)}</div>` : "";
24222
- const watermarkCss = _optionalChain([options, 'optionalAccess', _269 => _269.watermark]) ? `
24321
+ const watermark = _optionalChain([options, 'optionalAccess', _270 => _270.watermark]) ? `<div class="watermark">${escapeHtml(options.watermark)}</div>` : "";
24322
+ const watermarkCss = _optionalChain([options, 'optionalAccess', _271 => _271.watermark]) ? `
24223
24323
  .watermark {
24224
24324
  position: fixed;
24225
24325
  top: 50%; left: 50%;
@@ -24249,14 +24349,14 @@ async function htmlToPdf(html, options) {
24249
24349
  let puppeteer;
24250
24350
  try {
24251
24351
  puppeteer = await Promise.resolve().then(() => _interopRequireWildcard(require("puppeteer-core")));
24252
- } catch (e35) {
24253
- throw new (0, _chunkQZCP3UWUcjs.KordocError)(
24352
+ } catch (e30) {
24353
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
24254
24354
  "PDF \uC0DD\uC131\uC5D0 puppeteer-core\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC124\uCE58: npm install puppeteer-core"
24255
24355
  );
24256
24356
  }
24257
24357
  const executablePath = _nullishCoalesce(process.env.PUPPETEER_EXECUTABLE_PATH, () => ( findChromiumPath()));
24258
24358
  if (!executablePath) {
24259
- throw new (0, _chunkQZCP3UWUcjs.KordocError)(
24359
+ throw new (0, _chunkLFCS3UVGcjs.KordocError)(
24260
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."
24261
24361
  );
24262
24362
  }
@@ -24268,10 +24368,10 @@ async function htmlToPdf(html, options) {
24268
24368
  try {
24269
24369
  const page = await browser.newPage();
24270
24370
  await page.setContent(html, { waitUntil: "networkidle0" });
24271
- const margin = _optionalChain([options, 'optionalAccess', _270 => _270.margin]);
24371
+ const margin = _optionalChain([options, 'optionalAccess', _272 => _272.margin]);
24272
24372
  const pdf = await page.pdf({
24273
- format: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _271 => _271.pageSize]), () => ( "A4")),
24274
- landscape: _optionalChain([options, 'optionalAccess', _272 => _272.orientation]) === "landscape",
24373
+ format: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _273 => _273.pageSize]), () => ( "A4")),
24374
+ landscape: _optionalChain([options, 'optionalAccess', _274 => _274.orientation]) === "landscape",
24275
24375
  printBackground: true,
24276
24376
  margin: margin ? {
24277
24377
  top: toCss(margin.top),
@@ -24279,9 +24379,9 @@ async function htmlToPdf(html, options) {
24279
24379
  bottom: toCss(margin.bottom),
24280
24380
  left: toCss(margin.left)
24281
24381
  } : void 0,
24282
- displayHeaderFooter: !!(_optionalChain([options, 'optionalAccess', _273 => _273.header]) || _optionalChain([options, 'optionalAccess', _274 => _274.footer])),
24283
- headerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _275 => _275.header]), () => ( "<div></div>")),
24284
- footerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _276 => _276.footer]), () => ( '<div style="font-size:8pt;width:100%;text-align:center;color:#777;"><span class="pageNumber"></span>/<span class="totalPages"></span></div>'))
24382
+ displayHeaderFooter: !!(_optionalChain([options, 'optionalAccess', _275 => _275.header]) || _optionalChain([options, 'optionalAccess', _276 => _276.footer])),
24383
+ headerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _277 => _277.header]), () => ( "<div></div>")),
24384
+ footerTemplate: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _278 => _278.footer]), () => ( '<div style="font-size:8pt;width:100%;text-align:center;color:#777;"><span class="pageNumber"></span>/<span class="totalPages"></span></div>'))
24285
24385
  });
24286
24386
  return Buffer.from(pdf);
24287
24387
  } finally {
@@ -24315,24 +24415,24 @@ async function markdownToPdf(markdown, options) {
24315
24415
  return htmlToPdf(html, options);
24316
24416
  }
24317
24417
  async function blocksToPdf(blocks, options) {
24318
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, blocks);
24418
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, blocks);
24319
24419
  return markdownToPdf(markdown, options);
24320
24420
  }
24321
24421
 
24322
24422
  // src/index.ts
24323
24423
  async function parse(input, options) {
24324
24424
  let buffer;
24325
- const opts = typeof input === "string" && !_optionalChain([options, 'optionalAccess', _277 => _277.filePath]) ? { ...options, filePath: input } : options;
24425
+ const opts = typeof input === "string" && !_optionalChain([options, 'optionalAccess', _279 => _279.filePath]) ? { ...options, filePath: input } : options;
24326
24426
  if (typeof input === "string") {
24327
24427
  try {
24328
24428
  const buf = await _promises.readFile.call(void 0, input);
24329
- buffer = _chunkQZCP3UWUcjs.toArrayBuffer.call(void 0, buf);
24429
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, buf);
24330
24430
  } catch (err) {
24331
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}`;
24332
24432
  return { success: false, fileType: "unknown", error: msg2, code: "PARSE_ERROR" };
24333
24433
  }
24334
24434
  } else if (Buffer.isBuffer(input)) {
24335
- buffer = _chunkQZCP3UWUcjs.toArrayBuffer.call(void 0, input);
24435
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, input);
24336
24436
  } else {
24337
24437
  buffer = input;
24338
24438
  }
@@ -24367,21 +24467,21 @@ async function parseHwp3(buffer, options) {
24367
24467
  const { markdown, blocks, metadata, outline, warnings } = parseHwp3Document(buffer, options);
24368
24468
  return { success: true, fileType: "hwp3", markdown, blocks, metadata, outline, warnings };
24369
24469
  } catch (err) {
24370
- return { success: false, fileType: "hwp3", error: err instanceof Error ? err.message : "HWP3 \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24371
24471
  }
24372
24472
  }
24373
24473
  async function parseHwpx(buffer, options) {
24374
24474
  try {
24375
24475
  const { markdown, blocks, metadata, outline, warnings, images } = await parseHwpxDocument(buffer, options);
24376
- return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _278 => _278.length]) ? images : void 0 };
24476
+ return { success: true, fileType: "hwpx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _280 => _280.length]) ? images : void 0 };
24377
24477
  } catch (err) {
24378
- return { success: false, fileType: "hwpx", error: err instanceof Error ? err.message : "HWPX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24379
24479
  }
24380
24480
  }
24381
24481
  async function parseHwp(buffer, options) {
24382
24482
  try {
24383
24483
  const { markdown, blocks, metadata, outline, warnings, images } = parseHwp5Document(Buffer.from(buffer), options);
24384
- if (isDistributionSentinel(markdown) && isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _279 => _279.filePath])) {
24484
+ if (isDistributionSentinel(markdown) && isComFallbackAvailable() && _optionalChain([options, 'optionalAccess', _281 => _281.filePath])) {
24385
24485
  try {
24386
24486
  const { pages, pageCount, warnings: comWarns } = extractTextViaCom(options.filePath);
24387
24487
  if (pages.some((p) => p && p.trim().length > 0)) {
@@ -24395,20 +24495,20 @@ async function parseHwp(buffer, options) {
24395
24495
  warnings: com.warnings
24396
24496
  };
24397
24497
  }
24398
- } catch (e36) {
24498
+ } catch (e31) {
24399
24499
  }
24400
24500
  }
24401
- return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _280 => _280.length]) ? images : void 0 };
24501
+ return { success: true, fileType: "hwp", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _282 => _282.length]) ? images : void 0 };
24402
24502
  } catch (err) {
24403
- return { success: false, fileType: "hwp", error: err instanceof Error ? err.message : "HWP \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24404
24504
  }
24405
24505
  }
24406
24506
  async function parsePdf(buffer, options) {
24407
24507
  let parsePdfDocument;
24408
24508
  try {
24409
- const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-RFLPUZ7P.cjs")));
24509
+ const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./parser-IXK5V7YG.cjs")));
24410
24510
  parsePdfDocument = mod.parsePdfDocument;
24411
- } catch (e37) {
24511
+ } catch (e32) {
24412
24512
  return {
24413
24513
  success: false,
24414
24514
  fileType: "pdf",
@@ -24421,7 +24521,7 @@ async function parsePdf(buffer, options) {
24421
24521
  return { success: true, fileType: "pdf", markdown, blocks, metadata, outline, warnings, isImageBased, pageQuality, qualitySummary };
24422
24522
  } catch (err) {
24423
24523
  const isImageBased = err instanceof Error && "isImageBased" in err ? true : void 0;
24424
- return { success: false, fileType: "pdf", error: err instanceof Error ? err.message : "PDF \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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 };
24425
24525
  }
24426
24526
  }
24427
24527
  async function parseXlsx(buffer, options) {
@@ -24429,7 +24529,7 @@ async function parseXlsx(buffer, options) {
24429
24529
  const { markdown, blocks, metadata, warnings } = await parseXlsxDocument(buffer, options);
24430
24530
  return { success: true, fileType: "xlsx", markdown, blocks, metadata, warnings };
24431
24531
  } catch (err) {
24432
- return { success: false, fileType: "xlsx", error: err instanceof Error ? err.message : "XLSX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24433
24533
  }
24434
24534
  }
24435
24535
  async function parseXls(buffer, options) {
@@ -24437,15 +24537,15 @@ async function parseXls(buffer, options) {
24437
24537
  const { markdown, blocks, metadata, warnings } = await parseXlsDocument(buffer, options);
24438
24538
  return { success: true, fileType: "xls", markdown, blocks, metadata, warnings };
24439
24539
  } catch (err) {
24440
- return { success: false, fileType: "xls", error: err instanceof Error ? err.message : "XLS \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24441
24541
  }
24442
24542
  }
24443
24543
  async function parseDocx(buffer, options) {
24444
24544
  try {
24445
24545
  const { markdown, blocks, metadata, outline, warnings, images } = await parseDocxDocument(buffer, options);
24446
- return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _281 => _281.length]) ? images : void 0 };
24546
+ return { success: true, fileType: "docx", markdown, blocks, metadata, outline, warnings, images: _optionalChain([images, 'optionalAccess', _283 => _283.length]) ? images : void 0 };
24447
24547
  } catch (err) {
24448
- return { success: false, fileType: "docx", error: err instanceof Error ? err.message : "DOCX \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24449
24549
  }
24450
24550
  }
24451
24551
  async function parseHwpml(buffer, options) {
@@ -24453,16 +24553,16 @@ async function parseHwpml(buffer, options) {
24453
24553
  const { markdown, blocks, metadata, outline, warnings } = parseHwpmlDocument(buffer, options);
24454
24554
  return { success: true, fileType: "hwpml", markdown, blocks, metadata, outline, warnings };
24455
24555
  } catch (err) {
24456
- return { success: false, fileType: "hwpml", error: err instanceof Error ? err.message : "HWPML \uD30C\uC2F1 \uC2E4\uD328", code: _chunkQZCP3UWUcjs.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) };
24457
24557
  }
24458
24558
  }
24459
24559
  async function fillForm(input, values, outputFormat = "markdown") {
24460
24560
  let buffer;
24461
24561
  if (typeof input === "string") {
24462
24562
  const buf = await _promises.readFile.call(void 0, input);
24463
- buffer = _chunkQZCP3UWUcjs.toArrayBuffer.call(void 0, buf);
24563
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, buf);
24464
24564
  } else if (Buffer.isBuffer(input)) {
24465
- buffer = _chunkQZCP3UWUcjs.toArrayBuffer.call(void 0, input);
24565
+ buffer = _chunkLFCS3UVGcjs.toArrayBuffer.call(void 0, input);
24466
24566
  } else {
24467
24567
  buffer = input;
24468
24568
  }
@@ -24488,7 +24588,7 @@ async function fillForm(input, values, outputFormat = "markdown") {
24488
24588
  throw new Error(`\uC11C\uC2DD \uD30C\uC2F1 \uC2E4\uD328: ${parsed.error}`);
24489
24589
  }
24490
24590
  const fill = fillFormFields(parsed.blocks, values);
24491
- const markdown = _chunkQZCP3UWUcjs.blocksToMarkdown.call(void 0, fill.blocks);
24591
+ const markdown = _chunkLFCS3UVGcjs.blocksToMarkdown.call(void 0, fill.blocks);
24492
24592
  if (outputFormat === "hwpx") {
24493
24593
  const hwpxBuffer = await markdownToHwpx(markdown);
24494
24594
  return { output: hwpxBuffer, format: "hwpx", fill };
@@ -24546,5 +24646,5 @@ async function fillForm(input, values, outputFormat = "markdown") {
24546
24646
 
24547
24647
 
24548
24648
 
24549
- exports.HwpxSession = HwpxSession; exports.PRESET_ALIAS = PRESET_ALIAS; exports.SPACE_EM_FIXED = SPACE_EM_FIXED; exports.SPACE_EM_FONT = SPACE_EM_FONT; exports.VERSION = _chunkQZCP3UWUcjs.VERSION; exports.ValueCursor = ValueCursor; exports.applySplices = applySplices; exports.blocksToMarkdown = _chunkQZCP3UWUcjs.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;
24550
24650
  //# sourceMappingURL=index.cjs.map