@kalyptos/narcissus 0.0.0-stage → 0.0.0

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 (81) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +45 -2
  3. package/dist/adapters/disk.d.ts +3 -0
  4. package/dist/adapters/files.d.ts +3 -0
  5. package/dist/adapters/http.d.ts +3 -0
  6. package/dist/adapters/memory.d.ts +3 -0
  7. package/dist/adapters/opfs.d.ts +9 -0
  8. package/dist/cli/export.d.ts +1 -0
  9. package/dist/cli/info.d.ts +1 -0
  10. package/dist/cli/main.d.ts +2 -0
  11. package/dist/cli/main.js +151 -0
  12. package/dist/cli/publish.d.ts +2 -0
  13. package/dist/cli/shared.d.ts +8 -0
  14. package/dist/cli/validate.d.ts +1 -0
  15. package/dist/controls/controls.d.ts +22 -0
  16. package/dist/controls/index.d.ts +2 -0
  17. package/dist/controls/pose.d.ts +65 -0
  18. package/dist/controls-5FaXzanr.js +2633 -0
  19. package/dist/element/index.d.ts +27 -0
  20. package/dist/element/index.js +107 -0
  21. package/dist/engine/engine.d.ts +73 -0
  22. package/dist/engine/gpu/buffers.d.ts +22 -0
  23. package/dist/engine/gpu/cull.d.ts +8 -0
  24. package/dist/engine/gpu/device.d.ts +12 -0
  25. package/dist/engine/gpu/fullscreen.d.ts +7 -0
  26. package/dist/engine/gpu/heights.d.ts +12 -0
  27. package/dist/engine/gpu/layout.d.ts +24 -0
  28. package/dist/engine/gpu/pool.d.ts +44 -0
  29. package/dist/engine/gpu/present.d.ts +3 -0
  30. package/dist/engine/gpu/project.d.ts +18 -0
  31. package/dist/engine/gpu/raster.d.ts +19 -0
  32. package/dist/engine/gpu/renderer.d.ts +39 -0
  33. package/dist/engine/gpu/sort.d.ts +13 -0
  34. package/dist/engine/gpu/timing.d.ts +18 -0
  35. package/dist/engine/index.d.ts +10 -0
  36. package/dist/engine/math/frustum.d.ts +5 -0
  37. package/dist/engine/math/mat4.d.ts +13 -0
  38. package/dist/engine/plan/cut.d.ts +46 -0
  39. package/dist/engine/plan/draw.d.ts +16 -0
  40. package/dist/engine/plan/footprint.d.ts +13 -0
  41. package/dist/engine/plugin.d.ts +52 -0
  42. package/dist/engine/plugins/dof.d.ts +3 -0
  43. package/dist/engine/plugins/fog.d.ts +3 -0
  44. package/dist/engine/plugins/grade.d.ts +3 -0
  45. package/dist/engine/quality.d.ts +10 -0
  46. package/dist/engine/stream/feed.d.ts +27 -0
  47. package/dist/engine/stream/jobs.d.ts +18 -0
  48. package/dist/engine/stream/loader.d.ts +22 -0
  49. package/dist/engine/stream/remote.d.ts +24 -0
  50. package/dist/engine/stream/scheduler.d.ts +43 -0
  51. package/dist/engine/stream/synthetic.d.ts +5 -0
  52. package/dist/engine/stream/worker.d.ts +43 -0
  53. package/dist/engine/types.d.ts +51 -0
  54. package/dist/engine/world/tree.d.ts +54 -0
  55. package/dist/format/col.d.ts +5 -0
  56. package/dist/format/encode.d.ts +41 -0
  57. package/dist/format/hash.d.ts +2 -0
  58. package/dist/format/idx.d.ts +16 -0
  59. package/dist/format/index.d.ts +9 -0
  60. package/dist/format/index.js +1 -0
  61. package/dist/format/inflate.d.ts +4 -0
  62. package/dist/format/page.d.ts +25 -0
  63. package/dist/format/spec.d.ts +57 -0
  64. package/dist/format/types.d.ts +78 -0
  65. package/dist/format/world.d.ts +5 -0
  66. package/dist/format-CxKTIugr.js +905 -0
  67. package/dist/http-DL7R39Nc.js +14 -0
  68. package/dist/index.d.ts +5 -0
  69. package/dist/index.js +81 -0
  70. package/dist/ports-DZRKjdYD.js +6 -0
  71. package/dist/ports.d.ts +11 -0
  72. package/dist/synthetic-BZcHRI1P.js +383 -0
  73. package/dist/tools/index.d.ts +8 -0
  74. package/dist/tools/index.js +1 -0
  75. package/dist/tools/info.d.ts +15 -0
  76. package/dist/tools/ply.d.ts +18 -0
  77. package/dist/tools/validate.d.ts +25 -0
  78. package/dist/tools/walk.d.ts +15 -0
  79. package/dist/tools-DwOGah9N.js +242 -0
  80. package/docs/format.md +166 -0
  81. package/package.json +58 -5
