kordoc 4.12.2 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +32 -1
  2. package/dist/{-EZH6NKTE.js → -UZDRUWTX.js} +43 -22
  3. package/dist/{chunk-FBLMVHDK.js → chunk-27QN27I3.js} +2 -2
  4. package/dist/{chunk-MUYU4JI5.js → chunk-2B45S7FM.js} +2 -2
  5. package/dist/{chunk-LD2K4K5V.js → chunk-2RREQZ44.js} +1662 -652
  6. package/dist/chunk-2RREQZ44.js.map +1 -0
  7. package/dist/{chunk-OEYECZGV.js → chunk-3ABHPKYA.js} +10 -6
  8. package/dist/chunk-3ABHPKYA.js.map +1 -0
  9. package/dist/{chunk-QM2RSJ2S.js → chunk-3MCFJIN2.js} +5 -5
  10. package/dist/{chunk-JCMBQC5N.js → chunk-5VHLKNCE.js} +2 -2
  11. package/dist/{chunk-FVBR7SC3.js → chunk-6JXMIX3G.js} +2 -2
  12. package/dist/chunk-6JXMIX3G.js.map +1 -0
  13. package/dist/{chunk-5RPYBC2Q.js → chunk-6NLXGGNH.js} +37 -6
  14. package/dist/chunk-6NLXGGNH.js.map +1 -0
  15. package/dist/{chunk-2B7OIEJJ.js → chunk-AGBFCFQY.js} +10 -6
  16. package/dist/chunk-AGBFCFQY.js.map +1 -0
  17. package/dist/{rasterize-NRWP2C6L.js → chunk-BQLZOQES.js} +22 -6
  18. package/dist/chunk-BQLZOQES.js.map +1 -0
  19. package/dist/{chunk-ONNAHSPV.cjs → chunk-CKMK42FV.cjs} +18 -14
  20. package/dist/chunk-CKMK42FV.cjs.map +1 -0
  21. package/dist/{chunk-T7GRHAIW.cjs → chunk-COUGOFT3.cjs} +1 -1
  22. package/dist/chunk-COUGOFT3.cjs.map +1 -0
  23. package/dist/{chunk-2LO525TL.js → chunk-F3FEIYI7.js} +2 -2
  24. package/dist/{chunk-Q6ETEJFK.js → chunk-GWFX5ZD7.js} +11 -7
  25. package/dist/chunk-GWFX5ZD7.js.map +1 -0
  26. package/dist/{chunk-2HBYWA5X.js → chunk-H5JWPWQP.js} +2 -2
  27. package/dist/{chunk-N3DLQ2YH.js → chunk-HG5LXXCC.js} +1 -1
  28. package/dist/chunk-HG5LXXCC.js.map +1 -0
  29. package/dist/{chunk-KX7IYCCZ.js → chunk-IEJR23OA.js} +3 -3
  30. package/dist/{chunk-7XUXSDH5.js → chunk-ILDTN72S.js} +10 -6
  31. package/dist/chunk-ILDTN72S.js.map +1 -0
  32. package/dist/{chunk-QBCMFNHS.js → chunk-L3CEPNQS.js} +2 -2
  33. package/dist/{chunk-XXDZ2KTW.js → chunk-LP5RTYFM.js} +2 -2
  34. package/dist/{chunk-2LKYJ4G3.cjs → chunk-MCD45IHO.cjs} +6 -6
  35. package/dist/{chunk-2LKYJ4G3.cjs.map → chunk-MCD45IHO.cjs.map} +1 -1
  36. package/dist/{chunk-V5BUPZ6I.cjs → chunk-OJV7HNGJ.cjs} +13 -9
  37. package/dist/chunk-OJV7HNGJ.cjs.map +1 -0
  38. package/dist/{chunk-DBGEUDBY.js → chunk-OSLJ3A6D.js} +2 -2
  39. package/dist/{chunk-2LPBIW2B.cjs → chunk-S2VKZKUX.cjs} +3 -3
  40. package/dist/{chunk-2LPBIW2B.cjs.map → chunk-S2VKZKUX.cjs.map} +1 -1
  41. package/dist/{chunk-IOJX4Q63.js → chunk-T7AFLXGA.js} +786 -19
  42. package/dist/chunk-T7AFLXGA.js.map +1 -0
  43. package/dist/{chunk-UL2MDA5C.js → chunk-TA2LEFOF.js} +3 -3
  44. package/dist/{chunk-62IU4NV3.cjs → chunk-TAYCQE6K.cjs} +2 -2
  45. package/dist/{chunk-62IU4NV3.cjs.map → chunk-TAYCQE6K.cjs.map} +1 -1
  46. package/dist/{chunk-ONQHGZTS.js → chunk-XVIJLHCW.js} +1 -1
  47. package/dist/chunk-XVIJLHCW.js.map +1 -0
  48. package/dist/chunks-G3GK536Y.js +10 -0
  49. package/dist/cli.js +187 -38
  50. package/dist/cli.js.map +1 -1
  51. package/dist/{formula-6RQX4NMJ.js → formula-3T7HQA4O.js} +4 -4
  52. package/dist/{formula-NW33S4TA.js → formula-FWVAOSIK.js} +3 -3
  53. package/dist/{formula-NBEO6CFC.cjs → formula-YALEMZMF.cjs} +9 -9
  54. package/dist/{formula-NBEO6CFC.cjs.map → formula-YALEMZMF.cjs.map} +1 -1
  55. package/dist/{image-ocr-SO56VETS.js → image-ocr-2M7K3CE5.js} +8 -8
  56. package/dist/{image-ocr-V4KY373B.cjs → image-ocr-4EUZIF6M.cjs} +12 -12
  57. package/dist/{image-ocr-V4KY373B.cjs.map → image-ocr-4EUZIF6M.cjs.map} +1 -1
  58. package/dist/{image-ocr-CAVU2TNZ.js → image-ocr-X3I2HUK2.js} +6 -6
  59. package/dist/index.cjs +2349 -576
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +305 -12
  62. package/dist/index.d.ts +305 -12
  63. package/dist/index.js +1980 -207
  64. package/dist/index.js.map +1 -1
  65. package/dist/mcp.js +109 -35
  66. package/dist/mcp.js.map +1 -1
  67. package/dist/{model-bundle-EIJF34DR.js → model-bundle-XXYZ6ELQ.js} +5 -5
  68. package/dist/{models-6V4CPQXC.js → models-APDSXJW7.js} +5 -5
  69. package/dist/{parser-OMT25WH2.cjs → parser-4KE2FR5F.cjs} +60 -39
  70. package/dist/parser-4KE2FR5F.cjs.map +1 -0
  71. package/dist/{parser-OBHNXEQM.js → parser-T5R4YVZS.js} +32 -11
  72. package/dist/parser-T5R4YVZS.js.map +1 -0
  73. package/dist/{parser-GIREMEPD.js → parser-XKSOS6GY.js} +32 -11
  74. package/dist/parser-XKSOS6GY.js.map +1 -0
  75. package/dist/pdf-ocr-JZKCEKWX.cjs +14 -0
  76. package/dist/{pdf-ocr-TFYVK4FI.cjs.map → pdf-ocr-JZKCEKWX.cjs.map} +1 -1
  77. package/dist/pdf-ocr-X62B7YDV.js +13 -0
  78. package/dist/pdf-ocr-YDJQEGDS.js +16 -0
  79. package/dist/{profile-io-PZVMM66V.js → profile-io-Y24GOHWM.js} +3 -3
  80. package/dist/rasterize-QCOBWHAG.js +13 -0
  81. package/dist/render-DHFQQCSV.js +38 -0
  82. package/dist/seal-UTHFQPLO.js +10 -0
  83. package/dist/seal-UTHFQPLO.js.map +1 -0
  84. package/dist/{setup-V55AJP6H.js → setup-UWX3KH3G.js} +3 -3
  85. package/dist/visual-DF2KSPEC.js +19 -0
  86. package/dist/visual-DF2KSPEC.js.map +1 -0
  87. package/dist/{watch-7CQSMDDP.js → watch-4ZUTMC3Q.js} +15 -13
  88. package/dist/{watch-7CQSMDDP.js.map → watch-4ZUTMC3Q.js.map} +1 -1
  89. package/package.json +1 -1
  90. package/dist/chunk-2B7OIEJJ.js.map +0 -1
  91. package/dist/chunk-5RPYBC2Q.js.map +0 -1
  92. package/dist/chunk-7XUXSDH5.js.map +0 -1
  93. package/dist/chunk-FVBR7SC3.js.map +0 -1
  94. package/dist/chunk-IOJX4Q63.js.map +0 -1
  95. package/dist/chunk-LD2K4K5V.js.map +0 -1
  96. package/dist/chunk-N3DLQ2YH.js.map +0 -1
  97. package/dist/chunk-OEYECZGV.js.map +0 -1
  98. package/dist/chunk-ONNAHSPV.cjs.map +0 -1
  99. package/dist/chunk-ONQHGZTS.js.map +0 -1
  100. package/dist/chunk-Q6ETEJFK.js.map +0 -1
  101. package/dist/chunk-T7GRHAIW.cjs.map +0 -1
  102. package/dist/chunk-V5BUPZ6I.cjs.map +0 -1
  103. package/dist/chunks-TT7ZE5QQ.js +0 -10
  104. package/dist/parser-GIREMEPD.js.map +0 -1
  105. package/dist/parser-OBHNXEQM.js.map +0 -1
  106. package/dist/parser-OMT25WH2.cjs.map +0 -1
  107. package/dist/pdf-ocr-IRXQ5GBM.js +0 -13
  108. package/dist/pdf-ocr-SL4GCOGS.js +0 -16
  109. package/dist/pdf-ocr-TFYVK4FI.cjs +0 -14
  110. package/dist/rasterize-NRWP2C6L.js.map +0 -1
  111. package/dist/render-V5ZPTZQ7.js +0 -10
  112. package/dist/seal-LVG2DGAB.js +0 -10
  113. /package/dist/{-EZH6NKTE.js.map → -UZDRUWTX.js.map} +0 -0
  114. /package/dist/{chunk-FBLMVHDK.js.map → chunk-27QN27I3.js.map} +0 -0
  115. /package/dist/{chunk-MUYU4JI5.js.map → chunk-2B45S7FM.js.map} +0 -0
  116. /package/dist/{chunk-QM2RSJ2S.js.map → chunk-3MCFJIN2.js.map} +0 -0
  117. /package/dist/{chunk-JCMBQC5N.js.map → chunk-5VHLKNCE.js.map} +0 -0
  118. /package/dist/{chunk-2LO525TL.js.map → chunk-F3FEIYI7.js.map} +0 -0
  119. /package/dist/{chunk-2HBYWA5X.js.map → chunk-H5JWPWQP.js.map} +0 -0
  120. /package/dist/{chunk-KX7IYCCZ.js.map → chunk-IEJR23OA.js.map} +0 -0
  121. /package/dist/{chunk-QBCMFNHS.js.map → chunk-L3CEPNQS.js.map} +0 -0
  122. /package/dist/{chunk-XXDZ2KTW.js.map → chunk-LP5RTYFM.js.map} +0 -0
  123. /package/dist/{chunk-DBGEUDBY.js.map → chunk-OSLJ3A6D.js.map} +0 -0
  124. /package/dist/{chunk-UL2MDA5C.js.map → chunk-TA2LEFOF.js.map} +0 -0
  125. /package/dist/{chunks-TT7ZE5QQ.js.map → chunks-G3GK536Y.js.map} +0 -0
  126. /package/dist/{formula-6RQX4NMJ.js.map → formula-3T7HQA4O.js.map} +0 -0
  127. /package/dist/{formula-NW33S4TA.js.map → formula-FWVAOSIK.js.map} +0 -0
  128. /package/dist/{image-ocr-SO56VETS.js.map → image-ocr-2M7K3CE5.js.map} +0 -0
  129. /package/dist/{image-ocr-CAVU2TNZ.js.map → image-ocr-X3I2HUK2.js.map} +0 -0
  130. /package/dist/{model-bundle-EIJF34DR.js.map → model-bundle-XXYZ6ELQ.js.map} +0 -0
  131. /package/dist/{models-6V4CPQXC.js.map → models-APDSXJW7.js.map} +0 -0
  132. /package/dist/{pdf-ocr-IRXQ5GBM.js.map → pdf-ocr-X62B7YDV.js.map} +0 -0
  133. /package/dist/{pdf-ocr-SL4GCOGS.js.map → pdf-ocr-YDJQEGDS.js.map} +0 -0
  134. /package/dist/{profile-io-PZVMM66V.js.map → profile-io-Y24GOHWM.js.map} +0 -0
  135. /package/dist/{render-V5ZPTZQ7.js.map → rasterize-QCOBWHAG.js.map} +0 -0
  136. /package/dist/{seal-LVG2DGAB.js.map → render-DHFQQCSV.js.map} +0 -0
  137. /package/dist/{setup-V55AJP6H.js.map → setup-UWX3KH3G.js.map} +0 -0
