xshell 1.2.30 → 1.2.32
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/fflate.d.ts +359 -0
- package/fflate.js +1175 -0
- package/file.d.ts +41 -0
- package/file.js +220 -3
- package/package.json +7 -7
- package/path.d.ts +2 -2
package/fflate.js
ADDED
|
@@ -0,0 +1,1175 @@
|
|
|
1
|
+
// 从 https://github.com/101arrowz/fflate v0.7.4 复制过来并修改,github commit 0f439ed3293b1da1f439fbbc5125b1097b75d3ac
|
|
2
|
+
// 删掉了 worker, async, stream 相关的实现和接口,主要保证 unzipSync 能够使用
|
|
3
|
+
// 增加了 decoder 参数以支持文件名使用别的编码方式解码,如 gb18030, shift-jis
|
|
4
|
+
import { encode } from "./utils.js";
|
|
5
|
+
// DEFLATE is a complex format; to read this code, you should probably check the RFC first:
|
|
6
|
+
// https://tools.ietf.org/html/rfc1951
|
|
7
|
+
// You may also wish to take a look at the guide I made about this program:
|
|
8
|
+
// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad
|
|
9
|
+
// Some of the following code is similar to that of UZIP.js:
|
|
10
|
+
// https://github.com/photopea/UZIP.js
|
|
11
|
+
// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.
|
|
12
|
+
// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint
|
|
13
|
+
// is better for memory in most engines (I *think*).
|
|
14
|
+
// fixed length extra bits
|
|
15
|
+
const fleb = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);
|
|
16
|
+
// fixed distance extra bits
|
|
17
|
+
// see fleb note
|
|
18
|
+
const fdeb = Buffer.from([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);
|
|
19
|
+
// code length index map
|
|
20
|
+
const clim = Buffer.from([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
21
|
+
// get base, reverse index map from extra bits
|
|
22
|
+
function freb(eb, start) {
|
|
23
|
+
const b = new Uint16Array(31);
|
|
24
|
+
for (let i = 0; i < 31; ++i)
|
|
25
|
+
b[i] = start += 1 << eb[i - 1];
|
|
26
|
+
// numbers here are at max 18 bits
|
|
27
|
+
const r = new Uint32Array(b[30]);
|
|
28
|
+
for (let i = 1; i < 30; ++i)
|
|
29
|
+
for (let j = b[i]; j < b[i + 1]; ++j)
|
|
30
|
+
r[j] = ((j - b[i]) << 5) | i;
|
|
31
|
+
return [b, r];
|
|
32
|
+
}
|
|
33
|
+
const [fl, revfl] = freb(fleb, 2);
|
|
34
|
+
(fl[28] = 258), (revfl[258] = 28);
|
|
35
|
+
const [fd, revfd] = freb(fdeb, 0);
|
|
36
|
+
// map of value to reverse (assuming 16 bits)
|
|
37
|
+
const rev = new Uint16Array(32768);
|
|
38
|
+
for (let i = 0; i < 32768; ++i) {
|
|
39
|
+
// reverse table algorithm from SO
|
|
40
|
+
let x = ((i & 0xaaaa) >>> 1) | ((i & 0x5555) << 1);
|
|
41
|
+
x = ((x & 0xcccc) >>> 2) | ((x & 0x3333) << 2);
|
|
42
|
+
x = ((x & 0xf0f0) >>> 4) | ((x & 0x0f0f) << 4);
|
|
43
|
+
rev[i] = (((x & 0xff00) >>> 8) | ((x & 0x00ff) << 8)) >>> 1;
|
|
44
|
+
}
|
|
45
|
+
// create huffman tree from u8 "map": index -> code length for code index
|
|
46
|
+
// mb (max bits) must be at most 15
|
|
47
|
+
// TODO: optimize/split up?
|
|
48
|
+
function hMap(cd, mb, r) {
|
|
49
|
+
const s = cd.length;
|
|
50
|
+
// index
|
|
51
|
+
let i = 0;
|
|
52
|
+
// u16 "map": index -> # of codes with bit length = index
|
|
53
|
+
const l = new Uint16Array(mb);
|
|
54
|
+
// length of cd must be 288 (total # of codes)
|
|
55
|
+
for (; i < s; ++i)
|
|
56
|
+
if (cd[i])
|
|
57
|
+
++l[cd[i] - 1];
|
|
58
|
+
// u16 "map": index -> minimum code for bit length = index
|
|
59
|
+
const le = new Uint16Array(mb);
|
|
60
|
+
for (i = 0; i < mb; ++i)
|
|
61
|
+
le[i] = (le[i - 1] + l[i - 1]) << 1;
|
|
62
|
+
let co;
|
|
63
|
+
if (r) {
|
|
64
|
+
// u16 "map": index -> number of actual bits, symbol for code
|
|
65
|
+
co = new Uint16Array(1 << mb);
|
|
66
|
+
// bits to remove for reverser
|
|
67
|
+
const rvb = 15 - mb;
|
|
68
|
+
for (i = 0; i < s; ++i)
|
|
69
|
+
// ignore 0 lengths
|
|
70
|
+
if (cd[i]) {
|
|
71
|
+
// num encoding both symbol and bits read
|
|
72
|
+
const sv = (i << 4) | cd[i];
|
|
73
|
+
// free bits
|
|
74
|
+
const r = mb - cd[i];
|
|
75
|
+
// start value
|
|
76
|
+
let v = le[cd[i] - 1]++ << r;
|
|
77
|
+
// m is end value
|
|
78
|
+
for (const m = v | ((1 << r) - 1); v <= m; ++v)
|
|
79
|
+
// every 16 bit value starting with the code yields the same result
|
|
80
|
+
co[rev[v] >>> rvb] = sv;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
co = new Uint16Array(s);
|
|
85
|
+
for (i = 0; i < s; ++i)
|
|
86
|
+
if (cd[i])
|
|
87
|
+
co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);
|
|
88
|
+
}
|
|
89
|
+
return co;
|
|
90
|
+
}
|
|
91
|
+
// fixed length tree
|
|
92
|
+
const flt = new Uint8Array(288);
|
|
93
|
+
for (let i = 0; i < 144; ++i)
|
|
94
|
+
flt[i] = 8;
|
|
95
|
+
for (let i = 144; i < 256; ++i)
|
|
96
|
+
flt[i] = 9;
|
|
97
|
+
for (let i = 256; i < 280; ++i)
|
|
98
|
+
flt[i] = 7;
|
|
99
|
+
for (let i = 280; i < 288; ++i)
|
|
100
|
+
flt[i] = 8;
|
|
101
|
+
// fixed distance tree
|
|
102
|
+
const fdt = new Uint8Array(32);
|
|
103
|
+
for (let i = 0; i < 32; ++i)
|
|
104
|
+
fdt[i] = 5;
|
|
105
|
+
// fixed length map
|
|
106
|
+
const flm = hMap(flt, 9, 0), flrm = hMap(flt, 9, 1);
|
|
107
|
+
// fixed distance map
|
|
108
|
+
const fdm = hMap(fdt, 5, 0), fdrm = hMap(fdt, 5, 1);
|
|
109
|
+
// find max of array
|
|
110
|
+
function max(a) {
|
|
111
|
+
let m = a[0];
|
|
112
|
+
for (let i = 1; i < a.length; ++i)
|
|
113
|
+
if (a[i] > m)
|
|
114
|
+
m = a[i];
|
|
115
|
+
return m;
|
|
116
|
+
}
|
|
117
|
+
// read d, starting at bit p and mask with m
|
|
118
|
+
function bits(d, p, m) {
|
|
119
|
+
const o = (p / 8) | 0;
|
|
120
|
+
return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;
|
|
121
|
+
}
|
|
122
|
+
// read d, starting at bit p continuing for at least 16 bits
|
|
123
|
+
function bits16(d, p) {
|
|
124
|
+
const o = (p / 8) | 0;
|
|
125
|
+
return (d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7);
|
|
126
|
+
}
|
|
127
|
+
// get end of byte
|
|
128
|
+
const shft = (p) => ((p + 7) / 8) | 0;
|
|
129
|
+
// typed array slice - allows garbage collector to free original reference,
|
|
130
|
+
// while being more compatible than .slice
|
|
131
|
+
function slc(v, s, e) {
|
|
132
|
+
if (s == null || s < 0)
|
|
133
|
+
s = 0;
|
|
134
|
+
if (e == null || e > v.length)
|
|
135
|
+
e = v.length;
|
|
136
|
+
// can't use .constructor in case user-supplied
|
|
137
|
+
const n = new (v.BYTES_PER_ELEMENT === 2 ? Uint16Array : v.BYTES_PER_ELEMENT === 4 ? Uint32Array : Uint8Array)(e - s);
|
|
138
|
+
n.set(v.subarray(s, e));
|
|
139
|
+
return n;
|
|
140
|
+
}
|
|
141
|
+
/** Codes for errors generated within this library */
|
|
142
|
+
export const FlateErrorCode = {
|
|
143
|
+
UnexpectedEOF: 0,
|
|
144
|
+
InvalidBlockType: 1,
|
|
145
|
+
InvalidLengthLiteral: 2,
|
|
146
|
+
InvalidDistance: 3,
|
|
147
|
+
StreamFinished: 4,
|
|
148
|
+
NoStreamHandler: 5,
|
|
149
|
+
InvalidHeader: 6,
|
|
150
|
+
NoCallback: 7,
|
|
151
|
+
InvalidUTF8: 8,
|
|
152
|
+
ExtraFieldTooLong: 9,
|
|
153
|
+
InvalidDate: 10,
|
|
154
|
+
FilenameTooLong: 11,
|
|
155
|
+
StreamFinishing: 12,
|
|
156
|
+
InvalidZipData: 13,
|
|
157
|
+
UnknownCompressionMethod: 14
|
|
158
|
+
};
|
|
159
|
+
// error codes
|
|
160
|
+
const ec = [
|
|
161
|
+
'unexpected EOF',
|
|
162
|
+
'invalid block type',
|
|
163
|
+
'invalid length/literal',
|
|
164
|
+
'invalid distance',
|
|
165
|
+
'stream finished',
|
|
166
|
+
'no stream handler', // determined by compression function
|
|
167
|
+
,
|
|
168
|
+
'no callback',
|
|
169
|
+
'invalid UTF-8 data',
|
|
170
|
+
'extra field too long',
|
|
171
|
+
'date not in range 1980-2099',
|
|
172
|
+
'filename too long',
|
|
173
|
+
'stream finishing',
|
|
174
|
+
'invalid zip data'
|
|
175
|
+
// determined by unknown compression method
|
|
176
|
+
];
|
|
177
|
+
function err(ind, msg, nt) {
|
|
178
|
+
const e = new Error(msg || ec[ind]);
|
|
179
|
+
e.code = ind;
|
|
180
|
+
if (Error.captureStackTrace)
|
|
181
|
+
Error.captureStackTrace(e, err);
|
|
182
|
+
if (!nt)
|
|
183
|
+
throw e;
|
|
184
|
+
return e;
|
|
185
|
+
}
|
|
186
|
+
// expands raw DEFLATE data
|
|
187
|
+
function inflt(dat, buf, st) {
|
|
188
|
+
// source length
|
|
189
|
+
const sl = dat.length;
|
|
190
|
+
if (!sl || (st && st.f && !st.l))
|
|
191
|
+
return buf || new Uint8Array(0);
|
|
192
|
+
// have to estimate size
|
|
193
|
+
const noBuf = !buf || st;
|
|
194
|
+
// no state
|
|
195
|
+
const noSt = !st || st.i;
|
|
196
|
+
if (!st)
|
|
197
|
+
st = {};
|
|
198
|
+
// Assumes roughly 33% compression ratio average
|
|
199
|
+
if (!buf)
|
|
200
|
+
buf = new Uint8Array(sl * 3);
|
|
201
|
+
// ensure buffer can fit at least l elements
|
|
202
|
+
function cbuf(l) {
|
|
203
|
+
let bl = buf.length;
|
|
204
|
+
// need to increase size to fit
|
|
205
|
+
if (l > bl) {
|
|
206
|
+
// Double or set to necessary, whichever is greater
|
|
207
|
+
const nbuf = new Uint8Array(Math.max(bl * 2, l));
|
|
208
|
+
nbuf.set(buf);
|
|
209
|
+
buf = nbuf;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// last chunk bitpos bytes
|
|
213
|
+
let final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
214
|
+
// total bits
|
|
215
|
+
const tbts = sl * 8;
|
|
216
|
+
do {
|
|
217
|
+
if (!lm) {
|
|
218
|
+
// BFINAL - this is only 1 when last chunk is next
|
|
219
|
+
final = bits(dat, pos, 1);
|
|
220
|
+
// type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman
|
|
221
|
+
const type = bits(dat, pos + 1, 3);
|
|
222
|
+
pos += 3;
|
|
223
|
+
if (!type) {
|
|
224
|
+
// go to end of byte boundary
|
|
225
|
+
const s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;
|
|
226
|
+
if (t > sl) {
|
|
227
|
+
if (noSt)
|
|
228
|
+
err(0);
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
// ensure size
|
|
232
|
+
if (noBuf)
|
|
233
|
+
cbuf(bt + l);
|
|
234
|
+
// Copy over uncompressed data
|
|
235
|
+
buf.set(dat.subarray(s, t), bt);
|
|
236
|
+
(st.b = bt += l), (st.p = pos = t * 8), (st.f = final);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
else if (type == 1)
|
|
240
|
+
(lm = flrm), (dm = fdrm), (lbt = 9), (dbt = 5);
|
|
241
|
+
else if (type == 2) {
|
|
242
|
+
// literal lengths
|
|
243
|
+
const hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
244
|
+
const tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
245
|
+
pos += 14;
|
|
246
|
+
// length+distance tree
|
|
247
|
+
const ldt = new Uint8Array(tl);
|
|
248
|
+
// code length tree
|
|
249
|
+
const clt = new Uint8Array(19);
|
|
250
|
+
for (let i = 0; i < hcLen; ++i)
|
|
251
|
+
// use index map to get real code
|
|
252
|
+
clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
253
|
+
pos += hcLen * 3;
|
|
254
|
+
// code lengths bits
|
|
255
|
+
const clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
256
|
+
// code lengths map
|
|
257
|
+
const clm = hMap(clt, clb, 1);
|
|
258
|
+
for (let i = 0; i < tl;) {
|
|
259
|
+
const r = clm[bits(dat, pos, clbmsk)];
|
|
260
|
+
// bits read
|
|
261
|
+
pos += r & 15;
|
|
262
|
+
// symbol
|
|
263
|
+
const s = r >>> 4;
|
|
264
|
+
// code length to copy
|
|
265
|
+
if (s < 16)
|
|
266
|
+
ldt[i++] = s;
|
|
267
|
+
else {
|
|
268
|
+
// copy count
|
|
269
|
+
let c = 0, n = 0;
|
|
270
|
+
if (s == 16)
|
|
271
|
+
(n = 3 + bits(dat, pos, 3)), (pos += 2), (c = ldt[i - 1]);
|
|
272
|
+
else if (s == 17)
|
|
273
|
+
(n = 3 + bits(dat, pos, 7)), (pos += 3);
|
|
274
|
+
else if (s == 18)
|
|
275
|
+
(n = 11 + bits(dat, pos, 127)), (pos += 7);
|
|
276
|
+
while (n--)
|
|
277
|
+
ldt[i++] = c;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// length tree distance tree
|
|
281
|
+
const lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
282
|
+
// max length bits
|
|
283
|
+
lbt = max(lt);
|
|
284
|
+
// max dist bits
|
|
285
|
+
dbt = max(dt);
|
|
286
|
+
lm = hMap(lt, lbt, 1);
|
|
287
|
+
dm = hMap(dt, dbt, 1);
|
|
288
|
+
}
|
|
289
|
+
else
|
|
290
|
+
err(1);
|
|
291
|
+
if (pos > tbts) {
|
|
292
|
+
if (noSt)
|
|
293
|
+
err(0);
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Make sure the buffer can hold this + the largest possible addition
|
|
298
|
+
// Maximum chunk size (practically, theoretically infinite) is 2^17;
|
|
299
|
+
if (noBuf)
|
|
300
|
+
cbuf(bt + 131072);
|
|
301
|
+
const lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
302
|
+
let lpos = pos;
|
|
303
|
+
for (;; lpos = pos) {
|
|
304
|
+
// bits read, code
|
|
305
|
+
const c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
|
|
306
|
+
pos += c & 15;
|
|
307
|
+
if (pos > tbts) {
|
|
308
|
+
if (noSt)
|
|
309
|
+
err(0);
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
if (!c)
|
|
313
|
+
err(2);
|
|
314
|
+
if (sym < 256)
|
|
315
|
+
buf[bt++] = sym;
|
|
316
|
+
else if (sym == 256) {
|
|
317
|
+
(lpos = pos), (lm = null);
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
let add = sym - 254;
|
|
322
|
+
// no extra bits needed if less
|
|
323
|
+
if (sym > 264) {
|
|
324
|
+
// index
|
|
325
|
+
const i = sym - 257, b = fleb[i];
|
|
326
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
|
327
|
+
pos += b;
|
|
328
|
+
}
|
|
329
|
+
// dist
|
|
330
|
+
const d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
|
|
331
|
+
if (!d)
|
|
332
|
+
err(3);
|
|
333
|
+
pos += d & 15;
|
|
334
|
+
let dt = fd[dsym];
|
|
335
|
+
if (dsym > 3) {
|
|
336
|
+
const b = fdeb[dsym];
|
|
337
|
+
(dt += bits16(dat, pos) & ((1 << b) - 1)), (pos += b);
|
|
338
|
+
}
|
|
339
|
+
if (pos > tbts) {
|
|
340
|
+
if (noSt)
|
|
341
|
+
err(0);
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
if (noBuf)
|
|
345
|
+
cbuf(bt + 131072);
|
|
346
|
+
const end = bt + add;
|
|
347
|
+
for (; bt < end; bt += 4) {
|
|
348
|
+
buf[bt] = buf[bt - dt];
|
|
349
|
+
buf[bt + 1] = buf[bt + 1 - dt];
|
|
350
|
+
buf[bt + 2] = buf[bt + 2 - dt];
|
|
351
|
+
buf[bt + 3] = buf[bt + 3 - dt];
|
|
352
|
+
}
|
|
353
|
+
bt = end;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
(st.l = lm), (st.p = lpos), (st.b = bt), (st.f = final);
|
|
357
|
+
if (lm)
|
|
358
|
+
(final = 1), (st.m = lbt), (st.d = dm), (st.n = dbt);
|
|
359
|
+
} while (!final);
|
|
360
|
+
return bt == buf.length ? buf : slc(buf, 0, bt);
|
|
361
|
+
}
|
|
362
|
+
// starting at p, write the minimum number of bits that can hold v to d
|
|
363
|
+
function wbits(d, p, v) {
|
|
364
|
+
v <<= p & 7;
|
|
365
|
+
const o = (p / 8) | 0;
|
|
366
|
+
d[o] |= v;
|
|
367
|
+
d[o + 1] |= v >>> 8;
|
|
368
|
+
}
|
|
369
|
+
// starting at p, write the minimum number of bits (>8) that can hold v to d
|
|
370
|
+
function wbits16(d, p, v) {
|
|
371
|
+
v <<= p & 7;
|
|
372
|
+
const o = (p / 8) | 0;
|
|
373
|
+
d[o] |= v;
|
|
374
|
+
d[o + 1] |= v >>> 8;
|
|
375
|
+
d[o + 2] |= v >>> 16;
|
|
376
|
+
}
|
|
377
|
+
// creates code lengths from a frequency table
|
|
378
|
+
function hTree(d, mb) {
|
|
379
|
+
// Need extra info to make a tree
|
|
380
|
+
const t = [];
|
|
381
|
+
for (let i = 0; i < d.length; ++i)
|
|
382
|
+
if (d[i])
|
|
383
|
+
t.push({ s: i, f: d[i] });
|
|
384
|
+
const s = t.length;
|
|
385
|
+
const t2 = t.slice();
|
|
386
|
+
if (!s)
|
|
387
|
+
return [et, 0];
|
|
388
|
+
if (s == 1) {
|
|
389
|
+
const v = new Uint8Array(t[0].s + 1);
|
|
390
|
+
v[t[0].s] = 1;
|
|
391
|
+
return [v, 1];
|
|
392
|
+
}
|
|
393
|
+
t.sort((a, b) => a.f - b.f);
|
|
394
|
+
// after i2 reaches last ind, will be stopped
|
|
395
|
+
// freq must be greater than largest possible number of symbols
|
|
396
|
+
t.push({ s: -1, f: 25001 });
|
|
397
|
+
let l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;
|
|
398
|
+
t[0] = { s: -1, f: l.f + r.f, l, r };
|
|
399
|
+
// efficient algorithm from UZIP.js
|
|
400
|
+
// i0 is lookbehind, i2 is lookahead - after processing two low-freq
|
|
401
|
+
// symbols that combined have high freq, will start processing i2 (high-freq,
|
|
402
|
+
// non-composite) symbols instead
|
|
403
|
+
// see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/
|
|
404
|
+
while (i1 != s - 1) {
|
|
405
|
+
l = t[t[i0].f < t[i2].f ? i0++ : i2++];
|
|
406
|
+
r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
|
|
407
|
+
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
408
|
+
}
|
|
409
|
+
let maxSym = t2[0].s;
|
|
410
|
+
for (let i = 1; i < s; ++i)
|
|
411
|
+
if (t2[i].s > maxSym)
|
|
412
|
+
maxSym = t2[i].s;
|
|
413
|
+
// code lengths
|
|
414
|
+
const tr = new Uint16Array(maxSym + 1);
|
|
415
|
+
// max bits in tree
|
|
416
|
+
let mbt = ln(t[i1 - 1], tr, 0);
|
|
417
|
+
if (mbt > mb) {
|
|
418
|
+
// more algorithms from UZIP.js
|
|
419
|
+
// TODO: find out how this code works (debt)
|
|
420
|
+
// ind debt
|
|
421
|
+
let i = 0, dt = 0;
|
|
422
|
+
// left cost
|
|
423
|
+
const lft = mbt - mb, cst = 1 << lft;
|
|
424
|
+
t2.sort((a, b) => tr[b.s] - tr[a.s] || a.f - b.f);
|
|
425
|
+
for (; i < s; ++i) {
|
|
426
|
+
const i2 = t2[i].s;
|
|
427
|
+
if (tr[i2] > mb) {
|
|
428
|
+
dt += cst - (1 << (mbt - tr[i2]));
|
|
429
|
+
tr[i2] = mb;
|
|
430
|
+
}
|
|
431
|
+
else
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
dt >>>= lft;
|
|
435
|
+
while (dt > 0) {
|
|
436
|
+
const i2 = t2[i].s;
|
|
437
|
+
if (tr[i2] < mb)
|
|
438
|
+
dt -= 1 << (mb - tr[i2]++ - 1);
|
|
439
|
+
else
|
|
440
|
+
++i;
|
|
441
|
+
}
|
|
442
|
+
for (; i >= 0 && dt; --i) {
|
|
443
|
+
const i2 = t2[i].s;
|
|
444
|
+
if (tr[i2] == mb) {
|
|
445
|
+
--tr[i2];
|
|
446
|
+
++dt;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
mbt = mb;
|
|
450
|
+
}
|
|
451
|
+
return [new Uint8Array(tr), mbt];
|
|
452
|
+
}
|
|
453
|
+
// get the max length and assign length codes
|
|
454
|
+
function ln(n, l, d) {
|
|
455
|
+
return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : (l[n.s] = d);
|
|
456
|
+
}
|
|
457
|
+
// length codes generation
|
|
458
|
+
function lc(c) {
|
|
459
|
+
let s = c.length;
|
|
460
|
+
// Note that the semicolon was intentional
|
|
461
|
+
while (s && !c[--s])
|
|
462
|
+
;
|
|
463
|
+
const cl = new Uint16Array(++s);
|
|
464
|
+
// ind num streak
|
|
465
|
+
let cli = 0, cln = c[0], cls = 1;
|
|
466
|
+
function w(v) {
|
|
467
|
+
cl[cli++] = v;
|
|
468
|
+
}
|
|
469
|
+
for (let i = 1; i <= s; ++i)
|
|
470
|
+
if (c[i] == cln && i != s)
|
|
471
|
+
++cls;
|
|
472
|
+
else {
|
|
473
|
+
if (!cln && cls > 2) {
|
|
474
|
+
for (; cls > 138; cls -= 138)
|
|
475
|
+
w(32754);
|
|
476
|
+
if (cls > 2) {
|
|
477
|
+
w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);
|
|
478
|
+
cls = 0;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else if (cls > 3) {
|
|
482
|
+
w(cln), --cls;
|
|
483
|
+
for (; cls > 6; cls -= 6)
|
|
484
|
+
w(8304);
|
|
485
|
+
if (cls > 2)
|
|
486
|
+
w(((cls - 3) << 5) | 8208), (cls = 0);
|
|
487
|
+
}
|
|
488
|
+
while (cls--)
|
|
489
|
+
w(cln);
|
|
490
|
+
cls = 1;
|
|
491
|
+
cln = c[i];
|
|
492
|
+
}
|
|
493
|
+
return [cl.subarray(0, cli), s];
|
|
494
|
+
}
|
|
495
|
+
// calculate the length of output from tree, code lengths
|
|
496
|
+
function clen(cf, cl) {
|
|
497
|
+
let l = 0;
|
|
498
|
+
for (let i = 0; i < cl.length; ++i)
|
|
499
|
+
l += cf[i] * cl[i];
|
|
500
|
+
return l;
|
|
501
|
+
}
|
|
502
|
+
// writes a fixed block
|
|
503
|
+
// returns the new bit pos
|
|
504
|
+
function wfblk(out, pos, dat) {
|
|
505
|
+
// no need to write 00 as type: TypedArray defaults to 0
|
|
506
|
+
const s = dat.length;
|
|
507
|
+
const o = shft(pos + 2);
|
|
508
|
+
out[o] = s & 255;
|
|
509
|
+
out[o + 1] = s >>> 8;
|
|
510
|
+
out[o + 2] = out[o] ^ 255;
|
|
511
|
+
out[o + 3] = out[o + 1] ^ 255;
|
|
512
|
+
for (let i = 0; i < s; ++i)
|
|
513
|
+
out[o + i + 4] = dat[i];
|
|
514
|
+
return (o + 4 + s) * 8;
|
|
515
|
+
}
|
|
516
|
+
// writes a block
|
|
517
|
+
function wblk(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
518
|
+
wbits(out, p++, final);
|
|
519
|
+
++lf[256];
|
|
520
|
+
const [dlt, mlb] = hTree(lf, 15);
|
|
521
|
+
const [ddt, mdb] = hTree(df, 15);
|
|
522
|
+
const [lclt, nlc] = lc(dlt);
|
|
523
|
+
const [lcdt, ndc] = lc(ddt);
|
|
524
|
+
const lcfreq = new Uint16Array(19);
|
|
525
|
+
for (let i = 0; i < lclt.length; ++i)
|
|
526
|
+
lcfreq[lclt[i] & 31]++;
|
|
527
|
+
for (let i = 0; i < lcdt.length; ++i)
|
|
528
|
+
lcfreq[lcdt[i] & 31]++;
|
|
529
|
+
const [lct, mlcb] = hTree(lcfreq, 7);
|
|
530
|
+
let nlcc = 19;
|
|
531
|
+
for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
532
|
+
;
|
|
533
|
+
const flen = (bl + 5) << 3;
|
|
534
|
+
const ftlen = clen(lf, flt) + clen(df, fdt) + eb;
|
|
535
|
+
const dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);
|
|
536
|
+
if (flen <= ftlen && flen <= dtlen)
|
|
537
|
+
return wfblk(out, p, dat.subarray(bs, bs + bl));
|
|
538
|
+
let lm, ll, dm, dl;
|
|
539
|
+
wbits(out, p, 1 + (dtlen < ftlen)), (p += 2);
|
|
540
|
+
if (dtlen < ftlen) {
|
|
541
|
+
(lm = hMap(dlt, mlb, 0)), (ll = dlt), (dm = hMap(ddt, mdb, 0)), (dl = ddt);
|
|
542
|
+
const llm = hMap(lct, mlcb, 0);
|
|
543
|
+
wbits(out, p, nlc - 257);
|
|
544
|
+
wbits(out, p + 5, ndc - 1);
|
|
545
|
+
wbits(out, p + 10, nlcc - 4);
|
|
546
|
+
p += 14;
|
|
547
|
+
for (let i = 0; i < nlcc; ++i)
|
|
548
|
+
wbits(out, p + 3 * i, lct[clim[i]]);
|
|
549
|
+
p += 3 * nlcc;
|
|
550
|
+
const lcts = [lclt, lcdt];
|
|
551
|
+
for (let it = 0; it < 2; ++it) {
|
|
552
|
+
const clct = lcts[it];
|
|
553
|
+
for (let i = 0; i < clct.length; ++i) {
|
|
554
|
+
const len = clct[i] & 31;
|
|
555
|
+
wbits(out, p, llm[len]), (p += lct[len]);
|
|
556
|
+
if (len > 15)
|
|
557
|
+
wbits(out, p, (clct[i] >>> 5) & 127), (p += clct[i] >>> 12);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
else
|
|
562
|
+
(lm = flm), (ll = flt), (dm = fdm), (dl = fdt);
|
|
563
|
+
for (let i = 0; i < li; ++i)
|
|
564
|
+
if (syms[i] > 255) {
|
|
565
|
+
const len = (syms[i] >>> 18) & 31;
|
|
566
|
+
wbits16(out, p, lm[len + 257]), (p += ll[len + 257]);
|
|
567
|
+
if (len > 7)
|
|
568
|
+
wbits(out, p, (syms[i] >>> 23) & 31), (p += fleb[len]);
|
|
569
|
+
const dst = syms[i] & 31;
|
|
570
|
+
wbits16(out, p, dm[dst]), (p += dl[dst]);
|
|
571
|
+
if (dst > 3)
|
|
572
|
+
wbits16(out, p, (syms[i] >>> 5) & 8191), (p += fdeb[dst]);
|
|
573
|
+
}
|
|
574
|
+
else
|
|
575
|
+
wbits16(out, p, lm[syms[i]]), (p += ll[syms[i]]);
|
|
576
|
+
wbits16(out, p, lm[256]);
|
|
577
|
+
return p + ll[256];
|
|
578
|
+
}
|
|
579
|
+
// deflate options (nice << 13) | chain
|
|
580
|
+
const deo = new Uint32Array([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
|
|
581
|
+
// empty
|
|
582
|
+
const et = new Uint8Array(0);
|
|
583
|
+
// compresses data into a raw DEFLATE buffer
|
|
584
|
+
function dflt(dat, lvl, plvl, pre, post, lst) {
|
|
585
|
+
const s = dat.length;
|
|
586
|
+
const o = new Uint8Array(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);
|
|
587
|
+
// writing to this writes to the output buffer
|
|
588
|
+
const w = o.subarray(pre, o.length - post);
|
|
589
|
+
let pos = 0;
|
|
590
|
+
if (!lvl || s < 8)
|
|
591
|
+
for (let i = 0; i <= s; i += 65535) {
|
|
592
|
+
// end
|
|
593
|
+
const e = i + 65535;
|
|
594
|
+
if (e >= s)
|
|
595
|
+
// write final block
|
|
596
|
+
w[pos >> 3] = lst;
|
|
597
|
+
pos = wfblk(w, pos + 1, dat.subarray(i, e));
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
const opt = deo[lvl - 1];
|
|
601
|
+
const n = opt >>> 13, c = opt & 8191;
|
|
602
|
+
const msk = (1 << plvl) - 1;
|
|
603
|
+
// prev 2-byte val map curr 2-byte val map
|
|
604
|
+
const prev = new Uint16Array(32768), head = new Uint16Array(msk + 1);
|
|
605
|
+
const bs1 = Math.ceil(plvl / 3), bs2 = 2 * bs1;
|
|
606
|
+
const hsh = (i) => (dat[i] ^ (dat[i + 1] << bs1) ^ (dat[i + 2] << bs2)) & msk;
|
|
607
|
+
// 24576 is an arbitrary number of maximum symbols per block
|
|
608
|
+
// 424 buffer for last block
|
|
609
|
+
const syms = new Uint32Array(25000);
|
|
610
|
+
// length/literal freq distance freq
|
|
611
|
+
const lf = new Uint16Array(288), df = new Uint16Array(32);
|
|
612
|
+
// l/lcnt exbits index l/lind waitdx bitpos
|
|
613
|
+
let lc = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;
|
|
614
|
+
for (; i < s; ++i) {
|
|
615
|
+
// hash value
|
|
616
|
+
// deopt when i > s - 3 - at end, deopt acceptable
|
|
617
|
+
const hv = hsh(i);
|
|
618
|
+
// index mod 32768 previous index mod
|
|
619
|
+
let imod = i & 32767, pimod = head[hv];
|
|
620
|
+
prev[imod] = pimod;
|
|
621
|
+
head[hv] = imod;
|
|
622
|
+
// We always should modify head and prev, but only add symbols if
|
|
623
|
+
// this data is not yet processed ("wait" for wait index)
|
|
624
|
+
if (wi <= i) {
|
|
625
|
+
// bytes remaining
|
|
626
|
+
const rem = s - i;
|
|
627
|
+
if ((lc > 7000 || li > 24576) && rem > 423) {
|
|
628
|
+
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
|
|
629
|
+
(li = lc = eb = 0), (bs = i);
|
|
630
|
+
for (let j = 0; j < 286; ++j)
|
|
631
|
+
lf[j] = 0;
|
|
632
|
+
for (let j = 0; j < 30; ++j)
|
|
633
|
+
df[j] = 0;
|
|
634
|
+
}
|
|
635
|
+
// len dist chain
|
|
636
|
+
let l = 2, d = 0, ch = c, dif = (imod - pimod) & 32767;
|
|
637
|
+
if (rem > 2 && hv == hsh(i - dif)) {
|
|
638
|
+
const maxn = Math.min(n, rem) - 1;
|
|
639
|
+
const maxd = Math.min(32767, i);
|
|
640
|
+
// max possible length
|
|
641
|
+
// not capped at dif because decompressors implement "rolling" index population
|
|
642
|
+
const ml = Math.min(258, rem);
|
|
643
|
+
while (dif <= maxd && --ch && imod != pimod) {
|
|
644
|
+
if (dat[i + l] == dat[i + l - dif]) {
|
|
645
|
+
let nl = 0;
|
|
646
|
+
for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)
|
|
647
|
+
;
|
|
648
|
+
if (nl > l) {
|
|
649
|
+
(l = nl), (d = dif);
|
|
650
|
+
// break out early when we reach "nice" (we are satisfied enough)
|
|
651
|
+
if (nl > maxn)
|
|
652
|
+
break;
|
|
653
|
+
// now, find the rarest 2-byte sequence within this
|
|
654
|
+
// length of literals and search for that instead.
|
|
655
|
+
// Much faster than just using the start
|
|
656
|
+
const mmd = Math.min(dif, nl - 2);
|
|
657
|
+
let md = 0;
|
|
658
|
+
for (let j = 0; j < mmd; ++j) {
|
|
659
|
+
const ti = (i - dif + j + 32768) & 32767;
|
|
660
|
+
const pti = prev[ti];
|
|
661
|
+
const cd = (ti - pti + 32768) & 32767;
|
|
662
|
+
if (cd > md)
|
|
663
|
+
(md = cd), (pimod = ti);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
// check the previous match
|
|
668
|
+
(imod = pimod), (pimod = prev[imod]);
|
|
669
|
+
dif += (imod - pimod + 32768) & 32767;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
// d will be nonzero only when a match was found
|
|
673
|
+
if (d) {
|
|
674
|
+
// store both dist and len data in one Uint32
|
|
675
|
+
// Make sure this is recognized as a len/dist with 28th bit (2^28)
|
|
676
|
+
syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];
|
|
677
|
+
const lin = revfl[l] & 31, din = revfd[d] & 31;
|
|
678
|
+
eb += fleb[lin] + fdeb[din];
|
|
679
|
+
++lf[257 + lin];
|
|
680
|
+
++df[din];
|
|
681
|
+
wi = i + l;
|
|
682
|
+
++lc;
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
syms[li++] = dat[i];
|
|
686
|
+
++lf[dat[i]];
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
|
|
691
|
+
// this is the easiest way to avoid needing to maintain state
|
|
692
|
+
if (!lst && pos & 7)
|
|
693
|
+
pos = wfblk(w, pos + 1, et);
|
|
694
|
+
}
|
|
695
|
+
return slc(o, 0, pre + shft(pos) + post);
|
|
696
|
+
}
|
|
697
|
+
// CRC32 table
|
|
698
|
+
const crct = (() => {
|
|
699
|
+
const t = new Int32Array(256);
|
|
700
|
+
for (let i = 0; i < 256; ++i) {
|
|
701
|
+
let c = i, k = 9;
|
|
702
|
+
while (--k)
|
|
703
|
+
c = (c & 1 && -306674912) ^ (c >>> 1);
|
|
704
|
+
t[i] = c;
|
|
705
|
+
}
|
|
706
|
+
return t;
|
|
707
|
+
})();
|
|
708
|
+
// CRC32
|
|
709
|
+
function crc() {
|
|
710
|
+
let c = -1;
|
|
711
|
+
return {
|
|
712
|
+
p(d) {
|
|
713
|
+
// closures have awful performance
|
|
714
|
+
let cr = c;
|
|
715
|
+
for (let i = 0; i < d.length; ++i)
|
|
716
|
+
cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);
|
|
717
|
+
c = cr;
|
|
718
|
+
},
|
|
719
|
+
d() {
|
|
720
|
+
return ~c;
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
// Alder32
|
|
725
|
+
function adler() {
|
|
726
|
+
let a = 1, b = 0;
|
|
727
|
+
return {
|
|
728
|
+
p(d) {
|
|
729
|
+
// closures have awful performance
|
|
730
|
+
let n = a, m = b;
|
|
731
|
+
const l = d.length | 0;
|
|
732
|
+
for (let i = 0; i != l;) {
|
|
733
|
+
const e = Math.min(i + 2655, l);
|
|
734
|
+
for (; i < e; ++i)
|
|
735
|
+
m += n += d[i];
|
|
736
|
+
(n = (n & 65535) + 15 * (n >> 16)), (m = (m & 65535) + 15 * (m >> 16));
|
|
737
|
+
}
|
|
738
|
+
(a = n), (b = m);
|
|
739
|
+
},
|
|
740
|
+
d() {
|
|
741
|
+
(a %= 65521), (b %= 65521);
|
|
742
|
+
return ((a & 255) << 24) | ((a >>> 8) << 16) | ((b & 255) << 8) | (b >>> 8);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
// deflate with opts
|
|
747
|
+
const dopt = (dat, opt, pre, post, st) => dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 12 + opt.mem, pre, post, !st);
|
|
748
|
+
// Walmart object spread
|
|
749
|
+
function mrg(a, b) {
|
|
750
|
+
const o = {};
|
|
751
|
+
for (const k in a)
|
|
752
|
+
o[k] = a[k];
|
|
753
|
+
for (const k in b)
|
|
754
|
+
o[k] = b[k];
|
|
755
|
+
return o;
|
|
756
|
+
}
|
|
757
|
+
// read 2 bytes
|
|
758
|
+
const b2 = (d, b) => d[b] | (d[b + 1] << 8);
|
|
759
|
+
// read 4 bytes
|
|
760
|
+
const b4 = (d, b) => (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0;
|
|
761
|
+
const b8 = (d, b) => b4(d, b) + b4(d, b + 4) * 4294967296;
|
|
762
|
+
// write bytes
|
|
763
|
+
function wbytes(d, b, v) {
|
|
764
|
+
for (; v; ++b)
|
|
765
|
+
(d[b] = v), (v >>>= 8);
|
|
766
|
+
}
|
|
767
|
+
// gzip header
|
|
768
|
+
function gzh(c, o) {
|
|
769
|
+
const fn = o.filename;
|
|
770
|
+
(c[0] = 31), (c[1] = 139), (c[2] = 8), (c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0), (c[9] = 3); // assume Unix
|
|
771
|
+
if (o.mtime != 0)
|
|
772
|
+
wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));
|
|
773
|
+
if (fn) {
|
|
774
|
+
c[3] = 8;
|
|
775
|
+
for (let i = 0; i <= fn.length; ++i)
|
|
776
|
+
c[i + 10] = fn.charCodeAt(i);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
// gzip footer: -8 to -4 = CRC, -4 to -0 is length
|
|
780
|
+
// gzip start
|
|
781
|
+
function gzs(d) {
|
|
782
|
+
if (d[0] != 31 || d[1] != 139 || d[2] != 8)
|
|
783
|
+
err(6, 'invalid gzip data');
|
|
784
|
+
const flg = d[3];
|
|
785
|
+
let st = 10;
|
|
786
|
+
if (flg & 4)
|
|
787
|
+
st += d[10] | ((d[11] << 8) + 2);
|
|
788
|
+
for (let zs = ((flg >> 3) & 1) + ((flg >> 4) & 1); zs > 0; zs -= !d[st++])
|
|
789
|
+
;
|
|
790
|
+
return st + (flg & 2);
|
|
791
|
+
}
|
|
792
|
+
// gzip length
|
|
793
|
+
function gzl(d) {
|
|
794
|
+
const l = d.length;
|
|
795
|
+
return (d[l - 4] | (d[l - 3] << 8) | (d[l - 2] << 16) | (d[l - 1] << 24)) >>> 0;
|
|
796
|
+
}
|
|
797
|
+
// gzip header length
|
|
798
|
+
const gzhl = (o) => 10 + ((o.filename && o.filename.length + 1) || 0);
|
|
799
|
+
// zlib header
|
|
800
|
+
function zlh(c, o) {
|
|
801
|
+
const lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;
|
|
802
|
+
(c[0] = 120), (c[1] = (fl << 6) | (fl ? 32 - 2 * fl : 1));
|
|
803
|
+
}
|
|
804
|
+
// zlib valid
|
|
805
|
+
function zlv(d) {
|
|
806
|
+
if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || ((d[0] << 8) | d[1]) % 31)
|
|
807
|
+
err(6, 'invalid zlib data');
|
|
808
|
+
if (d[1] & 32)
|
|
809
|
+
err(6, 'invalid zlib data: preset dictionaries not supported');
|
|
810
|
+
}
|
|
811
|
+
// zlib footer: -4 to -0 is Adler32
|
|
812
|
+
/** Streaming DEFLATE compression */
|
|
813
|
+
export class Deflate {
|
|
814
|
+
constructor(opts, cb) {
|
|
815
|
+
if (!cb && typeof opts == 'function')
|
|
816
|
+
(cb = opts), (opts = {});
|
|
817
|
+
this.ondata = cb;
|
|
818
|
+
this.o = opts || {};
|
|
819
|
+
}
|
|
820
|
+
o;
|
|
821
|
+
d;
|
|
822
|
+
/** The handler to call whenever data is available */
|
|
823
|
+
ondata;
|
|
824
|
+
p(c, f) {
|
|
825
|
+
this.ondata(dopt(c, this.o, 0, 0, !f), f);
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
Pushes a chunk to be deflated
|
|
829
|
+
@param chunk The chunk to push
|
|
830
|
+
@param final Whether this is the last chunk
|
|
831
|
+
*/
|
|
832
|
+
push(chunk, final) {
|
|
833
|
+
if (!this.ondata)
|
|
834
|
+
err(5);
|
|
835
|
+
if (this.d)
|
|
836
|
+
err(4);
|
|
837
|
+
this.d = final;
|
|
838
|
+
this.p(chunk, final || false);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
Expands DEFLATE data with no wrapper
|
|
843
|
+
@param data The data to decompress
|
|
844
|
+
@param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
|
|
845
|
+
@returns The decompressed version of the data
|
|
846
|
+
*/
|
|
847
|
+
export function inflateSync(data, out) {
|
|
848
|
+
return inflt(data, out);
|
|
849
|
+
}
|
|
850
|
+
// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.
|
|
851
|
+
/** Streaming GZIP compression */
|
|
852
|
+
export class Gzip {
|
|
853
|
+
c = crc();
|
|
854
|
+
l = 0;
|
|
855
|
+
v = 1;
|
|
856
|
+
o;
|
|
857
|
+
/** The handler to call whenever data is available */
|
|
858
|
+
ondata;
|
|
859
|
+
constructor(opts, cb) {
|
|
860
|
+
Deflate.call(this, opts, cb);
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
Pushes a chunk to be GZIPped
|
|
864
|
+
@param chunk The chunk to push
|
|
865
|
+
@param final Whether this is the last chunk
|
|
866
|
+
*/
|
|
867
|
+
push(chunk, final) {
|
|
868
|
+
Deflate.prototype.push.call(this, chunk, final);
|
|
869
|
+
}
|
|
870
|
+
p(c, f) {
|
|
871
|
+
this.c.p(c);
|
|
872
|
+
this.l += c.length;
|
|
873
|
+
const raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, !f);
|
|
874
|
+
if (this.v)
|
|
875
|
+
gzh(raw, this.o), (this.v = 0);
|
|
876
|
+
if (f)
|
|
877
|
+
wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);
|
|
878
|
+
this.ondata(raw, f);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
Compresses data with GZIP
|
|
883
|
+
@param data The data to compress
|
|
884
|
+
@param opts The compression options
|
|
885
|
+
@returns The gzipped version of the data
|
|
886
|
+
*/
|
|
887
|
+
export function gzipSync(data, opts) {
|
|
888
|
+
if (!opts)
|
|
889
|
+
opts = {};
|
|
890
|
+
const c = crc(), l = data.length;
|
|
891
|
+
c.p(data);
|
|
892
|
+
const d = dopt(data, opts, gzhl(opts), 8), s = d.length;
|
|
893
|
+
return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
Expands GZIP data
|
|
897
|
+
@param data The data to decompress
|
|
898
|
+
@param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.
|
|
899
|
+
@returns The decompressed version of the data
|
|
900
|
+
*/
|
|
901
|
+
export function gunzipSync(data, out) {
|
|
902
|
+
return inflt(data.subarray(gzs(data), -8), out || new Uint8Array(gzl(data)));
|
|
903
|
+
}
|
|
904
|
+
/** Streaming Zlib compression */
|
|
905
|
+
export class Zlib {
|
|
906
|
+
c = adler();
|
|
907
|
+
v = 1;
|
|
908
|
+
o;
|
|
909
|
+
/** The handler to call whenever data is available */
|
|
910
|
+
ondata;
|
|
911
|
+
constructor(opts, cb) {
|
|
912
|
+
Deflate.call(this, opts, cb);
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
Pushes a chunk to be zlibbed
|
|
916
|
+
@param chunk The chunk to push
|
|
917
|
+
@param final Whether this is the last chunk
|
|
918
|
+
*/
|
|
919
|
+
push(chunk, final) {
|
|
920
|
+
Deflate.prototype.push.call(this, chunk, final);
|
|
921
|
+
}
|
|
922
|
+
p(c, f) {
|
|
923
|
+
this.c.p(c);
|
|
924
|
+
const raw = dopt(c, this.o, this.v && 2, f && 4, !f);
|
|
925
|
+
if (this.v)
|
|
926
|
+
zlh(raw, this.o), (this.v = 0);
|
|
927
|
+
if (f)
|
|
928
|
+
wbytes(raw, raw.length - 4, this.c.d());
|
|
929
|
+
this.ondata(raw, f);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
Compress data with Zlib
|
|
934
|
+
@param data The data to compress
|
|
935
|
+
@param opts The compression options
|
|
936
|
+
@returns The zlib-compressed version of the data
|
|
937
|
+
*/
|
|
938
|
+
export function zlibSync(data, opts) {
|
|
939
|
+
if (!opts)
|
|
940
|
+
opts = {};
|
|
941
|
+
const a = adler();
|
|
942
|
+
a.p(data);
|
|
943
|
+
const d = dopt(data, opts, 2, 4);
|
|
944
|
+
return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
Expands Zlib data
|
|
948
|
+
@param data The data to decompress
|
|
949
|
+
@param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
|
|
950
|
+
@returns The decompressed version of the data
|
|
951
|
+
*/
|
|
952
|
+
export function unzlibSync(data, out) {
|
|
953
|
+
return inflt((zlv(data), data.subarray(2, -4)), out);
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format
|
|
957
|
+
@param data The data to decompress
|
|
958
|
+
@param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
|
|
959
|
+
@returns The decompressed version of the data
|
|
960
|
+
*/
|
|
961
|
+
export function decompressSync(data, out) {
|
|
962
|
+
return data[0] == 31 && data[1] == 139 && data[2] == 8
|
|
963
|
+
? gunzipSync(data, out)
|
|
964
|
+
: (data[0] & 15) != 8 || data[0] >> 4 > 7 || ((data[0] << 8) | data[1]) % 31
|
|
965
|
+
? inflateSync(data, out)
|
|
966
|
+
: unzlibSync(data, out);
|
|
967
|
+
}
|
|
968
|
+
// flatten a directory structure
|
|
969
|
+
function fltn(d, p, t, o) {
|
|
970
|
+
for (const k in d) {
|
|
971
|
+
let val = d[k], n = p + k, op = o;
|
|
972
|
+
if (Array.isArray(val))
|
|
973
|
+
(op = mrg(o, val[1])), (val = val[0]);
|
|
974
|
+
if (val instanceof Uint8Array)
|
|
975
|
+
t[n] = [val, op];
|
|
976
|
+
else {
|
|
977
|
+
t[(n += '/')] = [new Uint8Array(0), op];
|
|
978
|
+
fltn(val, n, t, o);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
// text decoder
|
|
983
|
+
const td = new TextDecoder();
|
|
984
|
+
// text decoder stream
|
|
985
|
+
let tds = 0;
|
|
986
|
+
try {
|
|
987
|
+
td.decode(et, { stream: true });
|
|
988
|
+
tds = 1;
|
|
989
|
+
}
|
|
990
|
+
catch (e) { }
|
|
991
|
+
// decode UTF8
|
|
992
|
+
function dutf8(d) {
|
|
993
|
+
for (let r = '', i = 0;;) {
|
|
994
|
+
let c = d[i++];
|
|
995
|
+
const eb = (c > 127) + (c > 223) + (c > 239);
|
|
996
|
+
if (i + eb > d.length)
|
|
997
|
+
return [r, slc(d, i - 1)];
|
|
998
|
+
if (!eb)
|
|
999
|
+
r += String.fromCharCode(c);
|
|
1000
|
+
else if (eb == 3)
|
|
1001
|
+
(c = (((c & 15) << 18) | ((d[i++] & 63) << 12) | ((d[i++] & 63) << 6) | (d[i++] & 63)) - 65536),
|
|
1002
|
+
(r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023)));
|
|
1003
|
+
else if (eb & 1)
|
|
1004
|
+
r += String.fromCharCode(((c & 31) << 6) | (d[i++] & 63));
|
|
1005
|
+
else
|
|
1006
|
+
r += String.fromCharCode(((c & 15) << 12) | ((d[i++] & 63) << 6) | (d[i++] & 63));
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
/** Streaming UTF-8 decoding */
|
|
1010
|
+
export class DecodeUTF8 {
|
|
1011
|
+
p;
|
|
1012
|
+
t;
|
|
1013
|
+
/**
|
|
1014
|
+
Creates a UTF-8 decoding stream
|
|
1015
|
+
@param cb The callback to call whenever data is decoded
|
|
1016
|
+
*/
|
|
1017
|
+
constructor(cb) {
|
|
1018
|
+
this.ondata = cb;
|
|
1019
|
+
if (tds)
|
|
1020
|
+
this.t = new TextDecoder();
|
|
1021
|
+
else
|
|
1022
|
+
this.p = et;
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
Pushes a chunk to be decoded from UTF-8 binary
|
|
1026
|
+
@param chunk The chunk to push
|
|
1027
|
+
@param final Whether this is the last chunk
|
|
1028
|
+
*/
|
|
1029
|
+
push(chunk, final) {
|
|
1030
|
+
if (!this.ondata)
|
|
1031
|
+
err(5);
|
|
1032
|
+
final = !!final;
|
|
1033
|
+
if (this.t) {
|
|
1034
|
+
this.ondata(this.t.decode(chunk, { stream: true }), final);
|
|
1035
|
+
if (final) {
|
|
1036
|
+
if (this.t.decode().length)
|
|
1037
|
+
err(8);
|
|
1038
|
+
this.t = null;
|
|
1039
|
+
}
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
if (!this.p)
|
|
1043
|
+
err(4);
|
|
1044
|
+
const dat = new Uint8Array(this.p.length + chunk.length);
|
|
1045
|
+
dat.set(this.p);
|
|
1046
|
+
dat.set(chunk, this.p.length);
|
|
1047
|
+
const [ch, np] = dutf8(dat);
|
|
1048
|
+
if (final) {
|
|
1049
|
+
if (np.length)
|
|
1050
|
+
err(8);
|
|
1051
|
+
this.p = null;
|
|
1052
|
+
}
|
|
1053
|
+
else
|
|
1054
|
+
this.p = np;
|
|
1055
|
+
this.ondata(ch, final);
|
|
1056
|
+
}
|
|
1057
|
+
/** The handler to call whenever data is available */
|
|
1058
|
+
ondata;
|
|
1059
|
+
}
|
|
1060
|
+
/** Streaming UTF-8 encoding */
|
|
1061
|
+
export class EncodeUTF8 {
|
|
1062
|
+
d;
|
|
1063
|
+
/**
|
|
1064
|
+
Creates a UTF-8 decoding stream
|
|
1065
|
+
@param cb The callback to call whenever data is encoded
|
|
1066
|
+
*/
|
|
1067
|
+
constructor(cb) {
|
|
1068
|
+
this.ondata = cb;
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
Pushes a chunk to be encoded to UTF-8
|
|
1072
|
+
@param chunk The string data to push
|
|
1073
|
+
@param final Whether this is the last chunk
|
|
1074
|
+
*/
|
|
1075
|
+
push(chunk, final) {
|
|
1076
|
+
if (!this.ondata)
|
|
1077
|
+
err(5);
|
|
1078
|
+
if (this.d)
|
|
1079
|
+
err(4);
|
|
1080
|
+
this.ondata(strToU8(chunk), (this.d = final || false));
|
|
1081
|
+
}
|
|
1082
|
+
/** The handler to call whenever data is available */
|
|
1083
|
+
ondata;
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
Converts a string into a Uint8Array for use with compression/decompression methods
|
|
1087
|
+
@param str The string to encode
|
|
1088
|
+
@param latin1 Whether or not to interpret the data as Latin-1. This should
|
|
1089
|
+
not need to be true unless decoding a binary string.
|
|
1090
|
+
@returns The string encoded in UTF-8/Latin-1 binary
|
|
1091
|
+
*/
|
|
1092
|
+
export function strToU8(str, latin1) {
|
|
1093
|
+
if (latin1) {
|
|
1094
|
+
const ar = new Uint8Array(str.length);
|
|
1095
|
+
for (let i = 0; i < str.length; ++i)
|
|
1096
|
+
ar[i] = str.charCodeAt(i);
|
|
1097
|
+
return ar;
|
|
1098
|
+
}
|
|
1099
|
+
return encode(str);
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
Converts a Uint8Array to a string
|
|
1103
|
+
@param dat The data to decode to string
|
|
1104
|
+
@param latin1 Whether or not to interpret the data as Latin-1. This should
|
|
1105
|
+
not need to be true unless encoding to binary string.
|
|
1106
|
+
@returns The original UTF-8/Latin-1 string
|
|
1107
|
+
*/
|
|
1108
|
+
export function strFromU8(dat, decoder) {
|
|
1109
|
+
return decoder(dat);
|
|
1110
|
+
}
|
|
1111
|
+
// deflate bit flag
|
|
1112
|
+
const dbf = (l) => (l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0);
|
|
1113
|
+
// skip local zip header
|
|
1114
|
+
const slzh = (d, b) => b + 30 + b2(d, b + 26) + b2(d, b + 28);
|
|
1115
|
+
// read zip header
|
|
1116
|
+
function zh(d, b, z, decoder) {
|
|
1117
|
+
const fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), decoder),
|
|
1118
|
+
// fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048), decoder),
|
|
1119
|
+
es = b + 46 + fnl, bs = b4(d, b + 20);
|
|
1120
|
+
const [sc, su, off] = z && bs == 4294967295 ? z64e(d, es) : [bs, b4(d, b + 24), b4(d, b + 42)];
|
|
1121
|
+
return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];
|
|
1122
|
+
}
|
|
1123
|
+
// read zip64 extra field
|
|
1124
|
+
function z64e(d, b) {
|
|
1125
|
+
for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))
|
|
1126
|
+
;
|
|
1127
|
+
return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
Synchronously decompresses a ZIP archive. Prefer using `unzip` for better
|
|
1131
|
+
performance with more than one file.
|
|
1132
|
+
@param data The raw compressed ZIP file
|
|
1133
|
+
@param opts The ZIP extraction options
|
|
1134
|
+
@returns The decompressed files
|
|
1135
|
+
*/
|
|
1136
|
+
export function unzipSync(data, opts) {
|
|
1137
|
+
const files = {};
|
|
1138
|
+
let e = data.length - 22;
|
|
1139
|
+
for (; b4(data, e) != 0x6054b50; --e)
|
|
1140
|
+
if (!e || data.length - e > 65558)
|
|
1141
|
+
err(13);
|
|
1142
|
+
let c = b2(data, e + 8);
|
|
1143
|
+
if (!c)
|
|
1144
|
+
return {};
|
|
1145
|
+
let o = b4(data, e + 16);
|
|
1146
|
+
let z = o == 4294967295 || c == 65535;
|
|
1147
|
+
if (z) {
|
|
1148
|
+
let ze = b4(data, e - 12);
|
|
1149
|
+
z = b4(data, ze) == 0x6064b50;
|
|
1150
|
+
if (z) {
|
|
1151
|
+
c = b4(data, ze + 32);
|
|
1152
|
+
o = b4(data, ze + 48);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
const fltr = opts && opts.filter;
|
|
1156
|
+
for (let i = 0; i < c; ++i) {
|
|
1157
|
+
const [c, sc, su, fn, no, off] = zh(data, o, z, opts.decoder), b = slzh(data, off);
|
|
1158
|
+
o = no;
|
|
1159
|
+
if (!fltr ||
|
|
1160
|
+
fltr({
|
|
1161
|
+
name: fn,
|
|
1162
|
+
size: sc,
|
|
1163
|
+
originalSize: su,
|
|
1164
|
+
compression: c
|
|
1165
|
+
}))
|
|
1166
|
+
if (!c)
|
|
1167
|
+
files[fn] = slc(data, b, b + sc);
|
|
1168
|
+
else if (c == 8)
|
|
1169
|
+
files[fn] = inflateSync(data.subarray(b, b + sc), new Uint8Array(su));
|
|
1170
|
+
else
|
|
1171
|
+
err(14, 'unknown compression type ' + c);
|
|
1172
|
+
}
|
|
1173
|
+
return files;
|
|
1174
|
+
}
|
|
1175
|
+
//# sourceMappingURL=fflate.js.map
|