kordoc 3.16.0 → 3.16.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 (53) hide show
  1. package/README.md +1 -1
  2. package/dist/{-H7N62NZU.js → -YVONYEEN.js} +7 -7
  3. package/dist/{chunk-FGL7BH4P.js → chunk-7WUTJXKP.js} +49 -20
  4. package/dist/chunk-7WUTJXKP.js.map +1 -0
  5. package/dist/{chunk-5RHRQ7HK.js → chunk-CDFCA37S.js} +8 -4
  6. package/dist/chunk-CDFCA37S.js.map +1 -0
  7. package/dist/{chunk-LYL4IL3E.js → chunk-F62GOZFB.js} +13 -6
  8. package/dist/chunk-F62GOZFB.js.map +1 -0
  9. package/dist/{chunk-WD5NUUU6.js → chunk-I6T3DKYK.js} +315 -262
  10. package/dist/chunk-I6T3DKYK.js.map +1 -0
  11. package/dist/{chunk-JFNWJFKP.js → chunk-IY3NX4FT.js} +2 -2
  12. package/dist/{chunk-IC56KHBL.js → chunk-K4L563FA.js} +2 -2
  13. package/dist/{chunk-Q7EGGW3H.js → chunk-QOPY6URE.js} +13 -6
  14. package/dist/chunk-QOPY6URE.js.map +1 -0
  15. package/dist/{chunk-BIP4JAVG.cjs → chunk-VNIQK4AL.cjs} +13 -6
  16. package/dist/chunk-VNIQK4AL.cjs.map +1 -0
  17. package/dist/cli.js +56 -17
  18. package/dist/cli.js.map +1 -1
  19. package/dist/index.cjs +586 -502
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +11 -3
  22. package/dist/index.d.ts +11 -3
  23. package/dist/index.js +358 -274
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp.js +25 -16
  26. package/dist/mcp.js.map +1 -1
  27. package/dist/{parser-6V7F3GET.cjs → parser-3O2UF6VO.cjs} +35 -22
  28. package/dist/parser-3O2UF6VO.cjs.map +1 -0
  29. package/dist/{parser-HBHCD7TE.js → parser-B4O7CW5Q.js} +24 -11
  30. package/dist/parser-B4O7CW5Q.js.map +1 -0
  31. package/dist/{parser-5G247XYD.js → parser-BNEAMKUF.js} +23 -10
  32. package/dist/parser-BNEAMKUF.js.map +1 -0
  33. package/dist/render-QCNMRR7L.js +10 -0
  34. package/dist/seal-REDSMUI5.js +10 -0
  35. package/dist/{watch-HIYNOSFD.js → watch-RLF5F3TN.js} +7 -7
  36. package/package.json +2 -5
  37. package/dist/chunk-5RHRQ7HK.js.map +0 -1
  38. package/dist/chunk-BIP4JAVG.cjs.map +0 -1
  39. package/dist/chunk-FGL7BH4P.js.map +0 -1
  40. package/dist/chunk-LYL4IL3E.js.map +0 -1
  41. package/dist/chunk-Q7EGGW3H.js.map +0 -1
  42. package/dist/chunk-WD5NUUU6.js.map +0 -1
  43. package/dist/parser-5G247XYD.js.map +0 -1
  44. package/dist/parser-6V7F3GET.cjs.map +0 -1
  45. package/dist/parser-HBHCD7TE.js.map +0 -1
  46. package/dist/render-VA4NHROW.js +0 -10
  47. package/dist/seal-UVDRGHEF.js +0 -10
  48. /package/dist/{-H7N62NZU.js.map → -YVONYEEN.js.map} +0 -0
  49. /package/dist/{chunk-JFNWJFKP.js.map → chunk-IY3NX4FT.js.map} +0 -0
  50. /package/dist/{chunk-IC56KHBL.js.map → chunk-K4L563FA.js.map} +0 -0
  51. /package/dist/{render-VA4NHROW.js.map → render-QCNMRR7L.js.map} +0 -0
  52. /package/dist/{seal-UVDRGHEF.js.map → seal-REDSMUI5.js.map} +0 -0
  53. /package/dist/{watch-HIYNOSFD.js.map → watch-RLF5F3TN.js.map} +0 -0
@@ -10,7 +10,7 @@ import {
10
10
  convertTableToText,
11
11
  flattenLayoutTables,
12
12
  mapPuaText
13
- } from "./chunk-LYL4IL3E.js";
13
+ } from "./chunk-F62GOZFB.js";
14
14
  import {
15
15
  detectFormat,
16
16
  detectOle2Format,
@@ -31,12 +31,12 @@ import {
31
31
  paraTextPureT,
32
32
  patchZipEntries,
33
33
  scanSectionXml
34
- } from "./chunk-FGL7BH4P.js";
34
+ } from "./chunk-7WUTJXKP.js";
35
35
  import {
36
36
  SPACE_EM_FIXED,
37
37
  charWidthEm1000,
38
38
  fitRatioForFewerLines
39
- } from "./chunk-5RHRQ7HK.js";
39
+ } from "./chunk-CDFCA37S.js";
40
40
  import {
41
41
  MAX_DECOMPRESS_SIZE,
42
42
  MAX_XML_DEPTH,
@@ -47,7 +47,7 @@ import {
47
47
  createXmlParser,
48
48
  extractTextFromNode,
49
49
  findChildByLocalName
50
- } from "./chunk-JFNWJFKP.js";
50
+ } from "./chunk-IY3NX4FT.js";
51
51
  import {
52
52
  KordocError,
53
53
  classifyError,
@@ -58,7 +58,7 @@ import {
58
58
  sanitizeHref,
59
59
  stripDtd,
60
60
  toArrayBuffer
61
- } from "./chunk-IC56KHBL.js";
61
+ } from "./chunk-K4L563FA.js";
62
62
 
63
63
  // src/index.ts
64
64
  import { readFile } from "fs/promises";
