@loaders.gl/zip 4.0.4 → 4.1.0-alpha.10
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/dist/dist.dev.js +434 -27
- package/dist/filesystems/zip-filesystem.d.ts.map +1 -1
- package/dist/filesystems/zip-filesystem.js.map +1 -1
- package/dist/hash-file-utility.d.ts +6 -0
- package/dist/hash-file-utility.d.ts.map +1 -1
- package/dist/hash-file-utility.js +22 -0
- package/dist/hash-file-utility.js.map +1 -1
- package/dist/index.cjs +462 -32
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/tar/header.d.ts.map +1 -1
- package/dist/lib/tar/header.js.map +1 -1
- package/dist/lib/tar/tar.d.ts.map +1 -1
- package/dist/lib/tar/tar.js.map +1 -1
- package/dist/lib/tar/types.d.ts.map +1 -1
- package/dist/lib/tar/types.js.map +1 -1
- package/dist/lib/tar/utils.d.ts.map +1 -1
- package/dist/lib/tar/utils.js.map +1 -1
- package/dist/parse-zip/cd-file-header.d.ts +18 -0
- package/dist/parse-zip/cd-file-header.d.ts.map +1 -1
- package/dist/parse-zip/cd-file-header.js +101 -1
- package/dist/parse-zip/cd-file-header.js.map +1 -1
- package/dist/parse-zip/end-of-central-directory.d.ts +19 -0
- package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -1
- package/dist/parse-zip/end-of-central-directory.js +41 -8
- package/dist/parse-zip/end-of-central-directory.js.map +1 -1
- package/dist/parse-zip/local-file-header.d.ts +16 -0
- package/dist/parse-zip/local-file-header.d.ts.map +1 -1
- package/dist/parse-zip/local-file-header.js +73 -1
- package/dist/parse-zip/local-file-header.js.map +1 -1
- package/dist/parse-zip/search-from-the-end.d.ts.map +1 -1
- package/dist/parse-zip/search-from-the-end.js.map +1 -1
- package/dist/parse-zip/zip-compozition.d.ts +8 -0
- package/dist/parse-zip/zip-compozition.d.ts.map +1 -0
- package/dist/parse-zip/zip-compozition.js +43 -0
- package/dist/parse-zip/zip-compozition.js.map +1 -0
- package/dist/parse-zip/zip64-info-generation.d.ts +24 -0
- package/dist/parse-zip/zip64-info-generation.d.ts.map +1 -0
- package/dist/parse-zip/zip64-info-generation.js +50 -0
- package/dist/parse-zip/zip64-info-generation.js.map +1 -0
- package/dist/tar-builder.d.ts.map +1 -1
- package/dist/tar-builder.js.map +1 -1
- package/dist/zip-loader.d.ts.map +1 -1
- package/dist/zip-loader.js +1 -1
- package/dist/zip-loader.js.map +1 -1
- package/dist/zip-writer.d.ts +2 -2
- package/dist/zip-writer.d.ts.map +1 -1
- package/dist/zip-writer.js +22 -7
- package/dist/zip-writer.js.map +1 -1
- package/package.json +7 -7
- package/src/filesystems/zip-filesystem.ts +2 -1
- package/src/hash-file-utility.ts +52 -2
- package/src/index.ts +8 -4
- package/src/lib/tar/header.ts +2 -1
- package/src/lib/tar/tar.ts +2 -1
- package/src/lib/tar/types.ts +2 -1
- package/src/lib/tar/utils.ts +2 -1
- package/src/parse-zip/cd-file-header.ts +185 -2
- package/src/parse-zip/end-of-central-directory.ts +99 -9
- package/src/parse-zip/local-file-header.ts +128 -2
- package/src/parse-zip/search-from-the-end.ts +2 -1
- package/src/parse-zip/zip-compozition.ts +113 -0
- package/src/parse-zip/zip64-info-generation.ts +106 -0
- package/src/tar-builder.ts +2 -1
- package/src/zip-loader.ts +2 -1
- package/src/zip-writer.ts +24 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-file-utility.d.ts","sourceRoot":"","sources":["../src/hash-file-utility.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hash-file-utility.d.ts","sourceRoot":"","sources":["../src/hash-file-utility.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,YAAY,EAGb,MAAM,0BAA0B,CAAC;AAGlC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY/E;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAejC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAMtF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MD5Hash } from '@loaders.gl/crypto';
|
|
2
|
+
import { concatenateArrayBuffers, concatenateArrayBuffersFromArray } from '@loaders.gl/loader-utils';
|
|
2
3
|
import { makeZipCDHeaderIterator } from "./parse-zip/cd-file-header.js";
|
|
3
4
|
export function parseHashTable(arrayBuffer) {
|
|
4
5
|
const dataView = new DataView(arrayBuffer);
|
|
@@ -26,4 +27,25 @@ export async function makeHashTableFromZipHeaders(fileProvider) {
|
|
|
26
27
|
}
|
|
27
28
|
return hashTable;
|
|
28
29
|
}
|
|
30
|
+
export async function composeHashFile(fileProvider) {
|
|
31
|
+
const hashArray = await makeHashTableFromZipHeaders(fileProvider);
|
|
32
|
+
const bufferArray = Object.entries(hashArray).map(_ref => {
|
|
33
|
+
let [key, value] = _ref;
|
|
34
|
+
return concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value));
|
|
35
|
+
}).sort(compareHashes);
|
|
36
|
+
return concatenateArrayBuffersFromArray(bufferArray);
|
|
37
|
+
}
|
|
38
|
+
function compareHashes(arrA, arrB) {
|
|
39
|
+
const a = new BigUint64Array(arrA);
|
|
40
|
+
const b = new BigUint64Array(arrB);
|
|
41
|
+
return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
|
|
42
|
+
}
|
|
43
|
+
function hexStringToBuffer(str) {
|
|
44
|
+
var _str$match;
|
|
45
|
+
const byteArray = (_str$match = str.match(/../g)) === null || _str$match === void 0 ? void 0 : _str$match.map(h => parseInt(h, 16));
|
|
46
|
+
return new Uint8Array(byteArray !== null && byteArray !== void 0 ? byteArray : new Array(16)).buffer;
|
|
47
|
+
}
|
|
48
|
+
function bigintToBuffer(n) {
|
|
49
|
+
return new BigUint64Array([n]).buffer;
|
|
50
|
+
}
|
|
29
51
|
//# sourceMappingURL=hash-file-utility.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-file-utility.js","names":["MD5Hash","makeZipCDHeaderIterator","parseHashTable","arrayBuffer","dataView","DataView","hashMap","i","byteLength","offset","getBigUint64","hash","bufferToHex","buffer","start","length","Uint8Array","map","x","toString","padStart","join","makeHashTableFromZipHeaders","fileProvider","zipCDIterator","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset"],"sources":["../src/hash-file-utility.ts"],"sourcesContent":["// loaders.gl
|
|
1
|
+
{"version":3,"file":"hash-file-utility.js","names":["MD5Hash","concatenateArrayBuffers","concatenateArrayBuffersFromArray","makeZipCDHeaderIterator","parseHashTable","arrayBuffer","dataView","DataView","hashMap","i","byteLength","offset","getBigUint64","hash","bufferToHex","buffer","start","length","Uint8Array","map","x","toString","padStart","join","makeHashTableFromZipHeaders","fileProvider","zipCDIterator","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset","composeHashFile","hashArray","bufferArray","Object","entries","_ref","key","value","hexStringToBuffer","bigintToBuffer","sort","compareHashes","arrA","arrB","a","BigUint64Array","b","Number","str","_str$match","byteArray","match","h","parseInt","Array","n"],"sources":["../src/hash-file-utility.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {MD5Hash} from '@loaders.gl/crypto';\nimport {\n FileProvider,\n concatenateArrayBuffers,\n concatenateArrayBuffersFromArray\n} from '@loaders.gl/loader-utils';\nimport {makeZipCDHeaderIterator} from './parse-zip/cd-file-header';\n\n/**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param arrayBuffer - buffer containing hash file\n * @returns Map containing hash and offset\n */\nexport function parseHashTable(arrayBuffer: ArrayBuffer): Record<string, bigint> {\n const dataView = new DataView(arrayBuffer);\n\n const hashMap: Record<string, bigint> = {};\n\n for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {\n const offset = dataView.getBigUint64(i + 16, true);\n const hash = bufferToHex(arrayBuffer, i, 16);\n hashMap[hash] = offset;\n }\n\n return hashMap;\n}\n\nfunction bufferToHex(buffer: ArrayBuffer, start: number, length: number): string {\n // buffer is an ArrayBuffer\n return [...new Uint8Array(buffer, start, length)]\n .map((x) => x.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * generates hash info from zip files \"central directory\"\n * @param fileProvider - provider of the archive\n * @returns ready to use hash info\n */\nexport async function makeHashTableFromZipHeaders(\n fileProvider: FileProvider\n): Promise<Record<string, bigint>> {\n const zipCDIterator = makeZipCDHeaderIterator(fileProvider);\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashTable: Record<string, bigint> = {};\n\n for await (const cdHeader of zipCDIterator) {\n const filename = cdHeader.fileName.split('\\\\').join('/').toLocaleLowerCase();\n const arrayBuffer = textEncoder.encode(filename).buffer;\n const md5 = await md5Hash.hash(arrayBuffer, 'hex');\n hashTable[md5] = cdHeader.localHeaderOffset;\n }\n\n return hashTable;\n}\n\n/**\n * creates hash file that later can be added to the SLPK archive\n * @param fileProvider SLPK archive where we need to add hash file\n * @returns ArrayBuffer containing hash file\n */\nexport async function composeHashFile(fileProvider: FileProvider): Promise<ArrayBuffer> {\n const hashArray = await makeHashTableFromZipHeaders(fileProvider);\n const bufferArray = Object.entries(hashArray)\n .map(([key, value]) => concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value)))\n .sort(compareHashes);\n return concatenateArrayBuffersFromArray(bufferArray);\n}\n\n/**\n * Function to compare md5 hashes according to https://github.com/Esri/i3s-spec/blob/master/docs/2.0/slpk_hashtable.pcsl.md\n * @param arrA first hash to compare\n * @param arrB second hash to compare\n * @returns 0 if equal, negative number if a<b, pozitive if a>b\n */\nfunction compareHashes(arrA: ArrayBuffer, arrB: ArrayBuffer): number {\n const a = new BigUint64Array(arrA);\n const b = new BigUint64Array(arrB);\n\n return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);\n}\n\n/**\n * converts hex string to buffer\n * @param str hex string to convert\n * @returns conversion result\n */\nfunction hexStringToBuffer(str: string): ArrayBuffer {\n const byteArray = str.match(/../g)?.map((h) => parseInt(h, 16));\n return new Uint8Array(byteArray ?? new Array(16)).buffer;\n}\n\n/**\n * converts bigint to buffer\n * @param n bigint to convert\n * @returns convertion result\n */\nfunction bigintToBuffer(n: bigint): ArrayBuffer {\n return new BigUint64Array([n]).buffer;\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -30,12 +30,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
CD_HEADER_SIGNATURE: () => signature2,
|
|
33
34
|
TarBuilder: () => TarBuilder,
|
|
34
35
|
ZipFileSystem: () => ZipFileSystem,
|
|
35
36
|
ZipLoader: () => ZipLoader,
|
|
36
37
|
ZipWriter: () => ZipWriter,
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
addOneFile: () => addOneFile,
|
|
39
|
+
composeHashFile: () => composeHashFile,
|
|
40
|
+
generateCDHeader: () => generateCDHeader,
|
|
41
|
+
generateLocalHeader: () => generateLocalHeader,
|
|
42
|
+
localHeaderSignature: () => signature3,
|
|
39
43
|
makeHashTableFromZipHeaders: () => makeHashTableFromZipHeaders,
|
|
40
44
|
makeZipCDHeaderIterator: () => makeZipCDHeaderIterator,
|
|
41
45
|
parseEoCDRecord: () => parseEoCDRecord,
|
|
@@ -93,27 +97,41 @@ async function loadZipEntry(jsZip, subFilename, options = {}) {
|
|
|
93
97
|
|
|
94
98
|
// src/zip-writer.ts
|
|
95
99
|
var import_jszip2 = __toESM(require("jszip"), 1);
|
|
100
|
+
var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
|
|
96
101
|
var ZipWriter = {
|
|
97
102
|
name: "Zip Archive",
|
|
103
|
+
id: "zip",
|
|
104
|
+
module: "zip",
|
|
105
|
+
version: VERSION2,
|
|
98
106
|
extensions: ["zip"],
|
|
99
107
|
category: "archive",
|
|
100
108
|
mimeTypes: ["application/zip"],
|
|
101
|
-
|
|
109
|
+
options: {
|
|
110
|
+
zip: {
|
|
111
|
+
onUpdate: () => {
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
jszip: {}
|
|
115
|
+
},
|
|
102
116
|
encode: encodeZipAsync
|
|
103
117
|
};
|
|
104
118
|
async function encodeZipAsync(fileMap, options = {}) {
|
|
119
|
+
var _a;
|
|
105
120
|
const jsZip = new import_jszip2.default();
|
|
106
121
|
for (const subFileName in fileMap) {
|
|
107
122
|
const subFileData = fileMap[subFileName];
|
|
108
123
|
jsZip.file(subFileName, subFileData, (options == null ? void 0 : options.jszip) || {});
|
|
109
124
|
}
|
|
110
|
-
const
|
|
111
|
-
const {
|
|
112
|
-
} } = options;
|
|
125
|
+
const zipOptions = { ...ZipWriter.options.zip, ...options == null ? void 0 : options.zip };
|
|
126
|
+
const jszipOptions = { ...(_a = ZipWriter.options) == null ? void 0 : _a.jszip, ...options.jszip };
|
|
113
127
|
try {
|
|
114
|
-
return await jsZip.generateAsync(
|
|
128
|
+
return await jsZip.generateAsync(
|
|
129
|
+
{ ...jszipOptions, type: "arraybuffer" },
|
|
130
|
+
// generate an arraybuffer
|
|
131
|
+
zipOptions.onUpdate
|
|
132
|
+
);
|
|
115
133
|
} catch (error) {
|
|
116
|
-
options.log.error(`Unable to
|
|
134
|
+
options.log.error(`Unable to encode zip archive: ${error}`);
|
|
117
135
|
throw error;
|
|
118
136
|
}
|
|
119
137
|
}
|
|
@@ -334,10 +352,10 @@ var TarBuilder = class {
|
|
|
334
352
|
};
|
|
335
353
|
|
|
336
354
|
// src/parse-zip/cd-file-header.ts
|
|
337
|
-
var
|
|
355
|
+
var import_loader_utils3 = require("@loaders.gl/loader-utils");
|
|
338
356
|
|
|
339
357
|
// src/parse-zip/end-of-central-directory.ts
|
|
340
|
-
var
|
|
358
|
+
var import_loader_utils2 = require("@loaders.gl/loader-utils");
|
|
341
359
|
|
|
342
360
|
// src/parse-zip/search-from-the-end.ts
|
|
343
361
|
var searchFromTheEnd = async (file, target) => {
|
|
@@ -361,40 +379,143 @@ var searchFromTheEnd = async (file, target) => {
|
|
|
361
379
|
return targetOffset;
|
|
362
380
|
};
|
|
363
381
|
|
|
382
|
+
// src/parse-zip/zip64-info-generation.ts
|
|
383
|
+
var import_loader_utils = require("@loaders.gl/loader-utils");
|
|
384
|
+
var signature = new Uint8Array([1, 0]);
|
|
385
|
+
function createZip64Info(options) {
|
|
386
|
+
const optionsToUse = {
|
|
387
|
+
...options,
|
|
388
|
+
zip64Length: (options.offset ? 1 : 0) * 8 + (options.size ? 1 : 0) * 16
|
|
389
|
+
};
|
|
390
|
+
const arraysToConcat = [];
|
|
391
|
+
for (const field of ZIP64_FIELDS) {
|
|
392
|
+
if (!optionsToUse[field.name ?? ""] && !field.default) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const newValue = new DataView(new ArrayBuffer(field.size));
|
|
396
|
+
NUMBER_SETTERS[field.size](newValue, 0, optionsToUse[field.name ?? ""] ?? field.default);
|
|
397
|
+
arraysToConcat.push(newValue.buffer);
|
|
398
|
+
}
|
|
399
|
+
return (0, import_loader_utils.concatenateArrayBuffers)(...arraysToConcat);
|
|
400
|
+
}
|
|
401
|
+
function setFieldToNumber(header, fieldSize, fieldOffset, value) {
|
|
402
|
+
NUMBER_SETTERS[fieldSize](header, Number(fieldOffset), value);
|
|
403
|
+
}
|
|
404
|
+
var NUMBER_SETTERS = {
|
|
405
|
+
2: (header, offset, value) => {
|
|
406
|
+
header.setUint16(offset, Number(value), true);
|
|
407
|
+
},
|
|
408
|
+
4: (header, offset, value) => {
|
|
409
|
+
header.setUint32(offset, Number(value), true);
|
|
410
|
+
},
|
|
411
|
+
8: (header, offset, value) => {
|
|
412
|
+
header.setBigUint64(offset, BigInt(value), true);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
var ZIP64_FIELDS = [
|
|
416
|
+
// Header ID 0x0001
|
|
417
|
+
{
|
|
418
|
+
size: 2,
|
|
419
|
+
default: new DataView(signature.buffer).getUint16(0, true)
|
|
420
|
+
},
|
|
421
|
+
// Size of the extra field chunk (8, 16, 24 or 28)
|
|
422
|
+
{
|
|
423
|
+
size: 2,
|
|
424
|
+
name: "zip64Length"
|
|
425
|
+
},
|
|
426
|
+
// Original uncompressed file size
|
|
427
|
+
{
|
|
428
|
+
size: 8,
|
|
429
|
+
name: "size"
|
|
430
|
+
},
|
|
431
|
+
// Size of compressed data
|
|
432
|
+
{
|
|
433
|
+
size: 8,
|
|
434
|
+
name: "size"
|
|
435
|
+
},
|
|
436
|
+
// Offset of local header record
|
|
437
|
+
{
|
|
438
|
+
size: 8,
|
|
439
|
+
name: "offset"
|
|
440
|
+
}
|
|
441
|
+
];
|
|
442
|
+
|
|
364
443
|
// src/parse-zip/end-of-central-directory.ts
|
|
365
444
|
var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
|
|
366
445
|
var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
|
|
367
446
|
var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
|
|
368
447
|
var CD_RECORDS_NUMBER_OFFSET = 8n;
|
|
448
|
+
var CD_RECORDS_NUMBER_ON_DISC_OFFSET = 10n;
|
|
449
|
+
var CD_CD_BYTE_SIZE_OFFSET = 12n;
|
|
369
450
|
var CD_START_OFFSET_OFFSET = 16n;
|
|
370
451
|
var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
|
|
371
452
|
var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
|
|
453
|
+
var ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET = 32n;
|
|
454
|
+
var ZIP64_CD_CD_BYTE_SIZE_OFFSET = 40n;
|
|
372
455
|
var ZIP64_CD_START_OFFSET_OFFSET = 48n;
|
|
373
456
|
var parseEoCDRecord = async (file) => {
|
|
374
457
|
const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
|
|
375
458
|
let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
|
|
376
459
|
let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
const zip64EoCDOffset = await file.getBigUint64(
|
|
460
|
+
let zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
|
|
461
|
+
let zip64EoCDOffset = 0n;
|
|
462
|
+
const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
|
|
463
|
+
if ((0, import_loader_utils2.compareArrayBuffers)(magicBytes, zip64EoCDLocatorSignature)) {
|
|
464
|
+
zip64EoCDOffset = await file.getBigUint64(
|
|
384
465
|
zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
|
|
385
466
|
);
|
|
386
467
|
const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
|
|
387
|
-
if (!(0,
|
|
468
|
+
if (!(0, import_loader_utils2.compareArrayBuffers)(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
|
|
388
469
|
throw new Error("zip64 EoCD not found");
|
|
389
470
|
}
|
|
390
471
|
cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
|
|
391
472
|
cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
|
|
473
|
+
} else {
|
|
474
|
+
zip64EoCDLocatorOffset = 0n;
|
|
392
475
|
}
|
|
393
476
|
return {
|
|
394
477
|
cdRecordsNumber,
|
|
395
|
-
cdStartOffset
|
|
478
|
+
cdStartOffset,
|
|
479
|
+
offsets: {
|
|
480
|
+
zip64EoCDOffset,
|
|
481
|
+
zip64EoCDLocatorOffset,
|
|
482
|
+
zipEoCDOffset
|
|
483
|
+
}
|
|
396
484
|
};
|
|
397
485
|
};
|
|
486
|
+
async function updateEoCD(eocdBody, oldEoCDOffsets, newCDStartOffset, eocdStartOffset, newCDRecordsNumber) {
|
|
487
|
+
const eocd = new DataView(eocdBody);
|
|
488
|
+
const classicEoCDOffset = oldEoCDOffsets.zip64EoCDOffset ? oldEoCDOffsets.zipEoCDOffset - oldEoCDOffsets.zip64EoCDOffset : 0n;
|
|
489
|
+
if (Number(newCDRecordsNumber) <= 65535) {
|
|
490
|
+
setFieldToNumber(eocd, 2, classicEoCDOffset + CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
|
|
491
|
+
setFieldToNumber(
|
|
492
|
+
eocd,
|
|
493
|
+
2,
|
|
494
|
+
classicEoCDOffset + CD_RECORDS_NUMBER_ON_DISC_OFFSET,
|
|
495
|
+
newCDRecordsNumber
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
if (eocdStartOffset - newCDStartOffset <= 4294967295) {
|
|
499
|
+
setFieldToNumber(
|
|
500
|
+
eocd,
|
|
501
|
+
4,
|
|
502
|
+
classicEoCDOffset + CD_CD_BYTE_SIZE_OFFSET,
|
|
503
|
+
eocdStartOffset - newCDStartOffset
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
if (newCDStartOffset < 4294967295) {
|
|
507
|
+
setFieldToNumber(eocd, 4, classicEoCDOffset + CD_START_OFFSET_OFFSET, newCDStartOffset);
|
|
508
|
+
}
|
|
509
|
+
if (oldEoCDOffsets.zip64EoCDLocatorOffset && oldEoCDOffsets.zip64EoCDOffset) {
|
|
510
|
+
const locatorOffset = oldEoCDOffsets.zip64EoCDLocatorOffset - oldEoCDOffsets.zip64EoCDOffset;
|
|
511
|
+
setFieldToNumber(eocd, 8, locatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET, eocdStartOffset);
|
|
512
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_START_OFFSET_OFFSET, newCDStartOffset);
|
|
513
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
|
|
514
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET, newCDRecordsNumber);
|
|
515
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_CD_BYTE_SIZE_OFFSET, eocdStartOffset - newCDStartOffset);
|
|
516
|
+
}
|
|
517
|
+
return new Uint8Array(eocd.buffer);
|
|
518
|
+
}
|
|
398
519
|
|
|
399
520
|
// src/parse-zip/cd-file-header.ts
|
|
400
521
|
var CD_COMPRESSED_SIZE_OFFSET = 20n;
|
|
@@ -404,10 +525,10 @@ var CD_EXTRA_FIELD_LENGTH_OFFSET = 30n;
|
|
|
404
525
|
var CD_START_DISK_OFFSET = 32n;
|
|
405
526
|
var CD_LOCAL_HEADER_OFFSET_OFFSET = 42n;
|
|
406
527
|
var CD_FILE_NAME_OFFSET = 46n;
|
|
407
|
-
var
|
|
528
|
+
var signature2 = new Uint8Array([80, 75, 1, 2]);
|
|
408
529
|
var parseZipCDFileHeader = async (headerOffset, file) => {
|
|
409
530
|
const magicBytes = await file.slice(headerOffset, headerOffset + 4n);
|
|
410
|
-
if (!(0,
|
|
531
|
+
if (!(0, import_loader_utils3.compareArrayBuffers)(magicBytes, signature2.buffer)) {
|
|
411
532
|
return null;
|
|
412
533
|
}
|
|
413
534
|
const compressedSize = BigInt(await file.getUint32(headerOffset + CD_COMPRESSED_SIZE_OFFSET));
|
|
@@ -489,19 +610,157 @@ var findExpectedData = (zip64data) => {
|
|
|
489
610
|
}
|
|
490
611
|
return zip64dataList;
|
|
491
612
|
};
|
|
613
|
+
function generateCDHeader(options) {
|
|
614
|
+
const optionsToUse = {
|
|
615
|
+
...options,
|
|
616
|
+
fnlength: options.fileName.length,
|
|
617
|
+
extraLength: 0
|
|
618
|
+
};
|
|
619
|
+
let zip64header = new ArrayBuffer(0);
|
|
620
|
+
const optionsToZip64 = {};
|
|
621
|
+
if (optionsToUse.offset >= 4294967295) {
|
|
622
|
+
optionsToZip64.offset = optionsToUse.offset;
|
|
623
|
+
optionsToUse.offset = BigInt(4294967295);
|
|
624
|
+
}
|
|
625
|
+
if (optionsToUse.length >= 4294967295) {
|
|
626
|
+
optionsToZip64.size = optionsToUse.length;
|
|
627
|
+
optionsToUse.length = 4294967295;
|
|
628
|
+
}
|
|
629
|
+
if (Object.keys(optionsToZip64).length) {
|
|
630
|
+
zip64header = createZip64Info(optionsToZip64);
|
|
631
|
+
optionsToUse.extraLength = zip64header.byteLength;
|
|
632
|
+
}
|
|
633
|
+
const header = new DataView(new ArrayBuffer(Number(CD_FILE_NAME_OFFSET)));
|
|
634
|
+
for (const field of ZIP_HEADER_FIELDS) {
|
|
635
|
+
setFieldToNumber(
|
|
636
|
+
header,
|
|
637
|
+
field.size,
|
|
638
|
+
field.offset,
|
|
639
|
+
optionsToUse[field.name ?? ""] ?? field.default ?? 0
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
const encodedName = new TextEncoder().encode(optionsToUse.fileName);
|
|
643
|
+
const resHeader = (0, import_loader_utils3.concatenateArrayBuffers)(header.buffer, encodedName, zip64header);
|
|
644
|
+
return resHeader;
|
|
645
|
+
}
|
|
646
|
+
var ZIP_HEADER_FIELDS = [
|
|
647
|
+
// Central directory file header signature = 0x02014b50
|
|
648
|
+
{
|
|
649
|
+
offset: 0,
|
|
650
|
+
size: 4,
|
|
651
|
+
default: new DataView(signature2.buffer).getUint32(0, true)
|
|
652
|
+
},
|
|
653
|
+
// Version made by
|
|
654
|
+
{
|
|
655
|
+
offset: 4,
|
|
656
|
+
size: 2,
|
|
657
|
+
default: 45
|
|
658
|
+
},
|
|
659
|
+
// Version needed to extract (minimum)
|
|
660
|
+
{
|
|
661
|
+
offset: 6,
|
|
662
|
+
size: 2,
|
|
663
|
+
default: 45
|
|
664
|
+
},
|
|
665
|
+
// General purpose bit flag
|
|
666
|
+
{
|
|
667
|
+
offset: 8,
|
|
668
|
+
size: 2,
|
|
669
|
+
default: 0
|
|
670
|
+
},
|
|
671
|
+
// Compression method
|
|
672
|
+
{
|
|
673
|
+
offset: 10,
|
|
674
|
+
size: 2,
|
|
675
|
+
default: 0
|
|
676
|
+
},
|
|
677
|
+
// File last modification time
|
|
678
|
+
{
|
|
679
|
+
offset: 12,
|
|
680
|
+
size: 2,
|
|
681
|
+
default: 0
|
|
682
|
+
},
|
|
683
|
+
// File last modification date
|
|
684
|
+
{
|
|
685
|
+
offset: 14,
|
|
686
|
+
size: 2,
|
|
687
|
+
default: 0
|
|
688
|
+
},
|
|
689
|
+
// CRC-32 of uncompressed data
|
|
690
|
+
{
|
|
691
|
+
offset: 16,
|
|
692
|
+
size: 4,
|
|
693
|
+
name: "crc32"
|
|
694
|
+
},
|
|
695
|
+
// Compressed size (or 0xffffffff for ZIP64)
|
|
696
|
+
{
|
|
697
|
+
offset: 20,
|
|
698
|
+
size: 4,
|
|
699
|
+
name: "length"
|
|
700
|
+
},
|
|
701
|
+
// Uncompressed size (or 0xffffffff for ZIP64)
|
|
702
|
+
{
|
|
703
|
+
offset: 24,
|
|
704
|
+
size: 4,
|
|
705
|
+
name: "length"
|
|
706
|
+
},
|
|
707
|
+
// File name length (n)
|
|
708
|
+
{
|
|
709
|
+
offset: 28,
|
|
710
|
+
size: 2,
|
|
711
|
+
name: "fnlength"
|
|
712
|
+
},
|
|
713
|
+
// Extra field length (m)
|
|
714
|
+
{
|
|
715
|
+
offset: 30,
|
|
716
|
+
size: 2,
|
|
717
|
+
default: 0,
|
|
718
|
+
name: "extraLength"
|
|
719
|
+
},
|
|
720
|
+
// File comment length (k)
|
|
721
|
+
{
|
|
722
|
+
offset: 32,
|
|
723
|
+
size: 2,
|
|
724
|
+
default: 0
|
|
725
|
+
},
|
|
726
|
+
// Disk number where file starts (or 0xffff for ZIP64)
|
|
727
|
+
{
|
|
728
|
+
offset: 34,
|
|
729
|
+
size: 2,
|
|
730
|
+
default: 0
|
|
731
|
+
},
|
|
732
|
+
// Internal file attributes
|
|
733
|
+
{
|
|
734
|
+
offset: 36,
|
|
735
|
+
size: 2,
|
|
736
|
+
default: 0
|
|
737
|
+
},
|
|
738
|
+
// External file attributes
|
|
739
|
+
{
|
|
740
|
+
offset: 38,
|
|
741
|
+
size: 4,
|
|
742
|
+
default: 0
|
|
743
|
+
},
|
|
744
|
+
// Relative offset of local file header
|
|
745
|
+
{
|
|
746
|
+
offset: 42,
|
|
747
|
+
size: 4,
|
|
748
|
+
name: "offset"
|
|
749
|
+
}
|
|
750
|
+
];
|
|
492
751
|
|
|
493
752
|
// src/parse-zip/local-file-header.ts
|
|
494
|
-
var
|
|
753
|
+
var import_loader_utils4 = require("@loaders.gl/loader-utils");
|
|
495
754
|
var COMPRESSION_METHOD_OFFSET = 8n;
|
|
496
755
|
var COMPRESSED_SIZE_OFFSET = 18n;
|
|
497
756
|
var UNCOMPRESSED_SIZE_OFFSET = 22n;
|
|
498
757
|
var FILE_NAME_LENGTH_OFFSET = 26n;
|
|
499
758
|
var EXTRA_FIELD_LENGTH_OFFSET = 28n;
|
|
500
759
|
var FILE_NAME_OFFSET = 30n;
|
|
501
|
-
var
|
|
760
|
+
var signature3 = new Uint8Array([80, 75, 3, 4]);
|
|
502
761
|
var parseZipLocalFileHeader = async (headerOffset, buffer) => {
|
|
503
762
|
const magicBytes = await buffer.slice(headerOffset, headerOffset + 4n);
|
|
504
|
-
if (!(0,
|
|
763
|
+
if (!(0, import_loader_utils4.compareArrayBuffers)(magicBytes, signature3)) {
|
|
505
764
|
return null;
|
|
506
765
|
}
|
|
507
766
|
const fileNameLength = await buffer.getUint16(headerOffset + FILE_NAME_LENGTH_OFFSET);
|
|
@@ -538,9 +797,162 @@ var parseZipLocalFileHeader = async (headerOffset, buffer) => {
|
|
|
538
797
|
compressionMethod
|
|
539
798
|
};
|
|
540
799
|
};
|
|
800
|
+
function generateLocalHeader(options) {
|
|
801
|
+
const optionsToUse = {
|
|
802
|
+
...options,
|
|
803
|
+
extraLength: 0,
|
|
804
|
+
fnlength: options.fileName.length
|
|
805
|
+
};
|
|
806
|
+
let zip64header = new ArrayBuffer(0);
|
|
807
|
+
const optionsToZip64 = {};
|
|
808
|
+
if (optionsToUse.length >= 4294967295) {
|
|
809
|
+
optionsToZip64.size = optionsToUse.length;
|
|
810
|
+
optionsToUse.length = 4294967295;
|
|
811
|
+
}
|
|
812
|
+
if (Object.keys(optionsToZip64).length) {
|
|
813
|
+
zip64header = createZip64Info(optionsToZip64);
|
|
814
|
+
optionsToUse.extraLength = zip64header.byteLength;
|
|
815
|
+
}
|
|
816
|
+
const header = new DataView(new ArrayBuffer(Number(FILE_NAME_OFFSET)));
|
|
817
|
+
for (const field of ZIP_HEADER_FIELDS2) {
|
|
818
|
+
setFieldToNumber(
|
|
819
|
+
header,
|
|
820
|
+
field.size,
|
|
821
|
+
field.offset,
|
|
822
|
+
optionsToUse[field.name ?? ""] ?? field.default ?? 0
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
const encodedName = new TextEncoder().encode(optionsToUse.fileName);
|
|
826
|
+
const resHeader = (0, import_loader_utils4.concatenateArrayBuffers)(header.buffer, encodedName, zip64header);
|
|
827
|
+
return resHeader;
|
|
828
|
+
}
|
|
829
|
+
var ZIP_HEADER_FIELDS2 = [
|
|
830
|
+
// Local file header signature = 0x04034b50
|
|
831
|
+
{
|
|
832
|
+
offset: 0,
|
|
833
|
+
size: 4,
|
|
834
|
+
default: new DataView(signature3.buffer).getUint32(0, true)
|
|
835
|
+
},
|
|
836
|
+
// Version needed to extract (minimum)
|
|
837
|
+
{
|
|
838
|
+
offset: 4,
|
|
839
|
+
size: 2,
|
|
840
|
+
default: 45
|
|
841
|
+
},
|
|
842
|
+
// General purpose bit flag
|
|
843
|
+
{
|
|
844
|
+
offset: 6,
|
|
845
|
+
size: 2,
|
|
846
|
+
default: 0
|
|
847
|
+
},
|
|
848
|
+
// Compression method
|
|
849
|
+
{
|
|
850
|
+
offset: 8,
|
|
851
|
+
size: 2,
|
|
852
|
+
default: 0
|
|
853
|
+
},
|
|
854
|
+
// File last modification time
|
|
855
|
+
{
|
|
856
|
+
offset: 10,
|
|
857
|
+
size: 2,
|
|
858
|
+
default: 0
|
|
859
|
+
},
|
|
860
|
+
// File last modification date
|
|
861
|
+
{
|
|
862
|
+
offset: 12,
|
|
863
|
+
size: 2,
|
|
864
|
+
default: 0
|
|
865
|
+
},
|
|
866
|
+
// CRC-32 of uncompressed data
|
|
867
|
+
{
|
|
868
|
+
offset: 14,
|
|
869
|
+
size: 4,
|
|
870
|
+
name: "crc32"
|
|
871
|
+
},
|
|
872
|
+
// Compressed size (or 0xffffffff for ZIP64)
|
|
873
|
+
{
|
|
874
|
+
offset: 18,
|
|
875
|
+
size: 4,
|
|
876
|
+
name: "length"
|
|
877
|
+
},
|
|
878
|
+
// Uncompressed size (or 0xffffffff for ZIP64)
|
|
879
|
+
{
|
|
880
|
+
offset: 22,
|
|
881
|
+
size: 4,
|
|
882
|
+
name: "length"
|
|
883
|
+
},
|
|
884
|
+
// File name length (n)
|
|
885
|
+
{
|
|
886
|
+
offset: 26,
|
|
887
|
+
size: 2,
|
|
888
|
+
name: "fnlength"
|
|
889
|
+
},
|
|
890
|
+
// Extra field length (m)
|
|
891
|
+
{
|
|
892
|
+
offset: 28,
|
|
893
|
+
size: 2,
|
|
894
|
+
default: 0,
|
|
895
|
+
name: "extraLength"
|
|
896
|
+
}
|
|
897
|
+
];
|
|
541
898
|
|
|
542
|
-
// src/
|
|
899
|
+
// src/parse-zip/zip-compozition.ts
|
|
900
|
+
var import_loader_utils5 = require("@loaders.gl/loader-utils");
|
|
543
901
|
var import_crypto = require("@loaders.gl/crypto");
|
|
902
|
+
async function cutTheTailOff(provider) {
|
|
903
|
+
const oldEoCDinfo = await parseEoCDRecord(provider);
|
|
904
|
+
const oldCDStartOffset = oldEoCDinfo.cdStartOffset;
|
|
905
|
+
const oldCDLength = Number(
|
|
906
|
+
oldEoCDinfo.offsets.zip64EoCDOffset ? oldEoCDinfo.offsets.zip64EoCDOffset - oldCDStartOffset : oldEoCDinfo.offsets.zipEoCDOffset - oldCDStartOffset
|
|
907
|
+
);
|
|
908
|
+
const zipEnding = await provider.slice(oldCDStartOffset, provider.length);
|
|
909
|
+
await provider.truncate(Number(oldCDStartOffset));
|
|
910
|
+
const oldCDBody = zipEnding.slice(0, oldCDLength);
|
|
911
|
+
const eocdBody = zipEnding.slice(oldCDLength, zipEnding.byteLength);
|
|
912
|
+
return [oldCDBody, eocdBody, oldEoCDinfo];
|
|
913
|
+
}
|
|
914
|
+
async function generateFileHeaders(fileName, fileToAdd, localFileHeaderOffset) {
|
|
915
|
+
const newFileCRC322 = parseInt(await new import_crypto.CRC32Hash().hash(fileToAdd, "hex"), 16);
|
|
916
|
+
const newFileLocalHeader = generateLocalHeader({
|
|
917
|
+
crc32: newFileCRC322,
|
|
918
|
+
fileName,
|
|
919
|
+
length: fileToAdd.byteLength
|
|
920
|
+
});
|
|
921
|
+
const newFileCDHeader = generateCDHeader({
|
|
922
|
+
crc32: newFileCRC322,
|
|
923
|
+
fileName,
|
|
924
|
+
offset: localFileHeaderOffset,
|
|
925
|
+
length: fileToAdd.byteLength
|
|
926
|
+
});
|
|
927
|
+
return [
|
|
928
|
+
new Uint8Array((0, import_loader_utils5.concatenateArrayBuffers)(newFileLocalHeader, fileToAdd)),
|
|
929
|
+
new Uint8Array(newFileCDHeader)
|
|
930
|
+
];
|
|
931
|
+
}
|
|
932
|
+
async function addOneFile(zipUrl, fileToAdd, fileName) {
|
|
933
|
+
const provider = new import_loader_utils5.FileHandleFile(zipUrl, true);
|
|
934
|
+
const [oldCDBody, eocdBody, oldEoCDinfo] = await cutTheTailOff(provider);
|
|
935
|
+
const newFileOffset = provider.length;
|
|
936
|
+
const [localPart, cdHeaderPart] = await generateFileHeaders(fileName, fileToAdd, newFileOffset);
|
|
937
|
+
await provider.append(localPart);
|
|
938
|
+
const newCDBody = (0, import_loader_utils5.concatenateArrayBuffers)(oldCDBody, cdHeaderPart);
|
|
939
|
+
const newCDStartOffset = provider.length;
|
|
940
|
+
await provider.append(new Uint8Array(newCDBody));
|
|
941
|
+
const eocdOffset = provider.length;
|
|
942
|
+
await provider.append(
|
|
943
|
+
await updateEoCD(
|
|
944
|
+
eocdBody,
|
|
945
|
+
oldEoCDinfo.offsets,
|
|
946
|
+
newCDStartOffset,
|
|
947
|
+
eocdOffset,
|
|
948
|
+
oldEoCDinfo.cdRecordsNumber + 1n
|
|
949
|
+
)
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// src/hash-file-utility.ts
|
|
954
|
+
var import_crypto2 = require("@loaders.gl/crypto");
|
|
955
|
+
var import_loader_utils6 = require("@loaders.gl/loader-utils");
|
|
544
956
|
function parseHashTable(arrayBuffer) {
|
|
545
957
|
const dataView = new DataView(arrayBuffer);
|
|
546
958
|
const hashMap = {};
|
|
@@ -556,7 +968,7 @@ function bufferToHex(buffer, start, length) {
|
|
|
556
968
|
}
|
|
557
969
|
async function makeHashTableFromZipHeaders(fileProvider) {
|
|
558
970
|
const zipCDIterator = makeZipCDHeaderIterator(fileProvider);
|
|
559
|
-
const md5Hash = new
|
|
971
|
+
const md5Hash = new import_crypto2.MD5Hash();
|
|
560
972
|
const textEncoder = new TextEncoder();
|
|
561
973
|
const hashTable = {};
|
|
562
974
|
for await (const cdHeader of zipCDIterator) {
|
|
@@ -567,11 +979,29 @@ async function makeHashTableFromZipHeaders(fileProvider) {
|
|
|
567
979
|
}
|
|
568
980
|
return hashTable;
|
|
569
981
|
}
|
|
982
|
+
async function composeHashFile(fileProvider) {
|
|
983
|
+
const hashArray = await makeHashTableFromZipHeaders(fileProvider);
|
|
984
|
+
const bufferArray = Object.entries(hashArray).map(([key, value]) => (0, import_loader_utils6.concatenateArrayBuffers)(hexStringToBuffer(key), bigintToBuffer(value))).sort(compareHashes);
|
|
985
|
+
return (0, import_loader_utils6.concatenateArrayBuffersFromArray)(bufferArray);
|
|
986
|
+
}
|
|
987
|
+
function compareHashes(arrA, arrB) {
|
|
988
|
+
const a = new BigUint64Array(arrA);
|
|
989
|
+
const b = new BigUint64Array(arrB);
|
|
990
|
+
return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
|
|
991
|
+
}
|
|
992
|
+
function hexStringToBuffer(str) {
|
|
993
|
+
var _a;
|
|
994
|
+
const byteArray = (_a = str.match(/../g)) == null ? void 0 : _a.map((h) => parseInt(h, 16));
|
|
995
|
+
return new Uint8Array(byteArray ?? new Array(16)).buffer;
|
|
996
|
+
}
|
|
997
|
+
function bigintToBuffer(n) {
|
|
998
|
+
return new BigUint64Array([n]).buffer;
|
|
999
|
+
}
|
|
570
1000
|
|
|
571
1001
|
// src/filesystems/zip-filesystem.ts
|
|
572
|
-
var
|
|
573
|
-
var
|
|
574
|
-
var
|
|
1002
|
+
var import_loader_utils7 = require("@loaders.gl/loader-utils");
|
|
1003
|
+
var import_loader_utils8 = require("@loaders.gl/loader-utils");
|
|
1004
|
+
var import_loader_utils9 = require("@loaders.gl/loader-utils");
|
|
575
1005
|
var import_compression = require("@loaders.gl/compression");
|
|
576
1006
|
var COMPRESSION_METHODS = {
|
|
577
1007
|
/** No compression */
|
|
@@ -593,12 +1023,12 @@ var ZipFileSystem = class {
|
|
|
593
1023
|
this.fileProvider = null;
|
|
594
1024
|
if (typeof file === "string") {
|
|
595
1025
|
this.fileName = file;
|
|
596
|
-
if (!
|
|
597
|
-
this.fileProvider = new
|
|
1026
|
+
if (!import_loader_utils7.isBrowser) {
|
|
1027
|
+
this.fileProvider = new import_loader_utils9.FileHandleFile(file);
|
|
598
1028
|
} else {
|
|
599
1029
|
throw new Error("Cannot open file for random access in a WEB browser");
|
|
600
1030
|
}
|
|
601
|
-
} else if ((0,
|
|
1031
|
+
} else if ((0, import_loader_utils8.isFileProvider)(file)) {
|
|
602
1032
|
this.fileProvider = file;
|
|
603
1033
|
}
|
|
604
1034
|
}
|