kordoc 3.17.0 → 3.18.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 (48) hide show
  1. package/README.md +5 -0
  2. package/dist/{-3KPDRR3A.js → -V66QW3WA.js} +9 -7
  3. package/dist/{chunk-WHMNPQXW.js → chunk-2IBFK5ZO.js} +39 -3
  4. package/dist/chunk-2IBFK5ZO.js.map +1 -0
  5. package/dist/{chunk-NKICMZ7F.js → chunk-4RGDFDQ2.js} +2 -2
  6. package/dist/{chunk-VUS6LRVY.js → chunk-7K5P4RNT.js} +571 -83
  7. package/dist/chunk-7K5P4RNT.js.map +1 -0
  8. package/dist/{chunk-TDIDUEBH.js → chunk-NZJAXMN7.js} +3 -3
  9. package/dist/{chunk-SADQWCWR.js → chunk-QMJJI6TD.js} +3 -3
  10. package/dist/{chunk-EL2Y4BL2.cjs → chunk-R2H34FY5.cjs} +45 -9
  11. package/dist/chunk-R2H34FY5.cjs.map +1 -0
  12. package/dist/{chunk-E6NQWOFQ.js → chunk-UHYPUIRH.js} +39 -3
  13. package/dist/chunk-UHYPUIRH.js.map +1 -0
  14. package/dist/{chunk-HVEEFHN7.js → chunk-UNV7F3FK.js} +2 -2
  15. package/dist/cli.js +19 -16
  16. package/dist/cli.js.map +1 -1
  17. package/dist/index.cjs +899 -411
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +124 -1
  20. package/dist/index.d.ts +124 -1
  21. package/dist/index.js +629 -141
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp.js +10 -9
  24. package/dist/mcp.js.map +1 -1
  25. package/dist/{parser-CYJMOXUR.js → parser-DOBK652H.js} +3 -3
  26. package/dist/{parser-LHBXIKXX.js → parser-JBBA5A5E.js} +2 -2
  27. package/dist/{parser-I5GC4QQ5.cjs → parser-XEY5MRGV.cjs} +14 -14
  28. package/dist/{parser-I5GC4QQ5.cjs.map → parser-XEY5MRGV.cjs.map} +1 -1
  29. package/dist/render-VX4H2S4F.js +10 -0
  30. package/dist/seal-6Z6H4YXN.js +10 -0
  31. package/dist/{watch-VT7BSLNI.js → watch-2MNRQWGV.js} +7 -7
  32. package/package.json +1 -1
  33. package/dist/chunk-E6NQWOFQ.js.map +0 -1
  34. package/dist/chunk-EL2Y4BL2.cjs.map +0 -1
  35. package/dist/chunk-VUS6LRVY.js.map +0 -1
  36. package/dist/chunk-WHMNPQXW.js.map +0 -1
  37. package/dist/render-HY7KKYPV.js +0 -10
  38. package/dist/seal-ITGYHENO.js +0 -10
  39. /package/dist/{-3KPDRR3A.js.map → -V66QW3WA.js.map} +0 -0
  40. /package/dist/{chunk-NKICMZ7F.js.map → chunk-4RGDFDQ2.js.map} +0 -0
  41. /package/dist/{chunk-TDIDUEBH.js.map → chunk-NZJAXMN7.js.map} +0 -0
  42. /package/dist/{chunk-SADQWCWR.js.map → chunk-QMJJI6TD.js.map} +0 -0
  43. /package/dist/{chunk-HVEEFHN7.js.map → chunk-UNV7F3FK.js.map} +0 -0
  44. /package/dist/{parser-CYJMOXUR.js.map → parser-DOBK652H.js.map} +0 -0
  45. /package/dist/{parser-LHBXIKXX.js.map → parser-JBBA5A5E.js.map} +0 -0
  46. /package/dist/{render-HY7KKYPV.js.map → render-VX4H2S4F.js.map} +0 -0
  47. /package/dist/{seal-ITGYHENO.js.map → seal-6Z6H4YXN.js.map} +0 -0
  48. /package/dist/{watch-VT7BSLNI.js.map → watch-2MNRQWGV.js.map} +0 -0
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  classifyError,
12
12
  compareSectionPaths,
13
13
  convertTableToText,
14
+ dedupeRunningHeaders,
14
15
  flattenLayoutTables,
15
16
  isPathTraversal,
16
17
  mapPuaText,
@@ -19,7 +20,7 @@ import {
19
20
  sanitizeHref,
20
21
  stripDtd,
21
22
  toArrayBuffer
22
- } from "./chunk-E6NQWOFQ.js";
23
+ } from "./chunk-UHYPUIRH.js";
23
24
  import {
24
25
  parsePageRange
25
26
  } from "./chunk-GE43BE46.js";
@@ -2527,11 +2528,11 @@ function formatRoman(n, upper) {
2527
2528
  const values = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
2528
2529
  const symbols = upper ? ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] : ["m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i"];
2529
2530
  let result = "";