@@ -660,8 +660,8 @@ function maskLiteralSpans(eqString) {
660
660
  function findKeywordToken(eqString, word, from = 0) {
661
661
  const masked = maskLiteralSpans(eqString);
662
662
  for (let i = masked.indexOf(word, from); i !== -1; i = masked.indexOf(word, i + 1)) {
663
- const okL = i === 0 || masked[i - 1] === " ";
664
- const okR = i + word.length === masked.length || masked[i + word.length] === " ";
663
+ const okL = i === 0 || /\s/.test(masked[i - 1]);
664
+ const okR = i + word.length === masked.length || /\s/.test(masked[i + word.length]);
665
665
  if (okL && okR) return i;
666
666
  }
667
667
  return -1;
@@ -672,11 +672,22 @@ function replaceFrac(eqString) {
672
672
  const cursor = findKeywordToken(eqString, hmlFrac);
673
673
  if (cursor === -1) break;
674
674
  try {
675
- const [numStart, numEnd] = findBrackets(eqString, cursor, 0);
676
- const numerator = eqString.slice(numStart, numEnd);
675
+ let end = cursor;
676
+ while (end > 0 && /\s/.test(eqString[end - 1])) end--;
677
+ let numStart, numEnd, wrapped;
678
+ if (end > 0 && eqString[end - 1] === "}") {
679
+ [numStart, numEnd] = findBrackets(eqString, end - 1, 0);
680
+ wrapped = eqString.slice(numStart, numEnd);
681
+ } else {
682
+ numEnd = end;
683
+ numStart = end;
684
+ while (numStart > 0 && !/\s/.test(eqString[numStart - 1])) numStart--;
685
+ if (numStart === numEnd) throw new Error("empty numerator");
686
+ wrapped = "{" + eqString.slice(numStart, numEnd) + "}";
687
+ }
677
688
  const beforeFrac = eqString.slice(0, numStart);
678
689
  const afterFrac = eqString.slice(cursor + hmlFrac.length);
679
- eqString = beforeFrac + "\\frac" + numerator + afterFrac;
690
+ eqString = beforeFrac + "\\frac" + wrapped + afterFrac;
680
691
  } catch {
681
692
  return eqString;
682
693
  }
@@ -18109,7 +18120,7 @@ function parseTable(tbl, styles, numbering, footnotes, rels) {
18109
18120
  if (trPrEls.length > 0) {
18110
18121
  const gridBeforeEls = getChildElements(trPrEls[0], "gridBefore");
18111
18122
  if (gridBeforeEls.length > 0) {
18112
- col = parseInt(getAttr(gridBeforeEls[0], "val") ?? "0", 10) || 0;
18123
+ col = Math.max(0, parseInt(getAttr(gridBeforeEls[0], "val") ?? "0", 10) || 0);
18113
18124
  }
18114
18125
  }
18115
18126
  for (const tc of getChildElements(tr, "tc")) {
@@ -18638,34 +18649,47 @@ function countSections(body) {
18638
18649
 
18639
18650
  // src/form/match.ts
18640
18651
  function parseYMD(v) {
18641
- const d = v.replace(/\D/g, "");
18642
18652
  let y, m, day;
18643
- if (d.length >= 8) {
18644
- y = d.slice(0, 4);
18645
- m = d.slice(4, 6);
18646
- day = d.slice(6, 8);
18647
- } else if (d.length === 6) {
18648
- const yy = +d.slice(0, 2);
18649
- y = String(yy <= 29 ? 2e3 + yy : 1900 + yy);
18650
- m = d.slice(2, 4);
18651
- day = d.slice(4, 6);
18652
- } else return null;
18653
+ const parts = v.split(/[^0-9]+/).filter(Boolean);
18654
+ if (parts.length === 3) {
18655
+ const [yp, mp, dp] = parts;
18656
+ const yn = +yp;
18657
+ y = yp.length >= 3 ? yp : String(yn <= 29 ? 2e3 + yn : 1900 + yn);
18658
+ m = mp.padStart(2, "0");
18659
+ day = dp.padStart(2, "0");
18660
+ } else {
18661
+ const d = v.replace(/\D/g, "");
18662
+ if (d.length >= 8) {
18663
+ y = d.slice(0, 4);
18664
+ m = d.slice(4, 6);
18665
+ day = d.slice(6, 8);
18666
+ } else if (d.length === 6) {
18667
+ const yy = +d.slice(0, 2);
18668
+ y = String(yy <= 29 ? 2e3 + yy : 1900 + yy);
18669
+ m = d.slice(2, 4);
18670
+ day = d.slice(4, 6);
18671
+ } else return null;
18672
+ }
18673
+ if (+m < 1 || +m > 12 || +day < 1 || +day > 31) return null;
18653
18674
  return { y, yy: y.slice(2), m, d: day };
18654
18675
  }
18655
18676
  function fmtDate(v, style) {
18656
18677
  const p = parseYMD(v);
18657
18678
  if (!p) return v;
18658
- return (style || "yyyy-mm-dd").replace(/yyyy/g, p.y).replace(/yy/g, p.yy).replace(/mm/g, p.m).replace(/dd/g, p.d).replace(/m/g, String(+p.m)).replace(/d/g, String(+p.d));
18679
+ return (style || "yyyy-mm-dd").replace(/yyyy/gi, p.y).replace(/yy/gi, p.yy).replace(/mm/gi, p.m).replace(/dd/gi, p.d).replace(/(?<![a-z])m(?![a-z])/gi, String(+p.m)).replace(/(?<![a-z])d(?![a-z])/gi, String(+p.d));
18659
18680
  }
18660
18681
  function maskDigits(v, pattern) {
18661
18682
  const ds = v.replace(/\D/g, "");
18683
+ const need = (pattern.match(/#/g) ?? []).length;
18684
+ if (need === 0 || ds.length !== need) return v;
18662
18685
  let i = 0;
18663
- return pattern.replace(/#/g, () => ds[i++] ?? "");
18686
+ return pattern.replace(/#/g, () => ds[i++]);
18664
18687
  }
18665
18688
  function fmtPhone(v, style) {
18666
18689
  const d = v.replace(/\D/g, "");
18667
18690
  if (d.length < 9) return v;
18668
- const a = d.slice(0, 3), b = d.slice(3, -4), c = d.slice(-4);
18691
+ const areaLen = d.startsWith("02") ? 2 : 3;
18692
+ const a = d.slice(0, areaLen), b = d.slice(areaLen, -4), c = d.slice(-4);
18669
18693
  switch (style) {
18670
18694
  case "digits":
18671
18695
  return d;
@@ -18674,9 +18698,9 @@ function fmtPhone(v, style) {
18674
18698
  case "space":
18675
18699
  return `${a} ${b} ${c}`;
18676
18700
  case "intl":
18677
- return `+82-${d.slice(1, 3)}-${b}-${c}`;
18701
+ return `+82-${d.slice(1, areaLen)}-${b}-${c}`;
18678
18702
  case "intl-paren":
18679
- return `82)${d.slice(1, 3)}-${b}-${c}`;
18703
+ return `82)${d.slice(1, areaLen)}-${b}-${c}`;
18680
18704
  default:
18681
18705
  return `${a}-${b}-${c}`;
18682
18706
  }
@@ -18704,7 +18728,10 @@ function formatFillValue(value, format) {
18704
18728
  if (kind === "phone") return fmtPhone(value, style);
18705
18729
  if (kind === "rrn") return fmtRRN(value, style);
18706
18730
  if (kind === "mask") return maskDigits(value, style);
18707
- if (kind === "digits") return value.replace(/\D/g, "");
18731
+ if (kind === "digits") {
18732
+ const only = value.replace(/\D/g, "");
18733
+ return only || value;
18734
+ }
18708
18735
  if (kind === "upper") return value.toUpperCase();
18709
18736
  if (kind === "lower") return value.toLowerCase();
18710
18737
  if (kind === "nospace") return value.replace(/\s+/g, "");
@@ -18781,7 +18808,7 @@ function isKeywordLabel(text) {
18781
18808
  }
18782
18809
  return false;
18783
18810
  }
18784
- function fillInCellPatterns(cellText, values, matchedLabels) {
18811
+ function fillInCellPatterns(cellText, values, matchedLabels, blockedLabels) {
18785
18812
  let text = cellText;
18786
18813
  const matches = [];
18787
18814
  text = text.replace(
@@ -18789,6 +18816,7 @@ function fillInCellPatterns(cellText, values, matchedLabels) {
18789
18816
  (match, prefix, suffix) => {
18790
18817
  const label = prefix + suffix;
18791
18818
  const normalizedLabel = normalizeLabel(label);
18819
+ if (blockedLabels?.has(normalizedLabel)) return match;
18792
18820
  const matchKey = values.available(normalizedLabel) ? normalizedLabel : values.available(normalizeLabel(prefix)) ? normalizeLabel(prefix) : void 0;
18793
18821
  if (matchKey === void 0) return match;
18794
18822
  const newValue = values.consume(matchKey);
@@ -18884,8 +18912,12 @@ async function fillWithUniqueGuard(values, run) {
18884
18912
  };
18885
18913
  const dup = new Set([...counts].filter(([k, n]) => n >= 2 && !isArrayValue(k)).map(([k]) => k));
18886
18914
  if (dup.size === 0) return { ...first, rejected: [] };
18915
+ const blockedLabels = /* @__PURE__ */ new Set();
18916
+ for (const f of first.filled) {
18917
+ if (f.key && dup.has(f.key)) blockedLabels.add(normalizeLabel(f.label));
18918
+ }
18887
18919
  const filtered = Object.fromEntries(Object.entries(values).filter(([label]) => !dup.has(normalizeLabel(label))));
18888
- const second = await run(filtered);
18920
+ const second = await run(filtered, blockedLabels);
18889
18921
  const rejected = Object.keys(values).filter((label) => dup.has(normalizeLabel(label)));
18890
18922
  return { ...second, rejected };
18891
18923
  }
@@ -19140,7 +19172,7 @@ function extractFormSchema(blocks) {
19140
19172
  }
19141
19173
 
19142
19174
  // src/form/filler.ts
19143
- function fillFormFields(blocks, values) {
19175
+ function fillFormFields(blocks, values, blockedLabels) {
19144
19176
  const cloned = structuredClone(blocks);
19145
19177
  const filled = [];
19146
19178
  const matchedLabels = /* @__PURE__ */ new Set();
@@ -19153,7 +19185,7 @@ function fillFormFields(blocks, values) {
19153
19185
  for (let c = 0; c < table.cols; c++) {
19154
19186
  const cell = table.cells[r]?.[c];
19155
19187
  if (!cell) continue;
19156
- const result = fillInCellPatterns(cell.text, cursor, matchedLabels);
19188
+ const result = fillInCellPatterns(cell.text, cursor, matchedLabels, blockedLabels);
19157
19189
  if (result) {
19158
19190
  cell.text = result.text;
19159
19191
  patternFilledCells.add(cell);
@@ -19165,11 +19197,11 @@ function fillFormFields(blocks, values) {
19165
19197
  }
19166
19198
  }
19167
19199
  for (const table of allTables) {
19168
- fillTable(table, cursor, filled, matchedLabels, patternFilledCells);
19200
+ fillTable(table, cursor, filled, matchedLabels, patternFilledCells, blockedLabels);
19169
19201
  }
19170
19202
  for (const block of cloned) {
19171
19203
  if (block.type !== "paragraph" || !block.text) continue;
19172
- const newText = fillInlineFields(block.text, cursor, filled, matchedLabels);
19204
+ const newText = fillInlineFields(block.text, cursor, filled, matchedLabels, blockedLabels);
19173
19205
  if (newText !== block.text) block.text = newText;
19174
19206
  }
19175
19207
  const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values);
@@ -19207,7 +19239,7 @@ function coveredPositions(table) {
19207
19239
  }
19208
19240
  return covered;
19209
19241
  }
19210
- function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19242
+ function fillTable(table, values, filled, matchedLabels, patternFilledCells, blockedLabels) {
19211
19243
  if (table.cols < 2) return;
19212
19244
  const covered = coveredPositions(table);
19213
19245
  for (let r = 0; r < table.rows; r++) {
@@ -19224,6 +19256,7 @@ function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19224
19256
  if (isKeywordLabel(valueCell.text)) continue;
19225
19257
  const normalizedCellLabel = normalizeLabel(labelCell.text);
19226
19258
  if (!normalizedCellLabel) continue;
19259
+ if (blockedLabels?.has(normalizedCellLabel)) continue;
19227
19260
  const matchKey = findMatchingKey(normalizedCellLabel, values);
19228
19261
  if (matchKey === void 0) continue;
19229
19262
  const newValue = values.consume(matchKey);
@@ -19257,6 +19290,7 @@ function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19257
19290
  const valueCell = table.cells[r]?.[c];
19258
19291
  if (!headerCell || !valueCell) continue;
19259
19292
  const headerLabel = normalizeLabel(headerCell.text);
19293
+ if (blockedLabels?.has(headerLabel)) continue;
19260
19294
  const matchKey = findMatchingKey(headerLabel, values);
19261
19295
  if (matchKey === void 0) continue;
19262
19296
  if (!values.isArray(matchKey) && matchedLabels.has(matchKey)) continue;
@@ -19275,13 +19309,15 @@ function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19275
19309
  }
19276
19310
  }
19277
19311
  }
19278
- function fillInlineFields(text, values, filled, matchedLabels) {
19312
+ function fillInlineFields(text, values, filled, matchedLabels, blockedLabels) {
19279
19313
  const segments = scanInlineSegments(text);
19280
19314
  if (segments.length === 0) return text;
19281
19315
  let out = "";
19282
19316
  let pos = 0;
19283
19317
  for (const seg of segments) {
19284
- const matchKey = findMatchingKey(normalizeLabel(seg.label), values);
19318
+ const nlabel = normalizeLabel(seg.label);
19319
+ if (blockedLabels?.has(nlabel)) continue;
19320
+ const matchKey = findMatchingKey(nlabel, values);
19285
19321
  if (matchKey === void 0) continue;
19286
19322
  const newValue = values.consume(matchKey);
19287
19323
  if (newValue === void 0) continue;
@@ -19297,7 +19333,7 @@ function fillInlineFields(text, values, filled, matchedLabels) {
19297
19333
 
19298
19334
  // src/form/filler-hwpx.ts
19299
19335
  import JSZip5 from "jszip";
19300
- async function fillHwpx(hwpxBuffer, values) {
19336
+ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
19301
19337
  const u8 = new Uint8Array(hwpxBuffer);
19302
19338
  const zip = await JSZip5.loadAsync(hwpxBuffer);
19303
19339
  const sectionPaths = Object.keys(zip.files).filter((name) => /[Ss]ection\d+\.xml$/i.test(name)).sort();
@@ -19341,7 +19377,7 @@ async function fillHwpx(hwpxBuffer, values) {
19341
19377
  for (const cell of row) {
19342
19378
  for (const para of cell.paragraphs) {
19343
19379
  const text = matchText(para);
19344
- const result = fillInCellPatterns(text, cursor, matchedLabels);
19380
+ const result = fillInCellPatterns(text, cursor, matchedLabels, blockedLabels);
19345
19381
  if (!result) continue;
19346
19382
  const l = led(para);
19347
19383
  if (l.fullText !== void 0) continue;
@@ -19359,7 +19395,7 @@ async function fillHwpx(hwpxBuffer, values) {
19359
19395
  for (const m of result.matches) {
19360
19396
  l.filledIdx.push(filled.length);
19361
19397
  l.matchKeys.push(m.key);
19362
- filled.push({ label: m.label, value: m.value, row: -1, col: -1 });
19398
+ filled.push({ label: m.label, value: m.value, row: -1, col: -1, key: m.key });
19363
19399
  }
19364
19400
  }
19365
19401
  }
@@ -19375,6 +19411,7 @@ async function fillHwpx(hwpxBuffer, values) {
19375
19411
  if (isKeywordLabel(cellLabelText(valueCell))) continue;
19376
19412
  const normalizedCellLabel = normalizeLabel(labelText);
19377
19413
  if (!normalizedCellLabel) continue;
19414
+ if (blockedLabels?.has(normalizedCellLabel)) continue;
19378
19415
  const matchKey = findMatchingKey(normalizedCellLabel, cursor);
19379
19416
  if (matchKey === void 0) continue;
19380
19417
  if (patternApplied.has(valueCell)) {
@@ -19392,7 +19429,8 @@ async function fillHwpx(hwpxBuffer, values) {
19392
19429
  label: labelText.trim().replace(/[::]\s*$/, ""),
19393
19430
  value: newValue,
19394
19431
  row: rowIdx,
19395
- col: colIdx
19432
+ col: colIdx,
19433
+ key: matchKey
19396
19434
  });
19397
19435
  } else {
19398
19436
  const paras = valueCell.paragraphs;
@@ -19414,7 +19452,8 @@ async function fillHwpx(hwpxBuffer, values) {
19414
19452
  label: labelText.trim().replace(/[::]\s*$/, ""),
19415
19453
  value: newValue,
19416
19454
  row: rowIdx,
19417
- col: colIdx
19455
+ col: colIdx,
19456
+ key: matchKey
19418
19457
  });
19419
19458
  }
19420
19459
  }
@@ -19430,6 +19469,7 @@ async function fillHwpx(hwpxBuffer, values) {
19430
19469
  const dataCells = table.rows[rowIdx];
19431
19470
  for (let colIdx = 0; colIdx < Math.min(headerCells.length, dataCells.length); colIdx++) {
19432
19471
  const headerLabel = normalizeLabel(cellLabelText(headerCells[colIdx]));
19472
+ if (blockedLabels?.has(headerLabel)) continue;
19433
19473
  const matchKey = findMatchingKey(headerLabel, cursor);
19434
19474
  if (matchKey === void 0) continue;
19435
19475
  if (!cursor.isArray(matchKey) && matchedLabels.has(matchKey)) continue;
@@ -19465,7 +19505,9 @@ async function fillHwpx(hwpxBuffer, values) {
19465
19505
  if (existing?.fullText !== void 0) continue;
19466
19506
  const text = matchText(para);
19467
19507
  for (const seg of scanInlineSegments(text)) {
19468
- const matchKey = findMatchingKey(normalizeLabel(seg.label), cursor);
19508
+ const nlabel = normalizeLabel(seg.label);
19509
+ if (blockedLabels?.has(nlabel)) continue;
19510
+ const matchKey = findMatchingKey(nlabel, cursor);
19469
19511
  if (matchKey === void 0) continue;
19470
19512
  const newValue = cursor.consume(matchKey);
19471
19513
  if (newValue === void 0) continue;
@@ -19475,7 +19517,7 @@ async function fillHwpx(hwpxBuffer, values) {
19475
19517
  matchedLabels.add(matchKey);
19476
19518
  l.filledIdx.push(filled.length);
19477
19519
  l.matchKeys.push(matchKey);
19478
- filled.push({ label: seg.label.trim(), value: newValue, row: -1, col: -1 });
19520
+ filled.push({ label: seg.label.trim(), value: newValue, row: -1, col: -1, key: matchKey });
19479
19521
  }
19480
19522
  }
19481
19523
  const splices = [];
@@ -19769,7 +19811,8 @@ function buildPrvText(blocks) {
19769
19811
  let bytes = 0;
19770
19812
  for (const b of blocks) {
19771
19813
  let text = b.text || (b.rows ? b.rows.map((r) => r.join(" ")).join("\n") : "");
19772
- if (b.type === "html_table") text = text.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
19814
+ if (b.type === "code_block" && (b.lang || "").toLowerCase() === "chart") text = "[\uCC28\uD2B8]";
19815
+ else if (b.type === "html_table") text = text.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
19773
19816
  if (!text) continue;
19774
19817
  lines.push(text);
19775
19818
  bytes += text.length * 3;
@@ -19788,7 +19831,7 @@ function findMathDelim(s, from) {
19788
19831
  return i;
19789
19832
  }
19790
19833
  function parseMarkdownToBlocks(md2) {
19791
- const lines = md2.split("\n");
19834
+ const lines = md2.replace(/\r\n?/g, "\n").split("\n");
19792
19835
  const blocks = [];
19793
19836
  let i = 0;
19794
19837
  while (i < lines.length) {
@@ -19836,13 +19879,13 @@ function parseMarkdownToBlocks(md2) {
19836
19879
  continue;
19837
19880
  }
19838
19881
  }
19839
- const fenceMatch = line.match(/^(`{3,}|~{3,})(.*)$/);
19882
+ const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
19840
19883
  if (fenceMatch) {
19841
19884
  const fence = fenceMatch[1];
19842
19885
  const lang = fenceMatch[2].trim();
19843
19886
  const codeLines = [];
19844
19887
  i++;
19845
- while (i < lines.length && !lines[i].startsWith(fence)) {
19888
+ while (i < lines.length && !lines[i].replace(/^ {0,3}/, "").startsWith(fence)) {
19846
19889
  codeLines.push(lines[i]);
19847
19890
  i++;
19848
19891
  }
@@ -20178,6 +20221,219 @@ function generateHeaderXml(theme, gongmun, ratioVariants = []) {
20178
20221
  </hh:head>`;
20179
20222
  }
20180
20223
 
20224
+ // src/hwpx/chart-gen.ts
20225
+ var XML_ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;" };
20226
+ var xmlEscape = (s) => s.replace(/[&<>]/g, (c) => XML_ESC[c]);
20227
+ var CHART_TYPES = {
20228
+ 0: { el: "barChart", dir: "col", grp: "clustered" },
20229
+ 1: { el: "barChart", dir: "col", grp: "stacked", overlap: 100 },
20230
+ 2: { el: "lineChart", grp: "standard", marker: true },
20231
+ 3: { el: "barChart", dir: "bar", grp: "clustered" },
20232
+ 4: { el: "barChart", dir: "bar", grp: "stacked", overlap: 100 },
20233
+ 5: { el: "scatterChart", scatter: true },
20234
+ 6: { el: "pieChart", pie: true },
20235
+ 7: { el: "pieChart", pie: true, explode: true },
20236
+ 8: { el: "doughnutChart", pie: true, hole: 50 },
20237
+ 9: { el: "areaChart", grp: "standard" },
20238
+ 10: { el: "areaChart", grp: "stacked" },
20239
+ 11: { el: "radarChart", radar: true },
20240
+ 12: { el: "bar3DChart", dir: "col", grp: "clustered" },
20241
+ 13: { el: "bar3DChart", dir: "col", grp: "stacked", overlap: 100 },
20242
+ 14: { el: "bar3DChart", dir: "bar", grp: "clustered" },
20243
+ 15: { el: "bar3DChart", dir: "bar", grp: "stacked", overlap: 100 },
20244
+ 16: { el: "pie3DChart", pie: true },
20245
+ 17: { el: "pie3DChart", pie: true, explode: true },
20246
+ 18: { el: "area3DChart", grp: "standard" },
20247
+ 19: { el: "area3DChart", grp: "stacked" }
20248
+ };
20249
+ var CHART_ALIAS = {
20250
+ column: 0,
20251
+ col: 0,
20252
+ \uC138\uB85C\uB9C9\uB300: 0,
20253
+ \uB9C9\uB300: 0,
20254
+ column_stacked: 1,
20255
+ \uC138\uB85C\uB9C9\uB300_\uB204\uC801: 1,
20256
+ line: 2,
20257
+ \uC120: 2,
20258
+ \uAEBE\uC740\uC120: 2,
20259
+ bar: 3,
20260
+ \uAC00\uB85C\uB9C9\uB300: 3,
20261
+ bar_stacked: 4,
20262
+ scatter: 5,
20263
+ \uBD84\uC0B0: 5,
20264
+ pie: 6,
20265
+ \uC6D0: 6,
20266
+ \uD30C\uC774: 6,
20267
+ pie_explode: 7,
20268
+ doughnut: 8,
20269
+ donut: 8,
20270
+ \uB3C4\uB11B: 8,
20271
+ area: 9,
20272
+ \uC601\uC5ED: 9,
20273
+ area_stacked: 10,
20274
+ radar: 11,
20275
+ \uBC29\uC0AC\uD615: 11,
20276
+ bar3d: 12,
20277
+ column3d: 12,
20278
+ pie3d: 16
20279
+ };
20280
+ function chartSpec(t) {
20281
+ if (!t) return CHART_TYPES[0];
20282
+ const key = CHART_ALIAS[t.toLowerCase()] ?? Number(t);
20283
+ return CHART_TYPES[key] ?? CHART_TYPES[0];
20284
+ }
20285
+ var HU_PER_MM = 7200 / 25.4;
20286
+ var RESERVED_KEYS = /* @__PURE__ */ new Set(["type", "cat", "size", "colors", "point_colors", "title"]);
20287
+ function parseChartFence(text) {
20288
+ let type;
20289
+ let cat = null;
20290
+ let widthMm = 32250 / HU_PER_MM;
20291
+ let heightMm = 18750 / HU_PER_MM;
20292
+ let colors = null;
20293
+ let pointColors = null;
20294
+ const series = [];
20295
+ for (const rawLine of text.split("\n")) {
20296
+ const line = rawLine.trim();
20297
+ if (!line || line.startsWith("#")) continue;
20298
+ const colon = line.search(/[::]/);
20299
+ if (colon <= 0) continue;
20300
+ const key = line.slice(0, colon).trim();
20301
+ const value = line.slice(colon + 1).trim();
20302
+ const keyLower = key.toLowerCase();
20303
+ if (keyLower === "type") {
20304
+ type = value;
20305
+ } else if (keyLower === "cat") {
20306
+ cat = value.split(",").map((s) => s.trim()).filter(Boolean);
20307
+ } else if (keyLower === "size") {
20308
+ const m = value.match(/^(\d+(?:\.\d+)?)\s*[x×]\s*(\d+(?:\.\d+)?)$/i);
20309
+ if (m) {
20310
+ const clamp = (n) => Math.min(500, Math.max(10, n));
20311
+ widthMm = clamp(Number(m[1]));
20312
+ heightMm = clamp(Number(m[2]));
20313
+ }
20314
+ } else if (keyLower === "colors") {
20315
+ colors = value.split(",").map((s) => s.trim()).filter(Boolean);
20316
+ } else if (keyLower === "point_colors") {
20317
+ pointColors = value.split(",").map((s) => s.trim()).filter(Boolean);
20318
+ } else if (keyLower === "title") {
20319
+ } else if (!RESERVED_KEYS.has(keyLower)) {
20320
+ const segs = value.replace(/(\d),(?=\d{3}(?:\D|$))/g, "$1").split(",").map((s) => s.trim()).filter(Boolean);
20321
+ if (segs.length === 0) continue;
20322
+ const nums = segs.map(Number);
20323
+ if (nums.every((n) => Number.isFinite(n))) {
20324
+ series.push({ name: key, values: nums });
20325
+ } else {
20326
+ return null;
20327
+ }
20328
+ }
20329
+ }
20330
+ if (series.length === 0) return null;
20331
+ const spec = chartSpec(type);
20332
+ let finalSeries = spec.pie ? [series[0]] : series;
20333
+ finalSeries = finalSeries.map((s) => ({ ...s }));
20334
+ const ptLen = Math.max(cat?.length ?? 0, ...finalSeries.map((s) => s.values.length));
20335
+ const catFinal = Array.from({ length: ptLen }, (_, i) => cat?.[i] ?? `\uD56D\uBAA9 ${i + 1}`);
20336
+ if (!spec.scatter) {
20337
+ finalSeries = finalSeries.map((s) => ({ ...s, values: catFinal.map((_, i) => s.values[i] ?? 0) }));
20338
+ }
20339
+ if (spec.pie) {
20340
+ const slice = colors ?? pointColors;
20341
+ if (slice) finalSeries[0].pointColors = slice;
20342
+ } else {
20343
+ if (colors) finalSeries.forEach((s, i) => {
20344
+ s.color = colors[i % colors.length];
20345
+ });
20346
+ if (pointColors && finalSeries[0]) finalSeries[0].pointColors = pointColors;
20347
+ }
20348
+ return {
20349
+ spec,
20350
+ cat: catFinal,
20351
+ series: finalSeries,
20352
+ widthHu: Math.round(widthMm * HU_PER_MM),
20353
+ heightHu: Math.round(heightMm * HU_PER_MM)
20354
+ };
20355
+ }
20356
+ var colLetter = (i) => String.fromCharCode(66 + i);
20357
+ function strCachePts(vals) {
20358
+ return `<c:ptCount val="${vals.length}"/>` + vals.map((v, i) => `<c:pt idx="${i}"><c:v>${xmlEscape(v)}</c:v></c:pt>`).join("");
20359
+ }
20360
+ function numCachePts(vals) {
20361
+ return `<c:formatCode>General</c:formatCode><c:ptCount val="${vals.length}"/>` + vals.map((v, i) => `<c:pt idx="${i}"><c:v>${Number(v) || 0}</c:v></c:pt>`).join("");
20362
+ }
20363
+ function chartColorFill(color) {
20364
+ if (color == null) return null;
20365
+ const c = color.trim();
20366
+ if (/^accent[1-6]$/i.test(c)) return `<a:solidFill><a:schemeClr val="${c.toLowerCase()}"/></a:solidFill>`;
20367
+ const hex = c.replace(/^#/, "").toUpperCase();
20368
+ if (/^[0-9A-F]{6}$/.test(hex)) return `<a:solidFill><a:srgbClr val="${hex}"/></a:solidFill>`;
20369
+ return null;
20370
+ }
20371
+ function serSpPr(color, stroke) {
20372
+ const f = chartColorFill(color);
20373
+ if (!f) return "<c:spPr/>";
20374
+ return stroke ? `<c:spPr><a:ln w="28575" cap="flat" cmpd="sng" algn="ctr">${f}<a:prstDash val="solid"/><a:round/></a:ln></c:spPr>` : `<c:spPr>${f}</c:spPr>`;
20375
+ }
20376
+ function dPtXml(pointColors, pie) {
20377
+ if (!pointColors?.length) return "";
20378
+ return pointColors.map((col, i) => {
20379
+ const f = chartColorFill(col);
20380
+ if (!f) return "";
20381
+ const mid = pie ? '<c:invertIfNegative val="0"/><c:bubble3D val="0"/><c:explosion val="0"/>' : '<c:bubble3D val="0"/>';
20382
+ return `<c:dPt><c:idx val="${i}"/>${mid}<c:spPr>${f}</c:spPr></c:dPt>`;
20383
+ }).join("");
20384
+ }
20385
+ function stdSer(idx, name, cat, values, explode, color, pointColors, stroke, pie) {
20386
+ const cl = colLetter(idx);
20387
+ return `<c:ser><c:idx val="${idx}"/><c:order val="${idx}"/><c:tx><c:strRef><c:f>Sheet1!$${cl}$1</c:f><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>${xmlEscape(name)}</c:v></c:pt></c:strCache></c:strRef></c:tx>${serSpPr(color, stroke)}<c:invertIfNegative val="0"/>` + (explode ? `<c:explosion val="25"/>` : "") + dPtXml(pointColors, pie) + `<c:cat><c:strRef><c:f>Sheet1!$A$2:$A$${cat.length + 1}</c:f><c:strCache>${strCachePts(cat)}</c:strCache></c:strRef></c:cat><c:val><c:numRef><c:f>Sheet1!$${cl}$2:$${cl}$${values.length + 1}</c:f><c:numCache>${numCachePts(values)}</c:numCache></c:numRef></c:val></c:ser>`;
20388
+ }
20389
+ function scatterSer(idx, name, xvals, yvals) {
20390
+ const cl = colLetter(idx);
20391
+ return `<c:ser><c:idx val="${idx}"/><c:order val="${idx}"/><c:tx><c:strRef><c:f>Sheet1!$${cl}$1</c:f><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>${xmlEscape(name)}</c:v></c:pt></c:strCache></c:strRef></c:tx><c:spPr><a:ln w="28575"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="7"/></c:marker><c:xVal><c:numRef><c:f>Sheet1!$A$2:$A$${xvals.length + 1}</c:f><c:numCache>${numCachePts(xvals)}</c:numCache></c:numRef></c:xVal><c:yVal><c:numRef><c:f>Sheet1!$${cl}$2:$${cl}$${yvals.length + 1}</c:f><c:numCache>${numCachePts(yvals)}</c:numCache></c:numRef></c:yVal></c:ser>`;
20392
+ }
20393
+ function catAxXml(id, pos, cross) {
20394
+ return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:axPos val="${pos}"/><c:crossAx val="${cross}"/><c:delete val="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
20395
+ }
20396
+ function valAxXml(id, pos, cross) {
20397
+ return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:axPos val="${pos}"/><c:majorGridlines/><c:numFmt formatCode="General" sourceLinked="1"/><c:crossAx val="${cross}"/><c:delete val="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crosses val="autoZero"/><c:crossBetween val="between"/></c:valAx>`;
20398
+ }
20399
+ function buildChartSpaceXml(fence) {
20400
+ const { spec, cat, series } = fence;
20401
+ const NS = 'xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"';
20402
+ const ax1 = "111111111";
20403
+ const ax2 = "222222222";
20404
+ let plot;
20405
+ if (spec.scatter) {
20406
+ const n = Math.max(0, ...series.map((s) => s.values.length));
20407
+ const xs = Array.from({ length: n }, (_, i) => {
20408
+ const c = cat[i];
20409
+ const v = Number(c);
20410
+ return c !== void 0 && c !== "" && Number.isFinite(v) ? v : i + 1;
20411
+ });
20412
+ const sers = series.map((s, i) => scatterSer(i, s.name, xs, s.values)).join("");
20413
+ plot = `<c:scatterChart><c:scatterStyle val="lineMarker"/><c:varyColors val="0"/>${sers}<c:axId val="${ax1}"/><c:axId val="${ax2}"/></c:scatterChart>` + valAxXml(ax1, "b", ax2) + valAxXml(ax2, "l", ax1);
20414
+ } else if (spec.pie) {
20415
+ const s0 = series[0];
20416
+ plot = `<c:${spec.el}><c:varyColors val="1"/>${stdSer(0, s0.name, cat, s0.values, !!spec.explode, s0.color, s0.pointColors, false, true)}<c:firstSliceAng val="0"/>` + (spec.hole != null ? `<c:holeSize val="${spec.hole}"/>` : "") + `</c:${spec.el}>`;
20417
+ } else {
20418
+ const stroke = spec.el === "lineChart" || spec.el === "radarChart" || !!spec.radar;
20419
+ const sers = series.map((s, i) => stdSer(i, s.name, cat, s.values, false, s.color, s.pointColors, stroke, false)).join("");
20420
+ const horiz = spec.dir === "bar";
20421
+ let inner = "";
20422
+ if (spec.dir) inner += `<c:barDir val="${spec.dir}"/>`;
20423
+ if (spec.grp) inner += `<c:grouping val="${spec.grp}"/>`;
20424
+ if (spec.radar) inner += `<c:radarStyle val="standard"/>`;
20425
+ inner += `<c:varyColors val="0"/>${sers}`;
20426
+ if (spec.marker) inner += `<c:marker val="1"/>`;
20427
+ if (spec.el.startsWith("bar")) inner += `<c:gapWidth val="150"/><c:overlap val="${spec.overlap ?? 0}"/>`;
20428
+ inner += `<c:axId val="${ax1}"/><c:axId val="${ax2}"/>`;
20429
+ plot = `<c:${spec.el}>${inner}</c:${spec.el}>` + catAxXml(ax1, horiz ? "l" : "b", ax2) + valAxXml(ax2, horiz ? "b" : "l", ax1);
20430
+ }
20431
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><c:chartSpace ${NS}><c:date1904 val="0"/><c:roundedCorners val="0"/><c:chart><c:autoTitleDeleted val="0"/><c:plotArea><c:layout/>${plot}</c:plotArea><c:legend><c:legendPos val="r"/><c:overlay val="0"/></c:legend><c:plotVisOnly val="1"/><c:dispBlanksAs val="gap"/></c:chart></c:chartSpace>`;
20432
+ }
20433
+ function buildChartElementXml(partName, widthHu, heightHu, id) {
20434
+ return `<hp:chart id="${id}" zOrder="0" numberingType="PICTURE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" chartIDRef="${partName}"><hp:sz width="${widthHu}" widthRelTo="ABSOLUTE" height="${heightHu}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="709" right="709" top="709" bottom="709"/></hp:chart>`;
20435
+ }
20436
+
20181
20437
  // src/hwpx/gen-gongmun-fit.ts
20182
20438
  function plainRenderText(text) {
20183
20439
  return parseInlineMarkdown(text).map((s) => s.text).join("");
@@ -20230,18 +20486,18 @@ function precomputeGongmunList(blocks, gongmun) {
20230
20486
  i++;
20231
20487
  continue;
20232
20488
  }
20233
- const passThrough = (t) => t === "table" || t === "html_table" || t === "equation";
20489
+ const passThrough = (b) => b.type === "table" || b.type === "html_table" || b.type === "equation" || b.type === "code_block" && (b.lang || "").toLowerCase() === "chart" && parseChartFence(b.text || "") !== null;
20234
20490
  const run = [];
20235
20491
  while (i < blocks.length) {
20236
- const t = blocks[i].type;
20237
- if (t === "list_item") {
20492
+ const b = blocks[i];
20493
+ if (b.type === "list_item") {
20238
20494
  run.push(i);
20239
20495
  i++;
20240
20496
  continue;
20241
20497
  }
20242
- if (passThrough(t)) {
20498
+ if (passThrough(b)) {
20243
20499
  let j = i + 1;
20244
- while (j < blocks.length && passThrough(blocks[j].type)) j++;
20500
+ while (j < blocks.length && passThrough(blocks[j])) j++;
20245
20501
  if (j < blocks.length && blocks[j].type === "list_item") {
20246
20502
  i = j;
20247
20503
  continue;
@@ -21044,210 +21300,6 @@ function generateEquationParagraph(input, zOrder = 0) {
21044
21300
  return `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${generateEquationXml(script, zOrder)}</hp:run></hp:p>`;
21045
21301
  }
21046
21302
 
21047
- // src/hwpx/chart-gen.ts
21048
- var XML_ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;" };
21049
- var xmlEscape = (s) => s.replace(/[&<>]/g, (c) => XML_ESC[c]);
21050
- var CHART_TYPES = {
21051
- 0: { el: "barChart", dir: "col", grp: "clustered" },
21052
- 1: { el: "barChart", dir: "col", grp: "stacked", overlap: 100 },
21053
- 2: { el: "lineChart", grp: "standard", marker: true },
21054
- 3: { el: "barChart", dir: "bar", grp: "clustered" },
21055
- 4: { el: "barChart", dir: "bar", grp: "stacked", overlap: 100 },
21056
- 5: { el: "scatterChart", scatter: true },
21057
- 6: { el: "pieChart", pie: true },
21058
- 7: { el: "pieChart", pie: true, explode: true },
21059
- 8: { el: "doughnutChart", pie: true, hole: 50 },
21060
- 9: { el: "areaChart", grp: "standard" },
21061
- 10: { el: "areaChart", grp: "stacked" },
21062
- 11: { el: "radarChart", radar: true },
21063
- 12: { el: "bar3DChart", dir: "col", grp: "clustered" },
21064
- 13: { el: "bar3DChart", dir: "col", grp: "stacked", overlap: 100 },
21065
- 14: { el: "bar3DChart", dir: "bar", grp: "clustered" },
21066
- 15: { el: "bar3DChart", dir: "bar", grp: "stacked", overlap: 100 },
21067
- 16: { el: "pie3DChart", pie: true },
21068
- 17: { el: "pie3DChart", pie: true, explode: true },
21069
- 18: { el: "area3DChart", grp: "standard" },
21070
- 19: { el: "area3DChart", grp: "stacked" }
21071
- };
21072
- var CHART_ALIAS = {
21073
- column: 0,
21074
- col: 0,
21075
- \uC138\uB85C\uB9C9\uB300: 0,
21076
- \uB9C9\uB300: 0,
21077
- column_stacked: 1,
21078
- \uC138\uB85C\uB9C9\uB300_\uB204\uC801: 1,
21079
- line: 2,
21080
- \uC120: 2,
21081
- \uAEBE\uC740\uC120: 2,
21082
- bar: 3,
21083
- \uAC00\uB85C\uB9C9\uB300: 3,
21084
- bar_stacked: 4,
21085
- scatter: 5,
21086
- \uBD84\uC0B0: 5,
21087
- pie: 6,
21088
- \uC6D0: 6,
21089
- \uD30C\uC774: 6,
21090
- pie_explode: 7,
21091
- doughnut: 8,
21092
- donut: 8,
21093
- \uB3C4\uB11B: 8,
21094
- area: 9,
21095
- \uC601\uC5ED: 9,
21096
- area_stacked: 10,
21097
- radar: 11,
21098
- \uBC29\uC0AC\uD615: 11,
21099
- bar3d: 12,
21100
- column3d: 12,
21101
- pie3d: 16
21102
- };
21103
- function chartSpec(t) {
21104
- if (!t) return CHART_TYPES[0];
21105
- const key = CHART_ALIAS[t.toLowerCase()] ?? Number(t);
21106
- return CHART_TYPES[key] ?? CHART_TYPES[0];
21107
- }
21108
- var HU_PER_MM = 7200 / 25.4;
21109
- var RESERVED_KEYS = /* @__PURE__ */ new Set(["type", "cat", "size", "colors", "point_colors", "title"]);
21110
- function parseChartFence(text) {
21111
- let type;
21112
- let cat = null;
21113
- let widthMm = 32250 / HU_PER_MM;
21114
- let heightMm = 18750 / HU_PER_MM;
21115
- let colors = null;
21116
- let pointColors = null;
21117
- const series = [];
21118
- for (const rawLine of text.split("\n")) {
21119
- const line = rawLine.trim();
21120
- if (!line || line.startsWith("#")) continue;
21121
- const colon = line.search(/[::]/);
21122
- if (colon <= 0) continue;
21123
- const key = line.slice(0, colon).trim();
21124
- const value = line.slice(colon + 1).trim();
21125
- const keyLower = key.toLowerCase();
21126
- if (keyLower === "type") {
21127
- type = value;
21128
- } else if (keyLower === "cat") {
21129
- cat = value.split(",").map((s) => s.trim()).filter(Boolean);
21130
- } else if (keyLower === "size") {
21131
- const m = value.match(/^(\d+(?:\.\d+)?)\s*[x×]\s*(\d+(?:\.\d+)?)$/i);
21132
- if (m) {
21133
- widthMm = Number(m[1]);
21134
- heightMm = Number(m[2]);
21135
- }
21136
- } else if (keyLower === "colors") {
21137
- colors = value.split(",").map((s) => s.trim()).filter(Boolean);
21138
- } else if (keyLower === "point_colors") {
21139
- pointColors = value.split(",").map((s) => s.trim()).filter(Boolean);
21140
- } else if (keyLower === "title") {
21141
- } else if (!RESERVED_KEYS.has(keyLower)) {
21142
- const nums = value.split(",").map((s) => Number(s.trim()));
21143
- if (nums.length > 0 && nums.every((n) => Number.isFinite(n))) {
21144
- series.push({ name: key, values: nums });
21145
- }
21146
- }
21147
- }
21148
- if (series.length === 0) return null;
21149
- const spec = chartSpec(type);
21150
- const catFinal = cat ?? series[0].values.map((_, i) => `\uD56D\uBAA9 ${i + 1}`);
21151
- let finalSeries = spec.pie ? [series[0]] : series;
21152
- finalSeries = finalSeries.map((s) => ({ ...s }));
21153
- if (spec.pie) {
21154
- const slice = colors ?? pointColors;
21155
- if (slice) finalSeries[0].pointColors = slice;
21156
- } else {
21157
- if (colors) finalSeries.forEach((s, i) => {
21158
- s.color = colors[i % colors.length];
21159
- });
21160
- if (pointColors && finalSeries[0]) finalSeries[0].pointColors = pointColors;
21161
- }
21162
- return {
21163
- spec,
21164
- cat: catFinal,
21165
- series: finalSeries,
21166
- widthHu: Math.round(widthMm * HU_PER_MM),
21167
- heightHu: Math.round(heightMm * HU_PER_MM)
21168
- };
21169
- }
21170
- var colLetter = (i) => String.fromCharCode(66 + i);
21171
- function strCachePts(vals) {
21172
- return `<c:ptCount val="${vals.length}"/>` + vals.map((v, i) => `<c:pt idx="${i}"><c:v>${xmlEscape(v)}</c:v></c:pt>`).join("");
21173
- }
21174
- function numCachePts(vals) {
21175
- return `<c:formatCode>General</c:formatCode><c:ptCount val="${vals.length}"/>` + vals.map((v, i) => `<c:pt idx="${i}"><c:v>${Number(v) || 0}</c:v></c:pt>`).join("");
21176
- }
21177
- function chartColorFill(color) {
21178
- if (color == null) return null;
21179
- const c = color.trim();
21180
- if (/^accent[1-6]$/i.test(c)) return `<a:solidFill><a:schemeClr val="${c.toLowerCase()}"/></a:solidFill>`;
21181
- const hex = c.replace(/^#/, "").toUpperCase();
21182
- if (/^[0-9A-F]{6}$/.test(hex)) return `<a:solidFill><a:srgbClr val="${hex}"/></a:solidFill>`;
21183
- return null;
21184
- }
21185
- function serSpPr(color, stroke) {
21186
- const f = chartColorFill(color);
21187
- if (!f) return "<c:spPr/>";
21188
- return stroke ? `<c:spPr><a:ln w="28575" cap="flat" cmpd="sng" algn="ctr">${f}<a:prstDash val="solid"/><a:round/></a:ln></c:spPr>` : `<c:spPr>${f}</c:spPr>`;
21189
- }
21190
- function dPtXml(pointColors, pie) {
21191
- if (!pointColors?.length) return "";
21192
- return pointColors.map((col, i) => {
21193
- const f = chartColorFill(col);
21194
- if (!f) return "";
21195
- const mid = pie ? '<c:invertIfNegative val="0"/><c:bubble3D val="0"/><c:explosion val="0"/>' : '<c:bubble3D val="0"/>';
21196
- return `<c:dPt><c:idx val="${i}"/>${mid}<c:spPr>${f}</c:spPr></c:dPt>`;
21197
- }).join("");
21198
- }
21199
- function stdSer(idx, name, cat, values, explode, color, pointColors, stroke, pie) {
21200
- const cl = colLetter(idx);
21201
- return `<c:ser><c:idx val="${idx}"/><c:order val="${idx}"/><c:tx><c:strRef><c:f>Sheet1!$${cl}$1</c:f><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>${xmlEscape(name)}</c:v></c:pt></c:strCache></c:strRef></c:tx>${serSpPr(color, stroke)}<c:invertIfNegative val="0"/>` + (explode ? `<c:explosion val="25"/>` : "") + dPtXml(pointColors, pie) + `<c:cat><c:strRef><c:f>Sheet1!$A$2:$A$${cat.length + 1}</c:f><c:strCache>${strCachePts(cat)}</c:strCache></c:strRef></c:cat><c:val><c:numRef><c:f>Sheet1!$${cl}$2:$${cl}$${values.length + 1}</c:f><c:numCache>${numCachePts(values)}</c:numCache></c:numRef></c:val></c:ser>`;
21202
- }
21203
- function scatterSer(idx, name, xvals, yvals) {
21204
- const cl = colLetter(idx);
21205
- return `<c:ser><c:idx val="${idx}"/><c:order val="${idx}"/><c:tx><c:strRef><c:f>Sheet1!$${cl}$1</c:f><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>${xmlEscape(name)}</c:v></c:pt></c:strCache></c:strRef></c:tx><c:spPr><a:ln w="28575"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="7"/></c:marker><c:xVal><c:numRef><c:f>Sheet1!$A$2:$A$${xvals.length + 1}</c:f><c:numCache>${numCachePts(xvals)}</c:numCache></c:numRef></c:xVal><c:yVal><c:numRef><c:f>Sheet1!$${cl}$2:$${cl}$${yvals.length + 1}</c:f><c:numCache>${numCachePts(yvals)}</c:numCache></c:numRef></c:yVal></c:ser>`;
21206
- }
21207
- function catAxXml(id, pos, cross) {
21208
- return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:axPos val="${pos}"/><c:crossAx val="${cross}"/><c:delete val="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
21209
- }
21210
- function valAxXml(id, pos, cross) {
21211
- return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:axPos val="${pos}"/><c:majorGridlines/><c:numFmt formatCode="General" sourceLinked="1"/><c:crossAx val="${cross}"/><c:delete val="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crosses val="autoZero"/><c:crossBetween val="between"/></c:valAx>`;
21212
- }
21213
- function buildChartSpaceXml(fence) {
21214
- const { spec, cat, series } = fence;
21215
- const NS = 'xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"';
21216
- const ax1 = "111111111";
21217
- const ax2 = "222222222";
21218
- let plot;
21219
- if (spec.scatter) {
21220
- const n = Math.max(0, ...series.map((s) => s.values.length));
21221
- const xs = Array.from({ length: n }, (_, i) => {
21222
- const c = cat[i];
21223
- const v = Number(c);
21224
- return c !== void 0 && c !== "" && Number.isFinite(v) ? v : i + 1;
21225
- });
21226
- const sers = series.map((s, i) => scatterSer(i, s.name, xs, s.values)).join("");
21227
- plot = `<c:scatterChart><c:scatterStyle val="lineMarker"/><c:varyColors val="0"/>${sers}<c:axId val="${ax1}"/><c:axId val="${ax2}"/></c:scatterChart>` + valAxXml(ax1, "b", ax2) + valAxXml(ax2, "l", ax1);
21228
- } else if (spec.pie) {
21229
- const s0 = series[0];
21230
- plot = `<c:${spec.el}><c:varyColors val="1"/>${stdSer(0, s0.name, cat, s0.values, !!spec.explode, s0.color, s0.pointColors, false, true)}<c:firstSliceAng val="0"/>` + (spec.hole != null ? `<c:holeSize val="${spec.hole}"/>` : "") + `</c:${spec.el}>`;
21231
- } else {
21232
- const stroke = spec.el === "lineChart" || spec.el === "radarChart" || !!spec.radar;
21233
- const sers = series.map((s, i) => stdSer(i, s.name, cat, s.values, false, s.color, s.pointColors, stroke, false)).join("");
21234
- const horiz = spec.dir === "bar";
21235
- let inner = "";
21236
- if (spec.dir) inner += `<c:barDir val="${spec.dir}"/>`;
21237
- if (spec.grp) inner += `<c:grouping val="${spec.grp}"/>`;
21238
- if (spec.radar) inner += `<c:radarStyle val="standard"/>`;
21239
- inner += `<c:varyColors val="0"/>${sers}`;
21240
- if (spec.marker) inner += `<c:marker val="1"/>`;
21241
- if (spec.el.startsWith("bar")) inner += `<c:gapWidth val="150"/><c:overlap val="${spec.overlap ?? 0}"/>`;
21242
- inner += `<c:axId val="${ax1}"/><c:axId val="${ax2}"/>`;
21243
- plot = `<c:${spec.el}>${inner}</c:${spec.el}>` + catAxXml(ax1, horiz ? "l" : "b", ax2) + valAxXml(ax2, horiz ? "b" : "l", ax1);
21244
- }
21245
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><c:chartSpace ${NS}><c:date1904 val="0"/><c:roundedCorners val="0"/><c:chart><c:autoTitleDeleted val="0"/><c:plotArea><c:layout/>${plot}</c:plotArea><c:legend><c:legendPos val="r"/><c:overlay val="0"/></c:legend><c:plotVisOnly val="1"/><c:dispBlanksAs val="gap"/></c:chart></c:chartSpace>`;
21246
- }
21247
- function buildChartElementXml(partName, widthHu, heightHu, id) {
21248
- return `<hp:chart id="${id}" zOrder="0" numberingType="PICTURE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" chartIDRef="${partName}"><hp:sz width="${widthHu}" widthRelTo="ABSOLUTE" height="${heightHu}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="709" right="709" top="709" bottom="709"/></hp:chart>`;
21249
- }
21250
-
21251
21303
  // src/hwpx/gen-section.ts
21252
21304
  function generateSecPr(gongmun) {
21253
21305
  const m = gongmun ? {
@@ -23069,7 +23121,8 @@ async function patchHwp(original, editedMarkdown, options) {
23069
23121
  if (options?.verify !== false) {
23070
23122
  try {
23071
23123
  const reparsed = parseHwp5Document(Buffer.from(data));
23072
- verification = diffUnitLists(splitMarkdownUnits(reparsed.markdown), editedUnits);
23124
+ const normBr = (u) => ({ ...u, raw: u.raw.replace(/<br\s*\/?\s*>/gi, "\n") });
23125
+ verification = diffUnitLists(splitMarkdownUnits(reparsed.markdown).map(normBr), editedUnits.map(normBr));
23073
23126
  } catch (err) {
23074
23127
  return { success: false, applied, skipped, error: `\uD328\uCE58\uBCF8 \uC7AC\uD30C\uC2F1 \uC2E4\uD328 \u2014 \uD328\uCE58 \uC911\uB2E8: ${msg(err)}` };
23075
23128
  }
@@ -23192,7 +23245,7 @@ function handleModified(orig, edited, ctx) {
23192
23245
  function patchParagraph(block, orig, edited, ctx, skip) {
23193
23246
  const mapping = ctx.paraMap.get(orig.blockIdx);
23194
23247
  if (!mapping?.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)");
23195
- const restoreBr = (s) => s.replace(/\s*<br\s*\/?\s*>\s*/gi, "\n");
23248
+ const restoreBr = (s) => s.replace(/(?:\s*<br\s*\/?\s*>\s*)+/gi, "\n");
23196
23249
  let newPlain = restoreBr(textUnitToPlain(edited.raw, block));
23197
23250
  if (block.text && block.text.includes("\n") && !newPlain.includes("\n")) {
23198
23251
  return skip("\uB2E4\uC911\uC904 \uBB38\uB2E8 \uC218\uC815\uC5D0 <br> \uC5C6\uC74C \u2014 \uC904\uBC14\uAFC8 \uC704\uCE58 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0 (\uC904\uBC14\uAFC8\uC740 <br>\uB85C \uD45C\uAE30)");
@@ -23218,7 +23271,7 @@ function patchParagraph(block, orig, edited, ctx, skip) {
23218
23271
  ctx.skipped.push({ reason: "\uC790\uB3D9\uBC88\uD638 \uC811\uB450 \uC2DD\uBCC4 \uC2E4\uD328 \u2014 \uBC88\uD638 \uD3EC\uD568 \uD14D\uC2A4\uD2B8\uB85C \uC801\uC6A9 (\uBDF0\uC5B4\uC5D0\uC11C \uC911\uBCF5 \uD45C\uC2DC \uAC00\uB2A5)", after: summarize(newPlain) });
23219
23272
  }
23220
23273
  }
23221
- const origPlain = restoreBr(textUnitToPlain(orig.raw, block));
23274
+ const origPlain = block.text != null ? block.text : restoreBr(textUnitToPlain(orig.raw, block));
23222
23275
  if (newPlain === origPlain) return skip("\uD14D\uC2A4\uD2B8 \uC678 \uBCC0\uACBD(\uD5E4\uB529 \uB808\uBCA8/\uC11C\uC2DD)\uB9CC \uAC10\uC9C0 \u2014 \uC2A4\uD0C0\uC77C \uBCC0\uACBD\uC740 \uBBF8\uC9C0\uC6D0");
23223
23276
  if (sanitizeText(newPlain) !== newPlain) {
23224
23277
  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");
@@ -24292,7 +24345,7 @@ async function parseHwp(buffer, options) {
24292
24345
  async function parsePdf(buffer, options) {
24293
24346
  let parsePdfDocument;
24294
24347
  try {
24295
- const mod = await import("./parser-HBHCD7TE.js");
24348
+ const mod = await import("./parser-B4O7CW5Q.js");
24296
24349
  parsePdfDocument = mod.parsePdfDocument;
24297
24350
  } catch {
24298
24351
  return {
@@ -24419,4 +24472,4 @@ export {
24419
24472
  parseHwpml,
24420
24473
  fillForm
24421
24474
  };
24422
- //# sourceMappingURL=chunk-WD5NUUU6.js.map
24475
+ //# sourceMappingURL=chunk-I6T3DKYK.js.map