package/dist/mcp.js CHANGED
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ assertWithinRoot,
4
+ getAccessRoot,
5
+ isOfflineMode
6
+ } from "./chunk-L3CEPNQS.js";
2
7
  import {
3
8
  APPROVAL_MAX,
4
9
  BODY_FONTS,
@@ -6,22 +11,21 @@ import {
6
11
  BULLET2_CHARS,
7
12
  DOC_FOOT_KEYS,
8
13
  DOC_HEAD_KEYS,
14
+ DOC_INFO_KEYS,
9
15
  FONT_ROLE_KEYS,
10
16
  H2_MARKERS,
17
+ LEVEL_STYLE_KEYS,
11
18
  LINE_SPACING_RANGE,
12
19
  NOTICE_HEAD_KEYS,
13
20
  PRESS_CONTACT_KEYS,
14
21
  SIZE_KEYS,
15
22
  SIZE_PT_RANGE,
16
23
  buildGongmunOptions
17
- } from "./chunk-5RPYBC2Q.js";
24
+ } from "./chunk-6NLXGGNH.js";
18
25
  import {
19
26
  BUILTIN_TEMPLATES,
20
27
  PRESET_ALIAS,
21
28
  compare,
22
- detectFormat,
23
- detectOle2Format,
24
- detectZipFormat,
25
29
  extractFormFields,
26
30
  extractHwp5MetadataOnly,
27
31
  extractHwpxMetadataOnly,
@@ -39,30 +43,30 @@ import {
39
43
  resolveBuiltinTemplate,
40
44
  unknownFontWarnings,
41
45
  usesGaejosikMunche
42
- } from "./chunk-LD2K4K5V.js";
46
+ } from "./chunk-2RREQZ44.js";
43
47
  import "./chunk-7FCNOKOR.js";
44
- import "./chunk-N3DLQ2YH.js";
45
- import "./chunk-MOL7MDBG.js";
46
- import "./chunk-KX7IYCCZ.js";
48
+ import "./chunk-HG5LXXCC.js";
49
+ import "./chunk-IEJR23OA.js";
47
50
  import "./chunk-DZIXKL7E.js";
