@loaders.gl/tile-converter 5.0.0-alpha.11 → 5.0.0-alpha.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +178 -2
  2. package/bin/converter-v5.js +2 -0
  3. package/dist/converter.min.cjs +162 -163
  4. package/dist/i3s-server/bin/i3s-server.min.cjs +73 -73
  5. package/dist/index.cjs +1749 -2152
  6. package/dist/index.js +1748 -2162
  7. package/dist/v5/adapters.cjs +1550 -128
  8. package/dist/v5/adapters.d.ts +16 -0
  9. package/dist/v5/adapters.js +1558 -117
  10. package/dist/v5/archive-source.d.ts +36 -0
  11. package/dist/v5/browser-tileset-source.d.ts +55 -11
  12. package/dist/v5/browser.cjs +18 -0
  13. package/dist/v5/browser.d.ts +14 -0
  14. package/dist/v5/browser.js +26 -0
  15. package/dist/v5/conversion-api.d.ts +9 -0
  16. package/dist/v5/converter-cli.d.ts +1 -0
  17. package/dist/v5/converter-cli.js +1214 -0
  18. package/dist/v5/core.cjs +471 -60
  19. package/dist/v5/core.d.ts +2 -0
  20. package/dist/v5/core.js +471 -60
  21. package/dist/v5/i3s-mesh-conversion.d.ts +4 -0
  22. package/dist/v5/i3s-selection-source.d.ts +70 -0
  23. package/dist/v5/index.cjs +10 -0
  24. package/dist/v5/index.d.ts +8 -0
  25. package/dist/v5/index.js +14 -0
  26. package/dist/v5/mesh-conversion.d.ts +18 -0
  27. package/dist/v5/mesh-hierarchy.d.ts +47 -0
  28. package/dist/v5/mesh-source-features.d.ts +2 -1
  29. package/dist/v5/mesh-source-schema.d.ts +12 -0
  30. package/dist/v5/mesh-source.d.ts +5 -2
  31. package/dist/v5/mesh-tileset-sink.d.ts +5 -0
  32. package/dist/v5/node-cli.d.ts +9 -0
  33. package/dist/v5/node-conversion.d.ts +32 -0
  34. package/dist/v5/node-feature-schema.d.ts +3 -0
  35. package/dist/v5/node-i3s-source.d.ts +41 -0
  36. package/dist/v5/node-source.d.ts +47 -0
  37. package/dist/v5/node.cjs +900 -0
  38. package/dist/v5/node.d.ts +6 -0
  39. package/dist/v5/node.js +877 -0
  40. package/dist/v5/point-cloud-file.d.ts +83 -0
  41. package/dist/v5/point-cloud-potree.d.ts +47 -0
  42. package/dist/v5/point-cloud-tileset.d.ts +44 -0
  43. package/dist/v5/resource-manifest.d.ts +10 -1
  44. package/dist/v5/selected-mesh-source.d.ts +53 -0
  45. package/package.json +33 -25
  46. package/src/index.ts +4 -1
  47. package/src/v4/3d-tiles-converter/helpers/load-i3s.ts +2 -4
  48. package/src/v4/converter-cli.ts +8 -2
  49. package/src/v4/i3s-converter/helpers/load-3d-tiles.ts +3 -51
  50. package/src/v4/i3s-converter/helpers/node-index-document.ts +5 -2
  51. package/src/v4/i3s-converter/helpers/preprocess-3d-tiles.ts +1 -1
  52. package/src/v4/i3s-converter/json-templates/store.ts +2 -1
  53. package/src/v5/adapters.ts +48 -0
  54. package/src/v5/archive-source.ts +235 -0
  55. package/src/v5/browser-tileset-source.ts +418 -48
  56. package/src/v5/browser.ts +45 -0
  57. package/src/v5/conversion-api.ts +69 -9
  58. package/src/v5/converter-cli.ts +28 -0
  59. package/src/v5/core.ts +6 -0
  60. package/src/v5/i3s-mesh-conversion.ts +40 -2
  61. package/src/v5/i3s-mesh-sink.ts +1 -1
  62. package/src/v5/i3s-mesh-source.ts +1 -0
  63. package/src/v5/i3s-selection-source.ts +298 -0
  64. package/src/v5/index.ts +26 -0
  65. package/src/v5/mesh-conversion.ts +20 -0
  66. package/src/v5/mesh-hierarchy.ts +648 -0
  67. package/src/v5/mesh-source-features.ts +39 -7
  68. package/src/v5/mesh-source-schema.ts +134 -0
  69. package/src/v5/mesh-source.ts +16 -4
  70. package/src/v5/mesh-tileset-sink.ts +1 -1
  71. package/src/v5/node-cli.ts +197 -0
  72. package/src/v5/node-conversion.ts +345 -0
  73. package/src/v5/node-feature-schema.ts +155 -0
  74. package/src/v5/node-i3s-source.ts +181 -0
  75. package/src/v5/node-source.ts +328 -0
  76. package/src/v5/node.ts +16 -0
  77. package/src/v5/point-cloud-file.ts +306 -0
  78. package/src/v5/point-cloud-potree.ts +130 -0
  79. package/src/v5/point-cloud-tileset.ts +137 -0
  80. package/src/v5/resource-fetcher.ts +4 -1
  81. package/src/v5/resource-manifest.ts +40 -5
  82. package/src/v5/selected-mesh-source.ts +384 -0
  83. package/src/v5/spatial-conversion.ts +88 -17
package/dist/index.cjs CHANGED
@@ -5,12 +5,12 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res, err2) => function __init() {
9
- if (err2) throw err2[0];
8
+ var __esm = (fn, res, err) => function __init() {
9
+ if (err) throw err[0];
10
10
  try {
11
11
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
12
  } catch (e) {
13
- throw err2 = [e], e;
13
+ throw err = [e], e;
14
14
  }
15
15
  };
16
16
  var __export = (target, all) => {
@@ -25,7 +25,6 @@ var __copyProps = (to, from, except, desc) => {
25
25
  }
26
26
  return to;
27
27
  };
28
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
29
28
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
29
  // If the importer is in node compatibility mode or this is not an ESM
31
30
  // file that has been converted to a CommonJS file using a Babel-
@@ -153,6 +152,41 @@ var init_merge_options = __esm({
153
152
  }
154
153
  });
155
154
 
155
+ // ../../modules/loader-utils/src/lib/module-utils/initialize-wasm-module.ts
156
+ function initializeWasmModule(initialize, extractExports) {
157
+ return new Promise((resolve2, reject) => {
158
+ let isSettled = false;
159
+ function rejectInitialization(error) {
160
+ if (!isSettled) {
161
+ isSettled = true;
162
+ reject(error);
163
+ }
164
+ }
165
+ function resolveInitialization(module2) {
166
+ if (isSettled) {
167
+ return;
168
+ }
169
+ isSettled = true;
170
+ try {
171
+ resolve2(extractExports(module2));
172
+ } catch (error) {
173
+ reject(error);
174
+ }
175
+ }
176
+ try {
177
+ const modulePromise = initialize(resolveInitialization, rejectInitialization);
178
+ modulePromise?.then(resolveInitialization, rejectInitialization);
179
+ } catch (error) {
180
+ rejectInitialization(error);
181
+ }
182
+ });
183
+ }
184
+ var init_initialize_wasm_module = __esm({
185
+ "../../modules/loader-utils/src/lib/module-utils/initialize-wasm-module.ts"() {
186
+ "use strict";
187
+ }
188
+ });
189
+
156
190
  // ../../modules/loader-utils/src/lib/module-utils/js-module-utils.ts
