@loaders.gl/splats 4.5.3 → 5.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +14 -3
  2. package/dist/dist.dev.js +33699 -27589
  3. package/dist/dist.min.js +49 -52
  4. package/dist/index.cjs +2880 -689
  5. package/dist/index.cjs.map +3 -4
  6. package/dist/index.d.ts +6 -5
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +5 -4
  9. package/dist/index.js.map +1 -1
  10. package/dist/ksplat-loader-types.d.ts +24 -1
  11. package/dist/ksplat-loader-types.d.ts.map +1 -1
  12. package/dist/ksplat-loader-types.js +9 -3
  13. package/dist/ksplat-loader-types.js.map +1 -1
  14. package/dist/ksplat-loader.d.ts +1 -0
  15. package/dist/ksplat-loader.d.ts.map +1 -1
  16. package/dist/ksplat-loader.js +2 -1
  17. package/dist/ksplat-loader.js.map +1 -1
  18. package/dist/lib/parse-ksplat.d.ts.map +1 -1
  19. package/dist/lib/parse-ksplat.js +2 -2
  20. package/dist/lib/parse-ksplat.js.map +1 -1
  21. package/dist/lib/parse-rad-chunk.js +5 -5
  22. package/dist/lib/parse-rad-chunk.js.map +1 -1
  23. package/dist/lib/parse-spz.d.ts.map +1 -1
  24. package/dist/lib/parse-spz.js +156 -7
  25. package/dist/lib/parse-spz.js.map +1 -1
  26. package/dist/lib/splats-arrow-table.d.ts.map +1 -1
  27. package/dist/lib/splats-arrow-table.js +0 -1
  28. package/dist/lib/splats-arrow-table.js.map +1 -1
  29. package/dist/rad-loader-types.d.ts +21 -1
  30. package/dist/rad-loader-types.d.ts.map +1 -1
  31. package/dist/rad-loader-types.js +9 -3
  32. package/dist/rad-loader-types.js.map +1 -1
  33. package/dist/rad-loader.d.ts +1 -0
  34. package/dist/rad-loader.d.ts.map +1 -1
  35. package/dist/rad-loader.js +2 -1
  36. package/dist/rad-loader.js.map +1 -1
  37. package/dist/rad-source-loader.d.ts +6 -3
  38. package/dist/rad-source-loader.d.ts.map +1 -1
  39. package/dist/rad-source-loader.js +15 -6
  40. package/dist/rad-source-loader.js.map +1 -1
  41. package/dist/rad-zod-schema.cjs.map +0 -1
  42. package/dist/splat-loader-types.d.ts +24 -1
  43. package/dist/splat-loader-types.d.ts.map +1 -1
  44. package/dist/splat-loader-types.js +9 -3
  45. package/dist/splat-loader-types.js.map +1 -1
  46. package/dist/splat-loader.d.ts +1 -0
  47. package/dist/splat-loader.d.ts.map +1 -1
  48. package/dist/splat-loader.js +2 -1
  49. package/dist/splat-loader.js.map +1 -1
  50. package/dist/splats-format.d.ts +4 -0
  51. package/dist/splats-format.d.ts.map +1 -1
  52. package/dist/splats-format.js +4 -0
  53. package/dist/splats-format.js.map +1 -1
  54. package/dist/spz-loader-types.d.ts +25 -1
  55. package/dist/spz-loader-types.d.ts.map +1 -1
  56. package/dist/spz-loader-types.js +9 -3
  57. package/dist/spz-loader-types.js.map +1 -1
  58. package/dist/spz-loader.d.ts +1 -0
  59. package/dist/spz-loader.d.ts.map +1 -1
  60. package/dist/spz-loader.js +2 -1
  61. package/dist/spz-loader.js.map +1 -1
  62. package/dist/types.d.ts +6 -0
  63. package/dist/types.d.ts.map +1 -1
  64. package/package.json +6 -6
  65. package/src/index.ts +6 -5
  66. package/src/ksplat-loader-types.ts +9 -2
  67. package/src/ksplat-loader.ts +3 -1
  68. package/src/lib/parse-ksplat.ts +2 -4
  69. package/src/lib/parse-rad-chunk.ts +5 -5
  70. package/src/lib/parse-spz.ts +193 -8
  71. package/src/lib/splats-arrow-table.ts +0 -2
  72. package/src/rad-loader-types.ts +9 -2
  73. package/src/rad-loader.ts +3 -1
  74. package/src/rad-source-loader.ts +21 -8
  75. package/src/splat-loader-types.ts +9 -2
  76. package/src/splat-loader.ts +3 -1
  77. package/src/splats-format.ts +4 -0
  78. package/src/spz-loader-types.ts +9 -2
  79. package/src/spz-loader.ts +3 -1
  80. package/src/types.ts +7 -0
package/dist/index.cjs CHANGED
@@ -5,6 +5,14 @@ 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];
10
+ try {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ } catch (e) {
13
+ throw err2 = [e], e;
14
+ }
15
+ };
8
16
  var __export = (target, all) => {
9
17
  for (var name in all)
10
18
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,598 +35,2149 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
35
  ));
28
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
37
 
