@clazic/kordoc 2.1.5 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -4
- package/dist/chunk-JJMA5HGQ.js +9617 -0
- package/dist/chunk-JJMA5HGQ.js.map +1 -0
- package/dist/{chunk-LP7HUOZB.js → chunk-XWET7ONC.js} +2 -2
- package/dist/chunk-ZWE3DS7E.js +39 -0
- package/dist/cli.js +114 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +3134 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -4
- package/dist/index.d.ts +36 -4
- package/dist/index.js +3158 -148
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +100 -7
- package/dist/mcp.js.map +1 -1
- package/dist/{page-range-737B4EZW.js → page-range-ALIRXAL5.js} +2 -1
- package/dist/provider-XVKP5OGI.js +167 -0
- package/dist/provider-XVKP5OGI.js.map +1 -0
- package/dist/resolve-Y3KMGD3R.js +187 -0
- package/dist/resolve-Y3KMGD3R.js.map +1 -0
- package/dist/tesseract-provider-MZ37ZKQW.js +31 -0
- package/dist/tesseract-provider-MZ37ZKQW.js.map +1 -0
- package/dist/{utils-EHWBYPP7.js → utils-4NP2VUFW.js} +3 -2
- package/dist/utils-4NP2VUFW.js.map +1 -0
- package/dist/{watch-TNLNQF2I.js → watch-4VVWG2WC.js} +4 -3
- package/dist/{watch-TNLNQF2I.js.map → watch-4VVWG2WC.js.map} +1 -1
- package/package.json +4 -2
- package/dist/chunk-A7G6BYLH.js +0 -5494
- package/dist/chunk-A7G6BYLH.js.map +0 -1
- package/dist/provider-A4FHJSID.js +0 -38
- package/dist/provider-A4FHJSID.js.map +0 -1
- /package/dist/{chunk-LP7HUOZB.js.map → chunk-XWET7ONC.js.map} +0 -0
- /package/dist/{page-range-737B4EZW.js.map → chunk-ZWE3DS7E.js.map} +0 -0
- /package/dist/{utils-EHWBYPP7.js.map → page-range-ALIRXAL5.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,9 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
8
8
|
var __esm = (fn, res) => function __init() {
|
|
9
9
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
10
|
};
|
|
11
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
12
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
|
+
};
|
|
11
14
|
var __export = (target, all) => {
|
|
12
15
|
for (var name in all)
|
|
13
16
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -68,23 +71,2280 @@ var init_page_range = __esm({
|
|
|
68
71
|
}
|
|
69
72
|
});
|
|
70
73
|
|
|
74
|
+
// node_modules/cfb/cfb.js
|
|
75
|
+
var require_cfb = __commonJS({
|
|
76
|
+
"node_modules/cfb/cfb.js"(exports2, module2) {
|
|
77
|
+
"use strict";
|
|
78
|
+
var Base64_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
79
|
+
function Base64_encode(input) {
|
|
80
|
+
var o = "";
|
|
81
|
+
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
|
82
|
+
for (var i = 0; i < input.length; ) {
|
|
83
|
+
c1 = input.charCodeAt(i++);
|
|
84
|
+
e1 = c1 >> 2;
|
|
85
|
+
c2 = input.charCodeAt(i++);
|
|
86
|
+
e2 = (c1 & 3) << 4 | c2 >> 4;
|
|
87
|
+
c3 = input.charCodeAt(i++);
|
|
88
|
+
e3 = (c2 & 15) << 2 | c3 >> 6;
|
|
89
|
+
e4 = c3 & 63;
|
|
90
|
+
if (isNaN(c2)) e3 = e4 = 64;
|
|
91
|
+
else if (isNaN(c3)) e4 = 64;
|
|
92
|
+
o += Base64_map.charAt(e1) + Base64_map.charAt(e2) + Base64_map.charAt(e3) + Base64_map.charAt(e4);
|
|
93
|
+
}
|
|
94
|
+
return o;
|
|
95
|
+
}
|
|
96
|
+
function Base64_decode(input) {
|
|
97
|
+
var o = "";
|
|
98
|
+
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
|
99
|
+
input = input.replace(/[^\w\+\/\=]/g, "");
|
|
100
|
+
for (var i = 0; i < input.length; ) {
|
|
101
|
+
e1 = Base64_map.indexOf(input.charAt(i++));
|
|
102
|
+
e2 = Base64_map.indexOf(input.charAt(i++));
|
|
103
|
+
c1 = e1 << 2 | e2 >> 4;
|
|
104
|
+
o += String.fromCharCode(c1);
|
|
105
|
+
e3 = Base64_map.indexOf(input.charAt(i++));
|
|
106
|
+
c2 = (e2 & 15) << 4 | e3 >> 2;
|
|
107
|
+
if (e3 !== 64) o += String.fromCharCode(c2);
|
|
108
|
+
e4 = Base64_map.indexOf(input.charAt(i++));
|
|
109
|
+
c3 = (e3 & 3) << 6 | e4;
|
|
110
|
+
if (e4 !== 64) o += String.fromCharCode(c3);
|
|
111
|
+
}
|
|
112
|
+
return o;
|
|
113
|
+
}
|
|
114
|
+
var has_buf = (function() {
|
|
115
|
+
return typeof Buffer !== "undefined" && typeof process !== "undefined" && typeof process.versions !== "undefined" && !!process.versions.node;
|
|
116
|
+
})();
|
|
117
|
+
var Buffer_from = (function() {
|
|
118
|
+
if (typeof Buffer !== "undefined") {
|
|
119
|
+
var nbfs = !Buffer.from;
|
|
120
|
+
if (!nbfs) try {
|
|
121
|
+
Buffer.from("foo", "utf8");
|
|
122
|
+
} catch (e) {
|
|
123
|
+
nbfs = true;
|
|
124
|
+
}
|
|
125
|
+
return nbfs ? function(buf, enc) {
|
|
126
|
+
return enc ? new Buffer(buf, enc) : new Buffer(buf);
|
|
127
|
+
} : Buffer.from.bind(Buffer);
|
|
128
|
+
}
|
|
129
|
+
return function() {
|
|
130
|
+
};
|
|
131
|
+
})();
|
|
132
|
+
function new_raw_buf(len) {
|
|
133
|
+
if (has_buf) {
|
|
134
|
+
if (Buffer.alloc) return Buffer.alloc(len);
|
|
135
|
+
var b = new Buffer(len);
|
|
136
|
+
b.fill(0);
|
|
137
|
+
return b;
|
|
138
|
+
}
|
|
139
|
+
return typeof Uint8Array != "undefined" ? new Uint8Array(len) : new Array(len);
|
|
140
|
+
}
|
|
141
|
+
function new_unsafe_buf(len) {
|
|
142
|
+
if (has_buf) return Buffer.allocUnsafe ? Buffer.allocUnsafe(len) : new Buffer(len);
|
|
143
|
+
return typeof Uint8Array != "undefined" ? new Uint8Array(len) : new Array(len);
|
|
144
|
+
}
|
|
145
|
+
var s2a = function s2a2(s) {
|
|
146
|
+
if (has_buf) return Buffer_from(s, "binary");
|
|
147
|
+
return s.split("").map(function(x) {
|
|
148
|
+
return x.charCodeAt(0) & 255;
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
var chr0 = /\u0000/g;
|
|
152
|
+
var chr1 = /[\u0001-\u0006]/g;
|
|
153
|
+
var __toBuffer = function(bufs) {
|
|
154
|
+
var x = [];
|
|
155
|
+
for (var i = 0; i < bufs[0].length; ++i) {
|
|
156
|
+
x.push.apply(x, bufs[0][i]);
|
|
157
|
+
}
|
|
158
|
+
return x;
|
|
159
|
+
};
|
|
160
|
+
var ___toBuffer = __toBuffer;
|
|
161
|
+
var __utf16le = function(b, s, e) {
|
|
162
|
+
var ss = [];
|
|
163
|
+
for (var i = s; i < e; i += 2) ss.push(String.fromCharCode(__readUInt16LE(b, i)));
|
|
164
|
+
return ss.join("").replace(chr0, "");
|
|
165
|
+
};
|
|
166
|
+
var ___utf16le = __utf16le;
|
|
167
|
+
var __hexlify = function(b, s, l) {
|
|
168
|
+
var ss = [];
|
|
169
|
+
for (var i = s; i < s + l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2));
|
|
170
|
+
return ss.join("");
|
|
171
|
+
};
|
|
172
|
+
var ___hexlify = __hexlify;
|
|
173
|
+
var __bconcat = function(bufs) {
|
|
174
|
+
if (Array.isArray(bufs[0])) return [].concat.apply([], bufs);
|
|
175
|
+
var maxlen = 0, i = 0;
|
|
176
|
+
for (i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;
|
|
177
|
+
var o = new Uint8Array(maxlen);
|
|
178
|
+
for (i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) o.set(bufs[i], maxlen);
|
|
179
|
+
return o;
|
|
180
|
+
};
|
|
181
|
+
var bconcat = __bconcat;
|
|
182
|
+
if (has_buf) {
|
|
183
|
+
__utf16le = function(b, s, e) {
|
|
184
|
+
if (!Buffer.isBuffer(b)) return ___utf16le(b, s, e);
|
|
185
|
+
return b.toString("utf16le", s, e).replace(chr0, "");
|
|
186
|
+
};
|
|
187
|
+
__hexlify = function(b, s, l) {
|
|
188
|
+
return Buffer.isBuffer(b) ? b.toString("hex", s, s + l) : ___hexlify(b, s, l);
|
|
189
|
+
};
|
|
190
|
+
__toBuffer = function(bufs) {
|
|
191
|
+
return bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0]) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);
|
|
192
|
+
};
|
|
193
|
+
s2a = function(s) {
|
|
194
|
+
return Buffer_from(s, "binary");
|
|
195
|
+
};
|
|
196
|
+
bconcat = function(bufs) {
|
|
197
|
+
return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : __bconcat(bufs);
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
var __readUInt8 = function(b, idx) {
|
|
201
|
+
return b[idx];
|
|
202
|
+
};
|
|
203
|
+
var __readUInt16LE = function(b, idx) {
|
|
204
|
+
return b[idx + 1] * (1 << 8) + b[idx];
|
|
205
|
+
};
|
|
206
|
+
var __readInt16LE = function(b, idx) {
|
|
207
|
+
var u = b[idx + 1] * (1 << 8) + b[idx];
|
|
208
|
+
return u < 32768 ? u : (65535 - u + 1) * -1;
|
|
209
|
+
};
|
|
210
|
+
var __readUInt32LE = function(b, idx) {
|
|
211
|
+
return b[idx + 3] * (1 << 24) + (b[idx + 2] << 16) + (b[idx + 1] << 8) + b[idx];
|
|
212
|
+
};
|
|
213
|
+
var __readInt32LE = function(b, idx) {
|
|
214
|
+
return (b[idx + 3] << 24) + (b[idx + 2] << 16) + (b[idx + 1] << 8) + b[idx];
|
|
215
|
+
};
|
|
216
|
+
function ReadShift(size, t) {
|
|
217
|
+
var oI, oS, type = 0;
|
|
218
|
+
switch (size) {
|
|
219
|
+
case 1:
|
|
220
|
+
oI = __readUInt8(this, this.l);
|
|
221
|
+
break;
|
|
222
|
+
case 2:
|
|
223
|
+
oI = (t !== "i" ? __readUInt16LE : __readInt16LE)(this, this.l);
|
|
224
|
+
break;
|
|
225
|
+
case 4:
|
|
226
|
+
oI = __readInt32LE(this, this.l);
|
|
227
|
+
break;
|
|
228
|
+
case 16:
|
|
229
|
+
type = 2;
|
|
230
|
+
oS = __hexlify(this, this.l, size);
|
|
231
|
+
}
|
|
232
|
+
this.l += size;
|
|
233
|
+
if (type === 0) return oI;
|
|
234
|
+
return oS;
|
|
235
|
+
}
|
|
236
|
+
var __writeUInt32LE = function(b, val, idx) {
|
|
237
|
+
b[idx] = val & 255;
|
|
238
|
+
b[idx + 1] = val >>> 8 & 255;
|
|
239
|
+
b[idx + 2] = val >>> 16 & 255;
|
|
240
|
+
b[idx + 3] = val >>> 24 & 255;
|
|
241
|
+
};
|
|
242
|
+
var __writeInt32LE = function(b, val, idx) {
|
|
243
|
+
b[idx] = val & 255;
|
|
244
|
+
b[idx + 1] = val >> 8 & 255;
|
|
245
|
+
b[idx + 2] = val >> 16 & 255;
|
|
246
|
+
b[idx + 3] = val >> 24 & 255;
|
|
247
|
+
};
|
|
248
|
+
function WriteShift(t, val, f) {
|
|
249
|
+
var size = 0, i = 0;
|
|
250
|
+
switch (f) {
|
|
251
|
+
case "hex":
|
|
252
|
+
for (; i < t; ++i) {
|
|
253
|
+
this[this.l++] = parseInt(val.slice(2 * i, 2 * i + 2), 16) || 0;
|
|
254
|
+
}
|
|
255
|
+
return this;
|
|
256
|
+
case "utf16le":
|
|
257
|
+
var end = this.l + t;
|
|
258
|
+
for (i = 0; i < Math.min(val.length, t); ++i) {
|
|
259
|
+
var cc = val.charCodeAt(i);
|
|
260
|
+
this[this.l++] = cc & 255;
|
|
261
|
+
this[this.l++] = cc >> 8;
|
|
262
|
+
}
|
|
263
|
+
while (this.l < end) this[this.l++] = 0;
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
switch (t) {
|
|
267
|
+
case 1:
|
|
268
|
+
size = 1;
|
|
269
|
+
this[this.l] = val & 255;
|
|
270
|
+
break;
|
|
271
|
+
case 2:
|
|
272
|
+
size = 2;
|
|
273
|
+
this[this.l] = val & 255;
|
|
274
|
+
val >>>= 8;
|
|
275
|
+
this[this.l + 1] = val & 255;
|
|
276
|
+
break;
|
|
277
|
+
case 4:
|
|
278
|
+
size = 4;
|
|
279
|
+
__writeUInt32LE(this, val, this.l);
|
|
280
|
+
break;
|
|
281
|
+
case -4:
|
|
282
|
+
size = 4;
|
|
283
|
+
__writeInt32LE(this, val, this.l);
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
this.l += size;
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
function CheckField(hexstr, fld) {
|
|
290
|
+
var m = __hexlify(this, this.l, hexstr.length >> 1);
|
|
291
|
+
if (m !== hexstr) throw new Error(fld + "Expected " + hexstr + " saw " + m);
|
|
292
|
+
this.l += hexstr.length >> 1;
|
|
293
|
+
}
|
|
294
|
+
function prep_blob(blob, pos) {
|
|
295
|
+
blob.l = pos;
|
|
296
|
+
blob.read_shift = ReadShift;
|
|
297
|
+
blob.chk = CheckField;
|
|
298
|
+
blob.write_shift = WriteShift;
|
|
299
|
+
}
|
|
300
|
+
function new_buf(sz) {
|
|
301
|
+
var o = new_raw_buf(sz);
|
|
302
|
+
prep_blob(o, 0);
|
|
303
|
+
return o;
|
|
304
|
+
}
|
|
305
|
+
var CRC32 = (function() {
|
|
306
|
+
var CRC322 = {};
|
|
307
|
+
CRC322.version = "1.2.1";
|
|
308
|
+
function signed_crc_table() {
|
|
309
|
+
var c = 0, table = new Array(256);
|
|
310
|
+
for (var n = 0; n != 256; ++n) {
|
|
311
|
+
c = n;
|
|
312
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
313
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
314
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
315
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
316
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
317
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
318
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
319
|
+
c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
|
|
320
|
+
table[n] = c;
|
|
321
|
+
}
|
|
322
|
+
return typeof Int32Array !== "undefined" ? new Int32Array(table) : table;
|
|
323
|
+
}
|
|
324
|
+
var T0 = signed_crc_table();
|
|
325
|
+
function slice_by_16_tables(T) {
|
|
326
|
+
var c = 0, v = 0, n = 0, table = typeof Int32Array !== "undefined" ? new Int32Array(4096) : new Array(4096);
|
|
327
|
+
for (n = 0; n != 256; ++n) table[n] = T[n];
|
|
328
|
+
for (n = 0; n != 256; ++n) {
|
|
329
|
+
v = T[n];
|
|
330
|
+
for (c = 256 + n; c < 4096; c += 256) v = table[c] = v >>> 8 ^ T[v & 255];
|
|
331
|
+
}
|
|
332
|
+
var out = [];
|
|
333
|
+
for (n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== "undefined" ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256);
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
336
|
+
var TT = slice_by_16_tables(T0);
|
|
337
|
+
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
|
|
338
|
+
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
|
|
339
|
+
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
|
|
340
|
+
function crc32_bstr(bstr, seed) {
|
|
341
|
+
var C = seed ^ -1;
|
|
342
|
+
for (var i = 0, L = bstr.length; i < L; ) C = C >>> 8 ^ T0[(C ^ bstr.charCodeAt(i++)) & 255];
|
|
343
|
+
return ~C;
|
|
344
|
+
}
|
|
345
|
+
function crc32_buf(B, seed) {
|
|
346
|
+
var C = seed ^ -1, L = B.length - 15, i = 0;
|
|
347
|
+
for (; i < L; ) C = Tf[B[i++] ^ C & 255] ^ Te[B[i++] ^ C >> 8 & 255] ^ Td[B[i++] ^ C >> 16 & 255] ^ Tc[B[i++] ^ C >>> 24] ^ Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]];
|
|
348
|
+
L += 15;
|
|
349
|
+
while (i < L) C = C >>> 8 ^ T0[(C ^ B[i++]) & 255];
|
|
350
|
+
return ~C;
|
|
351
|
+
}
|
|
352
|
+
function crc32_str(str, seed) {
|
|
353
|
+
var C = seed ^ -1;
|
|
354
|
+
for (var i = 0, L = str.length, c = 0, d = 0; i < L; ) {
|
|
355
|
+
c = str.charCodeAt(i++);
|
|
356
|
+
if (c < 128) {
|
|
357
|
+
C = C >>> 8 ^ T0[(C ^ c) & 255];
|
|
358
|
+
} else if (c < 2048) {
|
|
359
|
+
C = C >>> 8 ^ T0[(C ^ (192 | c >> 6 & 31)) & 255];
|
|
360
|
+
C = C >>> 8 ^ T0[(C ^ (128 | c & 63)) & 255];
|
|
361
|
+
} else if (c >= 55296 && c < 57344) {
|
|
362
|
+
c = (c & 1023) + 64;
|
|
363
|
+
d = str.charCodeAt(i++) & 1023;
|
|
364
|
+
C = C >>> 8 ^ T0[(C ^ (240 | c >> 8 & 7)) & 255];
|
|
365
|
+
C = C >>> 8 ^ T0[(C ^ (128 | c >> 2 & 63)) & 255];
|
|
366
|
+
C = C >>> 8 ^ T0[(C ^ (128 | d >> 6 & 15 | (c & 3) << 4)) & 255];
|
|
367
|
+
C = C >>> 8 ^ T0[(C ^ (128 | d & 63)) & 255];
|
|
368
|
+
} else {
|
|
369
|
+
C = C >>> 8 ^ T0[(C ^ (224 | c >> 12 & 15)) & 255];
|
|
370
|
+
C = C >>> 8 ^ T0[(C ^ (128 | c >> 6 & 63)) & 255];
|
|
371
|
+
C = C >>> 8 ^ T0[(C ^ (128 | c & 63)) & 255];
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return ~C;
|
|
375
|
+
}
|
|
376
|
+
CRC322.table = T0;
|
|
377
|
+
CRC322.bstr = crc32_bstr;
|
|
378
|
+
CRC322.buf = crc32_buf;
|
|
379
|
+
CRC322.str = crc32_str;
|
|
380
|
+
return CRC322;
|
|
381
|
+
})();
|
|
382
|
+
var CFB2 = (function _CFB() {
|
|
383
|
+
var exports3 = {};
|
|
384
|
+
exports3.version = "1.2.2";
|
|
385
|
+
function namecmp(l, r) {
|
|
386
|
+
var L = l.split("/"), R = r.split("/");
|
|
387
|
+
for (var i2 = 0, c = 0, Z = Math.min(L.length, R.length); i2 < Z; ++i2) {
|
|
388
|
+
if (c = L[i2].length - R[i2].length) return c;
|
|
389
|
+
if (L[i2] != R[i2]) return L[i2] < R[i2] ? -1 : 1;
|
|
390
|
+
}
|
|
391
|
+
return L.length - R.length;
|
|
392
|
+
}
|
|
393
|
+
function dirname(p) {
|
|
394
|
+
if (p.charAt(p.length - 1) == "/") return p.slice(0, -1).indexOf("/") === -1 ? p : dirname(p.slice(0, -1));
|
|
395
|
+
var c = p.lastIndexOf("/");
|
|
396
|
+
return c === -1 ? p : p.slice(0, c + 1);
|
|
397
|
+
}
|
|
398
|
+
function filename(p) {
|
|
399
|
+
if (p.charAt(p.length - 1) == "/") return filename(p.slice(0, -1));
|
|
400
|
+
var c = p.lastIndexOf("/");
|
|
401
|
+
return c === -1 ? p : p.slice(c + 1);
|
|
402
|
+
}
|
|
403
|
+
function write_dos_date(buf, date) {
|
|
404
|
+
if (typeof date === "string") date = new Date(date);
|
|
405
|
+
var hms = date.getHours();
|
|
406
|
+
hms = hms << 6 | date.getMinutes();
|
|
407
|
+
hms = hms << 5 | date.getSeconds() >>> 1;
|
|
408
|
+
buf.write_shift(2, hms);
|
|
409
|
+
var ymd = date.getFullYear() - 1980;
|
|
410
|
+
ymd = ymd << 4 | date.getMonth() + 1;
|
|
411
|
+
ymd = ymd << 5 | date.getDate();
|
|
412
|
+
buf.write_shift(2, ymd);
|
|
413
|
+
}
|
|
414
|
+
function parse_dos_date(buf) {
|
|
415
|
+
var hms = buf.read_shift(2) & 65535;
|
|
416
|
+
var ymd = buf.read_shift(2) & 65535;
|
|
417
|
+
var val = /* @__PURE__ */ new Date();
|
|
418
|
+
var d = ymd & 31;
|
|
419
|
+
ymd >>>= 5;
|
|
420
|
+
var m = ymd & 15;
|
|
421
|
+
ymd >>>= 4;
|
|
422
|
+
val.setMilliseconds(0);
|
|
423
|
+
val.setFullYear(ymd + 1980);
|
|
424
|
+
val.setMonth(m - 1);
|
|
425
|
+
val.setDate(d);
|
|
426
|
+
var S = hms & 31;
|
|
427
|
+
hms >>>= 5;
|
|
428
|
+
var M = hms & 63;
|
|
429
|
+
hms >>>= 6;
|
|
430
|
+
val.setHours(hms);
|
|
431
|
+
val.setMinutes(M);
|
|
432
|
+
val.setSeconds(S << 1);
|
|
433
|
+
return val;
|
|
434
|
+
}
|
|
435
|
+
function parse_extra_field(blob) {
|
|
436
|
+
prep_blob(blob, 0);
|
|
437
|
+
var o = {};
|
|
438
|
+
var flags = 0;
|
|
439
|
+
while (blob.l <= blob.length - 4) {
|
|
440
|
+
var type = blob.read_shift(2);
|
|
441
|
+
var sz = blob.read_shift(2), tgt = blob.l + sz;
|
|
442
|
+
var p = {};
|
|
443
|
+
switch (type) {
|
|
444
|
+
/* UNIX-style Timestamps */
|
|
445
|
+
case 21589:
|
|
446
|
+
{
|
|
447
|
+
flags = blob.read_shift(1);
|
|
448
|
+
if (flags & 1) p.mtime = blob.read_shift(4);
|
|
449
|
+
if (sz > 5) {
|
|
450
|
+
if (flags & 2) p.atime = blob.read_shift(4);
|
|
451
|
+
if (flags & 4) p.ctime = blob.read_shift(4);
|
|
452
|
+
}
|
|
453
|
+
if (p.mtime) p.mt = new Date(p.mtime * 1e3);
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
blob.l = tgt;
|
|
458
|
+
o[type] = p;
|
|
459
|
+
}
|
|
460
|
+
return o;
|
|
461
|
+
}
|
|
462
|
+
var fs;
|
|
463
|
+
function get_fs() {
|
|
464
|
+
return fs || (fs = require("fs"));
|
|
465
|
+
}
|
|
466
|
+
function parse3(file, options) {
|
|
467
|
+
if (file[0] == 80 && file[1] == 75) return parse_zip(file, options);
|
|
468
|
+
if ((file[0] | 32) == 109 && (file[1] | 32) == 105) return parse_mad(file, options);
|
|
469
|
+
if (file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
|
|
470
|
+
var mver = 3;
|
|
471
|
+
var ssz = 512;
|
|
472
|
+
var nmfs = 0;
|
|
473
|
+
var difat_sec_cnt = 0;
|
|
474
|
+
var dir_start = 0;
|
|
475
|
+
var minifat_start = 0;
|
|
476
|
+
var difat_start = 0;
|
|
477
|
+
var fat_addrs = [];
|
|
478
|
+
var blob = file.slice(0, 512);
|
|
479
|
+
prep_blob(blob, 0);
|
|
480
|
+
var mv = check_get_mver(blob);
|
|
481
|
+
mver = mv[0];
|
|
482
|
+
switch (mver) {
|
|
483
|
+
case 3:
|
|
484
|
+
ssz = 512;
|
|
485
|
+
break;
|
|
486
|
+
case 4:
|
|
487
|
+
ssz = 4096;
|
|
488
|
+
break;
|
|
489
|
+
case 0:
|
|
490
|
+
if (mv[1] == 0) return parse_zip(file, options);
|
|
491
|
+
/* falls through */
|
|
492
|
+
default:
|
|
493
|
+
throw new Error("Major Version: Expected 3 or 4 saw " + mver);
|
|
494
|
+
}
|
|
495
|
+
if (ssz !== 512) {
|
|
496
|
+
blob = file.slice(0, ssz);
|
|
497
|
+
prep_blob(
|
|
498
|
+
blob,
|
|
499
|
+
28
|
|
500
|
+
/* blob.l */
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
var header = file.slice(0, ssz);
|
|
504
|
+
check_shifts(blob, mver);
|
|
505
|
+
var dir_cnt = blob.read_shift(4, "i");
|
|
506
|
+
if (mver === 3 && dir_cnt !== 0) throw new Error("# Directory Sectors: Expected 0 saw " + dir_cnt);
|
|
507
|
+
blob.l += 4;
|
|
508
|
+
dir_start = blob.read_shift(4, "i");
|
|
509
|
+
blob.l += 4;
|
|
510
|
+
blob.chk("00100000", "Mini Stream Cutoff Size: ");
|
|
511
|
+
minifat_start = blob.read_shift(4, "i");
|
|
512
|
+
nmfs = blob.read_shift(4, "i");
|
|
513
|
+
difat_start = blob.read_shift(4, "i");
|
|
514
|
+
difat_sec_cnt = blob.read_shift(4, "i");
|
|
515
|
+
for (var q2 = -1, j = 0; j < 109; ++j) {
|
|
516
|
+
q2 = blob.read_shift(4, "i");
|
|
517
|
+
if (q2 < 0) break;
|
|
518
|
+
fat_addrs[j] = q2;
|
|
519
|
+
}
|
|
520
|
+
var sectors = sectorify(file, ssz);
|
|
521
|
+
sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);
|
|
522
|
+
var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
|
523
|
+
sector_list[dir_start].name = "!Directory";
|
|
524
|
+
if (nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
|
|
525
|
+
sector_list[fat_addrs[0]].name = "!FAT";
|
|
526
|
+
sector_list.fat_addrs = fat_addrs;
|
|
527
|
+
sector_list.ssz = ssz;
|
|
528
|
+
var files = {}, Paths = [], FileIndex = [], FullPaths = [];
|
|
529
|
+
read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, minifat_start);
|
|
530
|
+
build_full_paths(FileIndex, FullPaths, Paths);
|
|
531
|
+
Paths.shift();
|
|
532
|
+
var o = {
|
|
533
|
+
FileIndex,
|
|
534
|
+
FullPaths
|
|
535
|
+
};
|
|
536
|
+
if (options && options.raw) o.raw = { header, sectors };
|
|
537
|
+
return o;
|
|
538
|
+
}
|
|
539
|
+
function check_get_mver(blob) {
|
|
540
|
+
if (blob[blob.l] == 80 && blob[blob.l + 1] == 75) return [0, 0];
|
|
541
|
+
blob.chk(HEADER_SIGNATURE, "Header Signature: ");
|
|
542
|
+
blob.l += 16;
|
|
543
|
+
var mver = blob.read_shift(2, "u");
|
|
544
|
+
return [blob.read_shift(2, "u"), mver];
|
|
545
|
+
}
|
|
546
|
+
function check_shifts(blob, mver) {
|
|
547
|
+
var shift = 9;
|
|
548
|
+
blob.l += 2;
|
|
549
|
+
switch (shift = blob.read_shift(2)) {
|
|
550
|
+
case 9:
|
|
551
|
+
if (mver != 3) throw new Error("Sector Shift: Expected 9 saw " + shift);
|
|
552
|
+
break;
|
|
553
|
+
case 12:
|
|
554
|
+
if (mver != 4) throw new Error("Sector Shift: Expected 12 saw " + shift);
|
|
555
|
+
break;
|
|
556
|
+
default:
|
|
557
|
+
throw new Error("Sector Shift: Expected 9 or 12 saw " + shift);
|
|
558
|
+
}
|
|
559
|
+
blob.chk("0600", "Mini Sector Shift: ");
|
|
560
|
+
blob.chk("000000000000", "Reserved: ");
|
|
561
|
+
}
|
|
562
|
+
function sectorify(file, ssz) {
|
|
563
|
+
var nsectors = Math.ceil(file.length / ssz) - 1;
|
|
564
|
+
var sectors = [];
|
|
565
|
+
for (var i2 = 1; i2 < nsectors; ++i2) sectors[i2 - 1] = file.slice(i2 * ssz, (i2 + 1) * ssz);
|
|
566
|
+
sectors[nsectors - 1] = file.slice(nsectors * ssz);
|
|
567
|
+
return sectors;
|
|
568
|
+
}
|
|
569
|
+
function build_full_paths(FI, FP, Paths) {
|
|
570
|
+
var i2 = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length;
|
|
571
|
+
var dad = [], q2 = [];
|
|
572
|
+
for (; i2 < pl; ++i2) {
|
|
573
|
+
dad[i2] = q2[i2] = i2;
|
|
574
|
+
FP[i2] = Paths[i2];
|
|
575
|
+
}
|
|
576
|
+
for (; j < q2.length; ++j) {
|
|
577
|
+
i2 = q2[j];
|
|
578
|
+
L = FI[i2].L;
|
|
579
|
+
R = FI[i2].R;
|
|
580
|
+
C = FI[i2].C;
|
|
581
|
+
if (dad[i2] === i2) {
|
|
582
|
+
if (L !== -1 && dad[L] !== L) dad[i2] = dad[L];
|
|
583
|
+
if (R !== -1 && dad[R] !== R) dad[i2] = dad[R];
|
|
584
|
+
}
|
|
585
|
+
if (C !== -1) dad[C] = i2;
|
|
586
|
+
if (L !== -1 && i2 != dad[i2]) {
|
|
587
|
+
dad[L] = dad[i2];
|
|
588
|
+
if (q2.lastIndexOf(L) < j) q2.push(L);
|
|
589
|
+
}
|
|
590
|
+
if (R !== -1 && i2 != dad[i2]) {
|
|
591
|
+
dad[R] = dad[i2];
|
|
592
|
+
if (q2.lastIndexOf(R) < j) q2.push(R);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
for (i2 = 1; i2 < pl; ++i2) if (dad[i2] === i2) {
|
|
596
|
+
if (R !== -1 && dad[R] !== R) dad[i2] = dad[R];
|
|
597
|
+
else if (L !== -1 && dad[L] !== L) dad[i2] = dad[L];
|
|
598
|
+
}
|
|
599
|
+
for (i2 = 1; i2 < pl; ++i2) {
|
|
600
|
+
if (FI[i2].type === 0) continue;
|
|
601
|
+
j = i2;
|
|
602
|
+
if (j != dad[j]) do {
|
|
603
|
+
j = dad[j];
|
|
604
|
+
FP[i2] = FP[j] + "/" + FP[i2];
|
|
605
|
+
} while (j !== 0 && -1 !== dad[j] && j != dad[j]);
|
|
606
|
+
dad[i2] = -1;
|
|
607
|
+
}
|
|
608
|
+
FP[0] += "/";
|
|
609
|
+
for (i2 = 1; i2 < pl; ++i2) {
|
|
610
|
+
if (FI[i2].type !== 2) FP[i2] += "/";
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function get_mfat_entry(entry, payload, mini) {
|
|
614
|
+
var start = entry.start, size = entry.size;
|
|
615
|
+
var o = [];
|
|
616
|
+
var idx = start;
|
|
617
|
+
while (mini && size > 0 && idx >= 0) {
|
|
618
|
+
o.push(payload.slice(idx * MSSZ, idx * MSSZ + MSSZ));
|
|
619
|
+
size -= MSSZ;
|
|
620
|
+
idx = __readInt32LE(mini, idx * 4);
|
|
621
|
+
}
|
|
622
|
+
if (o.length === 0) return new_buf(0);
|
|
623
|
+
return bconcat(o).slice(0, entry.size);
|
|
624
|
+
}
|
|
625
|
+
function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
|
|
626
|
+
var q2 = ENDOFCHAIN;
|
|
627
|
+
if (idx === ENDOFCHAIN) {
|
|
628
|
+
if (cnt !== 0) throw new Error("DIFAT chain shorter than expected");
|
|
629
|
+
} else if (idx !== -1) {
|
|
630
|
+
var sector = sectors[idx], m = (ssz >>> 2) - 1;
|
|
631
|
+
if (!sector) return;
|
|
632
|
+
for (var i2 = 0; i2 < m; ++i2) {
|
|
633
|
+
if ((q2 = __readInt32LE(sector, i2 * 4)) === ENDOFCHAIN) break;
|
|
634
|
+
fat_addrs.push(q2);
|
|
635
|
+
}
|
|
636
|
+
if (cnt >= 1) sleuth_fat(__readInt32LE(sector, ssz - 4), cnt - 1, sectors, ssz, fat_addrs);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {
|
|
640
|
+
var buf = [], buf_chain = [];
|
|
641
|
+
if (!chkd) chkd = [];
|
|
642
|
+
var modulus = ssz - 1, j = 0, jj = 0;
|
|
643
|
+
for (j = start; j >= 0; ) {
|
|
644
|
+
chkd[j] = true;
|
|
645
|
+
buf[buf.length] = j;
|
|
646
|
+
buf_chain.push(sectors[j]);
|
|
647
|
+
var addr = fat_addrs[Math.floor(j * 4 / ssz)];
|
|
648
|
+
jj = j * 4 & modulus;
|
|
649
|
+
if (ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 " + ssz);
|
|
650
|
+
if (!sectors[addr]) break;
|
|
651
|
+
j = __readInt32LE(sectors[addr], jj);
|
|
652
|
+
}
|
|
653
|
+
return { nodes: buf, data: __toBuffer([buf_chain]) };
|
|
654
|
+
}
|
|
655
|
+
function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
|
656
|
+
var sl = sectors.length, sector_list = [];
|
|
657
|
+
var chkd = [], buf = [], buf_chain = [];
|
|
658
|
+
var modulus = ssz - 1, i2 = 0, j = 0, k = 0, jj = 0;
|
|
659
|
+
for (i2 = 0; i2 < sl; ++i2) {
|
|
660
|
+
buf = [];
|
|
661
|
+
k = i2 + dir_start;
|
|
662
|
+
if (k >= sl) k -= sl;
|
|
663
|
+
if (chkd[k]) continue;
|
|
664
|
+
buf_chain = [];
|
|
665
|
+
var seen = [];
|
|
666
|
+
for (j = k; j >= 0; ) {
|
|
667
|
+
seen[j] = true;
|
|
668
|
+
chkd[j] = true;
|
|
669
|
+
buf[buf.length] = j;
|
|
670
|
+
buf_chain.push(sectors[j]);
|
|
671
|
+
var addr = fat_addrs[Math.floor(j * 4 / ssz)];
|
|
672
|
+
jj = j * 4 & modulus;
|
|
673
|
+
if (ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 " + ssz);
|
|
674
|
+
if (!sectors[addr]) break;
|
|
675
|
+
j = __readInt32LE(sectors[addr], jj);
|
|
676
|
+
if (seen[j]) break;
|
|
677
|
+
}
|
|
678
|
+
sector_list[k] = { nodes: buf, data: __toBuffer([buf_chain]) };
|
|
679
|
+
}
|
|
680
|
+
return sector_list;
|
|
681
|
+
}
|
|
682
|
+
function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, mini) {
|
|
683
|
+
var minifat_store = 0, pl = Paths.length ? 2 : 0;
|
|
684
|
+
var sector = sector_list[dir_start].data;
|
|
685
|
+
var i2 = 0, namelen = 0, name;
|
|
686
|
+
for (; i2 < sector.length; i2 += 128) {
|
|
687
|
+
var blob = sector.slice(i2, i2 + 128);
|
|
688
|
+
prep_blob(blob, 64);
|
|
689
|
+
namelen = blob.read_shift(2);
|
|
690
|
+
name = __utf16le(blob, 0, namelen - pl);
|
|
691
|
+
Paths.push(name);
|
|
692
|
+
var o = {
|
|
693
|
+
name,
|
|
694
|
+
type: blob.read_shift(1),
|
|
695
|
+
color: blob.read_shift(1),
|
|
696
|
+
L: blob.read_shift(4, "i"),
|
|
697
|
+
R: blob.read_shift(4, "i"),
|
|
698
|
+
C: blob.read_shift(4, "i"),
|
|
699
|
+
clsid: blob.read_shift(16),
|
|
700
|
+
state: blob.read_shift(4, "i"),
|
|
701
|
+
start: 0,
|
|
702
|
+
size: 0
|
|
703
|
+
};
|
|
704
|
+
var ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
|
|
705
|
+
if (ctime !== 0) o.ct = read_date(blob, blob.l - 8);
|
|
706
|
+
var mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
|
|
707
|
+
if (mtime !== 0) o.mt = read_date(blob, blob.l - 8);
|
|
708
|
+
o.start = blob.read_shift(4, "i");
|
|
709
|
+
o.size = blob.read_shift(4, "i");
|
|
710
|
+
if (o.size < 0 && o.start < 0) {
|
|
711
|
+
o.size = o.type = 0;
|
|
712
|
+
o.start = ENDOFCHAIN;
|
|
713
|
+
o.name = "";
|
|
714
|
+
}
|
|
715
|
+
if (o.type === 5) {
|
|
716
|
+
minifat_store = o.start;
|
|
717
|
+
if (nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";
|
|
718
|
+
} else if (o.size >= 4096) {
|
|
719
|
+
o.storage = "fat";
|
|
720
|
+
if (sector_list[o.start] === void 0) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz);
|
|
721
|
+
sector_list[o.start].name = o.name;
|
|
722
|
+
o.content = sector_list[o.start].data.slice(0, o.size);
|
|
723
|
+
} else {
|
|
724
|
+
o.storage = "minifat";
|
|
725
|
+
if (o.size < 0) o.size = 0;
|
|
726
|
+
else if (minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
|
|
727
|
+
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini] || {}).data);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (o.content) prep_blob(o.content, 0);
|
|
731
|
+
files[name] = o;
|
|
732
|
+
FileIndex.push(o);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
function read_date(blob, offset) {
|
|
736
|
+
return new Date((__readUInt32LE(blob, offset + 4) / 1e7 * Math.pow(2, 32) + __readUInt32LE(blob, offset) / 1e7 - 11644473600) * 1e3);
|
|
737
|
+
}
|
|
738
|
+
function read_file(filename2, options) {
|
|
739
|
+
get_fs();
|
|
740
|
+
return parse3(fs.readFileSync(filename2), options);
|
|
741
|
+
}
|
|
742
|
+
function read(blob, options) {
|
|
743
|
+
var type = options && options.type;
|
|
744
|
+
if (!type) {
|
|
745
|
+
if (has_buf && Buffer.isBuffer(blob)) type = "buffer";
|
|
746
|
+
}
|
|
747
|
+
switch (type || "base64") {
|
|
748
|
+
case "file":
|
|
749
|
+
return read_file(blob, options);
|
|
750
|
+
case "base64":
|
|
751
|
+
return parse3(s2a(Base64_decode(blob)), options);
|
|
752
|
+
case "binary":
|
|
753
|
+
return parse3(s2a(blob), options);
|
|
754
|
+
}
|
|
755
|
+
return parse3(blob, options);
|
|
756
|
+
}
|
|
757
|
+
function init_cfb(cfb, opts) {
|
|
758
|
+
var o = opts || {}, root = o.root || "Root Entry";
|
|
759
|
+
if (!cfb.FullPaths) cfb.FullPaths = [];
|
|
760
|
+
if (!cfb.FileIndex) cfb.FileIndex = [];
|
|
761
|
+
if (cfb.FullPaths.length !== cfb.FileIndex.length) throw new Error("inconsistent CFB structure");
|
|
762
|
+
if (cfb.FullPaths.length === 0) {
|
|
763
|
+
cfb.FullPaths[0] = root + "/";
|
|
764
|
+
cfb.FileIndex[0] = { name: root, type: 5 };
|
|
765
|
+
}
|
|
766
|
+
if (o.CLSID) cfb.FileIndex[0].clsid = o.CLSID;
|
|
767
|
+
seed_cfb(cfb);
|
|
768
|
+
}
|
|
769
|
+
function seed_cfb(cfb) {
|
|
770
|
+
var nm = "Sh33tJ5";
|
|
771
|
+
if (CFB2.find(cfb, "/" + nm)) return;
|
|
772
|
+
var p = new_buf(4);
|
|
773
|
+
p[0] = 55;
|
|
774
|
+
p[1] = p[3] = 50;
|
|
775
|
+
p[2] = 54;
|
|
776
|
+
cfb.FileIndex.push({ name: nm, type: 2, content: p, size: 4, L: 69, R: 69, C: 69 });
|
|
777
|
+
cfb.FullPaths.push(cfb.FullPaths[0] + nm);
|
|
778
|
+
rebuild_cfb(cfb);
|
|
779
|
+
}
|
|
780
|
+
function rebuild_cfb(cfb, f) {
|
|
781
|
+
init_cfb(cfb);
|
|
782
|
+
var gc = false, s = false;
|
|
783
|
+
for (var i2 = cfb.FullPaths.length - 1; i2 >= 0; --i2) {
|
|
784
|
+
var _file = cfb.FileIndex[i2];
|
|
785
|
+
switch (_file.type) {
|
|
786
|
+
case 0:
|
|
787
|
+
if (s) gc = true;
|
|
788
|
+
else {
|
|
789
|
+
cfb.FileIndex.pop();
|
|
790
|
+
cfb.FullPaths.pop();
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
case 1:
|
|
794
|
+
case 2:
|
|
795
|
+
case 5:
|
|
796
|
+
s = true;
|
|
797
|
+
if (isNaN(_file.R * _file.L * _file.C)) gc = true;
|
|
798
|
+
if (_file.R > -1 && _file.L > -1 && _file.R == _file.L) gc = true;
|
|
799
|
+
break;
|
|
800
|
+
default:
|
|
801
|
+
gc = true;
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
if (!gc && !f) return;
|
|
806
|
+
var now = new Date(1987, 1, 19), j = 0;
|
|
807
|
+
var fullPaths = Object.create ? /* @__PURE__ */ Object.create(null) : {};
|
|
808
|
+
var data = [];
|
|
809
|
+
for (i2 = 0; i2 < cfb.FullPaths.length; ++i2) {
|
|
810
|
+
fullPaths[cfb.FullPaths[i2]] = true;
|
|
811
|
+
if (cfb.FileIndex[i2].type === 0) continue;
|
|
812
|
+
data.push([cfb.FullPaths[i2], cfb.FileIndex[i2]]);
|
|
813
|
+
}
|
|
814
|
+
for (i2 = 0; i2 < data.length; ++i2) {
|
|
815
|
+
var dad = dirname(data[i2][0]);
|
|
816
|
+
s = fullPaths[dad];
|
|
817
|
+
while (!s) {
|
|
818
|
+
while (dirname(dad) && !fullPaths[dirname(dad)]) dad = dirname(dad);
|
|
819
|
+
data.push([dad, {
|
|
820
|
+
name: filename(dad).replace("/", ""),
|
|
821
|
+
type: 1,
|
|
822
|
+
clsid: HEADER_CLSID,
|
|
823
|
+
ct: now,
|
|
824
|
+
mt: now,
|
|
825
|
+
content: null
|
|
826
|
+
}]);
|
|
827
|
+
fullPaths[dad] = true;
|
|
828
|
+
dad = dirname(data[i2][0]);
|
|
829
|
+
s = fullPaths[dad];
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
data.sort(function(x, y) {
|
|
833
|
+
return namecmp(x[0], y[0]);
|
|
834
|
+
});
|
|
835
|
+
cfb.FullPaths = [];
|
|
836
|
+
cfb.FileIndex = [];
|
|
837
|
+
for (i2 = 0; i2 < data.length; ++i2) {
|
|
838
|
+
cfb.FullPaths[i2] = data[i2][0];
|
|
839
|
+
cfb.FileIndex[i2] = data[i2][1];
|
|
840
|
+
}
|
|
841
|
+
for (i2 = 0; i2 < data.length; ++i2) {
|
|
842
|
+
var elt = cfb.FileIndex[i2];
|
|
843
|
+
var nm = cfb.FullPaths[i2];
|
|
844
|
+
elt.name = filename(nm).replace("/", "");
|
|
845
|
+
elt.L = elt.R = elt.C = -(elt.color = 1);
|
|
846
|
+
elt.size = elt.content ? elt.content.length : 0;
|
|
847
|
+
elt.start = 0;
|
|
848
|
+
elt.clsid = elt.clsid || HEADER_CLSID;
|
|
849
|
+
if (i2 === 0) {
|
|
850
|
+
elt.C = data.length > 1 ? 1 : -1;
|
|
851
|
+
elt.size = 0;
|
|
852
|
+
elt.type = 5;
|
|
853
|
+
} else if (nm.slice(-1) == "/") {
|
|
854
|
+
for (j = i2 + 1; j < data.length; ++j) if (dirname(cfb.FullPaths[j]) == nm) break;
|
|
855
|
+
elt.C = j >= data.length ? -1 : j;
|
|
856
|
+
for (j = i2 + 1; j < data.length; ++j) if (dirname(cfb.FullPaths[j]) == dirname(nm)) break;
|
|
857
|
+
elt.R = j >= data.length ? -1 : j;
|
|
858
|
+
elt.type = 1;
|
|
859
|
+
} else {
|
|
860
|
+
if (dirname(cfb.FullPaths[i2 + 1] || "") == dirname(nm)) elt.R = i2 + 1;
|
|
861
|
+
elt.type = 2;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
function _write(cfb, options) {
|
|
866
|
+
var _opts = options || {};
|
|
867
|
+
if (_opts.fileType == "mad") return write_mad(cfb, _opts);
|
|
868
|
+
rebuild_cfb(cfb);
|
|
869
|
+
switch (_opts.fileType) {
|
|
870
|
+
case "zip":
|
|
871
|
+
return write_zip(cfb, _opts);
|
|
872
|
+
}
|
|
873
|
+
var L = (function(cfb2) {
|
|
874
|
+
var mini_size = 0, fat_size = 0;
|
|
875
|
+
for (var i3 = 0; i3 < cfb2.FileIndex.length; ++i3) {
|
|
876
|
+
var file2 = cfb2.FileIndex[i3];
|
|
877
|
+
if (!file2.content) continue;
|
|
878
|
+
var flen2 = file2.content.length;
|
|
879
|
+
if (flen2 > 0) {
|
|
880
|
+
if (flen2 < 4096) mini_size += flen2 + 63 >> 6;
|
|
881
|
+
else fat_size += flen2 + 511 >> 9;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
var dir_cnt = cfb2.FullPaths.length + 3 >> 2;
|
|
885
|
+
var mini_cnt = mini_size + 7 >> 3;
|
|
886
|
+
var mfat_cnt = mini_size + 127 >> 7;
|
|
887
|
+
var fat_base = mini_cnt + fat_size + dir_cnt + mfat_cnt;
|
|
888
|
+
var fat_cnt = fat_base + 127 >> 7;
|
|
889
|
+
var difat_cnt = fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt - 109) / 127);
|
|
890
|
+
while (fat_base + fat_cnt + difat_cnt + 127 >> 7 > fat_cnt) difat_cnt = ++fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt - 109) / 127);
|
|
891
|
+
var L2 = [1, difat_cnt, fat_cnt, mfat_cnt, dir_cnt, fat_size, mini_size, 0];
|
|
892
|
+
cfb2.FileIndex[0].size = mini_size << 6;
|
|
893
|
+
L2[7] = (cfb2.FileIndex[0].start = L2[0] + L2[1] + L2[2] + L2[3] + L2[4] + L2[5]) + (L2[6] + 7 >> 3);
|
|
894
|
+
return L2;
|
|
895
|
+
})(cfb);
|
|
896
|
+
var o = new_buf(L[7] << 9);
|
|
897
|
+
var i2 = 0, T = 0;
|
|
898
|
+
{
|
|
899
|
+
for (i2 = 0; i2 < 8; ++i2) o.write_shift(1, HEADER_SIG[i2]);
|
|
900
|
+
for (i2 = 0; i2 < 8; ++i2) o.write_shift(2, 0);
|
|
901
|
+
o.write_shift(2, 62);
|
|
902
|
+
o.write_shift(2, 3);
|
|
903
|
+
o.write_shift(2, 65534);
|
|
904
|
+
o.write_shift(2, 9);
|
|
905
|
+
o.write_shift(2, 6);
|
|
906
|
+
for (i2 = 0; i2 < 3; ++i2) o.write_shift(2, 0);
|
|
907
|
+
o.write_shift(4, 0);
|
|
908
|
+
o.write_shift(4, L[2]);
|
|
909
|
+
o.write_shift(4, L[0] + L[1] + L[2] + L[3] - 1);
|
|
910
|
+
o.write_shift(4, 0);
|
|
911
|
+
o.write_shift(4, 1 << 12);
|
|
912
|
+
o.write_shift(4, L[3] ? L[0] + L[1] + L[2] - 1 : ENDOFCHAIN);
|
|
913
|
+
o.write_shift(4, L[3]);
|
|
914
|
+
o.write_shift(-4, L[1] ? L[0] - 1 : ENDOFCHAIN);
|
|
915
|
+
o.write_shift(4, L[1]);
|
|
916
|
+
for (i2 = 0; i2 < 109; ++i2) o.write_shift(-4, i2 < L[2] ? L[1] + i2 : -1);
|
|
917
|
+
}
|
|
918
|
+
if (L[1]) {
|
|
919
|
+
for (T = 0; T < L[1]; ++T) {
|
|
920
|
+
for (; i2 < 236 + T * 127; ++i2) o.write_shift(-4, i2 < L[2] ? L[1] + i2 : -1);
|
|
921
|
+
o.write_shift(-4, T === L[1] - 1 ? ENDOFCHAIN : T + 1);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
var chainit = function(w) {
|
|
925
|
+
for (T += w; i2 < T - 1; ++i2) o.write_shift(-4, i2 + 1);
|
|
926
|
+
if (w) {
|
|
927
|
+
++i2;
|
|
928
|
+
o.write_shift(-4, ENDOFCHAIN);
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
T = i2 = 0;
|
|
932
|
+
for (T += L[1]; i2 < T; ++i2) o.write_shift(-4, consts.DIFSECT);
|
|
933
|
+
for (T += L[2]; i2 < T; ++i2) o.write_shift(-4, consts.FATSECT);
|
|
934
|
+
chainit(L[3]);
|
|
935
|
+
chainit(L[4]);
|
|
936
|
+
var j = 0, flen = 0;
|
|
937
|
+
var file = cfb.FileIndex[0];
|
|
938
|
+
for (; j < cfb.FileIndex.length; ++j) {
|
|
939
|
+
file = cfb.FileIndex[j];
|
|
940
|
+
if (!file.content) continue;
|
|
941
|
+
flen = file.content.length;
|
|
942
|
+
if (flen < 4096) continue;
|
|
943
|
+
file.start = T;
|
|
944
|
+
chainit(flen + 511 >> 9);
|
|
945
|
+
}
|
|
946
|
+
chainit(L[6] + 7 >> 3);
|
|
947
|
+
while (o.l & 511) o.write_shift(-4, consts.ENDOFCHAIN);
|
|
948
|
+
T = i2 = 0;
|
|
949
|
+
for (j = 0; j < cfb.FileIndex.length; ++j) {
|
|
950
|
+
file = cfb.FileIndex[j];
|
|
951
|
+
if (!file.content) continue;
|
|
952
|
+
flen = file.content.length;
|
|
953
|
+
if (!flen || flen >= 4096) continue;
|
|
954
|
+
file.start = T;
|
|
955
|
+
chainit(flen + 63 >> 6);
|
|
956
|
+
}
|
|
957
|
+
while (o.l & 511) o.write_shift(-4, consts.ENDOFCHAIN);
|
|
958
|
+
for (i2 = 0; i2 < L[4] << 2; ++i2) {
|
|
959
|
+
var nm = cfb.FullPaths[i2];
|
|
960
|
+
if (!nm || nm.length === 0) {
|
|
961
|
+
for (j = 0; j < 17; ++j) o.write_shift(4, 0);
|
|
962
|
+
for (j = 0; j < 3; ++j) o.write_shift(4, -1);
|
|
963
|
+
for (j = 0; j < 12; ++j) o.write_shift(4, 0);
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
file = cfb.FileIndex[i2];
|
|
967
|
+
if (i2 === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
|
|
968
|
+
var _nm = i2 === 0 && _opts.root || file.name;
|
|
969
|
+
if (_nm.length > 32) {
|
|
970
|
+
console.error("Name " + _nm + " will be truncated to " + _nm.slice(0, 32));
|
|
971
|
+
_nm = _nm.slice(0, 32);
|
|
972
|
+
}
|
|
973
|
+
flen = 2 * (_nm.length + 1);
|
|
974
|
+
o.write_shift(64, _nm, "utf16le");
|
|
975
|
+
o.write_shift(2, flen);
|
|
976
|
+
o.write_shift(1, file.type);
|
|
977
|
+
o.write_shift(1, file.color);
|
|
978
|
+
o.write_shift(-4, file.L);
|
|
979
|
+
o.write_shift(-4, file.R);
|
|
980
|
+
o.write_shift(-4, file.C);
|
|
981
|
+
if (!file.clsid) for (j = 0; j < 4; ++j) o.write_shift(4, 0);
|
|
982
|
+
else o.write_shift(16, file.clsid, "hex");
|
|
983
|
+
o.write_shift(4, file.state || 0);
|
|
984
|
+
o.write_shift(4, 0);
|
|
985
|
+
o.write_shift(4, 0);
|
|
986
|
+
o.write_shift(4, 0);
|
|
987
|
+
o.write_shift(4, 0);
|
|
988
|
+
o.write_shift(4, file.start);
|
|
989
|
+
o.write_shift(4, file.size);
|
|
990
|
+
o.write_shift(4, 0);
|
|
991
|
+
}
|
|
992
|
+
for (i2 = 1; i2 < cfb.FileIndex.length; ++i2) {
|
|
993
|
+
file = cfb.FileIndex[i2];
|
|
994
|
+
if (file.size >= 4096) {
|
|
995
|
+
o.l = file.start + 1 << 9;
|
|
996
|
+
if (has_buf && Buffer.isBuffer(file.content)) {
|
|
997
|
+
file.content.copy(o, o.l, 0, file.size);
|
|
998
|
+
o.l += file.size + 511 & -512;
|
|
999
|
+
} else {
|
|
1000
|
+
for (j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
|
|
1001
|
+
for (; j & 511; ++j) o.write_shift(1, 0);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
for (i2 = 1; i2 < cfb.FileIndex.length; ++i2) {
|
|
1006
|
+
file = cfb.FileIndex[i2];
|
|
1007
|
+
if (file.size > 0 && file.size < 4096) {
|
|
1008
|
+
if (has_buf && Buffer.isBuffer(file.content)) {
|
|
1009
|
+
file.content.copy(o, o.l, 0, file.size);
|
|
1010
|
+
o.l += file.size + 63 & -64;
|
|
1011
|
+
} else {
|
|
1012
|
+
for (j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
|
|
1013
|
+
for (; j & 63; ++j) o.write_shift(1, 0);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
if (has_buf) {
|
|
1018
|
+
o.l = o.length;
|
|
1019
|
+
} else {
|
|
1020
|
+
while (o.l < o.length) o.write_shift(1, 0);
|
|
1021
|
+
}
|
|
1022
|
+
return o;
|
|
1023
|
+
}
|
|
1024
|
+
function find2(cfb, path) {
|
|
1025
|
+
var UCFullPaths = cfb.FullPaths.map(function(x) {
|
|
1026
|
+
return x.toUpperCase();
|
|
1027
|
+
});
|
|
1028
|
+
var UCPaths = UCFullPaths.map(function(x) {
|
|
1029
|
+
var y = x.split("/");
|
|
1030
|
+
return y[y.length - (x.slice(-1) == "/" ? 2 : 1)];
|
|
1031
|
+
});
|
|
1032
|
+
var k = false;
|
|
1033
|
+
if (path.charCodeAt(0) === 47) {
|
|
1034
|
+
k = true;
|
|
1035
|
+
path = UCFullPaths[0].slice(0, -1) + path;
|
|
1036
|
+
} else k = path.indexOf("/") !== -1;
|
|
1037
|
+
var UCPath = path.toUpperCase();
|
|
1038
|
+
var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
|
1039
|
+
if (w !== -1) return cfb.FileIndex[w];
|
|
1040
|
+
var m = !UCPath.match(chr1);
|
|
1041
|
+
UCPath = UCPath.replace(chr0, "");
|
|
1042
|
+
if (m) UCPath = UCPath.replace(chr1, "!");
|
|
1043
|
+
for (w = 0; w < UCFullPaths.length; ++w) {
|
|
1044
|
+
if ((m ? UCFullPaths[w].replace(chr1, "!") : UCFullPaths[w]).replace(chr0, "") == UCPath) return cfb.FileIndex[w];
|
|
1045
|
+
if ((m ? UCPaths[w].replace(chr1, "!") : UCPaths[w]).replace(chr0, "") == UCPath) return cfb.FileIndex[w];
|
|
1046
|
+
}
|
|
1047
|
+
return null;
|
|
1048
|
+
}
|
|
1049
|
+
var MSSZ = 64;
|
|
1050
|
+
var ENDOFCHAIN = -2;
|
|
1051
|
+
var HEADER_SIGNATURE = "d0cf11e0a1b11ae1";
|
|
1052
|
+
var HEADER_SIG = [208, 207, 17, 224, 161, 177, 26, 225];
|
|
1053
|
+
var HEADER_CLSID = "00000000000000000000000000000000";
|
|
1054
|
+
var consts = {
|
|
1055
|
+
/* 2.1 Compund File Sector Numbers and Types */
|
|
1056
|
+
MAXREGSECT: -6,
|
|
1057
|
+
DIFSECT: -4,
|
|
1058
|
+
FATSECT: -3,
|
|
1059
|
+
ENDOFCHAIN,
|
|
1060
|
+
FREESECT: -1,
|
|
1061
|
+
/* 2.2 Compound File Header */
|
|
1062
|
+
HEADER_SIGNATURE,
|
|
1063
|
+
HEADER_MINOR_VERSION: "3e00",
|
|
1064
|
+
MAXREGSID: -6,
|
|
1065
|
+
NOSTREAM: -1,
|
|
1066
|
+
HEADER_CLSID,
|
|
1067
|
+
/* 2.6.1 Compound File Directory Entry */
|
|
1068
|
+
EntryTypes: ["unknown", "storage", "stream", "lockbytes", "property", "root"]
|
|
1069
|
+
};
|
|
1070
|
+
function write_file(cfb, filename2, options) {
|
|
1071
|
+
get_fs();
|
|
1072
|
+
var o = _write(cfb, options);
|
|
1073
|
+
fs.writeFileSync(filename2, o);
|
|
1074
|
+
}
|
|
1075
|
+
function a2s(o) {
|
|
1076
|
+
var out = new Array(o.length);
|
|
1077
|
+
for (var i2 = 0; i2 < o.length; ++i2) out[i2] = String.fromCharCode(o[i2]);
|
|
1078
|
+
return out.join("");
|
|
1079
|
+
}
|
|
1080
|
+
function write(cfb, options) {
|
|
1081
|
+
var o = _write(cfb, options);
|
|
1082
|
+
switch (options && options.type || "buffer") {
|
|
1083
|
+
case "file":
|
|
1084
|
+
get_fs();
|
|
1085
|
+
fs.writeFileSync(options.filename, o);
|
|
1086
|
+
return o;
|
|
1087
|
+
case "binary":
|
|
1088
|
+
return typeof o == "string" ? o : a2s(o);
|
|
1089
|
+
case "base64":
|
|
1090
|
+
return Base64_encode(typeof o == "string" ? o : a2s(o));
|
|
1091
|
+
case "buffer":
|
|
1092
|
+
if (has_buf) return Buffer.isBuffer(o) ? o : Buffer_from(o);
|
|
1093
|
+
/* falls through */
|
|
1094
|
+
case "array":
|
|
1095
|
+
return typeof o == "string" ? s2a(o) : o;
|
|
1096
|
+
}
|
|
1097
|
+
return o;
|
|
1098
|
+
}
|
|
1099
|
+
var _zlib;
|
|
1100
|
+
function use_zlib(zlib) {
|
|
1101
|
+
try {
|
|
1102
|
+
var InflateRaw = zlib.InflateRaw;
|
|
1103
|
+
var InflRaw = new InflateRaw();
|
|
1104
|
+
InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag);
|
|
1105
|
+
if (InflRaw.bytesRead) _zlib = zlib;
|
|
1106
|
+
else throw new Error("zlib does not expose bytesRead");
|
|
1107
|
+
} catch (e) {
|
|
1108
|
+
console.error("cannot use native zlib: " + (e.message || e));
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
function _inflateRawSync(payload, usz) {
|
|
1112
|
+
if (!_zlib) return _inflate(payload, usz);
|
|
1113
|
+
var InflateRaw = _zlib.InflateRaw;
|
|
1114
|
+
var InflRaw = new InflateRaw();
|
|
1115
|
+
var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag);
|
|
1116
|
+
payload.l += InflRaw.bytesRead;
|
|
1117
|
+
return out;
|
|
1118
|
+
}
|
|
1119
|
+
function _deflateRawSync(payload) {
|
|
1120
|
+
return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload);
|
|
1121
|
+
}
|
|
1122
|
+
var CLEN_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
|
|
1123
|
+
var LEN_LN = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];
|
|
1124
|
+
var DST_LN = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];
|
|
1125
|
+
function bit_swap_8(n) {
|
|
1126
|
+
var t = (n << 1 | n << 11) & 139536 | (n << 5 | n << 15) & 558144;
|
|
1127
|
+
return (t >> 16 | t >> 8 | t) & 255;
|
|
1128
|
+
}
|
|
1129
|
+
var use_typed_arrays = typeof Uint8Array !== "undefined";
|
|
1130
|
+
var bitswap8 = use_typed_arrays ? new Uint8Array(1 << 8) : [];
|
|
1131
|
+
for (var q = 0; q < 1 << 8; ++q) bitswap8[q] = bit_swap_8(q);
|
|
1132
|
+
function bit_swap_n(n, b) {
|
|
1133
|
+
var rev = bitswap8[n & 255];
|
|
1134
|
+
if (b <= 8) return rev >>> 8 - b;
|
|
1135
|
+
rev = rev << 8 | bitswap8[n >> 8 & 255];
|
|
1136
|
+
if (b <= 16) return rev >>> 16 - b;
|
|
1137
|
+
rev = rev << 8 | bitswap8[n >> 16 & 255];
|
|
1138
|
+
return rev >>> 24 - b;
|
|
1139
|
+
}
|
|
1140
|
+
function read_bits_2(buf, bl) {
|
|
1141
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1142
|
+
return (buf[h] | (w <= 6 ? 0 : buf[h + 1] << 8)) >>> w & 3;
|
|
1143
|
+
}
|
|
1144
|
+
function read_bits_3(buf, bl) {
|
|
1145
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1146
|
+
return (buf[h] | (w <= 5 ? 0 : buf[h + 1] << 8)) >>> w & 7;
|
|
1147
|
+
}
|
|
1148
|
+
function read_bits_4(buf, bl) {
|
|
1149
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1150
|
+
return (buf[h] | (w <= 4 ? 0 : buf[h + 1] << 8)) >>> w & 15;
|
|
1151
|
+
}
|
|
1152
|
+
function read_bits_5(buf, bl) {
|
|
1153
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1154
|
+
return (buf[h] | (w <= 3 ? 0 : buf[h + 1] << 8)) >>> w & 31;
|
|
1155
|
+
}
|
|
1156
|
+
function read_bits_7(buf, bl) {
|
|
1157
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1158
|
+
return (buf[h] | (w <= 1 ? 0 : buf[h + 1] << 8)) >>> w & 127;
|
|
1159
|
+
}
|
|
1160
|
+
function read_bits_n(buf, bl, n) {
|
|
1161
|
+
var w = bl & 7, h = bl >>> 3, f = (1 << n) - 1;
|
|
1162
|
+
var v = buf[h] >>> w;
|
|
1163
|
+
if (n < 8 - w) return v & f;
|
|
1164
|
+
v |= buf[h + 1] << 8 - w;
|
|
1165
|
+
if (n < 16 - w) return v & f;
|
|
1166
|
+
v |= buf[h + 2] << 16 - w;
|
|
1167
|
+
if (n < 24 - w) return v & f;
|
|
1168
|
+
v |= buf[h + 3] << 24 - w;
|
|
1169
|
+
return v & f;
|
|
1170
|
+
}
|
|
1171
|
+
function write_bits_3(buf, bl, v) {
|
|
1172
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1173
|
+
if (w <= 5) buf[h] |= (v & 7) << w;
|
|
1174
|
+
else {
|
|
1175
|
+
buf[h] |= v << w & 255;
|
|
1176
|
+
buf[h + 1] = (v & 7) >> 8 - w;
|
|
1177
|
+
}
|
|
1178
|
+
return bl + 3;
|
|
1179
|
+
}
|
|
1180
|
+
function write_bits_1(buf, bl, v) {
|
|
1181
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1182
|
+
v = (v & 1) << w;
|
|
1183
|
+
buf[h] |= v;
|
|
1184
|
+
return bl + 1;
|
|
1185
|
+
}
|
|
1186
|
+
function write_bits_8(buf, bl, v) {
|
|
1187
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1188
|
+
v <<= w;
|
|
1189
|
+
buf[h] |= v & 255;
|
|
1190
|
+
v >>>= 8;
|
|
1191
|
+
buf[h + 1] = v;
|
|
1192
|
+
return bl + 8;
|
|
1193
|
+
}
|
|
1194
|
+
function write_bits_16(buf, bl, v) {
|
|
1195
|
+
var w = bl & 7, h = bl >>> 3;
|
|
1196
|
+
v <<= w;
|
|
1197
|
+
buf[h] |= v & 255;
|
|
1198
|
+
v >>>= 8;
|
|
1199
|
+
buf[h + 1] = v & 255;
|
|
1200
|
+
buf[h + 2] = v >>> 8;
|
|
1201
|
+
return bl + 16;
|
|
1202
|
+
}
|
|
1203
|
+
function realloc(b, sz) {
|
|
1204
|
+
var L = b.length, M = 2 * L > sz ? 2 * L : sz + 5, i2 = 0;
|
|
1205
|
+
if (L >= sz) return b;
|
|
1206
|
+
if (has_buf) {
|
|
1207
|
+
var o = new_unsafe_buf(M);
|
|
1208
|
+
if (b.copy) b.copy(o);
|
|
1209
|
+
else for (; i2 < b.length; ++i2) o[i2] = b[i2];
|
|
1210
|
+
return o;
|
|
1211
|
+
} else if (use_typed_arrays) {
|
|
1212
|
+
var a = new Uint8Array(M);
|
|
1213
|
+
if (a.set) a.set(b);
|
|
1214
|
+
else for (; i2 < L; ++i2) a[i2] = b[i2];
|
|
1215
|
+
return a;
|
|
1216
|
+
}
|
|
1217
|
+
b.length = M;
|
|
1218
|
+
return b;
|
|
1219
|
+
}
|
|
1220
|
+
function zero_fill_array(n) {
|
|
1221
|
+
var o = new Array(n);
|
|
1222
|
+
for (var i2 = 0; i2 < n; ++i2) o[i2] = 0;
|
|
1223
|
+
return o;
|
|
1224
|
+
}
|
|
1225
|
+
function build_tree(clens, cmap, MAX) {
|
|
1226
|
+
var maxlen = 1, w = 0, i2 = 0, j = 0, ccode = 0, L = clens.length;
|
|
1227
|
+
var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
|
|
1228
|
+
for (i2 = 0; i2 < 32; ++i2) bl_count[i2] = 0;
|
|
1229
|
+
for (i2 = L; i2 < MAX; ++i2) clens[i2] = 0;
|
|
1230
|
+
L = clens.length;
|
|
1231
|
+
var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L);
|
|
1232
|
+
for (i2 = 0; i2 < L; ++i2) {
|
|
1233
|
+
bl_count[w = clens[i2]]++;
|
|
1234
|
+
if (maxlen < w) maxlen = w;
|
|
1235
|
+
ctree[i2] = 0;
|
|
1236
|
+
}
|
|
1237
|
+
bl_count[0] = 0;
|
|
1238
|
+
for (i2 = 1; i2 <= maxlen; ++i2) bl_count[i2 + 16] = ccode = ccode + bl_count[i2 - 1] << 1;
|
|
1239
|
+
for (i2 = 0; i2 < L; ++i2) {
|
|
1240
|
+
ccode = clens[i2];
|
|
1241
|
+
if (ccode != 0) ctree[i2] = bl_count[ccode + 16]++;
|
|
1242
|
+
}
|
|
1243
|
+
var cleni = 0;
|
|
1244
|
+
for (i2 = 0; i2 < L; ++i2) {
|
|
1245
|
+
cleni = clens[i2];
|
|
1246
|
+
if (cleni != 0) {
|
|
1247
|
+
ccode = bit_swap_n(ctree[i2], maxlen) >> maxlen - cleni;
|
|
1248
|
+
for (j = (1 << maxlen + 4 - cleni) - 1; j >= 0; --j)
|
|
1249
|
+
cmap[ccode | j << cleni] = cleni & 15 | i2 << 4;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
return maxlen;
|
|
1253
|
+
}
|
|
1254
|
+
var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512);
|
|
1255
|
+
var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
|
|
1256
|
+
if (!use_typed_arrays) {
|
|
1257
|
+
for (var i = 0; i < 512; ++i) fix_lmap[i] = 0;
|
|
1258
|
+
for (i = 0; i < 32; ++i) fix_dmap[i] = 0;
|
|
1259
|
+
}
|
|
1260
|
+
(function() {
|
|
1261
|
+
var dlens = [];
|
|
1262
|
+
var i2 = 0;
|
|
1263
|
+
for (; i2 < 32; i2++) dlens.push(5);
|
|
1264
|
+
build_tree(dlens, fix_dmap, 32);
|
|
1265
|
+
var clens = [];
|
|
1266
|
+
i2 = 0;
|
|
1267
|
+
for (; i2 <= 143; i2++) clens.push(8);
|
|
1268
|
+
for (; i2 <= 255; i2++) clens.push(9);
|
|
1269
|
+
for (; i2 <= 279; i2++) clens.push(7);
|
|
1270
|
+
for (; i2 <= 287; i2++) clens.push(8);
|
|
1271
|
+
build_tree(clens, fix_lmap, 288);
|
|
1272
|
+
})();
|
|
1273
|
+
var _deflateRaw = (function _deflateRawIIFE() {
|
|
1274
|
+
var DST_LN_RE = use_typed_arrays ? new Uint8Array(32768) : [];
|
|
1275
|
+
var j = 0, k = 0;
|
|
1276
|
+
for (; j < DST_LN.length - 1; ++j) {
|
|
1277
|
+
for (; k < DST_LN[j + 1]; ++k) DST_LN_RE[k] = j;
|
|
1278
|
+
}
|
|
1279
|
+
for (; k < 32768; ++k) DST_LN_RE[k] = 29;
|
|
1280
|
+
var LEN_LN_RE = use_typed_arrays ? new Uint8Array(259) : [];
|
|
1281
|
+
for (j = 0, k = 0; j < LEN_LN.length - 1; ++j) {
|
|
1282
|
+
for (; k < LEN_LN[j + 1]; ++k) LEN_LN_RE[k] = j;
|
|
1283
|
+
}
|
|
1284
|
+
function write_stored(data, out) {
|
|
1285
|
+
var boff = 0;
|
|
1286
|
+
while (boff < data.length) {
|
|
1287
|
+
var L = Math.min(65535, data.length - boff);
|
|
1288
|
+
var h = boff + L == data.length;
|
|
1289
|
+
out.write_shift(1, +h);
|
|
1290
|
+
out.write_shift(2, L);
|
|
1291
|
+
out.write_shift(2, ~L & 65535);
|
|
1292
|
+
while (L-- > 0) out[out.l++] = data[boff++];
|
|
1293
|
+
}
|
|
1294
|
+
return out.l;
|
|
1295
|
+
}
|
|
1296
|
+
function write_huff_fixed(data, out) {
|
|
1297
|
+
var bl = 0;
|
|
1298
|
+
var boff = 0;
|
|
1299
|
+
var addrs = use_typed_arrays ? new Uint16Array(32768) : [];
|
|
1300
|
+
while (boff < data.length) {
|
|
1301
|
+
var L = (
|
|
1302
|
+
/* data.length - boff; */
|
|
1303
|
+
Math.min(65535, data.length - boff)
|
|
1304
|
+
);
|
|
1305
|
+
if (L < 10) {
|
|
1306
|
+
bl = write_bits_3(out, bl, +!!(boff + L == data.length));
|
|
1307
|
+
if (bl & 7) bl += 8 - (bl & 7);
|
|
1308
|
+
out.l = bl / 8 | 0;
|
|
1309
|
+
out.write_shift(2, L);
|
|
1310
|
+
out.write_shift(2, ~L & 65535);
|
|
1311
|
+
while (L-- > 0) out[out.l++] = data[boff++];
|
|
1312
|
+
bl = out.l * 8;
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1315
|
+
bl = write_bits_3(out, bl, +!!(boff + L == data.length) + 2);
|
|
1316
|
+
var hash = 0;
|
|
1317
|
+
while (L-- > 0) {
|
|
1318
|
+
var d = data[boff];
|
|
1319
|
+
hash = (hash << 5 ^ d) & 32767;
|
|
1320
|
+
var match = -1, mlen = 0;
|
|
1321
|
+
if (match = addrs[hash]) {
|
|
1322
|
+
match |= boff & ~32767;
|
|
1323
|
+
if (match > boff) match -= 32768;
|
|
1324
|
+
if (match < boff) while (data[match + mlen] == data[boff + mlen] && mlen < 250) ++mlen;
|
|
1325
|
+
}
|
|
1326
|
+
if (mlen > 2) {
|
|
1327
|
+
d = LEN_LN_RE[mlen];
|
|
1328
|
+
if (d <= 22) bl = write_bits_8(out, bl, bitswap8[d + 1] >> 1) - 1;
|
|
1329
|
+
else {
|
|
1330
|
+
write_bits_8(out, bl, 3);
|
|
1331
|
+
bl += 5;
|
|
1332
|
+
write_bits_8(out, bl, bitswap8[d - 23] >> 5);
|
|
1333
|
+
bl += 3;
|
|
1334
|
+
}
|
|
1335
|
+
var len_eb = d < 8 ? 0 : d - 4 >> 2;
|
|
1336
|
+
if (len_eb > 0) {
|
|
1337
|
+
write_bits_16(out, bl, mlen - LEN_LN[d]);
|
|
1338
|
+
bl += len_eb;
|
|
1339
|
+
}
|
|
1340
|
+
d = DST_LN_RE[boff - match];
|
|
1341
|
+
bl = write_bits_8(out, bl, bitswap8[d] >> 3);
|
|
1342
|
+
bl -= 3;
|
|
1343
|
+
var dst_eb = d < 4 ? 0 : d - 2 >> 1;
|
|
1344
|
+
if (dst_eb > 0) {
|
|
1345
|
+
write_bits_16(out, bl, boff - match - DST_LN[d]);
|
|
1346
|
+
bl += dst_eb;
|
|
1347
|
+
}
|
|
1348
|
+
for (var q2 = 0; q2 < mlen; ++q2) {
|
|
1349
|
+
addrs[hash] = boff & 32767;
|
|
1350
|
+
hash = (hash << 5 ^ data[boff]) & 32767;
|
|
1351
|
+
++boff;
|
|
1352
|
+
}
|
|
1353
|
+
L -= mlen - 1;
|
|
1354
|
+
} else {
|
|
1355
|
+
if (d <= 143) d = d + 48;
|
|
1356
|
+
else bl = write_bits_1(out, bl, 1);
|
|
1357
|
+
bl = write_bits_8(out, bl, bitswap8[d]);
|
|
1358
|
+
addrs[hash] = boff & 32767;
|
|
1359
|
+
++boff;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
bl = write_bits_8(out, bl, 0) - 1;
|
|
1363
|
+
}
|
|
1364
|
+
out.l = (bl + 7) / 8 | 0;
|
|
1365
|
+
return out.l;
|
|
1366
|
+
}
|
|
1367
|
+
return function _deflateRaw2(data, out) {
|
|
1368
|
+
if (data.length < 8) return write_stored(data, out);
|
|
1369
|
+
return write_huff_fixed(data, out);
|
|
1370
|
+
};
|
|
1371
|
+
})();
|
|
1372
|
+
function _deflate(data) {
|
|
1373
|
+
var buf = new_buf(50 + Math.floor(data.length * 1.1));
|
|
1374
|
+
var off = _deflateRaw(data, buf);
|
|
1375
|
+
return buf.slice(0, off);
|
|
1376
|
+
}
|
|
1377
|
+
var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
|
|
1378
|
+
var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
|
|
1379
|
+
var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128);
|
|
1380
|
+
var dyn_len_1 = 1, dyn_len_2 = 1;
|
|
1381
|
+
function dyn(data, boff) {
|
|
1382
|
+
var _HLIT = read_bits_5(data, boff) + 257;
|
|
1383
|
+
boff += 5;
|
|
1384
|
+
var _HDIST = read_bits_5(data, boff) + 1;
|
|
1385
|
+
boff += 5;
|
|
1386
|
+
var _HCLEN = read_bits_4(data, boff) + 4;
|
|
1387
|
+
boff += 4;
|
|
1388
|
+
var w = 0;
|
|
1389
|
+
var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19);
|
|
1390
|
+
var ctree = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
1391
|
+
var maxlen = 1;
|
|
1392
|
+
var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
|
|
1393
|
+
var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
|
|
1394
|
+
var L = clens.length;
|
|
1395
|
+
for (var i2 = 0; i2 < _HCLEN; ++i2) {
|
|
1396
|
+
clens[CLEN_ORDER[i2]] = w = read_bits_3(data, boff);
|
|
1397
|
+
if (maxlen < w) maxlen = w;
|
|
1398
|
+
bl_count[w]++;
|
|
1399
|
+
boff += 3;
|
|
1400
|
+
}
|
|
1401
|
+
var ccode = 0;
|
|
1402
|
+
bl_count[0] = 0;
|
|
1403
|
+
for (i2 = 1; i2 <= maxlen; ++i2) next_code[i2] = ccode = ccode + bl_count[i2 - 1] << 1;
|
|
1404
|
+
for (i2 = 0; i2 < L; ++i2) if ((ccode = clens[i2]) != 0) ctree[i2] = next_code[ccode]++;
|
|
1405
|
+
var cleni = 0;
|
|
1406
|
+
for (i2 = 0; i2 < L; ++i2) {
|
|
1407
|
+
cleni = clens[i2];
|
|
1408
|
+
if (cleni != 0) {
|
|
1409
|
+
ccode = bitswap8[ctree[i2]] >> 8 - cleni;
|
|
1410
|
+
for (var j = (1 << 7 - cleni) - 1; j >= 0; --j) dyn_cmap[ccode | j << cleni] = cleni & 7 | i2 << 3;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
var hcodes = [];
|
|
1414
|
+
maxlen = 1;
|
|
1415
|
+
for (; hcodes.length < _HLIT + _HDIST; ) {
|
|
1416
|
+
ccode = dyn_cmap[read_bits_7(data, boff)];
|
|
1417
|
+
boff += ccode & 7;
|
|
1418
|
+
switch (ccode >>>= 3) {
|
|
1419
|
+
case 16:
|
|
1420
|
+
w = 3 + read_bits_2(data, boff);
|
|
1421
|
+
boff += 2;
|
|
1422
|
+
ccode = hcodes[hcodes.length - 1];
|
|
1423
|
+
while (w-- > 0) hcodes.push(ccode);
|
|
1424
|
+
break;
|
|
1425
|
+
case 17:
|
|
1426
|
+
w = 3 + read_bits_3(data, boff);
|
|
1427
|
+
boff += 3;
|
|
1428
|
+
while (w-- > 0) hcodes.push(0);
|
|
1429
|
+
break;
|
|
1430
|
+
case 18:
|
|
1431
|
+
w = 11 + read_bits_7(data, boff);
|
|
1432
|
+
boff += 7;
|
|
1433
|
+
while (w-- > 0) hcodes.push(0);
|
|
1434
|
+
break;
|
|
1435
|
+
default:
|
|
1436
|
+
hcodes.push(ccode);
|
|
1437
|
+
if (maxlen < ccode) maxlen = ccode;
|
|
1438
|
+
break;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT);
|
|
1442
|
+
for (i2 = _HLIT; i2 < 286; ++i2) h1[i2] = 0;
|
|
1443
|
+
for (i2 = _HDIST; i2 < 30; ++i2) h2[i2] = 0;
|
|
1444
|
+
dyn_len_1 = build_tree(h1, dyn_lmap, 286);
|
|
1445
|
+
dyn_len_2 = build_tree(h2, dyn_dmap, 30);
|
|
1446
|
+
return boff;
|
|
1447
|
+
}
|
|
1448
|
+
function inflate(data, usz) {
|
|
1449
|
+
if (data[0] == 3 && !(data[1] & 3)) {
|
|
1450
|
+
return [new_raw_buf(usz), 2];
|
|
1451
|
+
}
|
|
1452
|
+
var boff = 0;
|
|
1453
|
+
var header = 0;
|
|
1454
|
+
var outbuf = new_unsafe_buf(usz ? usz : 1 << 18);
|
|
1455
|
+
var woff = 0;
|
|
1456
|
+
var OL = outbuf.length >>> 0;
|
|
1457
|
+
var max_len_1 = 0, max_len_2 = 0;
|
|
1458
|
+
while ((header & 1) == 0) {
|
|
1459
|
+
header = read_bits_3(data, boff);
|
|
1460
|
+
boff += 3;
|
|
1461
|
+
if (header >>> 1 == 0) {
|
|
1462
|
+
if (boff & 7) boff += 8 - (boff & 7);
|
|
1463
|
+
var sz = data[boff >>> 3] | data[(boff >>> 3) + 1] << 8;
|
|
1464
|
+
boff += 32;
|
|
1465
|
+
if (sz > 0) {
|
|
1466
|
+
if (!usz && OL < woff + sz) {
|
|
1467
|
+
outbuf = realloc(outbuf, woff + sz);
|
|
1468
|
+
OL = outbuf.length;
|
|
1469
|
+
}
|
|
1470
|
+
while (sz-- > 0) {
|
|
1471
|
+
outbuf[woff++] = data[boff >>> 3];
|
|
1472
|
+
boff += 8;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
continue;
|
|
1476
|
+
} else if (header >> 1 == 1) {
|
|
1477
|
+
max_len_1 = 9;
|
|
1478
|
+
max_len_2 = 5;
|
|
1479
|
+
} else {
|
|
1480
|
+
boff = dyn(data, boff);
|
|
1481
|
+
max_len_1 = dyn_len_1;
|
|
1482
|
+
max_len_2 = dyn_len_2;
|
|
1483
|
+
}
|
|
1484
|
+
for (; ; ) {
|
|
1485
|
+
if (!usz && OL < woff + 32767) {
|
|
1486
|
+
outbuf = realloc(outbuf, woff + 32767);
|
|
1487
|
+
OL = outbuf.length;
|
|
1488
|
+
}
|
|
1489
|
+
var bits = read_bits_n(data, boff, max_len_1);
|
|
1490
|
+
var code = header >>> 1 == 1 ? fix_lmap[bits] : dyn_lmap[bits];
|
|
1491
|
+
boff += code & 15;
|
|
1492
|
+
code >>>= 4;
|
|
1493
|
+
if ((code >>> 8 & 255) === 0) outbuf[woff++] = code;
|
|
1494
|
+
else if (code == 256) break;
|
|
1495
|
+
else {
|
|
1496
|
+
code -= 257;
|
|
1497
|
+
var len_eb = code < 8 ? 0 : code - 4 >> 2;
|
|
1498
|
+
if (len_eb > 5) len_eb = 0;
|
|
1499
|
+
var tgt = woff + LEN_LN[code];
|
|
1500
|
+
if (len_eb > 0) {
|
|
1501
|
+
tgt += read_bits_n(data, boff, len_eb);
|
|
1502
|
+
boff += len_eb;
|
|
1503
|
+
}
|
|
1504
|
+
bits = read_bits_n(data, boff, max_len_2);
|
|
1505
|
+
code = header >>> 1 == 1 ? fix_dmap[bits] : dyn_dmap[bits];
|
|
1506
|
+
boff += code & 15;
|
|
1507
|
+
code >>>= 4;
|
|
1508
|
+
var dst_eb = code < 4 ? 0 : code - 2 >> 1;
|
|
1509
|
+
var dst = DST_LN[code];
|
|
1510
|
+
if (dst_eb > 0) {
|
|
1511
|
+
dst += read_bits_n(data, boff, dst_eb);
|
|
1512
|
+
boff += dst_eb;
|
|
1513
|
+
}
|
|
1514
|
+
if (!usz && OL < tgt) {
|
|
1515
|
+
outbuf = realloc(outbuf, tgt + 100);
|
|
1516
|
+
OL = outbuf.length;
|
|
1517
|
+
}
|
|
1518
|
+
while (woff < tgt) {
|
|
1519
|
+
outbuf[woff] = outbuf[woff - dst];
|
|
1520
|
+
++woff;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
if (usz) return [outbuf, boff + 7 >>> 3];
|
|
1526
|
+
return [outbuf.slice(0, woff), boff + 7 >>> 3];
|
|
1527
|
+
}
|
|
1528
|
+
function _inflate(payload, usz) {
|
|
1529
|
+
var data = payload.slice(payload.l || 0);
|
|
1530
|
+
var out = inflate(data, usz);
|
|
1531
|
+
payload.l += out[1];
|
|
1532
|
+
return out[0];
|
|
1533
|
+
}
|
|
1534
|
+
function warn_or_throw(wrn, msg) {
|
|
1535
|
+
if (wrn) {
|
|
1536
|
+
if (typeof console !== "undefined") console.error(msg);
|
|
1537
|
+
} else throw new Error(msg);
|
|
1538
|
+
}
|
|
1539
|
+
function parse_zip(file, options) {
|
|
1540
|
+
var blob = file;
|
|
1541
|
+
prep_blob(blob, 0);
|
|
1542
|
+
var FileIndex = [], FullPaths = [];
|
|
1543
|
+
var o = {
|
|
1544
|
+
FileIndex,
|
|
1545
|
+
FullPaths
|
|
1546
|
+
};
|
|
1547
|
+
init_cfb(o, { root: options.root });
|
|
1548
|
+
var i2 = blob.length - 4;
|
|
1549
|
+
while ((blob[i2] != 80 || blob[i2 + 1] != 75 || blob[i2 + 2] != 5 || blob[i2 + 3] != 6) && i2 >= 0) --i2;
|
|
1550
|
+
blob.l = i2 + 4;
|
|
1551
|
+
blob.l += 4;
|
|
1552
|
+
var fcnt = blob.read_shift(2);
|
|
1553
|
+
blob.l += 6;
|
|
1554
|
+
var start_cd = blob.read_shift(4);
|
|
1555
|
+
blob.l = start_cd;
|
|
1556
|
+
for (i2 = 0; i2 < fcnt; ++i2) {
|
|
1557
|
+
blob.l += 20;
|
|
1558
|
+
var csz = blob.read_shift(4);
|
|
1559
|
+
var usz = blob.read_shift(4);
|
|
1560
|
+
var namelen = blob.read_shift(2);
|
|
1561
|
+
var efsz = blob.read_shift(2);
|
|
1562
|
+
var fcsz = blob.read_shift(2);
|
|
1563
|
+
blob.l += 8;
|
|
1564
|
+
var offset = blob.read_shift(4);
|
|
1565
|
+
var EF = parse_extra_field(blob.slice(blob.l + namelen, blob.l + namelen + efsz));
|
|
1566
|
+
blob.l += namelen + efsz + fcsz;
|
|
1567
|
+
var L = blob.l;
|
|
1568
|
+
blob.l = offset + 4;
|
|
1569
|
+
parse_local_file(blob, csz, usz, o, EF);
|
|
1570
|
+
blob.l = L;
|
|
1571
|
+
}
|
|
1572
|
+
return o;
|
|
1573
|
+
}
|
|
1574
|
+
function parse_local_file(blob, csz, usz, o, EF) {
|
|
1575
|
+
blob.l += 2;
|
|
1576
|
+
var flags = blob.read_shift(2);
|
|
1577
|
+
var meth = blob.read_shift(2);
|
|
1578
|
+
var date = parse_dos_date(blob);
|
|
1579
|
+
if (flags & 8257) throw new Error("Unsupported ZIP encryption");
|
|
1580
|
+
var crc32 = blob.read_shift(4);
|
|
1581
|
+
var _csz = blob.read_shift(4);
|
|
1582
|
+
var _usz = blob.read_shift(4);
|
|
1583
|
+
var namelen = blob.read_shift(2);
|
|
1584
|
+
var efsz = blob.read_shift(2);
|
|
1585
|
+
var name = "";
|
|
1586
|
+
for (var i2 = 0; i2 < namelen; ++i2) name += String.fromCharCode(blob[blob.l++]);
|
|
1587
|
+
if (efsz) {
|
|
1588
|
+
var ef = parse_extra_field(blob.slice(blob.l, blob.l + efsz));
|
|
1589
|
+
if ((ef[21589] || {}).mt) date = ef[21589].mt;
|
|
1590
|
+
if (((EF || {})[21589] || {}).mt) date = EF[21589].mt;
|
|
1591
|
+
}
|
|
1592
|
+
blob.l += efsz;
|
|
1593
|
+
var data = blob.slice(blob.l, blob.l + _csz);
|
|
1594
|
+
switch (meth) {
|
|
1595
|
+
case 8:
|
|
1596
|
+
data = _inflateRawSync(blob, _usz);
|
|
1597
|
+
break;
|
|
1598
|
+
case 0:
|
|
1599
|
+
break;
|
|
1600
|
+
// TODO: scan for magic number
|
|
1601
|
+
default:
|
|
1602
|
+
throw new Error("Unsupported ZIP Compression method " + meth);
|
|
1603
|
+
}
|
|
1604
|
+
var wrn = false;
|
|
1605
|
+
if (flags & 8) {
|
|
1606
|
+
crc32 = blob.read_shift(4);
|
|
1607
|
+
if (crc32 == 134695760) {
|
|
1608
|
+
crc32 = blob.read_shift(4);
|
|
1609
|
+
wrn = true;
|
|
1610
|
+
}
|
|
1611
|
+
_csz = blob.read_shift(4);
|
|
1612
|
+
_usz = blob.read_shift(4);
|
|
1613
|
+
}
|
|
1614
|
+
if (_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz);
|
|
1615
|
+
if (_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz);
|
|
1616
|
+
var _crc32 = CRC32.buf(data, 0);
|
|
1617
|
+
if (crc32 >> 0 != _crc32 >> 0) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32);
|
|
1618
|
+
cfb_add(o, name, data, { unsafe: true, mt: date });
|
|
1619
|
+
}
|
|
1620
|
+
function write_zip(cfb, options) {
|
|
1621
|
+
var _opts = options || {};
|
|
1622
|
+
var out = [], cdirs = [];
|
|
1623
|
+
var o = new_buf(1);
|
|
1624
|
+
var method = _opts.compression ? 8 : 0, flags = 0;
|
|
1625
|
+
var desc = false;
|
|
1626
|
+
if (desc) flags |= 8;
|
|
1627
|
+
var i2 = 0, j = 0;
|
|
1628
|
+
var start_cd = 0, fcnt = 0;
|
|
1629
|
+
var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0];
|
|
1630
|
+
var crcs = [];
|
|
1631
|
+
var sz_cd = 0;
|
|
1632
|
+
for (i2 = 1; i2 < cfb.FullPaths.length; ++i2) {
|
|
1633
|
+
fp = cfb.FullPaths[i2].slice(root.length);
|
|
1634
|
+
fi = cfb.FileIndex[i2];
|
|
1635
|
+
if (!fi.size || !fi.content || fp == "Sh33tJ5") continue;
|
|
1636
|
+
var start = start_cd;
|
|
1637
|
+
var namebuf = new_buf(fp.length);
|
|
1638
|
+
for (j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 127);
|
|
1639
|
+
namebuf = namebuf.slice(0, namebuf.l);
|
|
1640
|
+
crcs[fcnt] = CRC32.buf(fi.content, 0);
|
|
1641
|
+
var outbuf = fi.content;
|
|
1642
|
+
if (method == 8) outbuf = _deflateRawSync(outbuf);
|
|
1643
|
+
o = new_buf(30);
|
|
1644
|
+
o.write_shift(4, 67324752);
|
|
1645
|
+
o.write_shift(2, 20);
|
|
1646
|
+
o.write_shift(2, flags);
|
|
1647
|
+
o.write_shift(2, method);
|
|
1648
|
+
if (fi.mt) write_dos_date(o, fi.mt);
|
|
1649
|
+
else o.write_shift(4, 0);
|
|
1650
|
+
o.write_shift(-4, flags & 8 ? 0 : crcs[fcnt]);
|
|
1651
|
+
o.write_shift(4, flags & 8 ? 0 : outbuf.length);
|
|
1652
|
+
o.write_shift(4, flags & 8 ? 0 : fi.content.length);
|
|
1653
|
+
o.write_shift(2, namebuf.length);
|
|
1654
|
+
o.write_shift(2, 0);
|
|
1655
|
+
start_cd += o.length;
|
|
1656
|
+
out.push(o);
|
|
1657
|
+
start_cd += namebuf.length;
|
|
1658
|
+
out.push(namebuf);
|
|
1659
|
+
start_cd += outbuf.length;
|
|
1660
|
+
out.push(outbuf);
|
|
1661
|
+
if (flags & 8) {
|
|
1662
|
+
o = new_buf(12);
|
|
1663
|
+
o.write_shift(-4, crcs[fcnt]);
|
|
1664
|
+
o.write_shift(4, outbuf.length);
|
|
1665
|
+
o.write_shift(4, fi.content.length);
|
|
1666
|
+
start_cd += o.l;
|
|
1667
|
+
out.push(o);
|
|
1668
|
+
}
|
|
1669
|
+
o = new_buf(46);
|
|
1670
|
+
o.write_shift(4, 33639248);
|
|
1671
|
+
o.write_shift(2, 0);
|
|
1672
|
+
o.write_shift(2, 20);
|
|
1673
|
+
o.write_shift(2, flags);
|
|
1674
|
+
o.write_shift(2, method);
|
|
1675
|
+
o.write_shift(4, 0);
|
|
1676
|
+
o.write_shift(-4, crcs[fcnt]);
|
|
1677
|
+
o.write_shift(4, outbuf.length);
|
|
1678
|
+
o.write_shift(4, fi.content.length);
|
|
1679
|
+
o.write_shift(2, namebuf.length);
|
|
1680
|
+
o.write_shift(2, 0);
|
|
1681
|
+
o.write_shift(2, 0);
|
|
1682
|
+
o.write_shift(2, 0);
|
|
1683
|
+
o.write_shift(2, 0);
|
|
1684
|
+
o.write_shift(4, 0);
|
|
1685
|
+
o.write_shift(4, start);
|
|
1686
|
+
sz_cd += o.l;
|
|
1687
|
+
cdirs.push(o);
|
|
1688
|
+
sz_cd += namebuf.length;
|
|
1689
|
+
cdirs.push(namebuf);
|
|
1690
|
+
++fcnt;
|
|
1691
|
+
}
|
|
1692
|
+
o = new_buf(22);
|
|
1693
|
+
o.write_shift(4, 101010256);
|
|
1694
|
+
o.write_shift(2, 0);
|
|
1695
|
+
o.write_shift(2, 0);
|
|
1696
|
+
o.write_shift(2, fcnt);
|
|
1697
|
+
o.write_shift(2, fcnt);
|
|
1698
|
+
o.write_shift(4, sz_cd);
|
|
1699
|
+
o.write_shift(4, start_cd);
|
|
1700
|
+
o.write_shift(2, 0);
|
|
1701
|
+
return bconcat([bconcat(out), bconcat(cdirs), o]);
|
|
1702
|
+
}
|
|
1703
|
+
var ContentTypeMap = {
|
|
1704
|
+
"htm": "text/html",
|
|
1705
|
+
"xml": "text/xml",
|
|
1706
|
+
"gif": "image/gif",
|
|
1707
|
+
"jpg": "image/jpeg",
|
|
1708
|
+
"png": "image/png",
|
|
1709
|
+
"mso": "application/x-mso",
|
|
1710
|
+
"thmx": "application/vnd.ms-officetheme",
|
|
1711
|
+
"sh33tj5": "application/octet-stream"
|
|
1712
|
+
};
|
|
1713
|
+
function get_content_type(fi, fp) {
|
|
1714
|
+
if (fi.ctype) return fi.ctype;
|
|
1715
|
+
var ext = fi.name || "", m = ext.match(/\.([^\.]+)$/);
|
|
1716
|
+
if (m && ContentTypeMap[m[1]]) return ContentTypeMap[m[1]];
|
|
1717
|
+
if (fp) {
|
|
1718
|
+
m = (ext = fp).match(/[\.\\]([^\.\\])+$/);
|
|
1719
|
+
if (m && ContentTypeMap[m[1]]) return ContentTypeMap[m[1]];
|
|
1720
|
+
}
|
|
1721
|
+
return "application/octet-stream";
|
|
1722
|
+
}
|
|
1723
|
+
function write_base64_76(bstr) {
|
|
1724
|
+
var data = Base64_encode(bstr);
|
|
1725
|
+
var o = [];
|
|
1726
|
+
for (var i2 = 0; i2 < data.length; i2 += 76) o.push(data.slice(i2, i2 + 76));
|
|
1727
|
+
return o.join("\r\n") + "\r\n";
|
|
1728
|
+
}
|
|
1729
|
+
function write_quoted_printable(text) {
|
|
1730
|
+
var encoded = text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF=]/g, function(c) {
|
|
1731
|
+
var w = c.charCodeAt(0).toString(16).toUpperCase();
|
|
1732
|
+
return "=" + (w.length == 1 ? "0" + w : w);
|
|
1733
|
+
});
|
|
1734
|
+
encoded = encoded.replace(/ $/mg, "=20").replace(/\t$/mg, "=09");
|
|
1735
|
+
if (encoded.charAt(0) == "\n") encoded = "=0D" + encoded.slice(1);
|
|
1736
|
+
encoded = encoded.replace(/\r(?!\n)/mg, "=0D").replace(/\n\n/mg, "\n=0A").replace(/([^\r\n])\n/mg, "$1=0A");
|
|
1737
|
+
var o = [], split = encoded.split("\r\n");
|
|
1738
|
+
for (var si = 0; si < split.length; ++si) {
|
|
1739
|
+
var str = split[si];
|
|
1740
|
+
if (str.length == 0) {
|
|
1741
|
+
o.push("");
|
|
1742
|
+
continue;
|
|
1743
|
+
}
|
|
1744
|
+
for (var i2 = 0; i2 < str.length; ) {
|
|
1745
|
+
var end = 76;
|
|
1746
|
+
var tmp = str.slice(i2, i2 + end);
|
|
1747
|
+
if (tmp.charAt(end - 1) == "=") end--;
|
|
1748
|
+
else if (tmp.charAt(end - 2) == "=") end -= 2;
|
|
1749
|
+
else if (tmp.charAt(end - 3) == "=") end -= 3;
|
|
1750
|
+
tmp = str.slice(i2, i2 + end);
|
|
1751
|
+
i2 += end;
|
|
1752
|
+
if (i2 < str.length) tmp += "=";
|
|
1753
|
+
o.push(tmp);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
return o.join("\r\n");
|
|
1757
|
+
}
|
|
1758
|
+
function parse_quoted_printable(data) {
|
|
1759
|
+
var o = [];
|
|
1760
|
+
for (var di = 0; di < data.length; ++di) {
|
|
1761
|
+
var line = data[di];
|
|
1762
|
+
while (di <= data.length && line.charAt(line.length - 1) == "=") line = line.slice(0, line.length - 1) + data[++di];
|
|
1763
|
+
o.push(line);
|
|
1764
|
+
}
|
|
1765
|
+
for (var oi = 0; oi < o.length; ++oi) o[oi] = o[oi].replace(/[=][0-9A-Fa-f]{2}/g, function($$) {
|
|
1766
|
+
return String.fromCharCode(parseInt($$.slice(1), 16));
|
|
1767
|
+
});
|
|
1768
|
+
return s2a(o.join("\r\n"));
|
|
1769
|
+
}
|
|
1770
|
+
function parse_mime(cfb, data, root) {
|
|
1771
|
+
var fname = "", cte = "", ctype = "", fdata;
|
|
1772
|
+
var di = 0;
|
|
1773
|
+
for (; di < 10; ++di) {
|
|
1774
|
+
var line = data[di];
|
|
1775
|
+
if (!line || line.match(/^\s*$/)) break;
|
|
1776
|
+
var m = line.match(/^(.*?):\s*([^\s].*)$/);
|
|
1777
|
+
if (m) switch (m[1].toLowerCase()) {
|
|
1778
|
+
case "content-location":
|
|
1779
|
+
fname = m[2].trim();
|
|
1780
|
+
break;
|
|
1781
|
+
case "content-type":
|
|
1782
|
+
ctype = m[2].trim();
|
|
1783
|
+
break;
|
|
1784
|
+
case "content-transfer-encoding":
|
|
1785
|
+
cte = m[2].trim();
|
|
1786
|
+
break;
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
++di;
|
|
1790
|
+
switch (cte.toLowerCase()) {
|
|
1791
|
+
case "base64":
|
|
1792
|
+
fdata = s2a(Base64_decode(data.slice(di).join("")));
|
|
1793
|
+
break;
|
|
1794
|
+
case "quoted-printable":
|
|
1795
|
+
fdata = parse_quoted_printable(data.slice(di));
|
|
1796
|
+
break;
|
|
1797
|
+
default:
|
|
1798
|
+
throw new Error("Unsupported Content-Transfer-Encoding " + cte);
|
|
1799
|
+
}
|
|
1800
|
+
var file = cfb_add(cfb, fname.slice(root.length), fdata, { unsafe: true });
|
|
1801
|
+
if (ctype) file.ctype = ctype;
|
|
1802
|
+
}
|
|
1803
|
+
function parse_mad(file, options) {
|
|
1804
|
+
if (a2s(file.slice(0, 13)).toLowerCase() != "mime-version:") throw new Error("Unsupported MAD header");
|
|
1805
|
+
var root = options && options.root || "";
|
|
1806
|
+
var data = (has_buf && Buffer.isBuffer(file) ? file.toString("binary") : a2s(file)).split("\r\n");
|
|
1807
|
+
var di = 0, row = "";
|
|
1808
|
+
for (di = 0; di < data.length; ++di) {
|
|
1809
|
+
row = data[di];
|
|
1810
|
+
if (!/^Content-Location:/i.test(row)) continue;
|
|
1811
|
+
row = row.slice(row.indexOf("file"));
|
|
1812
|
+
if (!root) root = row.slice(0, row.lastIndexOf("/") + 1);
|
|
1813
|
+
if (row.slice(0, root.length) == root) continue;
|
|
1814
|
+
while (root.length > 0) {
|
|
1815
|
+
root = root.slice(0, root.length - 1);
|
|
1816
|
+
root = root.slice(0, root.lastIndexOf("/") + 1);
|
|
1817
|
+
if (row.slice(0, root.length) == root) break;
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
var mboundary = (data[1] || "").match(/boundary="(.*?)"/);
|
|
1821
|
+
if (!mboundary) throw new Error("MAD cannot find boundary");
|
|
1822
|
+
var boundary = "--" + (mboundary[1] || "");
|
|
1823
|
+
var FileIndex = [], FullPaths = [];
|
|
1824
|
+
var o = {
|
|
1825
|
+
FileIndex,
|
|
1826
|
+
FullPaths
|
|
1827
|
+
};
|
|
1828
|
+
init_cfb(o);
|
|
1829
|
+
var start_di, fcnt = 0;
|
|
1830
|
+
for (di = 0; di < data.length; ++di) {
|
|
1831
|
+
var line = data[di];
|
|
1832
|
+
if (line !== boundary && line !== boundary + "--") continue;
|
|
1833
|
+
if (fcnt++) parse_mime(o, data.slice(start_di, di), root);
|
|
1834
|
+
start_di = di;
|
|
1835
|
+
}
|
|
1836
|
+
return o;
|
|
1837
|
+
}
|
|
1838
|
+
function write_mad(cfb, options) {
|
|
1839
|
+
var opts = options || {};
|
|
1840
|
+
var boundary = opts.boundary || "SheetJS";
|
|
1841
|
+
boundary = "------=" + boundary;
|
|
1842
|
+
var out = [
|
|
1843
|
+
"MIME-Version: 1.0",
|
|
1844
|
+
'Content-Type: multipart/related; boundary="' + boundary.slice(2) + '"',
|
|
1845
|
+
"",
|
|
1846
|
+
"",
|
|
1847
|
+
""
|
|
1848
|
+
];
|
|
1849
|
+
var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0];
|
|
1850
|
+
for (var i2 = 1; i2 < cfb.FullPaths.length; ++i2) {
|
|
1851
|
+
fp = cfb.FullPaths[i2].slice(root.length);
|
|
1852
|
+
fi = cfb.FileIndex[i2];
|
|
1853
|
+
if (!fi.size || !fi.content || fp == "Sh33tJ5") continue;
|
|
1854
|
+
fp = fp.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF]/g, function(c) {
|
|
1855
|
+
return "_x" + c.charCodeAt(0).toString(16) + "_";
|
|
1856
|
+
}).replace(/[\u0080-\uFFFF]/g, function(u) {
|
|
1857
|
+
return "_u" + u.charCodeAt(0).toString(16) + "_";
|
|
1858
|
+
});
|
|
1859
|
+
var ca = fi.content;
|
|
1860
|
+
var cstr = has_buf && Buffer.isBuffer(ca) ? ca.toString("binary") : a2s(ca);
|
|
1861
|
+
var dispcnt = 0, L = Math.min(1024, cstr.length), cc = 0;
|
|
1862
|
+
for (var csl = 0; csl <= L; ++csl) if ((cc = cstr.charCodeAt(csl)) >= 32 && cc < 128) ++dispcnt;
|
|
1863
|
+
var qp = dispcnt >= L * 4 / 5;
|
|
1864
|
+
out.push(boundary);
|
|
1865
|
+
out.push("Content-Location: " + (opts.root || "file:///C:/SheetJS/") + fp);
|
|
1866
|
+
out.push("Content-Transfer-Encoding: " + (qp ? "quoted-printable" : "base64"));
|
|
1867
|
+
out.push("Content-Type: " + get_content_type(fi, fp));
|
|
1868
|
+
out.push("");
|
|
1869
|
+
out.push(qp ? write_quoted_printable(cstr) : write_base64_76(cstr));
|
|
1870
|
+
}
|
|
1871
|
+
out.push(boundary + "--\r\n");
|
|
1872
|
+
return out.join("\r\n");
|
|
1873
|
+
}
|
|
1874
|
+
function cfb_new(opts) {
|
|
1875
|
+
var o = {};
|
|
1876
|
+
init_cfb(o, opts);
|
|
1877
|
+
return o;
|
|
1878
|
+
}
|
|
1879
|
+
function cfb_add(cfb, name, content, opts) {
|
|
1880
|
+
var unsafe = opts && opts.unsafe;
|
|
1881
|
+
if (!unsafe) init_cfb(cfb);
|
|
1882
|
+
var file = !unsafe && CFB2.find(cfb, name);
|
|
1883
|
+
if (!file) {
|
|
1884
|
+
var fpath = cfb.FullPaths[0];
|
|
1885
|
+
if (name.slice(0, fpath.length) == fpath) fpath = name;
|
|
1886
|
+
else {
|
|
1887
|
+
if (fpath.slice(-1) != "/") fpath += "/";
|
|
1888
|
+
fpath = (fpath + name).replace("//", "/");
|
|
1889
|
+
}
|
|
1890
|
+
file = { name: filename(name), type: 2 };
|
|
1891
|
+
cfb.FileIndex.push(file);
|
|
1892
|
+
cfb.FullPaths.push(fpath);
|
|
1893
|
+
if (!unsafe) CFB2.utils.cfb_gc(cfb);
|
|
1894
|
+
}
|
|
1895
|
+
file.content = content;
|
|
1896
|
+
file.size = content ? content.length : 0;
|
|
1897
|
+
if (opts) {
|
|
1898
|
+
if (opts.CLSID) file.clsid = opts.CLSID;
|
|
1899
|
+
if (opts.mt) file.mt = opts.mt;
|
|
1900
|
+
if (opts.ct) file.ct = opts.ct;
|
|
1901
|
+
}
|
|
1902
|
+
return file;
|
|
1903
|
+
}
|
|
1904
|
+
function cfb_del(cfb, name) {
|
|
1905
|
+
init_cfb(cfb);
|
|
1906
|
+
var file = CFB2.find(cfb, name);
|
|
1907
|
+
if (file) {
|
|
1908
|
+
for (var j = 0; j < cfb.FileIndex.length; ++j) if (cfb.FileIndex[j] == file) {
|
|
1909
|
+
cfb.FileIndex.splice(j, 1);
|
|
1910
|
+
cfb.FullPaths.splice(j, 1);
|
|
1911
|
+
return true;
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
return false;
|
|
1915
|
+
}
|
|
1916
|
+
function cfb_mov(cfb, old_name, new_name) {
|
|
1917
|
+
init_cfb(cfb);
|
|
1918
|
+
var file = CFB2.find(cfb, old_name);
|
|
1919
|
+
if (file) {
|
|
1920
|
+
for (var j = 0; j < cfb.FileIndex.length; ++j) if (cfb.FileIndex[j] == file) {
|
|
1921
|
+
cfb.FileIndex[j].name = filename(new_name);
|
|
1922
|
+
cfb.FullPaths[j] = new_name;
|
|
1923
|
+
return true;
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
return false;
|
|
1927
|
+
}
|
|
1928
|
+
function cfb_gc(cfb) {
|
|
1929
|
+
rebuild_cfb(cfb, true);
|
|
1930
|
+
}
|
|
1931
|
+
exports3.find = find2;
|
|
1932
|
+
exports3.read = read;
|
|
1933
|
+
exports3.parse = parse3;
|
|
1934
|
+
exports3.write = write;
|
|
1935
|
+
exports3.writeFile = write_file;
|
|
1936
|
+
exports3.utils = {
|
|
1937
|
+
cfb_new,
|
|
1938
|
+
cfb_add,
|
|
1939
|
+
cfb_del,
|
|
1940
|
+
cfb_mov,
|
|
1941
|
+
cfb_gc,
|
|
1942
|
+
ReadShift,
|
|
1943
|
+
CheckField,
|
|
1944
|
+
prep_blob,
|
|
1945
|
+
bconcat,
|
|
1946
|
+
use_zlib,
|
|
1947
|
+
_deflateRaw: _deflate,
|
|
1948
|
+
_inflateRaw: _inflate,
|
|
1949
|
+
consts
|
|
1950
|
+
};
|
|
1951
|
+
return exports3;
|
|
1952
|
+
})();
|
|
1953
|
+
if (typeof require !== "undefined" && typeof module2 !== "undefined" && typeof DO_NOT_EXPORT_CFB === "undefined") {
|
|
1954
|
+
module2.exports = CFB2;
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
});
|
|
1958
|
+
|
|
1959
|
+
// src/ocr/auto-detect.ts
|
|
1960
|
+
function detectAvailableOcr() {
|
|
1961
|
+
for (const cli of CLI_PRIORITY) {
|
|
1962
|
+
if (isCliInstalled(cli)) return cli;
|
|
1963
|
+
}
|
|
1964
|
+
if (isTesseractAvailable()) return "tesseract";
|
|
1965
|
+
return null;
|
|
1966
|
+
}
|
|
1967
|
+
function isCliInstalled(name) {
|
|
1968
|
+
try {
|
|
1969
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
1970
|
+
(0, import_child_process.execSync)(`${cmd} ${name}`, { stdio: "ignore", timeout: 3e3 });
|
|
1971
|
+
return true;
|
|
1972
|
+
} catch {
|
|
1973
|
+
return false;
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
function isTesseractAvailable() {
|
|
1977
|
+
try {
|
|
1978
|
+
const require2 = (0, import_module.createRequire)(import_meta.url);
|
|
1979
|
+
require2.resolve("tesseract.js");
|
|
1980
|
+
return true;
|
|
1981
|
+
} catch {
|
|
1982
|
+
return false;
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
function validateOcrMode(mode) {
|
|
1986
|
+
if (mode === "auto" || mode === "off") return;
|
|
1987
|
+
if (mode === "tesseract") {
|
|
1988
|
+
if (!isTesseractAvailable()) {
|
|
1989
|
+
throw new Error(
|
|
1990
|
+
"tesseract.js\uAC00 \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.\n\uC124\uCE58: npm install tesseract.js"
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
if (!isCliInstalled(mode)) {
|
|
1996
|
+
throw new Error(`'${mode}' CLI\uAC00 \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
|
|
1997
|
+
${getInstallGuide(mode)}`);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
function getInstallGuide(mode) {
|
|
2001
|
+
const guides = {
|
|
2002
|
+
gemini: "\uC124\uCE58: https://ai.google.dev/gemini-api/docs/cli",
|
|
2003
|
+
claude: "\uC124\uCE58: npm install -g @anthropic-ai/claude-code \uB610\uB294 https://claude.ai/code",
|
|
2004
|
+
codex: "\uC124\uCE58: npm install -g @openai/codex \uB610\uB294 https://github.com/openai/codex",
|
|
2005
|
+
ollama: "\uC124\uCE58: brew install ollama \uB610\uB294 https://ollama.com/download"
|
|
2006
|
+
};
|
|
2007
|
+
return guides[mode] || `'${mode}'\uC744(\uB97C) \uC124\uCE58\uD574\uC8FC\uC138\uC694.`;
|
|
2008
|
+
}
|
|
2009
|
+
var import_child_process, import_module, import_meta, CLI_PRIORITY;
|
|
2010
|
+
var init_auto_detect = __esm({
|
|
2011
|
+
"src/ocr/auto-detect.ts"() {
|
|
2012
|
+
"use strict";
|
|
2013
|
+
import_child_process = require("child_process");
|
|
2014
|
+
import_module = require("module");
|
|
2015
|
+
import_meta = {};
|
|
2016
|
+
CLI_PRIORITY = ["gemini", "claude", "codex", "ollama"];
|
|
2017
|
+
}
|
|
2018
|
+
});
|
|
2019
|
+
|
|
2020
|
+
// src/ocr/cli-provider.ts
|
|
2021
|
+
function getTempDir() {
|
|
2022
|
+
if (!_tempDir) _tempDir = (0, import_fs.mkdtempSync)((0, import_path.join)((0, import_os.tmpdir)(), "kordoc-ocr-"));
|
|
2023
|
+
return _tempDir;
|
|
2024
|
+
}
|
|
2025
|
+
function createCliOcrProvider(mode) {
|
|
2026
|
+
return async (pageImage, pageNumber) => {
|
|
2027
|
+
const tempPath = (0, import_path.join)(getTempDir(), `page-${pageNumber}.png`);
|
|
2028
|
+
try {
|
|
2029
|
+
(0, import_fs.writeFileSync)(tempPath, pageImage);
|
|
2030
|
+
let output;
|
|
2031
|
+
if (mode === "ollama") {
|
|
2032
|
+
output = await callOllamaApi(tempPath);
|
|
2033
|
+
} else {
|
|
2034
|
+
output = callCli(mode, tempPath);
|
|
2035
|
+
}
|
|
2036
|
+
return { markdown: stripCodeFence(output.trim()) };
|
|
2037
|
+
} finally {
|
|
2038
|
+
try {
|
|
2039
|
+
(0, import_fs.unlinkSync)(tempPath);
|
|
2040
|
+
} catch {
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
};
|
|
2044
|
+
}
|
|
2045
|
+
function callCli(mode, imagePath) {
|
|
2046
|
+
const args = buildCliArgs(mode, imagePath);
|
|
2047
|
+
const result = (0, import_child_process2.spawnSync)(mode === "codex" ? "codex" : mode, args, {
|
|
2048
|
+
encoding: "utf-8",
|
|
2049
|
+
timeout: 6e4,
|
|
2050
|
+
maxBuffer: 10 * 1024 * 1024
|
|
2051
|
+
});
|
|
2052
|
+
if (result.error) {
|
|
2053
|
+
throw new Error(`${mode} CLI \uC2E4\uD589 \uC2E4\uD328: ${result.error.message}`);
|
|
2054
|
+
}
|
|
2055
|
+
if (result.status !== 0) {
|
|
2056
|
+
const errMsg = result.stderr?.trim() || `exit code ${result.status}`;
|
|
2057
|
+
throw new Error(`${mode} OCR \uC2E4\uD328: ${errMsg}`);
|
|
2058
|
+
}
|
|
2059
|
+
return result.stdout || "";
|
|
2060
|
+
}
|
|
2061
|
+
function buildCliArgs(mode, imagePath) {
|
|
2062
|
+
const promptWithImage = `${OCR_PROMPT}
|
|
2063
|
+
|
|
2064
|
+
\uC774\uBBF8\uC9C0: @${imagePath}`;
|
|
2065
|
+
const promptOnly = OCR_PROMPT;
|
|
2066
|
+
switch (mode) {
|
|
2067
|
+
case "gemini":
|
|
2068
|
+
return ["--prompt", promptWithImage, "--yolo"];
|
|
2069
|
+
case "claude":
|
|
2070
|
+
return ["--print", promptWithImage];
|
|
2071
|
+
case "codex":
|
|
2072
|
+
return ["exec", "--image", imagePath, promptOnly];
|
|
2073
|
+
default:
|
|
2074
|
+
throw new Error(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 CLI: ${mode}`);
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
async function callOllamaApi(imagePath) {
|
|
2078
|
+
const { readFileSync } = await import("fs");
|
|
2079
|
+
const imageBase64 = readFileSync(imagePath).toString("base64");
|
|
2080
|
+
const model = process.env.KORDOC_OLLAMA_MODEL || "gemma4:27b";
|
|
2081
|
+
const host = process.env.KORDOC_OLLAMA_HOST || "http://localhost:11434";
|
|
2082
|
+
const response = await fetch(`${host}/api/chat`, {
|
|
2083
|
+
method: "POST",
|
|
2084
|
+
headers: { "Content-Type": "application/json" },
|
|
2085
|
+
body: JSON.stringify({
|
|
2086
|
+
model,
|
|
2087
|
+
messages: [{
|
|
2088
|
+
role: "user",
|
|
2089
|
+
content: OCR_PROMPT,
|
|
2090
|
+
images: [imageBase64]
|
|
2091
|
+
}],
|
|
2092
|
+
stream: false
|
|
2093
|
+
}),
|
|
2094
|
+
signal: AbortSignal.timeout(6e4)
|
|
2095
|
+
});
|
|
2096
|
+
if (!response.ok) {
|
|
2097
|
+
throw new Error(`Ollama API \uC624\uB958: ${response.status} ${response.statusText}`);
|
|
2098
|
+
}
|
|
2099
|
+
const data = await response.json();
|
|
2100
|
+
return data.message?.content || "";
|
|
2101
|
+
}
|
|
2102
|
+
function stripCodeFence(text) {
|
|
2103
|
+
const match = text.match(/^```(?:markdown|md)?\s*\n([\s\S]*?)\n```\s*$/m);
|
|
2104
|
+
return match ? match[1].trim() : text;
|
|
2105
|
+
}
|
|
2106
|
+
var import_child_process2, import_fs, import_path, import_os, OCR_PROMPT, _tempDir;
|
|
2107
|
+
var init_cli_provider = __esm({
|
|
2108
|
+
"src/ocr/cli-provider.ts"() {
|
|
2109
|
+
"use strict";
|
|
2110
|
+
import_child_process2 = require("child_process");
|
|
2111
|
+
import_fs = require("fs");
|
|
2112
|
+
import_path = require("path");
|
|
2113
|
+
import_os = require("os");
|
|
2114
|
+
OCR_PROMPT = "\uC774 PDF \uD398\uC774\uC9C0 \uC774\uBBF8\uC9C0\uC5D0\uC11C \uD14D\uC2A4\uD2B8\uC640 \uD14C\uC774\uBE14\uC744 \uCD94\uCD9C\uD558\uC5EC \uC21C\uC218 Markdown\uC73C\uB85C \uBCC0\uD658\uD558\uC138\uC694.\n\uADDC\uCE59:\n- \uD14C\uC774\uBE14\uC740 Markdown \uD14C\uC774\uBE14 \uBB38\uBC95 \uC0AC\uC6A9 (| \uAD6C\uBD84, |---|---| \uD5E4\uB354 \uAD6C\uBD84\uC120 \uD3EC\uD568)\n- \uBCD1\uD569\uB41C \uC140\uC740 \uD574\uB2F9 \uC704\uCE58\uC5D0 \uB0B4\uC6A9 \uAE30\uC7AC\n- \uD5E4\uB529\uC740 \uAE00\uC790 \uD06C\uAE30\uC5D0 \uB530\uB77C ## ~ ###### \uC0AC\uC6A9\n- \uB9AC\uC2A4\uD2B8\uB294 - \uB610\uB294 1. \uC0AC\uC6A9\n- \uC774\uBBF8\uC9C0, \uB3C4\uD615 \uB4F1 \uBE44\uD14D\uC2A4\uD2B8 \uC694\uC18C\uB294 \uBB34\uC2DC\n- \uC6D0\uBB38\uC758 \uC77D\uAE30 \uC21C\uC11C\uC640 \uAD6C\uC870\uB97C \uC720\uC9C0\n- ```\uB85C \uAC10\uC2F8\uC9C0 \uB9D0\uACE0 \uC21C\uC218 Markdown\uB9CC \uCD9C\uB825";
|
|
2115
|
+
_tempDir = null;
|
|
2116
|
+
}
|
|
2117
|
+
});
|
|
2118
|
+
|
|
2119
|
+
// src/ocr/tesseract-provider.ts
|
|
2120
|
+
var tesseract_provider_exports = {};
|
|
2121
|
+
__export(tesseract_provider_exports, {
|
|
2122
|
+
createTesseractProvider: () => createTesseractProvider
|
|
2123
|
+
});
|
|
2124
|
+
async function createTesseractProvider() {
|
|
2125
|
+
let tesseract;
|
|
2126
|
+
try {
|
|
2127
|
+
tesseract = await import("tesseract.js");
|
|
2128
|
+
} catch {
|
|
2129
|
+
throw new Error(
|
|
2130
|
+
"tesseract.js\uAC00 \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.\n\uC124\uCE58: npm install tesseract.js"
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
const worker = await tesseract.createWorker("kor+eng");
|
|
2134
|
+
let terminated = false;
|
|
2135
|
+
const provider = async (pageImage, _pageNumber, _mimeType) => {
|
|
2136
|
+
const { data } = await worker.recognize(pageImage);
|
|
2137
|
+
return data.text;
|
|
2138
|
+
};
|
|
2139
|
+
provider.terminate = async () => {
|
|
2140
|
+
if (!terminated) {
|
|
2141
|
+
await worker.terminate();
|
|
2142
|
+
terminated = true;
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
return provider;
|
|
2146
|
+
}
|
|
2147
|
+
var init_tesseract_provider = __esm({
|
|
2148
|
+
"src/ocr/tesseract-provider.ts"() {
|
|
2149
|
+
"use strict";
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
|
|
2153
|
+
// src/ocr/resolve.ts
|
|
2154
|
+
var resolve_exports = {};
|
|
2155
|
+
__export(resolve_exports, {
|
|
2156
|
+
resolveOcrProvider: () => resolveOcrProvider
|
|
2157
|
+
});
|
|
2158
|
+
async function resolveOcrProvider(mode, warnings) {
|
|
2159
|
+
if (mode === "off") {
|
|
2160
|
+
throw new Error("OCR\uC774 \uBE44\uD65C\uC131\uD654\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (--ocr off).");
|
|
2161
|
+
}
|
|
2162
|
+
if (mode !== "auto") {
|
|
2163
|
+
validateOcrMode(mode);
|
|
2164
|
+
if (mode === "tesseract") {
|
|
2165
|
+
const { createTesseractProvider: createTesseractProvider2 } = await Promise.resolve().then(() => (init_tesseract_provider(), tesseract_provider_exports));
|
|
2166
|
+
return createTesseractProvider2();
|
|
2167
|
+
}
|
|
2168
|
+
return createCliOcrProvider(mode);
|
|
2169
|
+
}
|
|
2170
|
+
const detected = detectAvailableOcr();
|
|
2171
|
+
if (!detected) {
|
|
2172
|
+
throw new Error("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C OCR \uB3C4\uAD6C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
2173
|
+
}
|
|
2174
|
+
if (detected !== "gemini") {
|
|
2175
|
+
warnings?.push({
|
|
2176
|
+
message: `OCR: '${detected}' \uC0AC\uC6A9 \uC911 (gemini CLI\uAC00 \uC5C6\uC5B4 fallback). \uB354 \uB098\uC740 \uD488\uC9C8\uC744 \uC704\uD574 gemini CLI \uC124\uCE58\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.`,
|
|
2177
|
+
code: "OCR_CLI_FALLBACK"
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
if (detected === "tesseract") {
|
|
2181
|
+
warnings?.push({
|
|
2182
|
+
message: "tesseract.js\uB294 \uD14C\uC774\uBE14 \uAD6C\uC870\uB97C \uBCF5\uC6D0\uD558\uC9C0 \uBABB\uD569\uB2C8\uB2E4. Vision LLM CLI(gemini/claude/codex) \uC124\uCE58\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
2183
|
+
code: "OCR_CLI_FALLBACK"
|
|
2184
|
+
});
|
|
2185
|
+
const { createTesseractProvider: createTesseractProvider2 } = await Promise.resolve().then(() => (init_tesseract_provider(), tesseract_provider_exports));
|
|
2186
|
+
return createTesseractProvider2();
|
|
2187
|
+
}
|
|
2188
|
+
return createCliOcrProvider(detected);
|
|
2189
|
+
}
|
|
2190
|
+
var init_resolve = __esm({
|
|
2191
|
+
"src/ocr/resolve.ts"() {
|
|
2192
|
+
"use strict";
|
|
2193
|
+
init_auto_detect();
|
|
2194
|
+
init_cli_provider();
|
|
2195
|
+
}
|
|
2196
|
+
});
|
|
2197
|
+
|
|
2198
|
+
// src/ocr/markdown-to-blocks.ts
|
|
2199
|
+
function markdownToBlocks(markdown, pageNumber) {
|
|
2200
|
+
const blocks = [];
|
|
2201
|
+
const lines = markdown.split("\n");
|
|
2202
|
+
let i = 0;
|
|
2203
|
+
while (i < lines.length) {
|
|
2204
|
+
const line = lines[i];
|
|
2205
|
+
if (line.trim() === "") {
|
|
2206
|
+
i++;
|
|
2207
|
+
continue;
|
|
2208
|
+
}
|
|
2209
|
+
const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
2210
|
+
if (headingMatch) {
|
|
2211
|
+
blocks.push({
|
|
2212
|
+
type: "heading",
|
|
2213
|
+
level: headingMatch[1].length,
|
|
2214
|
+
text: headingMatch[2].trim(),
|
|
2215
|
+
pageNumber
|
|
2216
|
+
});
|
|
2217
|
+
i++;
|
|
2218
|
+
continue;
|
|
2219
|
+
}
|
|
2220
|
+
if (/^[-*_]{3,}\s*$/.test(line.trim())) {
|
|
2221
|
+
blocks.push({ type: "separator", pageNumber });
|
|
2222
|
+
i++;
|
|
2223
|
+
continue;
|
|
2224
|
+
}
|
|
2225
|
+
if (line.trim().startsWith("|")) {
|
|
2226
|
+
const tableLines = [];
|
|
2227
|
+
while (i < lines.length && lines[i].trim().startsWith("|")) {
|
|
2228
|
+
tableLines.push(lines[i]);
|
|
2229
|
+
i++;
|
|
2230
|
+
}
|
|
2231
|
+
const table = parseMarkdownTable(tableLines);
|
|
2232
|
+
if (table) {
|
|
2233
|
+
blocks.push({ type: "table", table, pageNumber });
|
|
2234
|
+
}
|
|
2235
|
+
continue;
|
|
2236
|
+
}
|
|
2237
|
+
const ulMatch = line.match(/^(\s*)[-*+]\s+(.+)$/);
|
|
2238
|
+
if (ulMatch) {
|
|
2239
|
+
blocks.push({
|
|
2240
|
+
type: "list",
|
|
2241
|
+
listType: "unordered",
|
|
2242
|
+
text: ulMatch[2].trim(),
|
|
2243
|
+
pageNumber
|
|
2244
|
+
});
|
|
2245
|
+
i++;
|
|
2246
|
+
continue;
|
|
2247
|
+
}
|
|
2248
|
+
const olMatch = line.match(/^(\s*)\d+\.\s+(.+)$/);
|
|
2249
|
+
if (olMatch) {
|
|
2250
|
+
blocks.push({
|
|
2251
|
+
type: "list",
|
|
2252
|
+
listType: "ordered",
|
|
2253
|
+
text: olMatch[2].trim(),
|
|
2254
|
+
pageNumber
|
|
2255
|
+
});
|
|
2256
|
+
i++;
|
|
2257
|
+
continue;
|
|
2258
|
+
}
|
|
2259
|
+
const paraLines = [];
|
|
2260
|
+
while (i < lines.length && lines[i].trim() !== "" && !isStructuralLine(lines[i])) {
|
|
2261
|
+
paraLines.push(lines[i].trim());
|
|
2262
|
+
i++;
|
|
2263
|
+
}
|
|
2264
|
+
if (paraLines.length > 0) {
|
|
2265
|
+
blocks.push({
|
|
2266
|
+
type: "paragraph",
|
|
2267
|
+
text: paraLines.join("\n"),
|
|
2268
|
+
pageNumber
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
return blocks;
|
|
2273
|
+
}
|
|
2274
|
+
function isStructuralLine(line) {
|
|
2275
|
+
if (/^#{1,6}\s+/.test(line)) return true;
|
|
2276
|
+
if (line.trim().startsWith("|")) return true;
|
|
2277
|
+
if (/^[-*_]{3,}\s*$/.test(line.trim())) return true;
|
|
2278
|
+
if (/^\s*[-*+]\s+/.test(line)) return true;
|
|
2279
|
+
if (/^\s*\d+\.\s+/.test(line)) return true;
|
|
2280
|
+
return false;
|
|
2281
|
+
}
|
|
2282
|
+
function parseMarkdownTable(lines) {
|
|
2283
|
+
const hasSeparator = lines.some((line) => /^\|[\s:|-]+\|$/.test(line.trim()));
|
|
2284
|
+
const rows = [];
|
|
2285
|
+
let maxCols = 0;
|
|
2286
|
+
for (const line of lines) {
|
|
2287
|
+
if (/^\|\s*:?-+:?\s*(\|\s*:?-+:?\s*)+\|?\s*$/.test(line.trim())) continue;
|
|
2288
|
+
const parts = line.split("|");
|
|
2289
|
+
const cells = parts.slice(1, parts[parts.length - 1].trim() === "" ? -1 : void 0).map((cell) => ({
|
|
2290
|
+
text: cell.trim(),
|
|
2291
|
+
colSpan: 1,
|
|
2292
|
+
rowSpan: 1
|
|
2293
|
+
}));
|
|
2294
|
+
if (cells.length > 0) {
|
|
2295
|
+
rows.push(cells);
|
|
2296
|
+
maxCols = Math.max(maxCols, cells.length);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
if (rows.length === 0) return null;
|
|
2300
|
+
for (const row of rows) {
|
|
2301
|
+
while (row.length < maxCols) {
|
|
2302
|
+
row.push({ text: "", colSpan: 1, rowSpan: 1 });
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
return {
|
|
2306
|
+
rows: rows.length,
|
|
2307
|
+
cols: maxCols,
|
|
2308
|
+
cells: rows,
|
|
2309
|
+
hasHeader: hasSeparator && rows.length > 1
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
var init_markdown_to_blocks = __esm({
|
|
2313
|
+
"src/ocr/markdown-to-blocks.ts"() {
|
|
2314
|
+
"use strict";
|
|
2315
|
+
}
|
|
2316
|
+
});
|
|
2317
|
+
|
|
71
2318
|
// src/ocr/provider.ts
|
|
72
2319
|
var provider_exports = {};
|
|
73
2320
|
__export(provider_exports, {
|
|
74
2321
|
ocrPages: () => ocrPages
|
|
75
2322
|
});
|
|
76
|
-
async function ocrPages(doc, provider, pageFilter, effectivePageCount) {
|
|
2323
|
+
async function ocrPages(doc, provider, pageFilter, effectivePageCount, warnings) {
|
|
77
2324
|
const blocks = [];
|
|
78
2325
|
for (let i = 1; i <= effectivePageCount; i++) {
|
|
79
2326
|
if (pageFilter && !pageFilter.has(i)) continue;
|
|
80
2327
|
const page = await doc.getPage(i);
|
|
81
2328
|
try {
|
|
82
2329
|
const imageData = await renderPageToPng(page);
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
-
|
|
2330
|
+
const result = await provider(imageData, i, "image/png");
|
|
2331
|
+
if (typeof result === "string") {
|
|
2332
|
+
if (result.trim()) {
|
|
2333
|
+
blocks.push({ type: "paragraph", text: result.trim(), pageNumber: i });
|
|
2334
|
+
}
|
|
2335
|
+
} else if (result && typeof result === "object" && "markdown" in result) {
|
|
2336
|
+
const structured = result;
|
|
2337
|
+
if (structured.markdown.trim()) {
|
|
2338
|
+
const pageBlocks = markdownToBlocks(structured.markdown, i);
|
|
2339
|
+
for (const b of pageBlocks) blocks.push(b);
|
|
2340
|
+
}
|
|
86
2341
|
}
|
|
87
|
-
} catch {
|
|
2342
|
+
} catch (err) {
|
|
2343
|
+
warnings?.push({
|
|
2344
|
+
page: i,
|
|
2345
|
+
message: `\uD398\uC774\uC9C0 ${i} OCR \uC2E4\uD328: ${err instanceof Error ? err.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`,
|
|
2346
|
+
code: "OCR_PAGE_FAILED"
|
|
2347
|
+
});
|
|
88
2348
|
}
|
|
89
2349
|
}
|
|
90
2350
|
return blocks;
|
|
@@ -107,6 +2367,7 @@ async function renderPageToPng(page) {
|
|
|
107
2367
|
var init_provider = __esm({
|
|
108
2368
|
"src/ocr/provider.ts"() {
|
|
109
2369
|
"use strict";
|
|
2370
|
+
init_markdown_to_blocks();
|
|
110
2371
|
}
|
|
111
2372
|
});
|
|
112
2373
|
|
|
@@ -125,7 +2386,8 @@ __export(index_exports, {
|
|
|
125
2386
|
isPdfFile: () => isPdfFile,
|
|
126
2387
|
isZipFile: () => isZipFile,
|
|
127
2388
|
markdownToHwpx: () => markdownToHwpx,
|
|
128
|
-
|
|
2389
|
+
markdownToXlsx: () => markdownToXlsx,
|
|
2390
|
+
parse: () => parse2,
|
|
129
2391
|
parseDocx: () => parseDocx,
|
|
130
2392
|
parseHwp: () => parseHwp,
|
|
131
2393
|
parseHwpx: () => parseHwpx,
|
|
@@ -181,7 +2443,7 @@ var import_jszip2 = __toESM(require("jszip"), 1);
|
|
|
181
2443
|
var import_xmldom = require("@xmldom/xmldom");
|
|
182
2444
|
|
|
183
2445
|
// src/utils.ts
|
|
184
|
-
var VERSION = true ? "2.
|
|
2446
|
+
var VERSION = true ? "2.2.0" : "0.0.0-dev";
|
|
185
2447
|
function toArrayBuffer(buf) {
|
|
186
2448
|
if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
|
|
187
2449
|
return buf.buffer;
|
|
@@ -514,7 +2776,7 @@ var HEADING_RATIO_H3 = 1.15;
|
|
|
514
2776
|
// src/hwpx/parser.ts
|
|
515
2777
|
init_page_range();
|
|
516
2778
|
var MAX_DECOMPRESS_SIZE = 500 * 1024 * 1024;
|
|
517
|
-
var MAX_ZIP_ENTRIES =
|
|
2779
|
+
var MAX_ZIP_ENTRIES = 2e3;
|
|
518
2780
|
function clampSpan(val, max) {
|
|
519
2781
|
return Math.max(1, Math.min(val, max));
|
|
520
2782
|
}
|
|
@@ -673,6 +2935,16 @@ function imageExtToMime(ext) {
|
|
|
673
2935
|
return "application/octet-stream";
|
|
674
2936
|
}
|
|
675
2937
|
}
|
|
2938
|
+
function detectImageMimeFromBytes(data) {
|
|
2939
|
+
if (data.length >= 3 && data[0] === 255 && data[1] === 216 && data[2] === 255) return "image/jpeg";
|
|
2940
|
+
if (data.length >= 4 && data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) return "image/png";
|
|
2941
|
+
if (data.length >= 3 && data[0] === 71 && data[1] === 73 && data[2] === 70) return "image/gif";
|
|
2942
|
+
if (data.length >= 2 && data[0] === 66 && data[1] === 77) return "image/bmp";
|
|
2943
|
+
if (data.length >= 4 && data[0] === 215 && data[1] === 205 && data[2] === 198 && data[3] === 154) return "image/wmf";
|
|
2944
|
+
if (data.length >= 4 && (data[0] === 1 || data[0] === 2) && data[1] === 0 && data[2] === 9 && data[3] === 0) return "image/wmf";
|
|
2945
|
+
if (data.length >= 4 && data[0] === 1 && data[1] === 0 && data[2] === 0 && data[3] === 0) return "image/emf";
|
|
2946
|
+
return "image/png";
|
|
2947
|
+
}
|
|
676
2948
|
function mimeToExt(mime) {
|
|
677
2949
|
if (mime.includes("jpeg")) return "jpg";
|
|
678
2950
|
if (mime.includes("png")) return "png";
|
|
@@ -690,12 +2962,12 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
|
|
|
690
2962
|
for (const block of blocks) {
|
|
691
2963
|
if (block.type !== "image" || !block.text) continue;
|
|
692
2964
|
const ref = block.text;
|
|
693
|
-
const
|
|
694
|
-
|
|
695
|
-
`
|
|
696
|
-
ref
|
|
697
|
-
|
|
698
|
-
];
|
|
2965
|
+
const exts = ref.includes(".") ? [""] : [".jpg", ".jpeg", ".png", ".bmp", ".gif", ".wmf", ".emf", ".tif", ""];
|
|
2966
|
+
const candidates = exts.flatMap((ext) => [
|
|
2967
|
+
`BinData/${ref}${ext}`,
|
|
2968
|
+
`Contents/BinData/${ref}${ext}`,
|
|
2969
|
+
`${ref}${ext}`
|
|
2970
|
+
]);
|
|
699
2971
|
let found = false;
|
|
700
2972
|
for (const path of candidates) {
|
|
701
2973
|
if (isPathTraversal(path)) continue;
|
|
@@ -705,8 +2977,10 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
|
|
|
705
2977
|
const data = await file.async("uint8array");
|
|
706
2978
|
decompressed.total += data.length;
|
|
707
2979
|
if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
|
|
708
|
-
const
|
|
709
|
-
const
|
|
2980
|
+
const refExt = ref.includes(".") ? ref.split(".").pop().toLowerCase() : "";
|
|
2981
|
+
const pathExt = !refExt && path.includes(".") ? path.split(".").pop().toLowerCase() : "";
|
|
2982
|
+
const ext = refExt || pathExt;
|
|
2983
|
+
const mimeType = ext ? imageExtToMime(ext) : detectImageMimeFromBytes(data);
|
|
710
2984
|
imageIndex++;
|
|
711
2985
|
const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
|
|
712
2986
|
images.push({ filename, data, mimeType });
|
|
@@ -1029,13 +3303,18 @@ function walkSection(node, blocks, tableCtx, tableStack, styleMap, warnings, sec
|
|
|
1029
3303
|
}
|
|
1030
3304
|
break;
|
|
1031
3305
|
case "p": {
|
|
1032
|
-
const { text, href, footnote, style } = extractParagraphInfo(el, styleMap);
|
|
3306
|
+
const { text, href, footnote, style, headingLevel } = extractParagraphInfo(el, styleMap);
|
|
1033
3307
|
if (text) {
|
|
1034
3308
|
if (tableCtx?.cell) {
|
|
1035
3309
|
tableCtx.cell.text += (tableCtx.cell.text ? "\n" : "") + text;
|
|
1036
3310
|
} else if (!tableCtx) {
|
|
1037
|
-
|
|
1038
|
-
if (
|
|
3311
|
+
let block;
|
|
3312
|
+
if (headingLevel) {
|
|
3313
|
+
block = { type: "heading", text, level: headingLevel, pageNumber: sectionNum };
|
|
3314
|
+
} else {
|
|
3315
|
+
block = { type: "paragraph", text, pageNumber: sectionNum };
|
|
3316
|
+
if (style) block.style = style;
|
|
3317
|
+
}
|
|
1039
3318
|
if (href) block.href = href;
|
|
1040
3319
|
if (footnote) block.footnoteText = footnote;
|
|
1041
3320
|
blocks.push(block);
|
|
@@ -1269,7 +3548,19 @@ function extractParagraphInfo(para, styleMap) {
|
|
|
1269
3548
|
if (!style.fontSize && !style.bold && !style.italic) style = void 0;
|
|
1270
3549
|
}
|
|
1271
3550
|
}
|
|
1272
|
-
|
|
3551
|
+
let headingLevel;
|
|
3552
|
+
const styleIdRef = para.getAttribute("styleIDRef");
|
|
3553
|
+
if (styleMap && styleIdRef) {
|
|
3554
|
+
const styleDef = styleMap.styles.get(styleIdRef);
|
|
3555
|
+
if (styleDef?.name) {
|
|
3556
|
+
const sn = styleDef.name;
|
|
3557
|
+
if (/장제목|대제목|간지제목|제목[\s_]?1|개요[\s_]?1|heading[\s_]?1/i.test(sn)) headingLevel = 1;
|
|
3558
|
+
else if (/절제목|제목[\s_]?2|개요[\s_]?2|heading[\s_]?2|^B-1\.$|[\s(]1\.$/i.test(sn)) headingLevel = 2;
|
|
3559
|
+
else if (/제목[\s_]?3|개요[\s_]?3|heading[\s_]?3|1\.1\s*제목|1\.1[\s_]|^B-1\.1/i.test(sn)) headingLevel = 3;
|
|
3560
|
+
else if (/제목[\s_]?4|개요[\s_]?4|heading[\s_]?4/i.test(sn)) headingLevel = 4;
|
|
3561
|
+
}
|
|
3562
|
+
}
|
|
3563
|
+
return { text: cleanText, href, footnote, style, headingLevel };
|
|
1273
3564
|
}
|
|
1274
3565
|
function extractTextFromNode(node) {
|
|
1275
3566
|
let result = "";
|
|
@@ -2335,10 +4626,7 @@ function parseLenientCfb(data) {
|
|
|
2335
4626
|
|
|
2336
4627
|
// src/hwp5/parser.ts
|
|
2337
4628
|
init_page_range();
|
|
2338
|
-
var
|
|
2339
|
-
var import_meta = {};
|
|
2340
|
-
var require2 = (0, import_module.createRequire)(import_meta.url);
|
|
2341
|
-
var CFB = require2("cfb");
|
|
4629
|
+
var CFB = __toESM(require_cfb(), 1);
|
|
2342
4630
|
var MAX_SECTIONS = 100;
|
|
2343
4631
|
var MAX_TOTAL_DECOMPRESS = 500 * 1024 * 1024;
|
|
2344
4632
|
function parseHwp5Document(buffer, options) {
|
|
@@ -3197,7 +5485,7 @@ function clusterCoordinates(values) {
|
|
|
3197
5485
|
}
|
|
3198
5486
|
function groupConnectedLines(lines) {
|
|
3199
5487
|
const parent = lines.map((_, i) => i);
|
|
3200
|
-
function
|
|
5488
|
+
function find2(x) {
|
|
3201
5489
|
while (parent[x] !== x) {
|
|
3202
5490
|
parent[x] = parent[parent[x]];
|
|
3203
5491
|
x = parent[x];
|
|
@@ -3205,7 +5493,7 @@ function groupConnectedLines(lines) {
|
|
|
3205
5493
|
return x;
|
|
3206
5494
|
}
|
|
3207
5495
|
function union(a, b) {
|
|
3208
|
-
const ra =
|
|
5496
|
+
const ra = find2(a), rb = find2(b);
|
|
3209
5497
|
if (ra !== rb) parent[ra] = rb;
|
|
3210
5498
|
}
|
|
3211
5499
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -3217,7 +5505,7 @@ function groupConnectedLines(lines) {
|
|
|
3217
5505
|
}
|
|
3218
5506
|
const groups = /* @__PURE__ */ new Map();
|
|
3219
5507
|
for (let i = 0; i < lines.length; i++) {
|
|
3220
|
-
const root =
|
|
5508
|
+
const root = find2(i);
|
|
3221
5509
|
if (!groups.has(root)) groups.set(root, []);
|
|
3222
5510
|
groups.get(root).push(lines[i]);
|
|
3223
5511
|
}
|
|
@@ -3667,18 +5955,43 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3667
5955
|
}
|
|
3668
5956
|
const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
|
|
3669
5957
|
if (totalChars / Math.max(parsedPageCount, 1) < 10) {
|
|
3670
|
-
|
|
5958
|
+
let ocrProvider = options?.ocr ?? null;
|
|
5959
|
+
const ocrMode = options?.ocrMode;
|
|
5960
|
+
if (!ocrProvider && ocrMode && ocrMode !== "off") {
|
|
5961
|
+
try {
|
|
5962
|
+
const { resolveOcrProvider: resolveOcrProvider2 } = await Promise.resolve().then(() => (init_resolve(), resolve_exports));
|
|
5963
|
+
ocrProvider = await resolveOcrProvider2(ocrMode, warnings);
|
|
5964
|
+
} catch (resolveErr) {
|
|
5965
|
+
if (ocrMode !== "auto") {
|
|
5966
|
+
throw Object.assign(
|
|
5967
|
+
new KordocError(resolveErr instanceof Error ? resolveErr.message : "OCR \uD504\uB85C\uBC14\uC774\uB354 \uCD08\uAE30\uD654 \uC2E4\uD328"),
|
|
5968
|
+
{ isImageBased: true }
|
|
5969
|
+
);
|
|
5970
|
+
}
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
if (ocrProvider) {
|
|
3671
5974
|
try {
|
|
3672
5975
|
const { ocrPages: ocrPages2 } = await Promise.resolve().then(() => (init_provider(), provider_exports));
|
|
3673
|
-
const ocrBlocks = await ocrPages2(doc,
|
|
5976
|
+
const ocrBlocks = await ocrPages2(doc, ocrProvider, pageFilter, effectivePageCount, warnings);
|
|
3674
5977
|
if (ocrBlocks.length > 0) {
|
|
3675
|
-
const ocrMarkdown = ocrBlocks
|
|
3676
|
-
return {
|
|
5978
|
+
const ocrMarkdown = blocksToMarkdown(ocrBlocks);
|
|
5979
|
+
return {
|
|
5980
|
+
markdown: ocrMarkdown,
|
|
5981
|
+
blocks: ocrBlocks,
|
|
5982
|
+
metadata,
|
|
5983
|
+
warnings: warnings.length > 0 ? warnings : void 0,
|
|
5984
|
+
isImageBased: true
|
|
5985
|
+
};
|
|
3677
5986
|
}
|
|
3678
5987
|
} catch {
|
|
3679
5988
|
}
|
|
3680
5989
|
}
|
|
3681
|
-
|
|
5990
|
+
if (ocrMode === "off") {
|
|
5991
|
+
throw Object.assign(new KordocError(`\uC774\uBBF8\uC9C0 \uAE30\uBC18 PDF (${pageCount}\uD398\uC774\uC9C0, ${totalChars}\uC790)`), { isImageBased: true });
|
|
5992
|
+
}
|
|
5993
|
+
const errMsg = ocrMode ? `\uC774\uBBF8\uC9C0 \uAE30\uBC18 PDF \u2014 OCR \uC2E4\uD328 (${pageCount}\uD398\uC774\uC9C0, ${totalChars}\uC790)` : `\uC774\uBBF8\uC9C0 \uAE30\uBC18 PDF (${pageCount}\uD398\uC774\uC9C0, ${totalChars}\uC790)`;
|
|
5994
|
+
throw Object.assign(new KordocError(errMsg), { isImageBased: true });
|
|
3682
5995
|
}
|
|
3683
5996
|
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
3684
5997
|
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings);
|
|
@@ -5290,8 +7603,8 @@ function levenshtein(a, b) {
|
|
|
5290
7603
|
var SIMILARITY_THRESHOLD = 0.4;
|
|
5291
7604
|
async function compare(bufferA, bufferB, options) {
|
|
5292
7605
|
const [resultA, resultB] = await Promise.all([
|
|
5293
|
-
|
|
5294
|
-
|
|
7606
|
+
parse2(bufferA, options),
|
|
7607
|
+
parse2(bufferB, options)
|
|
5295
7608
|
]);
|
|
5296
7609
|
if (!resultA.success) throw new Error(`\uBB38\uC11CA \uD30C\uC2F1 \uC2E4\uD328: ${resultA.error}`);
|
|
5297
7610
|
if (!resultB.success) throw new Error(`\uBB38\uC11CB \uD30C\uC2F1 \uC2E4\uD328: ${resultB.error}`);
|
|
@@ -5612,7 +7925,7 @@ var HEADER_XML = `<?xml version='1.0' encoding='UTF-8'?>
|
|
|
5612
7925
|
</hh:font>
|
|
5613
7926
|
</hh:fontface>
|
|
5614
7927
|
</hh:fontfaces>
|
|
5615
|
-
<hh:borderFills itemCnt="
|
|
7928
|
+
<hh:borderFills itemCnt="5">
|
|
5616
7929
|
<hh:borderFill id="1" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
|
|
5617
7930
|
<hh:slash type="NONE" Crooked="0" isCounter="0"/>
|
|
5618
7931
|
<hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
|
|
@@ -5643,8 +7956,26 @@ var HEADER_XML = `<?xml version='1.0' encoding='UTF-8'?>
|
|
|
5643
7956
|
<hh:bottomBorder type="SOLID" width="0.12 mm" color="#000000"/>
|
|
5644
7957
|
<hh:diagonal type="SOLID" width="0.1 mm" color="#000000"/>
|
|
5645
7958
|
</hh:borderFill>
|
|
7959
|
+
<hh:borderFill id="4" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
|
|
7960
|
+
<hh:slash type="NONE" Crooked="0" isCounter="0"/>
|
|
7961
|
+
<hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
|
|
7962
|
+
<hh:leftBorder type="SOLID" width="0.5 mm" color="#AAAAAA"/>
|
|
7963
|
+
<hh:rightBorder type="NONE" width="0.1 mm" color="#000000"/>
|
|
7964
|
+
<hh:topBorder type="NONE" width="0.1 mm" color="#000000"/>
|
|
7965
|
+
<hh:bottomBorder type="NONE" width="0.1 mm" color="#000000"/>
|
|
7966
|
+
<hh:diagonal type="SOLID" width="0.1 mm" color="#000000"/>
|
|
7967
|
+
</hh:borderFill>
|
|
7968
|
+
<hh:borderFill id="5" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
|
|
7969
|
+
<hh:slash type="NONE" Crooked="0" isCounter="0"/>
|
|
7970
|
+
<hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
|
|
7971
|
+
<hh:leftBorder type="NONE" width="0.1 mm" color="#000000"/>
|
|
7972
|
+
<hh:rightBorder type="NONE" width="0.1 mm" color="#000000"/>
|
|
7973
|
+
<hh:topBorder type="NONE" width="0.1 mm" color="#000000"/>
|
|
7974
|
+
<hh:bottomBorder type="SOLID" width="0.4 mm" color="#888888"/>
|
|
7975
|
+
<hh:diagonal type="SOLID" width="0.1 mm" color="#000000"/>
|
|
7976
|
+
</hh:borderFill>
|
|
5646
7977
|
</hh:borderFills>
|
|
5647
|
-
<hh:charProperties itemCnt="
|
|
7978
|
+
<hh:charProperties itemCnt="16">
|
|
5648
7979
|
<hh:charPr id="0" height="1000" textColor="#000000" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="2">
|
|
5649
7980
|
<hh:fontRef hangul="1" latin="1" hanja="1" japanese="1" other="1" symbol="1" user="1"/>
|
|
5650
7981
|
<hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
@@ -5795,6 +8126,41 @@ var HEADER_XML = `<?xml version='1.0' encoding='UTF-8'?>
|
|
|
5795
8126
|
<hh:outline type="NONE"/>
|
|
5796
8127
|
<hh:shadow type="NONE" color="#C0C0C0" offsetX="10" offsetY="10"/>
|
|
5797
8128
|
</hh:charPr>
|
|
8129
|
+
<hh:charPr id="13" height="1000" textColor="#000000" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="2">
|
|
8130
|
+
<hh:fontRef hangul="1" latin="1" hanja="1" japanese="1" other="1" symbol="1" user="1"/>
|
|
8131
|
+
<hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
8132
|
+
<hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
|
|
8133
|
+
<hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
8134
|
+
<hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
|
|
8135
|
+
<hh:bold/>
|
|
8136
|
+
<hh:italic/>
|
|
8137
|
+
<hh:underline type="NONE" shape="SOLID" color="#000000"/>
|
|
8138
|
+
<hh:strikeout shape="NONE" color="#000000"/>
|
|
8139
|
+
<hh:outline type="NONE"/>
|
|
8140
|
+
<hh:shadow type="NONE" color="#C0C0C0" offsetX="10" offsetY="10"/>
|
|
8141
|
+
</hh:charPr>
|
|
8142
|
+
<hh:charPr id="14" height="900" textColor="#333333" shadeColor="#F0F0F0" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="2">
|
|
8143
|
+
<hh:fontRef hangul="1" latin="1" hanja="1" japanese="1" other="1" symbol="1" user="1"/>
|
|
8144
|
+
<hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
8145
|
+
<hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
|
|
8146
|
+
<hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
8147
|
+
<hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
|
|
8148
|
+
<hh:underline type="NONE" shape="SOLID" color="#000000"/>
|
|
8149
|
+
<hh:strikeout shape="NONE" color="#000000"/>
|
|
8150
|
+
<hh:outline type="NONE"/>
|
|
8151
|
+
<hh:shadow type="NONE" color="#C0C0C0" offsetX="10" offsetY="10"/>
|
|
8152
|
+
</hh:charPr>
|
|
8153
|
+
<hh:charPr id="15" height="1000" textColor="#000000" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="2">
|
|
8154
|
+
<hh:fontRef hangul="1" latin="1" hanja="1" japanese="1" other="1" symbol="1" user="1"/>
|
|
8155
|
+
<hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
8156
|
+
<hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
|
|
8157
|
+
<hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
|
|
8158
|
+
<hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
|
|
8159
|
+
<hh:underline type="NONE" shape="SOLID" color="#000000"/>
|
|
8160
|
+
<hh:strikeout shape="SINGLE" color="#000000"/>
|
|
8161
|
+
<hh:outline type="NONE"/>
|
|
8162
|
+
<hh:shadow type="NONE" color="#C0C0C0" offsetX="10" offsetY="10"/>
|
|
8163
|
+
</hh:charPr>
|
|
5798
8164
|
</hh:charProperties>
|
|
5799
8165
|
<hh:tabProperties itemCnt="3">
|
|
5800
8166
|
<hh:tabPr id="0" autoTabLeft="0" autoTabRight="0"/>
|
|
@@ -5815,7 +8181,7 @@ var HEADER_XML = `<?xml version='1.0' encoding='UTF-8'?>
|
|
|
5815
8181
|
<hh:paraHead start="1" level="10" align="LEFT" useInstWidth="1" autoIndent="1" widthAdjust="0" textOffsetType="PERCENT" textOffset="50" numFormat="ROMAN_SMALL" charPrIDRef="4294967295" checkable="1"/>
|
|
5816
8182
|
</hh:numbering>
|
|
5817
8183
|
</hh:numberings>
|
|
5818
|
-
<hh:paraProperties itemCnt="
|
|
8184
|
+
<hh:paraProperties itemCnt="22">
|
|
5819
8185
|
<hh:paraPr id="0" tabPrIDRef="0" condense="0" fontLineHeight="0" snapToGrid="1" suppressLineNumbers="0" checked="0" textDir="LTR">
|
|
5820
8186
|
<hh:align horizontal="JUSTIFY" vertical="BASELINE"/>
|
|
5821
8187
|
<hh:heading type="NONE" idRef="0" level="0"/>
|
|
@@ -6417,6 +8783,64 @@ var HEADER_XML = `<?xml version='1.0' encoding='UTF-8'?>
|
|
|
6417
8783
|
</hp:switch>
|
|
6418
8784
|
<hh:border borderFillIDRef="2" offsetLeft="0" offsetRight="0" offsetTop="0" offsetBottom="0" connect="0" ignoreMargin="0"/>
|
|
6419
8785
|
</hh:paraPr>
|
|
8786
|
+
<hh:paraPr id="20" tabPrIDRef="0" condense="0" fontLineHeight="0" snapToGrid="1" suppressLineNumbers="0" checked="0" textDir="LTR">
|
|
8787
|
+
<hh:align horizontal="JUSTIFY" vertical="BASELINE"/>
|
|
8788
|
+
<hh:heading type="NONE" idRef="0" level="0"/>
|
|
8789
|
+
<hh:breakSetting breakLatinWord="KEEP_WORD" breakNonLatinWord="BREAK_WORD" widowOrphan="0" keepWithNext="0" keepLines="0" pageBreakBefore="0" lineWrap="BREAK"/>
|
|
8790
|
+
<hh:autoSpacing eAsianEng="0" eAsianNum="0"/>
|
|
8791
|
+
<hp:switch>
|
|
8792
|
+
<hp:case hp:required-namespace="http://www.hancom.co.kr/hwpml/2016/HwpUnitChar">
|
|
8793
|
+
<hh:margin>
|
|
8794
|
+
<hc:intent value="0" unit="HWPUNIT"/>
|
|
8795
|
+
<hc:left value="4252" unit="HWPUNIT"/>
|
|
8796
|
+
<hc:right value="0" unit="HWPUNIT"/>
|
|
8797
|
+
<hc:prev value="0" unit="HWPUNIT"/>
|
|
8798
|
+
<hc:next value="0" unit="HWPUNIT"/>
|
|
8799
|
+
</hh:margin>
|
|
8800
|
+
<hh:lineSpacing type="PERCENT" value="160" unit="HWPUNIT"/>
|
|
8801
|
+
</hp:case>
|
|
8802
|
+
<hp:default>
|
|
8803
|
+
<hh:margin>
|
|
8804
|
+
<hc:intent value="0" unit="HWPUNIT"/>
|
|
8805
|
+
<hc:left value="4252" unit="HWPUNIT"/>
|
|
8806
|
+
<hc:right value="0" unit="HWPUNIT"/>
|
|
8807
|
+
<hc:prev value="0" unit="HWPUNIT"/>
|
|
8808
|
+
<hc:next value="0" unit="HWPUNIT"/>
|
|
8809
|
+
</hh:margin>
|
|
8810
|
+
<hh:lineSpacing type="PERCENT" value="160" unit="HWPUNIT"/>
|
|
8811
|
+
</hp:default>
|
|
8812
|
+
</hp:switch>
|
|
8813
|
+
<hh:border borderFillIDRef="4" offsetLeft="0" offsetRight="0" offsetTop="0" offsetBottom="0" connect="0" ignoreMargin="0"/>
|
|
8814
|
+
</hh:paraPr>
|
|
8815
|
+
<hh:paraPr id="21" tabPrIDRef="0" condense="0" fontLineHeight="0" snapToGrid="1" suppressLineNumbers="0" checked="0" textDir="LTR">
|
|
8816
|
+
<hh:align horizontal="JUSTIFY" vertical="BASELINE"/>
|
|
8817
|
+
<hh:heading type="NONE" idRef="0" level="0"/>
|
|
8818
|
+
<hh:breakSetting breakLatinWord="KEEP_WORD" breakNonLatinWord="BREAK_WORD" widowOrphan="0" keepWithNext="0" keepLines="0" pageBreakBefore="0" lineWrap="BREAK"/>
|
|
8819
|
+
<hh:autoSpacing eAsianEng="0" eAsianNum="0"/>
|
|
8820
|
+
<hp:switch>
|
|
8821
|
+
<hp:case hp:required-namespace="http://www.hancom.co.kr/hwpml/2016/HwpUnitChar">
|
|
8822
|
+
<hh:margin>
|
|
8823
|
+
<hc:intent value="0" unit="HWPUNIT"/>
|
|
8824
|
+
<hc:left value="0" unit="HWPUNIT"/>
|
|
8825
|
+
<hc:right value="0" unit="HWPUNIT"/>
|
|
8826
|
+
<hc:prev value="0" unit="HWPUNIT"/>
|
|
8827
|
+
<hc:next value="0" unit="HWPUNIT"/>
|
|
8828
|
+
</hh:margin>
|
|
8829
|
+
<hh:lineSpacing type="PERCENT" value="160" unit="HWPUNIT"/>
|
|
8830
|
+
</hp:case>
|
|
8831
|
+
<hp:default>
|
|
8832
|
+
<hh:margin>
|
|
8833
|
+
<hc:intent value="0" unit="HWPUNIT"/>
|
|
8834
|
+
<hc:left value="0" unit="HWPUNIT"/>
|
|
8835
|
+
<hc:right value="0" unit="HWPUNIT"/>
|
|
8836
|
+
<hc:prev value="0" unit="HWPUNIT"/>
|
|
8837
|
+
<hc:next value="0" unit="HWPUNIT"/>
|
|
8838
|
+
</hh:margin>
|
|
8839
|
+
<hh:lineSpacing type="PERCENT" value="160" unit="HWPUNIT"/>
|
|
8840
|
+
</hp:default>
|
|
8841
|
+
</hp:switch>
|
|
8842
|
+
<hh:border borderFillIDRef="5" offsetLeft="0" offsetRight="0" offsetTop="0" offsetBottom="0" connect="0" ignoreMargin="0"/>
|
|
8843
|
+
</hh:paraPr>
|
|
6420
8844
|
</hh:paraProperties>
|
|
6421
8845
|
<hh:styles itemCnt="23">
|
|
6422
8846
|
<hh:style id="0" type="PARA" name="\uBC14\uD0D5\uAE00" engName="Normal" paraPrIDRef="0" charPrIDRef="0" nextStyleIDRef="0" langID="1042" lockForm="0"/>
|
|
@@ -6520,7 +8944,11 @@ async function extractTemplateStyles(templateArrayBuffer) {
|
|
|
6520
8944
|
charPr: /* @__PURE__ */ new Map(),
|
|
6521
8945
|
paraPr: /* @__PURE__ */ new Map(),
|
|
6522
8946
|
borderFill: /* @__PURE__ */ new Map(),
|
|
6523
|
-
fontfaces: /* @__PURE__ */ new Map()
|
|
8947
|
+
fontfaces: /* @__PURE__ */ new Map(),
|
|
8948
|
+
styles: /* @__PURE__ */ new Map(),
|
|
8949
|
+
stylesById: /* @__PURE__ */ new Map(),
|
|
8950
|
+
masterpages: [],
|
|
8951
|
+
headerXml: headerXmlText
|
|
6524
8952
|
};
|
|
6525
8953
|
const fontfaces = doc.getElementsByTagNameNS(ns.hh, "fontFamily");
|
|
6526
8954
|
for (let i = 0; i < fontfaces.length; i++) {
|
|
@@ -6595,6 +9023,34 @@ async function extractTemplateStyles(templateArrayBuffer) {
|
|
|
6595
9023
|
if (fillColor) borderFillProp.fillColor = fillColor;
|
|
6596
9024
|
template.borderFill.set(id, borderFillProp);
|
|
6597
9025
|
}
|
|
9026
|
+
const styleEls = doc.getElementsByTagNameNS(ns.hh, "style");
|
|
9027
|
+
for (let i = 0; i < styleEls.length; i++) {
|
|
9028
|
+
const el = styleEls.item(i);
|
|
9029
|
+
const id = el.getAttribute("id");
|
|
9030
|
+
const name = el.getAttribute("name") || "";
|
|
9031
|
+
const engName = el.getAttribute("engName") || "";
|
|
9032
|
+
const charPrIDRef = el.getAttribute("charPrIDRef") || "0";
|
|
9033
|
+
const paraPrIDRef = el.getAttribute("paraPrIDRef") || "0";
|
|
9034
|
+
if (!id) continue;
|
|
9035
|
+
const def = { id, name, engName, charPrIDRef, paraPrIDRef };
|
|
9036
|
+
template.styles.set(name, def);
|
|
9037
|
+
template.stylesById.set(id, def);
|
|
9038
|
+
}
|
|
9039
|
+
const section0File = zip.file("Contents/section0.xml");
|
|
9040
|
+
if (section0File) {
|
|
9041
|
+
const sec0 = await section0File.async("text");
|
|
9042
|
+
const secPrMatch = sec0.match(/<hp:secPr[\s\S]*?<\/hp:secPr>/);
|
|
9043
|
+
if (secPrMatch) template.secPrXml = secPrMatch[0];
|
|
9044
|
+
const colPrMatch = sec0.match(/<hp:ctrl>[\s\S]*?<\/hp:ctrl>/);
|
|
9045
|
+
if (colPrMatch) template.colPrXml = colPrMatch[0];
|
|
9046
|
+
}
|
|
9047
|
+
for (const [path, file] of Object.entries(zip.files)) {
|
|
9048
|
+
if (/^Contents\/masterpage\d+\.xml$/.test(path)) {
|
|
9049
|
+
const content = await file.async("text");
|
|
9050
|
+
template.masterpages.push({ filename: path, content });
|
|
9051
|
+
}
|
|
9052
|
+
}
|
|
9053
|
+
template.masterpages.sort((a, b) => a.filename.localeCompare(b.filename));
|
|
6598
9054
|
return template;
|
|
6599
9055
|
}
|
|
6600
9056
|
function findCharPrByCharacteristic(charPrMap, characteristic) {
|
|
@@ -6655,35 +9111,61 @@ function getDefaultBorderFillId(borderFillMap) {
|
|
|
6655
9111
|
}
|
|
6656
9112
|
|
|
6657
9113
|
// src/hwpx/style-matcher.ts
|
|
9114
|
+
function findStyleByName(styles, candidates) {
|
|
9115
|
+
for (const cand of candidates) {
|
|
9116
|
+
if (styles.has(cand)) return styles.get(cand);
|
|
9117
|
+
}
|
|
9118
|
+
for (const cand of candidates) {
|
|
9119
|
+
for (const [name, def] of styles) {
|
|
9120
|
+
if (name === `B-${cand}` || name.endsWith(` ${cand}`) || name.endsWith(`-${cand}`)) return def;
|
|
9121
|
+
}
|
|
9122
|
+
}
|
|
9123
|
+
for (const cand of candidates) {
|
|
9124
|
+
let best = null;
|
|
9125
|
+
for (const [name, def] of styles) {
|
|
9126
|
+
if (name.includes(cand)) {
|
|
9127
|
+
if (!best || name.length < best[0].length) best = [name, def];
|
|
9128
|
+
}
|
|
9129
|
+
}
|
|
9130
|
+
if (best) return best[1];
|
|
9131
|
+
}
|
|
9132
|
+
return null;
|
|
9133
|
+
}
|
|
6658
9134
|
function createStyleMap(template, warnings = []) {
|
|
6659
9135
|
const charPrMap = template.charPr || /* @__PURE__ */ new Map();
|
|
6660
|
-
const paraPrMap = template.paraPr || /* @__PURE__ */ new Map();
|
|
6661
9136
|
const borderFillMap = template.borderFill || /* @__PURE__ */ new Map();
|
|
9137
|
+
const styles = template.styles || /* @__PURE__ */ new Map();
|
|
6662
9138
|
const defaultCharPr = getDefaultCharPrId(charPrMap);
|
|
6663
|
-
const defaultParaPr = getDefaultParaPrId(
|
|
9139
|
+
const defaultParaPr = getDefaultParaPrId(template.paraPr || /* @__PURE__ */ new Map());
|
|
6664
9140
|
const defaultBorderFill = getDefaultBorderFillId(borderFillMap);
|
|
6665
|
-
const
|
|
6666
|
-
const
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
9141
|
+
const defaultStyleId = "0";
|
|
9142
|
+
const toEntry = (def, fallbackCharPr) => ({
|
|
9143
|
+
charPr: def?.charPrIDRef ?? fallbackCharPr,
|
|
9144
|
+
paraPr: def?.paraPrIDRef ?? defaultParaPr,
|
|
9145
|
+
styleId: def?.id ?? defaultStyleId
|
|
9146
|
+
});
|
|
9147
|
+
const bodyDef = findStyleByName(styles, ["\uBC14\uD0D5\uAE00", "Normal", "\uBCF8\uBB38", "\uBC14\uD0D5"]) || findStyleByName(styles, ["body", "normal"]);
|
|
9148
|
+
const h1Def = findStyleByName(styles, ["\uC81C\uBAA91", "\uC81C\uBAA9 1", "\uAC1C\uC694 1", "\uAC1C\uC6941", "Heading 1"]) || findStyleByName(styles, ["\uC7A5\uC81C\uBAA9", "\uB300\uC81C\uBAA9", "\uC81C\uBAA9"]);
|
|
9149
|
+
const h2Def = findStyleByName(styles, ["\uC81C\uBAA92", "\uC81C\uBAA9 2", "\uAC1C\uC694 2", "\uAC1C\uC6942", "Heading 2"]) || findStyleByName(styles, ["\uC808\uC81C\uBAA9", "1.", "1 "]);
|
|
9150
|
+
const h3Def = findStyleByName(styles, ["\uC81C\uBAA93", "\uC81C\uBAA9 3", "\uAC1C\uC694 3", "\uAC1C\uC6943", "Heading 3"]) || findStyleByName(styles, ["1.1", "\uD56D\uBAA9"]);
|
|
9151
|
+
const tableCellDef = findStyleByName(styles, ["\uD45C \uB0B4\uC6A9", "\uD45C\uB0B4\uC6A9", "B-\uD45C\uB0B4\uC6A9", "\uD45C \uB0B4\uC6A9(\uC77C\uBC18)"]) || findStyleByName(styles, ["\uD45C", "table"]);
|
|
9152
|
+
const tableHeaderDef = findStyleByName(styles, ["\uD45C\uC81C\uBAA9", "\uD45C \uC81C\uBAA9", "B-\uD45C\uC81C\uBAA9", "\uD45C \uB0B4\uC6A9(\uAC15\uC870)"]) || tableCellDef;
|
|
9153
|
+
const bodyCharPr = bodyDef?.charPrIDRef ?? findCharPrByCharacteristic(charPrMap, "normal") ?? defaultCharPr;
|
|
9154
|
+
const h1CharPr = h1Def?.charPrIDRef ?? findCharPrByCharacteristic(charPrMap, "heading1") ?? defaultCharPr;
|
|
9155
|
+
const h2CharPr = h2Def?.charPrIDRef ?? findCharPrByCharacteristic(charPrMap, "heading2") ?? defaultCharPr;
|
|
9156
|
+
const h3CharPr = h3Def?.charPrIDRef ?? findCharPrByCharacteristic(charPrMap, "heading3") ?? defaultCharPr;
|
|
9157
|
+
const boldCharPr = findCharPrByCharacteristic(charPrMap, "bold") ?? defaultCharPr;
|
|
9158
|
+
const italicCharPr = findCharPrByCharacteristic(charPrMap, "italic") ?? defaultCharPr;
|
|
6677
9159
|
return {
|
|
6678
|
-
h1: { charPr: h1CharPr, paraPr: defaultParaPr },
|
|
6679
|
-
h2: { charPr: h2CharPr, paraPr: defaultParaPr },
|
|
6680
|
-
h3: { charPr: h3CharPr, paraPr: defaultParaPr },
|
|
6681
|
-
h456: { charPr:
|
|
6682
|
-
body: { charPr: bodyCharPr, paraPr: defaultParaPr },
|
|
9160
|
+
h1: { charPr: h1CharPr, paraPr: h1Def?.paraPrIDRef ?? defaultParaPr, styleId: h1Def?.id ?? defaultStyleId },
|
|
9161
|
+
h2: { charPr: h2CharPr, paraPr: h2Def?.paraPrIDRef ?? defaultParaPr, styleId: h2Def?.id ?? defaultStyleId },
|
|
9162
|
+
h3: { charPr: h3CharPr, paraPr: h3Def?.paraPrIDRef ?? defaultParaPr, styleId: h3Def?.id ?? defaultStyleId },
|
|
9163
|
+
h456: { charPr: h3CharPr, paraPr: h3Def?.paraPrIDRef ?? defaultParaPr, styleId: h3Def?.id ?? defaultStyleId },
|
|
9164
|
+
body: { charPr: bodyCharPr, paraPr: bodyDef?.paraPrIDRef ?? defaultParaPr, styleId: bodyDef?.id ?? defaultStyleId },
|
|
6683
9165
|
bold: { charPr: boldCharPr },
|
|
6684
9166
|
italic: { charPr: italicCharPr },
|
|
6685
|
-
tableCell: { charPr: bodyCharPr, borderFill: defaultBorderFill },
|
|
6686
|
-
tableHeader: { charPr:
|
|
9167
|
+
tableCell: { charPr: tableCellDef?.charPrIDRef ?? bodyCharPr, paraPr: tableCellDef?.paraPrIDRef ?? defaultParaPr, styleId: tableCellDef?.id ?? defaultStyleId, borderFill: defaultBorderFill },
|
|
9168
|
+
tableHeader: { charPr: tableHeaderDef?.charPrIDRef ?? bodyCharPr, paraPr: tableHeaderDef?.paraPrIDRef ?? defaultParaPr, styleId: tableHeaderDef?.id ?? defaultStyleId, borderFill: defaultBorderFill }
|
|
6687
9169
|
};
|
|
6688
9170
|
}
|
|
6689
9171
|
function getStyleForBlock(styleMap, blockType, inlineStyle) {
|
|
@@ -6717,7 +9199,12 @@ var CHAR_H3 = "9";
|
|
|
6717
9199
|
var CHAR_H456 = "10";
|
|
6718
9200
|
var CHAR_BOLD = "11";
|
|
6719
9201
|
var CHAR_ITALIC = "12";
|
|
9202
|
+
var CHAR_BOLD_ITALIC = "13";
|
|
9203
|
+
var CHAR_CODE = "14";
|
|
9204
|
+
var CHAR_STRIKETHROUGH = "15";
|
|
6720
9205
|
var PARA_NORMAL = "0";
|
|
9206
|
+
var PARA_BLOCKQUOTE = "20";
|
|
9207
|
+
var PARA_HR = "21";
|
|
6721
9208
|
var SEC_NS = [
|
|
6722
9209
|
`xmlns:ha="http://www.hancom.co.kr/hwpml/2011/app"`,
|
|
6723
9210
|
`xmlns:hp="http://www.hancom.co.kr/hwpml/2011/paragraph"`,
|
|
@@ -6744,7 +9231,7 @@ function escapeXml(text) {
|
|
|
6744
9231
|
}
|
|
6745
9232
|
function parseInlineRuns(text) {
|
|
6746
9233
|
const runs = [];
|
|
6747
|
-
const re = /\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|\*(.+?)\*|_(.+?)_|`(.+?)
|
|
9234
|
+
const re = /\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|\*(.+?)\*|_(.+?)_|`(.+?)`|~~(.+?)~~|\[([^\]]+)\]\(([^)]+)\)/g;
|
|
6748
9235
|
let last = 0;
|
|
6749
9236
|
let m;
|
|
6750
9237
|
while ((m = re.exec(text)) !== null) {
|
|
@@ -6753,13 +9240,18 @@ function parseInlineRuns(text) {
|
|
|
6753
9240
|
else if (m[2]) runs.push({ text: m[2], bold: true });
|
|
6754
9241
|
else if (m[3]) runs.push({ text: m[3], italic: true });
|
|
6755
9242
|
else if (m[4]) runs.push({ text: m[4], italic: true });
|
|
6756
|
-
else if (m[5]) runs.push({ text: m[5] });
|
|
9243
|
+
else if (m[5]) runs.push({ text: m[5], code: true });
|
|
9244
|
+
else if (m[6]) runs.push({ text: m[6], strikethrough: true });
|
|
9245
|
+
else if (m[7]) runs.push({ text: m[7], url: m[8] });
|
|
6757
9246
|
last = m.index + m[0].length;
|
|
6758
9247
|
}
|
|
6759
9248
|
if (last < text.length) runs.push({ text: text.slice(last) });
|
|
6760
9249
|
return runs.filter((r) => r.text.length > 0);
|
|
6761
9250
|
}
|
|
6762
9251
|
function charPrForRun(run) {
|
|
9252
|
+
if (run.code) return CHAR_CODE;
|
|
9253
|
+
if (run.strikethrough) return CHAR_STRIKETHROUGH;
|
|
9254
|
+
if (run.bold && run.italic) return CHAR_BOLD_ITALIC;
|
|
6763
9255
|
if (run.bold) return CHAR_BOLD;
|
|
6764
9256
|
if (run.italic) return CHAR_ITALIC;
|
|
6765
9257
|
return CHAR_NORMAL;
|
|
@@ -6767,23 +9259,71 @@ function charPrForRun(run) {
|
|
|
6767
9259
|
function makeRun(text, charPrId) {
|
|
6768
9260
|
return `<hp:run charPrIDRef="${charPrId}"><hp:t${text ? `>${escapeXml(text)}</hp:t` : "/"}></hp:run>`;
|
|
6769
9261
|
}
|
|
6770
|
-
function
|
|
9262
|
+
function makeHyperlinkRun(text, url, charPrId, nextId) {
|
|
9263
|
+
const subId = nextId();
|
|
9264
|
+
const paraId = nextId();
|
|
9265
|
+
return [
|
|
9266
|
+
`<hp:run charPrIDRef="${charPrId}">`,
|
|
9267
|
+
` <hp:ctrl>`,
|
|
9268
|
+
` <hp:hyperLink url="${escapeXml(url)}" macro="" visitedStyle="UNKNOWN" visitedStyleIDRef="4294967295">`,
|
|
9269
|
+
` <hp:subList id="${subId}" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP"`,
|
|
9270
|
+
` linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0"`,
|
|
9271
|
+
` hasTextRef="0" hasNumRef="0">`,
|
|
9272
|
+
` <hp:p id="${paraId}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
9273
|
+
` <hp:run charPrIDRef="${charPrId}"><hp:t>${escapeXml(text)}</hp:t></hp:run>`,
|
|
9274
|
+
` </hp:p>`,
|
|
9275
|
+
` </hp:subList>`,
|
|
9276
|
+
` </hp:hyperLink>`,
|
|
9277
|
+
` </hp:ctrl>`,
|
|
9278
|
+
`</hp:run>`
|
|
9279
|
+
].join("\n");
|
|
9280
|
+
}
|
|
9281
|
+
function makeRunsFromText(text, defaultCharPr, nextId) {
|
|
9282
|
+
if (/<br\s*\/?>/i.test(text)) {
|
|
9283
|
+
const parts = text.split(/<br\s*\/?>/i);
|
|
9284
|
+
return parts.map((part, i) => {
|
|
9285
|
+
const seg = makeRunsFromText(part, defaultCharPr, nextId);
|
|
9286
|
+
return i < parts.length - 1 ? seg + `<hp:run charPrIDRef="${defaultCharPr}"><hp:lf/></hp:run>` : seg;
|
|
9287
|
+
}).join("");
|
|
9288
|
+
}
|
|
6771
9289
|
const runs = parseInlineRuns(text);
|
|
6772
9290
|
if (runs.length === 0) return makeRun("", defaultCharPr);
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
return runs.map((r) =>
|
|
9291
|
+
const isPlain = runs.length === 1 && !runs[0].bold && !runs[0].italic && !runs[0].code && !runs[0].strikethrough && !runs[0].url;
|
|
9292
|
+
if (isPlain) return makeRun(runs[0].text, defaultCharPr);
|
|
9293
|
+
return runs.map((r) => {
|
|
9294
|
+
if (r.url && nextId) return makeHyperlinkRun(r.text, r.url, CHAR_NORMAL, nextId);
|
|
9295
|
+
return makeRun(r.text, charPrForRun(r));
|
|
9296
|
+
}).join("");
|
|
9297
|
+
}
|
|
9298
|
+
function makeLineseg(horzsize, vertsize) {
|
|
9299
|
+
const baseline = Math.round(vertsize * 0.85);
|
|
9300
|
+
return ` <hp:linesegarray>
|
|
9301
|
+
<hp:lineseg textpos="0" vertpos="0" vertsize="${vertsize}" textheight="${vertsize}" baseline="${baseline}" spacing="600" horzpos="0" horzsize="${horzsize}" flags="393216"/>
|
|
9302
|
+
</hp:linesegarray>`;
|
|
6776
9303
|
}
|
|
6777
|
-
var
|
|
6778
|
-
|
|
9304
|
+
var CHAR_HWP = 1e3;
|
|
9305
|
+
var LINE_HWP = 1400;
|
|
9306
|
+
var BASELINE_RATIO = 0.85;
|
|
9307
|
+
function estimateCellLineseg(plainText, cellHorzsize) {
|
|
9308
|
+
const stripped = plainText.replace(/<[^>]*>/g, "").replace(/\s+/g, " ").trim();
|
|
9309
|
+
const charsPerLine = Math.max(1, Math.floor(cellHorzsize / CHAR_HWP));
|
|
9310
|
+
const lineCount = Math.max(1, Math.ceil(stripped.length / charsPerLine));
|
|
9311
|
+
const baseline = Math.round(LINE_HWP * BASELINE_RATIO);
|
|
9312
|
+
const segs = Array.from({ length: lineCount }, (_, i) => {
|
|
9313
|
+
const textpos = i * charsPerLine;
|
|
9314
|
+
const vertpos = i * LINE_HWP;
|
|
9315
|
+
return ` <hp:lineseg textpos="${textpos}" vertpos="${vertpos}" vertsize="${LINE_HWP}" textheight="${LINE_HWP}" baseline="${vertpos + baseline}" spacing="600" horzpos="0" horzsize="${cellHorzsize}" flags="393216"/>`;
|
|
9316
|
+
});
|
|
9317
|
+
return ` <hp:linesegarray>
|
|
9318
|
+
${segs.join("\n")}
|
|
6779
9319
|
</hp:linesegarray>`;
|
|
6780
|
-
|
|
9320
|
+
}
|
|
9321
|
+
function makeParagraph(text, charPrId, paraPrId, nextId, styleId = "0") {
|
|
6781
9322
|
const id = nextId();
|
|
6782
|
-
const runs = makeRunsFromText(text, charPrId);
|
|
9323
|
+
const runs = makeRunsFromText(text, charPrId, nextId);
|
|
6783
9324
|
return [
|
|
6784
|
-
`<hp:p id="${id}" paraPrIDRef="${paraPrId}" styleIDRef="
|
|
9325
|
+
`<hp:p id="${id}" paraPrIDRef="${paraPrId}" styleIDRef="${styleId}" pageBreak="0" columnBreak="0" merged="0">`,
|
|
6785
9326
|
` ${runs}`,
|
|
6786
|
-
LINESEG,
|
|
6787
9327
|
`</hp:p>`
|
|
6788
9328
|
].join("\n");
|
|
6789
9329
|
}
|
|
@@ -6792,7 +9332,23 @@ function makeEmptyParagraph(nextId) {
|
|
|
6792
9332
|
return [
|
|
6793
9333
|
`<hp:p id="${id}" paraPrIDRef="${PARA_NORMAL}" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
6794
9334
|
` <hp:run charPrIDRef="${CHAR_NORMAL}"><hp:t/></hp:run>`,
|
|
6795
|
-
|
|
9335
|
+
`</hp:p>`
|
|
9336
|
+
].join("\n");
|
|
9337
|
+
}
|
|
9338
|
+
function makeBlockquoteParagraph(text, nextId) {
|
|
9339
|
+
const id = nextId();
|
|
9340
|
+
const runs = makeRunsFromText(text, CHAR_ITALIC, nextId);
|
|
9341
|
+
return [
|
|
9342
|
+
`<hp:p id="${id}" paraPrIDRef="${PARA_BLOCKQUOTE}" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
9343
|
+
` ${runs}`,
|
|
9344
|
+
`</hp:p>`
|
|
9345
|
+
].join("\n");
|
|
9346
|
+
}
|
|
9347
|
+
function makeHrParagraph(nextId) {
|
|
9348
|
+
const id = nextId();
|
|
9349
|
+
return [
|
|
9350
|
+
`<hp:p id="${id}" paraPrIDRef="${PARA_HR}" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
9351
|
+
` <hp:run charPrIDRef="${CHAR_NORMAL}"><hp:t/></hp:run>`,
|
|
6796
9352
|
`</hp:p>`
|
|
6797
9353
|
].join("\n");
|
|
6798
9354
|
}
|
|
@@ -6803,8 +9359,7 @@ function headingCharPr(level) {
|
|
|
6803
9359
|
return CHAR_H456;
|
|
6804
9360
|
}
|
|
6805
9361
|
var BODY_WIDTH = 42520;
|
|
6806
|
-
|
|
6807
|
-
function makeTableCell(text, colAddr, rowAddr, colWidth, isHeader, nextId, styleMap) {
|
|
9362
|
+
function makeTableCell(text, colAddr, rowAddr, colWidth, cellHeight, isHeader, nextId, styleMap) {
|
|
6808
9363
|
let charPr;
|
|
6809
9364
|
let borderFill = "3";
|
|
6810
9365
|
if (styleMap) {
|
|
@@ -6814,20 +9369,28 @@ function makeTableCell(text, colAddr, rowAddr, colWidth, isHeader, nextId, style
|
|
|
6814
9369
|
} else {
|
|
6815
9370
|
charPr = isHeader ? CHAR_BOLD : CHAR_NORMAL;
|
|
6816
9371
|
}
|
|
6817
|
-
const paraId = nextId();
|
|
6818
9372
|
const subId = nextId();
|
|
9373
|
+
const cellHorzsize = Math.max(1e3, colWidth - 2e3);
|
|
9374
|
+
const segments = text.split(/<br\s*\/?>/i);
|
|
9375
|
+
const cellParas = segments.map((seg) => {
|
|
9376
|
+
const pid = nextId();
|
|
9377
|
+
return [
|
|
9378
|
+
` <hp:p id="${pid}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
9379
|
+
` ${makeRunsFromText(seg, charPr, nextId)}`,
|
|
9380
|
+
estimateCellLineseg(seg, cellHorzsize),
|
|
9381
|
+
` </hp:p>`
|
|
9382
|
+
].join("\n");
|
|
9383
|
+
}).join("\n");
|
|
6819
9384
|
return [
|
|
6820
9385
|
`<hp:tc name="" header="${isHeader ? 1 : 0}" hasMargin="0" protect="0" editable="0" dirty="1" borderFillIDRef="${borderFill}">`,
|
|
6821
9386
|
` <hp:subList id="${subId}" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="CENTER"`,
|
|
6822
9387
|
` linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0"`,
|
|
6823
9388
|
` hasTextRef="0" hasNumRef="0">`,
|
|
6824
|
-
|
|
6825
|
-
` <hp:run charPrIDRef="${charPr}"><hp:t${text ? `>${escapeXml(text)}</hp:t` : "/"}></hp:run>`,
|
|
6826
|
-
` </hp:p>`,
|
|
9389
|
+
cellParas,
|
|
6827
9390
|
` </hp:subList>`,
|
|
6828
9391
|
` <hp:cellAddr colAddr="${colAddr}" rowAddr="${rowAddr}"/>`,
|
|
6829
9392
|
` <hp:cellSpan colSpan="1" rowSpan="1"/>`,
|
|
6830
|
-
` <hp:cellSz width="${colWidth}" height="${
|
|
9393
|
+
` <hp:cellSz width="${colWidth}" height="${cellHeight}"/>`,
|
|
6831
9394
|
` <hp:cellMargin left="1000" right="1000" top="500" bottom="500"/>`,
|
|
6832
9395
|
`</hp:tc>`
|
|
6833
9396
|
].join("\n");
|
|
@@ -6837,10 +9400,21 @@ function makeTable(rows, nextId, styleMap) {
|
|
|
6837
9400
|
const colCnt = rows[0].length;
|
|
6838
9401
|
const colWidth = Math.floor(BODY_WIDTH / colCnt);
|
|
6839
9402
|
const totalWidth = colWidth * colCnt;
|
|
6840
|
-
const
|
|
9403
|
+
const cellHorzsize = Math.max(1e3, colWidth - 2e3);
|
|
9404
|
+
const rowHeights = rows.map((row) => {
|
|
9405
|
+
const maxTotalLines = Math.max(1, ...row.map((cell) => {
|
|
9406
|
+
return cell.split(/<br\s*\/?>/i).reduce((sum, seg) => {
|
|
9407
|
+
const plain = seg.replace(/<[^>]*>/g, "").replace(/\s+/g, " ").trim();
|
|
9408
|
+
const charsPerLine = Math.max(1, Math.floor(cellHorzsize / CHAR_HWP));
|
|
9409
|
+
return sum + Math.max(1, Math.ceil(plain.length / charsPerLine));
|
|
9410
|
+
}, 0);
|
|
9411
|
+
}));
|
|
9412
|
+
return maxTotalLines * LINE_HWP + 1e3;
|
|
9413
|
+
});
|
|
9414
|
+
const totalHeight = rowHeights.reduce((s, h) => s + h, 0);
|
|
6841
9415
|
const trElements = rows.map(
|
|
6842
9416
|
(row, rowIdx) => `<hp:tr>
|
|
6843
|
-
${row.map((cell, colIdx) => makeTableCell(cell, colIdx, rowIdx, colWidth, rowIdx === 0, nextId, styleMap)).join("\n")}
|
|
9417
|
+
${row.map((cell, colIdx) => makeTableCell(cell, colIdx, rowIdx, colWidth, rowHeights[rowIdx], rowIdx === 0, nextId, styleMap)).join("\n")}
|
|
6844
9418
|
</hp:tr>`
|
|
6845
9419
|
).join("\n");
|
|
6846
9420
|
const tableId = nextId();
|
|
@@ -6861,10 +9435,19 @@ ${row.map((cell, colIdx) => makeTableCell(cell, colIdx, rowIdx, colWidth, rowIdx
|
|
|
6861
9435
|
trElements,
|
|
6862
9436
|
`</hp:tbl>`,
|
|
6863
9437
|
`</hp:run>`,
|
|
6864
|
-
|
|
9438
|
+
makeLineseg(totalWidth, totalHeight),
|
|
6865
9439
|
`</hp:p>`
|
|
6866
9440
|
].join("\n");
|
|
6867
9441
|
}
|
|
9442
|
+
function getIndent(line) {
|
|
9443
|
+
let spaces = 0;
|
|
9444
|
+
for (const ch of line) {
|
|
9445
|
+
if (ch === " ") spaces++;
|
|
9446
|
+
else if (ch === " ") spaces += 2;
|
|
9447
|
+
else break;
|
|
9448
|
+
}
|
|
9449
|
+
return Math.floor(spaces / 2);
|
|
9450
|
+
}
|
|
6868
9451
|
function parseMarkdownToBlocks(md) {
|
|
6869
9452
|
const lines = md.split("\n");
|
|
6870
9453
|
const blocks = [];
|
|
@@ -6877,12 +9460,32 @@ function parseMarkdownToBlocks(md) {
|
|
|
6877
9460
|
i++;
|
|
6878
9461
|
continue;
|
|
6879
9462
|
}
|
|
9463
|
+
if (/^(-{3,}|\*{3,}|_{3,})$/.test(trimmed)) {
|
|
9464
|
+
blocks.push({ type: "hr" });
|
|
9465
|
+
i++;
|
|
9466
|
+
continue;
|
|
9467
|
+
}
|
|
9468
|
+
if (trimmed.startsWith(">")) {
|
|
9469
|
+
const quoteLines = [];
|
|
9470
|
+
while (i < lines.length && lines[i].trim().startsWith(">")) {
|
|
9471
|
+
quoteLines.push(lines[i].trim().replace(/^>\s?/, ""));
|
|
9472
|
+
i++;
|
|
9473
|
+
}
|
|
9474
|
+
blocks.push({ type: "blockquote", text: quoteLines.join(" ") });
|
|
9475
|
+
continue;
|
|
9476
|
+
}
|
|
6880
9477
|
const hm = trimmed.match(/^(#{1,6})\s+(.+)$/);
|
|
6881
9478
|
if (hm) {
|
|
6882
9479
|
blocks.push({ type: "heading", text: hm[2].trim(), level: hm[1].length });
|
|
6883
9480
|
i++;
|
|
6884
9481
|
continue;
|
|
6885
9482
|
}
|
|
9483
|
+
const imgm = trimmed.match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
|
|
9484
|
+
if (imgm) {
|
|
9485
|
+
blocks.push({ type: "image", alt: imgm[1], src: imgm[2] });
|
|
9486
|
+
i++;
|
|
9487
|
+
continue;
|
|
9488
|
+
}
|
|
6886
9489
|
if (trimmed.startsWith("|")) {
|
|
6887
9490
|
const tableRows = [];
|
|
6888
9491
|
while (i < lines.length && lines[i].trim().startsWith("|")) {
|
|
@@ -6898,127 +9501,290 @@ function parseMarkdownToBlocks(md) {
|
|
|
6898
9501
|
if (tableRows.length > 0) blocks.push({ type: "table", rows: tableRows });
|
|
6899
9502
|
continue;
|
|
6900
9503
|
}
|
|
6901
|
-
if (
|
|
9504
|
+
if (/^\s*[-*+]\s/.test(line)) {
|
|
6902
9505
|
const items = [];
|
|
6903
|
-
while (i < lines.length && /^\s*[-*+]\s/.test(lines[i]))
|
|
6904
|
-
|
|
9506
|
+
while (i < lines.length && /^\s*[-*+]\s/.test(lines[i])) {
|
|
9507
|
+
const indent = getIndent(lines[i]);
|
|
9508
|
+
const text = lines[i].trim().replace(/^[-*+]\s+/, "");
|
|
9509
|
+
items.push({ text, indent });
|
|
9510
|
+
i++;
|
|
9511
|
+
}
|
|
6905
9512
|
blocks.push({ type: "list", listType: "unordered", items });
|
|
6906
9513
|
continue;
|
|
6907
9514
|
}
|
|
6908
|
-
if (/^\d+\.\s/.test(
|
|
9515
|
+
if (/^\s*\d+\.\s/.test(line)) {
|
|
6909
9516
|
const items = [];
|
|
6910
|
-
while (i < lines.length && /^\s*\d+\.\s/.test(lines[i]))
|
|
6911
|
-
|
|
9517
|
+
while (i < lines.length && /^\s*\d+\.\s/.test(lines[i])) {
|
|
9518
|
+
const indent = getIndent(lines[i]);
|
|
9519
|
+
const text = lines[i].trim().replace(/^\d+\.\s+/, "");
|
|
9520
|
+
items.push({ text, indent });
|
|
9521
|
+
i++;
|
|
9522
|
+
}
|
|
6912
9523
|
blocks.push({ type: "list", listType: "ordered", items });
|
|
6913
9524
|
continue;
|
|
6914
9525
|
}
|
|
6915
9526
|
if (trimmed.startsWith("```")) {
|
|
9527
|
+
const lang = trimmed.slice(3).trim();
|
|
6916
9528
|
i++;
|
|
6917
9529
|
const codeLines = [];
|
|
6918
9530
|
while (i < lines.length && !lines[i].trim().startsWith("```")) codeLines.push(lines[i++]);
|
|
6919
9531
|
if (i < lines.length) i++;
|
|
6920
|
-
if (codeLines.length > 0) blocks.push({ type: "
|
|
9532
|
+
if (codeLines.length > 0) blocks.push({ type: "code", text: codeLines.join("\n"), lang });
|
|
6921
9533
|
continue;
|
|
6922
9534
|
}
|
|
6923
9535
|
const paraLines = [];
|
|
6924
|
-
while (i < lines.length && lines[i].trim() && !lines[i].trim().startsWith("#") && !lines[i].trim().startsWith("|") && !/^\s*[-*+]\s/.test(lines[i]) && !/^\s*\d+\.\s/.test(lines[i]) && !lines[i].trim().startsWith("```")) paraLines.push(lines[i++].trim());
|
|
9536
|
+
while (i < lines.length && lines[i].trim() && !lines[i].trim().startsWith("#") && !lines[i].trim().startsWith("|") && !lines[i].trim().startsWith(">") && !/^\s*[-*+]\s/.test(lines[i]) && !/^\s*\d+\.\s/.test(lines[i]) && !lines[i].trim().startsWith("```") && !lines[i].trim().match(/^!\[[^\]]*\]\([^)]+\)$/) && !/^(-{3,}|\*{3,}|_{3,})$/.test(lines[i].trim())) paraLines.push(lines[i++].trim());
|
|
6925
9537
|
if (paraLines.length > 0) blocks.push({ type: "paragraph", text: paraLines.join(" ") });
|
|
6926
9538
|
}
|
|
6927
9539
|
return blocks;
|
|
6928
9540
|
}
|
|
6929
|
-
function
|
|
9541
|
+
function getImageDimensions(data) {
|
|
9542
|
+
if (data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) {
|
|
9543
|
+
if (data.length < 24) return null;
|
|
9544
|
+
const w = (data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19]) >>> 0;
|
|
9545
|
+
const h = (data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23]) >>> 0;
|
|
9546
|
+
return w > 0 && h > 0 ? { width: w, height: h } : null;
|
|
9547
|
+
}
|
|
9548
|
+
if (data[0] === 255 && data[1] === 216) {
|
|
9549
|
+
let i = 2;
|
|
9550
|
+
while (i < data.length - 8) {
|
|
9551
|
+
if (data[i] !== 255) break;
|
|
9552
|
+
const marker = data[i + 1];
|
|
9553
|
+
if (marker >= 192 && marker <= 195) {
|
|
9554
|
+
const h = data[i + 5] << 8 | data[i + 6];
|
|
9555
|
+
const w = data[i + 7] << 8 | data[i + 8];
|
|
9556
|
+
return w > 0 && h > 0 ? { width: w, height: h } : null;
|
|
9557
|
+
}
|
|
9558
|
+
if (marker === 217 || marker === 1 || marker >= 208 && marker <= 215) {
|
|
9559
|
+
i += 2;
|
|
9560
|
+
continue;
|
|
9561
|
+
}
|
|
9562
|
+
const segLen = data[i + 2] << 8 | data[i + 3];
|
|
9563
|
+
if (segLen < 2) break;
|
|
9564
|
+
i += 2 + segLen;
|
|
9565
|
+
}
|
|
9566
|
+
}
|
|
9567
|
+
return null;
|
|
9568
|
+
}
|
|
9569
|
+
function calcHwpSize(width, height) {
|
|
9570
|
+
if (width <= 0 || height <= 0) return { widthHwp: 28346, heightHwp: 19843 };
|
|
9571
|
+
const HWP_PER_PIXEL = 7200 / 96;
|
|
9572
|
+
const naturalW = Math.round(width * HWP_PER_PIXEL);
|
|
9573
|
+
const naturalH = Math.round(height * HWP_PER_PIXEL);
|
|
9574
|
+
const maxWidthHwp = 28346;
|
|
9575
|
+
if (naturalW <= maxWidthHwp) {
|
|
9576
|
+
return { widthHwp: naturalW, heightHwp: naturalH };
|
|
9577
|
+
}
|
|
9578
|
+
const ratio = height / width;
|
|
9579
|
+
return { widthHwp: maxWidthHwp, heightHwp: Math.round(maxWidthHwp * ratio) };
|
|
9580
|
+
}
|
|
9581
|
+
function mimeToFormat(mimeType) {
|
|
9582
|
+
if (mimeType.includes("jpeg") || mimeType.includes("jpg")) return "JPG";
|
|
9583
|
+
if (mimeType.includes("gif")) return "GIF";
|
|
9584
|
+
if (mimeType.includes("bmp")) return "BMP";
|
|
9585
|
+
return "PNG";
|
|
9586
|
+
}
|
|
9587
|
+
function makeImageParagraph(ref, nextId, widthHwp = 28346, heightHwp = 19843, naturalWidth, naturalHeight) {
|
|
9588
|
+
const paraId = nextId();
|
|
9589
|
+
const picId = nextId();
|
|
9590
|
+
const natW = naturalWidth || widthHwp;
|
|
9591
|
+
const natH = naturalHeight || heightHwp;
|
|
9592
|
+
const cx = Math.round(widthHwp / 2);
|
|
9593
|
+
const cy = Math.round(heightHwp / 2);
|
|
9594
|
+
const imgLineseg = [
|
|
9595
|
+
` <hp:linesegarray>`,
|
|
9596
|
+
` <hp:lineseg textpos="0" vertpos="0" vertsize="${heightHwp}" textheight="${heightHwp}"`,
|
|
9597
|
+
` baseline="${Math.round(heightHwp * 0.85)}" spacing="600"`,
|
|
9598
|
+
` horzpos="0" horzsize="42520" flags="393216"/>`,
|
|
9599
|
+
` </hp:linesegarray>`
|
|
9600
|
+
].join("\n");
|
|
9601
|
+
const pic = [
|
|
9602
|
+
` <hp:pic id="${picId}" zOrder="0" numberingType="NONE" textWrap="SQUARE" textFlow="BOTH_SIDES"`,
|
|
9603
|
+
` lock="0" dropcapstyle="None" href="" groupLevel="0" instid="0" reverse="0">`,
|
|
9604
|
+
` <hp:offset x="0" y="0"/>`,
|
|
9605
|
+
` <hp:orgSz width="${widthHwp}" height="${heightHwp}"/>`,
|
|
9606
|
+
` <hp:curSz width="${widthHwp}" height="${heightHwp}"/>`,
|
|
9607
|
+
` <hp:flip horizontal="0" vertical="0"/>`,
|
|
9608
|
+
` <hp:rotationInfo angle="0" centerX="${cx}" centerY="${cy}" rotateimage="1"/>`,
|
|
9609
|
+
` <hp:renderingInfo>`,
|
|
9610
|
+
` <hc:transMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/>`,
|
|
9611
|
+
` <hc:scaMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/>`,
|
|
9612
|
+
` <hc:rotMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/>`,
|
|
9613
|
+
` </hp:renderingInfo>`,
|
|
9614
|
+
` <hc:img binaryItemIDRef="${ref}" bright="0" contrast="0" effect="REAL_PIC" alpha="0"/>`,
|
|
9615
|
+
` <hp:imgRect>`,
|
|
9616
|
+
` <hc:pt0 x="0" y="0"/>`,
|
|
9617
|
+
` <hc:pt1 x="${widthHwp}" y="0"/>`,
|
|
9618
|
+
` <hc:pt2 x="${widthHwp}" y="${heightHwp}"/>`,
|
|
9619
|
+
` <hc:pt3 x="0" y="${heightHwp}"/>`,
|
|
9620
|
+
` </hp:imgRect>`,
|
|
9621
|
+
` <hp:imgClip left="0" right="${natW}" top="0" bottom="${natH}"/>`,
|
|
9622
|
+
` <hp:inMargin left="0" right="0" top="0" bottom="0"/>`,
|
|
9623
|
+
` <hp:imgDim dimwidth="${natW}" dimheight="${natH}"/>`,
|
|
9624
|
+
` <hp:effects/>`,
|
|
9625
|
+
` <hp:sz width="${widthHwp}" widthRelTo="ABSOLUTE" height="${heightHwp}" heightRelTo="ABSOLUTE" protect="0"/>`,
|
|
9626
|
+
` <hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0"`,
|
|
9627
|
+
` holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA"`,
|
|
9628
|
+
` vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/>`,
|
|
9629
|
+
` <hp:outMargin left="0" right="0" top="0" bottom="0"/>`,
|
|
9630
|
+
` </hp:pic>`
|
|
9631
|
+
].join("\n");
|
|
9632
|
+
return [
|
|
9633
|
+
`<hp:p id="${paraId}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
9634
|
+
` <hp:run charPrIDRef="0">`,
|
|
9635
|
+
pic,
|
|
9636
|
+
` </hp:run>`,
|
|
9637
|
+
imgLineseg,
|
|
9638
|
+
`</hp:p>`
|
|
9639
|
+
].join("\n");
|
|
9640
|
+
}
|
|
9641
|
+
function makeCodeParagraphs(code, nextId) {
|
|
9642
|
+
const lines = code.split("\n");
|
|
9643
|
+
return lines.map((line) => {
|
|
9644
|
+
const id = nextId();
|
|
9645
|
+
const safe = escapeXml(line || " ");
|
|
9646
|
+
return [
|
|
9647
|
+
`<hp:p id="${id}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
9648
|
+
` <hp:run charPrIDRef="${CHAR_CODE}"><hp:t>${safe}</hp:t></hp:run>`,
|
|
9649
|
+
`</hp:p>`
|
|
9650
|
+
].join("\n");
|
|
9651
|
+
}).join("\n");
|
|
9652
|
+
}
|
|
9653
|
+
function generateSectionXml(blocks, styleMap, imageMap, imageDimsMap, secPrXml, colPrXml, masterPageCnt = 0) {
|
|
6930
9654
|
const nextId = makeIdGen();
|
|
6931
9655
|
const firstId = nextId();
|
|
6932
9656
|
const defaultCharPr = styleMap ? styleMap.body.charPr : CHAR_NORMAL;
|
|
6933
9657
|
const defaultParaPr = styleMap ? styleMap.body.paraPr : PARA_NORMAL;
|
|
9658
|
+
const secPrContent = secPrXml ? secPrXml.replace(/masterPageCnt="\d+"/, `masterPageCnt="${masterPageCnt}"`) : [
|
|
9659
|
+
`<hp:secPr id="" textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" tabStopVal="4000" tabStopUnit="HWPUNIT" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="${masterPageCnt}">`,
|
|
9660
|
+
` <hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/>`,
|
|
9661
|
+
` <hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/>`,
|
|
9662
|
+
` <hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/>`,
|
|
9663
|
+
` <hp:lineNumberShape restartType="0" countBy="0" distance="0" startNumber="0"/>`,
|
|
9664
|
+
` <hp:pagePr landscape="WIDELY" width="59528" height="84186" gutterType="LEFT_ONLY">`,
|
|
9665
|
+
` <hp:margin header="4252" footer="4252" gutter="0" left="8504" right="8504" top="8504" bottom="8504"/>`,
|
|
9666
|
+
` </hp:pagePr>`,
|
|
9667
|
+
` <hp:footNotePr>`,
|
|
9668
|
+
` <hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/>`,
|
|
9669
|
+
` <hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/>`,
|
|
9670
|
+
` <hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/>`,
|
|
9671
|
+
` <hp:numbering type="CONTINUOUS" newNum="1"/>`,
|
|
9672
|
+
` <hp:placement place="EACH_COLUMN" beneathText="0"/>`,
|
|
9673
|
+
` </hp:footNotePr>`,
|
|
9674
|
+
` <hp:endNotePr>`,
|
|
9675
|
+
` <hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/>`,
|
|
9676
|
+
` <hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/>`,
|
|
9677
|
+
` <hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/>`,
|
|
9678
|
+
` <hp:numbering type="CONTINUOUS" newNum="1"/>`,
|
|
9679
|
+
` <hp:placement place="END_OF_DOCUMENT" beneathText="0"/>`,
|
|
9680
|
+
` </hp:endNotePr>`,
|
|
9681
|
+
`</hp:secPr>`
|
|
9682
|
+
].join("\n");
|
|
9683
|
+
const colPrContent = colPrXml || `<hp:ctrl>
|
|
9684
|
+
<hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="1" sameSz="1" sameGap="0"/>
|
|
9685
|
+
</hp:ctrl>`;
|
|
6934
9686
|
const secPrBlock = [
|
|
6935
9687
|
`<hp:p id="${firstId}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">`,
|
|
6936
9688
|
` <hp:run charPrIDRef="0">`,
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
` <hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/>`,
|
|
6940
|
-
` <hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/>`,
|
|
6941
|
-
` <hp:lineNumberShape restartType="0" countBy="0" distance="0" startNumber="0"/>`,
|
|
6942
|
-
` <hp:pagePr landscape="WIDELY" width="59528" height="84186" gutterType="LEFT_ONLY">`,
|
|
6943
|
-
` <hp:margin header="4252" footer="4252" gutter="0" left="8504" right="8504" top="8504" bottom="8504"/>`,
|
|
6944
|
-
` </hp:pagePr>`,
|
|
6945
|
-
` <hp:footNotePr>`,
|
|
6946
|
-
` <hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/>`,
|
|
6947
|
-
` <hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/>`,
|
|
6948
|
-
` <hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/>`,
|
|
6949
|
-
` <hp:numbering type="CONTINUOUS" newNum="1"/>`,
|
|
6950
|
-
` <hp:placement place="EACH_COLUMN" beneathText="0"/>`,
|
|
6951
|
-
` </hp:footNotePr>`,
|
|
6952
|
-
` <hp:endNotePr>`,
|
|
6953
|
-
` <hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/>`,
|
|
6954
|
-
` <hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/>`,
|
|
6955
|
-
` <hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/>`,
|
|
6956
|
-
` <hp:numbering type="CONTINUOUS" newNum="1"/>`,
|
|
6957
|
-
` <hp:placement place="END_OF_DOCUMENT" beneathText="0"/>`,
|
|
6958
|
-
` </hp:endNotePr>`,
|
|
6959
|
-
` <hp:pageBorderFill type="BOTH" borderFillIDRef="1" textBorder="PAPER" headerInside="0" footerInside="0" fillArea="PAPER">`,
|
|
6960
|
-
` <hp:offset left="1417" right="1417" top="1417" bottom="1417"/>`,
|
|
6961
|
-
` </hp:pageBorderFill>`,
|
|
6962
|
-
` <hp:pageBorderFill type="EVEN" borderFillIDRef="1" textBorder="PAPER" headerInside="0" footerInside="0" fillArea="PAPER">`,
|
|
6963
|
-
` <hp:offset left="1417" right="1417" top="1417" bottom="1417"/>`,
|
|
6964
|
-
` </hp:pageBorderFill>`,
|
|
6965
|
-
` <hp:pageBorderFill type="ODD" borderFillIDRef="1" textBorder="PAPER" headerInside="0" footerInside="0" fillArea="PAPER">`,
|
|
6966
|
-
` <hp:offset left="1417" right="1417" top="1417" bottom="1417"/>`,
|
|
6967
|
-
` </hp:pageBorderFill>`,
|
|
6968
|
-
` </hp:secPr>`,
|
|
6969
|
-
` <hp:ctrl>`,
|
|
6970
|
-
` <hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="1" sameSz="1" sameGap="0"/>`,
|
|
6971
|
-
` </hp:ctrl>`,
|
|
9689
|
+
secPrContent,
|
|
9690
|
+
colPrContent,
|
|
6972
9691
|
` </hp:run>`,
|
|
6973
9692
|
` <hp:run charPrIDRef="0"><hp:t/></hp:run>`,
|
|
6974
|
-
|
|
9693
|
+
makeLineseg(42520, 1e3),
|
|
6975
9694
|
`</hp:p>`
|
|
6976
9695
|
].join("\n");
|
|
6977
9696
|
const bodyParts = [];
|
|
9697
|
+
const orderedCounters = /* @__PURE__ */ new Map();
|
|
6978
9698
|
for (const block of blocks) {
|
|
9699
|
+
if (block.type !== "list") orderedCounters.clear();
|
|
6979
9700
|
switch (block.type) {
|
|
6980
9701
|
case "heading": {
|
|
6981
9702
|
const level = block.level || 1;
|
|
6982
|
-
const headingKey = `h${level}`;
|
|
6983
9703
|
let charPrId;
|
|
6984
9704
|
let paraPrId;
|
|
9705
|
+
let styleId = "0";
|
|
6985
9706
|
if (styleMap) {
|
|
6986
9707
|
const blockType = level === 1 ? "h1" : level === 2 ? "h2" : level === 3 ? "h3" : "h4";
|
|
6987
9708
|
const style = getStyleForBlock(styleMap, blockType);
|
|
6988
9709
|
charPrId = style.charPr;
|
|
6989
9710
|
paraPrId = style.paraPr || defaultParaPr;
|
|
9711
|
+
styleId = style.styleId ?? "0";
|
|
6990
9712
|
} else {
|
|
6991
9713
|
charPrId = headingCharPr(level);
|
|
6992
9714
|
paraPrId = PARA_NORMAL;
|
|
6993
9715
|
}
|
|
6994
|
-
bodyParts.push(makeParagraph(block.text || "", charPrId, paraPrId, nextId));
|
|
9716
|
+
bodyParts.push(makeParagraph(block.text || "", charPrId, paraPrId, nextId, styleId));
|
|
6995
9717
|
break;
|
|
6996
9718
|
}
|
|
6997
9719
|
case "paragraph": {
|
|
6998
9720
|
if (block.text) {
|
|
6999
9721
|
const charPrId = styleMap ? styleMap.body.charPr : CHAR_NORMAL;
|
|
7000
9722
|
const paraPrId = styleMap ? styleMap.body.paraPr : PARA_NORMAL;
|
|
7001
|
-
|
|
9723
|
+
const styleId = styleMap ? styleMap.body.styleId ?? "0" : "0";
|
|
9724
|
+
bodyParts.push(makeParagraph(block.text, charPrId, paraPrId, nextId, styleId));
|
|
7002
9725
|
} else {
|
|
7003
9726
|
bodyParts.push(makeEmptyParagraph(nextId));
|
|
7004
9727
|
}
|
|
7005
9728
|
break;
|
|
7006
9729
|
}
|
|
9730
|
+
case "code": {
|
|
9731
|
+
bodyParts.push(makeCodeParagraphs(block.text || "", nextId));
|
|
9732
|
+
break;
|
|
9733
|
+
}
|
|
9734
|
+
case "blockquote":
|
|
9735
|
+
if (block.text) bodyParts.push(makeBlockquoteParagraph(block.text, nextId));
|
|
9736
|
+
break;
|
|
9737
|
+
case "hr":
|
|
9738
|
+
bodyParts.push(makeHrParagraph(nextId));
|
|
9739
|
+
break;
|
|
7007
9740
|
case "empty":
|
|
7008
9741
|
bodyParts.push(makeEmptyParagraph(nextId));
|
|
7009
9742
|
break;
|
|
7010
9743
|
case "list": {
|
|
7011
9744
|
const charPrId = styleMap ? styleMap.body.charPr : CHAR_NORMAL;
|
|
7012
9745
|
const paraPrId = styleMap ? styleMap.body.paraPr : PARA_NORMAL;
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
9746
|
+
const items = block.items || [];
|
|
9747
|
+
if (block.listType === "ordered") {
|
|
9748
|
+
for (const item of items) {
|
|
9749
|
+
const cnt = (orderedCounters.get(item.indent) || 0) + 1;
|
|
9750
|
+
orderedCounters.set(item.indent, cnt);
|
|
9751
|
+
for (const [k] of orderedCounters) {
|
|
9752
|
+
if (k > item.indent) orderedCounters.set(k, 0);
|
|
9753
|
+
}
|
|
9754
|
+
const indent = " ".repeat(item.indent);
|
|
9755
|
+
bodyParts.push(makeParagraph(`${indent}${cnt}. ${item.text}`, charPrId, paraPrId, nextId));
|
|
9756
|
+
}
|
|
9757
|
+
} else {
|
|
9758
|
+
for (const item of items) {
|
|
9759
|
+
const bullets = ["\u2022", "\u25E6", "\u25AA"];
|
|
9760
|
+
const bullet = bullets[Math.min(item.indent, bullets.length - 1)];
|
|
9761
|
+
const indent = " ".repeat(item.indent);
|
|
9762
|
+
bodyParts.push(makeParagraph(`${indent}${bullet} ${item.text}`, charPrId, paraPrId, nextId));
|
|
9763
|
+
}
|
|
7016
9764
|
}
|
|
7017
9765
|
break;
|
|
7018
9766
|
}
|
|
7019
9767
|
case "table":
|
|
7020
9768
|
if (block.rows?.length) bodyParts.push(makeTable(block.rows, nextId, styleMap));
|
|
7021
9769
|
break;
|
|
9770
|
+
case "image": {
|
|
9771
|
+
const src = block.src || "";
|
|
9772
|
+
const srcBasename = src.includes("/") || src.includes("\\") ? src.split(/[\\/]/).pop() : src;
|
|
9773
|
+
const extLower = srcBasename.toLowerCase();
|
|
9774
|
+
if (extLower.endsWith(".wmf") || extLower.endsWith(".emf")) break;
|
|
9775
|
+
const ref = imageMap?.get(src) ?? imageMap?.get(srcBasename);
|
|
9776
|
+
if (ref !== void 0) {
|
|
9777
|
+
const dims = imageDimsMap?.get(ref);
|
|
9778
|
+
const { widthHwp, heightHwp } = dims ? calcHwpSize(dims.width, dims.height) : { widthHwp: 28346, heightHwp: 19843 };
|
|
9779
|
+
const natW = dims ? Math.round(dims.width * 75) : widthHwp;
|
|
9780
|
+
const natH = dims ? Math.round(dims.height * 75) : heightHwp;
|
|
9781
|
+
bodyParts.push(makeImageParagraph(ref, nextId, widthHwp, heightHwp, natW, natH));
|
|
9782
|
+
} else {
|
|
9783
|
+
const alt = block.alt || src || "(\uC774\uBBF8\uC9C0)";
|
|
9784
|
+
bodyParts.push(makeParagraph(`[\uC774\uBBF8\uC9C0: ${alt}]`, CHAR_NORMAL, PARA_NORMAL, nextId));
|
|
9785
|
+
}
|
|
9786
|
+
break;
|
|
9787
|
+
}
|
|
7022
9788
|
}
|
|
7023
9789
|
}
|
|
7024
9790
|
return [
|
|
@@ -7039,25 +9805,86 @@ async function markdownToHwpx(markdown, options) {
|
|
|
7039
9805
|
const warnings = opts.warnings || [];
|
|
7040
9806
|
let styleMap = null;
|
|
7041
9807
|
let headerXml = HEADER_XML;
|
|
7042
|
-
let
|
|
9808
|
+
let secPrXml;
|
|
9809
|
+
let colPrXml;
|
|
9810
|
+
let masterpages = [];
|
|
7043
9811
|
if (opts.templateArrayBuffer) {
|
|
7044
9812
|
try {
|
|
7045
9813
|
const templateStyles = await extractTemplateStyles(opts.templateArrayBuffer);
|
|
7046
9814
|
styleMap = createStyleMap(templateStyles, warnings);
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
if (
|
|
7051
|
-
headerXml = await headerFile.async("text");
|
|
7052
|
-
}
|
|
9815
|
+
if (templateStyles.headerXml) headerXml = templateStyles.headerXml;
|
|
9816
|
+
if (templateStyles.secPrXml) secPrXml = templateStyles.secPrXml;
|
|
9817
|
+
if (templateStyles.colPrXml) colPrXml = templateStyles.colPrXml;
|
|
9818
|
+
if (templateStyles.masterpages?.length) masterpages = templateStyles.masterpages;
|
|
7053
9819
|
} catch (err) {
|
|
7054
9820
|
const msg = err instanceof Error ? err.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958";
|
|
7055
9821
|
warnings.push(`[warn] \uD15C\uD50C\uB9BF \uCC98\uB9AC \uC2E4\uD328: ${msg}. \uAE30\uBCF8 \uC2A4\uD0C0\uC77C \uC0AC\uC6A9`);
|
|
7056
9822
|
}
|
|
7057
9823
|
}
|
|
9824
|
+
const imageMap = /* @__PURE__ */ new Map();
|
|
9825
|
+
const imageDimsMap = /* @__PURE__ */ new Map();
|
|
9826
|
+
const binDataEntries = [];
|
|
9827
|
+
const usedRefs = /* @__PURE__ */ new Set();
|
|
9828
|
+
if (opts.images && opts.images.length > 0) {
|
|
9829
|
+
for (const img of opts.images) {
|
|
9830
|
+
const nameWithoutExt = img.filename.replace(/\.[^.]+$/, "");
|
|
9831
|
+
const format = mimeToFormat(img.mimeType);
|
|
9832
|
+
const ext = format.toLowerCase() === "jpg" ? "jpg" : format.toLowerCase();
|
|
9833
|
+
let ref = nameWithoutExt;
|
|
9834
|
+
let counter = 1;
|
|
9835
|
+
while (usedRefs.has(ref)) ref = `${nameWithoutExt}_${counter++}`;
|
|
9836
|
+
usedRefs.add(ref);
|
|
9837
|
+
const dims = getImageDimensions(img.data) || void 0;
|
|
9838
|
+
binDataEntries.push({ ref, zipPath: `BinData/${ref}.${ext}`, data: img.data, dims });
|
|
9839
|
+
if (dims) imageDimsMap.set(ref, dims);
|
|
9840
|
+
imageMap.set(img.filename, ref);
|
|
9841
|
+
}
|
|
9842
|
+
}
|
|
9843
|
+
const allBlocks = parseMarkdownToBlocks(markdown);
|
|
9844
|
+
for (const block of allBlocks) {
|
|
9845
|
+
if (block.type === "image" && block.src?.startsWith("data:") && !imageMap.has(block.src)) {
|
|
9846
|
+
const commaIdx = block.src.indexOf(",");
|
|
9847
|
+
if (commaIdx === -1) continue;
|
|
9848
|
+
const header = block.src.slice(0, commaIdx);
|
|
9849
|
+
const b64 = block.src.slice(commaIdx + 1);
|
|
9850
|
+
const mimeMatch = header.match(/data:([^;]+)/);
|
|
9851
|
+
const mimeType = mimeMatch?.[1] || "image/png";
|
|
9852
|
+
const format = mimeToFormat(mimeType);
|
|
9853
|
+
const ext = format.toLowerCase() === "jpg" ? "jpg" : format.toLowerCase();
|
|
9854
|
+
const data = Buffer.from(b64, "base64");
|
|
9855
|
+
const ref = `datauri_${binDataEntries.length + 1}`;
|
|
9856
|
+
const dims = getImageDimensions(data) || void 0;
|
|
9857
|
+
imageMap.set(block.src, ref);
|
|
9858
|
+
binDataEntries.push({ ref, zipPath: `BinData/${ref}.${ext}`, data, dims });
|
|
9859
|
+
if (dims) imageDimsMap.set(ref, dims);
|
|
9860
|
+
}
|
|
9861
|
+
}
|
|
7058
9862
|
const sectionXml = generateSectionXml(
|
|
7059
|
-
|
|
7060
|
-
styleMap || void 0
|
|
9863
|
+
allBlocks,
|
|
9864
|
+
styleMap || void 0,
|
|
9865
|
+
imageMap.size > 0 ? imageMap : void 0,
|
|
9866
|
+
imageDimsMap.size > 0 ? imageDimsMap : void 0,
|
|
9867
|
+
secPrXml,
|
|
9868
|
+
colPrXml,
|
|
9869
|
+
masterpages.length
|
|
9870
|
+
);
|
|
9871
|
+
const formatToMediaType = (zipPath) => {
|
|
9872
|
+
const ext = zipPath.split(".").pop()?.toLowerCase() || "";
|
|
9873
|
+
if (ext === "png") return "image/png";
|
|
9874
|
+
if (ext === "gif") return "image/gif";
|
|
9875
|
+
if (ext === "bmp") return "image/bmp";
|
|
9876
|
+
return "image/jpg";
|
|
9877
|
+
};
|
|
9878
|
+
const imageItems = binDataEntries.map((e) => ` <opf:item id="${e.ref}" href="${e.zipPath}" media-type="${formatToMediaType(e.zipPath)}" isEmbeded="1"/>`).join("\n");
|
|
9879
|
+
const masterpageItems = masterpages.map((mp) => {
|
|
9880
|
+
const id = mp.filename.replace("Contents/", "").replace(".xml", "");
|
|
9881
|
+
return ` <opf:item id="${id}" href="${mp.filename}" media-type="application/xml"/>`;
|
|
9882
|
+
}).join("\n");
|
|
9883
|
+
const extraItems = [imageItems, masterpageItems].filter(Boolean).join("\n");
|
|
9884
|
+
const contentHpf = CONTENT_HPF.replace(
|
|
9885
|
+
` <opf:item id="header"`,
|
|
9886
|
+
extraItems ? `${extraItems}
|
|
9887
|
+
<opf:item id="header"` : ` <opf:item id="header"`
|
|
7061
9888
|
);
|
|
7062
9889
|
const zip = new import_jszip6.default();
|
|
7063
9890
|
zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
|
|
@@ -7067,21 +9894,173 @@ async function markdownToHwpx(markdown, options) {
|
|
|
7067
9894
|
zip.file("version.xml", VERSION_XML);
|
|
7068
9895
|
zip.file("settings.xml", SETTINGS_XML);
|
|
7069
9896
|
zip.file("Preview/PrvText.txt", "");
|
|
7070
|
-
zip.file("Contents/content.hpf",
|
|
9897
|
+
zip.file("Contents/content.hpf", contentHpf);
|
|
7071
9898
|
zip.file("Contents/header.xml", headerXml);
|
|
7072
9899
|
zip.file("Contents/section0.xml", sectionXml);
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
9900
|
+
for (const mp of masterpages) {
|
|
9901
|
+
zip.file(mp.filename, mp.content);
|
|
9902
|
+
}
|
|
9903
|
+
for (const entry of binDataEntries) {
|
|
9904
|
+
if (entry.data) {
|
|
9905
|
+
zip.file(entry.zipPath, entry.data);
|
|
7078
9906
|
}
|
|
7079
9907
|
}
|
|
7080
9908
|
return await zip.generateAsync({ type: "arraybuffer" });
|
|
7081
9909
|
}
|
|
7082
9910
|
|
|
9911
|
+
// src/xlsx/generator.ts
|
|
9912
|
+
var import_exceljs = __toESM(require("exceljs"), 1);
|
|
9913
|
+
function mimeToExtension(mimeType) {
|
|
9914
|
+
if (mimeType.includes("jpeg") || mimeType.includes("jpg")) return "jpeg";
|
|
9915
|
+
if (mimeType.includes("gif")) return "gif";
|
|
9916
|
+
return "png";
|
|
9917
|
+
}
|
|
9918
|
+
function buildImageMap(images) {
|
|
9919
|
+
const map = /* @__PURE__ */ new Map();
|
|
9920
|
+
if (!images) return map;
|
|
9921
|
+
for (const img of images) map.set(img.filename, img);
|
|
9922
|
+
return map;
|
|
9923
|
+
}
|
|
9924
|
+
async function fillBodySheet(sheet, workbook, blocks, imageMap) {
|
|
9925
|
+
sheet.getColumn(1).width = 80;
|
|
9926
|
+
for (const block of blocks) {
|
|
9927
|
+
switch (block.type) {
|
|
9928
|
+
case "heading": {
|
|
9929
|
+
const level = block.level || 1;
|
|
9930
|
+
const size = level === 1 ? 20 : level === 2 ? 16 : level === 3 ? 14 : 12;
|
|
9931
|
+
const row = sheet.addRow([block.text || ""]);
|
|
9932
|
+
row.getCell(1).font = { bold: true, size };
|
|
9933
|
+
row.getCell(1).alignment = { wrapText: true };
|
|
9934
|
+
break;
|
|
9935
|
+
}
|
|
9936
|
+
case "paragraph": {
|
|
9937
|
+
const row = sheet.addRow([block.text || ""]);
|
|
9938
|
+
row.getCell(1).alignment = { wrapText: true };
|
|
9939
|
+
break;
|
|
9940
|
+
}
|
|
9941
|
+
case "code": {
|
|
9942
|
+
const lines = (block.text || "").split("\n");
|
|
9943
|
+
for (const line of lines) {
|
|
9944
|
+
const row = sheet.addRow([line || " "]);
|
|
9945
|
+
row.getCell(1).font = { name: "Courier New", size: 9 };
|
|
9946
|
+
row.getCell(1).fill = {
|
|
9947
|
+
type: "pattern",
|
|
9948
|
+
pattern: "solid",
|
|
9949
|
+
fgColor: { argb: "FFF2F2F2" }
|
|
9950
|
+
};
|
|
9951
|
+
}
|
|
9952
|
+
break;
|
|
9953
|
+
}
|
|
9954
|
+
case "blockquote": {
|
|
9955
|
+
const row = sheet.addRow([block.text || ""]);
|
|
9956
|
+
row.getCell(1).font = { italic: true, color: { argb: "FF888888" } };
|
|
9957
|
+
row.getCell(1).alignment = { wrapText: true };
|
|
9958
|
+
break;
|
|
9959
|
+
}
|
|
9960
|
+
case "hr": {
|
|
9961
|
+
const row = sheet.addRow([""]);
|
|
9962
|
+
row.getCell(1).border = {
|
|
9963
|
+
bottom: { style: "medium", color: { argb: "FF888888" } }
|
|
9964
|
+
};
|
|
9965
|
+
break;
|
|
9966
|
+
}
|
|
9967
|
+
case "empty": {
|
|
9968
|
+
sheet.addRow([""]);
|
|
9969
|
+
break;
|
|
9970
|
+
}
|
|
9971
|
+
case "list": {
|
|
9972
|
+
for (const item of block.items || []) {
|
|
9973
|
+
const indent = " ".repeat(item.indent);
|
|
9974
|
+
const bullet = block.listType === "ordered" ? `${item.indent + 1}. ` : ["\u2022 ", "\u25E6 ", "\u25AA "][Math.min(item.indent, 2)];
|
|
9975
|
+
const row = sheet.addRow([`${indent}${bullet}${item.text}`]);
|
|
9976
|
+
row.getCell(1).alignment = { wrapText: true };
|
|
9977
|
+
}
|
|
9978
|
+
break;
|
|
9979
|
+
}
|
|
9980
|
+
case "image": {
|
|
9981
|
+
const src = block.src || "";
|
|
9982
|
+
const img = imageMap.get(src);
|
|
9983
|
+
if (img) {
|
|
9984
|
+
const currentRow = sheet.rowCount + 1;
|
|
9985
|
+
const ext = mimeToExtension(img.mimeType);
|
|
9986
|
+
const imageId = workbook.addImage({ base64: Buffer.from(img.data).toString("base64"), extension: ext });
|
|
9987
|
+
sheet.addRow([""]);
|
|
9988
|
+
sheet.addImage(imageId, {
|
|
9989
|
+
tl: { col: 0, row: currentRow - 1 },
|
|
9990
|
+
ext: { width: 300, height: 200 }
|
|
9991
|
+
});
|
|
9992
|
+
sheet.getRow(currentRow).height = 155;
|
|
9993
|
+
} else {
|
|
9994
|
+
const alt = block.alt || src || "(\uC774\uBBF8\uC9C0)";
|
|
9995
|
+
const row = sheet.addRow([`[\uC774\uBBF8\uC9C0: ${alt}]`]);
|
|
9996
|
+
row.getCell(1).font = { italic: true, color: { argb: "FF999999" } };
|
|
9997
|
+
}
|
|
9998
|
+
break;
|
|
9999
|
+
}
|
|
10000
|
+
}
|
|
10001
|
+
}
|
|
10002
|
+
}
|
|
10003
|
+
function fillTableSheet(sheet, rows) {
|
|
10004
|
+
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
|
|
10005
|
+
const cells = rows[rowIdx];
|
|
10006
|
+
const row = sheet.addRow(cells);
|
|
10007
|
+
cells.forEach((cell, colIdx) => {
|
|
10008
|
+
const col = sheet.getColumn(colIdx + 1);
|
|
10009
|
+
col.width = Math.max(col.width ?? 10, Math.min(cell.length + 4, 40));
|
|
10010
|
+
});
|
|
10011
|
+
if (rowIdx === 0) {
|
|
10012
|
+
row.eachCell((cell) => {
|
|
10013
|
+
cell.font = { bold: true };
|
|
10014
|
+
cell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FFD9E1F2" } };
|
|
10015
|
+
cell.border = {
|
|
10016
|
+
top: { style: "thin" },
|
|
10017
|
+
bottom: { style: "thin" },
|
|
10018
|
+
left: { style: "thin" },
|
|
10019
|
+
right: { style: "thin" }
|
|
10020
|
+
};
|
|
10021
|
+
cell.alignment = { wrapText: true };
|
|
10022
|
+
});
|
|
10023
|
+
} else {
|
|
10024
|
+
row.eachCell((cell) => {
|
|
10025
|
+
cell.border = {
|
|
10026
|
+
top: { style: "thin" },
|
|
10027
|
+
bottom: { style: "thin" },
|
|
10028
|
+
left: { style: "thin" },
|
|
10029
|
+
right: { style: "thin" }
|
|
10030
|
+
};
|
|
10031
|
+
cell.alignment = { wrapText: true };
|
|
10032
|
+
});
|
|
10033
|
+
}
|
|
10034
|
+
}
|
|
10035
|
+
}
|
|
10036
|
+
async function markdownToXlsx(markdown, options) {
|
|
10037
|
+
const warnings = options?.warnings || [];
|
|
10038
|
+
const imageMap = buildImageMap(options?.images);
|
|
10039
|
+
const blocks = parseMarkdownToBlocks(markdown);
|
|
10040
|
+
const workbook = new import_exceljs.default.Workbook();
|
|
10041
|
+
workbook.created = /* @__PURE__ */ new Date();
|
|
10042
|
+
const tableBlocks = blocks.filter((b) => b.type === "table");
|
|
10043
|
+
const bodyBlocks = blocks.filter((b) => b.type !== "table");
|
|
10044
|
+
const hasBodyContent = bodyBlocks.some((b) => b.type !== "empty");
|
|
10045
|
+
if (hasBodyContent) {
|
|
10046
|
+
const bodySheet = workbook.addWorksheet("\uBCF8\uBB38");
|
|
10047
|
+
await fillBodySheet(bodySheet, workbook, bodyBlocks, imageMap);
|
|
10048
|
+
}
|
|
10049
|
+
tableBlocks.forEach((block, idx) => {
|
|
10050
|
+
if (!block.rows?.length) return;
|
|
10051
|
+
const sheet = workbook.addWorksheet(`Table ${idx + 1}`);
|
|
10052
|
+
fillTableSheet(sheet, block.rows);
|
|
10053
|
+
});
|
|
10054
|
+
if (workbook.worksheets.length === 0) {
|
|
10055
|
+
workbook.addWorksheet("\uBCF8\uBB38");
|
|
10056
|
+
warnings.push("[warn] \uBCC0\uD658\uD560 \uB0B4\uC6A9\uC774 \uC5C6\uC5B4 \uBE48 \uC2DC\uD2B8\uB97C \uC0DD\uC131\uD588\uC2B5\uB2C8\uB2E4.");
|
|
10057
|
+
}
|
|
10058
|
+
const buffer = await workbook.xlsx.writeBuffer();
|
|
10059
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
10060
|
+
}
|
|
10061
|
+
|
|
7083
10062
|
// src/index.ts
|
|
7084
|
-
async function
|
|
10063
|
+
async function parse2(input, options) {
|
|
7085
10064
|
let buffer;
|
|
7086
10065
|
if (typeof input === "string") {
|
|
7087
10066
|
try {
|
|
@@ -7170,6 +10149,7 @@ async function parseDocx(buffer, options) {
|
|
|
7170
10149
|
isPdfFile,
|
|
7171
10150
|
isZipFile,
|
|
7172
10151
|
markdownToHwpx,
|
|
10152
|
+
markdownToXlsx,
|
|
7173
10153
|
parse,
|
|
7174
10154
|
parseDocx,
|
|
7175
10155
|
parseHwp,
|
|
@@ -7177,4 +10157,9 @@ async function parseDocx(buffer, options) {
|
|
|
7177
10157
|
parsePdf,
|
|
7178
10158
|
parseXlsx
|
|
7179
10159
|
});
|
|
10160
|
+
/*! Bundled license information:
|
|
10161
|
+
|
|
10162
|
+
cfb/cfb.js:
|
|
10163
|
+
(*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com *)
|
|
10164
|
+
*/
|
|
7180
10165
|
//# sourceMappingURL=index.cjs.map
|