157
191
  function registerJSModules(modules) {
158
192
  globalThis.loaders ||= {};
@@ -312,17 +346,11 @@ var init_worker_job = __esm({
312
346
  });
313
347
 
314
348
  // ../../modules/worker-utils/src/lib/node/worker_threads.ts
315
- var worker_threads_exports = {};
316
- __export(worker_threads_exports, {
317
- NodeWorker: () => NodeWorker,
318
- parentPort: () => parentPort
319
- });
320
349
  var WorkerThreads, parentPort, NodeWorker;
321
350
  var init_worker_threads = __esm({
322
351
  "../../modules/worker-utils/src/lib/node/worker_threads.ts"() {
323
352
  "use strict";
324
353
  WorkerThreads = __toESM(require("worker_threads"), 1);
325
- __reExport(worker_threads_exports, require("worker_threads"));
326
354
  parentPort = WorkerThreads?.parentPort;
327
355
  NodeWorker = WorkerThreads.Worker;
328
356
  }
@@ -1443,6 +1471,9 @@ var init_src = __esm({
1443
1471
 
1444
1472
  // ../../modules/loader-utils/src/lib/worker-loader-utils/parse-with-worker.ts
1445
1473
  function canParseWithWorker(loader, options) {
1474
+ const workerUrl = options?.[loader.id]?.workerUrl;
1475
+ if (options?.core?.worker === false || !(loader.worker || loader.loadWorker || workerUrl))
1476
+ return false;
1446
1477
  if (options?.core?.credentials?.some(
1447
1478
  (credential) => credential.type === "request" || "token" in credential && typeof credential.token === "function"
1448
1479
  ))
@@ -1573,12 +1604,14 @@ function resolveWorkerLoaders(loader, loaderIds, loaderIsArray, context, options
1573
1604
  }
1574
1605
  }
1575
1606
  function getWorkerOptions(options = {}, loader) {
1607
+ const optionsToSerialize = {
1608
+ ...options,
1609
+ ...options.core ? { core: { ...options.core, authentications: void 0 } } : {}
1610
+ };
1576
1611
  const serializedOptions = JSON.parse(
1577
- JSON.stringify({
1578
- ...options,
1579
- ...options.core ? { core: { ...options.core, authentications: void 0 } } : {}
1580
- })
1612
+ JSON.stringify(optionsToSerialize, (_key, value) => typeof value === "bigint" ? null : value)
1581
1613
  );
1614
+ restoreBigIntOptions(optionsToSerialize, serializedOptions);
1582
1615
  const workerOptions = {
1583
1616
  ...serializedOptions.core,
1584
1617
  ...serializedOptions
@@ -1591,6 +1624,14 @@ function getWorkerOptions(options = {}, loader) {
1591
1624
  }
1592
1625
  return workerOptions;
1593
1626
  }
1627
+ function restoreBigIntOptions(original, serialized) {
1628
+ if (!serialized || typeof serialized !== "object") return;
1629
+ for (const key of Object.keys(serialized)) {
1630
+ const value = original?.[key];
1631
+ if (typeof value === "bigint") serialized[key] = value;
1632
+ else restoreBigIntOptions(value, serialized[key]);
1633
+ }
1634
+ }
1594
1635
  function getSerializableLoaderContext(context) {
1595
1636
  if (!context) {
1596
1637
  return {};
@@ -3778,6 +3819,7 @@ var init_src2 = __esm({
3778
3819
  init_log();
3779
3820
  init_is_type();
3780
3821
  init_merge_options();
3822
+ init_initialize_wasm_module();
3781
3823
  init_js_module_utils();
3782
3824
  init_js_module_utils();
3783
3825
  init_parse_with_worker();
@@ -6321,6 +6363,7 @@ function convertArrowTableToMesh(table) {
6321
6363
  const schema = serializeArrowSchema(arrowTable.schema);
6322
6364
  const fields = schema.fields;
6323
6365
  const attributes = {};
6366
+ const columns = [];
6324
6367
  for (const field of fields) {
6325
6368
  const { name: name18 } = field;
6326
6369
  if (name18 === "indices") {
@@ -6330,11 +6373,16 @@ function convertArrowTableToMesh(table) {
6330
6373
  const size = getFixedSizeListSize(attributeData);
6331
6374
  const typedArray = getAttributeTypedArray(attributeData, size);
6332
6375
  const metadata = getMeshAttributeMetadata(field.metadata);
6376
+ const value = metadata.componentType === "float16" ? restoreFloat16Array(typedArray) : typedArray;
6377
+ const shared = columns.find(
6378
+ (column) => column.data.length === attributeData.data.length && attributes[column.name].value.constructor === value.constructor && column.data.every((chunk, index) => shareArrowStorage(chunk, attributeData.data[index]))
6379
+ );
6333
6380
  attributes[name18] = {
6334
- value: metadata.componentType === "float16" ? restoreFloat16Array(typedArray) : typedArray,
6381
+ value: shared ? attributes[shared.name].value : value,
6335
6382
  size,
6336
6383
  ...metadata
6337
6384
  };
6385
+ if (!shared) columns.push({ name: name18, data: attributeData.data });
6338
6386
  }
6339
6387
  fixMetadata(schema);
6340
6388
  const topology = schema.metadata.topology;
@@ -6451,6 +6499,15 @@ function getIndices(arrowTable) {
6451
6499
  const values = indicesData.children[0].values.subarray(start, end);
6452
6500
  return { value: values, size: 1 };
6453
6501
  }
6502
+ function shareArrowStorage(left, right) {
6503
+ const rightBuffers = Object.values(right.buffers);
6504
+ return left.type.toString() === right.type.toString() && left.offset === right.offset && left.length === right.length && left.nullCount === right.nullCount && left.dictionary === right.dictionary && Object.values(left.buffers).every((buffer, index) => {
6505
+ const other = rightBuffers[index];
6506
+ return buffer === other || Boolean(
6507
+ buffer && other && buffer.buffer === other.buffer && buffer.byteOffset === other.byteOffset && buffer.byteLength === other.byteLength
6508
+ );
6509
+ }) && left.children.length === right.children.length && left.children.every((child, index) => shareArrowStorage(child, right.children[index]));
6510
+ }
6454
6511
  var arrow5;
6455
6512
  var init_convert_table_to_mesh = __esm({
6456
6513
  "../../modules/schema-utils/src/lib/mesh/convert-table-to-mesh.ts"() {
@@ -6605,8 +6662,8 @@ function convertDataToBatch(parsedData, loader) {
6605
6662
  }
6606
6663
  async function applyInputTransforms(inputIterator, transforms = []) {
6607
6664
  let iteratorChain = inputIterator;
6608
- for await (const transformBatches of transforms) {
6609
- iteratorChain = transformBatches(iteratorChain);
6665
+ for await (const transformBatches2 of transforms) {
6666
+ iteratorChain = transformBatches2(iteratorChain);
6610
6667
  }
6611
6668
  return iteratorChain;
6612
6669
  }
@@ -9959,16 +10016,16 @@ function encodeExtMeshFeaturesForPrimitive(scenegraph, primitive) {
9959
10016
  function createAccessorKey(attributes) {
9960
10017
  const prefix = "_FEATURE_ID_";
9961
10018
  const attrs = Object.keys(attributes).filter((item) => item.indexOf(prefix) === 0);
9962
- let max2 = -1;
10019
+ let max = -1;
9963
10020
  for (const a of attrs) {
9964
10021
  const n = Number(a.substring(prefix.length));
9965
- if (n > max2) {
9966
- max2 = n;
10022
+ if (n > max) {
10023
+ max = n;
9967
10024
  }
9968
10025
  }
9969
- max2++;
9970
- const accessorKey = `${prefix}${max2}`;
9971
- return { accessorKey, index: max2 };
10026
+ max++;
10027
+ const accessorKey = `${prefix}${max}`;
10028
+ return { accessorKey, index: max };
9972
10029
  }
9973
10030
  var EXT_MESH_FEATURES_NAME, name;
9974
10031
  var init_EXT_mesh_features = __esm({
@@ -11882,8 +11939,9 @@ function initializeBasisTranscoderModule(BasisModule, wasmBinary) {
11882
11939
  if (wasmBinary) {
11883
11940
  options.wasmBinary = wasmBinary;
11884
11941
  }
11885
- return new Promise((resolve2) => {
11886
- BasisModule(options).then((module2) => {
11942
+ return initializeWasmModule(
11943
+ () => BasisModule(options),
11944
+ (module2) => {
11887
11945
  const {
11888
11946
  BasisFile,
11889
11947
  KTX2File,
@@ -11893,15 +11951,15 @@ function initializeBasisTranscoderModule(BasisModule, wasmBinary) {
11893
11951
  isFormatSupported
11894
11952
  } = module2;
11895
11953
  initializeBasis();
11896
- resolve2({
11954
+ return {
11897
11955
  BasisFile,
11898
11956
  KTX2File,
11899
11957
  getBasisTexFormatBlockHeight,
11900
11958
  getBasisTexFormatBlockWidth,
11901
11959
  isFormatSupported
11902
- });
11903
- });
11904
- });
11960
+ };
11961
+ }
11962
+ );
11905
11963
  }
11906
11964
  var BASIS_EXTERNAL_LIBRARIES, loadBasisTranscoderPromise;
11907
11965
  var init_basis_module_loader = __esm({
@@ -13159,7 +13217,6 @@ var init_src7 = __esm({
13159
13217
  init_version4();
13160
13218
  init_basis_loader();
13161
13219
  init_compressed_texture_loader();
13162
- init_gl_extensions();
13163
13220
  KTX2BasisWriterWorker = {
13164
13221
  name: "Basis Universal Supercompressed GPU Texture",
13165
13222
  id: "ktx2-basis-writer",
@@ -13692,7 +13749,10 @@ async function loadDracoDecoderModuleFromDraco3D(draco3DModule) {
13692
13749
  const typedDraco3DModule = validateDracoDecoderModule(draco3DModule);
13693
13750
  let decoderPromise = injectedDecoderPromises.get(typedDraco3DModule);
13694
13751
  if (!decoderPromise) {
13695
- decoderPromise = typedDraco3DModule.createDecoderModule({}).then((draco) => ({ draco }));
13752
+ decoderPromise = initializeWasmModule(
13753
+ () => typedDraco3DModule.createDecoderModule({}),
13754
+ (draco) => ({ draco })
13755
+ );
13696
13756
  injectedDecoderPromises.set(typedDraco3DModule, decoderPromise);
13697
13757
  }
13698
13758
  return await decoderPromise;
@@ -13703,7 +13763,10 @@ async function loadDracoEncoderModule(options = {}) {
13703
13763
  const typedDraco3DModule = validateDracoEncoderModule(draco3DModule);
13704
13764
  let encoderPromise2 = injectedEncoderPromises.get(typedDraco3DModule);
13705
13765
  if (!encoderPromise2) {
13706
- encoderPromise2 = typedDraco3DModule.createEncoderModule({}).then((draco) => ({ draco }));
13766
+ encoderPromise2 = initializeWasmModule(
13767
+ () => typedDraco3DModule.createEncoderModule({}),
13768
+ (draco) => ({ draco })
13769
+ );
13707
13770
  injectedEncoderPromises.set(typedDraco3DModule, encoderPromise2);
13708
13771
  }
13709
13772
  return await encoderPromise2;
@@ -13833,17 +13896,13 @@ function initializeDracoModule(initializer, wasmBinary) {
13833
13896
  if (typeof initializer !== "function") {
13834
13897
  throw new Error("Draco module initializer could not be loaded");
13835
13898
  }
13836
- return new Promise((resolve2, reject) => {
13837
- try {
13838
- const modulePromise = initializer({
13839
- ...wasmBinary ? { wasmBinary } : {},
13840
- onModuleLoaded: (draco) => resolve2({ draco })
13841
- });
13842
- modulePromise?.then((draco) => resolve2({ draco }), reject);
13843
- } catch (error) {
13844
- reject(error);
13845
- }
13846
- });
13899
+ return initializeWasmModule(
13900
+ (onInitialized) => initializer({
13901
+ ...wasmBinary ? { wasmBinary } : {},
13902
+ onModuleLoaded: onInitialized
13903
+ }),
13904
+ (draco) => ({ draco })
13905
+ );
13847
13906
  }
13848
13907
  function getLibraryExport(library, exportName) {
13849
13908
  if (typeof library === "function") {
@@ -13893,6 +13952,7 @@ var DRACO_VERSION, DRACO_RELEASE_COMMIT, STATIC_DECODER_URL, STATIC_ENCODER_URL,
13893
13952
  var init_draco_module_loader = __esm({
13894
13953
  "../../modules/draco/src/lib/draco-module-loader.ts"() {
13895
13954
  "use strict";
13955
+ init_src2();
13896
13956
  init_draco_library_loader();
13897
13957
  DRACO_VERSION = "1.5.7";
13898
13958
  DRACO_RELEASE_COMMIT = "8786740086a9f4d83f44aa83badfbea4dce7a1b5";
@@ -13989,13 +14049,13 @@ function hasAttributeQuantization(options) {
13989
14049
  options.attributeQuantization && Object.keys(options.attributeQuantization).length
13990
14050
  );
13991
14051
  }
13992
- function validateQuantizationBits(attributeName, bits2, attributeType) {
13993
- if (!Number.isInteger(bits2) || bits2 < 1 || bits2 > 30) {
14052
+ function validateQuantizationBits(attributeName, bits, attributeType) {
14053
+ if (!Number.isInteger(bits) || bits < 1 || bits > 30) {
13994
14054
  throw new Error(
13995
14055
  `DracoWriter: quantization bits for "${attributeName}" must be an integer from 1 to 30`
13996
14056
  );
13997
14057
  }
13998
- if (attributeType === "NORMAL" && (bits2 < 2 || bits2 > 29)) {
14058
+ if (attributeType === "NORMAL" && (bits < 2 || bits > 29)) {
13999
14059
  throw new Error(
14000
14060
  `DracoWriter: quantization bits for NORMAL attribute "${attributeName}" must be an integer from 2 to 29`
14001
14061
  );
@@ -14234,10 +14294,10 @@ var init_draco_builder = __esm({
14234
14294
  if (options.quantization) {
14235
14295
  for (const attribute in options.quantization) {
14236
14296
  const attributeType = attribute;
14237
- const bits2 = options.quantization[attributeType];
14238
- if (bits2 !== void 0) {
14239
- validateQuantizationBits(attributeType, bits2, attributeType);
14240
- this.dracoEncoder.SetAttributeQuantization(this.draco[attributeType], bits2);
14297
+ const bits = options.quantization[attributeType];
14298
+ if (bits !== void 0) {
14299
+ validateQuantizationBits(attributeType, bits, attributeType);
14300
+ this.dracoEncoder.SetAttributeQuantization(this.draco[attributeType], bits);
14241
14301
  }
14242
14302
  }
14243
14303
  }
@@ -14270,17 +14330,17 @@ var init_draco_builder = __esm({
14270
14330
  _getAttributeQuantization(attributes, options) {
14271
14331
  const categoryQuantization = /* @__PURE__ */ new Map();
14272
14332
  for (const attributeType of Object.keys(options.quantization || {})) {
14273
- const bits2 = options.quantization?.[attributeType];
14274
- if (bits2 !== void 0) {
14275
- validateQuantizationBits(attributeType, bits2, attributeType);
14276
- categoryQuantization.set(this.draco[attributeType], bits2);
14333
+ const bits = options.quantization?.[attributeType];
14334
+ if (bits !== void 0) {
14335
+ validateQuantizationBits(attributeType, bits, attributeType);
14336
+ categoryQuantization.set(this.draco[attributeType], bits);
14277
14337
  }
14278
14338
  }
14279
14339
  const quantization = /* @__PURE__ */ new Map();
14280
14340
  for (const [attributeName, attribute] of Object.entries(attributes)) {
14281
- const bits2 = categoryQuantization.get(attribute.attributeType);
14282
- if (bits2 !== void 0) {
14283
- quantization.set(attributeName, bits2);
14341
+ const bits = categoryQuantization.get(attribute.attributeType);
14342
+ if (bits !== void 0) {
14343
+ quantization.set(attributeName, bits);
14284
14344
  }
14285
14345
  }
14286
14346
  for (const [attributeName, setting] of Object.entries(options.attributeQuantization || {})) {
@@ -15064,8 +15124,8 @@ function getTransformedMeshBoundingBox(attributes) {
15064
15124
  if (position?.transform?.type !== "quantization") {
15065
15125
  return boundingBox;
15066
15126
  }
15067
- const { bits: bits2, origin, range } = position.transform;
15068
- const scale = range / (2 ** bits2 - 1);
15127
+ const { bits, origin, range } = position.transform;
15128
+ const scale = range / (2 ** bits - 1);
15069
15129
  return boundingBox.map(
15070
15130
  (bounds) => bounds.map((value, componentIndex) => origin[componentIndex] + value * scale)
15071
15131
  );
@@ -20860,12 +20920,13 @@ function transformHeight(height, geoidUndulation, source, target) {
20860
20920
  }
20861
20921
  throw new Error(`Unsupported height conversion from ${source} to ${target}`);
20862
20922
  }
20863
- var import_core4, import_geospatial2, SpatialCoordinateTransformer;
20923
+ var import_core4, import_geospatial2, import_bulk, SpatialCoordinateTransformer;
20864
20924
  var init_spatial_coordinate_transformer = __esm({
20865
20925
  "../../modules/tiles/src/spatial/spatial-coordinate-transformer.ts"() {
20866
20926
  "use strict";
20867
20927
  import_core4 = require("@math.gl/core");
20868
20928
  import_geospatial2 = require("@math.gl/geospatial");
20929
+ import_bulk = require("@math.gl/projection/bulk");
20869
20930
  init_spatial_resource_registry();
20870
20931
  init_normalize_crs_identifier();
20871
20932
  init_get_spatial_coordinate_frame();
@@ -20874,6 +20935,8 @@ var init_spatial_coordinate_transformer = __esm({
20874
20935
  spatialReference;
20875
20936
  /** Projection from the source CRS directly to the requested horizontal target CRS. */
20876
20937
  horizontalProjection;
20938
+ /** Reusable packed xyz projection for horizontal-only coordinate batches. */
20939
+ horizontalProjectionBuffer;
20877
20940
  /** Projection from the source CRS to geographic longitude, latitude, and ellipsoidal height. */
20878
20941
  geographicProjection;
20879
20942
  /** Projection from adjusted geographic coordinates to the requested output CRS. */
@@ -20909,6 +20972,12 @@ var init_spatial_coordinate_transformer = __esm({
20909
20972
  to: getHorizontalProjectionDefinition(spatialReference.targetCrs),
20910
20973
  enforceAxis: false
20911
20974
  });
20975
+ if (!requiresHeightTransformation(spatialReference)) {
20976
+ this.horizontalProjectionBuffer = new import_bulk.ProjectionBuffer({
20977
+ projection: this.horizontalProjection,
20978
+ dimension: 3
20979
+ });
20980
+ }
20912
20981
  }
20913
20982
  if (requiresHeightTransformation(spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
20914
20983
  if (!this.sourceIsGeographic && !this.sourceIsGeocentric) {
@@ -20971,12 +21040,21 @@ var init_spatial_coordinate_transformer = __esm({
20971
21040
  }
20972
21041
  return result;
20973
21042
  }
20974
- /** Transform a packed sequence of xyz positions, preserving the input array type only when safe. */
21043
+ /** Transform packed xyz positions into owned Float64 storage, batching finite horizontal transforms. */
20975
21044
  transformPositions(positions) {
20976
21045
  if (positions.length % 3 !== 0) {
20977
21046
  throw new Error("Packed spatial positions must contain a multiple of three components");
20978
21047
  }
20979
21048
  const transformedPositions = new Float64Array(positions.length);
21049
+ if (this.horizontalProjectionBuffer) {
21050
+ transformedPositions.set(positions);
21051
+ if (transformedPositions.every(Number.isFinite)) {
21052
+ return this.horizontalProjectionBuffer.projectFlatTo(
21053
+ transformedPositions,
21054
+ transformedPositions
21055
+ );
21056
+ }
21057
+ }
20980
21058
  for (let index = 0; index < positions.length; index += 3) {
20981
21059
  const transformed = this.transformPosition([
20982
21060
  Number(positions[index]),
@@ -25822,6 +25900,152 @@ var init_cesium_ion_loader = __esm({
25822
25900
  }
25823
25901
  });
25824
25902
 
25903
+ // ../../modules/compression/src/lib/compression.ts
25904
+ var CompressionTransform, Decompressor;
25905
+ var init_compression = __esm({
25906
+ "../../modules/compression/src/lib/compression.ts"() {
25907
+ "use strict";
25908
+ init_src2();
25909
+ CompressionTransform = class {
25910
+ /** Preloads any dynamic libraries. May enable sync functions */
25911
+ async preload(modules = {}) {
25912
+ registerJSModules(modules);
25913
+ return void 0;
25914
+ }
25915
+ // HELPERS
25916
+ concatenate(asyncIterator) {
25917
+ return concatenateArrayBuffersAsync(asyncIterator);
25918
+ }
25919
+ improveError(error) {
25920
+ if (!error.message.includes(this.name)) {
25921
+ error.message = `${this.name} ${error.message}`;
25922
+ }
25923
+ return error;
25924
+ }
25925
+ };
25926
+ Decompressor = class extends CompressionTransform {
25927
+ constructor(options) {
25928
+ super();
25929
+ this.decompressBatches = this.decompressBatches.bind(this);
25930
+ }
25931
+ /** Asynchronously decompresses data. */
25932
+ async decompress(input, size) {
25933
+ await this.preload();
25934
+ return this.decompressSync(input, size);
25935
+ }
25936
+ /** Synchronously decompresses data. */
25937
+ decompressSync(input, size) {
25938
+ throw new Error(`${this.name}: sync decompression not supported`);
25939
+ }
25940
+ /** Decompresses batches. */
25941
+ async *decompressBatches(asyncIterator) {
25942
+ const input = await this.concatenate(asyncIterator);
25943
+ yield this.decompress(input);
25944
+ }
25945
+ };
25946
+ }
25947
+ });
25948
+
25949
+ // ../../modules/compression/src/lib/compress-utils-compression.ts
25950
+ async function* transformBatches(stream, inputBatches) {
25951
+ try {
25952
+ for await (const input of inputBatches) {
25953
+ const output2 = stream.write(new Uint8Array(input));
25954
+ if (output2.byteLength > 0) yield copyArrayBuffer2(output2);
25955
+ }
25956
+ const output = stream.finish();
25957
+ if (output.byteLength > 0) yield copyArrayBuffer2(output);
25958
+ } finally {
25959
+ stream.destroy();
25960
+ }
25961
+ }
25962
+ function copyArrayBuffer2(bytes) {
25963
+ return bytes.slice().buffer;
25964
+ }
25965
+ function getDecompressOptions(options, size) {
25966
+ const decodeOptions = {
25967
+ ...options.compressUtils,
25968
+ ...size === void 0 ? {} : { expectedSize: size }
25969
+ };
25970
+ const capacity = decodeOptions.expectedSize;
25971
+ const maximum = options.maxOutputByteLength ?? 512 * 1024 * 1024;
25972
+ if (!Number.isSafeInteger(maximum) || maximum < 0 || maximum > 2147483647)
25973
+ throw new RangeError("Invalid maxOutputByteLength");
25974
+ if (capacity !== void 0 && (!Number.isSafeInteger(capacity) || capacity < 0 || capacity > maximum)) {
25975
+ throw new RangeError("expectedSize exceeds the configured output capacity limit");
25976
+ }
25977
+ return decodeOptions;
25978
+ }
25979
+ var CompressUtilsDecompressor;
25980
+ var init_compress_utils_compression = __esm({
25981
+ "../../modules/compression/src/lib/compress-utils-compression.ts"() {
25982
+ "use strict";
25983
+ init_compression();
25984
+ CompressUtilsDecompressor = class extends Decompressor {
25985
+ name;
25986
+ extensions;
25987
+ contentEncodings;
25988
+ isSupported = true;
25989
+ options;
25990
+ loadModule;
25991
+ /** Module initialized for synchronous operations. */
25992
+ module = null;
25993
+ /** Shared import and WASM initialization for concurrent callers. */
25994
+ modulePromise = null;
25995
+ /** Creates a format-specific compress-utils decoder. */
25996
+ constructor(metadata, loadModule, options = {}) {
25997
+ super(options);
25998
+ this.name = metadata.name;
25999
+ this.extensions = metadata.extensions || [];
26000
+ this.contentEncodings = metadata.contentEncodings || [];
26001
+ this.loadModule = loadModule;
26002
+ this.options = options;
26003
+ }
26004
+ /** Imports and initializes the codec without loading the opposite direction. */
26005
+ async preload(modules = {}) {
26006
+ await super.preload(modules);
26007
+ this.modulePromise ||= this.loadModule().then(async (module2) => {
26008
+ await module2.preload?.();
26009
+ this.module = module2;
26010
+ });
26011
+ try {
26012
+ await this.modulePromise;
26013
+ } catch (error) {
26014
+ this.modulePromise = null;
26015
+ throw error;
26016
+ }
26017
+ }
26018
+ /** Runs synchronously after preload has initialized the WASM codec. */
26019
+ decompressSync(input, size) {
26020
+ if (!this.module?.decompressSync)
26021
+ throw new Error(`${this.name}: call preload() before decompressSync()`);
26022
+ return copyArrayBuffer2(
26023
+ this.module.decompressSync(new Uint8Array(input), getDecompressOptions(this.options, size))
26024
+ );
26025
+ }
26026
+ /** Decompresses one buffer with the selected compress-utils decoder. */
26027
+ async decompress(input, size) {
26028
+ const decodeOptions = getDecompressOptions(this.options, size);
26029
+ await this.preload();
26030
+ const module2 = this.module;
26031
+ const output = await module2.decompress(new Uint8Array(input), decodeOptions);
26032
+ return copyArrayBuffer2(output);
26033
+ }
26034
+ /** Incrementally decompresses input batches with compress-utils. */
26035
+ async *decompressBatches(inputBatches) {
26036
+ await this.preload();
26037
+ const module2 = this.module;
26038
+ if (!module2.createDecompressStream) {
26039
+ yield await this.decompress(await this.concatenate(inputBatches));
26040
+ return;
26041
+ }
26042
+ const stream = await module2.createDecompressStream();
26043
+ yield* transformBatches(stream, inputBatches);
26044
+ }
26045
+ };
26046
+ }
26047
+ });
26048
+
25825
26049
  // ../../modules/crypto/src/lib/hash.ts
25826
26050
  var Hash;
25827
26051
  var init_hash = __esm({
@@ -26278,65 +26502,25 @@ var init_crc32_hash = __esm({
26278
26502
  });
26279
26503
 
26280
26504
  // ../../modules/crypto/src/lib/algorithms/md5-wasm.ts
26281
- function md5WASM(data) {
26282
- var mem, memView, importObj, imports, len, buff, thenFun, catchFun, result, endTime;
26283
- const md5JS = makeMD5JS(), md5WA = makeMD5WA(), returnObj = {}, startTime = (/* @__PURE__ */ new Date()).getTime();
26284
- returnObj["then"] = function(fun) {
26285
- thenFun = fun;
26286
- getThen();
26287
- return returnObj;
26288
- };
26289
- returnObj["catch"] = function(fun) {
26290
- catchFun = fun;
26291
- return returnObj;
26292
- };
26293
- buff = normalizeInput(data);
26294
- if (!buff) {
26295
- getCatch(new TypeError(parmTypeErrStr));
26296
- }
26297
- if (buff) {
26298
- len = buff.length;
26299
- if (wasm && len > bounder) {
26300
- if (len > upperLimit) {
26301
- getCatch(new Error(tooBigErrStr));
26302
- } else {
26303
- mem = new WebAssembly.Memory({
26304
- initial: len > 32e6 ? len > 64e6 ? len > 128e6 ? 4096 : 2048 : 1024 : 512
26305
- });
26306
- memView = new Uint32Array(mem.buffer);
26307
- imports = { mem, log: console.log };
26308
- importObj = { imports };
26309
- WebAssembly.instantiate(wasm, importObj).then(giterdone);
26310
- }
26311
- } else {
26312
- getThen(md5JS(buff));
26313
- }
26505
+ async function md5WASM(data) {
26506
+ const input = normalizeInput(data);
26507
+ if (!input) {
26508
+ throw new TypeError(parmTypeErrStr);
26314
26509
  }
26315
- return returnObj;
26316
- function giterdone(obj) {
26317
- getThen(md5WA(buff, obj.instance.exports, memView));
26318
- }
26319
- function getThen(r) {
26320
- var res = Boolean(r) ? r : result;
26321
- if (Boolean(r)) {
26322
- endTime = (/* @__PURE__ */ new Date()).getTime();
26323
- }
26324
- if (typeof thenFun === "function") {
26325
- if (Boolean(res)) {
26326
- thenFun(res, endTime - startTime);
26327
- thenFun = catchFun = null;
26328
- }
26329
- } else {
26330
- if (Boolean(r)) {
26331
- result = r;
26332
- }
26333
- }
26510
+ if (!wasm || input.length <= bounder) {
26511
+ return makeMD5JS()(input);
26334
26512
  }
26335
- function getCatch(err2) {
26336
- if (typeof catchFun === "function") {
26337
- catchFun(err2);
26338
- }
26513
+ if (input.length > upperLimit) {
26514
+ throw new Error(tooBigErrStr);
26339
26515
  }
26516
+ const memory = new WebAssembly.Memory({
26517
+ initial: input.length > 32e6 ? input.length > 64e6 ? input.length > 128e6 ? 4096 : 2048 : 1024 : 512
26518
+ });
26519
+ const memoryView = new Uint32Array(memory.buffer);
26520
+ const { instance } = await WebAssembly.instantiate(wasm, {
26521
+ imports: { mem: memory, log: console.log }
26522
+ });
26523
+ return makeMD5WA()(input, instance.exports, memoryView);
26340
26524
  }
26341
26525
  function makeMD5WA() {
26342
26526
  var _loop, loops;
@@ -26737,13 +26921,7 @@ var init_md5_hash = __esm({
26737
26921
  * @returns base64 encoded hash
26738
26922
  */
26739
26923
  async hash(input, encoding) {
26740
- const md5Promise = new Promise(
26741
- (resolve2, reject) => (
26742
- // @ts-expect-error
26743
- md5WASM(input).then(resolve2).catch(reject)
26744
- )
26745
- );
26746
- const hex = await md5Promise;
26924
+ const hex = await md5WASM(input);
26747
26925
  return encodeHex(hex, encoding);
26748
26926
  }
26749
26927
  };
@@ -26759,442 +26937,7 @@ var init_src11 = __esm({
26759
26937
  }
26760
26938
  });
26761
26939
 
26762
- // ../../modules/zip/src/parse-zip/readable-file-utils.ts
26763
- function toBigInt(value) {
26764
- return typeof value === "bigint" ? value : BigInt(value);
26765
- }
26766
- function toNumber(value) {
26767
- const numberValue = Number(value);
26768
- if (!Number.isFinite(numberValue)) {
26769
- throw new Error("Offset is out of bounds");
26770
- }
26771
- return numberValue;
26772
- }
26773
- function normalizeOffset2(offset, size) {
26774
- if (offset < 0) {
26775
- return Math.max(size + offset, 0);
26776
- }
26777
- return Math.min(offset, size);
26778
- }
26779
- async function readRange(file, start, end) {
26780
- const startOffset = toBigInt(start);
26781
- const endOffset = toBigInt(end);
26782
- const length = endOffset - startOffset;
26783
- if (length < 0) {
26784
- throw new Error("Invalid range requested");
26785
- }
26786
- return await file.read(startOffset, toNumber(length));
26787
- }
26788
- async function readDataView(file, start, end) {
26789
- const arrayBuffer = await readRange(file, start, end);
26790
- return new DataView(arrayBuffer);
26791
- }
26792
- async function readUint16(file, offset) {
26793
- const dataView = await readDataView(file, offset, toBigInt(offset) + 2n);
26794
- return dataView.getUint16(0, true);
26795
- }
26796
- async function readUint32(file, offset) {
26797
- const dataView = await readDataView(file, offset, toBigInt(offset) + 4n);
26798
- return dataView.getUint32(0, true);
26799
- }
26800
- async function readBigUint64(file, offset) {
26801
- const dataView = await readDataView(file, offset, toBigInt(offset) + 8n);
26802
- return dataView.getBigUint64(0, true);
26803
- }
26804
- async function getReadableFileSize(file) {
26805
- if (file.bigsize > 0n) {
26806
- return file.bigsize;
26807
- }
26808
- if (file.size > 0) {
26809
- return BigInt(file.size);
26810
- }
26811
- if (file.stat) {
26812
- const stats = await file.stat();
26813
- if (stats?.bigsize !== void 0) {
26814
- return stats.bigsize;
26815
- }
26816
- if (stats?.size !== void 0) {
26817
- return BigInt(stats.size);
26818
- }
26819
- }
26820
- return 0n;
26821
- }
26822
- var DataViewReadableFile;
26823
- var init_readable_file_utils = __esm({
26824
- "../../modules/zip/src/parse-zip/readable-file-utils.ts"() {
26825
- "use strict";
26826
- init_src2();
26827
- DataViewReadableFile = class {
26828
- handle;
26829
- size;
26830
- bigsize;
26831
- url;
26832
- constructor(dataView, url = "") {
26833
- this.handle = dataView;
26834
- this.size = dataView.byteLength;
26835
- this.bigsize = BigInt(dataView.byteLength);
26836
- this.url = url;
26837
- }
26838
- async close() {
26839
- }
26840
- async stat() {
26841
- return { size: this.size, bigsize: this.bigsize, isDirectory: false };
26842
- }
26843
- async read(start = 0, length) {
26844
- const offset = toNumber(start);
26845
- const end = length ? offset + length : this.size;
26846
- const normalizedStart = normalizeOffset2(offset, this.size);
26847
- const normalizedEnd = normalizeOffset2(end, this.size);
26848
- const clampedEnd = Math.max(normalizedEnd, normalizedStart);
26849
- const lengthToRead = clampedEnd - normalizedStart;
26850
- if (lengthToRead <= 0) {
26851
- return new ArrayBuffer(0);
26852
- }
26853
- return copyToArrayBuffer2(this.handle.buffer, normalizedStart, lengthToRead);
26854
- }
26855
- };
26856
- }
26857
- });
26858
-
26859
- // ../../modules/zip/src/parse-zip/search-from-the-end.ts
26860
- var buffLength, searchFromTheEnd;
26861
- var init_search_from_the_end = __esm({
26862
- "../../modules/zip/src/parse-zip/search-from-the-end.ts"() {
26863
- "use strict";
26864
- init_readable_file_utils();
26865
- buffLength = 1024;
26866
- searchFromTheEnd = async (file, target) => {
26867
- const fileLength = await getReadableFileSize(file);
26868
- if (fileLength < BigInt(target.length)) {
26869
- return -1n;
26870
- }
26871
- const lastBytes = new Uint8Array(await readRange(file, fileLength - 3n, fileLength));
26872
- const searchWindow = [lastBytes[0], lastBytes[1], lastBytes[2], void 0];
26873
- let targetOffset = -1;
26874
- let point = fileLength - 3n;
26875
- do {
26876
- const prevPoint = point;
26877
- point -= BigInt(buffLength);
26878
- point = point >= 0n ? point : 0n;
26879
- const buff = new Uint8Array(await readRange(file, point, prevPoint));
26880
- for (let i = buff.length - 1; i > -1; i--) {
26881
- searchWindow[3] = searchWindow[2];
26882
- searchWindow[2] = searchWindow[1];
26883
- searchWindow[1] = searchWindow[0];
26884
- searchWindow[0] = buff[i];
26885
- if (searchWindow.every((val, index) => val === target[index])) {
26886
- targetOffset = i;
26887
- break;
26888
- }
26889
- }
26890
- } while (targetOffset === -1 && point > 0n);
26891
- return point + BigInt(targetOffset);
26892
- };
26893
- }
26894
- });
26895
-
26896
- // ../../modules/zip/src/parse-zip/zip64-info-generation.ts
26897
- function createZip64Info(options) {
26898
- const optionsToUse = {
26899
- ...options,
26900
- zip64Length: (options.offset ? 1 : 0) * 8 + (options.size ? 1 : 0) * 16
26901
- };
26902
- const arraysToConcat = [];
26903
- for (const field of ZIP64_FIELDS) {
26904
- if (!optionsToUse[field.name ?? ""] && !field.default) {
26905
- continue;
26906
- }
26907
- const newValue = new DataView(new ArrayBuffer(field.size));
26908
- NUMBER_SETTERS[field.size](newValue, 0, optionsToUse[field.name ?? ""] ?? field.default);
26909
- arraysToConcat.push(newValue.buffer);
26910
- }
26911
- return concatenateArrayBuffers(...arraysToConcat);
26912
- }
26913
- function setFieldToNumber(header, fieldSize, fieldOffset, value) {
26914
- NUMBER_SETTERS[fieldSize](header, Number(fieldOffset), value);
26915
- }
26916
- var signature, NUMBER_SETTERS, ZIP64_FIELDS;
26917
- var init_zip64_info_generation = __esm({
26918
- "../../modules/zip/src/parse-zip/zip64-info-generation.ts"() {
26919
- "use strict";
26920
- init_src2();
26921
- signature = new Uint8Array([1, 0]);
26922
- NUMBER_SETTERS = {
26923
- 2: (header, offset, value) => {
26924
- header.setUint16(offset, Number(value > 65535 ? 65535 : value), true);
26925
- },
26926
- 4: (header, offset, value) => {
26927
- header.setUint32(offset, Number(value > 4294967295 ? 4294967295 : value), true);
26928
- },
26929
- 8: (header, offset, value) => {
26930
- header.setBigUint64(offset, BigInt(value), true);
26931
- }
26932
- };
26933
- ZIP64_FIELDS = [
26934
- // Header ID 0x0001
26935
- {
26936
- size: 2,
26937
- default: new DataView(signature.buffer).getUint16(0, true)
26938
- },
26939
- // Size of the extra field chunk (8, 16, 24 or 28)
26940
- {
26941
- size: 2,
26942
- name: "zip64Length"
26943
- },
26944
- // Original uncompressed file size
26945
- {
26946
- size: 8,
26947
- name: "size"
26948
- },
26949
- // Size of compressed data
26950
- {
26951
- size: 8,
26952
- name: "size"
26953
- },
26954
- // Offset of local header record
26955
- {
26956
- size: 8,
26957
- name: "offset"
26958
- }
26959
- ];
26960
- }
26961
- });
26962
-
26963
- // ../../modules/zip/src/parse-zip/end-of-central-directory.ts
26964
- function generateEoCD(options) {
26965
- const header = new DataView(new ArrayBuffer(Number(CD_COMMENT_OFFSET)));
26966
- for (const field of EOCD_FIELDS) {
26967
- setFieldToNumber(
26968
- header,
26969
- field.size,
26970
- field.offset,
26971
- options[field.name ?? ""] ?? field.default ?? 0
26972
- );
26973
- }
26974
- const locator = generateZip64InfoLocator(options);
26975
- const zip64Record = generateZip64Info(options);
26976
- return concatenateArrayBuffers(zip64Record, locator, header.buffer);
26977
- }
26978
- function generateZip64Info(options) {
26979
- const record = new DataView(new ArrayBuffer(Number(ZIP64_COMMENT_OFFSET)));
26980
- for (const field of ZIP64_EOCD_FIELDS) {
26981
- setFieldToNumber(
26982
- record,
26983
- field.size,
26984
- field.offset,
26985
- options[field.name ?? ""] ?? field.default ?? 0
26986
- );
26987
- }
26988
- return record.buffer;
26989
- }
26990
- function generateZip64InfoLocator(options) {
26991
- const locator = new DataView(new ArrayBuffer(Number(20)));
26992
- for (const field of ZIP64_EOCD_LOCATOR_FIELDS) {
26993
- setFieldToNumber(
26994
- locator,
26995
- field.size,
26996
- field.offset,
26997
- options[field.name ?? ""] ?? field.default ?? 0
26998
- );
26999
- }
27000
- return locator.buffer;
27001
- }
27002
- var eoCDSignature, zip64EoCDLocatorSignature, zip64EoCDSignature, CD_RECORDS_NUMBER_OFFSET, CD_CD_BYTE_SIZE_OFFSET, CD_START_OFFSET_OFFSET, CD_COMMENT_OFFSET, ZIP64_EOCD_START_OFFSET_OFFSET, ZIP64_CD_RECORDS_NUMBER_OFFSET, ZIP64_CD_CD_BYTE_SIZE_OFFSET, ZIP64_CD_START_OFFSET_OFFSET, ZIP64_COMMENT_OFFSET, parseEoCDRecord, EOCD_FIELDS, ZIP64_EOCD_LOCATOR_FIELDS, ZIP64_EOCD_FIELDS;
27003
- var init_end_of_central_directory = __esm({
27004
- "../../modules/zip/src/parse-zip/end-of-central-directory.ts"() {
27005
- "use strict";
27006
- init_src2();
27007
- init_search_from_the_end();
27008
- init_readable_file_utils();
27009
- init_zip64_info_generation();
27010
- eoCDSignature = new Uint8Array([80, 75, 5, 6]);
27011
- zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
27012
- zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
27013
- CD_RECORDS_NUMBER_OFFSET = 8n;
27014
- CD_CD_BYTE_SIZE_OFFSET = 12n;
27015
- CD_START_OFFSET_OFFSET = 16n;
27016
- CD_COMMENT_OFFSET = 22n;
27017
- ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
27018
- ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
27019
- ZIP64_CD_CD_BYTE_SIZE_OFFSET = 40n;
27020
- ZIP64_CD_START_OFFSET_OFFSET = 48n;
27021
- ZIP64_COMMENT_OFFSET = 56n;
27022
- parseEoCDRecord = async (file) => {
27023
- const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
27024
- let cdRecordsNumber = BigInt(await readUint16(file, zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
27025
- let cdByteSize = BigInt(await readUint32(file, zipEoCDOffset + CD_CD_BYTE_SIZE_OFFSET));
27026
- let cdStartOffset = BigInt(await readUint32(file, zipEoCDOffset + CD_START_OFFSET_OFFSET));
27027
- let zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
27028
- let zip64EoCDOffset = 0n;
27029
- const magicBytes = await readRange(file, zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
27030
- if (compareArrayBuffers(magicBytes, zip64EoCDLocatorSignature.buffer)) {
27031
- zip64EoCDOffset = await readBigUint64(
27032
- file,
27033
- zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
27034
- );
27035
- const endOfCDMagicBytes = await readRange(file, zip64EoCDOffset, zip64EoCDOffset + 4n);
27036
- if (!compareArrayBuffers(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
27037
- throw new Error("zip64 EoCD not found");
27038
- }
27039
- cdRecordsNumber = await readBigUint64(file, zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
27040
- cdByteSize = await readBigUint64(file, zip64EoCDOffset + ZIP64_CD_CD_BYTE_SIZE_OFFSET);
27041
- cdStartOffset = await readBigUint64(file, zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
27042
- } else {
27043
- zip64EoCDLocatorOffset = 0n;
27044
- }
27045
- return {
27046
- cdRecordsNumber,
27047
- cdStartOffset,
27048
- cdByteSize,
27049
- offsets: {
27050
- zip64EoCDOffset,
27051
- zip64EoCDLocatorOffset,
27052
- zipEoCDOffset
27053
- }
27054
- };
27055
- };
27056
- EOCD_FIELDS = [
27057
- // End of central directory signature = 0x06054b50
27058
- {
27059
- offset: 0,
27060
- size: 4,
27061
- default: new DataView(eoCDSignature.buffer).getUint32(0, true)
27062
- },
27063
- // Number of this disk (or 0xffff for ZIP64)
27064
- {
27065
- offset: 4,
27066
- size: 2,
27067
- default: 0
27068
- },
27069
- // Disk where central directory starts (or 0xffff for ZIP64)
27070
- {
27071
- offset: 6,
27072
- size: 2,
27073
- default: 0
27074
- },
27075
- // Number of central directory records on this disk (or 0xffff for ZIP64)
27076
- {
27077
- offset: 8,
27078
- size: 2,
27079
- name: "recordsNumber"
27080
- },
27081
- // Total number of central directory records (or 0xffff for ZIP64)
27082
- {
27083
- offset: 10,
27084
- size: 2,
27085
- name: "recordsNumber"
27086
- },
27087
- // Size of central directory (bytes) (or 0xffffffff for ZIP64)
27088
- {
27089
- offset: 12,
27090
- size: 4,
27091
- name: "cdSize"
27092
- },
27093
- // Offset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)
27094
- {
27095
- offset: 16,
27096
- size: 4,
27097
- name: "cdOffset"
27098
- },
27099
- // Comment length (n)
27100
- {
27101
- offset: 20,
27102
- size: 2,
27103
- default: 0
27104
- }
27105
- ];
27106
- ZIP64_EOCD_LOCATOR_FIELDS = [
27107
- // zip64 end of central dir locator signature
27108
- {
27109
- offset: 0,
27110
- size: 4,
27111
- default: new DataView(zip64EoCDLocatorSignature.buffer).getUint32(0, true)
27112
- },
27113
- // number of the disk with the start of the zip64 end of
27114
- {
27115
- offset: 4,
27116
- size: 4,
27117
- default: 0
27118
- },
27119
- // start of the zip64 end of central directory
27120
- {
27121
- offset: 8,
27122
- size: 8,
27123
- name: "eoCDStart"
27124
- },
27125
- // total number of disks
27126
- {
27127
- offset: 16,
27128
- size: 4,
27129
- default: 1
27130
- }
27131
- ];
27132
- ZIP64_EOCD_FIELDS = [
27133
- // End of central directory signature = 0x06064b50
27134
- {
27135
- offset: 0,
27136
- size: 4,
27137
- default: new DataView(zip64EoCDSignature.buffer).getUint32(0, true)
27138
- },
27139
- // Size of the EOCD64 minus 12
27140
- {
27141
- offset: 4,
27142
- size: 8,
27143
- default: 44
27144
- },
27145
- // Version made by
27146
- {
27147
- offset: 12,
27148
- size: 2,
27149
- default: 45
27150
- },
27151
- // Version needed to extract (minimum)
27152
- {
27153
- offset: 14,
27154
- size: 2,
27155
- default: 45
27156
- },
27157
- // Number of this disk
27158
- {
27159
- offset: 16,
27160
- size: 4,
27161
- default: 0
27162
- },
27163
- // Disk where central directory starts
27164
- {
27165
- offset: 20,
27166
- size: 4,
27167
- default: 0
27168
- },
27169
- // Number of central directory records on this disk
27170
- {
27171
- offset: 24,
27172
- size: 8,
27173
- name: "recordsNumber"
27174
- },
27175
- // Total number of central directory records
27176
- {
27177
- offset: 32,
27178
- size: 8,
27179
- name: "recordsNumber"
27180
- },
27181
- // Size of central directory (bytes)
27182
- {
27183
- offset: 40,
27184
- size: 8,
27185
- name: "cdSize"
27186
- },
27187
- // Offset of start of central directory, relative to start of archive
27188
- {
27189
- offset: 48,
27190
- size: 8,
27191
- name: "cdOffset"
27192
- }
27193
- ];
27194
- }
27195
- });
27196
-
27197
- // ../../modules/zip/src/parse-zip/zip64-extra-field.ts
26940
+ // ../../modules/zip/src/lib/zip64-extra-field.ts
27198
26941
  function parseZip64ExtraField(extraField, expectedFields) {
27199
26942
  const values = {};
27200
26943
  if (expectedFields.length === 0) {
@@ -27237,537 +26980,264 @@ function parseZip64ExtraField(extraField, expectedFields) {
27237
26980
  }
27238
26981
  throw new Error("Invalid ZIP archive: required ZIP64 extended information is missing");
27239
26982
  }
27240
- var ZIP64_EXTRA_FIELD_ID, ZIP64_UINT16_SENTINEL, ZIP64_UINT32_SENTINEL;
26983
+ var ZIP64_EXTRA_FIELD_ID;
27241
26984
  var init_zip64_extra_field = __esm({
27242
- "../../modules/zip/src/parse-zip/zip64-extra-field.ts"() {
26985
+ "../../modules/zip/src/lib/zip64-extra-field.ts"() {
27243
26986
  "use strict";
27244
26987
  ZIP64_EXTRA_FIELD_ID = 1;
27245
- ZIP64_UINT16_SENTINEL = 0xffffn;
27246
- ZIP64_UINT32_SENTINEL = 0xffffffffn;
27247
26988
  }
27248
26989
  });
27249
26990
 
27250
- // ../../modules/zip/src/parse-zip/cd-file-header.ts
27251
- async function* makeZipCDHeaderIterator(fileProvider) {
27252
- const { cdStartOffset, cdByteSize } = await parseEoCDRecord(fileProvider);
27253
- const centralDirectory = new DataViewReadableFile(
27254
- new DataView(await readRange(fileProvider, cdStartOffset, cdStartOffset + cdByteSize))
27255
- );
27256
- let cdHeader = await parseZipCDFileHeader(0n, centralDirectory);
27257
- while (cdHeader) {
27258
- yield cdHeader;
27259
- cdHeader = await parseZipCDFileHeader(
27260
- cdHeader.extraOffset + BigInt(cdHeader.extraFieldLength),
27261
- centralDirectory
27262
- );
27263
- }
27264
- }
27265
- function generateCDHeader(options) {
27266
- const optionsToUse = {
27267
- ...options,
27268
- fnlength: options.fileName.length,
27269
- extraLength: 0
26991
+ // ../../modules/zip/src/lib/zip-entry-metadata.ts
26992
+ function decodeZipHeader(bytes, central) {
26993
+ const header = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
26994
+ const fixedBytes = central ? 46 : 30;
26995
+ if (bytes.byteLength < fixedBytes || header.getUint32(0, true) !== (central ? 33639248 : 67324752))
26996
+ throw new Error("Invalid ZIP archive: missing entry header");
26997
+ const nameLength = header.getUint16(central ? 28 : 26, true);
26998
+ const extraLength = header.getUint16(central ? 30 : 28, true);
26999
+ const commentLength = central ? header.getUint16(32, true) : 0;
27000
+ if (bytes.byteLength !== fixedBytes + nameLength + extraLength + commentLength)
27001
+ throw new Error("Invalid ZIP archive: truncated entry metadata");
27002
+ const flags = header.getUint16(central ? 8 : 6, true);
27003
+ const method = header.getUint16(central ? 10 : 8, true);
27004
+ if (flags & (1 | 64 | 8192)) throw new Error("Unsupported ZIP encryption");
27005
+ if (flags & ~(8 | 2048 | (method === 8 ? 6 : 0))) throw new Error("Unsupported ZIP flags");
27006
+ if (method !== 0 && method !== 8)
27007
+ throw new Error(`Unsupported ZIP compression method: ${method}`);
27008
+ let compressedSize = BigInt(header.getUint32(central ? 20 : 18, true));
27009
+ let size = BigInt(header.getUint32(central ? 24 : 22, true));
27010
+ let localHeaderOffset = central ? BigInt(header.getUint32(42, true)) : 0n;
27011
+ let disk = central ? BigInt(header.getUint16(34, true)) : 0n;
27012
+ let zip64 = compressedSize === 0xffffffffn || size === 0xffffffffn;
27013
+ const fields = [];
27014
+ if (central) {
27015
+ if (size === 0xffffffffn) fields.push({ name: "size", byteLength: 8 });
27016
+ if (compressedSize === 0xffffffffn) fields.push({ name: "compressedSize", byteLength: 8 });
27017
+ if (localHeaderOffset === 0xffffffffn) fields.push({ name: "localHeaderOffset", byteLength: 8 });
27018
+ if (disk === 0xffffn) fields.push({ name: "disk", byteLength: 4 });
27019
+ } else if (zip64)
27020
+ fields.push({ name: "size", byteLength: 8 }, { name: "compressedSize", byteLength: 8 });
27021
+ const extraBytes = bytes.subarray(fixedBytes + nameLength, fixedBytes + nameLength + extraLength);
27022
+ const extra = new DataView(extraBytes.buffer, extraBytes.byteOffset, extraBytes.byteLength);
27023
+ const extraValues = parseZip64ExtraField(extra, fields);
27024
+ if (size === 0xffffffffn) size = extraValues.size;
27025
+ if (compressedSize === 0xffffffffn) compressedSize = extraValues.compressedSize;
27026
+ if (localHeaderOffset === 0xffffffffn) localHeaderOffset = extraValues.localHeaderOffset;
27027
+ if (disk === 0xffffn) disk = extraValues.disk;
27028
+ if (disk !== 0n) throw new Error("Unsupported split ZIP archive");
27029
+ const nameBytes = bytes.subarray(fixedBytes, fixedBytes + nameLength);
27030
+ let path = decodeZipText(nameBytes, Boolean(flags & 2048));
27031
+ const commentBytes = bytes.subarray(fixedBytes + nameLength + extraLength);
27032
+ let comment = decodeZipText(commentBytes, Boolean(flags & 2048));
27033
+ for (let offset = 0; offset < extra.byteLength; ) {
27034
+ if (offset + 4 > extra.byteLength)
27035
+ throw new Error("Invalid ZIP archive: truncated extra field");
27036
+ const identifier = extra.getUint16(offset, true);
27037
+ const length = extra.getUint16(offset + 2, true);
27038
+ if (offset + 4 + length > extra.byteLength)
27039
+ throw new Error("Invalid ZIP archive: truncated extra field");
27040
+ if (!central && flags & 8 && identifier === 1) {
27041
+ if (length >= 16) zip64 = true;
27042
+ }
27043
+ if (identifier === 28789 || identifier === 25461) {
27044
+ const original = identifier === 28789 ? nameBytes : commentBytes;
27045
+ if (length < 5) throw new Error("Invalid ZIP archive: truncated Unicode extra field");
27046
+ if (extra.getUint8(offset + 4) === 1 && extra.getUint32(offset + 5, true) === calculateZipChecksum(original)) {
27047
+ const text = decodeZipText(extraBytes.subarray(offset + 9, offset + 4 + length), true);
27048
+ if (identifier === 28789) path = text;
27049
+ else comment = text;
27050
+ }
27051
+ }
27052
+ offset += 4 + length;
27053
+ }
27054
+ validateZipPath(path);
27055
+ return {
27056
+ path,
27057
+ nameBytes,
27058
+ flags,
27059
+ method,
27060
+ crc32: header.getUint32(central ? 16 : 14, true),
27061
+ compressedSize,
27062
+ size,
27063
+ localHeaderOffset,
27064
+ comment,
27065
+ zip64
27270
27066
  };
27271
- let zip64header = new ArrayBuffer(0);
27272
- const optionsToZip64 = {};
27273
- if (optionsToUse.offset >= 4294967295) {
27274
- optionsToZip64.offset = optionsToUse.offset;
27275
- optionsToUse.offset = BigInt(4294967295);
27276
- }
27277
- if (optionsToUse.length >= 4294967295) {
27278
- optionsToZip64.size = optionsToUse.length;
27279
- optionsToUse.length = 4294967295;
27280
- }
27281
- if (Object.keys(optionsToZip64).length) {
27282
- zip64header = createZip64Info(optionsToZip64);
27283
- optionsToUse.extraLength = zip64header.byteLength;
27284
- }
27285
- const header = new DataView(new ArrayBuffer(Number(CD_FILE_NAME_OFFSET)));
27286
- for (const field of ZIP_HEADER_FIELDS) {
27287
- setFieldToNumber(
27288
- header,
27289
- field.size,
27290
- field.offset,
27291
- optionsToUse[field.name ?? ""] ?? field.default ?? 0
27292
- );
27293
- }
27294
- const encodedName = new TextEncoder().encode(optionsToUse.fileName);
27295
- const resHeader = concatenateArrayBuffers(header.buffer, encodedName, zip64header);
27296
- return resHeader;
27297
27067
  }
27298
- var CD_COMPRESSED_SIZE_OFFSET, CD_UNCOMPRESSED_SIZE_OFFSET, CD_FILE_NAME_LENGTH_OFFSET, CD_EXTRA_FIELD_LENGTH_OFFSET, CD_START_DISK_OFFSET, CD_LOCAL_HEADER_OFFSET_OFFSET, CD_FILE_NAME_OFFSET, signature2, parseZipCDFileHeader, ZIP_HEADER_FIELDS;
27299
- var init_cd_file_header = __esm({
27300
- "../../modules/zip/src/parse-zip/cd-file-header.ts"() {
27301
- "use strict";
27302
- init_src2();
27303
- init_end_of_central_directory();
27304
- init_zip64_info_generation();
27305
- init_zip64_extra_field();
27306
- init_readable_file_utils();
27307
- CD_COMPRESSED_SIZE_OFFSET = 20;
27308
- CD_UNCOMPRESSED_SIZE_OFFSET = 24;
27309
- CD_FILE_NAME_LENGTH_OFFSET = 28;
27310
- CD_EXTRA_FIELD_LENGTH_OFFSET = 30;
27311
- CD_START_DISK_OFFSET = 34;
27312
- CD_LOCAL_HEADER_OFFSET_OFFSET = 42;
27313
- CD_FILE_NAME_OFFSET = 46n;
27314
- signature2 = new Uint8Array([80, 75, 1, 2]);
27315
- parseZipCDFileHeader = async (headerOffset, file) => {
27316
- const fileLength = await getReadableFileSize(file);
27317
- if (headerOffset >= fileLength) {
27318
- return null;
27319
- }
27320
- const mainHeader = await readDataView(file, headerOffset, headerOffset + CD_FILE_NAME_OFFSET);
27321
- const magicBytes = mainHeader.buffer.slice(0, 4);
27322
- if (!compareArrayBuffers(magicBytes, signature2.buffer)) {
27323
- return null;
27324
- }
27325
- const compressedSize = BigInt(mainHeader.getUint32(CD_COMPRESSED_SIZE_OFFSET, true));
27326
- const uncompressedSize = BigInt(mainHeader.getUint32(CD_UNCOMPRESSED_SIZE_OFFSET, true));
27327
- const extraFieldLength = mainHeader.getUint16(CD_EXTRA_FIELD_LENGTH_OFFSET, true);
27328
- const startDisk = BigInt(mainHeader.getUint16(CD_START_DISK_OFFSET, true));
27329
- const fileNameLength = mainHeader.getUint16(CD_FILE_NAME_LENGTH_OFFSET, true);
27330
- const additionalHeader = await readRange(
27331
- file,
27332
- headerOffset + CD_FILE_NAME_OFFSET,
27333
- headerOffset + CD_FILE_NAME_OFFSET + BigInt(fileNameLength + extraFieldLength)
27334
- );
27335
- const filenameBytes = additionalHeader.slice(0, fileNameLength);
27336
- const fileName = new TextDecoder().decode(filenameBytes);
27337
- const extraOffset = headerOffset + CD_FILE_NAME_OFFSET + BigInt(fileNameLength);
27338
- const oldFormatOffset = mainHeader.getUint32(CD_LOCAL_HEADER_OFFSET_OFFSET, true);
27339
- const localHeaderOffset = BigInt(oldFormatOffset);
27340
- const extraField = new DataView(
27341
- additionalHeader.slice(fileNameLength, additionalHeader.byteLength)
27342
- );
27343
- const zip64Data = {
27344
- uncompressedSize,
27345
- compressedSize,
27346
- localHeaderOffset,
27347
- startDisk
27348
- };
27349
- const expectedZip64Fields = [];
27350
- if (zip64Data.uncompressedSize === ZIP64_UINT32_SENTINEL) {
27351
- expectedZip64Fields.push({ name: "uncompressedSize", byteLength: 8 });
27352
- }
27353
- if (zip64Data.compressedSize === ZIP64_UINT32_SENTINEL) {
27354
- expectedZip64Fields.push({ name: "compressedSize", byteLength: 8 });
27355
- }
27356
- if (zip64Data.localHeaderOffset === ZIP64_UINT32_SENTINEL) {
27357
- expectedZip64Fields.push({ name: "localHeaderOffset", byteLength: 8 });
27358
- }
27359
- if (zip64Data.startDisk === ZIP64_UINT16_SENTINEL) {
27360
- expectedZip64Fields.push({ name: "startDisk", byteLength: 4 });
27361
- }
27362
- const zip64Values = parseZip64ExtraField(extraField, expectedZip64Fields);
27363
- return {
27364
- ...zip64Data,
27365
- ...zip64Values,
27366
- extraFieldLength,
27367
- fileNameLength,
27368
- fileName,
27369
- extraOffset
27370
- };
27371
- };
27372
- ZIP_HEADER_FIELDS = [
27373
- // Central directory file header signature = 0x02014b50
27374
- {
27375
- offset: 0,
27376
- size: 4,
27377
- default: new DataView(signature2.buffer).getUint32(0, true)
27378
- },
27379
- // Version made by
27380
- {
27381
- offset: 4,
27382
- size: 2,
27383
- default: 45
27384
- },
27385
- // Version needed to extract (minimum)
27386
- {
27387
- offset: 6,
27388
- size: 2,
27389
- default: 45
27390
- },
27391
- // General purpose bit flag
27392
- {
27393
- offset: 8,
27394
- size: 2,
27395
- default: 0
27396
- },
27397
- // Compression method
27398
- {
27399
- offset: 10,
27400
- size: 2,
27401
- default: 0
27402
- },
27403
- // File last modification time
27404
- {
27405
- offset: 12,
27406
- size: 2,
27407
- default: 0
27408
- },
27409
- // File last modification date
27410
- {
27411
- offset: 14,
27412
- size: 2,
27413
- default: 0
27414
- },
27415
- // CRC-32 of uncompressed data
27416
- {
27417
- offset: 16,
27418
- size: 4,
27419
- name: "crc32"
27420
- },
27421
- // Compressed size (or 0xffffffff for ZIP64)
27422
- {
27423
- offset: 20,
27424
- size: 4,
27425
- name: "length"
27426
- },
27427
- // Uncompressed size (or 0xffffffff for ZIP64)
27428
- {
27429
- offset: 24,
27430
- size: 4,
27431
- name: "length"
27432
- },
27433
- // File name length (n)
27434
- {
27435
- offset: 28,
27436
- size: 2,
27437
- name: "fnlength"
27438
- },
27439
- // Extra field length (m)
27440
- {
27441
- offset: 30,
27442
- size: 2,
27443
- default: 0,
27444
- name: "extraLength"
27445
- },
27446
- // File comment length (k)
27447
- {
27448
- offset: 32,
27449
- size: 2,
27450
- default: 0
27451
- },
27452
- // Disk number where file starts (or 0xffff for ZIP64)
27453
- {
27454
- offset: 34,
27455
- size: 2,
27456
- default: 0
27457
- },
27458
- // Internal file attributes
27459
- {
27460
- offset: 36,
27461
- size: 2,
27462
- default: 0
27463
- },
27464
- // External file attributes
27465
- {
27466
- offset: 38,
27467
- size: 4,
27468
- default: 0
27469
- },
27470
- // Relative offset of local file header
27471
- {
27472
- offset: 42,
27473
- size: 4,
27474
- name: "offset"
27475
- }
27476
- ];
27477
- }
27478
- });
27479
-
27480
- // ../../modules/zip/src/parse-zip/local-file-header.ts
27481
- function generateLocalHeader(options) {
27482
- const optionsToUse = {
27483
- ...options,
27484
- extraLength: 0,
27485
- fnlength: options.fileName.length
27486
- };
27487
- let zip64header = new ArrayBuffer(0);
27488
- const optionsToZip64 = {};
27489
- if (optionsToUse.length >= 4294967295) {
27490
- optionsToZip64.size = optionsToUse.length;
27491
- optionsToUse.length = 4294967295;
27492
- }
27493
- if (Object.keys(optionsToZip64).length) {
27494
- zip64header = createZip64Info(optionsToZip64);
27495
- optionsToUse.extraLength = zip64header.byteLength;
27496
- }
27497
- const header = new DataView(new ArrayBuffer(Number(FILE_NAME_OFFSET)));
27498
- for (const field of ZIP_HEADER_FIELDS2) {
27499
- setFieldToNumber(
27500
- header,
27501
- field.size,
27502
- field.offset,
27503
- optionsToUse[field.name ?? ""] ?? field.default ?? 0
27504
- );
27505
- }
27506
- const encodedName = new TextEncoder().encode(optionsToUse.fileName);
27507
- const resHeader = concatenateArrayBuffers(header.buffer, encodedName, zip64header);
27508
- return resHeader;
27068
+ function decodeZipText(bytes, utf8) {
27069
+ if (utf8) return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
27070
+ return Array.from(
27071
+ bytes,
27072
+ (value) => value < 128 ? String.fromCharCode(value) : CP437_HIGH[value - 128]
27073
+ ).join("");
27074
+ }
27075
+ function validateZipPath(path) {
27076
+ const segments = path.endsWith("/") ? path.slice(0, -1).split("/") : path.split("/");
27077
+ if (!path || path.includes("\\") || path.includes("\0") || /^[A-Za-z]:/.test(path) || segments.some((segment) => !segment || segment === "." || segment === ".."))
27078
+ throw new Error("Invalid ZIP archive: noncanonical relative path");
27079
+ }
27080
+ function calculateZipChecksum(bytes) {
27081
+ return Number.parseInt(new CRC32Hash().hashSync(bytes.slice().buffer, "hex"), 16);
27082
+ }
27083
+ function encodeUtf8Text(value) {
27084
+ const bytes = new TextEncoder().encode(value);
27085
+ if (new TextDecoder("utf-8", { ignoreBOM: true }).decode(bytes) !== value)
27086
+ throw new TypeError("ZIP names and entry comments must be well-formed Unicode");
27087
+ return bytes;
27509
27088
  }
27510
- var COMPRESSION_METHOD_OFFSET, COMPRESSED_SIZE_OFFSET, UNCOMPRESSED_SIZE_OFFSET, FILE_NAME_LENGTH_OFFSET, EXTRA_FIELD_LENGTH_OFFSET, FILE_NAME_OFFSET, signature3, parseZipLocalFileHeader, ZIP_HEADER_FIELDS2;
27511
- var init_local_file_header = __esm({
27512
- "../../modules/zip/src/parse-zip/local-file-header.ts"() {
27089
+ var CP437_HIGH;
27090
+ var init_zip_entry_metadata = __esm({
27091
+ "../../modules/zip/src/lib/zip-entry-metadata.ts"() {
27513
27092
  "use strict";
27514
- init_src2();
27515
- init_zip64_info_generation();
27093
+ init_src11();
27516
27094
  init_zip64_extra_field();
27517
- init_readable_file_utils();
27518
- COMPRESSION_METHOD_OFFSET = 8;
27519
- COMPRESSED_SIZE_OFFSET = 18;
27520
- UNCOMPRESSED_SIZE_OFFSET = 22;
27521
- FILE_NAME_LENGTH_OFFSET = 26;
27522
- EXTRA_FIELD_LENGTH_OFFSET = 28;
27523
- FILE_NAME_OFFSET = 30n;
27524
- signature3 = new Uint8Array([80, 75, 3, 4]);
27525
- parseZipLocalFileHeader = async (headerOffset, file) => {
27526
- const mainHeader = await readDataView(file, headerOffset, headerOffset + FILE_NAME_OFFSET);
27527
- const magicBytes = mainHeader.buffer.slice(0, 4);
27528
- if (!compareArrayBuffers(magicBytes, signature3.buffer)) {
27529
- return null;
27530
- }
27531
- const fileNameLength = mainHeader.getUint16(FILE_NAME_LENGTH_OFFSET, true);
27532
- const extraFieldLength = mainHeader.getUint16(EXTRA_FIELD_LENGTH_OFFSET, true);
27533
- const additionalHeader = await readRange(
27534
- file,
27535
- headerOffset + FILE_NAME_OFFSET,
27536
- headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength + extraFieldLength)
27537
- );
27538
- const fileNameBuffer = additionalHeader.slice(0, fileNameLength);
27539
- const extraDataBuffer = new DataView(
27540
- additionalHeader.slice(fileNameLength, additionalHeader.byteLength)
27541
- );
27542
- const fileName = new TextDecoder().decode(fileNameBuffer).split("\\").join("/");
27543
- const fileDataOffset = headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength + extraFieldLength);
27544
- const compressionMethod = mainHeader.getUint16(COMPRESSION_METHOD_OFFSET, true);
27545
- let compressedSize = BigInt(mainHeader.getUint32(COMPRESSED_SIZE_OFFSET, true));
27546
- const uncompressedSize = BigInt(mainHeader.getUint32(UNCOMPRESSED_SIZE_OFFSET, true));
27547
- const expectedZip64Fields = [];
27548
- if (uncompressedSize === ZIP64_UINT32_SENTINEL || compressedSize === ZIP64_UINT32_SENTINEL) {
27549
- expectedZip64Fields.push(
27550
- { name: "uncompressedSize", byteLength: 8 },
27551
- { name: "compressedSize", byteLength: 8 }
27552
- );
27553
- }
27554
- const zip64Sizes = parseZip64ExtraField(extraDataBuffer, expectedZip64Fields);
27555
- if (compressedSize === ZIP64_UINT32_SENTINEL && zip64Sizes.compressedSize !== void 0) {
27556
- compressedSize = zip64Sizes.compressedSize;
27557
- }
27558
- return {
27559
- fileNameLength,
27560
- fileName,
27561
- extraFieldLength,
27562
- fileDataOffset,
27563
- compressedSize,
27564
- compressionMethod
27565
- };
27566
- };
27567
- ZIP_HEADER_FIELDS2 = [
27568
- // Local file header signature = 0x04034b50
27569
- {
27570
- offset: 0,
27571
- size: 4,
27572
- default: new DataView(signature3.buffer).getUint32(0, true)
27573
- },
27574
- // Version needed to extract (minimum)
27575
- {
27576
- offset: 4,
27577
- size: 2,
27578
- default: 45
27579
- },
27580
- // General purpose bit flag
27581
- {
27582
- offset: 6,
27583
- size: 2,
27584
- default: 0
27585
- },
27586
- // Compression method
27587
- {
27588
- offset: 8,
27589
- size: 2,
27590
- default: 0
27591
- },
27592
- // File last modification time
27593
- {
27594
- offset: 10,
27595
- size: 2,
27596
- default: 0
27597
- },
27598
- // File last modification date
27599
- {
27600
- offset: 12,
27601
- size: 2,
27602
- default: 0
27603
- },
27604
- // CRC-32 of uncompressed data
27605
- {
27606
- offset: 14,
27607
- size: 4,
27608
- name: "crc32"
27609
- },
27610
- // Compressed size (or 0xffffffff for ZIP64)
27611
- {
27612
- offset: 18,
27613
- size: 4,
27614
- name: "length"
27615
- },
27616
- // Uncompressed size (or 0xffffffff for ZIP64)
27617
- {
27618
- offset: 22,
27619
- size: 4,
27620
- name: "length"
27621
- },
27622
- // File name length (n)
27623
- {
27624
- offset: 26,
27625
- size: 2,
27626
- name: "fnlength"
27627
- },
27628
- // Extra field length (m)
27629
- {
27630
- offset: 28,
27631
- size: 2,
27632
- default: 0,
27633
- name: "extraLength"
27634
- }
27635
- ];
27636
- }
27637
- });
27638
-
27639
- // ../../modules/zip/src/parse-zip/zip-composition.ts
27640
- async function generateFileHeaders(fileName, fileToAdd, localFileHeaderOffset) {
27641
- const newFileCRC322 = parseInt(await new CRC32Hash().hash(fileToAdd, "hex"), 16);
27642
- const newFileLocalHeader = generateLocalHeader({
27643
- crc32: newFileCRC322,
27644
- fileName,
27645
- length: fileToAdd.byteLength
27646
- });
27647
- const newFileCDHeader = generateCDHeader({
27648
- crc32: newFileCRC322,
27649
- fileName,
27650
- offset: localFileHeaderOffset,
27651
- length: fileToAdd.byteLength
27652
- });
27653
- return [
27654
- new Uint8Array(concatenateArrayBuffers(newFileLocalHeader, fileToAdd)),
27655
- new Uint8Array(newFileCDHeader)
27656
- ];
27657
- }
27658
- async function createZip(inputPath, outputPath, createAdditionalData) {
27659
- const fileIterator = getFileIterator(inputPath);
27660
- const resFile = new NodeFileFacade(outputPath, "w");
27661
- const fileList = [];
27662
- const cdArray = [];
27663
- for await (const file of fileIterator) {
27664
- await addFile(file, resFile, cdArray, fileList);
27665
- }
27666
- if (createAdditionalData) {
27667
- const additionaldata = await createAdditionalData(fileList);
27668
- await addFile(additionaldata, resFile, cdArray);
27669
- }
27670
- const cdOffset = (await resFile.stat()).bigsize;
27671
- const cd = concatenateArrayBuffers(...cdArray);
27672
- await resFile.append(new Uint8Array(cd));
27673
- const eoCDStart = (await resFile.stat()).bigsize;
27674
- await resFile.append(
27675
- new Uint8Array(
27676
- generateEoCD({ recordsNumber: cdArray.length, cdSize: cd.byteLength, cdOffset, eoCDStart })
27677
- )
27095
+ CP437_HIGH = "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0";
27096
+ }
27097
+ });
27098
+
27099
+ // ../../modules/zip/src/lib/zip-serialization.ts
27100
+ function encodeZipLocalHeader(entry) {
27101
+ validateHeaderEntry(entry);
27102
+ const bytes = new Uint8Array(30 + entry.nameBytes.length + (entry.zip64 ? 20 : 0));
27103
+ const view = new DataView(bytes.buffer);
27104
+ view.setUint32(0, 67324752, true);
27105
+ view.setUint16(4, getZipVersion(entry), true);
27106
+ view.setUint16(6, entry.flags, true);
27107
+ view.setUint16(8, entry.method, true);
27108
+ view.setUint32(10, encodeZipTimestamp(entry.date), true);
27109
+ const descriptor = Boolean(entry.flags & 8);
27110
+ view.setUint32(14, descriptor ? 0 : entry.crc32, true);
27111
+ view.setUint32(
27112
+ 18,
27113
+ entry.zip64 ? Number(ZIP32_SENTINEL) : descriptor ? 0 : Number(entry.compressedSize),
27114
+ true
27678
27115
  );
27116
+ view.setUint32(
27117
+ 22,
27118
+ entry.zip64 ? Number(ZIP32_SENTINEL) : descriptor ? 0 : Number(entry.size),
27119
+ true
27120
+ );
27121
+ view.setUint16(26, entry.nameBytes.length, true);
27122
+ view.setUint16(28, entry.zip64 ? 20 : 0, true);
27123
+ bytes.set(entry.nameBytes, 30);
27124
+ if (entry.zip64) {
27125
+ const extraOffset = 30 + entry.nameBytes.length;
27126
+ view.setUint16(extraOffset, 1, true);
27127
+ view.setUint16(extraOffset + 2, 16, true);
27128
+ view.setBigUint64(extraOffset + 4, descriptor ? 0n : entry.size, true);
27129
+ view.setBigUint64(extraOffset + 12, descriptor ? 0n : entry.compressedSize, true);
27130
+ }
27131
+ return bytes;
27679
27132
  }
27680
- async function addFile(file, resFile, cdArray, fileList) {
27681
- const size = (await resFile.stat()).bigsize;
27682
- fileList?.push({ fileName: file.path, localHeaderOffset: size });
27683
- const [localPart, cdHeaderPart] = await generateFileHeaders(file.path, file.file, size);
27684
- await resFile.append(localPart);
27685
- cdArray.push(toArrayBuffer2(cdHeaderPart));
27133
+ function encodeZipCentralHeader(entry) {
27134
+ validateHeaderEntry(entry);
27135
+ const comment = entry.commentBytes ?? new Uint8Array();
27136
+ const extraBytes = entry.zip64 ? 28 : 0;
27137
+ const bytes = new Uint8Array(46 + entry.nameBytes.length + extraBytes + comment.length);
27138
+ const view = new DataView(bytes.buffer);
27139
+ view.setUint32(0, 33639248, true);
27140
+ view.setUint16(4, entry.zip64 ? 45 : 20, true);
27141
+ view.setUint16(6, getZipVersion(entry), true);
27142
+ view.setUint16(8, entry.flags, true);
27143
+ view.setUint16(10, entry.method, true);
27144
+ view.setUint32(12, encodeZipTimestamp(entry.date), true);
27145
+ view.setUint32(16, entry.crc32, true);
27146
+ view.setUint32(20, entry.zip64 ? Number(ZIP32_SENTINEL) : Number(entry.compressedSize), true);
27147
+ view.setUint32(24, entry.zip64 ? Number(ZIP32_SENTINEL) : Number(entry.size), true);
27148
+ view.setUint16(28, entry.nameBytes.length, true);
27149
+ view.setUint16(30, extraBytes, true);
27150
+ view.setUint16(32, comment.length, true);
27151
+ view.setUint32(38, entry.directory ? 16 : 0, true);
27152
+ view.setUint32(42, entry.zip64 ? Number(ZIP32_SENTINEL) : Number(entry.localHeaderOffset), true);
27153
+ bytes.set(entry.nameBytes, 46);
27154
+ if (entry.zip64) {
27155
+ const extraOffset = 46 + entry.nameBytes.length;
27156
+ view.setUint16(extraOffset, 1, true);
27157
+ view.setUint16(extraOffset + 2, 24, true);
27158
+ view.setBigUint64(extraOffset + 4, entry.size, true);
27159
+ view.setBigUint64(extraOffset + 12, entry.compressedSize, true);
27160
+ view.setBigUint64(extraOffset + 20, entry.localHeaderOffset, true);
27161
+ }
27162
+ bytes.set(comment, 46 + entry.nameBytes.length + extraBytes);
27163
+ return bytes;
27686
27164
  }
27687
- function getFileIterator(inputPath) {
27688
- async function* iterable() {
27689
- const fileList = await getAllFiles(inputPath);
27690
- for (const filePath of fileList) {
27691
- const provider = new NodeFileFacade(path_exports.join(inputPath, filePath), "r");
27692
- const { bigsize } = await provider.stat();
27693
- const file = await provider.read(0, Number(bigsize));
27694
- await provider.close();
27695
- yield { path: filePath, file };
27696
- }
27697
- }
27698
- return iterable();
27165
+ function encodeZipEndRecords(count, directorySize, directoryOffset, zip64, comment = new Uint8Array()) {
27166
+ for (const value of [count, directorySize, directoryOffset, directoryOffset + directorySize])
27167
+ validateUint64(value);
27168
+ if (comment.length > 65535) throw new RangeError("ZIP archive comment exceeds 65535 bytes");
27169
+ if (!zip64 && (count > 0xffffn || directorySize >= ZIP32_SENTINEL || directoryOffset >= ZIP32_SENTINEL))
27170
+ throw new RangeError("ZIP32 end record capacity exceeded");
27171
+ const bytes = new Uint8Array((zip64 ? 98 : 22) + comment.length);
27172
+ const view = new DataView(bytes.buffer);
27173
+ if (zip64) {
27174
+ view.setUint32(0, 101075792, true);
27175
+ view.setBigUint64(4, 44n, true);
27176
+ view.setUint16(12, 45, true);
27177
+ view.setUint16(14, 45, true);
27178
+ view.setBigUint64(24, count, true);
27179
+ view.setBigUint64(32, count, true);
27180
+ view.setBigUint64(40, directorySize, true);
27181
+ view.setBigUint64(48, directoryOffset, true);
27182
+ view.setUint32(56, 117853008, true);
27183
+ view.setBigUint64(64, directoryOffset + directorySize, true);
27184
+ view.setUint32(72, 1, true);
27185
+ }
27186
+ const endOffset = zip64 ? 76 : 0;
27187
+ view.setUint32(endOffset, 101010256, true);
27188
+ view.setUint16(endOffset + 8, zip64 ? 65535 : Number(count), true);
27189
+ view.setUint16(endOffset + 10, zip64 ? 65535 : Number(count), true);
27190
+ view.setUint32(endOffset + 12, zip64 ? Number(ZIP32_SENTINEL) : Number(directorySize), true);
27191
+ view.setUint32(endOffset + 16, zip64 ? Number(ZIP32_SENTINEL) : Number(directoryOffset), true);
27192
+ view.setUint16(endOffset + 20, comment.length, true);
27193
+ bytes.set(comment, endOffset + 22);
27194
+ return bytes;
27699
27195
  }
27700
- async function getAllFiles(basePath, subfolder = "", fsPassed) {
27701
- const fs3 = fsPassed ? fsPassed : new NodeFileSystemFacade({});
27702
- const files = await fs3.readdir(pathJoin(basePath, subfolder));
27703
- const arrayOfFiles = [];
27704
- for (const file of files) {
27705
- const fullPath = pathJoin(basePath, subfolder, file);
27706
- if ((await fs3.stat(fullPath)).isDirectory) {
27707
- const files2 = await getAllFiles(basePath, pathJoin(subfolder, file));
27708
- arrayOfFiles.push(...files2);
27709
- } else {
27710
- arrayOfFiles.push(pathJoin(subfolder, file));
27711
- }
27712
- }
27713
- return arrayOfFiles;
27196
+ function encodeZipTimestamp(date) {
27197
+ if (!(date instanceof Date) || !Number.isFinite(date.getTime()) || date.getUTCFullYear() < 1980 || date.getUTCFullYear() > 2107)
27198
+ throw new RangeError("ZIP timestamp must be a valid UTC date in 1980\u20132107");
27199
+ const time = date.getUTCHours() << 11 | date.getUTCMinutes() << 5 | Math.floor(date.getUTCSeconds() / 2);
27200
+ const day = date.getUTCFullYear() - 1980 << 9 | date.getUTCMonth() + 1 << 5 | date.getUTCDate();
27201
+ return (day << 16 | time) >>> 0;
27202
+ }
27203
+ function getZipVersion(entry) {
27204
+ return entry.zip64 ? 45 : entry.method === 8 || entry.flags & 8 ? 20 : 10;
27205
+ }
27206
+ function validateHeaderEntry(entry) {
27207
+ if (!entry.nameBytes.length || entry.nameBytes.length > 65535 || (entry.commentBytes?.length ?? 0) > 65535)
27208
+ throw new RangeError("ZIP name/comment exceeds header capacity");
27209
+ for (const value of [entry.size, entry.compressedSize, entry.localHeaderOffset])
27210
+ validateUint64(value);
27211
+ if (!entry.zip64 && [entry.size, entry.compressedSize, entry.localHeaderOffset].some(
27212
+ (value) => value >= ZIP32_SENTINEL
27213
+ ))
27214
+ throw new RangeError("ZIP32 entry capacity exceeded");
27714
27215
  }
27715
- function pathJoin(...paths) {
27716
- const resPaths = paths.filter((val) => val.length);
27717
- return path_exports.join(...resPaths);
27216
+ function validateUint64(value) {
27217
+ if (typeof value !== "bigint" || value < 0n || value > 0xffffffffffffffffn)
27218
+ throw new RangeError("ZIP64 unsigned integer capacity exceeded");
27718
27219
  }
27719
- var init_zip_composition = __esm({
27720
- "../../modules/zip/src/parse-zip/zip-composition.ts"() {
27220
+ var ZIP32_SENTINEL;
27221
+ var init_zip_serialization = __esm({
27222
+ "../../modules/zip/src/lib/zip-serialization.ts"() {
27721
27223
  "use strict";
27722
- init_src2();
27723
- init_end_of_central_directory();
27724
- init_src11();
27725
- init_local_file_header();
27726
- init_cd_file_header();
27224
+ ZIP32_SENTINEL = 0xffffffffn;
27727
27225
  }
27728
27226
  });
27729
27227
 
27730
- // ../../modules/compression/src/lib/compression.ts
27731
- var CompressionTransform, Decompressor;
27732
- var init_compression = __esm({
27733
- "../../modules/compression/src/lib/compression.ts"() {
27228
+ // ../../modules/compression/src/deflate-decompressor-compress-utils.ts
27229
+ var DeflateCompressUtilsDecompressor;
27230
+ var init_deflate_decompressor_compress_utils = __esm({
27231
+ "../../modules/compression/src/deflate-decompressor-compress-utils.ts"() {
27734
27232
  "use strict";
27735
- init_src2();
27736
- CompressionTransform = class {
27737
- /** Preloads any dynamic libraries. May enable sync functions */
27738
- async preload(modules = {}) {
27739
- registerJSModules(modules);
27740
- return void 0;
27741
- }
27742
- // HELPERS
27743
- concatenate(asyncIterator) {
27744
- return concatenateArrayBuffersAsync(asyncIterator);
27745
- }
27746
- improveError(error) {
27747
- if (!error.message.includes(this.name)) {
27748
- error.message = `${this.name} ${error.message}`;
27749
- }
27750
- return error;
27751
- }
27752
- };
27753
- Decompressor = class extends CompressionTransform {
27754
- constructor(options) {
27755
- super();
27756
- this.decompressBatches = this.decompressBatches.bind(this);
27757
- }
27758
- /** Asynchronously decompresses data. */
27759
- async decompress(input, size) {
27760
- await this.preload();
27761
- return this.decompressSync(input, size);
27762
- }
27763
- /** Synchronously decompresses data. */
27764
- decompressSync(input, size) {
27765
- throw new Error(`${this.name}: sync decompression not supported`);
27766
- }
27767
- /** Decompresses batches. */
27768
- async *decompressBatches(asyncIterator) {
27769
- const input = await this.concatenate(asyncIterator);
27770
- yield this.decompress(input);
27233
+ init_compress_utils_compression();
27234
+ DeflateCompressUtilsDecompressor = class extends CompressUtilsDecompressor {
27235
+ constructor(options = {}) {
27236
+ super(
27237
+ { name: "deflate", contentEncodings: ["deflate"] },
27238
+ () => options.raw ? import("compress-utils/deflate/decompress") : import("compress-utils/zlib/decompress"),
27239
+ options
27240
+ );
27771
27241
  }
27772
27242
  };
27773
27243
  }
@@ -27868,680 +27338,32 @@ var init_decompression_stream = __esm({
27868
27338
  }
27869
27339
  });
27870
27340
 
27871
- // ../../modules/compression/src/lib/native-decompressor.ts
27872
- var native_decompressor_exports = {};
27873
- __export(native_decompressor_exports, {
27874
- NativeDecompressor: () => NativeDecompressor
27875
- });
27876
- var NativeDecompressor;
27877
- var init_native_decompressor = __esm({
27878
- "../../modules/compression/src/lib/native-decompressor.ts"() {
27879
- "use strict";
27880
- init_compression();
27881
- init_decompression_stream();
27882
- NativeDecompressor = class extends Decompressor {
27883
- name;
27884
- extensions;
27885
- contentEncodings;
27886
- isSupported = true;
27887
- /** Runtime stream format used for every operation. */
27888
- format;
27889
- constructor(metadata, format, options = {}) {
27890
- super(options);
27891
- this.name = metadata.name;
27892
- this.extensions = [...metadata.extensions];
27893
- this.contentEncodings = [...metadata.contentEncodings];
27894
- this.format = format;
27895
- }
27896
- /** Decompresses one buffer with the runtime-provided stream. */
27897
- async decompress(input) {
27898
- const output = await decompressWithNativeDecompressionStream(input, this.format);
27899
- if (!output) throw new Error(`${this.name}: built-in decompression is no longer available`);
27900
- return output;
27901
- }
27902
- /** Decompresses batches incrementally with the runtime-provided stream. */
27903
- async *decompressBatches(inputBatches) {
27904
- const output = decompressBatchesWithNativeDecompressionStream(inputBatches, this.format);
27905
- if (!output) throw new Error(`${this.name}: built-in decompression is no longer available`);
27906
- yield* output;
27907
- }
27908
- };
27909
- }
27910
- });
27911
-
27912
- // ../../modules/compression/src/lib/lazy-compression.ts
27913
- function mergeModules(options, modules) {
27914
- return { ...options, modules: { ...options.modules, ...modules } };
27915
- }
27916
- var LazyDecompressor;
27917
- var init_lazy_compression = __esm({
27918
- "../../modules/compression/src/lib/lazy-compression.ts"() {
27919
- "use strict";
27920
- init_compression();
27921
- init_decompression_stream();
27922
- LazyDecompressor = class extends Decompressor {
27923
- name;
27924
- extensions;
27925
- contentEncodings;
27926
- isSupported = true;
27927
- /** Constructor options retained until a concrete implementation is selected. */
27928
- options;
27929
- /** Built-in stream format to probe, or null when the format has no built-in path. */
27930
- nativeFormat;
27931
- /** Returns whether built-in selection remains eligible for the merged preload options. */
27932
- shouldUseNative;
27933
- /** Dynamically imports the balanced fallback constructor. */
27934
- loadFallback;
27935
- /** Selected concrete implementation after preload completes. */
27936
- implementation = null;
27937
- /** Shared in-flight selection used by concurrent asynchronous calls. */
27938
- implementationPromise = null;
27939
- constructor(metadata, loadFallback, options = {}, nativeFormat = null, shouldUseNative = () => true) {
27940
- super(options);
27941
- this.name = metadata.name;
27942
- this.extensions = [...metadata.extensions];
27943
- this.contentEncodings = [...metadata.contentEncodings];
27944
- this.options = options;
27945
- this.nativeFormat = nativeFormat;
27946
- this.shouldUseNative = shouldUseNative;
27947
- this.loadFallback = loadFallback;
27948
- }
27949
- /** Selects and returns the built-in or dynamically imported fallback decompressor. */
27950
- async preload(modules = {}) {
27951
- if (this.implementation) return this.implementation;
27952
- const options = mergeModules(this.options, modules);
27953
- this.implementationPromise ||= this.loadImplementation(options);
27954
- try {
27955
- this.implementation = await this.implementationPromise;
27956
- return this.implementation;
27957
- } catch (error) {
27958
- this.implementationPromise = null;
27959
- throw error;
27960
- }
27961
- }
27962
- /** Loads the selected concrete decompressor. */
27963
- async loadImplementation(options) {
27964
- if (options.useNative !== false && this.nativeFormat && this.shouldUseNative(options) && isNativeDecompressionSupported(this.nativeFormat)) {
27965
- const { NativeDecompressor: NativeDecompressor2 } = await Promise.resolve().then(() => (init_native_decompressor(), native_decompressor_exports));
27966
- return new NativeDecompressor2(this, this.nativeFormat, options);
27967
- }
27968
- const Decompressor2 = await this.loadFallback();
27969
- const implementation = new Decompressor2({ ...options, useNative: false });
27970
- await implementation.preload(options.modules);
27971
- return implementation;
27972
- }
27973
- /** Decompresses after lazily selecting the default implementation. */
27974
- async decompress(input, size) {
27975
- return (await this.preload()).decompress(input, size);
27976
- }
27977
- /** Decompresses synchronously after an implementation has been preloaded. */
27978
- decompressSync(input, size) {
27979
- if (!this.implementation) {
27980
- throw new Error(`${this.name}: call preload() before decompressSync()`);
27981
- }
27982
- return this.implementation.decompressSync(input, size);
27983
- }
27984
- /** Decompresses batches after lazily selecting the default implementation. */
27985
- async *decompressBatches(inputBatches) {
27986
- yield* (await this.preload()).decompressBatches(inputBatches);
27987
- }
27988
- };
27989
- }
27990
- });
27991
-
27992
- // ../../modules/compression/src/no-decompressor.ts
27993
- var no_decompressor_exports = {};
27994
- __export(no_decompressor_exports, {
27995
- NoDecompressor: () => NoDecompressor
27996
- });
27997
- var NoDecompressor;
27998
- var init_no_decompressor = __esm({
27999
- "../../modules/compression/src/no-decompressor.ts"() {
28000
- "use strict";
28001
- init_compression();
28002
- NoDecompressor = class extends Decompressor {
28003
- name = "uncompressed";
28004
- extensions = [];
28005
- contentEncodings = [];
28006
- isSupported = true;
28007
- constructor(options = {}) {
28008
- super(options);
28009
- }
28010
- /** Returns the input without modification. */
28011
- decompressSync(input) {
28012
- return input;
28013
- }
28014
- };
28015
- }
28016
- });
28017
-
28018
- // ../../modules/compression/src/lib/fflate/index.ts
28019
- function inflateSync(data, out) {
28020
- return inflt(data, out);
28021
- }
28022
- function gunzipSync(data, out) {
28023
- return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));
28024
- }
28025
- function unzlibSync(data, out) {
28026
- return inflt((zlv(data), data.subarray(2, -4)), out);
28027
- }
28028
- var u8, u16, u32, fleb, fdeb, clim, freb, fl, revfl, fd, revfd, rev, hMap, flt, fdt, flrm, fdrm, max, bits, bits16, shft, slc, ec, err, inflt, gzs, gzl, zlv, Inflate, Gunzip, Unzlib;
28029
- var init_fflate = __esm({
28030
- "../../modules/compression/src/lib/fflate/index.ts"() {
28031
- "use strict";
28032
- u8 = Uint8Array;
28033
- u16 = Uint16Array;
28034
- u32 = Uint32Array;
28035
- fleb = new u8([
28036
- 0,
28037
- 0,
28038
- 0,
28039
- 0,
28040
- 0,
28041
- 0,
28042
- 0,
28043
- 0,
28044
- 1,
28045
- 1,
28046
- 1,
28047
- 1,
28048
- 2,
28049
- 2,
28050
- 2,
28051
- 2,
28052
- 3,
28053
- 3,
28054
- 3,
28055
- 3,
28056
- 4,
28057
- 4,
28058
- 4,
28059
- 4,
28060
- 5,
28061
- 5,
28062
- 5,
28063
- 5,
28064
- 0,
28065
- /* unused */
28066
- 0,
28067
- 0,
28068
- /* impossible */
28069
- 0
28070
- ]);
28071
- fdeb = new u8([
28072
- 0,
28073
- 0,
28074
- 0,
28075
- 0,
28076
- 1,
28077
- 1,
28078
- 2,
28079
- 2,
28080
- 3,
28081
- 3,
28082
- 4,
28083
- 4,
28084
- 5,
28085
- 5,
28086
- 6,
28087
- 6,
28088
- 7,
28089
- 7,
28090
- 8,
28091
- 8,
28092
- 9,
28093
- 9,
28094
- 10,
28095
- 10,
28096
- 11,
28097
- 11,
28098
- 12,
28099
- 12,
28100
- 13,
28101
- 13,
28102
- /* unused */
28103
- 0,
28104
- 0
28105
- ]);
28106
- clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
28107
- freb = (eb, start) => {
28108
- const b = new u16(31);
28109
- for (let i = 0; i < 31; ++i) {
28110
- b[i] = start += 1 << eb[i - 1];
28111
- }
28112
- const r = new u32(b[30]);
28113
- for (let i = 1; i < 30; ++i) {
28114
- for (let j = b[i]; j < b[i + 1]; ++j) {
28115
- r[j] = j - b[i] << 5 | i;
28116
- }
28117
- }
28118
- return [b, r];
28119
- };
28120
- [fl, revfl] = freb(fleb, 2);
28121
- fl[28] = 258, revfl[258] = 28;
28122
- [fd, revfd] = freb(fdeb, 0);
28123
- rev = new u16(32768);
28124
- for (let i = 0; i < 32768; ++i) {
28125
- let x = (i & 43690) >>> 1 | (i & 21845) << 1;
28126
- x = (x & 52428) >>> 2 | (x & 13107) << 2;
28127
- x = (x & 61680) >>> 4 | (x & 3855) << 4;
28128
- rev[i] = ((x & 65280) >>> 8 | (x & 255) << 8) >>> 1;
28129
- }
28130
- hMap = (cd, mb, r) => {
28131
- const s = cd.length;
28132
- let i = 0;
28133
- const l = new u16(mb);
28134
- for (; i < s; ++i) {
28135
- if (cd[i]) ++l[cd[i] - 1];
28136
- }
28137
- const le = new u16(mb);
28138
- for (i = 0; i < mb; ++i) {
28139
- le[i] = le[i - 1] + l[i - 1] << 1;
28140
- }
28141
- let co;
28142
- if (r) {
28143
- co = new u16(1 << mb);
28144
- const rvb = 15 - mb;
28145
- for (i = 0; i < s; ++i) {
28146
- if (cd[i]) {
28147
- const sv = i << 4 | cd[i];
28148
- const r2 = mb - cd[i];
28149
- let v = le[cd[i] - 1]++ << r2;
28150
- for (const m = v | (1 << r2) - 1; v <= m; ++v) {
28151
- co[rev[v] >>> rvb] = sv;
28152
- }
28153
- }
28154
- }
28155
- } else {
28156
- co = new u16(s);
28157
- for (i = 0; i < s; ++i) {
28158
- if (cd[i]) {
28159
- co[i] = rev[le[cd[i] - 1]++] >>> 15 - cd[i];
28160
- }
28161
- }
28162
- }
28163
- return co;
28164
- };
28165
- flt = new u8(288);
28166
- for (let i = 0; i < 144; ++i) flt[i] = 8;
28167
- for (let i = 144; i < 256; ++i) flt[i] = 9;
28168
- for (let i = 256; i < 280; ++i) flt[i] = 7;
28169
- for (let i = 280; i < 288; ++i) flt[i] = 8;
28170
- fdt = new u8(32);
28171
- for (let i = 0; i < 32; ++i) fdt[i] = 5;
28172
- flrm = /* @__PURE__ */ hMap(flt, 9, 1);
28173
- fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
28174
- max = (a) => {
28175
- let m = a[0];
28176
- for (let i = 1; i < a.length; ++i) {
28177
- if (a[i] > m) m = a[i];
28178
- }
28179
- return m;
28180
- };
28181
- bits = (d, p, m) => {
28182
- const o = p / 8 | 0;
28183
- return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
28184
- };
28185
- bits16 = (d, p) => {
28186
- const o = p / 8 | 0;
28187
- return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
28188
- };
28189
- shft = (p) => (p + 7) / 8 | 0;
28190
- slc = (v, s, e) => {
28191
- if (s == null || s < 0) s = 0;
28192
- if (e == null || e > v.length) e = v.length;
28193
- const n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s);
28194
- n.set(v.subarray(s, e));
28195
- return n;
28196
- };
28197
- ec = [
28198
- "unexpected EOF",
28199
- "invalid block type",
28200
- "invalid length/literal",
28201
- "invalid distance",
28202
- "stream finished",
28203
- "no stream handler",
28204
- ,
28205
- // determined by compression function
28206
- "no callback",
28207
- "invalid UTF-8 data",
28208
- "extra field too long",
28209
- "date not in range 1980-2099",
28210
- "filename too long",
28211
- "stream finishing",
28212
- "invalid zip data"
28213
- // determined by unknown compression method
28214
- ];
28215
- err = (ind, msg, nt) => {
28216
- const e = new Error(msg || ec[ind]);
28217
- e.code = ind;
28218
- if (Error.captureStackTrace) Error.captureStackTrace(e, err);
28219
- if (!nt) throw e;
28220
- return e;
28221
- };
28222
- inflt = (dat, buf, st) => {
28223
- const sl = dat.length;
28224
- if (!sl || st && st.f && !st.l) return buf || new u8(0);
28225
- const noBuf = !buf || st;
28226
- const noSt = !st || st.i;
28227
- if (!st) st = {};
28228
- if (!buf) buf = new u8(sl * 3);
28229
- const cbuf = (l) => {
28230
- let bl = buf.length;
28231
- if (l > bl) {
28232
- const nbuf = new u8(Math.max(bl * 2, l));
28233
- nbuf.set(buf);
28234
- buf = nbuf;
28235
- }
28236
- };
28237
- 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;
28238
- const tbts = sl * 8;
28239
- do {
28240
- if (!lm) {
28241
- final = bits(dat, pos, 1);
28242
- const type = bits(dat, pos + 1, 3);
28243
- pos += 3;
28244
- if (!type) {
28245
- const s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
28246
- if (t > sl) {
28247
- if (noSt) err(0);
28248
- break;
28249
- }
28250
- if (noBuf) cbuf(bt + l);
28251
- buf.set(dat.subarray(s, t), bt);
28252
- st.b = bt += l, st.p = pos = t * 8, st.f = final;
28253
- continue;
28254
- } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
28255
- else if (type == 2) {
28256
- const hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
28257
- const tl = hLit + bits(dat, pos + 5, 31) + 1;
28258
- pos += 14;
28259
- const ldt = new u8(tl);
28260
- const clt = new u8(19);
28261
- for (let i = 0; i < hcLen; ++i) {
28262
- clt[clim[i]] = bits(dat, pos + i * 3, 7);
28263
- }
28264
- pos += hcLen * 3;
28265
- const clb = max(clt), clbmsk = (1 << clb) - 1;
28266
- const clm = hMap(clt, clb, 1);
28267
- for (let i = 0; i < tl; ) {
28268
- const r = clm[bits(dat, pos, clbmsk)];
28269
- pos += r & 15;
28270
- const s = r >>> 4;
28271
- if (s < 16) {
28272
- ldt[i++] = s;
28273
- } else {
28274
- let c = 0, n = 0;
28275
- if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
28276
- else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;
28277
- else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
28278
- while (n--) ldt[i++] = c;
28279
- }
28280
- }
28281
- const lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
28282
- lbt = max(lt);
28283
- dbt = max(dt);
28284
- lm = hMap(lt, lbt, 1);
28285
- dm = hMap(dt, dbt, 1);
28286
- } else err(1);
28287
- if (pos > tbts) {
28288
- if (noSt) err(0);
28289
- break;
28290
- }
28291
- }
28292
- if (noBuf) cbuf(bt + 131072);
28293
- const lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
28294
- let lpos = pos;
28295
- for (; ; lpos = pos) {
28296
- const c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
28297
- pos += c & 15;
28298
- if (pos > tbts) {
28299
- if (noSt) err(0);
28300
- break;
28301
- }
28302
- if (!c) err(2);
28303
- if (sym < 256) buf[bt++] = sym;
28304
- else if (sym == 256) {
28305
- lpos = pos, lm = void 0;
28306
- break;
28307
- } else {
28308
- let add = sym - 254;
28309
- if (sym > 264) {
28310
- const i = sym - 257, b = fleb[i];
28311
- add = bits(dat, pos, (1 << b) - 1) + fl[i];
28312
- pos += b;
28313
- }
28314
- const d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
28315
- if (!d) err(3);
28316
- pos += d & 15;
28317
- let dt = fd[dsym];
28318
- if (dsym > 3) {
28319
- const b = fdeb[dsym];
28320
- dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
28321
- }
28322
- if (pos > tbts) {
28323
- if (noSt) err(0);
28324
- break;
28325
- }
28326
- if (noBuf) cbuf(bt + 131072);
28327
- const end = bt + add;
28328
- for (; bt < end; bt += 4) {
28329
- buf[bt] = buf[bt - dt];
28330
- buf[bt + 1] = buf[bt + 1 - dt];
28331
- buf[bt + 2] = buf[bt + 2 - dt];
28332
- buf[bt + 3] = buf[bt + 3 - dt];
28333
- }
28334
- bt = end;
28335
- }
28336
- }
28337
- st.l = lm, st.p = lpos, st.b = bt, st.f = final;
28338
- if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
28339
- } while (!final);
28340
- return bt == buf.length ? buf : slc(buf, 0, bt);
28341
- };
28342
- gzs = (d) => {
28343
- if (d[0] != 31 || d[1] != 139 || d[2] != 8) err(6, "invalid gzip data");
28344
- const flg = d[3];
28345
- let st = 10;
28346
- if (flg & 4) st += d[10] | (d[11] << 8) + 2;
28347
- for (let zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++]) ;
28348
- return st + (flg & 2);
28349
- };
28350
- gzl = (d) => {
28351
- const l = d.length;
28352
- return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
28353
- };
28354
- zlv = (d) => {
28355
- if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || (d[0] << 8 | d[1]) % 31) err(6, "invalid zlib data");
28356
- if (d[1] & 32) err(6, "invalid zlib data: preset dictionaries not supported");
28357
- };
28358
- Inflate = class {
28359
- /**
28360
- * Creates an inflation stream
28361
- * @param cb The callback to call whenever data is inflated
28362
- */
28363
- constructor(cb) {
28364
- this.ondata = cb;
28365
- }
28366
- /** Persistent bit-reader and Huffman decoding state. */
28367
- s = {};
28368
- /** Compression options or retained output window for this stream. */
28369
- o;
28370
- /** Compressed bytes pending decoding. */
28371
- p = new u8(0);
28372
- /** Whether the stream has received its final chunk. */
28373
- d;
28374
- /**
28375
- * The handler to call whenever data is available
28376
- */
28377
- ondata;
28378
- /** Appends pending input after checking stream lifecycle. */
28379
- e(c) {
28380
- if (!this.ondata) err(5);
28381
- if (this.d) err(4);
28382
- const l = this.p.length;
28383
- const n = new u8(l + c.length);
28384
- n.set(this.p), n.set(c, l), this.p = n;
28385
- }
28386
- /** Decodes pending input and retains the sliding window. */
28387
- c(final) {
28388
- this.d = this.s.i = final || false;
28389
- const bts = this.s.b;
28390
- const dt = inflt(this.p, this.o, this.s);
28391
- this.ondata(slc(dt, bts, this.s.b), this.d);
28392
- this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;
28393
- this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;
28394
- }
28395
- /**
28396
- * Pushes a chunk to be inflated
28397
- * @param chunk The chunk to push
28398
- * @param final Whether this is the final chunk
28399
- */
28400
- push(chunk, final) {
28401
- this.e(chunk), this.c(final);
28402
- }
28403
- };
28404
- Gunzip = class extends Inflate {
28405
- /** Whether the stream header still needs to be emitted or consumed. */
28406
- v = 1;
28407
- /**
28408
- * Creates a GUNZIP stream
28409
- * @param cb The callback to call whenever data is inflated
28410
- */
28411
- constructor(cb) {
28412
- super(cb);
28413
- }
28414
- /**
28415
- * Pushes a chunk to be GUNZIPped
28416
- * @param chunk The chunk to push
28417
- * @param final Whether this is the last chunk
28418
- */
28419
- push(chunk, final) {
28420
- Inflate.prototype.e.call(this, chunk);
28421
- if (this.v) {
28422
- const s = this.p.length > 3 ? gzs(this.p) : 4;
28423
- if (s >= this.p.length && !final) return;
28424
- this.p = this.p.subarray(s), this.v = 0;
28425
- }
28426
- if (final) {
28427
- if (this.p.length < 8) err(6, "invalid gzip data");
28428
- this.p = this.p.subarray(0, -8);
28429
- }
28430
- Inflate.prototype.c.call(this, final);
28431
- }
28432
- };
28433
- Unzlib = class extends Inflate {
28434
- /** Whether the stream header still needs to be emitted or consumed. */
28435
- v = 1;
28436
- /**
28437
- * Creates a Zlib decompression stream
28438
- * @param cb The callback to call whenever data is inflated
28439
- */
28440
- constructor(cb) {
28441
- super(cb);
28442
- }
28443
- /**
28444
- * Pushes a chunk to be unzlibbed
28445
- * @param chunk The chunk to push
28446
- * @param final Whether this is the last chunk
28447
- */
28448
- push(chunk, final) {
28449
- Inflate.prototype.e.call(this, chunk);
28450
- if (this.v) {
28451
- if (this.p.length < 2 && !final) return;
28452
- this.p = this.p.subarray(2), this.v = 0;
28453
- }
28454
- if (final) {
28455
- if (this.p.length < 4) err(6, "invalid zlib data");
28456
- this.p = this.p.subarray(0, -4);
28457
- }
28458
- Inflate.prototype.c.call(this, final);
28459
- }
28460
- };
28461
- }
28462
- });
28463
-
28464
- // ../../modules/compression/src/lib/fflate-stream.ts
28465
- async function* transformFflateBatches(processor, inputBatches) {
28466
- const chunks = [];
28467
- processor.ondata = (data) => {
28468
- chunks.push(data.slice().buffer);
28469
- };
28470
- for await (const batch of inputBatches) {
28471
- processor.push(new Uint8Array(batch), false);
28472
- yield* chunks.splice(0);
28473
- }
28474
- processor.push(new Uint8Array(0), true);
28475
- yield* chunks;
28476
- }
28477
- var init_fflate_stream = __esm({
28478
- "../../modules/compression/src/lib/fflate-stream.ts"() {
28479
- "use strict";
28480
- }
28481
- });
28482
-
28483
- // ../../modules/compression/src/deflate-decompressor-fflate.ts
28484
- var DeflateFflateDecompressor;
28485
- var init_deflate_decompressor_fflate = __esm({
28486
- "../../modules/compression/src/deflate-decompressor-fflate.ts"() {
28487
- "use strict";
28488
- init_fflate();
28489
- init_compression();
28490
- init_fflate_stream();
28491
- DeflateFflateDecompressor = class extends Decompressor {
28492
- name = "deflate";
28493
- extensions = [];
28494
- contentEncodings = ["deflate"];
28495
- isSupported = true;
28496
- options;
28497
- constructor(options = {}) {
28498
- super(options);
28499
- this.options = options;
28500
- }
28501
- /** Decompresses one zlib-wrapped DEFLATE payload synchronously. */
28502
- decompressSync(input) {
28503
- const bytes = new Uint8Array(input);
28504
- const output = this.options.raw ? inflateSync(bytes) : unzlibSync(bytes);
28505
- return output.slice().buffer;
28506
- }
28507
- /** Decompresses DEFLATE batches incrementally. */
28508
- async *decompressBatches(inputBatches) {
28509
- const processor = this.options.raw ? new Inflate() : new Unzlib();
28510
- yield* transformFflateBatches(processor, inputBatches);
28511
- }
28512
- };
28513
- }
28514
- });
28515
-
28516
27341
  // ../../modules/compression/src/deflate-decompressor.ts
28517
- var deflate_decompressor_exports = {};
28518
- __export(deflate_decompressor_exports, {
28519
- DeflateDecompressor: () => DeflateDecompressor
28520
- });
28521
27342
  var DeflateDecompressor;
28522
27343
  var init_deflate_decompressor = __esm({
28523
27344
  "../../modules/compression/src/deflate-decompressor.ts"() {
28524
27345
  "use strict";
28525
- init_deflate_decompressor_fflate();
27346
+ init_deflate_decompressor_compress_utils();
28526
27347
  init_decompression_stream();
28527
- DeflateDecompressor = class extends DeflateFflateDecompressor {
28528
- constructor(options = {}) {
28529
- super(options);
28530
- }
28531
- /** Decompresses with the built-in stream when available, then falls back to fflate. */
28532
- async decompress(input) {
27348
+ DeflateDecompressor = class extends DeflateCompressUtilsDecompressor {
27349
+ /** Decompresses with native streams when available, otherwise lazily initializes WASM. */
27350
+ async decompress(input, size) {
28533
27351
  if (this.options.useNative !== false) {
28534
- const format = this.options.raw ? "deflate-raw" : "deflate";
28535
- const output = await decompressWithNativeDecompressionStream(input, format);
27352
+ const output = await decompressWithNativeDecompressionStream(
27353
+ input,
27354
+ this.options.raw ? "deflate-raw" : "deflate"
27355
+ );
28536
27356
  if (output) return output;
28537
27357
  }
28538
- return this.decompressSync(input);
27358
+ return super.decompress(input, size);
28539
27359
  }
28540
- /** Decompresses batches with a built-in or fflate stream. */
27360
+ /** Streams native batches when available, otherwise uses the WASM stream. */
28541
27361
  async *decompressBatches(inputBatches) {
28542
27362
  if (this.options.useNative !== false) {
28543
- const format = this.options.raw ? "deflate-raw" : "deflate";
28544
- const output = decompressBatchesWithNativeDecompressionStream(inputBatches, format);
27363
+ const output = decompressBatchesWithNativeDecompressionStream(
27364
+ inputBatches,
27365
+ this.options.raw ? "deflate-raw" : "deflate"
27366
+ );
28545
27367
  if (output) {
28546
27368
  yield* output;
28547
27369
  return;
@@ -28553,303 +27375,679 @@ var init_deflate_decompressor = __esm({
28553
27375
  }
28554
27376
  });
28555
27377
 
28556
- // ../../modules/compression/src/gzip-decompressor-fflate.ts
28557
- var GZipFflateDecompressor;
28558
- var init_gzip_decompressor_fflate = __esm({
28559
- "../../modules/compression/src/gzip-decompressor-fflate.ts"() {
28560
- "use strict";
28561
- init_fflate();
28562
- init_compression();
28563
- init_fflate_stream();
28564
- GZipFflateDecompressor = class extends Decompressor {
28565
- name = "gzip";
28566
- extensions = ["gz", "gzip"];
28567
- contentEncodings = ["gzip", "x-gzip"];
28568
- isSupported = true;
28569
- constructor(options = {}) {
28570
- super(options);
28571
- }
28572
- /** Decompresses one GZIP payload synchronously. */
28573
- decompressSync(input) {
28574
- return gunzipSync(new Uint8Array(input)).slice().buffer;
28575
- }
28576
- /** Decompresses GZIP batches incrementally. */
28577
- async *decompressBatches(inputBatches) {
28578
- yield* transformFflateBatches(new Gunzip(), inputBatches);
28579
- }
28580
- };
28581
- }
28582
- });
28583
-
28584
- // ../../modules/compression/src/gzip-decompressor.ts
28585
- var gzip_decompressor_exports = {};
28586
- __export(gzip_decompressor_exports, {
28587
- GZipDecompressor: () => GZipDecompressor
28588
- });
28589
- var GZipDecompressor;
28590
- var init_gzip_decompressor = __esm({
28591
- "../../modules/compression/src/gzip-decompressor.ts"() {
27378
+ // ../../modules/zip/src/zip-archive.ts
27379
+ async function openZipArchive(input, options = {}) {
27380
+ return await ZipArchive.open(input, options);
27381
+ }
27382
+ function normalizeZipInput(input) {
27383
+ if (input instanceof ArrayBuffer) return new BlobFile(input);
27384
+ if (ArrayBuffer.isView(input))
27385
+ return new BlobFile(
27386
+ new Blob([new Uint8Array(input.buffer, input.byteOffset, input.byteLength).slice()])
27387
+ );
27388
+ if (input instanceof Blob) return new BlobFile(input);
27389
+ return input;
27390
+ }
27391
+ function minimumBigInt(left, right) {
27392
+ return left < right ? left : right;
27393
+ }
27394
+ var DEFAULT_OPTIONS, ZipArchive;
27395
+ var init_zip_archive = __esm({
27396
+ "../../modules/zip/src/zip-archive.ts"() {
28592
27397
  "use strict";
28593
- init_gzip_decompressor_fflate();
28594
- init_decompression_stream();
28595
- GZipDecompressor = class extends GZipFflateDecompressor {
28596
- options;
28597
- constructor(options = {}) {
28598
- super(options);
28599
- this.options = options;
28600
- }
28601
- /** Decompresses with the built-in stream when available, then falls back to fflate. */
28602
- async decompress(input) {
28603
- if (this.options.useNative !== false) {
28604
- const output = await decompressWithNativeDecompressionStream(input, "gzip");
28605
- if (output) return output;
27398
+ init_src2();
27399
+ init_deflate_decompressor();
27400
+ init_src11();
27401
+ init_zip_entry_metadata();
27402
+ init_zip_serialization();
27403
+ DEFAULT_OPTIONS = {
27404
+ maxArchiveBytes: 1024n ** 4n,
27405
+ maxDirectoryBytes: 32 * 1024 * 1024,
27406
+ maxEntries: 1e5,
27407
+ maxReadBytes: 1024 * 1024,
27408
+ maxCompressedBytes: 64n * 1024n * 1024n,
27409
+ maxDecodedBytes: 64n * 1024n * 1024n,
27410
+ chunkBytes: 64 * 1024
27411
+ };
27412
+ ZipArchive = class _ZipArchive {
27413
+ /** Archive byte length, without losing ZIP64 precision. */
27414
+ size;
27415
+ /** Archive comment, decoded using legacy ZIP CP437. */
27416
+ comment;
27417
+ /** Shared file limits captured at open time. */
27418
+ limits;
27419
+ /** Owned random-access transport. */
27420
+ file;
27421
+ /** File lifetime, including in-flight operations. */
27422
+ controller = new AbortController();
27423
+ /** Initialization/caller cancellation combined with close. */
27424
+ signal;
27425
+ /** Validated directory boundary. */
27426
+ directory;
27427
+ /** A single directory-index promise shared by concurrent lookups. */
27428
+ directoryPromise;
27429
+ /** Local-header validation shared by repeated path reads. */
27430
+ entriesByOffset = /* @__PURE__ */ new Map();
27431
+ /** Central-validated named lookups share their local-header work. */
27432
+ entriesByPath = /* @__PURE__ */ new Map();
27433
+ /** Next local-header boundary for central-validated, nonoverlapping payloads. */
27434
+ nextOffsets = /* @__PURE__ */ new Map();
27435
+ /** Only entries issued by this archive can be used for reads. */
27436
+ issuedEntries = /* @__PURE__ */ new WeakSet();
27437
+ /** Idempotent file cleanup, including open failure. */
27438
+ closePromise;
27439
+ /** Captures the owned transport and validates independent limits. */
27440
+ constructor(file, size, options) {
27441
+ this.file = file;
27442
+ this.size = size;
27443
+ this.comment = "";
27444
+ this.limits = {
27445
+ maxArchiveBytes: options.maxArchiveBytes ?? DEFAULT_OPTIONS.maxArchiveBytes,
27446
+ maxDirectoryBytes: options.maxDirectoryBytes ?? DEFAULT_OPTIONS.maxDirectoryBytes,
27447
+ maxEntries: options.maxEntries ?? DEFAULT_OPTIONS.maxEntries,
27448
+ maxReadBytes: options.maxReadBytes ?? DEFAULT_OPTIONS.maxReadBytes,
27449
+ maxCompressedBytes: options.maxCompressedBytes ?? DEFAULT_OPTIONS.maxCompressedBytes,
27450
+ maxDecodedBytes: options.maxDecodedBytes ?? DEFAULT_OPTIONS.maxDecodedBytes,
27451
+ chunkBytes: options.chunkBytes ?? DEFAULT_OPTIONS.chunkBytes
27452
+ };
27453
+ for (const [name18, value] of Object.entries(this.limits)) {
27454
+ const bigintLimit = ["maxArchiveBytes", "maxCompressedBytes", "maxDecodedBytes"].includes(
27455
+ name18
27456
+ );
27457
+ if (bigintLimit ? typeof value !== "bigint" || value < 0n : typeof value !== "number" || !Number.isSafeInteger(value) || value < 1)
27458
+ throw new RangeError(`Invalid ZIP ${name18} limit`);
28606
27459
  }
28607
- return this.decompressSync(input);
27460
+ this.signal = options.signal ? AbortSignal.any([this.controller.signal, options.signal]) : this.controller.signal;
28608
27461
  }
28609
- /** Decompresses batches with a built-in or fflate stream. */
28610
- async *decompressBatches(inputBatches) {
28611
- if (this.options.useNative !== false) {
28612
- const output = decompressBatchesWithNativeDecompressionStream(inputBatches, "gzip");
28613
- if (output) {
28614
- yield* output;
28615
- return;
28616
- }
27462
+ /** Initializes directory bounds without scanning entries or reading their payloads. */
27463
+ static async open(input, options = {}) {
27464
+ const file = normalizeZipInput(input);
27465
+ let archive;
27466
+ try {
27467
+ const advertisedSize = file.bigsize;
27468
+ const status = advertisedSize === void 0 || advertisedSize === 0n ? await file.stat?.() : void 0;
27469
+ const reportedBigsize = status?.bigsize ?? file.bigsize;
27470
+ const size = reportedBigsize !== void 0 && reportedBigsize !== 0n ? reportedBigsize : BigInt(status?.size || file.size);
27471
+ archive = new _ZipArchive(file, size, options);
27472
+ archive.signal.throwIfAborted();
27473
+ if (size < 22n || size > archive.limits.maxArchiveBytes)
27474
+ throw new RangeError("ZIP archive size limit or minimum header size");
27475
+ archive.directory = await archive.readDirectoryLocation();
27476
+ Object.defineProperty(archive, "comment", { value: archive.directory.comment });
27477
+ return archive;
27478
+ } catch (error) {
27479
+ if (archive) await archive.close();
27480
+ else await file.close();
27481
+ throw error;
28617
27482
  }
28618
- yield* super.decompressBatches(inputBatches);
28619
- }
28620
- };
28621
- }
28622
- });
28623
-
28624
- // ../../modules/compression/src/default-codecs.ts
28625
- var UNCOMPRESSED, DEFLATE, GZIP, NoDecompressor2, DeflateDecompressor2, GZipDecompressor2;
28626
- var init_default_codecs = __esm({
28627
- "../../modules/compression/src/default-codecs.ts"() {
28628
- "use strict";
28629
- init_lazy_compression();
28630
- UNCOMPRESSED = { name: "uncompressed", extensions: [], contentEncodings: [] };
28631
- DEFLATE = { name: "deflate", extensions: [], contentEncodings: ["deflate"] };
28632
- GZIP = { name: "gzip", extensions: ["gz"], contentEncodings: ["gzip"] };
28633
- NoDecompressor2 = class extends LazyDecompressor {
28634
- constructor(options = {}) {
28635
- super(UNCOMPRESSED, async () => (await Promise.resolve().then(() => (init_no_decompressor(), no_decompressor_exports))).NoDecompressor, options);
28636
27483
  }
28637
- };
28638
- DeflateDecompressor2 = class extends LazyDecompressor {
28639
- constructor(options = {}) {
28640
- super(
28641
- DEFLATE,
28642
- async () => (await Promise.resolve().then(() => (init_deflate_decompressor(), deflate_decompressor_exports))).DeflateDecompressor,
28643
- options,
28644
- options.raw ? "deflate-raw" : "deflate"
28645
- );
28646
- }
28647
- };
28648
- GZipDecompressor2 = class extends LazyDecompressor {
28649
- constructor(options = {}) {
28650
- super(
28651
- GZIP,
28652
- async () => (await Promise.resolve().then(() => (init_gzip_decompressor(), gzip_decompressor_exports))).GZipDecompressor,
28653
- options,
28654
- "gzip"
28655
- );
28656
- }
28657
- };
28658
- }
28659
- });
28660
-
28661
- // ../../modules/compression/src/index.ts
28662
- var init_src12 = __esm({
28663
- "../../modules/compression/src/index.ts"() {
28664
- "use strict";
28665
- init_default_codecs();
28666
- }
28667
- });
28668
-
28669
- // ../../modules/zip/src/filesystems/zip-filesystem.ts
28670
- var ZIP_COMPRESSION_HANDLERS, ZipFileSystem;
28671
- var init_zip_filesystem = __esm({
28672
- "../../modules/zip/src/filesystems/zip-filesystem.ts"() {
28673
- "use strict";
28674
- init_src2();
28675
- init_cd_file_header();
28676
- init_local_file_header();
28677
- init_src12();
28678
- init_IndexedArchive();
28679
- init_readable_file_utils();
28680
- ZIP_COMPRESSION_HANDLERS = {
28681
- /** No compression */
28682
- 0: async (compressedFile) => compressedFile,
28683
- /** Deflation */
28684
- 8: async (compressedFile) => {
28685
- const compression = new DeflateDecompressor2({ raw: true });
28686
- const decompressedData = await compression.decompress(compressedFile);
28687
- return decompressedData;
28688
- }
28689
- };
28690
- ZipFileSystem = class {
28691
- /** File instance */
28692
- file = null;
28693
- fileName;
28694
- archive = null;
28695
27484
  /**
28696
- * Constructor
28697
- * @param file - instance of ReadableFile or file path string
27485
+ * Appends one STORE entry through validated container metadata and the native serializer.
27486
+ * Internal composition operation: callers own the writable file and discard it on write failure.
27487
+ * Existing payload offsets, central metadata and archive comments are retained.
28698
27488
  */
28699
- constructor(file) {
28700
- if (typeof file === "string") {
28701
- this.fileName = file;
28702
- if (isBrowser) {
28703
- throw new Error("ZipFileSystem cannot open file paths in browser environments");
27489
+ static async appendEntry(file, path, data, options = {}) {
27490
+ const archive = await _ZipArchive.open(file, options);
27491
+ try {
27492
+ validateZipPath(path);
27493
+ if (archive.directory.offset > BigInt(Number.MAX_SAFE_INTEGER))
27494
+ throw new RangeError("ZIP append transport offset exceeds safe integer range");
27495
+ if (await archive.getEntry(path)) throw new Error("ZIP entry already exists");
27496
+ for await (const _entry of archive.entries()) {
28704
27497
  }
28705
- this.file = new NodeFileFacade(file);
28706
- } else if (file instanceof Blob || file instanceof ArrayBuffer) {
28707
- this.file = new BlobFile(file);
28708
- } else if (file instanceof IndexedArchive) {
28709
- this.file = file.file;
28710
- this.archive = file;
28711
- this.fileName = file.fileName;
28712
- } else {
28713
- this.file = file;
27498
+ const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
27499
+ if (path.endsWith("/") && bytes.length)
27500
+ throw new Error("ZIP directory payload must be empty");
27501
+ const entry = {
27502
+ nameBytes: encodeUtf8Text(path),
27503
+ date: /* @__PURE__ */ new Date("1980-01-01T00:00:00Z"),
27504
+ flags: 2048,
27505
+ method: 0,
27506
+ crc32: 0,
27507
+ size: BigInt(bytes.length),
27508
+ compressedSize: BigInt(bytes.length),
27509
+ localHeaderOffset: archive.directory.offset,
27510
+ zip64: archive.directory.offset >= 0xffffffffn || bytes.length >= 4294967295
27511
+ };
27512
+ let local = encodeZipLocalHeader(entry);
27513
+ let central = encodeZipCentralHeader(entry);
27514
+ const directoryBytes = archive.directory.size + BigInt(central.length);
27515
+ const directoryOffset = archive.directory.offset + BigInt(local.length + bytes.length);
27516
+ const count = archive.directory.count + 1n;
27517
+ const comment = new Uint8Array(
27518
+ await archive.readExact(
27519
+ archive.size - BigInt(archive.comment.length),
27520
+ archive.comment.length
27521
+ )
27522
+ );
27523
+ const footer = encodeZipEndRecords(
27524
+ count,
27525
+ directoryBytes,
27526
+ directoryOffset,
27527
+ directoryOffset + directoryBytes > 0x7fffffffn || count >= 0xffffn,
27528
+ comment
27529
+ );
27530
+ if (count > BigInt(archive.limits.maxEntries) || directoryBytes > BigInt(archive.limits.maxDirectoryBytes) || directoryOffset + directoryBytes + BigInt(footer.length) > archive.limits.maxArchiveBytes)
27531
+ throw new RangeError("ZIP append metadata/archive limit exceeded");
27532
+ entry.crc32 = calculateZipChecksum(bytes);
27533
+ local = encodeZipLocalHeader(entry);
27534
+ central = encodeZipCentralHeader(entry);
27535
+ const directory = new Uint8Array(
27536
+ await archive.readExact(archive.directory.offset, Number(archive.directory.size))
27537
+ );
27538
+ archive.signal.throwIfAborted();
27539
+ await file.truncate(Number(archive.directory.offset));
27540
+ for (const chunk of [local, bytes, directory, central, footer]) {
27541
+ archive.signal.throwIfAborted();
27542
+ await file.append(chunk);
27543
+ }
27544
+ archive.signal.throwIfAborted();
27545
+ } finally {
27546
+ await archive.close();
28714
27547
  }
28715
27548
  }
28716
- /** Clean up resources */
28717
- async destroy() {
28718
- if (this.file) {
28719
- await this.file.close();
28720
- }
27549
+ /** Enumerates validated entries in central-directory order; metadata is indexed once. */
27550
+ async *entries() {
27551
+ for (const path of (await this.getDirectory()).keys()) yield await this.getEntry(path);
28721
27552
  }
28722
27553
  /**
28723
- * Get file names list from zip archive
28724
- * @returns array of file names
27554
+ * Reads the final central entry using at most one maximum-sized header from the directory tail.
27555
+ * Ambiguous header signatures in comments fall back to the cached directory. This supports
27556
+ * final-index discovery without scanning a large directory in the normal indexed profile.
28725
27557
  */
28726
- async readdir() {
28727
- if (!this.file) {
28728
- throw new Error("No data detected in the zip archive");
28729
- }
28730
- const fileNames = [];
28731
- const zipCDIterator = makeZipCDHeaderIterator(this.file);
28732
- for await (const cdHeader of zipCDIterator) {
28733
- fileNames.push(cdHeader.fileName);
27558
+ async getLastEntry() {
27559
+ this.signal.throwIfAborted();
27560
+ if (!this.directory.count) return void 0;
27561
+ const length = Number(minimumBigInt(this.directory.size, 46n + 3n * 65535n));
27562
+ const bytes = new Uint8Array(
27563
+ await this.readExact(this.directory.offset + this.directory.size - BigInt(length), length)
27564
+ );
27565
+ const view = new DataView(bytes.buffer);
27566
+ const positions = [];
27567
+ for (let position = 0; position + 46 <= length; position++) {
27568
+ if (view.getUint32(position, true) !== 33639248) continue;
27569
+ const end = position + 46 + view.getUint16(position + 28, true) + view.getUint16(position + 30, true) + view.getUint16(position + 32, true);
27570
+ if (end === length) positions.push(position);
27571
+ }
27572
+ if (positions.length !== 1) {
27573
+ const headers = [...(await this.getDirectory()).values()];
27574
+ return await this.getEntry(headers[headers.length - 1].path);
27575
+ }
27576
+ const metadata = decodeZipHeader(bytes.subarray(positions[0]), true);
27577
+ return await this.getValidatedEntry(metadata.localHeaderOffset, metadata);
27578
+ }
27579
+ /** Looks up a canonical path; returns undefined when the entry is absent. */
27580
+ async getEntry(path) {
27581
+ this.signal.throwIfAborted();
27582
+ const metadata = (await this.getDirectory()).get(path);
27583
+ if (!metadata) return void 0;
27584
+ let promise = this.entriesByPath.get(path);
27585
+ if (!promise) {
27586
+ promise = this.getValidatedEntry(metadata.localHeaderOffset, metadata).catch((error) => {
27587
+ this.entriesByPath.delete(path);
27588
+ throw error;
27589
+ });
27590
+ this.entriesByPath.set(path, promise);
28734
27591
  }
28735
- return fileNames;
27592
+ return await promise;
28736
27593
  }
28737
27594
  /**
28738
- * Get file metadata
28739
- * @param filename - name of a file
28740
- * @returns central directory data
27595
+ * Validates a populated local header at an index-provided offset without a directory scan.
27596
+ * Descriptor entries fall back to the shared directory because their local sizes may be zero.
27597
+ * Direct access validates local layout/bounds; central consistency requires named lookup.
28741
27598
  */
28742
- async stat(filename2) {
28743
- const cdFileHeader = await this.getCDFileHeader(filename2);
28744
- return { ...cdFileHeader, size: Number(cdFileHeader.uncompressedSize) };
28745
- }
28746
- /**
28747
- * Implementation of fetch against this file system
28748
- * @param filename - name of a file
28749
- * @returns - Response with file data
28750
- */
28751
- async fetch(filename2) {
28752
- if (this.fileName && filename2.indexOf(this.fileName) === 0) {
28753
- filename2 = filename2.substring(this.fileName.length + 1);
28754
- }
28755
- let uncompressedFile;
28756
- if (this.archive) {
28757
- uncompressedFile = await this.archive.getFile(filename2, "http");
28758
- } else {
28759
- if (!this.file) {
28760
- throw new Error("No data detected in the zip archive");
28761
- }
28762
- const cdFileHeader = await this.getCDFileHeader(filename2);
28763
- const localFileHeader = await parseZipLocalFileHeader(
28764
- cdFileHeader.localHeaderOffset,
28765
- this.file
28766
- );
28767
- if (!localFileHeader) {
28768
- throw new Error("Local file header has not been found in the zip archive`");
28769
- }
28770
- const compressionHandler = ZIP_COMPRESSION_HANDLERS[localFileHeader.compressionMethod.toString()];
28771
- if (!compressionHandler) {
28772
- throw Error("Only Deflation compression is supported");
27599
+ async getEntryAt(localHeaderOffset) {
27600
+ this.signal.throwIfAborted();
27601
+ const existing = this.entriesByOffset.get(localHeaderOffset);
27602
+ if (existing) return await existing;
27603
+ const metadata = await this.readLocalHeader(localHeaderOffset);
27604
+ if (metadata.header.flags & 8) {
27605
+ for (const header of (await this.getDirectory()).values())
27606
+ if (header.localHeaderOffset === localHeaderOffset)
27607
+ return await this.getEntry(header.path);
27608
+ throw new Error("Invalid ZIP archive: indexed offset missing from directory");
27609
+ }
27610
+ return await this.getValidatedEntry(localHeaderOffset, void 0, metadata);
27611
+ }
27612
+ /** Reads one complete entry and verifies its decoded size and CRC-32. */
27613
+ async read(entryOrPath, options = {}) {
27614
+ const signal = this.getReadSignal(options);
27615
+ signal.throwIfAborted();
27616
+ const entry = await this.resolveEntry(entryOrPath);
27617
+ signal.throwIfAborted();
27618
+ this.checkEntryBudget(entry);
27619
+ if (entry.size > BigInt(Number.MAX_SAFE_INTEGER))
27620
+ throw new RangeError("ZIP allocation is not safely representable");
27621
+ const output = new Uint8Array(Number(entry.size));
27622
+ let offset = 0;
27623
+ for await (const chunk of this.readInBatches(entry, options)) {
27624
+ output.set(chunk, offset);
27625
+ offset += chunk.byteLength;
27626
+ }
27627
+ return output.buffer;
27628
+ }
27629
+ /** Streams decoded chunks with backpressure; consuming through completion verifies CRC-32. */
27630
+ async *readInBatches(entryOrPath, options = {}) {
27631
+ const signal = this.getReadSignal(options);
27632
+ signal.throwIfAborted();
27633
+ const entry = await this.resolveEntry(entryOrPath);
27634
+ signal.throwIfAborted();
27635
+ this.checkEntryBudget(entry);
27636
+ let decodedBytes = 0n;
27637
+ let checksum = 0;
27638
+ const hash = new CRC32Hash({
27639
+ crypto: {
27640
+ onEnd: (result) => {
27641
+ checksum = Number.parseInt(result.hash, 16);
27642
+ }
28773
27643
  }
28774
- const compressedFile = await readRange(
28775
- this.file,
28776
- localFileHeader.fileDataOffset,
28777
- localFileHeader.fileDataOffset + cdFileHeader.compressedSize
28778
- );
28779
- uncompressedFile = await compressionHandler(compressedFile);
28780
- }
28781
- const response = new Response(uncompressedFile);
28782
- Object.defineProperty(response, "url", {
28783
- value: filename2 ? `${this.fileName || ""}/${filename2}` : this.fileName || ""
28784
27644
  });
28785
- return response;
27645
+ const compressed = this.readPayloadChunks(entry, signal);
27646
+ const decoded = entry.compression === "store" ? compressed : new DeflateDecompressor({ raw: true }).decompressBatches(compressed);
27647
+ for await (const chunk of hash.hashBatches(decoded, "hex")) {
27648
+ signal.throwIfAborted();
27649
+ decodedBytes += BigInt(chunk.byteLength);
27650
+ if (decodedBytes > entry.size || decodedBytes > this.limits.maxDecodedBytes)
27651
+ throw new RangeError("ZIP decoded entry size limit exceeded");
27652
+ yield new Uint8Array(chunk);
27653
+ }
27654
+ signal.throwIfAborted();
27655
+ if (decodedBytes !== entry.size) throw new Error("Invalid ZIP archive: decoded size mismatch");
27656
+ if (checksum !== entry.crc32) throw new Error("Invalid ZIP archive: CRC-32 mismatch");
27657
+ }
27658
+ /** Reads only a STORE byte range. Partial reads cannot verify a whole-entry CRC. */
27659
+ async readRange(entryOrPath, options) {
27660
+ const signal = this.getReadSignal(options);
27661
+ signal.throwIfAborted();
27662
+ const entry = await this.resolveEntry(entryOrPath);
27663
+ if (entry.compression !== "store") throw new Error("ZIP ranges require STORE entries");
27664
+ if (options.start < 0n || options.end < options.start || options.end > entry.size || options.end - options.start > BigInt(this.limits.maxReadBytes))
27665
+ throw new RangeError("ZIP byte-range limit exceeded");
27666
+ return await this.readExact(
27667
+ entry.dataOffset + options.start,
27668
+ Number(options.end - options.start),
27669
+ signal
27670
+ );
28786
27671
  }
28787
- /**
28788
- * Get central directory file header
28789
- * @param filename - name of a file
28790
- * @returns central directory file header
28791
- */
28792
- async getCDFileHeader(filename2) {
28793
- if (!this.file) {
28794
- throw new Error("No data detected in the zip archive");
28795
- }
28796
- const zipCDIterator = makeZipCDHeaderIterator(this.file);
28797
- let result = null;
28798
- for await (const cdHeader of zipCDIterator) {
28799
- if (cdHeader.fileName === filename2) {
28800
- result = cdHeader;
27672
+ /** Cancels reads and closes the owned transport exactly once; all subsequent reads reject. */
27673
+ close() {
27674
+ this.controller.abort(new Error("ZIP archive is closed"));
27675
+ this.closePromise ||= this.file.close();
27676
+ return this.closePromise;
27677
+ }
27678
+ /** Resolves a named entry or rejects metadata not issued by this archive. */
27679
+ async resolveEntry(entryOrPath) {
27680
+ this.signal.throwIfAborted();
27681
+ const entry = typeof entryOrPath === "string" ? await this.getEntry(entryOrPath) : entryOrPath;
27682
+ if (!entry || !this.issuedEntries.has(entry))
27683
+ throw new Error("ZIP entry not found or belongs to another archive");
27684
+ return entry;
27685
+ }
27686
+ /** Combines per-read cancellation with the owned lifetime. */
27687
+ getReadSignal(options) {
27688
+ return options.signal ? AbortSignal.any([this.signal, options.signal]) : this.signal;
27689
+ }
27690
+ /** Checks whole-entry consumption before allocation or decompression. */
27691
+ checkEntryBudget(entry) {
27692
+ if (entry.size > this.limits.maxDecodedBytes || entry.compressedSize > this.limits.maxCompressedBytes)
27693
+ throw new RangeError("ZIP entry compressed/decoded byte limit exceeded");
27694
+ }
27695
+ /** Yields compressed bytes without retaining a complete entry. */
27696
+ async *readPayloadChunks(entry, signal) {
27697
+ const chunkBytes = Math.min(this.limits.chunkBytes, this.limits.maxReadBytes);
27698
+ for (let offset = 0n; offset < entry.compressedSize; offset += BigInt(chunkBytes)) {
27699
+ const length = Number(minimumBigInt(BigInt(chunkBytes), entry.compressedSize - offset));
27700
+ yield await this.readExact(entry.dataOffset + offset, length, signal);
27701
+ }
27702
+ }
27703
+ /** Performs exact, bounded physical reads and rejects truncated transports. */
27704
+ async readExact(offset, length, signal = this.signal) {
27705
+ signal.throwIfAborted();
27706
+ if (offset < 0n || !Number.isSafeInteger(length) || length < 0 || offset + BigInt(length) > this.size)
27707
+ throw new Error("Invalid ZIP archive: read outside file");
27708
+ const output = new Uint8Array(length);
27709
+ for (let copied = 0; copied < length; ) {
27710
+ const readBytes = Math.min(length - copied, this.limits.maxReadBytes);
27711
+ const bytes = await this.file.read(offset + BigInt(copied), readBytes, signal);
27712
+ signal.throwIfAborted();
27713
+ if (bytes.byteLength !== readBytes)
27714
+ throw new Error("Invalid ZIP archive: truncated file read");
27715
+ output.set(new Uint8Array(bytes), copied);
27716
+ copied += readBytes;
27717
+ }
27718
+ return output.buffer;
27719
+ }
27720
+ /** Finds an EOCD whose complete comment ends at EOF, not a signature embedded in the comment. */
27721
+ async readDirectoryLocation() {
27722
+ const magic = new DataView(await this.readExact(0n, 4)).getUint32(0, true);
27723
+ if (magic !== 67324752 && magic !== 101010256 && magic !== 101075792)
27724
+ throw new Error("Unsupported ZIP prefix or archive format");
27725
+ const tailLength = Number(minimumBigInt(this.size, 65557n));
27726
+ const tailStart = this.size - BigInt(tailLength);
27727
+ const tail = new DataView(await this.readExact(tailStart, tailLength));
27728
+ let position = -1;
27729
+ for (let candidate = tailLength - 22; candidate >= 0; candidate--) {
27730
+ if (tail.getUint32(candidate, true) !== 101010256 || candidate + 22 + tail.getUint16(candidate + 20, true) !== tailLength)
27731
+ continue;
27732
+ if (position < 0) position = candidate;
27733
+ const emptyDirectoryAtEnd = tail.getUint32(candidate + 12, true) === 0 && BigInt(tail.getUint32(candidate + 16, true)) === tailStart + BigInt(candidate);
27734
+ if (tail.getUint16(candidate + 10, true) !== 0 || emptyDirectoryAtEnd || magic === 101075792) {
27735
+ position = candidate;
28801
27736
  break;
28802
27737
  }
28803
27738
  }
28804
- if (!result) {
28805
- throw new Error("File has not been found in the zip archive");
27739
+ if (position < 0) throw new Error("Invalid ZIP archive: end record not found");
27740
+ const disk = tail.getUint16(position + 4, true);
27741
+ const directoryDisk = tail.getUint16(position + 6, true);
27742
+ if (disk !== 0 && disk !== 65535 || directoryDisk !== 0 && directoryDisk !== 65535)
27743
+ throw new Error("Unsupported split ZIP archive");
27744
+ const onDisk = BigInt(tail.getUint16(position + 8, true));
27745
+ let count = BigInt(tail.getUint16(position + 10, true));
27746
+ let size = BigInt(tail.getUint32(position + 12, true));
27747
+ let offset = BigInt(tail.getUint32(position + 16, true));
27748
+ let footerOffset = tailStart + BigInt(position);
27749
+ let zip64 = false;
27750
+ if (footerOffset >= 20n) {
27751
+ const locator = new DataView(await this.readExact(footerOffset - 20n, 20));
27752
+ const locatorInsideDirectory = size !== 0xffffffffn && offset !== 0xffffffffn && offset + size > footerOffset - 20n;
27753
+ if (locator.getUint32(0, true) === 117853008 && !locatorInsideDirectory) {
27754
+ zip64 = true;
27755
+ if (locator.getUint32(4, true) || locator.getUint32(16, true) !== 1)
27756
+ throw new Error("Unsupported split ZIP64 archive");
27757
+ const zip64Offset = locator.getBigUint64(8, true);
27758
+ const record = new DataView(await this.readExact(zip64Offset, 56));
27759
+ if (record.getUint32(0, true) !== 101075792 || record.getBigUint64(4, true) < 44n || zip64Offset + 12n + record.getBigUint64(4, true) !== footerOffset - 20n || record.getUint32(16, true) || record.getUint32(20, true) || record.getBigUint64(24, true) !== record.getBigUint64(32, true))
27760
+ throw new Error("Invalid ZIP64 end record");
27761
+ const zip64Count = record.getBigUint64(32, true);
27762
+ const zip64Size = record.getBigUint64(40, true);
27763
+ const zip64DirectoryOffset = record.getBigUint64(48, true);
27764
+ if (onDisk !== 0xffffn && onDisk !== zip64Count || count !== 0xffffn && count !== zip64Count || size !== 0xffffffffn && size !== zip64Size || offset !== 0xffffffffn && offset !== zip64DirectoryOffset)
27765
+ throw new Error("Invalid ZIP64 legacy end values");
27766
+ count = zip64Count;
27767
+ size = zip64Size;
27768
+ offset = zip64DirectoryOffset;
27769
+ footerOffset = zip64Offset;
27770
+ } else if (size === 0xffffffffn || offset === 0xffffffffn)
27771
+ throw new Error("Invalid ZIP archive: ZIP64 locator missing");
27772
+ } else if (size === 0xffffffffn || offset === 0xffffffffn)
27773
+ throw new Error("Invalid ZIP archive: ZIP64 locator missing");
27774
+ if (!zip64) {
27775
+ if (disk === 65535 || directoryDisk === 65535)
27776
+ throw new Error("Invalid ZIP archive: ZIP64 locator missing");
27777
+ if (onDisk !== count) throw new Error("Invalid ZIP archive: inconsistent entry counts");
27778
+ }
27779
+ if (count > BigInt(this.limits.maxEntries) || size > BigInt(this.limits.maxDirectoryBytes))
27780
+ throw new RangeError("ZIP directory entry/byte limit exceeded");
27781
+ if (offset + size > footerOffset || size < count * 46n || count === 0n !== (size === 0n))
27782
+ throw new Error("Invalid ZIP archive: directory outside bounds");
27783
+ if (count && new DataView(await this.readExact(offset, 4)).getUint32(0, true) !== 33639248)
27784
+ throw new Error("Invalid ZIP archive: directory signature missing");
27785
+ const comment = decodeZipText(new Uint8Array(tail.buffer, position + 22), false);
27786
+ return { count, size, offset, comment };
27787
+ }
27788
+ /** Indexes central metadata once, without eagerly reading every local header. */
27789
+ getDirectory() {
27790
+ this.signal.throwIfAborted();
27791
+ this.directoryPromise ||= this.readDirectory().catch((error) => {
27792
+ this.directoryPromise = void 0;
27793
+ this.nextOffsets.clear();
27794
+ throw error;
27795
+ });
27796
+ return this.directoryPromise;
27797
+ }
27798
+ /** Parses exact directory records, including comments and Unicode/ZIP64 extras. */
27799
+ async readDirectory() {
27800
+ const bytes = new Uint8Array(
27801
+ await this.readExact(this.directory.offset, Number(this.directory.size))
27802
+ );
27803
+ const view = new DataView(bytes.buffer);
27804
+ const entries = /* @__PURE__ */ new Map();
27805
+ const offsets = /* @__PURE__ */ new Set();
27806
+ let position = 0;
27807
+ for (let index = 0n; index < this.directory.count; index++) {
27808
+ if (position + 46 > bytes.byteLength)
27809
+ throw new Error("Invalid ZIP archive: truncated directory");
27810
+ const length = 46 + view.getUint16(position + 28, true) + view.getUint16(position + 30, true) + view.getUint16(position + 32, true);
27811
+ const header = decodeZipHeader(bytes.subarray(position, position + length), true);
27812
+ if (header.localHeaderOffset + 30n > this.directory.offset)
27813
+ throw new Error("Invalid ZIP archive: local header outside data region");
27814
+ if (entries.has(header.path) || offsets.has(header.localHeaderOffset))
27815
+ throw new Error("Invalid ZIP archive: duplicate path or local-header offset");
27816
+ entries.set(header.path, header);
27817
+ offsets.add(header.localHeaderOffset);
27818
+ position += length;
27819
+ }
27820
+ const sortedOffsets = [...offsets].sort(
27821
+ (left, right) => left < right ? -1 : left > right ? 1 : 0
27822
+ );
27823
+ sortedOffsets.forEach(
27824
+ (offset, index) => this.nextOffsets.set(offset, sortedOffsets[index + 1] ?? this.directory.offset)
27825
+ );
27826
+ if (position !== bytes.byteLength)
27827
+ throw new Error("Invalid ZIP archive: directory length mismatch");
27828
+ return entries;
27829
+ }
27830
+ /** Reads local metadata without inspecting unrelated payloads. */
27831
+ async readLocalHeader(offset) {
27832
+ if (offset < 0n || offset + 30n > this.directory.offset)
27833
+ throw new Error("Invalid ZIP archive: local header outside data region");
27834
+ const fixed = new DataView(await this.readExact(offset, 30));
27835
+ const length = 30 + fixed.getUint16(26, true) + fixed.getUint16(28, true);
27836
+ if (offset + BigInt(length) > this.directory.offset)
27837
+ throw new Error("Invalid ZIP archive: local metadata overlaps directory");
27838
+ const bytes = new Uint8Array(length);
27839
+ bytes.set(new Uint8Array(fixed.buffer));
27840
+ bytes.set(new Uint8Array(await this.readExact(offset + 30n, length - 30)), 30);
27841
+ const header = decodeZipHeader(bytes, false);
27842
+ return { header, dataOffset: offset + BigInt(length) };
27843
+ }
27844
+ /** Shares local validation; a later named lookup additionally verifies central metadata. */
27845
+ async getValidatedEntry(offset, central, localMetadata) {
27846
+ if (central) return await this.validateEntry(offset, central);
27847
+ let entry = this.entriesByOffset.get(offset);
27848
+ if (!entry) {
27849
+ entry = this.validateEntry(offset, void 0, localMetadata).catch((error) => {
27850
+ this.entriesByOffset.delete(offset);
27851
+ throw error;
27852
+ });
27853
+ this.entriesByOffset.set(offset, entry);
27854
+ }
27855
+ return await entry;
27856
+ }
27857
+ /** Validates local/central identity, payload bounds and signed or unsigned descriptors. */
27858
+ async validateEntry(offset, central, localMetadata) {
27859
+ const { header: local, dataOffset } = localMetadata ?? await this.readLocalHeader(offset);
27860
+ const metadata = central || local;
27861
+ const descriptor = Boolean(local.flags & 8);
27862
+ if (central && (central.flags !== local.flags || central.method !== local.method || central.nameBytes.length !== local.nameBytes.length || central.nameBytes.some((value, index) => value !== local.nameBytes[index]) || !descriptor && (central.crc32 !== local.crc32 || central.size !== local.size || central.compressedSize !== local.compressedSize)))
27863
+ throw new Error("Invalid ZIP archive: local/central metadata mismatch");
27864
+ if (metadata.method === 0 && metadata.size !== metadata.compressedSize)
27865
+ throw new Error("Invalid ZIP archive: STORE sizes mismatch");
27866
+ if (central && descriptor && (local.crc32 !== 0 && local.crc32 !== central.crc32 || local.size !== 0n && local.size !== central.size || local.compressedSize !== 0n && local.compressedSize !== central.compressedSize))
27867
+ throw new Error("Invalid ZIP archive: descriptor local/central metadata mismatch");
27868
+ const payloadEnd = dataOffset + metadata.compressedSize;
27869
+ const entryEnd = central ? this.nextOffsets.get(offset) ?? this.directory.offset : this.directory.offset;
27870
+ if (payloadEnd > entryEnd) throw new Error("Invalid ZIP archive: payload overlaps directory");
27871
+ if (descriptor)
27872
+ await this.validateDescriptor(
27873
+ payloadEnd,
27874
+ metadata,
27875
+ local.zip64 || Boolean(central?.zip64),
27876
+ entryEnd
27877
+ );
27878
+ const entry = Object.freeze({
27879
+ path: metadata.path,
27880
+ directory: metadata.path.endsWith("/"),
27881
+ compression: metadata.method === 0 ? "store" : "deflate",
27882
+ size: metadata.size,
27883
+ compressedSize: metadata.compressedSize,
27884
+ crc32: metadata.crc32,
27885
+ localHeaderOffset: offset,
27886
+ dataOffset,
27887
+ comment: central?.comment || ""
27888
+ });
27889
+ this.issuedEntries.add(entry);
27890
+ return entry;
27891
+ }
27892
+ /** Resolves the optional descriptor signature using the expected CRC and sizes. */
27893
+ async validateDescriptor(offset, metadata, zip64, entryEnd) {
27894
+ const length = Number(minimumBigInt(24n, entryEnd - offset));
27895
+ const bytes = new DataView(await this.readExact(offset, length));
27896
+ for (const wide of zip64 ? [true, false] : [false, true]) {
27897
+ if (!wide && (metadata.size > 0xffffffffn || metadata.compressedSize > 0xffffffffn)) continue;
27898
+ const descriptorLength = wide ? 20 : 12;
27899
+ for (const prefix of [4, 0]) {
27900
+ if (length < prefix + descriptorLength || prefix && bytes.getUint32(0, true) !== 134695760)
27901
+ continue;
27902
+ const compressed = wide ? bytes.getBigUint64(prefix + 4, true) : BigInt(bytes.getUint32(prefix + 4, true));
27903
+ const decoded = wide ? bytes.getBigUint64(prefix + 12, true) : BigInt(bytes.getUint32(prefix + 8, true));
27904
+ if (bytes.getUint32(prefix, true) === metadata.crc32 && compressed === metadata.compressedSize && decoded === metadata.size)
27905
+ return;
27906
+ }
28806
27907
  }
28807
- return result;
27908
+ throw new Error("Invalid ZIP archive: data descriptor mismatch");
28808
27909
  }
28809
27910
  };
28810
27911
  }
28811
27912
  });
28812
27913
 
28813
- // ../../modules/zip/src/filesystems/IndexedArchive.ts
28814
- var IndexedArchive;
28815
- var init_IndexedArchive = __esm({
28816
- "../../modules/zip/src/filesystems/IndexedArchive.ts"() {
28817
- "use strict";
28818
- init_zip_filesystem();
28819
- IndexedArchive = class {
28820
- file;
28821
- fileName;
28822
- /**
28823
- * Constructor
28824
- * @param fileProvider - readable file instance for random access
28825
- * @param hashTable - pre-loaded hashTable. If presented, getFile will skip reading the hash file
28826
- * @param fileName - name of the archive. It is used to add to an URL of a loader context
28827
- */
28828
- constructor(file, hashTable, fileName) {
28829
- this.file = file;
28830
- this.fileName = fileName;
28831
- }
28832
- /**
28833
- * Get file as from order ZIP arhive without using the hash file
28834
- * @param filename - path to the internal file
28835
- * @returns
28836
- */
28837
- async getFileWithoutHash(filename2) {
28838
- const zipFS = new ZipFileSystem(this.file);
28839
- const response = await zipFS.fetch(filename2);
28840
- return await response.arrayBuffer();
27914
+ // ../../modules/zip/src/lib/zip-composition.ts
27915
+ async function generateFileHeaders(fileName, file, offset) {
27916
+ validateZipPath(fileName);
27917
+ const header = {
27918
+ nameBytes: encodeUtf8Text(fileName),
27919
+ date: /* @__PURE__ */ new Date("1980-01-01T00:00:00Z"),
27920
+ flags: 2048,
27921
+ method: 0,
27922
+ crc32: Number.parseInt(await new CRC32Hash().hash(file, "hex"), 16),
27923
+ size: BigInt(file.byteLength),
27924
+ compressedSize: BigInt(file.byteLength),
27925
+ localHeaderOffset: offset,
27926
+ zip64: offset >= 0xffffffffn || file.byteLength >= 4294967295
27927
+ };
27928
+ return [
27929
+ new Uint8Array(concatenateArrayBuffers(encodeZipLocalHeader(header), file)),
27930
+ encodeZipCentralHeader(header)
27931
+ ];
27932
+ }
27933
+ async function createZip(inputPath, outputPath, createAdditionalData, options = {}) {
27934
+ const state = {
27935
+ maxArchiveBytes: options.maxArchiveBytes ?? 1024n ** 4n,
27936
+ maxEntries: options.maxEntries ?? 1e5,
27937
+ maxDirectoryBytes: options.maxDirectoryBytes ?? 32 * 1024 * 1024,
27938
+ signal: options.signal,
27939
+ directoryBytes: 0
27940
+ };
27941
+ if (typeof state.maxArchiveBytes !== "bigint" || state.maxArchiveBytes < 0n || !Number.isSafeInteger(state.maxEntries) || state.maxEntries < 1 || !Number.isSafeInteger(state.maxDirectoryBytes) || state.maxDirectoryBytes < 1)
27942
+ throw new RangeError("Invalid ZIP composition limits");
27943
+ if (state.maxArchiveBytes < 22n) throw new RangeError("ZIP composition archive limit exceeded");
27944
+ state.signal?.throwIfAborted();
27945
+ const fileIterator = getFileIterator(inputPath);
27946
+ const resFile = new NodeFileFacade(outputPath, "w");
27947
+ const fileList = [];
27948
+ const cdArray = [];
27949
+ try {
27950
+ for await (const file of fileIterator) {
27951
+ await addFile(file, resFile, cdArray, state, fileList);
27952
+ }
27953
+ if (createAdditionalData) {
27954
+ const additionaldata = await createAdditionalData(fileList);
27955
+ await addFile(additionaldata, resFile, cdArray, state);
27956
+ }
27957
+ state.signal?.throwIfAborted();
27958
+ const cdOffset = (await resFile.stat()).bigsize;
27959
+ const cd = concatenateArrayBuffers(...cdArray);
27960
+ await resFile.append(new Uint8Array(cd));
27961
+ const eoCDStart = (await resFile.stat()).bigsize;
27962
+ await resFile.append(
27963
+ new Uint8Array(
27964
+ encodeZipEndRecords(
27965
+ BigInt(cdArray.length),
27966
+ BigInt(cd.byteLength),
27967
+ cdOffset,
27968
+ eoCDStart > 0x7fffffffn || cdArray.length >= 65535
27969
+ )
27970
+ )
27971
+ );
27972
+ } finally {
27973
+ await resFile.close();
27974
+ }
27975
+ }
27976
+ async function addFile(file, resFile, cdArray, state, fileList) {
27977
+ state.signal?.throwIfAborted();
27978
+ const size = (await resFile.stat()).bigsize;
27979
+ fileList?.push({ fileName: file.path, localHeaderOffset: size });
27980
+ const [localPart, cdHeaderPart] = await generateFileHeaders(file.path, file.file, size);
27981
+ const directoryBytes = state.directoryBytes + cdHeaderPart.byteLength;
27982
+ const directoryOffset = size + BigInt(localPart.byteLength);
27983
+ const count = cdArray.length + 1;
27984
+ const footer = encodeZipEndRecords(
27985
+ BigInt(count),
27986
+ BigInt(directoryBytes),
27987
+ directoryOffset,
27988
+ directoryOffset + BigInt(directoryBytes) > 0x7fffffffn || count >= 65535
27989
+ );
27990
+ if (count > state.maxEntries || directoryBytes > state.maxDirectoryBytes || directoryOffset + BigInt(directoryBytes + footer.length) > state.maxArchiveBytes)
27991
+ throw new RangeError("ZIP composition metadata/archive limit exceeded");
27992
+ state.signal?.throwIfAborted();
27993
+ await resFile.append(localPart);
27994
+ state.directoryBytes = directoryBytes;
27995
+ cdArray.push(toArrayBuffer2(cdHeaderPart));
27996
+ }
27997
+ function getFileIterator(inputPath) {
27998
+ async function* iterable() {
27999
+ const fileList = await getAllFiles(inputPath);
28000
+ for (const filePath of fileList) {
28001
+ const provider = new NodeFileFacade(path_exports.join(inputPath, filePath), "r");
28002
+ try {
28003
+ const { bigsize } = await provider.stat();
28004
+ const file = await provider.read(0, Number(bigsize));
28005
+ yield { path: filePath, file };
28006
+ } finally {
28007
+ await provider.close();
28841
28008
  }
28842
- };
28009
+ }
28010
+ }
28011
+ return iterable();
28012
+ }
28013
+ async function getAllFiles(basePath, subfolder = "", fsPassed) {
28014
+ const fs3 = fsPassed ? fsPassed : new NodeFileSystemFacade({});
28015
+ const files = await fs3.readdir(pathJoin(basePath, subfolder));
28016
+ const arrayOfFiles = [];
28017
+ for (const file of files) {
28018
+ const fullPath = pathJoin(basePath, subfolder, file);
28019
+ if ((await fs3.stat(fullPath)).isDirectory) {
28020
+ const files2 = await getAllFiles(basePath, pathJoin(subfolder, file));
28021
+ arrayOfFiles.push(...files2);
28022
+ } else {
28023
+ arrayOfFiles.push(pathJoin(subfolder, file));
28024
+ }
28025
+ }
28026
+ return arrayOfFiles;
28027
+ }
28028
+ function pathJoin(...paths) {
28029
+ const resPaths = paths.filter((val) => val.length);
28030
+ return path_exports.join(...resPaths);
28031
+ }
28032
+ var init_zip_composition = __esm({
28033
+ "../../modules/zip/src/lib/zip-composition.ts"() {
28034
+ "use strict";
28035
+ init_src2();
28036
+ init_zip_entry_metadata();
28037
+ init_src11();
28038
+ init_zip_serialization();
28843
28039
  }
28844
28040
  });
28845
28041
 
28846
28042
  // ../../modules/zip/src/hash-file-utility.ts
28847
28043
  function parseHashTable(arrayBuffer) {
28044
+ if (arrayBuffer.byteLength % 24) throw new Error("Invalid ZIP index length");
28848
28045
  const dataView = new DataView(arrayBuffer);
28849
28046
  const hashMap = {};
28850
28047
  for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {
28851
28048
  const offset = dataView.getBigUint64(i + 16, true);
28852
28049
  const hash = bufferToHex(arrayBuffer, i, 16);
28050
+ if (hash in hashMap) throw new Error("Duplicate ZIP index hash");
28853
28051
  hashMap[hash] = offset;
28854
28052
  }
28855
28053
  return hashMap;
@@ -28857,30 +28055,14 @@ function parseHashTable(arrayBuffer) {
28857
28055
  function bufferToHex(buffer, start, length) {
28858
28056
  return [...new Uint8Array(buffer, start, length)].map((x) => x.toString(16).padStart(2, "0")).join("");
28859
28057
  }
28860
- async function makeHashTableFromZipHeaders(fileProvider) {
28861
- const zipCDIterator = makeZipCDHeaderIterator(fileProvider);
28862
- return getHashTable(zipCDIterator);
28863
- }
28864
- async function getHashTable(zipCDIterator) {
28865
- const md5Hash = new MD5Hash();
28866
- const textEncoder = new TextEncoder();
28867
- const hashTable = {};
28868
- for await (const cdHeader of zipCDIterator) {
28869
- const filename2 = cdHeader.fileName.split("\\").join("/").toLocaleLowerCase();
28870
- const arrayBuffer = textEncoder.encode(filename2).buffer;
28871
- const md53 = await md5Hash.hash(arrayBuffer, "hex");
28872
- hashTable[md53] = cdHeader.localHeaderOffset;
28873
- }
28874
- return hashTable;
28875
- }
28876
28058
  async function composeHashFile(zipCDIterator) {
28877
28059
  const md5Hash = new MD5Hash();
28878
28060
  const textEncoder = new TextEncoder();
28879
28061
  const hashArray = [];
28880
28062
  for await (const cdHeader of zipCDIterator) {
28881
- let filename2 = cdHeader.fileName.split("\\").join("/");
28063
+ let filename2 = ("path" in cdHeader ? cdHeader.path : cdHeader.fileName).split("\\").join("/");
28882
28064
  if (filename2 !== "3dSceneLayer.json.gz") {
28883
- filename2 = filename2.toLocaleLowerCase();
28065
+ filename2 = filename2.toLowerCase();
28884
28066
  }
28885
28067
  const arrayBuffer = textEncoder.encode(filename2).buffer;
28886
28068
  const md53 = await md5Hash.hash(arrayBuffer, "hex");
@@ -28908,18 +28090,313 @@ var init_hash_file_utility = __esm({
28908
28090
  "use strict";
28909
28091
  init_src11();
28910
28092
  init_src2();
28911
- init_cd_file_header();
28093
+ }
28094
+ });
28095
+
28096
+ // ../../modules/zip/src/filesystems/IndexedArchive.ts
28097
+ var IndexedArchive;
28098
+ var init_IndexedArchive = __esm({
28099
+ "../../modules/zip/src/filesystems/IndexedArchive.ts"() {
28100
+ "use strict";
28101
+ init_src11();
28102
+ init_zip_archive();
28103
+ init_hash_file_utility();
28104
+ IndexedArchive = class {
28105
+ /** Captures the source and an optional already-loaded format index. */
28106
+ constructor(file, hashTable, fileName, options = {}) {
28107
+ this.options = options;
28108
+ this.file = file;
28109
+ this.hashTable = hashTable;
28110
+ this.fileName = fileName;
28111
+ }
28112
+ options;
28113
+ /** Owned random-access archive source. */
28114
+ file;
28115
+ /** Optional resource URL prefix. */
28116
+ fileName;
28117
+ /** Format-provided path hashes, or a directory-derived fallback. */
28118
+ hashTable;
28119
+ /** Cancellation for metadata initialization and indexed reads. */
28120
+ controller = new AbortController();
28121
+ /** Shared lazy ZIP reader and directory cache. */
28122
+ readerPromise;
28123
+ /** Idempotent release even when no reader has been opened. */
28124
+ closePromise;
28125
+ /**
28126
+ * Loads a final index when present, otherwise hashes validated directory entries.
28127
+ * The format supplies the reserved name and fallback path-case policy. Returns true for an index.
28128
+ */
28129
+ async initializeIndex(indexPath, lowercasePaths = false) {
28130
+ const reader = await this.getZipArchive();
28131
+ const last = await reader.getLastEntry();
28132
+ if (last?.path === indexPath) {
28133
+ this.hashTable = parseHashTable(await reader.read(last));
28134
+ return true;
28135
+ }
28136
+ const hash = new MD5Hash();
28137
+ const table = /* @__PURE__ */ Object.create(null);
28138
+ for await (const entry of reader.entries()) {
28139
+ const path = lowercasePaths ? entry.path.toLowerCase() : entry.path;
28140
+ const digest = await hash.hash(new TextEncoder().encode(path).buffer, "hex");
28141
+ if (digest in table) throw new Error("Duplicate ZIP index path hash");
28142
+ table[digest] = entry.localHeaderOffset;
28143
+ }
28144
+ this.hashTable = table;
28145
+ return false;
28146
+ }
28147
+ /** Closes the reader/transport exactly once and rejects subsequent resource reads. */
28148
+ async close() {
28149
+ this.controller.abort(new Error("ZIP archive is closed"));
28150
+ this.closePromise ||= this.readerPromise ? this.readerPromise.then(
28151
+ (reader) => reader.close(),
28152
+ () => {
28153
+ }
28154
+ ) : this.file.close();
28155
+ await this.closePromise;
28156
+ }
28157
+ /** Reads and verifies a complete ZIP entry, retaining direct indexed local-header access. */
28158
+ async readZipEntry(path) {
28159
+ const reader = await this.getZipArchive();
28160
+ let entry;
28161
+ if (this.hashTable) {
28162
+ const digest = await new MD5Hash().hash(new TextEncoder().encode(path).buffer, "hex");
28163
+ const offset = this.hashTable[digest];
28164
+ if (offset === void 0) return void 0;
28165
+ entry = await reader.getEntryAt(offset);
28166
+ if (entry.path.toLowerCase() !== path.toLowerCase())
28167
+ throw new Error("ZIP index path mismatch");
28168
+ } else entry = await reader.getEntry(path);
28169
+ return entry ? await reader.read(entry) : void 0;
28170
+ }
28171
+ /** Compatibility helper for adapters with no path index. */
28172
+ async getFileWithoutHash(path) {
28173
+ const data = await this.readZipEntry(path);
28174
+ if (!data) throw new Error(`No such file in the archive: ${path}`);
28175
+ return data;
28176
+ }
28177
+ /** Initializes container metadata once without reading unrelated payloads. */
28178
+ async getZipArchive() {
28179
+ if (this.closePromise) throw new Error("ZIP archive is closed");
28180
+ this.readerPromise ||= openZipArchive(this.file, {
28181
+ ...this.options,
28182
+ signal: this.options.signal ? AbortSignal.any([this.controller.signal, this.options.signal]) : this.controller.signal
28183
+ });
28184
+ return await this.readerPromise;
28185
+ }
28186
+ };
28187
+ }
28188
+ });
28189
+
28190
+ // ../../modules/zip/src/filesystems/zip-filesystem.ts
28191
+ function parseByteRange(value, size) {
28192
+ const match = /^bytes=(\d*)-(\d*)$/i.exec(value.trim());
28193
+ if (!match || !match[1] && !match[2] || size === 0n) return void 0;
28194
+ if (!match[1]) {
28195
+ const suffix = BigInt(match[2]);
28196
+ if (!suffix) return void 0;
28197
+ return { start: suffix < size ? size - suffix : 0n, end: size };
28198
+ }
28199
+ const start = BigInt(match[1]);
28200
+ const last = match[2] ? BigInt(match[2]) : size - 1n;
28201
+ if (start >= size || last < start) return void 0;
28202
+ return { start, end: last < size ? last + 1n : size };
28203
+ }
28204
+ var ZipFileSystem;
28205
+ var init_zip_filesystem = __esm({
28206
+ "../../modules/zip/src/filesystems/zip-filesystem.ts"() {
28207
+ "use strict";
28208
+ init_src2();
28209
+ init_IndexedArchive();
28210
+ init_zip_archive();
28211
+ ZipFileSystem = class {
28212
+ /** Opens portable bytes, a random-access file, a format adapter, or a Node file path lazily. */
28213
+ constructor(file, options = {}) {
28214
+ this.options = options;
28215
+ this.signal = options.signal ? AbortSignal.any([this.controller.signal, options.signal]) : this.controller.signal;
28216
+ this.archive = file instanceof IndexedArchive ? file : null;
28217
+ if (typeof file === "string") {
28218
+ if (isBrowser)
28219
+ throw new Error("ZipFileSystem cannot open file paths in browser environments");
28220
+ this.fileName = file;
28221
+ this.file = new NodeFileFacade(file);
28222
+ } else if (file instanceof IndexedArchive) {
28223
+ this.file = file.file;
28224
+ this.fileName = file.fileName;
28225
+ } else if (file instanceof Blob || file instanceof ArrayBuffer) {
28226
+ this.file = new BlobFile(file);
28227
+ } else if (ArrayBuffer.isView(file)) {
28228
+ this.file = new BlobFile(
28229
+ Uint8Array.from(new Uint8Array(file.buffer, file.byteOffset, file.byteLength)).buffer
28230
+ );
28231
+ } else {
28232
+ this.file = file;
28233
+ }
28234
+ }
28235
+ options;
28236
+ /** Owned random-access transport. */
28237
+ file;
28238
+ /** Optional archive name used in response URLs. */
28239
+ fileName;
28240
+ /** Optional format adapter retaining resource aliases and content-level decoding. */
28241
+ archive;
28242
+ /** Shared reader initialization, performed once when first needed. */
28243
+ readerPromise;
28244
+ /** Cancellation for opening and all reads during the filesystem lifetime. */
28245
+ controller = new AbortController();
28246
+ /** Caller cancellation combined with filesystem destruction. */
28247
+ signal;
28248
+ /** Idempotent transport release. */
28249
+ destroyPromise;
28250
+ /** Cancels pending reads and closes the owned file once; later operations reject. */
28251
+ destroy() {
28252
+ this.controller.abort(new Error("ZIP filesystem is closed"));
28253
+ this.destroyPromise ||= this.archive ? this.archive.close() : this.readerPromise ? this.readerPromise.then(
28254
+ (reader) => reader.close(),
28255
+ () => {
28256
+ }
28257
+ ) : this.file.close();
28258
+ return this.destroyPromise;
28259
+ }
28260
+ /** Lists validated archive paths in central-directory order, including directory entries. */
28261
+ async readdir() {
28262
+ const reader = await this.getReader();
28263
+ const paths = [];
28264
+ for await (const entry of reader.entries()) paths.push(entry.path);
28265
+ return paths;
28266
+ }
28267
+ /** Returns validated metadata; rejects sizes that cannot be represented safely as a number. */
28268
+ async stat(filename2) {
28269
+ const entry = await this.getEntry(filename2);
28270
+ if (entry.size > BigInt(Number.MAX_SAFE_INTEGER))
28271
+ throw new RangeError("ZIP FileSystem size is not safely representable");
28272
+ return { ...entry, size: Number(entry.size), uncompressedSize: entry.size };
28273
+ }
28274
+ /**
28275
+ * Fetches a confined resource. Complete streams verify CRC when consumed through completion.
28276
+ * Single STORE ranges return 206 or 416; compressed and format-decoded ranges reject.
28277
+ */
28278
+ async fetch(filename2, options = {}) {
28279
+ this.signal.throwIfAborted();
28280
+ options.signal?.throwIfAborted();
28281
+ if (options.method && options.method.toUpperCase() !== "GET")
28282
+ throw new Error("ZIP filesystem only supports GET");
28283
+ let path;
28284
+ const range = new Headers(options.headers).get("range");
28285
+ let response;
28286
+ if (this.archive) {
28287
+ path = this.resolveResourcePath(filename2);
28288
+ if (range !== null)
28289
+ throw new Error("ZIP ranges are unavailable through format resource adapters");
28290
+ response = new Response(await this.archive.getFile(path, "http"));
28291
+ this.signal.throwIfAborted();
28292
+ options.signal?.throwIfAborted();
28293
+ } else {
28294
+ const reader = await this.getReader();
28295
+ options.signal?.throwIfAborted();
28296
+ const entry = await this.getEntry(filename2);
28297
+ options.signal?.throwIfAborted();
28298
+ path = entry.path;
28299
+ const headers = new Headers({
28300
+ "Accept-Ranges": entry.compression === "store" ? "bytes" : "none",
28301
+ "Content-Length": String(entry.size)
28302
+ });
28303
+ if (range !== null) {
28304
+ if (entry.compression !== "store") throw new Error("ZIP ranges require STORE entries");
28305
+ const bounds = parseByteRange(range, entry.size);
28306
+ if (!bounds) {
28307
+ headers.set("Content-Range", `bytes */${entry.size}`);
28308
+ headers.set("Content-Length", "0");
28309
+ response = new Response(null, { status: 416, headers });
28310
+ } else {
28311
+ const bytes = await reader.readRange(entry, {
28312
+ ...bounds,
28313
+ signal: options.signal || void 0
28314
+ });
28315
+ headers.set("Content-Range", `bytes ${bounds.start}-${bounds.end - 1n}/${entry.size}`);
28316
+ headers.set("Content-Length", String(bounds.end - bounds.start));
28317
+ response = new Response(bytes, { status: 206, headers });
28318
+ }
28319
+ } else {
28320
+ const iterator = reader.readInBatches(entry, { signal: options.signal || void 0 })[Symbol.asyncIterator]();
28321
+ const stream = new ReadableStream(
28322
+ {
28323
+ async pull(controller) {
28324
+ try {
28325
+ const chunk = await iterator.next();
28326
+ if (chunk.done) controller.close();
28327
+ else controller.enqueue(chunk.value);
28328
+ } catch (error) {
28329
+ controller.error(error);
28330
+ }
28331
+ },
28332
+ async cancel() {
28333
+ await iterator.return?.();
28334
+ }
28335
+ },
28336
+ { highWaterMark: 0 }
28337
+ );
28338
+ response = new Response(stream, { headers });
28339
+ }
28340
+ }
28341
+ Object.defineProperty(response, "url", {
28342
+ value: this.getResourceUrl(path)
28343
+ });
28344
+ return response;
28345
+ }
28346
+ /** Resolves resources once, allowing parents inside the archive but rejecting root escapes. */
28347
+ resolveResourcePath(filename2, decodeUri = false) {
28348
+ const archivePath = filename2.startsWith("./") ? filename2.slice(2) : filename2;
28349
+ const archiveName = this.fileName?.replace(/^\.\//, "");
28350
+ if (archiveName && (archivePath === archiveName || archivePath.startsWith(`${archiveName}/`))) {
28351
+ filename2 = archivePath.slice(archiveName.length).replace(/^\//, "");
28352
+ decodeUri = true;
28353
+ }
28354
+ decodeUri ||= filename2.startsWith("/") || filename2.startsWith("./");
28355
+ if (/^[a-z][a-z\d+.-]*:/i.test(filename2) || filename2.startsWith("//"))
28356
+ throw new Error("ZIP resource must stay inside the archive");
28357
+ const decoded = decodeUri ? decodeURIComponent(filename2.split(/[?#]/, 1)[0]) : filename2;
28358
+ if (decoded.includes("\\") || decoded.includes("\0") || decoded.startsWith("//") || /^[a-z][a-z\d+.-]*:/i.test(decoded))
28359
+ throw new Error("ZIP resource must stay inside the archive");
28360
+ const segments = [];
28361
+ for (const segment of decoded.split("/")) {
28362
+ if (!segment || segment === ".") continue;
28363
+ if (segment === "..") {
28364
+ if (!segments.length) throw new Error("ZIP resource escapes the archive");
28365
+ segments.pop();
28366
+ } else segments.push(segment);
28367
+ }
28368
+ return segments.join("/") + (decoded.endsWith("/") && segments.length ? "/" : "");
28369
+ }
28370
+ /** Creates a qualified URL that cannot be confused with a canonical literal archive path. */
28371
+ getResourceUrl(path) {
28372
+ const prefix = this.fileName && !/^(?:\/|[a-z][a-z\d+.-]*:)/i.test(this.fileName) ? `./${this.fileName.replace(/^\.\//, "")}` : this.fileName || "";
28373
+ return `${prefix}/${path.split("/").map(encodeURIComponent).join("/")}`;
28374
+ }
28375
+ /** Shares the directory cache and lifetime with every filesystem lookup. */
28376
+ async getReader() {
28377
+ this.signal.throwIfAborted();
28378
+ if (this.archive) return await this.archive.getZipArchive();
28379
+ this.readerPromise ||= openZipArchive(this.file, {
28380
+ ...this.options,
28381
+ signal: this.signal
28382
+ });
28383
+ return await this.readerPromise;
28384
+ }
28385
+ /** Resolves one validated entry and reports absent resources explicitly. */
28386
+ async getEntry(path) {
28387
+ const reader = await this.getReader();
28388
+ const entry = await reader.getEntry(path) || await reader.getEntry(this.resolveResourcePath(path, true));
28389
+ if (!entry) throw new Error(`File has not been found in the zip archive: ${path}`);
28390
+ return entry;
28391
+ }
28392
+ };
28912
28393
  }
28913
28394
  });
28914
28395
 
28915
28396
  // ../../modules/zip/src/index.ts
28916
- var init_src13 = __esm({
28397
+ var init_src12 = __esm({
28917
28398
  "../../modules/zip/src/index.ts"() {
28918
28399
  "use strict";
28919
- init_cd_file_header();
28920
- init_local_file_header();
28921
- init_search_from_the_end();
28922
- init_readable_file_utils();
28923
28400
  init_zip_composition();
28924
28401
  init_IndexedArchive();
28925
28402
  init_hash_file_utility();
@@ -28928,30 +28405,19 @@ var init_src13 = __esm({
28928
28405
  });
28929
28406
 
28930
28407
  // ../../modules/3d-tiles/src/3d-tiles-archive/3d-tiles-archive-archive.ts
28931
- var COMPRESSION_METHODS, Tiles3DArchive;
28408
+ var Tiles3DArchive;
28932
28409
  var init_d_tiles_archive_archive = __esm({
28933
28410
  "../../modules/3d-tiles/src/3d-tiles-archive/3d-tiles-archive-archive.ts"() {
28934
28411
  "use strict";
28935
- init_src11();
28936
28412
  init_src12();
28937
- init_src13();
28938
- COMPRESSION_METHODS = {
28939
- /** No compression */
28940
- 0: (data) => new NoDecompressor2().decompress(data),
28941
- /** Deflation */
28942
- 8: (data) => new DeflateDecompressor2({ raw: true }).decompress(data)
28943
- };
28944
28413
  Tiles3DArchive = class extends IndexedArchive {
28945
- /** hash info */
28946
- hashTable;
28947
28414
  /**
28948
28415
  * creates Tiles3DArchive handler
28949
28416
  * @param fileProvider - readable file handle with the whole archive
28950
28417
  * @param hashTable - hash info
28951
28418
  */
28952
- constructor(fileProvider, hashTable, fileName) {
28953
- super(fileProvider, hashTable, fileName);
28954
- this.hashTable = hashTable;
28419
+ constructor(fileProvider, hashTable, fileName, options) {
28420
+ super(fileProvider, hashTable, fileName, options);
28955
28421
  }
28956
28422
  /**
28957
28423
  * Returns file with the given path from 3tz archive
@@ -28974,37 +28440,33 @@ var init_d_tiles_archive_archive = __esm({
28974
28440
  * @returns buffer with the raw file data
28975
28441
  */
28976
28442
  async getFileBytes(path) {
28977
- let uncompressedFile;
28978
- if (this.hashTable) {
28979
- const arrayBuffer = new TextEncoder().encode(path).buffer;
28980
- const nameHash = await new MD5Hash().hash(arrayBuffer, "hex");
28981
- const byteOffset = this.hashTable[nameHash];
28982
- if (byteOffset === void 0) {
28983
- return null;
28984
- }
28985
- const localFileHeader = await parseZipLocalFileHeader(byteOffset, this.file);
28986
- if (!localFileHeader) {
28987
- return null;
28988
- }
28989
- const compressedFile = await readRange(
28990
- this.file,
28991
- localFileHeader.fileDataOffset,
28992
- localFileHeader.fileDataOffset + localFileHeader.compressedSize
28993
- );
28994
- const compressionMethod = COMPRESSION_METHODS[localFileHeader.compressionMethod];
28995
- if (!compressionMethod) {
28996
- throw Error("Only Deflation compression is supported");
28997
- }
28998
- uncompressedFile = await compressionMethod(compressedFile);
28999
- } else {
29000
- uncompressedFile = await this.getFileWithoutHash(path);
29001
- }
29002
- return uncompressedFile;
28443
+ return await this.readZipEntry(path) ?? null;
29003
28444
  }
29004
28445
  };
29005
28446
  }
29006
28447
  });
29007
28448
 
28449
+ // ../../modules/3d-tiles/src/3d-tiles-archive/3d-tiles-archive-parser.ts
28450
+ async function parse3DTilesArchive(fileProvider, callback, fileName, options) {
28451
+ const archive = new Tiles3DArchive(fileProvider, void 0, fileName, options);
28452
+ try {
28453
+ if (!await archive.initializeIndex("@3dtilesIndex1@", false))
28454
+ callback?.(
28455
+ "3tz doesnt contain hash file, hash info has been composed according to zip archive headers"
28456
+ );
28457
+ return archive;
28458
+ } catch (error) {
28459
+ await archive.close();
28460
+ throw error;
28461
+ }
28462
+ }
28463
+ var init_d_tiles_archive_parser = __esm({
28464
+ "../../modules/3d-tiles/src/3d-tiles-archive/3d-tiles-archive-parser.ts"() {
28465
+ "use strict";
28466
+ init_d_tiles_archive_archive();
28467
+ }
28468
+ });
28469
+
29008
28470
  // ../../modules/i3s/src/i3s-zod-schema.ts
29009
28471
  var import_zod3, I3SObbSchema, I3SMeshMaterialSchema, I3SMeshGeometrySchema, I3SNodeInPageSchema, I3SNodePageSchema, I3SPointCloudNodeSchema, I3SPointCloudNodePageSchema, I3SSpatialReferenceSchema, I3SPointCloudStoreSchema, I3SPointCloudSceneLayerBaseSchema, I3SPointCloudNodePagesRequirementSchema, I3SPointCloudSceneLayerSchema, I3SGeometryBufferItemSchema, I3SGeometryBufferSchema, I3SGeometryDefinitionSchema, I3SSceneLayerSchema, I3SPointSceneLayerSchema;
29010
28472
  var init_i3s_zod_schema = __esm({
@@ -30909,14 +30371,215 @@ var init_i3s_loader = __esm({
30909
30371
  }
30910
30372
  });
30911
30373
 
30374
+ // ../../modules/compression/src/lib/native-decompressor.ts
30375
+ var native_decompressor_exports = {};
30376
+ __export(native_decompressor_exports, {
30377
+ NativeDecompressor: () => NativeDecompressor
30378
+ });
30379
+ var NativeDecompressor;
30380
+ var init_native_decompressor = __esm({
30381
+ "../../modules/compression/src/lib/native-decompressor.ts"() {
30382
+ "use strict";
30383
+ init_compression();
30384
+ init_decompression_stream();
30385
+ NativeDecompressor = class extends Decompressor {
30386
+ name;
30387
+ extensions;
30388
+ contentEncodings;
30389
+ isSupported = true;
30390
+ /** Runtime stream format used for every operation. */
30391
+ format;
30392
+ constructor(metadata, format, options = {}) {
30393
+ super(options);
30394
+ this.name = metadata.name;
30395
+ this.extensions = [...metadata.extensions];
30396
+ this.contentEncodings = [...metadata.contentEncodings];
30397
+ this.format = format;
30398
+ }
30399
+ /** Decompresses one buffer with the runtime-provided stream. */
30400
+ async decompress(input) {
30401
+ const output = await decompressWithNativeDecompressionStream(input, this.format);
30402
+ if (!output) throw new Error(`${this.name}: built-in decompression is no longer available`);
30403
+ return output;
30404
+ }
30405
+ /** Decompresses batches incrementally with the runtime-provided stream. */
30406
+ async *decompressBatches(inputBatches) {
30407
+ const output = decompressBatchesWithNativeDecompressionStream(inputBatches, this.format);
30408
+ if (!output) throw new Error(`${this.name}: built-in decompression is no longer available`);
30409
+ yield* output;
30410
+ }
30411
+ };
30412
+ }
30413
+ });
30414
+
30415
+ // ../../modules/compression/src/lib/lazy-compression.ts
30416
+ function mergeModules(options, modules) {
30417
+ return { ...options, modules: { ...options.modules, ...modules } };
30418
+ }
30419
+ var LazyDecompressor;
30420
+ var init_lazy_compression = __esm({
30421
+ "../../modules/compression/src/lib/lazy-compression.ts"() {
30422
+ "use strict";
30423
+ init_compression();
30424
+ init_decompression_stream();
30425
+ LazyDecompressor = class extends Decompressor {
30426
+ name;
30427
+ extensions;
30428
+ contentEncodings;
30429
+ isSupported = true;
30430
+ /** Constructor options retained until a concrete implementation is selected. */
30431
+ options;
30432
+ /** Built-in stream format to probe, or null when the format has no built-in path. */
30433
+ nativeFormat;
30434
+ /** Returns whether built-in selection remains eligible for the merged preload options. */
30435
+ shouldUseNative;
30436
+ /** Dynamically imports the balanced fallback constructor. */
30437
+ loadFallback;
30438
+ /** Selected concrete implementation after preload completes. */
30439
+ implementation = null;
30440
+ /** Shared in-flight selection used by concurrent asynchronous calls. */
30441
+ implementationPromise = null;
30442
+ constructor(metadata, loadFallback, options = {}, nativeFormat = null, shouldUseNative = () => true) {
30443
+ super(options);
30444
+ this.name = metadata.name;
30445
+ this.extensions = [...metadata.extensions];
30446
+ this.contentEncodings = [...metadata.contentEncodings];
30447
+ this.options = options;
30448
+ this.nativeFormat = nativeFormat;
30449
+ this.shouldUseNative = shouldUseNative;
30450
+ this.loadFallback = loadFallback;
30451
+ }
30452
+ /** Selects and returns the built-in or dynamically imported fallback decompressor. */
30453
+ async preload(modules = {}) {
30454
+ if (this.implementation) return this.implementation;
30455
+ const options = mergeModules(this.options, modules);
30456
+ this.implementationPromise ||= this.loadImplementation(options);
30457
+ try {
30458
+ this.implementation = await this.implementationPromise;
30459
+ return this.implementation;
30460
+ } catch (error) {
30461
+ this.implementationPromise = null;
30462
+ throw error;
30463
+ }
30464
+ }
30465
+ /** Loads the selected concrete decompressor. */
30466
+ async loadImplementation(options) {
30467
+ if (options.useNative !== false && this.nativeFormat && this.shouldUseNative(options) && isNativeDecompressionSupported(this.nativeFormat)) {
30468
+ const { NativeDecompressor: NativeDecompressor2 } = await Promise.resolve().then(() => (init_native_decompressor(), native_decompressor_exports));
30469
+ return new NativeDecompressor2(this, this.nativeFormat, options);
30470
+ }
30471
+ const Decompressor2 = await this.loadFallback();
30472
+ const implementation = new Decompressor2({ ...options, useNative: false });
30473
+ await implementation.preload(options.modules);
30474
+ return implementation;
30475
+ }
30476
+ /** Decompresses after lazily selecting the default implementation. */
30477
+ async decompress(input, size) {
30478
+ return (await this.preload()).decompress(input, size);
30479
+ }
30480
+ /** Decompresses synchronously after an implementation has been preloaded. */
30481
+ decompressSync(input, size) {
30482
+ if (!this.implementation) {
30483
+ throw new Error(`${this.name}: call preload() before decompressSync()`);
30484
+ }
30485
+ return this.implementation.decompressSync(input, size);
30486
+ }
30487
+ /** Decompresses batches after lazily selecting the default implementation. */
30488
+ async *decompressBatches(inputBatches) {
30489
+ yield* (await this.preload()).decompressBatches(inputBatches);
30490
+ }
30491
+ };
30492
+ }
30493
+ });
30494
+
30495
+ // ../../modules/compression/src/gzip-decompressor-compress-utils.ts
30496
+ var GZipCompressUtilsDecompressor;
30497
+ var init_gzip_decompressor_compress_utils = __esm({
30498
+ "../../modules/compression/src/gzip-decompressor-compress-utils.ts"() {
30499
+ "use strict";
30500
+ init_compress_utils_compression();
30501
+ GZipCompressUtilsDecompressor = class extends CompressUtilsDecompressor {
30502
+ constructor(options = {}) {
30503
+ super(
30504
+ { name: "gzip", extensions: ["gz", "gzip"], contentEncodings: ["gzip", "x-gzip"] },
30505
+ () => import("compress-utils/gzip/decompress"),
30506
+ options
30507
+ );
30508
+ }
30509
+ };
30510
+ }
30511
+ });
30512
+
30513
+ // ../../modules/compression/src/gzip-decompressor.ts
30514
+ var gzip_decompressor_exports = {};
30515
+ __export(gzip_decompressor_exports, {
30516
+ GZipDecompressor: () => GZipDecompressor
30517
+ });
30518
+ var GZipDecompressor;
30519
+ var init_gzip_decompressor = __esm({
30520
+ "../../modules/compression/src/gzip-decompressor.ts"() {
30521
+ "use strict";
30522
+ init_gzip_decompressor_compress_utils();
30523
+ init_decompression_stream();
30524
+ GZipDecompressor = class extends GZipCompressUtilsDecompressor {
30525
+ /** Decompresses with native streams when available, otherwise lazily initializes WASM. */
30526
+ async decompress(input, size) {
30527
+ if (this.options.useNative !== false) {
30528
+ const output = await decompressWithNativeDecompressionStream(input, "gzip");
30529
+ if (output) return output;
30530
+ }
30531
+ return super.decompress(input, size);
30532
+ }
30533
+ /** Streams native batches when available, otherwise uses the WASM stream. */
30534
+ async *decompressBatches(inputBatches) {
30535
+ if (this.options.useNative !== false) {
30536
+ const output = decompressBatchesWithNativeDecompressionStream(inputBatches, "gzip");
30537
+ if (output) {
30538
+ yield* output;
30539
+ return;
30540
+ }
30541
+ }
30542
+ yield* super.decompressBatches(inputBatches);
30543
+ }
30544
+ };
30545
+ }
30546
+ });
30547
+
30548
+ // ../../modules/compression/src/default-codecs.ts
30549
+ var GZIP, GZipDecompressor2;
30550
+ var init_default_codecs = __esm({
30551
+ "../../modules/compression/src/default-codecs.ts"() {
30552
+ "use strict";
30553
+ init_lazy_compression();
30554
+ GZIP = { name: "gzip", extensions: ["gz"], contentEncodings: ["gzip"] };
30555
+ GZipDecompressor2 = class extends LazyDecompressor {
30556
+ constructor(options = {}) {
30557
+ super(
30558
+ GZIP,
30559
+ async () => (await Promise.resolve().then(() => (init_gzip_decompressor(), gzip_decompressor_exports))).GZipDecompressor,
30560
+ options,
30561
+ "gzip"
30562
+ );
30563
+ }
30564
+ };
30565
+ }
30566
+ });
30567
+
30568
+ // ../../modules/compression/src/index.ts
30569
+ var init_src13 = __esm({
30570
+ "../../modules/compression/src/index.ts"() {
30571
+ "use strict";
30572
+ init_default_codecs();
30573
+ }
30574
+ });
30575
+
30912
30576
  // ../../modules/i3s/src/lib/parsers/parse-slpk/slpk-archieve.ts
30913
30577
  var PATH_DESCRIPTIONS, SLPKArchive;
30914
30578
  var init_slpk_archieve = __esm({
30915
30579
  "../../modules/i3s/src/lib/parsers/parse-slpk/slpk-archieve.ts"() {
30916
30580
  "use strict";
30917
- init_src11();
30918
- init_src13();
30919
30581
  init_src12();
30582
+ init_src13();
30920
30583
  PATH_DESCRIPTIONS = [
30921
30584
  {
30922
30585
  test: /^$/,
@@ -30956,20 +30619,14 @@ var init_slpk_archieve = __esm({
30956
30619
  }
30957
30620
  ];
30958
30621
  SLPKArchive = class extends IndexedArchive {
30959
- // Maps hex-encoded md5 filename hashes to bigint offsets into the archive
30960
- hashTable;
30961
- _textEncoder = new TextEncoder();
30962
- _textDecoder = new TextDecoder();
30963
- _md5Hash = new MD5Hash();
30964
30622
  /**
30965
30623
  * Constructor
30966
30624
  * @param fileProvider - readable file handle for random access
30967
30625
  * @param hashTable - pre-loaded hashTable. If presented, getFile will skip reading the hash file
30968
30626
  * @param fileName - name of the archive. It is used to add to an URL of a loader context
30969
30627
  */
30970
- constructor(fileProvider, hashTable, fileName) {
30971
- super(fileProvider, hashTable, fileName);
30972
- this.hashTable = hashTable;
30628
+ constructor(fileProvider, hashTable, fileName, options) {
30629
+ super(fileProvider, hashTable, fileName, options);
30973
30630
  }
30974
30631
  /**
30975
30632
  * Returns file with the given path from slpk archive
@@ -31014,7 +30671,7 @@ var init_slpk_archieve = __esm({
31014
30671
  * @returns buffer with the file data
31015
30672
  */
31016
30673
  async getDataByPath(path) {
31017
- let data = await this.getFileBytes(path.toLocaleLowerCase());
30674
+ let data = await this.getFileBytes(path.toLowerCase());
31018
30675
  if (!data) {
31019
30676
  data = await this.getFileBytes(path);
31020
30677
  }
@@ -31034,68 +30691,29 @@ var init_slpk_archieve = __esm({
31034
30691
  * @returns buffer with the raw file data
31035
30692
  */
31036
30693
  async getFileBytes(path) {
31037
- let compressedFile;
31038
- if (this.hashTable) {
31039
- const binaryPath = this._textEncoder.encode(path);
31040
- const nameHash = await this._md5Hash.hash(binaryPath.buffer, "hex");
31041
- const offset = this.hashTable[nameHash];
31042
- if (offset === void 0) {
31043
- return void 0;
31044
- }
31045
- const localFileHeader = await parseZipLocalFileHeader(offset, this.file);
31046
- if (!localFileHeader) {
31047
- return void 0;
31048
- }
31049
- compressedFile = await readRange(
31050
- this.file,
31051
- localFileHeader.fileDataOffset,
31052
- localFileHeader.fileDataOffset + localFileHeader.compressedSize
31053
- );
31054
- } else {
31055
- try {
31056
- compressedFile = await this.getFileWithoutHash(path);
31057
- } catch {
31058
- compressedFile = void 0;
31059
- }
31060
- }
31061
- return compressedFile;
30694
+ return await this.readZipEntry(path);
31062
30695
  }
31063
30696
  };
31064
30697
  }
31065
30698
  });
31066
30699
 
31067
30700
  // ../../modules/i3s/src/lib/parsers/parse-slpk/parse-slpk.ts
31068
- async function parseSLPKArchive(fileProvider, cb, fileName) {
31069
- const hashCDOffset = await searchFromTheEnd(fileProvider, signature2);
31070
- const cdFileHeader = await parseZipCDFileHeader(hashCDOffset, fileProvider);
31071
- let hashTable;
31072
- if (cdFileHeader?.fileName !== "@specialIndexFileHASH128@") {
31073
- hashTable = await makeHashTableFromZipHeaders(fileProvider);
31074
- cb?.(
31075
- "SLPK doesnt contain hash file, hash info has been composed according to zip archive headers"
31076
- );
31077
- } else {
31078
- const localFileHeader = await parseZipLocalFileHeader(
31079
- cdFileHeader.localHeaderOffset,
31080
- fileProvider
31081
- );
31082
- if (!localFileHeader) {
31083
- throw new Error("corrupted SLPK");
31084
- }
31085
- const fileDataOffset = localFileHeader.fileDataOffset;
31086
- const hashFile = await readRange(
31087
- fileProvider,
31088
- fileDataOffset,
31089
- fileDataOffset + localFileHeader.compressedSize
31090
- );
31091
- hashTable = parseHashTable(hashFile);
30701
+ async function parseSLPKArchive(fileProvider, callback, fileName, options) {
30702
+ const archive = new SLPKArchive(fileProvider, void 0, fileName, options);
30703
+ try {
30704
+ if (!await archive.initializeIndex("@specialIndexFileHASH128@", true))
30705
+ callback?.(
30706
+ "SLPK doesnt contain hash file, hash info has been composed according to zip archive headers"
30707
+ );
30708
+ return archive;
30709
+ } catch (error) {
30710
+ await archive.close();
30711
+ throw error;
31092
30712
  }
31093
- return new SLPKArchive(fileProvider, hashTable, fileName);
31094
30713
  }
31095
30714
  var init_parse_slpk = __esm({
31096
30715
  "../../modules/i3s/src/lib/parsers/parse-slpk/parse-slpk.ts"() {
31097
30716
  "use strict";
31098
- init_src13();
31099
30717
  init_slpk_archieve();
31100
30718
  }
31101
30719
  });
@@ -32012,7 +31630,7 @@ function encodeSync3(tile, options) {
32012
31630
 
32013
31631
  // ../../modules/3d-tiles/src/index.ts
32014
31632
  init_constants();
32015
- init_d_tiles_archive_archive();
31633
+ init_d_tiles_archive_parser();
32016
31634
 
32017
31635
  // src/v4/i3s-converter/i3s-converter.ts
32018
31636
  var import_path7 = require("path");
@@ -32090,8 +31708,8 @@ async function writeFile(path, data, fileName = "index.json") {
32090
31708
  const pathFile = (0, import_path.join)(path, fileName);
32091
31709
  try {
32092
31710
  await import_fs2.promises.writeFile(pathFile, toWriteData);
32093
- } catch (err2) {
32094
- throw err2;
31711
+ } catch (err) {
31712
+ throw err;
32095
31713
  }
32096
31714
  console.log(`${pathFile} saved.`);
32097
31715
  return pathFile;
@@ -32151,8 +31769,8 @@ function getAbsoluteFilePath(filePath) {
32151
31769
  async function renameFile(oldPath, newPath) {
32152
31770
  try {
32153
31771
  await import_fs2.promises.rename(oldPath, newPath);
32154
- } catch (err2) {
32155
- console.log("Can't rename file", err2);
31772
+ } catch (err) {
31773
+ console.log("Can't rename file", err);
32156
31774
  }
32157
31775
  }
32158
31776
 
@@ -34314,7 +33932,8 @@ var STORE = {
34314
33932
  },
34315
33933
  normalReferenceFrame: {
34316
33934
  path: "normalReferenceFrame",
34317
- default: "east-north-up"
33935
+ // Geometry conversion rotates normals into the ECEF frame.
33936
+ default: "earth-centered"
34318
33937
  },
34319
33938
  attributeEncoding: {
34320
33939
  path: "attributeEncoding",
@@ -35131,7 +34750,7 @@ var NodeIndexDocument = class _NodeIndexDocument {
35131
34750
  }
35132
34751
  }
35133
34752
  /**
35134
- * Add neighbors to child nodes of this node
34753
+ * Add neighbors, save leaf documents and children, then release finalized child data.
35135
34754
  */
35136
34755
  async addNeighbors() {
35137
34756
  if (this.finalized) {
@@ -35159,6 +34778,9 @@ var NodeIndexDocument = class _NodeIndexDocument {
35159
34778
  }
35160
34779
  await childNode.save();
35161
34780
  }
34781
+ if (!this.children.length) {
34782
+ await this.save();
34783
+ }
35162
34784
  this.finalize();
35163
34785
  }
35164
34786
  /** Save 3DNodeIndexDocument in file on disk */
@@ -35331,7 +34953,7 @@ var NodeIndexDocument = class _NodeIndexDocument {
35331
34953
  // src/v4/i3s-converter/helpers/load-3d-tiles.ts
35332
34954
  init_src5();
35333
34955
  init_src2();
35334
- init_src13();
34956
+ init_src12();
35335
34957
  var loadNestedTileset = async (sourceTileset, sourceTile, tilesetLoadOptions) => {
35336
34958
  const isTileset = isNestedTileset(sourceTile);
35337
34959
  if (!sourceTileset || !sourceTile.contentUrl || !isTileset) {
@@ -35390,8 +35012,7 @@ async function loadFromArchive(url, loader, loadOptions) {
35390
35012
  if (filename2) {
35391
35013
  const tz3Path = `${tz3UrlParts[0]}.3tz`;
35392
35014
  const fileProvider = createReadableFile(tz3Path);
35393
- const hashTable = await loadHashTable(fileProvider);
35394
- const archive = new Tiles3DArchive(fileProvider, hashTable, tz3Path);
35015
+ const archive = await parse3DTilesArchive(fileProvider, void 0, tz3Path);
35395
35016
  const fileSystem = new ZipFileSystem(archive);
35396
35017
  const archiveLoadOptions = {
35397
35018
  ...loadOptions,
@@ -35412,28 +35033,6 @@ function createReadableFile(path) {
35412
35033
  }
35413
35034
  return isBrowser ? new HttpFile(path) : new NodeFileFacade(path);
35414
35035
  }
35415
- async function loadHashTable(fileProvider) {
35416
- let hashTable;
35417
- const hashCDOffset = await searchFromTheEnd(fileProvider, signature2);
35418
- const cdFileHeader = await parseZipCDFileHeader(hashCDOffset, fileProvider);
35419
- if (cdFileHeader?.fileName === "@3dtilesIndex1@") {
35420
- const localFileHeader = await parseZipLocalFileHeader(
35421
- cdFileHeader.localHeaderOffset,
35422
- fileProvider
35423
- );
35424
- if (!localFileHeader) {
35425
- throw new Error("corrupted 3tz");
35426
- }
35427
- const fileDataOffset = localFileHeader.fileDataOffset;
35428
- const hashFile = await readRange(
35429
- fileProvider,
35430
- fileDataOffset,
35431
- fileDataOffset + localFileHeader.compressedSize
35432
- );
35433
- hashTable = parseHashTable(hashFile);
35434
- }
35435
- return hashTable;
35436
- }
35437
35036
 
35438
35037
  // src/v4/i3s-converter/i3s-converter.ts
35439
35038
  var import_core22 = require("@math.gl/core");
@@ -35497,7 +35096,7 @@ var analyzeTileContent = async (tileContent) => {
35497
35096
  return defaultResult;
35498
35097
  }
35499
35098
  const gltfData = await parse(tileContent.gltfArrayBuffer, GLTFLoader, {
35500
- gltf: { normalize: false, loadBuffers: false, loadImages: false, decompressMeshes: false }
35099
+ gltf: { normalize: true, loadBuffers: false, loadImages: false, decompressMeshes: false }
35501
35100
  });
35502
35101
  const gltf = gltfData.json;
35503
35102
  if (!gltf) {
@@ -35691,7 +35290,7 @@ var Progress = class {
35691
35290
  };
35692
35291
 
35693
35292
  // src/v4/i3s-converter/i3s-converter.ts
35694
- init_src13();
35293
+ init_src12();
35695
35294
 
35696
35295
  // src/v4/lib/utils/conversion-dump.ts
35697
35296
  var import_util = require("util");
@@ -38105,7 +37704,7 @@ var Tiles3DContentConverter = class {
38105
37704
  // src/v4/3d-tiles-converter/helpers/load-i3s.ts
38106
37705
  init_src5();
38107
37706
  init_src2();
38108
- init_src13();
37707
+ init_src12();
38109
37708
  var loadI3SContent = async (sourceTileset, sourceTile, tilesetLoadOptions, slpkFilesystem) => {
38110
37709
  if (!sourceTileset || !sourceTile.contentUrl) {
38111
37710
  return null;
@@ -38170,9 +37769,7 @@ async function getNodeCount(fileSystem) {
38170
37769
  return 0;
38171
37770
  }
38172
37771
  const nodeSet = /* @__PURE__ */ new Set();
38173
- const filesIterator = makeZipCDHeaderIterator(fileSystem.file);
38174
- for await (const file of filesIterator) {
38175
- const filename2 = file.fileName;
37772
+ for (const filename2 of await fileSystem.readdir()) {
38176
37773
  const nodeNumberSearchResult = /^nodes\/(\d+)\//.exec(filename2);
38177
37774
  if (nodeNumberSearchResult) {
38178
37775
  nodeSet.add(nodeNumberSearchResult[1]);