30
- // dist/index.js
31
- var dist_exports = {};
32
- __export(dist_exports, {
33
- KSPLATFormat: () => KSPLATFormat,
34
- KSPLATLoader: () => KSPLATLoaderWithParser,
35
- RADFormat: () => RADFormat,
36
- RADLoader: () => RADLoaderWithParser,
37
- RADSource: () => RADSource,
38
- RADSourceLoader: () => RADSourceLoader,
39
- SPLATFormat: () => SPLATFormat,
40
- SPLATLoader: () => SPLATLoaderWithParser,
41
- SPZFormat: () => SPZFormat,
42
- SPZLoader: () => SPZLoaderWithParser,
43
- resolveRADChunkUrl: () => resolveRADChunkUrl
38
+ // dist/splats-format.js
39
+ var SPLATFormat, KSPLATFormat, SPZFormat, RADFormat;
40
+ var init_splats_format = __esm({
41
+ "dist/splats-format.js"() {
42
+ "use strict";
43
+ SPLATFormat = {
44
+ name: "SPLAT",
45
+ id: "splat",
46
+ module: "splats",
47
+ format: "splat",
48
+ extensions: ["splat"],
49
+ mimeTypes: ["application/octet-stream"],
50
+ binary: true
51
+ };
52
+ KSPLATFormat = {
53
+ name: "KSPLAT",
54
+ id: "ksplat",
55
+ module: "splats",
56
+ format: "ksplat",
57
+ extensions: ["ksplat"],
58
+ mimeTypes: ["application/octet-stream"],
59
+ binary: true
60
+ };
61
+ SPZFormat = {
62
+ name: "SPZ",
63
+ id: "spz",
64
+ module: "splats",
65
+ format: "spz",
66
+ extensions: ["spz"],
67
+ mimeTypes: ["application/octet-stream"],
68
+ binary: true,
69
+ tests: [new Uint8Array([78, 71, 83, 80]).buffer]
70
+ };
71
+ RADFormat = {
72
+ name: "RAD",
73
+ id: "rad",
74
+ module: "splats",
75
+ format: "rad",
76
+ extensions: ["rad"],
77
+ mimeTypes: ["application/octet-stream"],
78
+ binary: true,
79
+ tests: [new Uint8Array([82, 65, 68, 48]).buffer]
80
+ };
81
+ }
44
82
  });
45
- module.exports = __toCommonJS(dist_exports);
46
83
 
47
- // dist/splats-format.js
48
- var SPLATFormat = {
49
- name: "SPLAT",
50
- id: "splat",
51
- module: "splats",
52
- extensions: ["splat"],
53
- mimeTypes: ["application/octet-stream"],
54
- binary: true
55
- };
56
- var KSPLATFormat = {
57
- name: "KSPLAT",
58
- id: "ksplat",
59
- module: "splats",
60
- extensions: ["ksplat"],
61
- mimeTypes: ["application/octet-stream"],
62
- binary: true
63
- };
64
- var SPZFormat = {
65
- name: "SPZ",
66
- id: "spz",
67
- module: "splats",
68
- extensions: ["spz"],
69
- mimeTypes: ["application/octet-stream"],
70
- binary: true,
71
- tests: [new Uint8Array([78, 71, 83, 80]).buffer]
72
- };
73
- var RADFormat = {
74
- name: "RAD",
75
- id: "rad",
76
- module: "splats",
77
- extensions: ["rad"],
78
- mimeTypes: ["application/octet-stream"],
79
- binary: true,
80
- tests: [new Uint8Array([82, 65, 68, 48]).buffer]
81
- };
84
+ // ../loader-utils/src/lib/log-utils/log.ts
85
+ function createLog() {
86
+ const log2 = new import_log.Log({ id: "loaders.gl" });
87
+ globalThis.loaders ||= {};
88
+ globalThis.loaders.log = log2;
89
+ globalThis.loaders.version = version;
90
+ globalThis.probe ||= {};
91
+ globalThis.probe.loaders = log2;
92
+ return log2;
93
+ }
94
+ var import_log, VERSION, version, log;
95
+ var init_log = __esm({
96
+ "../loader-utils/src/lib/log-utils/log.ts"() {
97
+ "use strict";
98
+ import_log = require("@probe.gl/log");
99
+ VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
100
+ version = VERSION[0] >= "0" && VERSION[0] <= "9" ? `v${VERSION}` : "";
101
+ log = createLog();
102
+ }
103
+ });
82
104
 
83
- // dist/lib/splats-arrow-table.js
84
- var arrow = __toESM(require("apache-arrow"), 1);
105
+ // ../loader-utils/src/lib/javascript-utils/is-type.ts
106
+ var isObject, isPureObject, isSharedArrayBuffer;
107
+ var init_is_type = __esm({
108
+ "../loader-utils/src/lib/javascript-utils/is-type.ts"() {
109
+ "use strict";
110
+ isObject = (value) => value !== null && typeof value === "object";
111
+ isPureObject = (value) => isObject(value) && value.constructor === {}.constructor;
112
+ isSharedArrayBuffer = (value) => typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
113
+ }
114
+ });
85
115
 
86
- // dist/lib/splat-utils.js
87
- var SH_C0 = 0.28209479177387814;
88
- function convertColorByteToSphericalHarmonicDc(colorByte) {
89
- return (colorByte / 255 - 0.5) / SH_C0;
116
+ // ../loader-utils/src/lib/option-utils/merge-options.ts
117
+ function mergeOptions(baseOptions, newOptions) {
118
+ return mergeOptionsRecursively(baseOptions || {}, newOptions);
119
+ }
120
+ function mergeOptionsRecursively(baseOptions, newOptions, level = 0) {
121
+ if (level > 3) {
122
+ return newOptions;
123
+ }
124
+ const options = { ...baseOptions };
125
+ for (const [key, newValue] of Object.entries(newOptions)) {
126
+ if (isPureObject(newValue)) {
127
+ options[key] = mergeOptionsRecursively(
128
+ options[key] || {},
129
+ newOptions[key],
130
+ level + 1
131
+ );
132
+ } else {
133
+ options[key] = newOptions[key];
134
+ }
135
+ }
136
+ return options;
90
137
  }
91
- function convertAlphaByteToLinearOpacity(alphaByte) {
92
- return Math.min(Math.max(alphaByte / 255, 0), 1);
138
+ var init_merge_options = __esm({
139
+ "../loader-utils/src/lib/option-utils/merge-options.ts"() {
140
+ "use strict";
141
+ init_is_type();
142
+ }
143
+ });
144
+
145
+ // ../loader-utils/src/lib/module-utils/js-module-utils.ts
146
+ function registerJSModules(modules) {
147
+ globalThis.loaders ||= {};
148
+ globalThis.loaders.modules ||= {};
149
+ Object.assign(globalThis.loaders.modules, modules);
93
150
  }
94
- function normalizeQuaternion(w, x, y, z2) {
95
- const length = Math.hypot(w, x, y, z2);
96
- if (!Number.isFinite(length) || length <= Number.EPSILON) {
97
- return [1, 0, 0, 0];
151
+ function getJSModule(name, caller) {
152
+ var _a, _b;
153
+ const module2 = (_b = (_a = globalThis.loaders) == null ? void 0 : _a.modules) == null ? void 0 : _b[name];
154
+ if (!module2) {
155
+ throw new Error(`${caller}: ${name} library not installed`);
98
156
  }
99
- return [w / length, x / length, y / length, z2 / length];
157
+ return module2;
100
158
  }
101
- function decodeQuaternionByte(byte) {
102
- return (byte - 128) / 128;
159
+ function getJSModuleOrNull(name) {
160
+ var _a, _b;
161
+ const module2 = (_b = (_a = globalThis.loaders) == null ? void 0 : _a.modules) == null ? void 0 : _b[name];
162
+ return module2 || null;
103
163
  }
104
- function decodeFloat16(value) {
105
- const sign = value & 32768 ? -1 : 1;
106
- const exponent = value >> 10 & 31;
107
- const fraction = value & 1023;
108
- if (exponent === 0) {
109
- return sign * Math.pow(2, -14) * (fraction / 1024);
164
+ var init_js_module_utils = __esm({
165
+ "../loader-utils/src/lib/module-utils/js-module-utils.ts"() {
166
+ "use strict";
110
167
  }
111
- if (exponent === 31) {
112
- return fraction ? Number.NaN : sign * Number.POSITIVE_INFINITY;
168
+ });
169
+
170
+ // ../loader-utils/src/lib/binary-utils/array-buffer-utils.ts
171
+ function concatenateArrayBuffers(...sources) {
172
+ return concatenateArrayBuffersFromArray(sources);
173
+ }
174
+ function concatenateArrayBuffersFromArray(sources) {
175
+ const sourceArrays = sources.map(
176
+ (source2) => source2 instanceof ArrayBuffer ? new Uint8Array(source2) : source2
177
+ );
178
+ const byteLength = sourceArrays.reduce((length, typedArray) => length + typedArray.byteLength, 0);
179
+ const result = new Uint8Array(byteLength);
180
+ let offset = 0;
181
+ for (const sourceArray of sourceArrays) {
182
+ result.set(sourceArray, offset);
183
+ offset += sourceArray.byteLength;
184
+ }
185
+ return result.buffer;
186
+ }
187
+ var init_array_buffer_utils = __esm({
188
+ "../loader-utils/src/lib/binary-utils/array-buffer-utils.ts"() {
189
+ "use strict";
113
190
  }
114
- return sign * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
191
+ });
192
+
193
+ // ../loader-utils/src/lib/iterators/async-iteration.ts
194
+ async function concatenateArrayBuffersAsync(asyncIterator) {
195
+ const arrayBuffers = [];
196
+ for await (const chunk of asyncIterator) {
197
+ arrayBuffers.push(copyToArrayBuffer(chunk));
198
+ }
199
+ return concatenateArrayBuffers(...arrayBuffers);
200
+ }
201
+ function copyToArrayBuffer(chunk) {
202
+ if (chunk instanceof ArrayBuffer) {
203
+ return chunk;
204
+ }
205
+ if (ArrayBuffer.isView(chunk)) {
206
+ const { buffer, byteOffset, byteLength } = chunk;
207
+ return copyFromBuffer(buffer, byteOffset, byteLength);
208
+ }
209
+ return copyFromBuffer(chunk);
115
210
  }
211
+ function copyFromBuffer(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
212
+ const view = new Uint8Array(buffer, byteOffset, byteLength);
213
+ const copy = new Uint8Array(view.length);
214
+ copy.set(view);
215
+ return copy.buffer;
216
+ }
217
+ var init_async_iteration = __esm({
218
+ "../loader-utils/src/lib/iterators/async-iteration.ts"() {
219
+ "use strict";
220
+ init_array_buffer_utils();
221
+ }
222
+ });
116
223
 
117
- // dist/lib/splats-arrow-table.js
118
- function makeGaussianSplatsArrowTable(splats) {
119
- const columns = {};
120
- const fields = [];
121
- const schemaFields = [];
122
- addColumn(columns, fields, schemaFields, "POSITION", makeFixedSizeListVector(splats.positions, 3), {
123
- type: "fixed-size-list",
124
- listSize: 3,
125
- children: [{ name: "value", type: "float32" }]
126
- });
127
- const colorCoefficients = getColorCoefficients(splats);
128
- addScalarColumn(columns, fields, schemaFields, "f_dc_0", colorCoefficients[0], {
129
- "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_dc",
130
- "loaders_gl.gaussian_splats.component": "0",
131
- "loaders_gl.gaussian_splats.encoding": "coefficient"
132
- });
133
- addScalarColumn(columns, fields, schemaFields, "f_dc_1", colorCoefficients[1], {
134
- "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_dc",
135
- "loaders_gl.gaussian_splats.component": "1",
136
- "loaders_gl.gaussian_splats.encoding": "coefficient"
224
+ // ../loader-utils/src/lib/request-utils/authentication.ts
225
+ function resolveCredentials(credentials, authentications = []) {
226
+ if (credentials.every(isAuthentication)) return credentials;
227
+ return credentials.map((credential, index) => {
228
+ if (isAuthentication(credential)) return credential;
229
+ const AuthenticationClass = authentications.find(
230
+ (authentication2) => authentication2.type === (credential == null ? void 0 : credential.type)
231
+ );
232
+ if (!AuthenticationClass) {
233
+ throw new Error(`No authentication class registered for credential at index ${index}.`);
234
+ }
235
+ let authentication;
236
+ try {
237
+ authentication = new AuthenticationClass(credential);
238
+ } catch {
239
+ throw new Error(`Invalid authentication configuration at index ${index}.`);
240
+ }
241
+ if (!isAuthentication(authentication)) {
242
+ throw new Error(`Authentication class returned an invalid credential at index ${index}.`);
243
+ }
244
+ return authentication;
137
245
  });
138
- addScalarColumn(columns, fields, schemaFields, "f_dc_2", colorCoefficients[2], {
139
- "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_dc",
140
- "loaders_gl.gaussian_splats.component": "2",
141
- "loaders_gl.gaussian_splats.encoding": "coefficient"
246
+ }
247
+ function resolveAuthenticationOptions(options) {
248
+ var _a, _b;
249
+ if (!((_b = (_a = options.core) == null ? void 0 : _a.credentials) == null ? void 0 : _b.length)) return options;
250
+ const credentials = resolveCredentials(options.core.credentials, options.core.authentications);
251
+ if (credentials === options.core.credentials) return options;
252
+ return { ...options, core: { ...options.core, credentials } };
253
+ }
254
+ function isAuthentication(credential) {
255
+ if (!credential || typeof credential !== "object") return false;
256
+ if (typeof credential.id !== "string" || !Array.isArray(credential.origins)) return false;
257
+ if (credential.type === "request") return typeof credential.authenticate === "function";
258
+ return (credential.type === "header" || credential.type === "query-parameter") && typeof credential.name === "string" && (typeof credential.token === "string" || typeof credential.token === "function") && Array.isArray(credential.refreshStatusCodes);
259
+ }
260
+ var init_authentication = __esm({
261
+ "../loader-utils/src/lib/request-utils/authentication.ts"() {
262
+ "use strict";
263
+ }
264
+ });
265
+
266
+ // ../loader-utils/src/lib/request-utils/request-credentials.ts
267
+ function createAuthenticatedFetch(options) {
268
+ const suppliedFetch = options.fetch || ((url, requestOptions) => fetch(url, requestOptions));
269
+ const existingMetadata = suppliedFetch[AUTHENTICATED_FETCH];
270
+ const credentialResolutions = new Map(existingMetadata == null ? void 0 : existingMetadata.credentialResolutions);
271
+ const resolvedCredentials = resolveCredentials(
272
+ options.credentials.map((credential) => credentialResolutions.get(credential) || credential),
273
+ options.authentications
274
+ );
275
+ options.credentials.forEach((credential, index) => {
276
+ credentialResolutions.set(credential, resolvedCredentials[index]);
142
277
  });
143
- addScalarColumn(columns, fields, schemaFields, "opacity", splats.opacities, {
144
- "loaders_gl.gaussian_splats.semantic": "opacity",
145
- "loaders_gl.gaussian_splats.encoding": "linear"
278
+ if (!options.fetchOptions && (!resolvedCredentials.length || (existingMetadata == null ? void 0 : existingMetadata.credentials.length) === resolvedCredentials.length && resolvedCredentials.every(
279
+ (credential, index) => credential === existingMetadata.credentials[index]
280
+ )))
281
+ return suppliedFetch;
282
+ const baseFetch = (existingMetadata == null ? void 0 : existingMetadata.fetch) || suppliedFetch;
283
+ const credentials = existingMetadata ? [.../* @__PURE__ */ new Set([...resolvedCredentials, ...existingMetadata.credentials])] : resolvedCredentials;
284
+ const fetchOptions = mergeFetchOptions(
285
+ (existingMetadata == null ? void 0 : existingMetadata.fetchOptions) || {},
286
+ options.fetchOptions
287
+ );
288
+ const tokenCredentials = credentials.filter(
289
+ (credential) => credential.type !== "request"
290
+ );
291
+ const requestCredentials = credentials.filter(
292
+ (credential) => credential.type === "request"
293
+ );
294
+ for (const credential of requestCredentials) normalizeRequestOrigins(credential.origins);
295
+ const authenticatedFetch = async (url, requestOptions = {}) => {
296
+ var _a, _b, _c, _d, _e, _f, _g;
297
+ requestOptions = mergeFetchOptions(fetchOptions, requestOptions);
298
+ if ((_a = requestOptions.signal) == null ? void 0 : _a.aborted) throw createAbortError();
299
+ if (!credentials.length) return baseFetch(url, requestOptions);
300
+ const resolvedURL = parseHTTPURL(url);
301
+ const authorization = resolvedURL ? await authorizeRequest(resolvedURL, requestOptions, tokenCredentials) : { url, options: requestOptions, credentials: [] };
302
+ const signedRequest = await authenticateRequest(authorization, requestCredentials, "request");
303
+ const response = await baseFetch(signedRequest.url, signedRequest.options);
304
+ const refreshableCredentials = [];
305
+ for (const resolvedCredential of authorization.credentials) {
306
+ const { credential } = resolvedCredential;
307
+ if (typeof credential.token === "function" && (isReplayableRequest(requestOptions) || ((_b = credential.canReplayRequest) == null ? void 0 : _b.call(credential, url, requestOptions))) && (isReplayableRequest(signedRequest.options) || ((_c = credential.canReplayRequest) == null ? void 0 : _c.call(credential, signedRequest.url, signedRequest.options))) && (credential.refreshStatusCodes.includes(response.status) || await ((_d = credential.shouldRefresh) == null ? void 0 : _d.call(credential, response))))
308
+ refreshableCredentials.push(resolvedCredential);
309
+ }
310
+ const shouldRetrySignature = isReplayableRequest(requestOptions) && isReplayableRequest(signedRequest.options) && signedRequest.credentials.some(
311
+ (credential) => {
312
+ var _a2;
313
+ return (_a2 = credential.refreshStatusCodes) == null ? void 0 : _a2.includes(response.status);
314
+ }
315
+ );
316
+ if (!refreshableCredentials.length && !shouldRetrySignature) return response;
317
+ if ((_e = requestOptions.signal) == null ? void 0 : _e.aborted) throw createAbortError();
318
+ const refreshedTokens = /* @__PURE__ */ new Map();
319
+ await Promise.all(
320
+ refreshableCredentials.map(async ({ credential }) => {
321
+ const token = await refreshCredential(credential, url, response);
322
+ if (token) refreshedTokens.set(credential, token);
323
+ })
324
+ );
325
+ if (!refreshedTokens.size && !shouldRetrySignature) return response;
326
+ await ((_f = response.body) == null ? void 0 : _f.cancel().catch(() => {
327
+ }));
328
+ if ((_g = requestOptions.signal) == null ? void 0 : _g.aborted) throw createAbortError();
329
+ const replayAuthorization = resolvedURL ? await authorizeRequest(
330
+ resolvedURL,
331
+ requestOptions,
332
+ tokenCredentials,
333
+ refreshedTokens,
334
+ authorization.credentials
335
+ ) : { url, options: requestOptions };
336
+ const replayRequest = await authenticateRequest(
337
+ replayAuthorization,
338
+ requestCredentials,
339
+ "retry",
340
+ response
341
+ );
342
+ return baseFetch(replayRequest.url, replayRequest.options);
343
+ };
344
+ Object.defineProperty(authenticatedFetch, AUTHENTICATED_FETCH, {
345
+ value: {
346
+ fetch: baseFetch,
347
+ credentials,
348
+ credentialResolutions,
349
+ fetchOptions
350
+ }
146
351
  });
147
- addVectorComponents(columns, fields, schemaFields, "scale", splats.scales, 3, {
148
- "loaders_gl.gaussian_splats.semantic": "scale",
149
- "loaders_gl.gaussian_splats.encoding": "linear"
352
+ return authenticatedFetch;
353
+ }
354
+ function getAuthenticatedFetch(options = {}) {
355
+ var _a, _b, _c;
356
+ const fetchOption = options.fetch ?? ((_a = options.core) == null ? void 0 : _a.fetch);
357
+ let fetchFunction;
358
+ if (typeof fetchOption === "function") {
359
+ fetchFunction = fetchOption;
360
+ } else {
361
+ fetchFunction = (url, requestOptions) => fetch(url, requestOptions);
362
+ }
363
+ return createAuthenticatedFetch({
364
+ fetch: fetchFunction,
365
+ fetchOptions: typeof fetchOption === "object" && fetchOption ? fetchOption : void 0,
366
+ credentials: ((_b = options.core) == null ? void 0 : _b.credentials) || [],
367
+ authentications: (_c = options.core) == null ? void 0 : _c.authentications
150
368
  });
151
- addVectorComponents(columns, fields, schemaFields, "rot", splats.rotations, 4, {
152
- "loaders_gl.gaussian_splats.semantic": "rotation",
153
- "loaders_gl.gaussian_splats.encoding": "quaternion"
369
+ }
370
+ function mergeFetchOptions(defaultOptions, requestOptions) {
371
+ const mergedOptions = { ...defaultOptions, ...requestOptions };
372
+ if (defaultOptions.headers || (requestOptions == null ? void 0 : requestOptions.headers)) {
373
+ const headers = new Headers(defaultOptions.headers);
374
+ new Headers(requestOptions == null ? void 0 : requestOptions.headers).forEach((value, key) => headers.set(key, value));
375
+ mergedOptions.headers = headers;
376
+ }
377
+ return mergedOptions;
378
+ }
379
+ async function authenticateRequest(request, credentials, reason, response) {
380
+ const appliedCredentials = [];
381
+ const signal = request.options.signal;
382
+ for (const credential of credentials) {
383
+ const origin = getRequestOrigin(request.url);
384
+ if (!origin || !normalizeRequestOrigins(credential.origins).includes(origin)) continue;
385
+ if (signal == null ? void 0 : signal.aborted) throw createAbortError();
386
+ const authenticatedRequest = await credential.authenticate({
387
+ url: request.url,
388
+ options: { ...request.options, headers: new Headers(request.options.headers) },
389
+ reason,
390
+ response: response ? { status: response.status, headers: new Headers(response.headers) } : void 0
391
+ });
392
+ if (!authenticatedRequest || typeof authenticatedRequest.url !== "string" || !authenticatedRequest.options || typeof authenticatedRequest.options !== "object") {
393
+ throw new Error("Authentication callback returned an invalid request.");
394
+ }
395
+ request = {
396
+ url: authenticatedRequest.url,
397
+ options: { ...authenticatedRequest.options, ...signal ? { signal } : {} }
398
+ };
399
+ appliedCredentials.push(credential);
400
+ }
401
+ if (signal == null ? void 0 : signal.aborted) throw createAbortError();
402
+ return { ...request, credentials: appliedCredentials };
403
+ }
404
+ function getRequestOrigin(url) {
405
+ try {
406
+ const parsedURL = new URL(url);
407
+ if (!parsedURL.host || parsedURL.username || parsedURL.password) return null;
408
+ return parsedURL.origin !== "null" ? parsedURL.origin : `${parsedURL.protocol}//${parsedURL.host}`;
409
+ } catch {
410
+ return null;
411
+ }
412
+ }
413
+ function normalizeRequestOrigins(origins) {
414
+ if (!origins.length)
415
+ throw new Error("Request authentication requires at least one exact origin.");
416
+ return origins.map((origin) => {
417
+ const resolvedOrigin = getRequestOrigin(origin);
418
+ let url;
419
+ try {
420
+ url = new URL(origin);
421
+ } catch {
422
+ throw new Error("Invalid request authentication origin.");
423
+ }
424
+ if (!resolvedOrigin || url.pathname && url.pathname !== "/" || url.search || url.hash) {
425
+ throw new Error("Invalid request authentication origin.");
426
+ }
427
+ return resolvedOrigin;
154
428
  });
155
- if (splats.sphericalHarmonics && splats.sphericalHarmonicsComponentCount) {
156
- addSphericalHarmonicRestColumns(columns, fields, schemaFields, splats.sphericalHarmonics, splats.sphericalHarmonicsComponentCount);
429
+ }
430
+ async function authorizeRequest(sourceURL, requestOptions, credentials, tokenOverrides = /* @__PURE__ */ new Map(), previousCredentials = []) {
431
+ const url = new URL(sourceURL);
432
+ const headers = new Headers(requestOptions.headers);
433
+ const resolvedCredentials = [];
434
+ const previousTokens = new Map(
435
+ previousCredentials.map(({ credential, token }) => [credential, token])
436
+ );
437
+ for (const credential of credentials) {
438
+ if (!credential.origins.includes(url.origin)) continue;
439
+ const overrideToken = tokenOverrides.get(credential);
440
+ const previousToken = previousTokens.get(credential);
441
+ const ownsQueryParameter = credential.type === "query-parameter" && previousToken !== void 0;
442
+ const ownsHeader = credential.type === "header" && previousToken !== void 0;
443
+ if (credential.type === "query-parameter" && url.searchParams.has(credential.name) && !ownsQueryParameter || credential.type === "header" && headers.has(credential.name) && !ownsHeader) {
444
+ continue;
445
+ }
446
+ const token = overrideToken ?? previousToken ?? await resolveToken(credential.token, { url: sourceURL.toString(), reason: "request" });
447
+ if (!token) continue;
448
+ if (credential.type === "query-parameter") {
449
+ url.searchParams.set(credential.name, token);
450
+ } else {
451
+ headers.set(credential.name, `${credential.prefix || ""}${token}`);
452
+ }
453
+ resolvedCredentials.push({ credential, token });
157
454
  }
158
- const metadata = /* @__PURE__ */ new Map([
159
- ["loaders_gl.semantic_type", "gaussian-splats"],
160
- ["loaders_gl.gaussian_splats.version", "1"],
161
- ["loaders_gl.gaussian_splats.source_format", splats.format],
162
- ["topology", "point-list"],
163
- ["mode", "0"]
164
- ]);
165
- const arrowSchema = new arrow.Schema(fields, metadata);
166
- const schema = {
167
- fields: schemaFields,
168
- metadata: Object.fromEntries(metadata)
169
- };
170
455
  return {
171
- shape: "arrow-table",
172
- schema,
173
- data: new arrow.Table(arrowSchema, columns),
174
- topology: "point-list",
175
- loaderData: splats.loaderData
456
+ url: url.toString(),
457
+ options: { ...requestOptions, headers },
458
+ credentials: resolvedCredentials
176
459
  };
177
460
  }
178
- function addVectorComponents(columns, fields, schemaFields, prefix, values, size, metadata) {
179
- for (let component = 0; component < size; component++) {
180
- const componentValues = new Float32Array(values.length / size);
181
- for (let rowIndex = 0; rowIndex < componentValues.length; rowIndex++) {
182
- componentValues[rowIndex] = values[rowIndex * size + component];
183
- }
184
- addScalarColumn(columns, fields, schemaFields, `${prefix}_${component}`, componentValues, {
185
- ...metadata,
186
- "loaders_gl.gaussian_splats.component": String(component)
187
- });
461
+ async function refreshCredential(credential, url, response) {
462
+ const existingPromise = refreshPromises.get(credential);
463
+ if (existingPromise) return existingPromise;
464
+ const tokenProvider = credential.token;
465
+ const promise = Promise.resolve(
466
+ tokenProvider({
467
+ url,
468
+ reason: "refresh",
469
+ response: { status: response.status, headers: response.headers }
470
+ })
471
+ ).finally(() => refreshPromises.delete(credential));
472
+ refreshPromises.set(credential, promise);
473
+ return promise;
474
+ }
475
+ async function resolveToken(token, context) {
476
+ return typeof token === "function" ? token(context) : token;
477
+ }
478
+ function parseHTTPURL(url) {
479
+ try {
480
+ const parsedURL = new URL(url);
481
+ return ["http:", "https:"].includes(parsedURL.protocol) ? parsedURL : null;
482
+ } catch {
483
+ return null;
188
484
  }
189
485
  }
190
- function addSphericalHarmonicRestColumns(columns, fields, schemaFields, sphericalHarmonics, componentCount) {
191
- for (let component = 0; component < componentCount; component++) {
192
- const componentValues = new Float32Array(sphericalHarmonics.length / componentCount);
193
- for (let rowIndex = 0; rowIndex < componentValues.length; rowIndex++) {
194
- componentValues[rowIndex] = sphericalHarmonics[rowIndex * componentCount + component];
486
+ function isReplayableRequest(options) {
487
+ const method = (options.method || "GET").toUpperCase();
488
+ if (!["GET", "HEAD", "OPTIONS", "PUT", "DELETE"].includes(method)) return false;
489
+ return !(options.body && typeof ReadableStream !== "undefined" && options.body instanceof ReadableStream);
490
+ }
491
+ function createAbortError() {
492
+ return new DOMException("The operation was aborted.", "AbortError");
493
+ }
494
+ var AUTHENTICATED_FETCH, refreshPromises;
495
+ var init_request_credentials = __esm({
496
+ "../loader-utils/src/lib/request-utils/request-credentials.ts"() {
497
+ "use strict";
498
+ init_authentication();
499
+ AUTHENTICATED_FETCH = /* @__PURE__ */ Symbol("loaders.gl.authenticated-fetch");
500
+ refreshPromises = /* @__PURE__ */ new WeakMap();
501
+ }
502
+ });
503
+
504
+ // ../loader-utils/src/lib/path-utils/file-aliases.ts
505
+ function resolvePath(filename) {
506
+ for (const alias in fileAliases) {
507
+ if (filename.startsWith(alias)) {
508
+ const replacement = fileAliases[alias];
509
+ filename = filename.replace(alias, replacement);
195
510
  }
196
- addScalarColumn(columns, fields, schemaFields, `f_rest_${component}`, componentValues, {
197
- "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_rest",
198
- "loaders_gl.gaussian_splats.component": String(component),
199
- "loaders_gl.gaussian_splats.encoding": "coefficient"
200
- });
201
511
  }
512
+ if (!filename.startsWith("http://") && !filename.startsWith("https://")) {
513
+ filename = `${pathPrefix}${filename}`;
514
+ }
515
+ return filename;
202
516
  }
203
- function addScalarColumn(columns, fields, schemaFields, name, values, metadata) {
204
- addColumn(columns, fields, schemaFields, name, arrow.makeVector(values), "float32", metadata);
517
+ var pathPrefix, fileAliases;
518
+ var init_file_aliases = __esm({
519
+ "../loader-utils/src/lib/path-utils/file-aliases.ts"() {
520
+ "use strict";
521
+ pathPrefix = "";
522
+ fileAliases = {};
523
+ }
524
+ });
525
+
526
+ // ../loader-utils/src/lib/binary-utils/memory-conversion-utils.ts
527
+ function ensureArrayBuffer(bufferSource) {
528
+ if (bufferSource instanceof ArrayBuffer) {
529
+ return bufferSource;
530
+ }
531
+ if (isSharedArrayBuffer(bufferSource)) {
532
+ return copyToArrayBuffer2(bufferSource);
533
+ }
534
+ const { buffer, byteOffset, byteLength } = bufferSource;
535
+ if (buffer instanceof ArrayBuffer && byteOffset === 0 && byteLength === buffer.byteLength) {
536
+ return buffer;
537
+ }
538
+ return copyToArrayBuffer2(buffer, byteOffset, byteLength);
205
539
  }
206
- function addColumn(columns, fields, schemaFields, name, column, schemaType, metadata = {}) {
207
- columns[name] = column;
208
- fields.push(new arrow.Field(name, column.type, false, new Map(Object.entries(metadata))));
209
- schemaFields.push({ name, type: schemaType, nullable: false, metadata });
540
+ function copyToArrayBuffer2(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
541
+ const view = new Uint8Array(buffer, byteOffset, byteLength);
542
+ const copy = new Uint8Array(view.length);
543
+ copy.set(view);
544
+ return copy.buffer;
210
545
  }
211
- function makeFixedSizeListVector(value, size) {
212
- const values = arrow.makeVector(value);
213
- const child = values.data[0];
214
- const type = new arrow.FixedSizeList(size, new arrow.Field("value", child.type, false));
215
- const data = new arrow.Data(type, 0, value.length / size, 0, {}, [child]);
216
- return new arrow.Vector([data]);
546
+ var init_memory_conversion_utils = __esm({
547
+ "../loader-utils/src/lib/binary-utils/memory-conversion-utils.ts"() {
548
+ "use strict";
549
+ init_is_type();
550
+ }
551
+ });
552
+
553
+ // ../loader-utils/src/lib/sources/data-source.ts
554
+ function getFetchFunction(options) {
555
+ return getAuthenticatedFetch(options);
217
556
  }
218
- function getColorCoefficients(splats) {
219
- const rowCount = splats.splatCount;
220
- const fdc0 = new Float32Array(rowCount);
221
- const fdc1 = new Float32Array(rowCount);
222
- const fdc2 = new Float32Array(rowCount);
223
- for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
224
- if (splats.sphericalHarmonicDcs) {
225
- fdc0[rowIndex] = splats.sphericalHarmonicDcs[rowIndex * 3 + 0];
226
- fdc1[rowIndex] = splats.sphericalHarmonicDcs[rowIndex * 3 + 1];
227
- fdc2[rowIndex] = splats.sphericalHarmonicDcs[rowIndex * 3 + 2];
228
- } else {
229
- fdc0[rowIndex] = convertColorByteToSphericalHarmonicDc(splats.colors[rowIndex * 3 + 0]);
230
- fdc1[rowIndex] = convertColorByteToSphericalHarmonicDc(splats.colors[rowIndex * 3 + 1]);
231
- fdc2[rowIndex] = convertColorByteToSphericalHarmonicDc(splats.colors[rowIndex * 3 + 2]);
557
+ function getSourceLoaderOptions(options) {
558
+ var _a;
559
+ if (options.loadOptions !== void 0 || ((_a = options.core) == null ? void 0 : _a.loadOptions) !== void 0) {
560
+ throw new Error(
561
+ "Source loadOptions and core.loadOptions were removed. Use core and root loader namespaces directly."
562
+ );
563
+ }
564
+ const loadOptions = { ...options };
565
+ if (options == null ? void 0 : options.core) {
566
+ loadOptions.core = { ...options.core };
567
+ const parserCore = loadOptions.core;
568
+ for (const key of ["type", "attributions", "loaders", "onError", "loadOptions"]) {
569
+ delete parserCore[key];
570
+ }
571
+ if (Object.keys(parserCore).length === 0) {
572
+ delete loadOptions.core;
232
573
  }
233
574
  }
234
- return [fdc0, fdc1, fdc2];
575
+ const topLevelBaseUri = typeof loadOptions.baseUri === "string" ? loadOptions.baseUri : void 0;
576
+ const topLevelBaseUrl = typeof loadOptions.baseUrl === "string" ? loadOptions.baseUrl : void 0;
577
+ if (topLevelBaseUri !== void 0 || topLevelBaseUrl !== void 0) {
578
+ loadOptions.core ||= {};
579
+ if (loadOptions.core.baseUrl === void 0) {
580
+ loadOptions.core.baseUrl = topLevelBaseUrl ?? topLevelBaseUri;
581
+ }
582
+ delete loadOptions.baseUri;
583
+ delete loadOptions.baseUrl;
584
+ }
585
+ return loadOptions;
235
586
  }
236
-
237
- // dist/lib/parse-splat.js
238
- var SPLAT_ROW_BYTE_LENGTH = 32;
239
- function parseSPLAT(data) {
240
- return makeGaussianSplatsArrowTable(parseSPLATToGaussianSplats(data));
587
+ function normalizeError(error, message) {
588
+ if (error instanceof Error) {
589
+ return error;
590
+ }
591
+ if (typeof error === "string") {
592
+ return new Error(error);
593
+ }
594
+ return new Error(message);
241
595
  }
242
- function parseSPLATToGaussianSplats(data) {
243
- if (data.byteLength % SPLAT_ROW_BYTE_LENGTH !== 0) {
244
- throw new Error(`SPLATLoader: byte length must be a multiple of ${SPLAT_ROW_BYTE_LENGTH}.`);
596
+ function unavailableCoreApiMethod(methodName) {
597
+ return () => {
598
+ throw new Error(
599
+ `CoreAPI.${methodName} is unavailable. Use @loaders.gl/core.createDataSource().`
600
+ );
601
+ };
602
+ }
603
+ var UNAVAILABLE_CORE_API, DataSource;
604
+ var init_data_source = __esm({
605
+ "../loader-utils/src/lib/sources/data-source.ts"() {
606
+ "use strict";
607
+ init_merge_options();
608
+ init_file_aliases();
609
+ init_log();
610
+ init_request_credentials();
611
+ init_authentication();
612
+ UNAVAILABLE_CORE_API = {
613
+ fetchFile: unavailableCoreApiMethod("fetchFile"),
614
+ parse: unavailableCoreApiMethod("parse"),
615
+ parseFile: unavailableCoreApiMethod("parseFile"),
616
+ parseSync: unavailableCoreApiMethod("parseSync"),
617
+ parseInBatches: unavailableCoreApiMethod("parseInBatches"),
618
+ load: unavailableCoreApiMethod("load"),
619
+ loadInBatches: unavailableCoreApiMethod("loadInBatches")
620
+ };
621
+ DataSource = class _DataSource {
622
+ static defaultOptions = {
623
+ core: {
624
+ type: "auto",
625
+ attributions: [],
626
+ loaders: [],
627
+ onError: void 0
628
+ }
629
+ };
630
+ optionsType;
631
+ options;
632
+ data;
633
+ url;
634
+ /** Shared parser options derived from the source options, excluding source-only core controls. */
635
+ loadOptions;
636
+ /** A resolved fetch function extracted from the shared core options. */
637
+ fetch;
638
+ /** Shared source-level runtime hooks, when supplied by the source factory. */
639
+ coreApi;
640
+ /** Whether a real CoreAPI instance was injected by the integration layer. */
641
+ hasCoreApi;
642
+ _needsRefresh = true;
643
+ constructor(data, options, defaultOptions, coreApi) {
644
+ this.options = mergeOptions(
645
+ mergeOptions(_DataSource.defaultOptions, defaultOptions || {}),
646
+ options
647
+ );
648
+ this.data = data;
649
+ this.url = typeof data === "string" ? resolvePath(data) : "";
650
+ const loadOptions = resolveAuthenticationOptions(getSourceLoaderOptions(this.options));
651
+ this.loadOptions = loadOptions;
652
+ const fetch2 = getFetchFunction(loadOptions);
653
+ this.coreApi = coreApi || UNAVAILABLE_CORE_API;
654
+ this.hasCoreApi = Boolean(coreApi);
655
+ this.fetch = fetch2;
656
+ }
657
+ setProps(options) {
658
+ const mergedOptions = mergeOptions(this.options, options);
659
+ const loadOptions = resolveAuthenticationOptions(getSourceLoaderOptions(mergedOptions));
660
+ this.options = mergedOptions;
661
+ this.loadOptions = loadOptions;
662
+ this.fetch = getFetchFunction(loadOptions);
663
+ this.setNeedsRefresh();
664
+ }
665
+ /** Mark this data source as needing a refresh (redraw) */
666
+ setNeedsRefresh() {
667
+ this._needsRefresh = true;
668
+ }
669
+ /**
670
+ * Does this data source need refreshing?
671
+ * @note The specifics of the refresh mechanism depends on type of data source
672
+ */
673
+ getNeedsRefresh(clear = true) {
674
+ const needsRefresh = this._needsRefresh;
675
+ if (clear) {
676
+ this._needsRefresh = false;
677
+ }
678
+ return needsRefresh;
679
+ }
680
+ /** Reports a source-level failure through the configured callback or the shared logger. */
681
+ reportError(error, message) {
682
+ var _a;
683
+ const normalizedError = normalizeError(error, message);
684
+ const callback = (_a = this.options.core) == null ? void 0 : _a.onError;
685
+ if (callback) {
686
+ callback(normalizedError, this);
687
+ } else {
688
+ log.warn(`${this.constructor.name}: ${normalizedError.message}`)();
689
+ }
690
+ return normalizedError;
691
+ }
692
+ };
245
693
  }
246
- const splatCount = data.byteLength / SPLAT_ROW_BYTE_LENGTH;
247
- const dataView = new DataView(data);
248
- const positions = new Float32Array(splatCount * 3);
249
- const scales = new Float32Array(splatCount * 3);
250
- const rotations = new Float32Array(splatCount * 4);
251
- const colors = new Uint8Array(splatCount * 3);
252
- const opacities = new Float32Array(splatCount);
253
- for (let splatIndex = 0; splatIndex < splatCount; splatIndex++) {
254
- const byteOffset = splatIndex * SPLAT_ROW_BYTE_LENGTH;
255
- const positionOffset = splatIndex * 3;
256
- const rotationOffset = splatIndex * 4;
257
- positions[positionOffset + 0] = dataView.getFloat32(byteOffset + 0, true);
258
- positions[positionOffset + 1] = dataView.getFloat32(byteOffset + 4, true);
259
- positions[positionOffset + 2] = dataView.getFloat32(byteOffset + 8, true);
260
- scales[positionOffset + 0] = dataView.getFloat32(byteOffset + 12, true);
261
- scales[positionOffset + 1] = dataView.getFloat32(byteOffset + 16, true);
262
- scales[positionOffset + 2] = dataView.getFloat32(byteOffset + 20, true);
263
- colors[positionOffset + 0] = dataView.getUint8(byteOffset + 24);
264
- colors[positionOffset + 1] = dataView.getUint8(byteOffset + 25);
265
- colors[positionOffset + 2] = dataView.getUint8(byteOffset + 26);
266
- opacities[splatIndex] = convertAlphaByteToLinearOpacity(dataView.getUint8(byteOffset + 27));
267
- const [w, x, y, z2] = normalizeQuaternion(decodeQuaternionByte(dataView.getUint8(byteOffset + 28)), decodeQuaternionByte(dataView.getUint8(byteOffset + 29)), decodeQuaternionByte(dataView.getUint8(byteOffset + 30)), decodeQuaternionByte(dataView.getUint8(byteOffset + 31)));
268
- rotations[rotationOffset + 0] = w;
269
- rotations[rotationOffset + 1] = x;
270
- rotations[rotationOffset + 2] = y;
271
- rotations[rotationOffset + 3] = z2;
694
+ });
695
+
696
+ // ../loader-utils/src/index.ts
697
+ var init_src = __esm({
698
+ "../loader-utils/src/index.ts"() {
699
+ "use strict";
700
+ init_js_module_utils();
701
+ init_js_module_utils();
702
+ init_async_iteration();
703
+ init_memory_conversion_utils();
704
+ init_data_source();
272
705
  }
273
- return {
274
- format: "splat",
275
- splatCount,
276
- positions,
277
- scales,
278
- rotations,
279
- colors,
280
- opacities,
281
- loaderData: {
282
- format: "splat",
283
- splatCount,
284
- rowByteLength: SPLAT_ROW_BYTE_LENGTH
285
- }
286
- };
287
- }
706
+ });
288
707
 
289
- // dist/splat-loader-types.js
290
- var VERSION = true ? "4.5.3" : "latest";
291
- var SPLATLoader = {
292
- dataType: null,
293
- batchType: null,
294
- ...SPLATFormat,
295
- version: VERSION,
296
- options: {
297
- splats: {
298
- shape: "arrow-table"
299
- }
708
+ // ../compression/src/lib/compression.ts
709
+ var CompressionTransform, Compressor, Decompressor, Compression;
710
+ var init_compression = __esm({
711
+ "../compression/src/lib/compression.ts"() {
712
+ "use strict";
713
+ init_src();
714
+ CompressionTransform = class {
715
+ /** Preloads any dynamic libraries. May enable sync functions */
716
+ async preload(modules = {}) {
717
+ registerJSModules(modules);
718
+ return void 0;
719
+ }
720
+ // HELPERS
721
+ concatenate(asyncIterator) {
722
+ return concatenateArrayBuffersAsync(asyncIterator);
723
+ }
724
+ improveError(error) {
725
+ if (!error.message.includes(this.name)) {
726
+ error.message = `${this.name} ${error.message}`;
727
+ }
728
+ return error;
729
+ }
730
+ };
731
+ Compressor = class extends CompressionTransform {
732
+ constructor(options) {
733
+ super();
734
+ this.compressBatches = this.compressBatches.bind(this);
735
+ }
736
+ /** Asynchronously compresses data. */
737
+ async compress(input) {
738
+ await this.preload();
739
+ return this.compressSync(input);
740
+ }
741
+ /** Synchronously compresses data. */
742
+ compressSync(input) {
743
+ throw new Error(`${this.name}: sync compression not supported`);
744
+ }
745
+ /** Compresses batches. */
746
+ async *compressBatches(asyncIterator) {
747
+ const input = await this.concatenate(asyncIterator);
748
+ yield this.compress(input);
749
+ }
750
+ };
751
+ Decompressor = class extends CompressionTransform {
752
+ constructor(options) {
753
+ super();
754
+ this.decompressBatches = this.decompressBatches.bind(this);
755
+ }
756
+ /** Asynchronously decompresses data. */
757
+ async decompress(input, size) {
758
+ await this.preload();
759
+ return this.decompressSync(input, size);
760
+ }
761
+ /** Synchronously decompresses data. */
762
+ decompressSync(input, size) {
763
+ throw new Error(`${this.name}: sync decompression not supported`);
764
+ }
765
+ /** Decompresses batches. */
766
+ async *decompressBatches(asyncIterator) {
767
+ const input = await this.concatenate(asyncIterator);
768
+ yield this.decompress(input);
769
+ }
770
+ };
771
+ Compression = class extends Compressor {
772
+ constructor(options) {
773
+ super(options);
774
+ this.decompressBatches = this.decompressBatches.bind(this);
775
+ }
776
+ /** Asynchronously decompresses data. */
777
+ async decompress(input, size) {
778
+ await this.preload();
779
+ return this.decompressSync(input, size);
780
+ }
781
+ /** Synchronously decompresses data. */
782
+ decompressSync(input, size) {
783
+ throw new Error(`${this.name}: sync decompression not supported`);
784
+ }
785
+ /** Decompresses batches. */
786
+ async *decompressBatches(asyncIterator) {
787
+ const input = await this.concatenate(asyncIterator);
788
+ yield this.decompress(input);
789
+ }
790
+ };
300
791
  }
301
- };
792
+ });
302
793
 
303
- // dist/splat-loader.js
304
- var SPLATLoaderWithParser = {
305
- ...SPLATLoader,
306
- parse: async (arrayBuffer) => parseSPLAT(arrayBuffer),
307
- parseSync: (arrayBuffer) => parseSPLAT(arrayBuffer)
308
- };
794
+ // ../compression/src/lib/fflate/index.ts
795
+ function inflateSync(data, out) {
796
+ return inflt(data, out);
797
+ }
798
+ function gunzipSync(data, out) {
799
+ return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));
800
+ }
801
+ function unzlibSync(data, out) {
802
+ return inflt((zlv(data), data.subarray(2, -4)), out);
803
+ }
804
+ 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;
805
+ var init_fflate = __esm({
806
+ "../compression/src/lib/fflate/index.ts"() {
807
+ "use strict";
808
+ u8 = Uint8Array;
809
+ u16 = Uint16Array;
810
+ u32 = Uint32Array;
811
+ fleb = new u8([
812
+ 0,
813
+ 0,
814
+ 0,
815
+ 0,
816
+ 0,
817
+ 0,
818
+ 0,
819
+ 0,
820
+ 1,
821
+ 1,
822
+ 1,
823
+ 1,
824
+ 2,
825
+ 2,
826
+ 2,
827
+ 2,
828
+ 3,
829
+ 3,
830
+ 3,
831
+ 3,
832
+ 4,
833
+ 4,
834
+ 4,
835
+ 4,
836
+ 5,
837
+ 5,
838
+ 5,
839
+ 5,
840
+ 0,
841
+ /* unused */
842
+ 0,
843
+ 0,
844
+ /* impossible */
845
+ 0
846
+ ]);
847
+ fdeb = new u8([
848
+ 0,
849
+ 0,
850
+ 0,
851
+ 0,
852
+ 1,
853
+ 1,
854
+ 2,
855
+ 2,
856
+ 3,
857
+ 3,
858
+ 4,
859
+ 4,
860
+ 5,
861
+ 5,
862
+ 6,
863
+ 6,
864
+ 7,
865
+ 7,
866
+ 8,
867
+ 8,
868
+ 9,
869
+ 9,
870
+ 10,
871
+ 10,
872
+ 11,
873
+ 11,
874
+ 12,
875
+ 12,
876
+ 13,
877
+ 13,
878
+ /* unused */
879
+ 0,
880
+ 0
881
+ ]);
882
+ clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
883
+ freb = (eb, start) => {
884
+ const b = new u16(31);
885
+ for (let i = 0; i < 31; ++i) {
886
+ b[i] = start += 1 << eb[i - 1];
887
+ }
888
+ const r = new u32(b[30]);
889
+ for (let i = 1; i < 30; ++i) {
890
+ for (let j = b[i]; j < b[i + 1]; ++j) {
891
+ r[j] = j - b[i] << 5 | i;
892
+ }
893
+ }
894
+ return [b, r];
895
+ };
896
+ [fl, revfl] = freb(fleb, 2);
897
+ fl[28] = 258, revfl[258] = 28;
898
+ [fd, revfd] = freb(fdeb, 0);
899
+ rev = new u16(32768);
900
+ for (let i = 0; i < 32768; ++i) {
901
+ let x = (i & 43690) >>> 1 | (i & 21845) << 1;
902
+ x = (x & 52428) >>> 2 | (x & 13107) << 2;
903
+ x = (x & 61680) >>> 4 | (x & 3855) << 4;
904
+ rev[i] = ((x & 65280) >>> 8 | (x & 255) << 8) >>> 1;
905
+ }
906
+ hMap = (cd, mb, r) => {
907
+ const s = cd.length;
908
+ let i = 0;
909
+ const l = new u16(mb);
910
+ for (; i < s; ++i) {
911
+ if (cd[i]) ++l[cd[i] - 1];
912
+ }
913
+ const le = new u16(mb);
914
+ for (i = 0; i < mb; ++i) {
915
+ le[i] = le[i - 1] + l[i - 1] << 1;
916
+ }
917
+ let co;
918
+ if (r) {
919
+ co = new u16(1 << mb);
920
+ const rvb = 15 - mb;
921
+ for (i = 0; i < s; ++i) {
922
+ if (cd[i]) {
923
+ const sv = i << 4 | cd[i];
924
+ const r2 = mb - cd[i];
925
+ let v = le[cd[i] - 1]++ << r2;
926
+ for (const m = v | (1 << r2) - 1; v <= m; ++v) {
927
+ co[rev[v] >>> rvb] = sv;
928
+ }
929
+ }
930
+ }
931
+ } else {
932
+ co = new u16(s);
933
+ for (i = 0; i < s; ++i) {
934
+ if (cd[i]) {
935
+ co[i] = rev[le[cd[i] - 1]++] >>> 15 - cd[i];
936
+ }
937
+ }
938
+ }
939
+ return co;
940
+ };
941
+ flt = new u8(288);
942
+ for (let i = 0; i < 144; ++i) flt[i] = 8;
943
+ for (let i = 144; i < 256; ++i) flt[i] = 9;
944
+ for (let i = 256; i < 280; ++i) flt[i] = 7;
945
+ for (let i = 280; i < 288; ++i) flt[i] = 8;
946
+ fdt = new u8(32);
947
+ for (let i = 0; i < 32; ++i) fdt[i] = 5;
948
+ flrm = /* @__PURE__ */ hMap(flt, 9, 1);
949
+ fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
950
+ max = (a) => {
951
+ let m = a[0];
952
+ for (let i = 1; i < a.length; ++i) {
953
+ if (a[i] > m) m = a[i];
954
+ }
955
+ return m;
956
+ };
957
+ bits = (d, p, m) => {
958
+ const o = p / 8 | 0;
959
+ return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
960
+ };
961
+ bits16 = (d, p) => {
962
+ const o = p / 8 | 0;
963
+ return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
964
+ };
965
+ shft = (p) => (p + 7) / 8 | 0;
966
+ slc = (v, s, e) => {
967
+ if (s == null || s < 0) s = 0;
968
+ if (e == null || e > v.length) e = v.length;
969
+ const n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s);
970
+ n.set(v.subarray(s, e));
971
+ return n;
972
+ };
973
+ ec = [
974
+ "unexpected EOF",
975
+ "invalid block type",
976
+ "invalid length/literal",
977
+ "invalid distance",
978
+ "stream finished",
979
+ "no stream handler",
980
+ ,
981
+ // determined by compression function
982
+ "no callback",
983
+ "invalid UTF-8 data",
984
+ "extra field too long",
985
+ "date not in range 1980-2099",
986
+ "filename too long",
987
+ "stream finishing",
988
+ "invalid zip data"
989
+ // determined by unknown compression method
990
+ ];
991
+ err = (ind, msg, nt) => {
992
+ const e = new Error(msg || ec[ind]);
993
+ e.code = ind;
994
+ if (Error.captureStackTrace) Error.captureStackTrace(e, err);
995
+ if (!nt) throw e;
996
+ return e;
997
+ };
998
+ inflt = (dat, buf, st) => {
999
+ const sl = dat.length;
1000
+ if (!sl || st && st.f && !st.l) return buf || new u8(0);
1001
+ const noBuf = !buf || st;
1002
+ const noSt = !st || st.i;
1003
+ if (!st) st = {};
1004
+ if (!buf) buf = new u8(sl * 3);
1005
+ const cbuf = (l) => {
1006
+ let bl = buf.length;
1007
+ if (l > bl) {
1008
+ const nbuf = new u8(Math.max(bl * 2, l));
1009
+ nbuf.set(buf);
1010
+ buf = nbuf;
1011
+ }
1012
+ };
1013
+ 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;
1014
+ const tbts = sl * 8;
1015
+ do {
1016
+ if (!lm) {
1017
+ final = bits(dat, pos, 1);
1018
+ const type = bits(dat, pos + 1, 3);
1019
+ pos += 3;
1020
+ if (!type) {
1021
+ const s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
1022
+ if (t > sl) {
1023
+ if (noSt) err(0);
1024
+ break;
1025
+ }
1026
+ if (noBuf) cbuf(bt + l);
1027
+ buf.set(dat.subarray(s, t), bt);
1028
+ st.b = bt += l, st.p = pos = t * 8, st.f = final;
1029
+ continue;
1030
+ } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
1031
+ else if (type == 2) {
1032
+ const hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
1033
+ const tl = hLit + bits(dat, pos + 5, 31) + 1;
1034
+ pos += 14;
1035
+ const ldt = new u8(tl);
1036
+ const clt = new u8(19);
1037
+ for (let i = 0; i < hcLen; ++i) {
1038
+ clt[clim[i]] = bits(dat, pos + i * 3, 7);
1039
+ }
1040
+ pos += hcLen * 3;
1041
+ const clb = max(clt), clbmsk = (1 << clb) - 1;
1042
+ const clm = hMap(clt, clb, 1);
1043
+ for (let i = 0; i < tl; ) {
1044
+ const r = clm[bits(dat, pos, clbmsk)];
1045
+ pos += r & 15;
1046
+ const s = r >>> 4;
1047
+ if (s < 16) {
1048
+ ldt[i++] = s;
1049
+ } else {
1050
+ let c = 0, n = 0;
1051
+ if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
1052
+ else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;
1053
+ else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
1054
+ while (n--) ldt[i++] = c;
1055
+ }
1056
+ }
1057
+ const lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
1058
+ lbt = max(lt);
1059
+ dbt = max(dt);
1060
+ lm = hMap(lt, lbt, 1);
1061
+ dm = hMap(dt, dbt, 1);
1062
+ } else err(1);
1063
+ if (pos > tbts) {
1064
+ if (noSt) err(0);
1065
+ break;
1066
+ }
1067
+ }
1068
+ if (noBuf) cbuf(bt + 131072);
1069
+ const lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
1070
+ let lpos = pos;
1071
+ for (; ; lpos = pos) {
1072
+ const c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
1073
+ pos += c & 15;
1074
+ if (pos > tbts) {
1075
+ if (noSt) err(0);
1076
+ break;
1077
+ }
1078
+ if (!c) err(2);
1079
+ if (sym < 256) buf[bt++] = sym;
1080
+ else if (sym == 256) {
1081
+ lpos = pos, lm = void 0;
1082
+ break;
1083
+ } else {
1084
+ let add = sym - 254;
1085
+ if (sym > 264) {
1086
+ const i = sym - 257, b = fleb[i];
1087
+ add = bits(dat, pos, (1 << b) - 1) + fl[i];
1088
+ pos += b;
1089
+ }
1090
+ const d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
1091
+ if (!d) err(3);
1092
+ pos += d & 15;
1093
+ let dt = fd[dsym];
1094
+ if (dsym > 3) {
1095
+ const b = fdeb[dsym];
1096
+ dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
1097
+ }
1098
+ if (pos > tbts) {
1099
+ if (noSt) err(0);
1100
+ break;
1101
+ }
1102
+ if (noBuf) cbuf(bt + 131072);
1103
+ const end = bt + add;
1104
+ for (; bt < end; bt += 4) {
1105
+ buf[bt] = buf[bt - dt];
1106
+ buf[bt + 1] = buf[bt + 1 - dt];
1107
+ buf[bt + 2] = buf[bt + 2 - dt];
1108
+ buf[bt + 3] = buf[bt + 3 - dt];
1109
+ }
1110
+ bt = end;
1111
+ }
1112
+ }
1113
+ st.l = lm, st.p = lpos, st.b = bt, st.f = final;
1114
+ if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
1115
+ } while (!final);
1116
+ return bt == buf.length ? buf : slc(buf, 0, bt);
1117
+ };
1118
+ gzs = (d) => {
1119
+ if (d[0] != 31 || d[1] != 139 || d[2] != 8) err(6, "invalid gzip data");
1120
+ const flg = d[3];
1121
+ let st = 10;
1122
+ if (flg & 4) st += d[10] | (d[11] << 8) + 2;
1123
+ for (let zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++]) ;
1124
+ return st + (flg & 2);
1125
+ };
1126
+ gzl = (d) => {
1127
+ const l = d.length;
1128
+ return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
1129
+ };
1130
+ zlv = (d) => {
1131
+ if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || (d[0] << 8 | d[1]) % 31) err(6, "invalid zlib data");
1132
+ if (d[1] & 32) err(6, "invalid zlib data: preset dictionaries not supported");
1133
+ };
1134
+ Inflate = class {
1135
+ /**
1136
+ * Creates an inflation stream
1137
+ * @param cb The callback to call whenever data is inflated
1138
+ */
1139
+ constructor(cb) {
1140
+ this.ondata = cb;
1141
+ }
1142
+ /** Persistent bit-reader and Huffman decoding state. */
1143
+ s = {};
1144
+ /** Compression options or retained output window for this stream. */
1145
+ o;
1146
+ /** Compressed bytes pending decoding. */
1147
+ p = new u8(0);
1148
+ /** Whether the stream has received its final chunk. */
1149
+ d;
1150
+ /**
1151
+ * The handler to call whenever data is available
1152
+ */
1153
+ ondata;
1154
+ /** Appends pending input after checking stream lifecycle. */
1155
+ e(c) {
1156
+ if (!this.ondata) err(5);
1157
+ if (this.d) err(4);
1158
+ const l = this.p.length;
1159
+ const n = new u8(l + c.length);
1160
+ n.set(this.p), n.set(c, l), this.p = n;
1161
+ }
1162
+ /** Decodes pending input and retains the sliding window. */
1163
+ c(final) {
1164
+ this.d = this.s.i = final || false;
1165
+ const bts = this.s.b;
1166
+ const dt = inflt(this.p, this.o, this.s);
1167
+ this.ondata(slc(dt, bts, this.s.b), this.d);
1168
+ this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;
1169
+ this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;
1170
+ }
1171
+ /**
1172
+ * Pushes a chunk to be inflated
1173
+ * @param chunk The chunk to push
1174
+ * @param final Whether this is the final chunk
1175
+ */
1176
+ push(chunk, final) {
1177
+ this.e(chunk), this.c(final);
1178
+ }
1179
+ };
1180
+ Gunzip = class extends Inflate {
1181
+ /** Whether the stream header still needs to be emitted or consumed. */
1182
+ v = 1;
1183
+ /**
1184
+ * Creates a GUNZIP stream
1185
+ * @param cb The callback to call whenever data is inflated
1186
+ */
1187
+ constructor(cb) {
1188
+ super(cb);
1189
+ }
1190
+ /**
1191
+ * Pushes a chunk to be GUNZIPped
1192
+ * @param chunk The chunk to push
1193
+ * @param final Whether this is the last chunk
1194
+ */
1195
+ push(chunk, final) {
1196
+ Inflate.prototype.e.call(this, chunk);
1197
+ if (this.v) {
1198
+ const s = this.p.length > 3 ? gzs(this.p) : 4;
1199
+ if (s >= this.p.length && !final) return;
1200
+ this.p = this.p.subarray(s), this.v = 0;
1201
+ }
1202
+ if (final) {
1203
+ if (this.p.length < 8) err(6, "invalid gzip data");
1204
+ this.p = this.p.subarray(0, -8);
1205
+ }
1206
+ Inflate.prototype.c.call(this, final);
1207
+ }
1208
+ };
1209
+ Unzlib = class extends Inflate {
1210
+ /** Whether the stream header still needs to be emitted or consumed. */
1211
+ v = 1;
1212
+ /**
1213
+ * Creates a Zlib decompression stream
1214
+ * @param cb The callback to call whenever data is inflated
1215
+ */
1216
+ constructor(cb) {
1217
+ super(cb);
1218
+ }
1219
+ /**
1220
+ * Pushes a chunk to be unzlibbed
1221
+ * @param chunk The chunk to push
1222
+ * @param final Whether this is the last chunk
1223
+ */
1224
+ push(chunk, final) {
1225
+ Inflate.prototype.e.call(this, chunk);
1226
+ if (this.v) {
1227
+ if (this.p.length < 2 && !final) return;
1228
+ this.p = this.p.subarray(2), this.v = 0;
1229
+ }
1230
+ if (final) {
1231
+ if (this.p.length < 4) err(6, "invalid zlib data");
1232
+ this.p = this.p.subarray(0, -4);
1233
+ }
1234
+ Inflate.prototype.c.call(this, final);
1235
+ }
1236
+ };
1237
+ }
1238
+ });
309
1239
 
310
- // dist/lib/parse-ksplat.js
311
- var CURRENT_MAJOR_VERSION = 0;
312
- var CURRENT_MINOR_VERSION = 1;
313
- var HEADER_BYTE_LENGTH = 4096;
314
- var SECTION_HEADER_BYTE_LENGTH = 1024;
315
- var DEFAULT_SH_8BIT_COMPRESSION_RANGE = 3;
316
- var DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE = DEFAULT_SH_8BIT_COMPRESSION_RANGE / 2;
317
- var COMPRESSION_LAYOUTS = {
318
- 0: {
319
- bytesPerCenter: 12,
320
- bytesPerScale: 12,
321
- bytesPerRotation: 16,
322
- bytesPerColor: 4,
323
- scaleOffsetBytes: 12,
324
- colorOffsetBytes: 40,
325
- sphericalHarmonicsOffsetBytes: 44,
326
- scaleRange: 1,
327
- bytesPerSphericalHarmonicsComponent: 4
328
- },
329
- 1: {
330
- bytesPerCenter: 6,
331
- bytesPerScale: 6,
332
- bytesPerRotation: 8,
333
- bytesPerColor: 4,
334
- scaleOffsetBytes: 6,
335
- colorOffsetBytes: 20,
336
- sphericalHarmonicsOffsetBytes: 24,
337
- scaleRange: 32767,
338
- bytesPerSphericalHarmonicsComponent: 2
339
- },
340
- 2: {
341
- bytesPerCenter: 6,
342
- bytesPerScale: 6,
343
- bytesPerRotation: 8,
344
- bytesPerColor: 4,
345
- scaleOffsetBytes: 6,
346
- colorOffsetBytes: 20,
347
- sphericalHarmonicsOffsetBytes: 24,
348
- scaleRange: 32767,
349
- bytesPerSphericalHarmonicsComponent: 1
1240
+ // ../compression/src/lib/compression-stream.ts
1241
+ async function compressWithNativeCompressionStream(input, format) {
1242
+ const outputBatches = compressBatchesWithNativeCompressionStream([input], format);
1243
+ return outputBatches ? await concatenateBatches(outputBatches) : null;
1244
+ }
1245
+ function compressBatchesWithNativeCompressionStream(inputBatches, format) {
1246
+ const compressionStream = createNativeCompressionStream(format);
1247
+ return compressionStream ? transformBatches(inputBatches, compressionStream) : null;
1248
+ }
1249
+ function createNativeCompressionStream(format) {
1250
+ if (typeof globalThis.CompressionStream === "undefined") {
1251
+ return null;
1252
+ }
1253
+ try {
1254
+ const CompressionStreamConstructor = globalThis.CompressionStream;
1255
+ return new CompressionStreamConstructor(format);
1256
+ } catch (error) {
1257
+ if (error instanceof TypeError || (error == null ? void 0 : error.name) === "TypeError") {
1258
+ return null;
1259
+ }
1260
+ throw error;
350
1261
  }
351
- };
352
- function parseKSPLAT(data) {
353
- return makeGaussianSplatsArrowTable(parseKSPLATToGaussianSplats(data));
354
1262
  }
355
- function parseKSPLATToGaussianSplats(data) {
356
- if (data.byteLength < HEADER_BYTE_LENGTH) {
357
- throw new Error(`KSPLATLoader: file must contain a ${HEADER_BYTE_LENGTH}-byte header.`);
1263
+ async function* transformBatches(inputBatches, compressionStream) {
1264
+ const writer = compressionStream.writable.getWriter();
1265
+ const reader = compressionStream.readable.getReader();
1266
+ const writePromise = writeBatches(inputBatches, writer);
1267
+ writePromise.catch(() => {
1268
+ });
1269
+ let outputCompleted = false;
1270
+ try {
1271
+ while (true) {
1272
+ const { done, value } = await reader.read();
1273
+ if (done) {
1274
+ outputCompleted = true;
1275
+ break;
1276
+ }
1277
+ yield new Uint8Array(value).buffer;
1278
+ }
1279
+ await writePromise;
1280
+ } finally {
1281
+ if (!outputCompleted) {
1282
+ await reader.cancel().catch(() => {
1283
+ });
1284
+ await writer.abort().catch(() => {
1285
+ });
1286
+ await writePromise.catch(() => {
1287
+ });
1288
+ }
1289
+ reader.releaseLock();
358
1290
  }
359
- const header = parseKSPLATHeader(data);
360
- checkKSPLATVersion(header);
361
- const sections = parseKSPLATSections(data, header);
362
- const splatCount = getTotalSplatCount(header, sections);
363
- const sphericalHarmonicsComponentCount = Math.max(0, ...sections.slice(0, getActiveSectionCount(header)).map((section) => getSphericalHarmonicsComponentCount(section.sphericalHarmonicsDegree)));
364
- const positions = new Float32Array(splatCount * 3);
365
- const scales = new Float32Array(splatCount * 3);
366
- const rotations = new Float32Array(splatCount * 4);
367
- const colors = new Uint8Array(splatCount * 3);
368
- const opacities = new Float32Array(splatCount);
369
- const sphericalHarmonics = sphericalHarmonicsComponentCount ? new Float32Array(splatCount * sphericalHarmonicsComponentCount) : void 0;
370
- let outputSplatIndex = 0;
371
- for (const section of sections.slice(0, getActiveSectionCount(header))) {
372
- validateSectionBounds(data, section);
373
- for (let localSplatIndex = 0; localSplatIndex < section.splatCount && outputSplatIndex < splatCount; localSplatIndex++) {
374
- decodeKSPLATSplat(data, header, section, localSplatIndex, outputSplatIndex, positions, scales, rotations, colors, opacities, sphericalHarmonics, sphericalHarmonicsComponentCount);
375
- outputSplatIndex++;
1291
+ }
1292
+ async function writeBatches(inputBatches, writer) {
1293
+ try {
1294
+ for await (const inputBatch of inputBatches) {
1295
+ await writer.write(new Uint8Array(inputBatch));
376
1296
  }
1297
+ await writer.close();
1298
+ } catch (error) {
1299
+ await writer.abort(error).catch(() => {
1300
+ });
1301
+ throw error;
377
1302
  }
378
- return {
379
- format: "ksplat",
380
- splatCount,
381
- positions,
382
- scales,
383
- rotations,
384
- colors,
385
- opacities,
386
- sphericalHarmonics,
387
- sphericalHarmonicsComponentCount,
388
- loaderData: {
389
- format: "ksplat",
390
- ...header,
391
- sections: sections.slice(0, getActiveSectionCount(header)).map((section) => ({
392
- splatCount: section.splatCount,
393
- maxSplatCount: section.maxSplatCount,
394
- sphericalHarmonicsDegree: section.sphericalHarmonicsDegree
395
- }))
1303
+ }
1304
+ async function concatenateBatches(batches) {
1305
+ const output = [];
1306
+ let byteLength = 0;
1307
+ for await (const batch of batches) {
1308
+ const bytes = new Uint8Array(batch);
1309
+ output.push(bytes);
1310
+ byteLength += bytes.byteLength;
1311
+ }
1312
+ const result = new Uint8Array(byteLength);
1313
+ let offset = 0;
1314
+ for (const batch of output) {
1315
+ result.set(batch, offset);
1316
+ offset += batch.byteLength;
1317
+ }
1318
+ return result.buffer;
1319
+ }
1320
+ var init_compression_stream = __esm({
1321
+ "../compression/src/lib/compression-stream.ts"() {
1322
+ "use strict";
1323
+ }
1324
+ });
1325
+
1326
+ // ../compression/src/lib/decompression-stream.ts
1327
+ async function decompressWithNativeDecompressionStream(input, format) {
1328
+ const outputBatches = decompressBatchesWithNativeDecompressionStream([input], format);
1329
+ return outputBatches ? await concatenateNativeDecompressionBatches(outputBatches) : null;
1330
+ }
1331
+ function decompressBatchesWithNativeDecompressionStream(inputBatches, format) {
1332
+ const decompressionStream = createNativeDecompressionStream(format);
1333
+ return decompressionStream ? transformBatchesWithNativeDecompressionStream(inputBatches, decompressionStream) : null;
1334
+ }
1335
+ function isNativeDecompressionSupported(format) {
1336
+ return Boolean(createNativeDecompressionStream(format));
1337
+ }
1338
+ function createNativeDecompressionStream(format) {
1339
+ var _a, _b;
1340
+ if (typeof globalThis.DecompressionStream === "undefined") {
1341
+ return null;
1342
+ }
1343
+ if (((_b = (_a = globalThis.process) == null ? void 0 : _a.release) == null ? void 0 : _b.name) === "node" && typeof globalThis.Buffer === "undefined") {
1344
+ return null;
1345
+ }
1346
+ try {
1347
+ const DecompressionStreamConstructor = globalThis.DecompressionStream;
1348
+ return new DecompressionStreamConstructor(format);
1349
+ } catch (error) {
1350
+ if (error instanceof TypeError || (error == null ? void 0 : error.name) === "TypeError") {
1351
+ return null;
1352
+ }
1353
+ throw error;
1354
+ }
1355
+ }
1356
+ async function* transformBatchesWithNativeDecompressionStream(inputBatches, decompressionStream) {
1357
+ const writer = decompressionStream.writable.getWriter();
1358
+ const reader = decompressionStream.readable.getReader();
1359
+ const writePromise = writeBatchesToNativeDecompressionStream(inputBatches, writer);
1360
+ writePromise.catch(() => {
1361
+ });
1362
+ let outputCompleted = false;
1363
+ try {
1364
+ while (true) {
1365
+ const { done, value } = await reader.read();
1366
+ if (done) {
1367
+ outputCompleted = true;
1368
+ break;
1369
+ }
1370
+ yield copyExactArrayBuffer(value);
1371
+ }
1372
+ await writePromise;
1373
+ } finally {
1374
+ if (!outputCompleted) {
1375
+ await reader.cancel().catch(() => {
1376
+ });
1377
+ await writer.abort().catch(() => {
1378
+ });
1379
+ await writePromise.catch(() => {
1380
+ });
1381
+ }
1382
+ reader.releaseLock();
1383
+ }
1384
+ }
1385
+ async function concatenateNativeDecompressionBatches(outputBatches) {
1386
+ const batches = [];
1387
+ let byteLength = 0;
1388
+ for await (const outputBatch of outputBatches) {
1389
+ const bytes = new Uint8Array(outputBatch);
1390
+ batches.push(bytes);
1391
+ byteLength += bytes.byteLength;
1392
+ }
1393
+ const output = new Uint8Array(byteLength);
1394
+ let byteOffset = 0;
1395
+ for (const batch of batches) {
1396
+ output.set(batch, byteOffset);
1397
+ byteOffset += batch.byteLength;
1398
+ }
1399
+ return output.buffer;
1400
+ }
1401
+ function copyExactArrayBuffer(value) {
1402
+ return new Uint8Array(value).buffer;
1403
+ }
1404
+ async function writeBatchesToNativeDecompressionStream(inputBatches, writer) {
1405
+ try {
1406
+ for await (const inputBatch of inputBatches) {
1407
+ await writer.write(new Uint8Array(inputBatch));
396
1408
  }
1409
+ await writer.close();
1410
+ } catch (error) {
1411
+ await writer.abort(error).catch(() => {
1412
+ });
1413
+ throw error;
1414
+ }
1415
+ }
1416
+ var init_decompression_stream = __esm({
1417
+ "../compression/src/lib/decompression-stream.ts"() {
1418
+ "use strict";
1419
+ }
1420
+ });
1421
+
1422
+ // ../compression/src/lib/native-decompressor.ts
1423
+ var native_decompressor_exports = {};
1424
+ __export(native_decompressor_exports, {
1425
+ NativeDecompressor: () => NativeDecompressor
1426
+ });
1427
+ var NativeDecompressor;
1428
+ var init_native_decompressor = __esm({
1429
+ "../compression/src/lib/native-decompressor.ts"() {
1430
+ "use strict";
1431
+ init_compression();
1432
+ init_decompression_stream();
1433
+ NativeDecompressor = class extends Decompressor {
1434
+ name;
1435
+ extensions;
1436
+ contentEncodings;
1437
+ isSupported = true;
1438
+ /** Runtime stream format used for every operation. */
1439
+ format;
1440
+ constructor(metadata, format, options = {}) {
1441
+ super(options);
1442
+ this.name = metadata.name;
1443
+ this.extensions = [...metadata.extensions];
1444
+ this.contentEncodings = [...metadata.contentEncodings];
1445
+ this.format = format;
1446
+ }
1447
+ /** Decompresses one buffer with the runtime-provided stream. */
1448
+ async decompress(input) {
1449
+ const output = await decompressWithNativeDecompressionStream(input, this.format);
1450
+ if (!output) throw new Error(`${this.name}: built-in decompression is no longer available`);
1451
+ return output;
1452
+ }
1453
+ /** Decompresses batches incrementally with the runtime-provided stream. */
1454
+ async *decompressBatches(inputBatches) {
1455
+ const output = decompressBatchesWithNativeDecompressionStream(inputBatches, this.format);
1456
+ if (!output) throw new Error(`${this.name}: built-in decompression is no longer available`);
1457
+ yield* output;
1458
+ }
1459
+ };
1460
+ }
1461
+ });
1462
+
1463
+ // ../compression/src/lib/lazy-compression.ts
1464
+ function mergeModules(options, modules) {
1465
+ return { ...options, modules: { ...options.modules, ...modules } };
1466
+ }
1467
+ var LazyDecompressor;
1468
+ var init_lazy_compression = __esm({
1469
+ "../compression/src/lib/lazy-compression.ts"() {
1470
+ "use strict";
1471
+ init_compression();
1472
+ init_decompression_stream();
1473
+ LazyDecompressor = class extends Decompressor {
1474
+ name;
1475
+ extensions;
1476
+ contentEncodings;
1477
+ isSupported = true;
1478
+ /** Constructor options retained until a concrete implementation is selected. */
1479
+ options;
1480
+ /** Built-in stream format to probe, or null when the format has no built-in path. */
1481
+ nativeFormat;
1482
+ /** Returns whether built-in selection remains eligible for the merged preload options. */
1483
+ shouldUseNative;
1484
+ /** Dynamically imports the balanced fallback constructor. */
1485
+ loadFallback;
1486
+ /** Selected concrete implementation after preload completes. */
1487
+ implementation = null;
1488
+ /** Shared in-flight selection used by concurrent asynchronous calls. */
1489
+ implementationPromise = null;
1490
+ constructor(metadata, loadFallback, options = {}, nativeFormat = null, shouldUseNative = () => true) {
1491
+ super(options);
1492
+ this.name = metadata.name;
1493
+ this.extensions = [...metadata.extensions];
1494
+ this.contentEncodings = [...metadata.contentEncodings];
1495
+ this.options = options;
1496
+ this.nativeFormat = nativeFormat;
1497
+ this.shouldUseNative = shouldUseNative;
1498
+ this.loadFallback = loadFallback;
1499
+ }
1500
+ /** Selects and returns the built-in or dynamically imported fallback decompressor. */
1501
+ async preload(modules = {}) {
1502
+ if (this.implementation) return this.implementation;
1503
+ const options = mergeModules(this.options, modules);
1504
+ this.implementationPromise ||= this.loadImplementation(options);
1505
+ try {
1506
+ this.implementation = await this.implementationPromise;
1507
+ return this.implementation;
1508
+ } catch (error) {
1509
+ this.implementationPromise = null;
1510
+ throw error;
1511
+ }
1512
+ }
1513
+ /** Loads the selected concrete decompressor. */
1514
+ async loadImplementation(options) {
1515
+ if (options.useNative !== false && this.nativeFormat && this.shouldUseNative(options) && isNativeDecompressionSupported(this.nativeFormat)) {
1516
+ const { NativeDecompressor: NativeDecompressor2 } = await Promise.resolve().then(() => (init_native_decompressor(), native_decompressor_exports));
1517
+ return new NativeDecompressor2(this, this.nativeFormat, options);
1518
+ }
1519
+ const Decompressor2 = await this.loadFallback();
1520
+ const implementation = new Decompressor2({ ...options, useNative: false });
1521
+ await implementation.preload(options.modules);
1522
+ return implementation;
1523
+ }
1524
+ /** Decompresses after lazily selecting the default implementation. */
1525
+ async decompress(input, size) {
1526
+ return (await this.preload()).decompress(input, size);
1527
+ }
1528
+ /** Decompresses synchronously after an implementation has been preloaded. */
1529
+ decompressSync(input, size) {
1530
+ if (!this.implementation) {
1531
+ throw new Error(`${this.name}: call preload() before decompressSync()`);
1532
+ }
1533
+ return this.implementation.decompressSync(input, size);
1534
+ }
1535
+ /** Decompresses batches after lazily selecting the default implementation. */
1536
+ async *decompressBatches(inputBatches) {
1537
+ yield* (await this.preload()).decompressBatches(inputBatches);
1538
+ }
1539
+ };
1540
+ }
1541
+ });
1542
+
1543
+ // ../compression/src/lib/fflate-stream.ts
1544
+ async function* transformFflateBatches(processor, inputBatches) {
1545
+ const chunks = [];
1546
+ processor.ondata = (data) => {
1547
+ chunks.push(data.slice().buffer);
397
1548
  };
1549
+ for await (const batch of inputBatches) {
1550
+ processor.push(new Uint8Array(batch), false);
1551
+ yield* chunks.splice(0);
1552
+ }
1553
+ processor.push(new Uint8Array(0), true);
1554
+ yield* chunks;
398
1555
  }
399
- function decodeKSPLATSplat(data, header, section, localSplatIndex, outputSplatIndex, positions, scales, rotations, colors, opacities, sphericalHarmonics, sphericalHarmonicsComponentCount) {
400
- const layout = COMPRESSION_LAYOUTS[header.compressionLevel];
401
- const splatBase = section.dataBase + section.bytesPerSplat * localSplatIndex;
402
- const positionOffset = outputSplatIndex * 3;
403
- const rotationOffset = outputSplatIndex * 4;
404
- const bucketCenter = getBucketCenter(data, section, localSplatIndex);
405
- positions[positionOffset + 0] = decodeKSPLATCenterComponent(data, splatBase, 0, header, section, bucketCenter[0]);
406
- positions[positionOffset + 1] = decodeKSPLATCenterComponent(data, splatBase, 1, header, section, bucketCenter[1]);
407
- positions[positionOffset + 2] = decodeKSPLATCenterComponent(data, splatBase, 2, header, section, bucketCenter[2]);
408
- scales[positionOffset + 0] = readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 0, header.compressionLevel);
409
- scales[positionOffset + 1] = readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 1, header.compressionLevel);
410
- scales[positionOffset + 2] = readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 2, header.compressionLevel);
411
- const [w, x, y, z2] = normalizeQuaternion(readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 3, header.compressionLevel), readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 4, header.compressionLevel), readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 5, header.compressionLevel), readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 6, header.compressionLevel));
412
- rotations[rotationOffset + 0] = w;
413
- rotations[rotationOffset + 1] = x;
414
- rotations[rotationOffset + 2] = y;
415
- rotations[rotationOffset + 3] = z2;
416
- const colorBase = splatBase + layout.colorOffsetBytes;
417
- const colorView = new Uint8Array(data, colorBase, 4);
418
- colors[positionOffset + 0] = colorView[0];
419
- colors[positionOffset + 1] = colorView[1];
420
- colors[positionOffset + 2] = colorView[2];
421
- opacities[outputSplatIndex] = convertAlphaByteToLinearOpacity(colorView[3]);
422
- if (sphericalHarmonics && sphericalHarmonicsComponentCount) {
423
- decodeSphericalHarmonics(data, splatBase + layout.sphericalHarmonicsOffsetBytes, header, section, outputSplatIndex, sphericalHarmonics, sphericalHarmonicsComponentCount);
1556
+ var init_fflate_stream = __esm({
1557
+ "../compression/src/lib/fflate-stream.ts"() {
1558
+ "use strict";
1559
+ }
1560
+ });
1561
+
1562
+ // ../compression/src/gzip-decompressor-fflate.ts
1563
+ var GZipFflateDecompressor;
1564
+ var init_gzip_decompressor_fflate = __esm({
1565
+ "../compression/src/gzip-decompressor-fflate.ts"() {
1566
+ "use strict";
1567
+ init_fflate();
1568
+ init_compression();
1569
+ init_fflate_stream();
1570
+ GZipFflateDecompressor = class extends Decompressor {
1571
+ name = "gzip";
1572
+ extensions = ["gz", "gzip"];
1573
+ contentEncodings = ["gzip", "x-gzip"];
1574
+ isSupported = true;
1575
+ constructor(options = {}) {
1576
+ super(options);
1577
+ }
1578
+ /** Decompresses one GZIP payload synchronously. */
1579
+ decompressSync(input) {
1580
+ return gunzipSync(new Uint8Array(input)).slice().buffer;
1581
+ }
1582
+ /** Decompresses GZIP batches incrementally. */
1583
+ async *decompressBatches(inputBatches) {
1584
+ yield* transformFflateBatches(new Gunzip(), inputBatches);
1585
+ }
1586
+ };
1587
+ }
1588
+ });
1589
+
1590
+ // ../compression/src/gzip-decompressor.ts
1591
+ var gzip_decompressor_exports = {};
1592
+ __export(gzip_decompressor_exports, {
1593
+ GZipDecompressor: () => GZipDecompressor
1594
+ });
1595
+ var GZipDecompressor;
1596
+ var init_gzip_decompressor = __esm({
1597
+ "../compression/src/gzip-decompressor.ts"() {
1598
+ "use strict";
1599
+ init_gzip_decompressor_fflate();
1600
+ init_decompression_stream();
1601
+ GZipDecompressor = class extends GZipFflateDecompressor {
1602
+ options;
1603
+ constructor(options = {}) {
1604
+ super(options);
1605
+ this.options = options;
1606
+ }
1607
+ /** Decompresses with the built-in stream when available, then falls back to fflate. */
1608
+ async decompress(input) {
1609
+ if (this.options.useNative !== false) {
1610
+ const output = await decompressWithNativeDecompressionStream(input, "gzip");
1611
+ if (output) return output;
1612
+ }
1613
+ return this.decompressSync(input);
1614
+ }
1615
+ /** Decompresses batches with a built-in or fflate stream. */
1616
+ async *decompressBatches(inputBatches) {
1617
+ if (this.options.useNative !== false) {
1618
+ const output = decompressBatchesWithNativeDecompressionStream(inputBatches, "gzip");
1619
+ if (output) {
1620
+ yield* output;
1621
+ return;
1622
+ }
1623
+ }
1624
+ yield* super.decompressBatches(inputBatches);
1625
+ }
1626
+ };
1627
+ }
1628
+ });
1629
+
1630
+ // ../compression/src/zstd-decompressor-fzstd.ts
1631
+ var import_fzstd, ZstdFzstdDecompressor;
1632
+ var init_zstd_decompressor_fzstd = __esm({
1633
+ "../compression/src/zstd-decompressor-fzstd.ts"() {
1634
+ "use strict";
1635
+ init_compression();
1636
+ import_fzstd = require("fzstd");
1637
+ ZstdFzstdDecompressor = class extends Decompressor {
1638
+ name = "zstd";
1639
+ extensions = ["zst"];
1640
+ contentEncodings = ["zstd"];
1641
+ isSupported = true;
1642
+ constructor(options = {}) {
1643
+ super(options);
1644
+ }
1645
+ /** Decompresses one Zstandard frame synchronously. */
1646
+ decompressSync(input) {
1647
+ return (0, import_fzstd.decompress)(new Uint8Array(input)).slice().buffer;
1648
+ }
1649
+ };
424
1650
  }
1651
+ });
1652
+
1653
+ // ../compression/src/zstd-fallback.ts
1654
+ var zstd_fallback_exports = {};
1655
+ __export(zstd_fallback_exports, {
1656
+ decompressZstd: () => decompressZstd
1657
+ });
1658
+ function decompressZstd(input) {
1659
+ return (0, import_fzstd2.decompress)(input);
425
1660
  }
426
- function parseKSPLATHeader(data) {
427
- const dataView = new DataView(data, 0, HEADER_BYTE_LENGTH);
428
- const compressionLevel = dataView.getUint16(20, true);
429
- if (compressionLevel !== 0 && compressionLevel !== 1 && compressionLevel !== 2) {
430
- throw new Error(`KSPLATLoader: unsupported compression level ${compressionLevel}.`);
1661
+ var import_fzstd2;
1662
+ var init_zstd_fallback = __esm({
1663
+ "../compression/src/zstd-fallback.ts"() {
1664
+ "use strict";
1665
+ import_fzstd2 = require("fzstd");
1666
+ }
1667
+ });
1668
+
1669
+ // ../compression/src/lib/zstd-compression.ts
1670
+ var zstd_compression_exports = {};
1671
+ __export(zstd_compression_exports, {
1672
+ ZstdCompression: () => ZstdCompression
1673
+ });
1674
+ var CHUNK_SIZE, zstdPromise, zstd, ZstdCompression;
1675
+ var init_zstd_compression = __esm({
1676
+ "../compression/src/lib/zstd-compression.ts"() {
1677
+ "use strict";
1678
+ init_compression();
1679
+ init_src();
1680
+ init_compression_stream();
1681
+ init_decompression_stream();
1682
+ CHUNK_SIZE = 1e6;
1683
+ ZstdCompression = class extends Compression {
1684
+ name = "zstd";
1685
+ extensions = [];
1686
+ contentEncodings = [];
1687
+ isSupported = true;
1688
+ options;
1689
+ /**
1690
+ * zstd-codec is an injectable dependency due to big size
1691
+ * @param options
1692
+ */
1693
+ constructor(options = {}) {
1694
+ super(options);
1695
+ this.options = options;
1696
+ registerJSModules(options == null ? void 0 : options.modules);
1697
+ }
1698
+ async preload(modules = {}) {
1699
+ registerJSModules(modules);
1700
+ const ZstdCodec = getJSModuleOrNull("zstd-codec");
1701
+ if (!zstdPromise && ZstdCodec) {
1702
+ zstdPromise = new Promise((resolve) => ZstdCodec.run((zstd2) => resolve(zstd2)));
1703
+ }
1704
+ if (zstdPromise) {
1705
+ zstd = await zstdPromise;
1706
+ }
1707
+ }
1708
+ compressSync(input) {
1709
+ getJSModule("zstd-codec", this.name);
1710
+ const simpleZstd = new zstd.Simple();
1711
+ const inputArray = new Uint8Array(input);
1712
+ return simpleZstd.compress(inputArray).buffer;
1713
+ }
1714
+ async compress(input) {
1715
+ var _a;
1716
+ if (this.options.useNative !== false && ((_a = this.options.zstd) == null ? void 0 : _a.useNative) !== false) {
1717
+ const nativeOutput = await compressWithNativeCompressionStream(input, "zstd");
1718
+ if (nativeOutput) return nativeOutput;
1719
+ }
1720
+ await this.preload();
1721
+ return this.compressSync(input);
1722
+ }
1723
+ decompressSync(input) {
1724
+ getJSModule("zstd-codec", this.name);
1725
+ const simpleZstd = new zstd.Simple();
1726
+ const inputArray = new Uint8Array(input);
1727
+ return simpleZstd.decompress(inputArray).buffer;
1728
+ }
1729
+ async decompress(input, size) {
1730
+ var _a;
1731
+ if (!getJSModuleOrNull("zstd-codec") && this.options.useNative !== false && ((_a = this.options.zstd) == null ? void 0 : _a.useNative) !== false) {
1732
+ const nativeOutput = await decompressWithNativeDecompressionStream(input, "zstd");
1733
+ if (nativeOutput) return nativeOutput;
1734
+ }
1735
+ await this.preload();
1736
+ const inputArray = new Uint8Array(input);
1737
+ if (!zstd) {
1738
+ const { decompressZstd: decompressZstd2 } = await Promise.resolve().then(() => (init_zstd_fallback(), zstd_fallback_exports));
1739
+ return ensureArrayBuffer(decompressZstd2(inputArray));
1740
+ }
1741
+ const simpleZstd = new zstd.Streaming();
1742
+ const chunks = [];
1743
+ for (let i = 0; i <= inputArray.length; i += CHUNK_SIZE) {
1744
+ const chunkView = inputArray.subarray(i, i + CHUNK_SIZE);
1745
+ const chunkArrayBuffer = ensureArrayBuffer(chunkView);
1746
+ chunks.push(new Uint8Array(chunkArrayBuffer));
1747
+ }
1748
+ const decompressResult = await simpleZstd.decompressChunks(chunks);
1749
+ return decompressResult.buffer;
1750
+ }
1751
+ };
1752
+ }
1753
+ });
1754
+
1755
+ // ../compression/src/zstd-decompressor.ts
1756
+ var zstd_decompressor_exports = {};
1757
+ __export(zstd_decompressor_exports, {
1758
+ ZstdDecompressor: () => ZstdDecompressor
1759
+ });
1760
+ var ZstdDecompressor;
1761
+ var init_zstd_decompressor = __esm({
1762
+ "../compression/src/zstd-decompressor.ts"() {
1763
+ "use strict";
1764
+ init_zstd_decompressor_fzstd();
1765
+ init_decompression_stream();
1766
+ init_src();
1767
+ ZstdDecompressor = class extends ZstdFzstdDecompressor {
1768
+ options;
1769
+ compatibility = null;
1770
+ constructor(options = {}) {
1771
+ super(options);
1772
+ this.options = options;
1773
+ registerJSModules(options.modules);
1774
+ }
1775
+ /** Preloads an injected zstd-codec implementation when supplied. */
1776
+ async preload(modules = {}) {
1777
+ registerJSModules(modules);
1778
+ if (getJSModuleOrNull("zstd-codec")) {
1779
+ const { ZstdCompression: ZstdCompression2 } = await Promise.resolve().then(() => (init_zstd_compression(), zstd_compression_exports));
1780
+ this.compatibility ||= new ZstdCompression2(this.options);
1781
+ await this.compatibility.preload(modules);
1782
+ }
1783
+ }
1784
+ /** Decompresses with the built-in stream when available, then falls back to fzstd. */
1785
+ async decompress(input) {
1786
+ if (this.options.useNative !== false) {
1787
+ const output = await decompressWithNativeDecompressionStream(input, "zstd");
1788
+ if (output) return output;
1789
+ }
1790
+ if (getJSModuleOrNull("zstd-codec")) {
1791
+ await this.preload(this.options.modules);
1792
+ }
1793
+ return this.decompressSync(input);
1794
+ }
1795
+ /** Decompresses with a preloaded zstd-codec implementation or compact fzstd. */
1796
+ decompressSync(input) {
1797
+ if (this.compatibility) {
1798
+ return this.compatibility.decompressSync(input);
1799
+ }
1800
+ if (getJSModuleOrNull("zstd-codec")) {
1801
+ throw new Error("zstd: call preload() before synchronous decompression with zstd-codec");
1802
+ }
1803
+ return super.decompressSync(input);
1804
+ }
1805
+ /** Decompresses batches with a built-in stream or compact fzstd fallback. */
1806
+ async *decompressBatches(inputBatches) {
1807
+ if (this.options.useNative !== false) {
1808
+ const output = decompressBatchesWithNativeDecompressionStream(inputBatches, "zstd");
1809
+ if (output) {
1810
+ yield* output;
1811
+ return;
1812
+ }
1813
+ }
1814
+ if (getJSModuleOrNull("zstd-codec")) {
1815
+ yield this.decompress(await this.concatenate(inputBatches));
1816
+ return;
1817
+ }
1818
+ yield* super.decompressBatches(inputBatches);
1819
+ }
1820
+ };
1821
+ }
1822
+ });
1823
+
1824
+ // ../compression/src/default-codecs.ts
1825
+ var GZIP, ZSTD, GZipDecompressor2, ZstdDecompressor2;
1826
+ var init_default_codecs = __esm({
1827
+ "../compression/src/default-codecs.ts"() {
1828
+ "use strict";
1829
+ init_lazy_compression();
1830
+ init_src();
1831
+ GZIP = { name: "gzip", extensions: ["gz"], contentEncodings: ["gzip"] };
1832
+ ZSTD = { name: "zstd", extensions: ["zst"], contentEncodings: ["zstd"] };
1833
+ GZipDecompressor2 = class extends LazyDecompressor {
1834
+ constructor(options = {}) {
1835
+ super(
1836
+ GZIP,
1837
+ async () => (await Promise.resolve().then(() => (init_gzip_decompressor(), gzip_decompressor_exports))).GZipDecompressor,
1838
+ options,
1839
+ "gzip"
1840
+ );
1841
+ }
1842
+ };
1843
+ ZstdDecompressor2 = class extends LazyDecompressor {
1844
+ constructor(options = {}) {
1845
+ super(
1846
+ ZSTD,
1847
+ async () => (await Promise.resolve().then(() => (init_zstd_decompressor(), zstd_decompressor_exports))).ZstdDecompressor,
1848
+ options,
1849
+ "zstd",
1850
+ (preloadOptions) => {
1851
+ var _a;
1852
+ return !((_a = preloadOptions.modules) == null ? void 0 : _a["zstd-codec"]) && !getJSModuleOrNull("zstd-codec");
1853
+ }
1854
+ );
1855
+ }
1856
+ };
1857
+ }
1858
+ });
1859
+
1860
+ // ../compression/src/index.ts
1861
+ var init_src2 = __esm({
1862
+ "../compression/src/index.ts"() {
1863
+ "use strict";
1864
+ init_default_codecs();
1865
+ }
1866
+ });
1867
+
1868
+ // dist/lib/splat-utils.js
1869
+ function convertColorByteToSphericalHarmonicDc(colorByte) {
1870
+ return (colorByte / 255 - 0.5) / SH_C0;
1871
+ }
1872
+ function convertAlphaByteToLinearOpacity(alphaByte) {
1873
+ return Math.min(Math.max(alphaByte / 255, 0), 1);
1874
+ }
1875
+ function normalizeQuaternion(w, x, y, z2) {
1876
+ const length = Math.hypot(w, x, y, z2);
1877
+ if (!Number.isFinite(length) || length <= Number.EPSILON) {
1878
+ return [1, 0, 0, 0];
1879
+ }
1880
+ return [w / length, x / length, y / length, z2 / length];
1881
+ }
1882
+ function decodeQuaternionByte(byte) {
1883
+ return (byte - 128) / 128;
1884
+ }
1885
+ function decodeFloat16(value) {
1886
+ const sign = value & 32768 ? -1 : 1;
1887
+ const exponent = value >> 10 & 31;
1888
+ const fraction = value & 1023;
1889
+ if (exponent === 0) {
1890
+ return sign * Math.pow(2, -14) * (fraction / 1024);
1891
+ }
1892
+ if (exponent === 31) {
1893
+ return fraction ? Number.NaN : sign * Number.POSITIVE_INFINITY;
1894
+ }
1895
+ return sign * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
1896
+ }
1897
+ var SH_C0;
1898
+ var init_splat_utils = __esm({
1899
+ "dist/lib/splat-utils.js"() {
1900
+ "use strict";
1901
+ SH_C0 = 0.28209479177387814;
1902
+ }
1903
+ });
1904
+
1905
+ // dist/lib/splats-arrow-table.js
1906
+ function makeGaussianSplatsArrowTable(splats) {
1907
+ const columns = {};
1908
+ const fields = [];
1909
+ const schemaFields = [];
1910
+ addColumn(columns, fields, schemaFields, "POSITION", makeFixedSizeListVector(splats.positions, 3), {
1911
+ type: "fixed-size-list",
1912
+ listSize: 3,
1913
+ children: [{ name: "value", type: "float32" }]
1914
+ });
1915
+ const colorCoefficients = getColorCoefficients(splats);
1916
+ addScalarColumn(columns, fields, schemaFields, "f_dc_0", colorCoefficients[0], {
1917
+ "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_dc",
1918
+ "loaders_gl.gaussian_splats.component": "0",
1919
+ "loaders_gl.gaussian_splats.encoding": "coefficient"
1920
+ });
1921
+ addScalarColumn(columns, fields, schemaFields, "f_dc_1", colorCoefficients[1], {
1922
+ "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_dc",
1923
+ "loaders_gl.gaussian_splats.component": "1",
1924
+ "loaders_gl.gaussian_splats.encoding": "coefficient"
1925
+ });
1926
+ addScalarColumn(columns, fields, schemaFields, "f_dc_2", colorCoefficients[2], {
1927
+ "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_dc",
1928
+ "loaders_gl.gaussian_splats.component": "2",
1929
+ "loaders_gl.gaussian_splats.encoding": "coefficient"
1930
+ });
1931
+ addScalarColumn(columns, fields, schemaFields, "opacity", splats.opacities, {
1932
+ "loaders_gl.gaussian_splats.semantic": "opacity",
1933
+ "loaders_gl.gaussian_splats.encoding": "linear"
1934
+ });
1935
+ addVectorComponents(columns, fields, schemaFields, "scale", splats.scales, 3, {
1936
+ "loaders_gl.gaussian_splats.semantic": "scale",
1937
+ "loaders_gl.gaussian_splats.encoding": "linear"
1938
+ });
1939
+ addVectorComponents(columns, fields, schemaFields, "rot", splats.rotations, 4, {
1940
+ "loaders_gl.gaussian_splats.semantic": "rotation",
1941
+ "loaders_gl.gaussian_splats.encoding": "quaternion"
1942
+ });
1943
+ if (splats.sphericalHarmonics && splats.sphericalHarmonicsComponentCount) {
1944
+ addSphericalHarmonicRestColumns(columns, fields, schemaFields, splats.sphericalHarmonics, splats.sphericalHarmonicsComponentCount);
431
1945
  }
1946
+ const metadata = /* @__PURE__ */ new Map([
1947
+ ["loaders_gl.semantic_type", "gaussian-splats"],
1948
+ ["loaders_gl.gaussian_splats.version", "1"],
1949
+ ["loaders_gl.gaussian_splats.source_format", splats.format],
1950
+ ["topology", "point-list"],
1951
+ ["mode", "0"]
1952
+ ]);
1953
+ const arrowSchema = new arrow.Schema(fields, metadata);
1954
+ const schema = {
1955
+ fields: schemaFields,
1956
+ metadata: Object.fromEntries(metadata)
1957
+ };
432
1958
  return {
433
- versionMajor: dataView.getUint8(0),
434
- versionMinor: dataView.getUint8(1),
435
- maxSectionCount: dataView.getUint32(4, true),
436
- sectionCount: dataView.getUint32(8, true),
437
- maxSplatCount: dataView.getUint32(12, true),
438
- splatCount: dataView.getUint32(16, true),
439
- compressionLevel,
440
- minSphericalHarmonicsCoeff: dataView.getFloat32(36, true) || -DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE,
441
- maxSphericalHarmonicsCoeff: dataView.getFloat32(40, true) || DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE
1959
+ shape: "arrow-table",
1960
+ schema,
1961
+ data: new arrow.Table(arrowSchema, columns),
1962
+ topology: "point-list",
1963
+ loaderData: splats.loaderData
442
1964
  };
443
1965
  }
444
- function checkKSPLATVersion(header) {
445
- if (header.versionMajor === CURRENT_MAJOR_VERSION ? header.versionMinor >= CURRENT_MINOR_VERSION : header.versionMajor > CURRENT_MAJOR_VERSION) {
446
- return;
1966
+ function addVectorComponents(columns, fields, schemaFields, prefix, values, size, metadata) {
1967
+ for (let component = 0; component < size; component++) {
1968
+ const componentValues = new Float32Array(values.length / size);
1969
+ for (let rowIndex = 0; rowIndex < componentValues.length; rowIndex++) {
1970
+ componentValues[rowIndex] = values[rowIndex * size + component];
1971
+ }
1972
+ addScalarColumn(columns, fields, schemaFields, `${prefix}_${component}`, componentValues, {
1973
+ ...metadata,
1974
+ "loaders_gl.gaussian_splats.component": String(component)
1975
+ });
447
1976
  }
448
- throw new Error(`KSPLATLoader: version ${header.versionMajor}.${header.versionMinor} is not supported.`);
449
1977
  }
450
- function parseKSPLATSections(data, header) {
451
- if (data.byteLength < HEADER_BYTE_LENGTH + header.maxSectionCount * SECTION_HEADER_BYTE_LENGTH) {
452
- throw new Error("KSPLATLoader: file does not contain all section headers.");
453
- }
454
- const sections = [];
455
- let sectionBase = HEADER_BYTE_LENGTH + header.maxSectionCount * SECTION_HEADER_BYTE_LENGTH;
456
- let splatCountOffset = 0;
457
- for (let sectionIndex = 0; sectionIndex < header.maxSectionCount; sectionIndex++) {
458
- const sectionHeaderBase = HEADER_BYTE_LENGTH + sectionIndex * SECTION_HEADER_BYTE_LENGTH;
459
- const dataView = new DataView(data, sectionHeaderBase, SECTION_HEADER_BYTE_LENGTH);
460
- const splatCount = dataView.getUint32(0, true);
461
- const maxSplatCount = dataView.getUint32(4, true);
462
- const bucketSize = dataView.getUint32(8, true);
463
- const bucketCount = dataView.getUint32(12, true);
464
- const bucketBlockSize = dataView.getFloat32(16, true);
465
- const bucketStorageSizeBytes = dataView.getUint16(20, true);
466
- const compressionScaleRange = dataView.getUint32(24, true) || COMPRESSION_LAYOUTS[header.compressionLevel].scaleRange;
467
- const fullBucketCount = dataView.getUint32(32, true);
468
- const partiallyFilledBucketCount = dataView.getUint32(36, true);
469
- const sphericalHarmonicsDegree = dataView.getUint16(40, true);
470
- const bytesPerSplat = getBytesPerSplat(header.compressionLevel, sphericalHarmonicsDegree);
471
- const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
472
- const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;
473
- const storageSizeBytes = bytesPerSplat * maxSplatCount + bucketsStorageSizeBytes;
474
- sections.push({
475
- bytesPerSplat,
476
- splatCountOffset,
477
- splatCount: splatCount || maxSplatCount,
478
- maxSplatCount,
479
- bucketSize,
480
- bucketCount,
481
- bucketStorageSizeBytes,
482
- bucketsStorageSizeBytes,
483
- compressionScaleRange,
484
- compressionScaleFactor: bucketBlockSize / 2 / compressionScaleRange,
485
- base: sectionBase,
486
- bucketsBase: sectionBase + bucketsMetaDataSizeBytes,
487
- dataBase: sectionBase + bucketsStorageSizeBytes,
488
- fullBucketCount,
489
- partiallyFilledBucketCount,
490
- sphericalHarmonicsDegree
1978
+ function addSphericalHarmonicRestColumns(columns, fields, schemaFields, sphericalHarmonics, componentCount) {
1979
+ for (let component = 0; component < componentCount; component++) {
1980
+ const componentValues = new Float32Array(sphericalHarmonics.length / componentCount);
1981
+ for (let rowIndex = 0; rowIndex < componentValues.length; rowIndex++) {
1982
+ componentValues[rowIndex] = sphericalHarmonics[rowIndex * componentCount + component];
1983
+ }
1984
+ addScalarColumn(columns, fields, schemaFields, `f_rest_${component}`, componentValues, {
1985
+ "loaders_gl.gaussian_splats.semantic": "spherical_harmonic_rest",
1986
+ "loaders_gl.gaussian_splats.component": String(component),
1987
+ "loaders_gl.gaussian_splats.encoding": "coefficient"
491
1988
  });
492
- sectionBase += storageSizeBytes;
493
- splatCountOffset += maxSplatCount;
494
1989
  }
495
- return sections;
496
1990
  }
497
- function decodeKSPLATCenterComponent(data, splatBase, component, header, section, bucketCenter) {
498
- const value = readCompressedCenterValue(data, splatBase, component, header.compressionLevel);
499
- return header.compressionLevel >= 1 ? (value - section.compressionScaleRange) * section.compressionScaleFactor + bucketCenter : value;
1991
+ function addScalarColumn(columns, fields, schemaFields, name, values, metadata) {
1992
+ addColumn(columns, fields, schemaFields, name, arrow.makeVector(values), "float32", metadata);
500
1993
  }
501
- function readCompressedCenterValue(data, byteOffset, component, compressionLevel) {
502
- const dataView = new DataView(data);
503
- return compressionLevel === 0 ? dataView.getFloat32(byteOffset + component * 4, true) : dataView.getUint16(byteOffset + component * 2, true);
1994
+ function addColumn(columns, fields, schemaFields, name, column, schemaType, metadata = {}) {
1995
+ columns[name] = column;
1996
+ fields.push(new arrow.Field(name, column.type, false, new Map(Object.entries(metadata))));
1997
+ schemaFields.push({ name, type: schemaType, nullable: false, metadata });
504
1998
  }
505
- function getBucketCenter(data, section, localSplatIndex) {
506
- if (!section.bucketCount) {
507
- return [0, 0, 0];
508
- }
509
- const bucketIndex = getBucketIndex(data, section, localSplatIndex);
510
- const bucketBase = section.bucketsBase + bucketIndex * section.bucketStorageSizeBytes;
511
- const dataView = new DataView(data, bucketBase, 12);
512
- return [dataView.getFloat32(0, true), dataView.getFloat32(4, true), dataView.getFloat32(8, true)];
1999
+ function makeFixedSizeListVector(value, size) {
2000
+ const values = arrow.makeVector(value);
2001
+ const child = values.data[0];
2002
+ const type = new arrow.FixedSizeList(size, new arrow.Field("value", child.type, false));
2003
+ const data = new arrow.Data(type, 0, value.length / size, 0, {}, [child]);
2004
+ return new arrow.Vector([data]);
513
2005
  }
514
- function getBucketIndex(data, section, localSplatIndex) {
515
- const maxSplatIndexInFullBuckets = section.fullBucketCount * section.bucketSize;
516
- if (localSplatIndex < maxSplatIndexInFullBuckets) {
517
- return Math.floor(localSplatIndex / section.bucketSize);
518
- }
519
- let bucketSplatIndex = maxSplatIndexInFullBuckets;
520
- let bucketIndex = section.fullBucketCount;
521
- for (let partiallyFilledBucketIndex = 0; partiallyFilledBucketIndex < section.partiallyFilledBucketCount; partiallyFilledBucketIndex++) {
522
- const bucketLength = new DataView(data, section.base + partiallyFilledBucketIndex * 4, 4).getUint32(0, true);
523
- if (localSplatIndex < bucketSplatIndex + bucketLength) {
524
- return bucketIndex;
2006
+ function getColorCoefficients(splats) {
2007
+ const rowCount = splats.splatCount;
2008
+ const fdc0 = new Float32Array(rowCount);
2009
+ const fdc1 = new Float32Array(rowCount);
2010
+ const fdc2 = new Float32Array(rowCount);
2011
+ for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
2012
+ if (splats.sphericalHarmonicDcs) {
2013
+ fdc0[rowIndex] = splats.sphericalHarmonicDcs[rowIndex * 3 + 0];
2014
+ fdc1[rowIndex] = splats.sphericalHarmonicDcs[rowIndex * 3 + 1];
2015
+ fdc2[rowIndex] = splats.sphericalHarmonicDcs[rowIndex * 3 + 2];
2016
+ } else {
2017
+ fdc0[rowIndex] = convertColorByteToSphericalHarmonicDc(splats.colors[rowIndex * 3 + 0]);
2018
+ fdc1[rowIndex] = convertColorByteToSphericalHarmonicDc(splats.colors[rowIndex * 3 + 1]);
2019
+ fdc2[rowIndex] = convertColorByteToSphericalHarmonicDc(splats.colors[rowIndex * 3 + 2]);
525
2020
  }
526
- bucketSplatIndex += bucketLength;
527
- bucketIndex++;
528
2021
  }
529
- return Math.max(bucketIndex - 1, 0);
2022
+ return [fdc0, fdc1, fdc2];
530
2023
  }
531
- function decodeSphericalHarmonics(data, byteOffset, header, section, outputSplatIndex, output, outputComponentCount) {
532
- const componentCount = getSphericalHarmonicsComponentCount(section.sphericalHarmonicsDegree);
533
- const componentBase = outputSplatIndex * outputComponentCount;
534
- for (let component = 0; component < componentCount; component++) {
535
- output[componentBase + component] = readCompressedFloat(data, byteOffset, component, header.compressionLevel, true, header.minSphericalHarmonicsCoeff, header.maxSphericalHarmonicsCoeff);
2024
+ var arrow;
2025
+ var init_splats_arrow_table = __esm({
2026
+ "dist/lib/splats-arrow-table.js"() {
2027
+ "use strict";
2028
+ arrow = __toESM(require("apache-arrow"), 1);
2029
+ init_splat_utils();
536
2030
  }
2031
+ });
2032
+
2033
+ // dist/lib/parse-spz.js
2034
+ async function parseSPZ(data, options) {
2035
+ return makeGaussianSplatsArrowTable(await parseSPZToGaussianSplats(data, options));
537
2036
  }
538
- function readCompressedFloat(data, byteOffset, component, compressionLevel, sphericalHarmonic = false, sphericalHarmonicRangeMin = 0, sphericalHarmonicRangeMax = 0) {
539
- const dataView = new DataView(data);
540
- if (compressionLevel === 0) {
541
- return dataView.getFloat32(byteOffset + component * 4, true);
2037
+ async function parseSPZToGaussianSplats(data, options) {
2038
+ var _a, _b, _c;
2039
+ const version2 = detectSPZVersion(data);
2040
+ if (version2 === 0) {
2041
+ return await parseLegacySPZ(data, options);
542
2042
  }
543
- if (compressionLevel === 1 || !sphericalHarmonic) {
544
- return decodeFloat16(dataView.getUint16(byteOffset + component * 2, true));
2043
+ if (version2 !== SPZ_VERSION) {
2044
+ throw new Error(`SPZLoader: version ${version2} is not supported.`);
545
2045
  }
546
- const value = dataView.getUint8(byteOffset + component);
547
- return value / 255 * (sphericalHarmonicRangeMax - sphericalHarmonicRangeMin) + sphericalHarmonicRangeMin;
2046
+ const header = parseSPZHeader(data);
2047
+ const streamInfos = parseSPZStreamInfos(data, header, getSPZStreamByteLengths(header));
2048
+ const compressedStreams = streamInfos.map((streamInfo) => data.slice(streamInfo.compressedOffset, streamInfo.compressedOffset + streamInfo.compressedSize));
2049
+ const decompressor = new ZstdDecompressor2({ modules: options == null ? void 0 : options.modules });
2050
+ const streams = await Promise.all(compressedStreams.map((compressedStream, streamIndex) => decompressor.decompress(compressedStream, streamInfos[streamIndex].uncompressedSize)));
2051
+ validateSPZStreamLengths(streams, streamInfos);
2052
+ return applySPZCoordinateSystem(decodeSPZStreams(header, streams, data), ((_a = options == null ? void 0 : options.splats) == null ? void 0 : _a.sourceCoordinateSystem) ?? "RUB", ((_b = options == null ? void 0 : options.splats) == null ? void 0 : _b.targetCoordinateSystem) ?? ((_c = options == null ? void 0 : options.splats) == null ? void 0 : _c.sourceCoordinateSystem) ?? "RUB");
548
2053
  }
549
- function getBytesPerSplat(compressionLevel, sphericalHarmonicsDegree) {
550
- const layout = COMPRESSION_LAYOUTS[compressionLevel];
551
- return layout.bytesPerCenter + layout.bytesPerScale + layout.bytesPerRotation + layout.bytesPerColor + layout.bytesPerSphericalHarmonicsComponent * getSphericalHarmonicsComponentCount(sphericalHarmonicsDegree);
2054
+ function detectSPZVersion(data) {
2055
+ if (data.byteLength < 8) {
2056
+ throw new Error("SPZLoader: file must contain at least an 8-byte header.");
2057
+ }
2058
+ const bytes = new Uint8Array(data);
2059
+ if (bytes[0] === 31 && bytes[1] === 139) {
2060
+ return 0;
2061
+ }
2062
+ if (data.byteLength < SPZ_HEADER_BYTE_LENGTH) {
2063
+ throw new Error("SPZLoader: file must contain a 32-byte header.");
2064
+ }
2065
+ return new DataView(data).getUint32(4, true);
552
2066
  }
553
- function getSphericalHarmonicsComponentCount(sphericalHarmonicsDegree) {
554
- switch (sphericalHarmonicsDegree) {
555
- case 0:
556
- return 0;
557
- case 1:
558
- return 9;
559
- case 2:
560
- return 24;
561
- case 3:
562
- return 45;
563
- default:
564
- throw new Error(`KSPLATLoader: unsupported spherical harmonics degree ${sphericalHarmonicsDegree}.`);
2067
+ async function parseLegacySPZ(data, options) {
2068
+ var _a, _b, _c;
2069
+ const decompressed = await new GZipDecompressor2({
2070
+ modules: options == null ? void 0 : options.modules,
2071
+ useNative: true
2072
+ }).decompress(data);
2073
+ if (decompressed.byteLength < 16) {
2074
+ throw new Error("SPZLoader: legacy payload must contain a 16-byte header.");
2075
+ }
2076
+ const dataView = new DataView(decompressed);
2077
+ const header = {
2078
+ magic: dataView.getUint32(0, true),
2079
+ version: dataView.getUint32(4, true),
2080
+ numPoints: dataView.getUint32(8, true),
2081
+ shDegree: dataView.getUint8(12),
2082
+ fractionalBits: dataView.getUint8(13),
2083
+ flags: dataView.getUint8(14)
2084
+ };
2085
+ if (header.magic !== SPZ_MAGIC) {
2086
+ throw new Error("SPZLoader: NGSP magic header not found.");
2087
+ }
2088
+ if (header.version !== 2 && header.version !== 3) {
2089
+ throw new Error(`SPZLoader: version ${header.version} is not supported.`);
2090
+ }
2091
+ if (dataView.getUint8(15) !== 0) {
2092
+ throw new Error("SPZLoader: legacy header reserved byte must be zero.");
565
2093
  }
2094
+ if (header.shDegree > 3) {
2095
+ throw new Error(`SPZLoader: spherical harmonics degree ${header.shDegree} is not supported.`);
2096
+ }
2097
+ const count = header.numPoints;
2098
+ const shComponentCount = getSphericalHarmonicsComponentCount(header.shDegree);
2099
+ const positionByteLength = count * 9;
2100
+ const alphaByteLength = count;
2101
+ const colorByteLength = count * 3;
2102
+ const scaleByteLength = count * 3;
2103
+ const rotationByteLength = count * (header.version === 2 ? 3 : 4);
2104
+ const shByteLength = count * shComponentCount;
2105
+ const payloadByteLength = positionByteLength + alphaByteLength + colorByteLength + scaleByteLength + rotationByteLength + shByteLength;
2106
+ if (decompressed.byteLength - 16 !== payloadByteLength) {
2107
+ throw new Error(`SPZLoader: legacy payload has ${decompressed.byteLength - 16} bytes, expected ${payloadByteLength}.`);
2108
+ }
2109
+ let offset = 16;
2110
+ const positions = new Float32Array(count * 3);
2111
+ const opacities = new Float32Array(count);
2112
+ const colors = new Uint8Array(count * 3);
2113
+ const scales = new Float32Array(count * 3);
2114
+ const rotations = new Float32Array(count * 4);
2115
+ const sphericalHarmonicDcs = new Float32Array(count * 3);
2116
+ const sphericalHarmonics = shComponentCount ? new Float32Array(count * shComponentCount) : void 0;
2117
+ decodeSPZPositions(new Uint8Array(decompressed, offset, positionByteLength), positions, header.fractionalBits);
2118
+ offset += positionByteLength;
2119
+ decodeSPZOpacities(new Uint8Array(decompressed, offset, alphaByteLength), opacities);
2120
+ offset += alphaByteLength;
2121
+ decodeSPZColors(new Uint8Array(decompressed, offset, colorByteLength), colors, sphericalHarmonicDcs);
2122
+ offset += colorByteLength;
2123
+ decodeSPZScales(new Uint8Array(decompressed, offset, scaleByteLength), scales);
2124
+ offset += scaleByteLength;
2125
+ if (header.version === 2) {
2126
+ decodeLegacySPZRotations(new Uint8Array(decompressed, offset, rotationByteLength), rotations);
2127
+ } else {
2128
+ decodeSPZRotations(new Uint8Array(decompressed, offset, rotationByteLength), rotations);
2129
+ }
2130
+ offset += rotationByteLength;
2131
+ if (sphericalHarmonics) {
2132
+ decodeSPZSphericalHarmonics(new Uint8Array(decompressed, offset, shByteLength), sphericalHarmonics);
2133
+ }
2134
+ return applySPZCoordinateSystem({
2135
+ format: "spz",
2136
+ splatCount: count,
2137
+ positions,
2138
+ scales,
2139
+ rotations,
2140
+ colors,
2141
+ sphericalHarmonicDcs,
2142
+ opacities,
2143
+ sphericalHarmonics,
2144
+ sphericalHarmonicsComponentCount: shComponentCount || void 0,
2145
+ loaderData: { ...header, legacy: true }
2146
+ }, ((_a = options == null ? void 0 : options.splats) == null ? void 0 : _a.sourceCoordinateSystem) ?? "RUB", ((_b = options == null ? void 0 : options.splats) == null ? void 0 : _b.targetCoordinateSystem) ?? ((_c = options == null ? void 0 : options.splats) == null ? void 0 : _c.sourceCoordinateSystem) ?? "RUB");
566
2147
  }
567
- function getActiveSectionCount(header) {
568
- return header.sectionCount || header.maxSectionCount;
2148
+ function decodeLegacySPZRotations(rotationStream, rotations) {
2149
+ for (let splatIndex = 0; splatIndex < rotations.length / 4; splatIndex++) {
2150
+ const byteOffset = splatIndex * 3;
2151
+ const x = signedByte(rotationStream[byteOffset]) / 127;
2152
+ const y = signedByte(rotationStream[byteOffset + 1]) / 127;
2153
+ const z2 = signedByte(rotationStream[byteOffset + 2]) / 127;
2154
+ const w = Math.sqrt(Math.max(0, 1 - x * x - y * y - z2 * z2));
2155
+ const normalized = normalizeQuaternion(w, x, y, z2);
2156
+ rotations.set(normalized, splatIndex * 4);
2157
+ }
569
2158
  }
570
- function getTotalSplatCount(header, sections) {
571
- const sectionSplatCount = sections.slice(0, getActiveSectionCount(header)).reduce((splatCount, section) => splatCount + section.splatCount, 0);
572
- return header.splatCount ? Math.min(header.splatCount, sectionSplatCount || header.splatCount) : sectionSplatCount;
2159
+ function signedByte(value) {
2160
+ return value > 127 ? value - 256 : value;
573
2161
  }
574
- function validateSectionBounds(data, section) {
575
- const requiredByteLength = section.dataBase + section.bytesPerSplat * section.splatCount;
576
- if (requiredByteLength > data.byteLength) {
577
- throw new Error("KSPLATLoader: section data extends beyond the file length.");
2162
+ function applySPZCoordinateSystem(splats, source, target) {
2163
+ if (source === target || source === "UNSPECIFIED" || target === "UNSPECIFIED") {
2164
+ return splats;
578
2165
  }
579
- }
580
-
581
- // dist/ksplat-loader-types.js
582
- var VERSION2 = true ? "4.5.3" : "latest";
583
- var KSPLATLoader = {
584
- dataType: null,
585
- batchType: null,
586
- ...KSPLATFormat,
587
- version: VERSION2,
588
- options: {
589
- splats: {
590
- shape: "arrow-table"
2166
+ if (source === "RUB" && target === "LUF") {
2167
+ for (let index = 0; index < splats.positions.length; index += 3) {
2168
+ splats.positions[index] = -splats.positions[index];
2169
+ splats.positions[index + 2] = -splats.positions[index + 2];
591
2170
  }
2171
+ for (let index = 0; index < splats.rotations.length; index += 4) {
2172
+ splats.rotations[index + 1] = -splats.rotations[index + 1];
2173
+ splats.rotations[index + 3] = -splats.rotations[index + 3];
2174
+ }
2175
+ return splats;
592
2176
  }
593
- };
594
-
595
- // dist/ksplat-loader.js
596
- var KSPLATLoaderWithParser = {
597
- ...KSPLATLoader,
598
- parse: async (arrayBuffer) => parseKSPLAT(arrayBuffer),
599
- parseSync: (arrayBuffer) => parseKSPLAT(arrayBuffer)
600
- };
601
-
602
- // dist/lib/parse-spz.js
603
- var import_compression = require("@loaders.gl/compression");
604
- var SPZ_HEADER_BYTE_LENGTH = 32;
605
- var SPZ_MAGIC = 1347635022;
606
- var SPZ_VERSION = 4;
607
- var SPZ_EXTENSION_FLAG = 2;
608
- var SPZ_COLOR_SCALE = 0.15;
609
- var SPZ_ROTATION_COMPONENT_SCALE = Math.SQRT1_2;
610
- var SPZ_ROTATION_COMPONENT_MASK = (1 << 9) - 1;
611
- async function parseSPZ(data, options) {
612
- return makeGaussianSplatsArrowTable(await parseSPZToGaussianSplats(data, options));
613
- }
614
- async function parseSPZToGaussianSplats(data, options) {
615
- const header = parseSPZHeader(data);
616
- const streamInfos = parseSPZStreamInfos(data, header, getSPZStreamByteLengths(header));
617
- const compressedStreams = streamInfos.map((streamInfo) => data.slice(streamInfo.compressedOffset, streamInfo.compressedOffset + streamInfo.compressedSize));
618
- const compression = new import_compression.ZstdCompression({ modules: options == null ? void 0 : options.modules });
619
- const streams = await Promise.all(compressedStreams.map((compressedStream, streamIndex) => compression.decompress(compressedStream, streamInfos[streamIndex].uncompressedSize)));
620
- validateSPZStreamLengths(streams, streamInfos);
621
- return decodeSPZStreams(header, streams, data);
2177
+ if (source === "LUF" && target === "RUB") {
2178
+ return applySPZCoordinateSystem(splats, "RUB", "LUF");
2179
+ }
2180
+ throw new Error(`SPZLoader: coordinate conversion ${source} -> ${target} is not supported.`);
622
2181
  }
623
2182
  function parseSPZHeader(data) {
624
2183
  if (data.byteLength < SPZ_HEADER_BYTE_LENGTH) {
@@ -694,7 +2253,7 @@ function getSPZStreamByteLengths(header) {
694
2253
  header.numPoints * 3,
695
2254
  header.numPoints * 3,
696
2255
  header.numPoints * 4,
697
- header.numPoints * getSphericalHarmonicsComponentCount2(header.shDegree)
2256
+ header.numPoints * getSphericalHarmonicsComponentCount(header.shDegree)
698
2257
  ].filter((byteLength) => byteLength > 0);
699
2258
  }
700
2259
  function validateSPZStreamLengths(streams, streamInfos) {
@@ -712,7 +2271,7 @@ function decodeSPZStreams(header, streams, sourceData) {
712
2271
  const colors = new Uint8Array(splatCount * 3);
713
2272
  const sphericalHarmonicDcs = new Float32Array(splatCount * 3);
714
2273
  const opacities = new Float32Array(splatCount);
715
- const sphericalHarmonicsComponentCount = getSphericalHarmonicsComponentCount2(header.shDegree);
2274
+ const sphericalHarmonicsComponentCount = getSphericalHarmonicsComponentCount(header.shDegree);
716
2275
  const sphericalHarmonics = sphericalHarmonicsComponentCount ? new Float32Array(splatCount * sphericalHarmonicsComponentCount) : void 0;
717
2276
  const [positionStream, alphaStream, colorStream, scaleStream, rotationStream, sphericalHarmonicsStream] = streams.map((stream) => new Uint8Array(stream));
718
2277
  decodeSPZPositions(positionStream, positions, header.fractionalBits);
@@ -743,75 +2302,423 @@ function decodeSPZStreams(header, streams, sourceData) {
743
2302
  }
744
2303
  };
745
2304
  }
746
- function decodeSPZPositions(positionStream, positions, fractionalBits) {
747
- const scale = 1 / 2 ** fractionalBits;
748
- for (let componentIndex = 0; componentIndex < positions.length; componentIndex++) {
749
- const byteOffset = componentIndex * 3;
750
- let fixed32 = positionStream[byteOffset] | positionStream[byteOffset + 1] << 8 | positionStream[byteOffset + 2] << 16;
751
- fixed32 |= fixed32 & 8388608 ? 4278190080 : 0;
752
- positions[componentIndex] = fixed32 * scale;
2305
+ function decodeSPZPositions(positionStream, positions, fractionalBits) {
2306
+ const scale = 1 / 2 ** fractionalBits;
2307
+ for (let componentIndex = 0; componentIndex < positions.length; componentIndex++) {
2308
+ const byteOffset = componentIndex * 3;
2309
+ let fixed32 = positionStream[byteOffset] | positionStream[byteOffset + 1] << 8 | positionStream[byteOffset + 2] << 16;
2310
+ fixed32 |= fixed32 & 8388608 ? 4278190080 : 0;
2311
+ positions[componentIndex] = fixed32 * scale;
2312
+ }
2313
+ }
2314
+ function decodeSPZScales(scaleStream, scales) {
2315
+ for (let componentIndex = 0; componentIndex < scales.length; componentIndex++) {
2316
+ scales[componentIndex] = Math.exp(scaleStream[componentIndex] / 16 - 10);
2317
+ }
2318
+ }
2319
+ function decodeSPZRotations(rotationStream, rotations) {
2320
+ for (let splatIndex = 0; splatIndex < rotations.length / 4; splatIndex++) {
2321
+ const byteOffset = splatIndex * 4;
2322
+ const component = rotationStream[byteOffset] | rotationStream[byteOffset + 1] << 8 | rotationStream[byteOffset + 2] << 16 | rotationStream[byteOffset + 3] << 24;
2323
+ const xyzw = decodeSPZQuaternion(component >>> 0);
2324
+ const [w, x, y, z2] = normalizeQuaternion(xyzw[3], xyzw[0], xyzw[1], xyzw[2]);
2325
+ const rotationOffset = splatIndex * 4;
2326
+ rotations[rotationOffset + 0] = w;
2327
+ rotations[rotationOffset + 1] = x;
2328
+ rotations[rotationOffset + 2] = y;
2329
+ rotations[rotationOffset + 3] = z2;
2330
+ }
2331
+ }
2332
+ function decodeSPZQuaternion(component) {
2333
+ const rotation = [0, 0, 0, 0];
2334
+ const largestComponent = component >>> 30;
2335
+ let remainingBits = component;
2336
+ let sumSquares = 0;
2337
+ for (let componentIndex = 3; componentIndex >= 0; componentIndex--) {
2338
+ if (componentIndex !== largestComponent) {
2339
+ const magnitude = remainingBits & SPZ_ROTATION_COMPONENT_MASK;
2340
+ const isNegative = remainingBits >>> 9 & 1;
2341
+ remainingBits >>>= 10;
2342
+ let value = SPZ_ROTATION_COMPONENT_SCALE * magnitude / SPZ_ROTATION_COMPONENT_MASK;
2343
+ if (isNegative) {
2344
+ value = -value;
2345
+ }
2346
+ rotation[componentIndex] = value;
2347
+ sumSquares += value * value;
2348
+ }
2349
+ }
2350
+ rotation[largestComponent] = Math.sqrt(Math.max(0, 1 - sumSquares));
2351
+ return rotation;
2352
+ }
2353
+ function decodeSPZColors(colorStream, colors, sphericalHarmonicDcs) {
2354
+ for (let componentIndex = 0; componentIndex < colors.length; componentIndex++) {
2355
+ sphericalHarmonicDcs[componentIndex] = (colorStream[componentIndex] / 255 - 0.5) / SPZ_COLOR_SCALE;
2356
+ colors[componentIndex] = normalizeColorByte(sphericalHarmonicDcs[componentIndex]);
2357
+ }
2358
+ }
2359
+ function decodeSPZOpacities(alphaStream, opacities) {
2360
+ for (let splatIndex = 0; splatIndex < opacities.length; splatIndex++) {
2361
+ opacities[splatIndex] = alphaStream[splatIndex] / 255;
2362
+ }
2363
+ }
2364
+ function decodeSPZSphericalHarmonics(sphericalHarmonicsStream, sphericalHarmonics) {
2365
+ for (let componentIndex = 0; componentIndex < sphericalHarmonics.length; componentIndex++) {
2366
+ sphericalHarmonics[componentIndex] = (sphericalHarmonicsStream[componentIndex] - 128) / 128;
2367
+ }
2368
+ }
2369
+ function normalizeColorByte(sphericalHarmonicDc) {
2370
+ return Math.min(Math.max(Math.round((sphericalHarmonicDc * SPZ_COLOR_SCALE + 0.5) * 255), 0), 255);
2371
+ }
2372
+ function getSphericalHarmonicsComponentCount(shDegree) {
2373
+ switch (shDegree) {
2374
+ case 0:
2375
+ return 0;
2376
+ case 1:
2377
+ return 9;
2378
+ case 2:
2379
+ return 24;
2380
+ case 3:
2381
+ return 45;
2382
+ case 4:
2383
+ return 72;
2384
+ default:
2385
+ throw new Error(`SPZLoader: spherical harmonics degree ${shDegree} is not supported.`);
2386
+ }
2387
+ }
2388
+ function getSPZExtensionByteLength(header) {
2389
+ return header.flags & SPZ_EXTENSION_FLAG ? header.tocByteOffset - SPZ_HEADER_BYTE_LENGTH : 0;
2390
+ }
2391
+ function getSPZExtensionBytes(data, header) {
2392
+ const extensionByteLength = getSPZExtensionByteLength(header);
2393
+ return extensionByteLength ? new Uint8Array(data.slice(SPZ_HEADER_BYTE_LENGTH, header.tocByteOffset)) : void 0;
2394
+ }
2395
+ var SPZ_HEADER_BYTE_LENGTH, SPZ_MAGIC, SPZ_VERSION, SPZ_EXTENSION_FLAG, SPZ_COLOR_SCALE, SPZ_ROTATION_COMPONENT_SCALE, SPZ_ROTATION_COMPONENT_MASK;
2396
+ var init_parse_spz = __esm({
2397
+ "dist/lib/parse-spz.js"() {
2398
+ "use strict";
2399
+ init_src2();
2400
+ init_splats_arrow_table();
2401
+ init_splat_utils();
2402
+ SPZ_HEADER_BYTE_LENGTH = 32;
2403
+ SPZ_MAGIC = 1347635022;
2404
+ SPZ_VERSION = 4;
2405
+ SPZ_EXTENSION_FLAG = 2;
2406
+ SPZ_COLOR_SCALE = 0.15;
2407
+ SPZ_ROTATION_COMPONENT_SCALE = Math.SQRT1_2;
2408
+ SPZ_ROTATION_COMPONENT_MASK = (1 << 9) - 1;
2409
+ }
2410
+ });
2411
+
2412
+ // dist/lib/parse-splat.js
2413
+ function parseSPLAT(data) {
2414
+ return makeGaussianSplatsArrowTable(parseSPLATToGaussianSplats(data));
2415
+ }
2416
+ function parseSPLATToGaussianSplats(data) {
2417
+ if (data.byteLength % SPLAT_ROW_BYTE_LENGTH !== 0) {
2418
+ throw new Error(`SPLATLoader: byte length must be a multiple of ${SPLAT_ROW_BYTE_LENGTH}.`);
2419
+ }
2420
+ const splatCount = data.byteLength / SPLAT_ROW_BYTE_LENGTH;
2421
+ const dataView = new DataView(data);
2422
+ const positions = new Float32Array(splatCount * 3);
2423
+ const scales = new Float32Array(splatCount * 3);
2424
+ const rotations = new Float32Array(splatCount * 4);
2425
+ const colors = new Uint8Array(splatCount * 3);
2426
+ const opacities = new Float32Array(splatCount);
2427
+ for (let splatIndex = 0; splatIndex < splatCount; splatIndex++) {
2428
+ const byteOffset = splatIndex * SPLAT_ROW_BYTE_LENGTH;
2429
+ const positionOffset = splatIndex * 3;
2430
+ const rotationOffset = splatIndex * 4;
2431
+ positions[positionOffset + 0] = dataView.getFloat32(byteOffset + 0, true);
2432
+ positions[positionOffset + 1] = dataView.getFloat32(byteOffset + 4, true);
2433
+ positions[positionOffset + 2] = dataView.getFloat32(byteOffset + 8, true);
2434
+ scales[positionOffset + 0] = dataView.getFloat32(byteOffset + 12, true);
2435
+ scales[positionOffset + 1] = dataView.getFloat32(byteOffset + 16, true);
2436
+ scales[positionOffset + 2] = dataView.getFloat32(byteOffset + 20, true);
2437
+ colors[positionOffset + 0] = dataView.getUint8(byteOffset + 24);
2438
+ colors[positionOffset + 1] = dataView.getUint8(byteOffset + 25);
2439
+ colors[positionOffset + 2] = dataView.getUint8(byteOffset + 26);
2440
+ opacities[splatIndex] = convertAlphaByteToLinearOpacity(dataView.getUint8(byteOffset + 27));
2441
+ const [w, x, y, z2] = normalizeQuaternion(decodeQuaternionByte(dataView.getUint8(byteOffset + 28)), decodeQuaternionByte(dataView.getUint8(byteOffset + 29)), decodeQuaternionByte(dataView.getUint8(byteOffset + 30)), decodeQuaternionByte(dataView.getUint8(byteOffset + 31)));
2442
+ rotations[rotationOffset + 0] = w;
2443
+ rotations[rotationOffset + 1] = x;
2444
+ rotations[rotationOffset + 2] = y;
2445
+ rotations[rotationOffset + 3] = z2;
2446
+ }
2447
+ return {
2448
+ format: "splat",
2449
+ splatCount,
2450
+ positions,
2451
+ scales,
2452
+ rotations,
2453
+ colors,
2454
+ opacities,
2455
+ loaderData: {
2456
+ format: "splat",
2457
+ splatCount,
2458
+ rowByteLength: SPLAT_ROW_BYTE_LENGTH
2459
+ }
2460
+ };
2461
+ }
2462
+ var SPLAT_ROW_BYTE_LENGTH;
2463
+ var init_parse_splat = __esm({
2464
+ "dist/lib/parse-splat.js"() {
2465
+ "use strict";
2466
+ init_splats_arrow_table();
2467
+ init_splat_utils();
2468
+ SPLAT_ROW_BYTE_LENGTH = 32;
2469
+ }
2470
+ });
2471
+
2472
+ // dist/splat-loader.js
2473
+ var splat_loader_exports = {};
2474
+ __export(splat_loader_exports, {
2475
+ SPLATLoaderWithParser: () => SPLATLoaderWithParser
2476
+ });
2477
+ var _SPLATLoaderPreload, SPLATLoaderMetadataWithoutPreload, SPLATLoaderWithParser;
2478
+ var init_splat_loader = __esm({
2479
+ "dist/splat-loader.js"() {
2480
+ "use strict";
2481
+ init_parse_splat();
2482
+ init_splat_loader_types();
2483
+ ({ preload: _SPLATLoaderPreload, ...SPLATLoaderMetadataWithoutPreload } = SPLATLoader);
2484
+ SPLATLoaderWithParser = {
2485
+ ...SPLATLoaderMetadataWithoutPreload,
2486
+ parse: async (arrayBuffer) => parseSPLAT(arrayBuffer),
2487
+ parseSync: (arrayBuffer) => parseSPLAT(arrayBuffer)
2488
+ };
2489
+ }
2490
+ });
2491
+
2492
+ // dist/splat-loader-types.js
2493
+ async function preload() {
2494
+ const { SPLATLoaderWithParser: SPLATLoaderWithParser2 } = await Promise.resolve().then(() => (init_splat_loader(), splat_loader_exports));
2495
+ return SPLATLoaderWithParser2;
2496
+ }
2497
+ var VERSION2, SPLATLoader;
2498
+ var init_splat_loader_types = __esm({
2499
+ "dist/splat-loader-types.js"() {
2500
+ "use strict";
2501
+ init_splats_format();
2502
+ VERSION2 = true ? "5.0.0-alpha.10" : "latest";
2503
+ SPLATLoader = {
2504
+ dataType: null,
2505
+ batchType: null,
2506
+ ...SPLATFormat,
2507
+ version: VERSION2,
2508
+ options: {
2509
+ splats: {
2510
+ shape: "arrow-table"
2511
+ }
2512
+ },
2513
+ preload
2514
+ };
2515
+ }
2516
+ });
2517
+
2518
+ // dist/lib/parse-ksplat.js
2519
+ function parseKSPLAT(data) {
2520
+ return makeGaussianSplatsArrowTable(parseKSPLATToGaussianSplats(data));
2521
+ }
2522
+ function parseKSPLATToGaussianSplats(data) {
2523
+ if (data.byteLength < HEADER_BYTE_LENGTH) {
2524
+ throw new Error(`KSPLATLoader: file must contain a ${HEADER_BYTE_LENGTH}-byte header.`);
2525
+ }
2526
+ const header = parseKSPLATHeader(data);
2527
+ checkKSPLATVersion(header);
2528
+ const sections = parseKSPLATSections(data, header);
2529
+ const splatCount = getTotalSplatCount(header, sections);
2530
+ const sphericalHarmonicsComponentCount = Math.max(0, ...sections.slice(0, getActiveSectionCount(header)).map((section) => getSphericalHarmonicsComponentCount2(section.sphericalHarmonicsDegree)));
2531
+ const positions = new Float32Array(splatCount * 3);
2532
+ const scales = new Float32Array(splatCount * 3);
2533
+ const rotations = new Float32Array(splatCount * 4);
2534
+ const colors = new Uint8Array(splatCount * 3);
2535
+ const opacities = new Float32Array(splatCount);
2536
+ const sphericalHarmonics = sphericalHarmonicsComponentCount ? new Float32Array(splatCount * sphericalHarmonicsComponentCount) : void 0;
2537
+ let outputSplatIndex = 0;
2538
+ for (const section of sections.slice(0, getActiveSectionCount(header))) {
2539
+ validateSectionBounds(data, section);
2540
+ for (let localSplatIndex = 0; localSplatIndex < section.splatCount && outputSplatIndex < splatCount; localSplatIndex++) {
2541
+ decodeKSPLATSplat(data, header, section, localSplatIndex, outputSplatIndex, positions, scales, rotations, colors, opacities, sphericalHarmonics, sphericalHarmonicsComponentCount);
2542
+ outputSplatIndex++;
2543
+ }
2544
+ }
2545
+ return {
2546
+ format: "ksplat",
2547
+ splatCount,
2548
+ positions,
2549
+ scales,
2550
+ rotations,
2551
+ colors,
2552
+ opacities,
2553
+ sphericalHarmonics,
2554
+ sphericalHarmonicsComponentCount,
2555
+ loaderData: {
2556
+ format: "ksplat",
2557
+ ...header,
2558
+ sections: sections.slice(0, getActiveSectionCount(header)).map((section) => ({
2559
+ splatCount: section.splatCount,
2560
+ maxSplatCount: section.maxSplatCount,
2561
+ sphericalHarmonicsDegree: section.sphericalHarmonicsDegree
2562
+ }))
2563
+ }
2564
+ };
2565
+ }
2566
+ function decodeKSPLATSplat(data, header, section, localSplatIndex, outputSplatIndex, positions, scales, rotations, colors, opacities, sphericalHarmonics, sphericalHarmonicsComponentCount) {
2567
+ const layout = COMPRESSION_LAYOUTS[header.compressionLevel];
2568
+ const splatBase = section.dataBase + section.bytesPerSplat * localSplatIndex;
2569
+ const positionOffset = outputSplatIndex * 3;
2570
+ const rotationOffset = outputSplatIndex * 4;
2571
+ const bucketCenter = getBucketCenter(data, section, localSplatIndex);
2572
+ positions[positionOffset + 0] = decodeKSPLATCenterComponent(data, splatBase, 0, header, section, bucketCenter[0]);
2573
+ positions[positionOffset + 1] = decodeKSPLATCenterComponent(data, splatBase, 1, header, section, bucketCenter[1]);
2574
+ positions[positionOffset + 2] = decodeKSPLATCenterComponent(data, splatBase, 2, header, section, bucketCenter[2]);
2575
+ scales[positionOffset + 0] = readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 0, header.compressionLevel);
2576
+ scales[positionOffset + 1] = readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 1, header.compressionLevel);
2577
+ scales[positionOffset + 2] = readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 2, header.compressionLevel);
2578
+ const [w, x, y, z2] = normalizeQuaternion(readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 3, header.compressionLevel), readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 4, header.compressionLevel), readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 5, header.compressionLevel), readCompressedFloat(data, splatBase + layout.scaleOffsetBytes, 6, header.compressionLevel));
2579
+ rotations[rotationOffset + 0] = w;
2580
+ rotations[rotationOffset + 1] = x;
2581
+ rotations[rotationOffset + 2] = y;
2582
+ rotations[rotationOffset + 3] = z2;
2583
+ const colorBase = splatBase + layout.colorOffsetBytes;
2584
+ const colorView = new Uint8Array(data, colorBase, 4);
2585
+ colors[positionOffset + 0] = colorView[0];
2586
+ colors[positionOffset + 1] = colorView[1];
2587
+ colors[positionOffset + 2] = colorView[2];
2588
+ opacities[outputSplatIndex] = convertAlphaByteToLinearOpacity(colorView[3]);
2589
+ if (sphericalHarmonics && sphericalHarmonicsComponentCount) {
2590
+ decodeSphericalHarmonics(data, splatBase + layout.sphericalHarmonicsOffsetBytes, header, section, outputSplatIndex, sphericalHarmonics, sphericalHarmonicsComponentCount);
2591
+ }
2592
+ }
2593
+ function parseKSPLATHeader(data) {
2594
+ const dataView = new DataView(data, 0, HEADER_BYTE_LENGTH);
2595
+ const compressionLevel = dataView.getUint16(20, true);
2596
+ if (compressionLevel !== 0 && compressionLevel !== 1 && compressionLevel !== 2) {
2597
+ throw new Error(`KSPLATLoader: unsupported compression level ${compressionLevel}.`);
2598
+ }
2599
+ return {
2600
+ versionMajor: dataView.getUint8(0),
2601
+ versionMinor: dataView.getUint8(1),
2602
+ maxSectionCount: dataView.getUint32(4, true),
2603
+ sectionCount: dataView.getUint32(8, true),
2604
+ maxSplatCount: dataView.getUint32(12, true),
2605
+ splatCount: dataView.getUint32(16, true),
2606
+ compressionLevel,
2607
+ minSphericalHarmonicsCoeff: dataView.getFloat32(36, true) || -DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE,
2608
+ maxSphericalHarmonicsCoeff: dataView.getFloat32(40, true) || DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE
2609
+ };
2610
+ }
2611
+ function checkKSPLATVersion(header) {
2612
+ if (header.versionMajor === CURRENT_MAJOR_VERSION ? header.versionMinor >= CURRENT_MINOR_VERSION : header.versionMajor > CURRENT_MAJOR_VERSION) {
2613
+ return;
753
2614
  }
2615
+ throw new Error(`KSPLATLoader: version ${header.versionMajor}.${header.versionMinor} is not supported.`);
754
2616
  }
755
- function decodeSPZScales(scaleStream, scales) {
756
- for (let componentIndex = 0; componentIndex < scales.length; componentIndex++) {
757
- scales[componentIndex] = Math.exp(scaleStream[componentIndex] / 16 - 10);
2617
+ function parseKSPLATSections(data, header) {
2618
+ if (data.byteLength < HEADER_BYTE_LENGTH + header.maxSectionCount * SECTION_HEADER_BYTE_LENGTH) {
2619
+ throw new Error("KSPLATLoader: file does not contain all section headers.");
2620
+ }
2621
+ const sections = [];
2622
+ let sectionBase = HEADER_BYTE_LENGTH + header.maxSectionCount * SECTION_HEADER_BYTE_LENGTH;
2623
+ let splatCountOffset = 0;
2624
+ for (let sectionIndex = 0; sectionIndex < header.maxSectionCount; sectionIndex++) {
2625
+ const sectionHeaderBase = HEADER_BYTE_LENGTH + sectionIndex * SECTION_HEADER_BYTE_LENGTH;
2626
+ const dataView = new DataView(data, sectionHeaderBase, SECTION_HEADER_BYTE_LENGTH);
2627
+ const splatCount = dataView.getUint32(0, true);
2628
+ const maxSplatCount = dataView.getUint32(4, true);
2629
+ const bucketSize = dataView.getUint32(8, true);
2630
+ const bucketCount = dataView.getUint32(12, true);
2631
+ const bucketBlockSize = dataView.getFloat32(16, true);
2632
+ const bucketStorageSizeBytes = dataView.getUint16(20, true);
2633
+ const compressionScaleRange = dataView.getUint32(24, true) || COMPRESSION_LAYOUTS[header.compressionLevel].scaleRange;
2634
+ const fullBucketCount = dataView.getUint32(32, true);
2635
+ const partiallyFilledBucketCount = dataView.getUint32(36, true);
2636
+ const sphericalHarmonicsDegree = dataView.getUint16(40, true);
2637
+ const bytesPerSplat = getBytesPerSplat(header.compressionLevel, sphericalHarmonicsDegree);
2638
+ const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;
2639
+ const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;
2640
+ const storageSizeBytes = bytesPerSplat * maxSplatCount + bucketsStorageSizeBytes;
2641
+ sections.push({
2642
+ bytesPerSplat,
2643
+ splatCountOffset,
2644
+ splatCount: splatCount || maxSplatCount,
2645
+ maxSplatCount,
2646
+ bucketSize,
2647
+ bucketCount,
2648
+ bucketStorageSizeBytes,
2649
+ bucketsStorageSizeBytes,
2650
+ compressionScaleRange,
2651
+ compressionScaleFactor: bucketBlockSize / 2 / compressionScaleRange,
2652
+ base: sectionBase,
2653
+ bucketsBase: sectionBase + bucketsMetaDataSizeBytes,
2654
+ dataBase: sectionBase + bucketsStorageSizeBytes,
2655
+ fullBucketCount,
2656
+ partiallyFilledBucketCount,
2657
+ sphericalHarmonicsDegree
2658
+ });
2659
+ sectionBase += storageSizeBytes;
2660
+ splatCountOffset += maxSplatCount;
758
2661
  }
2662
+ return sections;
759
2663
  }
760
- function decodeSPZRotations(rotationStream, rotations) {
761
- for (let splatIndex = 0; splatIndex < rotations.length / 4; splatIndex++) {
762
- const byteOffset = splatIndex * 4;
763
- const component = rotationStream[byteOffset] | rotationStream[byteOffset + 1] << 8 | rotationStream[byteOffset + 2] << 16 | rotationStream[byteOffset + 3] << 24;
764
- const xyzw = decodeSPZQuaternion(component >>> 0);
765
- const [w, x, y, z2] = normalizeQuaternion(xyzw[3], xyzw[0], xyzw[1], xyzw[2]);
766
- const rotationOffset = splatIndex * 4;
767
- rotations[rotationOffset + 0] = w;
768
- rotations[rotationOffset + 1] = x;
769
- rotations[rotationOffset + 2] = y;
770
- rotations[rotationOffset + 3] = z2;
2664
+ function decodeKSPLATCenterComponent(data, splatBase, component, header, section, bucketCenter) {
2665
+ const value = readCompressedCenterValue(data, splatBase, component, header.compressionLevel);
2666
+ return header.compressionLevel >= 1 ? (value - section.compressionScaleRange) * section.compressionScaleFactor + bucketCenter : value;
2667
+ }
2668
+ function readCompressedCenterValue(data, byteOffset, component, compressionLevel) {
2669
+ const dataView = new DataView(data);
2670
+ return compressionLevel === 0 ? dataView.getFloat32(byteOffset + component * 4, true) : dataView.getUint16(byteOffset + component * 2, true);
2671
+ }
2672
+ function getBucketCenter(data, section, localSplatIndex) {
2673
+ if (!section.bucketCount) {
2674
+ return [0, 0, 0];
771
2675
  }
2676
+ const bucketIndex = getBucketIndex(data, section, localSplatIndex);
2677
+ const bucketBase = section.bucketsBase + bucketIndex * section.bucketStorageSizeBytes;
2678
+ const dataView = new DataView(data, bucketBase, 12);
2679
+ return [dataView.getFloat32(0, true), dataView.getFloat32(4, true), dataView.getFloat32(8, true)];
772
2680
  }
773
- function decodeSPZQuaternion(component) {
774
- const rotation = [0, 0, 0, 0];
775
- const largestComponent = component >>> 30;
776
- let remainingBits = component;
777
- let sumSquares = 0;
778
- for (let componentIndex = 3; componentIndex >= 0; componentIndex--) {
779
- if (componentIndex !== largestComponent) {
780
- const magnitude = remainingBits & SPZ_ROTATION_COMPONENT_MASK;
781
- const isNegative = remainingBits >>> 9 & 1;
782
- remainingBits >>>= 10;
783
- let value = SPZ_ROTATION_COMPONENT_SCALE * magnitude / SPZ_ROTATION_COMPONENT_MASK;
784
- if (isNegative) {
785
- value = -value;
786
- }
787
- rotation[componentIndex] = value;
788
- sumSquares += value * value;
2681
+ function getBucketIndex(data, section, localSplatIndex) {
2682
+ const maxSplatIndexInFullBuckets = section.fullBucketCount * section.bucketSize;
2683
+ if (localSplatIndex < maxSplatIndexInFullBuckets) {
2684
+ return Math.floor(localSplatIndex / section.bucketSize);
2685
+ }
2686
+ let bucketSplatIndex = maxSplatIndexInFullBuckets;
2687
+ let bucketIndex = section.fullBucketCount;
2688
+ for (let partiallyFilledBucketIndex = 0; partiallyFilledBucketIndex < section.partiallyFilledBucketCount; partiallyFilledBucketIndex++) {
2689
+ const bucketLength = new DataView(data, section.base + partiallyFilledBucketIndex * 4, 4).getUint32(0, true);
2690
+ if (localSplatIndex < bucketSplatIndex + bucketLength) {
2691
+ return bucketIndex;
789
2692
  }
2693
+ bucketSplatIndex += bucketLength;
2694
+ bucketIndex++;
790
2695
  }
791
- rotation[largestComponent] = Math.sqrt(Math.max(0, 1 - sumSquares));
792
- return rotation;
2696
+ return Math.max(bucketIndex - 1, 0);
793
2697
  }
794
- function decodeSPZColors(colorStream, colors, sphericalHarmonicDcs) {
795
- for (let componentIndex = 0; componentIndex < colors.length; componentIndex++) {
796
- sphericalHarmonicDcs[componentIndex] = (colorStream[componentIndex] / 255 - 0.5) / SPZ_COLOR_SCALE;
797
- colors[componentIndex] = normalizeColorByte(sphericalHarmonicDcs[componentIndex]);
2698
+ function decodeSphericalHarmonics(data, byteOffset, header, section, outputSplatIndex, output, outputComponentCount) {
2699
+ const componentCount = getSphericalHarmonicsComponentCount2(section.sphericalHarmonicsDegree);
2700
+ const componentBase = outputSplatIndex * outputComponentCount;
2701
+ for (let component = 0; component < componentCount; component++) {
2702
+ output[componentBase + component] = readCompressedFloat(data, byteOffset, component, header.compressionLevel, true, header.minSphericalHarmonicsCoeff, header.maxSphericalHarmonicsCoeff);
798
2703
  }
799
2704
  }
800
- function decodeSPZOpacities(alphaStream, opacities) {
801
- for (let splatIndex = 0; splatIndex < opacities.length; splatIndex++) {
802
- opacities[splatIndex] = alphaStream[splatIndex] / 255;
2705
+ function readCompressedFloat(data, byteOffset, component, compressionLevel, sphericalHarmonic = false, sphericalHarmonicRangeMin = 0, sphericalHarmonicRangeMax = 0) {
2706
+ const dataView = new DataView(data);
2707
+ if (compressionLevel === 0) {
2708
+ return dataView.getFloat32(byteOffset + component * 4, true);
803
2709
  }
804
- }
805
- function decodeSPZSphericalHarmonics(sphericalHarmonicsStream, sphericalHarmonics) {
806
- for (let componentIndex = 0; componentIndex < sphericalHarmonics.length; componentIndex++) {
807
- sphericalHarmonics[componentIndex] = (sphericalHarmonicsStream[componentIndex] - 128) / 128;
2710
+ if (compressionLevel === 1 || !sphericalHarmonic) {
2711
+ return decodeFloat16(dataView.getUint16(byteOffset + component * 2, true));
808
2712
  }
2713
+ const value = dataView.getUint8(byteOffset + component);
2714
+ return value / 255 * (sphericalHarmonicRangeMax - sphericalHarmonicRangeMin) + sphericalHarmonicRangeMin;
809
2715
  }
810
- function normalizeColorByte(sphericalHarmonicDc) {
811
- return Math.min(Math.max(Math.round((sphericalHarmonicDc * SPZ_COLOR_SCALE + 0.5) * 255), 0), 255);
2716
+ function getBytesPerSplat(compressionLevel, sphericalHarmonicsDegree) {
2717
+ const layout = COMPRESSION_LAYOUTS[compressionLevel];
2718
+ return layout.bytesPerCenter + layout.bytesPerScale + layout.bytesPerRotation + layout.bytesPerColor + layout.bytesPerSphericalHarmonicsComponent * getSphericalHarmonicsComponentCount2(sphericalHarmonicsDegree);
812
2719
  }
813
- function getSphericalHarmonicsComponentCount2(shDegree) {
814
- switch (shDegree) {
2720
+ function getSphericalHarmonicsComponentCount2(sphericalHarmonicsDegree) {
2721
+ switch (sphericalHarmonicsDegree) {
815
2722
  case 0:
816
2723
  return 0;
817
2724
  case 1:
@@ -820,99 +2727,224 @@ function getSphericalHarmonicsComponentCount2(shDegree) {
820
2727
  return 24;
821
2728
  case 3:
822
2729
  return 45;
823
- case 4:
824
- return 72;
825
2730
  default:
826
- throw new Error(`SPZLoader: spherical harmonics degree ${shDegree} is not supported.`);
2731
+ throw new Error(`KSPLATLoader: unsupported spherical harmonics degree ${sphericalHarmonicsDegree}.`);
827
2732
  }
828
2733
  }
829
- function getSPZExtensionByteLength(header) {
830
- return header.flags & SPZ_EXTENSION_FLAG ? header.tocByteOffset - SPZ_HEADER_BYTE_LENGTH : 0;
2734
+ function getActiveSectionCount(header) {
2735
+ return header.sectionCount || header.maxSectionCount;
831
2736
  }
832
- function getSPZExtensionBytes(data, header) {
833
- const extensionByteLength = getSPZExtensionByteLength(header);
834
- return extensionByteLength ? new Uint8Array(data.slice(SPZ_HEADER_BYTE_LENGTH, header.tocByteOffset)) : void 0;
2737
+ function getTotalSplatCount(header, sections) {
2738
+ const sectionSplatCount = sections.slice(0, getActiveSectionCount(header)).reduce((splatCount, section) => splatCount + section.splatCount, 0);
2739
+ return header.splatCount ? Math.min(header.splatCount, sectionSplatCount || header.splatCount) : sectionSplatCount;
2740
+ }
2741
+ function validateSectionBounds(data, section) {
2742
+ const requiredByteLength = section.dataBase + section.bytesPerSplat * section.splatCount;
2743
+ if (requiredByteLength > data.byteLength) {
2744
+ throw new Error("KSPLATLoader: section data extends beyond the file length.");
2745
+ }
835
2746
  }
2747
+ var CURRENT_MAJOR_VERSION, CURRENT_MINOR_VERSION, HEADER_BYTE_LENGTH, SECTION_HEADER_BYTE_LENGTH, DEFAULT_SH_8BIT_COMPRESSION_RANGE, DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE, COMPRESSION_LAYOUTS;
2748
+ var init_parse_ksplat = __esm({
2749
+ "dist/lib/parse-ksplat.js"() {
2750
+ "use strict";
2751
+ init_splats_arrow_table();
2752
+ init_splat_utils();
2753
+ CURRENT_MAJOR_VERSION = 0;
2754
+ CURRENT_MINOR_VERSION = 1;
2755
+ HEADER_BYTE_LENGTH = 4096;
2756
+ SECTION_HEADER_BYTE_LENGTH = 1024;
2757
+ DEFAULT_SH_8BIT_COMPRESSION_RANGE = 3;
2758
+ DEFAULT_SH_8BIT_COMPRESSION_HALF_RANGE = DEFAULT_SH_8BIT_COMPRESSION_RANGE / 2;
2759
+ COMPRESSION_LAYOUTS = {
2760
+ 0: {
2761
+ bytesPerCenter: 12,
2762
+ bytesPerScale: 12,
2763
+ bytesPerRotation: 16,
2764
+ bytesPerColor: 4,
2765
+ scaleOffsetBytes: 12,
2766
+ colorOffsetBytes: 40,
2767
+ sphericalHarmonicsOffsetBytes: 44,
2768
+ scaleRange: 1,
2769
+ bytesPerSphericalHarmonicsComponent: 4
2770
+ },
2771
+ 1: {
2772
+ bytesPerCenter: 6,
2773
+ bytesPerScale: 6,
2774
+ bytesPerRotation: 8,
2775
+ bytesPerColor: 4,
2776
+ scaleOffsetBytes: 6,
2777
+ colorOffsetBytes: 20,
2778
+ sphericalHarmonicsOffsetBytes: 24,
2779
+ scaleRange: 32767,
2780
+ bytesPerSphericalHarmonicsComponent: 2
2781
+ },
2782
+ 2: {
2783
+ bytesPerCenter: 6,
2784
+ bytesPerScale: 6,
2785
+ bytesPerRotation: 8,
2786
+ bytesPerColor: 4,
2787
+ scaleOffsetBytes: 6,
2788
+ colorOffsetBytes: 20,
2789
+ sphericalHarmonicsOffsetBytes: 24,
2790
+ scaleRange: 32767,
2791
+ bytesPerSphericalHarmonicsComponent: 1
2792
+ }
2793
+ };
2794
+ }
2795
+ });
836
2796
 
837
- // dist/spz-loader-types.js
838
- var VERSION3 = true ? "4.5.3" : "latest";
839
- var SPZLoader = {
840
- dataType: null,
841
- batchType: null,
842
- ...SPZFormat,
843
- version: VERSION3,
844
- options: {
845
- splats: {
846
- shape: "arrow-table"
847
- }
2797
+ // dist/ksplat-loader.js
2798
+ var ksplat_loader_exports = {};
2799
+ __export(ksplat_loader_exports, {
2800
+ KSPLATLoaderWithParser: () => KSPLATLoaderWithParser
2801
+ });
2802
+ var _KSPLATLoaderPreload, KSPLATLoaderMetadataWithoutPreload, KSPLATLoaderWithParser;
2803
+ var init_ksplat_loader = __esm({
2804
+ "dist/ksplat-loader.js"() {
2805
+ "use strict";
2806
+ init_parse_ksplat();
2807
+ init_ksplat_loader_types();
2808
+ ({ preload: _KSPLATLoaderPreload, ...KSPLATLoaderMetadataWithoutPreload } = KSPLATLoader);
2809
+ KSPLATLoaderWithParser = {
2810
+ ...KSPLATLoaderMetadataWithoutPreload,
2811
+ parse: async (arrayBuffer) => parseKSPLAT(arrayBuffer),
2812
+ parseSync: (arrayBuffer) => parseKSPLAT(arrayBuffer)
2813
+ };
848
2814
  }
849
- };
2815
+ });
2816
+
2817
+ // dist/ksplat-loader-types.js
2818
+ async function preload2() {
2819
+ const { KSPLATLoaderWithParser: KSPLATLoaderWithParser2 } = await Promise.resolve().then(() => (init_ksplat_loader(), ksplat_loader_exports));
2820
+ return KSPLATLoaderWithParser2;
2821
+ }
2822
+ var VERSION3, KSPLATLoader;
2823
+ var init_ksplat_loader_types = __esm({
2824
+ "dist/ksplat-loader-types.js"() {
2825
+ "use strict";
2826
+ init_splats_format();
2827
+ VERSION3 = true ? "5.0.0-alpha.10" : "latest";
2828
+ KSPLATLoader = {
2829
+ dataType: null,
2830
+ batchType: null,
2831
+ ...KSPLATFormat,
2832
+ version: VERSION3,
2833
+ options: {
2834
+ splats: {
2835
+ shape: "arrow-table"
2836
+ }
2837
+ },
2838
+ preload: preload2
2839
+ };
2840
+ }
2841
+ });
850
2842
 
851
2843
  // dist/spz-loader.js
852
- var SPZLoaderWithParser = {
853
- ...SPZLoader,
854
- parse: async (arrayBuffer, options) => parseSPZ(arrayBuffer, options)
855
- };
2844
+ var spz_loader_exports = {};
2845
+ __export(spz_loader_exports, {
2846
+ SPZLoaderWithParser: () => SPZLoaderWithParser
2847
+ });
2848
+ var _SPZLoaderPreload, SPZLoaderMetadataWithoutPreload, SPZLoaderWithParser;
2849
+ var init_spz_loader = __esm({
2850
+ "dist/spz-loader.js"() {
2851
+ "use strict";
2852
+ init_parse_spz();
2853
+ init_spz_loader_types();
2854
+ ({ preload: _SPZLoaderPreload, ...SPZLoaderMetadataWithoutPreload } = SPZLoader);
2855
+ SPZLoaderWithParser = {
2856
+ ...SPZLoaderMetadataWithoutPreload,
2857
+ parse: async (arrayBuffer, options) => parseSPZ(arrayBuffer, options)
2858
+ };
2859
+ }
2860
+ });
2861
+
2862
+ // dist/spz-loader-types.js
2863
+ async function preload3() {
2864
+ const { SPZLoaderWithParser: SPZLoaderWithParser2 } = await Promise.resolve().then(() => (init_spz_loader(), spz_loader_exports));
2865
+ return SPZLoaderWithParser2;
2866
+ }
2867
+ var VERSION4, SPZLoader;
2868
+ var init_spz_loader_types = __esm({
2869
+ "dist/spz-loader-types.js"() {
2870
+ "use strict";
2871
+ init_splats_format();
2872
+ VERSION4 = true ? "5.0.0-alpha.10" : "latest";
2873
+ SPZLoader = {
2874
+ dataType: null,
2875
+ batchType: null,
2876
+ ...SPZFormat,
2877
+ version: VERSION4,
2878
+ options: {
2879
+ splats: {
2880
+ shape: "arrow-table"
2881
+ }
2882
+ },
2883
+ preload: preload3
2884
+ };
2885
+ }
2886
+ });
856
2887
 
857
2888
  // dist/rad-zod-schema.js
858
- var import_zod = require("zod");
859
- var nonNegativeSafeIntegerSchema = import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
860
- var RADSplatEncodingSchema = import_zod.z.object({
861
- rgbMin: import_zod.z.number().finite().optional(),
862
- rgbMax: import_zod.z.number().finite().optional(),
863
- lnScaleMin: import_zod.z.number().finite().optional(),
864
- lnScaleMax: import_zod.z.number().finite().optional(),
865
- sh1Max: import_zod.z.number().finite().optional(),
866
- sh2Max: import_zod.z.number().finite().optional(),
867
- sh3Max: import_zod.z.number().finite().optional(),
868
- lodOpacity: import_zod.z.boolean().optional()
869
- }).passthrough();
870
- var RADChunkRangeSchema = import_zod.z.object({
871
- offset: nonNegativeSafeIntegerSchema,
872
- bytes: nonNegativeSafeIntegerSchema,
873
- base: nonNegativeSafeIntegerSchema.optional(),
874
- count: nonNegativeSafeIntegerSchema.optional(),
875
- filename: import_zod.z.string().optional()
876
- }).passthrough();
877
- var RADMetadataJSONSchema = import_zod.z.object({
878
- version: import_zod.z.literal(1),
879
- type: import_zod.z.literal("gsplat"),
880
- count: nonNegativeSafeIntegerSchema,
881
- maxSh: nonNegativeSafeIntegerSchema.optional(),
882
- lodTree: import_zod.z.boolean().optional(),
883
- chunkSize: nonNegativeSafeIntegerSchema.optional(),
884
- allChunkBytes: nonNegativeSafeIntegerSchema.optional(),
885
- chunks: import_zod.z.array(RADChunkRangeSchema),
886
- splatEncoding: RADSplatEncodingSchema.optional(),
887
- shCodeCount: nonNegativeSafeIntegerSchema.optional(),
888
- comment: import_zod.z.string().optional()
889
- }).passthrough();
890
- var RADChunkPropertySchema = import_zod.z.object({
891
- offset: nonNegativeSafeIntegerSchema,
892
- bytes: nonNegativeSafeIntegerSchema,
893
- property: import_zod.z.string(),
894
- encoding: import_zod.z.string(),
895
- compression: import_zod.z.string().optional(),
896
- min: import_zod.z.number().finite().optional(),
897
- max: import_zod.z.number().finite().optional()
898
- }).passthrough();
899
- var RADChunkMetadataJSONSchema = import_zod.z.object({
900
- version: import_zod.z.literal(1),
901
- base: nonNegativeSafeIntegerSchema,
902
- count: nonNegativeSafeIntegerSchema,
903
- payloadBytes: nonNegativeSafeIntegerSchema,
904
- maxSh: nonNegativeSafeIntegerSchema.optional(),
905
- lodTree: import_zod.z.boolean().optional(),
906
- splatEncoding: RADSplatEncodingSchema.optional(),
907
- properties: import_zod.z.array(RADChunkPropertySchema)
908
- }).passthrough();
2889
+ var import_zod, nonNegativeSafeIntegerSchema, RADSplatEncodingSchema, RADChunkRangeSchema, RADMetadataJSONSchema, RADChunkPropertySchema, RADChunkMetadataJSONSchema;
2890
+ var init_rad_zod_schema = __esm({
2891
+ "dist/rad-zod-schema.js"() {
2892
+ "use strict";
2893
+ import_zod = require("zod");
2894
+ nonNegativeSafeIntegerSchema = import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
2895
+ RADSplatEncodingSchema = import_zod.z.object({
2896
+ rgbMin: import_zod.z.number().finite().optional(),
2897
+ rgbMax: import_zod.z.number().finite().optional(),
2898
+ lnScaleMin: import_zod.z.number().finite().optional(),
2899
+ lnScaleMax: import_zod.z.number().finite().optional(),
2900
+ sh1Max: import_zod.z.number().finite().optional(),
2901
+ sh2Max: import_zod.z.number().finite().optional(),
2902
+ sh3Max: import_zod.z.number().finite().optional(),
2903
+ lodOpacity: import_zod.z.boolean().optional()
2904
+ }).passthrough();
2905
+ RADChunkRangeSchema = import_zod.z.object({
2906
+ offset: nonNegativeSafeIntegerSchema,
2907
+ bytes: nonNegativeSafeIntegerSchema,
2908
+ base: nonNegativeSafeIntegerSchema.optional(),
2909
+ count: nonNegativeSafeIntegerSchema.optional(),
2910
+ filename: import_zod.z.string().optional()
2911
+ }).passthrough();
2912
+ RADMetadataJSONSchema = import_zod.z.object({
2913
+ version: import_zod.z.literal(1),
2914
+ type: import_zod.z.literal("gsplat"),
2915
+ count: nonNegativeSafeIntegerSchema,
2916
+ maxSh: nonNegativeSafeIntegerSchema.optional(),
2917
+ lodTree: import_zod.z.boolean().optional(),
2918
+ chunkSize: nonNegativeSafeIntegerSchema.optional(),
2919
+ allChunkBytes: nonNegativeSafeIntegerSchema.optional(),
2920
+ chunks: import_zod.z.array(RADChunkRangeSchema),
2921
+ splatEncoding: RADSplatEncodingSchema.optional(),
2922
+ shCodeCount: nonNegativeSafeIntegerSchema.optional(),
2923
+ comment: import_zod.z.string().optional()
2924
+ }).passthrough();
2925
+ RADChunkPropertySchema = import_zod.z.object({
2926
+ offset: nonNegativeSafeIntegerSchema,
2927
+ bytes: nonNegativeSafeIntegerSchema,
2928
+ property: import_zod.z.string(),
2929
+ encoding: import_zod.z.string(),
2930
+ compression: import_zod.z.string().optional(),
2931
+ min: import_zod.z.number().finite().optional(),
2932
+ max: import_zod.z.number().finite().optional()
2933
+ }).passthrough();
2934
+ RADChunkMetadataJSONSchema = import_zod.z.object({
2935
+ version: import_zod.z.literal(1),
2936
+ base: nonNegativeSafeIntegerSchema,
2937
+ count: nonNegativeSafeIntegerSchema,
2938
+ payloadBytes: nonNegativeSafeIntegerSchema,
2939
+ maxSh: nonNegativeSafeIntegerSchema.optional(),
2940
+ lodTree: import_zod.z.boolean().optional(),
2941
+ splatEncoding: RADSplatEncodingSchema.optional(),
2942
+ properties: import_zod.z.array(RADChunkPropertySchema)
2943
+ }).passthrough();
2944
+ }
2945
+ });
909
2946
 
910
2947
  // dist/lib/parse-rad.js
911
- var RAD_MAGIC = 809779538;
912
- var RAD_CHUNK_MAGIC = 1128546642;
913
- var RAD_HEADER_BYTE_LENGTH = 8;
914
- var RAD_CHUNK_PAYLOAD_LENGTH_BYTE_LENGTH = 8;
915
- var TEXT_DECODER = new TextDecoder();
916
2948
  function parseRADHeader(data) {
917
2949
  const metadata = tryParseRADHeader(data);
918
2950
  if (!metadata) {
@@ -998,21 +3030,89 @@ function readSafeUint642(dataView, byteOffset, fieldName) {
998
3030
  function getUint8Array(data) {
999
3031
  return data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
1000
3032
  }
3033
+ var RAD_MAGIC, RAD_CHUNK_MAGIC, RAD_HEADER_BYTE_LENGTH, RAD_CHUNK_PAYLOAD_LENGTH_BYTE_LENGTH, TEXT_DECODER;
3034
+ var init_parse_rad = __esm({
3035
+ "dist/lib/parse-rad.js"() {
3036
+ "use strict";
3037
+ init_rad_zod_schema();
3038
+ RAD_MAGIC = 809779538;
3039
+ RAD_CHUNK_MAGIC = 1128546642;
3040
+ RAD_HEADER_BYTE_LENGTH = 8;
3041
+ RAD_CHUNK_PAYLOAD_LENGTH_BYTE_LENGTH = 8;
3042
+ TEXT_DECODER = new TextDecoder();
3043
+ }
3044
+ });
1001
3045
 
1002
- // dist/rad-loader-types.js
1003
- var VERSION4 = true ? "4.5.3" : "latest";
1004
- var RADLoader = {
1005
- dataType: null,
1006
- batchType: null,
1007
- ...RADFormat,
1008
- version: VERSION4,
1009
- options: {}
1010
- };
3046
+ // ../compression/src/deflate-decompressor-fflate.ts
3047
+ var DeflateFflateDecompressor;
3048
+ var init_deflate_decompressor_fflate = __esm({
3049
+ "../compression/src/deflate-decompressor-fflate.ts"() {
3050
+ "use strict";
3051
+ init_fflate();
3052
+ init_compression();
3053
+ init_fflate_stream();
3054
+ DeflateFflateDecompressor = class extends Decompressor {
3055
+ name = "deflate";
3056
+ extensions = [];
3057
+ contentEncodings = ["deflate"];
3058
+ isSupported = true;
3059
+ options;
3060
+ constructor(options = {}) {
3061
+ super(options);
3062
+ this.options = options;
3063
+ }
3064
+ /** Decompresses one zlib-wrapped DEFLATE payload synchronously. */
3065
+ decompressSync(input) {
3066
+ const bytes = new Uint8Array(input);
3067
+ const output = this.options.raw ? inflateSync(bytes) : unzlibSync(bytes);
3068
+ return output.slice().buffer;
3069
+ }
3070
+ /** Decompresses DEFLATE batches incrementally. */
3071
+ async *decompressBatches(inputBatches) {
3072
+ const processor = this.options.raw ? new Inflate() : new Unzlib();
3073
+ yield* transformFflateBatches(processor, inputBatches);
3074
+ }
3075
+ };
3076
+ }
3077
+ });
3078
+
3079
+ // ../compression/src/deflate-decompressor.ts
3080
+ var DeflateDecompressor2;
3081
+ var init_deflate_decompressor = __esm({
3082
+ "../compression/src/deflate-decompressor.ts"() {
3083
+ "use strict";
3084
+ init_deflate_decompressor_fflate();
3085
+ init_decompression_stream();
3086
+ DeflateDecompressor2 = class extends DeflateFflateDecompressor {
3087
+ constructor(options = {}) {
3088
+ super(options);
3089
+ }
3090
+ /** Decompresses with the built-in stream when available, then falls back to fflate. */
3091
+ async decompress(input) {
3092
+ if (this.options.useNative !== false) {
3093
+ const format = this.options.raw ? "deflate-raw" : "deflate";
3094
+ const output = await decompressWithNativeDecompressionStream(input, format);
3095
+ if (output) return output;
3096
+ }
3097
+ return this.decompressSync(input);
3098
+ }
3099
+ /** Decompresses batches with a built-in or fflate stream. */
3100
+ async *decompressBatches(inputBatches) {
3101
+ if (this.options.useNative !== false) {
3102
+ const format = this.options.raw ? "deflate-raw" : "deflate";
3103
+ const output = decompressBatchesWithNativeDecompressionStream(inputBatches, format);
3104
+ if (output) {
3105
+ yield* output;
3106
+ return;
3107
+ }
3108
+ }
3109
+ yield* super.decompressBatches(inputBatches);
3110
+ }
3111
+ };
3112
+ }
3113
+ });
1011
3114
 
1012
3115
  // dist/lib/parse-rad-chunk.js
1013
- var import_compression2 = require("@loaders.gl/compression");
1014
- var RAD_PROPERTY_DEFLATE = new import_compression2.DeflateCompression();
1015
- var RAD_PROPERTY_RAW_DEFLATE = new import_compression2.DeflateCompression({ raw: true });
1016
3116
  function parseRADChunk(data, options) {
1017
3117
  return makeGaussianSplatsArrowTable(parseRADChunkToGaussianSplats(data, options));
1018
3118
  }
@@ -1220,7 +3320,7 @@ function getRADPropertyBytes(bytes, metadata, property) {
1220
3320
  return decompressRADProperty(propertyBytes, property.property);
1221
3321
  }
1222
3322
  function decompressRADProperty(bytes, propertyName) {
1223
- const arrayBuffer = copyToArrayBuffer(bytes);
3323
+ const arrayBuffer = copyToArrayBuffer3(bytes);
1224
3324
  try {
1225
3325
  return new Uint8Array(RAD_PROPERTY_DEFLATE.decompressSync(arrayBuffer));
1226
3326
  } catch {
@@ -1278,9 +3378,9 @@ function decodeLeBytesFloat16(bytes, dimensions, count) {
1278
3378
  }
1279
3379
  return values;
1280
3380
  }
1281
- function decodeR8(bytes, dimensions, count, min, max) {
3381
+ function decodeR8(bytes, dimensions, count, min, max2) {
1282
3382
  const values = new Float32Array(count * dimensions);
1283
- const range = max - min;
3383
+ const range = max2 - min;
1284
3384
  for (let rowIndex = 0; rowIndex < count; rowIndex++) {
1285
3385
  for (let dimension = 0; dimension < dimensions; dimension++) {
1286
3386
  values[rowIndex * dimensions + dimension] = bytes[dimension * count + rowIndex] / 255 * range + min;
@@ -1288,9 +3388,9 @@ function decodeR8(bytes, dimensions, count, min, max) {
1288
3388
  }
1289
3389
  return values;
1290
3390
  }
1291
- function decodeR8Delta(bytes, dimensions, count, min, max) {
3391
+ function decodeR8Delta(bytes, dimensions, count, min, max2) {
1292
3392
  const values = new Float32Array(count * dimensions);
1293
- const range = max - min;
3393
+ const range = max2 - min;
1294
3394
  const last = new Uint8Array(dimensions);
1295
3395
  for (let rowIndex = 0; rowIndex < count; rowIndex++) {
1296
3396
  for (let dimension = 0; dimension < dimensions; dimension++) {
@@ -1302,17 +3402,17 @@ function decodeR8Delta(bytes, dimensions, count, min, max) {
1302
3402
  }
1303
3403
  return values;
1304
3404
  }
1305
- function decodeS8(bytes, dimensions, count, max) {
3405
+ function decodeS8(bytes, dimensions, count, max2) {
1306
3406
  const values = new Float32Array(count * dimensions);
1307
3407
  for (let rowIndex = 0; rowIndex < count; rowIndex++) {
1308
3408
  for (let dimension = 0; dimension < dimensions; dimension++) {
1309
3409
  const byte = bytes[dimension * count + rowIndex];
1310
- values[rowIndex * dimensions + dimension] = (byte << 24 >> 24) / 127 * max;
3410
+ values[rowIndex * dimensions + dimension] = (byte << 24 >> 24) / 127 * max2;
1311
3411
  }
1312
3412
  }
1313
3413
  return values;
1314
3414
  }
1315
- function decodeS8Delta(bytes, dimensions, count, max) {
3415
+ function decodeS8Delta(bytes, dimensions, count, max2) {
1316
3416
  const values = new Float32Array(count * dimensions);
1317
3417
  const last = new Uint8Array(dimensions);
1318
3418
  for (let rowIndex = 0; rowIndex < count; rowIndex++) {
@@ -1320,16 +3420,16 @@ function decodeS8Delta(bytes, dimensions, count, max) {
1320
3420
  const byteOffset = dimension * count + rowIndex;
1321
3421
  const value = last[dimension] + bytes[byteOffset] & 255;
1322
3422
  last[dimension] = value;
1323
- values[rowIndex * dimensions + dimension] = (value << 24 >> 24) / 127 * max;
3423
+ values[rowIndex * dimensions + dimension] = (value << 24 >> 24) / 127 * max2;
1324
3424
  }
1325
3425
  }
1326
3426
  return values;
1327
3427
  }
1328
- function decodeScaleR8(bytes, dimensions, count, min, max) {
3428
+ function decodeScaleR8(bytes, dimensions, count, min, max2) {
1329
3429
  const values = new Float32Array(count * dimensions);
1330
3430
  for (let rowIndex = 0; rowIndex < count; rowIndex++) {
1331
3431
  for (let dimension = 0; dimension < dimensions; dimension++) {
1332
- values[rowIndex * dimensions + dimension] = decodeScale8(bytes[dimension * count + rowIndex], min, max);
3432
+ values[rowIndex * dimensions + dimension] = decodeScale8(bytes[dimension * count + rowIndex], min, max2);
1333
3433
  }
1334
3434
  }
1335
3435
  return values;
@@ -1367,11 +3467,11 @@ function makeIdentityRotations(count) {
1367
3467
  }
1368
3468
  return rotations;
1369
3469
  }
1370
- function decodeScale8(scale, min, max) {
3470
+ function decodeScale8(scale, min, max2) {
1371
3471
  if (scale === 0) {
1372
3472
  return 0;
1373
3473
  }
1374
- const logScaleStep = (max - min) / 254;
3474
+ const logScaleStep = (max2 - min) / 254;
1375
3475
  return Math.exp(min + (scale - 1) * logScaleStep);
1376
3476
  }
1377
3477
  function decodeQuatOct888(u, v, r) {
@@ -1462,7 +3562,7 @@ function getSplatEncodingMaximum(splatEncoding, propertyName) {
1462
3562
  function normalizeColorByte2(value) {
1463
3563
  return Math.round(Math.min(Math.max(value, 0), 1) * 255);
1464
3564
  }
1465
- function copyToArrayBuffer(bytes) {
3565
+ function copyToArrayBuffer3(bytes) {
1466
3566
  const copy = new Uint8Array(bytes.byteLength);
1467
3567
  copy.set(bytes);
1468
3568
  return copy.buffer;
@@ -1470,25 +3570,108 @@ function copyToArrayBuffer(bytes) {
1470
3570
  function getUint8Array2(data) {
1471
3571
  return data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
1472
3572
  }
3573
+ var RAD_PROPERTY_DEFLATE, RAD_PROPERTY_RAW_DEFLATE;
3574
+ var init_parse_rad_chunk = __esm({
3575
+ "dist/lib/parse-rad-chunk.js"() {
3576
+ "use strict";
3577
+ init_deflate_decompressor();
3578
+ init_parse_rad();
3579
+ init_splats_arrow_table();
3580
+ init_splat_utils();
3581
+ RAD_PROPERTY_DEFLATE = new DeflateDecompressor2({ useNative: false });
3582
+ RAD_PROPERTY_RAW_DEFLATE = new DeflateDecompressor2({ raw: true, useNative: false });
3583
+ }
3584
+ });
1473
3585
 
1474
3586
  // dist/rad-loader.js
1475
- var RADLoaderWithParser = {
1476
- ...RADLoader,
1477
- parse: async (arrayBuffer) => parseRADHeader(arrayBuffer),
1478
- parseSync: (arrayBuffer) => parseRADHeader(arrayBuffer)
1479
- };
3587
+ var rad_loader_exports = {};
3588
+ __export(rad_loader_exports, {
3589
+ RADLoaderWithParser: () => RADLoaderWithParser,
3590
+ parseRADChunk: () => parseRADChunk,
3591
+ parseRADChunkHeader: () => parseRADChunkHeader,
3592
+ parseRADChunkToGaussianSplats: () => parseRADChunkToGaussianSplats,
3593
+ parseRADHeader: () => parseRADHeader,
3594
+ tryParseRADHeader: () => tryParseRADHeader
3595
+ });
3596
+ var _RADLoaderPreload, RADLoaderMetadataWithoutPreload, RADLoaderWithParser;
3597
+ var init_rad_loader = __esm({
3598
+ "dist/rad-loader.js"() {
3599
+ "use strict";
3600
+ init_parse_rad();
3601
+ init_rad_loader_types();
3602
+ init_parse_rad();
3603
+ init_parse_rad_chunk();
3604
+ ({ preload: _RADLoaderPreload, ...RADLoaderMetadataWithoutPreload } = RADLoader);
3605
+ RADLoaderWithParser = {
3606
+ ...RADLoaderMetadataWithoutPreload,
3607
+ parse: async (arrayBuffer) => parseRADHeader(arrayBuffer),
3608
+ parseSync: (arrayBuffer) => parseRADHeader(arrayBuffer)
3609
+ };
3610
+ }
3611
+ });
3612
+
3613
+ // dist/rad-loader-types.js
3614
+ async function preload4() {
3615
+ const { RADLoaderWithParser: RADLoaderWithParser2 } = await Promise.resolve().then(() => (init_rad_loader(), rad_loader_exports));
3616
+ return RADLoaderWithParser2;
3617
+ }
3618
+ var VERSION5, RADLoader;
3619
+ var init_rad_loader_types = __esm({
3620
+ "dist/rad-loader-types.js"() {
3621
+ "use strict";
3622
+ init_splats_format();
3623
+ VERSION5 = true ? "5.0.0-alpha.10" : "latest";
3624
+ RADLoader = {
3625
+ dataType: null,
3626
+ batchType: null,
3627
+ ...RADFormat,
3628
+ version: VERSION5,
3629
+ options: {},
3630
+ preload: preload4
3631
+ };
3632
+ }
3633
+ });
3634
+
3635
+ // dist/index.js
3636
+ var index_exports = {};
3637
+ __export(index_exports, {
3638
+ KSPLATFormat: () => KSPLATFormat,
3639
+ KSPLATLoader: () => KSPLATLoader,
3640
+ RADFormat: () => RADFormat,
3641
+ RADLoader: () => RADLoader,
3642
+ RADSource: () => RADSource,
3643
+ RADSourceLoader: () => RADSourceLoader,
3644
+ SPLATFormat: () => SPLATFormat,
3645
+ SPLATLoader: () => SPLATLoader,
3646
+ SPZFormat: () => SPZFormat,
3647
+ SPZLoader: () => SPZLoader,
3648
+ parseSPZ: () => parseSPZ,
3649
+ parseSPZToGaussianSplats: () => parseSPZToGaussianSplats,
3650
+ resolveRADChunkUrl: () => resolveRADChunkUrl
3651
+ });
3652
+ module.exports = __toCommonJS(index_exports);
3653
+ init_splats_format();
3654
+ init_parse_spz();
3655
+ init_splat_loader_types();
3656
+ init_ksplat_loader_types();
3657
+ init_spz_loader_types();
3658
+ init_rad_loader_types();
1480
3659
 
1481
3660
  // dist/rad-source-loader.js
1482
- var import_loader_utils = require("@loaders.gl/loader-utils");
3661
+ init_src();
3662
+ init_splats_format();
3663
+ init_parse_rad();
3664
+ init_parse_rad_chunk();
3665
+ init_splats_arrow_table();
1483
3666
  var DEFAULT_RAD_HEADER_BYTE_LENGTHS = [64 * 1024, 256 * 1024, 1024 * 1024];
1484
3667
  var DEFAULT_RAD_MAX_CONCURRENT_CHUNK_REQUESTS = 4;
1485
- var VERSION5 = true ? "4.5.3" : "latest";
3668
+ var VERSION6 = true ? "5.0.0-alpha.10" : "latest";
1486
3669
  var RADSourceLoader = {
1487
3670
  dataType: null,
1488
3671
  batchType: null,
1489
3672
  ...RADFormat,
1490
3673
  name: "RADSourceLoader",
1491
- version: VERSION5,
3674
+ version: VERSION6,
1492
3675
  type: "rad",
1493
3676
  fromUrl: true,
1494
3677
  fromBlob: true,
@@ -1507,17 +3690,17 @@ var RADSourceLoader = {
1507
3690
  }
1508
3691
  },
1509
3692
  testURL: (url) => /\.rad(?:$|[?#])/i.test(url),
1510
- createDataSource: (data, options) => new RADSource(data, options)
3693
+ createDataSource: (data, options, coreApi) => new RADSource(data, options, coreApi)
1511
3694
  };
1512
- var RADSource = class extends import_loader_utils.DataSource {
3695
+ var RADSource = class extends DataSource {
1513
3696
  /** Shared metadata promise exposed for source-style integrations. */
1514
3697
  metadata;
1515
3698
  /** Lazily initialized RAD header promise. */
1516
3699
  _metadataPromise = null;
1517
3700
  /** Lazily initialized per-chunk metadata promises. */
1518
3701
  _chunkMetadataPromises = /* @__PURE__ */ new Map();
1519
- constructor(data, options) {
1520
- super(data, options, RADSourceLoader.defaultOptions);
3702
+ constructor(data, options, coreApi) {
3703
+ super(data, options, RADSourceLoader.defaultOptions, coreApi);
1521
3704
  this.metadata = this.getMetadata();
1522
3705
  }
1523
3706
  /** Ensures the RAD header metadata has been loaded. */
@@ -1685,7 +3868,15 @@ var RADSource = class extends import_loader_utils.DataSource {
1685
3868
  }
1686
3869
  /** Fetches through custom source fetch hooks or the injected core fetchFile helper. */
1687
3870
  async _fetchResponse(url, requestInit) {
1688
- return await this.fetch(url, requestInit);
3871
+ if (this._hasCustomFetch()) {
3872
+ return await this.fetch(url, requestInit);
3873
+ }
3874
+ return this.hasCoreApi ? await this.coreApi.fetchFile(url, requestInit) : await this.fetch(url, requestInit);
3875
+ }
3876
+ /** Returns true when source options supplied an explicit fetch override. */
3877
+ _hasCustomFetch() {
3878
+ var _a, _b, _c;
3879
+ return Boolean(((_b = (_a = this.loadOptions) == null ? void 0 : _a.core) == null ? void 0 : _b.fetch) || ((_c = this.loadOptions) == null ? void 0 : _c.fetch));
1689
3880
  }
1690
3881
  /** Builds request options for RAD fetches. */
1691
3882
  _getRequestInit(range, options = {}) {