@lls/offline 24.27.0-bbbcfe5a → 24.27.0-d7760203
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/lib/assets/fetch-worker.js +30 -165
- package/lib/assets/offline-worker.js +643 -121
- package/lib/index.js +7 -71
- package/package.json +3 -4
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
// src/utils/stream.ts
|
|
2
|
-
var parseRange = (range, size) => {
|
|
3
|
-
const parts = range.replace("bytes=", "").split("-");
|
|
4
|
-
let start = Number.parseInt(parts[0], 10);
|
|
5
|
-
let end = Number.parseInt(parts[1], 10);
|
|
6
|
-
if (isNaN(start)) {
|
|
7
|
-
start = size - end;
|
|
8
|
-
end = size - 1;
|
|
9
|
-
} else if (isNaN(end)) {
|
|
10
|
-
end = size - 1;
|
|
11
|
-
}
|
|
12
|
-
if (end > size - 1) {
|
|
13
|
-
end = size - 1;
|
|
14
|
-
}
|
|
15
|
-
const chunkSize = end - start + 1;
|
|
16
|
-
return { start, end, chunkSize };
|
|
17
|
-
};
|
|
18
|
-
|
|
19
1
|
// src/utils/worker.ts
|
|
20
2
|
var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
21
3
|
const dic = {};
|
|
@@ -38,18 +20,7 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
38
20
|
return ({ ports, ...arg } = {}) => {
|
|
39
21
|
return new Promise((resolve, reject) => {
|
|
40
22
|
const eventId = `${methodName}:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
41
|
-
|
|
42
|
-
const timeout = setTimeout(() => {
|
|
43
|
-
console.warn("slow request for", methodName, arg);
|
|
44
|
-
}, 3e3);
|
|
45
|
-
const doResolve = (arg2) => {
|
|
46
|
-
if (!resolved) {
|
|
47
|
-
resolved = true;
|
|
48
|
-
clearTimeout(timeout);
|
|
49
|
-
resolve(arg2);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
dic[eventId] = { resolve: doResolve, reject };
|
|
23
|
+
dic[eventId] = { resolve, reject };
|
|
53
24
|
offlineWorker2.postMessage({ eventId, methodName, arg }, ports);
|
|
54
25
|
});
|
|
55
26
|
};
|
|
@@ -106,7 +77,7 @@ var cocoreFetchPartialPageScreen = async (_ev, { offlineWorkerSync: offlineWorke
|
|
|
106
77
|
const key = `gqls/${zipSlugName(variables.slugs[0] || "")}.json`;
|
|
107
78
|
const entryId = knownLinks2.get(key);
|
|
108
79
|
if (!entryId) {
|
|
109
|
-
throw new Error(`slug not found ${key}
|
|
80
|
+
throw new Error(`slug not found ${key}`);
|
|
110
81
|
}
|
|
111
82
|
const gqlPage = await offlineWorkerSync2.loadPageContent({ entryId });
|
|
112
83
|
return { data: gqlPage };
|
|
@@ -231,90 +202,22 @@ var coreFetchPagesApi = async (ev, { offlineWorkerSync: offlineWorkerSync2, vari
|
|
|
231
202
|
}
|
|
232
203
|
}
|
|
233
204
|
};
|
|
234
|
-
var cocoreFetchPrimaryMethod = async (_ev, { offlineWorkerSync: offlineWorkerSync2, variables }) => {
|
|
235
|
-
const uri = variables.uris?.[0];
|
|
236
|
-
if (!uri) {
|
|
237
|
-
throw new Error("invalid uri");
|
|
238
|
-
}
|
|
239
|
-
const method = await offlineWorkerSync2.readZipEntry({ bookId: uri, entryName: "gqls/method.json", asJson: true });
|
|
240
|
-
return {
|
|
241
|
-
data: method
|
|
242
|
-
};
|
|
243
|
-
};
|
|
244
|
-
var cocoreCreateLexicalFlower = async (_ev, { variables }) => {
|
|
245
|
-
const flower = variables.flower;
|
|
246
|
-
if (!flower) {
|
|
247
|
-
throw new Error("invalid flower");
|
|
248
|
-
}
|
|
249
|
-
const back = {
|
|
250
|
-
viewer: {
|
|
251
|
-
createLexicalFlower: {
|
|
252
|
-
...flower,
|
|
253
|
-
id: Date.now(),
|
|
254
|
-
user: null,
|
|
255
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
return {
|
|
260
|
-
data: back
|
|
261
|
-
};
|
|
262
|
-
};
|
|
263
|
-
var cocoreUpdateLexicalFlower = async (_ev, { variables }) => {
|
|
264
|
-
const flower = variables.flower;
|
|
265
|
-
if (!flower) {
|
|
266
|
-
throw new Error("invalid flower");
|
|
267
|
-
}
|
|
268
|
-
const back = {
|
|
269
|
-
viewer: {
|
|
270
|
-
updateLexicalFlower: {
|
|
271
|
-
...flower,
|
|
272
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
return {
|
|
277
|
-
data: back
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
var cocoreDeleteLexicalFlower = async (_ev, { variables }) => {
|
|
281
|
-
const flower = variables.flower;
|
|
282
|
-
if (!flower) {
|
|
283
|
-
throw new Error("invalid flower");
|
|
284
|
-
}
|
|
285
|
-
const back = {
|
|
286
|
-
viewer: {
|
|
287
|
-
deleteLexicalFlower: flower
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
return {
|
|
291
|
-
data: back
|
|
292
|
-
};
|
|
293
|
-
};
|
|
294
205
|
var handles = {
|
|
295
206
|
coreFetchBookDrawerScreen,
|
|
296
207
|
cocoreFetchBookScreen,
|
|
297
208
|
coreFetchPagesApi,
|
|
298
209
|
cocoreFetchPartialPageScreen,
|
|
299
|
-
cocoreFetchPartialPageSiblingsScreen
|
|
300
|
-
cocoreFetchPrimaryMethod,
|
|
301
|
-
cocoreCreateLexicalFlower,
|
|
302
|
-
cocoreUpdateLexicalFlower,
|
|
303
|
-
cocoreDeleteLexicalFlower
|
|
210
|
+
cocoreFetchPartialPageSiblingsScreen
|
|
304
211
|
};
|
|
305
212
|
var canHandleScreenCall = (url) => new RegExp(Object.keys(handles).join("|")).test(url);
|
|
306
213
|
var handleScreenCall = async (ev, { offlineWorkerSync: offlineWorkerSync2, knownLinks: knownLinks2 }) => {
|
|
307
214
|
try {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const body = await new Response(ev.request.body).json();
|
|
314
|
-
variables = body.variables;
|
|
315
|
-
}
|
|
215
|
+
const variables = (
|
|
216
|
+
// @ts-expect-error TODO: handle variables from body(stream) properly!!
|
|
217
|
+
ev.request.body?.variables || JSON.parse(new URLSearchParams(new URL(ev.request.url).search).get("variables") || "{}")
|
|
218
|
+
);
|
|
219
|
+
console.debug("variables are", variables, "vs", ev.request.body);
|
|
316
220
|
const key = ev.request.url.match(Object.keys(handles).join("|"))?.[0];
|
|
317
|
-
console.debug("screencall", key, "qs", variables, "vs body", ev.request.body);
|
|
318
221
|
if (!key) {
|
|
319
222
|
throw new Error("unknown ev");
|
|
320
223
|
}
|
|
@@ -335,39 +238,17 @@ var setKnownLinks = (knownLinks2, { entryNames, bookId }) => {
|
|
|
335
238
|
// src/worker/fetch-worker.ts
|
|
336
239
|
var STORAGE = "cache";
|
|
337
240
|
var CONF_ENV = "development";
|
|
338
|
-
var fetchAsset = async (
|
|
241
|
+
var fetchAsset = async (_ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
|
|
339
242
|
try {
|
|
340
|
-
const
|
|
341
|
-
const range = ev.request.headers.get("Range");
|
|
342
|
-
if (!ev.request.url.endsWith(".mp4") && !ev.request.url.endsWith(".webm")) {
|
|
343
|
-
return [buf2, {}];
|
|
344
|
-
}
|
|
345
|
-
if (!range) {
|
|
346
|
-
return [
|
|
347
|
-
buf2,
|
|
348
|
-
{
|
|
349
|
-
"Accept-Ranges": "bytes",
|
|
350
|
-
"Content-Range": `bytes ${0}-${buf2.byteLength}/${buf2.byteLength}`
|
|
351
|
-
}
|
|
352
|
-
];
|
|
353
|
-
}
|
|
354
|
-
const { start, end, chunkSize } = parseRange(range, buf2.byteLength);
|
|
355
|
-
const rangeHeaders = {
|
|
356
|
-
"Content-Length": chunkSize,
|
|
357
|
-
"Accept-Ranges": "bytes",
|
|
358
|
-
"Content-Range": `bytes ${start}-${end}/${buf2.byteLength}`
|
|
359
|
-
};
|
|
360
|
-
return [buf2.slice(start, end + 1), rangeHeaders];
|
|
361
|
-
});
|
|
243
|
+
const buf = await offlineWorkerSync2.readZipEntry(entryId);
|
|
362
244
|
return new Response(buf, {
|
|
363
245
|
headers: {
|
|
364
246
|
"Cache-Control": "max-age=600, s-maxage=600, public, proxy-revalidate",
|
|
365
247
|
"Content-Length": buf.byteLength,
|
|
366
|
-
"Content-Type": mimeType
|
|
367
|
-
...maybeRangeHeaders
|
|
248
|
+
"Content-Type": mimeType
|
|
368
249
|
},
|
|
369
250
|
// @ts-ignore: poor ts typing
|
|
370
|
-
status:
|
|
251
|
+
status: 200,
|
|
371
252
|
statusText: "OK"
|
|
372
253
|
});
|
|
373
254
|
} catch (e) {
|
|
@@ -424,30 +305,23 @@ var putInCache = async (request, response) => {
|
|
|
424
305
|
const cache = await openCache(CONF_ENV);
|
|
425
306
|
await cache.put(request, response);
|
|
426
307
|
};
|
|
427
|
-
var tryOnline = async (request, event) => {
|
|
428
|
-
const responseFromNetwork = await fetch(request);
|
|
429
|
-
if (isValidZipName(request.url) && !isValidS3Zip(responseFromNetwork)) {
|
|
430
|
-
throw new Error(`zip is invalid: got ${responseFromNetwork.headers.get("Content-Length")} bytes`);
|
|
431
|
-
}
|
|
432
|
-
const cached = request.method === "HEAD" ? Promise.resolve() : putInCache(request, responseFromNetwork.clone());
|
|
433
|
-
if (request.url.endsWith(".zip")) {
|
|
434
|
-
await cached;
|
|
435
|
-
event.waitUntil(Promise.resolve());
|
|
436
|
-
} else {
|
|
437
|
-
event.waitUntil(cached);
|
|
438
|
-
}
|
|
439
|
-
return responseFromNetwork;
|
|
440
|
-
};
|
|
441
|
-
var tryOffline = async (request, _event) => {
|
|
442
|
-
const over = /\/\?story=basic/.test(request.url) ? request.url.replace(/\/\?story=.*$/, "") : request;
|
|
443
|
-
const responseFromCache = await caches.match(over);
|
|
444
|
-
return responseFromCache;
|
|
445
|
-
};
|
|
446
308
|
var onlineFirst = async (request, event) => {
|
|
447
309
|
try {
|
|
448
|
-
|
|
310
|
+
const responseFromNetwork = await fetch(request);
|
|
311
|
+
if (isValidZipName(request.url) && !isValidS3Zip(responseFromNetwork)) {
|
|
312
|
+
throw new Error(`zip is invalid: got ${responseFromNetwork.headers.get("Content-Length")} bytes`);
|
|
313
|
+
}
|
|
314
|
+
const cached = request.method === "HEAD" ? Promise.resolve() : putInCache(request, responseFromNetwork.clone());
|
|
315
|
+
if (request.url.endsWith(".zip")) {
|
|
316
|
+
await cached;
|
|
317
|
+
event.waitUntil(Promise.resolve());
|
|
318
|
+
} else {
|
|
319
|
+
event.waitUntil(cached);
|
|
320
|
+
}
|
|
321
|
+
return responseFromNetwork;
|
|
449
322
|
} catch (e) {
|
|
450
|
-
const
|
|
323
|
+
const over = /\/\?story=basic/.test(request.url) ? request.url.replace(/\/\?story=.*$/, "") : request;
|
|
324
|
+
const responseFromCache = await caches.match(over);
|
|
451
325
|
if (!responseFromCache) {
|
|
452
326
|
return new Response(
|
|
453
327
|
`FAILED fetch ${e && typeof e === "object" && "message" in e ? e.message : e?.toString?.()}`,
|
|
@@ -469,23 +343,18 @@ swSelf.addEventListener("fetch", (ev) => {
|
|
|
469
343
|
const extension = url.match(/\.[^.]+$/)?.[0];
|
|
470
344
|
const mimeType = extension && extension in ACCEPTED_EXTENSIONS ? ACCEPTED_EXTENSIONS[extension] : "";
|
|
471
345
|
const isValidScreenCall = canHandleScreenCall(url);
|
|
472
|
-
if (url.endsWith(".zip")) {
|
|
473
|
-
if (STORAGE === "cache") {
|
|
474
|
-
return ev.respondWith(onlineFirst(ev.request, ev));
|
|
475
|
-
}
|
|
346
|
+
if (STORAGE !== "cache" && url.endsWith(".zip")) {
|
|
476
347
|
return;
|
|
477
348
|
}
|
|
478
349
|
if (!mimeType && !isValidScreenCall) {
|
|
479
|
-
if (!/\.(css|tsx?|
|
|
350
|
+
if (!/\.(css|tsx?|jsx?|woff2|fr|manifest)(\??|$)|@(vite|react|id)/.test(url)) {
|
|
480
351
|
console.debug("no ext", extension || url);
|
|
481
352
|
}
|
|
482
353
|
return ev.respondWith(onlineFirst(ev.request, ev));
|
|
483
354
|
}
|
|
484
|
-
if (/http:\/\/localhost:\d+\/(favicon\.svg|assets\/)/.test(url)) {
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
355
|
const entryId = knownLinks.get(url.replace(/https:\/\/.*?\//, "")) || knownLinks.get(`medias/${url.replace(/https:\/\/.*?\//, "")}`);
|
|
488
356
|
if (isValidScreenCall) {
|
|
357
|
+
console.debug("screencall!");
|
|
489
358
|
return ev.respondWith(fetchScreenCall(ev, { offlineWorkerSync, knownLinks }));
|
|
490
359
|
}
|
|
491
360
|
if (entryId) {
|
|
@@ -494,7 +363,6 @@ swSelf.addEventListener("fetch", (ev) => {
|
|
|
494
363
|
if (/lls|lelivrescolaire/.test(url)) {
|
|
495
364
|
console.info("no link for", url.replace(/https:\/\/.*?\//, ""), `medias/${url.replace(/https:\/\/.*?\//, "")}`);
|
|
496
365
|
}
|
|
497
|
-
console.debug("unintercepted url", url);
|
|
498
366
|
return;
|
|
499
367
|
});
|
|
500
368
|
swSelf.addEventListener("install", (_event) => {
|
|
@@ -515,10 +383,7 @@ var initChannel = async (__, { ports }) => {
|
|
|
515
383
|
);
|
|
516
384
|
offlineWorkerSync = sender;
|
|
517
385
|
offlineWorker.onmessage = handler.handle;
|
|
518
|
-
offlineWorkerSync.on("setKnownLinks", (
|
|
519
|
-
setKnownLinks(knownLinks, { entryNames, bookId });
|
|
520
|
-
offlineWorker.postMessage({ methodName: "setKnownLinks:back", eventId });
|
|
521
|
-
});
|
|
386
|
+
offlineWorkerSync.on("setKnownLinks", setKnownLinks.bind(null, knownLinks));
|
|
522
387
|
offlineWorker.postMessage({ methodName: "sendAppReady" });
|
|
523
388
|
};
|
|
524
389
|
var knownLinks = /* @__PURE__ */ new Map();
|
|
@@ -31,18 +31,7 @@ var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
|
31
31
|
return ({ ports, ...arg } = {}) => {
|
|
32
32
|
return new Promise((resolve, reject) => {
|
|
33
33
|
const eventId = `${methodName}:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
34
|
-
|
|
35
|
-
const timeout = setTimeout(() => {
|
|
36
|
-
console.warn("slow request for", methodName, arg);
|
|
37
|
-
}, 3e3);
|
|
38
|
-
const doResolve = (arg2) => {
|
|
39
|
-
if (!resolved) {
|
|
40
|
-
resolved = true;
|
|
41
|
-
clearTimeout(timeout);
|
|
42
|
-
resolve(arg2);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
dic[eventId] = { resolve: doResolve, reject };
|
|
34
|
+
dic[eventId] = { resolve, reject };
|
|
46
35
|
offlineWorker.postMessage({ eventId, methodName, arg }, ports);
|
|
47
36
|
});
|
|
48
37
|
};
|
|
@@ -95,6 +84,16 @@ var combineHandlers = (...handlers) => {
|
|
|
95
84
|
};
|
|
96
85
|
};
|
|
97
86
|
var openCache = async (mode) => caches.open(`LLS_OFFLINE_${mode}`);
|
|
87
|
+
var concatArrayBuffers = (buffers) => {
|
|
88
|
+
const totalLength = buffers.reduce((sum, buf) => sum + buf.byteLength, 0);
|
|
89
|
+
const concatenated = new Uint8Array(totalLength);
|
|
90
|
+
let offset = 0;
|
|
91
|
+
for (const buffer of buffers) {
|
|
92
|
+
concatenated.set(new Uint8Array(buffer), offset);
|
|
93
|
+
offset += buffer.byteLength;
|
|
94
|
+
}
|
|
95
|
+
return concatenated.buffer;
|
|
96
|
+
};
|
|
98
97
|
var isStoryZip = (name) => /story-.*?\.zip/.test(name);
|
|
99
98
|
var isValidZipName = (name) => {
|
|
100
99
|
return /lecture-cp\.zip/.test(name) || isStoryZip(name);
|
|
@@ -171,72 +170,615 @@ var loadPreload = (json) => {
|
|
|
171
170
|
});
|
|
172
171
|
};
|
|
173
172
|
|
|
174
|
-
//
|
|
175
|
-
var
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
173
|
+
// ../../node_modules/.pnpm/fflate@0.8.2/node_modules/fflate/esm/browser.js
|
|
174
|
+
var u8 = Uint8Array;
|
|
175
|
+
var u16 = Uint16Array;
|
|
176
|
+
var i32 = Int32Array;
|
|
177
|
+
var fleb = new u8([
|
|
178
|
+
0,
|
|
179
|
+
0,
|
|
180
|
+
0,
|
|
181
|
+
0,
|
|
182
|
+
0,
|
|
183
|
+
0,
|
|
184
|
+
0,
|
|
185
|
+
0,
|
|
186
|
+
1,
|
|
187
|
+
1,
|
|
188
|
+
1,
|
|
189
|
+
1,
|
|
190
|
+
2,
|
|
191
|
+
2,
|
|
192
|
+
2,
|
|
193
|
+
2,
|
|
194
|
+
3,
|
|
195
|
+
3,
|
|
196
|
+
3,
|
|
197
|
+
3,
|
|
198
|
+
4,
|
|
199
|
+
4,
|
|
200
|
+
4,
|
|
201
|
+
4,
|
|
202
|
+
5,
|
|
203
|
+
5,
|
|
204
|
+
5,
|
|
205
|
+
5,
|
|
206
|
+
0,
|
|
207
|
+
/* unused */
|
|
208
|
+
0,
|
|
209
|
+
0,
|
|
210
|
+
/* impossible */
|
|
211
|
+
0
|
|
212
|
+
]);
|
|
213
|
+
var fdeb = new u8([
|
|
214
|
+
0,
|
|
215
|
+
0,
|
|
216
|
+
0,
|
|
217
|
+
0,
|
|
218
|
+
1,
|
|
219
|
+
1,
|
|
220
|
+
2,
|
|
221
|
+
2,
|
|
222
|
+
3,
|
|
223
|
+
3,
|
|
224
|
+
4,
|
|
225
|
+
4,
|
|
226
|
+
5,
|
|
227
|
+
5,
|
|
228
|
+
6,
|
|
229
|
+
6,
|
|
230
|
+
7,
|
|
231
|
+
7,
|
|
232
|
+
8,
|
|
233
|
+
8,
|
|
234
|
+
9,
|
|
235
|
+
9,
|
|
236
|
+
10,
|
|
237
|
+
10,
|
|
238
|
+
11,
|
|
239
|
+
11,
|
|
240
|
+
12,
|
|
241
|
+
12,
|
|
242
|
+
13,
|
|
243
|
+
13,
|
|
244
|
+
/* unused */
|
|
245
|
+
0,
|
|
246
|
+
0
|
|
247
|
+
]);
|
|
248
|
+
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
249
|
+
var freb = function(eb, start) {
|
|
250
|
+
var b = new u16(31);
|
|
251
|
+
for (var i = 0; i < 31; ++i) {
|
|
252
|
+
b[i] = start += 1 << eb[i - 1];
|
|
253
|
+
}
|
|
254
|
+
var r = new i32(b[30]);
|
|
255
|
+
for (var i = 1; i < 30; ++i) {
|
|
256
|
+
for (var j = b[i]; j < b[i + 1]; ++j) {
|
|
257
|
+
r[j] = j - b[i] << 5 | i;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return { b, r };
|
|
261
|
+
};
|
|
262
|
+
var _a = freb(fleb, 2);
|
|
263
|
+
var fl = _a.b;
|
|
264
|
+
var revfl = _a.r;
|
|
265
|
+
fl[28] = 258, revfl[258] = 28;
|
|
266
|
+
var _b = freb(fdeb, 0);
|
|
267
|
+
var fd = _b.b;
|
|
268
|
+
var revfd = _b.r;
|
|
269
|
+
var rev = new u16(32768);
|
|
270
|
+
for (i = 0; i < 32768; ++i) {
|
|
271
|
+
x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
272
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
273
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
274
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
275
|
+
}
|
|
276
|
+
var x;
|
|
277
|
+
var i;
|
|
278
|
+
var hMap = function(cd, mb, r) {
|
|
279
|
+
var s = cd.length;
|
|
280
|
+
var i = 0;
|
|
281
|
+
var l = new u16(mb);
|
|
282
|
+
for (; i < s; ++i) {
|
|
283
|
+
if (cd[i])
|
|
284
|
+
++l[cd[i] - 1];
|
|
285
|
+
}
|
|
286
|
+
var le = new u16(mb);
|
|
287
|
+
for (i = 1; i < mb; ++i) {
|
|
288
|
+
le[i] = le[i - 1] + l[i - 1] << 1;
|
|
289
|
+
}
|
|
290
|
+
var co;
|
|
291
|
+
if (r) {
|
|
292
|
+
co = new u16(1 << mb);
|
|
293
|
+
var rvb = 15 - mb;
|
|
294
|
+
for (i = 0; i < s; ++i) {
|
|
295
|
+
if (cd[i]) {
|
|
296
|
+
var sv = i << 4 | cd[i];
|
|
297
|
+
var r_1 = mb - cd[i];
|
|
298
|
+
var v = le[cd[i] - 1]++ << r_1;
|
|
299
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
|
|
300
|
+
co[rev[v] >> rvb] = sv;
|
|
183
301
|
}
|
|
184
302
|
}
|
|
185
303
|
}
|
|
304
|
+
} else {
|
|
305
|
+
co = new u16(s);
|
|
306
|
+
for (i = 0; i < s; ++i) {
|
|
307
|
+
if (cd[i]) {
|
|
308
|
+
co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
186
311
|
}
|
|
187
|
-
|
|
312
|
+
return co;
|
|
188
313
|
};
|
|
189
|
-
var
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
314
|
+
var flt = new u8(288);
|
|
315
|
+
for (i = 0; i < 144; ++i)
|
|
316
|
+
flt[i] = 8;
|
|
317
|
+
var i;
|
|
318
|
+
for (i = 144; i < 256; ++i)
|
|
319
|
+
flt[i] = 9;
|
|
320
|
+
var i;
|
|
321
|
+
for (i = 256; i < 280; ++i)
|
|
322
|
+
flt[i] = 7;
|
|
323
|
+
var i;
|
|
324
|
+
for (i = 280; i < 288; ++i)
|
|
325
|
+
flt[i] = 8;
|
|
326
|
+
var i;
|
|
327
|
+
var fdt = new u8(32);
|
|
328
|
+
for (i = 0; i < 32; ++i)
|
|
329
|
+
fdt[i] = 5;
|
|
330
|
+
var i;
|
|
331
|
+
var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
332
|
+
var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
333
|
+
var max = function(a2) {
|
|
334
|
+
var m = a2[0];
|
|
335
|
+
for (var i = 1; i < a2.length; ++i) {
|
|
336
|
+
if (a2[i] > m)
|
|
337
|
+
m = a2[i];
|
|
211
338
|
}
|
|
212
|
-
return
|
|
339
|
+
return m;
|
|
340
|
+
};
|
|
341
|
+
var bits = function(d, p, m) {
|
|
342
|
+
var o = p / 8 | 0;
|
|
343
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
344
|
+
};
|
|
345
|
+
var bits16 = function(d, p) {
|
|
346
|
+
var o = p / 8 | 0;
|
|
347
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
213
348
|
};
|
|
214
|
-
var
|
|
215
|
-
|
|
216
|
-
const n = readIndex(buf, sofh + 26, 2);
|
|
217
|
-
const m = readIndex(buf, sofh + 28, 2);
|
|
218
|
-
return buf.slice(sofh + 30 + n + m, sofh + 30 + n + m + dataSize);
|
|
349
|
+
var shft = function(p) {
|
|
350
|
+
return (p + 7) / 8 | 0;
|
|
219
351
|
};
|
|
220
|
-
var
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return
|
|
352
|
+
var slc = function(v, s, e) {
|
|
353
|
+
if (s == null || s < 0)
|
|
354
|
+
s = 0;
|
|
355
|
+
if (e == null || e > v.length)
|
|
356
|
+
e = v.length;
|
|
357
|
+
return new u8(v.subarray(s, e));
|
|
226
358
|
};
|
|
359
|
+
var ec = [
|
|
360
|
+
"unexpected EOF",
|
|
361
|
+
"invalid block type",
|
|
362
|
+
"invalid length/literal",
|
|
363
|
+
"invalid distance",
|
|
364
|
+
"stream finished",
|
|
365
|
+
"no stream handler",
|
|
366
|
+
,
|
|
367
|
+
"no callback",
|
|
368
|
+
"invalid UTF-8 data",
|
|
369
|
+
"extra field too long",
|
|
370
|
+
"date not in range 1980-2099",
|
|
371
|
+
"filename too long",
|
|
372
|
+
"stream finishing",
|
|
373
|
+
"invalid zip data"
|
|
374
|
+
// determined by unknown compression method
|
|
375
|
+
];
|
|
376
|
+
var err = function(ind, msg, nt) {
|
|
377
|
+
var e = new Error(msg || ec[ind]);
|
|
378
|
+
e.code = ind;
|
|
379
|
+
if (Error.captureStackTrace)
|
|
380
|
+
Error.captureStackTrace(e, err);
|
|
381
|
+
if (!nt)
|
|
382
|
+
throw e;
|
|
383
|
+
return e;
|
|
384
|
+
};
|
|
385
|
+
var inflt = function(dat, st, buf, dict) {
|
|
386
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
387
|
+
if (!sl || st.f && !st.l)
|
|
388
|
+
return buf || new u8(0);
|
|
389
|
+
var noBuf = !buf;
|
|
390
|
+
var resize = noBuf || st.i != 2;
|
|
391
|
+
var noSt = st.i;
|
|
392
|
+
if (noBuf)
|
|
393
|
+
buf = new u8(sl * 3);
|
|
394
|
+
var cbuf = function(l2) {
|
|
395
|
+
var bl = buf.length;
|
|
396
|
+
if (l2 > bl) {
|
|
397
|
+
var nbuf = new u8(Math.max(bl * 2, l2));
|
|
398
|
+
nbuf.set(buf);
|
|
399
|
+
buf = nbuf;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
403
|
+
var tbts = sl * 8;
|
|
404
|
+
do {
|
|
405
|
+
if (!lm) {
|
|
406
|
+
final = bits(dat, pos, 1);
|
|
407
|
+
var type = bits(dat, pos + 1, 3);
|
|
408
|
+
pos += 3;
|
|
409
|
+
if (!type) {
|
|
410
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
411
|
+
if (t > sl) {
|
|
412
|
+
if (noSt)
|
|
413
|
+
err(0);
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
if (resize)
|
|
417
|
+
cbuf(bt + l);
|
|
418
|
+
buf.set(dat.subarray(s, t), bt);
|
|
419
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
420
|
+
continue;
|
|
421
|
+
} else if (type == 1)
|
|
422
|
+
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
423
|
+
else if (type == 2) {
|
|
424
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
425
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
426
|
+
pos += 14;
|
|
427
|
+
var ldt = new u8(tl);
|
|
428
|
+
var clt = new u8(19);
|
|
429
|
+
for (var i = 0; i < hcLen; ++i) {
|
|
430
|
+
clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
431
|
+
}
|
|
432
|
+
pos += hcLen * 3;
|
|
433
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
434
|
+
var clm = hMap(clt, clb, 1);
|
|
435
|
+
for (var i = 0; i < tl; ) {
|
|
436
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
437
|
+
pos += r & 15;
|
|
438
|
+
var s = r >> 4;
|
|
439
|
+
if (s < 16) {
|
|
440
|
+
ldt[i++] = s;
|
|
441
|
+
} else {
|
|
442
|
+
var c = 0, n = 0;
|
|
443
|
+
if (s == 16)
|
|
444
|
+
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
|
445
|
+
else if (s == 17)
|
|
446
|
+
n = 3 + bits(dat, pos, 7), pos += 3;
|
|
447
|
+
else if (s == 18)
|
|
448
|
+
n = 11 + bits(dat, pos, 127), pos += 7;
|
|
449
|
+
while (n--)
|
|
450
|
+
ldt[i++] = c;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
454
|
+
lbt = max(lt);
|
|
455
|
+
dbt = max(dt);
|
|
456
|
+
lm = hMap(lt, lbt, 1);
|
|
457
|
+
dm = hMap(dt, dbt, 1);
|
|
458
|
+
} else
|
|
459
|
+
err(1);
|
|
460
|
+
if (pos > tbts) {
|
|
461
|
+
if (noSt)
|
|
462
|
+
err(0);
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (resize)
|
|
467
|
+
cbuf(bt + 131072);
|
|
468
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
469
|
+
var lpos = pos;
|
|
470
|
+
for (; ; lpos = pos) {
|
|
471
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
472
|
+
pos += c & 15;
|
|
473
|
+
if (pos > tbts) {
|
|
474
|
+
if (noSt)
|
|
475
|
+
err(0);
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
if (!c)
|
|
479
|
+
err(2);
|
|
480
|
+
if (sym < 256)
|
|
481
|
+
buf[bt++] = sym;
|
|
482
|
+
else if (sym == 256) {
|
|
483
|
+
lpos = pos, lm = null;
|
|
484
|
+
break;
|
|
485
|
+
} else {
|
|
486
|
+
var add = sym - 254;
|
|
487
|
+
if (sym > 264) {
|
|
488
|
+
var i = sym - 257, b = fleb[i];
|
|
489
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
|
490
|
+
pos += b;
|
|
491
|
+
}
|
|
492
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
493
|
+
if (!d)
|
|
494
|
+
err(3);
|
|
495
|
+
pos += d & 15;
|
|
496
|
+
var dt = fd[dsym];
|
|
497
|
+
if (dsym > 3) {
|
|
498
|
+
var b = fdeb[dsym];
|
|
499
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
500
|
+
}
|
|
501
|
+
if (pos > tbts) {
|
|
502
|
+
if (noSt)
|
|
503
|
+
err(0);
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
if (resize)
|
|
507
|
+
cbuf(bt + 131072);
|
|
508
|
+
var end = bt + add;
|
|
509
|
+
if (bt < dt) {
|
|
510
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
511
|
+
if (shift + bt < 0)
|
|
512
|
+
err(3);
|
|
513
|
+
for (; bt < dend; ++bt)
|
|
514
|
+
buf[bt] = dict[shift + bt];
|
|
515
|
+
}
|
|
516
|
+
for (; bt < end; ++bt)
|
|
517
|
+
buf[bt] = buf[bt - dt];
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
521
|
+
if (lm)
|
|
522
|
+
final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
523
|
+
} while (!final);
|
|
524
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
525
|
+
};
|
|
526
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
527
|
+
var b2 = function(d, b) {
|
|
528
|
+
return d[b] | d[b + 1] << 8;
|
|
529
|
+
};
|
|
530
|
+
var b4 = function(d, b) {
|
|
531
|
+
return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
|
|
532
|
+
};
|
|
533
|
+
var b8 = function(d, b) {
|
|
534
|
+
return b4(d, b) + b4(d, b + 4) * 4294967296;
|
|
535
|
+
};
|
|
536
|
+
var Inflate = /* @__PURE__ */ function() {
|
|
537
|
+
function Inflate2(opts, cb) {
|
|
538
|
+
if (typeof opts == "function")
|
|
539
|
+
cb = opts, opts = {};
|
|
540
|
+
this.ondata = cb;
|
|
541
|
+
var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);
|
|
542
|
+
this.s = { i: 0, b: dict ? dict.length : 0 };
|
|
543
|
+
this.o = new u8(32768);
|
|
544
|
+
this.p = new u8(0);
|
|
545
|
+
if (dict)
|
|
546
|
+
this.o.set(dict);
|
|
547
|
+
}
|
|
548
|
+
Inflate2.prototype.e = function(c) {
|
|
549
|
+
if (!this.ondata)
|
|
550
|
+
err(5);
|
|
551
|
+
if (this.d)
|
|
552
|
+
err(4);
|
|
553
|
+
if (!this.p.length)
|
|
554
|
+
this.p = c;
|
|
555
|
+
else if (c.length) {
|
|
556
|
+
var n = new u8(this.p.length + c.length);
|
|
557
|
+
n.set(this.p), n.set(c, this.p.length), this.p = n;
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
Inflate2.prototype.c = function(final) {
|
|
561
|
+
this.s.i = +(this.d = final || false);
|
|
562
|
+
var bts = this.s.b;
|
|
563
|
+
var dt = inflt(this.p, this.s, this.o);
|
|
564
|
+
this.ondata(slc(dt, bts, this.s.b), this.d);
|
|
565
|
+
this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;
|
|
566
|
+
this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;
|
|
567
|
+
};
|
|
568
|
+
Inflate2.prototype.push = function(chunk, final) {
|
|
569
|
+
this.e(chunk), this.c(final);
|
|
570
|
+
};
|
|
571
|
+
return Inflate2;
|
|
572
|
+
}();
|
|
573
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
574
|
+
var tds = 0;
|
|
575
|
+
try {
|
|
576
|
+
td.decode(et, { stream: true });
|
|
577
|
+
tds = 1;
|
|
578
|
+
} catch (e) {
|
|
579
|
+
}
|
|
580
|
+
var dutf8 = function(d) {
|
|
581
|
+
for (var r = "", i = 0; ; ) {
|
|
582
|
+
var c = d[i++];
|
|
583
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
584
|
+
if (i + eb > d.length)
|
|
585
|
+
return { s: r, r: slc(d, i - 1) };
|
|
586
|
+
if (!eb)
|
|
587
|
+
r += String.fromCharCode(c);
|
|
588
|
+
else if (eb == 3) {
|
|
589
|
+
c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | d[i++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
|
|
590
|
+
} else if (eb & 1)
|
|
591
|
+
r += String.fromCharCode((c & 31) << 6 | d[i++] & 63);
|
|
592
|
+
else
|
|
593
|
+
r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | d[i++] & 63);
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
function strFromU8(dat, latin1) {
|
|
597
|
+
if (latin1) {
|
|
598
|
+
var r = "";
|
|
599
|
+
for (var i = 0; i < dat.length; i += 16384)
|
|
600
|
+
r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));
|
|
601
|
+
return r;
|
|
602
|
+
} else if (td) {
|
|
603
|
+
return td.decode(dat);
|
|
604
|
+
} else {
|
|
605
|
+
var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;
|
|
606
|
+
if (r.length)
|
|
607
|
+
err(8);
|
|
608
|
+
return s;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
var z64e = function(d, b) {
|
|
612
|
+
for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))
|
|
613
|
+
;
|
|
614
|
+
return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];
|
|
615
|
+
};
|
|
616
|
+
var UnzipPassThrough = /* @__PURE__ */ function() {
|
|
617
|
+
function UnzipPassThrough2() {
|
|
618
|
+
}
|
|
619
|
+
UnzipPassThrough2.prototype.push = function(data, final) {
|
|
620
|
+
this.ondata(null, data, final);
|
|
621
|
+
};
|
|
622
|
+
UnzipPassThrough2.compression = 0;
|
|
623
|
+
return UnzipPassThrough2;
|
|
624
|
+
}();
|
|
625
|
+
var UnzipInflate = /* @__PURE__ */ function() {
|
|
626
|
+
function UnzipInflate2() {
|
|
627
|
+
var _this = this;
|
|
628
|
+
this.i = new Inflate(function(dat, final) {
|
|
629
|
+
_this.ondata(null, dat, final);
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
UnzipInflate2.prototype.push = function(data, final) {
|
|
633
|
+
try {
|
|
634
|
+
this.i.push(data, final);
|
|
635
|
+
} catch (e) {
|
|
636
|
+
this.ondata(e, null, final);
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
UnzipInflate2.compression = 8;
|
|
640
|
+
return UnzipInflate2;
|
|
641
|
+
}();
|
|
642
|
+
var Unzip = /* @__PURE__ */ function() {
|
|
643
|
+
function Unzip2(cb) {
|
|
644
|
+
this.onfile = cb;
|
|
645
|
+
this.k = [];
|
|
646
|
+
this.o = {
|
|
647
|
+
0: UnzipPassThrough
|
|
648
|
+
};
|
|
649
|
+
this.p = et;
|
|
650
|
+
}
|
|
651
|
+
Unzip2.prototype.push = function(chunk, final) {
|
|
652
|
+
var _this = this;
|
|
653
|
+
if (!this.onfile)
|
|
654
|
+
err(5);
|
|
655
|
+
if (!this.p)
|
|
656
|
+
err(4);
|
|
657
|
+
if (this.c > 0) {
|
|
658
|
+
var len = Math.min(this.c, chunk.length);
|
|
659
|
+
var toAdd = chunk.subarray(0, len);
|
|
660
|
+
this.c -= len;
|
|
661
|
+
if (this.d)
|
|
662
|
+
this.d.push(toAdd, !this.c);
|
|
663
|
+
else
|
|
664
|
+
this.k[0].push(toAdd);
|
|
665
|
+
chunk = chunk.subarray(len);
|
|
666
|
+
if (chunk.length)
|
|
667
|
+
return this.push(chunk, final);
|
|
668
|
+
} else {
|
|
669
|
+
var f = 0, i = 0, is = void 0, buf = void 0;
|
|
670
|
+
if (!this.p.length)
|
|
671
|
+
buf = chunk;
|
|
672
|
+
else if (!chunk.length)
|
|
673
|
+
buf = this.p;
|
|
674
|
+
else {
|
|
675
|
+
buf = new u8(this.p.length + chunk.length);
|
|
676
|
+
buf.set(this.p), buf.set(chunk, this.p.length);
|
|
677
|
+
}
|
|
678
|
+
var l = buf.length, oc = this.c, add = oc && this.d;
|
|
679
|
+
var _loop_2 = function() {
|
|
680
|
+
var _a2;
|
|
681
|
+
var sig = b4(buf, i);
|
|
682
|
+
if (sig == 67324752) {
|
|
683
|
+
f = 1, is = i;
|
|
684
|
+
this_1.d = null;
|
|
685
|
+
this_1.c = 0;
|
|
686
|
+
var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);
|
|
687
|
+
if (l > i + 30 + fnl + es) {
|
|
688
|
+
var chks_3 = [];
|
|
689
|
+
this_1.k.unshift(chks_3);
|
|
690
|
+
f = 2;
|
|
691
|
+
var sc_1 = b4(buf, i + 18), su_1 = b4(buf, i + 22);
|
|
692
|
+
var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);
|
|
693
|
+
if (sc_1 == 4294967295) {
|
|
694
|
+
_a2 = dd ? [-2] : z64e(buf, i), sc_1 = _a2[0], su_1 = _a2[1];
|
|
695
|
+
} else if (dd)
|
|
696
|
+
sc_1 = -1;
|
|
697
|
+
i += es;
|
|
698
|
+
this_1.c = sc_1;
|
|
699
|
+
var d_1;
|
|
700
|
+
var file_1 = {
|
|
701
|
+
name: fn_1,
|
|
702
|
+
compression: cmp_1,
|
|
703
|
+
start: function() {
|
|
704
|
+
if (!file_1.ondata)
|
|
705
|
+
err(5);
|
|
706
|
+
if (!sc_1)
|
|
707
|
+
file_1.ondata(null, et, true);
|
|
708
|
+
else {
|
|
709
|
+
var ctr = _this.o[cmp_1];
|
|
710
|
+
if (!ctr)
|
|
711
|
+
file_1.ondata(err(14, "unknown compression type " + cmp_1, 1), null, false);
|
|
712
|
+
d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);
|
|
713
|
+
d_1.ondata = function(err2, dat3, final2) {
|
|
714
|
+
file_1.ondata(err2, dat3, final2);
|
|
715
|
+
};
|
|
716
|
+
for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {
|
|
717
|
+
var dat2 = chks_4[_i];
|
|
718
|
+
d_1.push(dat2, false);
|
|
719
|
+
}
|
|
720
|
+
if (_this.k[0] == chks_3 && _this.c)
|
|
721
|
+
_this.d = d_1;
|
|
722
|
+
else
|
|
723
|
+
d_1.push(et, true);
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
terminate: function() {
|
|
727
|
+
if (d_1 && d_1.terminate)
|
|
728
|
+
d_1.terminate();
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
if (sc_1 >= 0)
|
|
732
|
+
file_1.size = sc_1, file_1.originalSize = su_1;
|
|
733
|
+
this_1.onfile(file_1);
|
|
734
|
+
}
|
|
735
|
+
return "break";
|
|
736
|
+
} else if (oc) {
|
|
737
|
+
if (sig == 134695760) {
|
|
738
|
+
is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;
|
|
739
|
+
return "break";
|
|
740
|
+
} else if (sig == 33639248) {
|
|
741
|
+
is = i -= 4, f = 3, this_1.c = 0;
|
|
742
|
+
return "break";
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
var this_1 = this;
|
|
747
|
+
for (; i < l - 4; ++i) {
|
|
748
|
+
var state_1 = _loop_2();
|
|
749
|
+
if (state_1 === "break")
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
this.p = et;
|
|
753
|
+
if (oc < 0) {
|
|
754
|
+
var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 134695760 && 4)) : buf.subarray(0, i);
|
|
755
|
+
if (add)
|
|
756
|
+
add.push(dat, !!f);
|
|
757
|
+
else
|
|
758
|
+
this.k[+(f == 2)].push(dat);
|
|
759
|
+
}
|
|
760
|
+
if (f & 2)
|
|
761
|
+
return this.push(buf.subarray(i), final);
|
|
762
|
+
this.p = buf.subarray(i);
|
|
763
|
+
}
|
|
764
|
+
if (final) {
|
|
765
|
+
if (this.c)
|
|
766
|
+
err(13);
|
|
767
|
+
this.p = null;
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
Unzip2.prototype.register = function(decoder) {
|
|
771
|
+
this.o[decoder.compression] = decoder;
|
|
772
|
+
};
|
|
773
|
+
return Unzip2;
|
|
774
|
+
}();
|
|
227
775
|
|
|
228
776
|
// src/worker/wwZip.ts
|
|
229
777
|
var key = new Uint8Array([..."4c6520636f6e74656e7520646573206c".matchAll(/../g)].map(([c]) => Number(`0x${c}`)));
|
|
230
778
|
var iv = new Uint8Array(16).fill(0);
|
|
231
779
|
async function decryptData(encryptedData, key2, iv2) {
|
|
232
|
-
const cryptoKey = await crypto.subtle.importKey("raw", key2.buffer, { name: "AES-CBC" }, false, [
|
|
233
|
-
|
|
234
|
-
]);
|
|
235
|
-
const decryptedData = await crypto.subtle.decrypt(
|
|
236
|
-
{ name: "AES-CBC", iv: iv2.buffer },
|
|
237
|
-
cryptoKey,
|
|
238
|
-
encryptedData
|
|
239
|
-
);
|
|
780
|
+
const cryptoKey = await crypto.subtle.importKey("raw", key2.buffer, { name: "AES-CBC" }, false, ["decrypt"]);
|
|
781
|
+
const decryptedData = await crypto.subtle.decrypt({ name: "AES-CBC", iv: iv2.buffer }, cryptoKey, encryptedData);
|
|
240
782
|
return decryptedData;
|
|
241
783
|
}
|
|
242
784
|
var BOOKS = {};
|
|
@@ -260,14 +802,12 @@ var readZipEntry = async ({
|
|
|
260
802
|
const originalName = manifest.medias[zipName];
|
|
261
803
|
overridenName = `medias/${originalName}`;
|
|
262
804
|
} else {
|
|
263
|
-
|
|
264
|
-
console.error("any media should exist in manifest", zipName, entryName, bookId);
|
|
265
|
-
}
|
|
805
|
+
console.error("any media should exist in manifest", zipName, entryName, bookId);
|
|
266
806
|
}
|
|
267
807
|
}
|
|
268
808
|
const bookEntry = BOOKS[bookId].map.get(overridenName);
|
|
269
809
|
if (!bookEntry) {
|
|
270
|
-
console.info("no bookEntry", entryName, "
|
|
810
|
+
console.info("no bookEntry", entryName, "found", overridenName);
|
|
271
811
|
return null;
|
|
272
812
|
}
|
|
273
813
|
if (!bookEntry.decoded) {
|
|
@@ -280,19 +820,43 @@ var hasZip = (bookId) => {
|
|
|
280
820
|
};
|
|
281
821
|
var loadZip = async (buf, bookId) => {
|
|
282
822
|
const m = /* @__PURE__ */ new Map();
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (!name.includes(".")) {
|
|
287
|
-
|
|
823
|
+
const unzipper = new Unzip();
|
|
824
|
+
unzipper.register(UnzipInflate);
|
|
825
|
+
unzipper.onfile = (file) => {
|
|
826
|
+
if (!file.name.includes(".")) {
|
|
827
|
+
return;
|
|
288
828
|
}
|
|
289
|
-
m.set(name, {
|
|
829
|
+
m.set(file.name, {
|
|
290
830
|
decoded: null,
|
|
291
831
|
zipEntry: {
|
|
292
|
-
getData:
|
|
832
|
+
getData: () => {
|
|
833
|
+
return new Promise((resolve) => {
|
|
834
|
+
const buffers = [];
|
|
835
|
+
file.ondata = (err2, data, final) => {
|
|
836
|
+
if (err2) {
|
|
837
|
+
console.error("failed to read zip data", file.name, err2);
|
|
838
|
+
}
|
|
839
|
+
if (data.byteLength) {
|
|
840
|
+
buffers.push(data);
|
|
841
|
+
}
|
|
842
|
+
if (final) {
|
|
843
|
+
return resolve(concatArrayBuffers(buffers));
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
file.start();
|
|
847
|
+
});
|
|
848
|
+
}
|
|
293
849
|
}
|
|
294
850
|
});
|
|
851
|
+
};
|
|
852
|
+
const chunkSize = 32 * 1024 * 1024;
|
|
853
|
+
const nChunks = Math.max(1, Math.floor(buf.byteLength / chunkSize));
|
|
854
|
+
const sleep = new Promise((resolve) => setTimeout(resolve, 0));
|
|
855
|
+
for (let i = 0; i < nChunks - 1; ++i) {
|
|
856
|
+
unzipper.push(buf.slice(i * chunkSize, (i + 1) * chunkSize));
|
|
857
|
+
await sleep;
|
|
295
858
|
}
|
|
859
|
+
unzipper.push(buf.slice((nChunks - 1) * chunkSize, buf.byteLength), true);
|
|
296
860
|
BOOKS[bookId] = {
|
|
297
861
|
map: m,
|
|
298
862
|
manifest: null
|
|
@@ -322,8 +886,7 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
322
886
|
return back;
|
|
323
887
|
}
|
|
324
888
|
if (STORAGE === "cache") {
|
|
325
|
-
const
|
|
326
|
-
const response = await cache.match(zipUrl);
|
|
889
|
+
const response = await caches.match(zipUrl);
|
|
327
890
|
if (!response) {
|
|
328
891
|
throw new Error(`missing zip ${zipUrl}`);
|
|
329
892
|
}
|
|
@@ -347,11 +910,7 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
347
910
|
const buf = await readArrayBuffer();
|
|
348
911
|
if (CHECK_UPDATES) {
|
|
349
912
|
const response = await fetch(zipUrl, { method: "HEAD" });
|
|
350
|
-
|
|
351
|
-
if (!remoteSize) {
|
|
352
|
-
console.info("remoteSize not found. will skip update. Is the server up at", zipUrl);
|
|
353
|
-
remoteSize = buf.byteLength;
|
|
354
|
-
}
|
|
913
|
+
const remoteSize = Number.parseInt(response.headers.get("content-length") || "0", 10);
|
|
355
914
|
if (remoteSize !== buf.byteLength) {
|
|
356
915
|
const error = `new ${fileName} available, refetching (opfs:${buf.byteLength} vs remote:${remoteSize})`;
|
|
357
916
|
console.debug(error);
|
|
@@ -359,7 +918,6 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
359
918
|
throw new Error(`new ${fileName} available, refetching`);
|
|
360
919
|
}
|
|
361
920
|
}
|
|
362
|
-
self.postMessage({ methodName: "opfsProgress", arg: { total: buf.byteLength, bytes: buf.byteLength } });
|
|
363
921
|
return buf;
|
|
364
922
|
} catch (e) {
|
|
365
923
|
if (e instanceof Error && e.message !== "forceRefresh" && !e.message.includes("refetching")) {
|
|
@@ -389,7 +947,6 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
389
947
|
self.postMessage({ methodName: "opfsProgress", arg: { total: contentLength, bytes: position } });
|
|
390
948
|
}
|
|
391
949
|
}
|
|
392
|
-
console.debug("zip loaded:", arrayBuffer.byteLength);
|
|
393
950
|
if (STORAGE === "native") {
|
|
394
951
|
await sender.nativeWriteFile({ fname: fileName, buffer: arrayBuffer });
|
|
395
952
|
} else if (STORAGE === "opfs") {
|
|
@@ -434,15 +991,8 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
|
|
|
434
991
|
tryCatch(async () => {
|
|
435
992
|
const buf = await fetchZipFile(`${ZIP_BASE_URL}/${bookId}.zip`, { forceRefresh });
|
|
436
993
|
try {
|
|
437
|
-
console.time("loadzip");
|
|
438
994
|
const entryNames = await loadZip(new Uint8Array(buf), bookId);
|
|
439
|
-
|
|
440
|
-
const eventId = `setKnownLinks:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
441
|
-
const responseForEventId = new Promise((resolve, reject) => {
|
|
442
|
-
dicFetchWorkerCallback[eventId] = { resolve, reject };
|
|
443
|
-
});
|
|
444
|
-
fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId, eventId } });
|
|
445
|
-
await responseForEventId;
|
|
995
|
+
fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId } });
|
|
446
996
|
if (isOldZip(bookId)) {
|
|
447
997
|
const json = await readZipEntry({
|
|
448
998
|
entryName: `preload/${bookId}.json`,
|
|
@@ -450,13 +1000,6 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
|
|
|
450
1000
|
asJson: true
|
|
451
1001
|
});
|
|
452
1002
|
loadBook(json);
|
|
453
|
-
} else {
|
|
454
|
-
try {
|
|
455
|
-
const { createdAt } = await readZipEntry({ bookId, entryName: "manifest.json", asJson: true });
|
|
456
|
-
console.debug("zipversion", createdAt);
|
|
457
|
-
} catch (e) {
|
|
458
|
-
console.debug("failed to read manifest.json", e);
|
|
459
|
-
}
|
|
460
1003
|
}
|
|
461
1004
|
return true;
|
|
462
1005
|
} catch (e) {
|
|
@@ -486,14 +1029,6 @@ var loadPageContent2 = async ({
|
|
|
486
1029
|
return await loadPageContent({ chapterId, json });
|
|
487
1030
|
};
|
|
488
1031
|
var fetchWorker;
|
|
489
|
-
var dicFetchWorkerCallback = {};
|
|
490
|
-
var handleFetchWorkerCallback = ({ data: { eventId } }) => {
|
|
491
|
-
if (dicFetchWorkerCallback[eventId]) {
|
|
492
|
-
dicFetchWorkerCallback[eventId].resolve();
|
|
493
|
-
} else {
|
|
494
|
-
console.debug("unknown eventId", eventId);
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
1032
|
var initChannel = (__, { ports }) => {
|
|
498
1033
|
fetchWorker = ports[0];
|
|
499
1034
|
const { canHandle, handle } = makeSyncHandler(fetchWorker, {
|
|
@@ -508,14 +1043,6 @@ var initChannel = (__, { ports }) => {
|
|
|
508
1043
|
self.postMessage({ methodName: "ready" });
|
|
509
1044
|
return;
|
|
510
1045
|
}
|
|
511
|
-
if (dataObj.data?.methodName === "setKnownLinks:back") {
|
|
512
|
-
if (typeof dataObj?.data?.eventId !== "string") {
|
|
513
|
-
console.debug("missing eventId to get response back for setKnownLinks:back");
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
|
-
handleFetchWorkerCallback(dataObj);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
1046
|
if (canHandle(dataObj.data?.methodName || "")) {
|
|
520
1047
|
return handle(dataObj);
|
|
521
1048
|
}
|
|
@@ -589,18 +1116,13 @@ var loadPreload2 = async () => {
|
|
|
589
1116
|
console.error("failed to load preload", e);
|
|
590
1117
|
}
|
|
591
1118
|
};
|
|
592
|
-
var reset = async () => {
|
|
593
|
-
await (await navigator.storage.getDirectory()).remove({ recursive: true });
|
|
594
|
-
console.info("opfs cleared");
|
|
595
|
-
};
|
|
596
1119
|
var mainHandle = makeSyncHandler(self, {
|
|
597
1120
|
initChannel,
|
|
598
1121
|
loadPreload: loadPreload2,
|
|
599
1122
|
readZipEntry,
|
|
600
1123
|
loadBooks,
|
|
601
1124
|
loadBook: loadBook2,
|
|
602
|
-
configure
|
|
603
|
-
reset
|
|
1125
|
+
configure
|
|
604
1126
|
});
|
|
605
1127
|
var { handler, ...sender } = makeSyncWorker(self, ["nativeWriteFile", "nativeReadFile", "nativeListZips"]);
|
|
606
1128
|
self.onmessage = combineHandlers(mainHandle, handler);
|
package/lib/index.js
CHANGED
|
@@ -31,18 +31,7 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
31
31
|
return ({ ports, ...arg } = {}) => {
|
|
32
32
|
return new Promise((resolve, reject) => {
|
|
33
33
|
const eventId = `${methodName}:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
34
|
-
|
|
35
|
-
const timeout = setTimeout(() => {
|
|
36
|
-
console.warn("slow request for", methodName, arg);
|
|
37
|
-
}, 3e3);
|
|
38
|
-
const doResolve = (arg2) => {
|
|
39
|
-
if (!resolved) {
|
|
40
|
-
resolved = true;
|
|
41
|
-
clearTimeout(timeout);
|
|
42
|
-
resolve(arg2);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
dic[eventId] = { resolve: doResolve, reject };
|
|
34
|
+
dic[eventId] = { resolve, reject };
|
|
46
35
|
offlineWorker2.postMessage({ eventId, methodName, arg }, ports);
|
|
47
36
|
});
|
|
48
37
|
};
|
|
@@ -93,14 +82,13 @@ var combineHandlers = (...handlers) => {
|
|
|
93
82
|
console.error("no handlers matched", methodName);
|
|
94
83
|
};
|
|
95
84
|
};
|
|
96
|
-
var clearCache = async (mode) => caches.delete(`LLS_OFFLINE_${mode}`);
|
|
97
85
|
|
|
98
86
|
// src/hooks/useOfflineWorker.ts
|
|
99
87
|
import { useCallback, useEffect, useState } from "react";
|
|
100
88
|
var offlineWorker = new Worker("/src/worker/offline-worker.js", { type: "module" });
|
|
101
89
|
var { handler, ...offlineWorkerSync } = makeSyncWorker(
|
|
102
90
|
offlineWorker,
|
|
103
|
-
["initChannel", "readZipEntry", "configure", "loadPreload", "loadBooks", "loadBook"
|
|
91
|
+
["initChannel", "readZipEntry", "configure", "loadPreload", "loadBooks", "loadBook"],
|
|
104
92
|
"app:offlineWorker"
|
|
105
93
|
);
|
|
106
94
|
var fetchWorkerPromise = new Promise(
|
|
@@ -172,7 +160,6 @@ var installWorker = async ({
|
|
|
172
160
|
setBooksLoaded();
|
|
173
161
|
};
|
|
174
162
|
var useOfflineWorker_default = ({
|
|
175
|
-
skipLoadBooks,
|
|
176
163
|
primaryOnly = false,
|
|
177
164
|
nativeReadFile,
|
|
178
165
|
nativeWriteFile,
|
|
@@ -186,7 +173,6 @@ var useOfflineWorker_default = ({
|
|
|
186
173
|
useEffect(() => {
|
|
187
174
|
const fn = async () => {
|
|
188
175
|
await installWorker({
|
|
189
|
-
skipLoadBooks,
|
|
190
176
|
primaryOnly,
|
|
191
177
|
nativeReadFile,
|
|
192
178
|
nativeWriteFile,
|
|
@@ -201,69 +187,19 @@ var useOfflineWorker_default = ({
|
|
|
201
187
|
setReady(true);
|
|
202
188
|
};
|
|
203
189
|
fn();
|
|
204
|
-
}, [
|
|
205
|
-
skipLoadBooks,
|
|
206
|
-
primaryOnly,
|
|
207
|
-
nativeReadFile,
|
|
208
|
-
nativeWriteFile,
|
|
209
|
-
nativeListZips,
|
|
210
|
-
storage,
|
|
211
|
-
zipBaseUrl,
|
|
212
|
-
checkUpdates,
|
|
213
|
-
confEnv
|
|
214
|
-
]);
|
|
190
|
+
}, [primaryOnly, nativeReadFile, nativeWriteFile, nativeListZips, storage, zipBaseUrl, checkUpdates, confEnv]);
|
|
215
191
|
const loadBook = useCallback(
|
|
216
|
-
async ({
|
|
217
|
-
|
|
218
|
-
return await offlineWorkerSync.loadBook({ id
|
|
192
|
+
async ({ id, forceRefresh }, cbk) => {
|
|
193
|
+
offlineWorkerSync.on("opfsProgress", cbk);
|
|
194
|
+
return await offlineWorkerSync.loadBook({ id, forceRefresh });
|
|
219
195
|
},
|
|
220
196
|
[]
|
|
221
197
|
);
|
|
222
|
-
const reset = useCallback(async () => {
|
|
223
|
-
await offlineWorkerSync.reset();
|
|
224
|
-
await clearCache(confEnv || "development");
|
|
225
|
-
console.debug("reset: keys:", await caches.keys());
|
|
226
|
-
}, [confEnv]);
|
|
227
198
|
return {
|
|
228
199
|
ready,
|
|
229
|
-
loadBook
|
|
230
|
-
reset
|
|
200
|
+
loadBook
|
|
231
201
|
};
|
|
232
202
|
};
|
|
233
|
-
|
|
234
|
-
// src/store/index.ts
|
|
235
|
-
import { persistReducer } from "redux-persist";
|
|
236
|
-
var persistEntitiesReducer = (entitiesReducer, CONF_ENV) => {
|
|
237
|
-
const getKey = (key) => `store:${CONF_ENV}:${key}`;
|
|
238
|
-
return persistReducer(
|
|
239
|
-
{
|
|
240
|
-
key: "entities",
|
|
241
|
-
storage: {
|
|
242
|
-
getItem: async (key) => localStorage.getItem(getKey(key)) || "{}",
|
|
243
|
-
setItem: async (key, item) => localStorage.setItem(getKey(key), item),
|
|
244
|
-
removeItem: async (key) => localStorage.removeItem(getKey(key))
|
|
245
|
-
},
|
|
246
|
-
whitelist: ["lexicalFlowers"],
|
|
247
|
-
version: 1,
|
|
248
|
-
debug: true,
|
|
249
|
-
throttle: 1e3
|
|
250
|
-
// lexicalFlowers is small, we may persist it fast
|
|
251
|
-
},
|
|
252
|
-
entitiesReducer
|
|
253
|
-
);
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// src/store/offlinePersist.tsx
|
|
257
|
-
import { persistStore } from "redux-persist";
|
|
258
|
-
import { PersistGate } from "redux-persist/integration/react";
|
|
259
|
-
import { useMemo } from "react";
|
|
260
|
-
import { jsx } from "react/jsx-runtime";
|
|
261
|
-
var OfflinePersist = ({ store, children }) => {
|
|
262
|
-
const persistor = useMemo(() => persistStore(store), [store]);
|
|
263
|
-
return /* @__PURE__ */ jsx(PersistGate, { loading: null, persistor, children });
|
|
264
|
-
};
|
|
265
203
|
export {
|
|
266
|
-
OfflinePersist,
|
|
267
|
-
persistEntitiesReducer,
|
|
268
204
|
useOfflineWorker_default as useOfflineWorker
|
|
269
205
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lls/offline",
|
|
3
|
-
"version": "24.27.0-
|
|
3
|
+
"version": "24.27.0-d7760203",
|
|
4
4
|
"description": "offline",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.js",
|
|
@@ -48,15 +48,14 @@
|
|
|
48
48
|
"nock": "14.0.5",
|
|
49
49
|
"react": "18.3.1",
|
|
50
50
|
"react-dom": "18.3.1",
|
|
51
|
-
"redux": "5.0.1",
|
|
52
51
|
"typescript": "5.8.3",
|
|
53
52
|
"vite": "7.0.7",
|
|
54
53
|
"vite-tsconfig-paths": "5.1.4",
|
|
55
54
|
"zod": "3.25.50",
|
|
56
|
-
"@lls/vitescripts": "24.27.0-
|
|
55
|
+
"@lls/vitescripts": "24.27.0-d7760203"
|
|
57
56
|
},
|
|
58
57
|
"dependencies": {
|
|
59
|
-
"
|
|
58
|
+
"fflate": "0.8.2"
|
|
60
59
|
},
|
|
61
60
|
"scripts": {
|
|
62
61
|
"start": "pnpm ladle serve",
|