48
- import "./chunk-DBGEUDBY.js";
51
+ import "./chunk-OSLJ3A6D.js";
49
52
  import {
50
- blocksToMarkdown
51
- } from "./chunk-Q6ETEJFK.js";
52
- import "./chunk-IOJX4Q63.js";
53
- import "./chunk-FVBR7SC3.js";
53
+ detectFormat,
54
+ detectOle2Format,
55
+ detectZipFormat
56
+ } from "./chunk-T7AFLXGA.js";
57
+ import "./chunk-MOL7MDBG.js";
58
+ import "./chunk-6JXMIX3G.js";
54
59
  import {
55
- assertWithinRoot,
56
- getAccessRoot,
57
- isOfflineMode
58
- } from "./chunk-QBCMFNHS.js";
60
+ blocksToMarkdown
61
+ } from "./chunk-GWFX5ZD7.js";
62
+ import "./chunk-BQLZOQES.js";
59
63
  import {
60
64
  KordocError,
61
65
  VERSION,
62
66
  classifyError,
63
67
  sanitizeError,
64
68
  toArrayBuffer
65
- } from "./chunk-FBLMVHDK.js";
69
+ } from "./chunk-27QN27I3.js";
66
70
 
67
71
  // src/mcp.ts
68
72
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -312,7 +316,7 @@ server.tool(
312
316
  break;
313
317
  case "pdf":
314
318
  try {
315
- const { extractPdfMetadataOnly } = await import("./parser-OBHNXEQM.js");
319
+ const { extractPdfMetadataOnly } = await import("./parser-T5R4YVZS.js");
316
320
  metadata = await extractPdfMetadataOnly(buffer);
317
321
  } catch {
318
322
  metadata = void 0;
@@ -694,7 +698,7 @@ server.tool(
694
698
  }
695
699
  const image = new Uint8Array(await readFile(imgResolved));
696
700
  const ext = extname(imgResolved).slice(1).toLowerCase();
697
- const { placeSealHwpx } = await import("./seal-LVG2DGAB.js");
701
+ const { placeSealHwpx } = await import("./seal-UTHFQPLO.js");
698
702
  const result = await placeSealHwpx(buffer, [{
699
703
  anchor,
700
704
  occurrence,
@@ -787,16 +791,42 @@ server.tool(
787
791
  format: z.enum(["png", "svg"]).default("png").describe("png=\uC774\uBBF8\uC9C0\uB85C \uC751\uB2F5\uC5D0 \uC9C1\uC811 \uBC18\uD658 (sharp \uD544\uC694, \uAE30\uBCF8 \uC124\uCE58\uB428) / svg=output_path\uC5D0 \uD30C\uC77C \uC800\uC7A5"),
788
792
  output_path: z.string().min(1).optional().describe("\uACB0\uACFC \uC800\uC7A5 \uACBD\uB85C (png\uB294 \uC120\uD0DD, svg\uB294 \uD544\uC218 \u2014 \uD655\uC7A5\uC790\uB294 format\uACFC \uC77C\uCE58)"),
789
793
  highlights: z.array(z.string().min(1)).optional().describe("\uD615\uAD11\uD39C \uD45C\uC2DC\uD560 \uAC80\uC0C9\uC5B4 \uBAA9\uB85D \u2014 \uCC44\uC6B4 \uAC12\xB7\uC218\uC815 \uBB38\uAD6C \uC704\uCE58 \uD655\uC778\uC6A9"),
790
- reflow_mode: z.enum(["keep", "charAll"]).default("keep").describe("reflow \uC904\uBC14\uAFC8: keep=\uC5B4\uC808 \uB2E8\uC704, charAll=\uAE00\uC790 \uB2E8\uC704")
794
+ reflow_mode: z.enum(["keep", "charAll"]).default("keep").describe("reflow \uC904\uBC14\uAFC8: keep=\uC5B4\uC808 \uB2E8\uC704, charAll=\uAE00\uC790 \uB2E8\uC704"),
795
+ pages: z.string().min(1).optional().describe("\uD398\uC774\uC9C0 \uC120\uD0DD(1-based: '3', '1-3', '1,3,7-9') \u2014 \uC9C0\uC815\uD558\uBA74 \uD398\uC774\uC9C0\uBCC4 \uC774\uBBF8\uC9C0\uB85C \uC751\uB2F5(\uCD5C\uB300 8\uCABD). \uBBF8\uC9C0\uC815\uC774\uBA74 \uC804\uCCB4\uB97C \uC138\uB85C \uC2A4\uD0DD \uC774\uBBF8\uC9C0 1\uC7A5\uC73C\uB85C")
791
796
  },
792
- async ({ file_path, format, output_path, highlights, reflow_mode }) => {
797
+ async ({ file_path, format, output_path, highlights, reflow_mode, pages }) => {
793
798
  try {
794
799
  if (format === "svg" && !output_path) {
795
800
  return { content: [{ type: "text", text: 'format: "svg"\uB294 output_path(.svg)\uAC00 \uD544\uC218\uC785\uB2C8\uB2E4 \u2014 SVG \uC6D0\uBB38\uC740 \uCEE4\uC11C \uC751\uB2F5\uC5D0 \uC9C1\uC811 \uB2F4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.' }], isError: true };
796
801
  }
797
802
  const outPath = output_path ? safeOutputPath(output_path, /* @__PURE__ */ new Set([format === "png" ? ".png" : ".svg"])) : void 0;
798
803
  const { buffer } = await readValidatedFile(file_path, MAX_FILE_SIZE, /* @__PURE__ */ new Set([".hwpx"]));
799
- const { renderHwpxToSvg } = await import("./render-V5ZPTZQ7.js");
804
+ if (pages && format === "png") {
805
+ const { renderDocument } = await import("./render-DHFQQCSV.js");
806
+ const { scene, assets } = await renderDocument(buffer, { format: "png", pages, highlights, reflow: true, reflowMode: reflow_mode });
807
+ const MAX_PAGES = 8;
808
+ const shown = assets.slice(0, MAX_PAGES);
809
+ const summary2 = [
810
+ `\uB80C\uB354 \uC644\uB8CC: \uBB38\uC11C ${scene.pages.length}\uD398\uC774\uC9C0 \uC911 ${assets.length}\uCABD \uC120\uD0DD (\uD14D\uC2A4\uD2B8 ${scene.stats.texts}\xB7\uC774\uBBF8\uC9C0 ${scene.stats.images}\xB7\uD45C ${scene.stats.tables}\xB7\uB3C4\uD615 ${scene.stats.shapes})`,
811
+ ...scene.warnings.map((w) => `\u26A0\uFE0F ${w}`)
812
+ ];
813
+ if (assets.length > MAX_PAGES) summary2.push(`\u26A0\uFE0F ${MAX_PAGES}\uCABD\uAE4C\uC9C0\uB9CC \uC751\uB2F5\uC5D0 \uB2F4\uC558\uC2B5\uB2C8\uB2E4 \u2014 pages \uB97C \uC881\uD788\uC138\uC694`);
814
+ if (outPath) {
815
+ await mkdir(dirname(outPath), { recursive: true });
816
+ for (const a of assets) {
817
+ const p = assets.length === 1 ? outPath : outPath.replace(/\.png$/i, `_page_${String(a.page).padStart(3, "0")}.png`);
818
+ await writeFile(p, a.data);
819
+ summary2.push(`\uC800\uC7A5: ${p}`);
820
+ }
821
+ }
822
+ return {
823
+ content: [
824
+ ...shown.map((a) => ({ type: "image", data: a.data.toString("base64"), mimeType: "image/png" })),
825
+ { type: "text", text: summary2.join("\n") }
826
+ ]
827
+ };
828
+ }
829
+ const { renderHwpxToSvg } = await import("./render-DHFQQCSV.js");
800
830
  const result = await renderHwpxToSvg(buffer, { highlights, reflow: true, reflowMode: reflow_mode });
801
831
  const summary = [
802
832
  `\uB80C\uB354 \uC644\uB8CC: ${result.pageCount}\uD398\uC774\uC9C0, ${Math.round(result.width)}x${Math.round(result.height)}pt (\uD14D\uC2A4\uD2B8 ${result.stats.texts}\xB7\uC774\uBBF8\uC9C0 ${result.stats.images}\xB7\uD45C ${result.stats.tables})`,
@@ -808,7 +838,7 @@ server.tool(
808
838
  summary.push(`\uC800\uC7A5: ${outPath}`);
809
839
  return { content: [{ type: "text", text: summary.join("\n") }] };
810
840
  }
811
- const { rasterizeSvg } = await import("./rasterize-NRWP2C6L.js");
841
+ const { rasterizeSvg } = await import("./rasterize-QCOBWHAG.js");
812
842
  const raster = await rasterizeSvg(result.svg, result.width, result.height);
813
843
  if (outPath) {
814
844
  await mkdir(dirname(outPath), { recursive: true });
@@ -830,6 +860,39 @@ server.tool(
830
860
  }
831
861
  }
832
862
  );
863
+ server.tool(
864
+ "crop_regions",
865
+ "HWPX \uBB38\uC11C\uB97C \uB80C\uB354\uD574 \uD45C\xB7\uC774\uBBF8\uC9C0\xB7\uBB38\uB2E8\xB7\uB3C4\uD615 \uC601\uC5ED\uC744 \uD398\uC774\uC9C0 \uC774\uBBF8\uC9C0\uC5D0\uC11C \uC798\uB77C \uD30C\uC77C\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4(render_document \uC640 \uAC19\uC740 \uC870\uD310 \uC5D4\uC9C4, \uD398\uC774\uC9C0 \uB85C\uCEEC pt bbox \uB97C \uC2E4\uBC30\uC728\uB85C \uD658\uC0B0). \uD45C\uAC00 \uC9C4\uC9DC \uB370\uC774\uD130\uD45C\uC778\uC9C0 \uC870\uC9C1\uB3C4\uC778\uC9C0\uB294 \uD310\uB2E8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB7EC\uAC00 \uC544\uB294 \uAC1C\uCCB4\uB97C \uC790\uB97C \uBFD0. \uACB0\uACFC: output_dir/<\uC720\uD615>_<\uBC88\uD638>_page_<\uCABD>.png + regions.json(id\xB7\uC720\uD615\xB7\uD398\uC774\uC9C0\xB7bbox pt).",
866
+ {
867
+ file_path: z.string().min(1).describe("HWPX \uD30C\uC77C \uC808\uB300 \uACBD\uB85C"),
868
+ output_dir: z.string().min(1).describe("crop \uD30C\uC77C \uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC"),
869
+ target: z.array(z.enum(["table", "image", "paragraph", "shape"])).default(["table"]).describe("\uC798\uB77C\uB0BC \uAC1C\uCCB4 \uC720\uD615"),
870
+ format: z.enum(["png", "jpeg"]).default("png"),
871
+ pages: z.string().min(1).optional().describe("\uB300\uC0C1 \uD398\uC774\uC9C0(1-based \uBC94\uC704)"),
872
+ padding_pt: z.number().min(0).max(100).default(0).describe("bbox \uB458\uB808 \uC5EC\uBC31 pt")
873
+ },
874
+ async ({ file_path, output_dir, target, format, pages, padding_pt }) => {
875
+ try {
876
+ const { buffer } = await readValidatedFile(file_path, MAX_FILE_SIZE, /* @__PURE__ */ new Set([".hwpx"]));
877
+ const dir = safeOutputPath(join(output_dir, "regions.json"), /* @__PURE__ */ new Set([".json"])).replace(/[\\/]regions\.json$/, "");
878
+ const { extractRenderedRegions } = await import("./render-DHFQQCSV.js");
879
+ const regions = await extractRenderedRegions(buffer, { types: target, format, pages, paddingPt: padding_pt, reflow: true });
880
+ await mkdir(dir, { recursive: true });
881
+ const ext = format === "jpeg" ? "jpg" : "png";
882
+ const manifest = [];
883
+ for (const r of regions) {
884
+ const name = `${r.region.id.replace("-", "_")}_page_${String(r.page).padStart(3, "0")}.${ext}`;
885
+ await writeFile(join(dir, name), r.data);
886
+ manifest.push({ file: name, id: r.region.id, type: r.region.type, sourceId: r.region.sourceId, parentId: r.region.parentId, page: r.page, bbox: r.bbox, widthPx: r.widthPx, heightPx: r.heightPx });
887
+ }
888
+ await writeFile(join(dir, "regions.json"), JSON.stringify(manifest, null, 2));
889
+ return { content: [{ type: "text", text: `crop ${regions.length}\uAC74 \u2192 ${dir}
890
+ ` + manifest.map((m) => `${m.file} p${m.page} (${m.bbox.x},${m.bbox.y} ${m.bbox.width}\xD7${m.bbox.height}pt)${m.sourceId ? ` src=${m.sourceId}` : ""}`).join("\n") }] };
891
+ } catch (err) {
892
+ return { content: [{ type: "text", text: `crop \uC2E4\uD328: ${describeError(err)}` }], isError: true };
893
+ }
894
+ }
895
+ );
833
896
  server.tool(
834
897
  "redact_document",
835
898
  "\uBB38\uC11C\uC758 \uAC1C\uC778\uC815\uBCF4(\uC8FC\uBBFC\uBC88\uD638\xB7\uC804\uD654\xB7\uC774\uBA54\uC77C\xB7\uCE74\uB4DC\xB7\uACC4\uC88C)\uB97C \uD0D0\uC9C0\uD574 \uC11C\uC2DD \uBCF4\uC874 \uB9C8\uC2A4\uD0B9\uD569\uB2C8\uB2E4. HWPX/HWP\uB294 \uC6D0\uBCF8 \uC11C\uC2DD 1\uBC14\uC774\uD2B8 \uADF8\uB300\uB85C patch, \uADF8 \uC678 \uD3EC\uB9F7\uC740 \uB9C8\uC2A4\uD0B9\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uC73C\uB85C \uCD9C\uB825. \uC790\uB3D9 \uAC80\uCD9C \uBCF4\uC870 \uB3C4\uAD6C \u2014 \uACB0\uACFC \uB9AC\uD3EC\uD2B8\uB97C \uC0AC\uB78C\uC774 \uCD5C\uC885 \uD655\uC778\uD574\uC57C \uD558\uBA70 \uC774\uBBF8\uC9C0 \uC548 \uD14D\uC2A4\uD2B8\uB294 \uD0D0\uC9C0\uD558\uC9C0 \uBABB\uD569\uB2C8\uB2E4. \uB9C8\uC2A4\uD0B9 \uD6C4 render_document\uB85C \uB208\uC73C\uB85C \uD655\uC778\uD558\uB294 \uAC83\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
@@ -906,7 +969,7 @@ server.tool(
906
969
  if (!parsed.success) {
907
970
  return { content: [{ type: "text", text: `\uD30C\uC2F1 \uC2E4\uD328: ${parsed.error}` }], isError: true };
908
971
  }
909
- const { blocksToChunks } = await import("./chunks-TT7ZE5QQ.js");
972
+ const { blocksToChunks } = await import("./chunks-G3GK536Y.js");
910
973
  const chunks = blocksToChunks(parsed.blocks, { granularity, includeTableCells: include_table_cells });
911
974
  return { content: [{ type: "text", text: capResponseText(JSON.stringify(chunks, null, 2)) }] };
912
975
  } catch (err) {
@@ -925,7 +988,7 @@ server.tool(
925
988
  try {
926
989
  const out = safeOutputPath(output_path, PROFILE_EXTENSIONS);
927
990
  const { buffer } = await readValidatedFile(hwpx_path);
928
- const { hwpxToProfile } = await import("./-EZH6NKTE.js");
991
+ const { hwpxToProfile } = await import("./-UZDRUWTX.js");
929
992
  const profile = await hwpxToProfile(buffer);
930
993
  await mkdir(dirname(out), { recursive: true });
931
994
  await writeFile(out, JSON.stringify(profile, null, 2));
@@ -943,7 +1006,7 @@ server.tool(
943
1006
  );
944
1007
  server.tool(
945
1008
  "generate_document",
946
- `\uB9C8\uD06C\uB2E4\uC6B4\uC744 HWPX \uD55C\uAE00 \uBB38\uC11C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4. "\uBCF4\uACE0\uC11C\uB85C/\uACF5\uBB38\uC11C\uB85C/\uAC1C\uC870\uC2DD\uC73C\uB85C/\uACC4\uD68D\uC11C\uB85C \uBF51\uC544\uC918\xB7\uB9CC\uB4E4\uC5B4\uC918" \uC694\uCCAD\uC774 \uC774 \uB3C4\uAD6C\uC785\uB2C8\uB2E4. \uD504\uB9AC\uC14B \uB9E4\uD551: \uC815\uBD80 \uD45C\uC900 \uBCF4\uACE0\uC11C(\uD45C\uC9C0\xB7\uBAA9\uCC28\xB7\uB85C\uB9C8\uC22B\uC790 \uC7A5\uD5E4\uB354 \uC790\uB3D9)='\uAC1C\uC870\uC2DD', \uAE30\uC548\uBB38\xB7\uC2DC\uD589\uBB38\xB7\uC54C\uB9BC\uACF5\uBB38='\uAE30\uC548\uBB38', 1\uD398\uC774\uC9C0 \uC694\uC57D\uBCF4\uACE0\uC11C='\uBCF4\uACE0\uC11C', \uCD94\uC9C4\uACC4\uD68D='\uACC4\uD68D\uC11C'. \uD45C\uB294 \uC2E4\uCE21 \uC815\uBD80 \uC11C\uC2DD(\uD5E4\uB354 \uC74C\uC601+\uC774\uC911\uC120\xB7\uC678\uACFD \uAD75\uC740\uC120\xB7\uB0B4\uC6A9 \uBE44\uB840 \uC5F4\uD3ED), \uCABD\uBC88\uD638\xB7\uACB0\uC7AC\uB780\xB7'\uB05D.' \uD45C\uC2DC \uC9C0\uC6D0. \u26A0 \uC0DD\uC131 \uC804 \uD655\uC778 \uAD8C\uC7A5: \uBB38\uC11C\uC885\uB958(\uBCF4\uACE0\uC11C/\uAE30\uC548\uBB38)\xB7\uC81C\uBAA9\xB7\uAE30\uAD00\uBA85(org)\xB7\uB0A0\uC9DC\xB7\uBAA9\uCC28 \uC5EC\uBD80\uAC00 \uBD88\uBA85\uD655\uD558\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3C\uC5B4\uBCF4\uC138\uC694 \u2014 \uC5C9\uB6B1\uD55C \uD504\uB9AC\uC14B \uC120\uD0DD\uC774 \uAC00\uC7A5 \uD754\uD55C \uC624\uC0DD\uC131 \uC6D0\uC778. \uB9C8\uD06C\uB2E4\uC6B4 \uADDC\uCE59: #(h1)=\uBB38\uC11C \uC81C\uBAA9(\uD45C\uC9C0), ##(h2)=\uC7A5(\u2160 \u2161 \u2162 \uC790\uB3D9), \uB9AC\uC2A4\uD2B8 \uAE4A\uC774=\u25A1 \u25CB - \u318D \uBD80\uD638, \u203B\uC2DC\uC791 \uBB38\uB2E8=\uCC38\uACE0 \uC2A4\uD0C0\uC77C, <right>\uD14D\uC2A4\uD2B8</right>=\uC6B0\uCE21\uC815\uB82C \uCD9C\uCC98\uD589. (\uC6D0\uBCF8 \uC11C\uC2DD \uBCF4\uC874 \uC81C\uC790\uB9AC \uC218\uC815\uC740 patch_document, \uC11C\uC2DD \uBE48\uCE78 \uCC44\uC6B0\uAE30\uB294 fill_form)`,
1009
+ "\uB9C8\uD06C\uB2E4\uC6B4\uC744 HWPX \uD55C\uAE00 \uBB38\uC11C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4. \"\uBCF4\uACE0\uC11C\uB85C/\uACF5\uBB38\uC11C\uB85C/\uAC1C\uC870\uC2DD\uC73C\uB85C/\uACC4\uD68D\uC11C\uB85C \uBF51\uC544\uC918\xB7\uB9CC\uB4E4\uC5B4\uC918\" \uC694\uCCAD\uC774 \uC774 \uB3C4\uAD6C\uC785\uB2C8\uB2E4. \uD504\uB9AC\uC14B \uB9E4\uD551: \uC815\uBD80 \uD45C\uC900 \uBCF4\uACE0\uC11C(\uD45C\uC9C0\xB7\uBAA9\uCC28\xB7\uB85C\uB9C8\uC22B\uC790 \uC7A5\uD5E4\uB354 \uC790\uB3D9)='\uAC1C\uC870\uC2DD', \uAE30\uC548\uBB38\xB7\uC2DC\uD589\uBB38\xB7\uC54C\uB9BC\uACF5\uBB38='\uAE30\uC548\uBB38', 1\uD398\uC774\uC9C0 \uC694\uC57D\uBCF4\uACE0\uC11C='\uBCF4\uACE0\uC11C', \uCD94\uC9C4\uACC4\uD68D='\uACC4\uD68D\uC11C'. \uD45C\uB294 \uC2E4\uCE21 \uC815\uBD80 \uC11C\uC2DD(\uD5E4\uB354 \uC74C\uC601+\uC774\uC911\uC120\xB7\uC678\uACFD \uAD75\uC740\uC120\xB7\uB0B4\uC6A9 \uBE44\uB840 \uC5F4\uD3ED), \uCABD\uBC88\uD638\xB7\uACB0\uC7AC\uB780\xB7'\uB05D.' \uD45C\uC2DC \uC9C0\uC6D0. \u26A0 \uC0DD\uC131 \uC804 \uD655\uC778 \uAD8C\uC7A5: \uBB38\uC11C\uC885\uB958(\uBCF4\uACE0\uC11C/\uAE30\uC548\uBB38)\xB7\uC81C\uBAA9\xB7\uAE30\uAD00\uBA85(org)\xB7\uB0A0\uC9DC\xB7\uBAA9\uCC28 \uC5EC\uBD80\uAC00 \uBD88\uBA85\uD655\uD558\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3C\uC5B4\uBCF4\uC138\uC694 \u2014 \uC5C9\uB6B1\uD55C \uD504\uB9AC\uC14B \uC120\uD0DD\uC774 \uAC00\uC7A5 \uD754\uD55C \uC624\uC0DD\uC131 \uC6D0\uC778. \uB9C8\uD06C\uB2E4\uC6B4 \uADDC\uCE59(v4.13 \uC11C\uC6B8 \uC2E4\uACB0\uC7AC \uC2E4\uCE21 \uC704\uACC4): #(h1)=\uBB38\uC11C \uC81C\uBAA9, ##(h2)=\uC7A5(\uBCF4\uACE0\uC11C \u2160 \u2161 / \uAE30\uC548\uBB38\xB7\uD1B5\uC9C0\uB294 \uBC95\uC815 1.), ###(h3)=\u25A1 \uB300\uD56D\uBAA9(\uAE30\uC548\uBB38 \uAC00.), \uADF8 \uC544\uB798 \uB9AC\uC2A4\uD2B8=\u3147 \u2192 - \u2192 \u318D(\uAE30\uC548\uBB38 \uAC00. \u2192 1) \u2192 \uAC00)), \uBCF8\uBB38\uC5D0 \u25A1/\u3147/-/1./\uAC00. \uB97C \uC9C1\uC811 \uC368\uB3C4 \uAC19\uC740 \uC704\uACC4\uB85C \uC815\uADDC\uD654, \u203B\uC2DC\uC791\xB7'\uCD9C\uCC98:'\xB7'\uC790\uB8CC:'=\uCC38\uACE0(13pt), \uC81C\uBAA9 \uC9C1\uD6C4 \uC778\uC6A9\uBB38(>)=\uBCF4\uACE0\uC11C \uC694\uC57D\uBC15\uC2A4 \u2014 \u2605\uBCF4\uACE0\uC11C\uB294 \uBC18\uB4DC\uC2DC \uC81C\uBAA9 \uC9C1\uD6C4 `> \u2026\uD558\uACE0\uC790 \uD568` \uD55C \uBB38\uC7A5(\uC27C\uD45C \uD5C8\uC6A9\xB7\uBD80\uD638 \uC5C6\uC74C\xB73\uC904 \uC774\uB0B4 \uC57D 90~100\uC790)\uB85C \uBCF4\uACE0 \uBAA9\uC801\uC744 \uB123\uC744 \uAC83(\uC5C6\uAC70\uB098 3\uC904 \uCD08\uACFC\uBA74 \uACBD\uACE0), <right>\uD14D\uC2A4\uD2B8</right>=\uC6B0\uCE21\uC815\uB82C. \u25A1\xB7\uC81C\uBAA9\uC740 \uD55C \uC904\uC5D0 \uC790\uB3D9 \uCD95\uC18C, \uB458\uC9F8 \uC904 20% \uC774\uB0B4 \uACE0\uC544 \uC904\uC740 \uC790\uAC04 \uCD95\uC18C\uB85C \uD55C \uC904. \uBC95\uB839 \uCF54\uB4DC (282791)\xB7KOSIS \uD45C ID DT_\u2026\xB7(\uBC95\uC815\uB3D9\uCF54\uB4DC \u2026)\xB7\u25CB\u25CB MCP \uC870\uD68C \uAC19\uC740 \uB0B4\uBD80 \uC2DD\uBCC4\uC790\xB7\uB3C4\uAD6C \uC5B8\uAE09\uC740 \uC790\uB3D9 \uC81C\uAC70 \u2014 \uCD9C\uCC98\uB294 \uAE30\uAD00\xB7\uC790\uB8CC\uBA85\uB9CC \uC4F8 \uAC83. (\uC6D0\uBCF8 \uC11C\uC2DD \uBCF4\uC874 \uC81C\uC790\uB9AC \uC218\uC815\uC740 patch_document, \uC11C\uC2DD \uBE48\uCE78 \uCC44\uC6B0\uAE30\uB294 fill_form)",
947
1010
  {
948
1011
  markdown: z.string().min(1).describe("HWPX\uB85C \uBCC0\uD658\uD560 \uB9C8\uD06C\uB2E4\uC6B4 \uC804\uBB38. \uD45C\uB294 GFM \uBB38\uBC95 \uC0AC\uC6A9 (\uC608: '| \uC774\uB984 | \uBD80\uC11C |\\n| --- | --- |\\n| \uD64D\uAE38\uB3D9 | \uAE30\uD68D\uD300 |')"),
949
1012
  output_path: z.string().min(1).describe("\uCD9C\uB825 HWPX \uD30C\uC77C\uC758 \uC808\uB300 \uACBD\uB85C (.hwpx \uAD8C\uC7A5)"),
@@ -961,14 +1024,18 @@ server.tool(
961
1024
  page_numbers: z.boolean().optional().describe("\uCABD\uBC88\uD638(\uD558\uB2E8 \uC911\uC559 '- 1 -', \uD45C\uC9C0\xB7\uBAA9\uCC28 \uCE74\uC6B4\uD2B8 \uC81C\uC678). \uBBF8\uC9C0\uC815 \uC2DC \uAC1C\uC870\uC2DD\xB7\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uCF1C\uC9D0"),
962
1025
  end_mark: z.boolean().optional().describe("\uBCF8\uBB38 \uB05D '\uB05D.' \uD45C\uC2DC (\uD589\uC815\uC5C5\uBB34\uADDC\uC815). \uBBF8\uC9C0\uC815 \uC2DC \uAE30\uC548\uBB38\uB9CC \uCF1C\uC9D0, \uBCF8\uBB38\uC774 \uC774\uBBF8 '\uB05D.'\uC73C\uB85C \uB05D\uB098\uBA74 \uC911\uBCF5 \uC0DD\uC131 \uC548 \uD568"),
963
1026
  body_title_box: z.boolean().optional().describe("\uBCF8\uBB38 \uCCAB \uD398\uC774\uC9C0 \uC81C\uBAA9 \uBC18\uBCF5 \uBC15\uC2A4 (\uAC1C\uC870\uC2DD \uC2E4\uCE21 \uAD00\uD589). \uBBF8\uC9C0\uC815 \uC2DC \uAC1C\uC870\uC2DD+\uD45C\uC9C0 \uC870\uD569\uC5D0\uC11C \uCF1C\uC9D0"),
964
- h2_marker: z.enum(H2_MARKERS).optional().describe("h2 \uC139\uC158 \uC81C\uBAA9 \uB9D0\uBA38\uB9AC(\uBE44\uAC1C\uC870\uC2DD): box='\u25A1 \uC81C\uBAA9'(\uC2E4\uCE21 \uBCF4\uACE0\uC11C \uAD00\uD589), number='1. \uC81C\uBAA9'(\uACF5\uACE0\uBB38 \uAD00\uD589), none=\uB9D0\uBA38\uB9AC \uC5C6\uC74C. \uBBF8\uC9C0\uC815 \uC2DC \uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C box, \uADF8 \uC678 none"),
1027
+ h2_marker: z.enum(H2_MARKERS).optional().describe("h2 \uC7A5 \uC81C\uBAA9 \uD45C\uAE30: band=\uB85C\uB9C8\uC790 \uCC44\uC6C0 \uCE78+\uC81C\uBAA9 \uB760 \uD45C(\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uAE30\uBCF8), roman='\u2160. \uC81C\uBAA9' \uD14D\uC2A4\uD2B8, number='1. \uC81C\uBAA9'(\uD1B5\uC9C0 \uAE30\uBCF8), box=\uC7A5 \uC5C6\uC774 \u25A1 \uB300\uD56D\uBAA9\uC73C\uB85C, none=\uBC88\uD638 \uC5C6\uC74C. \uAE30\uC548\uBB38 \uBCF8\uBB38\uC758 h2\uB294 \uD56D\uC0C1 \uBC95\uC815 '1.' \uD56D\uBAA9"),
1028
+ summary: z.string().optional().describe("\uBCF4\uACE0\uC11C \uC694\uC57D \uBC15\uC2A4 \u2014 \uC81C\uBAA9\uD45C \uC544\uB798 #DFE6F7 \uC74C\uC601 \uC0C1\uC790(\uC11C\uC6B8 \uC2E4\uACB0\uC7AC \uAD00\uD589). \uB9C8\uD06C\uB2E4\uC6B4 \uC81C\uBAA9 \uC9C1\uD6C4 \uC778\uC6A9\uBB38(> \u2026)\uC73C\uB85C\uB3C4 \uC9C0\uC815 \uAC00\uB2A5"),
1029
+ doc_info: z.object(Object.fromEntries(DOC_INFO_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uBCF4\uACE0\uC11C \uD45C\uC9C0 \uBB38\uC11C\uC815\uBCF4\uD45C \u2014 docNum=\uBB38\uC11C\uBC88\uD638/date=\uACB0\uC7AC\uC77C\uC790/disclosure=\uACF5\uAC1C\uC5EC\uBD80/policyNo=\uBC29\uCE68\uBC88\uD638 (cover=true\uC640 \uD568\uAED8)"),
1030
+ dept: z.string().optional().describe("\uD45C\uC9C0 \uBD80\uC11C\uBA85 \u2014 \uAE30\uAD00\uBA85 \uC544\uB798 '(\uC2A4\uB9C8\uD2B8\uB3C4\uC2DC\uACFC)' (cover\uC640 \uD568\uAED8)"),
965
1031
  fonts: z.object(Object.fromEntries(FONT_ROLE_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uC694\uC18C\uBCC4 \uAE00\uAF34 \uC624\uBC84\uB77C\uC774\uB4DC(\uACF5\uBB38\uC11C \uBAA8\uB4DC) \u2014 body=\uBCF8\uBB38(\u25CB\xB7-)/heading=\uC81C\uBAA9 \uACC4\uC5F4(\u25A1\xB7\uC7A5\uD5E4\uB354\xB7\uD45C\uC9C0\xB7\uBAA9\uCC28)/ref=\u203B \uCC38\uACE0/table=\uD45C \uC140. \uAC1C\uC870\uC2DD\xB7\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C\uB294 \uB124 \uC5ED\uD560 \uC804\uBD80, \uADF8 \uC678 \uD504\uB9AC\uC14B\uC740 body\uB9CC \uC801\uC6A9"),
966
1032
  sizes: z.object(Object.fromEntries(SIZE_KEYS.map((k) => [k, z.number().min(SIZE_PT_RANGE.min).max(SIZE_PT_RANGE.max).optional()]))).optional().describe("\uAC1C\uC870\uC2DD \uC694\uC18C\uBCC4 \uAE00\uC790 \uD06C\uAE30(pt) \uC624\uBC84\uB77C\uC774\uB4DC \u2014 dae=\u25A1/cham=\u203B/chapter=\uC7A5\uD5E4\uB354/coverTitle\xB7coverSub=\uD45C\uC9C0/tocLabel\xB7tocRoman\xB7tocItem=\uBAA9\uCC28/table=\uD45C \uC140/bodyTitle=\uBCF8\uBB38 \uCCAB \uD398\uC774\uC9C0 \uC81C\uBAA9 \uBC18\uBCF5 \uBC15\uC2A4. \uBBF8\uC9C0\uC815 \uC694\uC18C\uB294 body_pt \uBE44\uB840 \uAE30\uBCF8\uAC12"),
1033
+ levels: z.record(z.string().regex(/^[0-7]$/), z.object(Object.fromEntries(LEVEL_STYLE_KEYS.map((k) => [k, k === "pt" ? z.number().min(SIZE_PT_RANGE.min).max(SIZE_PT_RANGE.max).optional() : k === "bold" ? z.boolean().optional() : z.string().optional()])))).optional().describe('\uD56D\uBAA9\uBD80\uD638 \uB2E8\uACC4\uBCC4 \uC704\uACC4 \uD0C0\uC774\uD3EC(\uACF5\uBB38\uC11C \uBAA8\uB4DC, v4.12.3) \u2014 {"0":{font:"HY\uACAC\uACE0\uB515",pt:17,bold:true},"1":{font:"\uD55C\uCEF4\uB3CB\uC6C0",bold:true}} \uAF34(depth 0~7). \uC2E4\uCE21: \uC804\uC790\uACB0\uC7AC \uAE30\uC548\uBB38 \u25A1/\u3147/- \uACC4\uC5F4\uC740 \u25A1=HY\uACAC\uACE0\uB515 +2~3pt \uAD75\uAC8C\xB7\u3147=\uD55C\uCEF4\uB3CB\uC6C0 \uAD75\uAC8C\xB7-=\uD734\uBA3C\uBA85\uC870 \uBCF8\uBB38. \uBC95\uC815 8\uB2E8\uACC4(1. \uAC00.)\uB294 \uBCF8\uBB38 \uB3D9\uC77C\uC774 \uAD00\uD589\uC774\uB77C \uAE30\uBCF8 \uBBF8\uC801\uC6A9'),
967
1034
  bullet2: z.enum(BULLET2_CHARS).optional().describe("2\uB2E8\uACC4 \uD56D\uBAA9\uBD80\uD638 \u2014 '\u3147'(\uC774\uC751, \uC804\uC790\uACB0\uC7AC \uAE30\uC548\uBB38\xB7\uACF5\uACE0\uBB38 \uC2E4\uCE21 \uC9C0\uBC30) / '\u25CB'(\uC6D0, \uBCF4\uACE0\uC11C \uC591\uC2DD). \uBBF8\uC9C0\uC815 \uC2DC \uD1B5\uC9C0\xB7\uBCF4\uB3C4\uC790\uB8CC \u3147, \uADF8 \uC678 \u25CB"),
968
1035
  suppress_single: z.boolean().optional().describe("\uB2E8\uC77C \uD615\uC81C \uD56D\uBAA9 \uBD80\uD638 \uC0DD\uB7B5(\uD3B8\uB78C \uADDC\uC815, \uBC95\uC815 \uBC88\uD638 standard \uC804\uC6A9 \u2014 \uBD88\uB9BF \uCCB4\uACC4\uC778 \uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C\xB7\uAC1C\uC870\uC2DD\xB7\uBCF4\uB3C4\uC790\uB8CC\uC5D4 \uBB34\uD6A8). \uAE30\uBCF8 false \u2014 \uD558\uB098\uBFD0\uC778 \uD56D\uBAA9\uC5D0\uB3C4 \uBD80\uD638(1. \uAC00.)\uB97C \uBD80\uC5EC (\uBD80\uD638 \uC5C6\uB294 \uACC4\uB2E8 \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC2E4\uBB34 \uB208\uC5D0 \uC5B4\uC0C9)"),
969
- doc_head: z.object(Object.fromEntries(DOC_HEAD_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uAE30\uC548\uBB38 \uB450\uBB38(\uBCC4\uC9C0 \uC81C1\uD638\uC11C\uC2DD) \u2014 org=\uD589\uC815\uAE30\uAD00\uBA85(18pt bold \uC911\uC559)/to=\uC218\uC2E0/via=\uACBD\uC720/title=\uC81C\uBAA9. \uAE30\uC548\uBB38 \uD504\uB9AC\uC14B \uC804\uC6A9"),
970
- doc_foot: z.object(Object.fromEntries(DOC_FOOT_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uAE30\uC548\uBB38 \uACB0\uBB38 \u2014 sender=\uBC1C\uC2E0\uBA85\uC758(22pt \uC911\uC559)/drafter\xB7reviewer\xB7approver=\uAE30\uC548\xB7\uAC80\uD1A0\xB7\uACB0\uC7AC/docNum=\uC2DC\uD589/receive=\uC811\uC218/disclosure=\uACF5\uAC1C\uAD6C\uBD84 \uB4F1. \uAE30\uC548\uBB38 \uD504\uB9AC\uC14B \uC804\uC6A9"),
971
- report_info: z.string().optional().describe("\uC5C5\uBB34\uBCF4\uACE0 \uC6B0\uC0C1\uB2E8 \uBCF4\uACE0\uC815\uBCF4 \uD589 \u2014 \uC608: '(2026. 7. 11., \uACFC\uC7A5 \uD64D\uAE38\uB3D9, \u260E02-120)' (\uC2E4\uCE21: 12pt \uC6B0\uCE21\uC815\uB82C)"),
1036
+ doc_head: z.object(Object.fromEntries(DOC_HEAD_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uAE30\uC548\uBB38 \uB450\uBB38\uD45C(\uBCC4\uC9C0 \uC81C1\uD638\uC11C\uC2DD\xB7\uC11C\uC6B8 \uC2E4\uACB0\uC7AC 6\uD589 \uD45C) \u2014 org=\uD589\uC815\uAE30\uAD00\uBA85(\uAD74\uB9BC 20pt bold \uC790\uAC04\uB744\uC6C0)/slogan=\uC6D0\uD6C8(\uC0C1\uB2E8 10pt)/to=\uC218\uC2E0('\uB0B4\uBD80\uACB0\uC7AC'\uBA74 \uBC1C\uC2E0\uBA85\uC758 \uC0DD\uB7B5)/via=\uACBD\uC720/title=\uC81C\uBAA9(\uBBF8\uC9C0\uC815 \uC2DC \uCCAB h1). \uAE30\uC548\uBB38 \uD504\uB9AC\uC14B \uC804\uC6A9"),
1037
+ doc_foot: z.object(Object.fromEntries(DOC_FOOT_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uAE30\uC548\uBB38 \uACB0\uBB38\uD45C \u2014 sender=\uBC1C\uC2E0\uBA85\uC758(18pt bold \uC911\uC559)/drafter\xB7reviewer\xB7approver='\uC9C1\uC704 \uC131\uBA85' \uACB0\uC7AC\uC120/cooperator=\uD611\uC870\uC790/recipients=\uC218\uC2E0\uC790 \uBAA9\uB85D/docNum=\uC2DC\uD589 '\uACFC-\uBC88\uD638 (\uB0A0\uC9DC)'/receive=\uC811\uC218/zip\xB7address\xB7site/phone\xB7fax\xB7email/disclosure=\uACF5\uAC1C\uAD6C\uBD84. \uAE30\uC548\uBB38 \uD504\uB9AC\uC14B \uC804\uC6A9"),
1038
+ report_info: z.string().optional().describe("\uBCF4\uACE0\uC11C: \uC81C\uBAA9\uD45C \uC544\uB798 \uB2F4\uB2F9\uC790 \uD589 '(2026. 9. 6., \uC2A4\uB9C8\uD2B8\uB3C4\uC2DC\uACFC \uD64D\uAE38\uB3D9, \u260E450-1234)' / \uAE30\uC548\uBB38: \uC6B0\uC0C1\uB2E8 12pt \uBCF4\uACE0\uC815\uBCF4 \uD589"),
972
1039
  notice_head: z.object(Object.fromEntries(NOTICE_HEAD_KEYS.map((k) => [k, z.string().optional()]))).optional().describe("\uACF5\uACE0\uBB38 \uB450\uBB38\xB7\uACB0\uBB38 \u2014 no=\uACF5\uACE0\uBC88\uD638(\uBCF8\uBB38 \uC704 bold)/date=\uB0A0\uC9DC(\uBCF8\uBB38 \uC544\uB798 \uC6B0\uCE21)/sender=\uBC1C\uC2E0\uBA85\uC758(\uC6B0\uCE21 bold). \uD1B5\uC9C0 \uD504\uB9AC\uC14B \uC804\uC6A9"),
973
1040
  press: z.object({
974
1041
  release: z.string().optional(),
@@ -983,7 +1050,7 @@ server.tool(
983
1050
  footer: z.string().optional().describe("\uAF2C\uB9AC\uB9D0 \uD14D\uC2A4\uD2B8 \u2014 \uBAA8\uB4E0 \uCABD \uD558\uB2E8 (v4.5.0)"),
984
1051
  image_dir: z.string().optional().describe("\uB9C8\uD06C\uB2E4\uC6B4 \uC774\uBBF8\uC9C0 \uCC38\uC870(![](x.png))\uB97C \uC774 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC77D\uC5B4 \uC2E4\uB370\uC774\uD130 \uC784\uBCA0\uB4DC (v4.5.0, PNG/JPEG/GIF/BMP). \uBBF8\uC9C0\uC815 \uC2DC \uCC38\uC870\uB9CC placeholder\uB85C \uBCF4\uC874")
985
1052
  },
986
- async ({ markdown, output_path, profile_path, preset, font, body_pt, line_spacing, org, date, toc, cover, approval, page_numbers, end_mark, body_title_box, h2_marker, fonts, sizes, bullet2, suppress_single, doc_head, doc_foot, report_info, notice_head, press, paper, landscape, columns, header, footer, image_dir }) => {
1053
+ async ({ markdown, output_path, profile_path, preset, font, body_pt, line_spacing, org, date, toc, cover, approval, page_numbers, end_mark, body_title_box, h2_marker, summary, doc_info, dept, fonts, sizes, levels, bullet2, suppress_single, doc_head, doc_foot, report_info, notice_head, press, paper, landscape, columns, header, footer, image_dir }) => {
987
1054
  try {
988
1055
  let gongmun;
989
1056
  if (preset) {
@@ -1003,18 +1070,22 @@ server.tool(
1003
1070
  h2Marker: h2_marker,
1004
1071
  fonts,
1005
1072
  sizes,
1073
+ levels,
1006
1074
  bullet2,
1007
1075
  suppressSingle: suppress_single,
1008
1076
  docHead: doc_head,
1009
1077
  docFoot: doc_foot,
1010
1078
  reportInfo: report_info,
1011
1079
  noticeHead: notice_head,
1012
- press
1080
+ press,
1081
+ summary,
1082
+ docInfo: doc_info,
1083
+ dept
1013
1084
  });
1014
1085
  }
1015
1086
  let profile;
1016
1087
  if (profile_path) {
1017
- const { parseFormatProfileJson } = await import("./profile-io-PZVMM66V.js");
1088
+ const { parseFormatProfileJson } = await import("./profile-io-Y24GOHWM.js");
1018
1089
  profile = parseFormatProfileJson(await readFile(safePath(profile_path, PROFILE_EXTENSIONS), "utf-8"));
1019
1090
  }
1020
1091
  const out = safeOutputPath(output_path, /* @__PURE__ */ new Set([".hwpx"]));
@@ -1039,11 +1110,13 @@ server.tool(
1039
1110
  }
1040
1111
  }
1041
1112
  }
1113
+ const genWarnings = [];
1042
1114
  const buf = await markdownToHwpx(markdown, gongmun || profile || page || images ? {
1043
1115
  ...gongmun ? { gongmun } : {},
1044
1116
  ...profile ? { profile } : {},
1045
1117
  ...page ? { page } : {},
1046
- ...images ? { images } : {}
1118
+ ...images ? { images } : {},
1119
+ warnings: genWarnings
1047
1120
  } : void 0);
1048
1121
  await mkdir(dirname(out), { recursive: true });
1049
1122
  await writeFile(out, Buffer.from(buf));
@@ -1053,6 +1126,7 @@ server.tool(
1053
1126
  if (gongmun) fontWarns.push(...incompatibleGongmunWarnings(gongmun));
1054
1127
  if (gongmun) fontWarns.push(...gongmunLintWarnings(markdown, 5));
1055
1128
  if (gongmun && usesGaejosikMunche(gongmun.preset)) fontWarns.push(...muncheLintWarnings(markdown, 5));
1129
+ fontWarns.push(...genWarnings);
1056
1130
  const warnText = fontWarns.length ? `
1057
1131
  \u26A0 ${fontWarns.join("\n\u26A0 ")}` : "";
1058
1132
  return {