2530
- let num3 = n;
2531
+ let num4 = n;
2531
2532
  for (let i = 0; i < values.length; i++) {
2532
- while (num3 >= values[i]) {
2533
+ while (num4 >= values[i]) {
2533
2534
  result += symbols[i];
2534
- num3 -= values[i];
2535
+ num4 -= values[i];
2535
2536
  }
2536
2537
  }
2537
2538
  return result;
@@ -2539,11 +2540,11 @@ function formatRoman(n, upper) {
2539
2540
  function formatLatin(n, upper) {
2540
2541
  if (n <= 0) return "";
2541
2542
  let result = "";
2542
- let num3 = n;
2543
- while (num3 > 0) {
2544
- num3--;
2545
- result = String.fromCharCode((upper ? 65 : 97) + num3 % 26) + result;
2546
- num3 = Math.floor(num3 / 26);
2543
+ let num4 = n;
2544
+ while (num4 > 0) {
2545
+ num4--;
2546
+ result = String.fromCharCode((upper ? 65 : 97) + num4 % 26) + result;
2547
+ num4 = Math.floor(num4 / 26);
2547
2548
  }
2548
2549
  return result;
2549
2550
  }
@@ -2551,15 +2552,15 @@ function formatEastAsianNumber(n, digits, units, zero) {
2551
2552
  if (n === 0) return zero;
2552
2553
  if (n < 0 || n > 99999) return String(n);
2553
2554
  let result = "";
2554
- let num3 = n;
2555
+ let num4 = n;
2555
2556
  let unit = 0;
2556
- while (num3 > 0) {
2557
- const d = num3 % 10;
2557
+ while (num4 > 0) {
2558
+ const d = num4 % 10;
2558
2559
  if (d > 0) {
2559
2560
  const digitStr = d === 1 && unit > 0 ? "" : digits[d];
2560
2561
  result = digitStr + units[unit] + result;
2561
2562
  }
2562
- num3 = Math.floor(num3 / 10);
2563
+ num4 = Math.floor(num4 / 10);
2563
2564
  unit++;
2564
2565
  }
2565
2566
  return result;
@@ -2606,8 +2607,8 @@ function expandNumberingFormat(formatStr, counters, numbering) {
2606
2607
  const idx = levelRef - 1;
2607
2608
  const counterVal = counters[idx] ?? 0;
2608
2609
  const start = numbering.startNumbers[idx] ?? 1;
2609
- const num3 = counterVal > 0 ? start - 1 + counterVal : start;
2610
- result += formatNumber(num3, headFormatToNumFmt(numbering.numberFormats[idx] ?? 0));
2610
+ const num4 = counterVal > 0 ? start - 1 + counterVal : start;
2611
+ result += formatNumber(num4, headFormatToNumFmt(numbering.numberFormats[idx] ?? 0));
2611
2612
  i += 2;
2612
2613
  continue;
2613
2614
  }
@@ -2756,6 +2757,143 @@ function extractHwp5ImagesLenient(lcfb, blocks, warnings) {
2756
2757
  return resolveImageBlocks(binDataMap, blocks, warnings);
2757
2758
  }
2758
2759
 
2760
+ // src/image/transcode.ts
2761
+ import { deflateSync } from "zlib";
2762
+ var CRC_TABLE = (() => {
2763
+ const table = new Uint32Array(256);
2764
+ for (let n = 0; n < 256; n++) {
2765
+ let c = n;
2766
+ for (let k = 0; k < 8; k++) {
2767
+ c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
2768
+ }
2769
+ table[n] = c >>> 0;
2770
+ }
2771
+ return table;
2772
+ })();
2773
+ function crc32(bytes) {
2774
+ let c = 4294967295;
2775
+ for (let i = 0; i < bytes.length; i++) {
2776
+ c = CRC_TABLE[(c ^ bytes[i]) & 255] ^ c >>> 8;
2777
+ }
2778
+ return (c ^ 4294967295) >>> 0;
2779
+ }
2780
+ var BI_RGB = 0;
2781
+ var MAX_DIM = 32767;
2782
+ var MAX_PIXELS = 36e6;
2783
+ function bmpToPng(bmp) {
2784
+ if (bmp.length < 54) return null;
2785
+ if (bmp[0] !== 66 || bmp[1] !== 77) return null;
2786
+ const dv = new DataView(bmp.buffer, bmp.byteOffset, bmp.byteLength);
2787
+ const dataOffset = dv.getUint32(10, true);
2788
+ const headerSize = dv.getUint32(14, true);
2789
+ if (headerSize < 40) return null;
2790
+ const width = dv.getInt32(18, true);
2791
+ const rawHeight = dv.getInt32(22, true);
2792
+ const bitCount = dv.getUint16(28, true);
2793
+ const compression = dv.getUint32(30, true);
2794
+ if (compression !== BI_RGB) return null;
2795
+ if (bitCount !== 24 && bitCount !== 32) return null;
2796
+ if (width <= 0 || rawHeight === 0) return null;
2797
+ if (width > MAX_DIM || Math.abs(rawHeight) > MAX_DIM) return null;
2798
+ const topDown = rawHeight < 0;
2799
+ const height = Math.abs(rawHeight);
2800
+ if (width * height > MAX_PIXELS) return null;
2801
+ const bytesPerPixel = bitCount >> 3;
2802
+ const rowStride = width * bytesPerPixel + 3 & ~3;
2803
+ if (dataOffset + rowStride * height > bmp.length) return null;
2804
+ const rgba = new Uint8Array(width * height * 4);
2805
+ let anyAlpha = 0;
2806
+ for (let y = 0; y < height; y++) {
2807
+ const srcRow = topDown ? y : height - 1 - y;
2808
+ let src = dataOffset + srcRow * rowStride;
2809
+ let dst = y * width * 4;
2810
+ for (let x = 0; x < width; x++) {
2811
+ rgba[dst] = bmp[src + 2];
2812
+ rgba[dst + 1] = bmp[src + 1];
2813
+ rgba[dst + 2] = bmp[src];
2814
+ const a = bitCount === 32 ? bmp[src + 3] : 255;
2815
+ rgba[dst + 3] = a;
2816
+ anyAlpha |= a;
2817
+ src += bytesPerPixel;
2818
+ dst += 4;
2819
+ }
2820
+ }
2821
+ if (bitCount === 32 && anyAlpha === 0) {
2822
+ for (let i = 3; i < rgba.length; i += 4) rgba[i] = 255;
2823
+ }
2824
+ return encodePng(width, height, rgba);
2825
+ }
2826
+ var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10);
2827
+ function chunk(type, data) {
2828
+ const body = new Uint8Array(4 + data.length);
2829
+ body[0] = type.charCodeAt(0);
2830
+ body[1] = type.charCodeAt(1);
2831
+ body[2] = type.charCodeAt(2);
2832
+ body[3] = type.charCodeAt(3);
2833
+ body.set(data, 4);
2834
+ const out = new Uint8Array(8 + data.length + 4);
2835
+ const dv = new DataView(out.buffer);
2836
+ dv.setUint32(0, data.length, false);
2837
+ out.set(body, 4);
2838
+ dv.setUint32(8 + data.length, crc32(body), false);
2839
+ return out;
2840
+ }
2841
+ function encodePng(width, height, rgba) {
2842
+ const ihdr = new Uint8Array(13);
2843
+ const iv = new DataView(ihdr.buffer);
2844
+ iv.setUint32(0, width, false);
2845
+ iv.setUint32(4, height, false);
2846
+ ihdr[8] = 8;
2847
+ ihdr[9] = 6;
2848
+ const stride = width * 4;
2849
+ const raw = new Uint8Array((stride + 1) * height);
2850
+ for (let y = 0; y < height; y++) {
2851
+ const rowStart = y * (stride + 1);
2852
+ raw[rowStart] = 0;
2853
+ raw.set(rgba.subarray(y * stride, y * stride + stride), rowStart + 1);
2854
+ }
2855
+ const idat = deflateSync(raw);
2856
+ const ihdrChunk = chunk("IHDR", ihdr);
2857
+ const idatChunk = chunk("IDAT", idat);
2858
+ const iendChunk = chunk("IEND", new Uint8Array(0));
2859
+ const out = new Uint8Array(PNG_SIGNATURE.length + ihdrChunk.length + idatChunk.length + iendChunk.length);
2860
+ let o = 0;
2861
+ out.set(PNG_SIGNATURE, o);
2862
+ o += PNG_SIGNATURE.length;
2863
+ out.set(ihdrChunk, o);
2864
+ o += ihdrChunk.length;
2865
+ out.set(idatChunk, o);
2866
+ o += idatChunk.length;
2867
+ out.set(iendChunk, o);
2868
+ return out;
2869
+ }
2870
+ function escapeRegExp(s) {
2871
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2872
+ }
2873
+ function inlineImagesIntoMarkdown(markdown, images, opts) {
2874
+ const compress = opts?.compress !== false;
2875
+ let out = markdown;
2876
+ for (const img of images) {
2877
+ let bytes = img.data;
2878
+ let mime = img.mimeType;
2879
+ if (compress && mime === "image/bmp") {
2880
+ const png = bmpToPng(img.data);
2881
+ if (png) {
2882
+ bytes = png;
2883
+ mime = "image/png";
2884
+ }
2885
+ }
2886
+ const base64 = Buffer.from(bytes).toString("base64");
2887
+ const dataUri = `data:${mime};base64,${base64}`;
2888
+ const name = escapeRegExp(img.filename);
2889
+ const mdRe = new RegExp(`!\\[image\\]\\((?:images/)?${name}\\)`, "g");
2890
+ out = out.replace(mdRe, () => `![image](${dataUri})`);
2891
+ const imgTagRe = new RegExp(`(<img\\b[^>]*\\bsrc=")(?:images/)?${name}(")`, "g");
2892
+ out = out.replace(imgTagRe, (_m, pre, post) => `${pre}${dataUri}${post}`);
2893
+ }
2894
+ return out;
2895
+ }
2896
+
2759
2897
  // src/hwp5/aes.ts
2760
2898
  var S_BOX = new Uint8Array([
2761
2899
  99,
@@ -3804,12 +3942,25 @@ function parseHwp5Document(buffer, options) {
3804
3942
  }
3805
3943
  const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
3806
3944
  const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings);
3807
- const flatBlocks = flattenLayoutTables(blocks);
3945
+ let flatBlocks = flattenLayoutTables(blocks);
3946
+ if (options?.dedupeRunningHeaders) {
3947
+ const deduped = dedupeRunningHeaders(flatBlocks);
3948
+ const removed = flatBlocks.length - deduped.length;
3949
+ if (removed > 0) warnings.push({ message: `\uBC18\uBCF5 \uB7EC\uB2DD \uD5E4\uB354 ${removed}\uAC1C \uC81C\uAC70`, code: "HIDDEN_TEXT_FILTERED" });
3950
+ flatBlocks = deduped;
3951
+ }
3808
3952
  if (docInfo) {
3809
3953
  detectHwp5Headings(flatBlocks, docInfo);
3810
3954
  }
3811
3955
  const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
3812
- const markdown = blocksToMarkdown(flatBlocks);
3956
+ let markdown = blocksToMarkdown(flatBlocks);
3957
+ if (options?.inlineImages && images.length > 0) {
3958
+ try {
3959
+ markdown = inlineImagesIntoMarkdown(markdown, images, { compress: true });
3960
+ } catch (inlineErr) {
3961
+ warnings.push({ message: `\uC774\uBBF8\uC9C0 \uC778\uB77C\uC778 \uC2E4\uD328 \u2014 \uC6D0\uBCF8 \uD30C\uC77C \uCC38\uC870\uB85C \uD3F4\uBC31: ${inlineErr instanceof Error ? inlineErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "SKIPPED_IMAGE" });
3962
+ }
3963
+ }
3813
3964
  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 };
3814
3965
  }
3815
3966
  function parseDocInfoStream(cfb, compressed) {
@@ -4175,11 +4326,11 @@ function applyCtrlEffect(ctrl, records, ctx) {
4175
4326
  const attr = ctrl.data.readUInt32LE(4);
4176
4327
  const type = attr & 15;
4177
4328
  const format = attr >>> 4 & 255;
4178
- const num3 = ctx.doc.autoCounters.get(type) ?? 1;
4179
- ctx.doc.autoCounters.set(type, num3 + 1);
4329
+ const num4 = ctx.doc.autoCounters.get(type) ?? 1;
4330
+ ctx.doc.autoCounters.set(type, num4 + 1);
4180
4331
  const prefix = ctrl.data.length >= 14 ? wcharAt(ctrl.data, 12) : "";
4181
4332
  const suffix = ctrl.data.length >= 16 ? wcharAt(ctrl.data, 14) : "";
4182
- ctrl.inlineText = `${prefix}${formatNumber(num3, shapeFormatToNumFmt(format))}${suffix}`;
4333
+ ctrl.inlineText = `${prefix}${formatNumber(num4, shapeFormatToNumFmt(format))}${suffix}`;
4183
4334
  }
4184
4335
  return;
4185
4336
  }
@@ -4187,8 +4338,8 @@ function applyCtrlEffect(ctrl, records, ctx) {
4187
4338
  if (ctrl.data.length >= 10) {
4188
4339
  const attr = ctrl.data.readUInt32LE(4);
4189
4340
  const type = attr & 15;
4190
- const num3 = ctrl.data.readUInt16LE(8);
4191
- if (num3 > 0) ctx.doc.autoCounters.set(type, num3);
4341
+ const num4 = ctrl.data.readUInt16LE(8);
4342
+ if (num4 > 0) ctx.doc.autoCounters.set(type, num4);
4192
4343
  }
4193
4344
  return;
4194
4345
  }
@@ -4250,7 +4401,7 @@ function blocksPlainText(blocks, sep) {
4250
4401
  return parts.join(sep).trim();
4251
4402
  }
4252
4403
  function applyNoteEffect(ctrl, records, ctx, autoType) {
4253
- const num3 = ctx.doc.autoCounters.get(autoType) ?? 1;
4404
+ const num4 = ctx.doc.autoCounters.get(autoType) ?? 1;
4254
4405
  let before = "";
4255
4406
  let after = "";
4256
4407
  let shape = 0;
@@ -4261,11 +4412,11 @@ function applyNoteEffect(ctrl, records, ctx, autoType) {
4261
4412
  if (ctrl.data.length >= 16) {
4262
4413
  shape = ctrl.data.readUInt32LE(12) & 255;
4263
4414
  }
4264
- const formatted = formatNumber(num3, shapeFormatToNumFmt(shape));
4415
+ const formatted = formatNumber(num4, shapeFormatToNumFmt(shape));
4265
4416
  const marker = before || after ? `${before}${formatted}${after}` : `${formatted})`;
4266
4417
  const content = blocksPlainText(parseListHeaderParagraphs(ctrl, records, ctx), " ");
4267
- if ((ctx.doc.autoCounters.get(autoType) ?? 1) <= num3) {
4268
- ctx.doc.autoCounters.set(autoType, num3 + 1);
4418
+ if ((ctx.doc.autoCounters.get(autoType) ?? 1) <= num4) {
4419
+ ctx.doc.autoCounters.set(autoType, num4 + 1);
4269
4420
  }
4270
4421
  ctrl.inlineText = marker;
4271
4422
  if (content) ctrl.footnote = content.startsWith(marker) ? content : `${marker} ${content}`;
@@ -16803,9 +16954,9 @@ var MAX_ROWS2 = 1e4;
16803
16954
  var MAX_COLS2 = 200;
16804
16955
  function cleanNumericValue(raw) {
16805
16956
  if (!/^-?\d+\.\d+$/.test(raw)) return raw;
16806
- const num3 = parseFloat(raw);
16807
- if (!isFinite(num3)) return raw;
16808
- const cleaned = parseFloat(num3.toPrecision(15)).toString();
16957
+ const num4 = parseFloat(raw);
16958
+ if (!isFinite(num4)) return raw;
16959
+ const cleaned = parseFloat(num4.toPrecision(15)).toString();
16809
16960
  return cleaned;
16810
16961
  }
16811
16962
  function parseCellRef(ref) {
@@ -17148,17 +17299,17 @@ function decodeRk(rk) {
17148
17299
  const fDiv100 = (rk & 1) !== 0;
17149
17300
  const fInt = (rk & 2) !== 0;
17150
17301
  const val30 = rk >> 2;
17151
- let num3;
17302
+ let num4;
17152
17303
  if (fInt) {
17153
- num3 = val30;
17304
+ num4 = val30;
17154
17305
  } else {
17155
17306
  const high32 = (rk & 4294967292) >>> 0;
17156
17307
  const buf = Buffer.alloc(8);
17157
17308
  buf.writeUInt32LE(0, 0);
17158
17309
  buf.writeUInt32LE(high32, 4);
17159
- num3 = buf.readDoubleLE(0);
17310
+ num4 = buf.readDoubleLE(0);
17160
17311
  }
17161
- return fDiv100 ? num3 / 100 : num3;
17312
+ return fDiv100 ? num4 / 100 : num4;
17162
17313
  }
17163
17314
  function decodeMulRk(data) {
17164
17315
  if (data.length < 6) return null;
@@ -17858,9 +18009,9 @@ function nodeToLatex(el) {
17858
18009
  case "f": {
17859
18010
  const n = firstKid(el, "num");
17860
18011
  const d = firstKid(el, "den");
17861
- const num3 = n ? childrenToLatex(n) : "";
18012
+ const num4 = n ? childrenToLatex(n) : "";
17862
18013
  const den = d ? childrenToLatex(d) : "";
17863
- return "\\frac" + grp(num3) + grp(den);
18014
+ return "\\frac" + grp(num4) + grp(den);
17864
18015
  }
17865
18016
  // 첨자
17866
18017
  case "sSup": {
@@ -20155,7 +20306,7 @@ function parseCentralDirectory(buf) {
20155
20306
  }
20156
20307
  return { entries, cdOffset, cdSize, eocdOffset };
20157
20308
  }
20158
- var CRC_TABLE = (() => {
20309
+ var CRC_TABLE2 = (() => {
20159
20310
  const table = new Uint32Array(256);
20160
20311
  for (let n = 0; n < 256; n++) {
20161
20312
  let c = n;
@@ -20164,10 +20315,10 @@ var CRC_TABLE = (() => {
20164
20315
  }
20165
20316
  return table;
20166
20317
  })();
20167
- function crc32(data) {
20318
+ function crc322(data) {
20168
20319
  let crc = 4294967295;
20169
20320
  for (let i = 0; i < data.length; i++) {
20170
- crc = CRC_TABLE[(crc ^ data[i]) & 255] ^ crc >>> 8;
20321
+ crc = CRC_TABLE2[(crc ^ data[i]) & 255] ^ crc >>> 8;
20171
20322
  }
20172
20323
  return (crc ^ 4294967295) >>> 0;
20173
20324
  }
@@ -20206,7 +20357,7 @@ function patchZipEntries(original, replacements, additions) {
20206
20357
  const hview = new DataView(header.buffer, header.byteOffset, header.byteLength);
20207
20358
  const method = e.method;
20208
20359
  const compData = method === 0 ? newData : new Uint8Array(deflateRawSync(newData));
20209
- const crc = crc32(newData);
20360
+ const crc = crc322(newData);
20210
20361
  const flags = e.flags & ~8;
20211
20362
  hview.setUint16(6, flags, true);
20212
20363
  hview.setUint32(14, crc, true);
@@ -20224,7 +20375,7 @@ function patchZipEntries(original, replacements, additions) {
20224
20375
  const deflated = new Uint8Array(deflateRawSync(data));
20225
20376
  const method = deflated.length < data.length ? 8 : 0;
20226
20377
  const compData = method === 8 ? deflated : data;
20227
- const crc = crc32(data);
20378
+ const crc = crc322(data);
20228
20379
  const header = new Uint8Array(30 + nameBytes.length);
20229
20380
  const hv = new DataView(header.buffer);
20230
20381
  hv.setUint32(0, LOCAL_SIG, true);
@@ -21253,7 +21404,7 @@ function generateManifest(chartParts = []) {
21253
21404
  </opf:spine>
21254
21405
  </opf:package>`;
21255
21406
  }
21256
- function buildCharProperties(theme, gongmun, ratioVariants = []) {
21407
+ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls = []) {
21257
21408
  let body = 1e3, code = 900, h1 = 1800, h2 = 1400, h3 = 1200, h4 = 1100;
21258
21409
  if (gongmun) {
21259
21410
  body = gongmun.bodyHeight;
@@ -21285,6 +21436,7 @@ function buildCharProperties(theme, gongmun, ratioVariants = []) {
21285
21436
  charPr(rows.length + 3, body, true, true, 0, theme.body, r)
21286
21437
  );
21287
21438
  }
21439
+ rows.push(...extraCharPrXmls);
21288
21440
  return `<hh:charProperties itemCnt="${rows.length}">
21289
21441
  ${rows.join("\n")}
21290
21442
  </hh:charProperties>`;
@@ -21338,9 +21490,9 @@ ${heads}
21338
21490
  </hh:numbering>
21339
21491
  </hh:numberings>`;
21340
21492
  }
21341
- function generateHeaderXml(theme, gongmun, ratioVariants = []) {
21493
+ function generateHeaderXml(theme, gongmun, ratioVariants = [], remap = null) {
21342
21494
  const bodyFace = gongmun?.bodyFont === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD568\uCD08\uB86C\uBC14\uD0D5";
21343
- const charPropsXml = buildCharProperties(theme, gongmun, ratioVariants);
21495
+ const charPropsXml = buildCharProperties(theme, gongmun, ratioVariants, remap?.charPrXmls ?? []);
21344
21496
  const paraPropsXml = buildParaProperties(gongmun);
21345
21497
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
21346
21498
  <hh:head xmlns:hh="${NS_HEAD}" xmlns:hp="${NS_PARA}" xmlns:hc="${NS_CORE}" version="1.4" secCnt="1">
@@ -21395,7 +21547,7 @@ function generateHeaderXml(theme, gongmun, ratioVariants = []) {
21395
21547
  </hh:font>
21396
21548
  </hh:fontface>
21397
21549
  </hh:fontfaces>
21398
- <hh:borderFills itemCnt="2">
21550
+ <hh:borderFills itemCnt="${2 + (remap?.borderFillXmls.length ?? 0)}">
21399
21551
  <hh:borderFill id="1" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
21400
21552
  <hh:slash type="NONE" Crooked="0" isCounter="0"/>
21401
21553
  <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
@@ -21411,7 +21563,7 @@ function generateHeaderXml(theme, gongmun, ratioVariants = []) {
21411
21563
  <hh:rightBorder type="SOLID" width="0.12 mm" color="#000000"/>
21412
21564
  <hh:topBorder type="SOLID" width="0.12 mm" color="#000000"/>
21413
21565
  <hh:bottomBorder type="SOLID" width="0.12 mm" color="#000000"/>
21414
- </hh:borderFill>
21566
+ </hh:borderFill>${remap && remap.borderFillXmls.length ? "\n" + remap.borderFillXmls.join("\n") : ""}
21415
21567
  </hh:borderFills>
21416
21568
  ${charPropsXml}
21417
21569
  <hh:tabProperties itemCnt="0"/>
@@ -22137,29 +22289,157 @@ function removeNestedTables(html) {
22137
22289
  return result;
22138
22290
  }
22139
22291
 
22292
+ // src/hwpx/gen-profile.ts
22293
+ function normalizeAnchor(s) {
22294
+ return s.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "").slice(0, 24);
22295
+ }
22296
+ function takeProfile(remap, rows, cols, anchor, seq) {
22297
+ if (!remap) return null;
22298
+ for (const t of remap.tables) {
22299
+ if (t.used) continue;
22300
+ if (t.rows !== rows || t.cols !== cols) continue;
22301
+ if (t.anchor && anchor) {
22302
+ if (t.anchor !== anchor) continue;
22303
+ } else if (t.index !== seq) {
22304
+ continue;
22305
+ }
22306
+ t.used = true;
22307
+ return t;
22308
+ }
22309
+ return null;
22310
+ }
22311
+ function parseHu(s) {
22312
+ if (s == null) return void 0;
22313
+ const n = parseInt(String(s).trim(), 10);
22314
+ return Number.isFinite(n) ? n : void 0;
22315
+ }
22316
+ function edgeXml(tag, d) {
22317
+ return d ? `<hh:${tag} type="${d.type}" width="${d.width}" color="${d.color}"/>` : `<hh:${tag} type="NONE" width="0.1 mm" color="#000000"/>`;
22318
+ }
22319
+ function borderFillDefToXml(id, def) {
22320
+ const fill = def.fill?.faceColor ? `<hh:fillBrush><hh:winBrush faceColor="${def.fill.faceColor}" hatchColor="#000000" alpha="0"/></hh:fillBrush>` : "";
22321
+ return ` <hh:borderFill id="${id}" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
22322
+ <hh:slash type="NONE" Crooked="0" isCounter="0"/>
22323
+ <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
22324
+ ${edgeXml("leftBorder", def.leftBorder)}
22325
+ ${edgeXml("rightBorder", def.rightBorder)}
22326
+ ${edgeXml("topBorder", def.topBorder)}
22327
+ ${edgeXml("bottomBorder", def.bottomBorder)}${fill ? `
22328
+ ${fill}` : ""}
22329
+ </hh:borderFill>`;
22330
+ }
22331
+ var PROFILE_FONT_MAX = 2;
22332
+ function profileCharPrXml(id, def) {
22333
+ const height = parseHu(def.height_hwpunit) ?? 1e3;
22334
+ const color = def.textColor ?? "#000000";
22335
+ const rawFont = def.fontRef_hangul != null ? parseInt(def.fontRef_hangul, 10) || 0 : 0;
22336
+ const font = rawFont >= 0 && rawFont <= PROFILE_FONT_MAX ? rawFont : 0;
22337
+ const boldAttr = def.bold ? ` bold="1"` : "";
22338
+ const italicAttr = def.italic ? ` italic="1"` : "";
22339
+ const underline = def.underline ? `
22340
+ <hh:underline type="BOTTOM" shape="SOLID" color="${color}"/>` : "";
22341
+ return ` <hh:charPr id="${id}" height="${height}" textColor="${color}" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="1"${boldAttr}${italicAttr}>
22342
+ <hh:fontRef hangul="${font}" latin="${font}" hanja="${font}" japanese="${font}" other="${font}" symbol="${font}" user="${font}"/>
22343
+ <hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
22344
+ <hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
22345
+ <hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
22346
+ <hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>${underline}
22347
+ </hh:charPr>`;
22348
+ }
22349
+ function buildProfileRemap(profile, charPrBase, borderFillBase = 3) {
22350
+ const remap = { borderFillXmls: [], charPrXmls: [], tables: [] };
22351
+ let bfNext = borderFillBase;
22352
+ let charNext = charPrBase;
22353
+ for (const t of profile.tables) {
22354
+ const localBf = {};
22355
+ for (const [key, def] of Object.entries(t.used_border_fills ?? {})) {
22356
+ const gid = bfNext++;
22357
+ remap.borderFillXmls.push(borderFillDefToXml(gid, def));
22358
+ localBf[key] = gid;
22359
+ }
22360
+ const localChar = {};
22361
+ for (const [key, def] of Object.entries(t.used_char_prs ?? {})) {
22362
+ const gid = charNext++;
22363
+ remap.charPrXmls.push(profileCharPrXml(gid, def));
22364
+ localChar[key] = gid;
22365
+ }
22366
+ let colWidths;
22367
+ if (t.col_widths_hwpunit && t.col_widths_hwpunit.length === t.cols) {
22368
+ const parsed = t.col_widths_hwpunit.map(parseHu);
22369
+ if (parsed.every((n) => n != null)) colWidths = parsed;
22370
+ }
22371
+ const tr = {
22372
+ index: t.table_index,
22373
+ rows: t.rows,
22374
+ cols: t.cols,
22375
+ // 재정규화 — 추출기는 정규화해 담지만 손편집된 프로필 JSON도 같은 키 공간으로
22376
+ anchor: t.anchor_text ? normalizeAnchor(t.anchor_text) : void 0,
22377
+ width: parseHu(t.width_hwpunit),
22378
+ colWidths,
22379
+ cellBf: /* @__PURE__ */ new Map(),
22380
+ cellChar: /* @__PURE__ */ new Map(),
22381
+ cellH: /* @__PURE__ */ new Map()
22382
+ };
22383
+ for (const cell of t.cells) {
22384
+ const k = `${cell.row},${cell.col}`;
22385
+ if (cell.borderFillIDRef != null && cell.borderFillIDRef in localBf) {
22386
+ tr.cellBf.set(k, localBf[cell.borderFillIDRef]);
22387
+ }
22388
+ if (cell.charPrIDRef != null && cell.charPrIDRef in localChar) {
22389
+ tr.cellChar.set(k, localChar[cell.charPrIDRef]);
22390
+ }
22391
+ const h = parseHu(cell.height_hwpunit);
22392
+ if (h != null) tr.cellH.set(k, h);
22393
+ }
22394
+ remap.tables.push(tr);
22395
+ }
22396
+ return remap;
22397
+ }
22398
+ function profileCharPrBase(ratioVariantCount) {
22399
+ return CHAR_VARIANT_BASE + ratioVariantCount * 4;
22400
+ }
22401
+
22140
22402
  // src/hwpx/gen-table.ts
22141
22403
  var TABLE_ID_BASE = 1e3;
22142
22404
  var tableIdCounter = TABLE_ID_BASE;
22143
22405
  function nextTableId() {
22144
22406
  return ++tableIdCounter;
22145
22407
  }
22146
- function generateTable(rows, theme) {
22408
+ function anchorOfMarkdownCell(cell) {
22409
+ return normalizeAnchor(cell.replace(/!\[[^\]]*\]\([^)]*\)/g, ""));
22410
+ }
22411
+ function anchorOfHtmlCell(inner) {
22412
+ const noNested = inner.replace(/<table[\s\S]*?<\/table>/gi, "");
22413
+ const { lines } = htmlCellInnerToLines(noNested);
22414
+ return normalizeAnchor(lines.join(""));
22415
+ }
22416
+ function resolveColWidths(tp, colCnt, fallbackTotal) {
22417
+ if (tp?.colWidths && tp.colWidths.length === colCnt) return tp.colWidths;
22418
+ const w = tp?.width ? Math.floor(tp.width / colCnt) : Math.floor(fallbackTotal / colCnt);
22419
+ return Array(colCnt).fill(w);
22420
+ }
22421
+ function generateTable(rows, theme, remap = null, seq = 0) {
22147
22422
  const rowCnt = rows.length;
22148
22423
  const colCnt = Math.max(...rows.map((r) => r.length), 1);
22149
- const cellW = Math.floor(44e3 / colCnt);
22150
22424
  const cellH = 1500;
22151
- const tblW = cellW * colCnt;
22152
- const tblH = cellH * rowCnt;
22153
22425
  const tblId = nextTableId();
22426
+ const prof = takeProfile(remap, rowCnt, colCnt, anchorOfMarkdownCell(rows[0]?.[0] ?? ""), seq);
22427
+ const colW = resolveColWidths(prof, colCnt, 44e3);
22428
+ const tblW = colW.reduce((a, b) => a + b, 0);
22429
+ const tblH = cellH * rowCnt;
22154
22430
  const useHeaderStyle = theme.tableHeader !== theme.body || theme.tableHeaderBold;
22155
22431
  const trElements = rows.map((row, rowIdx) => {
22156
22432
  const cells = row.length < colCnt ? [...row, ...Array(colCnt - row.length).fill("")] : row;
22157
22433
  const isHeaderRow = rowIdx === 0;
22158
22434
  const headerCharPr = isHeaderRow && useHeaderStyle ? CHAR_TABLE_HEADER : CHAR_NORMAL;
22159
22435
  const tdElements = cells.map((cell, colIdx) => {
22160
- const runs = generateRuns(cell, headerCharPr);
22436
+ const k = `${rowIdx},${colIdx}`;
22437
+ const bf = prof?.cellBf.get(k) ?? 2;
22438
+ const ch = prof?.cellChar.get(k) ?? headerCharPr;
22439
+ const h = prof?.cellH.get(k) ?? cellH;
22440
+ const runs = generateRuns(cell, ch);
22161
22441
  const p = `<hp:p paraPrIDRef="0" styleIDRef="0">${runs}</hp:p>`;
22162
- return `<hp:tc name="" header="${isHeaderRow ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="2"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${p}</hp:subList><hp:cellAddr colAddr="${colIdx}" rowAddr="${rowIdx}"/><hp:cellSpan colSpan="1" rowSpan="1"/><hp:cellSz width="${cellW}" height="${cellH}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22442
+ return `<hp:tc name="" header="${isHeaderRow ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${bf}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${p}</hp:subList><hp:cellAddr colAddr="${colIdx}" rowAddr="${rowIdx}"/><hp:cellSpan colSpan="1" rowSpan="1"/><hp:cellSz width="${colW[colIdx]}" height="${h}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22163
22443
  }).join("");
22164
22444
  return `<hp:tr>${tdElements}</hp:tr>`;
22165
22445
  }).join("");
@@ -22190,35 +22470,43 @@ function layoutHtmlRows(rows) {
22190
22470
  function unescapeHtml(s) {
22191
22471
  return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&");
22192
22472
  }
22193
- function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3) {
22473
+ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, remap = null, seq = 0) {
22194
22474
  const rows = parseHtmlTable(rawHtml);
22195
22475
  if (!rows || rows.length === 0) return null;
22196
22476
  const { placed, rowCnt, colCnt } = layoutHtmlRows(rows);
22197
22477
  if (rowCnt === 0 || colCnt === 0) return null;
22198
- const colW = Math.floor(totalWidth / colCnt);
22199
22478
  const cellH = 1500;
22200
- const tblW = colW * colCnt;
22201
22479
  const tblId = nextTableId();
22480
+ const first = placed.find((p) => p.r === 0 && p.c === 0) ?? placed[0];
22481
+ const prof = takeProfile(remap, rowCnt, colCnt, first ? anchorOfHtmlCell(first.inner) : "", seq);
22482
+ const colW = resolveColWidths(prof, colCnt, totalWidth);
22483
+ const tblW = colW.reduce((a, b) => a + b, 0);
22202
22484
  const useHeaderStyle = theme.tableHeader !== theme.body || theme.tableHeaderBold;
22485
+ const spanW = (c, colSpan) => colW.slice(c, c + colSpan).reduce((a, b) => a + b, 0);
22203
22486
  const tcXmls = placed.map((cell) => {
22487
+ const k = `${cell.r},${cell.c}`;
22488
+ const bf = prof?.cellBf.get(k) ?? 2;
22204
22489
  const headerCharPr = cell.isHeader && useHeaderStyle ? CHAR_TABLE_HEADER : CHAR_NORMAL;
22490
+ const ch = prof?.cellChar.get(k) ?? headerCharPr;
22205
22491
  const { lines } = htmlCellInnerToLines(cell.inner);
22206
22492
  const paras = lines.map(
22207
- (line) => `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${headerCharPr}"><hp:t>${escapeXml(unescapeHtml(line))}</hp:t></hp:run></hp:p>`
22493
+ (line) => `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${ch}"><hp:t>${escapeXml(unescapeHtml(line))}</hp:t></hp:run></hp:p>`
22208
22494
  );
22495
+ const cellW = spanW(cell.c, cell.colSpan);
22209
22496
  let nestedH = 0;
22210
22497
  for (const nested of extractTopLevelTables(cell.inner)) {
22211
- const nestedXml = generateHtmlTableXml(nested, theme, Math.max(colW * cell.colSpan - 1020, 4e3));
22498
+ const nestedXml = generateHtmlTableXml(nested, theme, Math.max(cellW - 1020, 4e3));
22212
22499
  if (nestedXml) {
22213
22500
  paras.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${nestedXml}</hp:run></hp:p>`);
22214
22501
  nestedH += (nested.match(/<tr[\s>]/gi) ?? []).length * cellH + 300;
22215
22502
  }
22216
22503
  }
22217
22504
  if (paras.length === 0) {
22218
- paras.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${headerCharPr}"><hp:t></hp:t></hp:run></hp:p>`);
22505
+ paras.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${ch}"><hp:t></hp:t></hp:run></hp:p>`);
22219
22506
  }
22220
- const cellHeight = Math.max(cellH * cell.rowSpan, Math.max(lines.length, 1) * 800 + nestedH);
22221
- return `<hp:tc name="" header="${cell.isHeader ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="2"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${paras.join("")}</hp:subList><hp:cellAddr colAddr="${cell.c}" rowAddr="${cell.r}"/><hp:cellSpan colSpan="${cell.colSpan}" rowSpan="${cell.rowSpan}"/><hp:cellSz width="${colW * cell.colSpan}" height="${cellHeight}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22507
+ const contentH = Math.max(cellH * cell.rowSpan, Math.max(lines.length, 1) * 800 + nestedH);
22508
+ const cellHeight = Math.max(prof?.cellH.get(k) ?? 0, contentH);
22509
+ return `<hp:tc name="" header="${cell.isHeader ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${bf}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${paras.join("")}</hp:subList><hp:cellAddr colAddr="${cell.c}" rowAddr="${cell.r}"/><hp:cellSpan colSpan="${cell.colSpan}" rowSpan="${cell.rowSpan}"/><hp:cellSz width="${cellW}" height="${cellHeight}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22222
22510
  });
22223
22511
  const trXmls = [];
22224
22512
  for (let r = 0; r < rowCnt; r++) {
@@ -22384,9 +22672,9 @@ function readCommand(input, idx, depth) {
22384
22672
  const command = name.value;
22385
22673
  if (command === "\\") return { value: "#", next: name.next };
22386
22674
  if (command === "frac") {
22387
- const num3 = readGroupOrToken(input, name.next, depth);
22388
- const den = readGroupOrToken(input, num3.next, depth);
22389
- return { value: `{${num3.value}} over {${den.value}}`, next: den.next };
22675
+ const num4 = readGroupOrToken(input, name.next, depth);
22676
+ const den = readGroupOrToken(input, num4.next, depth);
22677
+ return { value: `{${num4.value}} over {${den.value}}`, next: den.next };
22390
22678
  }
22391
22679
  if (command === "sqrt") {
22392
22680
  let cursor = skipSpaces(input, name.next);
@@ -22517,9 +22805,10 @@ function generateSecPr(gongmun) {
22517
22805
  } : { top: 8504, bottom: 4252, left: 5670, right: 4252, header: 2835, footer: 2835 };
22518
22806
  return `<hp:secPr textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="0"><hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/><hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/><hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/><hp:pagePr landscape="WIDELY" width="59528" height="84188" gutterType="LEFT_ONLY"><hp:margin header="${m.header}" footer="${m.footer}" gutter="0" left="${m.left}" right="${m.right}" top="${m.top}" bottom="${m.bottom}"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="EACH_COLUMN" beneathText="0"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="END_OF_DOCUMENT" beneathText="0"/></hp:endNotePr></hp:secPr>`;
22519
22807
  }
22520
- function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null) {
22808
+ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, remap = null) {
22521
22809
  const paraXmls = [];
22522
22810
  let isFirst = true;
22811
+ let tableSeq = 0;
22523
22812
  const orderedCounters = {};
22524
22813
  let prevWasOrdered = false;
22525
22814
  for (let blockIdx = 0; blockIdx < blocks.length; blockIdx++) {
@@ -22627,11 +22916,11 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22627
22916
  paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
22628
22917
  isFirst = false;
22629
22918
  }
22630
- xml = generateTable(block.rows, theme);
22919
+ xml = generateTable(block.rows, theme, remap, tableSeq++);
22631
22920
  }
22632
22921
  break;
22633
22922
  case "html_table": {
22634
- const tbl = generateHtmlTableXml(block.text || "", theme);
22923
+ const tbl = generateHtmlTableXml(block.text || "", theme, 44e3, remap, tableSeq++);
22635
22924
  if (tbl) {
22636
22925
  if (isFirst) {
22637
22926
  const secRun = `<hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run>`;
@@ -22672,13 +22961,20 @@ async function markdownToHwpx(markdown, options) {
22672
22961
  const blocks = parseMarkdownToBlocks(markdown);
22673
22962
  const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
22674
22963
  const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
22964
+ const remap = options?.profile ? buildProfileRemap(options.profile, profileCharPrBase(fit?.variants?.length ?? 0)) : null;
22675
22965
  const chartParts = [];
22676
- const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts);
22966
+ const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, remap);
22967
+ if (remap && remap.tables.length > 0) {
22968
+ const unused = remap.tables.filter((t) => !t.used).length;
22969
+ if (unused === remap.tables.length) {
22970
+ console.warn(`[kordoc] format profile: \uD504\uB85C\uD544 \uD45C ${unused}\uAC1C\uAC00 \uBB38\uC11C \uD45C\uC640 \uB9E4\uCE6D\uB418\uC9C0 \uC54A\uC544 \uBBF8\uC801\uC6A9 (\uD589\xB7\uC5F4/\uCCAB \uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)`);
22971
+ }
22972
+ }
22677
22973
  const zip = new JSZip7();
22678
22974
  zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
22679
22975
  zip.file("META-INF/container.xml", generateContainerXml());
22680
22976
  zip.file("Contents/content.hpf", generateManifest(chartParts));
22681
- zip.file("Contents/header.xml", generateHeaderXml(theme, gongmun, fit?.variants ?? []));
22977
+ zip.file("Contents/header.xml", generateHeaderXml(theme, gongmun, fit?.variants ?? [], remap));
22682
22978
  zip.file("Contents/section0.xml", sectionXml);
22683
22979
  for (const part of chartParts) zip.file(part.name, part.xml);
22684
22980
  zip.file("Preview/PrvText.txt", buildPrvText(blocks));
@@ -23310,8 +23606,199 @@ async function placeSealHwpx(hwpxBuffer, ops) {
23310
23606
  };
23311
23607
  }
23312
23608
 
23313
- // src/roundtrip/patcher.ts
23609
+ // src/hwpx/extract-profile.ts
23314
23610
  import JSZip9 from "jszip";
23611
+ function elemsByLocal(root, name) {
23612
+ const all = root.getElementsByTagName("*");
23613
+ const out = [];
23614
+ for (let i = 0; i < all.length; i++) {
23615
+ const el = all[i];
23616
+ const tag = (el.tagName || el.localName || "").replace(/^[^:]+:/, "");
23617
+ if (tag === name) out.push(el);
23618
+ }
23619
+ return out;
23620
+ }
23621
+ function borderDefOf(el) {
23622
+ if (!el) return void 0;
23623
+ const type = el.getAttribute("type") || "NONE";
23624
+ const width = el.getAttribute("width") || "0.1 mm";
23625
+ const color = el.getAttribute("color") || "#000000";
23626
+ return { type, width, color };
23627
+ }
23628
+ function parseBorderFills(headerDoc) {
23629
+ const map = /* @__PURE__ */ new Map();
23630
+ for (const bf of elemsByLocal(headerDoc, "borderFill")) {
23631
+ const id = bf.getAttribute("id");
23632
+ if (!id) continue;
23633
+ const def = {
23634
+ leftBorder: borderDefOf(findChildByLocalName(bf, "leftBorder")),
23635
+ rightBorder: borderDefOf(findChildByLocalName(bf, "rightBorder")),
23636
+ topBorder: borderDefOf(findChildByLocalName(bf, "topBorder")),
23637
+ bottomBorder: borderDefOf(findChildByLocalName(bf, "bottomBorder"))
23638
+ };
23639
+ const fillBrush = findChildByLocalName(bf, "fillBrush");
23640
+ const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
23641
+ const face = winBrush?.getAttribute("faceColor");
23642
+ if (face && face !== "none") def.fill = { faceColor: face };
23643
+ map.set(id, def);
23644
+ }
23645
+ return map;
23646
+ }
23647
+ function parseCharPrs(headerDoc) {
23648
+ const map = /* @__PURE__ */ new Map();
23649
+ for (const cp of elemsByLocal(headerDoc, "charPr")) {
23650
+ const id = cp.getAttribute("id");
23651
+ if (!id) continue;
23652
+ const def = {};
23653
+ const h = cp.getAttribute("height");
23654
+ if (h) def.height_hwpunit = h;
23655
+ const color = cp.getAttribute("textColor");
23656
+ if (color) def.textColor = color;
23657
+ if (cp.getAttribute("bold") === "1") def.bold = true;
23658
+ if (cp.getAttribute("italic") === "1") def.italic = true;
23659
+ if (findChildByLocalName(cp, "underline")) def.underline = true;
23660
+ const fontRef = findChildByLocalName(cp, "fontRef");
23661
+ const hangul = fontRef?.getAttribute("hangul");
23662
+ if (hangul) def.fontRef_hangul = hangul;
23663
+ map.set(id, def);
23664
+ }
23665
+ return map;
23666
+ }
23667
+ function isTopLevelTable(tbl) {
23668
+ let p = tbl.parentNode;
23669
+ while (p) {
23670
+ const tag = (p.tagName || p.localName || "").replace(/^[^:]+:/, "");
23671
+ if (tag === "tbl") return false;
23672
+ p = p.parentNode;
23673
+ }
23674
+ return true;
23675
+ }
23676
+ function num(s) {
23677
+ if (s == null) return void 0;
23678
+ const n = parseInt(s, 10);
23679
+ return Number.isFinite(n) ? n : void 0;
23680
+ }
23681
+ function parseTable3(tbl, tableIndex, borderFills, charPrs) {
23682
+ const rows = num(tbl.getAttribute("rowCnt")) ?? 0;
23683
+ const cols = num(tbl.getAttribute("colCnt")) ?? 0;
23684
+ const sz = findChildByLocalName(tbl, "sz");
23685
+ const width = sz?.getAttribute("width") || void 0;
23686
+ const cells = [];
23687
+ const usedBf = /* @__PURE__ */ new Set();
23688
+ const usedCp = /* @__PURE__ */ new Set();
23689
+ const colWidths = new Array(cols).fill(void 0);
23690
+ let anchorText = "";
23691
+ for (const tc of elemsByLocal(tbl, "tc")) {
23692
+ if (nearestTable(tc) !== tbl) continue;
23693
+ const addr = findChildByLocalName(tc, "cellAddr");
23694
+ const span = findChildByLocalName(tc, "cellSpan");
23695
+ const csz = findChildByLocalName(tc, "cellSz");
23696
+ const row = num(addr?.getAttribute("rowAddr")) ?? 0;
23697
+ const col = num(addr?.getAttribute("colAddr")) ?? 0;
23698
+ if (row === 0 && col === 0 && !anchorText) anchorText = directCellText(tc);
23699
+ const colSpan = num(span?.getAttribute("colSpan")) ?? 1;
23700
+ const rowSpan = num(span?.getAttribute("rowSpan")) ?? 1;
23701
+ const bfId = tc.getAttribute("borderFillIDRef") || void 0;
23702
+ const cpId = firstRunCharPr(tc);
23703
+ const cell = { row, col, rowSpan, colSpan };
23704
+ const w = csz?.getAttribute("width");
23705
+ const hh = csz?.getAttribute("height");
23706
+ if (w) cell.width_hwpunit = w;
23707
+ if (hh) cell.height_hwpunit = hh;
23708
+ if (bfId) {
23709
+ cell.borderFillIDRef = bfId;
23710
+ usedBf.add(bfId);
23711
+ }
23712
+ if (cpId) {
23713
+ cell.charPrIDRef = cpId;
23714
+ usedCp.add(cpId);
23715
+ }
23716
+ cells.push(cell);
23717
+ if (row === 0 && colSpan === 1 && col < cols && w) colWidths[col] = w;
23718
+ }
23719
+ const table = {
23720
+ table_index: tableIndex,
23721
+ rows,
23722
+ cols,
23723
+ cells,
23724
+ used_border_fills: pick(borderFills, usedBf)
23725
+ };
23726
+ const anchor = normalizeAnchor(anchorText);
23727
+ if (anchor) table.anchor_text = anchor;
23728
+ if (width) table.width_hwpunit = width;
23729
+ if (colWidths.every((w) => w != null)) table.col_widths_hwpunit = colWidths;
23730
+ const cp = pick(charPrs, usedCp);
23731
+ if (Object.keys(cp).length) table.used_char_prs = cp;
23732
+ return table;
23733
+ }
23734
+ function nearestTable(tc) {
23735
+ let p = tc.parentNode;
23736
+ while (p) {
23737
+ const tag = (p.tagName || p.localName || "").replace(/^[^:]+:/, "");
23738
+ if (tag === "tbl") return p;
23739
+ p = p.parentNode;
23740
+ }
23741
+ return null;
23742
+ }
23743
+ function firstRunCharPr(tc) {
23744
+ for (const run of elemsByLocal(tc, "run")) {
23745
+ if (nearestCell(run) !== tc) continue;
23746
+ const id = run.getAttribute("charPrIDRef");
23747
+ if (id) return id;
23748
+ }
23749
+ return void 0;
23750
+ }
23751
+ function nearestCell(el) {
23752
+ let p = el.parentNode;
23753
+ while (p) {
23754
+ const tag = (p.tagName || p.localName || "").replace(/^[^:]+:/, "");
23755
+ if (tag === "tc") return p;
23756
+ p = p.parentNode;
23757
+ }
23758
+ return null;
23759
+ }
23760
+ function directCellText(tc) {
23761
+ let out = "";
23762
+ for (const t of elemsByLocal(tc, "t")) {
23763
+ if (nearestCell(t) !== tc) continue;
23764
+ out += t.textContent ?? "";
23765
+ if (out.length >= 64) break;
23766
+ }
23767
+ return out;
23768
+ }
23769
+ function pick(map, keys) {
23770
+ const out = {};
23771
+ for (const k of keys) {
23772
+ const v = map.get(k);
23773
+ if (v !== void 0) out[k] = v;
23774
+ }
23775
+ return out;
23776
+ }
23777
+ async function hwpxToProfile(input) {
23778
+ const buf = input instanceof ArrayBuffer ? input : toArrayBuffer(input);
23779
+ const zip = await JSZip9.loadAsync(buf);
23780
+ const parser = createXmlParser();
23781
+ const headerFile = zip.file("Contents/header.xml") ?? zip.file(/[Hh]eader\.xml$/)?.[0];
23782
+ let headerXml = "<root/>";
23783
+ if (headerFile) headerXml = await headerFile.async("text");
23784
+ const headerDoc = parser.parseFromString(headerXml, "text/xml");
23785
+ const borderFills = parseBorderFills(headerDoc);
23786
+ const charPrs = parseCharPrs(headerDoc);
23787
+ const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/).sort((a, b) => (num(a.name.match(/(\d+)\.xml$/)?.[1] ?? null) ?? 0) - (num(b.name.match(/(\d+)\.xml$/)?.[1] ?? null) ?? 0));
23788
+ const tables = [];
23789
+ let tableIndex = 0;
23790
+ for (const f of sectionFiles) {
23791
+ const doc = parser.parseFromString(await f.async("text"), "text/xml");
23792
+ for (const tbl of elemsByLocal(doc, "tbl")) {
23793
+ if (!isTopLevelTable(tbl)) continue;
23794
+ tables.push(parseTable3(tbl, tableIndex++, borderFills, charPrs));
23795
+ }
23796
+ }
23797
+ return { schema_version: "0.2.0", tables };
23798
+ }
23799
+
23800
+ // src/roundtrip/patcher.ts
23801
+ import JSZip10 from "jszip";
23315
23802
 
23316
23803
  // src/roundtrip/table-rows.ts
23317
23804
  var ROW_OBJECT_RE = /<(?:[A-Za-z0-9_]+:)?(?:tbl|pic|equation|ole|container|shape|drawingObject|drawText|video|chart|fieldBegin|fieldEnd|ctrl)\b/;
@@ -23949,7 +24436,7 @@ async function patchHwpx(original, editedMarkdown, options) {
23949
24436
  }
23950
24437
  let zip;
23951
24438
  try {
23952
- zip = await JSZip9.loadAsync(original);
24439
+ zip = await JSZip10.loadAsync(original);
23953
24440
  } catch {
23954
24441
  return { success: false, applied: 0, skipped, error: "ZIP \uB85C\uB4DC \uC2E4\uD328" };
23955
24442
  }
@@ -24040,16 +24527,16 @@ function buildOrigUnits(blocks) {
24040
24527
  for (let i = 0; i < blocks.length; i++) {
24041
24528
  const block = blocks[i];
24042
24529
  let consume = 1;
24043
- let chunk;
24530
+ let chunk2;
24044
24531
  if (block.type === "paragraph" && block.text && /^\[별표\s*\d+/.test(sanitizeText(block.text))) {
24045
24532
  const next = blocks[i + 1];
24046
24533
  if (next?.type === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
24047
- chunk = blocksToMarkdown(blocks.slice(i, i + consume));
24534
+ chunk2 = blocksToMarkdown(blocks.slice(i, i + consume));
24048
24535
  } else {
24049
- chunk = blocksToMarkdown([block]);
24536
+ chunk2 = blocksToMarkdown([block]);
24050
24537
  }
24051
- if (chunk) {
24052
- const subUnits = splitMarkdownUnits(chunk);
24538
+ if (chunk2) {
24539
+ const subUnits = splitMarkdownUnits(chunk2);
24053
24540
  const isFragment = consume === 2 || (block.type === "paragraph" || block.type === "heading") && subUnits.length > 1;
24054
24541
  for (let s = 0; s < subUnits.length; s++) {
24055
24542
  const u = { ...subUnits[s], blockIdx: i, fragment: isFragment || void 0 };
@@ -24883,19 +25370,19 @@ function resolveTableMappings(blocks, scanTables) {
24883
25370
  if (scanTables[k].rows === table.rows && scanTables[k].cols === table.cols) cands.push(k);
24884
25371
  }
24885
25372
  if (cands.length === 0) continue;
24886
- let pick = cands[0];
25373
+ let pick2 = cands[0];
24887
25374
  if (cands.length > 1) {
24888
25375
  let best = tableContentScore(table, scanTables[cands[0]]);
24889
25376
  for (let ci = 1; ci < cands.length; ci++) {
24890
25377
  const sc = tableContentScore(table, scanTables[cands[ci]]);
24891
25378
  if (sc > best) {
24892
25379
  best = sc;
24893
- pick = cands[ci];
25380
+ pick2 = cands[ci];
24894
25381
  }
24895
25382
  }
24896
25383
  }
24897
- result.set(i, scanTables[pick]);
24898
- si = pick + 1;
25384
+ result.set(i, scanTables[pick2]);
25385
+ si = pick2 + 1;
24899
25386
  }
24900
25387
  return result;
24901
25388
  }
@@ -25371,7 +25858,7 @@ function stageParaPatch(scan, para, newPlain, skip) {
25371
25858
  }
25372
25859
 
25373
25860
  // src/validate.ts
25374
- import JSZip10 from "jszip";
25861
+ import JSZip11 from "jszip";
25375
25862
  import { DOMParser as DOMParser5 } from "@xmldom/xmldom";
25376
25863
  var REQUIRED_FILES = [
25377
25864
  "mimetype",
@@ -25389,7 +25876,7 @@ async function validateHwpx(buffer) {
25389
25876
  const issues = [];
25390
25877
  let zip;
25391
25878
  try {
25392
- zip = await JSZip10.loadAsync(buffer);
25879
+ zip = await JSZip11.loadAsync(buffer);
25393
25880
  } catch (err) {
25394
25881
  return {
25395
25882
  ok: false,
@@ -25457,10 +25944,10 @@ async function validateHwpx(buffer) {
25457
25944
  }
25458
25945
 
25459
25946
  // src/roundtrip/session.ts
25460
- import JSZip11 from "jszip";
25947
+ import JSZip12 from "jszip";
25461
25948
  async function buildState(bytes) {
25462
25949
  const parsed = await parseHwpxDocument(u8ToArrayBuffer2(bytes));
25463
- const zip = await JSZip11.loadAsync(bytes);
25950
+ const zip = await JSZip12.loadAsync(bytes);
25464
25951
  const sectionPaths = await resolveSectionEntryNames(zip);
25465
25952
  if (sectionPaths.length === 0) {
25466
25953
  throw new Error("HWPX \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
@@ -25955,7 +26442,7 @@ async function blocksToPdf(blocks, options) {
25955
26442
  }
25956
26443
 
25957
26444
  // src/render/svg-render.ts
25958
- import JSZip12 from "jszip";
26445
+ import JSZip13 from "jszip";
25959
26446
 
25960
26447
  // src/render/layout.ts
25961
26448
  function toInt32(v, fallback = 0) {
@@ -26044,7 +26531,7 @@ function elements(el) {
26044
26531
  for (let i = 0; i < kids2.length; i++) if (kids2[i].nodeType === 1) out.push(kids2[i]);
26045
26532
  return out;
26046
26533
  }
26047
- function num(el, attr, fallback = 0) {
26534
+ function num2(el, attr, fallback = 0) {
26048
26535
  return el ? toInt32(el.getAttribute(attr) ?? void 0, fallback) : fallback;
26049
26536
  }
26050
26537
  function shiftParaVert(p, delta) {
@@ -26052,7 +26539,7 @@ function shiftParaVert(p, delta) {
26052
26539
  if (ln(lsa) !== "linesegarray") continue;
26053
26540
  for (const seg of elements(lsa)) {
26054
26541
  if (ln(seg) !== "lineseg") continue;
26055
- seg.setAttribute("vertpos", String(num(seg, "vertpos") + delta));
26542
+ seg.setAttribute("vertpos", String(num2(seg, "vertpos") + delta));
26056
26543
  }
26057
26544
  }
26058
26545
  }
@@ -26142,9 +26629,9 @@ function reflowTablesIn(p, doc, styles, mode, counter) {
26142
26629
  if (ln(tc) !== "tc") continue;
26143
26630
  const csz = findChildByLocalName(tc, "cellSz");
26144
26631
  const cm = findChildByLocalName(tc, "cellMargin");
26145
- const cellW = num(csz, "width");
26146
- const mL = cm ? num(cm, "left", 141) : 141;
26147
- const mR = cm ? num(cm, "right", 141) : 141;
26632
+ const cellW = num2(csz, "width");
26633
+ const mL = cm ? num2(cm, "left", 141) : 141;
26634
+ const mR = cm ? num2(cm, "right", 141) : 141;
26148
26635
  const areaW = Math.max(500, cellW - mL - mR);
26149
26636
  const sub = findChildByLocalName(tc, "subList");
26150
26637
  if (sub) reflowBlockFlow(sub, doc, styles, areaW, mode, counter, 0);
@@ -26195,7 +26682,7 @@ function elements2(el) {
26195
26682
  }
26196
26683
  return out;
26197
26684
  }
26198
- function num2(el, attr, fallback = 0) {
26685
+ function num3(el, attr, fallback = 0) {
26199
26686
  return el ? toInt32(el.getAttribute(attr) ?? void 0, fallback) : fallback;
26200
26687
  }
26201
26688
  function findFirst(el, name, depth = 0) {
@@ -26263,8 +26750,8 @@ function buildPara(p) {
26263
26750
  } else if (OBJ_TAGS.has(cn)) {
26264
26751
  const sz = findChildByLocalName(ch, "sz");
26265
26752
  const pos = findChildByLocalName(ch, "pos");
26266
- const w = num2(sz, "width") || num2(findChildByLocalName(ch, "curSz"), "width") || num2(findChildByLocalName(ch, "orgSz"), "width");
26267
- const h = num2(sz, "height") || num2(findChildByLocalName(ch, "curSz"), "height") || num2(findChildByLocalName(ch, "orgSz"), "height");
26753
+ const w = num3(sz, "width") || num3(findChildByLocalName(ch, "curSz"), "width") || num3(findChildByLocalName(ch, "orgSz"), "width");
26754
+ const h = num3(sz, "height") || num3(findChildByLocalName(ch, "curSz"), "height") || num3(findChildByLocalName(ch, "orgSz"), "height");
26268
26755
  objs.push({
26269
26756
  el: ch,
26270
26757
  tag: cn,
@@ -26280,12 +26767,12 @@ function buildPara(p) {
26280
26767
  }
26281
26768
  } else if (tag === "linesegarray") {
26282
26769
  segs = elements2(runEl).filter((s) => ln2(s) === "lineseg").map((s) => ({
26283
- textpos: num2(s, "textpos"),
26284
- vertpos: num2(s, "vertpos"),
26285
- horzpos: num2(s, "horzpos"),
26286
- horzsize: num2(s, "horzsize"),
26287
- textheight: num2(s, "textheight", 1e3),
26288
- baseline: num2(s, "baseline", 850)
26770
+ textpos: num3(s, "textpos"),
26771
+ vertpos: num3(s, "vertpos"),
26772
+ horzpos: num3(s, "horzpos"),
26773
+ horzsize: num3(s, "horzsize"),
26774
+ textheight: num3(s, "textheight", 1e3),
26775
+ baseline: num3(s, "baseline", 850)
26289
26776
  }));
26290
26777
  }
26291
26778
  }
@@ -26455,11 +26942,11 @@ function anchorObject(o, ox, oy, baseV, areaW, ctx) {
26455
26942
  const { PW, PH, ML, MT, BODY_W, BODY_H } = ctx.geom;
26456
26943
  const pos = findChildByLocalName(o.el, "pos");
26457
26944
  const om = findChildByLocalName(o.el, "outMargin");
26458
- const omT = num2(om, "top"), omB = num2(om, "bottom");
26945
+ const omT = num3(om, "top"), omB = num3(om, "bottom");
26459
26946
  const w = o.width, h = o.height;
26460
26947
  if (!pos) return { x: ox, y: oy + baseV };
26461
- const vo = num2(pos, "vertOffset");
26462
- const ho = num2(pos, "horzOffset");
26948
+ const vo = num3(pos, "vertOffset");
26949
+ const ho = num3(pos, "horzOffset");
26463
26950
  const vrel = pos.getAttribute("vertRelTo") ?? "PARA";
26464
26951
  const hrel = pos.getAttribute("horzRelTo") ?? "PARA";
26465
26952
  const va = pos.getAttribute("vertAlign") ?? "TOP";
@@ -26496,8 +26983,8 @@ function drawObject(o, x, y, baseV, areaW, ctx, depth) {
26496
26983
  if (!OBJ_TAGS.has(tag)) continue;
26497
26984
  const sz = findChildByLocalName(ch, "sz");
26498
26985
  const off = findChildByLocalName(ch, "offset");
26499
- const sub = { el: ch, tag, index: 0, inline: true, width: num2(sz, "width"), height: num2(sz, "height") };
26500
- drawObject(sub, x + num2(off, "x"), y + num2(off, "y"), baseV, areaW, ctx, depth + 1);
26986
+ const sub = { el: ch, tag, index: 0, inline: true, width: num3(sz, "width"), height: num3(sz, "height") };
26987
+ drawObject(sub, x + num3(off, "x"), y + num3(off, "y"), baseV, areaW, ctx, depth + 1);
26501
26988
  }
26502
26989
  } else if (o.tag === "equation") {
26503
26990
  warnOnce(ctx, "equation", "\uC218\uC2DD \uAC1C\uCCB4\uB294 \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5");
@@ -26515,16 +27002,16 @@ function drawShape(o, x, y, ctx, depth) {
26515
27002
  const el = o.el;
26516
27003
  const orgSz = findChildByLocalName(el, "orgSz");
26517
27004
  const curSz = findChildByLocalName(el, "curSz");
26518
- const ow = num2(orgSz, "width"), oh = num2(orgSz, "height");
26519
- const w = num2(curSz, "width") || ow || o.width;
26520
- const h = num2(curSz, "height") || oh || o.height;
27005
+ const ow = num3(orgSz, "width"), oh = num3(orgSz, "height");
27006
+ const w = num3(curSz, "width") || ow || o.width;
27007
+ const h = num3(curSz, "height") || oh || o.height;
26521
27008
  const sx = ow > 0 ? w / ow : 1;
26522
27009
  const sy = oh > 0 ? h / oh : 1;
26523
27010
  const lineShape = findChildByLocalName(el, "lineShape");
26524
27011
  const lstyle = lineShape?.getAttribute("style") ?? "SOLID";
26525
27012
  const strokeCol = lineShape?.getAttribute("color") || "#000000";
26526
27013
  const hasStroke = lstyle !== "NONE";
26527
- const strokeW = hasStroke ? shapeStrokePt(lineShape ? num2(lineShape, "width") : 33) : 0;
27014
+ const strokeW = hasStroke ? shapeStrokePt(lineShape ? num3(lineShape, "width") : 33) : 0;
26528
27015
  const dash = /DASH|DOT/.test(lstyle) ? ` stroke-dasharray="${lstyle.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
26529
27016
  const strokeAttr = hasStroke ? ` stroke="${escapeXml3(strokeCol)}" stroke-width="${strokeW.toFixed(2)}"${dash}` : "";
26530
27017
  const fillBrush = findChildByLocalName(el, "fillBrush");
@@ -26538,12 +27025,12 @@ function drawShape(o, x, y, ctx, depth) {
26538
27025
  emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}"${fillAttr}${strokeAttr}/>`);
26539
27026
  } else if (o.tag === "line") {
26540
27027
  const s = findChildByLocalName(el, "startPt"), e = findChildByLocalName(el, "endPt");
26541
- const x1 = x + num2(s, "x") * sx, y1 = y + num2(s, "y") * sy;
26542
- const x2 = x + num2(e, "x") * sx, y2 = y + num2(e, "y") * sy;
27028
+ const x1 = x + num3(s, "x") * sx, y1 = y + num3(s, "y") * sy;
27029
+ const x2 = x + num3(e, "x") * sx, y2 = y + num3(e, "y") * sy;
26543
27030
  emit(ctx, `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml3(strokeCol)}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}/>`);
26544
27031
  } else if (o.tag === "polygon" || o.tag === "curv") {
26545
27032
  const pts = [];
26546
- for (const c of elements2(el)) if (ln2(c) === "pt") pts.push(`${pt(x + num2(c, "x") * sx)},${pt(y + num2(c, "y") * sy)}`);
27033
+ for (const c of elements2(el)) if (ln2(c) === "pt") pts.push(`${pt(x + num3(c, "x") * sx)},${pt(y + num3(c, "y") * sy)}`);
26547
27034
  if (pts.length >= 2) emit(ctx, `<polygon points="${pts.join(" ")}"${fillAttr}${strokeAttr}/>`);
26548
27035
  } else if (o.tag === "arc") {
26549
27036
  emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}" fill="none"${strokeAttr || ` stroke="${escapeXml3(strokeCol)}" stroke-width="0.3"`}/>`);
@@ -26571,9 +27058,9 @@ function cellContentExtent(cell) {
26571
27058
  const pos = findChildByLocalName(o.el, "pos");
26572
27059
  if ((pos?.getAttribute("vertRelTo") ?? "PARA") !== "PARA") continue;
26573
27060
  const om = findChildByLocalName(o.el, "outMargin");
26574
- const pushed = baseV - (num2(om, "top") + o.height + num2(om, "bottom"));
27061
+ const pushed = baseV - (num3(om, "top") + o.height + num3(om, "bottom"));
26575
27062
  const anchor = pushed >= -100 ? pushed : baseV;
26576
- ext = Math.max(ext, anchor + num2(om, "top") + num2(pos, "vertOffset") + o.height);
27063
+ ext = Math.max(ext, anchor + num3(om, "top") + num3(pos, "vertOffset") + o.height);
26577
27064
  }
26578
27065
  }
26579
27066
  return ext;
@@ -26584,8 +27071,8 @@ function edgeLine(x1, y1, x2, y2, e) {
26584
27071
  }
26585
27072
  function collectCells(tbl) {
26586
27073
  const inMargin = findChildByLocalName(tbl, "inMargin");
26587
- const defL = num2(inMargin, "left", 141), defR = num2(inMargin, "right", 141);
26588
- const defT = num2(inMargin, "top", 141), defB = num2(inMargin, "bottom", 141);
27074
+ const defL = num3(inMargin, "left", 141), defR = num3(inMargin, "right", 141);
27075
+ const defT = num3(inMargin, "top", 141), defB = num3(inMargin, "bottom", 141);
26589
27076
  const cells = [];
26590
27077
  for (const tr of elements2(tbl)) {
26591
27078
  if (ln2(tr) !== "tr") continue;
@@ -26598,18 +27085,18 @@ function collectCells(tbl) {
26598
27085
  if (!addr || !csz) continue;
26599
27086
  cells.push({
26600
27087
  el: tc,
26601
- ca: num2(addr, "colAddr"),
26602
- ra: num2(addr, "rowAddr"),
26603
- cs: Math.max(1, num2(span, "colSpan", 1)),
26604
- rs: Math.max(1, num2(span, "rowSpan", 1)),
26605
- w: num2(csz, "width"),
26606
- h: num2(csz, "height"),
27088
+ ca: num3(addr, "colAddr"),
27089
+ ra: num3(addr, "rowAddr"),
27090
+ cs: Math.max(1, num3(span, "colSpan", 1)),
27091
+ rs: Math.max(1, num3(span, "rowSpan", 1)),
27092
+ w: num3(csz, "width"),
27093
+ h: num3(csz, "height"),
26607
27094
  bfId: tc.getAttribute("borderFillIDRef"),
26608
27095
  sub: findChildByLocalName(tc, "subList"),
26609
- marginL: cm ? num2(cm, "left", defL) : defL,
26610
- marginR: cm ? num2(cm, "right", defR) : defR,
26611
- marginT: cm ? num2(cm, "top", defT) : defT,
26612
- marginB: cm ? num2(cm, "bottom", defB) : defB
27096
+ marginL: cm ? num3(cm, "left", defL) : defL,
27097
+ marginR: cm ? num3(cm, "right", defR) : defR,
27098
+ marginT: cm ? num3(cm, "top", defT) : defT,
27099
+ marginB: cm ? num3(cm, "bottom", defB) : defB
26613
27100
  });
26614
27101
  }
26615
27102
  }
@@ -26639,7 +27126,7 @@ function drawTable(tbl, tx, ty, ctx, depth) {
26639
27126
  const nCols = Math.max(...cells.map((c) => c.ca + c.cs));
26640
27127
  const nRows = Math.max(...cells.map((c) => c.ra + c.rs));
26641
27128
  const colCons = cells.map((c) => ({ a: c.ca, b: c.ca + c.cs, size: c.w }));
26642
- const colX = solveBoundaries(colCons, nCols, num2(tblSz, "width") || void 0);
27129
+ const colX = solveBoundaries(colCons, nCols, num3(tblSz, "width") || void 0);
26643
27130
  const rowH = solveRowHeights(
26644
27131
  cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c) : void 0 })),
26645
27132
  nRows
@@ -26691,7 +27178,7 @@ function imageSymbol(loaded, ctx) {
26691
27178
  }
26692
27179
  function drawPic(pic, x, y, ctx) {
26693
27180
  const sz = findChildByLocalName(pic, "sz");
26694
- const w = num2(sz, "width", 5669), h = num2(sz, "height", 5669);
27181
+ const w = num3(sz, "width", 5669), h = num3(sz, "height", 5669);
26695
27182
  const img = findFirst(pic, "img");
26696
27183
  const ref = img?.getAttribute("binaryItemIDRef");
26697
27184
  const loaded = ref != null ? ctx.images.get(ref) : void 0;
@@ -26704,11 +27191,11 @@ function drawPic(pic, x, y, ctx) {
26704
27191
  const clip = findChildByLocalName(pic, "imgClip");
26705
27192
  const imgDim = findChildByLocalName(pic, "imgDim");
26706
27193
  const orgSz = findChildByLocalName(pic, "orgSz");
26707
- const dimW = num2(imgDim, "dimwidth"), dimH = num2(imgDim, "dimheight");
26708
- const refW = dimW > 0 ? dimW : num2(orgSz, "width");
26709
- const refH = dimH > 0 ? dimH : num2(orgSz, "height");
26710
- const cl = num2(clip, "left"), ct = num2(clip, "top");
26711
- const cr = num2(clip, "right", refW), cb = num2(clip, "bottom", refH);
27194
+ const dimW = num3(imgDim, "dimwidth"), dimH = num3(imgDim, "dimheight");
27195
+ const refW = dimW > 0 ? dimW : num3(orgSz, "width");
27196
+ const refH = dimH > 0 ? dimH : num3(orgSz, "height");
27197
+ const cl = num3(clip, "left"), ct = num3(clip, "top");
27198
+ const cr = num3(clip, "right", refW), cb = num3(clip, "bottom", refH);
26712
27199
  const cropped = refW > 0 && refH > 0 && clip != null && (cl > 0 || ct > 0 || cr < refW || cb < refH) && cr > cl && cb > ct;
26713
27200
  const symId = imageSymbol(loaded, ctx);
26714
27201
  if (cropped) {
@@ -26731,23 +27218,23 @@ function sniffMime(name, bytes) {
26731
27218
  function readSectionGeom(root) {
26732
27219
  const pagePr = findFirst(root, "pagePr");
26733
27220
  const margin = pagePr ? findChildByLocalName(pagePr, "margin") : null;
26734
- let PW = num2(pagePr, "width", 59528), PH = num2(pagePr, "height", 84188);
27221
+ let PW = num3(pagePr, "width", 59528), PH = num3(pagePr, "height", 84188);
26735
27222
  if (pagePr?.getAttribute("landscape") === "NARROWLY" && PW < PH) {
26736
27223
  const t = PW;
26737
27224
  PW = PH;
26738
27225
  PH = t;
26739
27226
  }
26740
- const ML = num2(margin, "left", 8504);
26741
- const MT = num2(margin, "top", 5668) + num2(margin, "header", 0);
26742
- const BODY_H = PH - MT - num2(margin, "bottom", 4252) - num2(margin, "footer", 0);
26743
- const BODY_W = PW - ML - num2(margin, "right", 8504);
27227
+ const ML = num3(margin, "left", 8504);
27228
+ const MT = num3(margin, "top", 5668) + num3(margin, "header", 0);
27229
+ const BODY_H = PH - MT - num3(margin, "bottom", 4252) - num3(margin, "footer", 0);
27230
+ const BODY_W = PW - ML - num3(margin, "right", 8504);
26744
27231
  return { PW, PH, ML, MT, BODY_W, BODY_H };
26745
27232
  }
26746
27233
  function renderSectionToPages(root, geom, ctxBase, hasCache, reflowMode) {
26747
27234
  const { PW, PH, ML, MT, BODY_W, BODY_H } = geom;
26748
27235
  if (!hasCache) reflowSection(root, ctxBase.styles, { BODY_W, BODY_H }, reflowMode);
26749
27236
  const colPr = findFirst(root, "colPr");
26750
- const multiCol = num2(colPr, "colCount", 1) > 1;
27237
+ const multiCol = num3(colPr, "colCount", 1) > 1;
26751
27238
  const paraSegPages = /* @__PURE__ */ new Map();
26752
27239
  let nPages = 1;
26753
27240
  let maxTopV = 0;
@@ -26762,13 +27249,13 @@ function renderSectionToPages(root, geom, ctxBase, hasCache, reflowMode) {
26762
27249
  const pagesOf = [];
26763
27250
  let paraFirst = true;
26764
27251
  for (const s of segEls) {
26765
- const v = num2(s, "vertpos");
26766
- const h = num2(s, "horzpos");
27252
+ const v = num3(s, "vertpos");
27253
+ const h = num3(s, "horzpos");
26767
27254
  const brk = v < prevV ? !multiCol || h <= prevH : paraFirst && v === prevV && h <= prevH;
26768
27255
  if (brk) cur++;
26769
27256
  paraFirst = false;
26770
27257
  pagesOf.push(cur);
26771
- maxTopV = Math.max(maxTopV, v + num2(s, "textheight", 1e3));
27258
+ maxTopV = Math.max(maxTopV, v + num3(s, "textheight", 1e3));
26772
27259
  prevV = v;
26773
27260
  prevH = h;
26774
27261
  }
@@ -26795,7 +27282,7 @@ async function renderHwpxToSvg(input, options) {
26795
27282
  precheckZipSize(ab, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
26796
27283
  let zip;
26797
27284
  try {
26798
- zip = await JSZip12.loadAsync(input);
27285
+ zip = await JSZip13.loadAsync(input);
26799
27286
  } catch {
26800
27287
  throw new KordocError("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
26801
27288
  }
@@ -26998,7 +27485,7 @@ async function parseHwp(buffer, options) {
26998
27485
  async function parsePdf(buffer, options) {
26999
27486
  let parsePdfDocument;
27000
27487
  try {
27001
- const mod = await import("./parser-LHBXIKXX.js");
27488
+ const mod = await import("./parser-JBBA5A5E.js");
27002
27489
  parsePdfDocument = mod.parsePdfDocument;
27003
27490
  } catch {
27004
27491
  return {
@@ -27113,6 +27600,7 @@ export {
27113
27600
  fillWithUniqueGuard,
27114
27601
  fitRatioForFewerLines,
27115
27602
  formatFillValue,
27603
+ hwpxToProfile,
27116
27604
  inferFieldType,
27117
27605
  isHwpxFile,
27118
27606
  isLabelCell,