@@ -0,0 +1,2633 @@
1
+ import { F as e, I as t, c as n, l as r, m as i, u as a } from "./format-CxKTIugr.js";
2
+ import { t as o } from "./ports-DZRKjdYD.js";
3
+ import { t as s } from "./http-DL7R39Nc.js";
4
+ //#region src/engine/gpu/layout.ts
5
+ var c = (e) => Math.max(1, Math.ceil(e / 256)) * 256, l = {
6
+ visible: 0,
7
+ projected: 4,
8
+ drawArgs: 8,
9
+ list: 16
10
+ }, u = 65535, d = (e) => [Math.min(e, u), Math.ceil(e / u)], f = .075;
11
+ //#endregion
12
+ //#region src/engine/gpu/device.ts
13
+ async function p() {
14
+ if (!navigator.gpu) return null;
15
+ let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
16
+ if (!e) return null;
17
+ let t = e.features.has("timestamp-query");
18
+ return {
19
+ device: await e.requestDevice({
20
+ requiredFeatures: t ? ["timestamp-query"] : [],
21
+ requiredLimits: {
22
+ maxStorageBufferBindingSize: e.limits.maxStorageBufferBindingSize,
23
+ maxBufferSize: e.limits.maxBufferSize
24
+ }
25
+ }),
26
+ timestamps: t,
27
+ format: navigator.gpu.getPreferredCanvasFormat()
28
+ };
29
+ }
30
+ //#endregion
31
+ //#region src/engine/gpu/pool.ts
32
+ var m = 19, h = 1024, g = class {
33
+ #e = [];
34
+ mark(e, t) {
35
+ this.#e.push([e, t]);
36
+ }
37
+ clear() {
38
+ this.#e = [];
39
+ }
40
+ flush(e, t, n) {
41
+ let r = this.#e.sort((e, t) => e[0] - t[0]);
42
+ this.#e = [];
43
+ for (let i = 0; i < r.length;) {
44
+ let a = r[i][0], o = r[i++][1];
45
+ for (; i < r.length && r[i][0] <= o + h;) o = Math.max(o, r[i++][1]);
46
+ e.writeBuffer(t, a * 4, n, a, o - a);
47
+ }
48
+ }
49
+ }, _ = class {
50
+ geometry;
51
+ colour;
52
+ pages;
53
+ clusters;
54
+ list;
55
+ listed = 0;
56
+ capacity;
57
+ #e;
58
+ #t = /* @__PURE__ */ new Map();
59
+ #n = /* @__PURE__ */ new Set();
60
+ #r;
61
+ #i;
62
+ #a;
63
+ #o = [
64
+ 0,
65
+ 0,
66
+ 0
67
+ ];
68
+ #s;
69
+ #c;
70
+ #l = new g();
71
+ #u;
72
+ #d;
73
+ #f = new g();
74
+ #p;
75
+ constructor(e, t) {
76
+ this.capacity = t, this.#e = e;
77
+ let n = this.slots, r = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, i = (t, n) => e.createBuffer({
78
+ label: t,
79
+ size: n,
80
+ usage: r
81
+ });
82
+ this.geometry = i("pool geometry", t * 4 * 4), this.colour = i("pool colour", t * 3 * 4), this.pages = i("pool pages", n * 36 * 4), this.clusters = i("pool clusters", n * 12 * 4), this.list = i("pool list", n * 4), this.#r = new Uint8Array(n), this.#i = n, this.#a = Array.from({ length: n }, (e, t) => n - 1 - t), this.#s = new Uint32Array(n * 36), this.#c = new Float32Array(this.#s.buffer), this.#u = new Uint32Array(n * 12), this.#d = new Float32Array(this.#u.buffer), this.#p = new Uint32Array(n);
83
+ }
84
+ get slots() {
85
+ return this.capacity / 256;
86
+ }
87
+ get bytes() {
88
+ return [
89
+ this.geometry,
90
+ this.colour,
91
+ this.pages,
92
+ this.clusters,
93
+ this.list
94
+ ].reduce((e, t) => e + t.size, 0);
95
+ }
96
+ has(e) {
97
+ let t = this.#t.get(e);
98
+ return t !== void 0 && t.page === null;
99
+ }
100
+ holds(e) {
101
+ return this.#t.has(e);
102
+ }
103
+ *ids() {
104
+ for (let [e, t] of this.#t) t.page === null && (yield e);
105
+ }
106
+ add(e, n, r, i) {
107
+ if (this.#t.has(e)) return !0;
108
+ let a = c(n.count) / 256;
109
+ if (!this.#m(a, i)) return !1;
110
+ let o = t.origin;
111
+ return this.#t.set(e, {
112
+ page: n,
113
+ slots: this.#v(a),
114
+ table: this.#a.pop(),
115
+ base: [
116
+ n.params[o] + r[0],
117
+ n.params[o + 1] + r[1],
118
+ n.params[o + 2]
119
+ ],
120
+ factors: 0
121
+ }), this.#n.add(e), !0;
122
+ }
123
+ remove(e) {
124
+ let t = this.#t.get(e);
125
+ if (t) {
126
+ this.#t.delete(e), this.#n.delete(e);
127
+ for (let e of t.slots) this.#r[e] = 0;
128
+ this.#i += t.slots.length, this.#a.push(t.table), t.page === null && t.factors !== 0 && this.#_(t, 0);
129
+ }
130
+ }
131
+ clear() {
132
+ for (let e of this.#t.keys()) this.remove(e);
133
+ }
134
+ get queued() {
135
+ return this.#n.size;
136
+ }
137
+ upload(e) {
138
+ let t = 0;
139
+ for (let n of this.#n) {
140
+ if (t >= e) break;
141
+ t += this.#h(this.#t.get(n)), this.#n.delete(n);
142
+ }
143
+ return t;
144
+ }
145
+ draw(e) {
146
+ let t = 0;
147
+ for (let { id: n, factors: r } of e) {
148
+ let e = this.#t.get(n);
149
+ e && e.page === null && (e.factors !== r && this.#_(e, r), this.#t.delete(n), this.#t.set(n, e), this.#p.set(e.slots, t), t += e.slots.length);
150
+ }
151
+ this.listed = t;
152
+ let n = this.#e.queue;
153
+ this.#l.flush(n, this.pages, this.#s), this.#f.flush(n, this.clusters, this.#u), n.writeBuffer(this.list, 0, this.#p, 0, t);
154
+ }
155
+ setOrigin(e) {
156
+ this.#o = [
157
+ e[0],
158
+ e[1],
159
+ e[2]
160
+ ];
161
+ for (let e of this.#t.values()) e.page === null && this.#g(e);
162
+ this.#e.queue.writeBuffer(this.pages, 0, this.#s), this.#l.clear();
163
+ }
164
+ destroy() {
165
+ let e = [
166
+ this.geometry,
167
+ this.colour,
168
+ this.pages,
169
+ this.clusters,
170
+ this.list
171
+ ];
172
+ for (let t of e) t.destroy();
173
+ }
174
+ #m(e, t) {
175
+ let n = this.#i;
176
+ if (n >= e) return !0;
177
+ let r = [];
178
+ for (let [i, a] of this.#t) if (!(a.page !== null || t(i)) && (r.push(i), n += a.slots.length, n >= e)) break;
179
+ if (n < e) return !1;
180
+ for (let e of r) this.remove(e);
181
+ return !0;
182
+ }
183
+ #h(e) {
184
+ let n = e.page, { slots: r } = e, i = this.#e.queue, a = r.length, o = this.#u, s = this.#d;
185
+ for (let t = 0; t < a; t++) {
186
+ let i = r[t] * 12;
187
+ o.fill(0, i, i + 12), o[i] = e.table, o[i + 1] = r[t] * 256, o[i + 2] = t * 256, o[i + 3] = Math.max(0, Math.min(256, n.count - t * 256)), s.set(n.clusters.subarray(t * 6, t * 6 + 3), i + 4), s.set(n.clusters.subarray(t * 6 + 3, t * 6 + 6), i + 8);
188
+ }
189
+ for (let e = 0; e < a;) {
190
+ let t = 1;
191
+ for (; e + t < a && r[e + t] === r[e] + t;) t++;
192
+ let o = e * 256, s = Math.min((e + t) * 256, n.count) - o, c = r[e] * 256;
193
+ i.writeBuffer(this.geometry, c * 4 * 4, n.geometry, o * 4, s * 4), i.writeBuffer(this.colour, c * 3 * 4, n.colour, o * 3, s * 3), this.#f.mark(r[e] * 12, (r[e] + t) * 12), e += t;
194
+ }
195
+ let c = e.table * 36, l = this.#s, u = this.#c, d = n.params, [f, p, m] = n.quadrants;
196
+ return l.fill(0, c, c + 36), this.#g(e), l[c + 3] = n.count, u.set(d.subarray(t.step, t.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(t.scaleMin, t.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(t.scaleMax, t.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(t.dcMin, t.dcMin + 3), c + 16), u.set(d.subarray(t.dcMax, t.dcMax + 3), c + 20), u.set(d.subarray(t.shScale, t.shScale + 9), c + 24), this.#l.mark(c, c + 36), e.page = null, n.count * 7 * 4 + a * 12 * 4 + 144;
197
+ }
198
+ #g(e) {
199
+ let t = e.table * 36;
200
+ for (let n = 0; n < 3; n++) this.#c[t + n] = e.base[n] - this.#o[n];
201
+ }
202
+ #_(e, t) {
203
+ e.factors = t;
204
+ let n = e.table * 36 + m;
205
+ this.#s[n] = t, this.#l.mark(n, n + 1);
206
+ }
207
+ #v(e) {
208
+ let t = this.#r, n = -1;
209
+ for (let r = 0, i = 0; r < t.length; r++) if (i = t[r] ? 0 : i + 1, i === e) {
210
+ n = r - e + 1;
211
+ break;
212
+ }
213
+ let r = [];
214
+ if (n >= 0) for (let t = n; t < n + e; t++) r.push(t);
215
+ else for (let n = 0; r.length < e; n++) t[n] || r.push(n);
216
+ for (let e of r) t[e] = 1;
217
+ return this.#i -= e, r;
218
+ }
219
+ };
220
+ //#endregion
221
+ //#region src/engine/math/mat4.ts
222
+ function v(e, t) {
223
+ let n = Math.cos(t);
224
+ return [
225
+ Math.sin(e) * n,
226
+ Math.cos(e) * n,
227
+ Math.sin(t)
228
+ ];
229
+ }
230
+ function y(e, t, n, r) {
231
+ let [i, a, o] = v(n, r), s = Math.cos(n), c = -Math.sin(n), l = c * o, u = -s * o, d = s * a - c * i;
232
+ return e[0] = s, e[1] = l, e[2] = -i, e[3] = 0, e[4] = c, e[5] = u, e[6] = -a, e[7] = 0, e[8] = 0, e[9] = d, e[10] = -o, e[11] = 0, e[12] = -(s * t[0] + c * t[1]), e[13] = -(l * t[0] + u * t[1] + d * t[2]), e[14] = i * t[0] + a * t[1] + o * t[2], e[15] = 1, e;
233
+ }
234
+ function b(e, t, n, r, i) {
235
+ let a = 1 / Math.tan(t / 2);
236
+ return e.fill(0), e[0] = a / n, e[5] = a, e[10] = i / (r - i), e[11] = -1, e[14] = r * i / (r - i), e;
237
+ }
238
+ var x = /* @__PURE__ */ new Float64Array(16);
239
+ function S(e, t, n) {
240
+ for (let e = 0; e < 4; e++) for (let r = 0; r < 4; r++) {
241
+ let i = 0;
242
+ for (let a = 0; a < 4; a++) i += t[a * 4 + r] * n[e * 4 + a];
243
+ x[e * 4 + r] = i;
244
+ }
245
+ return e.set(x), e;
246
+ }
247
+ function C(e, t) {
248
+ let [n, r, i, a, o, s, c, l, u, d, f, p, m, h, g, _] = t, v = n * s - r * o, y = n * c - i * o, b = n * l - a * o, x = r * c - i * s, S = r * l - a * s, C = i * l - a * c, w = u * h - d * m, T = u * g - f * m, E = u * _ - p * m, D = d * g - f * h, O = d * _ - p * h, k = f * _ - p * g, A = v * k - y * O + b * D + x * E - S * T + C * w;
249
+ if (!A) return null;
250
+ let j = 1 / A;
251
+ return e[0] = (s * k - c * O + l * D) * j, e[1] = (i * O - r * k - a * D) * j, e[2] = (h * C - g * S + _ * x) * j, e[3] = (f * S - d * C - p * x) * j, e[4] = (c * E - o * k - l * T) * j, e[5] = (n * k - i * E + a * T) * j, e[6] = (g * b - m * C - _ * y) * j, e[7] = (u * C - f * b + p * y) * j, e[8] = (o * O - s * E + l * w) * j, e[9] = (r * E - n * O - a * w) * j, e[10] = (m * S - h * b + _ * v) * j, e[11] = (d * b - u * S - p * v) * j, e[12] = (s * T - o * D - c * w) * j, e[13] = (n * D - r * T + i * w) * j, e[14] = (h * y - m * x - g * v) * j, e[15] = (u * x - d * y + f * v) * j, e;
252
+ }
253
+ function w(e, t) {
254
+ let [n, r, i] = t;
255
+ return [
256
+ e[0] * n + e[4] * r + e[8] * i + e[12],
257
+ e[1] * n + e[5] * r + e[9] * i + e[13],
258
+ e[2] * n + e[6] * r + e[10] * i + e[14],
259
+ e[3] * n + e[7] * r + e[11] * i + e[15]
260
+ ];
261
+ }
262
+ //#endregion
263
+ //#region src/engine/gpu/buffers.ts
264
+ function T(e, t, n) {
265
+ let r = (t, n, r) => e.createBuffer({
266
+ label: t,
267
+ size: n,
268
+ usage: r
269
+ }), i = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, a = [
270
+ r("frame uniforms", 336, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
271
+ r("work", (l.list + n) * 4, i | GPUBufferUsage.INDIRECT),
272
+ r("projected", t * 6 * 4, i),
273
+ r("sort", t * 16, i),
274
+ r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
275
+ ], [o, s, c, u, d] = a;
276
+ return {
277
+ capacity: t,
278
+ uniforms: o,
279
+ work: s,
280
+ projected: c,
281
+ sort: u,
282
+ plugins: d,
283
+ bytes: a.reduce((e, t) => e + t.size, 0),
284
+ destroy: () => a.forEach((e) => e.destroy())
285
+ };
286
+ }
287
+ function E(e, t, n, r) {
288
+ return e.createBindGroupLayout({
289
+ label: t,
290
+ entries: r.map((e, t) => ({
291
+ binding: t,
292
+ visibility: n,
293
+ buffer: { type: e }
294
+ }))
295
+ });
296
+ }
297
+ function D(e, t, n, r) {
298
+ return e.createBindGroup({
299
+ label: t,
300
+ layout: n,
301
+ entries: r.map((e, t) => ({
302
+ binding: t,
303
+ resource: { buffer: e }
304
+ }))
305
+ });
306
+ }
307
+ //#endregion
308
+ //#region src/engine/gpu/common.wgsl?raw
309
+ var O = "// shared by every engine pass; sizes and word offsets mirror format/spec.ts\n\nconst KEY_BITS: u32 = 24u;\n// word offsets in the work buffer, layout.ts WORK\nconst WORK_VISIBLE: u32 = 0u;\nconst WORK_PROJECTED: u32 = 4u;\nconst WORK_LIST: u32 = 16u;\n// workgroups a dispatch row holds\nconst GROUPS_X: u32 = 65535u;\nconst C0: f32 = 0.28209479177387814;\nconst C1: f32 = 0.4886025119029199;\n\n// floating-origin ENU frame; camera looks down -z of view space\nstruct FrameUniforms {\n view: mat4x4f,\n proj: mat4x4f,\n viewProj: mat4x4f,\n // inside when dot(plane.xyz, p) + plane.w >= 0\n planes: array<vec4f, 6>,\n camera: vec3f,\n time: f32,\n // render target pixels\n viewport: vec2f,\n focal: vec2f,\n near: f32,\n far: f32,\n lowPass: f32,\n // drawn cluster ids in the pool's list\n clusters: u32,\n}\n\n// one resident page; dc and sh ranges are after the colour correction\nstruct Page {\n origin: vec3f,\n count: u32,\n step: vec3f,\n q1: u32,\n scaleMin: vec3f,\n q2: u32,\n scaleMax: vec3f,\n q3: u32,\n dcMin: vec3f,\n // quadrant k opacity 0-255 at bits 8k\n factors: u32,\n dcMax: vec3f,\n pad: u32,\n shScale: array<vec4f, 3>,\n}\n\n// up to CLUSTER consecutive splats of one page in one pool slot\nstruct Cluster {\n page: u32,\n // first pool record\n slot: u32,\n // index in the page of its first splat\n first: u32,\n count: u32,\n // extents relative to the page origin\n boxMin: vec3f,\n pad0: u32,\n boxMax: vec3f,\n pad1: u32,\n}\n\n// a splat on screen; pixels with y up from the bottom-left of the target\nstruct Projected {\n centre: vec2f,\n // pack2x16float: 1-sigma major axis xy, 1-sigma minor axis xy\n axes: vec2u,\n // pack2x16float: r g, b opacity\n colour: vec2u,\n}\n\n// what a shade hook may change; position in the floating-origin frame, depth in view metres\nstruct Splat {\n position: vec3f,\n depth: f32,\n colour: vec3f,\n opacity: f32,\n scale: vec3f,\n}\n\n// the byte of word at bit, 0 to 1\nfn fraction(word: u32, bit: u32) -> f32 {\n return f32(extractBits(word, bit, 8u)) / 255.0;\n}\n\n// sigmas out to where a gaussian of opacity falls under 1/255, at most 3; the quad raster draws\nfn reach(opacity: f32) -> f32 {\n return min(3.0, sqrt(max(2.0 * log(255.0 * opacity), 0.0)));\n}\n", k = "// one thread per listed cluster\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<storage, read> pages: array<Page>;\n@group(0) @binding(2) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(3) var<storage, read> list: array<u32>;\n@group(0) @binding(4) var<storage, read_write> work: array<atomic<u32>>;\n\n// false only when the box lies wholly outside one plane\nfn inside(lo: vec3f, hi: vec3f) -> bool {\n for (var p = 0u; p < 6u; p++) {\n let plane = uniforms.planes[p];\n let corner = select(lo, hi, plane.xyz >= vec3f(0.0));\n if (dot(plane.xyz, corner) + plane.w < 0.0) {\n return false;\n }\n }\n return true;\n}\n\n// some quadrant the cluster's splats overlap has a nonzero factor\nfn lit(page: Page, cluster: Cluster) -> bool {\n var starts = array<u32, 5>(0u, page.q1, page.q2, page.q3, page.count);\n let end = cluster.first + cluster.count;\n for (var k = 0u; k < 4u; k++) {\n let overlaps = max(starts[k], cluster.first) < min(starts[k + 1u], end);\n if (overlaps && extractBits(page.factors, 8u * k, 8u) != 0u) {\n return true;\n }\n }\n return false;\n}\n\n@compute @workgroup_size(64)\nfn cull(@builtin(global_invocation_id) id: vec3u) {\n if (id.x >= uniforms.clusters) {\n return;\n }\n let slot = list[id.x];\n let cluster = clusters[slot];\n let page = pages[cluster.page];\n if (!inside(page.origin + cluster.boxMin, page.origin + cluster.boxMax) || !lit(page, cluster)) {\n return;\n }\n atomicStore(&work[WORK_LIST + atomicAdd(&work[WORK_VISIBLE], 1u)], slot);\n}\n", A = 64, j = class {
310
+ #e;
311
+ #t;
312
+ #n;
313
+ constructor(e, t, n) {
314
+ this.#e = t;
315
+ let r = E(e, "cull", GPUShaderStage.COMPUTE, [
316
+ "uniform",
317
+ "read-only-storage",
318
+ "read-only-storage",
319
+ "read-only-storage",
320
+ "storage"
321
+ ]), i = e.createShaderModule({
322
+ label: "cull",
323
+ code: `${O}\n${k}`
324
+ });
325
+ this.#t = e.createComputePipeline({
326
+ label: "cull",
327
+ layout: e.createPipelineLayout({ bindGroupLayouts: [r] }),
328
+ compute: {
329
+ module: i,
330
+ entryPoint: "cull"
331
+ }
332
+ });
333
+ let a = [
334
+ n.uniforms,
335
+ t.pages,
336
+ t.clusters,
337
+ t.list,
338
+ n.work
339
+ ];
340
+ this.#n = D(e, "cull", r, a);
341
+ }
342
+ encode(e, t) {
343
+ let n = e.beginComputePass({
344
+ label: "cull",
345
+ timestampWrites: t
346
+ });
347
+ n.setBindGroup(0, this.#n), n.setPipeline(this.#t), n.dispatchWorkgroups(Math.ceil(this.#e.listed / A)), n.end();
348
+ }
349
+ }, M = "// the top of the solid drawn splats over a square of 1 m cells; one workgroup per listed cluster\n\nconst GROUP: u32 = 64u;\n\nstruct Area {\n // south-west corner, floating-origin frame\n corner: vec2f,\n cells: u32,\n clusters: u32,\n // least opacity and largest scale in metres of a splat that counts\n opacity: f32,\n scale: f32,\n}\n\n@group(0) @binding(0) var<uniform> area: Area;\n@group(0) @binding(1) var<storage, read> pages: array<Page>;\n@group(0) @binding(2) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(3) var<storage, read> list: array<u32>;\n@group(0) @binding(4) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(5) var<storage, read_write> tops: array<atomic<u32>>;\n\n// order-preserving bits of z, never 0, which marks an empty cell\nfn ordered(z: f32) -> u32 {\n let bits = bitcast<u32>(z);\n return select(bits | 0x80000000u, ~bits, z < 0.0);\n}\n\n@compute @workgroup_size(64)\nfn heights(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let index = wid.y * GROUPS_X + wid.x;\n if (index >= area.clusters) {\n return;\n }\n let cluster = clusters[list[index]];\n let page = pages[cluster.page];\n let size = f32(area.cells);\n let lo = page.origin.xy + cluster.boxMin.xy - area.corner;\n let hi = page.origin.xy + cluster.boxMax.xy - area.corner;\n if (any(hi < vec2f(0.0)) || any(lo >= vec2f(size))) {\n return;\n }\n for (var k = t; k < cluster.count; k += GROUP) {\n let g = geometry[cluster.slot + k];\n let i = cluster.first + k;\n let quadrant = u32(i >= page.q1) + u32(i >= page.q2) + u32(i >= page.q3);\n let opacity = fraction(g.y, 16u) * fraction(page.factors, 8u * quadrant);\n let level = vec3f(fraction(g.z, 24u), fraction(g.w, 0u), fraction(g.w, 8u));\n let scale = exp(mix(page.scaleMin, page.scaleMax, level));\n if (opacity < area.opacity || max(scale.x, max(scale.y, scale.z)) > area.scale) {\n continue;\n }\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n let p = page.origin + q * page.step;\n let cell = floor(p.xy - area.corner);\n if (any(cell < vec2f(0.0)) || any(cell >= vec2f(size))) {\n continue;\n }\n let c = vec2u(cell);\n atomicMax(&tops[c.y * area.cells + c.x], ordered(p.z));\n }\n}\n", ee = 32, te = .5, ne = 1;
350
+ function re(e) {
351
+ let t = new Uint32Array(e.length);
352
+ for (let n = 0; n < e.length; n++) {
353
+ let r = e[n];
354
+ t[n] = r === 0 ? 2143289344 : r & 2147483648 ? r & 2147483647 : ~r >>> 0;
355
+ }
356
+ return new Float32Array(t.buffer);
357
+ }
358
+ var ie = class {
359
+ #e;
360
+ #t;
361
+ #n;
362
+ #r;
363
+ constructor(e, t) {
364
+ this.#e = e, this.#t = t, this.#n = E(e, "heights", GPUShaderStage.COMPUTE, [
365
+ "uniform",
366
+ "read-only-storage",
367
+ "read-only-storage",
368
+ "read-only-storage",
369
+ "read-only-storage",
370
+ "storage"
371
+ ]);
372
+ let n = e.createShaderModule({
373
+ label: "heights",
374
+ code: `${O}\n${M}`
375
+ });
376
+ this.#r = e.createComputePipeline({
377
+ label: "heights",
378
+ layout: e.createPipelineLayout({ bindGroupLayouts: [this.#n] }),
379
+ compute: {
380
+ module: n,
381
+ entryPoint: "heights"
382
+ }
383
+ });
384
+ }
385
+ encode(e, t, n, r, i) {
386
+ let a = this.#e, o = this.#t, { listed: s } = o, c = r * r * 4, l = a.createBuffer({
387
+ label: "heights area",
388
+ size: ee,
389
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
390
+ }), u = a.createBuffer({
391
+ label: "heights",
392
+ size: c,
393
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
394
+ }), f = a.createBuffer({
395
+ label: "heights readback",
396
+ size: c,
397
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
398
+ }), p = /* @__PURE__ */ new ArrayBuffer(ee);
399
+ new Float32Array(p).set([
400
+ t,
401
+ n,
402
+ 0,
403
+ 0,
404
+ te,
405
+ ne
406
+ ]), new Uint32Array(p).set([r, s], 2), a.queue.writeBuffer(l, 0, p);
407
+ let m = [
408
+ l,
409
+ o.pages,
410
+ o.clusters,
411
+ o.list,
412
+ o.geometry,
413
+ u
414
+ ], h = D(a, "heights", this.#n, m), g = e.beginComputePass({
415
+ label: "heights",
416
+ timestampWrites: i
417
+ });
418
+ return g.setPipeline(this.#r), g.setBindGroup(0, h), s > 0 && g.dispatchWorkgroups(...d(s)), g.end(), e.copyBufferToBuffer(u, 0, f, 0, c), () => f.mapAsync(GPUMapMode.READ).then(() => re(new Uint32Array(f.getMappedRange())), () => null).finally(() => {
419
+ l.destroy(), u.destroy(), f.destroy();
420
+ });
421
+ }
422
+ }, ae = "@vertex\nfn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {\n // one triangle over the whole target\n let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\n", oe = class {
423
+ #e;
424
+ #t;
425
+ #n;
426
+ #r = [];
427
+ #i;
428
+ constructor(e, t, n, r) {
429
+ let i = e.createShaderModule({
430
+ label: t,
431
+ code: ae + n
432
+ });
433
+ this.#e = e, this.#t = t, this.#n = e.createRenderPipeline({
434
+ label: t,
435
+ layout: "auto",
436
+ vertex: {
437
+ module: i,
438
+ entryPoint: "vs"
439
+ },
440
+ fragment: {
441
+ module: i,
442
+ entryPoint: "fs",
443
+ targets: [{ format: r }]
444
+ }
445
+ });
446
+ }
447
+ encode(e, t, n) {
448
+ (!this.#i || t.some((e, t) => e !== this.#r[t])) && (this.#r = t, this.#i = this.#e.createBindGroup({
449
+ label: this.#t,
450
+ layout: this.#n.getBindGroupLayout(0),
451
+ entries: t.map((e, t) => ({
452
+ binding: t,
453
+ resource: e
454
+ }))
455
+ }));
456
+ let r = e.beginRenderPass({
457
+ label: this.#t,
458
+ colorAttachments: [{
459
+ view: n,
460
+ loadOp: "clear",
461
+ storeOp: "store"
462
+ }]
463
+ });
464
+ r.setPipeline(this.#n), r.setBindGroup(0, this.#i), r.draw(3), r.end();
465
+ }
466
+ }, se = "// the finished colour target onto the canvas, opaque\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n return vec4f(textureLoad(scene, vec2i(coord.xy), 0).rgb, 1.0);\n}\n", ce = (e, t) => new oe(e, "present", se, t), le = "// one workgroup per visible cluster, one thread per splat; shade() follows, generated with the hooks\n\n// ndc reach past the frustum, so splats centred just outside still cover the edge\nconst GUARD: f32 = 1.3;\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<uniform> plugins: array<vec4f, 16>;\n@group(0) @binding(2) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(3) var<storage, read> colours: array<u32>;\n@group(0) @binding(4) var<storage, read> pages: array<Page>;\n@group(0) @binding(5) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(6) var<storage, read_write> work: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> projected: array<Projected>;\n// keys in [0, capacity), values in [capacity, 2 capacity)\n@group(0) @binding(8) var<storage, read_write> sort: array<u32>;\n\nvar<workgroup> visible: u32;\nvar<workgroup> kept: atomic<u32>;\nvar<workgroup> base: u32;\n\n// i8 over 127, sign-extended by extractBits on i32\nfn code(word: u32, bit: u32) -> f32 {\n return f32(extractBits(i32(word), bit, 8u)) / 127.0;\n}\n\n// smallest three: w x y z with the largest at the stored index\nfn rotation(g: vec4u) -> vec4f {\n let v = (vec3f(fraction(g.z, 0u), fraction(g.z, 8u), fraction(g.z, 16u)) - 0.5) * sqrt(2.0);\n let big = sqrt(max(0.0, 1.0 - dot(v, v)));\n switch extractBits(g.y, 24u, 8u) {\n case 0u: {\n return normalize(vec4f(big, v));\n }\n case 1u: {\n return normalize(vec4f(v.x, big, v.yz));\n }\n case 2u: {\n return normalize(vec4f(v.xy, big, v.z));\n }\n default: {\n return normalize(vec4f(v, big));\n }\n }\n}\n\nfn rotate(q: vec4f) -> mat3x3f {\n let w = q.x;\n let x = q.y;\n let y = q.z;\n let z = q.w;\n return mat3x3f(\n 1.0 - 2.0 * (y * y + z * z), 2.0 * (x * y + w * z), 2.0 * (x * z - w * y),\n 2.0 * (x * y - w * z), 1.0 - 2.0 * (x * x + z * z), 2.0 * (y * z + w * x),\n 2.0 * (x * z + w * y), 2.0 * (y * z - w * x), 1.0 - 2.0 * (x * x + y * y)\n );\n}\n\n// false when splat t of the cluster cannot show; else its Projected and sort key\nfn shown(cluster: Cluster, t: u32, dest: ptr<function, Projected>, key: ptr<function, u32>) -> bool {\n let page = pages[cluster.page];\n let rec = cluster.slot + t;\n let g = geometry[rec];\n let w0 = colours[rec * 3u];\n let w1 = colours[rec * 3u + 1u];\n let w2 = colours[rec * 3u + 2u];\n let i = cluster.first + t;\n let quadrant = u32(i >= page.q1) + u32(i >= page.q2) + u32(i >= page.q3);\n\n // decode\n var s: Splat;\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n s.position = page.origin + q * page.step;\n s.opacity = fraction(g.y, 16u) * fraction(page.factors, 8u * quadrant);\n let level = vec3f(fraction(g.z, 24u), fraction(g.w, 0u), fraction(g.w, 8u));\n s.scale = exp(mix(page.scaleMin, page.scaleMax, level));\n let dc = mix(page.dcMin, page.dcMax, vec3f(fraction(w0, 0u), fraction(w0, 8u), fraction(w0, 16u)));\n // sh[c][m] at 3c + m, gathered per m across the colours\n let k = page.shScale;\n let m0 = vec3f(code(w0, 24u), code(w1, 16u), code(w2, 8u)) * vec3f(k[0].x, k[0].w, k[1].z);\n let m1 = vec3f(code(w1, 0u), code(w1, 24u), code(w2, 16u)) * vec3f(k[0].y, k[1].x, k[1].w);\n let m2 = vec3f(code(w1, 8u), code(w2, 0u), code(w2, 24u)) * vec3f(k[0].z, k[1].y, k[2].x);\n let d = normalize(s.position - uniforms.camera);\n s.colour = max(0.5 + C0 * dc + C1 * (-d.y * m0 + d.z * m1 - d.x * m2), vec3f(0.0));\n s.depth = -(uniforms.view * vec4f(s.position, 1.0)).z;\n\n shade(&s);\n if (s.opacity < 1.0 / 255.0) {\n return false;\n }\n\n // project\n let viewPos = (uniforms.view * vec4f(s.position, 1.0)).xyz;\n let depth = -viewPos.z;\n if (depth < uniforms.near || depth > uniforms.far) {\n return false;\n }\n let clip = uniforms.proj * vec4f(viewPos, 1.0);\n let ndc = clip.xy / clip.w;\n if (any(abs(ndc) > vec2f(GUARD))) {\n return false;\n }\n\n // ewa: view-space covariance wm wm^T through the jacobian of the pixel projection\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * s.scale.x, r[1] * s.scale.y, r[2] * s.scale.z);\n let w = mat3x3f(uniforms.view[0].xyz, uniforms.view[1].xyz, uniforms.view[2].xyz);\n let wm = w * m;\n let focal = uniforms.focal;\n let j0 = vec3f(focal.x / depth, 0.0, focal.x * viewPos.x / (depth * depth));\n let j1 = vec3f(0.0, focal.y / depth, focal.y * viewPos.y / (depth * depth));\n let u = j0 * wm;\n let v = j1 * wm;\n let a = dot(u, u) + uniforms.lowPass;\n let b = dot(u, v);\n let c = dot(v, v) + uniforms.lowPass;\n let mid = 0.5 * (a + c);\n let rad = length(vec2f(0.5 * (a - c), b));\n let major = sqrt(mid + rad);\n if (3.0 * major < 0.5) {\n return false;\n }\n let minor = sqrt(max(mid - rad, 0.0));\n let angle = 0.5 * atan2(2.0 * b, a - c);\n let axis = vec2f(cos(angle), sin(angle));\n // the quad raster draws; a centre inside the guard band can still miss the screen\n let centre = (ndc * 0.5 + 0.5) * uniforms.viewport;\n let extent = reach(s.opacity) * (abs(axis) * major + abs(axis.yx) * minor);\n if (any(centre + extent < vec2f(0.0)) || any(centre - extent > uniforms.viewport)) {\n return false;\n }\n\n *dest = Projected(\n centre,\n vec2u(pack2x16float(axis * major), pack2x16float(vec2f(-axis.y, axis.x) * minor)),\n vec2u(pack2x16float(s.colour.rg), pack2x16float(vec2f(s.colour.b, s.opacity)))\n );\n let span = clamp(log(depth / uniforms.near) / log(uniforms.far / uniforms.near), 0.0, 1.0);\n *key = u32((1.0 - span) * f32((1u << KEY_BITS) - 1u));\n return true;\n}\n\n@compute @workgroup_size(256)\nfn project(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n if (t == 0u) {\n visible = atomicLoad(&work[WORK_VISIBLE]);\n }\n let index = wid.y * GROUPS_X + wid.x;\n if (index >= workgroupUniformLoad(&visible)) {\n return;\n }\n let cluster = clusters[atomicLoad(&work[WORK_LIST + index])];\n var splat: Projected;\n var key = 0u;\n var keep = false;\n if (t < cluster.count) {\n keep = shown(cluster, t, &splat, &key);\n }\n\n // one global atomic per workgroup\n var rank = 0u;\n if (keep) {\n rank = atomicAdd(&kept, 1u);\n }\n workgroupBarrier();\n if (t == 0u) {\n base = atomicAdd(&work[WORK_PROJECTED], atomicLoad(&kept));\n }\n let i = workgroupUniformLoad(&base) + rank;\n let capacity = arrayLength(&projected);\n if (keep && i < capacity) {\n projected[i] = splat;\n sort[i] = key;\n sort[capacity + i] = i;\n }\n}\n", ue = class {
467
+ #e;
468
+ #t;
469
+ #n;
470
+ #r = [];
471
+ #i;
472
+ #a;
473
+ constructor(e, t, n) {
474
+ this.#e = e, this.#a = t;
475
+ let r = E(e, "project", GPUShaderStage.COMPUTE, [
476
+ "uniform",
477
+ "uniform",
478
+ "read-only-storage",
479
+ "read-only-storage",
480
+ "read-only-storage",
481
+ "read-only-storage",
482
+ "storage",
483
+ "storage",
484
+ "storage"
485
+ ]);
486
+ this.#t = e.createPipelineLayout({ bindGroupLayouts: [r] });
487
+ let i = [
488
+ n.uniforms,
489
+ n.plugins,
490
+ t.geometry,
491
+ t.colour,
492
+ t.pages,
493
+ t.clusters,
494
+ n.work,
495
+ n.projected,
496
+ n.sort
497
+ ];
498
+ this.#i = D(e, "project", r, i);
499
+ }
500
+ hooks(e) {
501
+ this.#r = e, this.#n = void 0;
502
+ }
503
+ encode(e, t) {
504
+ let n = Math.max(1, this.#a.listed), r = e.beginComputePass({
505
+ label: "project",
506
+ timestampWrites: t
507
+ });
508
+ r.setPipeline(this.#n ??= this.#o()), r.setBindGroup(0, this.#i), r.dispatchWorkgroups(...d(n)), r.end();
509
+ }
510
+ #o() {
511
+ let e = this.#r, t = e.map(({ shade: e, slot: t }) => {
512
+ let n = Array.from({ length: e.uniforms }, (e, n) => `plugins[${t + n}]`);
513
+ return `\t${e.name}(s, array<vec4f, ${e.uniforms}>(${n.join(", ")}));`;
514
+ }), n = [
515
+ O,
516
+ le,
517
+ ...e.map(({ shade: e }) => e.wgsl),
518
+ "fn shade(s: ptr<function, Splat>) {",
519
+ ...t,
520
+ "}"
521
+ ].join("\n"), r = this.#e.createShaderModule({
522
+ label: "project",
523
+ code: n
524
+ });
525
+ return this.#e.createComputePipeline({
526
+ label: "project",
527
+ layout: this.#t,
528
+ compute: {
529
+ module: r,
530
+ entryPoint: "project"
531
+ }
532
+ });
533
+ }
534
+ }, de = "// sorted splats as screen quads, premultiplied over what lies behind them\n\n// word offsets of the sorted keys and values in the sort buffer\nstruct Sorted {\n keys: u32,\n values: u32,\n}\n\nstruct Corner {\n @builtin(position) position: vec4f,\n // offset from the centre in sigmas\n @location(0) uv: vec2f,\n @location(1) colour: vec4f,\n}\n\n@group(0) @binding(0) var<uniform> frame: FrameUniforms;\n@group(0) @binding(1) var<storage, read> projected: array<Projected>;\n@group(0) @binding(2) var<storage, read> sort: array<u32>;\n@group(0) @binding(3) var<uniform> sorted: Sorted;\n\nfn corner(v: u32, i: u32) -> Corner {\n let p = projected[sort[sorted.values + i]];\n let major = unpack2x16float(p.axes.x);\n let minor = unpack2x16float(p.axes.y);\n let colour = vec4f(unpack2x16float(p.colour.x), unpack2x16float(p.colour.y));\n let r = reach(colour.a);\n let uv = vec2f(f32(v & 1u), f32(v >> 1u)) * 2.0 - 1.0;\n let pixel = p.centre + (major * uv.x + minor * uv.y) * r;\n return Corner(vec4f(pixel / frame.viewport * 2.0 - 1.0, 0.0, 1.0), uv * r, colour);\n}\n\nfn alpha(uv: vec2f, opacity: f32) -> f32 {\n return opacity * exp(-0.5 * dot(uv, uv));\n}\n\n@vertex\nfn vsColour(@builtin(vertex_index) v: u32, @builtin(instance_index) i: u32) -> Corner {\n return corner(v, i);\n}\n\n@vertex\nfn vsDepth(@builtin(vertex_index) v: u32, @builtin(instance_index) i: u32) -> Corner {\n var c = corner(v, i);\n // inverse of the key: the span from near to far in log depth\n c.position.z = 1.0 - f32(sort[sorted.keys + i]) / f32((1u << KEY_BITS) - 1u);\n return c;\n}\n\n@fragment\nfn fs(c: Corner) -> @location(0) vec4f {\n let a = alpha(c.uv, c.colour.a);\n if (a < 1.0 / 255.0) {\n discard;\n }\n return vec4f(c.colour.rgb * a, a);\n}\n", fe = "rgb10a2unorm", pe = "depth16unorm", me = {
535
+ srcFactor: "one",
536
+ dstFactor: "one-minus-src-alpha"
537
+ }, he = class {
538
+ #e;
539
+ #t;
540
+ #n;
541
+ #r;
542
+ #i;
543
+ constructor(e, t, n) {
544
+ this.#e = t.work, this.#t = e.createBuffer({
545
+ label: "raster sorted",
546
+ size: 16,
547
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
548
+ });
549
+ let r = new Uint32Array([
550
+ n.keys / 4,
551
+ n.values / 4,
552
+ 0,
553
+ 0
554
+ ]);
555
+ e.queue.writeBuffer(this.#t, 0, r);
556
+ let i = E(e, "raster", GPUShaderStage.VERTEX, [
557
+ "uniform",
558
+ "read-only-storage",
559
+ "read-only-storage",
560
+ "uniform"
561
+ ]);
562
+ this.#i = D(e, "raster", i, [
563
+ t.uniforms,
564
+ t.projected,
565
+ t.sort,
566
+ this.#t
567
+ ]);
568
+ let a = e.createShaderModule({
569
+ label: "raster",
570
+ code: O + de
571
+ }), o = e.createPipelineLayout({ bindGroupLayouts: [i] }), s = (t, n) => e.createRenderPipeline({
572
+ label: `raster ${t}`,
573
+ layout: o,
574
+ vertex: {
575
+ module: a,
576
+ entryPoint: `vs${t}`
577
+ },
578
+ fragment: {
579
+ module: a,
580
+ entryPoint: "fs",
581
+ targets: [{
582
+ format: fe,
583
+ blend: {
584
+ color: me,
585
+ alpha: me
586
+ }
587
+ }]
588
+ },
589
+ primitive: { topology: "triangle-strip" },
590
+ depthStencil: n
591
+ });
592
+ this.#n = s("Colour"), this.#r = s("Depth", {
593
+ format: pe,
594
+ depthWriteEnabled: !0,
595
+ depthCompare: "always"
596
+ });
597
+ }
598
+ encode(e, t, n, r, i) {
599
+ let a = e.beginRenderPass({
600
+ label: "raster",
601
+ colorAttachments: [{
602
+ view: t,
603
+ loadOp: "clear",
604
+ clearValue: [...r, 1],
605
+ storeOp: "store"
606
+ }],
607
+ depthStencilAttachment: n ? {
608
+ view: n,
609
+ depthClearValue: 1,
610
+ depthLoadOp: "clear",
611
+ depthStoreOp: "store"
612
+ } : void 0,
613
+ timestampWrites: i
614
+ });
615
+ a.setPipeline(n ? this.#r : this.#n), a.setBindGroup(0, this.#i), a.drawIndirect(this.#e, l.drawArgs * 4), a.end();
616
+ }
617
+ destroy() {
618
+ this.#t.destroy();
619
+ }
620
+ };
621
+ function ge(e, t, n, r, i, a, o) {
622
+ let { width: s, height: c } = n, l = Math.ceil(s * 2 / 256) * 256, u = e.createBuffer({
623
+ label: "pick",
624
+ size: l * c,
625
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
626
+ });
627
+ t.copyTextureToBuffer({ texture: n }, {
628
+ buffer: u,
629
+ bytesPerRow: l
630
+ }, [s, c]);
631
+ let d = (e, t) => Math.min(Math.max(Math.floor(e), 0), t - 1), f = d(i, c) * l / 2 + d(r, s);
632
+ return () => u.mapAsync(GPUMapMode.READ).then(() => {
633
+ let e = new Uint16Array(u.getMappedRange())[f] / 65535;
634
+ return e < 1 ? a * (o / a) ** e : null;
635
+ }, () => null).finally(() => u.destroy());
636
+ }
637
+ //#endregion
638
+ //#region src/engine/gpu/sort.wgsl?raw
639
+ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan, a stable scatter; no spin-waits\n\nconst THREADS: u32 = 256u;\nconst ITEMS: u32 = 4u;\nconst BLOCK: u32 = 1024u;\n// blocks per scan chunk\nconst CHUNK: u32 = 64u;\nconst DIGITS: u32 = 256u;\n\nstruct SortParams {\n shift: u32,\n // word offsets of the keys read and written; their values follow capacity words later\n src: u32,\n dst: u32,\n capacity: u32,\n // word offsets in the work buffer\n projected: u32,\n drawArgs: u32,\n}\n\nstruct SortState {\n count: u32,\n blocks: u32,\n chunks: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: SortParams;\n@group(0) @binding(1) var<storage, read_write> data: array<u32>;\n// block-major: count, then exclusive global offset, of digit d in block b at b DIGITS + d\n@group(0) @binding(2) var<storage, read_write> hist: array<u32>;\n// chunk-major sums of hist, then their exclusive global offsets\n@group(0) @binding(3) var<storage, read_write> sums: array<u32>;\n@group(0) @binding(4) var<storage, read> state: SortState;\n@group(0) @binding(5) var<storage, read_write> stateOut: SortState;\n@group(0) @binding(6) var<storage, read_write> work: array<u32>;\n\nvar<workgroup> bins: array<atomic<u32>, DIGITS>;\nvar<workgroup> totals: array<u32, DIGITS>;\nvar<workgroup> sk: array<u32, BLOCK>;\nvar<workgroup> sv: array<u32, BLOCK>;\nvar<workgroup> counts: array<vec4u, THREADS>;\nvar<workgroup> starts: array<u32, DIGITS>;\nvar<workgroup> offsets: array<u32, DIGITS>;\n\nfn digit(key: u32) -> u32 {\n return (key >> params.shift) & 0xffu;\n}\n\n@compute @workgroup_size(1)\nfn prepare() {\n let count = min(work[params.projected], params.capacity);\n let blocks = (count + BLOCK - 1u) / BLOCK;\n work[params.drawArgs] = 4u;\n work[params.drawArgs + 1u] = count;\n work[params.drawArgs + 2u] = 0u;\n work[params.drawArgs + 3u] = 0u;\n stateOut = SortState(count, blocks, (blocks + CHUNK - 1u) / CHUNK);\n}\n\n@compute @workgroup_size(THREADS)\nfn histogram(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n let block = wid.y * groups.x + wid.x;\n if (block >= state.blocks) {\n return;\n }\n atomicStore(&bins[t], 0u);\n workgroupBarrier();\n let head = block * BLOCK;\n for (var k = 0u; k < ITEMS; k++) {\n let i = head + k * THREADS + t;\n if (i < state.count) {\n atomicAdd(&bins[digit(data[params.src + i])], 1u);\n }\n }\n workgroupBarrier();\n hist[block * DIGITS + t] = atomicLoad(&bins[t]);\n}\n\n@compute @workgroup_size(DIGITS)\nfn reduce(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let end = min((wid.x + 1u) * CHUNK, state.blocks);\n var sum = 0u;\n for (var b = wid.x * CHUNK; b < end; b++) {\n sum += hist[b * DIGITS + t];\n }\n sums[wid.x * DIGITS + t] = sum;\n}\n\n@compute @workgroup_size(DIGITS)\nfn top(@builtin(local_invocation_index) t: u32) {\n var run = 0u;\n for (var c = 0u; c < state.chunks; c++) {\n let x = sums[c * DIGITS + t];\n sums[c * DIGITS + t] = run;\n run += x;\n }\n totals[t] = run;\n workgroupBarrier();\n for (var o = 1u; o < DIGITS; o *= 2u) {\n var x = 0u;\n if (t >= o) {\n x = totals[t - o];\n }\n workgroupBarrier();\n totals[t] += x;\n workgroupBarrier();\n }\n let base = totals[t] - run;\n for (var c = 0u; c < state.chunks; c++) {\n sums[c * DIGITS + t] += base;\n }\n}\n\n@compute @workgroup_size(DIGITS)\nfn down(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let end = min((wid.x + 1u) * CHUNK, state.blocks);\n var run = sums[wid.x * DIGITS + t];\n for (var b = wid.x * CHUNK; b < end; b++) {\n let x = hist[b * DIGITS + t];\n hist[b * DIGITS + t] = run;\n run += x;\n }\n}\n\n@compute @workgroup_size(THREADS)\nfn scatter(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n let block = wid.y * groups.x + wid.x;\n if (block >= state.blocks) {\n return;\n }\n let head = block * BLOCK;\n let valid = min(BLOCK, state.count - head);\n // padding has digit 255 at every shift, so it sorts behind the valid keys and is never written\n for (var k = 0u; k < ITEMS; k++) {\n let i = k * THREADS + t;\n var key = 0xffffffffu;\n var value = 0u;\n if (i < valid) {\n key = data[params.src + head + i];\n value = data[params.src + params.capacity + head + i];\n }\n sk[i] = key;\n sv[i] = value;\n }\n offsets[t] = hist[block * DIGITS + t];\n workgroupBarrier();\n\n // stable local sort by the digit, two bits a split; thread t owns positions t ITEMS + k\n for (var bit = 0u; bit < 8u; bit += 2u) {\n var keys: array<u32, ITEMS>;\n var values: array<u32, ITEMS>;\n var before: array<u32, ITEMS>;\n var mine = vec4u(0u);\n for (var k = 0u; k < ITEMS; k++) {\n keys[k] = sk[t * ITEMS + k];\n values[k] = sv[t * ITEMS + k];\n let b = (keys[k] >> (params.shift + bit)) & 3u;\n before[k] = mine[b];\n mine[b] += 1u;\n }\n counts[t] = mine;\n workgroupBarrier();\n for (var o = 1u; o < THREADS; o *= 2u) {\n var x = vec4u(0u);\n if (t >= o) {\n x = counts[t - o];\n }\n workgroupBarrier();\n counts[t] += x;\n workgroupBarrier();\n }\n let total = counts[THREADS - 1u];\n let prior = counts[t] - mine;\n let base = vec4u(0u, total.x, total.x + total.y, total.x + total.y + total.z);\n for (var k = 0u; k < ITEMS; k++) {\n let b = (keys[k] >> (params.shift + bit)) & 3u;\n let p = base[b] + prior[b] + before[k];\n sk[p] = keys[k];\n sv[p] = values[k];\n }\n workgroupBarrier();\n }\n\n for (var k = 0u; k < ITEMS; k++) {\n let i = t * ITEMS + k;\n let d = digit(sk[i]);\n if (i == 0u || digit(sk[i - 1u]) != d) {\n starts[d] = i;\n }\n }\n workgroupBarrier();\n for (var k = 0u; k < ITEMS; k++) {\n let i = k * THREADS + t;\n if (i < valid) {\n let d = digit(sk[i]);\n let slot = offsets[d] + i - starts[d];\n data[params.dst + slot] = sk[i];\n data[params.dst + params.capacity + slot] = sv[i];\n }\n }\n}\n", ve = 1024, ye = 64, be = 256, N = 3, P = 256, xe = 32, Se = class {
640
+ keys;
641
+ values;
642
+ bytes;
643
+ #e;
644
+ #t;
645
+ #n;
646
+ #r;
647
+ #i;
648
+ #a;
649
+ #o;
650
+ constructor(e, t) {
651
+ let { capacity: n } = t;
652
+ this.keys = n * 8, this.values = n * 12;
653
+ let r = Math.max(1, Math.ceil(n / ve));
654
+ this.#a = d(r), this.#o = Math.ceil(r / ye);
655
+ let i = (t, n, r) => e.createBuffer({
656
+ label: t,
657
+ size: n,
658
+ usage: r
659
+ }), a = GPUBufferUsage.STORAGE, o = i("sort params", N * P, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), s = i("sort histograms", r * be * 4, a), c = i("sort chunk sums", this.#o * be * 4, a), u = i("sort state", 12, a);
660
+ this.#e = [
661
+ o,
662
+ s,
663
+ c,
664
+ u
665
+ ], this.bytes = this.#e.reduce((e, t) => e + t.size, 0);
666
+ let f = new Uint32Array(N * P / 4);
667
+ for (let e = 0; e < N; e++) {
668
+ let [t, r] = e % 2 ? [2 * n, 0] : [0, 2 * n];
669
+ f.set([
670
+ 8 * e,
671
+ t,
672
+ r,
673
+ n,
674
+ l.projected,
675
+ l.drawArgs
676
+ ], e * P / 4);
677
+ }
678
+ e.queue.writeBuffer(o, 0, f);
679
+ let p = (e, t) => ({
680
+ binding: e,
681
+ visibility: GPUShaderStage.COMPUTE,
682
+ buffer: { type: t }
683
+ }), m = E(e, "sort", GPUShaderStage.COMPUTE, [
684
+ "uniform",
685
+ "storage",
686
+ "storage",
687
+ "storage",
688
+ "read-only-storage"
689
+ ]), h = e.createBindGroupLayout({
690
+ label: "sort prepare",
691
+ entries: [
692
+ p(0, "uniform"),
693
+ p(5, "storage"),
694
+ p(6, "storage")
695
+ ]
696
+ }), g = e.createShaderModule({
697
+ label: "sort",
698
+ code: O + _e
699
+ }), _ = (t, n) => e.createComputePipeline({
700
+ label: `sort ${t}`,
701
+ layout: e.createPipelineLayout({ bindGroupLayouts: [n] }),
702
+ compute: {
703
+ module: g,
704
+ entryPoint: t
705
+ }
706
+ });
707
+ this.#t = _("prepare", h), this.#n = [
708
+ "histogram",
709
+ "reduce",
710
+ "top",
711
+ "down",
712
+ "scatter"
713
+ ].map((e) => _(e, m));
714
+ let v = (e) => ({
715
+ buffer: o,
716
+ offset: e * P,
717
+ size: xe
718
+ });
719
+ this.#r = e.createBindGroup({
720
+ label: "sort prepare",
721
+ layout: h,
722
+ entries: [
723
+ {
724
+ binding: 0,
725
+ resource: v(0)
726
+ },
727
+ {
728
+ binding: 5,
729
+ resource: { buffer: u }
730
+ },
731
+ {
732
+ binding: 6,
733
+ resource: { buffer: t.work }
734
+ }
735
+ ]
736
+ }), this.#i = Array.from({ length: N }, (n, r) => e.createBindGroup({
737
+ label: `sort pass ${r}`,
738
+ layout: m,
739
+ entries: [
740
+ {
741
+ binding: 0,
742
+ resource: v(r)
743
+ },
744
+ {
745
+ binding: 1,
746
+ resource: { buffer: t.sort }
747
+ },
748
+ {
749
+ binding: 2,
750
+ resource: { buffer: s }
751
+ },
752
+ {
753
+ binding: 3,
754
+ resource: { buffer: c }
755
+ },
756
+ {
757
+ binding: 4,
758
+ resource: { buffer: u }
759
+ }
760
+ ]
761
+ }));
762
+ }
763
+ encode(e, t) {
764
+ let [n, r, i, a, o] = this.#n, s = this.#a, c = e.beginComputePass({
765
+ label: "sort",
766
+ timestampWrites: t
767
+ });
768
+ c.setPipeline(this.#t), c.setBindGroup(0, this.#r), c.dispatchWorkgroups(1);
769
+ for (let e of this.#i) c.setBindGroup(0, e), c.setPipeline(n), c.dispatchWorkgroups(...s), c.setPipeline(r), c.dispatchWorkgroups(this.#o), c.setPipeline(i), c.dispatchWorkgroups(1), c.setPipeline(a), c.dispatchWorkgroups(this.#o), c.setPipeline(o), c.dispatchWorkgroups(...s);
770
+ c.end();
771
+ }
772
+ destroy() {
773
+ for (let e of this.#e) e.destroy();
774
+ }
775
+ }, Ce = class {
776
+ ms = {};
777
+ #e;
778
+ #t;
779
+ #n;
780
+ #r;
781
+ #i = !1;
782
+ #a = !1;
783
+ constructor(e, t, n) {
784
+ if (this.#e = n, !t) return;
785
+ let r = n.length * 2;
786
+ this.#t = e.createQuerySet({
787
+ label: "timing",
788
+ type: "timestamp",
789
+ count: r
790
+ }), this.#n = e.createBuffer({
791
+ label: "timing resolved",
792
+ size: r * 8,
793
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
794
+ }), this.#r = e.createBuffer({
795
+ label: "timing readback",
796
+ size: r * 8,
797
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
798
+ });
799
+ }
800
+ writes(e) {
801
+ let t = this.#t;
802
+ if (!t) return;
803
+ let n = this.#e.indexOf(e);
804
+ return {
805
+ querySet: t,
806
+ beginningOfPassWriteIndex: 2 * n,
807
+ endOfPassWriteIndex: 2 * n + 1
808
+ };
809
+ }
810
+ resolve(e) {
811
+ !this.#t || !this.#n || !this.#r || this.#i || (e.resolveQuerySet(this.#t, 0, this.#e.length * 2, this.#n, 0), e.copyBufferToBuffer(this.#n, 0, this.#r, 0, this.#r.size), this.#a = !0);
812
+ }
813
+ read() {
814
+ let e = this.#r;
815
+ !e || this.#i || !this.#a || (this.#i = !0, this.#a = !1, e.mapAsync(GPUMapMode.READ).then(() => {
816
+ let t = new BigUint64Array(e.getMappedRange());
817
+ this.#e.forEach((e, n) => {
818
+ let [r, i] = [t[2 * n], t[2 * n + 1]];
819
+ this.ms[e] = i > r ? Number(i - r) / 1e6 : 0;
820
+ }), e.unmap();
821
+ }).catch(() => {}).finally(() => this.#i = !1));
822
+ }
823
+ destroy() {
824
+ this.#t?.destroy(), this.#n?.destroy(), this.#r?.destroy();
825
+ }
826
+ }, we = [
827
+ "cull",
828
+ "project",
829
+ "sort",
830
+ "raster",
831
+ "heights",
832
+ "post"
833
+ ], F = {
834
+ view: 0,
835
+ proj: 16,
836
+ viewProj: 32,
837
+ planes: 48,
838
+ camera: 72,
839
+ time: 75,
840
+ viewport: 76,
841
+ focal: 78,
842
+ near: 80,
843
+ far: 81,
844
+ lowPass: 82,
845
+ clusters: 83
846
+ }, Te = class {
847
+ #e;
848
+ #t;
849
+ #n;
850
+ #r;
851
+ #i;
852
+ #a;
853
+ #o;
854
+ #s;
855
+ #c;
856
+ #l;
857
+ #u;
858
+ #d;
859
+ #f = /* @__PURE__ */ new Float32Array(84);
860
+ #p = new Uint32Array(this.#f.buffer);
861
+ #m = /* @__PURE__ */ new Float32Array(16);
862
+ #h = /* @__PURE__ */ new Float32Array(64);
863
+ #g = [];
864
+ #_ = [];
865
+ #v = {};
866
+ #y = /* @__PURE__ */ new WeakMap();
867
+ #b;
868
+ #x;
869
+ #S;
870
+ #C = !1;
871
+ #w = 0;
872
+ constructor(e, t, n, r) {
873
+ let { device: i } = e;
874
+ this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = T(i, r, n.slots), this.#a = new j(i, n, this.#i), this.#o = new ue(i, n, this.#i), this.#s = new Se(i, this.#i), this.#c = new he(i, this.#i, this.#s), this.#u = new ie(i, n), this.#d = new Ce(i, e.timestamps, we), this.#S = i.createBuffer({
875
+ label: "drawn readback",
876
+ size: 4,
877
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
878
+ }), this.#b = Math.max(1, t.canvas.width), this.#x = Math.max(1, t.canvas.height);
879
+ }
880
+ shade(e) {
881
+ if (this.#g.reduce((e, { shade: t }) => e + t.uniforms, 0) + e.uniforms > 16) throw Error("Shade hooks may use 16 uniform slots in all.");
882
+ let t = {
883
+ shade: e,
884
+ slot: 0
885
+ };
886
+ return this.#g.push(t), this.#T(), () => {
887
+ let e = this.#g.indexOf(t);
888
+ e < 0 || (this.#g.splice(e, 1), this.#T());
889
+ };
890
+ }
891
+ post(e) {
892
+ let t = {
893
+ post: e,
894
+ pass: e.setup(this.#e, this.#n)
895
+ }, n = e.order ?? 0, r = this.#_.findIndex(({ post: e }) => (e.order ?? 0) > n);
896
+ return this.#_.splice(r < 0 ? this.#_.length : r, 0, t), () => {
897
+ let e = this.#_.indexOf(t);
898
+ e < 0 || (this.#_.splice(e, 1), t.pass.destroy());
899
+ };
900
+ }
901
+ resize(e, t) {
902
+ (e !== this.#b || t !== this.#x) && (this.#b = e, this.#x = t, this.#A());
903
+ }
904
+ render(e, t, n, r, i) {
905
+ let a = this.#e, o = this.#d, s = this.#_, c = this.#O(this.#D("colour", fe)), u = r.length > 0 || s.some(({ post: e }) => e.depth), d = this.#k("depth", pe, u), f = d ? this.#O(d) : null, p = [this.#k("ping", this.#n, s.length > 1), this.#k("pong", this.#n, s.length > 2)];
906
+ this.#E(e, t);
907
+ let m = a.createCommandEncoder({ label: "frame" });
908
+ m.clearBuffer(this.#i.work, 0, l.list * 4), this.#a.encode(m, o.writes("cull")), this.#o.encode(m, o.writes("project")), this.#s.encode(m, o.writes("sort")), this.#c.encode(m, c, f, n, o.writes("raster"));
909
+ let h = d ? r.map(({ x: t, y: n, resolve: r }) => ({
910
+ resolve: r,
911
+ read: ge(a, m, d, t, n, e.near, e.far)
912
+ })) : [], g = i.map(({ x: e, y: t, cells: n, resolve: r }, i) => ({
913
+ resolve: r,
914
+ read: this.#u.encode(m, e, t, n, i ? void 0 : o.writes("heights"))
915
+ })), _ = o.writes("post");
916
+ if (_) {
917
+ let { querySet: e, beginningOfPassWriteIndex: t } = _;
918
+ m.beginComputePass({ timestampWrites: {
919
+ querySet: e,
920
+ beginningOfPassWriteIndex: t
921
+ } }).end();
922
+ }
923
+ let v = this.#t.getCurrentTexture().createView();
924
+ if (!s.length) this.#l ??= ce(a, this.#n), this.#l.encode(m, [c], v);
925
+ else {
926
+ let t = c;
927
+ s.forEach(({ post: n, pass: r }, i) => {
928
+ let a = i === s.length - 1 ? v : this.#O(p[i % 2]);
929
+ r.run(m, e, t, n.depth ? f : null, a), t = a;
930
+ });
931
+ }
932
+ if (_) {
933
+ let { querySet: e, endOfPassWriteIndex: t } = _;
934
+ m.beginComputePass({ timestampWrites: {
935
+ querySet: e,
936
+ endOfPassWriteIndex: t
937
+ } }).end();
938
+ }
939
+ o.resolve(m);
940
+ let y = !this.#C;
941
+ y && m.copyBufferToBuffer(this.#i.work, l.projected * 4, this.#S, 0, 4), a.queue.submit([m.finish()]), o.read(), y && this.#j();
942
+ for (let { resolve: e, read: t } of h) t().then(e);
943
+ for (let { resolve: e, read: t } of g) t().then(e);
944
+ return a.queue.onSubmittedWorkDone();
945
+ }
946
+ stats() {
947
+ let e = { ...this.#d.ms }, t = this.#i.bytes + this.#s.bytes;
948
+ for (let e of Object.values(this.#v)) e && (t += e.width * e.height * (e.format === "depth16unorm" ? 2 : 4));
949
+ return {
950
+ gpuMs: Object.values(e).reduce((e, t) => e + t, 0),
951
+ passes: e,
952
+ drawn: this.#w,
953
+ bytes: t
954
+ };
955
+ }
956
+ destroy() {
957
+ for (let { pass: e } of this.#_.splice(0)) e.destroy();
958
+ this.#A(), this.#i.destroy(), this.#s.destroy(), this.#c.destroy(), this.#d.destroy(), this.#S.destroy();
959
+ }
960
+ #T() {
961
+ let e = 0;
962
+ for (let t of this.#g) t.slot = e, e += t.shade.uniforms;
963
+ this.#o.hooks(this.#g);
964
+ }
965
+ #E(e, t) {
966
+ let n = this.#f, [r, i] = [this.#b, this.#x];
967
+ n.set(e.view, F.view), n.set(e.proj, F.proj), n.set(S(this.#m, e.proj, e.view), F.viewProj), n.set(t, F.planes), n.set(e.camera.subarray(0, 3), F.camera), n[F.time] = e.time, n.set([r, i], F.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], F.focal), n[F.near] = e.near, n[F.far] = e.far, n[F.lowPass] = f, this.#p[F.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
968
+ for (let { shade: t, slot: n } of this.#g) t.update(e, this.#h.subarray(n * 4, (n + t.uniforms) * 4));
969
+ this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#h);
970
+ }
971
+ #D(e, t) {
972
+ let n = this.#v[e];
973
+ return n || (n = this.#e.createTexture({
974
+ label: e,
975
+ size: [this.#b, this.#x],
976
+ format: t,
977
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
978
+ }), this.#v[e] = n), n;
979
+ }
980
+ #O(e) {
981
+ let t = this.#y.get(e);
982
+ return t || this.#y.set(e, t = e.createView()), t;
983
+ }
984
+ #k(e, t, n) {
985
+ if (n) return this.#D(e, t);
986
+ this.#v[e]?.destroy(), delete this.#v[e];
987
+ }
988
+ #A() {
989
+ for (let e of Object.values(this.#v)) e?.destroy();
990
+ this.#v = {};
991
+ }
992
+ #j() {
993
+ this.#C = !0;
994
+ let e = this.#S;
995
+ e.mapAsync(GPUMapMode.READ).then(() => {
996
+ let t = new Uint32Array(e.getMappedRange())[0];
997
+ this.#w = Math.min(t, this.#i.capacity), e.unmap();
998
+ }).catch(() => {}).finally(() => this.#C = !1);
999
+ }
1000
+ }, Ee = [
1001
+ [0, 1],
1002
+ [0, -1],
1003
+ [1, 1],
1004
+ [1, -1],
1005
+ [2, 0],
1006
+ [2, -1]
1007
+ ];
1008
+ function De(e, t) {
1009
+ let n = (e, n) => t[n * 4 + e];
1010
+ return Ee.forEach(([t, r], i) => {
1011
+ for (let a = 0; a < 4; a++) e[i * 4 + a] = r ? n(3, a) + r * n(t, a) : n(t, a);
1012
+ let a = Math.hypot(e[i * 4], e[i * 4 + 1], e[i * 4 + 2]) || 1;
1013
+ for (let t = 0; t < 4; t++) e[i * 4 + t] /= a;
1014
+ }), e;
1015
+ }
1016
+ //#endregion
1017
+ //#region src/engine/plan/footprint.ts
1018
+ function Oe(e, t, n, r) {
1019
+ let i = (e * e + e * t + t * t + n * n + n * r + r * r) / 3;
1020
+ return 1 + 15 * Math.max(0, 1 - i) ** 2;
1021
+ }
1022
+ function ke(e, t, n, r, i, a, o, s = 1, c = {
1023
+ pixels: 0,
1024
+ weight: 1
1025
+ }) {
1026
+ let l = (e[0] + e[3]) / 2, u = (e[1] + e[4]) / 2, d = (e[2] + e[5]) / 2, f = (e[3] - e[0]) / 2, p = (e[4] - e[1]) / 2, m = (e[5] - e[2]) / 2, h = t[0] * l + t[4] * u + t[8] * d + t[12], g = t[1] * l + t[5] * u + t[9] * d + t[13], _ = -(t[2] * l + t[6] * u + t[10] * d + t[14]), v = Math.abs(t[0]) * f + Math.abs(t[4]) * p + Math.abs(t[8]) * m, y = Math.abs(t[1]) * f + Math.abs(t[5]) * p + Math.abs(t[9]) * m, b = Math.abs(t[2]) * f + Math.abs(t[6]) * p + Math.abs(t[10]) * m;
1027
+ if (c.pixels = 0, c.weight = 1, _ + b < a || _ - b > o) return c;
1028
+ let x = Math.max(a, _ - b), S = Math.max(a, _ + b), C = i * n / r, w = Math.min((h - v) / x, (h - v) / S) / C, T = Math.max((h + v) / x, (h + v) / S) / C, E = Math.min((g - y) / x, (g - y) / S) / i, D = Math.max((g + y) / x, (g + y) / S) / i;
1029
+ if (T < -s || w > s || D < -s || E > s) return c;
1030
+ let O = Math.max(-s, w), k = Math.min(s, T), A = Math.max(-s, E), j = Math.min(s, D), M = (T - w) * (D - E), ee = (k - O) * (j - A);
1031
+ return M <= 0 || ee <= 0 || (c.pixels = M * n * r / 4, c.weight = Oe(O, k, A, j)), c;
1032
+ }
1033
+ //#endregion
1034
+ //#region src/engine/plan/cut.ts
1035
+ var Ae = 1 / .8 ** 2, je = 1500, Me = 1.1, Ne = class {
1036
+ #e = /* @__PURE__ */ new Map();
1037
+ #t = /* @__PURE__ */ new Map();
1038
+ #n = /* @__PURE__ */ new Float64Array(6);
1039
+ #r = {
1040
+ pixels: 0,
1041
+ weight: 1
1042
+ };
1043
+ plan(e, t, n, r) {
1044
+ let { budget: i, capacity: a, now: o, predicted: s } = r, l = [], u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), p = new Fe(), m = 0, h = 0, g = /* @__PURE__ */ new Set(), _ = /* @__PURE__ */ new Set(), v = (e, t) => {
1045
+ let r = e.row.count;
1046
+ l.push(e), h += c(r), t.shown && (m += r, _.add(e.id)), t.near && g.add(e.id);
1047
+ let i = this.#e.get(e.id), a = i !== void 0, s = t.pixels * t.weight, u = s / Math.max(1, r);
1048
+ t.pixels > 0 && f.set(e.id, u);
1049
+ let d = o - (this.#t.get(e.id) ?? -Infinity) <= je, v = a && !t.shown && d ? i : null;
1050
+ (r < s * (a ? Ae : 1) || v !== null) && Pe(e, n) && p.push({
1051
+ page: e,
1052
+ shown: t.shown,
1053
+ held: v,
1054
+ ratio: u
1055
+ });
1056
+ };
1057
+ for (let n of e.roots) v(n, this.#i(n, t, s));
1058
+ let y = !1;
1059
+ for (; p.size;) {
1060
+ let { page: e, shown: n, held: r } = p.pop(), l = [], f = 0;
1061
+ if (e.children.forEach((e, n) => {
1062
+ if (!e) return;
1063
+ let i = this.#i(e, t, s);
1064
+ i.pixels <= 0 && !((r ?? 0) & 1 << n) || (l.push({
1065
+ child: e,
1066
+ m: i
1067
+ }), f |= 1 << n);
1068
+ }), !l.length) continue;
1069
+ let g = 0, _ = n ? -e.row.count : 0;
1070
+ for (let { child: e, m: t } of l) g += c(e.row.count), t.shown && (_ += e.row.count);
1071
+ if (h + g > a) break;
1072
+ if (_ > 0 && (y || m + _ > i)) {
1073
+ y = !0;
1074
+ continue;
1075
+ }
1076
+ u.set(e.id, f);
1077
+ let b = n ? o : this.#t.get(e.id);
1078
+ b !== void 0 && d.set(e.id, b), n && (m -= e.row.count);
1079
+ for (let { child: e, m: t } of l) v(e, t);
1080
+ }
1081
+ this.#e = u, this.#t = d;
1082
+ let b = l.filter((e) => !u.has(e.id)), x = new Set(u.keys());
1083
+ for (let e of b) x.add(e.id);
1084
+ let S = [];
1085
+ for (let t of e.wanted()) {
1086
+ let e = -1;
1087
+ for (let n of t.over) e = Math.max(e, f.get(n.id) ?? -1);
1088
+ e >= 0 && S.push({
1089
+ wanted: t,
1090
+ rank: e
1091
+ });
1092
+ }
1093
+ S.sort((e, t) => t.rank - e.rank);
1094
+ let C = 0;
1095
+ for (let e of b) _.has(e.id) && !n(e.id) && (C += e.row.count);
1096
+ return {
1097
+ cut: b,
1098
+ load: b.filter((e) => !n(e.id) && (g.has(e.id) || !s && C === 0)),
1099
+ idx: S.map((e) => e.wanted),
1100
+ keep: x,
1101
+ planned: m,
1102
+ missing: C
1103
+ };
1104
+ }
1105
+ #i(e, t, n) {
1106
+ let r = this.#a(e, t, 1).pixels > 0, { pixels: i, weight: a } = this.#a(e, t, Me), o = r;
1107
+ if (n) {
1108
+ let t = this.#a(e, n, Me);
1109
+ t.pixels > i && ({pixels: i, weight: a} = t), o ||= t.pixels > 0 && this.#a(e, n, 1).pixels > 0;
1110
+ }
1111
+ return {
1112
+ shown: r,
1113
+ near: o,
1114
+ pixels: i,
1115
+ weight: a
1116
+ };
1117
+ }
1118
+ #a(e, t, n) {
1119
+ let r = this.#n;
1120
+ for (let n = 0; n < 6; n++) r[n] = e.box[n] - t.origin[n % 3];
1121
+ let { width: i, height: a, tan: o, near: s, far: c } = t;
1122
+ return ke(r, t.view, i, a, o, s, c, n, this.#r);
1123
+ }
1124
+ };
1125
+ function Pe(e, t) {
1126
+ let { children: n } = e;
1127
+ return t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
1128
+ }
1129
+ var Fe = class {
1130
+ #e = [];
1131
+ get size() {
1132
+ return this.#e.length;
1133
+ }
1134
+ push(e) {
1135
+ let t = this.#e;
1136
+ t.push(e);
1137
+ let n = t.length - 1;
1138
+ for (; n > 0;) {
1139
+ let e = n - 1 >> 1;
1140
+ if (!I(t[n], t[e])) break;
1141
+ [t[n], t[e]] = [t[e], t[n]], n = e;
1142
+ }
1143
+ }
1144
+ pop() {
1145
+ let e = this.#e, t = e[0], n = e.pop();
1146
+ if (e.length) {
1147
+ e[0] = n;
1148
+ let t = 0;
1149
+ for (;;) {
1150
+ let n = 2 * t + 1, r = t;
1151
+ if (n < e.length && I(e[n], e[r]) && (r = n), n + 1 < e.length && I(e[n + 1], e[r]) && (r = n + 1), r === t) break;
1152
+ [e[t], e[r]] = [e[r], e[t]], t = r;
1153
+ }
1154
+ }
1155
+ return t;
1156
+ }
1157
+ };
1158
+ function I(e, t) {
1159
+ return e.shown === t.shown ? e.ratio > t.ratio : e.shown;
1160
+ }
1161
+ var L = .25, Ie = class {
1162
+ #e = /* @__PURE__ */ new Map();
1163
+ update(e, t, n, r) {
1164
+ let i = this.#e, a = Le(e, t);
1165
+ for (let [e, r] of i) t(r.page.id) ? r.held || (r.start !== null && n - r.start >= 250 && (r.start = null), a.has(e) || (r.frozen = Be(r, n), r.start = null, r.held = !0)) : i.delete(e);
1166
+ let o = /* @__PURE__ */ new Set();
1167
+ for (let [e, t] of a) {
1168
+ let r = i.get(e);
1169
+ if (r) r.held && (r.held = !1, r.frozen < 255 && (r.start = n - r.frozen / 255 * 250, o.add(r)));
1170
+ else {
1171
+ let r = Re(t, e % 4, n);
1172
+ i.set(e, r), o.add(r);
1173
+ }
1174
+ }
1175
+ let s = -1;
1176
+ for (let e of i.values()) s = Math.max(s, e.level);
1177
+ let l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
1178
+ for (let e of i.values()) if (e.held) {
1179
+ l.set(e.cell, e);
1180
+ for (let t = e.level, n = e.col, r = e.row; t <= s; t++, n >>= 1, r >>= 1) {
1181
+ let i = R(t, n, r), a = u.get(i);
1182
+ a ? a.push(e) : u.set(i, [e]);
1183
+ }
1184
+ }
1185
+ let d = (e) => {
1186
+ let t = [...u.get(e.cell) ?? []];
1187
+ for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= s; n++, r >>= 1, i >>= 1) {
1188
+ let e = l.get(R(n, r, i));
1189
+ e && t.push(e);
1190
+ }
1191
+ return t;
1192
+ }, f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), m = 0, h = 0, g = (e) => {
1193
+ p.has(e) || (p.add(e), h += c(e.row.count));
1194
+ };
1195
+ for (let e of i.values()) if (!(e.held || e.start === null || o.has(e))) {
1196
+ m += e.splats;
1197
+ for (let t of d(e)) f.has(t) || (f.add(t), m += t.splats, g(t.page));
1198
+ }
1199
+ let _ = L * r;
1200
+ for (let e of o) {
1201
+ let t = d(e).filter((e) => !f.has(e)), n = t.reduce((e, t) => e + t.splats, e.splats), r = new Set(t.map((e) => e.page).filter((e) => !p.has(e))), i = [...r].reduce((e, t) => e + c(t.row.count), 0);
1202
+ if (m + n > _ || h + i > _) e.start = null;
1203
+ else {
1204
+ m += n;
1205
+ for (let e of t) f.add(e);
1206
+ for (let e of r) g(e);
1207
+ }
1208
+ }
1209
+ for (let [e, t] of i) t.held && !f.has(t) && i.delete(e);
1210
+ let v = /* @__PURE__ */ new Map(), y = !1;
1211
+ for (let e of i.values()) {
1212
+ (e.held || e.start !== null) && (y = !0);
1213
+ let t = Be(e, n);
1214
+ if (!t) continue;
1215
+ let r = v.get(e.page.id);
1216
+ r ? r.factors = (r.factors | t << 8 * e.q) >>> 0 : v.set(e.page.id, {
1217
+ id: e.page.id,
1218
+ factors: t << 8 * e.q >>> 0
1219
+ });
1220
+ }
1221
+ return {
1222
+ drawn: [...v.values()],
1223
+ fading: y
1224
+ };
1225
+ }
1226
+ };
1227
+ function Le(e, t) {
1228
+ let n = new Set(e), r = /* @__PURE__ */ new Set(), i = [];
1229
+ for (let t of e) for (let e = t; e && !r.has(e); e = e.parent) r.add(e), e.parent || i.push(e);
1230
+ let a = /* @__PURE__ */ new Map(), o = (e) => {
1231
+ for (let i = 0; i < 4; i++) {
1232
+ let s = e.children[i];
1233
+ s && t(s.id) && r.has(s) ? o(s) : (s !== null || n.has(e)) && a.set(e.id * 4 + i, e);
1234
+ }
1235
+ };
1236
+ for (let e of i) t(e.id) && o(e);
1237
+ return a;
1238
+ }
1239
+ function Re(t, n, r) {
1240
+ let i = e * 2 ** t.g, a = t.g - 1, o = 2 * (Math.round(t.unit.e / i) + t.row.i) + (n & 1), s = 2 * (Math.round(t.unit.n / i) + t.row.j) + (n >> 1);
1241
+ return {
1242
+ page: t,
1243
+ q: n,
1244
+ level: a,
1245
+ col: o,
1246
+ row: s,
1247
+ cell: R(a, o, s),
1248
+ splats: ze(t.row, n),
1249
+ start: r,
1250
+ frozen: 0,
1251
+ held: !1
1252
+ };
1253
+ }
1254
+ var R = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1255
+ function ze({ count: e, quadrants: t }, n) {
1256
+ return (n < 3 ? t[n] : e) - (n > 0 ? t[n - 1] : 0);
1257
+ }
1258
+ function Be(e, t) {
1259
+ return e.held ? e.frozen : e.start === null ? 255 : Math.min(255, Math.round((t - e.start) / 250 * 255));
1260
+ }
1261
+ //#endregion
1262
+ //#region src/engine/quality.ts
1263
+ var Ve = 5e5, He = 2073600, Ue = [1, .85];
1264
+ function We(e, t, n, r) {
1265
+ return Math.min(n, Math.sqrt(He / Math.max(1, e * t))) * r;
1266
+ }
1267
+ function z(e, t) {
1268
+ if (!e.length) return 0;
1269
+ let n = [...e].sort((e, t) => e - t);
1270
+ return n[Math.ceil(n.length * t) - 1];
1271
+ }
1272
+ var Ge = class {
1273
+ #e = 0;
1274
+ #t = [];
1275
+ #n = -Infinity;
1276
+ #r = 0;
1277
+ #i = 0;
1278
+ get scale() {
1279
+ return Ue[this.#e];
1280
+ }
1281
+ full() {
1282
+ this.#e = 0, this.#a();
1283
+ }
1284
+ #a() {
1285
+ this.#t = [], this.#r = 0, this.#i = 0, this.#n = -Infinity;
1286
+ }
1287
+ sample(e, t, n) {
1288
+ if (!n || t - this.#n > 250 || !Number.isFinite(e) || e <= 0) return this.#a(), this.#n = t, !1;
1289
+ let r = Math.max(0, t - this.#n);
1290
+ if (this.#n = t, this.#t.push({
1291
+ time: t,
1292
+ ms: e
1293
+ }), this.#t = this.#t.filter((e) => t - e.time <= 1e3), this.#t.length < 20) return !1;
1294
+ let i = z(this.#t.map((e) => e.ms), .9);
1295
+ if (this.#r = i > 20 ? this.#r + r : 0, this.#i = i < 14 ? this.#i + r : 0, this.#r >= 2e3) {
1296
+ if (this.#e < Ue.length - 1) this.#e++;
1297
+ else return !1;
1298
+ } else if (this.#i >= 5e3) {
1299
+ if (this.#e > 0) this.#e--;
1300
+ else return !1;
1301
+ } else return !1;
1302
+ return this.#a(), !0;
1303
+ }
1304
+ }, Ke = class {
1305
+ #e;
1306
+ #t = [];
1307
+ #n = /* @__PURE__ */ new Set();
1308
+ #r = /* @__PURE__ */ new Set();
1309
+ #i = /* @__PURE__ */ new Set();
1310
+ #a = /* @__PURE__ */ new Map();
1311
+ constructor(e) {
1312
+ this.#e = e;
1313
+ }
1314
+ want(e) {
1315
+ this.#t = e, this.#n = new Set(e.map((e) => e.id));
1316
+ }
1317
+ next() {
1318
+ let e = [];
1319
+ for (let t of this.#r) this.#i.has(t) || t.pages.some((e) => this.#n.has(e.id)) || (this.#i.add(t), e.push(t));
1320
+ let t = [];
1321
+ if (this.#r.size >= this.#e.concurrency) return {
1322
+ start: t,
1323
+ abort: e
1324
+ };
1325
+ let n = /* @__PURE__ */ new Map();
1326
+ for (let e of this.#t) {
1327
+ if (this.#a.has(e.id)) continue;
1328
+ let t = n.get(e.pack);
1329
+ t ? t.push(e) : n.set(e.pack, [e]);
1330
+ }
1331
+ for (let e of n.values()) e.sort((e, t) => e.offset - t.offset);
1332
+ for (let e of this.#t) {
1333
+ if (this.#r.size >= this.#e.concurrency) break;
1334
+ if (this.#a.has(e.id)) continue;
1335
+ let r = this.#o(e, n.get(e.pack));
1336
+ for (let e of r.pages) this.#a.set(e.id, r);
1337
+ this.#r.add(r), t.push(r);
1338
+ }
1339
+ return {
1340
+ start: t,
1341
+ abort: e
1342
+ };
1343
+ }
1344
+ done(e) {
1345
+ if (this.#r.delete(e)) {
1346
+ this.#i.delete(e);
1347
+ for (let t of e.pages) this.#a.get(t.id) === e && this.#a.delete(t.id);
1348
+ }
1349
+ }
1350
+ get queued() {
1351
+ let e = 0;
1352
+ for (let t of this.#n) this.#a.has(t) || e++;
1353
+ return e;
1354
+ }
1355
+ get loading() {
1356
+ return this.#a.size;
1357
+ }
1358
+ #o(e, t) {
1359
+ let { gap: n, span: r } = this.#e, i = Math.floor(e.offset / r), a = t.indexOf(e), o = [e], s = e.offset, c = e.offset + e.length;
1360
+ for (let e = a + 1; e < t.length; e++) {
1361
+ let a = t[e];
1362
+ if (this.#a.has(a.id)) continue;
1363
+ let l = Math.max(c, a.offset + a.length);
1364
+ if (a.offset - c > n || l - s > r || Math.floor(a.offset / r) !== i) break;
1365
+ o.push(a), c = l;
1366
+ }
1367
+ for (let e = a - 1; e >= 0; e--) {
1368
+ let a = t[e];
1369
+ if (!this.#a.has(a.id)) {
1370
+ if (s - (a.offset + a.length) > n || c - a.offset > r || Math.floor(a.offset / r) !== i) break;
1371
+ o.unshift(a), s = a.offset;
1372
+ }
1373
+ }
1374
+ return {
1375
+ pack: e.pack,
1376
+ col: e.col,
1377
+ start: s,
1378
+ end: c,
1379
+ window: i,
1380
+ pages: o
1381
+ };
1382
+ }
1383
+ }, qe = {
1384
+ idx: 8,
1385
+ concurrency: 8,
1386
+ gap: 65536,
1387
+ span: 2097152
1388
+ }, Je = 1e3, Ye = 3e4, Xe = 1e3, Ze = 2e3, Qe = class {
1389
+ #e;
1390
+ #t;
1391
+ #n;
1392
+ #r;
1393
+ #i;
1394
+ #a;
1395
+ #o;
1396
+ #s = {
1397
+ cut: [],
1398
+ load: [],
1399
+ idx: [],
1400
+ keep: /* @__PURE__ */ new Set(),
1401
+ planned: 0,
1402
+ missing: 0
1403
+ };
1404
+ #c = /* @__PURE__ */ new Set();
1405
+ #l = [];
1406
+ #u = 0;
1407
+ #d = /* @__PURE__ */ new Set();
1408
+ #f = /* @__PURE__ */ new Map();
1409
+ #p = /* @__PURE__ */ new Map();
1410
+ #m = /* @__PURE__ */ new Map();
1411
+ #h = /* @__PURE__ */ new Map();
1412
+ #g = /* @__PURE__ */ new Set();
1413
+ #_ = /* @__PURE__ */ new Map();
1414
+ #v = [];
1415
+ #y = -Infinity;
1416
+ #b = !1;
1417
+ #x = !1;
1418
+ constructor(e, t, n, r, i, a = qe) {
1419
+ this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new Ke(a);
1420
+ }
1421
+ update(e, t, n) {
1422
+ if (!this.#x) {
1423
+ this.#s = e, this.#c = t, this.#u = n;
1424
+ for (let e of this.#v) this.#_.set(e, n);
1425
+ this.#v = [], this.#S(), this.#l = this.#C(), this.#o.want(this.#l), this.#w(), this.#M();
1426
+ }
1427
+ }
1428
+ get loading() {
1429
+ return this.#d.size + this.#f.size;
1430
+ }
1431
+ get queued() {
1432
+ return this.#o.queued;
1433
+ }
1434
+ get idle() {
1435
+ if (this.#d.size > 0 || this.#f.size > 0 || this.#n.queued > 0) return !1;
1436
+ let { idx: e, load: t } = this.#s;
1437
+ return e.length === 0 && t.every(({ id: e }) => this.#n.holds(e));
1438
+ }
1439
+ destroy() {
1440
+ this.#x = !0;
1441
+ for (let e of this.#f.values()) e.abort();
1442
+ this.#f.clear(), this.#d.clear();
1443
+ for (let e of this.#h.values()) clearTimeout(e);
1444
+ this.#h.clear();
1445
+ }
1446
+ #S() {
1447
+ if (!this.#b) for (let { path: e } of this.#s.idx) {
1448
+ if (this.#d.size >= this.#a.idx) break;
1449
+ this.#d.has(e) || this.#F(e) || (this.#d.add(e), this.#t.idx(e).then((t) => {
1450
+ this.#x || (this.#d.delete(e), this.#k(e), this.#v.push(this.#e.add(t, e)), this.#r());
1451
+ }, (t) => {
1452
+ this.#x || (this.#d.delete(e), this.#O(e, t));
1453
+ }));
1454
+ }
1455
+ }
1456
+ #C() {
1457
+ let e = [];
1458
+ for (let { id: t, unit: n, row: r } of this.#s.load) {
1459
+ let { idx: a } = n, o = i(n, a.pack, "pack");
1460
+ if (!this.#N(t, o)) continue;
1461
+ let s = a.col ? i(n, a.col, "col") : null;
1462
+ e.push({
1463
+ id: t,
1464
+ pack: o,
1465
+ col: s,
1466
+ offset: r.offset,
1467
+ length: r.length
1468
+ });
1469
+ }
1470
+ return e;
1471
+ }
1472
+ #w() {
1473
+ if (this.#b) return;
1474
+ let { start: e, abort: t } = this.#o.next();
1475
+ for (let e of t) this.#f.get(e)?.abort();
1476
+ for (let t of e) {
1477
+ let e = new AbortController();
1478
+ this.#f.set(t, e), this.#t.batch(t, e.signal, this.#T).then(() => this.#E(t), (e) => this.#D(t, e));
1479
+ }
1480
+ }
1481
+ #T = ({ id: e, page: t }) => {
1482
+ if (this.#x) return;
1483
+ let n = this.#e.pages.get(e);
1484
+ if (!n) return;
1485
+ let { keep: r } = this.#s, i = this.#c;
1486
+ this.#n.add(e, t, [n.unit.e, n.unit.n], (e) => r.has(e) || i.has(e)) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + Xe), this.#A(e, Xe)), this.#r();
1487
+ };
1488
+ #E(e) {
1489
+ this.#x || (this.#f.delete(e), this.#k(e.pack), this.#l = this.#l.filter((e) => this.#N(e.id, e.pack)), this.#o.want(this.#l), this.#o.done(e), this.#w(), this.#r());
1490
+ }
1491
+ #D(e, t) {
1492
+ this.#x || (this.#f.delete(e), this.#o.done(e), t instanceof DOMException && t.name === "AbortError" || this.#O(e.pack, t));
1493
+ }
1494
+ #O(e, t) {
1495
+ if (t instanceof o) {
1496
+ if (this.#b) return;
1497
+ this.#b = !0, this.#i();
1498
+ return;
1499
+ }
1500
+ let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, Ye) : Je;
1501
+ this.#p.set(e, {
1502
+ delay: r,
1503
+ until: this.#u + r
1504
+ }), this.#A(e, r);
1505
+ }
1506
+ #k(e) {
1507
+ this.#p.delete(e), this.#j(e);
1508
+ }
1509
+ #A(e, t) {
1510
+ clearTimeout(this.#h.get(e));
1511
+ let n = setTimeout(() => {
1512
+ this.#h.delete(e), this.#r();
1513
+ }, t);
1514
+ this.#h.set(e, n);
1515
+ }
1516
+ #j(e) {
1517
+ clearTimeout(this.#h.get(e)), this.#h.delete(e);
1518
+ }
1519
+ #M() {
1520
+ let e = this.#u;
1521
+ if (e - this.#y < Ze) return;
1522
+ this.#y = e;
1523
+ for (let e of this.#g) this.#n.holds(e) || this.#g.delete(e);
1524
+ for (let [t, n] of this.#m) n <= e && this.#m.delete(t);
1525
+ for (let [t, n] of this.#_) e - n >= Ze && this.#_.delete(t);
1526
+ let { keep: t } = this.#s;
1527
+ if (this.#e.pages.size <= 2 * (this.#g.size + t.size)) return;
1528
+ let n = /* @__PURE__ */ new Set([
1529
+ ...t,
1530
+ ...this.#c,
1531
+ ...this.#g
1532
+ ]);
1533
+ for (let e of this.#_.keys()) for (let { id: t } of e.pages) n.add(t);
1534
+ for (let e of this.#e.prune(n)) this.#n.holds(e) && this.#n.remove(e);
1535
+ }
1536
+ #N(e, t) {
1537
+ return !this.#e.pages.has(e) || this.#n.holds(e) ? !1 : !this.#P(e) && !this.#F(t);
1538
+ }
1539
+ #P(e) {
1540
+ let t = this.#m.get(e);
1541
+ return t !== void 0 && this.#u < t;
1542
+ }
1543
+ #F(e) {
1544
+ let t = this.#p.get(e);
1545
+ return t !== void 0 && this.#u < t.until;
1546
+ }
1547
+ };
1548
+ //#endregion
1549
+ //#region src/engine/stream/remote.ts
1550
+ function $e(e, t) {
1551
+ let n = /* @__PURE__ */ new Map();
1552
+ return (r) => {
1553
+ if ("unfetch" in r) return void n.get(r.unfetch)?.abort();
1554
+ let i = r.fetch, a = new AbortController();
1555
+ n.set(i, a), (async () => e(r.url, r.range, a.signal))().then((e) => {
1556
+ let n = e.slice();
1557
+ t({
1558
+ fetched: i,
1559
+ bytes: n
1560
+ }, [n.buffer]);
1561
+ }, (e) => {
1562
+ let n = e instanceof Error ? e.message : String(e);
1563
+ t({
1564
+ fetched: i,
1565
+ error: n,
1566
+ missing: e instanceof o
1567
+ }, []);
1568
+ }).finally(() => n.delete(i));
1569
+ };
1570
+ }
1571
+ //#endregion
1572
+ //#region src/engine/stream/worker.ts?worker&inline
1573
+ var et = "(function(){var e=class extends Error{name=`Missing`};let t=async(t,n,r)=>{let i=await fetch(t,n?{signal:r,headers:{Range:`bytes=${n[0]}-${n[1]-1}`}}:{signal:r});if(i.status===404)throw new e(`http 404 for ${t}`);if(i.status!==200&&i.status!==206)throw Error(`http ${i.status} for ${t}`);let a=new Uint8Array(await i.arrayBuffer());return n&&i.status===200?a.slice(n[0],n[1]):a},n=.28209479177387814,r=15.625,i=`GMIX`,a={position:0,alpha:6,rotationIndex:7,rotation:8,scale:11,dc:14,label:17},o={origin:0,step:3,scaleMin:6,scaleMax:9,dcMin:12,dcMax:15,shScale:18};async function s(e,t){let n=new ReadableStream({start(t){t.enqueue(e),t.close()}}).pipeThrough(t);return new Uint8Array(await new Response(n).arrayBuffer())}function c(e){return s(e,new DecompressionStream(`deflate-raw`))}function l(e){return s(e,new CompressionStream(`deflate-raw`))}async function u(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.length<8||String.fromCharCode(...e.subarray(0,4))!==t)throw Error(`not a ${n} file`);let i=r.getUint16(4,!0);if(i!==1)throw Error(`${n} version ${i}; narcissus reads 1`);let a;try{a=await c(e.subarray(8))}catch{throw Error(`${n} body is not a valid deflate stream`)}return new DataView(a.buffer,a.byteOffset,a.byteLength)}function d(e,t){let n=``;for(let r=0;r<8;r++){let i=e.getUint8(t+r);n+=i.toString(16).padStart(2,`0`)}return n}function f(e,t){let n=/* @__PURE__ */ new Float32Array(6);for(let r=0;r<6;r++)n[r]=e.getFloat32(t+20+4*r,!0);return{g:e.getUint8(t),i:e.getUint8(t+1),j:e.getUint8(t+2),count:e.getUint32(t+4,!0),quadrants:[e.getUint32(t+8,!0),e.getUint32(t+12,!0),e.getUint32(t+16,!0)],box:n,offset:e.getUint32(t+44,!0),length:e.getUint32(t+48,!0)}}async function p(e){let t=await u(e,i,`.idx`);if(t.byteLength<40)throw Error(`.idx header is cut off`);let n=t.getUint16(32,!0),r=t.getUint8(34),a=t.getUint16(36,!0),o=40+n*52+r*9+a*11;if(t.byteLength!==o)throw Error(`.idx holds ${t.byteLength} bytes, its counts need ${o}`);let s=d(t,24),c={level:t.getUint8(0),e:t.getInt32(4,!0),n:t.getInt32(8,!0),pack:d(t,12),packSize:t.getUint32(20,!0),col:s===`0000000000000000`?null:s,rows:[],children:[],descendants:[]},l=40;for(let e=0;e<n;e++,l+=52)c.rows.push(f(t,l));for(let e=0;e<r;e++,l+=9)c.children.push({quadrant:t.getUint8(l),idx:d(t,l+1)});for(let e=0;e<a;e++,l+=11)c.descendants.push({depth:t.getUint8(l),column:t.getUint8(l+1),row:t.getUint8(l+2),idx:d(t,l+3)});return c}function m(e,t,n){return`u/${e.level}/${e.e}/${e.n}.${t}.${n}`}let h=/(?:^|\\/)u\\/(\\d+)\\/(-?\\d+)\\/(-?\\d+)\\.([0-9a-f]{16})\\.(?:idx|pack|col)$/;function g(e){let t=h.exec(e);return t?{level:Number(t[1]),e:Number(t[2]),n:Number(t[3]),hash:t[4]}:null}async function _(e){let t=await u(e,`GMCL`,`.col`);if(t.byteLength<60)throw Error(`.col header is cut off`);let n=t.getUint16(0,!0),r=60+12*n*n;if(t.byteLength!==r)throw Error(`.col holds ${t.byteLength} bytes, ${n} nodes need ${r}`);let i=new Float32Array(12*n*n),a=60;for(let e=0;e<12;e++){let r=t.getFloat32(12+4*e,!0)/127;for(let o=0;o<n;o++){let s=0;for(let c=0;c<n;c++,a++)s=s+t.getInt8(a)<<24>>24,i[(e*n+o)*n+c]=s*r}}return{n,pitch:t.getFloat32(4,!0),margin:t.getFloat32(8,!0),values:i}}function v(e,t,n,r){let{n:i,pitch:a,margin:o,values:s}=e,c=i-1,l=Math.min(Math.max((t+o)/a-.5,0),c),u=Math.min(Math.max((n+o)/a-.5,0),c),d=Math.min(Math.floor(l),Math.max(c-1,0)),f=Math.min(Math.floor(u),Math.max(c-1,0)),p=Math.min(d+1,c),m=Math.min(f+1,c),h=l-d,g=u-f,_=(1-h)*(1-g),v=h*(1-g),y=(1-h)*g,b=h*g,x=i*i;for(let e=0,t=0;e<12;e++,t+=x)r[e]=s[t+f*i+d]*_+s[t+f*i+p]*v+s[t+m*i+d]*y+s[t+m*i+p]*b;return r}let y=Float64Array.from({length:256},(e,t)=>(t/255-.5)*Math.SQRT2);function b(e,t,n,r,i){let a=y[t],o=y[n],s=y[r];i[e]=Math.sqrt(Math.max(0,1-a*a-o*o-s*s)),i[e>0?0:1]=a,i[e>1?1:2]=o,i[e>2?2:3]=s}function x(e,t,n,r,i){let a=e[0],o=e[1],s=e[2],c=e[3],l=t*t,u=n*n,d=r*r,f=1-2*(s*s+c*c),p=2*(o*s-a*c),m=2*(o*c+a*s),h=2*(o*s+a*c),g=1-2*(o*o+c*c),_=2*(s*c-a*o),v=2*(o*c-a*s),y=2*(s*c+a*o),b=1-2*(o*o+s*s);i[0]=3*Math.sqrt(f*f*l+p*p*u+m*m*d),i[1]=3*Math.sqrt(h*h*l+g*g*u+_*_*d),i[2]=3*Math.sqrt(v*v*l+y*y*u+b*b*d)}function S(e){if(e.length<128)throw Error(`page payload is shorter than its header`);return new DataView(e.buffer,e.byteOffset,e.byteLength)}function C(e){let t=S(e),n=t.getUint32(0,!0),r=t.getUint16(16,!0),i=128+(17+(r>0?2:0))*n,a=i+r*9;if(e.length!==a)throw Error(`page payload holds ${e.length} bytes, its header needs ${a}`);return{view:t,count:n,k:r,book:i}}function w(e){return[e.getUint32(4,!0),e.getUint32(8,!0),e.getUint32(12,!0)]}function T(e,t){let{view:n,count:r,k:i,book:s}=C(e),c=/* @__PURE__ */ new Float32Array(27);for(let e=0;e<27;e++)c[e]=n.getFloat32(20+4*e,!0);i===0&&c.fill(0,o.shScale);let l=new Uint32Array(r*4),u=new Float32Array(Math.ceil(r/256)*6),d=/* @__PURE__ */ new Float64Array(768);for(let e=0;e<3;e++){let t=c[o.scaleMin+e],n=c[o.scaleMax+e]-t;for(let r=0;r<256;r++)d[e*256+r]=Math.exp(t+r/255*n)}let f=c[o.step],p=c[o.step+1],m=c[o.step+2],h=128+a.position*r,g=128+a.alpha*r,_=128+a.rotationIndex*r,v=128+a.rotation*r,y=128+a.scale*r,S=/* @__PURE__ */ new Float64Array(4),T=/* @__PURE__ */ new Float64Array(3),O=0,k=0,A=0;for(let t=0,n=0;n<r;t++){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,C=-1/0;for(let t=Math.min(n+256,r);n<t;n++){let t=e[h+n]|e[h+r+n]<<8;O=O+(t>>>1^-(t&1))&65535,t=e[h+2*r+n]|e[h+3*r+n]<<8,k=k+(t>>>1^-(t&1))&65535,t=e[h+4*r+n]|e[h+5*r+n]<<8,A=A+(t>>>1^-(t&1))&65535;let u=e[_+n],w=e[v+n],E=e[v+r+n],D=e[v+2*r+n],j=e[y+n],M=e[y+r+n],N=e[y+2*r+n],P=n*4;l[P]=O|k<<16,l[P+1]=A|e[g+n]<<16|u<<24,l[P+2]=w|E<<8|D<<16|j<<24,l[P+3]=M|N<<8,b(u,w,E,D,S),x(S,d[j],d[256+M],d[512+N],T);let F=O*f,I=k*p,L=A*m;i=Math.min(i,F-T[0]),a=Math.min(a,I-T[1]),o=Math.min(o,L-T[2]),s=Math.max(s,F+T[0]),c=Math.max(c,I+T[1]),C=Math.max(C,L+T[2])}u.set([i,a,o,s,c,C],t*6)}let j=t?D(e,r,i,s,l,c,t):E(e,r,i,s);return{count:r,quadrants:w(n),geometry:l,colour:j,params:c,clusters:u}}function E(e,t,n,r){let i=new Uint32Array(t*3),o=128+a.dc*t,s=128+a.label*t;for(let a=0;a<t;a++){let c=a*3;if(i[c]=e[o+a]|e[o+t+a]<<8|e[o+2*t+a]<<16,n===0)continue;let l=r+(e[s+a]|e[s+t+a]<<8)*9;i[c]|=e[l]<<24,i[c+1]=e[l+1]|e[l+2]<<8|e[l+3]<<16|e[l+4]<<24,i[c+2]=e[l+5]|e[l+6]<<8|e[l+7]<<16|e[l+8]<<24}return i}function D(e,t,r,i,s,c,l){let u=128+a.dc*t,d=128+a.label*t,f=new Int8Array(e.buffer,e.byteOffset+i,r*9),p=new Float32Array(t*3),m=new Float32Array(t*9),h=[1/0,1/0,1/0],g=[-1/0,-1/0,-1/0],_=/* @__PURE__ */ new Float32Array(9),y=/* @__PURE__ */ new Float32Array(12),b=c[o.origin],x=c[o.origin+1],S=c[o.step],C=c[o.step+1],w=/* @__PURE__ */ new Float64Array(768);for(let e=0;e<3;e++){let t=c[o.dcMin+e],n=c[o.dcMax+e]-t;for(let r=0;r<256;r++)w[e*256+r]=t+r/255*n}let T=new Float64Array(Math.max(r,1)*9);for(let e=0;e<r*9;e++)T[e]=f[e]/127*c[o.shScale+e%9];for(let i=0;i<t;i++){let a=s[i*4];v(l,b+(a&65535)*S,x+(a>>>16)*C,y);for(let r=0;r<3;r++){let a=i*3+r;p[a]=w[r*256+e[u+r*t+i]]+y[r]/n,h[r]=Math.min(h[r],p[a]),g[r]=Math.max(g[r],p[a])}let o=r>0?(e[d+i]|e[d+t+i]<<8)*9:0;for(let e=0;e<9;e++){let t=i*9+e;m[t]=T[o+e]+y[3+e],_[e]=Math.max(_[e],Math.abs(m[t]))}}for(let e=0;e<3;e++)c[o.dcMin+e]=t>0?h[e]:0,c[o.dcMax+e]=t>0?g[e]:0;c.set(_,o.shScale);let E=[0,1,2].map(e=>{let t=c[o.dcMax+e]-c[o.dcMin+e];return t>0?255/t:0}),D=Array.from(_,e=>e>0?127/e:0),O=[0,1,2].map(e=>c[o.dcMin+e]),k=new Uint32Array(t*3),A=new Uint8Array(k.buffer);for(let e=0;e<t;e++){let t=e*4*3;for(let n=0;n<3;n++){let r=Math.round((p[e*3+n]-O[n])*E[n]);A[t+n]=Math.min(255,Math.max(0,r))}for(let n=0;n<9;n++){let r=Math.round(m[e*9+n]*D[n]);A[t+3+n]=Math.min(127,Math.max(-127,r))}}return k}async function O(e,t){return p(await A(e,t))}async function*k(e,t,n,r){let i=t.col===null?null:M(e,t.col,n),a=await j(e,t,r),o=await i;for(let[e,n]of t.pages.entries()){let t=await c(a[e]);r?.throwIfAborted(),yield{id:n.id,page:T(t,o)}}}async function A(e,t){let n=await e.cache.get(t);if(n)return n;let r=await e.fetch(e.base+t,null);return e.cache.put(t,r),r}async function j(e,t,n){let r=t.pages.map(e=>`${t.pack}#${e.offset}+${e.length}`),i=await Promise.all(r.map(t=>e.cache.get(t)));if(n?.throwIfAborted(),i.every(e=>e!==void 0))return i;let a=await e.fetch(e.base+t.pack,[t.start,t.end],n);if(a.length!==t.end-t.start)throw Error(`${t.pack}: ${a.length} bytes for ${t.start}-${t.end}`);return t.pages.map((n,o)=>{let s=a.slice(n.offset-t.start,n.offset-t.start+n.length);return i[o]||e.cache.put(r[o],s),s})}function M(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=A(e,t).then(_);i.catch(()=>{n.get(t)===i&&n.delete(t)}),r=i}if(n.set(t,r),n.size>64){let[e]=n.keys();n.delete(e)}return r}function N(e){let t=/* @__PURE__ */ new Map,n=0;return{async get(e){let n=t.get(e);return n&&(t.delete(e),t.set(e,n)),n},async put(r,i){let a=t.get(r);if(a&&(t.delete(r),n-=a.length),!(i.length>e)){t.set(r,i),n+=i.length;for(let[r,i]of t){if(n<=e)break;t.delete(r),n-=i.length}}}}}async function P(e,t){let n;try{n=await(await I()).getDirectoryHandle(String(t),{create:!0})}catch{return null}let r=/* @__PURE__ */ new Map,i=0,a=!1,o=(e,t)=>{i+=t-(r.get(e)??0),r.delete(e),r.set(e,t)},s=e=>{i-=r.get(e)??0,r.delete(e)},c=()=>{if(a)for(let[t,a]of r){if(i<=e)break;r.delete(t),i-=a,n.removeEntry(t).catch(()=>void 0)}};return z(n).then(e=>{let t=[...r];r.clear(),i=0;for(let{name:t,size:n}of e.sort((e,t)=>e.time-t.time))o(t,n);for(let[e,n]of t)o(e,n);a=!0,c()}),{async get(e){let t=encodeURIComponent(e);if(a&&!r.has(t))return;let i=await L(n,t);return i?o(t,i.length):s(t),i},async put(t,r){if(r.length===0||r.length>e)return;let i=encodeURIComponent(t);await R(n,i,r)&&(o(i,r.length),c())}}}async function F(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await I(),n=[];for await(let[r,i]of e.entries())(i.kind!==`directory`||!t.has(r))&&n.push(r);let r={recursive:!0};for(let t of n)await e.removeEntry(t,r).catch(()=>void 0)}catch{}}async function I(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function L(e,t){try{let n=await(await e.getFileHandle(t)).getFile();return n.size>0?new Uint8Array(await n.arrayBuffer()):void 0}catch{return}}async function R(e,t,n){let r;try{return r=await(await e.getFileHandle(t,{create:!0})).createWritable(),await r.write(n),await r.close(),!0}catch{return r?.abort().catch(()=>void 0),!1}}async function z(e){let t=[];try{for await(let[n,r]of e.entries()){if(r.kind!==`file`)continue;let e=await r.getFile().catch(()=>null);e&&t.push({name:n,size:e.size,time:e.lastModified})}}catch{}return t}function B(t){let n=/* @__PURE__ */ new Map,r=0;return{fetch:(i,a,o)=>new Promise((s,c)=>{if(o?.aborted)return c(o.reason);let l=++r,u=()=>{n.delete(l),t({unfetch:l}),c(o.reason)};n.set(l,t=>{o?.removeEventListener(`abort`,u),`bytes`in t?s(t.bytes):c(t.missing?new e(t.error):Error(t.error))}),o?.addEventListener(`abort`,u,{once:!0}),t({fetch:l,url:i,range:a})}),take(e){let t=n.get(e.fetched);n.delete(e.fetched),t?.(e)}}}let V=(e,t,n)=>Math.min(n,Math.max(t,e));function ee(e,t,n){return n>t?V(Math.round((e-t)/(n-t)*255),0,255):0}function te(e,t){return t>0?V(Math.round(e/t*127),-127,127):0}function H(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function ne(e,t,n){return H(e>>6)|H(t>>6)<<1|H(n>>6)<<2}function re(e,t){let n=/* @__PURE__ */ new Float32Array(9);for(let r=0;r<t;r++)for(let t=0;t<9;t++)n[t]=Math.max(n[t],Math.abs(e[r*9+t]));return n}function ie(e,t,n){let r=new Int8Array(t*9);for(let i=0;i<t;i++)for(let t=0;t<9;t++)r[i*9+t]=te(e[i*9+t],n[t]);let i=e=>r.subarray(e*9,(e+1)*9),a=/* @__PURE__ */ new Map,o=[],s=new Uint16Array(t);for(let e=0;e<t;e++){let t=i(e).join(),n=a.get(t);n===void 0&&(n=o.length,a.set(t,n),o.push(e)),s[e]=n}if(o.length>2048){let e=o.length/256,n=Array.from({length:256},(t,n)=>o[Math.floor(n*e)]);o.splice(0,o.length,...n);for(let e=0;e<t;e++){let t=1/0;for(let n=0;n<256;n++){let i=0;for(let t=0;t<9;t++)i+=(r[e*9+t]-r[o[n]*9+t])**2;i<t&&(t=i,s[e]=n)}}}let c=new Int8Array(o.length*9);return o.forEach((e,t)=>c.set(i(e),t*9)),{book:c,labels:s}}function ae(e,t){let{count:n,position:i,rotation:o,scale:s,alpha:c,dc:l,sh:u}=e,d=[1/0,1/0,1/0],f=[-1/0,-1/0,-1/0],p=[...d],m=[...f],h=[...d],g=[...f];for(let e=0;e<n;e++)for(let t=0;t<3;t++)d[t]=Math.min(d[t],i[e*3+t]),f[t]=Math.max(f[t],i[e*3+t]),p[t]=Math.min(p[t],s[e*3+t]),m[t]=Math.max(m[t],s[e*3+t]),h[t]=Math.min(h[t],l[e*3+t]),g[t]=Math.max(g[t],l[e*3+t]);let _=5e-4*2**t.g,v=Float32Array.from(d),y=Float32Array.from(d,(e,t)=>Math.max(_,(f[t]-e)/65535)),b=new Uint16Array(n*3);for(let e=0;e<n;e++)for(let t=0;t<3;t++){let n=(i[e*3+t]-v[t])/y[t];b[e*3+t]=V(Math.round(n),0,65535)}let S=r*2**t.g,C=(t.i+.5)*S,w=(t.j+.5)*S,T=new Uint8Array(n),E=new Float64Array(n);for(let e=0;e<n;e++){let t=+(i[e*3]>=C),n=+(i[e*3+1]>=w);T[e]=t+2*n,E[e]=T[e]*2**30+ne(b[e*3],b[e*3+1],b[e*3+2])}let D=Uint32Array.from({length:n},(e,t)=>t).sort((e,t)=>E[e]-E[t]),O=[0,0,0];for(let e=1;e<4;e++)O[e-1]=T.filter(t=>t<e).length;let k=u?re(u,n):/* @__PURE__ */ new Float32Array(9),{book:A,labels:j}=u?ie(u,n,k):{book:null,labels:null},M=A?A.length/9:0,N=17+(M>0?2:0),P=new Uint8Array(128+N*n+M*9),F=new DataView(P.buffer);F.setUint32(0,n,!0),O.forEach((e,t)=>F.setUint32(4+4*t,e,!0)),F.setUint16(16,M,!0),[...v,...y,...p,...m,...h,...g,...k].forEach((e,t)=>F.setFloat32(20+4*t,e,!0));let I=e=>128+e*n,L=new Float32Array([...d,...f]),R=/* @__PURE__ */ new Float64Array(4),z=/* @__PURE__ */ new Float64Array(3),B=[0,0,0];for(let e=0;e<n;e++){let t=D[e];for(let n=0;n<3;n++){let r=b[t*3+n]-B[n]<<16>>16,i=r<0?-2*r-1:2*r;B[n]=b[t*3+n],P[I(a.position+2*n)+e]=i&255,P[I(a.position+2*n+1)+e]=i>>8}P[I(a.alpha)+e]=V(Math.round(c[t]*255),0,255);let n=Math.hypot(...o.subarray(t*4,t*4+4));for(let e=0;e<4;e++)R[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(R[e])>Math.abs(R[r])&&(r=e);let u=R[r]<0?-1:1;P[I(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*R[t]/Math.SQRT2+.5)*255);P[I(a.rotation+n++)+e]=V(i,0,255)}for(let n=0;n<3;n++)P[I(a.scale+n)+e]=ee(s[t*3+n],p[n],m[n]),P[I(a.dc+n)+e]=ee(l[t*3+n],h[n],g[n]);j&&(P[I(a.label)+e]=j[t]&255,P[I(a.label+1)+e]=j[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(R,d,f,_,z);for(let e=0;e<3;e++)L[e]=Math.min(L[e],i[t*3+e]-z[e]),L[3+e]=Math.max(L[3+e],i[t*3+e]+z[e])}return A&&P.set(new Uint8Array(A.buffer),I(N)),{payload:P,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:O,box:L,offset:0,length:0}}}function oe(e,t,n){e.setUint8(t,n.g),e.setUint8(t+1,n.i),e.setUint8(t+2,n.j),e.setUint32(t+4,n.count,!0),n.quadrants.forEach((n,r)=>e.setUint32(t+8+4*r,n,!0)),n.box.forEach((n,r)=>e.setFloat32(t+20+4*r,n,!0)),e.setUint32(t+44,n.offset,!0),e.setUint32(t+48,n.length,!0)}function se(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function U(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function ce(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return se(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function le(e){let{rows:t,children:n,descendants:r}=e,a=new Uint8Array(40+t.length*52+n.length*9+r.length*11),o=new DataView(a.buffer);o.setUint8(0,e.level),o.setInt32(4,e.e,!0),o.setInt32(8,e.n,!0),a.set(U(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(U(e.col),24),o.setUint16(32,t.length,!0),o.setUint8(34,n.length),o.setUint16(36,r.length,!0);let s=40;for(let e of t)oe(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(U(e.idx),s+1),s+=9;for(let e of r)o.setUint8(s,e.depth),o.setUint8(s+1,e.column),o.setUint8(s+2,e.row),a.set(U(e.idx),s+3),s+=11;return ce(a,i)}function ue(e){let t=3421674724,n=2216829733;for(let r=0;r<e.length;r++){n=(n^e[r])>>>0;let i=n*435;t=t*435+(n<<8>>>0)+Math.floor(i/4294967296)>>>0,n=i>>>0}return t.toString(16).padStart(8,`0`)+n.toString(16).padStart(8,`0`)}function de(e){return()=>{e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/2**32}}let W=16384,fe=1408,pe=65535,G=324121,me=.4,he=[[12,1/7e3,0,1/9e3,.7],[9,1/2300,1.1,1/3100,.4],[6,1/800,.3,1/1100,2],[3,1/150,.9,1/210,1.7]],ge=he.reduce((e,[t,n,,r])=>e+t*(n+r),0),_e=Float32Array.from({length:fe*9},(e,t)=>{let n=Math.floor(t/9),r=t%9,i=(n*(37+2*r)+11*r)%255-127;return r===0&&(i=n%255-127),r===1&&(i=20*Math.floor(n/255)-50),i/127*.04}),K=new TextEncoder,ve={version:1,crs:`synthetic`,height:`synthetic`,leaf:250,roots:[512e4,6144e3].map(e=>({level:12,e:0,n:e})).map(e=>({...e,idx:m(e,q(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},ye=K.encode(JSON.stringify(ve));function be(){return async(t,n)=>{if(t.endsWith(`world.json`))return Se(ye,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!Ce(r)||r.hash!==q(r,i))throw new e(`no file ${t}`);return i===`idx`?Se(await ke(r),n):Ae(r,n,t)}}function xe(e,t){let n=30;for(let[r,i,a,o,s]of he)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function Se(e,t){return t?e.slice(t[0],t[1]):e.slice()}function q(e,t){return ue(K.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function J(e,t,n){let{e:r,n:i}=ve.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function Ce({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&J(t,n,r)}function we(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Te(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function Ee(e){let t=[];for(let n of we(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Te(r),o=Te(r>>1);J(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function De(e,t){let n=e.level-t,r=250*2**n,i=[];for(let a=0;n>=0&&a<2**t;a++)for(let o=0;o<2**t;o++){let t={level:n,e:e.e+o*r,n:e.n+a*r};J(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Oe(e,{g:t,i:n,j:i},a){let o=r*2**t,s=o/128,c=3*1.2*s,l=1.17*s,u=xe(e.e+(n+.5)*o,e.n+(i+.5)*o),d=ge*o/2,f=Float32Array.of(n*o-c,i*o-c,Math.max(0,u-d)-l,(n+1)*o+c,(i+1)*o+c,Math.min(60,u+d)+l),p=W/4;return{g:t,i:n,j:i,count:W,quadrants:[p,2*p,3*p],box:f,offset:a,length:G}}function ke(e){let t=Ee(e),n=[];for(let{column:t,row:r,unit:i}of De(e,1))n.push({quadrant:t+2*r,idx:q(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of De(e,t))r.push({depth:t,column:n,row:i,idx:q(a,`idx`)});return le({level:e.level,e:e.e,n:e.n,pack:q(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Oe(e,t,n*G)),children:n,descendants:r})}function Ae(e,t,n){let r=Ee(e);if(!t||t[0]%G!=0||t[1]%G!=0||t[0]>=t[1]||t[1]>r.length*G)throw Error(`${n}: the synthetic world serves whole pages only`);let i=new Uint8Array(t[1]-t[0]);for(let n=0;n<i.length;n+=G)je(Ne(e,r[(t[0]+n)/G]),i,n);return i}function je(e,t,n){let r=n;for(let n=0;n<e.length;n+=pe){let i=Math.min(pe,e.length-n);t[r]=+(n+i===e.length),t[r+1]=i&255,t[r+2]=i>>8,t[r+3]=~i&255,t[r+4]=~i>>8&255,t.set(e.subarray(n,n+i),r+5),r+=5+i}}let Me=e=>de(parseInt(ue(K.encode(e)).slice(8),16));function Ne(e,{g:t,i,j:a}){let o=W,s=r*2**t/128,c=Me(`${e.level}/${e.e}/${e.n}/${t}/${i}/${a}`),l=new Float64Array(3*o),u=new Float32Array(4*o),d=new Float32Array(3*o),f=new Float32Array(o),p=new Float32Array(3*o),m=new Float32Array(9*o);for(let t=0;t<o;t++){let r=(i*128+t%128+.5+me*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+me*(2*c()-1))*s,h=xe(e.e+r,e.n+o);l[3*t]=r,l[3*t+1]=o,l[3*t+2]=h;let g=Math.PI*c(),_=.1/2*(2*c()-1);u[4*t]=Math.cos(g)*Math.cos(_),u[4*t+1]=Math.cos(g)*Math.sin(_),u[4*t+2]=Math.sin(g)*Math.sin(_),u[4*t+3]=Math.sin(g)*Math.cos(_);for(let e=0;e<2;e++)d[3*t+e]=Math.log(s*(.6+.6*c()));d[3*t+2]=Math.log(s*.15*(.5+.5*c())),f[t]=.35+.65*c();let v=h/60,y=.5+.5*Math.sin((e.e+r)/410)*Math.sin((e.n+o)/330);p[3*t]=(.32+.2*v+.1*y-.5)/n,p[3*t+1]=(.42+.15*y-.1*v-.5)/n,p[3*t+2]=(.25+.1*v+.04*c()-.5)/n;let b=t%fe;m.set(_e.subarray(9*b,9*(b+1)),9*t)}return ae({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Y=2**20,X=self,Z,Pe=/* @__PURE__ */ new Map,Q=/* @__PURE__ */ new Map,Fe=B(e=>X.postMessage(e,[]));X.onmessage=({data:e})=>{`fetched`in e?Fe.take(e):e.type===`init`?(Z=Ie(e),Z.catch(()=>void 0)):e.type===`abort`?Q.get(e.id)?.abort():Re(e)};async function Ie(e){return e.source===`synthetic`?{fetch:be(),cache:await $({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Fe.fetch:t,cache:await $(e),base:e.base}}async function $({cache:e,shard:t,shards:n}){return e===`memory`?N(256*Y):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&F(n),await P(await Le()/n,t)??N(256*Y))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Y,e===void 0?1/0:e/2)}catch{return 4096*Y}}async function Re(t){let{id:n}=t,r=new AbortController;Q.set(n,r);try{if(!Z)throw Error(`stream worker used before init`);let e=await Z;if(t.type===`idx`)X.postMessage({id:n,value:await O(e,t.path)},[]);else{for await(let i of k(e,t.batch,Pe,r.signal))X.postMessage({id:n,page:i},ze(i));X.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);X.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Q.delete(n)}}function ze({page:e}){let t=/* @__PURE__ */ new Set;for(let n of[e.geometry,e.colour,e.params,e.clusters])t.add(n.buffer);return[...t]}})();", tt = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", et], { type: "text/javascript;charset=utf-8" });
1574
+ function nt(e) {
1575
+ let t;
1576
+ try {
1577
+ if (t = tt && (self.URL || self.webkitURL).createObjectURL(tt), !t) throw "";
1578
+ let n = new Worker(t, { name: e?.name });
1579
+ return n.addEventListener("error", () => {
1580
+ (self.URL || self.webkitURL).revokeObjectURL(t);
1581
+ }), n;
1582
+ } catch {
1583
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(et), { name: e?.name });
1584
+ }
1585
+ }
1586
+ //#endregion
1587
+ //#region src/engine/stream/loader.ts
1588
+ var rt = class {
1589
+ #e;
1590
+ #t = /* @__PURE__ */ new Map();
1591
+ #n = 0;
1592
+ constructor(e) {
1593
+ let { base: t, cache: n, source: r, workers: i } = e;
1594
+ this.#e = Array.from({ length: i }, (e, a) => {
1595
+ let o = new nt(), s = { worker: o }, c = typeof r == "function" ? $e(r, (e, t) => o.postMessage(e, t)) : void 0;
1596
+ o.onmessage = ({ data: e }) => {
1597
+ "id" in e ? this.#i(e) : c?.(e);
1598
+ }, o.onerror = () => this.#a(s);
1599
+ let l = {
1600
+ type: "init",
1601
+ base: t,
1602
+ cache: n,
1603
+ source: typeof r == "function" ? "page" : r,
1604
+ shard: a,
1605
+ shards: i
1606
+ };
1607
+ return o.postMessage(l), s;
1608
+ });
1609
+ }
1610
+ idx(e) {
1611
+ let t = {
1612
+ type: "idx",
1613
+ id: ++this.#n,
1614
+ path: e
1615
+ };
1616
+ return this.#r(this.#e[0], t);
1617
+ }
1618
+ batch(e, t, n) {
1619
+ if (t.aborted) return Promise.reject(B());
1620
+ let r = this.#e[it(`${e.pack}#${e.window}`, this.#e.length)], i = {
1621
+ type: "batch",
1622
+ id: ++this.#n,
1623
+ batch: e
1624
+ };
1625
+ return this.#r(r, i, t, n);
1626
+ }
1627
+ destroy() {
1628
+ for (let { worker: e } of this.#e) e.terminate();
1629
+ for (let e of this.#t.values()) e.reject(B());
1630
+ }
1631
+ #r(e, t, n, r) {
1632
+ if (e.error) return Promise.reject(e.error);
1633
+ let { id: i } = t;
1634
+ return new Promise((a, o) => {
1635
+ let s = () => {
1636
+ this.#t.delete(i), n?.removeEventListener("abort", c);
1637
+ }, c = () => {
1638
+ s(), e.worker.postMessage({
1639
+ type: "abort",
1640
+ id: i
1641
+ }), o(B());
1642
+ };
1643
+ this.#t.set(i, {
1644
+ slot: e,
1645
+ page: r,
1646
+ resolve: (e) => {
1647
+ s(), a(e);
1648
+ },
1649
+ reject: (e) => {
1650
+ s(), o(e);
1651
+ }
1652
+ }), n?.addEventListener("abort", c, { once: !0 }), e.worker.postMessage(t);
1653
+ });
1654
+ }
1655
+ #i(e) {
1656
+ let t = this.#t.get(e.id);
1657
+ t && ("page" in e ? t.page?.(e.page) : "error" in e ? t.reject(e.missing ? new o(e.error) : Error(e.error)) : t.resolve("value" in e ? e.value : void 0));
1658
+ }
1659
+ #a(e) {
1660
+ e.error = /* @__PURE__ */ Error("a stream worker failed");
1661
+ for (let t of this.#t.values()) t.slot === e && t.reject(e.error);
1662
+ }
1663
+ };
1664
+ function it(e, t) {
1665
+ let n = 2166136261;
1666
+ for (let t = 0; t < e.length; t++) n = Math.imul(n ^ e.charCodeAt(t), 16777619);
1667
+ return (n >>> 0) % t;
1668
+ }
1669
+ function B() {
1670
+ return new DOMException("The request was aborted.", "AbortError");
1671
+ }
1672
+ //#endregion
1673
+ //#region src/engine/world/tree.ts
1674
+ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1675
+ roots = [];
1676
+ pages = /* @__PURE__ */ new Map();
1677
+ units = /* @__PURE__ */ new Map();
1678
+ #e;
1679
+ #t;
1680
+ #n = 0;
1681
+ #r = /* @__PURE__ */ new Map();
1682
+ #i = /* @__PURE__ */ new Map();
1683
+ constructor(e) {
1684
+ this.#e = new Set(e.roots.map(H)), this.#t = Math.max(...e.roots.map((e) => e.level));
1685
+ }
1686
+ add(e, t) {
1687
+ let n = H(e), r = this.units.get(n);
1688
+ if (r) return r;
1689
+ let o = /* @__PURE__ */ new Map(), s = {
1690
+ level: e.level,
1691
+ e: e.e,
1692
+ n: e.n,
1693
+ idx: e,
1694
+ path: t,
1695
+ parent: null,
1696
+ pages: [],
1697
+ grid: o
1698
+ };
1699
+ for (let t of e.rows) {
1700
+ let n = t.box, r = {
1701
+ id: this.#n++,
1702
+ unit: s,
1703
+ row: t,
1704
+ g: t.g,
1705
+ box: Float64Array.of(e.e + n[0], e.n + n[1], n[2], e.e + n[3], e.n + n[4], n[5]),
1706
+ parent: null,
1707
+ children: [
1708
+ null,
1709
+ null,
1710
+ null,
1711
+ null
1712
+ ]
1713
+ };
1714
+ this.pages.set(r.id, r), s.pages.push(r), o.set(V(t.g, t.i, t.j), r);
1715
+ }
1716
+ this.units.set(n, s), this.#r.delete(n);
1717
+ for (let t = e.level + 1; t <= this.#t; t++) {
1718
+ let n = H(U(e, t));
1719
+ this.#i.set(n, (this.#i.get(n) ?? 0) + 1);
1720
+ }
1721
+ let c = new Set(e.rows.map((e) => e.g)), l = Math.max(...c), u = e.level === 0 ? 0 : e.level + 1, d = new Set(e.children.map((e) => e.quadrant));
1722
+ for (let e of s.pages) {
1723
+ let { g: t, i: n, j: r } = e.row;
1724
+ c.has(t + 1) && (e.parent = o.get(V(t + 1, n >> 1, r >> 1)) ?? null);
1725
+ for (let i = 0; i < 4; i++) {
1726
+ let a = 2 * n + (i & 1), s = 2 * r + (i >> 1);
1727
+ c.has(t - 1) ? e.children[i] = o.get(V(t - 1, a, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((a >> 3) + 2 * (s >> 3)) ? void 0 : null);
1728
+ }
1729
+ }
1730
+ if (this.#e.has(n)) for (let e of s.pages) e.g === l && this.roots.push(e);
1731
+ else {
1732
+ let t = this.units.get(H(U(e, e.level + 1)));
1733
+ t && this.#o(t, s);
1734
+ }
1735
+ let f = a(s.idx);
1736
+ for (let { key: t } of f) {
1737
+ let n = t.level === e.level - 1 ? this.units.get(H(t)) : void 0;
1738
+ n && this.#o(s, n);
1739
+ }
1740
+ for (let { key: e, hash: t } of f) {
1741
+ let n = H(e);
1742
+ if (this.units.has(n)) continue;
1743
+ let r = this.#r.get(n);
1744
+ if (r && r.from <= s.level) continue;
1745
+ let a = this.#s(s, e), o = {
1746
+ ...e,
1747
+ path: i(e, t, "idx"),
1748
+ over: a
1749
+ };
1750
+ this.#r.set(n, {
1751
+ wanted: o,
1752
+ from: s.level
1753
+ });
1754
+ }
1755
+ return s;
1756
+ }
1757
+ wanted() {
1758
+ return Array.from(this.#r.values(), (e) => e.wanted);
1759
+ }
1760
+ ground(e, t) {
1761
+ for (let n of this.roots) {
1762
+ let [r, i, a] = ot(n);
1763
+ if (e < r || e >= r + a || t < i || t >= i + a) continue;
1764
+ let o = n;
1765
+ for (;;) {
1766
+ let n = +(e >= r + a / 2), s = +(t >= i + a / 2), c = o.children[n + 2 * s];
1767
+ if (!c) return o.box[2];
1768
+ o = c, [r, i, a] = ot(o);
1769
+ }
1770
+ }
1771
+ }
1772
+ prune(e) {
1773
+ let t = [], n = [...this.units.values()].sort((e, t) => e.level - t.level);
1774
+ for (let r of n) {
1775
+ let n = H(r);
1776
+ if (this.#e.has(n) || this.#i.has(n) || r.pages.some((t) => e.has(t.id))) continue;
1777
+ for (let e of r.pages) this.pages.delete(e.id), t.push(e.id);
1778
+ let i = r.parent;
1779
+ if (i) {
1780
+ let e = 250 * 2 ** r.level, t = (r.e - i.e) / e, n = (r.n - i.n) / e, a = i.idx.children.some((e) => e.quadrant === t + 2 * n);
1781
+ for (let e of this.#s(i, r)) e.children.fill(a ? void 0 : null);
1782
+ }
1783
+ this.units.delete(n);
1784
+ for (let e = r.level + 1; e <= this.#t; e++) {
1785
+ let t = H(U(r, e)), n = this.#i.get(t) - 1;
1786
+ n ? this.#i.set(t, n) : this.#i.delete(t);
1787
+ }
1788
+ for (let { key: e } of a(r.idx)) this.#a(e);
1789
+ this.#a(r);
1790
+ }
1791
+ return t;
1792
+ }
1793
+ #a(e) {
1794
+ let t = H(e);
1795
+ this.#r.delete(t);
1796
+ for (let n = e.level + 1; n <= e.level + 3; n++) {
1797
+ let r = this.units.get(H(U(e, n)));
1798
+ if (!r) continue;
1799
+ let o = a(r.idx).find((e) => H(e.key) === t);
1800
+ if (!o) continue;
1801
+ let s = {
1802
+ level: e.level,
1803
+ e: e.e,
1804
+ n: e.n,
1805
+ path: i(o.key, o.hash, "idx"),
1806
+ over: this.#s(r, e)
1807
+ };
1808
+ this.#r.set(t, {
1809
+ wanted: s,
1810
+ from: r.level
1811
+ });
1812
+ return;
1813
+ }
1814
+ }
1815
+ #o(e, t) {
1816
+ t.parent = e;
1817
+ let n = t.level + 1, r = 250 * 2 ** t.level, i = (t.e - e.e) / r, a = (t.n - e.n) / r, o = e.grid;
1818
+ for (let n of this.#s(e, t)) n.children.fill(null);
1819
+ for (let e of t.pages) {
1820
+ if (e.g !== n) continue;
1821
+ let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(V(n + 1, t >> 1, r >> 1)) ?? null;
1822
+ e.parent = s, s && (s.children[(t & 1) + 2 * (r & 1)] = e);
1823
+ }
1824
+ }
1825
+ #s(t, n) {
1826
+ let r = t.level + 1, i = e * 2 ** r, a = (n.e - t.e) / i, o = (n.n - t.n) / i, s = 250 * 2 ** n.level / i, c = [];
1827
+ for (let e = o; e < o + s; e++) for (let n = a; n < a + s; n++) {
1828
+ let i = t.grid.get(V(r, n, e));
1829
+ i && c.push(i);
1830
+ }
1831
+ return c;
1832
+ }
1833
+ };
1834
+ function H(e) {
1835
+ return `${e.level}/${e.e}/${e.n}`;
1836
+ }
1837
+ function U(e, t) {
1838
+ let n = 250 * 2 ** t;
1839
+ return {
1840
+ level: t,
1841
+ e: Math.floor(e.e / n) * n,
1842
+ n: Math.floor(e.n / n) * n
1843
+ };
1844
+ }
1845
+ function ot(t) {
1846
+ let n = e * 2 ** t.g;
1847
+ return [
1848
+ t.unit.e + t.row.i * n,
1849
+ t.unit.n + t.row.j * n,
1850
+ n
1851
+ ];
1852
+ }
1853
+ //#endregion
1854
+ //#region src/engine/engine.ts
1855
+ var W = class extends Error {
1856
+ constructor() {
1857
+ super("This viewer needs WebGPU. Update to the latest Chrome, Edge, Safari or Firefox."), this.name = "NoWebGpu";
1858
+ }
1859
+ };
1860
+ async function st(e, t) {
1861
+ let n = await p();
1862
+ if (!n) throw new W();
1863
+ let r = e.getContext("webgpu");
1864
+ if (!r) throw n.device.destroy(), new W();
1865
+ r.configure({
1866
+ device: n.device,
1867
+ format: n.format,
1868
+ alphaMode: "opaque"
1869
+ }), (t.cache ?? "opfs") === "opfs" && navigator.storage?.persist().catch(() => !1);
1870
+ let { source: i = "http" } = t;
1871
+ return new Ot(e, n, r, t, i === "synthetic" ? (await import("./synthetic-BZcHRI1P.js")).synthetic() : i === "http" ? s : i);
1872
+ }
1873
+ var G = .2, ct = 25165824, lt = 2.5, ut = 1 + L, dt = 1024, ft = 2048, pt = 100, mt = 2, K = 300, ht = 100, gt = 250, _t = 300, vt = 1e3, yt = 400, bt = 5e3, xt = 60, q = Math.PI / 180, St = "The viewer was closed.", Ct = "Another world was opened.";
1874
+ function J(e, t) {
1875
+ let n = Math.min(t.maxStorageBufferBindingSize, t.maxBufferSize), r = (t, r) => {
1876
+ let i = Math.ceil(e * t / 256) * 256;
1877
+ return Math.min(i, Math.floor(n / r / 256) * 256);
1878
+ };
1879
+ return {
1880
+ pool: r(lt, 16),
1881
+ frame: r(ut, 24)
1882
+ };
1883
+ }
1884
+ function wt(e, t) {
1885
+ let [n, r, i] = t;
1886
+ if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= ft) return e;
1887
+ let a = (e) => Math.round(e / dt) * dt;
1888
+ return [
1889
+ a(n),
1890
+ a(r),
1891
+ a(i)
1892
+ ];
1893
+ }
1894
+ function Tt(e, t, n, r, i, a) {
1895
+ let o = 2 * e[0] / t[0] - 1, s = 1 - 2 * e[1] / t[1], c = [
1896
+ n * o / r[0],
1897
+ n * s / r[5],
1898
+ -n
1899
+ ], [l, u, d] = w(C(/* @__PURE__ */ new Float64Array(16), i), c);
1900
+ return [
1901
+ l + a[0],
1902
+ u + a[1],
1903
+ d + a[2]
1904
+ ];
1905
+ }
1906
+ function Et(e, t) {
1907
+ return [
1908
+ e.e - t[0],
1909
+ e.n - t[1],
1910
+ e.h - t[2]
1911
+ ];
1912
+ }
1913
+ function Dt(e, t) {
1914
+ e.push(t), e.length > xt && e.shift();
1915
+ }
1916
+ var Ot = class {
1917
+ #e;
1918
+ #t;
1919
+ #n;
1920
+ #r;
1921
+ #i;
1922
+ #a;
1923
+ #o = new Ge();
1924
+ #s;
1925
+ #c;
1926
+ #l;
1927
+ #u = new Ne();
1928
+ #d = new Ie();
1929
+ #f = (e) => this.#s.has(e);
1930
+ #p = null;
1931
+ #m = null;
1932
+ #h = null;
1933
+ #g = null;
1934
+ #_ = 0;
1935
+ #v = !1;
1936
+ #y = {
1937
+ e: 0,
1938
+ n: 0,
1939
+ h: 0,
1940
+ yaw: 0,
1941
+ pitch: 0,
1942
+ fov: 45
1943
+ };
1944
+ #b = -Infinity;
1945
+ #x = [
1946
+ 0,
1947
+ 0,
1948
+ 0
1949
+ ];
1950
+ #S = [
1951
+ 0,
1952
+ 0,
1953
+ 0
1954
+ ];
1955
+ #C = /* @__PURE__ */ new Float64Array(16);
1956
+ #w = /* @__PURE__ */ new Float64Array(16);
1957
+ #T = /* @__PURE__ */ new Float64Array(16);
1958
+ #E = /* @__PURE__ */ new Float64Array(16);
1959
+ #D = /* @__PURE__ */ new Float32Array(24);
1960
+ #O;
1961
+ #k;
1962
+ #A = 0;
1963
+ #j = 0;
1964
+ #M = !1;
1965
+ #N = null;
1966
+ #P = -Infinity;
1967
+ #F = !0;
1968
+ #I = !0;
1969
+ #L = !1;
1970
+ #R = !1;
1971
+ #z = !1;
1972
+ #B = 0;
1973
+ #V = -Infinity;
1974
+ #H = -Infinity;
1975
+ #U = -Infinity;
1976
+ #W = [];
1977
+ #G = [];
1978
+ #K = [];
1979
+ #q = [];
1980
+ #J = [];
1981
+ #Y = [];
1982
+ #X = [];
1983
+ #Z = /* @__PURE__ */ new Set();
1984
+ #Q = /* @__PURE__ */ new Set();
1985
+ #$ = !1;
1986
+ #ee = !1;
1987
+ #te = !1;
1988
+ constructor(e, t, n, r, i) {
1989
+ this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = { ...r.settings }, this.#O = [
1990
+ e.width,
1991
+ e.height,
1992
+ 1
1993
+ ], this.#k = [Math.max(1, e.width), Math.max(1, e.height)];
1994
+ let { pool: a, frame: o } = J(this.#ne, t.device.limits);
1995
+ this.#s = new _(t.device, a), this.#c = new Te(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
1996
+ if (!this.#ee) {
1997
+ this.#te = !0, cancelAnimationFrame(this.#A);
1998
+ for (let t of this.#Z) t(e.message || e.reason);
1999
+ }
2000
+ });
2001
+ }
2002
+ async open(e) {
2003
+ if (this.#ee) throw Error(St);
2004
+ let t = ++this.#_, i = () => {
2005
+ if (this.#ee) throw Error(St);
2006
+ if (t !== this.#_) throw Error(Ct);
2007
+ }, { cache: a = "opfs", source: o = "http" } = this.#r;
2008
+ o === "http" && (e = new URL(e, document.baseURI).href);
2009
+ let s = await this.#i(e, null), c = r(JSON.parse(new TextDecoder().decode(s)));
2010
+ i();
2011
+ let l = new rt({
2012
+ base: n(e),
2013
+ workers: Math.min(6, Math.max(2, navigator.hardwareConcurrency - 2)),
2014
+ cache: a,
2015
+ source: o
2016
+ }), u = new at(c);
2017
+ try {
2018
+ let e = await Promise.all(c.roots.map((e) => l.idx(e.idx)));
2019
+ i(), e.forEach((e, t) => u.add(e, c.roots[t].idx));
2020
+ } catch (e) {
2021
+ throw l.destroy(), e;
2022
+ }
2023
+ return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#N = null, this.#u = new Ne(), this.#d = new Ie(), this.#s.clear(), this.#g = this.#ie(u, l), this.#I = !0, this.requestFrame(), c;
2024
+ }
2025
+ setCamera(e) {
2026
+ if (this.#ee) return;
2027
+ let t = performance.now(), n = t - this.#b, r = this.#y, i = this.#x;
2028
+ if (n > gt) i.fill(0);
2029
+ else if (n > 0) {
2030
+ let t = 1 - Math.exp(-n / ht);
2031
+ i[0] += t * ((e.e - r.e) / n - i[0]), i[1] += t * ((e.n - r.n) / n - i[1]), i[2] += t * ((e.h - r.h) / n - i[2]);
2032
+ }
2033
+ this.#b = t, this.#y = { ...e }, this.#F = !0, this.#$ || this.requestFrame();
2034
+ }
2035
+ configure(e) {
2036
+ if (this.#ee) return;
2037
+ this.#a = {
2038
+ ...this.#a,
2039
+ ...e
2040
+ };
2041
+ let { pool: t, frame: n } = J(this.#ne, this.#t.device.limits);
2042
+ (t > this.#s.capacity || n > this.#l) && this.#re(t, n), this.#I = !0, this.requestFrame();
2043
+ }
2044
+ resize(e, t, n) {
2045
+ this.#ee || (this.#O = [
2046
+ e,
2047
+ t,
2048
+ n
2049
+ ], this.#se());
2050
+ }
2051
+ pick(e, t) {
2052
+ if (this.#ee || this.#te) return Promise.resolve(null);
2053
+ let [n, r] = this.#k, [i, a] = this.#O, o = e * n / Math.max(1, i), s = t * r / Math.max(1, a);
2054
+ return new Promise((e) => {
2055
+ this.#J.push({
2056
+ x: o,
2057
+ y: s,
2058
+ resolve: e
2059
+ }), this.requestFrame();
2060
+ });
2061
+ }
2062
+ ground(e, t) {
2063
+ return this.#m?.ground(e, t);
2064
+ }
2065
+ heights(e, t, n) {
2066
+ return this.#ee || this.#te ? Promise.resolve(null) : new Promise((r) => {
2067
+ this.#Y.push({
2068
+ west: e,
2069
+ south: t,
2070
+ cells: n,
2071
+ resolve: r
2072
+ }), this.requestFrame();
2073
+ });
2074
+ }
2075
+ stats() {
2076
+ let e = this.#s, t = this.#g, n = this.#c.stats();
2077
+ return {
2078
+ frameMs: z(this.#W, .5),
2079
+ cpuMs: z(this.#G, .5),
2080
+ gpuMs: n.gpuMs,
2081
+ passes: n.passes,
2082
+ drawn: n.drawn,
2083
+ planned: this.#N?.planned ?? 0,
2084
+ missing: this.#N?.missing ?? 0,
2085
+ pages: {
2086
+ resident: Array.from(e.ids()).length,
2087
+ drawn: this.#B,
2088
+ loading: t?.loading ?? 0,
2089
+ queued: t?.queued ?? 0
2090
+ },
2091
+ memory: {
2092
+ pool: e.bytes,
2093
+ buffers: n.bytes
2094
+ },
2095
+ capacity: e.capacity,
2096
+ scale: this.#o.scale,
2097
+ loading: t !== null && !t.idle
2098
+ };
2099
+ }
2100
+ idle() {
2101
+ return this.#ee ? Promise.resolve() : new Promise((e) => {
2102
+ this.#X.push(e), this.requestFrame();
2103
+ });
2104
+ }
2105
+ use(e) {
2106
+ if (this.#ee) return () => {};
2107
+ let t = e({
2108
+ shade: (e) => this.#oe(this.#K, e, this.#c.shade(e)),
2109
+ post: (e) => this.#oe(this.#q, e, this.#c.post(e))
2110
+ });
2111
+ return () => {
2112
+ this.#ee || t();
2113
+ };
2114
+ }
2115
+ warm() {
2116
+ let e = performance.now();
2117
+ e - this.#V < vt || (this.#H = e + yt, this.requestFrame());
2118
+ }
2119
+ onFrame(e) {
2120
+ return this.#Q.add(e), () => this.#Q.delete(e);
2121
+ }
2122
+ onLost(e) {
2123
+ return this.#Z.add(e), () => this.#Z.delete(e);
2124
+ }
2125
+ requestFrame() {
2126
+ this.#ee || this.#te || this.#r.manual || this.#A || (this.#A = requestAnimationFrame(this.#ce));
2127
+ }
2128
+ async step() {
2129
+ if (this.#ee || this.#te) return {
2130
+ cpuMs: 0,
2131
+ gpuMs: 0,
2132
+ passes: {}
2133
+ };
2134
+ let { done: e, cpuMs: t } = this.#le(!1);
2135
+ await e;
2136
+ let { gpuMs: n, passes: r } = this.#c.stats();
2137
+ return {
2138
+ cpuMs: t,
2139
+ gpuMs: n,
2140
+ passes: r
2141
+ };
2142
+ }
2143
+ destroy() {
2144
+ if (!this.#ee) {
2145
+ this.#ee = !0, cancelAnimationFrame(this.#A), this.#g?.destroy(), this.#h?.destroy(), this.#c.destroy(), this.#s.destroy();
2146
+ for (let { resolve: e } of this.#J.splice(0)) e(null);
2147
+ for (let { resolve: e } of this.#Y.splice(0)) e(null);
2148
+ for (let e of this.#X.splice(0)) e();
2149
+ this.#t.device.destroy();
2150
+ }
2151
+ }
2152
+ get #ne() {
2153
+ let e = Math.floor(J(Infinity, this.#t.device.limits).frame / ut);
2154
+ return Math.max(1, Math.min(this.#a.budget, e));
2155
+ }
2156
+ #re(e, t) {
2157
+ this.#g?.destroy(), this.#g = null, this.#c.destroy(), this.#s.destroy(), this.#s = new _(this.#t.device, e), this.#s.setOrigin(this.#S);
2158
+ let n = new Te(this.#t, this.#n, this.#s, t);
2159
+ n.resize(...this.#k);
2160
+ for (let e of this.#K) e.off = n.shade(e.hook);
2161
+ for (let e of this.#q) e.off = n.post(e.hook);
2162
+ this.#c = n, this.#l = t, this.#m && this.#h && (this.#g = this.#ie(this.#m, this.#h)), this.#N = null, this.#I = !0, this.requestFrame();
2163
+ }
2164
+ #ie(e, t) {
2165
+ return new Qe(e, t, this.#s, () => {
2166
+ this.#R = !0, this.requestFrame();
2167
+ }, this.#ae);
2168
+ }
2169
+ #ae = () => {
2170
+ let e = this.#p, t = this.#m;
2171
+ this.#v || this.#ee || e === null || (this.#v = !0, this.open(e).then(() => this.#v = !1, () => {
2172
+ this.#v = !1, this.#m === t && setTimeout(this.#ae, bt);
2173
+ }));
2174
+ };
2175
+ #oe(e, t, n) {
2176
+ let r = {
2177
+ hook: t,
2178
+ off: n
2179
+ };
2180
+ return e.push(r), this.requestFrame(), () => {
2181
+ let t = e.indexOf(r);
2182
+ this.#ee || t < 0 || (e.splice(t, 1), r.off(), this.requestFrame());
2183
+ };
2184
+ }
2185
+ #se() {
2186
+ let [e, t, n] = this.#O, r = We(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
2187
+ (i !== this.#k[0] || a !== this.#k[1]) && (this.#k = [i, a], this.#e.width = i, this.#e.height = a, this.#c.resize(i, a), this.#I = !0, this.requestFrame());
2188
+ }
2189
+ #ce = (e) => {
2190
+ if (this.#A = 0, !(this.#ee || this.#te)) {
2191
+ if (this.#j >= mt) this.#M = !0;
2192
+ else {
2193
+ this.#$ = !0;
2194
+ for (let t of this.#Q) t(e);
2195
+ this.#$ = !1, this.#j++, this.#le(!0).done.finally(() => {
2196
+ this.#j--, this.#M && (this.#M = !1, this.requestFrame());
2197
+ });
2198
+ }
2199
+ }
2200
+ };
2201
+ #le(e) {
2202
+ let t = performance.now(), n = this.#o, r = this.#s, i = this.#y, [a, o] = this.#k, s = this.#a.viewDistance, c = this.#F;
2203
+ this.#F = !1;
2204
+ let l = wt(this.#S, [
2205
+ i.e,
2206
+ i.n,
2207
+ i.h
2208
+ ]);
2209
+ l !== this.#S && (this.#S = l, r.setOrigin(l));
2210
+ let u = Et(i, l);
2211
+ y(this.#C, u, i.yaw * q, i.pitch * q), b(this.#w, i.fov * q, a / o, G, s);
2212
+ let d = {
2213
+ time: t,
2214
+ width: a,
2215
+ height: o,
2216
+ view: new Float32Array(this.#C),
2217
+ proj: new Float32Array(this.#w),
2218
+ near: G,
2219
+ far: s,
2220
+ camera: Float32Array.from(u),
2221
+ origin: l
2222
+ };
2223
+ De(this.#D, S(this.#E, d.proj, d.view));
2224
+ let f = this.#m, p = this.#g, m = this.#N;
2225
+ if (f && p) {
2226
+ let e = !p.idle && t - this.#P >= pt, n = this.#I || this.#R || this.#z || this.#L;
2227
+ (!m || c || e || n) && (m = this.#ue(f, t, c));
2228
+ }
2229
+ let h = [], g = !1;
2230
+ m && p && ({drawn: h, fading: g} = this.#d.update(m.cut, this.#f, t, this.#ne), p.update(m, new Set(h.map((e) => e.id)), t)), r.upload(ct) > 0 && (this.#R = !0), r.draw(h), this.#z = g, this.#B = h.length;
2231
+ let _ = this.#J.splice(0).map((e) => this.#fe(e, d)), v = this.#Y.splice(0).map((e) => this.#pe(e, l)), x = this.#c.render(d, this.#D, this.#r.sky, _, v), C = performance.now() - t;
2232
+ if (!this.#R && !this.#L && !g && r.queued === 0 && (!p || p.idle) && (!m || m.load.length === 0 && m.idx.length === 0) && this.#X.length) {
2233
+ let e = this.#X.splice(0);
2234
+ x.then(() => e.forEach((e) => e()));
2235
+ }
2236
+ e && this.#me(t, C, c);
2237
+ let w = t < this.#H;
2238
+ return (r.queued > 0 || this.#R || this.#L || g || n.scale < 1 || w) && this.requestFrame(), {
2239
+ done: x,
2240
+ cpuMs: C
2241
+ };
2242
+ }
2243
+ #ue(e, t, n) {
2244
+ let r = this.#y, i = this.#s, [a, o] = this.#k, s = this.#o.scale, c = this.#ne, l = {
2245
+ origin: this.#S,
2246
+ width: a / s,
2247
+ height: o / s,
2248
+ tan: Math.tan(r.fov * q / 2),
2249
+ near: G,
2250
+ far: this.#a.viewDistance
2251
+ }, u = {
2252
+ ...l,
2253
+ view: this.#C
2254
+ }, d = {
2255
+ budget: c,
2256
+ capacity: i.capacity - Math.ceil(L * c),
2257
+ now: t,
2258
+ predicted: n ? this.#de(l) : void 0
2259
+ }, f = this.#u.plan(e, u, this.#f, d);
2260
+ return this.#N = f, this.#P = t, this.#I = !1, this.#L = d.predicted !== void 0, this.#R = !1, f;
2261
+ }
2262
+ #de(e) {
2263
+ let t = this.#x;
2264
+ if (t.every((e) => e === 0)) return;
2265
+ let n = this.#y, r = [
2266
+ n.e + t[0] * K - e.origin[0],
2267
+ n.n + t[1] * K - e.origin[1],
2268
+ n.h + t[2] * K - e.origin[2]
2269
+ ];
2270
+ return {
2271
+ ...e,
2272
+ view: y(this.#T, r, n.yaw * q, n.pitch * q)
2273
+ };
2274
+ }
2275
+ #fe({ x: e, y: t, resolve: n }, r) {
2276
+ let i = this.#C.slice(), a = this.#S, o = [r.width, r.height], s = (n) => Tt([e, t], o, n, r.proj, i, a);
2277
+ return {
2278
+ x: e,
2279
+ y: t,
2280
+ resolve: (e) => n(e === null ? null : s(e))
2281
+ };
2282
+ }
2283
+ #pe({ west: e, south: t, cells: n, resolve: r }, i) {
2284
+ return {
2285
+ x: e - i[0],
2286
+ y: t - i[1],
2287
+ cells: n,
2288
+ resolve: (e) => {
2289
+ if (e) for (let t = 0; t < e.length; t++) e[t] += i[2];
2290
+ r(e);
2291
+ }
2292
+ };
2293
+ }
2294
+ #me(e, t, n) {
2295
+ let r = this.#o, i = e - this.#V <= gt;
2296
+ i && Dt(this.#W, e - this.#V), Dt(this.#G, t), this.#V = e, r.sample(this.#c.stats().gpuMs, e, i && n) && this.#se(), n ? this.#U = e : r.scale < 1 && e - this.#U > _t && (r.full(), this.#se());
2297
+ }
2298
+ }, kt = 45, At = {
2299
+ yaw: 0,
2300
+ pitch: -35,
2301
+ dist: 300
2302
+ }, Y = {
2303
+ pitch: [-90, -20],
2304
+ dist: [1, 2485],
2305
+ clearance: 10,
2306
+ floor: 50
2307
+ }, jt = .1, X = Math.PI / 180, Mt = (e, [t, n]) => Math.min(n, Math.max(t, e)), Nt = (e) => (e % 360 + 360) % 360, Pt = (e, t) => (t - e + 540) % 360 - 180;
2308
+ function Ft({ leaf: e, roots: t, extent: n }) {
2309
+ let r = {
2310
+ e: (n.e[0] + n.e[1]) / 2,
2311
+ n: (n.n[0] + n.n[1]) / 2,
2312
+ h: n.h[0]
2313
+ }, i = r, a = Infinity;
2314
+ for (let o of t) {
2315
+ let t = e * 2 ** o.level, [s, c] = [Math.max(o.e, n.e[0]), Math.min(o.e + t, n.e[1])], [l, u] = [Math.max(o.n, n.n[0]), Math.min(o.n + t, n.n[1])], d = Math.hypot(Math.max(s - r.e, 0, r.e - c), Math.max(l - r.n, 0, r.n - u));
2316
+ if (d === 0) return r;
2317
+ d < a && (a = d, i = {
2318
+ e: (s + c) / 2,
2319
+ n: (l + u) / 2,
2320
+ h: n.h[0]
2321
+ });
2322
+ }
2323
+ return i;
2324
+ }
2325
+ function It(e) {
2326
+ let t = e.split(",");
2327
+ if (t.length !== 6 || t.some((e) => e.trim() === "")) return null;
2328
+ let [n, r, i, a, o, s] = t.map(Number);
2329
+ return ![
2330
+ n,
2331
+ r,
2332
+ i,
2333
+ a,
2334
+ o,
2335
+ s
2336
+ ].every(Number.isFinite) || s <= 0 ? null : {
2337
+ e: n,
2338
+ n: r,
2339
+ h: i,
2340
+ yaw: a,
2341
+ pitch: o,
2342
+ dist: s
2343
+ };
2344
+ }
2345
+ function Lt(e) {
2346
+ let t = (e, t) => +e.toFixed(t);
2347
+ return [
2348
+ t(e.e, 2),
2349
+ t(e.n, 2),
2350
+ t(e.h, 2),
2351
+ t(e.yaw, 1),
2352
+ t(e.pitch, 1),
2353
+ t(e.dist, 1)
2354
+ ].join(",");
2355
+ }
2356
+ function Z(e, t, n = Y) {
2357
+ let r = {
2358
+ e: e.e,
2359
+ n: e.n,
2360
+ h: e.h,
2361
+ yaw: Nt(e.yaw),
2362
+ pitch: Mt(e.pitch, n.pitch),
2363
+ dist: Mt(e.dist, n.dist)
2364
+ };
2365
+ if (t) {
2366
+ let e = Q(r), i = Math.max(n.floor, t(e.e, e.n) + n.clearance);
2367
+ if (e.h < i) return {
2368
+ ...Vt({
2369
+ ...e,
2370
+ h: i
2371
+ }, r),
2372
+ yaw: r.yaw
2373
+ };
2374
+ }
2375
+ return r;
2376
+ }
2377
+ function Rt(e, t) {
2378
+ let n = Math.cos(t * X);
2379
+ return {
2380
+ e: Math.sin(e * X) * n,
2381
+ n: Math.cos(e * X) * n,
2382
+ h: Math.sin(t * X)
2383
+ };
2384
+ }
2385
+ function Q(e) {
2386
+ let t = Rt(e.yaw, e.pitch);
2387
+ return {
2388
+ e: e.e - t.e * e.dist,
2389
+ n: e.n - t.n * e.dist,
2390
+ h: e.h - t.h * e.dist
2391
+ };
2392
+ }
2393
+ function zt(e) {
2394
+ return {
2395
+ ...Q(e),
2396
+ yaw: e.yaw,
2397
+ pitch: e.pitch,
2398
+ fov: 45
2399
+ };
2400
+ }
2401
+ function Bt(e, t, n) {
2402
+ let r = Q(e), [i, a, o] = [
2403
+ n.e - r.e,
2404
+ n.n - r.n,
2405
+ n.h - r.h
2406
+ ], [s, c] = [Math.sin(e.yaw * X), Math.cos(e.yaw * X)], [l, u] = [Math.sin(e.pitch * X), Math.cos(e.pitch * X)], d = i * s + a * c, f = 2 * Math.tan(t * X / 2) * (d * u + o * l);
2407
+ return {
2408
+ x: (i * c - a * s) / f,
2409
+ y: (d * l - o * u) / f
2410
+ };
2411
+ }
2412
+ function Vt(e, t) {
2413
+ let [n, r, i] = [
2414
+ t.e - e.e,
2415
+ t.n - e.n,
2416
+ t.h - e.h
2417
+ ], a = Math.hypot(n, r, i);
2418
+ return {
2419
+ e: t.e,
2420
+ n: t.n,
2421
+ h: t.h,
2422
+ yaw: Nt(Math.atan2(n, r) / X),
2423
+ pitch: Math.asin(i / a) / X,
2424
+ dist: a
2425
+ };
2426
+ }
2427
+ function Ht(e, t, n, r = Y) {
2428
+ let i = Q(e), a = Z({
2429
+ ...e,
2430
+ yaw: t,
2431
+ pitch: n
2432
+ }, void 0, r), o = Rt(a.yaw, a.pitch);
2433
+ return {
2434
+ ...a,
2435
+ e: i.e + o.e * a.dist,
2436
+ n: i.n + o.n * a.dist,
2437
+ h: i.h + o.h * a.dist
2438
+ };
2439
+ }
2440
+ function Ut(e) {
2441
+ return e.dist * Math.max(Math.sin(-e.pitch * X), jt);
2442
+ }
2443
+ function Wt(e, t, n, r) {
2444
+ let [i, a] = [Math.sin(e.yaw * X), Math.cos(e.yaw * X)];
2445
+ return {
2446
+ ...e,
2447
+ e: e.e + t * a + n * i,
2448
+ n: e.n - t * i + n * a,
2449
+ h: e.h + r
2450
+ };
2451
+ }
2452
+ function Gt(e, t, n) {
2453
+ return Wt(e, t, n * e.dist / Ut(e), 0);
2454
+ }
2455
+ function Kt(e, t, n) {
2456
+ return {
2457
+ e: e.e + (t.e - e.e) * n,
2458
+ n: e.n + (t.n - e.n) * n,
2459
+ h: e.h + (t.h - e.h) * n,
2460
+ yaw: Nt(e.yaw + Pt(e.yaw, t.yaw) * n),
2461
+ pitch: e.pitch + (t.pitch - e.pitch) * n,
2462
+ dist: e.dist * (t.dist / e.dist) ** n
2463
+ };
2464
+ }
2465
+ function qt(e, t) {
2466
+ let n = e.dist * 1e-5;
2467
+ return Math.abs(e.e - t.e) < n && Math.abs(e.n - t.n) < n && Math.abs(e.h - t.h) < n && Math.abs(e.dist - t.dist) < n && Math.abs(Pt(e.yaw, t.yaw)) < .001 && Math.abs(e.pitch - t.pitch) < .001;
2468
+ }
2469
+ //#endregion
2470
+ //#region src/controls/controls.ts
2471
+ var Jt = .2, Yt = .002, Xt = .005, Zt = .5, Qt = .05;
2472
+ function $t(e, t) {
2473
+ return 2 * e * Math.tan(45 * Math.PI / 360) / Math.max(1, t);
2474
+ }
2475
+ function en(e) {
2476
+ let t = (t) => +!!e.has(t);
2477
+ return [
2478
+ t("KeyD") - t("KeyA") + t("ArrowRight") - t("ArrowLeft"),
2479
+ t("KeyW") - t("KeyS") + t("ArrowUp") - t("ArrowDown"),
2480
+ t("KeyE") - t("KeyQ")
2481
+ ];
2482
+ }
2483
+ function tn(e, t, n, r, i = Y) {
2484
+ return qt(e, t) ? t : Z(Kt(e, t, 1 - Math.exp(-n / Qt)), r, i);
2485
+ }
2486
+ var nn = class {
2487
+ #e;
2488
+ #t;
2489
+ #n;
2490
+ #r;
2491
+ #i = new AbortController();
2492
+ #a = /* @__PURE__ */ new Map();
2493
+ #o = /* @__PURE__ */ new Set();
2494
+ #s = [0, 0];
2495
+ #c = [0, 0];
2496
+ #l = 0;
2497
+ #u = !1;
2498
+ #d;
2499
+ #f;
2500
+ #p = /* @__PURE__ */ new Set();
2501
+ #m;
2502
+ #h = null;
2503
+ constructor(e, t, n, r, i = Y) {
2504
+ this.#e = e, this.#t = t, this.#n = n, this.#r = i, this.#d = this.#E(r), this.#f = this.#d, this.#m = t.onFrame(this.#T);
2505
+ let a = this.#i.signal;
2506
+ e.addEventListener("pointerdown", this.#g, { signal: a }), e.addEventListener("pointermove", this.#_, { signal: a });
2507
+ for (let t of [
2508
+ "pointerup",
2509
+ "pointercancel",
2510
+ "lostpointercapture"
2511
+ ]) e.addEventListener(t, this.#v, { signal: a });
2512
+ e.addEventListener("wheel", this.#y, {
2513
+ passive: !1,
2514
+ signal: a
2515
+ }), e.addEventListener("dblclick", this.#S, { signal: a }), e.addEventListener("contextmenu", (e) => e.preventDefault(), { signal: a }), window.addEventListener("keydown", this.#b, { signal: a }), window.addEventListener("keyup", this.#x, { signal: a }), window.addEventListener("blur", () => this.#o.clear(), { signal: a }), this.#D();
2516
+ }
2517
+ get pose() {
2518
+ return { ...this.#f };
2519
+ }
2520
+ onChange(e) {
2521
+ return this.#p.add(e), () => this.#p.delete(e);
2522
+ }
2523
+ moveTo(e, t) {
2524
+ let n = this.#d, r = Math.min(n.dist, At.dist);
2525
+ this.#d = this.#E({
2526
+ ...n,
2527
+ e,
2528
+ n: t,
2529
+ h: this.#n(e, t),
2530
+ dist: r
2531
+ }), this.#w();
2532
+ }
2533
+ destroy() {
2534
+ this.#i.abort(), this.#m(), this.#p.clear();
2535
+ }
2536
+ #g = (e) => {
2537
+ this.#e.setPointerCapture(e.pointerId), this.#a.set(e.pointerId, {
2538
+ x: e.clientX,
2539
+ y: e.clientY
2540
+ });
2541
+ };
2542
+ #_ = (e) => {
2543
+ let t = this.#a.get(e.pointerId);
2544
+ if (!t) return this.#t.warm();
2545
+ let n = this.#C(), [r, i] = [e.clientX - t.x, e.clientY - t.y];
2546
+ if (t.x = e.clientX, t.y = e.clientY, e.pointerType === "mouse") {
2547
+ let t = !!(e.buttons & 1);
2548
+ e.buttons & 6 || t && e.shiftKey ? $(this.#c, r, i) : t && $(this.#s, r, i);
2549
+ } else if (n) {
2550
+ let e = this.#C();
2551
+ $(this.#c, e.x - n.x, e.y - n.y), this.#l += (n.d - e.d) * Xt;
2552
+ } else $(this.#s, r, i);
2553
+ this.#w();
2554
+ };
2555
+ #v = (e) => {
2556
+ this.#a.delete(e.pointerId);
2557
+ };
2558
+ #y = (e) => {
2559
+ e.preventDefault(), this.#l += e.deltaY * Yt, this.#w();
2560
+ };
2561
+ #b = (e) => {
2562
+ e.code === "KeyF" && !e.repeat && (this.#u = !this.#u), this.#o.add(e.code), this.#u && this.#w();
2563
+ };
2564
+ #x = (e) => {
2565
+ this.#o.delete(e.code);
2566
+ };
2567
+ #S = async (e) => {
2568
+ let t = await this.#t.pick(e.offsetX, e.offsetY);
2569
+ if (!t || this.#i.signal.aborted) return;
2570
+ let [n, r, i] = t;
2571
+ this.#d = Z(Vt(Q(this.#f), {
2572
+ e: n,
2573
+ n: r,
2574
+ h: i
2575
+ }), void 0, this.#r), this.#w();
2576
+ };
2577
+ #C() {
2578
+ if (this.#a.size < 2) return null;
2579
+ let [e, t] = this.#a.values();
2580
+ return {
2581
+ x: (e.x + t.x) / 2,
2582
+ y: (e.y + t.y) / 2,
2583
+ d: Math.hypot(e.x - t.x, e.y - t.y)
2584
+ };
2585
+ }
2586
+ #w() {
2587
+ this.#i.signal.aborted || this.#t.requestFrame();
2588
+ }
2589
+ #T = (e) => {
2590
+ let t = this.#h === null ? 1 / 60 : Math.min(.1, (e - this.#h) / 1e3);
2591
+ this.#h = e;
2592
+ let n = this.#d, [r, i] = this.#c;
2593
+ if (r || i) {
2594
+ let e = $t(n.dist, this.#e.clientHeight);
2595
+ n = Gt(n, -r * e, i * e);
2596
+ }
2597
+ let [a, o] = this.#s;
2598
+ if (a || o) {
2599
+ let [e, t] = [n.yaw + a * Jt, n.pitch - o * Jt];
2600
+ n = this.#u ? Ht(n, e, t, this.#r) : Z({
2601
+ ...n,
2602
+ yaw: e,
2603
+ pitch: t
2604
+ }, void 0, this.#r);
2605
+ }
2606
+ this.#l && (n = Z({
2607
+ ...n,
2608
+ dist: n.dist * Math.exp(this.#l)
2609
+ }, void 0, this.#r)), this.#c = [0, 0], this.#s = [0, 0], this.#l = 0;
2610
+ let [s, c, l] = en(this.#o), u = this.#u && (s !== 0 || l !== 0 || c !== 0);
2611
+ if (u) {
2612
+ let e = Zt * Ut(n) * t;
2613
+ n = Wt(n, s * e, c * e, l * e);
2614
+ }
2615
+ let d = this.#f;
2616
+ if (d !== n) {
2617
+ this.#d = n = this.#E(n), this.#f = tn(d, n, t, this.#n, this.#r), this.#D();
2618
+ for (let e of this.#p) e();
2619
+ }
2620
+ u || this.#f !== this.#d ? this.#w() : this.#h = null;
2621
+ };
2622
+ #E(e) {
2623
+ return Z(e, this.#n, this.#r);
2624
+ }
2625
+ #D() {
2626
+ this.#t.setCamera(zt(this.#f));
2627
+ }
2628
+ };
2629
+ function $(e, t, n) {
2630
+ e[0] += t, e[1] += n;
2631
+ }
2632
+ //#endregion
2633
+ export { oe as S, qt as _, Q as a, st as b, Wt as c, Ht as d, Vt as f, Bt as g, It as h, Kt as i, Lt as l, Gt as m, kt as n, Z as o, Ft as p, Y as r, At as s, nn as t, Ut as u, zt as v, Ve as x, W as y };