@d5techs/3dgs-lib 1.4.22 → 1.4.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/3dgs-lib.cjs CHANGED
@@ -6303,91 +6303,231 @@ function findNearest(sortedCB, value) {
6303
6303
  }
6304
6304
  return lo;
6305
6305
  }
6306
- function kmeansVectors(vectors, dim, k, iterations) {
6307
- const n = vectors.length;
6308
- const labels = new Uint16Array(n);
6309
- if (n <= k) {
6310
- const centroids2 = [];
6311
- for (let i = 0; i < n; i++) {
6312
- centroids2.push(new Float32Array(vectors[i]));
6313
- labels[i] = i;
6306
+ function getGpuClusterShader(dim) {
6307
+ return (
6308
+ /* wgsl */
6309
+ `
6310
+ struct Uniforms {
6311
+ numPoints: u32,
6312
+ numCentroids: u32
6313
+ };
6314
+
6315
+ @group(0) @binding(0) var<uniform> uniforms: Uniforms;
6316
+ @group(0) @binding(1) var<storage, read> points: array<f32>;
6317
+ @group(0) @binding(2) var<storage, read> centroids: array<f32>;
6318
+ @group(0) @binding(3) var<storage, read_write> results: array<u32>;
6319
+
6320
+ const DIM = ${dim}u;
6321
+ const CHUNK_SIZE = 128u;
6322
+ var<workgroup> sharedChunk: array<f32, ${dim * 128}>;
6323
+
6324
+ fn calcDistSqr(point: array<f32, ${dim}>, cIdx: u32) -> f32 {
6325
+ var result = 0.0;
6326
+ var ci = cIdx * DIM;
6327
+ for (var i = 0u; i < DIM; i++) {
6328
+ let v = point[i] - sharedChunk[ci + i];
6329
+ result += v * v;
6330
+ }
6331
+ return result;
6332
+ }
6333
+
6334
+ @compute @workgroup_size(64)
6335
+ fn main(
6336
+ @builtin(local_invocation_index) localId: u32,
6337
+ @builtin(global_invocation_id) globalId: vec3u,
6338
+ @builtin(num_workgroups) numWgs: vec3u
6339
+ ) {
6340
+ let pointIdx = globalId.x + globalId.y * numWgs.x * 64u;
6341
+
6342
+ var point: array<f32, ${dim}>;
6343
+ if (pointIdx < uniforms.numPoints) {
6344
+ for (var i = 0u; i < DIM; i++) {
6345
+ point[i] = points[pointIdx * DIM + i];
6314
6346
  }
6315
- while (centroids2.length < k) centroids2.push(new Float32Array(dim));
6316
- return { centroids: centroids2, labels };
6317
6347
  }
6318
- const centroids = [];
6319
- centroids.push(new Float32Array(vectors[Math.floor(Math.random() * n)]));
6320
- const dist = new Float64Array(n);
6321
- dist.fill(Infinity);
6322
- for (let c = 1; c < k; c++) {
6323
- const last = centroids[c - 1];
6324
- let totalDist = 0;
6325
- for (let i = 0; i < n; i++) {
6326
- let d2 = 0;
6327
- for (let d = 0; d < dim; d++) {
6328
- const diff = vectors[i][d] - last[d];
6329
- d2 += diff * diff;
6330
- }
6331
- if (d2 < dist[i]) dist[i] = d2;
6332
- totalDist += dist[i];
6348
+
6349
+ var mind = 1e20;
6350
+ var mini = 0u;
6351
+
6352
+ let numChunks = (uniforms.numCentroids + CHUNK_SIZE - 1u) / CHUNK_SIZE;
6353
+ for (var chunk = 0u; chunk < numChunks; chunk++) {
6354
+
6355
+ let rowsPerThread = CHUNK_SIZE / 64u;
6356
+ let dstRow = localId * rowsPerThread;
6357
+ let srcRow = min(uniforms.numCentroids, chunk * CHUNK_SIZE + dstRow);
6358
+ let numRows = min(uniforms.numCentroids, srcRow + rowsPerThread) - srcRow;
6359
+
6360
+ var dst = dstRow * DIM;
6361
+ var src = srcRow * DIM;
6362
+ for (var c = 0u; c < numRows * DIM; c++) {
6363
+ sharedChunk[dst + c] = centroids[src + c];
6333
6364
  }
6334
- let target = Math.random() * totalDist;
6335
- let chosen = 0;
6336
- for (let i = 0; i < n; i++) {
6337
- target -= dist[i];
6338
- if (target <= 0) {
6339
- chosen = i;
6340
- break;
6365
+
6366
+ workgroupBarrier();
6367
+
6368
+ if (pointIdx < uniforms.numPoints) {
6369
+ let thisChunkSize = min(CHUNK_SIZE, uniforms.numCentroids - chunk * CHUNK_SIZE);
6370
+ for (var c = 0u; c < thisChunkSize; c++) {
6371
+ let d = calcDistSqr(point, c);
6372
+ if (d < mind) {
6373
+ mind = d;
6374
+ mini = chunk * CHUNK_SIZE + c;
6375
+ }
6341
6376
  }
6342
6377
  }
6343
- centroids.push(new Float32Array(vectors[chosen]));
6378
+
6379
+ workgroupBarrier();
6344
6380
  }
6345
- for (let iter = 0; iter < iterations; iter++) {
6346
- for (let i = 0; i < n; i++) {
6347
- let bestK = 0;
6348
- let bestD = Infinity;
6349
- for (let c = 0; c < k; c++) {
6350
- let d2 = 0;
6351
- for (let d = 0; d < dim; d++) {
6352
- const diff = vectors[i][d] - centroids[c][d];
6353
- d2 += diff * diff;
6354
- }
6355
- if (d2 < bestD) {
6356
- bestD = d2;
6357
- bestK = c;
6358
- }
6359
- }
6360
- labels[i] = bestK;
6381
+
6382
+ if (pointIdx < uniforms.numPoints) {
6383
+ results[pointIdx] = mini;
6384
+ }
6385
+ }`
6386
+ );
6387
+ }
6388
+ let _cachedDevice = null;
6389
+ let _deviceFailed = false;
6390
+ async function getGpuDevice() {
6391
+ if (_cachedDevice) return _cachedDevice;
6392
+ if (_deviceFailed) return null;
6393
+ try {
6394
+ if (typeof navigator === "undefined" || !navigator.gpu) {
6395
+ _deviceFailed = true;
6396
+ return null;
6361
6397
  }
6362
- const sums = [];
6363
- for (let c = 0; c < k; c++) sums.push(new Float64Array(dim));
6364
- const counts = new Uint32Array(k);
6365
- for (let i = 0; i < n; i++) {
6366
- const l = labels[i];
6367
- counts[l]++;
6368
- for (let d = 0; d < dim; d++) sums[l][d] += vectors[i][d];
6398
+ const adapter = await navigator.gpu.requestAdapter();
6399
+ if (!adapter) {
6400
+ _deviceFailed = true;
6401
+ return null;
6369
6402
  }
6370
- let changed = false;
6371
- for (let c = 0; c < k; c++) {
6372
- if (counts[c] > 0) {
6373
- for (let d = 0; d < dim; d++) {
6374
- const v = sums[c][d] / counts[c];
6375
- if (v !== centroids[c][d]) {
6376
- centroids[c][d] = v;
6377
- changed = true;
6378
- }
6379
- }
6403
+ _cachedDevice = await adapter.requestDevice({
6404
+ requiredLimits: {
6405
+ maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize,
6406
+ maxBufferSize: adapter.limits.maxBufferSize
6380
6407
  }
6408
+ });
6409
+ _cachedDevice.lost.then(() => {
6410
+ _cachedDevice = null;
6411
+ });
6412
+ return _cachedDevice;
6413
+ } catch {
6414
+ _deviceFailed = true;
6415
+ return null;
6416
+ }
6417
+ }
6418
+ async function gpuAssignLabels(device, pointsFlat, centroidsFlat, numPoints, numCentroids, dim) {
6419
+ const WORKGROUP_SIZE2 = 64;
6420
+ const BATCH_SIZE = 1024 * WORKGROUP_SIZE2;
6421
+ const numBatches = Math.ceil(numPoints / BATCH_SIZE);
6422
+ const shaderModule = device.createShaderModule({ code: getGpuClusterShader(dim) });
6423
+ const bindGroupLayout = device.createBindGroupLayout({
6424
+ entries: [
6425
+ { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: "uniform" } },
6426
+ { binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "read-only-storage" } },
6427
+ { binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: "read-only-storage" } },
6428
+ { binding: 3, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } }
6429
+ ]
6430
+ });
6431
+ const pipeline = device.createComputePipeline({
6432
+ layout: device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] }),
6433
+ compute: { module: shaderModule, entryPoint: "main" }
6434
+ });
6435
+ const uniformBuf = device.createBuffer({ size: 8, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
6436
+ const centroidsBuf = device.createBuffer({ size: centroidsFlat.byteLength, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
6437
+ device.queue.writeBuffer(centroidsBuf, 0, centroidsFlat.buffer);
6438
+ const pointsBufSize = BATCH_SIZE * dim * 4;
6439
+ const pointsBuf = device.createBuffer({ size: pointsBufSize, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
6440
+ const resultsBufSize = BATCH_SIZE * 4;
6441
+ const resultsBuf = device.createBuffer({ size: resultsBufSize, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC });
6442
+ const readbackBuf = device.createBuffer({ size: resultsBufSize, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST });
6443
+ const labels = new Uint32Array(numPoints);
6444
+ const bindGroup = device.createBindGroup({
6445
+ layout: bindGroupLayout,
6446
+ entries: [
6447
+ { binding: 0, resource: { buffer: uniformBuf } },
6448
+ { binding: 1, resource: { buffer: pointsBuf } },
6449
+ { binding: 2, resource: { buffer: centroidsBuf } },
6450
+ { binding: 3, resource: { buffer: resultsBuf } }
6451
+ ]
6452
+ });
6453
+ for (let batch = 0; batch < numBatches; batch++) {
6454
+ const offset = batch * BATCH_SIZE;
6455
+ const currentBatchSize = Math.min(numPoints - offset, BATCH_SIZE);
6456
+ const groups = Math.ceil(currentBatchSize / WORKGROUP_SIZE2);
6457
+ device.queue.writeBuffer(uniformBuf, 0, new Uint32Array([currentBatchSize, numCentroids]));
6458
+ device.queue.writeBuffer(pointsBuf, 0, pointsFlat.buffer, offset * dim * 4, currentBatchSize * dim * 4);
6459
+ const encoder = device.createCommandEncoder();
6460
+ const pass = encoder.beginComputePass();
6461
+ pass.setPipeline(pipeline);
6462
+ pass.setBindGroup(0, bindGroup);
6463
+ pass.dispatchWorkgroups(groups);
6464
+ pass.end();
6465
+ encoder.copyBufferToBuffer(resultsBuf, 0, readbackBuf, 0, currentBatchSize * 4);
6466
+ device.queue.submit([encoder.finish()]);
6467
+ await readbackBuf.mapAsync(GPUMapMode.READ);
6468
+ const mapped = new Uint32Array(readbackBuf.getMappedRange(0, currentBatchSize * 4));
6469
+ labels.set(mapped, offset);
6470
+ readbackBuf.unmap();
6471
+ }
6472
+ uniformBuf.destroy();
6473
+ centroidsBuf.destroy();
6474
+ pointsBuf.destroy();
6475
+ resultsBuf.destroy();
6476
+ readbackBuf.destroy();
6477
+ return labels;
6478
+ }
6479
+ async function kmeansGpu(pointsFlat, n, dim, k, iterations, onProgress) {
6480
+ const labels = new Uint32Array(n);
6481
+ if (n <= k) {
6482
+ const centroids2 = new Float32Array(k * dim);
6483
+ for (let i = 0; i < n; i++) {
6484
+ centroids2.set(pointsFlat.subarray(i * dim, i * dim + dim), i * dim);
6485
+ labels[i] = i;
6381
6486
  }
6382
- if (!changed) break;
6487
+ return { centroids: centroids2, labels };
6383
6488
  }
6489
+ const centroids = new Float32Array(k * dim);
6490
+ const indices = pickRandomIndices(n, k);
6491
+ for (let i = 0; i < k; i++) {
6492
+ centroids.set(pointsFlat.subarray(indices[i] * dim, indices[i] * dim + dim), i * dim);
6493
+ }
6494
+ const device = await getGpuDevice();
6495
+ for (let iter = 0; iter < iterations; iter++) {
6496
+ onProgress == null ? void 0 : onProgress(iter, iterations);
6497
+ if (device) {
6498
+ const newLabels = await gpuAssignLabels(device, pointsFlat, centroids, n, k, dim);
6499
+ labels.set(newLabels);
6500
+ } else {
6501
+ assignLabelsCpu(pointsFlat, centroids, labels, n, k, dim);
6502
+ }
6503
+ updateCentroids(pointsFlat, centroids, labels, n, k, dim);
6504
+ }
6505
+ onProgress == null ? void 0 : onProgress(iterations, iterations);
6506
+ if (device) {
6507
+ const finalLabels = await gpuAssignLabels(device, pointsFlat, centroids, n, k, dim);
6508
+ labels.set(finalLabels);
6509
+ } else {
6510
+ assignLabelsCpu(pointsFlat, centroids, labels, n, k, dim);
6511
+ }
6512
+ return { centroids, labels };
6513
+ }
6514
+ function pickRandomIndices(n, m) {
6515
+ const chosen = /* @__PURE__ */ new Set();
6516
+ for (let j = n - m; j < n; j++) {
6517
+ const t = Math.floor(Math.random() * (j + 1));
6518
+ chosen.add(chosen.has(t) ? j : t);
6519
+ }
6520
+ return [...chosen];
6521
+ }
6522
+ function assignLabelsCpu(points, centroids, labels, n, k, dim) {
6384
6523
  for (let i = 0; i < n; i++) {
6385
- let bestK = 0;
6386
- let bestD = Infinity;
6524
+ const pOff = i * dim;
6525
+ let bestK = 0, bestD = Infinity;
6387
6526
  for (let c = 0; c < k; c++) {
6527
+ const cOff = c * dim;
6388
6528
  let d2 = 0;
6389
6529
  for (let d = 0; d < dim; d++) {
6390
- const diff = vectors[i][d] - centroids[c][d];
6530
+ const diff = points[pOff + d] - centroids[cOff + d];
6391
6531
  d2 += diff * diff;
6392
6532
  }
6393
6533
  if (d2 < bestD) {
@@ -6397,7 +6537,25 @@ function kmeansVectors(vectors, dim, k, iterations) {
6397
6537
  }
6398
6538
  labels[i] = bestK;
6399
6539
  }
6400
- return { centroids: centroids.map((c) => new Float32Array(c)), labels };
6540
+ }
6541
+ function updateCentroids(points, centroids, labels, n, k, dim) {
6542
+ const sums = new Float64Array(k * dim);
6543
+ const counts = new Uint32Array(k);
6544
+ for (let i = 0; i < n; i++) {
6545
+ const l = labels[i];
6546
+ counts[l]++;
6547
+ const pOff = i * dim, sOff = l * dim;
6548
+ for (let d = 0; d < dim; d++) sums[sOff + d] += points[pOff + d];
6549
+ }
6550
+ for (let c = 0; c < k; c++) {
6551
+ if (counts[c] > 0) {
6552
+ const off = c * dim;
6553
+ for (let d = 0; d < dim; d++) centroids[off + d] = sums[off + d] / counts[c];
6554
+ } else {
6555
+ const idx = Math.floor(Math.random() * n);
6556
+ centroids.set(points.subarray(idx * dim, idx * dim + dim), c * dim);
6557
+ }
6558
+ }
6401
6559
  }
6402
6560
  function mortonSort(positions, count) {
6403
6561
  let minx = Infinity, miny = Infinity, minz = Infinity;
@@ -6468,11 +6626,12 @@ async function encodeWebP(width, height, pixelData) {
6468
6626
  }
6469
6627
  return new Uint8Array(await blob.arrayBuffer());
6470
6628
  }
6471
- async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6629
+ async function serializeSOG(data, coordinateSystem = "blender", options = {}, onProgress) {
6472
6630
  const { maxSHBands = 3, iterations = 10, paletteSize = 1024 } = options;
6473
6631
  const { count, colors, opacities } = data;
6474
6632
  let { positions, scales, rotations } = data;
6475
6633
  let shCoeffs = data.shCoeffs ? new Float32Array(data.shCoeffs) : void 0;
6634
+ onProgress == null ? void 0 : onProgress("coord_transform", 0);
6476
6635
  if (coordinateSystem === "blender") {
6477
6636
  positions = new Float32Array(positions);
6478
6637
  scales = new Float32Array(scales);
@@ -6495,6 +6654,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6495
6654
  }
6496
6655
  }
6497
6656
  }
6657
+ onProgress == null ? void 0 : onProgress("morton_sort", 0.05);
6498
6658
  const sortOrder = mortonSort(positions, count);
6499
6659
  const sPos = new Float32Array(count * 3);
6500
6660
  const sSca = new Float32Array(count * 3);
@@ -6527,6 +6687,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6527
6687
  }
6528
6688
  const { width, height } = calcImageDimensions(count);
6529
6689
  const totalPixels = width * height;
6690
+ onProgress == null ? void 0 : onProgress("encode_position", 0.1);
6530
6691
  const logPos = new Float32Array(count * 3);
6531
6692
  for (let i = 0; i < count * 3; i++) logPos[i] = symLog(sPos[i]);
6532
6693
  const mins = [Infinity, Infinity, Infinity];
@@ -6554,6 +6715,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6554
6715
  meansLData[off + 3] = 255;
6555
6716
  meansUData[off + 3] = 255;
6556
6717
  }
6718
+ onProgress == null ? void 0 : onProgress("encode_scale", 0.2);
6557
6719
  const logScales = new Float32Array(count * 3);
6558
6720
  for (let i = 0; i < count * 3; i++) logScales[i] = Math.log(Math.max(1e-8, sSca[i]));
6559
6721
  const scaleCodebook = buildCodebook(logScales, 256);
@@ -6566,6 +6728,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6566
6728
  scalesData[off + 2] = findNearest(scaleCodebook, logScales[i * 3 + 2]);
6567
6729
  scalesData[off + 3] = 255;
6568
6730
  }
6731
+ onProgress == null ? void 0 : onProgress("encode_quaternion", 0.3);
6569
6732
  const quatsData = new Uint8ClampedArray(totalPixels * 4);
6570
6733
  quatsData.fill(255);
6571
6734
  const SQRT2 = Math.SQRT2;
@@ -6618,6 +6781,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6618
6781
  quatsData[off + 2] = Math.round(Math.max(0, Math.min(255, (r2 / SQRT2 + 0.5) * 255)));
6619
6782
  quatsData[off + 3] = largest + 252;
6620
6783
  }
6784
+ onProgress == null ? void 0 : onProgress("encode_color", 0.4);
6621
6785
  const dcValues = new Float32Array(count * 3);
6622
6786
  for (let i = 0; i < count; i++) {
6623
6787
  dcValues[i * 3] = (sCol[i * 3] - 0.5) / SH_C0;
@@ -6646,18 +6810,28 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6646
6810
  encodeWebP(width, height, sh0Data)
6647
6811
  ];
6648
6812
  if (actualBands > 0 && sSH) {
6649
- const vectors = new Array(count);
6813
+ onProgress == null ? void 0 : onProgress("sh_compress", 0.5);
6814
+ const pointsFlat = new Float32Array(count * shDim);
6650
6815
  for (let i = 0; i < count; i++) {
6651
- const v = new Float32Array(shDim);
6652
6816
  const b = i * 45;
6653
- for (let j = 0; j < shDim; j++) v[j] = sSH[b + j];
6654
- vectors[i] = v;
6817
+ for (let j = 0; j < shDim; j++) pointsFlat[i * shDim + j] = sSH[b + j];
6655
6818
  }
6656
6819
  const effectivePaletteSize = Math.min(paletteSize, count);
6657
- const { centroids, labels } = kmeansVectors(vectors, shDim, effectivePaletteSize, iterations);
6658
- const allCoeffValues = new Float32Array(centroids.length * shDim);
6659
- for (let c = 0; c < centroids.length; c++) {
6660
- for (let d = 0; d < shDim; d++) allCoeffValues[c * shDim + d] = centroids[c][d];
6820
+ const { centroids, labels } = await kmeansGpu(
6821
+ pointsFlat,
6822
+ count,
6823
+ shDim,
6824
+ effectivePaletteSize,
6825
+ iterations,
6826
+ (iter, total) => {
6827
+ const p = 0.5 + 0.35 * (iter / total);
6828
+ onProgress == null ? void 0 : onProgress("sh_cluster", p, { iter, total });
6829
+ }
6830
+ );
6831
+ onProgress == null ? void 0 : onProgress("sh_quantize", 0.88);
6832
+ const allCoeffValues = new Float32Array(effectivePaletteSize * shDim);
6833
+ for (let c = 0; c < effectivePaletteSize; c++) {
6834
+ for (let d = 0; d < shDim; d++) allCoeffValues[c * shDim + d] = centroids[c * shDim + d];
6661
6835
  }
6662
6836
  const shCodebook = buildCodebook(allCoeffValues, 256);
6663
6837
  const centW = 64 * numCoeffs;
@@ -6665,14 +6839,14 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6665
6839
  const centData = new Uint8ClampedArray(centW * centH * 4);
6666
6840
  centData.fill(255);
6667
6841
  for (let n = 0; n < effectivePaletteSize; n++) {
6668
- const entry = centroids[n];
6669
6842
  for (let c = 0; c < numCoeffs; c++) {
6670
6843
  const u = n % 64 * numCoeffs + c;
6671
6844
  const v = Math.floor(n / 64);
6672
6845
  const off = (v * centW + u) * 4;
6673
- centData[off] = findNearest(shCodebook, entry[c * 3]);
6674
- centData[off + 1] = findNearest(shCodebook, entry[c * 3 + 1]);
6675
- centData[off + 2] = findNearest(shCodebook, entry[c * 3 + 2]);
6846
+ const cOff = n * shDim;
6847
+ centData[off] = findNearest(shCodebook, centroids[cOff + c * 3]);
6848
+ centData[off + 1] = findNearest(shCodebook, centroids[cOff + c * 3 + 1]);
6849
+ centData[off + 2] = findNearest(shCodebook, centroids[cOff + c * 3 + 2]);
6676
6850
  centData[off + 3] = 255;
6677
6851
  }
6678
6852
  }
@@ -6696,6 +6870,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6696
6870
  files: ["sh_centroids.webp", "sh_labels.webp"]
6697
6871
  };
6698
6872
  }
6873
+ onProgress == null ? void 0 : onProgress("encode_webp", 0.92);
6699
6874
  const webps = await Promise.all(webpPromises);
6700
6875
  const [meansLWebP, meansUWebP, scalesWebP, quatsWebP, sh0WebP] = webps;
6701
6876
  const meta = {
@@ -6721,7 +6896,9 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
6721
6896
  zipEntries["sh_centroids.webp"] = webps[5];
6722
6897
  zipEntries["sh_labels.webp"] = webps[6];
6723
6898
  }
6899
+ onProgress == null ? void 0 : onProgress("pack_zip", 0.98);
6724
6900
  const zipData = zipSync(zipEntries, { level: 0 });
6901
+ onProgress == null ? void 0 : onProgress("done", 1);
6725
6902
  return zipData.buffer;
6726
6903
  }
6727
6904
  const WORKGROUP_SIZE$1 = 256;